diff --git a/config/kernel/linux-sunxi-current.config b/config/kernel/linux-sunxi-current.config index 6c70a775e..081f82109 100644 --- a/config/kernel/linux-sunxi-current.config +++ b/config/kernel/linux-sunxi-current.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 5.4.51 Kernel Configuration +# Linux/arm 5.7.8 Kernel Configuration # # @@ -8,12 +8,13 @@ # CONFIG_CC_IS_GCC=y CONFIG_GCC_VERSION=90201 +CONFIG_LD_VERSION=233010000 CONFIG_CLANG_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_HAS_ASM_GOTO=y CONFIG_CC_HAS_ASM_INLINE=y CONFIG_IRQ_WORK=y -CONFIG_BUILDTIME_EXTABLE_SORT=y +CONFIG_BUILDTIME_TABLE_SORT=y # # General setup @@ -57,6 +58,7 @@ CONFIG_HARDIRQS_SW_RESEND=y CONFIG_GENERIC_IRQ_CHIP=y CONFIG_IRQ_DOMAIN=y CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_IRQ_FORCED_THREADING=y CONFIG_SPARSE_IRQ=y @@ -64,7 +66,6 @@ CONFIG_SPARSE_IRQ=y # end of IRQ subsystem CONFIG_GENERIC_IRQ_MULTI_HANDLER=y -CONFIG_ARCH_CLOCKSOURCE_DATA=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_ARCH_HAS_TICK_BROADCAST=y @@ -92,6 +93,7 @@ CONFIG_PREEMPT_NONE=y CONFIG_TICK_CPU_ACCOUNTING=y # CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set # CONFIG_IRQ_TIME_ACCOUNTING is not set +# CONFIG_SCHED_THERMAL_PRESSURE is not set CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_TASKSTATS=y @@ -170,6 +172,7 @@ CONFIG_RD_LZMA=y CONFIG_RD_XZ=y CONFIG_RD_LZO=y CONFIG_RD_LZ4=y +# CONFIG_BOOT_CONFIG is not set CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -180,7 +183,6 @@ CONFIG_UID16=y CONFIG_MULTIUSER=y # CONFIG_SGETMASK_SYSCALL is not set CONFIG_SYSFS_SYSCALL=y -# CONFIG_SYSCTL_SYSCALL is not set CONFIG_FHANDLE=y CONFIG_POSIX_TIMERS=y CONFIG_PRINTK=y @@ -203,7 +205,6 @@ CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set CONFIG_KALLSYMS_BASE_RELATIVE=y CONFIG_BPF_SYSCALL=y -# CONFIG_BPF_JIT_ALWAYS_ON is not set # CONFIG_USERFAULTFD is not set CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y CONFIG_RSEQ=y @@ -513,7 +514,6 @@ CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y CONFIG_CPUFREQ_DT=m CONFIG_CPUFREQ_DT_PLATDEV=y CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=m -CONFIG_ARM_BIG_LITTLE_CPUFREQ=m # CONFIG_QORIQ_CPUFREQ is not set # end of CPU Frequency scaling @@ -602,16 +602,12 @@ CONFIG_CRYPTO_AES_ARM=m CONFIG_CRYPTO_AES_ARM_BS=m CONFIG_CRYPTO_AES_ARM_CE=m CONFIG_CRYPTO_GHASH_ARM_CE=m -CONFIG_CRYPTO_CRCT10DIF_ARM_CE=m -CONFIG_CRYPTO_CRC32_ARM_CE=m +# CONFIG_CRYPTO_CRCT10DIF_ARM_CE is not set +# CONFIG_CRYPTO_CRC32_ARM_CE is not set CONFIG_CRYPTO_CHACHA20_NEON=m +CONFIG_CRYPTO_POLY1305_ARM=m CONFIG_CRYPTO_NHPOLY1305_NEON=m -CONFIG_VIRTUALIZATION=y -CONFIG_VHOST_NET=m -CONFIG_VHOST_SCSI=m -CONFIG_VHOST_VSOCK=m -CONFIG_VHOST=m -# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set +CONFIG_CRYPTO_CURVE25519_NEON=m # # General architecture-dependent options @@ -646,7 +642,8 @@ CONFIG_HAVE_ARCH_SECCOMP_FILTER=y CONFIG_SECCOMP_FILTER=y CONFIG_HAVE_STACKPROTECTOR=y CONFIG_CC_HAS_STACKPROTECTOR_NONE=y -# CONFIG_STACKPROTECTOR is not set +CONFIG_STACKPROTECTOR=y +CONFIG_STACKPROTECTOR_STRONG=y CONFIG_HAVE_CONTEXT_TRACKING=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y @@ -661,7 +658,6 @@ CONFIG_HAVE_COPY_THREAD_TLS=y CONFIG_CLONE_BACKWARDS=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_OLD_SIGACTION=y -CONFIG_64BIT_TIME=y CONFIG_COMPAT_32BIT_TIME=y CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y @@ -670,7 +666,6 @@ CONFIG_STRICT_KERNEL_RWX=y CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y CONFIG_STRICT_MODULE_RWX=y CONFIG_ARCH_HAS_PHYS_TO_DMA=y -CONFIG_REFCOUNT_FULL=y # CONFIG_LOCK_EVENT_COUNTS is not set # @@ -680,7 +675,6 @@ CONFIG_REFCOUNT_FULL=y CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y # end of GCOV-based kernel profiling -CONFIG_PLUGIN_HOSTCC="" CONFIG_HAVE_GCC_PLUGINS=y # end of General architecture-dependent options @@ -704,24 +698,26 @@ CONFIG_MODULE_SIG_SHA1=y CONFIG_MODULE_SIG_HASH="sha1" # CONFIG_MODULE_COMPRESS is not set # CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set -CONFIG_UNUSED_SYMBOLS=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_TRIM_UNUSED_KSYMS is not set CONFIG_MODULES_TREE_LOOKUP=y CONFIG_BLOCK=y CONFIG_BLK_SCSI_REQUEST=y +CONFIG_BLK_CGROUP_RWSTAT=y CONFIG_BLK_DEV_BSG=y CONFIG_BLK_DEV_BSGLIB=y CONFIG_BLK_DEV_INTEGRITY=y -CONFIG_BLK_DEV_ZONED=y +CONFIG_BLK_DEV_INTEGRITY_T10=y +# CONFIG_BLK_DEV_ZONED is not set CONFIG_BLK_DEV_THROTTLING=y # CONFIG_BLK_DEV_THROTTLING_LOW is not set # CONFIG_BLK_CMDLINE_PARSER is not set CONFIG_BLK_WBT=y -CONFIG_BLK_CGROUP_IOLATENCY=y +# CONFIG_BLK_CGROUP_IOLATENCY is not set # CONFIG_BLK_CGROUP_IOCOST is not set CONFIG_BLK_WBT_MQ=y -CONFIG_BLK_DEBUG_FS=y -CONFIG_BLK_DEBUG_FS_ZONED=y -CONFIG_BLK_SED_OPAL=y +# CONFIG_BLK_DEBUG_FS is not set +# CONFIG_BLK_SED_OPAL is not set # # Partition Types @@ -755,6 +751,7 @@ CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y CONFIG_MUTEX_SPIN_ON_OWNER=y CONFIG_RWSEM_SPIN_ON_OWNER=y CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y CONFIG_FREEZER=y # @@ -786,6 +783,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MEMORY_BALLOON=y CONFIG_BALLOON_COMPACTION=y CONFIG_COMPACTION=y +CONFIG_PAGE_REPORTING=y CONFIG_MIGRATION=y CONFIG_CONTIG_ALLOC=y CONFIG_BOUNCE=y @@ -798,10 +796,22 @@ CONFIG_CMA=y # CONFIG_CMA_DEBUGFS is not set CONFIG_CMA_AREAS=7 CONFIG_ZSWAP=y +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE is not set +CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO=y +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842 is not set +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4 is not set +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4HC is not set +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD is not set +CONFIG_ZSWAP_COMPRESSOR_DEFAULT="lzo" +CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y +# CONFIG_ZSWAP_ZPOOL_DEFAULT_Z3FOLD is not set +# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set +CONFIG_ZSWAP_ZPOOL_DEFAULT="zbud" +# CONFIG_ZSWAP_DEFAULT_ON is not set CONFIG_ZPOOL=y CONFIG_ZBUD=y -CONFIG_Z3FOLD=m -CONFIG_ZSMALLOC=m +CONFIG_Z3FOLD=y +CONFIG_ZSMALLOC=y # CONFIG_PGTABLE_MAPPING is not set # CONFIG_ZSMALLOC_STAT is not set CONFIG_GENERIC_EARLY_IOREMAP=y @@ -825,24 +835,20 @@ CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_SCM=y CONFIG_UNIX_DIAG=m -CONFIG_TLS=m -# CONFIG_TLS_DEVICE is not set +# CONFIG_TLS is not set CONFIG_XFRM=y CONFIG_XFRM_OFFLOAD=y CONFIG_XFRM_ALGO=y CONFIG_XFRM_USER=y CONFIG_XFRM_INTERFACE=m -CONFIG_XFRM_SUB_POLICY=y -CONFIG_XFRM_MIGRATE=y -CONFIG_XFRM_STATISTICS=y +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set CONFIG_XFRM_IPCOMP=m -CONFIG_NET_KEY=m -CONFIG_NET_KEY_MIGRATE=y -CONFIG_XDP_SOCKETS=y -CONFIG_XDP_SOCKETS_DIAG=m +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +# CONFIG_XDP_SOCKETS is not set CONFIG_INET=y -CONFIG_WIREGUARD=m -# CONFIG_WIREGUARD_DEBUG is not set CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_FIB_TRIE_STATS=y @@ -865,39 +871,46 @@ CONFIG_IP_MROUTE_MULTIPLE_TABLES=y CONFIG_IP_PIMSM_V1=y CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y -CONFIG_NET_IPVTI=m +# CONFIG_NET_IPVTI is not set CONFIG_NET_UDP_TUNNEL=m -CONFIG_NET_FOU=m -CONFIG_NET_FOU_IP_TUNNELS=y +# CONFIG_NET_FOU is not set +# CONFIG_NET_FOU_IP_TUNNELS is not set CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m +# CONFIG_INET_ESPINTCP is not set CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_TUNNEL=m CONFIG_INET_TUNNEL=m CONFIG_INET_DIAG=m CONFIG_INET_TCP_DIAG=m CONFIG_INET_UDP_DIAG=m -CONFIG_INET_RAW_DIAG=m -CONFIG_INET_DIAG_DESTROY=y +# CONFIG_INET_RAW_DIAG is not set +# CONFIG_INET_DIAG_DESTROY is not set CONFIG_TCP_CONG_ADVANCED=y -CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_BIC=y CONFIG_TCP_CONG_CUBIC=y -CONFIG_TCP_CONG_WESTWOOD=m -CONFIG_TCP_CONG_HTCP=m -CONFIG_TCP_CONG_HSTCP=m -CONFIG_TCP_CONG_HYBLA=m -CONFIG_TCP_CONG_VEGAS=m -CONFIG_TCP_CONG_NV=m -CONFIG_TCP_CONG_SCALABLE=m -CONFIG_TCP_CONG_LP=m -CONFIG_TCP_CONG_VENO=m -CONFIG_TCP_CONG_YEAH=m -CONFIG_TCP_CONG_ILLINOIS=m -CONFIG_TCP_CONG_DCTCP=m -CONFIG_TCP_CONG_CDG=m -CONFIG_TCP_CONG_BBR=m +CONFIG_TCP_CONG_WESTWOOD=y +CONFIG_TCP_CONG_HTCP=y +CONFIG_TCP_CONG_HSTCP=y +CONFIG_TCP_CONG_HYBLA=y +CONFIG_TCP_CONG_VEGAS=y +CONFIG_TCP_CONG_NV=y +CONFIG_TCP_CONG_SCALABLE=y +CONFIG_TCP_CONG_LP=y +CONFIG_TCP_CONG_VENO=y +CONFIG_TCP_CONG_YEAH=y +CONFIG_TCP_CONG_ILLINOIS=y +# CONFIG_TCP_CONG_DCTCP is not set +# CONFIG_TCP_CONG_CDG is not set +# CONFIG_TCP_CONG_BBR is not set +# CONFIG_DEFAULT_BIC is not set CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_HYBLA is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_VENO is not set +# CONFIG_DEFAULT_WESTWOOD is not set # CONFIG_DEFAULT_RENO is not set CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_TCP_MD5SIG=y @@ -913,14 +926,12 @@ CONFIG_IPV6_MIP6=m CONFIG_IPV6_ILA=m CONFIG_INET6_XFRM_TUNNEL=m CONFIG_INET6_TUNNEL=m -CONFIG_IPV6_VTI=m +# CONFIG_IPV6_VTI is not set CONFIG_IPV6_SIT=m CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m -CONFIG_IPV6_GRE=m -CONFIG_IPV6_FOU=m -CONFIG_IPV6_FOU_TUNNEL=m +# CONFIG_IPV6_GRE is not set CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y @@ -929,7 +940,9 @@ CONFIG_IPV6_PIMSM_V2=y CONFIG_IPV6_SEG6_LWTUNNEL=y CONFIG_IPV6_SEG6_HMAC=y CONFIG_IPV6_SEG6_BPF=y +# CONFIG_IPV6_RPL_LWTUNNEL is not set CONFIG_NETLABEL=y +# CONFIG_MPTCP is not set CONFIG_NETWORK_SECMARK=y CONFIG_NET_PTP_CLASSIFY=y CONFIG_NETWORK_PHY_TIMESTAMPING=y @@ -955,7 +968,7 @@ CONFIG_NETFILTER_CONNCOUNT=m CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_ZONES=y -CONFIG_NF_CONNTRACK_PROCFS=y +# CONFIG_NF_CONNTRACK_PROCFS is not set CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CONNTRACK_TIMEOUT=y CONFIG_NF_CONNTRACK_TIMESTAMP=y @@ -989,7 +1002,6 @@ CONFIG_NF_NAT_REDIRECT=y CONFIG_NF_NAT_MASQUERADE=y CONFIG_NETFILTER_SYNPROXY=m CONFIG_NF_TABLES=m -CONFIG_NF_TABLES_SET=m CONFIG_NF_TABLES_INET=y CONFIG_NF_TABLES_NETDEV=y CONFIG_NFT_NUMGEN=m @@ -1052,7 +1064,7 @@ CONFIG_NETFILTER_XT_NAT=m CONFIG_NETFILTER_XT_TARGET_NETMAP=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set CONFIG_NETFILTER_XT_TARGET_RATEEST=m CONFIG_NETFILTER_XT_TARGET_REDIRECT=m CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m @@ -1134,7 +1146,7 @@ CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m CONFIG_IP_VS=m CONFIG_IP_VS_IPV6=y -# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_DEBUG=y CONFIG_IP_VS_TAB_BITS=12 # @@ -1253,7 +1265,7 @@ 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_SECURITY is not set CONFIG_IP6_NF_NAT=m CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_IP6_NF_TARGET_NPT=m @@ -1261,10 +1273,10 @@ CONFIG_IP6_NF_TARGET_NPT=m CONFIG_NF_DEFRAG_IPV6=m CONFIG_NF_TABLES_BRIDGE=m -CONFIG_NFT_BRIDGE_META=m +# CONFIG_NFT_BRIDGE_META is not set CONFIG_NFT_BRIDGE_REJECT=m CONFIG_NF_LOG_BRIDGE=m -CONFIG_NF_CONNTRACK_BRIDGE=m +# CONFIG_NF_CONNTRACK_BRIDGE is not set CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m @@ -1311,35 +1323,36 @@ CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y # CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set # CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set CONFIG_SCTP_COOKIE_HMAC_MD5=y -CONFIG_SCTP_COOKIE_HMAC_SHA1=y +# CONFIG_SCTP_COOKIE_HMAC_SHA1 is not set CONFIG_INET_SCTP_DIAG=m CONFIG_RDS=m CONFIG_RDS_TCP=m # CONFIG_RDS_DEBUG is not set CONFIG_TIPC=m CONFIG_TIPC_MEDIA_UDP=y +CONFIG_TIPC_CRYPTO=y CONFIG_TIPC_DIAG=m CONFIG_ATM=m CONFIG_ATM_CLIP=m CONFIG_ATM_CLIP_NO_ICMP=y -CONFIG_ATM_LANE=m -# CONFIG_ATM_MPOA is not set +# CONFIG_ATM_LANE is not set CONFIG_ATM_BR2684=m CONFIG_ATM_BR2684_IPFILTER=y CONFIG_L2TP=m -CONFIG_L2TP_DEBUGFS=m +# CONFIG_L2TP_DEBUGFS is not set CONFIG_L2TP_V3=y CONFIG_L2TP_IP=m CONFIG_L2TP_ETH=m -CONFIG_STP=m -CONFIG_GARP=m -CONFIG_MRP=m -CONFIG_BRIDGE=m +CONFIG_STP=y +CONFIG_GARP=y +CONFIG_MRP=y +CONFIG_BRIDGE=y CONFIG_BRIDGE_IGMP_SNOOPING=y CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_HAVE_NET_DSA=y CONFIG_NET_DSA=m CONFIG_NET_DSA_TAG_8021Q=m +CONFIG_NET_DSA_TAG_AR9331=m CONFIG_NET_DSA_TAG_BRCM_COMMON=m CONFIG_NET_DSA_TAG_BRCM=m CONFIG_NET_DSA_TAG_BRCM_PREPEND=m @@ -1348,15 +1361,16 @@ CONFIG_NET_DSA_TAG_DSA=m CONFIG_NET_DSA_TAG_EDSA=m CONFIG_NET_DSA_TAG_MTK=m CONFIG_NET_DSA_TAG_KSZ=m +CONFIG_NET_DSA_TAG_OCELOT=m CONFIG_NET_DSA_TAG_QCA=m CONFIG_NET_DSA_TAG_LAN9303=m CONFIG_NET_DSA_TAG_SJA1105=m CONFIG_NET_DSA_TAG_TRAILER=m -CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q=y CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y # CONFIG_DECNET is not set -CONFIG_LLC=m +CONFIG_LLC=y # CONFIG_LLC2 is not set CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m @@ -1375,26 +1389,22 @@ CONFIG_6LOWPAN_NHC_IPV6=m CONFIG_6LOWPAN_NHC_MOBILITY=m CONFIG_6LOWPAN_NHC_ROUTING=m CONFIG_6LOWPAN_NHC_UDP=m -CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m -CONFIG_6LOWPAN_GHC_UDP=m -CONFIG_6LOWPAN_GHC_ICMPV6=m -CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m -CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m -CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m -CONFIG_IEEE802154=m -# CONFIG_IEEE802154_NL802154_EXPERIMENTAL is not set -CONFIG_IEEE802154_SOCKET=m -CONFIG_IEEE802154_6LOWPAN=m -CONFIG_MAC802154=m +# CONFIG_6LOWPAN_GHC_EXT_HDR_HOP is not set +# CONFIG_6LOWPAN_GHC_UDP is not set +# CONFIG_6LOWPAN_GHC_ICMPV6 is not set +# CONFIG_6LOWPAN_GHC_EXT_HDR_DEST is not set +# CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG is not set +# CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE is not set +# CONFIG_IEEE802154 is not set CONFIG_NET_SCHED=y # # Queueing/Scheduling # -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_CBQ=y +CONFIG_NET_SCH_HTB=y CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_ATM=m +# CONFIG_NET_SCH_ATM is not set CONFIG_NET_SCH_PRIO=m CONFIG_NET_SCH_MULTIQ=m CONFIG_NET_SCH_RED=m @@ -1402,32 +1412,27 @@ CONFIG_NET_SCH_SFB=m CONFIG_NET_SCH_SFQ=m CONFIG_NET_SCH_TEQL=m CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_CBS=m +# CONFIG_NET_SCH_CBS is not set CONFIG_NET_SCH_ETF=m CONFIG_NET_SCH_TAPRIO=m CONFIG_NET_SCH_GRED=m CONFIG_NET_SCH_DSMARK=m CONFIG_NET_SCH_NETEM=m -CONFIG_NET_SCH_DRR=m +# CONFIG_NET_SCH_DRR is not set CONFIG_NET_SCH_MQPRIO=m CONFIG_NET_SCH_SKBPRIO=m -CONFIG_NET_SCH_CHOKE=m +# CONFIG_NET_SCH_CHOKE is not set CONFIG_NET_SCH_QFQ=m CONFIG_NET_SCH_CODEL=m CONFIG_NET_SCH_FQ_CODEL=m CONFIG_NET_SCH_CAKE=m -CONFIG_NET_SCH_FQ=m -CONFIG_NET_SCH_HHF=m -CONFIG_NET_SCH_PIE=m +# CONFIG_NET_SCH_FQ is not set +# CONFIG_NET_SCH_HHF is not set +# CONFIG_NET_SCH_PIE is not set CONFIG_NET_SCH_INGRESS=m -CONFIG_NET_SCH_PLUG=m -CONFIG_NET_SCH_DEFAULT=y -# CONFIG_DEFAULT_FQ is not set -# CONFIG_DEFAULT_CODEL is not set -# CONFIG_DEFAULT_FQ_CODEL is not set -# CONFIG_DEFAULT_SFQ is not set -CONFIG_DEFAULT_PFIFO_FAST=y -CONFIG_DEFAULT_NET_SCH="pfifo_fast" +# CONFIG_NET_SCH_PLUG is not set +CONFIG_NET_SCH_ETS=m +# CONFIG_NET_SCH_DEFAULT is not set # # Classification @@ -1440,13 +1445,13 @@ CONFIG_NET_CLS_FW=m CONFIG_NET_CLS_U32=m CONFIG_CLS_U32_PERF=y CONFIG_CLS_U32_MARK=y -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -CONFIG_NET_CLS_FLOW=m +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +CONFIG_NET_CLS_FLOW=y CONFIG_NET_CLS_CGROUP=y -CONFIG_NET_CLS_BPF=m -CONFIG_NET_CLS_FLOWER=m -CONFIG_NET_CLS_MATCHALL=m +# CONFIG_NET_CLS_BPF is not set +# CONFIG_NET_CLS_FLOWER is not set +# CONFIG_NET_CLS_MATCHALL is not set CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_STACK=32 CONFIG_NET_EMATCH_CMP=m @@ -1455,36 +1460,32 @@ CONFIG_NET_EMATCH_U32=m CONFIG_NET_EMATCH_META=m CONFIG_NET_EMATCH_TEXT=m CONFIG_NET_EMATCH_CANID=m -CONFIG_NET_EMATCH_IPSET=m +# CONFIG_NET_EMATCH_IPSET is not set CONFIG_NET_EMATCH_IPT=m CONFIG_NET_CLS_ACT=y CONFIG_NET_ACT_POLICE=m -CONFIG_NET_ACT_GACT=m -CONFIG_GACT_PROB=y +# CONFIG_NET_ACT_GACT is not set CONFIG_NET_ACT_MIRRED=m CONFIG_NET_ACT_SAMPLE=m CONFIG_NET_ACT_IPT=m -CONFIG_NET_ACT_NAT=m -CONFIG_NET_ACT_PEDIT=m -CONFIG_NET_ACT_SIMP=m +# CONFIG_NET_ACT_NAT is not set +# CONFIG_NET_ACT_PEDIT is not set +# CONFIG_NET_ACT_SIMP is not set CONFIG_NET_ACT_SKBEDIT=m CONFIG_NET_ACT_CSUM=m -CONFIG_NET_ACT_MPLS=m +# CONFIG_NET_ACT_MPLS is not set CONFIG_NET_ACT_VLAN=m CONFIG_NET_ACT_BPF=m CONFIG_NET_ACT_CONNMARK=m -CONFIG_NET_ACT_CTINFO=m +# CONFIG_NET_ACT_CTINFO is not set CONFIG_NET_ACT_SKBMOD=m -CONFIG_NET_ACT_IFE=m +# CONFIG_NET_ACT_IFE is not set CONFIG_NET_ACT_TUNNEL_KEY=m -CONFIG_NET_ACT_CT=m -CONFIG_NET_IFE_SKBMARK=m -CONFIG_NET_IFE_SKBPRIO=m -CONFIG_NET_IFE_SKBTCINDEX=m +# CONFIG_NET_ACT_CT is not set # CONFIG_NET_TC_SKB_EXT is not set CONFIG_NET_SCH_FIFO=y CONFIG_DCB=y -CONFIG_DNS_RESOLVER=m +CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=m CONFIG_BATMAN_ADV_BATMAN_V=y CONFIG_BATMAN_ADV_BLA=y @@ -1494,26 +1495,21 @@ CONFIG_BATMAN_ADV_MCAST=y # CONFIG_BATMAN_ADV_DEBUGFS is not set # CONFIG_BATMAN_ADV_DEBUG is not set CONFIG_BATMAN_ADV_SYSFS=y -CONFIG_BATMAN_ADV_TRACING=y +# CONFIG_BATMAN_ADV_TRACING is not set CONFIG_OPENVSWITCH=m CONFIG_OPENVSWITCH_GRE=m CONFIG_OPENVSWITCH_VXLAN=m CONFIG_OPENVSWITCH_GENEVE=m -CONFIG_VSOCKETS=m -CONFIG_VSOCKETS_DIAG=m -CONFIG_VIRTIO_VSOCKETS=m -CONFIG_VIRTIO_VSOCKETS_COMMON=m +# CONFIG_VSOCKETS is not set CONFIG_NETLINK_DIAG=m CONFIG_MPLS=y CONFIG_NET_MPLS_GSO=m -CONFIG_MPLS_ROUTING=m -CONFIG_MPLS_IPTUNNEL=m +# CONFIG_MPLS_ROUTING is not set CONFIG_NET_NSH=m CONFIG_HSR=m CONFIG_NET_SWITCHDEV=y CONFIG_NET_L3_MASTER_DEV=y -CONFIG_NET_NCSI=y -CONFIG_NCSI_OEM_CMD_GET_MAC=y +# CONFIG_NET_NCSI is not set CONFIG_RPS=y CONFIG_RFS_ACCEL=y CONFIG_XPS=y @@ -1521,8 +1517,8 @@ CONFIG_CGROUP_NET_PRIO=y CONFIG_CGROUP_NET_CLASSID=y CONFIG_NET_RX_BUSY_POLL=y CONFIG_BQL=y -CONFIG_BPF_JIT=y -CONFIG_BPF_STREAM_PARSER=y +# CONFIG_BPF_JIT is not set +# CONFIG_BPF_STREAM_PARSER is not set CONFIG_NET_FLOW_LIMIT=y # @@ -1605,7 +1601,7 @@ CONFIG_CAN_EMS_USB=m CONFIG_CAN_ESD_USB2=m CONFIG_CAN_GS_USB=m CONFIG_CAN_KVASER_USB=m -CONFIG_CAN_MCBA_USB=m +# CONFIG_CAN_MCBA_USB is not set CONFIG_CAN_PEAK_USB=m CONFIG_CAN_UCAN=m # end of CAN USB interfaces @@ -1623,10 +1619,10 @@ CONFIG_BT_BNEP_PROTO_FILTER=y CONFIG_BT_HIDP=m CONFIG_BT_HS=y CONFIG_BT_LE=y -CONFIG_BT_6LOWPAN=m +# CONFIG_BT_6LOWPAN is not set CONFIG_BT_LEDS=y # CONFIG_BT_SELFTEST is not set -# CONFIG_BT_DEBUGFS is not set +CONFIG_BT_DEBUGFS=y # # Bluetooth device drivers @@ -1634,9 +1630,8 @@ CONFIG_BT_LEDS=y CONFIG_BT_INTEL=m CONFIG_BT_BCM=m CONFIG_BT_RTL=m -CONFIG_BT_QCA=m CONFIG_BT_HCIBTUSB=m -CONFIG_BT_HCIBTUSB_AUTOSUSPEND=y +# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set CONFIG_BT_HCIBTUSB_BCM=y # CONFIG_BT_HCIBTUSB_MTK is not set CONFIG_BT_HCIBTUSB_RTL=y @@ -1644,21 +1639,21 @@ CONFIG_BT_HCIBTSDIO=m CONFIG_BT_HCIUART=m CONFIG_BT_HCIUART_SERDEV=y CONFIG_BT_HCIUART_H4=y -CONFIG_BT_HCIUART_NOKIA=m +# CONFIG_BT_HCIUART_NOKIA is not set CONFIG_BT_HCIUART_BCSP=y CONFIG_BT_HCIUART_ATH3K=y CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIUART_3WIRE=y -CONFIG_BT_HCIUART_INTEL=y +# CONFIG_BT_HCIUART_INTEL is not set CONFIG_BT_HCIUART_BCM=y CONFIG_BT_HCIUART_RTL=y -CONFIG_BT_HCIUART_QCA=y -CONFIG_BT_HCIUART_AG6XX=y -CONFIG_BT_HCIUART_MRVL=y +# CONFIG_BT_HCIUART_QCA is not set +# CONFIG_BT_HCIUART_AG6XX is not set +# CONFIG_BT_HCIUART_MRVL is not set CONFIG_BT_HCIBCM203X=m CONFIG_BT_HCIBPA10X=m CONFIG_BT_HCIBFUSB=m -CONFIG_BT_HCIVHCI=m +# CONFIG_BT_HCIVHCI is not set CONFIG_BT_MRVL=m CONFIG_BT_MRVL_SDIO=m CONFIG_BT_ATH3K=m @@ -1681,12 +1676,12 @@ CONFIG_WEXT_PROC=y CONFIG_WEXT_PRIV=y CONFIG_CFG80211=m # CONFIG_NL80211_TESTMODE is not set -# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +CONFIG_CFG80211_DEVELOPER_WARNINGS=y # CONFIG_CFG80211_CERTIFICATION_ONUS is not set CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y -CONFIG_CFG80211_DEFAULT_PS=y -CONFIG_CFG80211_DEBUGFS=y +# CONFIG_CFG80211_DEFAULT_PS is not set +# CONFIG_CFG80211_DEBUGFS is not set CONFIG_CFG80211_CRDA_SUPPORT=y CONFIG_CFG80211_WEXT=y CONFIG_MAC80211=m @@ -1696,7 +1691,7 @@ CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" CONFIG_MAC80211_MESH=y CONFIG_MAC80211_LEDS=y -CONFIG_MAC80211_DEBUGFS=y +# CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_MESSAGE_TRACING is not set # CONFIG_MAC80211_DEBUG_MENU is not set CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 @@ -1704,11 +1699,9 @@ CONFIG_WIMAX=m CONFIG_WIMAX_DEBUG_LEVEL=8 CONFIG_RFKILL=m CONFIG_RFKILL_LEDS=y -CONFIG_RFKILL_INPUT=y +# CONFIG_RFKILL_INPUT is not set CONFIG_RFKILL_GPIO=m -CONFIG_NET_9P=m -CONFIG_NET_9P_VIRTIO=m -# CONFIG_NET_9P_DEBUG is not set +# CONFIG_NET_9P is not set # CONFIG_CAIF is not set CONFIG_CEPH_LIB=m # CONFIG_CEPH_LIB_PRETTYDEBUG is not set @@ -1734,6 +1727,7 @@ CONFIG_NFC_PN544_I2C=m CONFIG_NFC_PN533=m CONFIG_NFC_PN533_USB=m CONFIG_NFC_PN533_I2C=m +CONFIG_NFC_PN532_UART=m CONFIG_NFC_MICROREAD=m CONFIG_NFC_MICROREAD_I2C=m CONFIG_NFC_MRVL=m @@ -1756,13 +1750,13 @@ CONFIG_NFC_ST95HF=m CONFIG_PSAMPLE=m CONFIG_NET_IFE=m CONFIG_LWTUNNEL=y -CONFIG_LWTUNNEL_BPF=y +# CONFIG_LWTUNNEL_BPF is not set CONFIG_DST_CACHE=y CONFIG_GRO_CELLS=y -CONFIG_NET_SOCK_MSG=y CONFIG_NET_DEVLINK=y CONFIG_PAGE_POOL=y CONFIG_FAILOVER=m +CONFIG_ETHTOOL_NETLINK=y CONFIG_HAVE_EBPF_JIT=y # @@ -1791,6 +1785,7 @@ CONFIG_EXTRA_FIRMWARE="" CONFIG_FW_LOADER_USER_HELPER=y CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y # CONFIG_FW_LOADER_COMPRESS is not set +CONFIG_FW_CACHE=y # end of Firmware loader CONFIG_WANT_DEV_COREDUMP=y @@ -1804,8 +1799,6 @@ CONFIG_GENERIC_CPU_AUTOPROBE=y CONFIG_REGMAP=y CONFIG_REGMAP_I2C=y CONFIG_REGMAP_SPI=y -CONFIG_REGMAP_SPMI=m -CONFIG_REGMAP_W1=m CONFIG_REGMAP_MMIO=y CONFIG_REGMAP_IRQ=y CONFIG_REGMAP_SCCB=m @@ -1827,6 +1820,7 @@ CONFIG_ARM_CCI400_PORT_CTRL=y CONFIG_SUN50I_DE2_BUS=y CONFIG_SUNXI_RSB=y # CONFIG_VEXPRESS_CONFIG is not set +CONFIG_MHI_BUS=m # end of Bus devices # CONFIG_CONNECTOR is not set @@ -1867,19 +1861,13 @@ CONFIG_MTD_BLOCK_RO=m # # RAM/ROM/Flash chip drivers # -CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI is not set # CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=m -# CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_MAP_BANK_WIDTH_1=y CONFIG_MTD_MAP_BANK_WIDTH_2=y CONFIG_MTD_MAP_BANK_WIDTH_4=y CONFIG_MTD_CFI_I1=y CONFIG_MTD_CFI_I2=y -CONFIG_MTD_CFI_INTELEXT=m -CONFIG_MTD_CFI_AMDSTD=m -CONFIG_MTD_CFI_STAA=m -CONFIG_MTD_CFI_UTIL=m # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set @@ -1889,9 +1877,6 @@ CONFIG_MTD_CFI_UTIL=m # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_PHYSMAP=m -# CONFIG_MTD_PHYSMAP_COMPAT is not set -# CONFIG_MTD_PHYSMAP_OF is not set # CONFIG_MTD_PLATRAM is not set # end of Mapping drivers for chip access @@ -1901,7 +1886,6 @@ CONFIG_MTD_PHYSMAP=m # CONFIG_MTD_DATAFLASH is not set # CONFIG_MTD_MCHP23K256 is not set # CONFIG_MTD_SST25L is not set -CONFIG_MTD_BCM47XXSFLASH=m # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -1929,11 +1913,12 @@ CONFIG_MTD_NAND_SUNXI=m CONFIG_MTD_NAND_MXIC=m CONFIG_MTD_NAND_GPIO=m CONFIG_MTD_NAND_PLATFORM=m +CONFIG_MTD_NAND_CADENCE=m # # Misc # -CONFIG_MTD_NAND_NANDSIM=m +# CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_DISKONCHIP is not set CONFIG_MTD_SPI_NAND=m @@ -1947,7 +1932,6 @@ CONFIG_MTD_SPI_NAND=m CONFIG_MTD_SPI_NOR=y CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y # CONFIG_SPI_CADENCE_QUADSPI is not set -CONFIG_SPI_MTK_QUADSPI=m CONFIG_MTD_UBI=y CONFIG_MTD_UBI_WL_THRESHOLD=4096 CONFIG_MTD_UBI_BEB_LIMIT=20 @@ -1994,20 +1978,19 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_CDROM_PKTCDVD is not set CONFIG_ATA_OVER_ETH=m CONFIG_VIRTIO_BLK=m -# CONFIG_VIRTIO_BLK_SCSI is not set CONFIG_BLK_DEV_RBD=m # # NVME Support # CONFIG_NVME_CORE=m -CONFIG_NVME_MULTIPATH=y +# CONFIG_NVME_MULTIPATH is not set +# CONFIG_NVME_HWMON is not set CONFIG_NVME_FABRICS=m -CONFIG_NVME_FC=m +# CONFIG_NVME_FC is not set CONFIG_NVME_TARGET=m CONFIG_NVME_TARGET_LOOP=m -CONFIG_NVME_TARGET_FC=m -CONFIG_NVME_TARGET_FCLOOP=m +# CONFIG_NVME_TARGET_FC is not set CONFIG_NVME_TARGET_TCP=m # end of NVME Support @@ -2037,11 +2020,11 @@ CONFIG_PVPANIC=m # EEPROM support # CONFIG_EEPROM_AT24=m -CONFIG_EEPROM_AT25=m -CONFIG_EEPROM_LEGACY=m -CONFIG_EEPROM_MAX6875=m +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set CONFIG_EEPROM_93CX6=m -CONFIG_EEPROM_93XX46=m +# CONFIG_EEPROM_93XX46 is not set CONFIG_EEPROM_IDT_89HPESX=m CONFIG_EEPROM_EE1004=m # end of EEPROM support @@ -2059,43 +2042,12 @@ CONFIG_EEPROM_EE1004=m # # Intel MIC & related support # - -# -# Intel MIC Bus Driver -# - -# -# SCIF Bus Driver -# - -# -# VOP Bus Driver -# # CONFIG_VOP_BUS is not set - -# -# Intel MIC Host Driver -# - -# -# Intel MIC Card Driver -# - -# -# SCIF Driver -# - -# -# Intel MIC Coprocessor State Management (COSM) Drivers -# - -# -# VOP Driver -# # end of Intel MIC & related support -CONFIG_ECHO=m +# CONFIG_ECHO is not set CONFIG_MISC_RTSX_USB=m +CONFIG_UACCE=m # end of Misc devices # @@ -2113,7 +2065,6 @@ CONFIG_SCSI_PROC_FS=y CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set CONFIG_BLK_DEV_SR=m -# CONFIG_BLK_DEV_SR_VENDOR is not set CONFIG_CHR_DEV_SG=y CONFIG_CHR_DEV_SCH=m # CONFIG_SCSI_CONSTANTS is not set @@ -2141,7 +2092,9 @@ CONFIG_SCSI_VIRTIO=m # end of SCSI device support CONFIG_ATA=y +CONFIG_SATA_HOST=y CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_ATA_FORCE=y CONFIG_SATA_PMP=y # @@ -2204,13 +2157,12 @@ CONFIG_DM_CACHE_SMQ=m CONFIG_DM_WRITECACHE=m # CONFIG_DM_ERA is not set CONFIG_DM_CLONE=m -CONFIG_DM_MIRROR=m -# CONFIG_DM_LOG_USERSPACE is not set +# CONFIG_DM_MIRROR is not set CONFIG_DM_RAID=m -CONFIG_DM_ZERO=m +# CONFIG_DM_ZERO is not set CONFIG_DM_MULTIPATH=m -CONFIG_DM_MULTIPATH_QL=m -CONFIG_DM_MULTIPATH_ST=m +# CONFIG_DM_MULTIPATH_QL is not set +# CONFIG_DM_MULTIPATH_ST is not set # CONFIG_DM_DELAY is not set CONFIG_DM_DUST=m CONFIG_DM_UEVENT=y @@ -2221,7 +2173,6 @@ CONFIG_DM_VERITY=m CONFIG_DM_SWITCH=m CONFIG_DM_LOG_WRITES=m # CONFIG_DM_INTEGRITY is not set -CONFIG_DM_ZONED=m CONFIG_TARGET_CORE=m CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m @@ -2234,14 +2185,11 @@ CONFIG_MII=y CONFIG_NET_CORE=y CONFIG_BONDING=m CONFIG_DUMMY=m +CONFIG_WIREGUARD=m +# CONFIG_WIREGUARD_DEBUG is not set # CONFIG_EQUALIZER is not set CONFIG_IFB=m -CONFIG_NET_TEAM=m -CONFIG_NET_TEAM_MODE_BROADCAST=m -CONFIG_NET_TEAM_MODE_ROUNDROBIN=m -CONFIG_NET_TEAM_MODE_RANDOM=m -CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m -CONFIG_NET_TEAM_MODE_LOADBALANCE=m +# CONFIG_NET_TEAM is not set CONFIG_MACVLAN=m CONFIG_MACVTAP=m CONFIG_IPVLAN_L3S=y @@ -2249,6 +2197,7 @@ CONFIG_IPVLAN=m CONFIG_IPVTAP=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_BAREUDP=m CONFIG_GTP=m CONFIG_MACSEC=m # CONFIG_NETCONSOLE is not set @@ -2257,17 +2206,12 @@ CONFIG_TAP=m # CONFIG_TUN_VNET_CROSS_LE is not set CONFIG_VETH=m CONFIG_VIRTIO_NET=m -CONFIG_NLMON=m +# CONFIG_NLMON is not set CONFIG_NET_VRF=m -CONFIG_VSOCKMON=m CONFIG_ATM_DRIVERS=y # CONFIG_ATM_DUMMY is not set # CONFIG_ATM_TCP is not set -# -# CAIF transport drivers -# - # # Distributed Switch Architecture drivers # @@ -2291,9 +2235,9 @@ CONFIG_NET_DSA_MICROCHIP_KSZ8795_SPI=m CONFIG_NET_DSA_MV88E6XXX=m CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y CONFIG_NET_DSA_MV88E6XXX_PTP=y +CONFIG_NET_DSA_AR9331=m CONFIG_NET_DSA_SJA1105=m # CONFIG_NET_DSA_SJA1105_PTP is not set -# CONFIG_NET_DSA_SJA1105_TAS is not set CONFIG_NET_DSA_QCA8K=m CONFIG_NET_DSA_REALTEK_SMI=m CONFIG_NET_DSA_SMSC_LAN9303=m @@ -2331,7 +2275,6 @@ CONFIG_NET_VENDOR_HISILICON=y CONFIG_HIP04_ETH=m # CONFIG_HI13X1_GMAC is not set CONFIG_HNS_MDIO=m -# CONFIG_HNS is not set # CONFIG_HNS_DSAF is not set # CONFIG_HNS_ENET is not set CONFIG_NET_VENDOR_HUAWEI=y @@ -2379,6 +2322,7 @@ CONFIG_NET_VENDOR_SYNOPSYS=y # CONFIG_NET_VENDOR_WIZNET is not set CONFIG_NET_VENDOR_XILINX=y # CONFIG_XILINX_AXI_EMAC is not set +CONFIG_XILINX_LL_TEMAC=m CONFIG_MDIO_DEVICE=y CONFIG_MDIO_BUS=y CONFIG_MDIO_BCM_UNIMAC=m @@ -2388,8 +2332,11 @@ CONFIG_MDIO_BUS_MUX=y # CONFIG_MDIO_BUS_MUX_MMIOREG is not set CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m # CONFIG_MDIO_HISI_FEMAC is not set +CONFIG_MDIO_IPQ8064=m # CONFIG_MDIO_MSCC_MIIM is not set +CONFIG_MDIO_MVUSB=m CONFIG_MDIO_SUN4I=y +CONFIG_MDIO_XPCS=y CONFIG_PHYLINK=y CONFIG_PHYLIB=y CONFIG_SWPHY=y @@ -2404,35 +2351,37 @@ CONFIG_AC200_PHY=m CONFIG_AMD_PHY=m CONFIG_AQUANTIA_PHY=m CONFIG_AX88796B_PHY=m -CONFIG_AT803X_PHY=m CONFIG_BCM7XXX_PHY=m CONFIG_BCM87XX_PHY=m CONFIG_BCM_NET_PHYLIB=m CONFIG_BROADCOM_PHY=m +# CONFIG_BCM84881_PHY is not set CONFIG_CICADA_PHY=m -CONFIG_CORTINA_PHY=m +# CONFIG_CORTINA_PHY is not set CONFIG_DAVICOM_PHY=m -CONFIG_DP83822_PHY=m -# CONFIG_DP83TC811_PHY is not set +# CONFIG_DP83822_PHY is not set +CONFIG_DP83TC811_PHY=m CONFIG_DP83848_PHY=m # CONFIG_DP83867_PHY is not set +CONFIG_DP83869_PHY=m CONFIG_FIXED_PHY=y CONFIG_ICPLUS_PHY=m -CONFIG_INTEL_XWAY_PHY=m +# CONFIG_INTEL_XWAY_PHY is not set CONFIG_LSI_ET1011C_PHY=m CONFIG_LXT_PHY=m CONFIG_MARVELL_PHY=m -CONFIG_MARVELL_10G_PHY=m +# CONFIG_MARVELL_10G_PHY is not set CONFIG_MICREL_PHY=m CONFIG_MICROCHIP_PHY=m CONFIG_MICROCHIP_T1_PHY=m # CONFIG_MICROSEMI_PHY is not set CONFIG_NATIONAL_PHY=m # CONFIG_NXP_TJA11XX_PHY is not set +CONFIG_AT803X_PHY=m CONFIG_QSEMI_PHY=m CONFIG_REALTEK_PHY=m # CONFIG_RENESAS_PHY is not set -CONFIG_ROCKCHIP_PHY=m +# CONFIG_ROCKCHIP_PHY is not set CONFIG_SMSC_PHY=m CONFIG_STE10XP=m CONFIG_TERANETICS_PHY=m @@ -2523,7 +2472,6 @@ CONFIG_ATH9K_HTC=m CONFIG_ATH9K_HWRNG=y CONFIG_CARL9170=m CONFIG_CARL9170_LEDS=y -# CONFIG_CARL9170_DEBUGFS is not set CONFIG_CARL9170_WPC=y # CONFIG_CARL9170_HWRNG is not set CONFIG_ATH6KL=m @@ -2607,7 +2555,6 @@ CONFIG_RT2X00_LIB=m CONFIG_RT2X00_LIB_FIRMWARE=y CONFIG_RT2X00_LIB_CRYPTO=y CONFIG_RT2X00_LIB_LEDS=y -# CONFIG_RT2X00_LIB_DEBUGFS is not set # CONFIG_RT2X00_DEBUG is not set CONFIG_WLAN_VENDOR_REALTEK=y CONFIG_RTL8187=m @@ -2619,7 +2566,7 @@ CONFIG_RTLWIFI_USB=m # CONFIG_RTLWIFI_DEBUG is not set CONFIG_RTL8192C_COMMON=m CONFIG_RTL8XXXU=m -CONFIG_RTL8XXXU_UNTESTED=y +# CONFIG_RTL8XXXU_UNTESTED is not set CONFIG_RTL8723CS=m CONFIG_RTW88=m CONFIG_WLAN_VENDOR_RSI=y @@ -2659,18 +2606,6 @@ CONFIG_USB_NET_RNDIS_WLAN=m # end of WiMAX Wireless Broadband devices # CONFIG_WAN is not set -CONFIG_IEEE802154_DRIVERS=m -# CONFIG_IEEE802154_FAKELB is not set -CONFIG_IEEE802154_AT86RF230=m -# CONFIG_IEEE802154_AT86RF230_DEBUGFS is not set -CONFIG_IEEE802154_MRF24J40=m -CONFIG_IEEE802154_CC2520=m -CONFIG_IEEE802154_ATUSB=m -CONFIG_IEEE802154_ADF7242=m -CONFIG_IEEE802154_CA8210=m -# CONFIG_IEEE802154_CA8210_DEBUGFS is not set -CONFIG_IEEE802154_MCR20A=m -CONFIG_IEEE802154_HWSIM=m CONFIG_NETDEVSIM=m CONFIG_NET_FAILOVER=m # CONFIG_ISDN is not set @@ -2699,7 +2634,6 @@ CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_KEYBOARD=y # CONFIG_KEYBOARD_ADC is not set -CONFIG_KEYBOARD_ADP5520=m # CONFIG_KEYBOARD_ADP5588 is not set # CONFIG_KEYBOARD_ADP5589 is not set CONFIG_KEYBOARD_ATKBD=y @@ -2724,13 +2658,12 @@ CONFIG_KEYBOARD_MATRIX=m # CONFIG_KEYBOARD_STOWAWAY is not set # CONFIG_KEYBOARD_SUNKBD is not set CONFIG_KEYBOARD_SUN4I_LRADC=m +CONFIG_KEYBOARD_IQS62X=m # CONFIG_KEYBOARD_OMAP4 is not set CONFIG_KEYBOARD_TM2_TOUCHKEY=m -CONFIG_KEYBOARD_TWL4030=m # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_CAP11XX is not set # CONFIG_KEYBOARD_BCM is not set -CONFIG_KEYBOARD_MTK_PMIC=m CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=m # CONFIG_MOUSE_PS2_ALPS is not set @@ -2758,7 +2691,6 @@ CONFIG_MOUSE_SERIAL=m # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_PROPERTIES=y -CONFIG_TOUCHSCREEN_88PM860X=m CONFIG_TOUCHSCREEN_ADS7846=m # CONFIG_TOUCHSCREEN_AD7877 is not set # CONFIG_TOUCHSCREEN_AD7879 is not set @@ -2772,8 +2704,6 @@ CONFIG_TOUCHSCREEN_CHIPONE_ICN8318=m # CONFIG_TOUCHSCREEN_CY8CTMG110 is not set # CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set # CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set -CONFIG_TOUCHSCREEN_DA9034=m -CONFIG_TOUCHSCREEN_DA9052=m # CONFIG_TOUCHSCREEN_DYNAPRO is not set # CONFIG_TOUCHSCREEN_HAMPSHIRE is not set # CONFIG_TOUCHSCREEN_EETI is not set @@ -2803,23 +2733,15 @@ CONFIG_TOUCHSCREEN_ELO=m # CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set -CONFIG_TOUCHSCREEN_TI_AM335X_TSC=m -CONFIG_TOUCHSCREEN_UCB1400=m # CONFIG_TOUCHSCREEN_PIXCIR is not set # CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set -CONFIG_TOUCHSCREEN_WM831X=m -CONFIG_TOUCHSCREEN_WM97XX=m -CONFIG_TOUCHSCREEN_WM9705=y -CONFIG_TOUCHSCREEN_WM9712=y -CONFIG_TOUCHSCREEN_WM9713=y +# CONFIG_TOUCHSCREEN_WM97XX is not set # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set -CONFIG_TOUCHSCREEN_MC13783=m # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set # CONFIG_TOUCHSCREEN_TSC_SERIO is not set # CONFIG_TOUCHSCREEN_TSC2004 is not set # CONFIG_TOUCHSCREEN_TSC2005 is not set # CONFIG_TOUCHSCREEN_TSC2007 is not set -CONFIG_TOUCHSCREEN_PCAP=m # CONFIG_TOUCHSCREEN_RM_TS is not set # CONFIG_TOUCHSCREEN_SILEAD is not set # CONFIG_TOUCHSCREEN_SIS_I2C is not set @@ -2835,19 +2757,12 @@ CONFIG_TOUCHSCREEN_ZET6223=m # CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set CONFIG_TOUCHSCREEN_IQS5XX=m CONFIG_INPUT_MISC=y -CONFIG_INPUT_88PM860X_ONKEY=m -CONFIG_INPUT_88PM80X_ONKEY=m # CONFIG_INPUT_AD714X is not set -CONFIG_INPUT_ARIZONA_HAPTICS=m # CONFIG_INPUT_ATMEL_CAPTOUCH is not set # CONFIG_INPUT_BMA150 is not set # CONFIG_INPUT_E3X0_BUTTON is not set # CONFIG_INPUT_MSM_VIBRATOR is not set CONFIG_INPUT_MAX77650_ONKEY=m -CONFIG_INPUT_MAX77693_HAPTIC=m -CONFIG_INPUT_MAX8925_ONKEY=m -CONFIG_INPUT_MAX8997_HAPTIC=m -CONFIG_INPUT_MC13783_PWRBUTTON=m # CONFIG_INPUT_MMA8450 is not set # CONFIG_INPUT_GP2A is not set # CONFIG_INPUT_GPIO_BEEPER is not set @@ -2861,31 +2776,18 @@ CONFIG_INPUT_GPIO_VIBRA=m # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_CM109 is not set # CONFIG_INPUT_REGULATOR_HAPTIC is not set -CONFIG_INPUT_RETU_PWRBUTTON=m -CONFIG_INPUT_TPS65218_PWRBUTTON=m CONFIG_INPUT_AXP20X_PEK=y -CONFIG_INPUT_TWL4030_PWRBUTTON=m -CONFIG_INPUT_TWL4030_VIBRA=m -CONFIG_INPUT_TWL6040_VIBRA=m CONFIG_INPUT_UINPUT=m -CONFIG_INPUT_PALMAS_PWRBUTTON=m -CONFIG_INPUT_PCF50633_PMU=m # CONFIG_INPUT_PCF8574 is not set # CONFIG_INPUT_PWM_BEEPER is not set # CONFIG_INPUT_PWM_VIBRA is not set # CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -CONFIG_INPUT_DA9052_ONKEY=m -CONFIG_INPUT_DA9055_ONKEY=m -# CONFIG_INPUT_DA9063_ONKEY is not set -CONFIG_INPUT_WM831X_ON=m -CONFIG_INPUT_PCAP=m # CONFIG_INPUT_ADXL34X is not set # CONFIG_INPUT_IMS_PCU is not set # CONFIG_INPUT_CMA3000 is not set # CONFIG_INPUT_DRV260X_HAPTICS is not set # CONFIG_INPUT_DRV2665_HAPTICS is not set # CONFIG_INPUT_DRV2667_HAPTICS is not set -CONFIG_INPUT_RAVE_SP_PWRBUTTON=m CONFIG_INPUT_STPMIC1_ONKEY=m CONFIG_RMI4_CORE=m CONFIG_RMI4_I2C=m @@ -2915,7 +2817,7 @@ CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_APBPS2 is not set CONFIG_SERIO_SUN4I_PS2=m # CONFIG_SERIO_GPIO_PS2 is not set -CONFIG_USERIO=m +# CONFIG_USERIO is not set # CONFIG_GAMEPORT is not set # end of Hardware I/O ports # end of Input device support @@ -2931,25 +2833,17 @@ CONFIG_VT_CONSOLE_SLEEP=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=0 -CONFIG_SERIAL_NONSTANDARD=y -CONFIG_N_HDLC=m -CONFIG_N_GSM=m -CONFIG_TRACE_ROUTER=m -CONFIG_TRACE_SINK=m -CONFIG_NULL_TTY=m +# CONFIG_LEGACY_PTYS is not set CONFIG_LDISC_AUTOLOAD=y -CONFIG_DEVMEM=y -CONFIG_DEVKMEM=y # # Serial drivers # CONFIG_SERIAL_EARLYCON=y CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -CONFIG_SERIAL_8250_FINTEK=y +CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +# CONFIG_SERIAL_8250_16550A_VARIANTS is not set +# CONFIG_SERIAL_8250_FINTEK is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_DMA=y CONFIG_SERIAL_8250_NR_UARTS=8 @@ -2967,79 +2861,58 @@ CONFIG_SERIAL_OF_PLATFORM=y # Non-8250 serial port support # # CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -CONFIG_SERIAL_MAX3100=m -CONFIG_SERIAL_MAX310X=y +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX310X is not set CONFIG_SERIAL_UARTLITE=m CONFIG_SERIAL_UARTLITE_NR_UARTS=1 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_SIFIVE=m -CONFIG_SERIAL_SCCNXP=y -CONFIG_SERIAL_SCCNXP_CONSOLE=y +# CONFIG_SERIAL_SCCNXP is not set CONFIG_SERIAL_SC16IS7XX_CORE=m CONFIG_SERIAL_SC16IS7XX=m CONFIG_SERIAL_SC16IS7XX_I2C=y CONFIG_SERIAL_SC16IS7XX_SPI=y -CONFIG_SERIAL_BCM63XX=m -CONFIG_SERIAL_ALTERA_JTAGUART=m -CONFIG_SERIAL_ALTERA_UART=m -CONFIG_SERIAL_ALTERA_UART_MAXPORTS=4 -CONFIG_SERIAL_ALTERA_UART_BAUDRATE=115200 +# CONFIG_SERIAL_BCM63XX is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set # CONFIG_SERIAL_IFX6X60 is not set -CONFIG_SERIAL_XILINX_PS_UART=m -CONFIG_SERIAL_ARC=m -CONFIG_SERIAL_ARC_NR_PORTS=1 -CONFIG_SERIAL_FSL_LPUART=m -CONFIG_SERIAL_FSL_LINFLEXUART=m +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_FSL_LINFLEXUART is not set CONFIG_SERIAL_CONEXANT_DIGICOLOR=m # CONFIG_SERIAL_ST_ASC is not set +CONFIG_SERIAL_SPRD=m # end of Serial drivers CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SERIAL_DEV_BUS=y -CONFIG_SERIAL_DEV_CTRL_TTYPORT=y -CONFIG_TTY_PRINTK=y -CONFIG_TTY_PRINTK_LEVEL=6 -CONFIG_PRINTER=m -# CONFIG_LP_CONSOLE is not set -CONFIG_PPDEV=m +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +CONFIG_NULL_TTY=m +# CONFIG_TRACE_SINK is not set CONFIG_HVC_DRIVER=y # CONFIG_HVC_DCC is not set +CONFIG_SERIAL_DEV_BUS=y +CONFIG_SERIAL_DEV_CTRL_TTYPORT=y +# CONFIG_TTY_PRINTK is not set +# CONFIG_PRINTER is not set +# CONFIG_PPDEV is not set CONFIG_VIRTIO_CONSOLE=m -CONFIG_IPMI_HANDLER=m -CONFIG_IPMI_PLAT_DATA=y -# CONFIG_IPMI_PANIC_EVENT is not set -CONFIG_IPMI_DEVICE_INTERFACE=m -CONFIG_IPMI_SI=m -CONFIG_IPMI_SSIF=m -CONFIG_IPMI_WATCHDOG=m -CONFIG_IPMI_POWEROFF=m +# CONFIG_IPMI_HANDLER is not set # CONFIG_IPMB_DEVICE_INTERFACE is not set -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_TIMERIOMEM=m +CONFIG_HW_RANDOM=m +# CONFIG_HW_RANDOM_TIMERIOMEM is not set CONFIG_HW_RANDOM_VIRTIO=m CONFIG_HW_RANDOM_OPTEE=m -CONFIG_RAW_DRIVER=m -CONFIG_MAX_RAW_DEVS=256 -CONFIG_TCG_TPM=y -CONFIG_HW_RANDOM_TPM=y -CONFIG_TCG_TIS_CORE=y -CONFIG_TCG_TIS=y -CONFIG_TCG_TIS_SPI=m -CONFIG_TCG_TIS_I2C_ATMEL=m -CONFIG_TCG_TIS_I2C_INFINEON=m -CONFIG_TCG_TIS_I2C_NUVOTON=m -CONFIG_TCG_ATMEL=m -CONFIG_TCG_VTPM_PROXY=m -CONFIG_TCG_FTPM_TEE=m -CONFIG_TCG_TIS_ST33ZP24=m -CONFIG_TCG_TIS_ST33ZP24_I2C=m -CONFIG_TCG_TIS_ST33ZP24_SPI=m -CONFIG_XILLYBUS=m -CONFIG_XILLYBUS_OF=m +CONFIG_DEVMEM=y +CONFIG_DEVKMEM=y +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_XILLYBUS is not set # end of Character devices -CONFIG_RANDOM_TRUST_BOOTLOADER=y +# CONFIG_RANDOM_TRUST_BOOTLOADER is not set # # I2C support @@ -3048,27 +2921,25 @@ CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MUX=m +CONFIG_I2C_MUX=y # # Multiplexer I2C Chip support # CONFIG_I2C_ARB_GPIO_CHALLENGE=m CONFIG_I2C_MUX_GPIO=m -CONFIG_I2C_MUX_GPMUX=m -CONFIG_I2C_MUX_LTC4306=m +# CONFIG_I2C_MUX_GPMUX is not set +# CONFIG_I2C_MUX_LTC4306 is not set CONFIG_I2C_MUX_PCA9541=m CONFIG_I2C_MUX_PCA954x=m CONFIG_I2C_MUX_PINCTRL=m CONFIG_I2C_MUX_REG=m CONFIG_I2C_DEMUX_PINCTRL=m -CONFIG_I2C_MUX_MLXCPLD=m +# CONFIG_I2C_MUX_MLXCPLD is not set # end of Multiplexer I2C Chip support CONFIG_I2C_HELPER_AUTO=y -CONFIG_I2C_SMBUS=m CONFIG_I2C_ALGOBIT=y -CONFIG_I2C_ALGOPCA=m # # I2C Hardware Bus support @@ -3077,33 +2948,26 @@ CONFIG_I2C_ALGOPCA=m # # I2C system bus drivers (mostly embedded / system-on-chip) # -CONFIG_I2C_CBUS_GPIO=m -CONFIG_I2C_DESIGNWARE_CORE=y -CONFIG_I2C_DESIGNWARE_PLATFORM=y -# CONFIG_I2C_DESIGNWARE_SLAVE is not set -# CONFIG_I2C_EMEV2 is not set -CONFIG_I2C_GPIO=m -# CONFIG_I2C_GPIO_FAULT_INJECTOR is not set -CONFIG_I2C_KEMPLD=m +# CONFIG_I2C_CBUS_GPIO is not set +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +CONFIG_I2C_EMEV2=m +# CONFIG_I2C_GPIO is not set CONFIG_I2C_MV64XXX=y -CONFIG_I2C_OCORES=m -CONFIG_I2C_PCA_PLATFORM=m +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_RK3X is not set -CONFIG_I2C_SIMTEC=m +# CONFIG_I2C_SIMTEC is not set CONFIG_I2C_SUN6I_P2WI=m -CONFIG_I2C_XILINX=m +# CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers # -CONFIG_I2C_DIOLAN_U2C=m -CONFIG_I2C_DLN2=m -CONFIG_I2C_PARPORT=m -CONFIG_I2C_PARPORT_LIGHT=m -CONFIG_I2C_ROBOTFUZZ_OSIF=m -CONFIG_I2C_TAOS_EVM=m +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_ROBOTFUZZ_OSIF is not set +# CONFIG_I2C_TAOS_EVM is not set CONFIG_I2C_TINY_USB=m -CONFIG_I2C_VIPERBOARD=m # # Other I2C/SMBus bus drivers @@ -3120,7 +2984,7 @@ CONFIG_I2C_SLAVE_EEPROM=m # end of I2C support CONFIG_I3C=m -CONFIG_CDNS_I3C_MASTER=m +# CONFIG_CDNS_I3C_MASTER is not set CONFIG_DW_I3C_MASTER=m CONFIG_SPI=y # CONFIG_SPI_DEBUG is not set @@ -3130,51 +2994,42 @@ CONFIG_SPI_MEM=y # # SPI Master Controller Drivers # -CONFIG_SPI_ALTERA=m -CONFIG_SPI_AXI_SPI_ENGINE=m -CONFIG_SPI_BITBANG=m -CONFIG_SPI_BUTTERFLY=m -CONFIG_SPI_CADENCE=m -CONFIG_SPI_DESIGNWARE=m -CONFIG_SPI_DW_MMIO=m -CONFIG_SPI_DLN2=m +# CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_AXI_SPI_ENGINE is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_BUTTERFLY is not set +# CONFIG_SPI_CADENCE is not set +# CONFIG_SPI_DESIGNWARE is not set +CONFIG_SPI_FSI=m CONFIG_SPI_NXP_FLEXSPI=m -CONFIG_SPI_GPIO=m -CONFIG_SPI_LM70_LLP=m -CONFIG_SPI_FSL_LIB=m -CONFIG_SPI_FSL_SPI=m -CONFIG_SPI_OC_TINY=m +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_LM70_LLP is not set +# CONFIG_SPI_FSL_SPI is not set +# CONFIG_SPI_OC_TINY is not set # CONFIG_SPI_ROCKCHIP is not set -CONFIG_SPI_SC18IS602=m +# CONFIG_SPI_SC18IS602 is not set CONFIG_SPI_SIFIVE=m CONFIG_SPI_SUN4I=y CONFIG_SPI_SUN6I=y CONFIG_SPI_MXIC=m -CONFIG_SPI_XCOMM=m +# CONFIG_SPI_XCOMM is not set # CONFIG_SPI_XILINX is not set -CONFIG_SPI_ZYNQMP_GQSPI=m +# CONFIG_SPI_ZYNQMP_GQSPI is not set + +# +# SPI Multiplexer support +# +CONFIG_SPI_MUX=m # # SPI Protocol Masters # CONFIG_SPI_SPIDEV=m -CONFIG_SPI_LOOPBACK_TEST=m -CONFIG_SPI_TLE62X0=m -CONFIG_SPI_SLAVE=y -CONFIG_SPI_SLAVE_TIME=m -CONFIG_SPI_SLAVE_SYSTEM_CONTROL=m -CONFIG_SPMI=m -CONFIG_HSI=m -CONFIG_HSI_BOARDINFO=y - -# -# HSI controllers -# - -# -# HSI clients -# -CONFIG_HSI_CHAR=m +# CONFIG_SPI_LOOPBACK_TEST is not set +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_SPI_SLAVE is not set +# CONFIG_SPMI is not set +# CONFIG_HSI is not set CONFIG_PPS=y # CONFIG_PPS_DEBUG is not set @@ -3183,7 +3038,7 @@ CONFIG_PPS=y # # CONFIG_PPS_CLIENT_KTIMER is not set CONFIG_PPS_CLIENT_LDISC=m -CONFIG_PPS_CLIENT_PARPORT=m +# CONFIG_PPS_CLIENT_PARPORT is not set CONFIG_PPS_CLIENT_GPIO=m # @@ -3194,22 +3049,25 @@ CONFIG_PPS_CLIENT_GPIO=m # PTP clock support # CONFIG_PTP_1588_CLOCK=y -CONFIG_DP83640_PHY=m +# CONFIG_DP83640_PHY is not set +CONFIG_PTP_1588_CLOCK_INES=m +CONFIG_PTP_1588_CLOCK_IDT82P33=m +CONFIG_PTP_1588_CLOCK_IDTCM=m # end of PTP clock support CONFIG_PINCTRL=y +CONFIG_GENERIC_PINCTRL_GROUPS=y CONFIG_PINMUX=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y CONFIG_PINCONF=y CONFIG_GENERIC_PINCONF=y # CONFIG_DEBUG_PINCTRL is not set -CONFIG_PINCTRL_AS3722=m CONFIG_PINCTRL_AXP209=m # CONFIG_PINCTRL_AMD is not set -CONFIG_PINCTRL_MCP23S08=m +# CONFIG_PINCTRL_MCP23S08 is not set # CONFIG_PINCTRL_SINGLE is not set -CONFIG_PINCTRL_SX150X=y +# CONFIG_PINCTRL_SX150X is not set CONFIG_PINCTRL_STMFX=m -CONFIG_PINCTRL_PALMAS=m # CONFIG_PINCTRL_OCELOT is not set CONFIG_PINCTRL_SUNXI=y CONFIG_PINCTRL_SUN4I_A10=y @@ -3232,11 +3090,7 @@ CONFIG_PINCTRL_SUN50I_H5=y CONFIG_PINCTRL_SUN50I_H6=y CONFIG_PINCTRL_SUN50I_H6_R=y CONFIG_PINCTRL_MADERA=m -CONFIG_PINCTRL_CS47L15=y -CONFIG_PINCTRL_CS47L35=y -CONFIG_PINCTRL_CS47L85=y -CONFIG_PINCTRL_CS47L90=y -CONFIG_PINCTRL_CS47L92=y +CONFIG_PINCTRL_EQUILIBRIUM=m CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y CONFIG_GPIOLIB=y CONFIG_GPIOLIB_FASTPATH_LIMIT=512 @@ -3245,7 +3099,6 @@ CONFIG_GPIOLIB_IRQCHIP=y # CONFIG_DEBUG_GPIO is not set CONFIG_GPIO_SYSFS=y CONFIG_GPIO_GENERIC=m -CONFIG_GPIO_MAX730X=m # # Memory mapped GPIO drivers @@ -3258,11 +3111,13 @@ CONFIG_GPIO_CADENCE=m # CONFIG_GPIO_GENERIC_PLATFORM is not set # CONFIG_GPIO_GRGPIO is not set # CONFIG_GPIO_HLWD is not set -CONFIG_GPIO_MB86S7X=m +CONFIG_GPIO_LOGICVC=m +# CONFIG_GPIO_MB86S7X is not set # CONFIG_GPIO_MPC8XXX is not set CONFIG_GPIO_SAMA5D2_PIOBU=m +# CONFIG_GPIO_SIFIVE is not set CONFIG_GPIO_SYSCON=m -CONFIG_GPIO_XILINX=y +# CONFIG_GPIO_XILINX is not set # CONFIG_GPIO_ZEVIO is not set CONFIG_GPIO_AMD_FCH=m # end of Memory mapped GPIO drivers @@ -3270,63 +3125,39 @@ CONFIG_GPIO_AMD_FCH=m # # I2C GPIO expanders # -CONFIG_GPIO_ADP5588=m +# CONFIG_GPIO_ADP5588 is not set # CONFIG_GPIO_ADNP is not set CONFIG_GPIO_GW_PLD=m -CONFIG_GPIO_MAX7300=m -CONFIG_GPIO_MAX732X=m -CONFIG_GPIO_PCA953X=m +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set CONFIG_GPIO_PCF857X=m -CONFIG_GPIO_TPIC2810=m +# CONFIG_GPIO_TPIC2810 is not set # end of I2C GPIO expanders # # MFD GPIO expanders # -CONFIG_GPIO_ADP5520=m -CONFIG_GPIO_ARIZONA=m -CONFIG_GPIO_BD9571MWV=m -CONFIG_GPIO_DA9052=m -CONFIG_GPIO_DA9055=m -CONFIG_GPIO_DLN2=m +CONFIG_GPIO_BD71828=m # CONFIG_HTC_EGPIO is not set -CONFIG_GPIO_KEMPLD=m -CONFIG_GPIO_LP3943=m -CONFIG_GPIO_LP873X=m -CONFIG_GPIO_LP87565=m -CONFIG_GPIO_MADERA=m +# CONFIG_GPIO_MADERA is not set CONFIG_GPIO_MAX77650=m -CONFIG_GPIO_PALMAS=y -CONFIG_GPIO_RC5T583=y -CONFIG_GPIO_TPS65086=m -CONFIG_GPIO_TPS65218=m -CONFIG_GPIO_TPS6586X=y -CONFIG_GPIO_TPS65910=y -CONFIG_GPIO_TPS65912=m -CONFIG_GPIO_TQMX86=m -CONFIG_GPIO_TWL4030=m -CONFIG_GPIO_TWL6040=m -CONFIG_GPIO_UCB1400=m -CONFIG_GPIO_WM831X=m -CONFIG_GPIO_WM8350=m -CONFIG_GPIO_WM8994=m # end of MFD GPIO expanders # # SPI GPIO expanders # -CONFIG_GPIO_74X164=m -CONFIG_GPIO_MAX3191X=m -CONFIG_GPIO_MAX7301=m -CONFIG_GPIO_MC33880=m -CONFIG_GPIO_PISOSR=m -CONFIG_GPIO_XRA1403=m +# CONFIG_GPIO_74X164 is not set +# CONFIG_GPIO_MAX3191X is not set +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_PISOSR is not set +# CONFIG_GPIO_XRA1403 is not set # end of SPI GPIO expanders # # USB GPIO expanders # -CONFIG_GPIO_VIPERBOARD=m # end of USB GPIO expanders # CONFIG_GPIO_MOCKUP is not set @@ -3335,9 +3166,9 @@ CONFIG_W1=m # # 1-wire Bus Masters # -CONFIG_W1_MASTER_DS2490=m -CONFIG_W1_MASTER_DS2482=m -CONFIG_W1_MASTER_DS1WM=m +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_DS2482 is not set +# CONFIG_W1_MASTER_DS1WM is not set CONFIG_W1_MASTER_GPIO=m CONFIG_W1_MASTER_SGI=m # end of 1-wire Bus Masters @@ -3353,21 +3184,22 @@ CONFIG_W1_SLAVE_DS2408_READBACK=y CONFIG_W1_SLAVE_DS2413=m CONFIG_W1_SLAVE_DS2406=m CONFIG_W1_SLAVE_DS2423=m -CONFIG_W1_SLAVE_DS2805=m +# CONFIG_W1_SLAVE_DS2805 is not set +CONFIG_W1_SLAVE_DS2430=m CONFIG_W1_SLAVE_DS2431=m CONFIG_W1_SLAVE_DS2433=m # CONFIG_W1_SLAVE_DS2433_CRC is not set -CONFIG_W1_SLAVE_DS2438=m +# CONFIG_W1_SLAVE_DS2438 is not set CONFIG_W1_SLAVE_DS250X=m -CONFIG_W1_SLAVE_DS2780=m -CONFIG_W1_SLAVE_DS2781=m -CONFIG_W1_SLAVE_DS28E04=m -CONFIG_W1_SLAVE_DS28E17=m +# CONFIG_W1_SLAVE_DS2780 is not set +# CONFIG_W1_SLAVE_DS2781 is not set +# CONFIG_W1_SLAVE_DS28E04 is not set +# CONFIG_W1_SLAVE_DS28E17 is not set # end of 1-wire Slaves CONFIG_POWER_AVS=y +CONFIG_QCOM_CPR=m CONFIG_POWER_RESET=y -# CONFIG_POWER_RESET_AS3722 is not set # CONFIG_POWER_RESET_BRCMKONA is not set # CONFIG_POWER_RESET_BRCMSTB is not set # CONFIG_POWER_RESET_GPIO is not set @@ -3383,68 +3215,43 @@ CONFIG_SYSCON_REBOOT_MODE=y CONFIG_POWER_SUPPLY=y # CONFIG_POWER_SUPPLY_DEBUG is not set CONFIG_POWER_SUPPLY_HWMON=y -CONFIG_PDA_POWER=m -CONFIG_GENERIC_ADC_BATTERY=m -CONFIG_MAX8925_POWER=m -CONFIG_WM831X_BACKUP=m -CONFIG_WM831X_POWER=m -CONFIG_WM8350_POWER=m -CONFIG_TEST_POWER=m -CONFIG_BATTERY_88PM860X=m +# CONFIG_PDA_POWER is not set +# CONFIG_GENERIC_ADC_BATTERY is not set +# CONFIG_TEST_POWER is not set CONFIG_CHARGER_ADP5061=m CONFIG_BATTERY_CPCAP=m CONFIG_BATTERY_DS2760=m -CONFIG_BATTERY_DS2780=m -CONFIG_BATTERY_DS2781=m -CONFIG_BATTERY_DS2782=m -CONFIG_BATTERY_LEGO_EV3=m -CONFIG_BATTERY_SBS=m +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_LEGO_EV3 is not set +# CONFIG_BATTERY_SBS is not set CONFIG_CHARGER_SBS=m -CONFIG_MANAGER_SBS=m -CONFIG_BATTERY_BQ27XXX=m -CONFIG_BATTERY_BQ27XXX_I2C=m -CONFIG_BATTERY_BQ27XXX_HDQ=m -# CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM is not set -CONFIG_BATTERY_DA9030=m -CONFIG_BATTERY_DA9052=m -CONFIG_CHARGER_DA9150=m -CONFIG_BATTERY_DA9150=m -CONFIG_CHARGER_AXP20X=m +# CONFIG_MANAGER_SBS is not set +# CONFIG_BATTERY_BQ27XXX is not set +# CONFIG_CHARGER_AXP20X is not set CONFIG_BATTERY_AXP20X=m CONFIG_AXP20X_POWER=m CONFIG_AXP288_FUEL_GAUGE=m -CONFIG_BATTERY_MAX17040=m -CONFIG_BATTERY_MAX17042=m -CONFIG_BATTERY_MAX1721X=m -CONFIG_BATTERY_TWL4030_MADC=m -CONFIG_CHARGER_88PM860X=m -CONFIG_CHARGER_PCF50633=m -CONFIG_BATTERY_RX51=m -CONFIG_CHARGER_ISP1704=m -CONFIG_CHARGER_MAX8903=m -CONFIG_CHARGER_TWL4030=m -CONFIG_CHARGER_LP8727=m -CONFIG_CHARGER_LP8788=m -CONFIG_CHARGER_GPIO=m -CONFIG_CHARGER_MANAGER=y +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_BATTERY_MAX1721X is not set +# CONFIG_CHARGER_ISP1704 is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set +# CONFIG_CHARGER_GPIO is not set +# CONFIG_CHARGER_MANAGER is not set CONFIG_CHARGER_LT3651=m -CONFIG_CHARGER_MAX14577=m CONFIG_CHARGER_DETECTOR_MAX14656=m CONFIG_CHARGER_MAX77650=m -CONFIG_CHARGER_MAX77693=m -CONFIG_CHARGER_MAX8997=m -CONFIG_CHARGER_MAX8998=m -CONFIG_CHARGER_BQ2415X=m -CONFIG_CHARGER_BQ24190=m -CONFIG_CHARGER_BQ24257=m -CONFIG_CHARGER_BQ24735=m -CONFIG_CHARGER_BQ25890=m -CONFIG_CHARGER_SMB347=m -CONFIG_CHARGER_TPS65090=m -CONFIG_CHARGER_TPS65217=m -CONFIG_BATTERY_GAUGE_LTC2941=m -CONFIG_BATTERY_RT5033=m -CONFIG_CHARGER_RT9455=m +# CONFIG_CHARGER_BQ2415X is not set +# CONFIG_CHARGER_BQ24190 is not set +# CONFIG_CHARGER_BQ24257 is not set +# CONFIG_CHARGER_BQ24735 is not set +# CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_SMB347 is not set +# CONFIG_BATTERY_GAUGE_LTC2941 is not set +# CONFIG_CHARGER_RT9455 is not set CONFIG_CHARGER_UCS1002=m CONFIG_HWMON=y CONFIG_HWMON_VID=m @@ -3461,6 +3268,7 @@ CONFIG_SENSORS_ADM1025=m CONFIG_SENSORS_ADM1026=m CONFIG_SENSORS_ADM1029=m CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM1177=m CONFIG_SENSORS_ADM9240=m CONFIG_SENSORS_ADT7X10=m CONFIG_SENSORS_ADT7310=m @@ -3471,16 +3279,15 @@ CONFIG_SENSORS_ADT7470=m CONFIG_SENSORS_ADT7475=m CONFIG_SENSORS_AS370=m CONFIG_SENSORS_ASC7621=m -CONFIG_SENSORS_ASPEED=m +CONFIG_SENSORS_AXI_FAN_CONTROL=m +# CONFIG_SENSORS_ASPEED is not set CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_DRIVETEMP=m CONFIG_SENSORS_DS620=m CONFIG_SENSORS_DS1621=m -CONFIG_SENSORS_DA9052_ADC=m -CONFIG_SENSORS_DA9055=m CONFIG_SENSORS_F71805F=m CONFIG_SENSORS_F71882FG=m CONFIG_SENSORS_F75375S=m -CONFIG_SENSORS_MC13783_ADC=m CONFIG_SENSORS_FTSTEUTATES=m CONFIG_SENSORS_GL518SM=m CONFIG_SENSORS_GL520SM=m @@ -3488,14 +3295,15 @@ CONFIG_SENSORS_G760A=m CONFIG_SENSORS_G762=m CONFIG_SENSORS_GPIO_FAN=m CONFIG_SENSORS_HIH6130=m -CONFIG_SENSORS_IBMAEM=m -CONFIG_SENSORS_IBMPEX=m -CONFIG_SENSORS_IIO_HWMON=m +# CONFIG_SENSORS_IIO_HWMON is not set CONFIG_SENSORS_IT87=m CONFIG_SENSORS_JC42=m CONFIG_SENSORS_POWR1220=m CONFIG_SENSORS_LINEAGE=m CONFIG_SENSORS_LTC2945=m +CONFIG_SENSORS_LTC2947=m +CONFIG_SENSORS_LTC2947_I2C=m +CONFIG_SENSORS_LTC2947_SPI=m CONFIG_SENSORS_LTC2990=m CONFIG_SENSORS_LTC4151=m CONFIG_SENSORS_LTC4215=m @@ -3509,15 +3317,15 @@ CONFIG_SENSORS_MAX1619=m CONFIG_SENSORS_MAX1668=m CONFIG_SENSORS_MAX197=m CONFIG_SENSORS_MAX31722=m -CONFIG_SENSORS_MAX6621=m +CONFIG_SENSORS_MAX31730=m +# CONFIG_SENSORS_MAX6621 is not set CONFIG_SENSORS_MAX6639=m CONFIG_SENSORS_MAX6642=m CONFIG_SENSORS_MAX6650=m CONFIG_SENSORS_MAX6697=m CONFIG_SENSORS_MAX31790=m CONFIG_SENSORS_MCP3021=m -CONFIG_SENSORS_TC654=m -CONFIG_SENSORS_MENF21BMC_HWMON=m +# CONFIG_SENSORS_TC654 is not set CONFIG_SENSORS_ADCXX=m CONFIG_SENSORS_LM63=m CONFIG_SENSORS_LM70=m @@ -3546,30 +3354,7 @@ CONFIG_SENSORS_NPCM7XX=m CONFIG_SENSORS_OCC_P8_I2C=m CONFIG_SENSORS_OCC=m CONFIG_SENSORS_PCF8591=m -CONFIG_PMBUS=m -CONFIG_SENSORS_PMBUS=m -CONFIG_SENSORS_ADM1275=m -CONFIG_SENSORS_IBM_CFFPS=m -CONFIG_SENSORS_INSPUR_IPSPS=m -CONFIG_SENSORS_IR35221=m -CONFIG_SENSORS_IR38064=m -CONFIG_SENSORS_IRPS5401=m -CONFIG_SENSORS_ISL68137=m -CONFIG_SENSORS_LM25066=m -CONFIG_SENSORS_LTC2978=m -CONFIG_SENSORS_LTC2978_REGULATOR=y -CONFIG_SENSORS_LTC3815=m -CONFIG_SENSORS_MAX16064=m -CONFIG_SENSORS_MAX20751=m -CONFIG_SENSORS_MAX31785=m -CONFIG_SENSORS_MAX34440=m -CONFIG_SENSORS_MAX8688=m -CONFIG_SENSORS_PXE1610=m -CONFIG_SENSORS_TPS40422=m -CONFIG_SENSORS_TPS53679=m -CONFIG_SENSORS_UCD9000=m -CONFIG_SENSORS_UCD9200=m -CONFIG_SENSORS_ZL6100=m +# CONFIG_PMBUS is not set CONFIG_SENSORS_PWM_FAN=m CONFIG_SENSORS_SHT15=m CONFIG_SENSORS_SHT21=m @@ -3598,9 +3383,10 @@ CONFIG_SENSORS_TC74=m CONFIG_SENSORS_THMC50=m CONFIG_SENSORS_TMP102=m CONFIG_SENSORS_TMP103=m -CONFIG_SENSORS_TMP108=m +# CONFIG_SENSORS_TMP108 is not set CONFIG_SENSORS_TMP401=m CONFIG_SENSORS_TMP421=m +CONFIG_SENSORS_TMP513=m CONFIG_SENSORS_VT1211=m CONFIG_SENSORS_W83773G=m CONFIG_SENSORS_W83781D=m @@ -3613,93 +3399,71 @@ CONFIG_SENSORS_W83L785TS=m CONFIG_SENSORS_W83L786NG=m CONFIG_SENSORS_W83627HF=m CONFIG_SENSORS_W83627EHF=m -CONFIG_SENSORS_WM831X=m -CONFIG_SENSORS_WM8350=m CONFIG_THERMAL=y -CONFIG_THERMAL_STATISTICS=y +# CONFIG_THERMAL_STATISTICS is not set CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 CONFIG_THERMAL_HWMON=y CONFIG_THERMAL_OF=y CONFIG_THERMAL_WRITABLE_TRIPS=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE is not set +CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE=y # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set -# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set CONFIG_THERMAL_GOV_FAIR_SHARE=y CONFIG_THERMAL_GOV_STEP_WISE=y CONFIG_THERMAL_GOV_BANG_BANG=y -CONFIG_THERMAL_GOV_USER_SPACE=y -CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y +# CONFIG_THERMAL_GOV_USER_SPACE is not set CONFIG_CPU_THERMAL=y -# CONFIG_CLOCK_THERMAL is not set -CONFIG_DEVFREQ_THERMAL=y -CONFIG_THERMAL_EMULATION=y +CONFIG_CPU_FREQ_THERMAL=y +CONFIG_CLOCK_THERMAL=y +# CONFIG_DEVFREQ_THERMAL is not set +# CONFIG_THERMAL_EMULATION is not set CONFIG_THERMAL_MMIO=m # CONFIG_QORIQ_THERMAL is not set CONFIG_SUN8I_THERMAL=m -CONFIG_DA9062_THERMAL=m CONFIG_GENERIC_ADC_THERMAL=m CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y # CONFIG_WATCHDOG_NOWAYOUT is not set CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y CONFIG_WATCHDOG_OPEN_TIMEOUT=0 -CONFIG_WATCHDOG_SYSFS=y +# CONFIG_WATCHDOG_SYSFS is not set # # Watchdog Pretimeout Governors # -CONFIG_WATCHDOG_PRETIMEOUT_GOV=y -CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m -CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP=y -CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=m -CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP=y -# CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC is not set +# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set # # Watchdog Device Drivers # -CONFIG_SOFT_WATCHDOG=m -CONFIG_SOFT_WATCHDOG_PRETIMEOUT=y -CONFIG_DA9052_WATCHDOG=m -CONFIG_DA9055_WATCHDOG=m -CONFIG_DA9063_WATCHDOG=m -CONFIG_DA9062_WATCHDOG=m +# CONFIG_SOFT_WATCHDOG is not set CONFIG_GPIO_WATCHDOG=m -CONFIG_MENF21BMC_WATCHDOG=m -CONFIG_WM831X_WATCHDOG=m -CONFIG_WM8350_WATCHDOG=m -CONFIG_XILINX_WATCHDOG=m -CONFIG_ZIIRAVE_WATCHDOG=m -CONFIG_RAVE_SP_WATCHDOG=m -CONFIG_CADENCE_WATCHDOG=m +# CONFIG_XILINX_WATCHDOG is not set +# CONFIG_ZIIRAVE_WATCHDOG is not set +# CONFIG_CADENCE_WATCHDOG is not set CONFIG_FTWDT010_WATCHDOG=m -CONFIG_DW_WATCHDOG=m +# CONFIG_DW_WATCHDOG is not set CONFIG_SUNXI_WATCHDOG=y -CONFIG_TWL4030_WATCHDOG=m -CONFIG_MAX63XX_WATCHDOG=m -CONFIG_RETU_WATCHDOG=m -CONFIG_STPMIC1_WATCHDOG=m -CONFIG_KEMPLD_WDT=m -CONFIG_MEN_A21_WDT=m +# CONFIG_MAX63XX_WATCHDOG is not set +# CONFIG_STPMIC1_WATCHDOG is not set +# CONFIG_MEN_A21_WDT is not set # # USB-based Watchdog Cards # -CONFIG_USBPCWATCHDOG=m +# CONFIG_USBPCWATCHDOG is not set CONFIG_SSB_POSSIBLE=y CONFIG_SSB=m CONFIG_SSB_BLOCKIO=y CONFIG_SSB_SDIOHOST_POSSIBLE=y -CONFIG_SSB_SDIOHOST=y -CONFIG_SSB_DRIVER_GPIO=y +# CONFIG_SSB_SDIOHOST is not set +# CONFIG_SSB_DRIVER_GPIO is not set CONFIG_BCMA_POSSIBLE=y CONFIG_BCMA=m CONFIG_BCMA_BLOCKIO=y -CONFIG_BCMA_HOST_SOC=y -CONFIG_BCMA_SFLASH=y -CONFIG_BCMA_DRIVER_GMAC_CMN=y -CONFIG_BCMA_DRIVER_GPIO=y +# CONFIG_BCMA_HOST_SOC is not set +# CONFIG_BCMA_DRIVER_GMAC_CMN is not set +# CONFIG_BCMA_DRIVER_GPIO is not set # CONFIG_BCMA_DEBUG is not set # @@ -3708,248 +3472,186 @@ CONFIG_BCMA_DRIVER_GPIO=y CONFIG_MFD_CORE=y # CONFIG_MFD_ACT8945A is not set CONFIG_MFD_SUN4I_GPADC=m -CONFIG_MFD_AS3711=y -CONFIG_MFD_AS3722=m -CONFIG_PMIC_ADP5520=y -CONFIG_MFD_AAT2870_CORE=y -CONFIG_MFD_ATMEL_FLEXCOM=m -CONFIG_MFD_ATMEL_HLCDC=m -CONFIG_MFD_BCM590XX=m -CONFIG_MFD_BD9571MWV=m -CONFIG_MFD_AC100=m +# CONFIG_MFD_AS3711 is not set +# CONFIG_MFD_AS3722 is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_ATMEL_FLEXCOM is not set +# CONFIG_MFD_ATMEL_HLCDC is not set +# CONFIG_MFD_BCM590XX is not set +# CONFIG_MFD_BD9571MWV is not set +CONFIG_MFD_AC100=y CONFIG_MFD_AC200=m CONFIG_MFD_AXP20X=y -CONFIG_MFD_AXP20X_I2C=m +CONFIG_MFD_AXP20X_I2C=y CONFIG_MFD_AXP20X_RSB=y CONFIG_MFD_MADERA=m -CONFIG_MFD_MADERA_I2C=m -CONFIG_MFD_MADERA_SPI=m -CONFIG_MFD_CS47L15=y -CONFIG_MFD_CS47L35=y -CONFIG_MFD_CS47L85=y -CONFIG_MFD_CS47L90=y -CONFIG_MFD_CS47L92=y +# CONFIG_MFD_MADERA_I2C is not set +# CONFIG_MFD_MADERA_SPI is not set +# CONFIG_MFD_CS47L15 is not set +# CONFIG_MFD_CS47L35 is not set +# CONFIG_MFD_CS47L85 is not set +# CONFIG_MFD_CS47L90 is not set +# CONFIG_MFD_CS47L92 is not set # CONFIG_MFD_ASIC3 is not set -CONFIG_PMIC_DA903X=y -CONFIG_PMIC_DA9052=y -CONFIG_MFD_DA9052_SPI=y -CONFIG_MFD_DA9052_I2C=y -CONFIG_MFD_DA9055=y -CONFIG_MFD_DA9062=m -CONFIG_MFD_DA9063=y -CONFIG_MFD_DA9150=m -CONFIG_MFD_DLN2=m -CONFIG_MFD_MC13XXX=m -CONFIG_MFD_MC13XXX_SPI=m -CONFIG_MFD_MC13XXX_I2C=m +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9062 is not set +# CONFIG_MFD_DA9063 is not set +# CONFIG_MFD_DA9150 is not set +# CONFIG_MFD_DLN2 is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set # CONFIG_MFD_HI6421_PMIC is not set -CONFIG_HTC_PASIC3=m -CONFIG_HTC_I2CPLD=y -CONFIG_MFD_KEMPLD=m -CONFIG_MFD_88PM800=m -CONFIG_MFD_88PM805=m -CONFIG_MFD_88PM860X=y -CONFIG_MFD_MAX14577=y +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +CONFIG_MFD_IQS62X=m +# CONFIG_MFD_KEMPLD is not set +# CONFIG_MFD_88PM800 is not set +# CONFIG_MFD_88PM805 is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_MAX14577 is not set # CONFIG_MFD_MAX77620 is not set CONFIG_MFD_MAX77650=m # CONFIG_MFD_MAX77686 is not set -CONFIG_MFD_MAX77693=y -CONFIG_MFD_MAX77843=y -CONFIG_MFD_MAX8907=m -CONFIG_MFD_MAX8925=y -CONFIG_MFD_MAX8997=y -CONFIG_MFD_MAX8998=y -CONFIG_MFD_MT6397=m -CONFIG_MFD_MENF21BMC=m -CONFIG_EZX_PCAP=y +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77843 is not set +# CONFIG_MFD_MAX8907 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6397 is not set +# CONFIG_MFD_MENF21BMC is not set +# CONFIG_EZX_PCAP is not set CONFIG_MFD_CPCAP=m -CONFIG_MFD_VIPERBOARD=m -CONFIG_MFD_RETU=m -CONFIG_MFD_PCF50633=m -CONFIG_PCF50633_ADC=m -CONFIG_PCF50633_GPIO=m -CONFIG_UCB1400_CORE=m +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_UCB1400_CORE is not set # CONFIG_MFD_PM8XXX is not set -CONFIG_MFD_RT5033=m -CONFIG_MFD_RC5T583=y +# CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RC5T583 is not set # CONFIG_MFD_RK808 is not set # CONFIG_MFD_RN5T618 is not set -CONFIG_MFD_SEC_CORE=y -CONFIG_MFD_SI476X_CORE=m -CONFIG_MFD_SM501=m -CONFIG_MFD_SM501_GPIO=y -CONFIG_MFD_SKY81452=m -CONFIG_MFD_SMSC=y -CONFIG_ABX500_CORE=y -CONFIG_AB3100_CORE=y -CONFIG_AB3100_OTP=m +# CONFIG_MFD_SEC_CORE is not set +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set +# CONFIG_MFD_SMSC is not set +# CONFIG_ABX500_CORE is not set # CONFIG_MFD_STMPE is not set CONFIG_MFD_SUN6I_PRCM=y CONFIG_MFD_SYSCON=y -CONFIG_MFD_TI_AM335X_TSCADC=m -CONFIG_MFD_LP3943=m -CONFIG_MFD_LP8788=y -CONFIG_MFD_TI_LMU=m -CONFIG_MFD_PALMAS=y -CONFIG_TPS6105X=m -CONFIG_TPS65010=m -CONFIG_TPS6507X=m -CONFIG_MFD_TPS65086=m -CONFIG_MFD_TPS65090=y -CONFIG_MFD_TPS65217=m -CONFIG_MFD_TI_LP873X=m -CONFIG_MFD_TI_LP87565=m -CONFIG_MFD_TPS65218=m -CONFIG_MFD_TPS6586X=y -CONFIG_MFD_TPS65910=y -CONFIG_MFD_TPS65912=y -CONFIG_MFD_TPS65912_I2C=y -CONFIG_MFD_TPS65912_SPI=y -CONFIG_MFD_TPS80031=y -CONFIG_TWL4030_CORE=y -# CONFIG_TWL4030_POWER is not set -CONFIG_MFD_TWL4030_AUDIO=y -CONFIG_TWL6040_CORE=y +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_LP3943 is not set +# CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_TI_LMU is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65086 is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TI_LP873X is not set +# CONFIG_MFD_TI_LP87565 is not set +# CONFIG_MFD_TPS65218 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_MFD_TPS80031 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set CONFIG_MFD_WL1273_CORE=m -CONFIG_MFD_LM3533=m +# CONFIG_MFD_LM3533 is not set # CONFIG_MFD_TC3589X is not set # CONFIG_MFD_T7L66XB is not set # CONFIG_MFD_TC6387XB is not set # CONFIG_MFD_TC6393XB is not set -CONFIG_MFD_TQMX86=m +# CONFIG_MFD_TQMX86 is not set # CONFIG_MFD_LOCHNAGAR is not set -CONFIG_MFD_ARIZONA=y -CONFIG_MFD_ARIZONA_I2C=m -CONFIG_MFD_ARIZONA_SPI=m -CONFIG_MFD_CS47L24=y -CONFIG_MFD_WM5102=y -CONFIG_MFD_WM5110=y -CONFIG_MFD_WM8997=y -CONFIG_MFD_WM8998=y -CONFIG_MFD_WM8400=y -CONFIG_MFD_WM831X=y -CONFIG_MFD_WM831X_I2C=y -CONFIG_MFD_WM831X_SPI=y -CONFIG_MFD_WM8350=y -CONFIG_MFD_WM8350_I2C=y -CONFIG_MFD_WM8994=m +# CONFIG_MFD_ARIZONA_I2C is not set +# CONFIG_MFD_ARIZONA_SPI is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set CONFIG_MFD_ROHM_BD718XX=m # CONFIG_MFD_ROHM_BD70528 is not set +CONFIG_MFD_ROHM_BD71828=m CONFIG_MFD_STPMIC1=m CONFIG_MFD_STMFX=m -CONFIG_RAVE_SP_CORE=m +# CONFIG_RAVE_SP_CORE is not set # end of Multifunction device drivers CONFIG_REGULATOR=y # CONFIG_REGULATOR_DEBUG is not set -CONFIG_REGULATOR_FIXED_VOLTAGE=m -CONFIG_REGULATOR_VIRTUAL_CONSUMER=m -CONFIG_REGULATOR_USERSPACE_CONSUMER=m +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_VIRTUAL_CONSUMER=y +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set CONFIG_REGULATOR_USERSPACE_CONSUMER_OF=m -CONFIG_REGULATOR_88PG86X=m -CONFIG_REGULATOR_88PM800=m -CONFIG_REGULATOR_88PM8607=m -CONFIG_REGULATOR_ACT8865=m -CONFIG_REGULATOR_AD5398=m -CONFIG_REGULATOR_ANATOP=m -CONFIG_REGULATOR_AAT2870=m -CONFIG_REGULATOR_AB3100=m -CONFIG_REGULATOR_ARIZONA_LDO1=m -CONFIG_REGULATOR_ARIZONA_MICSUPP=m -CONFIG_REGULATOR_AS3711=m -CONFIG_REGULATOR_AS3722=m -CONFIG_REGULATOR_AXP20X=m -CONFIG_REGULATOR_BCM590XX=m +# CONFIG_REGULATOR_88PG86X is not set +# CONFIG_REGULATOR_ACT8865 is not set +# CONFIG_REGULATOR_AD5398 is not set +# CONFIG_REGULATOR_ARIZONA_LDO1 is not set +# CONFIG_REGULATOR_ARIZONA_MICSUPP is not set +CONFIG_REGULATOR_AXP20X=y +CONFIG_REGULATOR_BD71828=m CONFIG_REGULATOR_BD718XX=m -CONFIG_REGULATOR_BD9571MWV=m CONFIG_REGULATOR_CPCAP=m -CONFIG_REGULATOR_DA903X=m -CONFIG_REGULATOR_DA9052=m -CONFIG_REGULATOR_DA9055=m -CONFIG_REGULATOR_DA9062=m -CONFIG_REGULATOR_DA9063=m -CONFIG_REGULATOR_DA9210=m -CONFIG_REGULATOR_DA9211=m -CONFIG_REGULATOR_FAN53555=m -CONFIG_REGULATOR_GPIO=m -CONFIG_REGULATOR_ISL9305=m -CONFIG_REGULATOR_ISL6271A=m -CONFIG_REGULATOR_LM363X=m -CONFIG_REGULATOR_LP3971=m -CONFIG_REGULATOR_LP3972=m -CONFIG_REGULATOR_LP872X=m -CONFIG_REGULATOR_LP873X=m -CONFIG_REGULATOR_LP8755=m -CONFIG_REGULATOR_LP87565=m -CONFIG_REGULATOR_LP8788=m -CONFIG_REGULATOR_LTC3589=m -CONFIG_REGULATOR_LTC3676=m -CONFIG_REGULATOR_MAX14577=m -CONFIG_REGULATOR_MAX1586=m +# CONFIG_REGULATOR_DA9210 is not set +# CONFIG_REGULATOR_DA9211 is not set +# CONFIG_REGULATOR_FAN53555 is not set +CONFIG_REGULATOR_GPIO=y +# CONFIG_REGULATOR_ISL9305 is not set +# CONFIG_REGULATOR_ISL6271A is not set +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_LP3972 is not set +# CONFIG_REGULATOR_LP872X is not set +# CONFIG_REGULATOR_LP8755 is not set +# CONFIG_REGULATOR_LTC3589 is not set +# CONFIG_REGULATOR_LTC3676 is not set +# CONFIG_REGULATOR_MAX1586 is not set CONFIG_REGULATOR_MAX77650=m -CONFIG_REGULATOR_MAX8649=m -CONFIG_REGULATOR_MAX8660=m -CONFIG_REGULATOR_MAX8907=m -CONFIG_REGULATOR_MAX8925=m -CONFIG_REGULATOR_MAX8952=m +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_MAX8952 is not set # CONFIG_REGULATOR_MAX8973 is not set -CONFIG_REGULATOR_MAX8997=m -CONFIG_REGULATOR_MAX8998=m -CONFIG_REGULATOR_MAX77693=m -CONFIG_REGULATOR_MC13XXX_CORE=m -CONFIG_REGULATOR_MC13783=m -CONFIG_REGULATOR_MC13892=m CONFIG_REGULATOR_MCP16502=m -CONFIG_REGULATOR_MT6311=m -CONFIG_REGULATOR_MT6323=m -CONFIG_REGULATOR_MT6397=m -CONFIG_REGULATOR_PALMAS=m -CONFIG_REGULATOR_PCAP=m -CONFIG_REGULATOR_PCF50633=m -CONFIG_REGULATOR_PFUZE100=m -CONFIG_REGULATOR_PV88060=m -CONFIG_REGULATOR_PV88080=m -CONFIG_REGULATOR_PV88090=m +CONFIG_REGULATOR_MP5416=m +CONFIG_REGULATOR_MP8859=m +CONFIG_REGULATOR_MP886X=m +CONFIG_REGULATOR_MPQ7920=m +# CONFIG_REGULATOR_MT6311 is not set +# CONFIG_REGULATOR_PFUZE100 is not set +# CONFIG_REGULATOR_PV88060 is not set +# CONFIG_REGULATOR_PV88080 is not set +# CONFIG_REGULATOR_PV88090 is not set CONFIG_REGULATOR_PWM=m -CONFIG_REGULATOR_QCOM_SPMI=m -CONFIG_REGULATOR_RC5T583=m -CONFIG_REGULATOR_RT5033=m -CONFIG_REGULATOR_S2MPA01=m -CONFIG_REGULATOR_S2MPS11=m -CONFIG_REGULATOR_S5M8767=m -CONFIG_REGULATOR_SKY81452=m -CONFIG_REGULATOR_SLG51000=m +CONFIG_REGULATOR_ROHM=m +# CONFIG_REGULATOR_SLG51000 is not set CONFIG_REGULATOR_STPMIC1=m CONFIG_REGULATOR_SY8106A=m CONFIG_REGULATOR_SY8824X=m -CONFIG_REGULATOR_TPS51632=m -CONFIG_REGULATOR_TPS6105X=m -CONFIG_REGULATOR_TPS62360=m -CONFIG_REGULATOR_TPS65023=m -CONFIG_REGULATOR_TPS6507X=m -CONFIG_REGULATOR_TPS65086=m -CONFIG_REGULATOR_TPS65090=m -CONFIG_REGULATOR_TPS65132=m -CONFIG_REGULATOR_TPS65217=m -CONFIG_REGULATOR_TPS65218=m -CONFIG_REGULATOR_TPS6524X=m -CONFIG_REGULATOR_TPS6586X=m -CONFIG_REGULATOR_TPS65910=m -CONFIG_REGULATOR_TPS65912=m -CONFIG_REGULATOR_TPS80031=m -CONFIG_REGULATOR_TWL4030=m -CONFIG_REGULATOR_VCTRL=m -CONFIG_REGULATOR_WM831X=m -CONFIG_REGULATOR_WM8350=m -CONFIG_REGULATOR_WM8400=m -CONFIG_REGULATOR_WM8994=m -CONFIG_REGULATOR_TP65185X=m -CONFIG_CEC_CORE=m +# CONFIG_REGULATOR_TPS51632 is not set +# CONFIG_REGULATOR_TPS62360 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set +# CONFIG_REGULATOR_TPS65132 is not set +# CONFIG_REGULATOR_TPS6524X is not set +# CONFIG_REGULATOR_VCTRL is not set +# CONFIG_REGULATOR_TP65185X is not set +CONFIG_CEC_CORE=y CONFIG_CEC_NOTIFIER=y CONFIG_CEC_PIN=y -CONFIG_RC_CORE=m +CONFIG_RC_CORE=y CONFIG_RC_MAP=m CONFIG_LIRC=y +# CONFIG_BPF_LIRC_MODE2 is not set CONFIG_RC_DECODERS=y CONFIG_IR_NEC_DECODER=m CONFIG_IR_RC5_DECODER=m @@ -3963,27 +3665,26 @@ CONFIG_IR_XMP_DECODER=m CONFIG_IR_IMON_DECODER=m CONFIG_IR_RCMM_DECODER=m CONFIG_RC_DEVICES=y -CONFIG_RC_ATI_REMOTE=m -CONFIG_IR_HIX5HD2=m -CONFIG_IR_IMON=m -CONFIG_IR_IMON_RAW=m -CONFIG_IR_MCEUSB=m -CONFIG_IR_REDRAT3=m +# CONFIG_RC_ATI_REMOTE is not set +# CONFIG_IR_HIX5HD2 is not set +# CONFIG_IR_IMON is not set +# CONFIG_IR_IMON_RAW is not set +# CONFIG_IR_MCEUSB is not set +# CONFIG_IR_REDRAT3 is not set CONFIG_IR_SPI=m -CONFIG_IR_STREAMZAP=m -CONFIG_IR_IGORPLUGUSB=m -CONFIG_IR_IGUANA=m -CONFIG_IR_TTUSBIR=m -CONFIG_RC_LOOPBACK=m -CONFIG_IR_GPIO_CIR=m +# CONFIG_IR_STREAMZAP is not set +# CONFIG_IR_IGORPLUGUSB is not set +# CONFIG_IR_IGUANA is not set +# CONFIG_IR_TTUSBIR is not set +# CONFIG_RC_LOOPBACK is not set +# CONFIG_IR_GPIO_CIR is not set CONFIG_IR_GPIO_TX=m -CONFIG_IR_PWM_TX=m +# CONFIG_IR_PWM_TX is not set CONFIG_IR_SUNXI=m -CONFIG_IR_SERIAL=m -CONFIG_IR_SERIAL_TRANSMITTER=y +# CONFIG_IR_SERIAL is not set # CONFIG_IR_SIR is not set CONFIG_RC_XBOX_DVD=m -CONFIG_MEDIA_SUPPORT=m +CONFIG_MEDIA_SUPPORT=y # # Multimedia core support @@ -3999,19 +3700,19 @@ CONFIG_MEDIA_CEC_SUPPORT=y CONFIG_MEDIA_CONTROLLER=y CONFIG_MEDIA_CONTROLLER_DVB=y CONFIG_MEDIA_CONTROLLER_REQUEST_API=y -CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_DEV=y CONFIG_VIDEO_V4L2_SUBDEV_API=y -CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L2=y CONFIG_VIDEO_V4L2_I2C=y # CONFIG_VIDEO_ADV_DEBUG is not set CONFIG_VIDEO_FIXED_MINOR_RANGES=y CONFIG_VIDEO_TUNER=m -CONFIG_V4L2_MEM2MEM_DEV=m +CONFIG_V4L2_MEM2MEM_DEV=y CONFIG_V4L2_FLASH_LED_CLASS=m -CONFIG_V4L2_FWNODE=m +CONFIG_V4L2_FWNODE=y CONFIG_VIDEOBUF_GEN=m CONFIG_VIDEOBUF_VMALLOC=m -CONFIG_DVB_CORE=m +CONFIG_DVB_CORE=y # CONFIG_DVB_MMAP is not set CONFIG_DVB_NET=y CONFIG_TTPCI_EEPROM=m @@ -4097,20 +3798,16 @@ CONFIG_VIDEO_PVRUSB2_SYSFS=y CONFIG_VIDEO_PVRUSB2_DVB=y # CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set CONFIG_VIDEO_HDPVR=m -CONFIG_VIDEO_USBVISION=m CONFIG_VIDEO_STK1160_COMMON=m CONFIG_VIDEO_STK1160=m -CONFIG_VIDEO_GO7007=m -CONFIG_VIDEO_GO7007_USB=m -CONFIG_VIDEO_GO7007_LOADER=m -CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m +# CONFIG_VIDEO_GO7007 is not set # # Analog/digital TV USB devices # CONFIG_VIDEO_AU0828=m CONFIG_VIDEO_AU0828_V4L2=y -CONFIG_VIDEO_AU0828_RC=y +# CONFIG_VIDEO_AU0828_RC is not set CONFIG_VIDEO_CX231XX=m CONFIG_VIDEO_CX231XX_RC=y CONFIG_VIDEO_CX231XX_ALSA=m @@ -4132,7 +3829,7 @@ CONFIG_DVB_USB_DIBUSB_MC=m CONFIG_DVB_USB_DIB0700=m CONFIG_DVB_USB_UMT_010=m CONFIG_DVB_USB_CXUSB=m -CONFIG_DVB_USB_CXUSB_ANALOG=y +# CONFIG_DVB_USB_CXUSB_ANALOG is not set CONFIG_DVB_USB_M920X=m CONFIG_DVB_USB_DIGITV=m CONFIG_DVB_USB_VP7045=m @@ -4150,7 +3847,7 @@ CONFIG_DVB_USB_CINERGY_T2=m CONFIG_DVB_USB_DTV5100=m CONFIG_DVB_USB_AZ6027=m CONFIG_DVB_USB_TECHNISAT_USB2=m -CONFIG_DVB_USB_V2=m +CONFIG_DVB_USB_V2=y CONFIG_DVB_USB_AF9015=m CONFIG_DVB_USB_AF9035=m CONFIG_DVB_USB_ANYSEE=m @@ -4188,24 +3885,24 @@ CONFIG_USB_MSI2500=m # # USB HDMI CEC adapters # -CONFIG_USB_PULSE8_CEC=m -CONFIG_USB_RAINSHADOW_CEC=m +# CONFIG_USB_PULSE8_CEC is not set +# CONFIG_USB_RAINSHADOW_CEC is not set CONFIG_V4L_PLATFORM_DRIVERS=y -CONFIG_VIDEO_CADENCE=y -CONFIG_VIDEO_CADENCE_CSI2RX=m -CONFIG_VIDEO_CADENCE_CSI2TX=m +# CONFIG_VIDEO_CADENCE is not set CONFIG_VIDEO_ASPEED=m # CONFIG_VIDEO_MUX is not set # CONFIG_VIDEO_XILINX is not set CONFIG_VIDEO_SUN4I_CSI=m -CONFIG_VIDEO_SUN6I_CSI=m +CONFIG_VIDEO_SUN6I_CSI=y CONFIG_V4L_MEM2MEM_DRIVERS=y -CONFIG_VIDEO_MEM2MEM_DEINTERLACE=m -CONFIG_VIDEO_SH_VEU=m +# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set +# CONFIG_VIDEO_SH_VEU is not set +CONFIG_VIDEO_SUN8I_DEINTERLACE=m +CONFIG_VIDEO_SUN8I_ROTATE=y CONFIG_V4L_TEST_DRIVERS=y -CONFIG_VIDEO_VIMC=m +# CONFIG_VIDEO_VIMC is not set CONFIG_VIDEO_VIVID=m -CONFIG_VIDEO_VIVID_CEC=y +# CONFIG_VIDEO_VIVID_CEC is not set CONFIG_VIDEO_VIVID_MAX_DEVS=64 CONFIG_VIDEO_VIM2M=m CONFIG_VIDEO_VICODEC=m @@ -4220,14 +3917,13 @@ CONFIG_SDR_PLATFORM_DRIVERS=y CONFIG_SMS_SDIO_DRV=m CONFIG_RADIO_ADAPTERS=y CONFIG_RADIO_TEA575X=m -CONFIG_RADIO_SI470X=m +CONFIG_RADIO_SI470X=y CONFIG_USB_SI470X=m CONFIG_I2C_SI470X=m CONFIG_RADIO_SI4713=m CONFIG_USB_SI4713=m CONFIG_PLATFORM_SI4713=m CONFIG_I2C_SI4713=m -CONFIG_RADIO_SI476X=m CONFIG_USB_MR800=m CONFIG_USB_DSBR=m CONFIG_RADIO_SHARK=m @@ -4253,10 +3949,10 @@ CONFIG_MEDIA_COMMON_OPTIONS=y CONFIG_VIDEO_CX2341X=m CONFIG_VIDEO_TVEEPROM=m CONFIG_CYPRESS_FIRMWARE=m -CONFIG_VIDEOBUF2_CORE=m -CONFIG_VIDEOBUF2_V4L2=m -CONFIG_VIDEOBUF2_MEMOPS=m -CONFIG_VIDEOBUF2_DMA_CONTIG=m +CONFIG_VIDEOBUF2_CORE=y +CONFIG_VIDEOBUF2_V4L2=y +CONFIG_VIDEOBUF2_MEMOPS=y +CONFIG_VIDEOBUF2_DMA_CONTIG=y CONFIG_VIDEOBUF2_VMALLOC=m CONFIG_DVB_B2C2_FLEXCOP=m CONFIG_SMS_SIANO_MDTV=m @@ -4352,9 +4048,12 @@ CONFIG_VIDEO_THS8200=m # # Camera sensor devices # +CONFIG_VIDEO_HI556=m CONFIG_VIDEO_IMX214=m +CONFIG_VIDEO_IMX219=m # CONFIG_VIDEO_IMX258 is not set # CONFIG_VIDEO_IMX274 is not set +CONFIG_VIDEO_IMX290=m CONFIG_VIDEO_IMX319=m CONFIG_VIDEO_IMX355=m # CONFIG_VIDEO_OV2640 is not set @@ -4398,6 +4097,7 @@ CONFIG_VIDEO_RJ54N1=m # CONFIG_VIDEO_SMIAPP is not set CONFIG_VIDEO_ET8EK8=m # CONFIG_VIDEO_S5C73M3 is not set +CONFIG_VIDEO_HM5065=m # # Lens drivers @@ -4406,7 +4106,7 @@ CONFIG_VIDEO_ET8EK8=m CONFIG_VIDEO_AK7375=m # CONFIG_VIDEO_DW9714 is not set CONFIG_VIDEO_DW9807_VCM=m -CONFIG_VIDEO_HM5065=m +CONFIG_VIDEO_GC2145=m # # Flash devices @@ -4452,7 +4152,7 @@ CONFIG_VIDEO_ST_MIPID02=m CONFIG_CXD2880_SPI_DRV=m # end of Media SPI Adapters -CONFIG_MEDIA_TUNER=m +CONFIG_MEDIA_TUNER=y # # Customize TV tuners @@ -4669,7 +4369,7 @@ CONFIG_DVB_DUMMY_FE=m # # Graphics support # -# CONFIG_IMX_IPUV3_CORE is not set +CONFIG_IMX_IPUV3_CORE=m CONFIG_DRM=y CONFIG_DRM_MIPI_DBI=m CONFIG_DRM_MIPI_DSI=y @@ -4678,12 +4378,12 @@ CONFIG_DRM_MIPI_DSI=y # CONFIG_DRM_DEBUG_SELFTEST is not set CONFIG_DRM_KMS_HELPER=y CONFIG_DRM_KMS_FB_HELPER=y +# CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set CONFIG_DRM_FBDEV_EMULATION=y CONFIG_DRM_FBDEV_OVERALLOC=100 # CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set CONFIG_DRM_LOAD_EDID_FIRMWARE=y # CONFIG_DRM_DP_CEC is not set -CONFIG_DRM_TTM=m CONFIG_DRM_GEM_CMA_HELPER=y CONFIG_DRM_KMS_CMA_HELPER=y CONFIG_DRM_GEM_SHMEM_HELPER=y @@ -4692,42 +4392,37 @@ CONFIG_DRM_SCHED=m # # I2C encoder or helper chips # -CONFIG_DRM_I2C_CH7006=m -CONFIG_DRM_I2C_SIL164=m -CONFIG_DRM_I2C_NXP_TDA998X=m +# CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_SIL164 is not set +# CONFIG_DRM_I2C_NXP_TDA998X is not set # CONFIG_DRM_I2C_NXP_TDA9950 is not set # end of I2C encoder or helper chips # # ARM devices # -# CONFIG_DRM_HDLCD is not set +CONFIG_DRM_HDLCD=m +# CONFIG_DRM_HDLCD_SHOW_UNDERRUN is not set CONFIG_DRM_MALI_DISPLAY=m CONFIG_DRM_KOMEDA=m # end of ARM devices -# -# ACP (Audio CoProcessor) Configuration -# -# end of ACP (Audio CoProcessor) Configuration - # CONFIG_DRM_VGEM is not set CONFIG_DRM_VKMS=m # CONFIG_DRM_EXYNOS is not set # CONFIG_DRM_UDL is not set # CONFIG_DRM_ARMADA is not set -CONFIG_DRM_ATMEL_HLCDC=m CONFIG_DRM_RCAR_DW_HDMI=m # CONFIG_DRM_RCAR_LVDS is not set -CONFIG_DRM_SUN4I=m -CONFIG_DRM_SUN4I_HDMI=m +CONFIG_DRM_SUN4I=y +CONFIG_DRM_SUN4I_HDMI=y CONFIG_DRM_SUN4I_HDMI_AUDIO=y CONFIG_DRM_SUN4I_HDMI_CEC=y -CONFIG_DRM_SUN4I_BACKEND=m -CONFIG_DRM_SUN6I_DSI=m -CONFIG_DRM_SUN8I_DW_HDMI=m -CONFIG_DRM_SUN8I_MIXER=m -CONFIG_DRM_SUN8I_TCON_TOP=m +CONFIG_DRM_SUN4I_BACKEND=y +CONFIG_DRM_SUN6I_DSI=y +CONFIG_DRM_SUN8I_DW_HDMI=y +CONFIG_DRM_SUN8I_MIXER=y +CONFIG_DRM_SUN8I_TCON_TOP=y # CONFIG_DRM_OMAP is not set # CONFIG_DRM_TILCDC is not set CONFIG_DRM_VIRTIO_GPU=m @@ -4739,18 +4434,24 @@ CONFIG_DRM_PANEL=y # Display Panels # CONFIG_DRM_PANEL_ARM_VERSATILE=m +CONFIG_DRM_PANEL_BOE_HIMAX8279D=m +CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m CONFIG_DRM_PANEL_LVDS=m CONFIG_DRM_PANEL_SIMPLE=m +CONFIG_DRM_PANEL_ELIDA_KD35T133=m +CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02=m CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D=m CONFIG_DRM_PANEL_ILITEK_IL9322=m CONFIG_DRM_PANEL_ILITEK_ILI9881C=m # CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set # CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04=m +CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829=m # CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set CONFIG_DRM_PANEL_LG_LB035Q02=m # CONFIG_DRM_PANEL_LG_LG4573 is not set CONFIG_DRM_PANEL_NEC_NL8048HL11=m +CONFIG_DRM_PANEL_NOVATEK_NT35510=m CONFIG_DRM_PANEL_NOVATEK_NT39016=m CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO=m # CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set @@ -4765,18 +4466,23 @@ CONFIG_DRM_PANEL_SAMSUNG_S6D16D0=m # CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set # CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set # CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set +CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01=m # CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set # CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set # CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m # CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set -CONFIG_DRM_PANEL_SITRONIX_ST7701=m +# CONFIG_DRM_PANEL_SITRONIX_ST7701 is not set +# CONFIG_DRM_PANEL_SITRONIX_ST7703 is not set CONFIG_DRM_PANEL_SITRONIX_ST7789V=m +CONFIG_DRM_PANEL_SONY_ACX424AKP=m CONFIG_DRM_PANEL_SONY_ACX565AKM=m CONFIG_DRM_PANEL_TPO_TD028TTEC1=m CONFIG_DRM_PANEL_TPO_TD043MTEA1=m CONFIG_DRM_PANEL_TPO_TPG110=m CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m +CONFIG_DRM_PANEL_XINGBANGDA_XBD599=m +CONFIG_DRM_PANEL_XINPENG_XPP055C272=m # end of Display Panels CONFIG_DRM_BRIDGE=y @@ -4785,48 +4491,55 @@ CONFIG_DRM_PANEL_BRIDGE=y # # Display Interface Bridges # -# CONFIG_DRM_ANALOGIX_ANX78XX is not set # CONFIG_DRM_CDNS_DSI is not set -# CONFIG_DRM_DUMB_VGA_DAC is not set -# CONFIG_DRM_LVDS_ENCODER is not set +CONFIG_DRM_DISPLAY_CONNECTOR=m +CONFIG_DRM_LVDS_CODEC=m # CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set # CONFIG_DRM_NXP_PTN3460 is not set # CONFIG_DRM_PARADE_PS8622 is not set +CONFIG_DRM_PARADE_PS8640=m # CONFIG_DRM_SIL_SII8620 is not set # CONFIG_DRM_SII902X is not set # CONFIG_DRM_SII9234 is not set +CONFIG_DRM_SIMPLE_BRIDGE=m # CONFIG_DRM_THINE_THC63LVD1024 is not set CONFIG_DRM_TOSHIBA_TC358764=m # CONFIG_DRM_TOSHIBA_TC358767 is not set +CONFIG_DRM_TOSHIBA_TC358768=m # CONFIG_DRM_TI_TFP410 is not set CONFIG_DRM_TI_SN65DSI86=m +CONFIG_DRM_TI_TPD12S015=m CONFIG_DRM_ANALOGIX_ANX6345=m +# CONFIG_DRM_ANALOGIX_ANX78XX is not set CONFIG_DRM_ANALOGIX_DP=m # CONFIG_DRM_I2C_ADV7511 is not set -CONFIG_DRM_DW_HDMI=m +CONFIG_DRM_DW_HDMI=y CONFIG_DRM_DW_HDMI_AHB_AUDIO=m CONFIG_DRM_DW_HDMI_I2S_AUDIO=m CONFIG_DRM_DW_HDMI_CEC=m # end of Display Interface Bridges # CONFIG_DRM_STI is not set +# CONFIG_DRM_IMX is not set CONFIG_DRM_ETNAVIV=m CONFIG_DRM_ETNAVIV_THERMAL=y # CONFIG_DRM_ARCPGU is not set # CONFIG_DRM_MXSFB is not set CONFIG_DRM_GM12U320=m CONFIG_TINYDRM_HX8357D=m -# CONFIG_TINYDRM_ILI9225 is not set +CONFIG_TINYDRM_ILI9225=m CONFIG_TINYDRM_ILI9341=m +CONFIG_TINYDRM_ILI9486=m CONFIG_TINYDRM_MI0283QT=m -# CONFIG_TINYDRM_REPAPER is not set -# CONFIG_TINYDRM_ST7586 is not set -# CONFIG_TINYDRM_ST7735R is not set -# CONFIG_DRM_PL111 is not set -# CONFIG_DRM_TVE200 is not set +CONFIG_TINYDRM_REPAPER=m +CONFIG_TINYDRM_ST7586=m +CONFIG_TINYDRM_ST7735R=m +CONFIG_DRM_PL111=m +CONFIG_DRM_TVE200=m CONFIG_DRM_LIMA=m CONFIG_DRM_PANFROST=m -# CONFIG_DRM_MCDE is not set +CONFIG_DRM_MCDE=m +CONFIG_DRM_TIDSS=m # CONFIG_DRM_LEGACY is not set CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y @@ -4836,7 +4549,7 @@ CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y CONFIG_FB_CMDLINE=y CONFIG_FB_NOTIFY=y CONFIG_FB=y -# CONFIG_FIRMWARE_EDID is not set +CONFIG_FIRMWARE_EDID=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y @@ -4856,7 +4569,6 @@ CONFIG_FB_BACKLIGHT=m # CONFIG_FB_OPENCORES is not set # CONFIG_FB_S1D13XXX is not set # CONFIG_FB_SUN5I_EINK is not set -CONFIG_FB_SM501=m # CONFIG_FB_SMSCUFX is not set # CONFIG_FB_UDL is not set # CONFIG_FB_IBM_GXT4500 is not set @@ -4870,46 +4582,32 @@ CONFIG_FB_SIMPLE=y # Backlight & LCD device support # CONFIG_LCD_CLASS_DEVICE=m -CONFIG_LCD_L4F00242T03=m -CONFIG_LCD_LMS283GF05=m -CONFIG_LCD_LTV350QV=m -CONFIG_LCD_ILI922X=m -CONFIG_LCD_ILI9320=m -CONFIG_LCD_TDO24M=m -CONFIG_LCD_VGG2432A4=m -CONFIG_LCD_PLATFORM=m -CONFIG_LCD_AMS369FG06=m -CONFIG_LCD_LMS501KF03=m -CONFIG_LCD_HX8357=m +# CONFIG_LCD_L4F00242T03 is not set +# CONFIG_LCD_LMS283GF05 is not set +# CONFIG_LCD_LTV350QV is not set +# CONFIG_LCD_ILI922X is not set +# CONFIG_LCD_ILI9320 is not set +# CONFIG_LCD_TDO24M is not set +# CONFIG_LCD_VGG2432A4 is not set +# CONFIG_LCD_PLATFORM is not set +# CONFIG_LCD_AMS369FG06 is not set +# CONFIG_LCD_LMS501KF03 is not set +# CONFIG_LCD_HX8357 is not set # CONFIG_LCD_OTM3225A is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BACKLIGHT_GENERIC=m -CONFIG_BACKLIGHT_LM3533=m CONFIG_BACKLIGHT_PWM=m -CONFIG_BACKLIGHT_DA903X=m -# CONFIG_BACKLIGHT_DA9052 is not set -CONFIG_BACKLIGHT_MAX8925=m -# CONFIG_BACKLIGHT_PM8941_WLED is not set -CONFIG_BACKLIGHT_WM831X=m -CONFIG_BACKLIGHT_ADP5520=m +CONFIG_BACKLIGHT_QCOM_WLED=m # CONFIG_BACKLIGHT_ADP8860 is not set # CONFIG_BACKLIGHT_ADP8870 is not set -CONFIG_BACKLIGHT_88PM860X=m -CONFIG_BACKLIGHT_PCF50633=m -CONFIG_BACKLIGHT_AAT2870=m # CONFIG_BACKLIGHT_LM3630A is not set # CONFIG_BACKLIGHT_LM3639 is not set # CONFIG_BACKLIGHT_LP855X is not set -CONFIG_BACKLIGHT_LP8788=m -CONFIG_BACKLIGHT_PANDORA=m -CONFIG_BACKLIGHT_SKY81452=m -CONFIG_BACKLIGHT_TPS65217=m -CONFIG_BACKLIGHT_AS3711=m # CONFIG_BACKLIGHT_GPIO is not set # CONFIG_BACKLIGHT_LV5207LP is not set # CONFIG_BACKLIGHT_BD6107 is not set # CONFIG_BACKLIGHT_ARCXCNN is not set -CONFIG_BACKLIGHT_RAVE_SP=m +CONFIG_BACKLIGHT_LED=m # end of Backlight & LCD device support CONFIG_VIDEOMODE_HELPERS=y @@ -4930,25 +4628,31 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set # CONFIG_LOGO_LINUX_CLUT224 is not set -CONFIG_LOGO_ARMBIAN_CLUT224=y # end of Graphics support -CONFIG_SOUND=m -CONFIG_SND=m -CONFIG_SND_TIMER=m -CONFIG_SND_PCM=m +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y CONFIG_SND_PCM_ELD=y CONFIG_SND_PCM_IEC958=y -CONFIG_SND_DMAENGINE_PCM=m +CONFIG_SND_DMAENGINE_PCM=y CONFIG_SND_HWDEP=m CONFIG_SND_SEQ_DEVICE=m CONFIG_SND_RAWMIDI=m +CONFIG_SND_COMPRESS_OFFLOAD=y CONFIG_SND_JACK=y CONFIG_SND_JACK_INPUT_DEV=y -# CONFIG_SND_OSSEMUL is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y CONFIG_SND_PCM_TIMER=y -# CONFIG_SND_HRTIMER is not set -# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_HRTIMER=m +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_MAX_CARDS=32 CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_PROC_FS=y CONFIG_SND_VERBOSE_PROCFS=y @@ -4956,20 +4660,23 @@ CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_DEBUG is not set CONFIG_SND_VMASTER=y CONFIG_SND_SEQUENCER=m -# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQUENCER_OSS=m +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y CONFIG_SND_SEQ_MIDI_EVENT=m CONFIG_SND_SEQ_MIDI=m CONFIG_SND_SEQ_VIRMIDI=m +CONFIG_SND_MPU401_UART=m CONFIG_SND_AC97_CODEC=m CONFIG_SND_DRIVERS=y CONFIG_SND_DUMMY=m CONFIG_SND_ALOOP=m CONFIG_SND_VIRMIDI=m -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_MTS64 is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set -# CONFIG_SND_PORTMAN2X4 is not set +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +CONFIG_SND_PORTMAN2X4=m # CONFIG_SND_AC97_POWER_SAVE is not set # @@ -4978,8 +4685,8 @@ CONFIG_SND_VIRMIDI=m # end of HD-Audio CONFIG_SND_HDA_PREALLOC_SIZE=64 -# CONFIG_SND_ARM is not set -# CONFIG_SND_SPI is not set +CONFIG_SND_ARM=y +CONFIG_SND_SPI=y CONFIG_SND_USB=y CONFIG_SND_USB_AUDIO=m CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y @@ -4994,12 +4701,19 @@ CONFIG_SND_USB_POD=m CONFIG_SND_USB_PODHD=m CONFIG_SND_USB_TONEPORT=m CONFIG_SND_USB_VARIAX=m -CONFIG_SND_SOC=m +CONFIG_SND_SOC=y CONFIG_SND_SOC_AC97_BUS=y CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y -# CONFIG_SND_SOC_AMD_ACP is not set -# CONFIG_SND_ATMEL_SOC is not set -# CONFIG_SND_DESIGNWARE_I2S is not set +CONFIG_SND_SOC_COMPRESS=y +CONFIG_SND_SOC_TOPOLOGY=y +CONFIG_SND_SOC_AMD_ACP=m +CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH=m +CONFIG_SND_SOC_AMD_CZ_RT5645_MACH=m +CONFIG_SND_ATMEL_SOC=m +CONFIG_SND_SOC_MIKROE_PROTO=m +CONFIG_SND_BCM63XX_I2S_WHISTLER=m +CONFIG_SND_DESIGNWARE_I2S=m +CONFIG_SND_DESIGNWARE_PCM=y # # SoC Audio for Freescale CPUs @@ -5008,20 +4722,43 @@ CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y # # Common SoC Audio options for Freescale CPUs: # -# CONFIG_SND_SOC_FSL_ASRC is not set -# CONFIG_SND_SOC_FSL_SAI is not set +CONFIG_SND_SOC_FSL_ASRC=m +CONFIG_SND_SOC_FSL_SAI=m +CONFIG_SND_SOC_FSL_MQS=m CONFIG_SND_SOC_FSL_AUDMIX=m -# CONFIG_SND_SOC_FSL_SSI is not set -# CONFIG_SND_SOC_FSL_SPDIF is not set -# CONFIG_SND_SOC_FSL_ESAI is not set -# CONFIG_SND_SOC_FSL_MICFIL is not set -# CONFIG_SND_SOC_IMX_AUDMUX is not set +CONFIG_SND_SOC_FSL_SSI=m +CONFIG_SND_SOC_FSL_SPDIF=m +CONFIG_SND_SOC_FSL_ESAI=m +CONFIG_SND_SOC_FSL_MICFIL=m +CONFIG_SND_SOC_IMX_AUDMUX=m # end of SoC Audio for Freescale CPUs -# CONFIG_SND_I2S_HI6210_I2S is not set -# CONFIG_SND_SOC_IMG is not set +CONFIG_SND_I2S_HI6210_I2S=m +CONFIG_SND_SOC_IMG=y +CONFIG_SND_SOC_IMG_I2S_IN=m +CONFIG_SND_SOC_IMG_I2S_OUT=m +CONFIG_SND_SOC_IMG_PARALLEL_OUT=m +CONFIG_SND_SOC_IMG_SPDIF_IN=m +CONFIG_SND_SOC_IMG_SPDIF_OUT=m +CONFIG_SND_SOC_IMG_PISTACHIO_INTERNAL_DAC=m CONFIG_SND_SOC_MTK_BTCVSD=m -# CONFIG_SND_SOC_SOF_TOPLEVEL is not set +CONFIG_SND_SOC_SOF_TOPLEVEL=y +CONFIG_SND_SOC_SOF_OF=m +CONFIG_SND_SOC_SOF_DEBUG_PROBES=y +CONFIG_SND_SOC_SOF_DEVELOPER_SUPPORT=y +CONFIG_SND_SOC_SOF_NOCODEC=m +CONFIG_SND_SOC_SOF_NOCODEC_SUPPORT=y +CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS=y +CONFIG_SND_SOC_SOF_DEBUG=y +CONFIG_SND_SOC_SOF_FORCE_NOCODEC_MODE=y +CONFIG_SND_SOC_SOF_DEBUG_XRUN_STOP=y +CONFIG_SND_SOC_SOF_DEBUG_VERBOSE_IPC=y +CONFIG_SND_SOC_SOF_DEBUG_FORCE_IPC_POSITION=y +# CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE is not set +# CONFIG_SND_SOC_SOF_DEBUG_ENABLE_FIRMWARE_TRACE is not set +# CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST is not set +# CONFIG_SND_SOC_SOF_DEBUG_RETAIN_DSP_CONTEXT is not set +CONFIG_SND_SOC_SOF=m # # STMicroelectronics STM32 SOC audio support @@ -5031,173 +4768,193 @@ CONFIG_SND_SOC_MTK_BTCVSD=m # # Allwinner SoC Audio support # -CONFIG_SND_SUN4I_CODEC=m -CONFIG_SND_SUN8I_CODEC=m -CONFIG_SND_AC100_CODEC=m -CONFIG_SND_SUN8I_CODEC_ANALOG=m -CONFIG_SND_SUN4I_I2S=m -CONFIG_SND_SUN4I_SPDIF=m -CONFIG_SND_SUN8I_ADDA_PR_REGMAP=m +CONFIG_SND_SUN4I_CODEC=y +CONFIG_SND_SUN8I_CODEC=y +CONFIG_SND_AC100_CODEC=y +CONFIG_SND_SUN8I_CODEC_ANALOG=y +CONFIG_SND_SUN4I_I2S=y +CONFIG_SND_SUN4I_SPDIF=y +CONFIG_SND_SUN8I_ADDA_PR_REGMAP=y # end of Allwinner SoC Audio support CONFIG_SND_SOC_XILINX_I2S=m CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER=m CONFIG_SND_SOC_XILINX_SPDIF=m -# CONFIG_SND_SOC_XTFPGA_I2S is not set -# CONFIG_ZX_TDM is not set -CONFIG_SND_SOC_I2C_AND_SPI=m +CONFIG_SND_SOC_XTFPGA_I2S=m +CONFIG_ZX_TDM=m +CONFIG_SND_SOC_I2C_AND_SPI=y # # CODEC drivers # CONFIG_SND_SOC_AC97_CODEC=m CONFIG_SND_SOC_ADAU_UTILS=m -# CONFIG_SND_SOC_ADAU1701 is not set +CONFIG_SND_SOC_ADAU1701=m CONFIG_SND_SOC_ADAU17X1=m CONFIG_SND_SOC_ADAU1761=m CONFIG_SND_SOC_ADAU1761_I2C=m CONFIG_SND_SOC_ADAU1761_SPI=m CONFIG_SND_SOC_ADAU7002=m -# CONFIG_SND_SOC_AK4104 is not set +CONFIG_SND_SOC_ADAU7118=m +CONFIG_SND_SOC_ADAU7118_HW=m +CONFIG_SND_SOC_ADAU7118_I2C=m +CONFIG_SND_SOC_AK4104=m CONFIG_SND_SOC_AK4118=m CONFIG_SND_SOC_AK4458=m -# CONFIG_SND_SOC_AK4554 is not set -# CONFIG_SND_SOC_AK4613 is not set -# CONFIG_SND_SOC_AK4642 is not set -# CONFIG_SND_SOC_AK5386 is not set +CONFIG_SND_SOC_AK4554=m +CONFIG_SND_SOC_AK4613=m +CONFIG_SND_SOC_AK4642=m +CONFIG_SND_SOC_AK5386=m CONFIG_SND_SOC_AK5558=m -# CONFIG_SND_SOC_ALC5623 is not set +CONFIG_SND_SOC_ALC5623=m CONFIG_SND_SOC_BD28623=m -# CONFIG_SND_SOC_BT_SCO is not set +CONFIG_SND_SOC_BT_SCO=m CONFIG_SND_SOC_CPCAP=m -# CONFIG_SND_SOC_CS35L32 is not set -# CONFIG_SND_SOC_CS35L33 is not set -# CONFIG_SND_SOC_CS35L34 is not set +CONFIG_SND_SOC_CS35L32=m +CONFIG_SND_SOC_CS35L33=m +CONFIG_SND_SOC_CS35L34=m CONFIG_SND_SOC_CS35L35=m CONFIG_SND_SOC_CS35L36=m -# CONFIG_SND_SOC_CS42L42 is not set -# CONFIG_SND_SOC_CS42L51_I2C is not set -# CONFIG_SND_SOC_CS42L52 is not set -# CONFIG_SND_SOC_CS42L56 is not set -# CONFIG_SND_SOC_CS42L73 is not set -# CONFIG_SND_SOC_CS4265 is not set -# CONFIG_SND_SOC_CS4270 is not set -# CONFIG_SND_SOC_CS4271_I2C is not set -# CONFIG_SND_SOC_CS4271_SPI is not set -# CONFIG_SND_SOC_CS42XX8_I2C is not set -# CONFIG_SND_SOC_CS43130 is not set +CONFIG_SND_SOC_CS42L42=m +CONFIG_SND_SOC_CS42L51=m +CONFIG_SND_SOC_CS42L51_I2C=m +CONFIG_SND_SOC_CS42L52=m +CONFIG_SND_SOC_CS42L56=m +CONFIG_SND_SOC_CS42L73=m +CONFIG_SND_SOC_CS4265=m +CONFIG_SND_SOC_CS4270=m +CONFIG_SND_SOC_CS4271=m +CONFIG_SND_SOC_CS4271_I2C=m +CONFIG_SND_SOC_CS4271_SPI=m +CONFIG_SND_SOC_CS42XX8=m +CONFIG_SND_SOC_CS42XX8_I2C=m +CONFIG_SND_SOC_CS43130=m CONFIG_SND_SOC_CS4341=m -# CONFIG_SND_SOC_CS4349 is not set -# CONFIG_SND_SOC_CS53L30 is not set -# CONFIG_SND_SOC_CX2072X is not set +CONFIG_SND_SOC_CS4349=m +CONFIG_SND_SOC_CS53L30=m +CONFIG_SND_SOC_CX2072X=m +CONFIG_SND_SOC_DA7213=m +CONFIG_SND_SOC_DA7219=m CONFIG_SND_SOC_DMIC=m CONFIG_SND_SOC_HDMI_CODEC=m -# CONFIG_SND_SOC_ES7134 is not set +CONFIG_SND_SOC_ES7134=m CONFIG_SND_SOC_ES7241=m -# CONFIG_SND_SOC_ES8316 is not set +CONFIG_SND_SOC_ES8316=m CONFIG_SND_SOC_ES8328=m CONFIG_SND_SOC_ES8328_I2C=m CONFIG_SND_SOC_ES8328_SPI=m -# CONFIG_SND_SOC_GTM601 is not set -# CONFIG_SND_SOC_INNO_RK3036 is not set +CONFIG_SND_SOC_GTM601=m +CONFIG_SND_SOC_EC25=m +CONFIG_SND_SOC_INNO_RK3036=m CONFIG_SND_SOC_MAX98088=m -# CONFIG_SND_SOC_MAX98357A is not set -# CONFIG_SND_SOC_MAX98504 is not set +CONFIG_SND_SOC_MAX98357A=m +CONFIG_SND_SOC_MAX98504=m CONFIG_SND_SOC_MAX9867=m -# CONFIG_SND_SOC_MAX98927 is not set -# CONFIG_SND_SOC_MAX98373 is not set -# CONFIG_SND_SOC_MAX9860 is not set -CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m -# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set -# CONFIG_SND_SOC_PCM1681 is not set +CONFIG_SND_SOC_MAX98927=m +CONFIG_SND_SOC_MAX98373=m +CONFIG_SND_SOC_MAX9860=m +CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m +CONFIG_SND_SOC_PCM1681=m CONFIG_SND_SOC_PCM1789=m CONFIG_SND_SOC_PCM1789_I2C=m -# CONFIG_SND_SOC_PCM179X_I2C is not set -# CONFIG_SND_SOC_PCM179X_SPI is not set +CONFIG_SND_SOC_PCM179X=m +CONFIG_SND_SOC_PCM179X_I2C=m +CONFIG_SND_SOC_PCM179X_SPI=m CONFIG_SND_SOC_PCM186X=m CONFIG_SND_SOC_PCM186X_I2C=m CONFIG_SND_SOC_PCM186X_SPI=m CONFIG_SND_SOC_PCM3060=m CONFIG_SND_SOC_PCM3060_I2C=m CONFIG_SND_SOC_PCM3060_SPI=m -# CONFIG_SND_SOC_PCM3168A_I2C is not set -# CONFIG_SND_SOC_PCM3168A_SPI is not set +CONFIG_SND_SOC_PCM3168A=m +CONFIG_SND_SOC_PCM3168A_I2C=m +CONFIG_SND_SOC_PCM3168A_SPI=m CONFIG_SND_SOC_PCM5102A=m CONFIG_SND_SOC_PCM512x=m CONFIG_SND_SOC_PCM512x_I2C=m CONFIG_SND_SOC_PCM512x_SPI=m CONFIG_SND_SOC_RK3328=m -# CONFIG_SND_SOC_RT5616 is not set -# CONFIG_SND_SOC_RT5631 is not set -# CONFIG_SND_SOC_SGTL5000 is not set -CONFIG_SND_SOC_SI476X=m +CONFIG_SND_SOC_RL6231=m +CONFIG_SND_SOC_RT5616=m +CONFIG_SND_SOC_RT5631=m +CONFIG_SND_SOC_RT5645=m +CONFIG_SND_SOC_SGTL5000=m CONFIG_SND_SOC_SIGMADSP=m +CONFIG_SND_SOC_SIGMADSP_I2C=m CONFIG_SND_SOC_SIGMADSP_REGMAP=m CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m # CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set CONFIG_SND_SOC_SPDIF=m -# CONFIG_SND_SOC_SSM2305 is not set -# CONFIG_SND_SOC_SSM2602_SPI is not set -# CONFIG_SND_SOC_SSM2602_I2C is not set -# CONFIG_SND_SOC_SSM4567 is not set -# CONFIG_SND_SOC_STA32X is not set -# CONFIG_SND_SOC_STA350 is not set -# CONFIG_SND_SOC_STI_SAS is not set -# CONFIG_SND_SOC_TAS2552 is not set -# CONFIG_SND_SOC_TAS5086 is not set -# CONFIG_SND_SOC_TAS571X is not set -# CONFIG_SND_SOC_TAS5720 is not set +CONFIG_SND_SOC_SSM2305=m +CONFIG_SND_SOC_SSM2602=m +CONFIG_SND_SOC_SSM2602_SPI=m +CONFIG_SND_SOC_SSM2602_I2C=m +CONFIG_SND_SOC_SSM4567=m +CONFIG_SND_SOC_STA32X=m +CONFIG_SND_SOC_STA350=m +CONFIG_SND_SOC_STI_SAS=m +CONFIG_SND_SOC_TAS2552=m +CONFIG_SND_SOC_TAS2562=m +CONFIG_SND_SOC_TAS2770=m +CONFIG_SND_SOC_TAS5086=m +CONFIG_SND_SOC_TAS571X=m +CONFIG_SND_SOC_TAS5720=m CONFIG_SND_SOC_TAS6424=m CONFIG_SND_SOC_TDA7419=m -# CONFIG_SND_SOC_TFA9879 is not set -# CONFIG_SND_SOC_TLV320AIC23_I2C is not set -# CONFIG_SND_SOC_TLV320AIC23_SPI is not set -# CONFIG_SND_SOC_TLV320AIC31XX is not set -# CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set -# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set -# CONFIG_SND_SOC_TLV320AIC3X is not set -# CONFIG_SND_SOC_TS3A227E is not set -# CONFIG_SND_SOC_TSCS42XX is not set -# CONFIG_SND_SOC_TSCS454 is not set +CONFIG_SND_SOC_TFA9879=m +CONFIG_SND_SOC_TLV320AIC23=m +CONFIG_SND_SOC_TLV320AIC23_I2C=m +CONFIG_SND_SOC_TLV320AIC23_SPI=m +CONFIG_SND_SOC_TLV320AIC31XX=m +CONFIG_SND_SOC_TLV320AIC32X4=m +CONFIG_SND_SOC_TLV320AIC32X4_I2C=m +CONFIG_SND_SOC_TLV320AIC32X4_SPI=m +CONFIG_SND_SOC_TLV320AIC3X=m +CONFIG_SND_SOC_TLV320ADCX140=m +CONFIG_SND_SOC_TS3A227E=m +CONFIG_SND_SOC_TSCS42XX=m +CONFIG_SND_SOC_TSCS454=m CONFIG_SND_SOC_UDA1334=m -# CONFIG_SND_SOC_WM8510 is not set -# CONFIG_SND_SOC_WM8523 is not set -# CONFIG_SND_SOC_WM8524 is not set -# CONFIG_SND_SOC_WM8580 is not set -# CONFIG_SND_SOC_WM8711 is not set -# CONFIG_SND_SOC_WM8728 is not set -# CONFIG_SND_SOC_WM8731 is not set -# CONFIG_SND_SOC_WM8737 is not set -# CONFIG_SND_SOC_WM8741 is not set -# CONFIG_SND_SOC_WM8750 is not set -# CONFIG_SND_SOC_WM8753 is not set -# CONFIG_SND_SOC_WM8770 is not set -# CONFIG_SND_SOC_WM8776 is not set -# CONFIG_SND_SOC_WM8782 is not set -# CONFIG_SND_SOC_WM8804_I2C is not set -# CONFIG_SND_SOC_WM8804_SPI is not set -# CONFIG_SND_SOC_WM8903 is not set +CONFIG_SND_SOC_WM8510=m +CONFIG_SND_SOC_WM8523=m +CONFIG_SND_SOC_WM8524=m +CONFIG_SND_SOC_WM8580=m +CONFIG_SND_SOC_WM8711=m +CONFIG_SND_SOC_WM8728=m +CONFIG_SND_SOC_WM8731=m +CONFIG_SND_SOC_WM8737=m +CONFIG_SND_SOC_WM8741=m +CONFIG_SND_SOC_WM8750=m +CONFIG_SND_SOC_WM8753=m +CONFIG_SND_SOC_WM8770=m +CONFIG_SND_SOC_WM8776=m +CONFIG_SND_SOC_WM8782=m +CONFIG_SND_SOC_WM8804=m +CONFIG_SND_SOC_WM8804_I2C=m +CONFIG_SND_SOC_WM8804_SPI=m +CONFIG_SND_SOC_WM8903=m CONFIG_SND_SOC_WM8904=m -# CONFIG_SND_SOC_WM8960 is not set -# CONFIG_SND_SOC_WM8962 is not set -# CONFIG_SND_SOC_WM8974 is not set -# CONFIG_SND_SOC_WM8978 is not set -# CONFIG_SND_SOC_WM8985 is not set -# CONFIG_SND_SOC_ZX_AUD96P22 is not set +CONFIG_SND_SOC_WM8960=m +CONFIG_SND_SOC_WM8962=m +CONFIG_SND_SOC_WM8974=m +CONFIG_SND_SOC_WM8978=m +CONFIG_SND_SOC_WM8985=m +CONFIG_SND_SOC_ZX_AUD96P22=m CONFIG_SND_SOC_MAX9759=m -# CONFIG_SND_SOC_MT6351 is not set +CONFIG_SND_SOC_MT6351=m CONFIG_SND_SOC_MT6358=m +CONFIG_SND_SOC_MT6660=m CONFIG_SND_SOC_NAU8540=m -# CONFIG_SND_SOC_NAU8810 is not set +CONFIG_SND_SOC_NAU8810=m CONFIG_SND_SOC_NAU8822=m CONFIG_SND_SOC_NAU8824=m -# CONFIG_SND_SOC_TPA6130A2 is not set +CONFIG_SND_SOC_TPA6130A2=m # end of CODEC drivers -CONFIG_SND_SIMPLE_CARD_UTILS=m -CONFIG_SND_SIMPLE_CARD=m -# CONFIG_SND_AUDIO_GRAPH_CARD is not set -CONFIG_AC97_BUS=m +CONFIG_SND_SIMPLE_CARD_UTILS=y +CONFIG_SND_SIMPLE_CARD=y +CONFIG_SND_AUDIO_GRAPH_CARD=y +CONFIG_AC97_BUS=y # # HID support @@ -5217,7 +4974,7 @@ CONFIG_HID_ACRUX=m CONFIG_HID_ACRUX_FF=y CONFIG_HID_APPLE=m CONFIG_HID_APPLEIR=m -# CONFIG_HID_ASUS is not set +CONFIG_HID_ASUS=m CONFIG_HID_AUREAL=m CONFIG_HID_BELKIN=m CONFIG_HID_BETOP_FF=m @@ -5228,7 +4985,7 @@ CONFIG_HID_CORSAIR=m CONFIG_HID_COUGAR=m CONFIG_HID_MACALLY=m CONFIG_HID_PRODIKEYS=m -# CONFIG_HID_CMEDIA is not set +CONFIG_HID_CMEDIA=m CONFIG_HID_CP2112=m CONFIG_HID_CREATIVE_SB0540=m CONFIG_HID_CYPRESS=m @@ -5241,6 +4998,7 @@ CONFIG_HID_ELO=m CONFIG_HID_EZKEY=m CONFIG_HID_GEMBIRD=m CONFIG_HID_GFRM=m +CONFIG_HID_GLORIOUS=m CONFIG_HID_HOLTEK=m CONFIG_HOLTEK_FF=y CONFIG_HID_GT683R=m @@ -5287,14 +5045,14 @@ CONFIG_HID_PICOLCD_LEDS=y CONFIG_HID_PICOLCD_CIR=y CONFIG_HID_PLANTRONICS=m CONFIG_HID_PRIMAX=m -# CONFIG_HID_RETRODE is not set +CONFIG_HID_RETRODE=m CONFIG_HID_ROCCAT=m CONFIG_HID_SAITEK=m CONFIG_HID_SAMSUNG=m CONFIG_HID_SONY=m CONFIG_SONY_FF=y CONFIG_HID_SPEEDLINK=m -# CONFIG_HID_STEAM is not set +CONFIG_HID_STEAM=m CONFIG_HID_STEELSERIES=m CONFIG_HID_SUNPLUS=m CONFIG_HID_RMI=m @@ -5307,7 +5065,7 @@ CONFIG_HID_TOPSEED=m CONFIG_HID_THINGM=m CONFIG_HID_THRUSTMASTER=m CONFIG_THRUSTMASTER_FF=y -# CONFIG_HID_UDRAW_PS3 is not set +CONFIG_HID_UDRAW_PS3=m CONFIG_HID_U2FZERO=m CONFIG_HID_WACOM=m CONFIG_HID_WIIMOTE=m @@ -5318,6 +5076,7 @@ CONFIG_HID_ZYDACRON=m CONFIG_HID_SENSOR_HUB=m CONFIG_HID_SENSOR_CUSTOM_SENSOR=m CONFIG_HID_ALPS=m +CONFIG_HID_MCP2221=m # end of Special HID drivers # @@ -5349,7 +5108,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y # Miscellaneous USB options # CONFIG_USB_DEFAULT_PERSIST=y -# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_DYNAMIC_MINORS=y CONFIG_USB_OTG=y # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set @@ -5376,11 +5135,12 @@ CONFIG_USB_FOTG210_HCD=m CONFIG_USB_MAX3421_HCD=m CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y -CONFIG_USB_U132_HCD=m -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_HCD_BCMA is not set -# CONFIG_USB_HCD_SSB is not set +# CONFIG_USB_U132_HCD is not set +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SL811_HCD_ISO=y +CONFIG_USB_R8A66597_HCD=m +CONFIG_USB_HCD_BCMA=m +CONFIG_USB_HCD_SSB=m # CONFIG_USB_HCD_TEST_MODE is not set # @@ -5400,26 +5160,27 @@ CONFIG_USB_TMC=m # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_REALTEK is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_STORAGE_ENE_UB6250 is not set +CONFIG_USB_STORAGE_REALTEK=m +CONFIG_REALTEK_AUTOPM=y +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +CONFIG_USB_STORAGE_ENE_UB6250=m CONFIG_USB_UAS=m # # USB Imaging devices # -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m CONFIG_USBIP_CORE=m CONFIG_USBIP_VHCI_HCD=m CONFIG_USBIP_VHCI_HC_PORTS=8 @@ -5436,7 +5197,7 @@ CONFIG_USB_MUSB_DUAL_ROLE=y # # Platform Glue Layer # -CONFIG_USB_MUSB_SUNXI=y +CONFIG_USB_MUSB_SUNXI=m # # MUSB DMA mode @@ -5487,7 +5248,7 @@ CONFIG_USB_SERIAL_IR=m CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m CONFIG_USB_SERIAL_F81232=m -CONFIG_USB_SERIAL_F8153X=m +# CONFIG_USB_SERIAL_F8153X is not set CONFIG_USB_SERIAL_GARMIN=m CONFIG_USB_SERIAL_IPW=m CONFIG_USB_SERIAL_IUU=m @@ -5508,7 +5269,7 @@ CONFIG_USB_SERIAL_QCAUX=m CONFIG_USB_SERIAL_QUALCOMM=m CONFIG_USB_SERIAL_SPCP8X5=m CONFIG_USB_SERIAL_SAFE=m -CONFIG_USB_SERIAL_SAFE_PADDED=y +# CONFIG_USB_SERIAL_SAFE_PADDED is not set CONFIG_USB_SERIAL_SIERRAWIRELESS=m CONFIG_USB_SERIAL_SYMBOL=m CONFIG_USB_SERIAL_TI=m @@ -5528,31 +5289,32 @@ CONFIG_USB_SERIAL_DEBUG=m # # USB Miscellaneous drivers # -CONFIG_USB_EMI62=m -CONFIG_USB_EMI26=m -CONFIG_USB_ADUTUX=m +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set CONFIG_USB_SEVSEG=m CONFIG_USB_LEGOTOWER=m CONFIG_USB_LCD=m -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m CONFIG_USB_IDMOUSE=m CONFIG_USB_FTDI_ELAN=m CONFIG_USB_APPLEDISPLAY=m +CONFIG_APPLE_MFI_FASTCHARGE=m CONFIG_USB_SISUSBVGA=m CONFIG_USB_SISUSBVGA_CON=y CONFIG_USB_LD=m CONFIG_USB_TRANCEVIBRATOR=m CONFIG_USB_IOWARRIOR=m -# CONFIG_USB_TEST is not set -# CONFIG_USB_EHSET_TEST_FIXTURE is not set +CONFIG_USB_TEST=m +CONFIG_USB_EHSET_TEST_FIXTURE=m CONFIG_USB_ISIGHTFW=m CONFIG_USB_YUREX=m CONFIG_USB_EZUSB_FX2=m CONFIG_USB_HUB_USB251XB=m CONFIG_USB_HSIC_USB3503=m CONFIG_USB_HSIC_USB4604=m -# CONFIG_USB_LINK_LAYER_TEST is not set +CONFIG_USB_LINK_LAYER_TEST=m CONFIG_USB_CHAOSKEY=m CONFIG_USB_ATM=m CONFIG_USB_SPEEDTOUCH=m @@ -5564,13 +5326,13 @@ CONFIG_USB_XUSBATM=m # USB Physical Layer drivers # CONFIG_USB_PHY=y -CONFIG_NOP_USB_XCEIV=y -# CONFIG_AM335X_PHY_USB is not set -# CONFIG_USB_GPIO_VBUS is not set -CONFIG_TAHVO_USB=m -# CONFIG_TAHVO_USB_HOST_BY_DEFAULT is not set -# CONFIG_USB_ISP1301 is not set -# CONFIG_USB_ULPI is not set +CONFIG_NOP_USB_XCEIV=m +CONFIG_AM335X_CONTROL_USB=m +CONFIG_AM335X_PHY_USB=m +CONFIG_USB_GPIO_VBUS=m +CONFIG_USB_ISP1301=m +CONFIG_USB_ULPI=y +CONFIG_USB_ULPI_VIEWPORT=y # end of USB Physical Layer drivers CONFIG_USB_GADGET=y @@ -5596,11 +5358,13 @@ CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 # CONFIG_USB_BDC_UDC is not set # CONFIG_USB_NET2272 is not set # CONFIG_USB_GADGET_XILINX is not set +CONFIG_USB_MAX3420_UDC=m # CONFIG_USB_DUMMY_HCD is not set # end of USB Peripheral Controller CONFIG_USB_LIBCOMPOSITE=m CONFIG_USB_F_ACM=m +CONFIG_USB_F_SS_LB=m CONFIG_USB_U_SERIAL=m CONFIG_USB_U_ETHER=m CONFIG_USB_U_AUDIO=m @@ -5612,11 +5376,39 @@ CONFIG_USB_F_EEM=m CONFIG_USB_F_SUBSET=m CONFIG_USB_F_RNDIS=m CONFIG_USB_F_MASS_STORAGE=m +CONFIG_USB_F_FS=m CONFIG_USB_F_UAC1=m +CONFIG_USB_F_UAC1_LEGACY=m +CONFIG_USB_F_UAC2=m CONFIG_USB_F_UVC=m +CONFIG_USB_F_MIDI=m CONFIG_USB_F_HID=m CONFIG_USB_F_PRINTER=m -# CONFIG_USB_CONFIGFS is not set +CONFIG_USB_F_TCM=m +CONFIG_USB_CONFIGFS=m +CONFIG_USB_CONFIGFS_SERIAL=y +CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_OBEX=y +CONFIG_USB_CONFIGFS_NCM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_ECM_SUBSET=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_LB_SS=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_F_UAC1=y +CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y +CONFIG_USB_CONFIGFS_F_UAC2=y +CONFIG_USB_CONFIGFS_F_MIDI=y +CONFIG_USB_CONFIGFS_F_HID=y +CONFIG_USB_CONFIGFS_F_UVC=y +CONFIG_USB_CONFIGFS_F_PRINTER=y +CONFIG_USB_CONFIGFS_F_TCM=y + +# +# USB Gadget precomposed configurations +# # CONFIG_USB_ZERO is not set CONFIG_USB_AUDIO=m CONFIG_GADGET_UAC1=y @@ -5628,7 +5420,7 @@ CONFIG_USB_G_NCM=m CONFIG_USB_GADGETFS=m # CONFIG_USB_FUNCTIONFS is not set CONFIG_USB_MASS_STORAGE=m -# CONFIG_USB_GADGET_TARGET is not set +CONFIG_USB_GADGET_TARGET=m CONFIG_USB_G_SERIAL=m # CONFIG_USB_MIDI_GADGET is not set CONFIG_USB_G_PRINTER=m @@ -5636,12 +5428,38 @@ CONFIG_USB_CDC_COMPOSITE=m CONFIG_USB_G_ACM_MS=m CONFIG_USB_G_MULTI=m CONFIG_USB_G_MULTI_RNDIS=y -# CONFIG_USB_G_MULTI_CDC is not set +CONFIG_USB_G_MULTI_CDC=y CONFIG_USB_G_HID=m # CONFIG_USB_G_DBGP is not set CONFIG_USB_G_WEBCAM=m -# CONFIG_TYPEC is not set -CONFIG_USB_ROLE_SWITCH=m +CONFIG_USB_RAW_GADGET=m +# end of USB Gadget precomposed configurations + +CONFIG_TYPEC=m +CONFIG_TYPEC_TCPM=m +CONFIG_TYPEC_TCPCI=m +CONFIG_TYPEC_RT1711H=m +CONFIG_TYPEC_FUSB302=m +CONFIG_TYPEC_UCSI=m +CONFIG_UCSI_CCG=m +CONFIG_TYPEC_ANX7688=m +CONFIG_TYPEC_HD3SS3220=m +CONFIG_TYPEC_TPS6598X=m + +# +# USB Type-C Multiplexer/DeMultiplexer Switch support +# +CONFIG_TYPEC_MUX_PI3USB30532=m +# end of USB Type-C Multiplexer/DeMultiplexer Switch support + +# +# USB Type-C Alternate Mode drivers +# +CONFIG_TYPEC_DP_ALTMODE=m +CONFIG_TYPEC_NVIDIA_ALTMODE=m +# end of USB Type-C Alternate Mode drivers + +CONFIG_USB_ROLE_SWITCH=y CONFIG_MMC=y CONFIG_PWRSEQ_EMMC=m CONFIG_PWRSEQ_SD8787=m @@ -5665,6 +5483,7 @@ CONFIG_MMC_USHC=m # CONFIG_MMC_REALTEK_USB is not set CONFIG_MMC_SUNXI=y # CONFIG_MMC_CQHCI is not set +CONFIG_MMC_HSQ=m # CONFIG_MMC_MTK is not set # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y @@ -5675,54 +5494,45 @@ CONFIG_LEDS_CLASS_FLASH=m # # LED drivers # -CONFIG_LEDS_88PM860X=m # CONFIG_LEDS_AAT1290 is not set CONFIG_LEDS_AN30259A=m -# CONFIG_LEDS_AS3645A is not set -# CONFIG_LEDS_BCM6328 is not set -# CONFIG_LEDS_BCM6358 is not set +CONFIG_LEDS_AS3645A=m +CONFIG_LEDS_BCM6328=m +CONFIG_LEDS_BCM6358=m CONFIG_LEDS_CPCAP=m CONFIG_LEDS_CR0014114=m -# CONFIG_LEDS_LM3530 is not set +CONFIG_LEDS_EL15203000=m +CONFIG_LEDS_LM3530=m CONFIG_LEDS_LM3532=m -CONFIG_LEDS_LM3533=m -# CONFIG_LEDS_LM3642 is not set +CONFIG_LEDS_LM3642=m CONFIG_LEDS_LM3692X=m -# CONFIG_LEDS_LM3601X is not set -CONFIG_LEDS_MT6323=m -# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_LM3601X=m +CONFIG_LEDS_PCA9532=m +# CONFIG_LEDS_PCA9532_GPIO is not set CONFIG_LEDS_GPIO=y -# CONFIG_LEDS_LP3944 is not set -# CONFIG_LEDS_LP3952 is not set -# CONFIG_LEDS_LP5521 is not set -# CONFIG_LEDS_LP5523 is not set -# CONFIG_LEDS_LP5562 is not set -# CONFIG_LEDS_LP8501 is not set -CONFIG_LEDS_LP8788=m -# CONFIG_LEDS_LP8860 is not set -# CONFIG_LEDS_PCA955X is not set -# CONFIG_LEDS_PCA963X is not set -CONFIG_LEDS_WM831X_STATUS=m -CONFIG_LEDS_WM8350=m -CONFIG_LEDS_DA903X=m -CONFIG_LEDS_DA9052=m -# CONFIG_LEDS_DAC124S085 is not set +CONFIG_LEDS_LP3944=m +CONFIG_LEDS_LP3952=m +CONFIG_LEDS_LP55XX_COMMON=m +CONFIG_LEDS_LP5521=m +CONFIG_LEDS_LP5523=m +CONFIG_LEDS_LP5562=m +CONFIG_LEDS_LP8501=m +CONFIG_LEDS_LP8860=m +CONFIG_LEDS_PCA955X=m +CONFIG_LEDS_PCA955X_GPIO=y +CONFIG_LEDS_PCA963X=m +CONFIG_LEDS_DAC124S085=m CONFIG_LEDS_PWM=m CONFIG_LEDS_REGULATOR=m -# CONFIG_LEDS_BD2802 is not set -# CONFIG_LEDS_LT3593 is not set -CONFIG_LEDS_ADP5520=m -CONFIG_LEDS_MC13783=m -# CONFIG_LEDS_TCA6507 is not set -# CONFIG_LEDS_TLC591XX is not set +CONFIG_LEDS_BD2802=m +CONFIG_LEDS_LT3593=m +CONFIG_LEDS_TCA6507=m +CONFIG_LEDS_TLC591XX=m CONFIG_LEDS_MAX77650=m -CONFIG_LEDS_MAX77693=m -CONFIG_LEDS_MAX8997=m -# CONFIG_LEDS_LM355x is not set -CONFIG_LEDS_MENF21BMC=m -# CONFIG_LEDS_KTD2692 is not set -# CONFIG_LEDS_IS31FL319X is not set -# CONFIG_LEDS_IS31FL32XX is not set +CONFIG_LEDS_LM355x=m +CONFIG_LEDS_KTD2692=m +CONFIG_LEDS_IS31FL319X=m +CONFIG_LEDS_IS31FL32XX=m # # LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) @@ -5731,8 +5541,9 @@ CONFIG_LEDS_MENF21BMC=m CONFIG_LEDS_SYSCON=y CONFIG_LEDS_MLXREG=m CONFIG_LEDS_USER=y -# CONFIG_LEDS_SPI_BYTE is not set -# CONFIG_LEDS_TI_LMU_COMMON is not set +CONFIG_LEDS_SPI_BYTE=m +CONFIG_LEDS_TI_LMU_COMMON=m +CONFIG_LEDS_LM3697=m CONFIG_LEDS_AXP20X=m # @@ -5785,51 +5596,38 @@ CONFIG_RTC_INTF_DEV=y # # I2C RTC drivers # -CONFIG_RTC_DRV_88PM860X=m -CONFIG_RTC_DRV_88PM80X=m # CONFIG_RTC_DRV_ABB5ZES3 is not set CONFIG_RTC_DRV_ABEOZ9=m # CONFIG_RTC_DRV_ABX80X is not set CONFIG_RTC_DRV_AC100=m -CONFIG_RTC_DRV_AS3722=m CONFIG_RTC_DRV_DS1307=m # CONFIG_RTC_DRV_DS1307_CENTURY is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_HYM8563 is not set -CONFIG_RTC_DRV_LP8788=m -# CONFIG_RTC_DRV_MAX6900 is not set -CONFIG_RTC_DRV_MAX8907=m -CONFIG_RTC_DRV_MAX8925=m -CONFIG_RTC_DRV_MAX8998=m -CONFIG_RTC_DRV_MAX8997=m -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_ISL12022 is not set +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1374_WDT=y +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_HYM8563=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_ISL12022=m CONFIG_RTC_DRV_ISL12026=m CONFIG_RTC_DRV_X1205=m CONFIG_RTC_DRV_PCF8523=m CONFIG_RTC_DRV_PCF85063=m -# CONFIG_RTC_DRV_PCF85363 is not set +CONFIG_RTC_DRV_PCF85363=m CONFIG_RTC_DRV_PCF8563=m -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_BQ32K is not set -CONFIG_RTC_DRV_TWL4030=m -CONFIG_RTC_DRV_PALMAS=m -CONFIG_RTC_DRV_TPS6586X=m -CONFIG_RTC_DRV_TPS65910=m -CONFIG_RTC_DRV_TPS80031=m -CONFIG_RTC_DRV_RC5T583=m -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_BQ32K=y +CONFIG_RTC_DRV_S35390A=m +CONFIG_RTC_DRV_FM3130=m # CONFIG_RTC_DRV_RX8010 is not set # CONFIG_RTC_DRV_RX8581 is not set # CONFIG_RTC_DRV_RX8025 is not set # CONFIG_RTC_DRV_EM3027 is not set CONFIG_RTC_DRV_RV3028=m # CONFIG_RTC_DRV_RV8803 is not set -CONFIG_RTC_DRV_S5M=m CONFIG_RTC_DRV_SD3078=m # @@ -5837,32 +5635,34 @@ CONFIG_RTC_DRV_SD3078=m # CONFIG_RTC_DRV_M41T93=m CONFIG_RTC_DRV_M41T94=m -# CONFIG_RTC_DRV_DS1302 is not set +CONFIG_RTC_DRV_DS1302=m CONFIG_RTC_DRV_DS1305=m -# CONFIG_RTC_DRV_DS1343 is not set -# CONFIG_RTC_DRV_DS1347 is not set +CONFIG_RTC_DRV_DS1343=m +CONFIG_RTC_DRV_DS1347=m CONFIG_RTC_DRV_DS1390=m CONFIG_RTC_DRV_MAX6916=m CONFIG_RTC_DRV_R9701=m CONFIG_RTC_DRV_RX4581=m -# CONFIG_RTC_DRV_RX6110 is not set +CONFIG_RTC_DRV_RX6110=m CONFIG_RTC_DRV_RS5C348=m CONFIG_RTC_DRV_MAX6902=m CONFIG_RTC_DRV_PCF2123=m -# CONFIG_RTC_DRV_MCP795 is not set +CONFIG_RTC_DRV_MCP795=m CONFIG_RTC_I2C_AND_SPI=y # # SPI and I2C RTC drivers # -# CONFIG_RTC_DRV_DS3232 is not set -# CONFIG_RTC_DRV_PCF2127 is not set -# CONFIG_RTC_DRV_RV3029C2 is not set +CONFIG_RTC_DRV_DS3232=m +CONFIG_RTC_DRV_DS3232_HWMON=y +CONFIG_RTC_DRV_PCF2127=m +CONFIG_RTC_DRV_RV3029C2=m +CONFIG_RTC_DRV_RV3029_HWMON=y # # Platform RTC drivers # -CONFIG_RTC_DRV_CMOS=y +CONFIG_RTC_DRV_CMOS=m CONFIG_RTC_DRV_DS1286=m CONFIG_RTC_DRV_DS1511=m CONFIG_RTC_DRV_DS1553=m @@ -5874,22 +5674,15 @@ CONFIG_RTC_DRV_DS1685=y # CONFIG_RTC_DRV_DS17885 is not set CONFIG_RTC_DRV_DS1742=m CONFIG_RTC_DRV_DS2404=m -CONFIG_RTC_DRV_DA9052=m -CONFIG_RTC_DRV_DA9055=m -CONFIG_RTC_DRV_DA9063=m CONFIG_RTC_DRV_STK17TA8=m -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_MSM6242 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_RP5C01 is not set -# CONFIG_RTC_DRV_V3020 is not set -CONFIG_RTC_DRV_WM831X=m -CONFIG_RTC_DRV_WM8350=m -CONFIG_RTC_DRV_PCF50633=m -CONFIG_RTC_DRV_AB3100=m -# CONFIG_RTC_DRV_ZYNQMP is not set +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_M48T35=m +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_MSM6242=m +CONFIG_RTC_DRV_BQ4802=m +CONFIG_RTC_DRV_RP5C01=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_ZYNQMP=m # # on-CPU RTC drivers @@ -5897,18 +5690,14 @@ CONFIG_RTC_DRV_AB3100=m CONFIG_RTC_DRV_SUN6I=y CONFIG_RTC_DRV_SUNXI=y CONFIG_RTC_DRV_CADENCE=m -# CONFIG_RTC_DRV_FTRTC010 is not set -CONFIG_RTC_DRV_PCAP=m -CONFIG_RTC_DRV_MC13XXX=m -# CONFIG_RTC_DRV_SNVS is not set -CONFIG_RTC_DRV_MT6397=m -# CONFIG_RTC_DRV_R7301 is not set +CONFIG_RTC_DRV_FTRTC010=m +CONFIG_RTC_DRV_R7301=m CONFIG_RTC_DRV_CPCAP=m # # HID Sensor RTC drivers # -# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set +CONFIG_RTC_DRV_HID_SENSOR_TIME=m CONFIG_DMADEVICES=y # CONFIG_DMADEVICES_DEBUG is not set @@ -5930,6 +5719,7 @@ CONFIG_FSL_QDMA=m # CONFIG_QCOM_HIDMA_MGMT is not set # CONFIG_QCOM_HIDMA is not set # CONFIG_DW_DMAC is not set +# CONFIG_SF_PDMA is not set # # DMA Clients @@ -5944,7 +5734,9 @@ CONFIG_DMA_ENGINE_RAID=y CONFIG_SYNC_FILE=y # CONFIG_SW_SYNC is not set # CONFIG_UDMABUF is not set +# CONFIG_DMABUF_MOVE_NOTIFY is not set CONFIG_DMABUF_SELFTESTS=m +# CONFIG_DMABUF_HEAPS is not set # end of DMABUF options # CONFIG_AUXDISPLAY is not set @@ -5960,6 +5752,12 @@ CONFIG_VIRTIO_MENU=y CONFIG_VIRTIO_BALLOON=m CONFIG_VIRTIO_INPUT=m # CONFIG_VIRTIO_MMIO is not set +# CONFIG_VDPA is not set +CONFIG_VHOST_DPN=y +CONFIG_VHOST_MENU=y +# CONFIG_VHOST_NET is not set +# CONFIG_VHOST_SCSI is not set +# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set # # Microsoft Hyper-V guest support @@ -5991,7 +5789,6 @@ CONFIG_R8712U=m # Analog to digital converters # # CONFIG_AD7816 is not set -# CONFIG_AD7192 is not set # CONFIG_AD7280 is not set # end of Analog to digital converters @@ -6047,6 +5844,7 @@ CONFIG_VIDEO_SUNXI_CEDRUS=m # # soc_camera sensor drivers # +CONFIG_VIDEO_USBVISION=m # # Android @@ -6076,6 +5874,7 @@ CONFIG_FB_TFT_PCD8544=m CONFIG_FB_TFT_RA8875=m CONFIG_FB_TFT_S6D02A1=m CONFIG_FB_TFT_S6D1121=m +CONFIG_FB_TFT_SEPS525=m CONFIG_FB_TFT_SH1106=m CONFIG_FB_TFT_SSD1289=m CONFIG_FB_TFT_SSD1305=m @@ -6092,7 +5891,7 @@ CONFIG_FB_TFT_UPD161704=m CONFIG_FB_TFT_WATTEROTT=m # CONFIG_WILC1000_SDIO is not set # CONFIG_WILC1000_SPI is not set -CONFIG_MOST=m +CONFIG_MOST_COMPONENTS=m # CONFIG_MOST_CDEV is not set # CONFIG_MOST_NET is not set # CONFIG_MOST_SOUND is not set @@ -6113,16 +5912,8 @@ CONFIG_FIELDBUS_DEV=m CONFIG_HMS_ANYBUSS_BUS=m CONFIG_ARCX_ANYBUS_CONTROLLER=m CONFIG_HMS_PROFINET=m -# CONFIG_USB_WUSB_CBAF is not set -# CONFIG_UWB is not set -CONFIG_EXFAT_FS=m -CONFIG_EXFAT_DONT_MOUNT_VFAT=y -CONFIG_EXFAT_DISCARD=y -# CONFIG_EXFAT_DELAYED_SYNC is not set -# CONFIG_EXFAT_KERNEL_DEBUG is not set -# CONFIG_EXFAT_DEBUG_MSG is not set -CONFIG_EXFAT_DEFAULT_CODEPAGE=437 -CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" +CONFIG_WFX=m +CONFIG_RTL8723CS_NEW=m # CONFIG_GOLDFISH is not set # CONFIG_MFD_CROS_EC is not set # CONFIG_CHROME_PLATFORMS is not set @@ -6134,7 +5925,6 @@ CONFIG_COMMON_CLK=y # # Common Clock Framework # -CONFIG_COMMON_CLK_WM831X=m # CONFIG_CLK_HSDK is not set CONFIG_COMMON_CLK_MAX9485=m # CONFIG_COMMON_CLK_SI5341 is not set @@ -6145,10 +5935,7 @@ CONFIG_COMMON_CLK_MAX9485=m # CONFIG_COMMON_CLK_CDCE706 is not set # CONFIG_COMMON_CLK_CDCE925 is not set # CONFIG_COMMON_CLK_CS2000_CP is not set -CONFIG_COMMON_CLK_S2MPS11=m -CONFIG_CLK_TWL6040=m CONFIG_CLK_QORIQ=y -CONFIG_COMMON_CLK_PALMAS=m CONFIG_COMMON_CLK_PWM=m CONFIG_COMMON_CLK_VC5=m CONFIG_COMMON_CLK_BD718XX=m @@ -6185,6 +5972,7 @@ CONFIG_SUN4I_TIMER=y CONFIG_SUN5I_HSTIMER=y CONFIG_ARM_ARCH_TIMER=y CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +# CONFIG_MICROCHIP_PIT64B is not set # end of Clock Source drivers # CONFIG_MAILBOX is not set @@ -6205,6 +5993,7 @@ CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y # CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set CONFIG_OF_IOMMU=y CONFIG_ARM_SMMU=y +# CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS is not set CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y # @@ -6244,6 +6033,8 @@ CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y # # NXP/Freescale QorIQ SoC drivers # +# CONFIG_QUICC_ENGINE is not set +# CONFIG_FSL_RCPM is not set # end of NXP/Freescale QorIQ SoC drivers # @@ -6287,15 +6078,9 @@ CONFIG_EXTCON=y # Extcon Device Drivers # # CONFIG_EXTCON_ADC_JACK is not set -CONFIG_EXTCON_ARIZONA=m # CONFIG_EXTCON_FSA9480 is not set CONFIG_EXTCON_GPIO=m -CONFIG_EXTCON_MAX14577=m # CONFIG_EXTCON_MAX3355 is not set -CONFIG_EXTCON_MAX77693=m -CONFIG_EXTCON_MAX77843=m -CONFIG_EXTCON_MAX8997=m -CONFIG_EXTCON_PALMAS=m CONFIG_EXTCON_PTN5150=m # CONFIG_EXTCON_RT8973A is not set # CONFIG_EXTCON_SM5502 is not set @@ -6316,57 +6101,54 @@ CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 # # Accelerometers # -CONFIG_ADIS16201=m -CONFIG_ADIS16209=m +# CONFIG_ADIS16201 is not set +# CONFIG_ADIS16209 is not set CONFIG_ADXL345=m CONFIG_ADXL345_I2C=m CONFIG_ADXL345_SPI=m CONFIG_ADXL372=m CONFIG_ADXL372_SPI=m CONFIG_ADXL372_I2C=m -CONFIG_BMA180=m -CONFIG_BMA220=m -CONFIG_BMC150_ACCEL=m -CONFIG_BMC150_ACCEL_I2C=m -CONFIG_BMC150_ACCEL_SPI=m -CONFIG_DA280=m -CONFIG_DA311=m -CONFIG_DMARD06=m -CONFIG_DMARD09=m -CONFIG_DMARD10=m -CONFIG_HID_SENSOR_ACCEL_3D=m -CONFIG_IIO_ST_ACCEL_3AXIS=m -CONFIG_IIO_ST_ACCEL_I2C_3AXIS=m -CONFIG_IIO_ST_ACCEL_SPI_3AXIS=m -CONFIG_KXSD9=m -CONFIG_KXSD9_SPI=m -CONFIG_KXSD9_I2C=m -CONFIG_KXCJK1013=m -CONFIG_MC3230=m -CONFIG_MMA7455=m -CONFIG_MMA7455_I2C=m -CONFIG_MMA7455_SPI=m -CONFIG_MMA7660=m -CONFIG_MMA8452=m -CONFIG_MMA9551_CORE=m -CONFIG_MMA9551=m -CONFIG_MMA9553=m -CONFIG_MXC4005=m -CONFIG_MXC6255=m -CONFIG_SCA3000=m -CONFIG_STK8312=m -CONFIG_STK8BA50=m +# CONFIG_BMA180 is not set +# CONFIG_BMA220 is not set +CONFIG_BMA400=m +CONFIG_BMA400_I2C=m +# CONFIG_BMC150_ACCEL is not set +# CONFIG_DA280 is not set +# CONFIG_DA311 is not set +# CONFIG_DMARD06 is not set +# CONFIG_DMARD09 is not set +# CONFIG_DMARD10 is not set +# CONFIG_HID_SENSOR_ACCEL_3D is not set +# CONFIG_IIO_ST_ACCEL_3AXIS is not set +# CONFIG_KXSD9 is not set +# CONFIG_KXCJK1013 is not set +# CONFIG_MC3230 is not set +# CONFIG_MMA7455_I2C is not set +# CONFIG_MMA7455_SPI is not set +# CONFIG_MMA7660 is not set +# CONFIG_MMA8452 is not set +# CONFIG_MMA9551 is not set +# CONFIG_MMA9553 is not set +# CONFIG_MXC4005 is not set +# CONFIG_MXC6255 is not set +# CONFIG_SCA3000 is not set +# CONFIG_STK8312 is not set +# CONFIG_STK8BA50 is not set # end of Accelerometers # # Analog to digital converters # CONFIG_AD_SIGMA_DELTA=m +CONFIG_AD7091R5=m CONFIG_AD7124=m -CONFIG_AD7266=m -CONFIG_AD7291=m -CONFIG_AD7298=m -CONFIG_AD7476=m +# CONFIG_AD7192 is not set +# CONFIG_AD7266 is not set +# CONFIG_AD7291 is not set +CONFIG_AD7292=m +# CONFIG_AD7298 is not set +# CONFIG_AD7476 is not set CONFIG_AD7606=m CONFIG_AD7606_IFACE_PARALLEL=m CONFIG_AD7606_IFACE_SPI=m @@ -6383,15 +6165,13 @@ CONFIG_AXP20X_ADC=m CONFIG_AXP288_ADC=m # CONFIG_CC10001_ADC is not set CONFIG_CPCAP_ADC=m -CONFIG_DA9150_GPADC=m -CONFIG_DLN2_ADC=m # CONFIG_ENVELOPE_DETECTOR is not set # CONFIG_HI8435 is not set # CONFIG_HX711 is not set # CONFIG_INA2XX_ADC is not set -CONFIG_LP8788_ADC=m # CONFIG_LTC2471 is not set # CONFIG_LTC2485 is not set +CONFIG_LTC2496=m CONFIG_LTC2497=m # CONFIG_MAX1027 is not set CONFIG_MAX11100=m @@ -6402,11 +6182,6 @@ CONFIG_MAX1118=m # CONFIG_MCP3422 is not set CONFIG_MCP3911=m # CONFIG_NAU7802 is not set -CONFIG_PALMAS_GPADC=m -CONFIG_QCOM_VADC_COMMON=m -CONFIG_QCOM_SPMI_IADC=m -CONFIG_QCOM_SPMI_VADC=m -CONFIG_QCOM_SPMI_ADC5=m # CONFIG_SD_ADC_MODULATOR is not set CONFIG_SUN4I_GPADC=m # CONFIG_TI_ADC081C is not set @@ -6421,12 +6196,8 @@ CONFIG_TI_ADS7950=m CONFIG_TI_ADS8344=m # CONFIG_TI_ADS8688 is not set CONFIG_TI_ADS124S08=m -CONFIG_TI_AM335X_ADC=m CONFIG_TI_TLC4541=m -CONFIG_TWL4030_MADC=m -CONFIG_TWL6030_GPADC=m # CONFIG_VF610_ADC is not set -CONFIG_VIPERBOARD_ADC=m # CONFIG_XILINX_XADC is not set # end of Analog to digital converters @@ -6440,6 +6211,7 @@ CONFIG_VIPERBOARD_ADC=m # Amplifiers # # CONFIG_AD8366 is not set +CONFIG_HMC425=m # end of Amplifiers # @@ -6470,10 +6242,6 @@ CONFIG_HID_SENSOR_IIO_TRIGGER=m # CONFIG_IIO_SSP_SENSORHUB is not set # end of SSP Sensor Common -CONFIG_IIO_ST_SENSORS_I2C=m -CONFIG_IIO_ST_SENSORS_SPI=m -CONFIG_IIO_ST_SENSORS_CORE=m - # # Digital to analog converters # @@ -6487,19 +6255,20 @@ CONFIG_IIO_ST_SENSORS_CORE=m # CONFIG_AD5593R is not set # CONFIG_AD5504 is not set # CONFIG_AD5624R_SPI is not set -CONFIG_LTC1660=m -CONFIG_LTC2632=m # CONFIG_AD5686_SPI is not set # CONFIG_AD5696_I2C is not set # CONFIG_AD5755 is not set CONFIG_AD5758=m # CONFIG_AD5761 is not set # CONFIG_AD5764 is not set +CONFIG_AD5770R=m # CONFIG_AD5791 is not set # CONFIG_AD7303 is not set # CONFIG_AD8801 is not set # CONFIG_DPOT_DAC is not set # CONFIG_DS4424 is not set +CONFIG_LTC1660=m +CONFIG_LTC2632=m # CONFIG_M62332 is not set # CONFIG_MAX517 is not set # CONFIG_MAX5821 is not set @@ -6531,7 +6300,7 @@ CONFIG_TI_DAC7612=m # Phase-Locked Loop (PLL) frequency synthesizers # # CONFIG_ADF4350 is not set -CONFIG_ADF4371=m +# CONFIG_ADF4371 is not set # end of Phase-Locked Loop (PLL) frequency synthesizers # end of Frequency Synthesizers DDS/PLL @@ -6588,6 +6357,9 @@ CONFIG_ADIS16460=m # CONFIG_ADIS16480 is not set # CONFIG_BMI160_I2C is not set # CONFIG_BMI160_SPI is not set +CONFIG_FXOS8700=m +CONFIG_FXOS8700_I2C=m +CONFIG_FXOS8700_SPI=m # CONFIG_KMX61 is not set # CONFIG_INV_MPU6050_I2C is not set # CONFIG_INV_MPU6050_SPI is not set @@ -6603,18 +6375,22 @@ CONFIG_IIO_ADIS_LIB_BUFFER=y # # Light sensors # -CONFIG_ADJD_S311=m -CONFIG_AL3320A=m -CONFIG_APDS9300=m -CONFIG_APDS9960=m -CONFIG_BH1750=m -CONFIG_BH1780=m -CONFIG_CM32181=m -CONFIG_CM3232=m -CONFIG_CM3323=m +# CONFIG_ADJD_S311 is not set +CONFIG_ADUX1020=m +CONFIG_AL3010=m +# CONFIG_AL3320A is not set +# CONFIG_APDS9300 is not set +# CONFIG_APDS9960 is not set +# CONFIG_BH1750 is not set +# CONFIG_BH1780 is not set +# CONFIG_CM32181 is not set +# CONFIG_CM3232 is not set +# CONFIG_CM3323 is not set CONFIG_CM3605=m # CONFIG_CM36651 is not set +CONFIG_GP2AP002=m # CONFIG_GP2AP020A00F is not set +CONFIG_IQS621_ALS=m # CONFIG_SENSORS_ISL29018 is not set # CONFIG_SENSORS_ISL29028 is not set # CONFIG_ISL29125 is not set @@ -6622,14 +6398,13 @@ CONFIG_CM3605=m # CONFIG_HID_SENSOR_PROX is not set # CONFIG_JSA1212 is not set # CONFIG_RPR0521 is not set -CONFIG_SENSORS_LM3533=m # CONFIG_LTR501 is not set # CONFIG_LV0104CS is not set # CONFIG_MAX44000 is not set CONFIG_MAX44009=m CONFIG_NOA1305=m -CONFIG_OPT3001=m -CONFIG_PA12203001=m +# CONFIG_OPT3001 is not set +# CONFIG_PA12203001 is not set CONFIG_SI1133=m # CONFIG_SI1145 is not set # CONFIG_STK3310 is not set @@ -6639,13 +6414,14 @@ CONFIG_SI1133=m # CONFIG_SENSORS_TSL2563 is not set # CONFIG_TSL2583 is not set CONFIG_TSL2772=m -CONFIG_TSL4531=m -CONFIG_US5182D=m -CONFIG_VCNL4000=m +# CONFIG_TSL4531 is not set +# CONFIG_US5182D is not set +# CONFIG_VCNL4000 is not set CONFIG_VCNL4035=m -CONFIG_VEML6070=m +CONFIG_VEML6030=m +# CONFIG_VEML6070 is not set CONFIG_VL6180=m -CONFIG_ZOPT2201=m +# CONFIG_ZOPT2201 is not set # end of Light sensors # @@ -6687,6 +6463,12 @@ CONFIG_IIO_INTERRUPT_TRIGGER=m CONFIG_IIO_SYSFS_TRIGGER=m # end of Triggers - standalone +# +# Linear and angular position sensors +# +CONFIG_IQS624_POS=m +# end of Linear and angular position sensors + # # Digital potentiometers # @@ -6715,9 +6497,11 @@ CONFIG_MCP41010=m CONFIG_BMP280=m CONFIG_BMP280_I2C=m CONFIG_BMP280_SPI=m -CONFIG_DPS310=m -CONFIG_HID_SENSOR_PRESS=m +CONFIG_DLHL60D=m +# CONFIG_DPS310 is not set +# CONFIG_HID_SENSOR_PRESS is not set # CONFIG_HP03 is not set +CONFIG_ICP10100=m # CONFIG_MPL115_I2C is not set # CONFIG_MPL115_SPI is not set # CONFIG_MPL3115 is not set @@ -6741,6 +6525,7 @@ CONFIG_HID_SENSOR_PRESS=m CONFIG_ISL29501=m # CONFIG_LIDAR_LITE_V2 is not set CONFIG_MB1232=m +CONFIG_PING=m # CONFIG_RFD77402 is not set # CONFIG_SRF04 is not set # CONFIG_SX9500 is not set @@ -6758,11 +6543,13 @@ CONFIG_VL53L0X_I2C=m # # Temperature sensors # -CONFIG_MAXIM_THERMOCOUPLE=m +CONFIG_IQS620AT_TEMP=m +CONFIG_LTC2983=m +# CONFIG_MAXIM_THERMOCOUPLE is not set CONFIG_HID_SENSOR_TEMP=m -CONFIG_MLX90614=m -CONFIG_MLX90632=m -CONFIG_TMP006=m +# CONFIG_MLX90614 is not set +# CONFIG_MLX90632 is not set +# CONFIG_TMP006 is not set CONFIG_TMP007=m # CONFIG_TSYS01 is not set # CONFIG_TSYS02D is not set @@ -6771,13 +6558,10 @@ CONFIG_MAX31856=m CONFIG_PWM=y CONFIG_PWM_SYSFS=y -CONFIG_PWM_ATMEL_HLCDC_PWM=m +# CONFIG_PWM_DEBUG is not set # CONFIG_PWM_FSL_FTM is not set -CONFIG_PWM_LP3943=m # CONFIG_PWM_PCA9685 is not set CONFIG_PWM_SUN4I=m -CONFIG_PWM_TWL=m -CONFIG_PWM_TWL_LED=m # # IRQ chip support @@ -6792,6 +6576,8 @@ CONFIG_MADERA_IRQ=m # CONFIG_IPACK_BUS is not set CONFIG_ARCH_HAS_RESET_CONTROLLER=y CONFIG_RESET_CONTROLLER=y +# CONFIG_RESET_BRCMSTB_RESCAL is not set +# CONFIG_RESET_INTEL_GW is not set CONFIG_RESET_SIMPLE=y CONFIG_RESET_SUNXI=y # CONFIG_RESET_TI_SYSCON is not set @@ -6802,11 +6588,11 @@ CONFIG_RESET_SUNXI=y CONFIG_GENERIC_PHY=y CONFIG_GENERIC_PHY_MIPI_DPHY=y CONFIG_PHY_SUN4I_USB=y -CONFIG_PHY_SUN6I_MIPI_DPHY=m +CONFIG_PHY_SUN6I_MIPI_DPHY=y CONFIG_PHY_SUN9I_USB=y CONFIG_PHY_SUN50I_USB3=m # CONFIG_BCM_KONA_USB2_PHY is not set -CONFIG_PHY_CADENCE_DP=m +CONFIG_PHY_CADENCE_TORRENT=m CONFIG_PHY_CADENCE_DPHY=m CONFIG_PHY_CADENCE_SIERRA=m CONFIG_PHY_FSL_IMX8MQ_USB=m @@ -6820,6 +6606,7 @@ CONFIG_PHY_QCOM_USB_HS=m # CONFIG_PHY_QCOM_USB_HSIC is not set CONFIG_PHY_SAMSUNG_USB2=m # CONFIG_PHY_TUSB1210 is not set +CONFIG_PHY_INTEL_EMMC=m # end of PHY Subsystem # CONFIG_POWERCAP is not set @@ -6847,7 +6634,6 @@ CONFIG_DAX=m CONFIG_NVMEM=y CONFIG_NVMEM_SYSFS=y CONFIG_NVMEM_SUNXI_SID=y -CONFIG_RAVE_SP_EEPROM=m # # HW tracing support @@ -6867,6 +6653,7 @@ CONFIG_FSI=m # CONFIG_FSI_NEW_DEV_NODE is not set # CONFIG_FSI_MASTER_GPIO is not set # CONFIG_FSI_MASTER_HUB is not set +CONFIG_FSI_MASTER_ASPEED=m # CONFIG_FSI_SCOM is not set # CONFIG_FSI_SBEFIFO is not set CONFIG_TEE=m @@ -6895,6 +6682,7 @@ CONFIG_PM_OPP=y CONFIG_INTERCONNECT=m CONFIG_COUNTER=m CONFIG_FTM_QUADDEC=m +CONFIG_MOST=m # end of Device Drivers # @@ -6903,14 +6691,10 @@ CONFIG_FTM_QUADDEC=m CONFIG_DCACHE_WORD_ACCESS=y CONFIG_VALIDATE_FS_PARSER=y CONFIG_FS_IOMAP=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_EXT2_FS is not set +# CONFIG_EXT3_FS is not set CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT2=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y # CONFIG_EXT4_DEBUG is not set @@ -6919,7 +6703,7 @@ CONFIG_JBD2=y CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set -CONFIG_REISERFS_PROC_INFO=y +# CONFIG_REISERFS_PROC_INFO is not set CONFIG_REISERFS_FS_XATTR=y CONFIG_REISERFS_FS_POSIX_ACL=y CONFIG_REISERFS_FS_SECURITY=y @@ -6959,12 +6743,17 @@ CONFIG_F2FS_FS_SECURITY=y # CONFIG_F2FS_CHECK_FS is not set # CONFIG_F2FS_IO_TRACE is not set # CONFIG_F2FS_FAULT_INJECTION is not set +CONFIG_F2FS_FS_COMPRESSION=y +CONFIG_F2FS_FS_LZO=y +CONFIG_F2FS_FS_LZ4=y +CONFIG_F2FS_FS_ZSTD=y CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y CONFIG_EXPORTFS_BLOCK_OPS=y CONFIG_FILE_LOCKING=y CONFIG_MANDATORY_FILE_LOCKING=y CONFIG_FS_ENCRYPTION=y +CONFIG_FS_ENCRYPTION_ALGS=y CONFIG_FS_VERITY=y # CONFIG_FS_VERITY_DEBUG is not set CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y @@ -6990,7 +6779,6 @@ CONFIG_OVERLAY_FS=m # CONFIG_OVERLAY_FS_REDIRECT_DIR is not set CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y # CONFIG_OVERLAY_FS_INDEX is not set -CONFIG_OVERLAY_FS_XINO_AUTO=y # CONFIG_OVERLAY_FS_METACOPY is not set # @@ -7016,18 +6804,20 @@ CONFIG_UDF_FS=m # end of CD-ROM/DVD Filesystems # -# DOS/FAT/NT Filesystems +# DOS/FAT/EXFAT/NT Filesystems # CONFIG_FAT_FS=y CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=y CONFIG_FAT_DEFAULT_CODEPAGE=437 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -CONFIG_FAT_DEFAULT_UTF8=y +# CONFIG_FAT_DEFAULT_UTF8 is not set +CONFIG_EXFAT_FS=m +CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" CONFIG_NTFS_FS=m # CONFIG_NTFS_DEBUG is not set CONFIG_NTFS_RW=y -# end of DOS/FAT/NT Filesystems +# end of DOS/FAT/EXFAT/NT Filesystems # # Pseudo filesystems @@ -7068,28 +6858,26 @@ CONFIG_JFFS2_FS_POSIX_ACL=y CONFIG_JFFS2_FS_SECURITY=y CONFIG_JFFS2_COMPRESSION_OPTIONS=y CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_LZO=y +# CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set # CONFIG_JFFS2_CMODE_NONE is not set -# CONFIG_JFFS2_CMODE_PRIORITY is not set +CONFIG_JFFS2_CMODE_PRIORITY=y # CONFIG_JFFS2_CMODE_SIZE is not set -CONFIG_JFFS2_CMODE_FAVOURLZO=y -CONFIG_UBIFS_FS=m -# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +# CONFIG_JFFS2_CMODE_FAVOURLZO is not set +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y CONFIG_UBIFS_FS_LZO=y CONFIG_UBIFS_FS_ZLIB=y CONFIG_UBIFS_FS_ZSTD=y -CONFIG_UBIFS_ATIME_SUPPORT=y +# CONFIG_UBIFS_ATIME_SUPPORT is not set CONFIG_UBIFS_FS_XATTR=y CONFIG_UBIFS_FS_SECURITY=y -CONFIG_UBIFS_FS_AUTHENTICATION=y -CONFIG_CRAMFS=m -CONFIG_CRAMFS_BLOCKDEV=y -# CONFIG_CRAMFS_MTD is not set -CONFIG_SQUASHFS=m -CONFIG_SQUASHFS_FILE_CACHE=y -# CONFIG_SQUASHFS_FILE_DIRECT is not set +# CONFIG_UBIFS_FS_AUTHENTICATION is not set +# CONFIG_CRAMFS is not set +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_FILE_CACHE is not set +CONFIG_SQUASHFS_FILE_DIRECT=y CONFIG_SQUASHFS_DECOMP_SINGLE=y # CONFIG_SQUASHFS_DECOMP_MULTI is not set # CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set @@ -7116,17 +6904,13 @@ CONFIG_ROMFS_BACKED_BY_BLOCK=y CONFIG_ROMFS_ON_BLOCK=y CONFIG_PSTORE=y CONFIG_PSTORE_DEFLATE_COMPRESS=y -CONFIG_PSTORE_LZO_COMPRESS=m -CONFIG_PSTORE_LZ4_COMPRESS=m -CONFIG_PSTORE_LZ4HC_COMPRESS=m -CONFIG_PSTORE_842_COMPRESS=y +# CONFIG_PSTORE_LZO_COMPRESS is not set +# CONFIG_PSTORE_LZ4_COMPRESS is not set +# CONFIG_PSTORE_LZ4HC_COMPRESS is not set +# CONFIG_PSTORE_842_COMPRESS is not set # CONFIG_PSTORE_ZSTD_COMPRESS is not set CONFIG_PSTORE_COMPRESS=y CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y -# CONFIG_PSTORE_LZO_COMPRESS_DEFAULT is not set -# CONFIG_PSTORE_LZ4_COMPRESS_DEFAULT is not set -# CONFIG_PSTORE_LZ4HC_COMPRESS_DEFAULT is not set -# CONFIG_PSTORE_842_COMPRESS_DEFAULT is not set CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" # CONFIG_PSTORE_CONSOLE is not set # CONFIG_PSTORE_PMSG is not set @@ -7134,7 +6918,7 @@ CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" CONFIG_PSTORE_RAM=m CONFIG_SYSV_FS=m CONFIG_UFS_FS=m -CONFIG_UFS_FS_WRITE=y +# CONFIG_UFS_FS_WRITE is not set # CONFIG_UFS_DEBUG is not set CONFIG_EROFS_FS=m # CONFIG_EROFS_FS_DEBUG is not set @@ -7149,11 +6933,11 @@ CONFIG_AUFS_BRANCH_MAX_127=y # CONFIG_AUFS_BRANCH_MAX_32767 is not set CONFIG_AUFS_SBILIST=y # CONFIG_AUFS_HNOTIFY is not set -CONFIG_AUFS_EXPORT=y -CONFIG_AUFS_XATTR=y +# CONFIG_AUFS_EXPORT is not set +# CONFIG_AUFS_XATTR is not set # CONFIG_AUFS_FHSM is not set # CONFIG_AUFS_RDU is not set -CONFIG_AUFS_DIRREN=y +# CONFIG_AUFS_DIRREN is not set # CONFIG_AUFS_SHWH is not set # CONFIG_AUFS_BR_RAMFS is not set # CONFIG_AUFS_BR_FUSE is not set @@ -7179,7 +6963,8 @@ CONFIG_NFS_FSCACHE=y # CONFIG_NFS_USE_LEGACY_DNS is not set CONFIG_NFS_USE_KERNEL_DNS=y CONFIG_NFS_DEBUG=y -CONFIG_NFSD=y +CONFIG_NFS_DISABLE_UDP_SUPPORT=y +CONFIG_NFSD=m CONFIG_NFSD_V2_ACL=y CONFIG_NFSD_V3=y CONFIG_NFSD_V3_ACL=y @@ -7189,13 +6974,13 @@ CONFIG_NFSD_BLOCKLAYOUT=y CONFIG_NFSD_SCSILAYOUT=y CONFIG_NFSD_FLEXFILELAYOUT=y CONFIG_NFSD_V4_SECURITY_LABEL=y -CONFIG_GRACE_PERIOD=y -CONFIG_LOCKD=y +CONFIG_GRACE_PERIOD=m +CONFIG_LOCKD=m CONFIG_LOCKD_V4=y -CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_ACL_SUPPORT=m CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m CONFIG_SUNRPC_BACKCHANNEL=y CONFIG_SUNRPC_SWAP=y CONFIG_RPCSEC_GSS_KRB5=m @@ -7206,7 +6991,7 @@ CONFIG_CEPH_FSCACHE=y CONFIG_CEPH_FS_POSIX_ACL=y CONFIG_CEPH_FS_SECURITY_LABEL=y CONFIG_CIFS=m -CONFIG_CIFS_STATS2=y +# CONFIG_CIFS_STATS2 is not set CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y CONFIG_CIFS_WEAK_PW_HASH=y CONFIG_CIFS_UPCALL=y @@ -7222,10 +7007,6 @@ CONFIG_AFS_FS=m # CONFIG_AFS_DEBUG is not set CONFIG_AFS_FSCACHE=y # CONFIG_AFS_DEBUG_CURSOR is not set -CONFIG_9P_FS=m -CONFIG_9P_FSCACHE=y -CONFIG_9P_FS_POSIX_ACL=y -CONFIG_9P_FS_SECURITY=y CONFIG_NLS=y CONFIG_NLS_DEFAULT="utf8" CONFIG_NLS_CODEPAGE_437=y @@ -7281,6 +7062,7 @@ CONFIG_DLM=m # CONFIG_DLM_DEBUG is not set CONFIG_UNICODE=y # CONFIG_UNICODE_NORMALIZATION_SELFTEST is not set +CONFIG_IO_WQ=y # end of File systems # @@ -7290,7 +7072,6 @@ CONFIG_KEYS=y CONFIG_KEYS_REQUEST_CACHE=y CONFIG_PERSISTENT_KEYRINGS=y CONFIG_BIG_KEYS=y -CONFIG_TRUSTED_KEYS=m CONFIG_ENCRYPTED_KEYS=y CONFIG_KEY_DH_OPERATIONS=y # CONFIG_SECURITY_DMESG_RESTRICT is not set @@ -7312,6 +7093,8 @@ CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_DEVELOP=y CONFIG_SECURITY_SELINUX_AVC_STATS=y CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SELINUX_SIDTAB_HASH_BITS=9 +CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE=256 CONFIG_SECURITY_SMACK=y # CONFIG_SECURITY_SMACK_BRINGUP is not set CONFIG_SECURITY_SMACK_NETFILTER=y @@ -7341,33 +7124,15 @@ CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y CONFIG_INTEGRITY_TRUSTED_KEYRING=y CONFIG_INTEGRITY_PLATFORM_KEYRING=y CONFIG_INTEGRITY_AUDIT=y -CONFIG_IMA=y -CONFIG_IMA_MEASURE_PCR_IDX=10 -CONFIG_IMA_LSM_RULES=y -# CONFIG_IMA_TEMPLATE is not set -CONFIG_IMA_NG_TEMPLATE=y -# CONFIG_IMA_SIG_TEMPLATE is not set -CONFIG_IMA_DEFAULT_TEMPLATE="ima-ng" -# CONFIG_IMA_DEFAULT_HASH_SHA1 is not set -CONFIG_IMA_DEFAULT_HASH_SHA256=y -# CONFIG_IMA_DEFAULT_HASH_SHA512 is not set -CONFIG_IMA_DEFAULT_HASH="sha256" -CONFIG_IMA_WRITE_POLICY=y -CONFIG_IMA_READ_POLICY=y -CONFIG_IMA_APPRAISE=y -# CONFIG_IMA_ARCH_POLICY is not set -# CONFIG_IMA_APPRAISE_BUILD_POLICY is not set -CONFIG_IMA_APPRAISE_BOOTPARAM=y -# CONFIG_IMA_APPRAISE_MODSIG is not set -# CONFIG_IMA_TRUSTED_KEYRING is not set -CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY=y +# CONFIG_IMA is not set +# CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY is not set # CONFIG_EVM is not set # CONFIG_DEFAULT_SECURITY_SELINUX is not set # CONFIG_DEFAULT_SECURITY_SMACK is not set # CONFIG_DEFAULT_SECURITY_TOMOYO is not set CONFIG_DEFAULT_SECURITY_APPARMOR=y # CONFIG_DEFAULT_SECURITY_DAC is not set -CONFIG_LSM="yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor" +CONFIG_LSM="lockdown,yama,integrity,apparmor" # # Kernel hardening options @@ -7398,8 +7163,8 @@ CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=y CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_SKCIPHER=y +CONFIG_CRYPTO_SKCIPHER2=y CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_HASH2=y CONFIG_CRYPTO_RNG=y @@ -7432,6 +7197,7 @@ CONFIG_CRYPTO_DH=y CONFIG_CRYPTO_ECC=m CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_ECRDSA=m +CONFIG_CRYPTO_CURVE25519=m # # Authenticated Encryption with Associated Data @@ -7474,11 +7240,13 @@ CONFIG_CRYPTO_VMAC=m # CONFIG_CRYPTO_CRC32C=y CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_XXHASH=m +CONFIG_CRYPTO_XXHASH=y +CONFIG_CRYPTO_BLAKE2B=y +CONFIG_CRYPTO_BLAKE2S=m CONFIG_CRYPTO_CRCT10DIF=y CONFIG_CRYPTO_GHASH=y CONFIG_CRYPTO_POLY1305=m -CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m @@ -7486,7 +7254,6 @@ CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_RMD256=m CONFIG_CRYPTO_RMD320=m CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_LIB_SHA256=y CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_SHA3=m @@ -7498,11 +7265,9 @@ CONFIG_CRYPTO_WP512=m # # Ciphers # -CONFIG_CRYPTO_LIB_AES=y CONFIG_CRYPTO_AES=y CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_LIB_ARC4=m CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_BLOWFISH_COMMON=m @@ -7510,12 +7275,11 @@ CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST_COMMON=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_LIB_DES=m -CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SALSA20=m -CONFIG_CRYPTO_CHACHA20=m +CONFIG_CRYPTO_CHACHA20=y CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_SM4=m @@ -7528,10 +7292,10 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m # CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_842=y +CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m CONFIG_CRYPTO_LZ4HC=m -CONFIG_CRYPTO_ZSTD=m +CONFIG_CRYPTO_ZSTD=y # # Random Number Generation @@ -7550,23 +7314,49 @@ CONFIG_CRYPTO_USER_API_RNG=m CONFIG_CRYPTO_USER_API_AEAD=m CONFIG_CRYPTO_STATS=y CONFIG_CRYPTO_HASH_INFO=y + +# +# Crypto library routines +# +CONFIG_CRYPTO_LIB_AES=y +CONFIG_CRYPTO_LIB_ARC4=m +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=m +CONFIG_CRYPTO_LIB_BLAKE2S=m +CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=m +CONFIG_CRYPTO_LIB_CHACHA_GENERIC=y +CONFIG_CRYPTO_LIB_CHACHA=m +CONFIG_CRYPTO_ARCH_HAVE_LIB_CURVE25519=m +CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m +CONFIG_CRYPTO_LIB_CURVE25519=m +CONFIG_CRYPTO_LIB_DES=y +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 +CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m +CONFIG_CRYPTO_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m +CONFIG_CRYPTO_LIB_SHA256=y CONFIG_CRYPTO_HW=y -# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set -# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set +CONFIG_CRYPTO_DEV_ALLWINNER=y CONFIG_CRYPTO_DEV_SUN4I_SS=m # CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG is not set +CONFIG_CRYPTO_DEV_SUN8I_CE=m +# CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG is not set +CONFIG_CRYPTO_DEV_SUN8I_SS=m +# CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG is not set +# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set +# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set CONFIG_CRYPTO_DEV_VIRTIO=m CONFIG_CRYPTO_DEV_SAFEXCEL=m CONFIG_CRYPTO_DEV_CCREE=m +CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m +# CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG is not set CONFIG_ASYMMETRIC_KEY_TYPE=y CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y -CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE=m CONFIG_X509_CERTIFICATE_PARSER=y CONFIG_PKCS8_PRIVATE_KEY_PARSER=m -CONFIG_TPM_KEY_PARSER=m CONFIG_PKCS7_MESSAGE_PARSER=y # CONFIG_PKCS7_TEST_KEY is not set -CONFIG_SIGNED_PE_FILE_VERIFICATION=y +# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set # # Certificates for signature checking @@ -7601,28 +7391,28 @@ CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y CONFIG_CRC_CCITT=y CONFIG_CRC16=y CONFIG_CRC_T10DIF=y -CONFIG_CRC_ITU_T=m +CONFIG_CRC_ITU_T=y CONFIG_CRC32=y # CONFIG_CRC32_SELFTEST is not set CONFIG_CRC32_SLICEBY8=y # CONFIG_CRC32_SLICEBY4 is not set # CONFIG_CRC32_SARWATE is not set # CONFIG_CRC32_BIT is not set -CONFIG_CRC64=m +CONFIG_CRC64=y CONFIG_CRC4=m -CONFIG_CRC7=m +CONFIG_CRC7=y CONFIG_LIBCRC32C=y CONFIG_CRC8=m CONFIG_XXHASH=y CONFIG_AUDIT_GENERIC=y # CONFIG_RANDOM32_SELFTEST is not set -CONFIG_842_COMPRESS=y -CONFIG_842_DECOMPRESS=y +CONFIG_842_COMPRESS=m +CONFIG_842_DECOMPRESS=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y CONFIG_LZO_COMPRESS=y CONFIG_LZO_DECOMPRESS=y -CONFIG_LZ4_COMPRESS=m +CONFIG_LZ4_COMPRESS=y CONFIG_LZ4HC_COMPRESS=m CONFIG_LZ4_DECOMPRESS=y CONFIG_ZSTD_COMPRESS=y @@ -7659,6 +7449,7 @@ CONFIG_NEED_DMA_MAP_STATE=y CONFIG_DMA_DECLARE_COHERENT=y CONFIG_ARCH_HAS_SETUP_DMA_OPS=y CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y +CONFIG_DMA_NONCOHERENT_MMAP=y CONFIG_DMA_REMAP=y CONFIG_DMA_CMA=y @@ -7685,6 +7476,9 @@ CONFIG_MPILIB=y CONFIG_SIGNATURE=y CONFIG_LIBFDT=y CONFIG_OID_REGISTRY=y +CONFIG_HAVE_GENERIC_VDSO=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_VDSO_32=y CONFIG_FONT_SUPPORT=y CONFIG_FONTS=y CONFIG_FONT_8x8=y @@ -7716,8 +7510,10 @@ CONFIG_PRINTK_TIME=y CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 CONFIG_CONSOLE_LOGLEVEL_QUIET=4 CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -CONFIG_BOOT_PRINTK_DELAY=y +# CONFIG_BOOT_PRINTK_DELAY is not set CONFIG_DYNAMIC_DEBUG=y +CONFIG_SYMBOLIC_ERRNAME=y +CONFIG_DEBUG_BUGVERBOSE=y # end of printk and dmesg options # @@ -7728,17 +7524,25 @@ CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 # CONFIG_STRIP_ASM_SYMS is not set # CONFIG_READABLE_ASM is not set -CONFIG_DEBUG_FS=y # CONFIG_HEADERS_INSTALL is not set -CONFIG_OPTIMIZE_INLINING=y # CONFIG_DEBUG_SECTION_MISMATCH is not set CONFIG_SECTION_MISMATCH_WARN_ONLY=y # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # end of Compile-time checks and compiler options +# +# Generic Kernel Debugging Instruments +# CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 CONFIG_MAGIC_SYSRQ_SERIAL=y +CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="" +CONFIG_DEBUG_FS=y +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_UBSAN is not set +# end of Generic Kernel Debugging Instruments + CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_MISC=y @@ -7757,6 +7561,7 @@ CONFIG_PAGE_EXTENSION=y CONFIG_HAVE_DEBUG_KMEMLEAK=y # CONFIG_DEBUG_KMEMLEAK is not set # CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_SCHED_STACK_END_CHECK is not set # CONFIG_DEBUG_VM is not set CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y # CONFIG_DEBUG_VIRTUAL is not set @@ -7767,26 +7572,28 @@ CONFIG_CC_HAS_KASAN_GENERIC=y CONFIG_KASAN_STACK=1 # end of Memory Debugging -CONFIG_ARCH_HAS_KCOV=y -CONFIG_CC_HAS_SANCOV_TRACE_PC=y -# CONFIG_KCOV is not set # CONFIG_DEBUG_SHIRQ is not set # -# Debug Lockups and Hangs +# Debug Oops, Lockups and Hangs # -# CONFIG_SOFTLOCKUP_DETECTOR is not set -# CONFIG_DETECT_HUNG_TASK is not set -# CONFIG_WQ_WATCHDOG is not set -# end of Debug Lockups and Hangs - # CONFIG_PANIC_ON_OOPS is not set CONFIG_PANIC_ON_OOPS_VALUE=0 CONFIG_PANIC_TIMEOUT=0 +# CONFIG_SOFTLOCKUP_DETECTOR is not set +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_WQ_WATCHDOG is not set +CONFIG_TEST_LOCKUP=m +# end of Debug Oops, Lockups and Hangs + +# +# Scheduler Debugging +# CONFIG_SCHED_DEBUG=y CONFIG_SCHED_INFO=y # CONFIG_SCHEDSTATS is not set -# CONFIG_SCHED_STACK_END_CHECK is not set +# end of Scheduler Debugging + # CONFIG_DEBUG_TIMEKEEPING is not set # @@ -7810,11 +7617,17 @@ CONFIG_WW_MUTEX_SELFTEST=m CONFIG_STACKTRACE=y # CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set # CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y + +# +# Debug kernel data structures +# # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_PLIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_BUG_ON_DATA_CORRUPTION is not set +# end of Debug kernel data structures + # CONFIG_DEBUG_CREDENTIALS is not set # @@ -7830,8 +7643,6 @@ CONFIG_RCU_CPU_STALL_TIMEOUT=21 # CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set -# CONFIG_NOTIFIER_ERROR_INJECTION is not set -# CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y @@ -7848,7 +7659,12 @@ CONFIG_TRACING=y CONFIG_GENERIC_TRACER=y CONFIG_TRACING_SUPPORT=y CONFIG_FTRACE=y +# CONFIG_BOOTTIME_TRACING is not set CONFIG_FUNCTION_TRACER=y +CONFIG_DYNAMIC_FTRACE=y +CONFIG_DYNAMIC_FTRACE_WITH_REGS=y +# CONFIG_FUNCTION_PROFILER is not set +# CONFIG_STACK_TRACER is not set # CONFIG_PREEMPTIRQ_EVENTS is not set # CONFIG_IRQSOFF_TRACER is not set # CONFIG_SCHED_TRACER is not set @@ -7857,22 +7673,65 @@ CONFIG_FUNCTION_TRACER=y # CONFIG_TRACER_SNAPSHOT is not set CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_STACK_TRACER is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_UPROBE_EVENTS is not set -CONFIG_DYNAMIC_FTRACE=y -CONFIG_DYNAMIC_FTRACE_WITH_REGS=y -# CONFIG_FUNCTION_PROFILER is not set CONFIG_FTRACE_MCOUNT_RECORD=y -# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_TRACE_EVENT_INJECT is not set # CONFIG_TRACEPOINT_BENCHMARK is not set # CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_TRACE_EVAL_MAP_FILE is not set +# CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_RING_BUFFER_STARTUP_TEST is not set # CONFIG_PREEMPTIRQ_DELAY_TEST is not set -# CONFIG_TRACE_EVAL_MAP_FILE is not set +# CONFIG_SAMPLES is not set +CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y +# CONFIG_STRICT_DEVMEM is not set + +# +# arm Debugging +# +# CONFIG_ARM_PTDUMP_DEBUGFS is not set +# CONFIG_DEBUG_WX is not set +CONFIG_UNWINDER_ARM=y +CONFIG_ARM_UNWIND=y +# CONFIG_DEBUG_USER is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_SUN9I_UART0 is not set +CONFIG_DEBUG_SUNXI_UART0=y +# CONFIG_DEBUG_SUNXI_UART1 is not set +# CONFIG_DEBUG_SUNXI_R_UART is not set +# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_DEBUG_SEMIHOSTING is not set +# CONFIG_DEBUG_LL_UART_8250 is not set +# CONFIG_DEBUG_LL_UART_PL01X is not set +CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" +CONFIG_DEBUG_UART_8250=y +CONFIG_DEBUG_UART_PHYS=0x01c28000 +CONFIG_DEBUG_UART_VIRT=0xf1c28000 +CONFIG_DEBUG_UART_8250_SHIFT=2 +# CONFIG_DEBUG_UART_8250_WORD is not set +# CONFIG_DEBUG_UART_8250_PALMCHIP is not set +# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set +CONFIG_DEBUG_UNCOMPRESS=y +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +# CONFIG_EARLY_PRINTK is not set +# CONFIG_PID_IN_CONTEXTIDR is not set +# CONFIG_CORESIGHT is not set +# end of arm Debugging + +# +# Kernel Testing and Coverage +# +# CONFIG_KUNIT is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +CONFIG_ARCH_HAS_KCOV=y +CONFIG_CC_HAS_SANCOV_TRACE_PC=y +# CONFIG_KCOV is not set CONFIG_RUNTIME_TESTING_MENU=y # CONFIG_LKDTM is not set # CONFIG_TEST_LIST_SORT is not set +CONFIG_TEST_MIN_HEAP=m # CONFIG_TEST_SORT is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_RBTREE_TEST is not set @@ -7909,39 +7768,5 @@ CONFIG_TEST_MEMCAT_P=m # CONFIG_TEST_STACKINIT is not set # CONFIG_TEST_MEMINIT is not set # CONFIG_MEMTEST is not set -# CONFIG_BUG_ON_DATA_CORRUPTION is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -# CONFIG_UBSAN is not set -CONFIG_UBSAN_ALIGNMENT=y -CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y -# CONFIG_STRICT_DEVMEM is not set -# CONFIG_ARM_PTDUMP_DEBUGFS is not set -# CONFIG_DEBUG_WX is not set -CONFIG_UNWINDER_ARM=y -CONFIG_ARM_UNWIND=y -# CONFIG_DEBUG_USER is not set -CONFIG_DEBUG_LL=y -# CONFIG_DEBUG_SUN9I_UART0 is not set -CONFIG_DEBUG_SUNXI_UART0=y -# CONFIG_DEBUG_SUNXI_UART1 is not set -# CONFIG_DEBUG_SUNXI_R_UART is not set -# CONFIG_DEBUG_ICEDCC is not set -# CONFIG_DEBUG_SEMIHOSTING is not set -# CONFIG_DEBUG_LL_UART_8250 is not set -# CONFIG_DEBUG_LL_UART_PL01X is not set -CONFIG_DEBUG_LL_INCLUDE="debug/8250.S" -CONFIG_DEBUG_UART_8250=y -CONFIG_DEBUG_UART_PHYS=0x01c28000 -CONFIG_DEBUG_UART_VIRT=0xf1c28000 -CONFIG_DEBUG_UART_8250_SHIFT=2 -# CONFIG_DEBUG_UART_8250_WORD is not set -# CONFIG_DEBUG_UART_8250_PALMCHIP is not set -# CONFIG_DEBUG_UART_8250_FLOW_CONTROL is not set -CONFIG_DEBUG_UNCOMPRESS=y -CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -# CONFIG_EARLY_PRINTK is not set -# CONFIG_PID_IN_CONTEXTIDR is not set -# CONFIG_CORESIGHT is not set +# end of Kernel Testing and Coverage # end of Kernel hacking diff --git a/config/kernel/linux-sunxi-legacy.config b/config/kernel/linux-sunxi-legacy.config index 868a07d08..6c70a775e 100644 --- a/config/kernel/linux-sunxi-legacy.config +++ b/config/kernel/linux-sunxi-legacy.config @@ -1,15 +1,17 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 4.19.120 Kernel Configuration +# Linux/arm 5.4.51 Kernel Configuration # # -# Compiler: arm-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36)) 8.3.0 +# Compiler: arm-none-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10)) 9.2.1 20191025 # CONFIG_CC_IS_GCC=y -CONFIG_GCC_VERSION=80300 +CONFIG_GCC_VERSION=90201 CONFIG_CLANG_VERSION=0 +CONFIG_CC_CAN_LINK=y CONFIG_CC_HAS_ASM_GOTO=y +CONFIG_CC_HAS_ASM_INLINE=y CONFIG_IRQ_WORK=y CONFIG_BUILDTIME_EXTABLE_SORT=y @@ -42,8 +44,6 @@ CONFIG_USELIB=y CONFIG_AUDIT=y CONFIG_HAVE_ARCH_AUDITSYSCALL=y CONFIG_AUDITSYSCALL=y -CONFIG_AUDIT_WATCH=y -CONFIG_AUDIT_TREE=y # # IRQ subsystem @@ -61,6 +61,8 @@ CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_IRQ_FORCED_THREADING=y CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_IRQ_DEBUGFS is not set +# end of IRQ subsystem + CONFIG_GENERIC_IRQ_MULTI_HANDLER=y CONFIG_ARCH_CLOCKSOURCE_DATA=y CONFIG_GENERIC_TIME_VSYSCALL=y @@ -78,6 +80,8 @@ CONFIG_NO_HZ_IDLE=y # CONFIG_NO_HZ_FULL is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y +# end of Timers subsystem + CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -94,6 +98,9 @@ CONFIG_TASKSTATS=y CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y +# CONFIG_PSI is not set +# end of CPU/Task time and stats accounting + CONFIG_CPU_ISOLATION=y # @@ -105,13 +112,23 @@ CONFIG_SRCU=y CONFIG_TREE_SRCU=y CONFIG_RCU_STALL_COMMON=y CONFIG_RCU_NEED_SEGCBLIST=y +# end of RCU Subsystem + CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +CONFIG_IKHEADERS=m CONFIG_LOG_BUF_SHIFT=17 CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 CONFIG_GENERIC_SCHED_CLOCK=y + +# +# Scheduler features +# +# CONFIG_UCLAMP_TASK is not set +# end of Scheduler features + CONFIG_CGROUPS=y CONFIG_PAGE_COUNTER=y CONFIG_MEMCG=y @@ -119,7 +136,6 @@ CONFIG_MEMCG_SWAP=y CONFIG_MEMCG_SWAP_ENABLED=y CONFIG_MEMCG_KMEM=y CONFIG_BLK_CGROUP=y -# CONFIG_DEBUG_BLK_CGROUP is not set CONFIG_CGROUP_WRITEBACK=y CONFIG_CGROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y @@ -157,7 +173,6 @@ CONFIG_RD_LZ4=y CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y CONFIG_HAVE_UID16=y CONFIG_BPF=y CONFIG_EXPERT=y @@ -181,12 +196,14 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_IO_URING=y CONFIG_ADVISE_SYSCALLS=y CONFIG_MEMBARRIER=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set CONFIG_KALLSYMS_BASE_RELATIVE=y CONFIG_BPF_SYSCALL=y +# CONFIG_BPF_JIT_ALWAYS_ON is not set # CONFIG_USERFAULTFD is not set CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y CONFIG_RSEQ=y @@ -201,6 +218,8 @@ CONFIG_PERF_USE_VMALLOC=y # CONFIG_PERF_EVENTS=y # CONFIG_DEBUG_PERF_USE_VMALLOC is not set +# end of Kernel Performance Events And Counters + CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLUB_DEBUG=y # CONFIG_SLUB_MEMCG_SYSFS_ON is not set @@ -211,21 +230,22 @@ CONFIG_SLUB=y CONFIG_SLAB_MERGE_DEFAULT=y CONFIG_SLAB_FREELIST_RANDOM=y CONFIG_SLAB_FREELIST_HARDENED=y +# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set CONFIG_SLUB_CPU_PARTIAL=y CONFIG_SYSTEM_DATA_VERIFICATION=y # CONFIG_PROFILING is not set CONFIG_TRACEPOINTS=y +# end of General setup + CONFIG_ARM=y CONFIG_ARM_HAS_SG_CHAIN=y CONFIG_ARM_DMA_USE_IOMMU=y CONFIG_ARM_DMA_IOMMU_ALIGNMENT=8 -CONFIG_MIGHT_HAVE_PCI=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y CONFIG_HAVE_PROC_CPU=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_FIX_EARLYCON_MEM=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y @@ -244,20 +264,13 @@ CONFIG_ARCH_MULTIPLATFORM=y # CONFIG_ARCH_EBSA110 is not set # CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_IOP13XX is not set # CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IOP33X is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_DOVE is not set -# CONFIG_ARCH_KS8695 is not set -# CONFIG_ARCH_W90X900 is not set -# CONFIG_ARCH_LPC32XX is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set # CONFIG_ARCH_S3C24XX is not set -# CONFIG_ARCH_DAVINCI is not set # CONFIG_ARCH_OMAP1 is not set # @@ -270,10 +283,13 @@ CONFIG_ARCH_MULTIPLATFORM=y # CONFIG_ARCH_MULTI_V6 is not set CONFIG_ARCH_MULTI_V7=y CONFIG_ARCH_MULTI_V6_V7=y +# end of Multiple platform selection + # CONFIG_ARCH_VIRT is not set # CONFIG_ARCH_ACTIONS is not set # CONFIG_ARCH_ALPINE is not set # CONFIG_ARCH_ARTPEC is not set +# CONFIG_ARCH_ASPEED is not set # CONFIG_ARCH_AT91 is not set # CONFIG_ARCH_BCM is not set # CONFIG_ARCH_BERLIN is not set @@ -285,6 +301,7 @@ CONFIG_ARCH_MULTI_V6_V7=y # CONFIG_ARCH_KEYSTONE is not set # CONFIG_ARCH_MEDIATEK is not set # CONFIG_ARCH_MESON is not set +# CONFIG_ARCH_MILBEAUT is not set # CONFIG_ARCH_MMP is not set # CONFIG_ARCH_MVEBU is not set # CONFIG_ARCH_NPCM is not set @@ -298,8 +315,11 @@ CONFIG_ARCH_MULTI_V6_V7=y # CONFIG_SOC_AM33XX is not set # CONFIG_SOC_AM43XX is not set # CONFIG_SOC_DRA7XX is not set +# end of TI OMAP/AM/DM/DRA Family + # CONFIG_ARCH_SIRF is not set # CONFIG_ARCH_QCOM is not set +# CONFIG_ARCH_RDA is not set # CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_ROCKCHIP is not set # CONFIG_ARCH_S5PV210 is not set @@ -352,6 +372,7 @@ CONFIG_ARM_VIRT_EXT=y CONFIG_SWP_EMULATE=y # CONFIG_CPU_BIG_ENDIAN is not set # CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND is not set # CONFIG_CPU_BPREDICT_DISABLE is not set CONFIG_CPU_SPECTRE=y CONFIG_HARDEN_BRANCH_PREDICTOR=y @@ -384,19 +405,17 @@ CONFIG_ARM_ERRATA_643719=y # CONFIG_ARM_ERRATA_818325_852422 is not set # CONFIG_ARM_ERRATA_821420 is not set # CONFIG_ARM_ERRATA_825619 is not set +# CONFIG_ARM_ERRATA_857271 is not set # CONFIG_ARM_ERRATA_852421 is not set # CONFIG_ARM_ERRATA_852423 is not set +# CONFIG_ARM_ERRATA_857272 is not set +# end of System Type # # Bus support # -# CONFIG_PCI is not set - -# -# PCI Endpoint -# -# CONFIG_PCI_ENDPOINT is not set -# CONFIG_PCCARD is not set +# CONFIG_ARM_ERRATA_814220 is not set +# end of Bus support # # Kernel Features @@ -446,6 +465,7 @@ CONFIG_SECCOMP=y # CONFIG_PARAVIRT is not set # CONFIG_PARAVIRT_TIME_ACCOUNTING is not set # CONFIG_XEN is not set +# end of Kernel Features # # Boot options @@ -461,6 +481,7 @@ CONFIG_CMDLINE="" # CONFIG_CRASH_DUMP is not set CONFIG_AUTO_ZRELADDR=y # CONFIG_EFI is not set +# end of Boot options # # CPU Power Management @@ -491,9 +512,10 @@ CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y # CONFIG_CPUFREQ_DT=m CONFIG_CPUFREQ_DT_PLATDEV=y +CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=m CONFIG_ARM_BIG_LITTLE_CPUFREQ=m -CONFIG_ARM_DT_BL_CPUFREQ=m # CONFIG_QORIQ_CPUFREQ is not set +# end of CPU Frequency scaling # # CPU Idle @@ -502,13 +524,18 @@ CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y CONFIG_CPU_IDLE_GOV_LADDER=y CONFIG_CPU_IDLE_GOV_MENU=y +# CONFIG_CPU_IDLE_GOV_TEO is not set CONFIG_DT_IDLE_STATES=y # # ARM CPU Idle Drivers # CONFIG_ARM_CPUIDLE=y +CONFIG_ARM_PSCI_CPUIDLE=y # CONFIG_ARM_HIGHBANK_CPUIDLE is not set +# end of ARM CPU Idle Drivers +# end of CPU Idle +# end of CPU Power Management # # Floating point emulation @@ -521,6 +548,7 @@ CONFIG_VFP=y CONFIG_VFPv3=y CONFIG_NEON=y CONFIG_KERNEL_MODE_NEON=y +# end of Floating point emulation # # Power management options @@ -539,24 +567,30 @@ CONFIG_PM=y CONFIG_PM_CLK=y # CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set CONFIG_CPU_PM=y +# CONFIG_ENERGY_MODEL is not set CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARM_CPU_SUSPEND=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y +# end of Power management options # # Firmware Drivers # -CONFIG_ARM_PSCI_FW=y -# CONFIG_ARM_PSCI_CHECKER is not set # CONFIG_FIRMWARE_MEMMAP is not set CONFIG_FW_CFG_SYSFS=m # CONFIG_FW_CFG_SYSFS_CMDLINE is not set +# CONFIG_TRUSTED_FOUNDATIONS is not set CONFIG_HAVE_ARM_SMCCC=y +CONFIG_ARM_PSCI_FW=y +# CONFIG_ARM_PSCI_CHECKER is not set # CONFIG_GOOGLE_FIRMWARE is not set # # Tegra firmware driver # +# end of Tegra firmware driver +# end of Firmware Drivers + CONFIG_ARM_CRYPTO=y CONFIG_CRYPTO_SHA1_ARM=m CONFIG_CRYPTO_SHA1_ARM_NEON=m @@ -568,12 +602,15 @@ CONFIG_CRYPTO_AES_ARM=m CONFIG_CRYPTO_AES_ARM_BS=m CONFIG_CRYPTO_AES_ARM_CE=m CONFIG_CRYPTO_GHASH_ARM_CE=m -# CONFIG_CRYPTO_CRCT10DIF_ARM_CE is not set -# CONFIG_CRYPTO_CRC32_ARM_CE is not set -# CONFIG_CRYPTO_CHACHA20_NEON is not set +CONFIG_CRYPTO_CRCT10DIF_ARM_CE=m +CONFIG_CRYPTO_CRC32_ARM_CE=m +CONFIG_CRYPTO_CHACHA20_NEON=m +CONFIG_CRYPTO_NHPOLY1305_NEON=m CONFIG_VIRTUALIZATION=y -# CONFIG_VHOST_NET is not set -# CONFIG_VHOST_SCSI is not set +CONFIG_VHOST_NET=m +CONFIG_VHOST_SCSI=m +CONFIG_VHOST_VSOCK=m +CONFIG_VHOST=m # CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set # @@ -593,8 +630,10 @@ CONFIG_HAVE_DMA_CONTIGUOUS=y CONFIG_GENERIC_SMP_IDLE_THREAD=y CONFIG_GENERIC_IDLE_POLL_SETUP=y CONFIG_ARCH_HAS_FORTIFY_SOURCE=y +CONFIG_ARCH_HAS_KEEPINITRD=y CONFIG_ARCH_HAS_SET_MEMORY=y CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y +CONFIG_ARCH_32BIT_OFF_T=y CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y CONFIG_HAVE_RSEQ=y CONFIG_HAVE_CLK=y @@ -607,8 +646,7 @@ CONFIG_HAVE_ARCH_SECCOMP_FILTER=y CONFIG_SECCOMP_FILTER=y CONFIG_HAVE_STACKPROTECTOR=y CONFIG_CC_HAS_STACKPROTECTOR_NONE=y -CONFIG_STACKPROTECTOR=y -CONFIG_STACKPROTECTOR_STRONG=y +# CONFIG_STACKPROTECTOR is not set CONFIG_HAVE_CONTEXT_TRACKING=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y @@ -618,9 +656,13 @@ CONFIG_ARCH_HAS_ELF_RANDOMIZE=y CONFIG_HAVE_ARCH_MMAP_RND_BITS=y CONFIG_HAVE_EXIT_THREAD=y CONFIG_ARCH_MMAP_RND_BITS=8 +CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y +CONFIG_HAVE_COPY_THREAD_TLS=y CONFIG_CLONE_BACKWARDS=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_OLD_SIGACTION=y +CONFIG_64BIT_TIME=y +CONFIG_COMPAT_32BIT_TIME=y CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y @@ -629,42 +671,57 @@ CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y CONFIG_STRICT_MODULE_RWX=y CONFIG_ARCH_HAS_PHYS_TO_DMA=y CONFIG_REFCOUNT_FULL=y +# CONFIG_LOCK_EVENT_COUNTS is not set # # GCOV-based kernel profiling # # CONFIG_GCOV_KERNEL is not set CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +# end of GCOV-based kernel profiling + CONFIG_PLUGIN_HOSTCC="" CONFIG_HAVE_GCC_PLUGINS=y +# end of General architecture-dependent options + CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 +CONFIG_MODULE_SIG_FORMAT=y CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_MODULE_SIG is not set +CONFIG_MODULE_SIG=y +# CONFIG_MODULE_SIG_FORCE is not set +CONFIG_MODULE_SIG_ALL=y +CONFIG_MODULE_SIG_SHA1=y +# CONFIG_MODULE_SIG_SHA224 is not set +# CONFIG_MODULE_SIG_SHA256 is not set +# CONFIG_MODULE_SIG_SHA384 is not set +# CONFIG_MODULE_SIG_SHA512 is not set +CONFIG_MODULE_SIG_HASH="sha1" # CONFIG_MODULE_COMPRESS is not set -# CONFIG_TRIM_UNUSED_KSYMS is not set +# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set +CONFIG_UNUSED_SYMBOLS=y CONFIG_MODULES_TREE_LOOKUP=y CONFIG_BLOCK=y -CONFIG_LBDAF=y CONFIG_BLK_SCSI_REQUEST=y CONFIG_BLK_DEV_BSG=y CONFIG_BLK_DEV_BSGLIB=y CONFIG_BLK_DEV_INTEGRITY=y -# CONFIG_BLK_DEV_ZONED is not set +CONFIG_BLK_DEV_ZONED=y CONFIG_BLK_DEV_THROTTLING=y # CONFIG_BLK_DEV_THROTTLING_LOW is not set # CONFIG_BLK_CMDLINE_PARSER is not set CONFIG_BLK_WBT=y -# CONFIG_BLK_CGROUP_IOLATENCY is not set -CONFIG_BLK_WBT_SQ=y +CONFIG_BLK_CGROUP_IOLATENCY=y +# CONFIG_BLK_CGROUP_IOCOST is not set CONFIG_BLK_WBT_MQ=y -# CONFIG_BLK_DEBUG_FS is not set -# CONFIG_BLK_SED_OPAL is not set +CONFIG_BLK_DEBUG_FS=y +CONFIG_BLK_DEBUG_FS_ZONED=y +CONFIG_BLK_SED_OPAL=y # # Partition Types @@ -672,22 +729,21 @@ CONFIG_BLK_WBT_MQ=y # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y CONFIG_EFI_PARTITION=y +# end of Partition Types + +CONFIG_BLK_MQ_VIRTIO=y +CONFIG_BLK_PM=y # # IO Schedulers # -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_CFQ_GROUP_IOSCHED=y -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" CONFIG_MQ_IOSCHED_DEADLINE=y CONFIG_MQ_IOSCHED_KYBER=y CONFIG_IOSCHED_BFQ=y CONFIG_BFQ_GROUP_IOSCHED=y +# CONFIG_BFQ_CGROUP_DEBUG is not set +# end of IO Schedulers + CONFIG_PADATA=y CONFIG_ASN1=y CONFIG_INLINE_SPIN_UNLOCK_IRQ=y @@ -709,23 +765,29 @@ CONFIG_BINFMT_ELF=y CONFIG_ELFCORE=y CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y CONFIG_BINFMT_SCRIPT=y +CONFIG_ARCH_HAS_BINFMT_FLAT=y CONFIG_BINFMT_FLAT=y +CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y +# CONFIG_BINFMT_FLAT_OLD is not set CONFIG_BINFMT_ZFLAT=y CONFIG_BINFMT_SHARED_FLAT=y CONFIG_BINFMT_MISC=m CONFIG_COREDUMP=y +# end of Executable file formats # # Memory Management options # CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_NO_BOOTMEM=y +CONFIG_ARCH_KEEP_MEMBLOCK=y CONFIG_MEMORY_ISOLATION=y CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_MEMORY_BALLOON=y +CONFIG_BALLOON_COMPACTION=y CONFIG_COMPACTION=y CONFIG_MIGRATION=y +CONFIG_CONTIG_ALLOC=y CONFIG_BOUNCE=y CONFIG_KSM=y CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 @@ -738,8 +800,8 @@ CONFIG_CMA_AREAS=7 CONFIG_ZSWAP=y CONFIG_ZPOOL=y CONFIG_ZBUD=y -CONFIG_Z3FOLD=y -CONFIG_ZSMALLOC=y +CONFIG_Z3FOLD=m +CONFIG_ZSMALLOC=m # CONFIG_PGTABLE_MAPPING is not set # CONFIG_ZSMALLOC_STAT is not set CONFIG_GENERIC_EARLY_IOREMAP=y @@ -747,9 +809,13 @@ CONFIG_IDLE_PAGE_TRACKING=y CONFIG_FRAME_VECTOR=y # CONFIG_PERCPU_STATS is not set # CONFIG_GUP_BENCHMARK is not set +# end of Memory Management options + CONFIG_NET=y CONFIG_NET_INGRESS=y CONFIG_NET_EGRESS=y +CONFIG_NET_REDIRECT=y +CONFIG_SKB_EXTENSIONS=y # # Networking options @@ -757,20 +823,23 @@ CONFIG_NET_EGRESS=y CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y +CONFIG_UNIX_SCM=y CONFIG_UNIX_DIAG=m -# CONFIG_TLS is not set +CONFIG_TLS=m +# CONFIG_TLS_DEVICE is not set CONFIG_XFRM=y CONFIG_XFRM_OFFLOAD=y CONFIG_XFRM_ALGO=y CONFIG_XFRM_USER=y CONFIG_XFRM_INTERFACE=m -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_SUB_POLICY=y +CONFIG_XFRM_MIGRATE=y +CONFIG_XFRM_STATISTICS=y CONFIG_XFRM_IPCOMP=m -CONFIG_NET_KEY=y -# CONFIG_NET_KEY_MIGRATE is not set -# CONFIG_XDP_SOCKETS is not set +CONFIG_NET_KEY=m +CONFIG_NET_KEY_MIGRATE=y +CONFIG_XDP_SOCKETS=y +CONFIG_XDP_SOCKETS_DIAG=m CONFIG_INET=y CONFIG_WIREGUARD=m # CONFIG_WIREGUARD_DEBUG is not set @@ -796,48 +865,39 @@ CONFIG_IP_MROUTE_MULTIPLE_TABLES=y CONFIG_IP_PIMSM_V1=y CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y -# CONFIG_NET_IPVTI is not set +CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -# CONFIG_NET_FOU is not set -# CONFIG_NET_FOU_IP_TUNNELS is not set +CONFIG_NET_FOU=m +CONFIG_NET_FOU_IP_TUNNELS=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_TUNNEL=m CONFIG_INET_TUNNEL=m -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=m CONFIG_INET_DIAG=m CONFIG_INET_TCP_DIAG=m CONFIG_INET_UDP_DIAG=m -# CONFIG_INET_RAW_DIAG is not set -# CONFIG_INET_DIAG_DESTROY is not set +CONFIG_INET_RAW_DIAG=m +CONFIG_INET_DIAG_DESTROY=y CONFIG_TCP_CONG_ADVANCED=y -CONFIG_TCP_CONG_BIC=y +CONFIG_TCP_CONG_BIC=m CONFIG_TCP_CONG_CUBIC=y -CONFIG_TCP_CONG_WESTWOOD=y -CONFIG_TCP_CONG_HTCP=y -CONFIG_TCP_CONG_HSTCP=y -CONFIG_TCP_CONG_HYBLA=y -CONFIG_TCP_CONG_VEGAS=y -CONFIG_TCP_CONG_NV=y -CONFIG_TCP_CONG_SCALABLE=y -CONFIG_TCP_CONG_LP=y -CONFIG_TCP_CONG_VENO=y -CONFIG_TCP_CONG_YEAH=y -CONFIG_TCP_CONG_ILLINOIS=y -# CONFIG_TCP_CONG_DCTCP is not set -# CONFIG_TCP_CONG_CDG is not set +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_NV=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_DCTCP=m +CONFIG_TCP_CONG_CDG=m CONFIG_TCP_CONG_BBR=m -# CONFIG_DEFAULT_BIC is not set CONFIG_DEFAULT_CUBIC=y -# CONFIG_DEFAULT_HTCP is not set -# CONFIG_DEFAULT_HYBLA is not set -# CONFIG_DEFAULT_VEGAS is not set -# CONFIG_DEFAULT_VENO is not set -# CONFIG_DEFAULT_WESTWOOD is not set # CONFIG_DEFAULT_RENO is not set CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_TCP_MD5SIG=y @@ -853,16 +913,14 @@ CONFIG_IPV6_MIP6=m CONFIG_IPV6_ILA=m CONFIG_INET6_XFRM_TUNNEL=m CONFIG_INET6_TUNNEL=m -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -# CONFIG_IPV6_VTI is not set +CONFIG_IPV6_VTI=m CONFIG_IPV6_SIT=m CONFIG_IPV6_SIT_6RD=y CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m +CONFIG_IPV6_FOU=m +CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y @@ -871,7 +929,7 @@ CONFIG_IPV6_PIMSM_V2=y CONFIG_IPV6_SEG6_LWTUNNEL=y CONFIG_IPV6_SEG6_HMAC=y CONFIG_IPV6_SEG6_BPF=y -# CONFIG_NETLABEL is not set +CONFIG_NETLABEL=y CONFIG_NETWORK_SECMARK=y CONFIG_NET_PTP_CLASSIFY=y CONFIG_NETWORK_PHY_TIMESTAMPING=y @@ -897,13 +955,13 @@ CONFIG_NETFILTER_CONNCOUNT=m CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_ZONES=y -# CONFIG_NF_CONNTRACK_PROCFS is not set +CONFIG_NF_CONNTRACK_PROCFS=y CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CONNTRACK_TIMEOUT=y CONFIG_NF_CONNTRACK_TIMESTAMP=y CONFIG_NF_CONNTRACK_LABELS=y CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_GRE=y CONFIG_NF_CT_PROTO_SCTP=y CONFIG_NF_CT_PROTO_UDPLITE=y CONFIG_NF_CONNTRACK_AMANDA=m @@ -922,16 +980,13 @@ CONFIG_NF_CT_NETLINK_TIMEOUT=m CONFIG_NF_CT_NETLINK_HELPER=m CONFIG_NETFILTER_NETLINK_GLUE_CT=y CONFIG_NF_NAT=m -CONFIG_NF_NAT_NEEDED=y -CONFIG_NF_NAT_PROTO_DCCP=y -CONFIG_NF_NAT_PROTO_UDPLITE=y -CONFIG_NF_NAT_PROTO_SCTP=y CONFIG_NF_NAT_AMANDA=m CONFIG_NF_NAT_FTP=m CONFIG_NF_NAT_IRC=m CONFIG_NF_NAT_SIP=m CONFIG_NF_NAT_TFTP=m CONFIG_NF_NAT_REDIRECT=y +CONFIG_NF_NAT_MASQUERADE=y CONFIG_NETFILTER_SYNPROXY=m CONFIG_NF_TABLES=m CONFIG_NF_TABLES_SET=m @@ -957,9 +1012,11 @@ CONFIG_NFT_COMPAT=m CONFIG_NFT_HASH=m CONFIG_NFT_FIB=m CONFIG_NFT_FIB_INET=m +CONFIG_NFT_XFRM=m CONFIG_NFT_SOCKET=m CONFIG_NFT_OSF=m CONFIG_NFT_TPROXY=m +# CONFIG_NFT_SYNPROXY is not set CONFIG_NF_DUP_NETDEV=m CONFIG_NFT_DUP_NETDEV=m CONFIG_NFT_FWD_NETDEV=m @@ -995,9 +1052,10 @@ CONFIG_NETFILTER_XT_NAT=m CONFIG_NETFILTER_XT_TARGET_NETMAP=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m CONFIG_NETFILTER_XT_TARGET_RATEEST=m CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m @@ -1054,6 +1112,8 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m +# end of Core Netfilter Configuration + CONFIG_IP_SET=m CONFIG_IP_SET_MAX=256 CONFIG_IP_SET_BITMAP_IP=m @@ -1074,7 +1134,7 @@ CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m CONFIG_IP_VS=m CONFIG_IP_VS_IPV6=y -CONFIG_IP_VS_DEBUG=y +# CONFIG_IP_VS_DEBUG is not set CONFIG_IP_VS_TAB_BITS=12 # @@ -1128,7 +1188,6 @@ CONFIG_NF_DEFRAG_IPV4=m CONFIG_NF_SOCKET_IPV4=m CONFIG_NF_TPROXY_IPV4=m CONFIG_NF_TABLES_IPV4=y -CONFIG_NFT_CHAIN_ROUTE_IPV4=m CONFIG_NFT_REJECT_IPV4=m CONFIG_NFT_DUP_IPV4=m CONFIG_NFT_FIB_IPV4=m @@ -1138,13 +1197,7 @@ CONFIG_NF_DUP_IPV4=m CONFIG_NF_LOG_ARP=m CONFIG_NF_LOG_IPV4=m CONFIG_NF_REJECT_IPV4=m -CONFIG_NF_NAT_IPV4=m -CONFIG_NF_NAT_MASQUERADE_IPV4=y -CONFIG_NFT_CHAIN_NAT_IPV4=m -CONFIG_NFT_MASQ_IPV4=m -CONFIG_NFT_REDIR_IPV4=m CONFIG_NF_NAT_SNMP_BASIC=m -CONFIG_NF_NAT_PROTO_GRE=m CONFIG_NF_NAT_PPTP=m CONFIG_NF_NAT_H323=m CONFIG_IP_NF_IPTABLES=m @@ -1168,6 +1221,7 @@ CONFIG_IP_NF_SECURITY=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m +# end of IP: Netfilter Configuration # # IPv6: Netfilter Configuration @@ -1175,10 +1229,6 @@ CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_SOCKET_IPV6=m CONFIG_NF_TPROXY_IPV6=m CONFIG_NF_TABLES_IPV6=y -CONFIG_NFT_CHAIN_ROUTE_IPV6=m -CONFIG_NFT_CHAIN_NAT_IPV6=m -CONFIG_NFT_MASQ_IPV6=m -CONFIG_NFT_REDIR_IPV6=m CONFIG_NFT_REJECT_IPV6=m CONFIG_NFT_DUP_IPV6=m CONFIG_NFT_FIB_IPV6=m @@ -1186,8 +1236,6 @@ CONFIG_NF_FLOW_TABLE_IPV6=m CONFIG_NF_DUP_IPV6=m CONFIG_NF_REJECT_IPV6=m CONFIG_NF_LOG_IPV6=m -CONFIG_NF_NAT_IPV6=m -CONFIG_NF_NAT_MASQUERADE_IPV6=y CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -1209,10 +1257,14 @@ CONFIG_IP6_NF_SECURITY=m CONFIG_IP6_NF_NAT=m CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_IP6_NF_TARGET_NPT=m +# end of IPv6: Netfilter Configuration + CONFIG_NF_DEFRAG_IPV6=m -CONFIG_NF_TABLES_BRIDGE=y +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_NFT_BRIDGE_META=m CONFIG_NFT_BRIDGE_REJECT=m CONFIG_NF_LOG_BRIDGE=m +CONFIG_NF_CONNTRACK_BRIDGE=m CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m @@ -1245,18 +1297,21 @@ CONFIG_INET_DCCP_DIAG=m CONFIG_IP_DCCP_CCID3=y # CONFIG_IP_DCCP_CCID3_DEBUG is not set CONFIG_IP_DCCP_TFRC_LIB=y +# end of DCCP CCIDs Configuration # # DCCP Kernel Hacking # # CONFIG_IP_DCCP_DEBUG is not set +# end of DCCP Kernel Hacking + CONFIG_IP_SCTP=m # CONFIG_SCTP_DBG_OBJCNT is not set CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y # CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set # CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set CONFIG_SCTP_COOKIE_HMAC_MD5=y -# CONFIG_SCTP_COOKIE_HMAC_SHA1 is not set +CONFIG_SCTP_COOKIE_HMAC_SHA1=y CONFIG_INET_SCTP_DIAG=m CONFIG_RDS=m CONFIG_RDS_TCP=m @@ -1267,30 +1322,41 @@ CONFIG_TIPC_DIAG=m CONFIG_ATM=m CONFIG_ATM_CLIP=m CONFIG_ATM_CLIP_NO_ICMP=y -# CONFIG_ATM_LANE is not set +CONFIG_ATM_LANE=m +# CONFIG_ATM_MPOA is not set CONFIG_ATM_BR2684=m CONFIG_ATM_BR2684_IPFILTER=y CONFIG_L2TP=m -# CONFIG_L2TP_DEBUGFS is not set +CONFIG_L2TP_DEBUGFS=m CONFIG_L2TP_V3=y CONFIG_L2TP_IP=m CONFIG_L2TP_ETH=m -CONFIG_STP=y -CONFIG_GARP=y -CONFIG_MRP=y +CONFIG_STP=m +CONFIG_GARP=m +CONFIG_MRP=m CONFIG_BRIDGE=m CONFIG_BRIDGE_IGMP_SNOOPING=y CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_HAVE_NET_DSA=y CONFIG_NET_DSA=m -CONFIG_NET_DSA_LEGACY=y -CONFIG_NET_DSA_TAG_BRCM=y -CONFIG_NET_DSA_TAG_BRCM_PREPEND=y -CONFIG_VLAN_8021Q=y +CONFIG_NET_DSA_TAG_8021Q=m +CONFIG_NET_DSA_TAG_BRCM_COMMON=m +CONFIG_NET_DSA_TAG_BRCM=m +CONFIG_NET_DSA_TAG_BRCM_PREPEND=m +CONFIG_NET_DSA_TAG_GSWIP=m +CONFIG_NET_DSA_TAG_DSA=m +CONFIG_NET_DSA_TAG_EDSA=m +CONFIG_NET_DSA_TAG_MTK=m +CONFIG_NET_DSA_TAG_KSZ=m +CONFIG_NET_DSA_TAG_QCA=m +CONFIG_NET_DSA_TAG_LAN9303=m +CONFIG_NET_DSA_TAG_SJA1105=m +CONFIG_NET_DSA_TAG_TRAILER=m +CONFIG_VLAN_8021Q=m CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y # CONFIG_DECNET is not set -CONFIG_LLC=y +CONFIG_LLC=m # CONFIG_LLC2 is not set CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m @@ -1309,13 +1375,17 @@ CONFIG_6LOWPAN_NHC_IPV6=m CONFIG_6LOWPAN_NHC_MOBILITY=m CONFIG_6LOWPAN_NHC_ROUTING=m CONFIG_6LOWPAN_NHC_UDP=m -# CONFIG_6LOWPAN_GHC_EXT_HDR_HOP is not set -# CONFIG_6LOWPAN_GHC_UDP is not set -# CONFIG_6LOWPAN_GHC_ICMPV6 is not set -# CONFIG_6LOWPAN_GHC_EXT_HDR_DEST is not set -# CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG is not set -# CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE is not set -# CONFIG_IEEE802154 is not set +CONFIG_6LOWPAN_GHC_EXT_HDR_HOP=m +CONFIG_6LOWPAN_GHC_UDP=m +CONFIG_6LOWPAN_GHC_ICMPV6=m +CONFIG_6LOWPAN_GHC_EXT_HDR_DEST=m +CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG=m +CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE=m +CONFIG_IEEE802154=m +# CONFIG_IEEE802154_NL802154_EXPERIMENTAL is not set +CONFIG_IEEE802154_SOCKET=m +CONFIG_IEEE802154_6LOWPAN=m +CONFIG_MAC802154=m CONFIG_NET_SCHED=y # @@ -1324,7 +1394,7 @@ CONFIG_NET_SCHED=y CONFIG_NET_SCH_CBQ=m CONFIG_NET_SCH_HTB=m CONFIG_NET_SCH_HFSC=m -# CONFIG_NET_SCH_ATM is not set +CONFIG_NET_SCH_ATM=m CONFIG_NET_SCH_PRIO=m CONFIG_NET_SCH_MULTIQ=m CONFIG_NET_SCH_RED=m @@ -1334,6 +1404,7 @@ CONFIG_NET_SCH_TEQL=m CONFIG_NET_SCH_TBF=m CONFIG_NET_SCH_CBS=m CONFIG_NET_SCH_ETF=m +CONFIG_NET_SCH_TAPRIO=m CONFIG_NET_SCH_GRED=m CONFIG_NET_SCH_DSMARK=m CONFIG_NET_SCH_NETEM=m @@ -1367,12 +1438,12 @@ CONFIG_NET_CLS_TCINDEX=m CONFIG_NET_CLS_ROUTE4=m CONFIG_NET_CLS_FW=m CONFIG_NET_CLS_U32=m -# CONFIG_CLS_U32_PERF is not set +CONFIG_CLS_U32_PERF=y CONFIG_CLS_U32_MARK=y CONFIG_NET_CLS_RSVP=m CONFIG_NET_CLS_RSVP6=m CONFIG_NET_CLS_FLOW=m -CONFIG_NET_CLS_CGROUP=m +CONFIG_NET_CLS_CGROUP=y CONFIG_NET_CLS_BPF=m CONFIG_NET_CLS_FLOWER=m CONFIG_NET_CLS_MATCHALL=m @@ -1398,19 +1469,22 @@ CONFIG_NET_ACT_PEDIT=m CONFIG_NET_ACT_SIMP=m CONFIG_NET_ACT_SKBEDIT=m CONFIG_NET_ACT_CSUM=m +CONFIG_NET_ACT_MPLS=m CONFIG_NET_ACT_VLAN=m CONFIG_NET_ACT_BPF=m CONFIG_NET_ACT_CONNMARK=m +CONFIG_NET_ACT_CTINFO=m CONFIG_NET_ACT_SKBMOD=m CONFIG_NET_ACT_IFE=m CONFIG_NET_ACT_TUNNEL_KEY=m +CONFIG_NET_ACT_CT=m CONFIG_NET_IFE_SKBMARK=m CONFIG_NET_IFE_SKBPRIO=m CONFIG_NET_IFE_SKBTCINDEX=m -CONFIG_NET_CLS_IND=y +# CONFIG_NET_TC_SKB_EXT is not set CONFIG_NET_SCH_FIFO=y CONFIG_DCB=y -CONFIG_DNS_RESOLVER=y +CONFIG_DNS_RESOLVER=m CONFIG_BATMAN_ADV=m CONFIG_BATMAN_ADV_BATMAN_V=y CONFIG_BATMAN_ADV_BLA=y @@ -1418,19 +1492,28 @@ CONFIG_BATMAN_ADV_DAT=y CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_MCAST=y # CONFIG_BATMAN_ADV_DEBUGFS is not set +# CONFIG_BATMAN_ADV_DEBUG is not set +CONFIG_BATMAN_ADV_SYSFS=y +CONFIG_BATMAN_ADV_TRACING=y CONFIG_OPENVSWITCH=m CONFIG_OPENVSWITCH_GRE=m CONFIG_OPENVSWITCH_VXLAN=m -# CONFIG_VSOCKETS is not set +CONFIG_OPENVSWITCH_GENEVE=m +CONFIG_VSOCKETS=m +CONFIG_VSOCKETS_DIAG=m +CONFIG_VIRTIO_VSOCKETS=m +CONFIG_VIRTIO_VSOCKETS_COMMON=m CONFIG_NETLINK_DIAG=m CONFIG_MPLS=y CONFIG_NET_MPLS_GSO=m -# CONFIG_MPLS_ROUTING is not set +CONFIG_MPLS_ROUTING=m +CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_NSH=m CONFIG_HSR=m CONFIG_NET_SWITCHDEV=y CONFIG_NET_L3_MASTER_DEV=y -# CONFIG_NET_NCSI is not set +CONFIG_NET_NCSI=y +CONFIG_NCSI_OEM_CMD_GET_MAC=y CONFIG_RPS=y CONFIG_RFS_ACCEL=y CONFIG_XPS=y @@ -1438,8 +1521,8 @@ CONFIG_CGROUP_NET_PRIO=y CONFIG_CGROUP_NET_CLASSID=y CONFIG_NET_RX_BUSY_POLL=y CONFIG_BQL=y -# CONFIG_BPF_JIT is not set -# CONFIG_BPF_STREAM_PARSER is not set +CONFIG_BPF_JIT=y +CONFIG_BPF_STREAM_PARSER=y CONFIG_NET_FLOW_LIMIT=y # @@ -1447,6 +1530,9 @@ CONFIG_NET_FLOW_LIMIT=y # CONFIG_NET_PKTGEN=m # CONFIG_NET_DROP_MONITOR is not set +# end of Network testing +# end of Networking options + CONFIG_HAMRADIO=y # @@ -1468,10 +1554,13 @@ CONFIG_BAYCOM_SER_HDX=m # CONFIG_BAYCOM_PAR is not set # CONFIG_BAYCOM_EPP is not set CONFIG_YAM=m +# end of AX.25 network device drivers + CONFIG_CAN=m CONFIG_CAN_RAW=m CONFIG_CAN_BCM=m CONFIG_CAN_GW=m +CONFIG_CAN_J1939=m # # CAN Device Drivers @@ -1492,6 +1581,8 @@ CONFIG_CAN_CC770_ISA=m CONFIG_CAN_CC770_PLATFORM=m # CONFIG_CAN_IFI_CANFD is not set CONFIG_CAN_M_CAN=m +CONFIG_CAN_M_CAN_PLATFORM=m +CONFIG_CAN_M_CAN_TCAN4X5X=m CONFIG_CAN_RCAR=m CONFIG_CAN_RCAR_CANFD=m CONFIG_CAN_SJA1000=m @@ -1504,6 +1595,7 @@ CONFIG_CAN_SOFTING=m # CONFIG_CAN_HI311X=m CONFIG_CAN_MCP251X=m +# end of CAN SPI interfaces # # CAN USB interfaces @@ -1516,7 +1608,11 @@ CONFIG_CAN_KVASER_USB=m CONFIG_CAN_MCBA_USB=m CONFIG_CAN_PEAK_USB=m CONFIG_CAN_UCAN=m +# end of CAN USB interfaces + # CONFIG_CAN_DEBUG_DEVICES is not set +# end of CAN Device Drivers + CONFIG_BT=m CONFIG_BT_BREDR=y CONFIG_BT_RFCOMM=m @@ -1527,10 +1623,10 @@ CONFIG_BT_BNEP_PROTO_FILTER=y CONFIG_BT_HIDP=m CONFIG_BT_HS=y CONFIG_BT_LE=y -# CONFIG_BT_6LOWPAN is not set +CONFIG_BT_6LOWPAN=m CONFIG_BT_LEDS=y # CONFIG_BT_SELFTEST is not set -CONFIG_BT_DEBUGFS=y +# CONFIG_BT_DEBUGFS is not set # # Bluetooth device drivers @@ -1540,8 +1636,9 @@ CONFIG_BT_BCM=m CONFIG_BT_RTL=m CONFIG_BT_QCA=m CONFIG_BT_HCIBTUSB=m -# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set +CONFIG_BT_HCIBTUSB_AUTOSUSPEND=y CONFIG_BT_HCIBTUSB_BCM=y +# CONFIG_BT_HCIBTUSB_MTK is not set CONFIG_BT_HCIBTUSB_RTL=y CONFIG_BT_HCIBTSDIO=m CONFIG_BT_HCIUART=m @@ -1565,14 +1662,17 @@ CONFIG_BT_HCIVHCI=m CONFIG_BT_MRVL=m CONFIG_BT_MRVL_SDIO=m CONFIG_BT_ATH3K=m +CONFIG_BT_MTKSDIO=m CONFIG_BT_MTKUART=m +# end of Bluetooth device drivers + CONFIG_AF_RXRPC=m # CONFIG_AF_RXRPC_IPV6 is not set # CONFIG_AF_RXRPC_INJECT_LOSS is not set # CONFIG_AF_RXRPC_DEBUG is not set # CONFIG_RXKAD is not set CONFIG_AF_KCM=m -CONFIG_STREAM_PARSER=m +CONFIG_STREAM_PARSER=y CONFIG_FIB_RULES=y CONFIG_WIRELESS=y CONFIG_WIRELESS_EXT=y @@ -1581,77 +1681,96 @@ CONFIG_WEXT_PROC=y CONFIG_WEXT_PRIV=y CONFIG_CFG80211=m # CONFIG_NL80211_TESTMODE is not set -CONFIG_CFG80211_DEVELOPER_WARNINGS=y +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set # CONFIG_CFG80211_CERTIFICATION_ONUS is not set CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y CONFIG_CFG80211_DEFAULT_PS=y -# CONFIG_CFG80211_DEBUGFS is not set +CONFIG_CFG80211_DEBUGFS=y CONFIG_CFG80211_CRDA_SUPPORT=y CONFIG_CFG80211_WEXT=y CONFIG_MAC80211=m CONFIG_MAC80211_HAS_RC=y CONFIG_MAC80211_RC_MINSTREL=y -CONFIG_MAC80211_RC_MINSTREL_HT=y -# CONFIG_MAC80211_RC_MINSTREL_VHT is not set CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" CONFIG_MAC80211_MESH=y CONFIG_MAC80211_LEDS=y -# CONFIG_MAC80211_DEBUGFS is not set +CONFIG_MAC80211_DEBUGFS=y # CONFIG_MAC80211_MESSAGE_TRACING is not set # CONFIG_MAC80211_DEBUG_MENU is not set CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 CONFIG_WIMAX=m CONFIG_WIMAX_DEBUG_LEVEL=8 -CONFIG_RFKILL=y +CONFIG_RFKILL=m CONFIG_RFKILL_LEDS=y CONFIG_RFKILL_INPUT=y -CONFIG_RFKILL_GPIO=y -# CONFIG_NET_9P is not set +CONFIG_RFKILL_GPIO=m +CONFIG_NET_9P=m +CONFIG_NET_9P_VIRTIO=m +# CONFIG_NET_9P_DEBUG is not set # CONFIG_CAIF is not set CONFIG_CEPH_LIB=m # CONFIG_CEPH_LIB_PRETTYDEBUG is not set # CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set CONFIG_NFC=m -# CONFIG_NFC_DIGITAL is not set +CONFIG_NFC_DIGITAL=m CONFIG_NFC_NCI=m CONFIG_NFC_NCI_SPI=m CONFIG_NFC_NCI_UART=m -# CONFIG_NFC_HCI is not set +CONFIG_NFC_HCI=m +CONFIG_NFC_SHDLC=y # # Near Field Communication (NFC) devices # -# CONFIG_NFC_FDP is not set +CONFIG_NFC_TRF7970A=m +CONFIG_NFC_SIM=m +CONFIG_NFC_PORT100=m +CONFIG_NFC_FDP=m +CONFIG_NFC_FDP_I2C=m +CONFIG_NFC_PN544=m +CONFIG_NFC_PN544_I2C=m CONFIG_NFC_PN533=m CONFIG_NFC_PN533_USB=m CONFIG_NFC_PN533_I2C=m +CONFIG_NFC_MICROREAD=m +CONFIG_NFC_MICROREAD_I2C=m CONFIG_NFC_MRVL=m CONFIG_NFC_MRVL_USB=m CONFIG_NFC_MRVL_UART=m CONFIG_NFC_MRVL_I2C=m CONFIG_NFC_MRVL_SPI=m +CONFIG_NFC_ST21NFCA=m +CONFIG_NFC_ST21NFCA_I2C=m CONFIG_NFC_ST_NCI=m CONFIG_NFC_ST_NCI_I2C=m CONFIG_NFC_ST_NCI_SPI=m CONFIG_NFC_NXP_NCI=m CONFIG_NFC_NXP_NCI_I2C=m -# CONFIG_NFC_S3FWRN5_I2C is not set +CONFIG_NFC_S3FWRN5=m +CONFIG_NFC_S3FWRN5_I2C=m +CONFIG_NFC_ST95HF=m +# end of Near Field Communication (NFC) devices + CONFIG_PSAMPLE=m CONFIG_NET_IFE=m CONFIG_LWTUNNEL=y -# CONFIG_LWTUNNEL_BPF is not set +CONFIG_LWTUNNEL_BPF=y CONFIG_DST_CACHE=y CONFIG_GRO_CELLS=y -CONFIG_NET_DEVLINK=m -CONFIG_MAY_USE_DEVLINK=m +CONFIG_NET_SOCK_MSG=y +CONFIG_NET_DEVLINK=y +CONFIG_PAGE_POOL=y CONFIG_FAILOVER=m CONFIG_HAVE_EBPF_JIT=y # # Device Drivers # +CONFIG_HAVE_PCI=y +# CONFIG_PCI is not set +# CONFIG_PCCARD is not set # # Generic Driver Options @@ -1667,9 +1786,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # Firmware loader # CONFIG_FW_LOADER=y +CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_EXTRA_FIRMWARE="" CONFIG_FW_LOADER_USER_HELPER=y CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y +# CONFIG_FW_LOADER_COMPRESS is not set +# end of Firmware loader + CONFIG_WANT_DEV_COREDUMP=y CONFIG_ALLOW_DEV_COREDUMP=y CONFIG_DEV_COREDUMP=y @@ -1681,22 +1804,16 @@ CONFIG_GENERIC_CPU_AUTOPROBE=y CONFIG_REGMAP=y CONFIG_REGMAP_I2C=y CONFIG_REGMAP_SPI=y +CONFIG_REGMAP_SPMI=m +CONFIG_REGMAP_W1=m CONFIG_REGMAP_MMIO=y CONFIG_REGMAP_IRQ=y +CONFIG_REGMAP_SCCB=m +CONFIG_REGMAP_I3C=m CONFIG_DMA_SHARED_BUFFER=y # CONFIG_DMA_FENCE_TRACE is not set -CONFIG_DMA_CMA=y - -# -# Default contiguous memory area size: -# -CONFIG_CMA_SIZE_MBYTES=128 -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_ALIGNMENT=8 CONFIG_GENERIC_ARCH_TOPOLOGY=y +# end of Generic Driver Options # # Bus devices @@ -1705,25 +1822,31 @@ CONFIG_ARM_CCI=y CONFIG_ARM_CCI400_COMMON=y CONFIG_ARM_CCI400_PORT_CTRL=y # CONFIG_BRCMSTB_GISB_ARB is not set +# CONFIG_MOXTET is not set # CONFIG_SIMPLE_PM_BUS is not set CONFIG_SUN50I_DE2_BUS=y CONFIG_SUNXI_RSB=y # CONFIG_VEXPRESS_CONFIG is not set -CONFIG_CONNECTOR=m +# end of Bus devices + +# CONFIG_CONNECTOR is not set CONFIG_GNSS=m +CONFIG_GNSS_SERIAL=m +CONFIG_GNSS_MTK_SERIAL=m CONFIG_GNSS_SIRF_SERIAL=m # CONFIG_GNSS_UBX_SERIAL is not set CONFIG_MTD=y # CONFIG_MTD_TESTS is not set -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y -# CONFIG_MTD_AFS_PARTS is not set -CONFIG_MTD_OF_PARTS=y -# CONFIG_MTD_AR7_PARTS is not set # # Partition parsers # +# CONFIG_MTD_AR7_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# end of Partition parsers # # User Modules And Translation Layers @@ -1744,30 +1867,41 @@ CONFIG_MTD_BLOCK_RO=m # # RAM/ROM/Flash chip drivers # -# CONFIG_MTD_CFI is not set +CONFIG_MTD_CFI=m # CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set CONFIG_MTD_MAP_BANK_WIDTH_1=y CONFIG_MTD_MAP_BANK_WIDTH_2=y CONFIG_MTD_MAP_BANK_WIDTH_4=y CONFIG_MTD_CFI_I1=y CONFIG_MTD_CFI_I2=y +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set +# end of RAM/ROM/Flash chip drivers # # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=m +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_PHYSMAP_OF is not set # CONFIG_MTD_PLATRAM is not set +# end of Mapping drivers for chip access # # Self-contained MTD device drivers # # CONFIG_MTD_DATAFLASH is not set -CONFIG_MTD_M25P80=y # CONFIG_MTD_MCHP23K256 is not set # CONFIG_MTD_SST25L is not set +CONFIG_MTD_BCM47XXSFLASH=m # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -1777,20 +1911,30 @@ CONFIG_MTD_BLOCK2MTD=m # Disk-On-Chip Device Drivers # # CONFIG_MTD_DOCG3 is not set +# end of Self-contained MTD device drivers + CONFIG_MTD_NAND_CORE=m # CONFIG_MTD_ONENAND is not set -CONFIG_MTD_NAND_ECC=y -# CONFIG_MTD_NAND_ECC_SMC is not set -CONFIG_MTD_NAND=y -# CONFIG_MTD_NAND_ECC_BCH is not set +CONFIG_MTD_NAND_ECC_SW_HAMMING=m +# CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC is not set +CONFIG_MTD_RAW_NAND=m +# CONFIG_MTD_NAND_ECC_SW_BCH is not set + +# +# Raw/parallel NAND flash controllers +# # CONFIG_MTD_NAND_DENALI_DT is not set -CONFIG_MTD_NAND_GPIO=y -# CONFIG_MTD_NAND_DISKONCHIP is not set -# CONFIG_MTD_NAND_DOCG4 is not set -# CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_BRCMNAND is not set -CONFIG_MTD_NAND_PLATFORM=y -CONFIG_MTD_NAND_SUNXI=y +CONFIG_MTD_NAND_SUNXI=m +CONFIG_MTD_NAND_MXIC=m +CONFIG_MTD_NAND_GPIO=m +CONFIG_MTD_NAND_PLATFORM=m + +# +# Misc +# +CONFIG_MTD_NAND_NANDSIM=m +# CONFIG_MTD_NAND_DISKONCHIP is not set CONFIG_MTD_SPI_NAND=m # @@ -1798,16 +1942,19 @@ CONFIG_MTD_SPI_NAND=m # # CONFIG_MTD_LPDDR is not set # CONFIG_MTD_LPDDR2_NVM is not set +# end of LPDDR & LPDDR2 PCM memory drivers + CONFIG_MTD_SPI_NOR=y -# CONFIG_MTD_MT81xx_NOR is not set CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y # CONFIG_SPI_CADENCE_QUADSPI is not set +CONFIG_SPI_MTK_QUADSPI=m CONFIG_MTD_UBI=y CONFIG_MTD_UBI_WL_THRESHOLD=4096 CONFIG_MTD_UBI_BEB_LIMIT=20 # CONFIG_MTD_UBI_FASTMAP is not set # CONFIG_MTD_UBI_GLUEBI is not set # CONFIG_MTD_UBI_BLOCK is not set +# CONFIG_MTD_HYPERBUS is not set CONFIG_DTC=y CONFIG_OF=y # CONFIG_OF_UNITTEST is not set @@ -1838,25 +1985,31 @@ CONFIG_ZRAM_WRITEBACK=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 CONFIG_BLK_DEV_CRYPTOLOOP=m -# CONFIG_BLK_DEV_DRBD is not set +CONFIG_BLK_DEV_DRBD=m +# CONFIG_DRBD_FAULT_INJECTION is not set CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=4 CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_CDROM_PKTCDVD is not set CONFIG_ATA_OVER_ETH=m +CONFIG_VIRTIO_BLK=m +# CONFIG_VIRTIO_BLK_SCSI is not set CONFIG_BLK_DEV_RBD=m # # NVME Support # CONFIG_NVME_CORE=m -# CONFIG_NVME_MULTIPATH is not set +CONFIG_NVME_MULTIPATH=y CONFIG_NVME_FABRICS=m -# CONFIG_NVME_FC is not set +CONFIG_NVME_FC=m CONFIG_NVME_TARGET=m CONFIG_NVME_TARGET_LOOP=m -# CONFIG_NVME_TARGET_FC is not set +CONFIG_NVME_TARGET_FC=m +CONFIG_NVME_TARGET_FCLOOP=m +CONFIG_NVME_TARGET_TCP=m +# end of NVME Support # # Misc devices @@ -1873,27 +2026,32 @@ CONFIG_NVME_TARGET_LOOP=m # CONFIG_SENSORS_APDS990X is not set # CONFIG_HMC6352 is not set # CONFIG_DS1682 is not set -# CONFIG_USB_SWITCH_FSA9480 is not set # CONFIG_LATTICE_ECP3_CONFIG is not set # CONFIG_SRAM is not set +# CONFIG_XILINX_SDFEC is not set CONFIG_MISC_RTSX=m +CONFIG_PVPANIC=m # CONFIG_C2PORT is not set # # EEPROM support # CONFIG_EEPROM_AT24=m -# CONFIG_EEPROM_AT25 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EEPROM_AT25=m +CONFIG_EEPROM_LEGACY=m +CONFIG_EEPROM_MAX6875=m CONFIG_EEPROM_93CX6=m -# CONFIG_EEPROM_93XX46 is not set +CONFIG_EEPROM_93XX46=m CONFIG_EEPROM_IDT_89HPESX=m +CONFIG_EEPROM_EE1004=m +# end of EEPROM support # # Texas Instruments shared transport line discipline # # CONFIG_TI_ST is not set +# end of Texas Instruments shared transport line discipline + # CONFIG_SENSORS_LIS3_SPI is not set # CONFIG_SENSORS_LIS3_I2C is not set # CONFIG_ALTERA_STAPL is not set @@ -1913,6 +2071,7 @@ CONFIG_EEPROM_IDT_89HPESX=m # # VOP Bus Driver # +# CONFIG_VOP_BUS is not set # # Intel MIC Host Driver @@ -1933,8 +2092,11 @@ CONFIG_EEPROM_IDT_89HPESX=m # # VOP Driver # -# CONFIG_ECHO is not set +# end of Intel MIC & related support + +CONFIG_ECHO=m CONFIG_MISC_RTSX_USB=m +# end of Misc devices # # SCSI device support @@ -1943,7 +2105,6 @@ CONFIG_SCSI_MOD=y CONFIG_RAID_ATTRS=m CONFIG_SCSI=y CONFIG_SCSI_DMA=y -# CONFIG_SCSI_MQ_DEFAULT is not set CONFIG_SCSI_PROC_FS=y # @@ -1951,7 +2112,6 @@ CONFIG_SCSI_PROC_FS=y # CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set CONFIG_BLK_DEV_SR=m # CONFIG_BLK_DEV_SR_VENDOR is not set CONFIG_CHR_DEV_SG=y @@ -1969,16 +2129,17 @@ CONFIG_SCSI_ISCSI_ATTRS=m # CONFIG_SCSI_SAS_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set # CONFIG_SCSI_SRP_ATTRS is not set +# end of SCSI Transports + CONFIG_SCSI_LOWLEVEL=y CONFIG_ISCSI_TCP=m # CONFIG_ISCSI_BOOT_SYSFS is not set # CONFIG_SCSI_UFSHCD is not set # CONFIG_SCSI_DEBUG is not set +CONFIG_SCSI_VIRTIO=m # CONFIG_SCSI_DH is not set -CONFIG_SCSI_OSD_INITIATOR=m -# CONFIG_SCSI_OSD_ULD is not set -CONFIG_SCSI_OSD_DPRINT_SENSE=1 -# CONFIG_SCSI_OSD_DEBUG is not set +# end of SCSI device support + CONFIG_ATA=y CONFIG_ATA_VERBOSE_ERROR=y CONFIG_SATA_PMP=y @@ -2023,12 +2184,12 @@ CONFIG_MD_RAID10=m CONFIG_MD_RAID456=m CONFIG_MD_MULTIPATH=m CONFIG_MD_FAULTY=m +CONFIG_MD_CLUSTER=m CONFIG_BCACHE=m # CONFIG_BCACHE_DEBUG is not set # CONFIG_BCACHE_CLOSURES_DEBUG is not set CONFIG_BLK_DEV_DM_BUILTIN=y CONFIG_BLK_DEV_DM=m -# CONFIG_DM_MQ_DEFAULT is not set # CONFIG_DM_DEBUG is not set CONFIG_DM_BUFIO=m # CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set @@ -2042,20 +2203,25 @@ CONFIG_DM_CACHE=m CONFIG_DM_CACHE_SMQ=m CONFIG_DM_WRITECACHE=m # CONFIG_DM_ERA is not set -# CONFIG_DM_MIRROR is not set +CONFIG_DM_CLONE=m +CONFIG_DM_MIRROR=m +# CONFIG_DM_LOG_USERSPACE is not set CONFIG_DM_RAID=m -# CONFIG_DM_ZERO is not set +CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m -# CONFIG_DM_MULTIPATH_QL is not set -# CONFIG_DM_MULTIPATH_ST is not set +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m # CONFIG_DM_DELAY is not set +CONFIG_DM_DUST=m CONFIG_DM_UEVENT=y CONFIG_DM_FLAKEY=m CONFIG_DM_VERITY=m +# CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG is not set # CONFIG_DM_VERITY_FEC is not set CONFIG_DM_SWITCH=m CONFIG_DM_LOG_WRITES=m # CONFIG_DM_INTEGRITY is not set +CONFIG_DM_ZONED=m CONFIG_TARGET_CORE=m CONFIG_TCM_IBLOCK=m CONFIG_TCM_FILEIO=m @@ -2070,22 +2236,30 @@ CONFIG_BONDING=m CONFIG_DUMMY=m # CONFIG_EQUALIZER is not set CONFIG_IFB=m -# CONFIG_NET_TEAM is not set +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_RANDOM=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m CONFIG_MACVLAN=m CONFIG_MACVTAP=m +CONFIG_IPVLAN_L3S=y CONFIG_IPVLAN=m -# CONFIG_IPVTAP is not set +CONFIG_IPVTAP=m CONFIG_VXLAN=m -# CONFIG_GENEVE is not set -# CONFIG_GTP is not set +CONFIG_GENEVE=m +CONFIG_GTP=m CONFIG_MACSEC=m # CONFIG_NETCONSOLE is not set CONFIG_TUN=m CONFIG_TAP=m # CONFIG_TUN_VNET_CROSS_LE is not set CONFIG_VETH=m -# CONFIG_NLMON is not set +CONFIG_VIRTIO_NET=m +CONFIG_NLMON=m CONFIG_NET_VRF=m +CONFIG_VSOCKMON=m CONFIG_ATM_DRIVERS=y # CONFIG_ATM_DUMMY is not set # CONFIG_ATM_TCP is not set @@ -2102,17 +2276,33 @@ CONFIG_B53_SPI_DRIVER=m CONFIG_B53_MDIO_DRIVER=m CONFIG_B53_MMAP_DRIVER=m CONFIG_B53_SRAB_DRIVER=m -# CONFIG_NET_DSA_BCM_SF2 is not set -# CONFIG_NET_DSA_LOOP is not set -# CONFIG_NET_DSA_MT7530 is not set -# CONFIG_NET_DSA_MV88E6060 is not set -# CONFIG_MICROCHIP_KSZ is not set -# CONFIG_NET_DSA_MV88E6XXX is not set -# CONFIG_NET_DSA_QCA8K is not set +CONFIG_B53_SERDES=m +CONFIG_NET_DSA_BCM_SF2=m +CONFIG_NET_DSA_LOOP=m +CONFIG_NET_DSA_LANTIQ_GSWIP=m +CONFIG_NET_DSA_MT7530=m +CONFIG_NET_DSA_MV88E6060=m +CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=m +CONFIG_NET_DSA_MICROCHIP_KSZ9477=m +CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C=m +CONFIG_NET_DSA_MICROCHIP_KSZ9477_SPI=m +CONFIG_NET_DSA_MICROCHIP_KSZ8795=m +CONFIG_NET_DSA_MICROCHIP_KSZ8795_SPI=m +CONFIG_NET_DSA_MV88E6XXX=m +CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y +CONFIG_NET_DSA_MV88E6XXX_PTP=y +CONFIG_NET_DSA_SJA1105=m +# CONFIG_NET_DSA_SJA1105_PTP is not set +# CONFIG_NET_DSA_SJA1105_TAS is not set +CONFIG_NET_DSA_QCA8K=m CONFIG_NET_DSA_REALTEK_SMI=m -# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set -# CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set -CONFIG_NET_DSA_VITESSE_VSC73XX=m +CONFIG_NET_DSA_SMSC_LAN9303=m +CONFIG_NET_DSA_SMSC_LAN9303_I2C=m +CONFIG_NET_DSA_SMSC_LAN9303_MDIO=m +# CONFIG_NET_DSA_VITESSE_VSC73XX_SPI is not set +# CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM is not set +# end of Distributed Switch Architecture drivers + CONFIG_ETHERNET=y CONFIG_NET_VENDOR_ALACRITECH=y CONFIG_NET_VENDOR_ALLWINNER=y @@ -2134,10 +2324,12 @@ CONFIG_NET_VENDOR_CORTINA=y CONFIG_NET_VENDOR_EZCHIP=y # CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set # CONFIG_NET_VENDOR_FARADAY is not set +CONFIG_NET_VENDOR_GOOGLE=y CONFIG_NET_VENDOR_HISILICON=y # CONFIG_HIX5HD2_GMAC is not set # CONFIG_HISI_FEMAC is not set CONFIG_HIP04_ETH=m +# CONFIG_HI13X1_GMAC is not set CONFIG_HNS_MDIO=m # CONFIG_HNS is not set # CONFIG_HNS_DSAF is not set @@ -2158,7 +2350,9 @@ CONFIG_NET_VENDOR_MICROSEMI=y # CONFIG_NET_VENDOR_NATSEMI is not set CONFIG_NET_VENDOR_NETRONOME=y CONFIG_NET_VENDOR_NI=y +CONFIG_NI_XGE_MANAGEMENT_ENET=m # CONFIG_ETHOC is not set +CONFIG_NET_VENDOR_PENSANDO=y CONFIG_NET_VENDOR_QUALCOMM=y # CONFIG_QCA7000_SPI is not set # CONFIG_QCA7000_UART is not set @@ -2173,6 +2367,7 @@ CONFIG_NET_VENDOR_SOLARFLARE=y CONFIG_NET_VENDOR_SOCIONEXT=y CONFIG_NET_VENDOR_STMICRO=y CONFIG_STMMAC_ETH=y +# CONFIG_STMMAC_SELFTESTS is not set CONFIG_STMMAC_PLATFORM=y CONFIG_DWMAC_DWC_QOS_ETH=m CONFIG_DWMAC_GENERIC=y @@ -2182,17 +2377,20 @@ CONFIG_NET_VENDOR_SYNOPSYS=y # CONFIG_DWC_XLGMAC is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_NET_VENDOR_XILINX=y +# CONFIG_XILINX_AXI_EMAC is not set CONFIG_MDIO_DEVICE=y CONFIG_MDIO_BUS=y -# CONFIG_MDIO_BCM_UNIMAC is not set +CONFIG_MDIO_BCM_UNIMAC=m # CONFIG_MDIO_BITBANG is not set CONFIG_MDIO_BUS_MUX=y # CONFIG_MDIO_BUS_MUX_GPIO is not set # CONFIG_MDIO_BUS_MUX_MMIOREG is not set +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m # CONFIG_MDIO_HISI_FEMAC is not set # CONFIG_MDIO_MSCC_MIIM is not set CONFIG_MDIO_SUN4I=y -CONFIG_PHYLINK=m +CONFIG_PHYLINK=y CONFIG_PHYLIB=y CONFIG_SWPHY=y CONFIG_LED_TRIGGER_PHY=y @@ -2201,51 +2399,54 @@ CONFIG_LED_TRIGGER_PHY=y # MII PHY device drivers # # CONFIG_SFP is not set +CONFIG_ADIN_PHY=m +CONFIG_AC200_PHY=m CONFIG_AMD_PHY=m CONFIG_AQUANTIA_PHY=m CONFIG_AX88796B_PHY=m CONFIG_AT803X_PHY=m -# CONFIG_BCM7XXX_PHY is not set +CONFIG_BCM7XXX_PHY=m CONFIG_BCM87XX_PHY=m CONFIG_BCM_NET_PHYLIB=m CONFIG_BROADCOM_PHY=m CONFIG_CICADA_PHY=m -# CONFIG_CORTINA_PHY is not set +CONFIG_CORTINA_PHY=m CONFIG_DAVICOM_PHY=m -# CONFIG_DP83822_PHY is not set -CONFIG_DP83TC811_PHY=m +CONFIG_DP83822_PHY=m +# CONFIG_DP83TC811_PHY is not set CONFIG_DP83848_PHY=m # CONFIG_DP83867_PHY is not set CONFIG_FIXED_PHY=y CONFIG_ICPLUS_PHY=m -# CONFIG_INTEL_XWAY_PHY is not set +CONFIG_INTEL_XWAY_PHY=m CONFIG_LSI_ET1011C_PHY=m CONFIG_LXT_PHY=m CONFIG_MARVELL_PHY=m -# CONFIG_MARVELL_10G_PHY is not set +CONFIG_MARVELL_10G_PHY=m CONFIG_MICREL_PHY=m CONFIG_MICROCHIP_PHY=m CONFIG_MICROCHIP_T1_PHY=m # CONFIG_MICROSEMI_PHY is not set CONFIG_NATIONAL_PHY=m +# CONFIG_NXP_TJA11XX_PHY is not set CONFIG_QSEMI_PHY=m CONFIG_REALTEK_PHY=m # CONFIG_RENESAS_PHY is not set -# CONFIG_ROCKCHIP_PHY is not set +CONFIG_ROCKCHIP_PHY=m CONFIG_SMSC_PHY=m CONFIG_STE10XP=m CONFIG_TERANETICS_PHY=m CONFIG_VITESSE_PHY=m # CONFIG_XILINX_GMII2RGMII is not set # CONFIG_MICREL_KS8995MA is not set -# CONFIG_PLIP is not set +CONFIG_PLIP=m CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=m CONFIG_PPP_MULTILINK=y -# CONFIG_PPPOATM is not set +CONFIG_PPPOATM=m CONFIG_PPPOE=m CONFIG_PPTP=m CONFIG_PPPOL2TP=m @@ -2299,6 +2500,7 @@ CONFIG_USB_IPHETH=m CONFIG_USB_SIERRA_NET=m CONFIG_USB_VL600=m CONFIG_USB_NET_CH9200=m +CONFIG_USB_NET_AQC111=m CONFIG_WLAN=y # CONFIG_WIRELESS_WDS is not set CONFIG_WLAN_VENDOR_ADMTEK=y @@ -2321,6 +2523,7 @@ CONFIG_ATH9K_HTC=m CONFIG_ATH9K_HWRNG=y CONFIG_CARL9170=m CONFIG_CARL9170_LEDS=y +# CONFIG_CARL9170_DEBUGFS is not set CONFIG_CARL9170_WPC=y # CONFIG_CARL9170_HWRNG is not set CONFIG_ATH6KL=m @@ -2381,8 +2584,11 @@ CONFIG_MT7601U=m CONFIG_MT76_CORE=m CONFIG_MT76_LEDS=y CONFIG_MT76_USB=m -CONFIG_MT76x2_COMMON=m +CONFIG_MT76x02_LIB=m +CONFIG_MT76x02_USB=m +CONFIG_MT76x0_COMMON=m CONFIG_MT76x0U=m +CONFIG_MT76x2_COMMON=m CONFIG_MT76x2U=m CONFIG_WLAN_VENDOR_RALINK=y CONFIG_RT2X00=m @@ -2401,6 +2607,7 @@ CONFIG_RT2X00_LIB=m CONFIG_RT2X00_LIB_FIRMWARE=y CONFIG_RT2X00_LIB_CRYPTO=y CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_LIB_DEBUGFS is not set # CONFIG_RT2X00_DEBUG is not set CONFIG_WLAN_VENDOR_REALTEK=y CONFIG_RTL8187=m @@ -2412,8 +2619,9 @@ CONFIG_RTLWIFI_USB=m # CONFIG_RTLWIFI_DEBUG is not set CONFIG_RTL8192C_COMMON=m CONFIG_RTL8XXXU=m -# CONFIG_RTL8XXXU_UNTESTED is not set +CONFIG_RTL8XXXU_UNTESTED=y CONFIG_RTL8723CS=m +CONFIG_RTW88=m CONFIG_WLAN_VENDOR_RSI=y # CONFIG_RSI_91X is not set CONFIG_WLAN_VENDOR_ST=y @@ -2423,6 +2631,7 @@ CONFIG_WLAN_VENDOR_TI=y # CONFIG_WL12XX is not set # CONFIG_WL18XX is not set # CONFIG_WLCORE is not set +CONFIG_RTL8723DU=m CONFIG_RTL8723DS=m CONFIG_RTL8822BU=m CONFIG_RTL8188EU=m @@ -2441,21 +2650,37 @@ CONFIG_WLAN_VENDOR_ZYDAS=y CONFIG_WLAN_VENDOR_QUANTENNA=y CONFIG_MAC80211_HWSIM=m CONFIG_USB_NET_RNDIS_WLAN=m +# CONFIG_VIRT_WIFI is not set # # WiMAX Wireless Broadband devices # # CONFIG_WIMAX_I2400M_USB is not set +# end of WiMAX Wireless Broadband devices + # CONFIG_WAN is not set +CONFIG_IEEE802154_DRIVERS=m +# CONFIG_IEEE802154_FAKELB is not set +CONFIG_IEEE802154_AT86RF230=m +# CONFIG_IEEE802154_AT86RF230_DEBUGFS is not set +CONFIG_IEEE802154_MRF24J40=m +CONFIG_IEEE802154_CC2520=m +CONFIG_IEEE802154_ATUSB=m +CONFIG_IEEE802154_ADF7242=m +CONFIG_IEEE802154_CA8210=m +# CONFIG_IEEE802154_CA8210_DEBUGFS is not set +CONFIG_IEEE802154_MCR20A=m +CONFIG_IEEE802154_HWSIM=m CONFIG_NETDEVSIM=m CONFIG_NET_FAILOVER=m # CONFIG_ISDN is not set +# CONFIG_NVM is not set # # Input device support # CONFIG_INPUT=y -CONFIG_INPUT_LEDS=y +CONFIG_INPUT_LEDS=m CONFIG_INPUT_FF_MEMLESS=m CONFIG_INPUT_POLLDEV=m # CONFIG_INPUT_SPARSEKMAP is not set @@ -2474,15 +2699,17 @@ CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_KEYBOARD=y # CONFIG_KEYBOARD_ADC is not set +CONFIG_KEYBOARD_ADP5520=m # CONFIG_KEYBOARD_ADP5588 is not set # CONFIG_KEYBOARD_ADP5589 is not set CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_QT1050=m # CONFIG_KEYBOARD_QT1070 is not set # CONFIG_KEYBOARD_QT2160 is not set # CONFIG_KEYBOARD_DLINK_DIR685 is not set # CONFIG_KEYBOARD_LKKBD is not set -CONFIG_KEYBOARD_GPIO=y -# CONFIG_KEYBOARD_GPIO_POLLED is not set +CONFIG_KEYBOARD_GPIO=m +CONFIG_KEYBOARD_GPIO_POLLED=m # CONFIG_KEYBOARD_TCA6416 is not set # CONFIG_KEYBOARD_TCA8418 is not set CONFIG_KEYBOARD_MATRIX=m @@ -2499,9 +2726,11 @@ CONFIG_KEYBOARD_MATRIX=m CONFIG_KEYBOARD_SUN4I_LRADC=m # CONFIG_KEYBOARD_OMAP4 is not set CONFIG_KEYBOARD_TM2_TOUCHKEY=m +CONFIG_KEYBOARD_TWL4030=m # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_CAP11XX is not set # CONFIG_KEYBOARD_BCM is not set +CONFIG_KEYBOARD_MTK_PMIC=m CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=m # CONFIG_MOUSE_PS2_ALPS is not set @@ -2529,6 +2758,7 @@ CONFIG_MOUSE_SERIAL=m # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_PROPERTIES=y +CONFIG_TOUCHSCREEN_88PM860X=m CONFIG_TOUCHSCREEN_ADS7846=m # CONFIG_TOUCHSCREEN_AD7877 is not set # CONFIG_TOUCHSCREEN_AD7879 is not set @@ -2542,6 +2772,8 @@ CONFIG_TOUCHSCREEN_CHIPONE_ICN8318=m # CONFIG_TOUCHSCREEN_CY8CTMG110 is not set # CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set # CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set +CONFIG_TOUCHSCREEN_DA9034=m +CONFIG_TOUCHSCREEN_DA9052=m # CONFIG_TOUCHSCREEN_DYNAPRO is not set # CONFIG_TOUCHSCREEN_HAMPSHIRE is not set # CONFIG_TOUCHSCREEN_EETI is not set @@ -2571,14 +2803,23 @@ CONFIG_TOUCHSCREEN_ELO=m # CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set +CONFIG_TOUCHSCREEN_TI_AM335X_TSC=m +CONFIG_TOUCHSCREEN_UCB1400=m # CONFIG_TOUCHSCREEN_PIXCIR is not set # CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set +CONFIG_TOUCHSCREEN_WM831X=m +CONFIG_TOUCHSCREEN_WM97XX=m +CONFIG_TOUCHSCREEN_WM9705=y +CONFIG_TOUCHSCREEN_WM9712=y +CONFIG_TOUCHSCREEN_WM9713=y # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +CONFIG_TOUCHSCREEN_MC13783=m # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set # CONFIG_TOUCHSCREEN_TSC_SERIO is not set # CONFIG_TOUCHSCREEN_TSC2004 is not set # CONFIG_TOUCHSCREEN_TSC2005 is not set # CONFIG_TOUCHSCREEN_TSC2007 is not set +CONFIG_TOUCHSCREEN_PCAP=m # CONFIG_TOUCHSCREEN_RM_TS is not set # CONFIG_TOUCHSCREEN_SILEAD is not set # CONFIG_TOUCHSCREEN_SIS_I2C is not set @@ -2592,15 +2833,26 @@ CONFIG_TOUCHSCREEN_SUN4I=m CONFIG_TOUCHSCREEN_ZET6223=m # CONFIG_TOUCHSCREEN_ZFORCE is not set # CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set +CONFIG_TOUCHSCREEN_IQS5XX=m CONFIG_INPUT_MISC=y +CONFIG_INPUT_88PM860X_ONKEY=m +CONFIG_INPUT_88PM80X_ONKEY=m # CONFIG_INPUT_AD714X is not set +CONFIG_INPUT_ARIZONA_HAPTICS=m # CONFIG_INPUT_ATMEL_CAPTOUCH is not set # CONFIG_INPUT_BMA150 is not set # CONFIG_INPUT_E3X0_BUTTON is not set +# CONFIG_INPUT_MSM_VIBRATOR is not set +CONFIG_INPUT_MAX77650_ONKEY=m +CONFIG_INPUT_MAX77693_HAPTIC=m +CONFIG_INPUT_MAX8925_ONKEY=m +CONFIG_INPUT_MAX8997_HAPTIC=m +CONFIG_INPUT_MC13783_PWRBUTTON=m # CONFIG_INPUT_MMA8450 is not set # CONFIG_INPUT_GP2A is not set # CONFIG_INPUT_GPIO_BEEPER is not set # CONFIG_INPUT_GPIO_DECODER is not set +CONFIG_INPUT_GPIO_VIBRA=m # CONFIG_INPUT_CPCAP_PWRBUTTON is not set # CONFIG_INPUT_ATI_REMOTE2 is not set # CONFIG_INPUT_KEYSPAN_REMOTE is not set @@ -2609,19 +2861,32 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_CM109 is not set # CONFIG_INPUT_REGULATOR_HAPTIC is not set +CONFIG_INPUT_RETU_PWRBUTTON=m +CONFIG_INPUT_TPS65218_PWRBUTTON=m CONFIG_INPUT_AXP20X_PEK=y +CONFIG_INPUT_TWL4030_PWRBUTTON=m +CONFIG_INPUT_TWL4030_VIBRA=m +CONFIG_INPUT_TWL6040_VIBRA=m CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_PALMAS_PWRBUTTON=m +CONFIG_INPUT_PCF50633_PMU=m # CONFIG_INPUT_PCF8574 is not set # CONFIG_INPUT_PWM_BEEPER is not set # CONFIG_INPUT_PWM_VIBRA is not set # CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +CONFIG_INPUT_DA9052_ONKEY=m +CONFIG_INPUT_DA9055_ONKEY=m +# CONFIG_INPUT_DA9063_ONKEY is not set +CONFIG_INPUT_WM831X_ON=m +CONFIG_INPUT_PCAP=m # CONFIG_INPUT_ADXL34X is not set # CONFIG_INPUT_IMS_PCU is not set # CONFIG_INPUT_CMA3000 is not set -# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set # CONFIG_INPUT_DRV260X_HAPTICS is not set # CONFIG_INPUT_DRV2665_HAPTICS is not set # CONFIG_INPUT_DRV2667_HAPTICS is not set +CONFIG_INPUT_RAVE_SP_PWRBUTTON=m +CONFIG_INPUT_STPMIC1_ONKEY=m CONFIG_RMI4_CORE=m CONFIG_RMI4_I2C=m CONFIG_RMI4_SPI=m @@ -2650,8 +2915,10 @@ CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_APBPS2 is not set CONFIG_SERIO_SUN4I_PS2=m # CONFIG_SERIO_GPIO_PS2 is not set -# CONFIG_USERIO is not set +CONFIG_USERIO=m # CONFIG_GAMEPORT is not set +# end of Hardware I/O ports +# end of Input device support # # Character devices @@ -2664,10 +2931,14 @@ CONFIG_VT_CONSOLE_SLEEP=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_N_GSM is not set -# CONFIG_TRACE_SINK is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=0 +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_N_HDLC=m +CONFIG_N_GSM=m +CONFIG_TRACE_ROUTER=m +CONFIG_TRACE_SINK=m +CONFIG_NULL_TTY=m CONFIG_LDISC_AUTOLOAD=y CONFIG_DEVMEM=y CONFIG_DEVKMEM=y @@ -2677,14 +2948,15 @@ CONFIG_DEVKMEM=y # CONFIG_SERIAL_EARLYCON=y CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y -# CONFIG_SERIAL_8250_FINTEK is not set +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_FINTEK=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_DMA=y CONFIG_SERIAL_8250_NR_UARTS=8 CONFIG_SERIAL_8250_RUNTIME_UARTS=8 # CONFIG_SERIAL_8250_EXTENDED is not set # CONFIG_SERIAL_8250_ASPEED_VUART is not set +CONFIG_SERIAL_8250_DWLIB=y CONFIG_SERIAL_8250_FSL=y CONFIG_SERIAL_8250_DW=y # CONFIG_SERIAL_8250_EM is not set @@ -2695,34 +2967,79 @@ CONFIG_SERIAL_OF_PLATFORM=y # Non-8250 serial port support # # CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -# CONFIG_SERIAL_MAX3100 is not set -# CONFIG_SERIAL_MAX310X is not set +CONFIG_SERIAL_MAX3100=m +CONFIG_SERIAL_MAX310X=y CONFIG_SERIAL_UARTLITE=m CONFIG_SERIAL_UARTLITE_NR_UARTS=1 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_SCCNXP is not set -# CONFIG_SERIAL_SC16IS7XX is not set -# CONFIG_SERIAL_BCM63XX is not set -# CONFIG_SERIAL_ALTERA_JTAGUART is not set -# CONFIG_SERIAL_ALTERA_UART is not set +CONFIG_SERIAL_SIFIVE=m +CONFIG_SERIAL_SCCNXP=y +CONFIG_SERIAL_SCCNXP_CONSOLE=y +CONFIG_SERIAL_SC16IS7XX_CORE=m +CONFIG_SERIAL_SC16IS7XX=m +CONFIG_SERIAL_SC16IS7XX_I2C=y +CONFIG_SERIAL_SC16IS7XX_SPI=y +CONFIG_SERIAL_BCM63XX=m +CONFIG_SERIAL_ALTERA_JTAGUART=m +CONFIG_SERIAL_ALTERA_UART=m +CONFIG_SERIAL_ALTERA_UART_MAXPORTS=4 +CONFIG_SERIAL_ALTERA_UART_BAUDRATE=115200 # CONFIG_SERIAL_IFX6X60 is not set -# CONFIG_SERIAL_XILINX_PS_UART is not set -# CONFIG_SERIAL_ARC is not set -# CONFIG_SERIAL_FSL_LPUART is not set +CONFIG_SERIAL_XILINX_PS_UART=m +CONFIG_SERIAL_ARC=m +CONFIG_SERIAL_ARC_NR_PORTS=1 +CONFIG_SERIAL_FSL_LPUART=m +CONFIG_SERIAL_FSL_LINFLEXUART=m CONFIG_SERIAL_CONEXANT_DIGICOLOR=m # CONFIG_SERIAL_ST_ASC is not set -CONFIG_SERIAL_DEV_BUS=m -# CONFIG_TTY_PRINTK is not set -# CONFIG_PRINTER is not set -# CONFIG_PPDEV is not set +# end of Serial drivers + +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_DEV_BUS=y +CONFIG_SERIAL_DEV_CTRL_TTYPORT=y +CONFIG_TTY_PRINTK=y +CONFIG_TTY_PRINTK_LEVEL=6 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +CONFIG_PPDEV=m +CONFIG_HVC_DRIVER=y # CONFIG_HVC_DCC is not set -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=m -# CONFIG_HW_RANDOM_TIMERIOMEM is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -# CONFIG_XILLYBUS is not set +CONFIG_VIRTIO_CONSOLE=m +CONFIG_IPMI_HANDLER=m +CONFIG_IPMI_PLAT_DATA=y +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_SSIF=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m +# CONFIG_IPMB_DEVICE_INTERFACE is not set +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_TIMERIOMEM=m +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_HW_RANDOM_OPTEE=m +CONFIG_RAW_DRIVER=m +CONFIG_MAX_RAW_DEVS=256 +CONFIG_TCG_TPM=y +CONFIG_HW_RANDOM_TPM=y +CONFIG_TCG_TIS_CORE=y +CONFIG_TCG_TIS=y +CONFIG_TCG_TIS_SPI=m +CONFIG_TCG_TIS_I2C_ATMEL=m +CONFIG_TCG_TIS_I2C_INFINEON=m +CONFIG_TCG_TIS_I2C_NUVOTON=m +CONFIG_TCG_ATMEL=m +CONFIG_TCG_VTPM_PROXY=m +CONFIG_TCG_FTPM_TEE=m +CONFIG_TCG_TIS_ST33ZP24=m +CONFIG_TCG_TIS_ST33ZP24_I2C=m +CONFIG_TCG_TIS_ST33ZP24_SPI=m +CONFIG_XILLYBUS=m +CONFIG_XILLYBUS_OF=m +# end of Character devices + +CONFIG_RANDOM_TRUST_BOOTLOADER=y # # I2C support @@ -2731,23 +3048,27 @@ CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MUX=y +CONFIG_I2C_MUX=m # # Multiplexer I2C Chip support # CONFIG_I2C_ARB_GPIO_CHALLENGE=m CONFIG_I2C_MUX_GPIO=m -# CONFIG_I2C_MUX_GPMUX is not set -# CONFIG_I2C_MUX_LTC4306 is not set +CONFIG_I2C_MUX_GPMUX=m +CONFIG_I2C_MUX_LTC4306=m CONFIG_I2C_MUX_PCA9541=m CONFIG_I2C_MUX_PCA954x=m CONFIG_I2C_MUX_PINCTRL=m CONFIG_I2C_MUX_REG=m CONFIG_I2C_DEMUX_PINCTRL=m -# CONFIG_I2C_MUX_MLXCPLD is not set +CONFIG_I2C_MUX_MLXCPLD=m +# end of Multiplexer I2C Chip support + CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_SMBUS=m CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_ALGOPCA=m # # I2C Hardware Bus support @@ -2756,38 +3077,51 @@ CONFIG_I2C_ALGOBIT=y # # I2C system bus drivers (mostly embedded / system-on-chip) # -# CONFIG_I2C_CBUS_GPIO is not set -# CONFIG_I2C_DESIGNWARE_PLATFORM is not set -CONFIG_I2C_EMEV2=m -# CONFIG_I2C_GPIO is not set +CONFIG_I2C_CBUS_GPIO=m +CONFIG_I2C_DESIGNWARE_CORE=y +CONFIG_I2C_DESIGNWARE_PLATFORM=y +# CONFIG_I2C_DESIGNWARE_SLAVE is not set +# CONFIG_I2C_EMEV2 is not set +CONFIG_I2C_GPIO=m +# CONFIG_I2C_GPIO_FAULT_INJECTOR is not set +CONFIG_I2C_KEMPLD=m CONFIG_I2C_MV64XXX=y -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PCA_PLATFORM is not set +CONFIG_I2C_OCORES=m +CONFIG_I2C_PCA_PLATFORM=m # CONFIG_I2C_RK3X is not set -# CONFIG_I2C_SIMTEC is not set +CONFIG_I2C_SIMTEC=m CONFIG_I2C_SUN6I_P2WI=m -# CONFIG_I2C_XILINX is not set +CONFIG_I2C_XILINX=m # # External I2C/SMBus adapter drivers # -# CONFIG_I2C_DIOLAN_U2C is not set -# CONFIG_I2C_PARPORT is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_ROBOTFUZZ_OSIF is not set -# CONFIG_I2C_TAOS_EVM is not set +CONFIG_I2C_DIOLAN_U2C=m +CONFIG_I2C_DLN2=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_ROBOTFUZZ_OSIF=m +CONFIG_I2C_TAOS_EVM=m CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIPERBOARD=m # # Other I2C/SMBus bus drivers # CONFIG_I2C_FSI=m +# end of I2C Hardware Bus support + CONFIG_I2C_STUB=m CONFIG_I2C_SLAVE=y CONFIG_I2C_SLAVE_EEPROM=m # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set +# end of I2C support + +CONFIG_I3C=m +CONFIG_CDNS_I3C_MASTER=m +CONFIG_DW_I3C_MASTER=m CONFIG_SPI=y # CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y @@ -2796,33 +3130,51 @@ CONFIG_SPI_MEM=y # # SPI Master Controller Drivers # -# CONFIG_SPI_ALTERA is not set -# CONFIG_SPI_AXI_SPI_ENGINE is not set -# CONFIG_SPI_BITBANG is not set -# CONFIG_SPI_BUTTERFLY is not set -# CONFIG_SPI_CADENCE is not set -# CONFIG_SPI_DESIGNWARE is not set -# CONFIG_SPI_GPIO is not set -# CONFIG_SPI_LM70_LLP is not set -# CONFIG_SPI_FSL_SPI is not set -# CONFIG_SPI_OC_TINY is not set +CONFIG_SPI_ALTERA=m +CONFIG_SPI_AXI_SPI_ENGINE=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +CONFIG_SPI_CADENCE=m +CONFIG_SPI_DESIGNWARE=m +CONFIG_SPI_DW_MMIO=m +CONFIG_SPI_DLN2=m +CONFIG_SPI_NXP_FLEXSPI=m +CONFIG_SPI_GPIO=m +CONFIG_SPI_LM70_LLP=m +CONFIG_SPI_FSL_LIB=m +CONFIG_SPI_FSL_SPI=m +CONFIG_SPI_OC_TINY=m # CONFIG_SPI_ROCKCHIP is not set -# CONFIG_SPI_SC18IS602 is not set +CONFIG_SPI_SC18IS602=m +CONFIG_SPI_SIFIVE=m CONFIG_SPI_SUN4I=y CONFIG_SPI_SUN6I=y -# CONFIG_SPI_XCOMM is not set +CONFIG_SPI_MXIC=m +CONFIG_SPI_XCOMM=m # CONFIG_SPI_XILINX is not set -# CONFIG_SPI_ZYNQMP_GQSPI is not set +CONFIG_SPI_ZYNQMP_GQSPI=m # # SPI Protocol Masters # CONFIG_SPI_SPIDEV=m -# CONFIG_SPI_LOOPBACK_TEST is not set -# CONFIG_SPI_TLE62X0 is not set -# CONFIG_SPI_SLAVE is not set -# CONFIG_SPMI is not set -# CONFIG_HSI is not set +CONFIG_SPI_LOOPBACK_TEST=m +CONFIG_SPI_TLE62X0=m +CONFIG_SPI_SLAVE=y +CONFIG_SPI_SLAVE_TIME=m +CONFIG_SPI_SLAVE_SYSTEM_CONTROL=m +CONFIG_SPMI=m +CONFIG_HSI=m +CONFIG_HSI_BOARDINFO=y + +# +# HSI controllers +# + +# +# HSI clients +# +CONFIG_HSI_CHAR=m CONFIG_PPS=y # CONFIG_PPS_DEBUG is not set @@ -2831,7 +3183,7 @@ CONFIG_PPS=y # # CONFIG_PPS_CLIENT_KTIMER is not set CONFIG_PPS_CLIENT_LDISC=m -# CONFIG_PPS_CLIENT_PARPORT is not set +CONFIG_PPS_CLIENT_PARPORT=m CONFIG_PPS_CLIENT_GPIO=m # @@ -2842,17 +3194,23 @@ CONFIG_PPS_CLIENT_GPIO=m # PTP clock support # CONFIG_PTP_1588_CLOCK=y -# CONFIG_DP83640_PHY is not set +CONFIG_DP83640_PHY=m +# end of PTP clock support + CONFIG_PINCTRL=y CONFIG_PINMUX=y CONFIG_PINCONF=y CONFIG_GENERIC_PINCONF=y # CONFIG_DEBUG_PINCTRL is not set +CONFIG_PINCTRL_AS3722=m CONFIG_PINCTRL_AXP209=m # CONFIG_PINCTRL_AMD is not set -# CONFIG_PINCTRL_MCP23S08 is not set +CONFIG_PINCTRL_MCP23S08=m # CONFIG_PINCTRL_SINGLE is not set -# CONFIG_PINCTRL_SX150X is not set +CONFIG_PINCTRL_SX150X=y +CONFIG_PINCTRL_STMFX=m +CONFIG_PINCTRL_PALMAS=m +# CONFIG_PINCTRL_OCELOT is not set CONFIG_PINCTRL_SUNXI=y CONFIG_PINCTRL_SUN4I_A10=y CONFIG_PINCTRL_SUN5I=y @@ -2868,7 +3226,17 @@ CONFIG_PINCTRL_SUN8I_H3_R=y CONFIG_PINCTRL_SUN8I_V3S=y CONFIG_PINCTRL_SUN9I_A80=y CONFIG_PINCTRL_SUN9I_A80_R=y +CONFIG_PINCTRL_SUN50I_A64=y +CONFIG_PINCTRL_SUN50I_A64_R=y +CONFIG_PINCTRL_SUN50I_H5=y +CONFIG_PINCTRL_SUN50I_H6=y +CONFIG_PINCTRL_SUN50I_H6_R=y CONFIG_PINCTRL_MADERA=m +CONFIG_PINCTRL_CS47L15=y +CONFIG_PINCTRL_CS47L35=y +CONFIG_PINCTRL_CS47L85=y +CONFIG_PINCTRL_CS47L90=y +CONFIG_PINCTRL_CS47L92=y CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y CONFIG_GPIOLIB=y CONFIG_GPIOLIB_FASTPATH_LIMIT=512 @@ -2876,64 +3244,103 @@ CONFIG_OF_GPIO=y CONFIG_GPIOLIB_IRQCHIP=y # CONFIG_DEBUG_GPIO is not set CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_GENERIC=m +CONFIG_GPIO_MAX730X=m # # Memory mapped GPIO drivers # # CONFIG_GPIO_74XX_MMIO is not set CONFIG_GPIO_ALTERA=m +CONFIG_GPIO_CADENCE=m # CONFIG_GPIO_DWAPB is not set # CONFIG_GPIO_FTGPIO010 is not set # CONFIG_GPIO_GENERIC_PLATFORM is not set # CONFIG_GPIO_GRGPIO is not set # CONFIG_GPIO_HLWD is not set -# CONFIG_GPIO_MB86S7X is not set -# CONFIG_GPIO_MOCKUP is not set +CONFIG_GPIO_MB86S7X=m # CONFIG_GPIO_MPC8XXX is not set +CONFIG_GPIO_SAMA5D2_PIOBU=m CONFIG_GPIO_SYSCON=m -# CONFIG_GPIO_XILINX is not set +CONFIG_GPIO_XILINX=y # CONFIG_GPIO_ZEVIO is not set +CONFIG_GPIO_AMD_FCH=m +# end of Memory mapped GPIO drivers # # I2C GPIO expanders # -# CONFIG_GPIO_ADP5588 is not set +CONFIG_GPIO_ADP5588=m # CONFIG_GPIO_ADNP is not set -# CONFIG_GPIO_MAX7300 is not set -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCA953X is not set +CONFIG_GPIO_GW_PLD=m +CONFIG_GPIO_MAX7300=m +CONFIG_GPIO_MAX732X=m +CONFIG_GPIO_PCA953X=m CONFIG_GPIO_PCF857X=m -# CONFIG_GPIO_TPIC2810 is not set +CONFIG_GPIO_TPIC2810=m +# end of I2C GPIO expanders # # MFD GPIO expanders # +CONFIG_GPIO_ADP5520=m +CONFIG_GPIO_ARIZONA=m +CONFIG_GPIO_BD9571MWV=m +CONFIG_GPIO_DA9052=m +CONFIG_GPIO_DA9055=m +CONFIG_GPIO_DLN2=m # CONFIG_HTC_EGPIO is not set -# CONFIG_GPIO_MADERA is not set +CONFIG_GPIO_KEMPLD=m +CONFIG_GPIO_LP3943=m +CONFIG_GPIO_LP873X=m +CONFIG_GPIO_LP87565=m +CONFIG_GPIO_MADERA=m +CONFIG_GPIO_MAX77650=m +CONFIG_GPIO_PALMAS=y +CONFIG_GPIO_RC5T583=y +CONFIG_GPIO_TPS65086=m +CONFIG_GPIO_TPS65218=m +CONFIG_GPIO_TPS6586X=y +CONFIG_GPIO_TPS65910=y +CONFIG_GPIO_TPS65912=m +CONFIG_GPIO_TQMX86=m +CONFIG_GPIO_TWL4030=m +CONFIG_GPIO_TWL6040=m +CONFIG_GPIO_UCB1400=m +CONFIG_GPIO_WM831X=m +CONFIG_GPIO_WM8350=m +CONFIG_GPIO_WM8994=m +# end of MFD GPIO expanders # # SPI GPIO expanders # -# CONFIG_GPIO_74X164 is not set -# CONFIG_GPIO_MAX3191X is not set -# CONFIG_GPIO_MAX7301 is not set -# CONFIG_GPIO_MC33880 is not set -# CONFIG_GPIO_PISOSR is not set -# CONFIG_GPIO_XRA1403 is not set +CONFIG_GPIO_74X164=m +CONFIG_GPIO_MAX3191X=m +CONFIG_GPIO_MAX7301=m +CONFIG_GPIO_MC33880=m +CONFIG_GPIO_PISOSR=m +CONFIG_GPIO_XRA1403=m +# end of SPI GPIO expanders # # USB GPIO expanders # +CONFIG_GPIO_VIPERBOARD=m +# end of USB GPIO expanders + +# CONFIG_GPIO_MOCKUP is not set CONFIG_W1=m -CONFIG_W1_CON=y # # 1-wire Bus Masters # -# CONFIG_W1_MASTER_DS2490 is not set -# CONFIG_W1_MASTER_DS2482 is not set -# CONFIG_W1_MASTER_DS1WM is not set +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS1WM=m CONFIG_W1_MASTER_GPIO=m +CONFIG_W1_MASTER_SGI=m +# end of 1-wire Bus Masters # # 1-wire Slaves @@ -2946,17 +3353,21 @@ CONFIG_W1_SLAVE_DS2408_READBACK=y CONFIG_W1_SLAVE_DS2413=m CONFIG_W1_SLAVE_DS2406=m CONFIG_W1_SLAVE_DS2423=m -# CONFIG_W1_SLAVE_DS2805 is not set +CONFIG_W1_SLAVE_DS2805=m CONFIG_W1_SLAVE_DS2431=m CONFIG_W1_SLAVE_DS2433=m # CONFIG_W1_SLAVE_DS2433_CRC is not set -# CONFIG_W1_SLAVE_DS2438 is not set -# CONFIG_W1_SLAVE_DS2780 is not set -# CONFIG_W1_SLAVE_DS2781 is not set -# CONFIG_W1_SLAVE_DS28E04 is not set -# CONFIG_W1_SLAVE_DS28E17 is not set +CONFIG_W1_SLAVE_DS2438=m +CONFIG_W1_SLAVE_DS250X=m +CONFIG_W1_SLAVE_DS2780=m +CONFIG_W1_SLAVE_DS2781=m +CONFIG_W1_SLAVE_DS28E04=m +CONFIG_W1_SLAVE_DS28E17=m +# end of 1-wire Slaves + CONFIG_POWER_AVS=y CONFIG_POWER_RESET=y +# CONFIG_POWER_RESET_AS3722 is not set # CONFIG_POWER_RESET_BRCMKONA is not set # CONFIG_POWER_RESET_BRCMSTB is not set # CONFIG_POWER_RESET_GPIO is not set @@ -2968,44 +3379,73 @@ CONFIG_POWER_RESET_SYSCON=y CONFIG_POWER_RESET_SYSCON_POWEROFF=y CONFIG_REBOOT_MODE=y CONFIG_SYSCON_REBOOT_MODE=y +# CONFIG_NVMEM_REBOOT_MODE is not set CONFIG_POWER_SUPPLY=y # CONFIG_POWER_SUPPLY_DEBUG is not set -# CONFIG_PDA_POWER is not set -# CONFIG_GENERIC_ADC_BATTERY is not set -# CONFIG_TEST_POWER is not set +CONFIG_POWER_SUPPLY_HWMON=y +CONFIG_PDA_POWER=m +CONFIG_GENERIC_ADC_BATTERY=m +CONFIG_MAX8925_POWER=m +CONFIG_WM831X_BACKUP=m +CONFIG_WM831X_POWER=m +CONFIG_WM8350_POWER=m +CONFIG_TEST_POWER=m +CONFIG_BATTERY_88PM860X=m CONFIG_CHARGER_ADP5061=m CONFIG_BATTERY_CPCAP=m CONFIG_BATTERY_DS2760=m -# CONFIG_BATTERY_DS2780 is not set -# CONFIG_BATTERY_DS2781 is not set -# CONFIG_BATTERY_DS2782 is not set -# CONFIG_BATTERY_LEGO_EV3 is not set -# CONFIG_BATTERY_SBS is not set +CONFIG_BATTERY_DS2780=m +CONFIG_BATTERY_DS2781=m +CONFIG_BATTERY_DS2782=m +CONFIG_BATTERY_LEGO_EV3=m +CONFIG_BATTERY_SBS=m CONFIG_CHARGER_SBS=m -# CONFIG_MANAGER_SBS is not set -# CONFIG_BATTERY_BQ27XXX is not set -# CONFIG_CHARGER_AXP20X is not set +CONFIG_MANAGER_SBS=m +CONFIG_BATTERY_BQ27XXX=m +CONFIG_BATTERY_BQ27XXX_I2C=m +CONFIG_BATTERY_BQ27XXX_HDQ=m +# CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM is not set +CONFIG_BATTERY_DA9030=m +CONFIG_BATTERY_DA9052=m +CONFIG_CHARGER_DA9150=m +CONFIG_BATTERY_DA9150=m +CONFIG_CHARGER_AXP20X=m CONFIG_BATTERY_AXP20X=m CONFIG_AXP20X_POWER=m CONFIG_AXP288_FUEL_GAUGE=m -# CONFIG_BATTERY_MAX17040 is not set -# CONFIG_BATTERY_MAX17042 is not set -# CONFIG_BATTERY_MAX1721X is not set -# CONFIG_CHARGER_ISP1704 is not set -# CONFIG_CHARGER_MAX8903 is not set -# CONFIG_CHARGER_LP8727 is not set -# CONFIG_CHARGER_GPIO is not set -# CONFIG_CHARGER_MANAGER is not set -# CONFIG_CHARGER_LTC3651 is not set +CONFIG_BATTERY_MAX17040=m +CONFIG_BATTERY_MAX17042=m +CONFIG_BATTERY_MAX1721X=m +CONFIG_BATTERY_TWL4030_MADC=m +CONFIG_CHARGER_88PM860X=m +CONFIG_CHARGER_PCF50633=m +CONFIG_BATTERY_RX51=m +CONFIG_CHARGER_ISP1704=m +CONFIG_CHARGER_MAX8903=m +CONFIG_CHARGER_TWL4030=m +CONFIG_CHARGER_LP8727=m +CONFIG_CHARGER_LP8788=m +CONFIG_CHARGER_GPIO=m +CONFIG_CHARGER_MANAGER=y +CONFIG_CHARGER_LT3651=m +CONFIG_CHARGER_MAX14577=m CONFIG_CHARGER_DETECTOR_MAX14656=m -# CONFIG_CHARGER_BQ2415X is not set -# CONFIG_CHARGER_BQ24190 is not set -# CONFIG_CHARGER_BQ24257 is not set -# CONFIG_CHARGER_BQ24735 is not set -# CONFIG_CHARGER_BQ25890 is not set -# CONFIG_CHARGER_SMB347 is not set -# CONFIG_BATTERY_GAUGE_LTC2941 is not set -# CONFIG_CHARGER_RT9455 is not set +CONFIG_CHARGER_MAX77650=m +CONFIG_CHARGER_MAX77693=m +CONFIG_CHARGER_MAX8997=m +CONFIG_CHARGER_MAX8998=m +CONFIG_CHARGER_BQ2415X=m +CONFIG_CHARGER_BQ24190=m +CONFIG_CHARGER_BQ24257=m +CONFIG_CHARGER_BQ24735=m +CONFIG_CHARGER_BQ25890=m +CONFIG_CHARGER_SMB347=m +CONFIG_CHARGER_TPS65090=m +CONFIG_CHARGER_TPS65217=m +CONFIG_BATTERY_GAUGE_LTC2941=m +CONFIG_BATTERY_RT5033=m +CONFIG_CHARGER_RT9455=m +CONFIG_CHARGER_UCS1002=m CONFIG_HWMON=y CONFIG_HWMON_VID=m # CONFIG_HWMON_DEBUG_CHIP is not set @@ -3029,14 +3469,18 @@ CONFIG_SENSORS_ADT7411=m CONFIG_SENSORS_ADT7462=m CONFIG_SENSORS_ADT7470=m CONFIG_SENSORS_ADT7475=m +CONFIG_SENSORS_AS370=m CONFIG_SENSORS_ASC7621=m -# CONFIG_SENSORS_ASPEED is not set +CONFIG_SENSORS_ASPEED=m CONFIG_SENSORS_ATXP1=m CONFIG_SENSORS_DS620=m CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_DA9052_ADC=m +CONFIG_SENSORS_DA9055=m CONFIG_SENSORS_F71805F=m CONFIG_SENSORS_F71882FG=m CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_MC13783_ADC=m CONFIG_SENSORS_FTSTEUTATES=m CONFIG_SENSORS_GL518SM=m CONFIG_SENSORS_GL520SM=m @@ -3044,7 +3488,9 @@ CONFIG_SENSORS_G760A=m CONFIG_SENSORS_G762=m CONFIG_SENSORS_GPIO_FAN=m CONFIG_SENSORS_HIH6130=m -# CONFIG_SENSORS_IIO_HWMON is not set +CONFIG_SENSORS_IBMAEM=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IIO_HWMON=m CONFIG_SENSORS_IT87=m CONFIG_SENSORS_JC42=m CONFIG_SENSORS_POWR1220=m @@ -3063,14 +3509,15 @@ CONFIG_SENSORS_MAX1619=m CONFIG_SENSORS_MAX1668=m CONFIG_SENSORS_MAX197=m CONFIG_SENSORS_MAX31722=m -# CONFIG_SENSORS_MAX6621 is not set +CONFIG_SENSORS_MAX6621=m CONFIG_SENSORS_MAX6639=m CONFIG_SENSORS_MAX6642=m CONFIG_SENSORS_MAX6650=m CONFIG_SENSORS_MAX6697=m CONFIG_SENSORS_MAX31790=m CONFIG_SENSORS_MCP3021=m -# CONFIG_SENSORS_TC654 is not set +CONFIG_SENSORS_TC654=m +CONFIG_SENSORS_MENF21BMC_HWMON=m CONFIG_SENSORS_ADCXX=m CONFIG_SENSORS_LM63=m CONFIG_SENSORS_LM70=m @@ -3096,8 +3543,33 @@ CONFIG_SENSORS_NCT6775=m CONFIG_SENSORS_NCT7802=m CONFIG_SENSORS_NCT7904=m CONFIG_SENSORS_NPCM7XX=m +CONFIG_SENSORS_OCC_P8_I2C=m +CONFIG_SENSORS_OCC=m CONFIG_SENSORS_PCF8591=m -# CONFIG_PMBUS is not set +CONFIG_PMBUS=m +CONFIG_SENSORS_PMBUS=m +CONFIG_SENSORS_ADM1275=m +CONFIG_SENSORS_IBM_CFFPS=m +CONFIG_SENSORS_INSPUR_IPSPS=m +CONFIG_SENSORS_IR35221=m +CONFIG_SENSORS_IR38064=m +CONFIG_SENSORS_IRPS5401=m +CONFIG_SENSORS_ISL68137=m +CONFIG_SENSORS_LM25066=m +CONFIG_SENSORS_LTC2978=m +CONFIG_SENSORS_LTC2978_REGULATOR=y +CONFIG_SENSORS_LTC3815=m +CONFIG_SENSORS_MAX16064=m +CONFIG_SENSORS_MAX20751=m +CONFIG_SENSORS_MAX31785=m +CONFIG_SENSORS_MAX34440=m +CONFIG_SENSORS_MAX8688=m +CONFIG_SENSORS_PXE1610=m +CONFIG_SENSORS_TPS40422=m +CONFIG_SENSORS_TPS53679=m +CONFIG_SENSORS_UCD9000=m +CONFIG_SENSORS_UCD9200=m +CONFIG_SENSORS_ZL6100=m CONFIG_SENSORS_PWM_FAN=m CONFIG_SENSORS_SHT15=m CONFIG_SENSORS_SHT21=m @@ -3116,7 +3588,6 @@ CONFIG_SENSORS_SCH5636=m CONFIG_SENSORS_STTS751=m CONFIG_SENSORS_SMM665=m CONFIG_SENSORS_ADC128D818=m -CONFIG_SENSORS_ADS1015=m CONFIG_SENSORS_ADS7828=m CONFIG_SENSORS_ADS7871=m CONFIG_SENSORS_AMC6821=m @@ -3127,7 +3598,7 @@ CONFIG_SENSORS_TC74=m CONFIG_SENSORS_THMC50=m CONFIG_SENSORS_TMP102=m CONFIG_SENSORS_TMP103=m -# CONFIG_SENSORS_TMP108 is not set +CONFIG_SENSORS_TMP108=m CONFIG_SENSORS_TMP401=m CONFIG_SENSORS_TMP421=m CONFIG_SENSORS_VT1211=m @@ -3142,73 +3613,93 @@ CONFIG_SENSORS_W83L785TS=m CONFIG_SENSORS_W83L786NG=m CONFIG_SENSORS_W83627HF=m CONFIG_SENSORS_W83627EHF=m -CONFIG_THERMAL=m -# CONFIG_THERMAL_STATISTICS is not set +CONFIG_SENSORS_WM831X=m +CONFIG_SENSORS_WM8350=m +CONFIG_THERMAL=y +CONFIG_THERMAL_STATISTICS=y CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 CONFIG_THERMAL_HWMON=y CONFIG_THERMAL_OF=y CONFIG_THERMAL_WRITABLE_TRIPS=y -# CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE is not set -CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set # CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set CONFIG_THERMAL_GOV_FAIR_SHARE=y CONFIG_THERMAL_GOV_STEP_WISE=y CONFIG_THERMAL_GOV_BANG_BANG=y -# CONFIG_THERMAL_GOV_USER_SPACE is not set +CONFIG_THERMAL_GOV_USER_SPACE=y CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y CONFIG_CPU_THERMAL=y -CONFIG_CLOCK_THERMAL=y -# CONFIG_DEVFREQ_THERMAL is not set -# CONFIG_THERMAL_EMULATION is not set +# CONFIG_CLOCK_THERMAL is not set +CONFIG_DEVFREQ_THERMAL=y +CONFIG_THERMAL_EMULATION=y +CONFIG_THERMAL_MMIO=m # CONFIG_QORIQ_THERMAL is not set - -# -# ACPI INT340X thermal drivers -# -CONFIG_SUN8I_THS=m +CONFIG_SUN8I_THERMAL=m +CONFIG_DA9062_THERMAL=m CONFIG_GENERIC_ADC_THERMAL=m CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y # CONFIG_WATCHDOG_NOWAYOUT is not set CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y -# CONFIG_WATCHDOG_SYSFS is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_GPIO_WATCHDOG=m -# CONFIG_XILINX_WATCHDOG is not set -# CONFIG_ZIIRAVE_WATCHDOG is not set -# CONFIG_CADENCE_WATCHDOG is not set -CONFIG_FTWDT010_WATCHDOG=m -# CONFIG_DW_WATCHDOG is not set -CONFIG_SUNXI_WATCHDOG=y -# CONFIG_MAX63XX_WATCHDOG is not set -# CONFIG_MEN_A21_WDT is not set - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set +CONFIG_WATCHDOG_OPEN_TIMEOUT=0 +CONFIG_WATCHDOG_SYSFS=y # # Watchdog Pretimeout Governors # -# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set +CONFIG_WATCHDOG_PRETIMEOUT_GOV=y +CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m +CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP=y +CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=m +CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP=y +# CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +CONFIG_SOFT_WATCHDOG_PRETIMEOUT=y +CONFIG_DA9052_WATCHDOG=m +CONFIG_DA9055_WATCHDOG=m +CONFIG_DA9063_WATCHDOG=m +CONFIG_DA9062_WATCHDOG=m +CONFIG_GPIO_WATCHDOG=m +CONFIG_MENF21BMC_WATCHDOG=m +CONFIG_WM831X_WATCHDOG=m +CONFIG_WM8350_WATCHDOG=m +CONFIG_XILINX_WATCHDOG=m +CONFIG_ZIIRAVE_WATCHDOG=m +CONFIG_RAVE_SP_WATCHDOG=m +CONFIG_CADENCE_WATCHDOG=m +CONFIG_FTWDT010_WATCHDOG=m +CONFIG_DW_WATCHDOG=m +CONFIG_SUNXI_WATCHDOG=y +CONFIG_TWL4030_WATCHDOG=m +CONFIG_MAX63XX_WATCHDOG=m +CONFIG_RETU_WATCHDOG=m +CONFIG_STPMIC1_WATCHDOG=m +CONFIG_KEMPLD_WDT=m +CONFIG_MEN_A21_WDT=m + +# +# USB-based Watchdog Cards +# +CONFIG_USBPCWATCHDOG=m CONFIG_SSB_POSSIBLE=y CONFIG_SSB=m CONFIG_SSB_BLOCKIO=y CONFIG_SSB_SDIOHOST_POSSIBLE=y -# CONFIG_SSB_SDIOHOST is not set -# CONFIG_SSB_DRIVER_GPIO is not set +CONFIG_SSB_SDIOHOST=y +CONFIG_SSB_DRIVER_GPIO=y CONFIG_BCMA_POSSIBLE=y CONFIG_BCMA=m CONFIG_BCMA_BLOCKIO=y -# CONFIG_BCMA_HOST_SOC is not set -# CONFIG_BCMA_DRIVER_GMAC_CMN is not set -# CONFIG_BCMA_DRIVER_GPIO is not set +CONFIG_BCMA_HOST_SOC=y +CONFIG_BCMA_SFLASH=y +CONFIG_BCMA_DRIVER_GMAC_CMN=y +CONFIG_BCMA_DRIVER_GPIO=y # CONFIG_BCMA_DEBUG is not set # @@ -3217,159 +3708,248 @@ CONFIG_BCMA_BLOCKIO=y CONFIG_MFD_CORE=y # CONFIG_MFD_ACT8945A is not set CONFIG_MFD_SUN4I_GPADC=m -# CONFIG_MFD_AS3711 is not set -# CONFIG_MFD_AS3722 is not set -# CONFIG_PMIC_ADP5520 is not set -# CONFIG_MFD_AAT2870_CORE is not set -# CONFIG_MFD_ATMEL_FLEXCOM is not set -# CONFIG_MFD_ATMEL_HLCDC is not set -# CONFIG_MFD_BCM590XX is not set -# CONFIG_MFD_BD9571MWV is not set -# CONFIG_MFD_AC100 is not set +CONFIG_MFD_AS3711=y +CONFIG_MFD_AS3722=m +CONFIG_PMIC_ADP5520=y +CONFIG_MFD_AAT2870_CORE=y +CONFIG_MFD_ATMEL_FLEXCOM=m +CONFIG_MFD_ATMEL_HLCDC=m +CONFIG_MFD_BCM590XX=m +CONFIG_MFD_BD9571MWV=m +CONFIG_MFD_AC100=m +CONFIG_MFD_AC200=m CONFIG_MFD_AXP20X=y -CONFIG_MFD_AXP20X_I2C=y +CONFIG_MFD_AXP20X_I2C=m CONFIG_MFD_AXP20X_RSB=y -# CONFIG_MFD_CROS_EC is not set CONFIG_MFD_MADERA=m -# CONFIG_MFD_MADERA_I2C is not set -# CONFIG_MFD_MADERA_SPI is not set -# CONFIG_MFD_CS47L35 is not set -# CONFIG_MFD_CS47L85 is not set -# CONFIG_MFD_CS47L90 is not set +CONFIG_MFD_MADERA_I2C=m +CONFIG_MFD_MADERA_SPI=m +CONFIG_MFD_CS47L15=y +CONFIG_MFD_CS47L35=y +CONFIG_MFD_CS47L85=y +CONFIG_MFD_CS47L90=y +CONFIG_MFD_CS47L92=y # CONFIG_MFD_ASIC3 is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_MFD_DA9052_SPI is not set -# CONFIG_MFD_DA9052_I2C is not set -# CONFIG_MFD_DA9055 is not set -# CONFIG_MFD_DA9062 is not set -# CONFIG_MFD_DA9063 is not set -# CONFIG_MFD_DA9150 is not set -# CONFIG_MFD_DLN2 is not set -# CONFIG_MFD_MC13XXX_SPI is not set -# CONFIG_MFD_MC13XXX_I2C is not set +CONFIG_PMIC_DA903X=y +CONFIG_PMIC_DA9052=y +CONFIG_MFD_DA9052_SPI=y +CONFIG_MFD_DA9052_I2C=y +CONFIG_MFD_DA9055=y +CONFIG_MFD_DA9062=m +CONFIG_MFD_DA9063=y +CONFIG_MFD_DA9150=m +CONFIG_MFD_DLN2=m +CONFIG_MFD_MC13XXX=m +CONFIG_MFD_MC13XXX_SPI=m +CONFIG_MFD_MC13XXX_I2C=m # CONFIG_MFD_HI6421_PMIC is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_HTC_I2CPLD is not set -# CONFIG_MFD_KEMPLD is not set -# CONFIG_MFD_88PM800 is not set -# CONFIG_MFD_88PM805 is not set -# CONFIG_MFD_88PM860X is not set -# CONFIG_MFD_MAX14577 is not set +CONFIG_HTC_PASIC3=m +CONFIG_HTC_I2CPLD=y +CONFIG_MFD_KEMPLD=m +CONFIG_MFD_88PM800=m +CONFIG_MFD_88PM805=m +CONFIG_MFD_88PM860X=y +CONFIG_MFD_MAX14577=y # CONFIG_MFD_MAX77620 is not set +CONFIG_MFD_MAX77650=m # CONFIG_MFD_MAX77686 is not set -# CONFIG_MFD_MAX77693 is not set -# CONFIG_MFD_MAX77843 is not set -# CONFIG_MFD_MAX8907 is not set -# CONFIG_MFD_MAX8925 is not set -# CONFIG_MFD_MAX8997 is not set -# CONFIG_MFD_MAX8998 is not set -# CONFIG_MFD_MT6397 is not set -# CONFIG_MFD_MENF21BMC is not set -# CONFIG_EZX_PCAP is not set +CONFIG_MFD_MAX77693=y +CONFIG_MFD_MAX77843=y +CONFIG_MFD_MAX8907=m +CONFIG_MFD_MAX8925=y +CONFIG_MFD_MAX8997=y +CONFIG_MFD_MAX8998=y +CONFIG_MFD_MT6397=m +CONFIG_MFD_MENF21BMC=m +CONFIG_EZX_PCAP=y CONFIG_MFD_CPCAP=m -# CONFIG_MFD_VIPERBOARD is not set -# CONFIG_MFD_RETU is not set -# CONFIG_MFD_PCF50633 is not set +CONFIG_MFD_VIPERBOARD=m +CONFIG_MFD_RETU=m +CONFIG_MFD_PCF50633=m +CONFIG_PCF50633_ADC=m +CONFIG_PCF50633_GPIO=m +CONFIG_UCB1400_CORE=m # CONFIG_MFD_PM8XXX is not set -# CONFIG_MFD_RT5033 is not set -# CONFIG_MFD_RC5T583 is not set +CONFIG_MFD_RT5033=m +CONFIG_MFD_RC5T583=y # CONFIG_MFD_RK808 is not set # CONFIG_MFD_RN5T618 is not set -# CONFIG_MFD_SEC_CORE is not set -# CONFIG_MFD_SI476X_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_MFD_SKY81452 is not set -# CONFIG_MFD_SMSC is not set -# CONFIG_ABX500_CORE is not set +CONFIG_MFD_SEC_CORE=y +CONFIG_MFD_SI476X_CORE=m +CONFIG_MFD_SM501=m +CONFIG_MFD_SM501_GPIO=y +CONFIG_MFD_SKY81452=m +CONFIG_MFD_SMSC=y +CONFIG_ABX500_CORE=y +CONFIG_AB3100_CORE=y +CONFIG_AB3100_OTP=m # CONFIG_MFD_STMPE is not set CONFIG_MFD_SUN6I_PRCM=y CONFIG_MFD_SYSCON=y -# CONFIG_MFD_TI_AM335X_TSCADC is not set -# CONFIG_MFD_LP3943 is not set -# CONFIG_MFD_LP8788 is not set -# CONFIG_MFD_TI_LMU is not set -# CONFIG_MFD_PALMAS is not set -# CONFIG_TPS6105X is not set -# CONFIG_TPS65010 is not set -# CONFIG_TPS6507X is not set -# CONFIG_MFD_TPS65086 is not set -# CONFIG_MFD_TPS65090 is not set -# CONFIG_MFD_TPS65217 is not set -# CONFIG_MFD_TI_LP873X is not set -# CONFIG_MFD_TI_LP87565 is not set -# CONFIG_MFD_TPS65218 is not set -# CONFIG_MFD_TPS6586X is not set -# CONFIG_MFD_TPS65910 is not set -# CONFIG_MFD_TPS65912_I2C is not set -# CONFIG_MFD_TPS65912_SPI is not set -# CONFIG_MFD_TPS80031 is not set -# CONFIG_TWL4030_CORE is not set -# CONFIG_TWL6040_CORE is not set +CONFIG_MFD_TI_AM335X_TSCADC=m +CONFIG_MFD_LP3943=m +CONFIG_MFD_LP8788=y +CONFIG_MFD_TI_LMU=m +CONFIG_MFD_PALMAS=y +CONFIG_TPS6105X=m +CONFIG_TPS65010=m +CONFIG_TPS6507X=m +CONFIG_MFD_TPS65086=m +CONFIG_MFD_TPS65090=y +CONFIG_MFD_TPS65217=m +CONFIG_MFD_TI_LP873X=m +CONFIG_MFD_TI_LP87565=m +CONFIG_MFD_TPS65218=m +CONFIG_MFD_TPS6586X=y +CONFIG_MFD_TPS65910=y +CONFIG_MFD_TPS65912=y +CONFIG_MFD_TPS65912_I2C=y +CONFIG_MFD_TPS65912_SPI=y +CONFIG_MFD_TPS80031=y +CONFIG_TWL4030_CORE=y +# CONFIG_TWL4030_POWER is not set +CONFIG_MFD_TWL4030_AUDIO=y +CONFIG_TWL6040_CORE=y CONFIG_MFD_WL1273_CORE=m -# CONFIG_MFD_LM3533 is not set +CONFIG_MFD_LM3533=m # CONFIG_MFD_TC3589X is not set # CONFIG_MFD_T7L66XB is not set # CONFIG_MFD_TC6387XB is not set # CONFIG_MFD_TC6393XB is not set -# CONFIG_MFD_ARIZONA_I2C is not set -# CONFIG_MFD_ARIZONA_SPI is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM831X_I2C is not set -# CONFIG_MFD_WM831X_SPI is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_WM8994 is not set +CONFIG_MFD_TQMX86=m +# CONFIG_MFD_LOCHNAGAR is not set +CONFIG_MFD_ARIZONA=y +CONFIG_MFD_ARIZONA_I2C=m +CONFIG_MFD_ARIZONA_SPI=m +CONFIG_MFD_CS47L24=y +CONFIG_MFD_WM5102=y +CONFIG_MFD_WM5110=y +CONFIG_MFD_WM8997=y +CONFIG_MFD_WM8998=y +CONFIG_MFD_WM8400=y +CONFIG_MFD_WM831X=y +CONFIG_MFD_WM831X_I2C=y +CONFIG_MFD_WM831X_SPI=y +CONFIG_MFD_WM8350=y +CONFIG_MFD_WM8350_I2C=y +CONFIG_MFD_WM8994=m CONFIG_MFD_ROHM_BD718XX=m -# CONFIG_RAVE_SP_CORE is not set +# CONFIG_MFD_ROHM_BD70528 is not set +CONFIG_MFD_STPMIC1=m +CONFIG_MFD_STMFX=m +CONFIG_RAVE_SP_CORE=m +# end of Multifunction device drivers + CONFIG_REGULATOR=y # CONFIG_REGULATOR_DEBUG is not set -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_REGULATOR_VIRTUAL_CONSUMER=y -# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set -# CONFIG_REGULATOR_88PG86X is not set -# CONFIG_REGULATOR_ACT8865 is not set -# CONFIG_REGULATOR_AD5398 is not set -# CONFIG_REGULATOR_ANATOP is not set -CONFIG_REGULATOR_AXP20X=y +CONFIG_REGULATOR_FIXED_VOLTAGE=m +CONFIG_REGULATOR_VIRTUAL_CONSUMER=m +CONFIG_REGULATOR_USERSPACE_CONSUMER=m +CONFIG_REGULATOR_USERSPACE_CONSUMER_OF=m +CONFIG_REGULATOR_88PG86X=m +CONFIG_REGULATOR_88PM800=m +CONFIG_REGULATOR_88PM8607=m +CONFIG_REGULATOR_ACT8865=m +CONFIG_REGULATOR_AD5398=m +CONFIG_REGULATOR_ANATOP=m +CONFIG_REGULATOR_AAT2870=m +CONFIG_REGULATOR_AB3100=m +CONFIG_REGULATOR_ARIZONA_LDO1=m +CONFIG_REGULATOR_ARIZONA_MICSUPP=m +CONFIG_REGULATOR_AS3711=m +CONFIG_REGULATOR_AS3722=m +CONFIG_REGULATOR_AXP20X=m +CONFIG_REGULATOR_BCM590XX=m CONFIG_REGULATOR_BD718XX=m +CONFIG_REGULATOR_BD9571MWV=m CONFIG_REGULATOR_CPCAP=m -# CONFIG_REGULATOR_DA9210 is not set -# CONFIG_REGULATOR_DA9211 is not set -# CONFIG_REGULATOR_FAN53555 is not set -CONFIG_REGULATOR_GPIO=y -# CONFIG_REGULATOR_ISL9305 is not set -# CONFIG_REGULATOR_ISL6271A is not set -# CONFIG_REGULATOR_LP3971 is not set -# CONFIG_REGULATOR_LP3972 is not set -# CONFIG_REGULATOR_LP872X is not set -# CONFIG_REGULATOR_LP8755 is not set -# CONFIG_REGULATOR_LTC3589 is not set -# CONFIG_REGULATOR_LTC3676 is not set -# CONFIG_REGULATOR_MAX1586 is not set -# CONFIG_REGULATOR_MAX8649 is not set -# CONFIG_REGULATOR_MAX8660 is not set -# CONFIG_REGULATOR_MAX8952 is not set +CONFIG_REGULATOR_DA903X=m +CONFIG_REGULATOR_DA9052=m +CONFIG_REGULATOR_DA9055=m +CONFIG_REGULATOR_DA9062=m +CONFIG_REGULATOR_DA9063=m +CONFIG_REGULATOR_DA9210=m +CONFIG_REGULATOR_DA9211=m +CONFIG_REGULATOR_FAN53555=m +CONFIG_REGULATOR_GPIO=m +CONFIG_REGULATOR_ISL9305=m +CONFIG_REGULATOR_ISL6271A=m +CONFIG_REGULATOR_LM363X=m +CONFIG_REGULATOR_LP3971=m +CONFIG_REGULATOR_LP3972=m +CONFIG_REGULATOR_LP872X=m +CONFIG_REGULATOR_LP873X=m +CONFIG_REGULATOR_LP8755=m +CONFIG_REGULATOR_LP87565=m +CONFIG_REGULATOR_LP8788=m +CONFIG_REGULATOR_LTC3589=m +CONFIG_REGULATOR_LTC3676=m +CONFIG_REGULATOR_MAX14577=m +CONFIG_REGULATOR_MAX1586=m +CONFIG_REGULATOR_MAX77650=m +CONFIG_REGULATOR_MAX8649=m +CONFIG_REGULATOR_MAX8660=m +CONFIG_REGULATOR_MAX8907=m +CONFIG_REGULATOR_MAX8925=m +CONFIG_REGULATOR_MAX8952=m # CONFIG_REGULATOR_MAX8973 is not set -# CONFIG_REGULATOR_MT6311 is not set -# CONFIG_REGULATOR_PFUZE100 is not set -# CONFIG_REGULATOR_PV88060 is not set -# CONFIG_REGULATOR_PV88080 is not set -# CONFIG_REGULATOR_PV88090 is not set +CONFIG_REGULATOR_MAX8997=m +CONFIG_REGULATOR_MAX8998=m +CONFIG_REGULATOR_MAX77693=m +CONFIG_REGULATOR_MC13XXX_CORE=m +CONFIG_REGULATOR_MC13783=m +CONFIG_REGULATOR_MC13892=m +CONFIG_REGULATOR_MCP16502=m +CONFIG_REGULATOR_MT6311=m +CONFIG_REGULATOR_MT6323=m +CONFIG_REGULATOR_MT6397=m +CONFIG_REGULATOR_PALMAS=m +CONFIG_REGULATOR_PCAP=m +CONFIG_REGULATOR_PCF50633=m +CONFIG_REGULATOR_PFUZE100=m +CONFIG_REGULATOR_PV88060=m +CONFIG_REGULATOR_PV88080=m +CONFIG_REGULATOR_PV88090=m CONFIG_REGULATOR_PWM=m +CONFIG_REGULATOR_QCOM_SPMI=m +CONFIG_REGULATOR_RC5T583=m +CONFIG_REGULATOR_RT5033=m +CONFIG_REGULATOR_S2MPA01=m +CONFIG_REGULATOR_S2MPS11=m +CONFIG_REGULATOR_S5M8767=m +CONFIG_REGULATOR_SKY81452=m +CONFIG_REGULATOR_SLG51000=m +CONFIG_REGULATOR_STPMIC1=m CONFIG_REGULATOR_SY8106A=m -# CONFIG_REGULATOR_TPS51632 is not set -# CONFIG_REGULATOR_TPS62360 is not set -# CONFIG_REGULATOR_TPS65023 is not set -# CONFIG_REGULATOR_TPS6507X is not set -# CONFIG_REGULATOR_TPS65132 is not set -# CONFIG_REGULATOR_TPS6524X is not set -# CONFIG_REGULATOR_VCTRL is not set +CONFIG_REGULATOR_SY8824X=m +CONFIG_REGULATOR_TPS51632=m +CONFIG_REGULATOR_TPS6105X=m +CONFIG_REGULATOR_TPS62360=m +CONFIG_REGULATOR_TPS65023=m +CONFIG_REGULATOR_TPS6507X=m +CONFIG_REGULATOR_TPS65086=m +CONFIG_REGULATOR_TPS65090=m +CONFIG_REGULATOR_TPS65132=m +CONFIG_REGULATOR_TPS65217=m +CONFIG_REGULATOR_TPS65218=m +CONFIG_REGULATOR_TPS6524X=m +CONFIG_REGULATOR_TPS6586X=m +CONFIG_REGULATOR_TPS65910=m +CONFIG_REGULATOR_TPS65912=m +CONFIG_REGULATOR_TPS80031=m +CONFIG_REGULATOR_TWL4030=m +CONFIG_REGULATOR_VCTRL=m +CONFIG_REGULATOR_WM831X=m +CONFIG_REGULATOR_WM8350=m +CONFIG_REGULATOR_WM8400=m +CONFIG_REGULATOR_WM8994=m +CONFIG_REGULATOR_TP65185X=m CONFIG_CEC_CORE=m CONFIG_CEC_NOTIFIER=y CONFIG_CEC_PIN=y -CONFIG_RC_CORE=y +CONFIG_RC_CORE=m CONFIG_RC_MAP=m CONFIG_LIRC=y -# CONFIG_BPF_LIRC_MODE2 is not set CONFIG_RC_DECODERS=y CONFIG_IR_NEC_DECODER=m CONFIG_IR_RC5_DECODER=m @@ -3381,26 +3961,29 @@ CONFIG_IR_SHARP_DECODER=m CONFIG_IR_MCE_KBD_DECODER=m CONFIG_IR_XMP_DECODER=m CONFIG_IR_IMON_DECODER=m +CONFIG_IR_RCMM_DECODER=m CONFIG_RC_DEVICES=y -# CONFIG_RC_ATI_REMOTE is not set -# CONFIG_IR_HIX5HD2 is not set -# CONFIG_IR_IMON is not set -# CONFIG_IR_IMON_RAW is not set -# CONFIG_IR_MCEUSB is not set -# CONFIG_IR_REDRAT3 is not set +CONFIG_RC_ATI_REMOTE=m +CONFIG_IR_HIX5HD2=m +CONFIG_IR_IMON=m +CONFIG_IR_IMON_RAW=m +CONFIG_IR_MCEUSB=m +CONFIG_IR_REDRAT3=m CONFIG_IR_SPI=m -# CONFIG_IR_STREAMZAP is not set -# CONFIG_IR_IGORPLUGUSB is not set -# CONFIG_IR_IGUANA is not set -# CONFIG_IR_TTUSBIR is not set -# CONFIG_RC_LOOPBACK is not set -# CONFIG_IR_GPIO_CIR is not set +CONFIG_IR_STREAMZAP=m +CONFIG_IR_IGORPLUGUSB=m +CONFIG_IR_IGUANA=m +CONFIG_IR_TTUSBIR=m +CONFIG_RC_LOOPBACK=m +CONFIG_IR_GPIO_CIR=m CONFIG_IR_GPIO_TX=m -# CONFIG_IR_PWM_TX is not set +CONFIG_IR_PWM_TX=m CONFIG_IR_SUNXI=m -# CONFIG_IR_SERIAL is not set +CONFIG_IR_SERIAL=m +CONFIG_IR_SERIAL_TRANSMITTER=y # CONFIG_IR_SIR is not set -CONFIG_MEDIA_SUPPORT=y +CONFIG_RC_XBOX_DVD=m +CONFIG_MEDIA_SUPPORT=m # # Multimedia core support @@ -3410,23 +3993,25 @@ CONFIG_MEDIA_ANALOG_TV_SUPPORT=y CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y CONFIG_MEDIA_RADIO_SUPPORT=y CONFIG_MEDIA_SDR_SUPPORT=y -# CONFIG_MEDIA_CEC_SUPPORT is not set +CONFIG_MEDIA_CEC_SUPPORT=y # CONFIG_MEDIA_CEC_RC is not set # CONFIG_CEC_PIN_ERROR_INJ is not set CONFIG_MEDIA_CONTROLLER=y -# CONFIG_MEDIA_CONTROLLER_DVB is not set -CONFIG_VIDEO_DEV=y +CONFIG_MEDIA_CONTROLLER_DVB=y +CONFIG_MEDIA_CONTROLLER_REQUEST_API=y +CONFIG_VIDEO_DEV=m CONFIG_VIDEO_V4L2_SUBDEV_API=y -CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L2_I2C=y # CONFIG_VIDEO_ADV_DEBUG is not set CONFIG_VIDEO_FIXED_MINOR_RANGES=y CONFIG_VIDEO_TUNER=m CONFIG_V4L2_MEM2MEM_DEV=m CONFIG_V4L2_FLASH_LED_CLASS=m -CONFIG_V4L2_FWNODE=y +CONFIG_V4L2_FWNODE=m CONFIG_VIDEOBUF_GEN=m CONFIG_VIDEOBUF_VMALLOC=m -CONFIG_DVB_CORE=y +CONFIG_DVB_CORE=m # CONFIG_DVB_MMAP is not set CONFIG_DVB_NET=y CONFIG_TTPCI_EEPROM=m @@ -3515,14 +4100,17 @@ CONFIG_VIDEO_HDPVR=m CONFIG_VIDEO_USBVISION=m CONFIG_VIDEO_STK1160_COMMON=m CONFIG_VIDEO_STK1160=m -# CONFIG_VIDEO_GO7007 is not set +CONFIG_VIDEO_GO7007=m +CONFIG_VIDEO_GO7007_USB=m +CONFIG_VIDEO_GO7007_LOADER=m +CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m # # Analog/digital TV USB devices # CONFIG_VIDEO_AU0828=m CONFIG_VIDEO_AU0828_V4L2=y -# CONFIG_VIDEO_AU0828_RC is not set +CONFIG_VIDEO_AU0828_RC=y CONFIG_VIDEO_CX231XX=m CONFIG_VIDEO_CX231XX_RC=y CONFIG_VIDEO_CX231XX_ALSA=m @@ -3544,6 +4132,7 @@ CONFIG_DVB_USB_DIBUSB_MC=m CONFIG_DVB_USB_DIB0700=m CONFIG_DVB_USB_UMT_010=m CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_CXUSB_ANALOG=y CONFIG_DVB_USB_M920X=m CONFIG_DVB_USB_DIGITV=m CONFIG_DVB_USB_VP7045=m @@ -3561,7 +4150,7 @@ CONFIG_DVB_USB_CINERGY_T2=m CONFIG_DVB_USB_DTV5100=m CONFIG_DVB_USB_AZ6027=m CONFIG_DVB_USB_TECHNISAT_USB2=m -CONFIG_DVB_USB_V2=y +CONFIG_DVB_USB_V2=m CONFIG_DVB_USB_AF9015=m CONFIG_DVB_USB_AF9035=m CONFIG_DVB_USB_ANYSEE=m @@ -3595,25 +4184,35 @@ CONFIG_VIDEO_EM28XX_RC=m CONFIG_USB_AIRSPY=m CONFIG_USB_HACKRF=m CONFIG_USB_MSI2500=m + +# +# USB HDMI CEC adapters +# +CONFIG_USB_PULSE8_CEC=m +CONFIG_USB_RAINSHADOW_CEC=m CONFIG_V4L_PLATFORM_DRIVERS=y -# CONFIG_VIDEO_CADENCE is not set +CONFIG_VIDEO_CADENCE=y +CONFIG_VIDEO_CADENCE_CSI2RX=m +CONFIG_VIDEO_CADENCE_CSI2TX=m +CONFIG_VIDEO_ASPEED=m # CONFIG_VIDEO_MUX is not set -# CONFIG_SOC_CAMERA is not set # CONFIG_VIDEO_XILINX is not set -CONFIG_VIDEO_SUN6I_CSI=y +CONFIG_VIDEO_SUN4I_CSI=m +CONFIG_VIDEO_SUN6I_CSI=m CONFIG_V4L_MEM2MEM_DRIVERS=y -# CONFIG_VIDEO_MEM2MEM_DEINTERLACE is not set -# CONFIG_VIDEO_SH_VEU is not set +CONFIG_VIDEO_MEM2MEM_DEINTERLACE=m +CONFIG_VIDEO_SH_VEU=m CONFIG_V4L_TEST_DRIVERS=y -# CONFIG_VIDEO_VIMC is not set +CONFIG_VIDEO_VIMC=m CONFIG_VIDEO_VIVID=m -# CONFIG_VIDEO_VIVID_CEC is not set +CONFIG_VIDEO_VIVID_CEC=y CONFIG_VIDEO_VIVID_MAX_DEVS=64 CONFIG_VIDEO_VIM2M=m CONFIG_VIDEO_VICODEC=m CONFIG_DVB_PLATFORM_DRIVERS=y CONFIG_DVB_C8SECTPFE=m -# CONFIG_SDR_PLATFORM_DRIVERS is not set +CONFIG_CEC_PLATFORM_DRIVERS=y +CONFIG_SDR_PLATFORM_DRIVERS=y # # Supported MMC/SDIO adapters @@ -3621,13 +4220,14 @@ CONFIG_DVB_C8SECTPFE=m CONFIG_SMS_SDIO_DRV=m CONFIG_RADIO_ADAPTERS=y CONFIG_RADIO_TEA575X=m -CONFIG_RADIO_SI470X=y +CONFIG_RADIO_SI470X=m CONFIG_USB_SI470X=m CONFIG_I2C_SI470X=m CONFIG_RADIO_SI4713=m CONFIG_USB_SI4713=m CONFIG_PLATFORM_SI4713=m CONFIG_I2C_SI4713=m +CONFIG_RADIO_SI476X=m CONFIG_USB_MR800=m CONFIG_USB_DSBR=m CONFIG_RADIO_SHARK=m @@ -3643,6 +4243,8 @@ CONFIG_RADIO_WL1273=m # # Texas Instruments WL128x FM driver (ST based) # +# end of Texas Instruments WL128x FM driver (ST based) + CONFIG_MEDIA_COMMON_OPTIONS=y # @@ -3651,10 +4253,10 @@ CONFIG_MEDIA_COMMON_OPTIONS=y CONFIG_VIDEO_CX2341X=m CONFIG_VIDEO_TVEEPROM=m CONFIG_CYPRESS_FIRMWARE=m -CONFIG_VIDEOBUF2_CORE=y -CONFIG_VIDEOBUF2_V4L2=y -CONFIG_VIDEOBUF2_MEMOPS=y -CONFIG_VIDEOBUF2_DMA_CONTIG=y +CONFIG_VIDEOBUF2_CORE=m +CONFIG_VIDEOBUF2_V4L2=m +CONFIG_VIDEOBUF2_MEMOPS=m +CONFIG_VIDEOBUF2_DMA_CONTIG=m CONFIG_VIDEOBUF2_VMALLOC=m CONFIG_DVB_B2C2_FLEXCOP=m CONFIG_SMS_SIANO_MDTV=m @@ -3713,10 +4315,6 @@ CONFIG_VIDEO_BT856=m CONFIG_VIDEO_BT866=m CONFIG_VIDEO_KS0127=m CONFIG_VIDEO_ML86V7667=m -# CONFIG_VIDEO_AD5820 is not set -CONFIG_VIDEO_AK7375=m -# CONFIG_VIDEO_DW9714 is not set -CONFIG_VIDEO_DW9807_VCM=m CONFIG_VIDEO_SAA7110=m CONFIG_VIDEO_SAA711X=m CONFIG_VIDEO_TC358743=m @@ -3754,26 +4352,33 @@ CONFIG_VIDEO_THS8200=m # # Camera sensor devices # +CONFIG_VIDEO_IMX214=m # CONFIG_VIDEO_IMX258 is not set # CONFIG_VIDEO_IMX274 is not set +CONFIG_VIDEO_IMX319=m +CONFIG_VIDEO_IMX355=m # CONFIG_VIDEO_OV2640 is not set # CONFIG_VIDEO_OV2659 is not set CONFIG_VIDEO_OV2680=m CONFIG_VIDEO_OV2685=m -# CONFIG_VIDEO_OV5640 is not set +CONFIG_VIDEO_OV5640=m CONFIG_VIDEO_OV5645=m CONFIG_VIDEO_OV5647=m # CONFIG_VIDEO_OV6650 is not set # CONFIG_VIDEO_OV5670 is not set +CONFIG_VIDEO_OV5675=m CONFIG_VIDEO_OV5695=m CONFIG_VIDEO_OV7251=m CONFIG_VIDEO_OV772X=m # CONFIG_VIDEO_OV7640 is not set # CONFIG_VIDEO_OV7670 is not set CONFIG_VIDEO_OV7740=m +CONFIG_VIDEO_OV8856=m +CONFIG_VIDEO_OV9640=m # CONFIG_VIDEO_OV9650 is not set # CONFIG_VIDEO_OV13858 is not set # CONFIG_VIDEO_VS6624 is not set +CONFIG_VIDEO_MT9M001=m # CONFIG_VIDEO_MT9M032 is not set # CONFIG_VIDEO_MT9M111 is not set # CONFIG_VIDEO_MT9P031 is not set @@ -3793,6 +4398,14 @@ CONFIG_VIDEO_RJ54N1=m # CONFIG_VIDEO_SMIAPP is not set CONFIG_VIDEO_ET8EK8=m # CONFIG_VIDEO_S5C73M3 is not set + +# +# Lens drivers +# +# CONFIG_VIDEO_AD5820 is not set +CONFIG_VIDEO_AK7375=m +# CONFIG_VIDEO_DW9714 is not set +CONFIG_VIDEO_DW9807_VCM=m CONFIG_VIDEO_HM5065=m # @@ -3824,21 +4437,22 @@ CONFIG_VIDEO_SAA6752HS=m CONFIG_VIDEO_THS7303=m CONFIG_VIDEO_M52790=m CONFIG_VIDEO_I2C=m - -# -# Sensors used on soc_camera driver -# +CONFIG_VIDEO_ST_MIPID02=m +# end of I2C Encoders, decoders, sensors and other helper chips # # SPI helper chips # # CONFIG_VIDEO_GS1662 is not set +# end of SPI helper chips # # Media SPI Adapters # CONFIG_CXD2880_SPI_DRV=m -CONFIG_MEDIA_TUNER=y +# end of Media SPI Adapters + +CONFIG_MEDIA_TUNER=m # # Customize TV tuners @@ -3880,6 +4494,7 @@ CONFIG_MEDIA_TUNER_R820T=m CONFIG_MEDIA_TUNER_MXL301RF=m CONFIG_MEDIA_TUNER_QM1D1C0042=m CONFIG_MEDIA_TUNER_QM1D1B0004=m +# end of Customize TV tuners # # Customise DVB Frontends @@ -4021,6 +4636,7 @@ CONFIG_DVB_TUNER_DIB0090=m # CONFIG_DVB_DRX39XYJ=m CONFIG_DVB_LNBH25=m +CONFIG_DVB_LNBH29=m CONFIG_DVB_LNBP21=m CONFIG_DVB_LNBP22=m CONFIG_DVB_ISL6405=m @@ -4048,12 +4664,14 @@ CONFIG_DVB_SP2=m # Tools to develop new frontends # CONFIG_DVB_DUMMY_FE=m +# end of Customise DVB Frontends # # Graphics support # # CONFIG_IMX_IPUV3_CORE is not set CONFIG_DRM=y +CONFIG_DRM_MIPI_DBI=m CONFIG_DRM_MIPI_DSI=y # CONFIG_DRM_DP_AUX_CHARDEV is not set # CONFIG_DRM_DEBUG_MM is not set @@ -4068,35 +4686,42 @@ CONFIG_DRM_LOAD_EDID_FIRMWARE=y CONFIG_DRM_TTM=m CONFIG_DRM_GEM_CMA_HELPER=y CONFIG_DRM_KMS_CMA_HELPER=y +CONFIG_DRM_GEM_SHMEM_HELPER=y CONFIG_DRM_SCHED=m # # I2C encoder or helper chips # -# CONFIG_DRM_I2C_CH7006 is not set -# CONFIG_DRM_I2C_SIL164 is not set -# CONFIG_DRM_I2C_NXP_TDA998X is not set +CONFIG_DRM_I2C_CH7006=m +CONFIG_DRM_I2C_SIL164=m +CONFIG_DRM_I2C_NXP_TDA998X=m # CONFIG_DRM_I2C_NXP_TDA9950 is not set -CONFIG_DRM_ARM=y +# end of I2C encoder or helper chips + +# +# ARM devices +# # CONFIG_DRM_HDLCD is not set CONFIG_DRM_MALI_DISPLAY=m +CONFIG_DRM_KOMEDA=m +# end of ARM devices # # ACP (Audio CoProcessor) Configuration # +# end of ACP (Audio CoProcessor) Configuration -# -# AMD Library routines -# # CONFIG_DRM_VGEM is not set CONFIG_DRM_VKMS=m # CONFIG_DRM_EXYNOS is not set # CONFIG_DRM_UDL is not set # CONFIG_DRM_ARMADA is not set +CONFIG_DRM_ATMEL_HLCDC=m CONFIG_DRM_RCAR_DW_HDMI=m # CONFIG_DRM_RCAR_LVDS is not set CONFIG_DRM_SUN4I=m CONFIG_DRM_SUN4I_HDMI=m +CONFIG_DRM_SUN4I_HDMI_AUDIO=y CONFIG_DRM_SUN4I_HDMI_CEC=y CONFIG_DRM_SUN4I_BACKEND=m CONFIG_DRM_SUN6I_DSI=m @@ -4105,6 +4730,7 @@ CONFIG_DRM_SUN8I_MIXER=m CONFIG_DRM_SUN8I_TCON_TOP=m # CONFIG_DRM_OMAP is not set # CONFIG_DRM_TILCDC is not set +CONFIG_DRM_VIRTIO_GPU=m # CONFIG_DRM_FSL_DCU is not set # CONFIG_DRM_STM is not set CONFIG_DRM_PANEL=y @@ -4115,29 +4741,51 @@ CONFIG_DRM_PANEL=y CONFIG_DRM_PANEL_ARM_VERSATILE=m CONFIG_DRM_PANEL_LVDS=m CONFIG_DRM_PANEL_SIMPLE=m +CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D=m CONFIG_DRM_PANEL_ILITEK_IL9322=m CONFIG_DRM_PANEL_ILITEK_ILI9881C=m # CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set # CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set +CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04=m # CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set +CONFIG_DRM_PANEL_LG_LB035Q02=m # CONFIG_DRM_PANEL_LG_LG4573 is not set +CONFIG_DRM_PANEL_NEC_NL8048HL11=m +CONFIG_DRM_PANEL_NOVATEK_NT39016=m +CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO=m # CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set +# CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS is not set # CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set # CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set +CONFIG_DRM_PANEL_RAYDIUM_RM67191=m CONFIG_DRM_PANEL_RAYDIUM_RM68200=m +CONFIG_DRM_PANEL_ROCKTECH_JH057N00900=m +CONFIG_DRM_PANEL_RONBO_RB070D30=m +CONFIG_DRM_PANEL_SAMSUNG_S6D16D0=m # CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set # CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set # CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set # CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set # CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set +CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m # CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set +CONFIG_DRM_PANEL_SITRONIX_ST7701=m CONFIG_DRM_PANEL_SITRONIX_ST7789V=m +CONFIG_DRM_PANEL_SONY_ACX565AKM=m +CONFIG_DRM_PANEL_TPO_TD028TTEC1=m +CONFIG_DRM_PANEL_TPO_TD043MTEA1=m +CONFIG_DRM_PANEL_TPO_TPG110=m +CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m +# end of Display Panels + CONFIG_DRM_BRIDGE=y CONFIG_DRM_PANEL_BRIDGE=y # # Display Interface Bridges # +# CONFIG_DRM_ANALOGIX_ANX78XX is not set # CONFIG_DRM_CDNS_DSI is not set # CONFIG_DRM_DUMB_VGA_DAC is not set # CONFIG_DRM_LVDS_ENCODER is not set @@ -4148,21 +4796,26 @@ CONFIG_DRM_PANEL_BRIDGE=y # CONFIG_DRM_SII902X is not set # CONFIG_DRM_SII9234 is not set # CONFIG_DRM_THINE_THC63LVD1024 is not set +CONFIG_DRM_TOSHIBA_TC358764=m # CONFIG_DRM_TOSHIBA_TC358767 is not set # CONFIG_DRM_TI_TFP410 is not set -CONFIG_DRM_ANALOGIX_DP_I2C=m -# CONFIG_DRM_ANALOGIX_ANX78XX is not set +CONFIG_DRM_TI_SN65DSI86=m CONFIG_DRM_ANALOGIX_ANX6345=m +CONFIG_DRM_ANALOGIX_DP=m # CONFIG_DRM_I2C_ADV7511 is not set CONFIG_DRM_DW_HDMI=m CONFIG_DRM_DW_HDMI_AHB_AUDIO=m CONFIG_DRM_DW_HDMI_I2S_AUDIO=m CONFIG_DRM_DW_HDMI_CEC=m +# end of Display Interface Bridges + # CONFIG_DRM_STI is not set +CONFIG_DRM_ETNAVIV=m +CONFIG_DRM_ETNAVIV_THERMAL=y # CONFIG_DRM_ARCPGU is not set # CONFIG_DRM_MXSFB is not set -CONFIG_DRM_TINYDRM=m -CONFIG_TINYDRM_MIPI_DBI=m +CONFIG_DRM_GM12U320=m +CONFIG_TINYDRM_HX8357D=m # CONFIG_TINYDRM_ILI9225 is not set CONFIG_TINYDRM_ILI9341=m CONFIG_TINYDRM_MI0283QT=m @@ -4172,6 +4825,8 @@ CONFIG_TINYDRM_MI0283QT=m # CONFIG_DRM_PL111 is not set # CONFIG_DRM_TVE200 is not set CONFIG_DRM_LIMA=m +CONFIG_DRM_PANFROST=m +# CONFIG_DRM_MCDE is not set # CONFIG_DRM_LEGACY is not set CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y @@ -4191,53 +4846,72 @@ CONFIG_FB_SYS_IMAGEBLIT=y # CONFIG_FB_FOREIGN_ENDIAN is not set CONFIG_FB_SYS_FOPS=y CONFIG_FB_DEFERRED_IO=y -CONFIG_FB_BACKLIGHT=y -CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_BACKLIGHT=m +# CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set # # Frame buffer hardware drivers # -CONFIG_FB_UVESA=m # CONFIG_FB_OPENCORES is not set # CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_SUN5I_EINK is not set +CONFIG_FB_SM501=m # CONFIG_FB_SMSCUFX is not set # CONFIG_FB_UDL is not set # CONFIG_FB_IBM_GXT4500 is not set # CONFIG_FB_VIRTUAL is not set # CONFIG_FB_METRONOME is not set -# CONFIG_FB_BROADSHEET is not set CONFIG_FB_SIMPLE=y # CONFIG_FB_SSD1307 is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y +# end of Frame buffer Devices + +# +# Backlight & LCD device support +# CONFIG_LCD_CLASS_DEVICE=m -# CONFIG_LCD_L4F00242T03 is not set -# CONFIG_LCD_LMS283GF05 is not set -# CONFIG_LCD_LTV350QV is not set -# CONFIG_LCD_ILI922X is not set -# CONFIG_LCD_ILI9320 is not set -# CONFIG_LCD_TDO24M is not set -# CONFIG_LCD_VGG2432A4 is not set -# CONFIG_LCD_PLATFORM is not set -# CONFIG_LCD_S6E63M0 is not set -# CONFIG_LCD_LD9040 is not set -# CONFIG_LCD_AMS369FG06 is not set -# CONFIG_LCD_LMS501KF03 is not set -# CONFIG_LCD_HX8357 is not set +CONFIG_LCD_L4F00242T03=m +CONFIG_LCD_LMS283GF05=m +CONFIG_LCD_LTV350QV=m +CONFIG_LCD_ILI922X=m +CONFIG_LCD_ILI9320=m +CONFIG_LCD_TDO24M=m +CONFIG_LCD_VGG2432A4=m +CONFIG_LCD_PLATFORM=m +CONFIG_LCD_AMS369FG06=m +CONFIG_LCD_LMS501KF03=m +CONFIG_LCD_HX8357=m # CONFIG_LCD_OTM3225A is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BACKLIGHT_GENERIC=m +CONFIG_BACKLIGHT_LM3533=m CONFIG_BACKLIGHT_PWM=m +CONFIG_BACKLIGHT_DA903X=m +# CONFIG_BACKLIGHT_DA9052 is not set +CONFIG_BACKLIGHT_MAX8925=m # CONFIG_BACKLIGHT_PM8941_WLED is not set +CONFIG_BACKLIGHT_WM831X=m +CONFIG_BACKLIGHT_ADP5520=m # CONFIG_BACKLIGHT_ADP8860 is not set # CONFIG_BACKLIGHT_ADP8870 is not set +CONFIG_BACKLIGHT_88PM860X=m +CONFIG_BACKLIGHT_PCF50633=m +CONFIG_BACKLIGHT_AAT2870=m # CONFIG_BACKLIGHT_LM3630A is not set # CONFIG_BACKLIGHT_LM3639 is not set # CONFIG_BACKLIGHT_LP855X is not set +CONFIG_BACKLIGHT_LP8788=m +CONFIG_BACKLIGHT_PANDORA=m +CONFIG_BACKLIGHT_SKY81452=m +CONFIG_BACKLIGHT_TPS65217=m +CONFIG_BACKLIGHT_AS3711=m # CONFIG_BACKLIGHT_GPIO is not set # CONFIG_BACKLIGHT_LV5207LP is not set # CONFIG_BACKLIGHT_BD6107 is not set # CONFIG_BACKLIGHT_ARCXCNN is not set +CONFIG_BACKLIGHT_RAVE_SP=m +# end of Backlight & LCD device support + CONFIG_VIDEOMODE_HELPERS=y CONFIG_HDMI=y @@ -4249,11 +4923,16 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y # CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set +CONFIG_BOOTSPLASH=y +# end of Console display driver support + CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set # CONFIG_LOGO_LINUX_CLUT224 is not set CONFIG_LOGO_ARMBIAN_CLUT224=y +# end of Graphics support + CONFIG_SOUND=m CONFIG_SND=m CONFIG_SND_TIMER=m @@ -4281,6 +4960,7 @@ CONFIG_SND_SEQUENCER=m CONFIG_SND_SEQ_MIDI_EVENT=m CONFIG_SND_SEQ_MIDI=m CONFIG_SND_SEQ_VIRMIDI=m +CONFIG_SND_AC97_CODEC=m CONFIG_SND_DRIVERS=y CONFIG_SND_DUMMY=m CONFIG_SND_ALOOP=m @@ -4290,15 +4970,19 @@ CONFIG_SND_VIRMIDI=m # CONFIG_SND_SERIAL_U16550 is not set # CONFIG_SND_MPU401 is not set # CONFIG_SND_PORTMAN2X4 is not set +# CONFIG_SND_AC97_POWER_SAVE is not set # # HD-Audio # +# end of HD-Audio + CONFIG_SND_HDA_PREALLOC_SIZE=64 # CONFIG_SND_ARM is not set # CONFIG_SND_SPI is not set CONFIG_SND_USB=y CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y CONFIG_SND_USB_UA101=m CONFIG_SND_USB_CAIAQ=m # CONFIG_SND_USB_CAIAQ_INPUT is not set @@ -4311,6 +4995,7 @@ CONFIG_SND_USB_PODHD=m CONFIG_SND_USB_TONEPORT=m CONFIG_SND_USB_VARIAX=m CONFIG_SND_SOC=m +CONFIG_SND_SOC_AC97_BUS=y CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y # CONFIG_SND_SOC_AMD_ACP is not set # CONFIG_SND_ATMEL_SOC is not set @@ -4325,16 +5010,23 @@ CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y # # CONFIG_SND_SOC_FSL_ASRC is not set # CONFIG_SND_SOC_FSL_SAI is not set +CONFIG_SND_SOC_FSL_AUDMIX=m # CONFIG_SND_SOC_FSL_SSI is not set # CONFIG_SND_SOC_FSL_SPDIF is not set # CONFIG_SND_SOC_FSL_ESAI is not set +# CONFIG_SND_SOC_FSL_MICFIL is not set # CONFIG_SND_SOC_IMX_AUDMUX is not set +# end of SoC Audio for Freescale CPUs + # CONFIG_SND_I2S_HI6210_I2S is not set # CONFIG_SND_SOC_IMG is not set +CONFIG_SND_SOC_MTK_BTCVSD=m +# CONFIG_SND_SOC_SOF_TOPLEVEL is not set # # STMicroelectronics STM32 SOC audio support # +# end of STMicroelectronics STM32 SOC audio support # # Allwinner SoC Audio support @@ -4346,6 +5038,11 @@ CONFIG_SND_SUN8I_CODEC_ANALOG=m CONFIG_SND_SUN4I_I2S=m CONFIG_SND_SUN4I_SPDIF=m CONFIG_SND_SUN8I_ADDA_PR_REGMAP=m +# end of Allwinner SoC Audio support + +CONFIG_SND_SOC_XILINX_I2S=m +CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER=m +CONFIG_SND_SOC_XILINX_SPDIF=m # CONFIG_SND_SOC_XTFPGA_I2S is not set # CONFIG_ZX_TDM is not set CONFIG_SND_SOC_I2C_AND_SPI=m @@ -4353,12 +5050,16 @@ CONFIG_SND_SOC_I2C_AND_SPI=m # # CODEC drivers # -# CONFIG_SND_SOC_AC97_CODEC is not set +CONFIG_SND_SOC_AC97_CODEC=m +CONFIG_SND_SOC_ADAU_UTILS=m # CONFIG_SND_SOC_ADAU1701 is not set -# CONFIG_SND_SOC_ADAU1761_I2C is not set -# CONFIG_SND_SOC_ADAU1761_SPI is not set -# CONFIG_SND_SOC_ADAU7002 is not set +CONFIG_SND_SOC_ADAU17X1=m +CONFIG_SND_SOC_ADAU1761=m +CONFIG_SND_SOC_ADAU1761_I2C=m +CONFIG_SND_SOC_ADAU1761_SPI=m +CONFIG_SND_SOC_ADAU7002=m # CONFIG_SND_SOC_AK4104 is not set +CONFIG_SND_SOC_AK4118=m CONFIG_SND_SOC_AK4458=m # CONFIG_SND_SOC_AK4554 is not set # CONFIG_SND_SOC_AK4613 is not set @@ -4373,6 +5074,7 @@ CONFIG_SND_SOC_CPCAP=m # CONFIG_SND_SOC_CS35L33 is not set # CONFIG_SND_SOC_CS35L34 is not set CONFIG_SND_SOC_CS35L35=m +CONFIG_SND_SOC_CS35L36=m # CONFIG_SND_SOC_CS42L42 is not set # CONFIG_SND_SOC_CS42L51_I2C is not set # CONFIG_SND_SOC_CS42L52 is not set @@ -4384,8 +5086,11 @@ CONFIG_SND_SOC_CS35L35=m # CONFIG_SND_SOC_CS4271_SPI is not set # CONFIG_SND_SOC_CS42XX8_I2C is not set # CONFIG_SND_SOC_CS43130 is not set +CONFIG_SND_SOC_CS4341=m # CONFIG_SND_SOC_CS4349 is not set # CONFIG_SND_SOC_CS53L30 is not set +# CONFIG_SND_SOC_CX2072X is not set +CONFIG_SND_SOC_DMIC=m CONFIG_SND_SOC_HDMI_CODEC=m # CONFIG_SND_SOC_ES7134 is not set CONFIG_SND_SOC_ES7241=m @@ -4395,11 +5100,14 @@ CONFIG_SND_SOC_ES8328_I2C=m CONFIG_SND_SOC_ES8328_SPI=m # CONFIG_SND_SOC_GTM601 is not set # CONFIG_SND_SOC_INNO_RK3036 is not set +CONFIG_SND_SOC_MAX98088=m +# CONFIG_SND_SOC_MAX98357A is not set # CONFIG_SND_SOC_MAX98504 is not set CONFIG_SND_SOC_MAX9867=m # CONFIG_SND_SOC_MAX98927 is not set # CONFIG_SND_SOC_MAX98373 is not set # CONFIG_SND_SOC_MAX9860 is not set +CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m # CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set # CONFIG_SND_SOC_PCM1681 is not set CONFIG_SND_SOC_PCM1789=m @@ -4409,13 +5117,22 @@ CONFIG_SND_SOC_PCM1789_I2C=m CONFIG_SND_SOC_PCM186X=m CONFIG_SND_SOC_PCM186X_I2C=m CONFIG_SND_SOC_PCM186X_SPI=m +CONFIG_SND_SOC_PCM3060=m +CONFIG_SND_SOC_PCM3060_I2C=m +CONFIG_SND_SOC_PCM3060_SPI=m # CONFIG_SND_SOC_PCM3168A_I2C is not set # CONFIG_SND_SOC_PCM3168A_SPI is not set -# CONFIG_SND_SOC_PCM512x_I2C is not set -# CONFIG_SND_SOC_PCM512x_SPI is not set +CONFIG_SND_SOC_PCM5102A=m +CONFIG_SND_SOC_PCM512x=m +CONFIG_SND_SOC_PCM512x_I2C=m +CONFIG_SND_SOC_PCM512x_SPI=m +CONFIG_SND_SOC_RK3328=m # CONFIG_SND_SOC_RT5616 is not set # CONFIG_SND_SOC_RT5631 is not set # CONFIG_SND_SOC_SGTL5000 is not set +CONFIG_SND_SOC_SI476X=m +CONFIG_SND_SOC_SIGMADSP=m +CONFIG_SND_SOC_SIGMADSP_REGMAP=m CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m # CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set CONFIG_SND_SOC_SPDIF=m @@ -4442,6 +5159,7 @@ CONFIG_SND_SOC_TDA7419=m # CONFIG_SND_SOC_TS3A227E is not set # CONFIG_SND_SOC_TSCS42XX is not set # CONFIG_SND_SOC_TSCS454 is not set +CONFIG_SND_SOC_UDA1334=m # CONFIG_SND_SOC_WM8510 is not set # CONFIG_SND_SOC_WM8523 is not set # CONFIG_SND_SOC_WM8524 is not set @@ -4459,6 +5177,7 @@ CONFIG_SND_SOC_TDA7419=m # CONFIG_SND_SOC_WM8804_I2C is not set # CONFIG_SND_SOC_WM8804_SPI is not set # CONFIG_SND_SOC_WM8903 is not set +CONFIG_SND_SOC_WM8904=m # CONFIG_SND_SOC_WM8960 is not set # CONFIG_SND_SOC_WM8962 is not set # CONFIG_SND_SOC_WM8974 is not set @@ -4467,15 +5186,18 @@ CONFIG_SND_SOC_TDA7419=m # CONFIG_SND_SOC_ZX_AUD96P22 is not set CONFIG_SND_SOC_MAX9759=m # CONFIG_SND_SOC_MT6351 is not set +CONFIG_SND_SOC_MT6358=m CONFIG_SND_SOC_NAU8540=m # CONFIG_SND_SOC_NAU8810 is not set +CONFIG_SND_SOC_NAU8822=m CONFIG_SND_SOC_NAU8824=m # CONFIG_SND_SOC_TPA6130A2 is not set +# end of CODEC drivers + CONFIG_SND_SIMPLE_CARD_UTILS=m CONFIG_SND_SIMPLE_CARD=m -# CONFIG_SND_SIMPLE_SCU_CARD is not set # CONFIG_SND_AUDIO_GRAPH_CARD is not set -# CONFIG_SND_AUDIO_GRAPH_SCU_CARD is not set +CONFIG_AC97_BUS=m # # HID support @@ -4499,13 +5221,16 @@ CONFIG_HID_APPLEIR=m CONFIG_HID_AUREAL=m CONFIG_HID_BELKIN=m CONFIG_HID_BETOP_FF=m +CONFIG_HID_BIGBEN_FF=m CONFIG_HID_CHERRY=m CONFIG_HID_CHICONY=m CONFIG_HID_CORSAIR=m CONFIG_HID_COUGAR=m +CONFIG_HID_MACALLY=m CONFIG_HID_PRODIKEYS=m # CONFIG_HID_CMEDIA is not set CONFIG_HID_CP2112=m +CONFIG_HID_CREATIVE_SB0540=m CONFIG_HID_CYPRESS=m CONFIG_HID_DRAGONRISE=m CONFIG_DRAGONRISE_FF=y @@ -4518,12 +5243,12 @@ CONFIG_HID_GEMBIRD=m CONFIG_HID_GFRM=m CONFIG_HID_HOLTEK=m CONFIG_HOLTEK_FF=y -CONFIG_HID_GOOGLE_HAMMER=m CONFIG_HID_GT683R=m CONFIG_HID_KEYTOUCH=m CONFIG_HID_KYE=m CONFIG_HID_UCLOGIC=m CONFIG_HID_WALTOP=m +CONFIG_HID_VIEWSONIC=m CONFIG_HID_GYRATION=m CONFIG_HID_ICADE=m # CONFIG_HID_ITE is not set @@ -4541,6 +5266,7 @@ CONFIG_LOGIRUMBLEPAD2_FF=y CONFIG_LOGIG940_FF=y CONFIG_LOGIWHEELS_FF=y CONFIG_HID_MAGICMOUSE=m +CONFIG_HID_MALTRON=m # CONFIG_HID_MAYFLASH is not set # CONFIG_HID_REDRAGON is not set CONFIG_HID_MICROSOFT=m @@ -4582,6 +5308,7 @@ CONFIG_HID_THINGM=m CONFIG_HID_THRUSTMASTER=m CONFIG_THRUSTMASTER_FF=y # CONFIG_HID_UDRAW_PS3 is not set +CONFIG_HID_U2FZERO=m CONFIG_HID_WACOM=m CONFIG_HID_WIIMOTE=m CONFIG_HID_XINMO=m @@ -4591,6 +5318,7 @@ CONFIG_HID_ZYDACRON=m CONFIG_HID_SENSOR_HUB=m CONFIG_HID_SENSOR_CUSTOM_SENSOR=m CONFIG_HID_ALPS=m +# end of Special HID drivers # # USB HID support @@ -4598,14 +5326,21 @@ CONFIG_HID_ALPS=m CONFIG_USB_HID=y CONFIG_HID_PID=y CONFIG_USB_HIDDEV=y +# end of USB HID support # # I2C HID support # CONFIG_I2C_HID=m +# end of I2C HID support +# end of HID support + CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_SUPPORT=y CONFIG_USB_COMMON=y +# CONFIG_USB_LED_TRIG is not set +CONFIG_USB_ULPI_BUS=m +CONFIG_USB_CONN_GPIO=m CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y @@ -4620,8 +5355,8 @@ CONFIG_USB_OTG=y # CONFIG_USB_OTG_BLACKLIST_HUB is not set # CONFIG_USB_OTG_FSM is not set CONFIG_USB_LEDS_TRIGGER_USBPORT=y +CONFIG_USB_AUTOSUSPEND_DELAY=2 CONFIG_USB_MON=m -# CONFIG_USB_WUSB_CBAF is not set # # USB Host Controller Drivers @@ -4631,15 +5366,17 @@ CONFIG_USB_XHCI_HCD=y # CONFIG_USB_XHCI_DBGCAP is not set CONFIG_USB_XHCI_PLATFORM=y CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_FSL=m CONFIG_USB_EHCI_HCD_PLATFORM=y -# CONFIG_USB_OXU210HP_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_FOTG210_HCD is not set -# CONFIG_USB_MAX3421_HCD is not set +CONFIG_USB_OXU210HP_HCD=m +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_FOTG210_HCD=m +CONFIG_USB_MAX3421_HCD=m CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_U132_HCD=m # CONFIG_USB_SL811_HCD is not set # CONFIG_USB_R8A66597_HCD is not set # CONFIG_USB_HCD_BCMA is not set @@ -4690,6 +5427,7 @@ CONFIG_USBIP_VHCI_NR_HCS=1 CONFIG_USBIP_HOST=m CONFIG_USBIP_VUDC=m # CONFIG_USBIP_DEBUG is not set +# CONFIG_USB_CDNS3 is not set CONFIG_USB_MUSB_HDRC=y # CONFIG_USB_MUSB_HOST is not set # CONFIG_USB_MUSB_GADGET is not set @@ -4749,7 +5487,7 @@ CONFIG_USB_SERIAL_IR=m CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m CONFIG_USB_SERIAL_F81232=m -# CONFIG_USB_SERIAL_F8153X is not set +CONFIG_USB_SERIAL_F8153X=m CONFIG_USB_SERIAL_GARMIN=m CONFIG_USB_SERIAL_IPW=m CONFIG_USB_SERIAL_IUU=m @@ -4770,7 +5508,7 @@ CONFIG_USB_SERIAL_QCAUX=m CONFIG_USB_SERIAL_QUALCOMM=m CONFIG_USB_SERIAL_SPCP8X5=m CONFIG_USB_SERIAL_SAFE=m -# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SAFE_PADDED=y CONFIG_USB_SERIAL_SIERRAWIRELESS=m CONFIG_USB_SERIAL_SYMBOL=m CONFIG_USB_SERIAL_TI=m @@ -4790,32 +5528,37 @@ CONFIG_USB_SERIAL_DEBUG=m # # USB Miscellaneous drivers # -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_SISUSBVGA_CON=y +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m # CONFIG_USB_TEST is not set # CONFIG_USB_EHSET_TEST_FIXTURE is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_YUREX is not set +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_YUREX=m CONFIG_USB_EZUSB_FX2=m CONFIG_USB_HUB_USB251XB=m -# CONFIG_USB_HSIC_USB3503 is not set -# CONFIG_USB_HSIC_USB4604 is not set +CONFIG_USB_HSIC_USB3503=m +CONFIG_USB_HSIC_USB4604=m # CONFIG_USB_LINK_LAYER_TEST is not set CONFIG_USB_CHAOSKEY=m -# CONFIG_USB_ATM is not set +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m # # USB Physical Layer drivers @@ -4824,8 +5567,12 @@ CONFIG_USB_PHY=y CONFIG_NOP_USB_XCEIV=y # CONFIG_AM335X_PHY_USB is not set # CONFIG_USB_GPIO_VBUS is not set +CONFIG_TAHVO_USB=m +# CONFIG_TAHVO_USB_HOST_BY_DEFAULT is not set # CONFIG_USB_ISP1301 is not set # CONFIG_USB_ULPI is not set +# end of USB Physical Layer drivers + CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FILES is not set @@ -4850,6 +5597,8 @@ CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 # CONFIG_USB_NET2272 is not set # CONFIG_USB_GADGET_XILINX is not set # CONFIG_USB_DUMMY_HCD is not set +# end of USB Peripheral Controller + CONFIG_USB_LIBCOMPOSITE=m CONFIG_USB_F_ACM=m CONFIG_USB_U_SERIAL=m @@ -4893,9 +5642,6 @@ CONFIG_USB_G_HID=m CONFIG_USB_G_WEBCAM=m # CONFIG_TYPEC is not set CONFIG_USB_ROLE_SWITCH=m -# CONFIG_USB_LED_TRIG is not set -CONFIG_USB_ULPI_BUS=m -# CONFIG_UWB is not set CONFIG_MMC=y CONFIG_PWRSEQ_EMMC=m CONFIG_PWRSEQ_SD8787=m @@ -4929,16 +5675,21 @@ CONFIG_LEDS_CLASS_FLASH=m # # LED drivers # +CONFIG_LEDS_88PM860X=m # CONFIG_LEDS_AAT1290 is not set +CONFIG_LEDS_AN30259A=m # CONFIG_LEDS_AS3645A is not set # CONFIG_LEDS_BCM6328 is not set # CONFIG_LEDS_BCM6358 is not set CONFIG_LEDS_CPCAP=m CONFIG_LEDS_CR0014114=m # CONFIG_LEDS_LM3530 is not set +CONFIG_LEDS_LM3532=m +CONFIG_LEDS_LM3533=m # CONFIG_LEDS_LM3642 is not set CONFIG_LEDS_LM3692X=m # CONFIG_LEDS_LM3601X is not set +CONFIG_LEDS_MT6323=m # CONFIG_LEDS_PCA9532 is not set CONFIG_LEDS_GPIO=y # CONFIG_LEDS_LP3944 is not set @@ -4947,17 +5698,28 @@ CONFIG_LEDS_GPIO=y # CONFIG_LEDS_LP5523 is not set # CONFIG_LEDS_LP5562 is not set # CONFIG_LEDS_LP8501 is not set +CONFIG_LEDS_LP8788=m # CONFIG_LEDS_LP8860 is not set # CONFIG_LEDS_PCA955X is not set # CONFIG_LEDS_PCA963X is not set +CONFIG_LEDS_WM831X_STATUS=m +CONFIG_LEDS_WM8350=m +CONFIG_LEDS_DA903X=m +CONFIG_LEDS_DA9052=m # CONFIG_LEDS_DAC124S085 is not set CONFIG_LEDS_PWM=m CONFIG_LEDS_REGULATOR=m # CONFIG_LEDS_BD2802 is not set # CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_ADP5520=m +CONFIG_LEDS_MC13783=m # CONFIG_LEDS_TCA6507 is not set # CONFIG_LEDS_TLC591XX is not set +CONFIG_LEDS_MAX77650=m +CONFIG_LEDS_MAX77693=m +CONFIG_LEDS_MAX8997=m # CONFIG_LEDS_LM355x is not set +CONFIG_LEDS_MENF21BMC=m # CONFIG_LEDS_KTD2692 is not set # CONFIG_LEDS_IS31FL319X is not set # CONFIG_LEDS_IS31FL32XX is not set @@ -4969,6 +5731,8 @@ CONFIG_LEDS_REGULATOR=m CONFIG_LEDS_SYSCON=y CONFIG_LEDS_MLXREG=m CONFIG_LEDS_USER=y +# CONFIG_LEDS_SPI_BYTE is not set +# CONFIG_LEDS_TI_LMU_COMMON is not set CONFIG_LEDS_AXP20X=m # @@ -4982,7 +5746,7 @@ CONFIG_LEDS_TRIGGER_MTD=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_BACKLIGHT=m CONFIG_LEDS_TRIGGER_CPU=y -# CONFIG_LEDS_TRIGGER_ACTIVITY is not set +CONFIG_LEDS_TRIGGER_ACTIVITY=y CONFIG_LEDS_TRIGGER_GPIO=m CONFIG_LEDS_TRIGGER_DEFAULT_ON=y @@ -4992,12 +5756,15 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y CONFIG_LEDS_TRIGGER_TRANSIENT=m CONFIG_LEDS_TRIGGER_CAMERA=m CONFIG_LEDS_TRIGGER_PANIC=y -CONFIG_LEDS_TRIGGER_NETDEV=y +CONFIG_LEDS_TRIGGER_NETDEV=m +CONFIG_LEDS_TRIGGER_PATTERN=m +CONFIG_LEDS_TRIGGER_AUDIO=m # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set CONFIG_EDAC_ATOMIC_SCRUB=y CONFIG_EDAC_SUPPORT=y CONFIG_RTC_LIB=y +CONFIG_RTC_MC146818_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y CONFIG_RTC_HCTOSYS_DEVICE="rtc0" @@ -5018,51 +5785,70 @@ CONFIG_RTC_INTF_DEV=y # # I2C RTC drivers # +CONFIG_RTC_DRV_88PM860X=m +CONFIG_RTC_DRV_88PM80X=m # CONFIG_RTC_DRV_ABB5ZES3 is not set +CONFIG_RTC_DRV_ABEOZ9=m # CONFIG_RTC_DRV_ABX80X is not set +CONFIG_RTC_DRV_AC100=m +CONFIG_RTC_DRV_AS3722=m CONFIG_RTC_DRV_DS1307=m # CONFIG_RTC_DRV_DS1307_CENTURY is not set # CONFIG_RTC_DRV_DS1374 is not set # CONFIG_RTC_DRV_DS1672 is not set # CONFIG_RTC_DRV_HYM8563 is not set +CONFIG_RTC_DRV_LP8788=m # CONFIG_RTC_DRV_MAX6900 is not set +CONFIG_RTC_DRV_MAX8907=m +CONFIG_RTC_DRV_MAX8925=m +CONFIG_RTC_DRV_MAX8998=m +CONFIG_RTC_DRV_MAX8997=m # CONFIG_RTC_DRV_RS5C372 is not set # CONFIG_RTC_DRV_ISL1208 is not set # CONFIG_RTC_DRV_ISL12022 is not set CONFIG_RTC_DRV_ISL12026=m -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8523 is not set -# CONFIG_RTC_DRV_PCF85063 is not set +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_PCF8523=m +CONFIG_RTC_DRV_PCF85063=m # CONFIG_RTC_DRV_PCF85363 is not set CONFIG_RTC_DRV_PCF8563=m # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set # CONFIG_RTC_DRV_BQ32K is not set +CONFIG_RTC_DRV_TWL4030=m +CONFIG_RTC_DRV_PALMAS=m +CONFIG_RTC_DRV_TPS6586X=m +CONFIG_RTC_DRV_TPS65910=m +CONFIG_RTC_DRV_TPS80031=m +CONFIG_RTC_DRV_RC5T583=m # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8010 is not set # CONFIG_RTC_DRV_RX8581 is not set # CONFIG_RTC_DRV_RX8025 is not set # CONFIG_RTC_DRV_EM3027 is not set +CONFIG_RTC_DRV_RV3028=m # CONFIG_RTC_DRV_RV8803 is not set +CONFIG_RTC_DRV_S5M=m +CONFIG_RTC_DRV_SD3078=m # # SPI RTC drivers # -# CONFIG_RTC_DRV_M41T93 is not set -# CONFIG_RTC_DRV_M41T94 is not set +CONFIG_RTC_DRV_M41T93=m +CONFIG_RTC_DRV_M41T94=m # CONFIG_RTC_DRV_DS1302 is not set -# CONFIG_RTC_DRV_DS1305 is not set +CONFIG_RTC_DRV_DS1305=m # CONFIG_RTC_DRV_DS1343 is not set # CONFIG_RTC_DRV_DS1347 is not set -# CONFIG_RTC_DRV_DS1390 is not set -# CONFIG_RTC_DRV_MAX6916 is not set -# CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RX4581 is not set +CONFIG_RTC_DRV_DS1390=m +CONFIG_RTC_DRV_MAX6916=m +CONFIG_RTC_DRV_R9701=m +CONFIG_RTC_DRV_RX4581=m # CONFIG_RTC_DRV_RX6110 is not set -# CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_PCF2123 is not set +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF2123=m # CONFIG_RTC_DRV_MCP795 is not set CONFIG_RTC_I2C_AND_SPI=y @@ -5076,14 +5862,22 @@ CONFIG_RTC_I2C_AND_SPI=y # # Platform RTC drivers # -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1685_FAMILY is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_DS2404 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set +CONFIG_RTC_DRV_CMOS=y +CONFIG_RTC_DRV_DS1286=m +CONFIG_RTC_DRV_DS1511=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1685_FAMILY=m +CONFIG_RTC_DRV_DS1685=y +# CONFIG_RTC_DRV_DS1689 is not set +# CONFIG_RTC_DRV_DS17285 is not set +# CONFIG_RTC_DRV_DS17485 is not set +# CONFIG_RTC_DRV_DS17885 is not set +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_DS2404=m +CONFIG_RTC_DRV_DA9052=m +CONFIG_RTC_DRV_DA9055=m +CONFIG_RTC_DRV_DA9063=m +CONFIG_RTC_DRV_STK17TA8=m # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set @@ -5091,6 +5885,10 @@ CONFIG_RTC_I2C_AND_SPI=y # CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set +CONFIG_RTC_DRV_WM831X=m +CONFIG_RTC_DRV_WM8350=m +CONFIG_RTC_DRV_PCF50633=m +CONFIG_RTC_DRV_AB3100=m # CONFIG_RTC_DRV_ZYNQMP is not set # @@ -5098,8 +5896,12 @@ CONFIG_RTC_I2C_AND_SPI=y # CONFIG_RTC_DRV_SUN6I=y CONFIG_RTC_DRV_SUNXI=y +CONFIG_RTC_DRV_CADENCE=m # CONFIG_RTC_DRV_FTRTC010 is not set +CONFIG_RTC_DRV_PCAP=m +CONFIG_RTC_DRV_MC13XXX=m # CONFIG_RTC_DRV_SNVS is not set +CONFIG_RTC_DRV_MT6397=m # CONFIG_RTC_DRV_R7301 is not set CONFIG_RTC_DRV_CPCAP=m @@ -5113,6 +5915,7 @@ CONFIG_DMADEVICES=y # # DMA Devices # +CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y CONFIG_DMA_ENGINE=y CONFIG_DMA_VIRTUAL_CHANNELS=y CONFIG_DMA_OF=y @@ -5121,6 +5924,7 @@ CONFIG_DMA_SUN4I=y CONFIG_DMA_SUN6I=y CONFIG_DW_AXI_DMAC=m # CONFIG_FSL_EDMA is not set +CONFIG_FSL_QDMA=m # CONFIG_INTEL_IDMA64 is not set # CONFIG_NBPFAXI_DMA is not set # CONFIG_QCOM_HIDMA_MGMT is not set @@ -5132,12 +5936,17 @@ CONFIG_DW_AXI_DMAC=m # CONFIG_ASYNC_TX_DMA=y # CONFIG_DMATEST is not set +CONFIG_DMA_ENGINE_RAID=y # # DMABUF options # CONFIG_SYNC_FILE=y # CONFIG_SW_SYNC is not set +# CONFIG_UDMABUF is not set +CONFIG_DMABUF_SELFTESTS=m +# end of DMABUF options + # CONFIG_AUXDISPLAY is not set # CONFIG_PANEL is not set CONFIG_UIO=m @@ -5146,12 +5955,18 @@ CONFIG_UIO_DMEM_GENIRQ=m # CONFIG_UIO_PRUSS is not set # CONFIG_VFIO is not set # CONFIG_VIRT_DRIVERS is not set +CONFIG_VIRTIO=m CONFIG_VIRTIO_MENU=y +CONFIG_VIRTIO_BALLOON=m +CONFIG_VIRTIO_INPUT=m # CONFIG_VIRTIO_MMIO is not set # # Microsoft Hyper-V guest support # +# end of Microsoft Hyper-V guest support + +# CONFIG_GREYBUS is not set CONFIG_STAGING=y # CONFIG_PRISM2_USB is not set # CONFIG_COMEDI is not set @@ -5170,63 +5985,76 @@ CONFIG_R8712U=m # # CONFIG_ADIS16203 is not set # CONFIG_ADIS16240 is not set +# end of Accelerometers # # Analog to digital converters # -# CONFIG_AD7606 is not set -# CONFIG_AD7780 is not set # CONFIG_AD7816 is not set # CONFIG_AD7192 is not set # CONFIG_AD7280 is not set +# end of Analog to digital converters # # Analog digital bi-direction converters # # CONFIG_ADT7316 is not set +# end of Analog digital bi-direction converters # # Capacitance to digital converters # # CONFIG_AD7150 is not set -# CONFIG_AD7152 is not set # CONFIG_AD7746 is not set +# end of Capacitance to digital converters # # Direct Digital Synthesis # CONFIG_AD9832=m CONFIG_AD9834=m +# end of Direct Digital Synthesis # # Network Analyzer, Impedance Converters # # CONFIG_AD5933 is not set +# end of Network Analyzer, Impedance Converters # # Active energy metering IC # # CONFIG_ADE7854 is not set +# end of Active energy metering IC # # Resolver to digital converters # -# CONFIG_AD2S90 is not set # CONFIG_AD2S1210 is not set +# end of Resolver to digital converters +# end of IIO staging drivers # # Speakup console speech # # CONFIG_SPEAKUP is not set +# end of Speakup console speech + CONFIG_STAGING_MEDIA=y -CONFIG_I2C_BCM2048=m +CONFIG_VIDEO_SUNXI=y +CONFIG_VIDEO_SUNXI_CEDRUS=m + +# +# soc_camera sensor drivers +# # # Android # +# end of Android + # CONFIG_STAGING_BOARD is not set # CONFIG_LTE_GDM724X is not set -# CONFIG_MTD_SPINAND_MT29F is not set # CONFIG_GS_FPGABOOT is not set # CONFIG_UNISYSSPAR is not set # CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set @@ -5262,8 +6090,6 @@ CONFIG_FB_TFT_UC1611=m CONFIG_FB_TFT_UC1701=m CONFIG_FB_TFT_UPD161704=m CONFIG_FB_TFT_WATTEROTT=m -CONFIG_FB_FLEX=m -CONFIG_FB_TFT_FBTFT_DEVICE=m # CONFIG_WILC1000_SDIO is not set # CONFIG_WILC1000_SPI is not set CONFIG_MOST=m @@ -5275,25 +6101,30 @@ CONFIG_MOST=m # CONFIG_MOST_I2C is not set # CONFIG_MOST_USB is not set # CONFIG_KS7010 is not set -# CONFIG_GREYBUS is not set # CONFIG_PI433 is not set -CONFIG_MTK_MMC=m -# CONFIG_MTK_AEE_KDUMP is not set -# CONFIG_MTK_MMC_CD_POLL is not set # # Gasket devices # +# end of Gasket devices + CONFIG_XIL_AXIS_FIFO=m -CONFIG_EROFS_FS=m -# CONFIG_EROFS_FS_DEBUG is not set -CONFIG_EROFS_FS_XATTR=y -CONFIG_EROFS_FS_POSIX_ACL=y -# CONFIG_EROFS_FS_SECURITY is not set -# CONFIG_EROFS_FS_USE_VM_MAP_RAM is not set -# CONFIG_EROFS_FAULT_INJECTION is not set -# CONFIG_EROFS_FS_ZIP is not set +CONFIG_FIELDBUS_DEV=m +CONFIG_HMS_ANYBUSS_BUS=m +CONFIG_ARCX_ANYBUS_CONTROLLER=m +CONFIG_HMS_PROFINET=m +# CONFIG_USB_WUSB_CBAF is not set +# CONFIG_UWB is not set +CONFIG_EXFAT_FS=m +CONFIG_EXFAT_DONT_MOUNT_VFAT=y +CONFIG_EXFAT_DISCARD=y +# CONFIG_EXFAT_DELAYED_SYNC is not set +# CONFIG_EXFAT_KERNEL_DEBUG is not set +# CONFIG_EXFAT_DEBUG_MSG is not set +CONFIG_EXFAT_DEFAULT_CODEPAGE=437 +CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" # CONFIG_GOLDFISH is not set +# CONFIG_MFD_CROS_EC is not set # CONFIG_CHROME_PLATFORMS is not set # CONFIG_MELLANOX_PLATFORM is not set CONFIG_CLKDEV_LOOKUP=y @@ -5303,8 +6134,10 @@ CONFIG_COMMON_CLK=y # # Common Clock Framework # +CONFIG_COMMON_CLK_WM831X=m # CONFIG_CLK_HSDK is not set CONFIG_COMMON_CLK_MAX9485=m +# CONFIG_COMMON_CLK_SI5341 is not set # CONFIG_COMMON_CLK_SI5351 is not set # CONFIG_COMMON_CLK_SI514 is not set # CONFIG_COMMON_CLK_SI544 is not set @@ -5312,9 +6145,19 @@ CONFIG_COMMON_CLK_MAX9485=m # CONFIG_COMMON_CLK_CDCE706 is not set # CONFIG_COMMON_CLK_CDCE925 is not set # CONFIG_COMMON_CLK_CS2000_CP is not set +CONFIG_COMMON_CLK_S2MPS11=m +CONFIG_CLK_TWL6040=m CONFIG_CLK_QORIQ=y +CONFIG_COMMON_CLK_PALMAS=m CONFIG_COMMON_CLK_PWM=m CONFIG_COMMON_CLK_VC5=m +CONFIG_COMMON_CLK_BD718XX=m +# CONFIG_COMMON_CLK_FIXED_MMIO is not set +CONFIG_CLK_SUNXI=y +CONFIG_CLK_SUNXI_CLOCKS=y +CONFIG_CLK_SUNXI_PRCM_SUN6I=y +CONFIG_CLK_SUNXI_PRCM_SUN8I=y +CONFIG_CLK_SUNXI_PRCM_SUN9I=y CONFIG_SUNXI_CCU=y CONFIG_SUN4I_A10_CCU=y CONFIG_SUN5I_CCU=y @@ -5328,6 +6171,8 @@ CONFIG_SUN8I_DE2_CCU=y CONFIG_SUN8I_R40_CCU=y CONFIG_SUN9I_A80_CCU=y CONFIG_SUN8I_R_CCU=y +# end of Common Clock Framework + # CONFIG_HWSPINLOCK is not set # @@ -5340,7 +6185,8 @@ CONFIG_SUN4I_TIMER=y CONFIG_SUN5I_HSTIMER=y CONFIG_ARM_ARCH_TIMER=y CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -# CONFIG_ARM_TIMER_SP804 is not set +# end of Clock Source drivers + # CONFIG_MAILBOX is not set CONFIG_IOMMU_API=y CONFIG_IOMMU_SUPPORT=y @@ -5353,20 +6199,27 @@ CONFIG_IOMMU_IO_PGTABLE_LPAE=y # CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST is not set CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y # CONFIG_IOMMU_IO_PGTABLE_ARMV7S_SELFTEST is not set +# end of Generic IOMMU Pagetable Support + # CONFIG_IOMMU_DEBUGFS is not set # CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set CONFIG_OF_IOMMU=y CONFIG_ARM_SMMU=y +CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y # # Remoteproc drivers # # CONFIG_REMOTEPROC is not set +# end of Remoteproc drivers # # Rpmsg drivers # # CONFIG_RPMSG_VIRTIO is not set +# end of Rpmsg drivers + +# CONFIG_SOUNDWIRE is not set # # SOC (System On Chip) specific Drivers @@ -5375,23 +6228,34 @@ CONFIG_ARM_SMMU=y # # Amlogic SoC drivers # +# end of Amlogic SoC drivers + +# +# Aspeed SoC drivers +# +# end of Aspeed SoC drivers # # Broadcom SoC drivers # # CONFIG_SOC_BRCMSTB is not set +# end of Broadcom SoC drivers # # NXP/Freescale QorIQ SoC drivers # +# end of NXP/Freescale QorIQ SoC drivers # # i.MX SoC drivers # +# end of i.MX SoC drivers # # Qualcomm SoC drivers # +# end of Qualcomm SoC drivers + CONFIG_SUNXI_SRAM=y # CONFIG_SOC_TI is not set @@ -5399,6 +6263,9 @@ CONFIG_SUNXI_SRAM=y # Xilinx SoC drivers # # CONFIG_XILINX_VCU is not set +# end of Xilinx SoC drivers +# end of SOC (System On Chip) specific Drivers + CONFIG_PM_DEVFREQ=y # @@ -5420,8 +6287,16 @@ CONFIG_EXTCON=y # Extcon Device Drivers # # CONFIG_EXTCON_ADC_JACK is not set +CONFIG_EXTCON_ARIZONA=m +# CONFIG_EXTCON_FSA9480 is not set CONFIG_EXTCON_GPIO=m +CONFIG_EXTCON_MAX14577=m # CONFIG_EXTCON_MAX3355 is not set +CONFIG_EXTCON_MAX77693=m +CONFIG_EXTCON_MAX77843=m +CONFIG_EXTCON_MAX8997=m +CONFIG_EXTCON_PALMAS=m +CONFIG_EXTCON_PTN5150=m # CONFIG_EXTCON_RT8973A is not set # CONFIG_EXTCON_SM5502 is not set CONFIG_EXTCON_USB_GPIO=m @@ -5441,58 +6316,80 @@ CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 # # Accelerometers # -# CONFIG_ADIS16201 is not set -# CONFIG_ADIS16209 is not set +CONFIG_ADIS16201=m +CONFIG_ADIS16209=m CONFIG_ADXL345=m CONFIG_ADXL345_I2C=m CONFIG_ADXL345_SPI=m -# CONFIG_BMA180 is not set -# CONFIG_BMA220 is not set -# CONFIG_BMC150_ACCEL is not set -# CONFIG_DA280 is not set -# CONFIG_DA311 is not set -# CONFIG_DMARD06 is not set -# CONFIG_DMARD09 is not set -# CONFIG_DMARD10 is not set -# CONFIG_HID_SENSOR_ACCEL_3D is not set -# CONFIG_IIO_CROS_EC_ACCEL_LEGACY is not set -# CONFIG_IIO_ST_ACCEL_3AXIS is not set -# CONFIG_KXSD9 is not set -# CONFIG_KXCJK1013 is not set -# CONFIG_MC3230 is not set -# CONFIG_MMA7455_I2C is not set -# CONFIG_MMA7455_SPI is not set -# CONFIG_MMA7660 is not set -# CONFIG_MMA8452 is not set -# CONFIG_MMA9551 is not set -# CONFIG_MMA9553 is not set -# CONFIG_MXC4005 is not set -# CONFIG_MXC6255 is not set -# CONFIG_SCA3000 is not set -# CONFIG_STK8312 is not set -# CONFIG_STK8BA50 is not set +CONFIG_ADXL372=m +CONFIG_ADXL372_SPI=m +CONFIG_ADXL372_I2C=m +CONFIG_BMA180=m +CONFIG_BMA220=m +CONFIG_BMC150_ACCEL=m +CONFIG_BMC150_ACCEL_I2C=m +CONFIG_BMC150_ACCEL_SPI=m +CONFIG_DA280=m +CONFIG_DA311=m +CONFIG_DMARD06=m +CONFIG_DMARD09=m +CONFIG_DMARD10=m +CONFIG_HID_SENSOR_ACCEL_3D=m +CONFIG_IIO_ST_ACCEL_3AXIS=m +CONFIG_IIO_ST_ACCEL_I2C_3AXIS=m +CONFIG_IIO_ST_ACCEL_SPI_3AXIS=m +CONFIG_KXSD9=m +CONFIG_KXSD9_SPI=m +CONFIG_KXSD9_I2C=m +CONFIG_KXCJK1013=m +CONFIG_MC3230=m +CONFIG_MMA7455=m +CONFIG_MMA7455_I2C=m +CONFIG_MMA7455_SPI=m +CONFIG_MMA7660=m +CONFIG_MMA8452=m +CONFIG_MMA9551_CORE=m +CONFIG_MMA9551=m +CONFIG_MMA9553=m +CONFIG_MXC4005=m +CONFIG_MXC6255=m +CONFIG_SCA3000=m +CONFIG_STK8312=m +CONFIG_STK8BA50=m +# end of Accelerometers # # Analog to digital converters # -# CONFIG_AD7266 is not set -# CONFIG_AD7291 is not set -# CONFIG_AD7298 is not set -# CONFIG_AD7476 is not set +CONFIG_AD_SIGMA_DELTA=m +CONFIG_AD7124=m +CONFIG_AD7266=m +CONFIG_AD7291=m +CONFIG_AD7298=m +CONFIG_AD7476=m +CONFIG_AD7606=m +CONFIG_AD7606_IFACE_PARALLEL=m +CONFIG_AD7606_IFACE_SPI=m # CONFIG_AD7766 is not set +CONFIG_AD7768_1=m +# CONFIG_AD7780 is not set # CONFIG_AD7791 is not set # CONFIG_AD7793 is not set # CONFIG_AD7887 is not set # CONFIG_AD7923 is not set +CONFIG_AD7949=m # CONFIG_AD799X is not set CONFIG_AXP20X_ADC=m CONFIG_AXP288_ADC=m # CONFIG_CC10001_ADC is not set CONFIG_CPCAP_ADC=m +CONFIG_DA9150_GPADC=m +CONFIG_DLN2_ADC=m # CONFIG_ENVELOPE_DETECTOR is not set # CONFIG_HI8435 is not set # CONFIG_HX711 is not set # CONFIG_INA2XX_ADC is not set +CONFIG_LP8788_ADC=m # CONFIG_LTC2471 is not set # CONFIG_LTC2485 is not set CONFIG_LTC2497=m @@ -5503,7 +6400,13 @@ CONFIG_MAX1118=m # CONFIG_MAX9611 is not set # CONFIG_MCP320X is not set # CONFIG_MCP3422 is not set +CONFIG_MCP3911=m # CONFIG_NAU7802 is not set +CONFIG_PALMAS_GPADC=m +CONFIG_QCOM_VADC_COMMON=m +CONFIG_QCOM_SPMI_IADC=m +CONFIG_QCOM_SPMI_VADC=m +CONFIG_QCOM_SPMI_ADC5=m # CONFIG_SD_ADC_MODULATOR is not set CONFIG_SUN4I_GPADC=m # CONFIG_TI_ADC081C is not set @@ -5515,19 +6418,29 @@ CONFIG_SUN4I_GPADC=m # CONFIG_TI_ADC161S626 is not set # CONFIG_TI_ADS1015 is not set CONFIG_TI_ADS7950=m +CONFIG_TI_ADS8344=m # CONFIG_TI_ADS8688 is not set +CONFIG_TI_ADS124S08=m +CONFIG_TI_AM335X_ADC=m CONFIG_TI_TLC4541=m +CONFIG_TWL4030_MADC=m +CONFIG_TWL6030_GPADC=m # CONFIG_VF610_ADC is not set +CONFIG_VIPERBOARD_ADC=m +# CONFIG_XILINX_XADC is not set +# end of Analog to digital converters # # Analog Front Ends # # CONFIG_IIO_RESCALE is not set +# end of Analog Front Ends # # Amplifiers # # CONFIG_AD8366 is not set +# end of Amplifiers # # Chemical Sensors @@ -5538,22 +6451,28 @@ CONFIG_BME680_I2C=m CONFIG_BME680_SPI=m CONFIG_CCS811=m # CONFIG_IAQCORE is not set +CONFIG_PMS7003=m +CONFIG_SENSIRION_SGP30=m +CONFIG_SPS30=m # CONFIG_VZ89X is not set +# end of Chemical Sensors # # Hid Sensor IIO Common # CONFIG_HID_SENSOR_IIO_COMMON=m CONFIG_HID_SENSOR_IIO_TRIGGER=m +# end of Hid Sensor IIO Common # # SSP Sensor Common # # CONFIG_IIO_SSP_SENSORHUB is not set +# end of SSP Sensor Common -# -# Counters -# +CONFIG_IIO_ST_SENSORS_I2C=m +CONFIG_IIO_ST_SENSORS_SPI=m +CONFIG_IIO_ST_SENSORS_CORE=m # # Digital to analog converters @@ -5568,6 +6487,7 @@ CONFIG_HID_SENSOR_IIO_TRIGGER=m # CONFIG_AD5593R is not set # CONFIG_AD5504 is not set # CONFIG_AD5624R_SPI is not set +CONFIG_LTC1660=m CONFIG_LTC2632=m # CONFIG_AD5686_SPI is not set # CONFIG_AD5696_I2C is not set @@ -5587,11 +6507,15 @@ CONFIG_AD5758=m # CONFIG_MCP4922 is not set # CONFIG_TI_DAC082S085 is not set CONFIG_TI_DAC5571=m +CONFIG_TI_DAC7311=m +CONFIG_TI_DAC7612=m # CONFIG_VF610_DAC is not set +# end of Digital to analog converters # # IIO dummy driver # +# end of IIO dummy driver # # Frequency Synthesizers DDS/PLL @@ -5601,11 +6525,15 @@ CONFIG_TI_DAC5571=m # Clock Generator/Distribution # # CONFIG_AD9523 is not set +# end of Clock Generator/Distribution # # Phase-Locked Loop (PLL) frequency synthesizers # # CONFIG_ADF4350 is not set +CONFIG_ADF4371=m +# end of Phase-Locked Loop (PLL) frequency synthesizers +# end of Frequency Synthesizers DDS/PLL # # Digital gyroscope sensors @@ -5616,10 +6544,14 @@ CONFIG_TI_DAC5571=m # CONFIG_ADIS16260 is not set # CONFIG_ADXRS450 is not set # CONFIG_BMG160 is not set +CONFIG_FXAS21002C=m +CONFIG_FXAS21002C_I2C=m +CONFIG_FXAS21002C_SPI=m # CONFIG_HID_SENSOR_GYRO_3D is not set # CONFIG_MPU3050_I2C is not set # CONFIG_IIO_ST_GYRO_3AXIS is not set # CONFIG_ITG3200 is not set +# end of Digital gyroscope sensors # # Health Sensors @@ -5632,6 +6564,8 @@ CONFIG_TI_DAC5571=m # CONFIG_AFE4404 is not set # CONFIG_MAX30100 is not set CONFIG_MAX30102=m +# end of Heart Rate Monitors +# end of Health Sensors # # Humidity sensors @@ -5644,11 +6578,13 @@ CONFIG_HID_SENSOR_HUMIDITY=m # CONFIG_HTU21 is not set # CONFIG_SI7005 is not set CONFIG_SI7020=m +# end of Humidity sensors # # Inertial measurement units # # CONFIG_ADIS16400 is not set +CONFIG_ADIS16460=m # CONFIG_ADIS16480 is not set # CONFIG_BMI160_I2C is not set # CONFIG_BMI160_SPI is not set @@ -5658,19 +6594,24 @@ CONFIG_SI7020=m CONFIG_IIO_ST_LSM6DSX=m CONFIG_IIO_ST_LSM6DSX_I2C=m CONFIG_IIO_ST_LSM6DSX_SPI=m +CONFIG_IIO_ST_LSM6DSX_I3C=m +# end of Inertial measurement units + +CONFIG_IIO_ADIS_LIB=m +CONFIG_IIO_ADIS_LIB_BUFFER=y # # Light sensors # -# CONFIG_ADJD_S311 is not set -# CONFIG_AL3320A is not set -# CONFIG_APDS9300 is not set -# CONFIG_APDS9960 is not set -# CONFIG_BH1750 is not set -# CONFIG_BH1780 is not set -# CONFIG_CM32181 is not set -# CONFIG_CM3232 is not set -# CONFIG_CM3323 is not set +CONFIG_ADJD_S311=m +CONFIG_AL3320A=m +CONFIG_APDS9300=m +CONFIG_APDS9960=m +CONFIG_BH1750=m +CONFIG_BH1780=m +CONFIG_CM32181=m +CONFIG_CM3232=m +CONFIG_CM3323=m CONFIG_CM3605=m # CONFIG_CM36651 is not set # CONFIG_GP2AP020A00F is not set @@ -5681,11 +6622,14 @@ CONFIG_CM3605=m # CONFIG_HID_SENSOR_PROX is not set # CONFIG_JSA1212 is not set # CONFIG_RPR0521 is not set +CONFIG_SENSORS_LM3533=m # CONFIG_LTR501 is not set # CONFIG_LV0104CS is not set # CONFIG_MAX44000 is not set -# CONFIG_OPT3001 is not set -# CONFIG_PA12203001 is not set +CONFIG_MAX44009=m +CONFIG_NOA1305=m +CONFIG_OPT3001=m +CONFIG_PA12203001=m CONFIG_SI1133=m # CONFIG_SI1145 is not set # CONFIG_STK3310 is not set @@ -5695,12 +6639,14 @@ CONFIG_SI1133=m # CONFIG_SENSORS_TSL2563 is not set # CONFIG_TSL2583 is not set CONFIG_TSL2772=m -# CONFIG_TSL4531 is not set -# CONFIG_US5182D is not set -# CONFIG_VCNL4000 is not set -# CONFIG_VEML6070 is not set +CONFIG_TSL4531=m +CONFIG_US5182D=m +CONFIG_VCNL4000=m +CONFIG_VCNL4035=m +CONFIG_VEML6070=m CONFIG_VL6180=m -# CONFIG_ZOPT2201 is not set +CONFIG_ZOPT2201=m +# end of Light sensors # # Magnetometer sensors @@ -5716,40 +6662,51 @@ CONFIG_VL6180=m # CONFIG_IIO_ST_MAGN_3AXIS is not set # CONFIG_SENSORS_HMC5843_I2C is not set # CONFIG_SENSORS_HMC5843_SPI is not set +CONFIG_SENSORS_RM3100=m +CONFIG_SENSORS_RM3100_I2C=m +CONFIG_SENSORS_RM3100_SPI=m +# end of Magnetometer sensors # # Multiplexers # # CONFIG_IIO_MUX is not set +# end of Multiplexers # # Inclinometer sensors # # CONFIG_HID_SENSOR_INCLINOMETER_3D is not set # CONFIG_HID_SENSOR_DEVICE_ROTATION is not set +# end of Inclinometer sensors # # Triggers - standalone # CONFIG_IIO_INTERRUPT_TRIGGER=m CONFIG_IIO_SYSFS_TRIGGER=m +# end of Triggers - standalone # # Digital potentiometers # # CONFIG_AD5272 is not set # CONFIG_DS1803 is not set +CONFIG_MAX5432=m CONFIG_MAX5481=m # CONFIG_MAX5487 is not set # CONFIG_MCP4018 is not set # CONFIG_MCP4131 is not set # CONFIG_MCP4531 is not set +CONFIG_MCP41010=m # CONFIG_TPL0102 is not set +# end of Digital potentiometers # # Digital potentiostats # # CONFIG_LMP91000 is not set +# end of Digital potentiostats # # Pressure sensors @@ -5758,7 +6715,8 @@ CONFIG_MAX5481=m CONFIG_BMP280=m CONFIG_BMP280_I2C=m CONFIG_BMP280_SPI=m -# CONFIG_HID_SENSOR_PRESS is not set +CONFIG_DPS310=m +CONFIG_HID_SENSOR_PRESS=m # CONFIG_HP03 is not set # CONFIG_MPL115_I2C is not set # CONFIG_MPL115_SPI is not set @@ -5769,43 +6727,57 @@ CONFIG_BMP280_SPI=m # CONFIG_T5403 is not set # CONFIG_HP206C is not set # CONFIG_ZPA2326 is not set +# end of Pressure sensors # # Lightning sensors # # CONFIG_AS3935 is not set +# end of Lightning sensors # # Proximity and distance sensors # CONFIG_ISL29501=m # CONFIG_LIDAR_LITE_V2 is not set +CONFIG_MB1232=m # CONFIG_RFD77402 is not set # CONFIG_SRF04 is not set # CONFIG_SX9500 is not set CONFIG_SRF08=m +CONFIG_VL53L0X_I2C=m +# end of Proximity and distance sensors # # Resolver to digital converters # +# CONFIG_AD2S90 is not set # CONFIG_AD2S1200 is not set +# end of Resolver to digital converters # # Temperature sensors # -# CONFIG_MAXIM_THERMOCOUPLE is not set +CONFIG_MAXIM_THERMOCOUPLE=m CONFIG_HID_SENSOR_TEMP=m -# CONFIG_MLX90614 is not set -# CONFIG_MLX90632 is not set -# CONFIG_TMP006 is not set +CONFIG_MLX90614=m +CONFIG_MLX90632=m +CONFIG_TMP006=m CONFIG_TMP007=m # CONFIG_TSYS01 is not set # CONFIG_TSYS02D is not set +CONFIG_MAX31856=m +# end of Temperature sensors + CONFIG_PWM=y CONFIG_PWM_SYSFS=y +CONFIG_PWM_ATMEL_HLCDC_PWM=m # CONFIG_PWM_FSL_FTM is not set +CONFIG_PWM_LP3943=m # CONFIG_PWM_PCA9685 is not set CONFIG_PWM_SUN4I=m +CONFIG_PWM_TWL=m +CONFIG_PWM_TWL_LED=m # # IRQ chip support @@ -5813,30 +6785,43 @@ CONFIG_PWM_SUN4I=m CONFIG_IRQCHIP=y CONFIG_ARM_GIC=y CONFIG_ARM_GIC_MAX_NR=1 +# CONFIG_AL_FIC is not set +CONFIG_MADERA_IRQ=m +# end of IRQ chip support + # CONFIG_IPACK_BUS is not set CONFIG_ARCH_HAS_RESET_CONTROLLER=y CONFIG_RESET_CONTROLLER=y CONFIG_RESET_SIMPLE=y CONFIG_RESET_SUNXI=y # CONFIG_RESET_TI_SYSCON is not set -# CONFIG_FMC is not set # # PHY Subsystem # CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PHY_MIPI_DPHY=y CONFIG_PHY_SUN4I_USB=y +CONFIG_PHY_SUN6I_MIPI_DPHY=m CONFIG_PHY_SUN9I_USB=y CONFIG_PHY_SUN50I_USB3=m # CONFIG_BCM_KONA_USB2_PHY is not set +CONFIG_PHY_CADENCE_DP=m +CONFIG_PHY_CADENCE_DPHY=m +CONFIG_PHY_CADENCE_SIERRA=m +CONFIG_PHY_FSL_IMX8MQ_USB=m +# CONFIG_PHY_MIXEL_MIPI_DPHY is not set # CONFIG_PHY_PXA_28NM_HSIC is not set # CONFIG_PHY_PXA_28NM_USB2 is not set # CONFIG_PHY_CPCAP_USB is not set # CONFIG_PHY_MAPPHONE_MDM6600 is not set +CONFIG_PHY_OCELOT_SERDES=m CONFIG_PHY_QCOM_USB_HS=m # CONFIG_PHY_QCOM_USB_HSIC is not set CONFIG_PHY_SAMSUNG_USB2=m # CONFIG_PHY_TUSB1210 is not set +# end of PHY Subsystem + # CONFIG_POWERCAP is not set # CONFIG_MCB is not set @@ -5848,25 +6833,35 @@ CONFIG_ARM_CCI400_PMU=y # CONFIG_ARM_CCI5xx_PMU is not set # CONFIG_ARM_CCN is not set CONFIG_ARM_PMU=y +# end of Performance monitor support + # CONFIG_RAS is not set # # Android # # CONFIG_ANDROID is not set +# end of Android + CONFIG_DAX=m CONFIG_NVMEM=y +CONFIG_NVMEM_SYSFS=y CONFIG_NVMEM_SUNXI_SID=y +CONFIG_RAVE_SP_EEPROM=m # # HW tracing support # CONFIG_STM=m +CONFIG_STM_PROTO_BASIC=m +CONFIG_STM_PROTO_SYS_T=m CONFIG_STM_DUMMY=m CONFIG_STM_SOURCE_CONSOLE=m # CONFIG_STM_SOURCE_HEARTBEAT is not set # CONFIG_STM_SOURCE_FTRACE is not set # CONFIG_INTEL_TH is not set +# end of HW tracing support + # CONFIG_FPGA is not set CONFIG_FSI=m # CONFIG_FSI_NEW_DEV_NODE is not set @@ -5881,23 +6876,43 @@ CONFIG_TEE=m # CONFIG_OPTEE=m CONFIG_OPTEE_SHM_NUM_PRIV_PAGES=1 +# end of TEE drivers + +CONFIG_MULTIPLEXER=m + +# +# Multiplexer drivers +# +CONFIG_MUX_ADG792A=m +CONFIG_MUX_ADGS1408=m +CONFIG_MUX_GPIO=m +CONFIG_MUX_MMIO=m +# end of Multiplexer drivers + CONFIG_PM_OPP=y # CONFIG_SIOX is not set # CONFIG_SLIMBUS is not set +CONFIG_INTERCONNECT=m +CONFIG_COUNTER=m +CONFIG_FTM_QUADDEC=m +# end of Device Drivers # # File systems # CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_VALIDATE_FS_PARSER=y CONFIG_FS_IOMAP=y -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set +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_EXT4_FS=y -CONFIG_EXT4_USE_FOR_EXT2=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y -CONFIG_EXT4_ENCRYPTION=y -CONFIG_EXT4_FS_ENCRYPTION=y # CONFIG_EXT4_DEBUG is not set CONFIG_JBD2=y # CONFIG_JBD2_DEBUG is not set @@ -5905,21 +6920,29 @@ CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set CONFIG_REISERFS_PROC_INFO=y -# CONFIG_REISERFS_FS_XATTR is not set -CONFIG_JFS_FS=y +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m CONFIG_JFS_POSIX_ACL=y -# CONFIG_JFS_SECURITY is not set +CONFIG_JFS_SECURITY=y # CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set -CONFIG_XFS_FS=y +CONFIG_JFS_STATISTICS=y +CONFIG_XFS_FS=m CONFIG_XFS_QUOTA=y CONFIG_XFS_POSIX_ACL=y CONFIG_XFS_RT=y # CONFIG_XFS_ONLINE_SCRUB is not set # CONFIG_XFS_WARN is not set # CONFIG_XFS_DEBUG is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=y +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_DEBUG_MASKLOG=y +# CONFIG_OCFS2_DEBUG_FS is not set CONFIG_BTRFS_FS=y CONFIG_BTRFS_FS_POSIX_ACL=y # CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set @@ -5927,76 +6950,84 @@ CONFIG_BTRFS_FS_POSIX_ACL=y # CONFIG_BTRFS_DEBUG is not set # CONFIG_BTRFS_ASSERT is not set # CONFIG_BTRFS_FS_REF_VERIFY is not set -# CONFIG_NILFS2_FS is not set +CONFIG_NILFS2_FS=m CONFIG_F2FS_FS=y CONFIG_F2FS_STAT_FS=y CONFIG_F2FS_FS_XATTR=y CONFIG_F2FS_FS_POSIX_ACL=y -# CONFIG_F2FS_FS_SECURITY is not set +CONFIG_F2FS_FS_SECURITY=y # CONFIG_F2FS_CHECK_FS is not set -# CONFIG_F2FS_FS_ENCRYPTION is not set # CONFIG_F2FS_IO_TRACE is not set # CONFIG_F2FS_FAULT_INJECTION is not set CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y -# CONFIG_EXPORTFS_BLOCK_OPS is not set +CONFIG_EXPORTFS_BLOCK_OPS=y CONFIG_FILE_LOCKING=y CONFIG_MANDATORY_FILE_LOCKING=y CONFIG_FS_ENCRYPTION=y +CONFIG_FS_VERITY=y +# CONFIG_FS_VERITY_DEBUG is not set +CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y CONFIG_INOTIFY_USER=y CONFIG_FANOTIFY=y -# CONFIG_FANOTIFY_ACCESS_PERMISSIONS is not set +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y -CONFIG_PRINT_QUOTA_WARNING=y +# CONFIG_PRINT_QUOTA_WARNING is not set # CONFIG_QUOTA_DEBUG is not set CONFIG_QUOTA_TREE=m CONFIG_QFMT_V1=m CONFIG_QFMT_V2=m CONFIG_QUOTACTL=y -CONFIG_AUTOFS4_FS=y -CONFIG_AUTOFS_FS=y -CONFIG_FUSE_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_FUSE_FS=y CONFIG_CUSE=m +CONFIG_VIRTIO_FS=m CONFIG_OVERLAY_FS=m # CONFIG_OVERLAY_FS_REDIRECT_DIR is not set CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y # CONFIG_OVERLAY_FS_INDEX is not set -# CONFIG_OVERLAY_FS_XINO_AUTO is not set +CONFIG_OVERLAY_FS_XINO_AUTO=y # CONFIG_OVERLAY_FS_METACOPY is not set # # Caches # CONFIG_FSCACHE=m -# CONFIG_FSCACHE_STATS is not set +CONFIG_FSCACHE_STATS=y # CONFIG_FSCACHE_HISTOGRAM is not set # CONFIG_FSCACHE_DEBUG is not set # CONFIG_FSCACHE_OBJECT_LIST is not set -# CONFIG_CACHEFILES is not set +CONFIG_CACHEFILES=m +# CONFIG_CACHEFILES_DEBUG is not set +# CONFIG_CACHEFILES_HISTOGRAM is not set +# end of Caches # # CD-ROM/DVD Filesystems # -CONFIG_ISO9660_FS=y +CONFIG_ISO9660_FS=m CONFIG_JOLIET=y -# CONFIG_ZISOFS is not set -CONFIG_UDF_FS=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +# end of CD-ROM/DVD Filesystems # # DOS/FAT/NT Filesystems # CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y +CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=y CONFIG_FAT_DEFAULT_CODEPAGE=437 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_FAT_DEFAULT_UTF8 is not set +CONFIG_FAT_DEFAULT_UTF8=y CONFIG_NTFS_FS=m # CONFIG_NTFS_DEBUG is not set CONFIG_NTFS_RW=y +# end of DOS/FAT/NT Filesystems # # Pseudo filesystems @@ -6004,7 +7035,7 @@ CONFIG_NTFS_RW=y CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=y -# CONFIG_PROC_CHILDREN is not set +CONFIG_PROC_CHILDREN=y CONFIG_KERNFS=y CONFIG_SYSFS=y CONFIG_TMPFS=y @@ -6012,60 +7043,105 @@ CONFIG_TMPFS_POSIX_ACL=y CONFIG_TMPFS_XATTR=y CONFIG_MEMFD_CREATE=y CONFIG_CONFIGFS_FS=y +# end of Pseudo filesystems + CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ORANGEFS_FS is not set -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -CONFIG_ECRYPT_FS=m -# CONFIG_ECRYPT_FS_MESSAGING is not set +CONFIG_ORANGEFS_FS=m +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=y +CONFIG_ECRYPT_FS_MESSAGING=y CONFIG_HFS_FS=m CONFIG_HFSPLUS_FS=m -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m CONFIG_JFFS2_FS=m CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y # CONFIG_JFFS2_FS_WBUF_VERIFY is not set # CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_FS_POSIX_ACL=y +CONFIG_JFFS2_FS_SECURITY=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_LZO=y CONFIG_JFFS2_RTIME=y -CONFIG_UBIFS_FS=y -CONFIG_UBIFS_FS_ADVANCED_COMPR=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +CONFIG_UBIFS_FS=m +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set CONFIG_UBIFS_FS_LZO=y CONFIG_UBIFS_FS_ZLIB=y -# CONFIG_UBIFS_ATIME_SUPPORT is not set +CONFIG_UBIFS_FS_ZSTD=y +CONFIG_UBIFS_ATIME_SUPPORT=y CONFIG_UBIFS_FS_XATTR=y -# CONFIG_UBIFS_FS_ENCRYPTION is not set CONFIG_UBIFS_FS_SECURITY=y -# CONFIG_CRAMFS is not set +CONFIG_UBIFS_FS_AUTHENTICATION=y +CONFIG_CRAMFS=m +CONFIG_CRAMFS_BLOCKDEV=y +# CONFIG_CRAMFS_MTD is not set CONFIG_SQUASHFS=m CONFIG_SQUASHFS_FILE_CACHE=y # CONFIG_SQUASHFS_FILE_DIRECT is not set -# CONFIG_SQUASHFS_DECOMP_SINGLE is not set -CONFIG_SQUASHFS_DECOMP_MULTI=y +CONFIG_SQUASHFS_DECOMP_SINGLE=y +# CONFIG_SQUASHFS_DECOMP_MULTI is not set # CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set CONFIG_SQUASHFS_XATTR=y CONFIG_SQUASHFS_ZLIB=y -# CONFIG_SQUASHFS_LZ4 is not set +CONFIG_SQUASHFS_LZ4=y CONFIG_SQUASHFS_LZO=y CONFIG_SQUASHFS_XZ=y -# CONFIG_SQUASHFS_ZSTD is not set +CONFIG_SQUASHFS_ZSTD=y CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y CONFIG_SQUASHFS_EMBEDDED=y CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX6FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_PSTORE is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set +CONFIG_VXFS_FS=m +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_QNX6FS_FS=m +# CONFIG_QNX6FS_DEBUG is not set +CONFIG_ROMFS_FS=m +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y +CONFIG_PSTORE=y +CONFIG_PSTORE_DEFLATE_COMPRESS=y +CONFIG_PSTORE_LZO_COMPRESS=m +CONFIG_PSTORE_LZ4_COMPRESS=m +CONFIG_PSTORE_LZ4HC_COMPRESS=m +CONFIG_PSTORE_842_COMPRESS=y +# CONFIG_PSTORE_ZSTD_COMPRESS is not set +CONFIG_PSTORE_COMPRESS=y +CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y +# CONFIG_PSTORE_LZO_COMPRESS_DEFAULT is not set +# CONFIG_PSTORE_LZ4_COMPRESS_DEFAULT is not set +# CONFIG_PSTORE_LZ4HC_COMPRESS_DEFAULT is not set +# CONFIG_PSTORE_842_COMPRESS_DEFAULT is not set +CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" +# CONFIG_PSTORE_CONSOLE is not set +# CONFIG_PSTORE_PMSG is not set +# CONFIG_PSTORE_FTRACE is not set +CONFIG_PSTORE_RAM=m +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +CONFIG_UFS_FS_WRITE=y +# CONFIG_UFS_DEBUG is not set +CONFIG_EROFS_FS=m +# CONFIG_EROFS_FS_DEBUG is not set +CONFIG_EROFS_FS_XATTR=y +CONFIG_EROFS_FS_POSIX_ACL=y +CONFIG_EROFS_FS_SECURITY=y +# CONFIG_EROFS_FS_ZIP is not set CONFIG_AUFS_FS=m CONFIG_AUFS_BRANCH_MAX_127=y # CONFIG_AUFS_BRANCH_MAX_511 is not set @@ -6073,11 +7149,11 @@ CONFIG_AUFS_BRANCH_MAX_127=y # CONFIG_AUFS_BRANCH_MAX_32767 is not set CONFIG_AUFS_SBILIST=y # CONFIG_AUFS_HNOTIFY is not set -# CONFIG_AUFS_EXPORT is not set -# CONFIG_AUFS_XATTR is not set +CONFIG_AUFS_EXPORT=y +CONFIG_AUFS_XATTR=y # CONFIG_AUFS_FHSM is not set # CONFIG_AUFS_RDU is not set -# CONFIG_AUFS_DIRREN is not set +CONFIG_AUFS_DIRREN=y # CONFIG_AUFS_SHWH is not set # CONFIG_AUFS_BR_RAMFS is not set # CONFIG_AUFS_BR_FUSE is not set @@ -6085,33 +7161,34 @@ CONFIG_AUFS_BR_HFSPLUS=y CONFIG_AUFS_BDEV_LOOP=y # CONFIG_AUFS_DEBUG is not set CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V2=y -CONFIG_NFS_V3=y +CONFIG_NFS_FS=m +CONFIG_NFS_V2=m +CONFIG_NFS_V3=m CONFIG_NFS_V3_ACL=y -CONFIG_NFS_V4=y +CONFIG_NFS_V4=m CONFIG_NFS_SWAP=y CONFIG_NFS_V4_1=y CONFIG_NFS_V4_2=y -CONFIG_PNFS_FILE_LAYOUT=y +CONFIG_PNFS_FILE_LAYOUT=m CONFIG_PNFS_BLOCK=m CONFIG_PNFS_FLEXFILE_LAYOUT=m CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" -# CONFIG_NFS_V4_1_MIGRATION is not set +CONFIG_NFS_V4_1_MIGRATION=y CONFIG_NFS_V4_SECURITY_LABEL=y -CONFIG_ROOT_NFS=y +CONFIG_NFS_FSCACHE=y # CONFIG_NFS_USE_LEGACY_DNS is not set CONFIG_NFS_USE_KERNEL_DNS=y +CONFIG_NFS_DEBUG=y CONFIG_NFSD=y CONFIG_NFSD_V2_ACL=y CONFIG_NFSD_V3=y CONFIG_NFSD_V3_ACL=y CONFIG_NFSD_V4=y -# CONFIG_NFSD_BLOCKLAYOUT is not set -# CONFIG_NFSD_SCSILAYOUT is not set -# CONFIG_NFSD_FLEXFILELAYOUT is not set -# CONFIG_NFSD_V4_SECURITY_LABEL is not set -# CONFIG_NFSD_FAULT_INJECTION is not set +CONFIG_NFSD_PNFS=y +CONFIG_NFSD_BLOCKLAYOUT=y +CONFIG_NFSD_SCSILAYOUT=y +CONFIG_NFSD_FLEXFILELAYOUT=y +CONFIG_NFSD_V4_SECURITY_LABEL=y CONFIG_GRACE_PERIOD=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y @@ -6122,120 +7199,190 @@ CONFIG_SUNRPC_GSS=y CONFIG_SUNRPC_BACKCHANNEL=y CONFIG_SUNRPC_SWAP=y CONFIG_RPCSEC_GSS_KRB5=m -# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES is not set +CONFIG_SUNRPC_DEBUG=y CONFIG_CEPH_FS=m CONFIG_CEPH_FSCACHE=y CONFIG_CEPH_FS_POSIX_ACL=y +CONFIG_CEPH_FS_SECURITY_LABEL=y CONFIG_CIFS=m -# CONFIG_CIFS_STATS2 is not set +CONFIG_CIFS_STATS2=y CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y -# CONFIG_CIFS_WEAK_PW_HASH is not set +CONFIG_CIFS_WEAK_PW_HASH=y CONFIG_CIFS_UPCALL=y CONFIG_CIFS_XATTR=y CONFIG_CIFS_POSIX=y -CONFIG_CIFS_ACL=y -# CONFIG_CIFS_DEBUG is not set -# CONFIG_CIFS_DFS_UPCALL is not set +CONFIG_CIFS_DEBUG=y +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DEBUG_DUMP_KEYS is not set +CONFIG_CIFS_DFS_UPCALL=y CONFIG_CIFS_FSCACHE=y -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set +CONFIG_CODA_FS=m +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FSCACHE=y +# CONFIG_AFS_DEBUG_CURSOR is not set +CONFIG_9P_FS=m +CONFIG_9P_FSCACHE=y +CONFIG_9P_FS_POSIX_ACL=y +CONFIG_9P_FS_SECURITY=y CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_DEFAULT="utf8" CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_MAC_ROMAN is not set -# CONFIG_NLS_MAC_CELTIC is not set -# CONFIG_NLS_MAC_CENTEURO is not set -# CONFIG_NLS_MAC_CROATIAN is not set -# CONFIG_NLS_MAC_CYRILLIC is not set -# CONFIG_NLS_MAC_GAELIC is not set -# CONFIG_NLS_MAC_GREEK is not set -# CONFIG_NLS_MAC_ICELAND is not set -# CONFIG_NLS_MAC_INUIT is not set -# CONFIG_NLS_MAC_ROMANIAN is not set -# CONFIG_NLS_MAC_TURKISH is not set -CONFIG_NLS_UTF8=y -# CONFIG_DLM is not set +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m +CONFIG_NLS_UTF8=m +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_UNICODE=y +# CONFIG_UNICODE_NORMALIZATION_SELFTEST is not set +# end of File systems # # Security options # CONFIG_KEYS=y -# CONFIG_PERSISTENT_KEYRINGS is not set -# CONFIG_BIG_KEYS is not set +CONFIG_KEYS_REQUEST_CACHE=y +CONFIG_PERSISTENT_KEYRINGS=y +CONFIG_BIG_KEYS=y +CONFIG_TRUSTED_KEYS=m CONFIG_ENCRYPTED_KEYS=y -# CONFIG_KEY_DH_OPERATIONS is not set +CONFIG_KEY_DH_OPERATIONS=y # CONFIG_SECURITY_DMESG_RESTRICT is not set CONFIG_SECURITY=y CONFIG_SECURITYFS=y CONFIG_SECURITY_NETWORK=y -# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_PATH=y -CONFIG_LSM_MMAP_MIN_ADDR=32768 +CONFIG_LSM_MMAP_MIN_ADDR=0 CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -# CONFIG_HARDENED_USERCOPY is not set -# CONFIG_FORTIFY_SOURCE is not set +CONFIG_HARDENED_USERCOPY=y +CONFIG_HARDENED_USERCOPY_FALLBACK=y +# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set +CONFIG_FORTIFY_SOURCE=y # CONFIG_STATIC_USERMODEHELPER is not set CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y -CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 # CONFIG_SECURITY_SELINUX_DISABLE is not set CONFIG_SECURITY_SELINUX_DEVELOP=y CONFIG_SECURITY_SELINUX_AVC_STATS=y -CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=0 -# CONFIG_SECURITY_SMACK is not set -# CONFIG_SECURITY_TOMOYO is not set +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SMACK=y +# CONFIG_SECURITY_SMACK_BRINGUP is not set +CONFIG_SECURITY_SMACK_NETFILTER=y +CONFIG_SECURITY_SMACK_APPEND_SIGNALS=y +CONFIG_SECURITY_TOMOYO=y +CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY=2048 +CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG=1024 +# CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER is not set +CONFIG_SECURITY_TOMOYO_POLICY_LOADER="/sbin/tomoyo-init" +CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER="/sbin/init" +# CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING is not set CONFIG_SECURITY_APPARMOR=y -CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=0 CONFIG_SECURITY_APPARMOR_HASH=y CONFIG_SECURITY_APPARMOR_HASH_DEFAULT=y # CONFIG_SECURITY_APPARMOR_DEBUG is not set # CONFIG_SECURITY_LOADPIN is not set -# CONFIG_SECURITY_YAMA is not set +CONFIG_SECURITY_YAMA=y +CONFIG_SECURITY_SAFESETID=y +CONFIG_SECURITY_LOCKDOWN_LSM=y +CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y +CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y +# CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY is not set +# CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY is not set CONFIG_INTEGRITY=y -# CONFIG_INTEGRITY_SIGNATURE is not set +CONFIG_INTEGRITY_SIGNATURE=y +CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y +CONFIG_INTEGRITY_TRUSTED_KEYRING=y +CONFIG_INTEGRITY_PLATFORM_KEYRING=y CONFIG_INTEGRITY_AUDIT=y -# CONFIG_IMA is not set +CONFIG_IMA=y +CONFIG_IMA_MEASURE_PCR_IDX=10 +CONFIG_IMA_LSM_RULES=y +# CONFIG_IMA_TEMPLATE is not set +CONFIG_IMA_NG_TEMPLATE=y +# CONFIG_IMA_SIG_TEMPLATE is not set +CONFIG_IMA_DEFAULT_TEMPLATE="ima-ng" +# CONFIG_IMA_DEFAULT_HASH_SHA1 is not set +CONFIG_IMA_DEFAULT_HASH_SHA256=y +# CONFIG_IMA_DEFAULT_HASH_SHA512 is not set +CONFIG_IMA_DEFAULT_HASH="sha256" +CONFIG_IMA_WRITE_POLICY=y +CONFIG_IMA_READ_POLICY=y +CONFIG_IMA_APPRAISE=y +# CONFIG_IMA_ARCH_POLICY is not set +# CONFIG_IMA_APPRAISE_BUILD_POLICY is not set +CONFIG_IMA_APPRAISE_BOOTPARAM=y +# CONFIG_IMA_APPRAISE_MODSIG is not set +# CONFIG_IMA_TRUSTED_KEYRING is not set +CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY=y # CONFIG_EVM is not set # CONFIG_DEFAULT_SECURITY_SELINUX is not set -# CONFIG_DEFAULT_SECURITY_APPARMOR is not set -CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_DEFAULT_SECURITY="" +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_APPARMOR=y +# CONFIG_DEFAULT_SECURITY_DAC is not set +CONFIG_LSM="yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor" + +# +# Kernel hardening options +# + +# +# Memory initialization +# +CONFIG_INIT_STACK_NONE=y +CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y +# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set +# end of Memory initialization +# end of Kernel hardening options +# end of Security options + CONFIG_XOR_BLOCKS=y CONFIG_ASYNC_CORE=m CONFIG_ASYNC_MEMCPY=m @@ -6261,11 +7408,8 @@ CONFIG_CRYPTO_RNG_DEFAULT=y CONFIG_CRYPTO_AKCIPHER2=y CONFIG_CRYPTO_AKCIPHER=y CONFIG_CRYPTO_KPP2=y -CONFIG_CRYPTO_KPP=m +CONFIG_CRYPTO_KPP=y CONFIG_CRYPTO_ACOMP2=y -CONFIG_CRYPTO_RSA=y -CONFIG_CRYPTO_DH=m -CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y CONFIG_CRYPTO_USER=m @@ -6274,24 +7418,29 @@ CONFIG_CRYPTO_GF128MUL=y CONFIG_CRYPTO_NULL=y CONFIG_CRYPTO_NULL2=y CONFIG_CRYPTO_PCRYPT=m -CONFIG_CRYPTO_WORKQUEUE=y -CONFIG_CRYPTO_CRYPTD=m -CONFIG_CRYPTO_MCRYPTD=m -CONFIG_CRYPTO_AUTHENC=y -# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_SIMD=m +CONFIG_CRYPTO_ENGINE=m + +# +# Public-key cryptography +# +CONFIG_CRYPTO_RSA=y +CONFIG_CRYPTO_DH=y +CONFIG_CRYPTO_ECC=m +CONFIG_CRYPTO_ECDH=m +CONFIG_CRYPTO_ECRDSA=m # # Authenticated Encryption with Associated Data # CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_CHACHA20POLY1305=m -# CONFIG_CRYPTO_AEGIS128 is not set -CONFIG_CRYPTO_AEGIS128L=m -CONFIG_CRYPTO_AEGIS256=m -CONFIG_CRYPTO_MORUS640=m -CONFIG_CRYPTO_MORUS1280=m +CONFIG_CRYPTO_AEGIS128=m +CONFIG_CRYPTO_AEGIS128_SIMD=y CONFIG_CRYPTO_SEQIV=y CONFIG_CRYPTO_ECHAINIV=m @@ -6304,14 +7453,18 @@ CONFIG_CRYPTO_CTR=y CONFIG_CRYPTO_CTS=y CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_OFB=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=y CONFIG_CRYPTO_KEYWRAP=m +CONFIG_CRYPTO_NHPOLY1305=m +CONFIG_CRYPTO_ADIANTUM=m +CONFIG_CRYPTO_ESSIV=m # # Hash modes # -CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_CMAC=m CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -6321,10 +7474,11 @@ CONFIG_CRYPTO_VMAC=m # CONFIG_CRYPTO_CRC32C=y CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_XXHASH=m CONFIG_CRYPTO_CRCT10DIF=y -CONFIG_CRYPTO_GHASH=m +CONFIG_CRYPTO_GHASH=y CONFIG_CRYPTO_POLY1305=m -CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m @@ -6332,27 +7486,32 @@ CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_RMD256=m CONFIG_CRYPTO_RMD320=m CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_LIB_SHA256=y CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_SHA3=m -# CONFIG_CRYPTO_SM3 is not set +CONFIG_CRYPTO_SM3=m +CONFIG_CRYPTO_STREEBOG=m CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m # # Ciphers # +CONFIG_CRYPTO_LIB_AES=y CONFIG_CRYPTO_AES=y CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_ARC4=y +CONFIG_CRYPTO_LIB_ARC4=m +CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_BLOWFISH_COMMON=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST_COMMON=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_LIB_DES=m +CONFIG_CRYPTO_DES=m CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SALSA20=m @@ -6369,7 +7528,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m # CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_842=m +CONFIG_CRYPTO_842=y CONFIG_CRYPTO_LZ4=m CONFIG_CRYPTO_LZ4HC=m CONFIG_CRYPTO_ZSTD=m @@ -6377,7 +7536,7 @@ CONFIG_CRYPTO_ZSTD=m # # Random Number Generation # -CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_ANSI_CPRNG=m CONFIG_CRYPTO_DRBG_MENU=y CONFIG_CRYPTO_DRBG_HMAC=y CONFIG_CRYPTO_DRBG_HASH=y @@ -6389,44 +7548,60 @@ 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_STATS=y CONFIG_CRYPTO_HASH_INFO=y CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set +# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set CONFIG_CRYPTO_DEV_SUN4I_SS=m # CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG is not set +CONFIG_CRYPTO_DEV_VIRTIO=m +CONFIG_CRYPTO_DEV_SAFEXCEL=m CONFIG_CRYPTO_DEV_CCREE=m CONFIG_ASYMMETRIC_KEY_TYPE=y CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE=m CONFIG_X509_CERTIFICATE_PARSER=y +CONFIG_PKCS8_PRIVATE_KEY_PARSER=m +CONFIG_TPM_KEY_PARSER=m CONFIG_PKCS7_MESSAGE_PARSER=y # CONFIG_PKCS7_TEST_KEY is not set -# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set +CONFIG_SIGNED_PE_FILE_VERIFICATION=y # # Certificates for signature checking # +CONFIG_MODULE_SIG_KEY="certs/signing_key.pem" CONFIG_SYSTEM_TRUSTED_KEYRING=y CONFIG_SYSTEM_TRUSTED_KEYS="" -# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set -# CONFIG_SECONDARY_TRUSTED_KEYRING is not set -# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set +CONFIG_SYSTEM_EXTRA_CERTIFICATE=y +CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE=4096 +CONFIG_SECONDARY_TRUSTED_KEYRING=y +CONFIG_SYSTEM_BLACKLIST_KEYRING=y +CONFIG_SYSTEM_BLACKLIST_HASH_LIST="" +# end of Certificates for signature checking + CONFIG_BINARY_PRINTF=y # # Library routines # CONFIG_RAID6_PQ=y +CONFIG_RAID6_PQ_BENCHMARK=y +CONFIG_PACKING=y CONFIG_BITREVERSE=y CONFIG_HAVE_ARCH_BITREVERSE=y -CONFIG_RATIONAL=y CONFIG_GENERIC_STRNCPY_FROM_USER=y CONFIG_GENERIC_STRNLEN_USER=y CONFIG_GENERIC_NET_UTILS=y +CONFIG_CORDIC=m +CONFIG_RATIONAL=y CONFIG_GENERIC_PCI_IOMAP=y CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y CONFIG_CRC_CCITT=y CONFIG_CRC16=y CONFIG_CRC_T10DIF=y -CONFIG_CRC_ITU_T=y +CONFIG_CRC_ITU_T=m CONFIG_CRC32=y # CONFIG_CRC32_SELFTEST is not set CONFIG_CRC32_SLICEBY8=y @@ -6441,8 +7616,8 @@ CONFIG_CRC8=m CONFIG_XXHASH=y CONFIG_AUDIT_GENERIC=y # CONFIG_RANDOM32_SELFTEST is not set -CONFIG_842_COMPRESS=m -CONFIG_842_DECOMPRESS=m +CONFIG_842_COMPRESS=y +CONFIG_842_DECOMPRESS=y CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y CONFIG_LZO_COMPRESS=y @@ -6460,7 +7635,7 @@ CONFIG_XZ_DEC_ARM=y CONFIG_XZ_DEC_ARMTHUMB=y CONFIG_XZ_DEC_SPARC=y CONFIG_XZ_DEC_BCJ=y -# CONFIG_XZ_DEC_TEST is not set +CONFIG_XZ_DEC_TEST=m CONFIG_DECOMPRESS_GZIP=y CONFIG_DECOMPRESS_BZIP2=y CONFIG_DECOMPRESS_LZMA=y @@ -6468,6 +7643,9 @@ CONFIG_DECOMPRESS_XZ=y CONFIG_DECOMPRESS_LZO=y CONFIG_DECOMPRESS_LZ4=y CONFIG_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_ENC8=y +CONFIG_REED_SOLOMON_DEC8=y CONFIG_TEXTSEARCH=y CONFIG_TEXTSEARCH_KMP=m CONFIG_TEXTSEARCH_BM=m @@ -6478,28 +7656,53 @@ CONFIG_HAS_IOPORT_MAP=y CONFIG_HAS_DMA=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_DMA_DECLARE_COHERENT=y +CONFIG_ARCH_HAS_SETUP_DMA_OPS=y +CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y +CONFIG_DMA_REMAP=y +CONFIG_DMA_CMA=y + +# +# Default contiguous memory area size: +# +CONFIG_CMA_SIZE_MBYTES=128 +CONFIG_CMA_SIZE_SEL_MBYTES=y +# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set +# CONFIG_CMA_SIZE_SEL_MIN is not set +# CONFIG_CMA_SIZE_SEL_MAX is not set +CONFIG_CMA_ALIGNMENT=8 +# CONFIG_DMA_API_DEBUG is not set CONFIG_SGL_ALLOC=y CONFIG_CPU_RMAP=y CONFIG_DQL=y CONFIG_GLOB=y # CONFIG_GLOB_SELFTEST is not set CONFIG_NLATTR=y +CONFIG_LRU_CACHE=m CONFIG_CLZ_TAB=y -CONFIG_CORDIC=m -# CONFIG_DDR is not set -# CONFIG_IRQ_POLL is not set +CONFIG_IRQ_POLL=y CONFIG_MPILIB=y +CONFIG_SIGNATURE=y CONFIG_LIBFDT=y CONFIG_OID_REGISTRY=y CONFIG_FONT_SUPPORT=y -# CONFIG_FONTS is not set +CONFIG_FONTS=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +CONFIG_FONT_ACORN_8x8=y +# CONFIG_FONT_MINI_4x6 is not set +CONFIG_FONT_6x10=y +# CONFIG_FONT_10x18 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +CONFIG_FONT_TER16x32=y CONFIG_SG_POOL=y -CONFIG_ARCH_HAS_SG_CHAIN=y CONFIG_SBITMAP=y # CONFIG_STRING_SELFTEST is not set +# end of Library routines # # Kernel hacking @@ -6509,11 +7712,13 @@ CONFIG_SBITMAP=y # printk and dmesg options # CONFIG_PRINTK_TIME=y +# CONFIG_PRINTK_CALLER is not set CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 CONFIG_CONSOLE_LOGLEVEL_QUIET=4 CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_DYNAMIC_DEBUG is not set +CONFIG_BOOT_PRINTK_DELAY=y +CONFIG_DYNAMIC_DEBUG=y +# end of printk and dmesg options # # Compile-time checks and compiler options @@ -6523,23 +7728,26 @@ CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 # CONFIG_STRIP_ASM_SYMS is not set # CONFIG_READABLE_ASM is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_PAGE_OWNER is not set CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set +# CONFIG_HEADERS_INSTALL is not set +CONFIG_OPTIMIZE_INLINING=y # CONFIG_DEBUG_SECTION_MISMATCH is not set CONFIG_SECTION_MISMATCH_WARN_ONLY=y # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# end of Compile-time checks and compiler options + CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 CONFIG_MAGIC_SYSRQ_SERIAL=y CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_MISC=y # # Memory Debugging # CONFIG_PAGE_EXTENSION=y # CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_PAGE_OWNER is not set # CONFIG_PAGE_POISONING is not set # CONFIG_DEBUG_PAGE_REF is not set # CONFIG_DEBUG_RODATA_TEST is not set @@ -6555,6 +7763,10 @@ CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y # CONFIG_DEBUG_MEMORY_INIT is not set # CONFIG_DEBUG_PER_CPU_MAPS is not set # CONFIG_DEBUG_HIGHMEM is not set +CONFIG_CC_HAS_KASAN_GENERIC=y +CONFIG_KASAN_STACK=1 +# end of Memory Debugging + CONFIG_ARCH_HAS_KCOV=y CONFIG_CC_HAS_SANCOV_TRACE_PC=y # CONFIG_KCOV is not set @@ -6566,6 +7778,8 @@ CONFIG_CC_HAS_SANCOV_TRACE_PC=y # CONFIG_SOFTLOCKUP_DETECTOR is not set # CONFIG_DETECT_HUNG_TASK is not set # CONFIG_WQ_WATCHDOG is not set +# end of Debug Lockups and Hangs + # CONFIG_PANIC_ON_OOPS is not set CONFIG_PANIC_ON_OOPS_VALUE=0 CONFIG_PANIC_TIMEOUT=0 @@ -6591,12 +7805,14 @@ CONFIG_LOCK_DEBUGGING_SUPPORT=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_LOCK_TORTURE_TEST is not set CONFIG_WW_MUTEX_SELFTEST=m +# end of Lock Debugging (spinlocks, mutexes, etc...) + CONFIG_STACKTRACE=y # CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_PI_LIST is not set +# CONFIG_DEBUG_PLIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_DEBUG_NOTIFIERS is not set # CONFIG_DEBUG_CREDENTIALS is not set @@ -6609,6 +7825,8 @@ CONFIG_DEBUG_BUGVERBOSE=y CONFIG_RCU_CPU_STALL_TIMEOUT=21 # CONFIG_RCU_TRACE is not set # CONFIG_RCU_EQS_DEBUG is not set +# end of RCU Debugging + # CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set @@ -6639,7 +7857,6 @@ CONFIG_FUNCTION_TRACER=y # CONFIG_TRACER_SNAPSHOT is not set CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set # CONFIG_STACK_TRACER is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_UPROBE_EVENTS is not set @@ -6653,48 +7870,56 @@ CONFIG_FTRACE_MCOUNT_RECORD=y # CONFIG_RING_BUFFER_STARTUP_TEST is not set # CONFIG_PREEMPTIRQ_DELAY_TEST is not set # CONFIG_TRACE_EVAL_MAP_FILE is not set -CONFIG_TRACING_EVENTS_GPIO=y -# CONFIG_DMA_API_DEBUG is not set CONFIG_RUNTIME_TESTING_MENU=y # CONFIG_LKDTM is not set # CONFIG_TEST_LIST_SORT is not set # CONFIG_TEST_SORT is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_RBTREE_TEST is not set +# CONFIG_REED_SOLOMON_TEST is not set # CONFIG_INTERVAL_TREE_TEST is not set # CONFIG_PERCPU_TEST is not set # CONFIG_ATOMIC64_SELFTEST is not set # CONFIG_ASYNC_RAID6_TEST is not set CONFIG_TEST_HEXDUMP=m # CONFIG_TEST_STRING_HELPERS is not set +CONFIG_TEST_STRSCPY=m # CONFIG_TEST_KSTRTOX is not set # CONFIG_TEST_PRINTF is not set # CONFIG_TEST_BITMAP is not set # CONFIG_TEST_BITFIELD is not set # CONFIG_TEST_UUID is not set +CONFIG_TEST_XARRAY=m CONFIG_TEST_OVERFLOW=m # CONFIG_TEST_RHASHTABLE is not set # CONFIG_TEST_HASH is not set CONFIG_TEST_IDA=m # CONFIG_TEST_LKM is not set +CONFIG_TEST_VMALLOC=m # CONFIG_TEST_USER_COPY is not set # CONFIG_TEST_BPF is not set +# CONFIG_TEST_BLACKHOLE_DEV is not set # CONFIG_FIND_BIT_BENCHMARK is not set # CONFIG_TEST_FIRMWARE is not set # CONFIG_TEST_SYSCTL is not set # CONFIG_TEST_UDELAY is not set # CONFIG_TEST_STATIC_KEYS is not set # CONFIG_TEST_KMOD is not set +CONFIG_TEST_MEMCAT_P=m +# CONFIG_TEST_STACKINIT is not set +# CONFIG_TEST_MEMINIT is not set # CONFIG_MEMTEST is not set # CONFIG_BUG_ON_DATA_CORRUPTION is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set # CONFIG_UBSAN is not set +CONFIG_UBSAN_ALIGNMENT=y CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y # CONFIG_STRICT_DEVMEM is not set # CONFIG_ARM_PTDUMP_DEBUGFS is not set # CONFIG_DEBUG_WX is not set +CONFIG_UNWINDER_ARM=y CONFIG_ARM_UNWIND=y # CONFIG_DEBUG_USER is not set CONFIG_DEBUG_LL=y @@ -6719,3 +7944,4 @@ CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" # CONFIG_EARLY_PRINTK is not set # CONFIG_PID_IN_CONTEXTIDR is not set # CONFIG_CORESIGHT is not set +# end of Kernel hacking diff --git a/config/kernel/linux-sunxi64-current.config b/config/kernel/linux-sunxi64-current.config index a1983fcc1..a47d0fa87 100644 --- a/config/kernel/linux-sunxi64-current.config +++ b/config/kernel/linux-sunxi64-current.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 5.4.51 Kernel Configuration +# Linux/arm64 5.7.7 Kernel Configuration # # @@ -8,12 +8,13 @@ # CONFIG_CC_IS_GCC=y CONFIG_GCC_VERSION=80300 +CONFIG_LD_VERSION=232000000 CONFIG_CLANG_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_HAS_ASM_GOTO=y CONFIG_CC_HAS_ASM_INLINE=y CONFIG_IRQ_WORK=y -CONFIG_BUILDTIME_EXTABLE_SORT=y +CONFIG_BUILDTIME_TABLE_SORT=y CONFIG_THREAD_INFO_IN_TASK=y # @@ -31,7 +32,7 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_CROSS_MEMORY_ATTACH=y -CONFIG_USELIB=y +# CONFIG_USELIB is not set CONFIG_AUDIT=y CONFIG_HAVE_ARCH_AUDITSYSCALL=y CONFIG_AUDITSYSCALL=y @@ -49,6 +50,7 @@ CONFIG_GENERIC_IRQ_CHIP=y CONFIG_IRQ_DOMAIN=y CONFIG_IRQ_SIM=y CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y CONFIG_GENERIC_MSI_IRQ=y CONFIG_GENERIC_MSI_IRQ_DOMAIN=y CONFIG_IRQ_MSI_IOMMU=y @@ -59,7 +61,6 @@ CONFIG_SPARSE_IRQ=y # end of IRQ subsystem CONFIG_GENERIC_IRQ_MULTI_HANDLER=y -CONFIG_ARCH_CLOCKSOURCE_DATA=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_ARCH_HAS_TICK_BROADCAST=y @@ -87,6 +88,7 @@ CONFIG_PREEMPT_NONE=y CONFIG_TICK_CPU_ACCOUNTING=y # CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set # CONFIG_IRQ_TIME_ACCOUNTING is not set +# CONFIG_SCHED_THERMAL_PRESSURE is not set CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_TASKSTATS=y @@ -105,7 +107,6 @@ CONFIG_TREE_RCU=y # CONFIG_RCU_EXPERT is not set CONFIG_SRCU=y CONFIG_TREE_SRCU=y -CONFIG_TASKS_RCU=y CONFIG_RCU_STALL_COMMON=y CONFIG_RCU_NEED_SEGCBLIST=y # end of RCU Subsystem @@ -126,9 +127,9 @@ CONFIG_GENERIC_SCHED_CLOCK=y # end of Scheduler features CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y +CONFIG_CC_HAS_INT128=y CONFIG_ARCH_SUPPORTS_INT128=y -CONFIG_NUMA_BALANCING=y -CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y +# CONFIG_NUMA_BALANCING is not set CONFIG_CGROUPS=y CONFIG_PAGE_COUNTER=y CONFIG_MEMCG=y @@ -151,7 +152,6 @@ CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_PERF=y CONFIG_CGROUP_BPF=y -# CONFIG_CGROUP_DEBUG is not set CONFIG_SOCK_CGROUP_DATA=y CONFIG_NAMESPACES=y CONFIG_UTS_NS=y @@ -160,7 +160,7 @@ CONFIG_USER_NS=y CONFIG_PID_NS=y CONFIG_NET_NS=y # CONFIG_CHECKPOINT_RESTORE is not set -CONFIG_SCHED_AUTOGROUP=y +# CONFIG_SCHED_AUTOGROUP is not set # CONFIG_SYSFS_DEPRECATED is not set CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y @@ -171,18 +171,17 @@ CONFIG_RD_LZMA=y CONFIG_RD_XZ=y CONFIG_RD_LZO=y CONFIG_RD_LZ4=y +# CONFIG_BOOT_CONFIG is not set CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_HAVE_UID16=y CONFIG_SYSCTL_EXCEPTION_TRACE=y CONFIG_BPF=y -CONFIG_EXPERT=y +# CONFIG_EXPERT is not set CONFIG_UID16=y CONFIG_MULTIUSER=y -# CONFIG_SGETMASK_SYSCALL is not set CONFIG_SYSFS_SYSCALL=y -# CONFIG_SYSCTL_SYSCALL is not set CONFIG_FHANDLE=y CONFIG_POSIX_TIMERS=y CONFIG_PRINTK=y @@ -192,6 +191,7 @@ CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_FUTEX_PI=y +CONFIG_HAVE_FUTEX_CMPXCHG=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y @@ -202,39 +202,35 @@ CONFIG_IO_URING=y CONFIG_ADVISE_SYSCALLS=y CONFIG_MEMBARRIER=y CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set CONFIG_KALLSYMS_BASE_RELATIVE=y CONFIG_BPF_SYSCALL=y +CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y # CONFIG_BPF_JIT_ALWAYS_ON is not set +CONFIG_BPF_JIT_DEFAULT_ON=y # CONFIG_USERFAULTFD is not set CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y CONFIG_RSEQ=y -# CONFIG_DEBUG_RSEQ is not set # CONFIG_EMBEDDED is not set CONFIG_HAVE_PERF_EVENTS=y -# CONFIG_PC104 is not set # # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y -# CONFIG_DEBUG_PERF_USE_VMALLOC is not set # end of Kernel Performance Events And Counters CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLUB_DEBUG=y -# CONFIG_SLUB_MEMCG_SYSFS_ON is not set # CONFIG_COMPAT_BRK is not set # CONFIG_SLAB is not set CONFIG_SLUB=y -# CONFIG_SLOB is not set CONFIG_SLAB_MERGE_DEFAULT=y # CONFIG_SLAB_FREELIST_RANDOM is not set # CONFIG_SLAB_FREELIST_HARDENED is not set # CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set CONFIG_SLUB_CPU_PARTIAL=y CONFIG_SYSTEM_DATA_VERIFICATION=y -CONFIG_PROFILING=y +# CONFIG_PROFILING is not set # end of General setup CONFIG_ARM64=y @@ -256,8 +252,10 @@ CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CSUM=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ZONE_DMA=y CONFIG_ZONE_DMA32=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_SMP=y CONFIG_KERNEL_MODE_NEON=y CONFIG_FIX_EARLYCON_MEM=y @@ -290,6 +288,7 @@ CONFIG_ARCH_SUNXI=y # CONFIG_ARCH_REALTEK is not set # CONFIG_ARCH_RENESAS is not set # CONFIG_ARCH_ROCKCHIP is not set +# CONFIG_ARCH_S32 is not set # CONFIG_ARCH_SEATTLE is not set # CONFIG_ARCH_STRATIX10 is not set # CONFIG_ARCH_SYNQUACER is not set @@ -316,26 +315,29 @@ CONFIG_ARM64_ERRATUM_826319=y CONFIG_ARM64_ERRATUM_827319=y CONFIG_ARM64_ERRATUM_824069=y CONFIG_ARM64_ERRATUM_819472=y -CONFIG_ARM64_ERRATUM_832075=y -CONFIG_ARM64_ERRATUM_834220=y +# CONFIG_ARM64_ERRATUM_832075 is not set CONFIG_ARM64_ERRATUM_845719=y CONFIG_ARM64_ERRATUM_843419=y CONFIG_ARM64_ERRATUM_1024718=y CONFIG_ARM64_ERRATUM_1418040=y +CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT_VHE=y CONFIG_ARM64_ERRATUM_1165522=y +CONFIG_ARM64_ERRATUM_1530923=y CONFIG_ARM64_ERRATUM_1286807=y +CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT_NVHE=y +CONFIG_ARM64_ERRATUM_1319367=y CONFIG_ARM64_ERRATUM_1463225=y CONFIG_ARM64_ERRATUM_1542419=y -CONFIG_CAVIUM_ERRATUM_22375=y +# CONFIG_CAVIUM_ERRATUM_22375 is not set CONFIG_CAVIUM_ERRATUM_23144=y -CONFIG_CAVIUM_ERRATUM_23154=y -CONFIG_CAVIUM_ERRATUM_27456=y -CONFIG_CAVIUM_ERRATUM_30115=y +# CONFIG_CAVIUM_ERRATUM_23154 is not set +# CONFIG_CAVIUM_ERRATUM_27456 is not set +# CONFIG_CAVIUM_ERRATUM_30115 is not set CONFIG_CAVIUM_TX2_ERRATUM_219=y -CONFIG_QCOM_FALKOR_ERRATUM_1003=y +# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y -CONFIG_QCOM_FALKOR_ERRATUM_1009=y -CONFIG_QCOM_QDF2400_ERRATUM_0065=y +# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set +# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set CONFIG_SOCIONEXT_SYNQUACER_PREITS=y CONFIG_HISILICON_ERRATUM_161600802=y CONFIG_QCOM_FALKOR_ERRATUM_E1041=y @@ -351,9 +353,10 @@ CONFIG_ARM64_VA_BITS=48 CONFIG_ARM64_PA_BITS_48=y CONFIG_ARM64_PA_BITS=48 # CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_SCHED_MC=y # CONFIG_SCHED_SMT is not set -CONFIG_NR_CPUS=256 +CONFIG_NR_CPUS=8 CONFIG_HOTPLUG_CPU=y CONFIG_NUMA=y CONFIG_NODES_SHIFT=2 @@ -380,11 +383,10 @@ CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y CONFIG_SECCOMP=y CONFIG_PARAVIRT=y # CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -CONFIG_KEXEC=y +# CONFIG_KEXEC is not set # CONFIG_KEXEC_FILE is not set -CONFIG_CRASH_DUMP=y -CONFIG_XEN_DOM0=y -CONFIG_XEN=y +# CONFIG_CRASH_DUMP is not set +# CONFIG_XEN is not set CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_UNMAP_KERNEL_AT_EL0=y CONFIG_HARDEN_BRANCH_PREDICTOR=y @@ -405,7 +407,8 @@ CONFIG_SETEND_EMULATION=y # CONFIG_ARM64_HW_AFDBM=y CONFIG_ARM64_PAN=y -# CONFIG_ARM64_LSE_ATOMICS is not set +CONFIG_ARM64_LSE_ATOMICS=y +CONFIG_ARM64_USE_LSE_ATOMICS=y CONFIG_ARM64_VHE=y # end of ARMv8.1 architectural features @@ -422,8 +425,23 @@ CONFIG_ARM64_CNP=y # ARMv8.3 architectural features # CONFIG_ARM64_PTR_AUTH=y +CONFIG_CC_HAS_SIGN_RETURN_ADDRESS=y +CONFIG_AS_HAS_PAC=y # end of ARMv8.3 architectural features +# +# ARMv8.4 architectural features +# +CONFIG_ARM64_AMU_EXTN=y +# end of ARMv8.4 architectural features + +# +# ARMv8.5 architectural features +# +CONFIG_ARM64_E0PD=y +CONFIG_ARCH_RANDOM=y +# end of ARMv8.5 architectural features + CONFIG_ARM64_SVE=y CONFIG_ARM64_MODULE_PLTS=y # CONFIG_ARM64_PSEUDO_NMI is not set @@ -434,10 +452,7 @@ CONFIG_ARM64_MODULE_PLTS=y # Boot options # CONFIG_CMDLINE="" -# CONFIG_CMDLINE_FORCE is not set -CONFIG_EFI_STUB=y -CONFIG_EFI=y -CONFIG_DMI=y +# CONFIG_EFI is not set # end of Boot options CONFIG_SYSVIPC_COMPAT=y @@ -448,10 +463,7 @@ CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y # CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y -# CONFIG_SUSPEND_SKIP_SYNC is not set -CONFIG_HIBERNATE_CALLBACKS=y -CONFIG_HIBERNATION=y -CONFIG_PM_STD_PARTITION="" +# CONFIG_HIBERNATION is not set CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y # CONFIG_PM_AUTOSLEEP is not set @@ -466,7 +478,6 @@ CONFIG_PM_GENERIC_DOMAINS_OF=y CONFIG_CPU_PM=y # CONFIG_ENERGY_MODEL is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_HIBERNATION_HEADER=y CONFIG_ARCH_SUSPEND_POSSIBLE=y # end of Power management options @@ -532,31 +543,10 @@ CONFIG_ARM_SCMI_POWER_DOMAIN=y CONFIG_ARM_SCPI_PROTOCOL=y CONFIG_ARM_SCPI_POWER_DOMAIN=y # CONFIG_ARM_SDE_INTERFACE is not set -# CONFIG_FIRMWARE_MEMMAP is not set -CONFIG_DMIID=y -CONFIG_DMI_SYSFS=m CONFIG_HAVE_ARM_SMCCC=y CONFIG_ARM_PSCI_FW=y # CONFIG_ARM_PSCI_CHECKER is not set # CONFIG_GOOGLE_FIRMWARE is not set - -# -# EFI (Extensible Firmware Interface) Support -# -CONFIG_EFI_VARS=m -CONFIG_EFI_ESRT=y -CONFIG_EFI_VARS_PSTORE=m -# CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE is not set -CONFIG_EFI_PARAMS_FROM_FDT=y -CONFIG_EFI_RUNTIME_WRAPPERS=y -CONFIG_EFI_ARMSTUB=y -CONFIG_EFI_ARMSTUB_DTB_LOADER=y -CONFIG_EFI_BOOTLOADER_CONTROL=m -CONFIG_EFI_CAPSULE_LOADER=m -CONFIG_EFI_TEST=m -# CONFIG_RESET_ATTACK_MITIGATION is not set -# end of EFI (Extensible Firmware Interface) Support - CONFIG_EFI_EARLYCON=y # @@ -565,38 +555,15 @@ CONFIG_EFI_EARLYCON=y # end of Tegra firmware driver # end of Firmware Drivers -CONFIG_ARCH_SUPPORTS_ACPI=y -# CONFIG_ACPI is not set -CONFIG_HAVE_KVM_IRQCHIP=y -CONFIG_HAVE_KVM_IRQFD=y -CONFIG_HAVE_KVM_IRQ_ROUTING=y -CONFIG_HAVE_KVM_EVENTFD=y -CONFIG_KVM_MMIO=y -CONFIG_HAVE_KVM_MSI=y -CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y -CONFIG_KVM_VFIO=y -CONFIG_HAVE_KVM_ARCH_TLB_FLUSH_ALL=y -CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y -CONFIG_HAVE_KVM_IRQ_BYPASS=y -CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE=y -CONFIG_IRQ_BYPASS_MANAGER=y -CONFIG_VIRTUALIZATION=y -CONFIG_KVM=y -CONFIG_KVM_ARM_HOST=y -CONFIG_KVM_ARM_PMU=y -CONFIG_KVM_INDIRECT_VECTORS=y -CONFIG_VHOST_NET=m -# CONFIG_VHOST_VSOCK is not set -CONFIG_VHOST=m -# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set +# CONFIG_VIRTUALIZATION is not set CONFIG_ARM64_CRYPTO=y CONFIG_CRYPTO_SHA256_ARM64=y CONFIG_CRYPTO_SHA512_ARM64=y CONFIG_CRYPTO_SHA1_ARM64_CE=y CONFIG_CRYPTO_SHA2_ARM64_CE=y # CONFIG_CRYPTO_SHA512_ARM64_CE is not set -CONFIG_CRYPTO_SHA3_ARM64=m -CONFIG_CRYPTO_SM3_ARM64_CE=m +# CONFIG_CRYPTO_SHA3_ARM64 is not set +# CONFIG_CRYPTO_SM3_ARM64_CE is not set CONFIG_CRYPTO_SM4_ARM64_CE=m CONFIG_CRYPTO_GHASH_ARM64_CE=y # CONFIG_CRYPTO_CRCT10DIF_ARM64_CE is not set @@ -606,14 +573,14 @@ CONFIG_CRYPTO_AES_ARM64_CE_CCM=y CONFIG_CRYPTO_AES_ARM64_CE_BLK=y CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y CONFIG_CRYPTO_CHACHA20_NEON=y -CONFIG_CRYPTO_NHPOLY1305_NEON=m +CONFIG_CRYPTO_POLY1305_NEON=m +# CONFIG_CRYPTO_NHPOLY1305_NEON is not set CONFIG_CRYPTO_AES_ARM64_BS=y # # General architecture-dependent options # CONFIG_CRASH_CORE=y -CONFIG_KEXEC_CORE=y # CONFIG_KPROBES is not set CONFIG_JUMP_LABEL=y # CONFIG_STATIC_KEYS_SELFTEST is not set @@ -641,7 +608,8 @@ CONFIG_HAVE_PERF_REGS=y CONFIG_HAVE_PERF_USER_STACK_DUMP=y CONFIG_HAVE_ARCH_JUMP_LABEL=y CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y -CONFIG_HAVE_RCU_TABLE_FREE=y +CONFIG_MMU_GATHER_TABLE_FREE=y +CONFIG_MMU_GATHER_RCU_TABLE_FREE=y CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y CONFIG_HAVE_CMPXCHG_LOCAL=y @@ -671,7 +639,6 @@ CONFIG_HAVE_COPY_THREAD_TLS=y CONFIG_CLONE_BACKWARDS=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_COMPAT_OLD_SIGACTION=y -CONFIG_64BIT_TIME=y CONFIG_COMPAT_32BIT_TIME=y CONFIG_HAVE_ARCH_VMAP_STACK=y CONFIG_VMAP_STACK=y @@ -679,7 +646,7 @@ CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y CONFIG_STRICT_KERNEL_RWX=y CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y CONFIG_STRICT_MODULE_RWX=y -CONFIG_REFCOUNT_FULL=y +CONFIG_HAVE_ARCH_COMPILER_H=y CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y CONFIG_ARCH_USE_MEMREMAP_PROT=y # CONFIG_LOCK_EVENT_COUNTS is not set @@ -691,7 +658,6 @@ CONFIG_ARCH_USE_MEMREMAP_PROT=y CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y # end of GCOV-based kernel profiling -CONFIG_PLUGIN_HOSTCC="" CONFIG_HAVE_GCC_PLUGINS=y # end of General architecture-dependent options @@ -720,9 +686,11 @@ CONFIG_MODULE_SIG_HASH="sha1" CONFIG_MODULES_TREE_LOOKUP=y CONFIG_BLOCK=y CONFIG_BLK_SCSI_REQUEST=y +CONFIG_BLK_CGROUP_RWSTAT=y CONFIG_BLK_DEV_BSG=y CONFIG_BLK_DEV_BSGLIB=y CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_INTEGRITY_T10=y CONFIG_BLK_DEV_ZONED=y CONFIG_BLK_DEV_THROTTLING=y # CONFIG_BLK_DEV_THROTTLING_LOW is not set @@ -756,7 +724,6 @@ CONFIG_BFQ_GROUP_IOSCHED=y # CONFIG_BFQ_CGROUP_DEBUG is not set # end of IO Schedulers -CONFIG_PREEMPT_NOTIFIERS=y CONFIG_PADATA=y CONFIG_ASN1=y CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y @@ -818,6 +785,7 @@ CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y CONFIG_QUEUED_SPINLOCKS=y CONFIG_ARCH_USE_QUEUED_RWLOCKS=y CONFIG_QUEUED_RWLOCKS=y +CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y CONFIG_FREEZER=y @@ -853,10 +821,11 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MEMORY_BALLOON=y CONFIG_BALLOON_COMPACTION=y CONFIG_COMPACTION=y +CONFIG_PAGE_REPORTING=y CONFIG_MIGRATION=y CONFIG_CONTIG_ALLOC=y CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_MMU_NOTIFIER=y +CONFIG_BOUNCE=y CONFIG_KSM=y CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y @@ -864,14 +833,24 @@ CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y CONFIG_TRANSPARENT_HUGEPAGE=y # CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y -CONFIG_TRANSPARENT_HUGE_PAGECACHE=y CONFIG_CLEANCACHE=y CONFIG_FRONTSWAP=y CONFIG_CMA=y -# CONFIG_CMA_DEBUG is not set # CONFIG_CMA_DEBUGFS is not set CONFIG_CMA_AREAS=7 CONFIG_ZSWAP=y +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE is not set +CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO=y +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842 is not set +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4 is not set +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4HC is not set +# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD is not set +CONFIG_ZSWAP_COMPRESSOR_DEFAULT="lzo" +CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y +# CONFIG_ZSWAP_ZPOOL_DEFAULT_Z3FOLD is not set +# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set +CONFIG_ZSWAP_ZPOOL_DEFAULT="zbud" +# CONFIG_ZSWAP_DEFAULT_ON is not set CONFIG_ZPOOL=y CONFIG_ZBUD=y CONFIG_Z3FOLD=y @@ -892,8 +871,6 @@ CONFIG_ARCH_HAS_PTE_SPECIAL=y CONFIG_NET=y CONFIG_COMPAT_NETLINK_MESSAGES=y CONFIG_NET_INGRESS=y -CONFIG_NET_EGRESS=y -CONFIG_NET_REDIRECT=y CONFIG_SKB_EXTENSIONS=y # @@ -904,23 +881,22 @@ CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_SCM=y CONFIG_UNIX_DIAG=m -CONFIG_TLS=m -CONFIG_TLS_DEVICE=y +CONFIG_TLS=y +# CONFIG_TLS_DEVICE is not set +# CONFIG_TLS_TOE is not set CONFIG_XFRM=y CONFIG_XFRM_OFFLOAD=y CONFIG_XFRM_ALGO=m CONFIG_XFRM_USER=m CONFIG_XFRM_INTERFACE=m -CONFIG_XFRM_SUB_POLICY=y -CONFIG_XFRM_MIGRATE=y -CONFIG_XFRM_STATISTICS=y +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set CONFIG_XFRM_IPCOMP=m CONFIG_NET_KEY=m -CONFIG_NET_KEY_MIGRATE=y +# CONFIG_NET_KEY_MIGRATE is not set # CONFIG_XDP_SOCKETS is not set CONFIG_INET=y -CONFIG_WIREGUARD=m -# CONFIG_WIREGUARD_DEBUG is not set CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_FIB_TRIE_STATS=y @@ -945,11 +921,12 @@ CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=m CONFIG_NET_UDP_TUNNEL=m -CONFIG_NET_FOU=m -CONFIG_NET_FOU_IP_TUNNELS=y +# CONFIG_NET_FOU is not set +# CONFIG_NET_FOU_IP_TUNNELS is not set CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_ESP_OFFLOAD=m +# CONFIG_INET_ESPINTCP is not set CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_TUNNEL=m CONFIG_INET_TUNNEL=m @@ -957,7 +934,7 @@ CONFIG_INET_DIAG=m CONFIG_INET_TCP_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_INET_RAW_DIAG=m -CONFIG_INET_DIAG_DESTROY=y +# CONFIG_INET_DIAG_DESTROY is not set CONFIG_TCP_CONG_ADVANCED=y CONFIG_TCP_CONG_BIC=m CONFIG_TCP_CONG_CUBIC=y @@ -974,10 +951,10 @@ CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_ILLINOIS=m CONFIG_TCP_CONG_DCTCP=m CONFIG_TCP_CONG_CDG=m -# CONFIG_TCP_CONG_BBR is not set -# CONFIG_DEFAULT_CUBIC is not set -CONFIG_DEFAULT_RENO=y -CONFIG_DEFAULT_TCP_CONG="reno" +CONFIG_TCP_CONG_BBR=m +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_TCP_MD5SIG=y CONFIG_IPV6=y CONFIG_IPV6_ROUTER_PREF=y @@ -988,26 +965,26 @@ CONFIG_INET6_ESP=m CONFIG_INET6_ESP_OFFLOAD=m CONFIG_INET6_IPCOMP=m CONFIG_IPV6_MIP6=m -CONFIG_IPV6_ILA=m +# CONFIG_IPV6_ILA is not set CONFIG_INET6_XFRM_TUNNEL=m CONFIG_INET6_TUNNEL=m CONFIG_IPV6_VTI=m CONFIG_IPV6_SIT=m -CONFIG_IPV6_SIT_6RD=y +# CONFIG_IPV6_SIT_6RD is not set CONFIG_IPV6_NDISC_NODETYPE=y CONFIG_IPV6_TUNNEL=m CONFIG_IPV6_GRE=m -CONFIG_IPV6_FOU=m -CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y -CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y -CONFIG_IPV6_PIMSM_V2=y +# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set +# CONFIG_IPV6_PIMSM_V2 is not set CONFIG_IPV6_SEG6_LWTUNNEL=y CONFIG_IPV6_SEG6_HMAC=y CONFIG_IPV6_SEG6_BPF=y +# CONFIG_IPV6_RPL_LWTUNNEL is not set CONFIG_NETLABEL=y +# CONFIG_MPTCP is not set CONFIG_NETWORK_SECMARK=y CONFIG_NET_PTP_CLASSIFY=y CONFIG_NETWORK_PHY_TIMESTAMPING=y @@ -1033,7 +1010,7 @@ CONFIG_NETFILTER_CONNCOUNT=m CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_ZONES=y -CONFIG_NF_CONNTRACK_PROCFS=y +# CONFIG_NF_CONNTRACK_PROCFS is not set CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CONNTRACK_TIMEOUT=y CONFIG_NF_CONNTRACK_TIMESTAMP=y @@ -1067,7 +1044,6 @@ CONFIG_NF_NAT_REDIRECT=y CONFIG_NF_NAT_MASQUERADE=y CONFIG_NETFILTER_SYNPROXY=m CONFIG_NF_TABLES=m -CONFIG_NF_TABLES_SET=m CONFIG_NF_TABLES_INET=y CONFIG_NF_TABLES_NETDEV=y CONFIG_NFT_NUMGEN=m @@ -1094,14 +1070,14 @@ CONFIG_NFT_XFRM=m CONFIG_NFT_SOCKET=m CONFIG_NFT_OSF=m CONFIG_NFT_TPROXY=m -CONFIG_NFT_SYNPROXY=m +# CONFIG_NFT_SYNPROXY is not set CONFIG_NF_DUP_NETDEV=m CONFIG_NFT_DUP_NETDEV=m CONFIG_NFT_FWD_NETDEV=m CONFIG_NFT_FIB_NETDEV=m CONFIG_NF_FLOW_TABLE_INET=m CONFIG_NF_FLOW_TABLE=m -CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XTABLES=y # # Xtables combined modules @@ -1130,7 +1106,7 @@ CONFIG_NETFILTER_XT_NAT=m CONFIG_NETFILTER_XT_TARGET_NETMAP=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set CONFIG_NETFILTER_XT_TARGET_RATEEST=m CONFIG_NETFILTER_XT_TARGET_REDIRECT=m CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m @@ -1212,7 +1188,7 @@ CONFIG_IP_SET_HASH_NETIFACE=m CONFIG_IP_SET_LIST_SET=m CONFIG_IP_VS=m CONFIG_IP_VS_IPV6=y -CONFIG_IP_VS_DEBUG=y +# CONFIG_IP_VS_DEBUG is not set CONFIG_IP_VS_TAB_BITS=12 # @@ -1278,7 +1254,7 @@ CONFIG_NF_REJECT_IPV4=m CONFIG_NF_NAT_SNMP_BASIC=m CONFIG_NF_NAT_PPTP=m CONFIG_NF_NAT_H323=m -CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_IPTABLES=y CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_RPFILTER=m @@ -1338,18 +1314,11 @@ CONFIG_IP6_NF_TARGET_NPT=m # end of IPv6: Netfilter Configuration CONFIG_NF_DEFRAG_IPV6=m - -# -# DECnet: Netfilter Configuration -# -CONFIG_DECNET_NF_GRABULATOR=m -# end of DECnet: Netfilter Configuration - CONFIG_NF_TABLES_BRIDGE=m -CONFIG_NFT_BRIDGE_META=m +# CONFIG_NFT_BRIDGE_META is not set CONFIG_NFT_BRIDGE_REJECT=m CONFIG_NF_LOG_BRIDGE=m -CONFIG_NF_CONNTRACK_BRIDGE=m +# CONFIG_NF_CONNTRACK_BRIDGE is not set CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m @@ -1371,32 +1340,21 @@ CONFIG_BRIDGE_EBT_REDIRECT=m CONFIG_BRIDGE_EBT_SNAT=m CONFIG_BRIDGE_EBT_LOG=m CONFIG_BRIDGE_EBT_NFLOG=m -CONFIG_BPFILTER=y -CONFIG_BPFILTER_UMH=m +# CONFIG_BPFILTER is not set # CONFIG_IP_DCCP is not set CONFIG_IP_SCTP=m -CONFIG_SCTP_DBG_OBJCNT=y +# CONFIG_SCTP_DBG_OBJCNT is not set CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y # CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set # CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set CONFIG_SCTP_COOKIE_HMAC_MD5=y -CONFIG_SCTP_COOKIE_HMAC_SHA1=y +# CONFIG_SCTP_COOKIE_HMAC_SHA1 is not set CONFIG_INET_SCTP_DIAG=m -CONFIG_RDS=m -CONFIG_RDS_TCP=m -# CONFIG_RDS_DEBUG is not set -CONFIG_TIPC=m -CONFIG_TIPC_MEDIA_UDP=y -CONFIG_TIPC_DIAG=m -CONFIG_ATM=m -CONFIG_ATM_CLIP=m -CONFIG_ATM_CLIP_NO_ICMP=y -CONFIG_ATM_LANE=m -CONFIG_ATM_MPOA=m -CONFIG_ATM_BR2684=m -CONFIG_ATM_BR2684_IPFILTER=y +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set CONFIG_L2TP=m -CONFIG_L2TP_DEBUGFS=m +# CONFIG_L2TP_DEBUGFS is not set CONFIG_L2TP_V3=y CONFIG_L2TP_IP=m CONFIG_L2TP_ETH=m @@ -1409,6 +1367,7 @@ CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_HAVE_NET_DSA=y CONFIG_NET_DSA=m CONFIG_NET_DSA_TAG_8021Q=m +CONFIG_NET_DSA_TAG_AR9331=m CONFIG_NET_DSA_TAG_BRCM_COMMON=m CONFIG_NET_DSA_TAG_BRCM=m CONFIG_NET_DSA_TAG_BRCM_PREPEND=m @@ -1417,6 +1376,7 @@ CONFIG_NET_DSA_TAG_DSA=m CONFIG_NET_DSA_TAG_EDSA=m CONFIG_NET_DSA_TAG_MTK=m CONFIG_NET_DSA_TAG_KSZ=m +CONFIG_NET_DSA_TAG_OCELOT=m CONFIG_NET_DSA_TAG_QCA=m CONFIG_NET_DSA_TAG_LAN9303=m CONFIG_NET_DSA_TAG_SJA1105=m @@ -1424,17 +1384,13 @@ CONFIG_NET_DSA_TAG_TRAILER=m CONFIG_VLAN_8021Q=y CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y -CONFIG_DECNET=m -CONFIG_DECNET_ROUTER=y +# CONFIG_DECNET is not set CONFIG_LLC=y -CONFIG_LLC2=m -CONFIG_ATALK=m -CONFIG_DEV_APPLETALK=m -CONFIG_IPDDP=m -CONFIG_IPDDP_ENCAP=y -CONFIG_X25=m -CONFIG_LAPB=m -CONFIG_PHONET=m +# CONFIG_LLC2 is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set CONFIG_6LOWPAN=m # CONFIG_6LOWPAN_DEBUGFS is not set CONFIG_6LOWPAN_NHC=m @@ -1452,10 +1408,10 @@ CONFIG_6LOWPAN_NHC_UDP=m # CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG is not set # CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE is not set CONFIG_IEEE802154=m -CONFIG_IEEE802154_NL802154_EXPERIMENTAL=y +# CONFIG_IEEE802154_NL802154_EXPERIMENTAL is not set CONFIG_IEEE802154_SOCKET=m -CONFIG_IEEE802154_6LOWPAN=m -CONFIG_MAC802154=m +# CONFIG_IEEE802154_6LOWPAN is not set +# CONFIG_MAC802154 is not set CONFIG_NET_SCHED=y # @@ -1464,7 +1420,6 @@ CONFIG_NET_SCHED=y CONFIG_NET_SCH_CBQ=m CONFIG_NET_SCH_HTB=m CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_ATM=m CONFIG_NET_SCH_PRIO=m CONFIG_NET_SCH_MULTIQ=m CONFIG_NET_SCH_RED=m @@ -1484,17 +1439,16 @@ CONFIG_NET_SCH_SKBPRIO=m CONFIG_NET_SCH_CHOKE=m CONFIG_NET_SCH_QFQ=m CONFIG_NET_SCH_CODEL=m -CONFIG_NET_SCH_FQ_CODEL=m +# CONFIG_NET_SCH_FQ_CODEL is not set CONFIG_NET_SCH_CAKE=m CONFIG_NET_SCH_FQ=m -CONFIG_NET_SCH_HHF=m -CONFIG_NET_SCH_PIE=m -CONFIG_NET_SCH_INGRESS=m -CONFIG_NET_SCH_PLUG=m +# CONFIG_NET_SCH_HHF is not set +# CONFIG_NET_SCH_PIE is not set +# CONFIG_NET_SCH_PLUG is not set +CONFIG_NET_SCH_ETS=m CONFIG_NET_SCH_DEFAULT=y # CONFIG_DEFAULT_FQ is not set # CONFIG_DEFAULT_CODEL is not set -# CONFIG_DEFAULT_FQ_CODEL is not set # CONFIG_DEFAULT_SFQ is not set CONFIG_DEFAULT_PFIFO_FAST=y CONFIG_DEFAULT_NET_SCH="pfifo_fast" @@ -1503,55 +1457,20 @@ CONFIG_DEFAULT_NET_SCH="pfifo_fast" # Classification # CONFIG_NET_CLS=y -CONFIG_NET_CLS_BASIC=m -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -CONFIG_CLS_U32_PERF=y -CONFIG_CLS_U32_MARK=y -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -CONFIG_NET_CLS_FLOW=m +# CONFIG_NET_CLS_BASIC is not set +# CONFIG_NET_CLS_TCINDEX is not set +# CONFIG_NET_CLS_ROUTE4 is not set +# CONFIG_NET_CLS_FW is not set +# CONFIG_NET_CLS_U32 is not set +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_CLS_FLOW is not set CONFIG_NET_CLS_CGROUP=m -CONFIG_NET_CLS_BPF=m -CONFIG_NET_CLS_FLOWER=m -CONFIG_NET_CLS_MATCHALL=m -CONFIG_NET_EMATCH=y -CONFIG_NET_EMATCH_STACK=32 -CONFIG_NET_EMATCH_CMP=m -CONFIG_NET_EMATCH_NBYTE=m -CONFIG_NET_EMATCH_U32=m -CONFIG_NET_EMATCH_META=m -CONFIG_NET_EMATCH_TEXT=m -CONFIG_NET_EMATCH_CANID=m -CONFIG_NET_EMATCH_IPSET=m -CONFIG_NET_EMATCH_IPT=m -CONFIG_NET_CLS_ACT=y -CONFIG_NET_ACT_POLICE=m -CONFIG_NET_ACT_GACT=m -CONFIG_GACT_PROB=y -CONFIG_NET_ACT_MIRRED=m -CONFIG_NET_ACT_SAMPLE=m -CONFIG_NET_ACT_IPT=m -CONFIG_NET_ACT_NAT=m -CONFIG_NET_ACT_PEDIT=m -CONFIG_NET_ACT_SIMP=m -CONFIG_NET_ACT_SKBEDIT=m -CONFIG_NET_ACT_CSUM=m -CONFIG_NET_ACT_MPLS=m -CONFIG_NET_ACT_VLAN=m -CONFIG_NET_ACT_BPF=m -CONFIG_NET_ACT_CONNMARK=m -CONFIG_NET_ACT_CTINFO=m -CONFIG_NET_ACT_SKBMOD=m -CONFIG_NET_ACT_IFE=m -CONFIG_NET_ACT_TUNNEL_KEY=m -CONFIG_NET_ACT_CT=m -CONFIG_NET_IFE_SKBMARK=m -CONFIG_NET_IFE_SKBPRIO=m -CONFIG_NET_IFE_SKBTCINDEX=m -# CONFIG_NET_TC_SKB_EXT is not set +# CONFIG_NET_CLS_BPF is not set +# CONFIG_NET_CLS_FLOWER is not set +# CONFIG_NET_CLS_MATCHALL is not set +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set CONFIG_NET_SCH_FIFO=y CONFIG_DCB=y CONFIG_DNS_RESOLVER=y @@ -1570,6 +1489,7 @@ CONFIG_OPENVSWITCH_VXLAN=m CONFIG_OPENVSWITCH_GENEVE=m CONFIG_VSOCKETS=m CONFIG_VSOCKETS_DIAG=m +CONFIG_VSOCKETS_LOOPBACK=m CONFIG_VIRTIO_VSOCKETS=m CONFIG_VIRTIO_VSOCKETS_COMMON=m CONFIG_NETLINK_DIAG=m @@ -1578,7 +1498,7 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_NSH=m -CONFIG_HSR=m +# CONFIG_HSR is not set CONFIG_NET_SWITCHDEV=y CONFIG_NET_L3_MASTER_DEV=y # CONFIG_NET_NCSI is not set @@ -1596,7 +1516,8 @@ CONFIG_NET_FLOW_LIMIT=y # # Network testing # -CONFIG_NET_PKTGEN=m +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set # end of Network testing # end of Networking options @@ -1636,21 +1557,14 @@ CONFIG_CAN_SLCAN=m CONFIG_CAN_DEV=m CONFIG_CAN_CALC_BITTIMING=y # CONFIG_CAN_FLEXCAN is not set -CONFIG_CAN_GRCAN=m -CONFIG_CAN_XILINXCAN=m -CONFIG_CAN_C_CAN=m -CONFIG_CAN_C_CAN_PLATFORM=m -CONFIG_CAN_CC770=m -CONFIG_CAN_CC770_ISA=m -CONFIG_CAN_CC770_PLATFORM=m +# CONFIG_CAN_GRCAN is not set +# CONFIG_CAN_XILINXCAN is not set +# CONFIG_CAN_C_CAN is not set +# CONFIG_CAN_CC770 is not set # CONFIG_CAN_IFI_CANFD is not set -CONFIG_CAN_M_CAN=m -CONFIG_CAN_M_CAN_PLATFORM=m -CONFIG_CAN_M_CAN_TCAN4X5X=m -CONFIG_CAN_SJA1000=m -CONFIG_CAN_SJA1000_ISA=m -CONFIG_CAN_SJA1000_PLATFORM=m -CONFIG_CAN_SOFTING=m +# CONFIG_CAN_M_CAN is not set +# CONFIG_CAN_SJA1000 is not set +# CONFIG_CAN_SOFTING is not set # # CAN SPI interfaces @@ -1685,9 +1599,8 @@ CONFIG_BT_BNEP_PROTO_FILTER=y CONFIG_BT_HIDP=m CONFIG_BT_HS=y CONFIG_BT_LE=y -CONFIG_BT_6LOWPAN=m +# CONFIG_BT_6LOWPAN is not set CONFIG_BT_LEDS=y -# CONFIG_BT_SELFTEST is not set CONFIG_BT_DEBUGFS=y # @@ -1700,7 +1613,7 @@ CONFIG_BT_QCA=m CONFIG_BT_HCIBTUSB=m # CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set CONFIG_BT_HCIBTUSB_BCM=y -CONFIG_BT_HCIBTUSB_MTK=y +# CONFIG_BT_HCIBTUSB_MTK is not set CONFIG_BT_HCIBTUSB_RTL=y CONFIG_BT_HCIBTSDIO=m CONFIG_BT_HCIUART=m @@ -1744,15 +1657,12 @@ CONFIG_WEXT_PRIV=y CONFIG_CFG80211=m # CONFIG_NL80211_TESTMODE is not set # CONFIG_CFG80211_DEVELOPER_WARNINGS is not set -# CONFIG_CFG80211_CERTIFICATION_ONUS is not set CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y # CONFIG_CFG80211_DEFAULT_PS is not set # CONFIG_CFG80211_DEBUGFS is not set CONFIG_CFG80211_CRDA_SUPPORT=y CONFIG_CFG80211_WEXT=y -CONFIG_LIB80211=m -# CONFIG_LIB80211_DEBUG is not set CONFIG_MAC80211=m CONFIG_MAC80211_HAS_RC=y CONFIG_MAC80211_RC_MINSTREL=y @@ -1764,20 +1674,18 @@ CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_MESSAGE_TRACING is not set # CONFIG_MAC80211_DEBUG_MENU is not set CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 -CONFIG_WIMAX=m -CONFIG_WIMAX_DEBUG_LEVEL=8 +# CONFIG_WIMAX is not set CONFIG_RFKILL=m CONFIG_RFKILL_LEDS=y CONFIG_RFKILL_INPUT=y -CONFIG_RFKILL_GPIO=m -CONFIG_NET_9P=m -CONFIG_NET_9P_VIRTIO=m -CONFIG_NET_9P_XEN=m +# CONFIG_RFKILL_GPIO is not set +CONFIG_NET_9P=y +CONFIG_NET_9P_VIRTIO=y # CONFIG_NET_9P_DEBUG is not set # CONFIG_CAIF is not set CONFIG_CEPH_LIB=m # CONFIG_CEPH_LIB_PRETTYDEBUG is not set -CONFIG_CEPH_LIB_USE_DNS_RESOLVER=y +# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set CONFIG_NFC=m CONFIG_NFC_DIGITAL=m CONFIG_NFC_NCI=m @@ -1799,6 +1707,7 @@ CONFIG_NFC_PN544_I2C=m CONFIG_NFC_PN533=m CONFIG_NFC_PN533_USB=m CONFIG_NFC_PN533_I2C=m +CONFIG_NFC_PN532_UART=m CONFIG_NFC_MICROREAD=m CONFIG_NFC_MICROREAD_I2C=m CONFIG_NFC_MRVL=m @@ -1819,16 +1728,16 @@ CONFIG_NFC_ST95HF=m # end of Near Field Communication (NFC) devices CONFIG_PSAMPLE=m -CONFIG_NET_IFE=m +# CONFIG_NET_IFE is not set CONFIG_LWTUNNEL=y -CONFIG_LWTUNNEL_BPF=y +# CONFIG_LWTUNNEL_BPF is not set CONFIG_DST_CACHE=y CONFIG_GRO_CELLS=y -CONFIG_SOCK_VALIDATE_XMIT=y CONFIG_NET_SOCK_MSG=y CONFIG_NET_DEVLINK=y CONFIG_PAGE_POOL=y CONFIG_FAILOVER=m +CONFIG_ETHTOOL_NETLINK=y CONFIG_HAVE_EBPF_JIT=y # @@ -1856,27 +1765,22 @@ CONFIG_FW_LOADER=y CONFIG_EXTRA_FIRMWARE="" # CONFIG_FW_LOADER_USER_HELPER is not set # CONFIG_FW_LOADER_COMPRESS is not set +CONFIG_FW_CACHE=y # end of Firmware loader CONFIG_WANT_DEV_COREDUMP=y CONFIG_ALLOW_DEV_COREDUMP=y CONFIG_DEV_COREDUMP=y -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set # CONFIG_TEST_ASYNC_DRIVER_PROBE is not set -CONFIG_SYS_HYPERVISOR=y CONFIG_GENERIC_CPU_AUTOPROBE=y CONFIG_GENERIC_CPU_VULNERABILITIES=y -CONFIG_SOC_BUS=y CONFIG_REGMAP=y CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_SPI=y +CONFIG_REGMAP_SPI=m CONFIG_REGMAP_SPMI=m CONFIG_REGMAP_W1=m CONFIG_REGMAP_MMIO=y CONFIG_REGMAP_IRQ=y -CONFIG_REGMAP_SCCB=m CONFIG_DMA_SHARED_BUFFER=y # CONFIG_DMA_FENCE_TRACE is not set CONFIG_GENERIC_ARCH_TOPOLOGY=y @@ -1886,12 +1790,13 @@ CONFIG_GENERIC_ARCH_TOPOLOGY=y # Bus devices # CONFIG_ARM_CCI=y -CONFIG_BRCMSTB_GISB_ARB=y +# CONFIG_BRCMSTB_GISB_ARB is not set # CONFIG_MOXTET is not set # CONFIG_SIMPLE_PM_BUS is not set CONFIG_SUN50I_DE2_BUS=y CONFIG_SUNXI_RSB=y # CONFIG_VEXPRESS_CONFIG is not set +CONFIG_MHI_BUS=m # end of Bus devices CONFIG_CONNECTOR=m @@ -1940,9 +1845,9 @@ CONFIG_MTD_MAP_BANK_WIDTH_2=y CONFIG_MTD_MAP_BANK_WIDTH_4=y CONFIG_MTD_CFI_I1=y CONFIG_MTD_CFI_I2=y -CONFIG_MTD_CFI_INTELEXT=m -CONFIG_MTD_CFI_AMDSTD=m -CONFIG_MTD_CFI_STAA=m +# CONFIG_MTD_CFI_INTELEXT is not set +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set @@ -1991,6 +1896,7 @@ CONFIG_MTD_NAND_SUNXI=m CONFIG_MTD_NAND_MXIC=m CONFIG_MTD_NAND_GPIO=m CONFIG_MTD_NAND_PLATFORM=m +CONFIG_MTD_NAND_CADENCE=m # # Misc @@ -2011,7 +1917,6 @@ CONFIG_MTD_SPI_NAND=m CONFIG_MTD_SPI_NOR=y CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y # CONFIG_SPI_CADENCE_QUADSPI is not set -CONFIG_SPI_MTK_QUADSPI=m # CONFIG_MTD_UBI is not set # CONFIG_MTD_HYPERBUS is not set CONFIG_DTC=y @@ -2041,14 +1946,12 @@ CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_DRBD=m # CONFIG_DRBD_FAULT_INJECTION is not set -CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=m CONFIG_BLK_DEV_RAM_COUNT=8 CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_CDROM_PKTCDVD is not set CONFIG_ATA_OVER_ETH=m -CONFIG_XEN_BLKDEV_FRONTEND=m -CONFIG_XEN_BLKDEV_BACKEND=m # CONFIG_VIRTIO_BLK is not set CONFIG_BLK_DEV_RBD=m @@ -2106,43 +2009,12 @@ CONFIG_EEPROM_EE1004=m # # Intel MIC & related support # - -# -# Intel MIC Bus Driver -# - -# -# SCIF Bus Driver -# - -# -# VOP Bus Driver -# # CONFIG_VOP_BUS is not set - -# -# Intel MIC Host Driver -# - -# -# Intel MIC Card Driver -# - -# -# SCIF Driver -# - -# -# Intel MIC Coprocessor State Management (COSM) Drivers -# - -# -# VOP Driver -# # end of Intel MIC & related support # CONFIG_ECHO is not set # CONFIG_MISC_RTSX_USB is not set +CONFIG_UACCE=m # end of Misc devices # @@ -2184,7 +2056,6 @@ CONFIG_ISCSI_BOOT_SYSFS=m CONFIG_SCSI_UFSHCD=m # CONFIG_SCSI_UFSHCD_PLATFORM is not set # CONFIG_SCSI_UFS_BSG is not set -CONFIG_XEN_SCSI_FRONTEND=m # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_VIRTIO is not set # CONFIG_SCSI_DH is not set @@ -2193,7 +2064,7 @@ CONFIG_XEN_SCSI_FRONTEND=m CONFIG_HAVE_PATA_PLATFORM=y CONFIG_ATA=m # CONFIG_ATA_VERBOSE_ERROR is not set -# CONFIG_SATA_PMP is not set +CONFIG_ATA_FORCE=y # # Controllers with non-SFF native interface @@ -2204,21 +2075,22 @@ CONFIG_ATA=m # CONFIG_AHCI_QORIQ is not set # CONFIG_ATA_SFF is not set CONFIG_MD=y -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID10=m -CONFIG_MD_RAID456=m -CONFIG_MD_MULTIPATH=m -CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_MD=y +CONFIG_MD_AUTODETECT=y +CONFIG_MD_LINEAR=y +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +CONFIG_MD_RAID10=y +CONFIG_MD_RAID456=y +CONFIG_MD_MULTIPATH=y +CONFIG_MD_FAULTY=y CONFIG_MD_CLUSTER=m CONFIG_BCACHE=y # CONFIG_BCACHE_DEBUG is not set # CONFIG_BCACHE_CLOSURES_DEBUG is not set CONFIG_BLK_DEV_DM_BUILTIN=y CONFIG_BLK_DEV_DM=m -CONFIG_DM_DEBUG=y +# CONFIG_DM_DEBUG is not set CONFIG_DM_BUFIO=m # CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set CONFIG_DM_BIO_PRISON=m @@ -2237,27 +2109,26 @@ CONFIG_DM_LOG_USERSPACE=m CONFIG_DM_RAID=m CONFIG_DM_ZERO=m CONFIG_DM_MULTIPATH=m -CONFIG_DM_MULTIPATH_QL=m -CONFIG_DM_MULTIPATH_ST=m +# CONFIG_DM_MULTIPATH_QL is not set +# CONFIG_DM_MULTIPATH_ST is not set CONFIG_DM_DELAY=m CONFIG_DM_DUST=m -CONFIG_DM_UEVENT=y -CONFIG_DM_FLAKEY=m -CONFIG_DM_VERITY=m -# CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG is not set -CONFIG_DM_VERITY_FEC=y -CONFIG_DM_SWITCH=m -CONFIG_DM_LOG_WRITES=m +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_FLAKEY is not set +# CONFIG_DM_VERITY is not set +# CONFIG_DM_SWITCH is not set +# CONFIG_DM_LOG_WRITES is not set CONFIG_DM_INTEGRITY=m -CONFIG_DM_ZONED=m +# CONFIG_DM_ZONED is not set # CONFIG_TARGET_CORE is not set CONFIG_NETDEVICES=y CONFIG_MII=y CONFIG_NET_CORE=y CONFIG_BONDING=m CONFIG_DUMMY=m +CONFIG_WIREGUARD=m +# CONFIG_WIREGUARD_DEBUG is not set CONFIG_EQUALIZER=m -CONFIG_IFB=m CONFIG_NET_TEAM=m CONFIG_NET_TEAM_MODE_BROADCAST=m CONFIG_NET_TEAM_MODE_ROUNDROBIN=m @@ -2271,61 +2142,46 @@ CONFIG_IPVLAN=m CONFIG_IPVTAP=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_BAREUDP=m CONFIG_GTP=m CONFIG_MACSEC=m CONFIG_NETCONSOLE=m -CONFIG_NETCONSOLE_DYNAMIC=y +# CONFIG_NETCONSOLE_DYNAMIC is not set CONFIG_NETPOLL=y CONFIG_NET_POLL_CONTROLLER=y -CONFIG_TUN=y +CONFIG_TUN=m CONFIG_TAP=m -CONFIG_TUN_VNET_CROSS_LE=y +# CONFIG_TUN_VNET_CROSS_LE is not set CONFIG_VETH=m CONFIG_VIRTIO_NET=m CONFIG_NLMON=m -CONFIG_NET_VRF=m -CONFIG_ATM_DRIVERS=y -CONFIG_ATM_DUMMY=m -CONFIG_ATM_TCP=m - -# -# CAIF transport drivers -# +# CONFIG_NET_VRF is not set # # Distributed Switch Architecture drivers # -CONFIG_B53=m -CONFIG_B53_SPI_DRIVER=m -CONFIG_B53_MDIO_DRIVER=m -CONFIG_B53_MMAP_DRIVER=m -CONFIG_B53_SRAB_DRIVER=m -CONFIG_B53_SERDES=m -CONFIG_NET_DSA_BCM_SF2=m -CONFIG_NET_DSA_LOOP=m +# CONFIG_B53 is not set +# CONFIG_NET_DSA_BCM_SF2 is not set +# CONFIG_NET_DSA_LOOP is not set CONFIG_NET_DSA_LANTIQ_GSWIP=m -CONFIG_NET_DSA_MT7530=m -CONFIG_NET_DSA_MV88E6060=m +# CONFIG_NET_DSA_MT7530 is not set +# CONFIG_NET_DSA_MV88E6060 is not set CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=m CONFIG_NET_DSA_MICROCHIP_KSZ9477=m CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C=m CONFIG_NET_DSA_MICROCHIP_KSZ9477_SPI=m CONFIG_NET_DSA_MICROCHIP_KSZ8795=m CONFIG_NET_DSA_MICROCHIP_KSZ8795_SPI=m -CONFIG_NET_DSA_MV88E6XXX=m -CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y -# CONFIG_NET_DSA_MV88E6XXX_PTP is not set +# CONFIG_NET_DSA_MV88E6XXX is not set +CONFIG_NET_DSA_AR9331=m CONFIG_NET_DSA_SJA1105=m # CONFIG_NET_DSA_SJA1105_PTP is not set -# CONFIG_NET_DSA_SJA1105_TAS is not set -CONFIG_NET_DSA_QCA8K=m +# CONFIG_NET_DSA_QCA8K is not set CONFIG_NET_DSA_REALTEK_SMI=m -CONFIG_NET_DSA_SMSC_LAN9303=m -CONFIG_NET_DSA_SMSC_LAN9303_I2C=m -CONFIG_NET_DSA_SMSC_LAN9303_MDIO=m -CONFIG_NET_DSA_VITESSE_VSC73XX=m -CONFIG_NET_DSA_VITESSE_VSC73XX_SPI=m -CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM=m +# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set +# CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set +# CONFIG_NET_DSA_VITESSE_VSC73XX_SPI is not set +# CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM is not set # end of Distributed Switch Architecture drivers CONFIG_ETHERNET=y @@ -2356,7 +2212,6 @@ CONFIG_NET_VENDOR_HISILICON=y CONFIG_HIP04_ETH=m # CONFIG_HI13X1_GMAC is not set CONFIG_HNS_MDIO=m -# CONFIG_HNS is not set # CONFIG_HNS_DSAF is not set # CONFIG_HNS_ENET is not set CONFIG_NET_VENDOR_HUAWEI=y @@ -2365,10 +2220,7 @@ CONFIG_NET_VENDOR_HUAWEI=y CONFIG_NET_VENDOR_MELLANOX=y # CONFIG_MLXSW_CORE is not set # CONFIG_MLXFW is not set -CONFIG_NET_VENDOR_MICREL=y -# CONFIG_KS8842 is not set -# CONFIG_KS8851 is not set -# CONFIG_KS8851_MLL is not set +# CONFIG_NET_VENDOR_MICREL is not set CONFIG_NET_VENDOR_MICROCHIP=y CONFIG_ENC28J60=m CONFIG_ENC28J60_WRITEVERIFY=y @@ -2385,7 +2237,7 @@ CONFIG_NET_VENDOR_QUALCOMM=y CONFIG_QCA7000=m # CONFIG_QCA7000_SPI is not set CONFIG_QCA7000_UART=m -CONFIG_QCOM_EMAC=m +# CONFIG_QCOM_EMAC is not set # CONFIG_RMNET is not set CONFIG_NET_VENDOR_RENESAS=y CONFIG_NET_VENDOR_ROCKER=y @@ -2406,9 +2258,12 @@ CONFIG_NET_VENDOR_SYNOPSYS=y # CONFIG_DWC_XLGMAC is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_NET_VENDOR_XILINX=y +CONFIG_XILINX_AXI_EMAC=m +CONFIG_XILINX_LL_TEMAC=m CONFIG_MDIO_DEVICE=y CONFIG_MDIO_BUS=y -CONFIG_MDIO_BCM_UNIMAC=m +# CONFIG_MDIO_BCM_UNIMAC is not set CONFIG_MDIO_BITBANG=y CONFIG_MDIO_BUS_MUX=m # CONFIG_MDIO_BUS_MUX_GPIO is not set @@ -2416,10 +2271,12 @@ CONFIG_MDIO_BUS_MUX=m CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m # CONFIG_MDIO_GPIO is not set # CONFIG_MDIO_HISI_FEMAC is not set -CONFIG_MDIO_I2C=m +CONFIG_MDIO_IPQ8064=m CONFIG_MDIO_MSCC_MIIM=m +CONFIG_MDIO_MVUSB=m # CONFIG_MDIO_OCTEON is not set CONFIG_MDIO_SUN4I=y +CONFIG_MDIO_XPCS=y CONFIG_PHYLINK=y CONFIG_PHYLIB=y CONFIG_SWPHY=y @@ -2428,17 +2285,17 @@ CONFIG_LED_TRIGGER_PHY=y # # MII PHY device drivers # -CONFIG_SFP=m +# CONFIG_SFP is not set CONFIG_ADIN_PHY=m -CONFIG_AC200_PHY=m +CONFIG_AC200_PHY=y CONFIG_AMD_PHY=m CONFIG_AQUANTIA_PHY=m CONFIG_AX88796B_PHY=m -CONFIG_AT803X_PHY=m -CONFIG_BCM7XXX_PHY=m +# CONFIG_BCM7XXX_PHY is not set CONFIG_BCM87XX_PHY=m CONFIG_BCM_NET_PHYLIB=m CONFIG_BROADCOM_PHY=m +# CONFIG_BCM84881_PHY is not set CONFIG_CICADA_PHY=m # CONFIG_CORTINA_PHY is not set CONFIG_DAVICOM_PHY=m @@ -2446,26 +2303,28 @@ CONFIG_DAVICOM_PHY=m CONFIG_DP83TC811_PHY=m CONFIG_DP83848_PHY=m # CONFIG_DP83867_PHY is not set +CONFIG_DP83869_PHY=m CONFIG_FIXED_PHY=y CONFIG_ICPLUS_PHY=m # CONFIG_INTEL_XWAY_PHY is not set CONFIG_LSI_ET1011C_PHY=m CONFIG_LXT_PHY=m CONFIG_MARVELL_PHY=m -CONFIG_MARVELL_10G_PHY=m -CONFIG_MICREL_PHY=y +# CONFIG_MARVELL_10G_PHY is not set +CONFIG_MICREL_PHY=m CONFIG_MICROCHIP_PHY=m CONFIG_MICROCHIP_T1_PHY=m # CONFIG_MICROSEMI_PHY is not set CONFIG_NATIONAL_PHY=m # CONFIG_NXP_TJA11XX_PHY is not set +CONFIG_AT803X_PHY=m CONFIG_QSEMI_PHY=m CONFIG_REALTEK_PHY=m # CONFIG_RENESAS_PHY is not set -CONFIG_ROCKCHIP_PHY=y -# CONFIG_SMSC_PHY is not set -# CONFIG_STE10XP is not set -# CONFIG_TERANETICS_PHY is not set +# CONFIG_ROCKCHIP_PHY is not set +CONFIG_SMSC_PHY=m +CONFIG_STE10XP=m +CONFIG_TERANETICS_PHY=m CONFIG_VITESSE_PHY=m # CONFIG_XILINX_GMII2RGMII is not set # CONFIG_MICREL_KS8995MA is not set @@ -2475,18 +2334,14 @@ CONFIG_PPP_DEFLATE=m CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=m CONFIG_PPP_MULTILINK=y -CONFIG_PPPOATM=m CONFIG_PPPOE=m CONFIG_PPTP=m CONFIG_PPPOL2TP=m CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m -CONFIG_SLIP=m +# CONFIG_SLIP is not set CONFIG_SLHC=m -CONFIG_SLIP_COMPRESSED=y -CONFIG_SLIP_SMART=y -CONFIG_SLIP_MODE_SLIP6=y -CONFIG_USB_NET_DRIVERS=y +CONFIG_USB_NET_DRIVERS=m CONFIG_USB_CATC=m CONFIG_USB_KAWETH=m CONFIG_USB_PEGASUS=m @@ -2525,15 +2380,13 @@ CONFIG_USB_NET_KALMIA=m CONFIG_USB_NET_QMI_WWAN=m CONFIG_USB_HSO=m CONFIG_USB_NET_INT51X1=m -CONFIG_USB_CDC_PHONET=m CONFIG_USB_IPHETH=m CONFIG_USB_SIERRA_NET=m CONFIG_USB_VL600=m CONFIG_USB_NET_CH9200=m -CONFIG_USB_NET_AQC111=m +# CONFIG_USB_NET_AQC111 is not set CONFIG_WLAN=y -CONFIG_WIRELESS_WDS=y -# CONFIG_WLAN_VENDOR_ADMTEK is not set +CONFIG_WLAN_VENDOR_ADMTEK=y CONFIG_ATH_COMMON=m CONFIG_WLAN_VENDOR_ATH=y # CONFIG_ATH_DEBUG is not set @@ -2550,11 +2403,9 @@ CONFIG_ATH9K_RFKILL=y CONFIG_ATH9K_PCOEM=y CONFIG_ATH9K_HTC=m # CONFIG_ATH9K_HTC_DEBUGFS is not set -# CONFIG_ATH9K_HWRNG is not set CONFIG_CARL9170=m CONFIG_CARL9170_LEDS=y CONFIG_CARL9170_WPC=y -# CONFIG_CARL9170_HWRNG is not set # CONFIG_ATH6KL is not set CONFIG_AR5523=m CONFIG_ATH10K=m @@ -2580,11 +2431,9 @@ CONFIG_B43_PHY_N=y CONFIG_B43_PHY_LP=y CONFIG_B43_PHY_HT=y CONFIG_B43_LEDS=y -CONFIG_B43_HWRNG=y # CONFIG_B43_DEBUG is not set CONFIG_B43LEGACY=m CONFIG_B43LEGACY_LEDS=y -CONFIG_B43LEGACY_HWRNG=y CONFIG_B43LEGACY_DEBUG=y CONFIG_B43LEGACY_DMA=y CONFIG_B43LEGACY_PIO=y @@ -2657,38 +2506,17 @@ CONFIG_RTL8821CU=m CONFIG_88XXAU=m CONFIG_RTL8189FS=m CONFIG_RTL8189ES=m -CONFIG_WLAN_VENDOR_ZYDAS=y -CONFIG_USB_ZD1201=m -CONFIG_ZD1211RW=m -# CONFIG_ZD1211RW_DEBUG is not set +# CONFIG_WLAN_VENDOR_ZYDAS is not set CONFIG_WLAN_VENDOR_QUANTENNA=y # CONFIG_MAC80211_HWSIM is not set CONFIG_USB_NET_RNDIS_WLAN=m CONFIG_VIRT_WIFI=m # -# WiMAX Wireless Broadband devices +# Enable WiMAX (Networking options) to see the WiMAX drivers # -CONFIG_WIMAX_I2400M=m -CONFIG_WIMAX_I2400M_USB=m -CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8 -# end of WiMAX Wireless Broadband devices - # CONFIG_WAN is not set CONFIG_IEEE802154_DRIVERS=m -CONFIG_IEEE802154_FAKELB=m -CONFIG_IEEE802154_AT86RF230=m -# CONFIG_IEEE802154_AT86RF230_DEBUGFS is not set -CONFIG_IEEE802154_MRF24J40=m -CONFIG_IEEE802154_CC2520=m -CONFIG_IEEE802154_ATUSB=m -CONFIG_IEEE802154_ADF7242=m -CONFIG_IEEE802154_CA8210=m -# CONFIG_IEEE802154_CA8210_DEBUGFS is not set -CONFIG_IEEE802154_MCR20A=m -CONFIG_IEEE802154_HWSIM=m -CONFIG_XEN_NETDEV_FRONTEND=m -CONFIG_XEN_NETDEV_BACKEND=m CONFIG_NETDEVSIM=m CONFIG_NET_FAILOVER=m # CONFIG_ISDN is not set @@ -2702,7 +2530,7 @@ CONFIG_INPUT_LEDS=y CONFIG_INPUT_FF_MEMLESS=m CONFIG_INPUT_POLLDEV=m # CONFIG_INPUT_SPARSEKMAP is not set -CONFIG_INPUT_MATRIXKMAP=m +# CONFIG_INPUT_MATRIXKMAP is not set # # Userland interfaces @@ -2719,8 +2547,7 @@ CONFIG_INPUT_EVDEV=y # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ADC=m -CONFIG_KEYBOARD_ADP5520=m +# CONFIG_KEYBOARD_ADC is not set # CONFIG_KEYBOARD_ADP5588 is not set # CONFIG_KEYBOARD_ADP5589 is not set CONFIG_KEYBOARD_ATKBD=y @@ -2744,14 +2571,13 @@ CONFIG_KEYBOARD_GPIO=y # CONFIG_KEYBOARD_SAMSUNG is not set # CONFIG_KEYBOARD_STOWAWAY is not set # CONFIG_KEYBOARD_SUNKBD is not set -CONFIG_KEYBOARD_SUN4I_LRADC=m +# CONFIG_KEYBOARD_SUN4I_LRADC is not set +CONFIG_KEYBOARD_IQS62X=m # CONFIG_KEYBOARD_OMAP4 is not set # CONFIG_KEYBOARD_TM2_TOUCHKEY is not set -CONFIG_KEYBOARD_TWL4030=m # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_CAP11XX is not set # CONFIG_KEYBOARD_BCM is not set -CONFIG_KEYBOARD_MTK_PMIC=m CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y CONFIG_MOUSE_PS2_ALPS=y @@ -2779,7 +2605,6 @@ CONFIG_MOUSE_PS2_SMBUS=y # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_PROPERTIES=y -CONFIG_TOUCHSCREEN_88PM860X=m CONFIG_TOUCHSCREEN_ADS7846=m CONFIG_TOUCHSCREEN_AD7877=m CONFIG_TOUCHSCREEN_AD7879=m @@ -2788,33 +2613,31 @@ CONFIG_TOUCHSCREEN_AD7879_SPI=m CONFIG_TOUCHSCREEN_ADC=m CONFIG_TOUCHSCREEN_AR1021_I2C=m CONFIG_TOUCHSCREEN_ATMEL_MXT=m -CONFIG_TOUCHSCREEN_ATMEL_MXT_T37=y -CONFIG_TOUCHSCREEN_AUO_PIXCIR=m -CONFIG_TOUCHSCREEN_BU21013=m +# CONFIG_TOUCHSCREEN_ATMEL_MXT_T37 is not set +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set CONFIG_TOUCHSCREEN_BU21029=m # CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set # CONFIG_TOUCHSCREEN_CY8CTMG110 is not set # CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set # CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set -CONFIG_TOUCHSCREEN_DA9034=m -CONFIG_TOUCHSCREEN_DA9052=m # CONFIG_TOUCHSCREEN_DYNAPRO is not set # CONFIG_TOUCHSCREEN_HAMPSHIRE is not set # CONFIG_TOUCHSCREEN_EETI is not set # CONFIG_TOUCHSCREEN_EGALAX is not set # CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set CONFIG_TOUCHSCREEN_EXC3000=m -CONFIG_TOUCHSCREEN_FUJITSU=m +# CONFIG_TOUCHSCREEN_FUJITSU is not set CONFIG_TOUCHSCREEN_GOODIX=m CONFIG_TOUCHSCREEN_HIDEEP=m CONFIG_TOUCHSCREEN_ILI210X=m CONFIG_TOUCHSCREEN_S6SY761=m -CONFIG_TOUCHSCREEN_GUNZE=m -CONFIG_TOUCHSCREEN_EKTF2127=m -CONFIG_TOUCHSCREEN_ELAN=m -CONFIG_TOUCHSCREEN_ELO=m -CONFIG_TOUCHSCREEN_WACOM_W8001=m -CONFIG_TOUCHSCREEN_WACOM_I2C=m +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_EKTF2127 is not set +# CONFIG_TOUCHSCREEN_ELAN is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_WACOM_I2C is not set CONFIG_TOUCHSCREEN_MAX11801=m # CONFIG_TOUCHSCREEN_MCS5000 is not set # CONFIG_TOUCHSCREEN_MMS114 is not set @@ -2827,17 +2650,9 @@ CONFIG_TOUCHSCREEN_MAX11801=m # CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set -CONFIG_TOUCHSCREEN_TI_AM335X_TSC=m -CONFIG_TOUCHSCREEN_UCB1400=m # CONFIG_TOUCHSCREEN_PIXCIR is not set # CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set -CONFIG_TOUCHSCREEN_WM831X=m -CONFIG_TOUCHSCREEN_WM97XX=m -CONFIG_TOUCHSCREEN_WM9705=y -CONFIG_TOUCHSCREEN_WM9712=y -CONFIG_TOUCHSCREEN_WM9713=y CONFIG_TOUCHSCREEN_USB_COMPOSITE=m -CONFIG_TOUCHSCREEN_MC13783=m CONFIG_TOUCHSCREEN_USB_EGALAX=y CONFIG_TOUCHSCREEN_USB_PANJIT=y CONFIG_TOUCHSCREEN_USB_3M=y @@ -2861,7 +2676,6 @@ CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y # CONFIG_TOUCHSCREEN_TSC2004 is not set # CONFIG_TOUCHSCREEN_TSC2005 is not set # CONFIG_TOUCHSCREEN_TSC2007 is not set -CONFIG_TOUCHSCREEN_PCAP=m # CONFIG_TOUCHSCREEN_RM_TS is not set CONFIG_TOUCHSCREEN_SILEAD=m # CONFIG_TOUCHSCREEN_SIS_I2C is not set @@ -2877,25 +2691,17 @@ CONFIG_TOUCHSCREEN_SILEAD=m # CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set CONFIG_TOUCHSCREEN_IQS5XX=m CONFIG_INPUT_MISC=y -CONFIG_INPUT_88PM860X_ONKEY=m -CONFIG_INPUT_88PM80X_ONKEY=m # CONFIG_INPUT_AD714X is not set -CONFIG_INPUT_ARIZONA_HAPTICS=m # CONFIG_INPUT_ATMEL_CAPTOUCH is not set # CONFIG_INPUT_BMA150 is not set # CONFIG_INPUT_E3X0_BUTTON is not set CONFIG_INPUT_MSM_VIBRATOR=m CONFIG_INPUT_MAX77650_ONKEY=m -CONFIG_INPUT_MAX77693_HAPTIC=m -CONFIG_INPUT_MAX8925_ONKEY=m -CONFIG_INPUT_MAX8997_HAPTIC=m -CONFIG_INPUT_MC13783_PWRBUTTON=m # CONFIG_INPUT_MMA8450 is not set # CONFIG_INPUT_GP2A is not set # CONFIG_INPUT_GPIO_BEEPER is not set CONFIG_INPUT_GPIO_DECODER=m CONFIG_INPUT_GPIO_VIBRA=m -CONFIG_INPUT_CPCAP_PWRBUTTON=m # CONFIG_INPUT_ATI_REMOTE2 is not set # CONFIG_INPUT_KEYSPAN_REMOTE is not set # CONFIG_INPUT_KXTJ9 is not set @@ -2903,29 +2709,15 @@ CONFIG_INPUT_CPCAP_PWRBUTTON=m # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_CM109 is not set # CONFIG_INPUT_REGULATOR_HAPTIC is not set -CONFIG_INPUT_RETU_PWRBUTTON=m -CONFIG_INPUT_TPS65218_PWRBUTTON=m CONFIG_INPUT_AXP20X_PEK=y -CONFIG_INPUT_TWL4030_PWRBUTTON=m -CONFIG_INPUT_TWL4030_VIBRA=m -CONFIG_INPUT_TWL6040_VIBRA=m CONFIG_INPUT_UINPUT=m -CONFIG_INPUT_PALMAS_PWRBUTTON=m -CONFIG_INPUT_PCF50633_PMU=m CONFIG_INPUT_PCF8574=m # CONFIG_INPUT_PWM_BEEPER is not set CONFIG_INPUT_PWM_VIBRA=m -CONFIG_INPUT_RK805_PWRKEY=m CONFIG_INPUT_GPIO_ROTARY_ENCODER=m -CONFIG_INPUT_DA9052_ONKEY=m -CONFIG_INPUT_DA9055_ONKEY=m -CONFIG_INPUT_DA9063_ONKEY=m -CONFIG_INPUT_WM831X_ON=m -CONFIG_INPUT_PCAP=m # CONFIG_INPUT_ADXL34X is not set # CONFIG_INPUT_IMS_PCU is not set # CONFIG_INPUT_CMA3000 is not set -CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m # CONFIG_INPUT_DRV260X_HAPTICS is not set # CONFIG_INPUT_DRV2665_HAPTICS is not set # CONFIG_INPUT_DRV2667_HAPTICS is not set @@ -2974,28 +2766,21 @@ CONFIG_VT_CONSOLE_SLEEP=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=0 -CONFIG_SERIAL_NONSTANDARD=y -CONFIG_N_HDLC=m -CONFIG_N_GSM=m -CONFIG_TRACE_ROUTER=m -CONFIG_TRACE_SINK=m -CONFIG_NULL_TTY=m +# CONFIG_LEGACY_PTYS is not set CONFIG_LDISC_AUTOLOAD=y -CONFIG_DEVMEM=y # # Serial drivers # CONFIG_SERIAL_EARLYCON=y CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -CONFIG_SERIAL_8250_FINTEK=y +CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y +# CONFIG_SERIAL_8250_16550A_VARIANTS is not set +# CONFIG_SERIAL_8250_FINTEK is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_DMA=y -CONFIG_SERIAL_8250_NR_UARTS=8 -CONFIG_SERIAL_8250_RUNTIME_UARTS=8 +CONFIG_SERIAL_8250_NR_UARTS=6 +CONFIG_SERIAL_8250_RUNTIME_UARTS=6 # CONFIG_SERIAL_8250_EXTENDED is not set # CONFIG_SERIAL_8250_ASPEED_VUART is not set CONFIG_SERIAL_8250_DWLIB=y @@ -3007,82 +2792,65 @@ CONFIG_SERIAL_OF_PLATFORM=y # # Non-8250 serial port support # -CONFIG_SERIAL_AMBA_PL010=m -CONFIG_SERIAL_AMBA_PL011=m +# CONFIG_SERIAL_AMBA_PL010 is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y # CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -CONFIG_SERIAL_MAX3100=m -CONFIG_SERIAL_MAX310X=y -CONFIG_SERIAL_UARTLITE=m -CONFIG_SERIAL_UARTLITE_NR_UARTS=1 +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX310X is not set +# CONFIG_SERIAL_UARTLITE is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_SERIAL_SIFIVE=m -CONFIG_SERIAL_SCCNXP=y -CONFIG_SERIAL_SCCNXP_CONSOLE=y +# CONFIG_SERIAL_SCCNXP is not set CONFIG_SERIAL_SC16IS7XX_CORE=m CONFIG_SERIAL_SC16IS7XX=m CONFIG_SERIAL_SC16IS7XX_I2C=y -CONFIG_SERIAL_SC16IS7XX_SPI=y -CONFIG_SERIAL_ALTERA_JTAGUART=m -CONFIG_SERIAL_ALTERA_UART=m -CONFIG_SERIAL_ALTERA_UART_MAXPORTS=4 -CONFIG_SERIAL_ALTERA_UART_BAUDRATE=115200 +# CONFIG_SERIAL_SC16IS7XX_SPI is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set # CONFIG_SERIAL_IFX6X60 is not set CONFIG_SERIAL_XILINX_PS_UART=y CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y -CONFIG_SERIAL_ARC=m -CONFIG_SERIAL_ARC_NR_PORTS=1 -CONFIG_SERIAL_FSL_LPUART=m +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_FSL_LPUART is not set CONFIG_SERIAL_FSL_LINFLEXUART=m -CONFIG_SERIAL_CONEXANT_DIGICOLOR=m +# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set +CONFIG_SERIAL_SPRD=m # end of Serial drivers CONFIG_SERIAL_MCTRL_GPIO=y +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +CONFIG_NULL_TTY=m +# CONFIG_TRACE_SINK is not set +CONFIG_HVC_DRIVER=y +# CONFIG_HVC_DCC is not set CONFIG_SERIAL_DEV_BUS=y CONFIG_SERIAL_DEV_CTRL_TTYPORT=y -CONFIG_TTY_PRINTK=m -CONFIG_TTY_PRINTK_LEVEL=6 -CONFIG_HVC_DRIVER=y -CONFIG_HVC_IRQ=y -CONFIG_HVC_XEN=y -CONFIG_HVC_XEN_FRONTEND=y -# CONFIG_HVC_DCC is not set CONFIG_VIRTIO_CONSOLE=y -CONFIG_IPMI_HANDLER=m -CONFIG_IPMI_DMI_DECODE=y -CONFIG_IPMI_PLAT_DATA=y -# CONFIG_IPMI_PANIC_EVENT is not set -CONFIG_IPMI_DEVICE_INTERFACE=m -CONFIG_IPMI_SI=m -CONFIG_IPMI_SSIF=m -CONFIG_IPMI_WATCHDOG=m -CONFIG_IPMI_POWEROFF=m -CONFIG_IPMB_DEVICE_INTERFACE=m -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_TIMERIOMEM=m -CONFIG_HW_RANDOM_VIRTIO=m -CONFIG_HW_RANDOM_OPTEE=m -CONFIG_RAW_DRIVER=m -CONFIG_MAX_RAW_DEVS=256 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMB_DEVICE_INTERFACE is not set +# CONFIG_HW_RANDOM is not set +CONFIG_DEVMEM=y +# CONFIG_RAW_DRIVER is not set CONFIG_TCG_TPM=y -CONFIG_HW_RANDOM_TPM=y -CONFIG_TCG_TIS_CORE=y -CONFIG_TCG_TIS=y +CONFIG_TCG_TIS_CORE=m +CONFIG_TCG_TIS=m CONFIG_TCG_TIS_SPI=m +# CONFIG_TCG_TIS_SPI_CR50 is not set CONFIG_TCG_TIS_I2C_ATMEL=m CONFIG_TCG_TIS_I2C_INFINEON=m CONFIG_TCG_TIS_I2C_NUVOTON=m -CONFIG_TCG_XEN=m CONFIG_TCG_VTPM_PROXY=m -CONFIG_TCG_FTPM_TEE=m CONFIG_TCG_TIS_ST33ZP24=m CONFIG_TCG_TIS_ST33ZP24_I2C=m CONFIG_TCG_TIS_ST33ZP24_SPI=m -CONFIG_XILLYBUS=m -CONFIG_XILLYBUS_OF=m +# CONFIG_XILLYBUS is not set # end of Character devices -CONFIG_RANDOM_TRUST_BOOTLOADER=y +# CONFIG_RANDOM_TRUST_CPU is not set +# CONFIG_RANDOM_TRUST_BOOTLOADER is not set # # I2C support @@ -3091,7 +2859,7 @@ CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MUX=m +CONFIG_I2C_MUX=y # # Multiplexer I2C Chip support @@ -3122,13 +2890,12 @@ CONFIG_I2C_ALGOPCA=m # CONFIG_I2C_CADENCE=m CONFIG_I2C_CBUS_GPIO=m -CONFIG_I2C_DESIGNWARE_CORE=m -CONFIG_I2C_DESIGNWARE_PLATFORM=m +CONFIG_I2C_DESIGNWARE_CORE=y +CONFIG_I2C_DESIGNWARE_PLATFORM=y # CONFIG_I2C_DESIGNWARE_SLAVE is not set CONFIG_I2C_EMEV2=m CONFIG_I2C_GPIO=m # CONFIG_I2C_GPIO_FAULT_INJECTOR is not set -CONFIG_I2C_KEMPLD=m CONFIG_I2C_MV64XXX=m CONFIG_I2C_NOMADIK=m CONFIG_I2C_OCORES=m @@ -3141,12 +2908,9 @@ CONFIG_I2C_XILINX=m # External I2C/SMBus adapter drivers # CONFIG_I2C_DIOLAN_U2C=m -CONFIG_I2C_DLN2=m -CONFIG_I2C_PARPORT_LIGHT=m CONFIG_I2C_ROBOTFUZZ_OSIF=m CONFIG_I2C_TAOS_EVM=m CONFIG_I2C_TINY_USB=m -CONFIG_I2C_VIPERBOARD=m # # Other I2C/SMBus bus drivers @@ -3165,7 +2929,6 @@ CONFIG_I3C=m CONFIG_CDNS_I3C_MASTER=m CONFIG_DW_I3C_MASTER=m CONFIG_SPI=y -# CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y CONFIG_SPI_MEM=y @@ -3178,14 +2941,13 @@ CONFIG_SPI_BITBANG=m CONFIG_SPI_CADENCE=m CONFIG_SPI_DESIGNWARE=m CONFIG_SPI_DW_MMIO=m -CONFIG_SPI_DLN2=m CONFIG_SPI_NXP_FLEXSPI=m CONFIG_SPI_GPIO=m CONFIG_SPI_FSL_LIB=m CONFIG_SPI_FSL_SPI=m CONFIG_SPI_OC_TINY=m CONFIG_SPI_PL022=y -# CONFIG_SPI_ROCKCHIP is not set +CONFIG_SPI_ROCKCHIP=m CONFIG_SPI_SC18IS602=m CONFIG_SPI_SIFIVE=m CONFIG_SPI_SUN4I=y @@ -3195,6 +2957,11 @@ CONFIG_SPI_XCOMM=m CONFIG_SPI_XILINX=m CONFIG_SPI_ZYNQMP_GQSPI=m +# +# SPI Multiplexer support +# +CONFIG_SPI_MUX=m + # # SPI Protocol Masters # @@ -3204,18 +2971,8 @@ CONFIG_SPI_TLE62X0=m CONFIG_SPI_SLAVE=y CONFIG_SPI_SLAVE_TIME=m CONFIG_SPI_SLAVE_SYSTEM_CONTROL=m -CONFIG_SPMI=m -CONFIG_HSI=m -CONFIG_HSI_BOARDINFO=y - -# -# HSI controllers -# - -# -# HSI clients -# -CONFIG_HSI_CHAR=m +CONFIG_SPMI=y +# CONFIG_HSI is not set CONFIG_PPS=y # CONFIG_PPS_DEBUG is not set @@ -3234,7 +2991,10 @@ CONFIG_PPS_CLIENT_GPIO=m # PTP clock support # CONFIG_PTP_1588_CLOCK=y -CONFIG_DP83640_PHY=m +# CONFIG_DP83640_PHY is not set +CONFIG_PTP_1588_CLOCK_INES=m +CONFIG_PTP_1588_CLOCK_IDT82P33=m +CONFIG_PTP_1588_CLOCK_IDTCM=m # end of PTP clock support CONFIG_PINCTRL=y @@ -3243,69 +3003,62 @@ CONFIG_PINMUX=y CONFIG_GENERIC_PINMUX_FUNCTIONS=y CONFIG_PINCONF=y CONFIG_GENERIC_PINCONF=y -# CONFIG_DEBUG_PINCTRL is not set -CONFIG_PINCTRL_AS3722=m CONFIG_PINCTRL_AXP209=m -CONFIG_PINCTRL_AMD=y -CONFIG_PINCTRL_MCP23S08=m +# CONFIG_PINCTRL_AMD is not set +# CONFIG_PINCTRL_MCP23S08 is not set CONFIG_PINCTRL_SINGLE=y -CONFIG_PINCTRL_SX150X=y +# CONFIG_PINCTRL_SX150X is not set CONFIG_PINCTRL_STMFX=m -CONFIG_PINCTRL_PALMAS=m -CONFIG_PINCTRL_RK805=m # CONFIG_PINCTRL_OCELOT is not set CONFIG_PINCTRL_SUNXI=y # CONFIG_PINCTRL_SUN4I_A10 is not set -CONFIG_PINCTRL_SUN5I=y -CONFIG_PINCTRL_SUN6I_A31=y -CONFIG_PINCTRL_SUN6I_A31_R=y -CONFIG_PINCTRL_SUN8I_A23=y -CONFIG_PINCTRL_SUN8I_A33=y -CONFIG_PINCTRL_SUN8I_A83T=y -CONFIG_PINCTRL_SUN8I_A83T_R=y -CONFIG_PINCTRL_SUN8I_A23_R=y -CONFIG_PINCTRL_SUN8I_H3=y +# CONFIG_PINCTRL_SUN5I is not set +# CONFIG_PINCTRL_SUN6I_A31 is not set +# CONFIG_PINCTRL_SUN6I_A31_R is not set +# CONFIG_PINCTRL_SUN8I_A23 is not set +# CONFIG_PINCTRL_SUN8I_A33 is not set +# CONFIG_PINCTRL_SUN8I_A83T is not set +# CONFIG_PINCTRL_SUN8I_A83T_R is not set +# CONFIG_PINCTRL_SUN8I_A23_R is not set +# CONFIG_PINCTRL_SUN8I_H3 is not set CONFIG_PINCTRL_SUN8I_H3_R=y -CONFIG_PINCTRL_SUN8I_V3S=y -CONFIG_PINCTRL_SUN9I_A80=y -CONFIG_PINCTRL_SUN9I_A80_R=y +# CONFIG_PINCTRL_SUN8I_V3S is not set +# CONFIG_PINCTRL_SUN9I_A80 is not set +# CONFIG_PINCTRL_SUN9I_A80_R is not set CONFIG_PINCTRL_SUN50I_A64=y CONFIG_PINCTRL_SUN50I_A64_R=y CONFIG_PINCTRL_SUN50I_H5=y CONFIG_PINCTRL_SUN50I_H6=y CONFIG_PINCTRL_SUN50I_H6_R=y CONFIG_PINCTRL_MADERA=m -CONFIG_PINCTRL_CS47L15=y -CONFIG_PINCTRL_CS47L35=y -CONFIG_PINCTRL_CS47L85=y -CONFIG_PINCTRL_CS47L90=y -CONFIG_PINCTRL_CS47L92=y +CONFIG_PINCTRL_EQUILIBRIUM=m CONFIG_GPIOLIB=y CONFIG_GPIOLIB_FASTPATH_LIMIT=512 CONFIG_OF_GPIO=y CONFIG_GPIOLIB_IRQCHIP=y -# CONFIG_DEBUG_GPIO is not set CONFIG_GPIO_SYSFS=y -CONFIG_GPIO_GENERIC=m +CONFIG_GPIO_GENERIC=y CONFIG_GPIO_MAX730X=m # # Memory mapped GPIO drivers # -CONFIG_GPIO_74XX_MMIO=m -CONFIG_GPIO_ALTERA=m +# CONFIG_GPIO_74XX_MMIO is not set +# CONFIG_GPIO_ALTERA is not set CONFIG_GPIO_CADENCE=m -CONFIG_GPIO_DWAPB=m +CONFIG_GPIO_DWAPB=y # CONFIG_GPIO_FTGPIO010 is not set -CONFIG_GPIO_GENERIC_PLATFORM=m -CONFIG_GPIO_GRGPIO=m +CONFIG_GPIO_GENERIC_PLATFORM=y +# CONFIG_GPIO_GRGPIO is not set CONFIG_GPIO_HLWD=m -CONFIG_GPIO_MB86S7X=m -CONFIG_GPIO_PL061=y +CONFIG_GPIO_LOGICVC=m +# CONFIG_GPIO_MB86S7X is not set +# CONFIG_GPIO_PL061 is not set CONFIG_GPIO_SAMA5D2_PIOBU=m +# CONFIG_GPIO_SIFIVE is not set CONFIG_GPIO_SYSCON=m # CONFIG_GPIO_XGENE is not set -CONFIG_GPIO_XILINX=y +# CONFIG_GPIO_XILINX is not set CONFIG_GPIO_AMD_FCH=m # end of Memory mapped GPIO drivers @@ -3325,32 +3078,11 @@ CONFIG_GPIO_TPIC2810=m # # MFD GPIO expanders # -CONFIG_GPIO_ADP5520=m -CONFIG_GPIO_ARIZONA=m +CONFIG_GPIO_BD71828=m CONFIG_GPIO_BD9571MWV=m -CONFIG_GPIO_DA9052=m -CONFIG_GPIO_DA9055=m -CONFIG_GPIO_DLN2=m -CONFIG_GPIO_KEMPLD=m -CONFIG_GPIO_LP3943=m -CONFIG_GPIO_LP873X=m -CONFIG_GPIO_LP87565=m CONFIG_GPIO_MADERA=m CONFIG_GPIO_MAX77650=m -CONFIG_GPIO_PALMAS=y -CONFIG_GPIO_RC5T583=y -CONFIG_GPIO_TPS65086=m -CONFIG_GPIO_TPS65218=m -CONFIG_GPIO_TPS6586X=y -CONFIG_GPIO_TPS65910=y -CONFIG_GPIO_TPS65912=m CONFIG_GPIO_TQMX86=m -CONFIG_GPIO_TWL4030=m -CONFIG_GPIO_TWL6040=m -CONFIG_GPIO_UCB1400=m -CONFIG_GPIO_WM831X=m -CONFIG_GPIO_WM8350=m -CONFIG_GPIO_WM8994=m # end of MFD GPIO expanders # @@ -3367,7 +3099,6 @@ CONFIG_GPIO_XRA1403=m # # USB GPIO expanders # -CONFIG_GPIO_VIPERBOARD=m # end of USB GPIO expanders CONFIG_GPIO_MOCKUP=m @@ -3396,10 +3127,11 @@ CONFIG_W1_SLAVE_DS2413=m CONFIG_W1_SLAVE_DS2406=m CONFIG_W1_SLAVE_DS2423=m CONFIG_W1_SLAVE_DS2805=m +CONFIG_W1_SLAVE_DS2430=m CONFIG_W1_SLAVE_DS2431=m CONFIG_W1_SLAVE_DS2433=m # CONFIG_W1_SLAVE_DS2433_CRC is not set -CONFIG_W1_SLAVE_DS2438=m +# CONFIG_W1_SLAVE_DS2438 is not set CONFIG_W1_SLAVE_DS250X=m CONFIG_W1_SLAVE_DS2780=m CONFIG_W1_SLAVE_DS2781=m @@ -3407,14 +3139,13 @@ CONFIG_W1_SLAVE_DS28E04=m CONFIG_W1_SLAVE_DS28E17=m # end of 1-wire Slaves -CONFIG_POWER_AVS=y +# CONFIG_POWER_AVS is not set CONFIG_POWER_RESET=y -# CONFIG_POWER_RESET_AS3722 is not set # CONFIG_POWER_RESET_BRCMSTB is not set # CONFIG_POWER_RESET_GPIO is not set # CONFIG_POWER_RESET_GPIO_RESTART is not set # CONFIG_POWER_RESET_LTC2952 is not set -CONFIG_POWER_RESET_RESTART=y +# CONFIG_POWER_RESET_RESTART is not set # CONFIG_POWER_RESET_XGENE is not set CONFIG_POWER_RESET_SYSCON=y # CONFIG_POWER_RESET_SYSCON_POWEROFF is not set @@ -3423,16 +3154,10 @@ CONFIG_POWER_RESET_SYSCON=y CONFIG_POWER_SUPPLY=y # CONFIG_POWER_SUPPLY_DEBUG is not set CONFIG_POWER_SUPPLY_HWMON=y -CONFIG_PDA_POWER=m -CONFIG_GENERIC_ADC_BATTERY=m -CONFIG_MAX8925_POWER=m -CONFIG_WM831X_BACKUP=m -CONFIG_WM831X_POWER=m -CONFIG_WM8350_POWER=m -CONFIG_TEST_POWER=m -CONFIG_BATTERY_88PM860X=m +# CONFIG_PDA_POWER is not set +# CONFIG_GENERIC_ADC_BATTERY is not set +# CONFIG_TEST_POWER is not set CONFIG_CHARGER_ADP5061=m -CONFIG_BATTERY_CPCAP=m CONFIG_BATTERY_DS2760=m CONFIG_BATTERY_DS2780=m CONFIG_BATTERY_DS2781=m @@ -3445,46 +3170,29 @@ CONFIG_BATTERY_BQ27XXX=m CONFIG_BATTERY_BQ27XXX_I2C=m CONFIG_BATTERY_BQ27XXX_HDQ=m # CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM is not set -CONFIG_BATTERY_DA9030=m -CONFIG_BATTERY_DA9052=m -CONFIG_CHARGER_DA9150=m -CONFIG_BATTERY_DA9150=m CONFIG_CHARGER_AXP20X=m CONFIG_BATTERY_AXP20X=m CONFIG_AXP20X_POWER=m CONFIG_AXP288_FUEL_GAUGE=m -CONFIG_BATTERY_MAX17040=m -CONFIG_BATTERY_MAX17042=m +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set CONFIG_BATTERY_MAX1721X=m -CONFIG_BATTERY_TWL4030_MADC=m -CONFIG_CHARGER_88PM860X=m -CONFIG_CHARGER_PCF50633=m -CONFIG_BATTERY_RX51=m -CONFIG_CHARGER_ISP1704=m -CONFIG_CHARGER_MAX8903=m -CONFIG_CHARGER_TWL4030=m -CONFIG_CHARGER_LP8727=m -CONFIG_CHARGER_LP8788=m +# CONFIG_CHARGER_ISP1704 is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set CONFIG_CHARGER_GPIO=m -CONFIG_CHARGER_MANAGER=y +# CONFIG_CHARGER_MANAGER is not set CONFIG_CHARGER_LT3651=m -CONFIG_CHARGER_MAX14577=m CONFIG_CHARGER_DETECTOR_MAX14656=m CONFIG_CHARGER_MAX77650=m -CONFIG_CHARGER_MAX77693=m -CONFIG_CHARGER_MAX8997=m -CONFIG_CHARGER_MAX8998=m -CONFIG_CHARGER_BQ2415X=m -CONFIG_CHARGER_BQ24190=m -CONFIG_CHARGER_BQ24257=m -CONFIG_CHARGER_BQ24735=m -CONFIG_CHARGER_BQ25890=m -CONFIG_CHARGER_SMB347=m -CONFIG_CHARGER_TPS65090=m -CONFIG_CHARGER_TPS65217=m -CONFIG_BATTERY_GAUGE_LTC2941=m -CONFIG_BATTERY_RT5033=m -CONFIG_CHARGER_RT9455=m +# CONFIG_CHARGER_BQ2415X is not set +# CONFIG_CHARGER_BQ24190 is not set +# CONFIG_CHARGER_BQ24257 is not set +# CONFIG_CHARGER_BQ24735 is not set +# CONFIG_CHARGER_BQ25890 is not set +# CONFIG_CHARGER_SMB347 is not set +# CONFIG_BATTERY_GAUGE_LTC2941 is not set +# CONFIG_CHARGER_RT9455 is not set CONFIG_CHARGER_UCS1002=m CONFIG_HWMON=y CONFIG_HWMON_VID=m @@ -3501,6 +3209,7 @@ CONFIG_SENSORS_ADM1025=m CONFIG_SENSORS_ADM1026=m CONFIG_SENSORS_ADM1029=m CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM1177=m CONFIG_SENSORS_ADM9240=m CONFIG_SENSORS_ADT7X10=m CONFIG_SENSORS_ADT7310=m @@ -3511,18 +3220,17 @@ CONFIG_SENSORS_ADT7470=m CONFIG_SENSORS_ADT7475=m CONFIG_SENSORS_AS370=m CONFIG_SENSORS_ASC7621=m +CONFIG_SENSORS_AXI_FAN_CONTROL=m CONFIG_SENSORS_ARM_SCMI=m CONFIG_SENSORS_ARM_SCPI=m CONFIG_SENSORS_ASPEED=m CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_DRIVETEMP=m CONFIG_SENSORS_DS620=m CONFIG_SENSORS_DS1621=m -CONFIG_SENSORS_DA9052_ADC=m -CONFIG_SENSORS_DA9055=m CONFIG_SENSORS_F71805F=m CONFIG_SENSORS_F71882FG=m CONFIG_SENSORS_F75375S=m -CONFIG_SENSORS_MC13783_ADC=m CONFIG_SENSORS_FTSTEUTATES=m CONFIG_SENSORS_GL518SM=m CONFIG_SENSORS_GL520SM=m @@ -3530,14 +3238,15 @@ CONFIG_SENSORS_G760A=m CONFIG_SENSORS_G762=m CONFIG_SENSORS_GPIO_FAN=m CONFIG_SENSORS_HIH6130=m -CONFIG_SENSORS_IBMAEM=m -CONFIG_SENSORS_IBMPEX=m CONFIG_SENSORS_IIO_HWMON=m CONFIG_SENSORS_IT87=m CONFIG_SENSORS_JC42=m CONFIG_SENSORS_POWR1220=m CONFIG_SENSORS_LINEAGE=m CONFIG_SENSORS_LTC2945=m +CONFIG_SENSORS_LTC2947=m +CONFIG_SENSORS_LTC2947_I2C=m +# CONFIG_SENSORS_LTC2947_SPI is not set CONFIG_SENSORS_LTC2990=m CONFIG_SENSORS_LTC4151=m CONFIG_SENSORS_LTC4215=m @@ -3551,6 +3260,7 @@ CONFIG_SENSORS_MAX1619=m CONFIG_SENSORS_MAX1668=m CONFIG_SENSORS_MAX197=m CONFIG_SENSORS_MAX31722=m +CONFIG_SENSORS_MAX31730=m CONFIG_SENSORS_MAX6621=m CONFIG_SENSORS_MAX6639=m CONFIG_SENSORS_MAX6642=m @@ -3559,7 +3269,6 @@ CONFIG_SENSORS_MAX6697=m CONFIG_SENSORS_MAX31790=m CONFIG_SENSORS_MCP3021=m CONFIG_SENSORS_TC654=m -CONFIG_SENSORS_MENF21BMC_HWMON=m CONFIG_SENSORS_ADCXX=m CONFIG_SENSORS_LM63=m CONFIG_SENSORS_LM70=m @@ -3591,26 +3300,28 @@ CONFIG_SENSORS_PCF8591=m CONFIG_PMBUS=m CONFIG_SENSORS_PMBUS=m CONFIG_SENSORS_ADM1275=m +CONFIG_SENSORS_BEL_PFE=m CONFIG_SENSORS_IBM_CFFPS=m CONFIG_SENSORS_INSPUR_IPSPS=m CONFIG_SENSORS_IR35221=m CONFIG_SENSORS_IR38064=m -CONFIG_SENSORS_IRPS5401=m +# CONFIG_SENSORS_IRPS5401 is not set CONFIG_SENSORS_ISL68137=m CONFIG_SENSORS_LM25066=m -CONFIG_SENSORS_LTC2978=m -CONFIG_SENSORS_LTC2978_REGULATOR=y +# CONFIG_SENSORS_LTC2978 is not set CONFIG_SENSORS_LTC3815=m CONFIG_SENSORS_MAX16064=m +CONFIG_SENSORS_MAX20730=m CONFIG_SENSORS_MAX20751=m CONFIG_SENSORS_MAX31785=m CONFIG_SENSORS_MAX34440=m CONFIG_SENSORS_MAX8688=m -CONFIG_SENSORS_PXE1610=m +# CONFIG_SENSORS_PXE1610 is not set CONFIG_SENSORS_TPS40422=m CONFIG_SENSORS_TPS53679=m CONFIG_SENSORS_UCD9000=m CONFIG_SENSORS_UCD9200=m +CONFIG_SENSORS_XDPE122=m CONFIG_SENSORS_ZL6100=m CONFIG_SENSORS_PWM_FAN=m CONFIG_SENSORS_SHT15=m @@ -3643,6 +3354,7 @@ CONFIG_SENSORS_TMP103=m CONFIG_SENSORS_TMP108=m CONFIG_SENSORS_TMP401=m CONFIG_SENSORS_TMP421=m +CONFIG_SENSORS_TMP513=m CONFIG_SENSORS_VT1211=m CONFIG_SENSORS_W83773G=m CONFIG_SENSORS_W83781D=m @@ -3655,95 +3367,72 @@ CONFIG_SENSORS_W83L785TS=m CONFIG_SENSORS_W83L786NG=m CONFIG_SENSORS_W83627HF=m CONFIG_SENSORS_W83627EHF=m -CONFIG_SENSORS_WM831X=m -CONFIG_SENSORS_WM8350=m CONFIG_THERMAL=y -CONFIG_THERMAL_STATISTICS=y +# CONFIG_THERMAL_STATISTICS is not set CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 CONFIG_THERMAL_HWMON=y CONFIG_THERMAL_OF=y CONFIG_THERMAL_WRITABLE_TRIPS=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE is not set +CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE=y # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set -# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set CONFIG_THERMAL_GOV_FAIR_SHARE=y CONFIG_THERMAL_GOV_STEP_WISE=y CONFIG_THERMAL_GOV_BANG_BANG=y CONFIG_THERMAL_GOV_USER_SPACE=y -CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y CONFIG_CPU_THERMAL=y +CONFIG_CPU_FREQ_THERMAL=y CONFIG_CLOCK_THERMAL=y CONFIG_DEVFREQ_THERMAL=y CONFIG_THERMAL_EMULATION=y CONFIG_THERMAL_MMIO=m # CONFIG_QORIQ_THERMAL is not set CONFIG_SUN8I_THERMAL=y -CONFIG_DA9062_THERMAL=m CONFIG_GENERIC_ADC_THERMAL=m CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y # CONFIG_WATCHDOG_NOWAYOUT is not set CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y CONFIG_WATCHDOG_OPEN_TIMEOUT=0 -CONFIG_WATCHDOG_SYSFS=y +# CONFIG_WATCHDOG_SYSFS is not set # # Watchdog Pretimeout Governors # -CONFIG_WATCHDOG_PRETIMEOUT_GOV=y -CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m -CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP=y -CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=m -CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP=y -# CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC is not set +# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set # # Watchdog Device Drivers # CONFIG_SOFT_WATCHDOG=m -CONFIG_SOFT_WATCHDOG_PRETIMEOUT=y -CONFIG_DA9052_WATCHDOG=m -CONFIG_DA9055_WATCHDOG=m -CONFIG_DA9063_WATCHDOG=m -CONFIG_DA9062_WATCHDOG=m CONFIG_GPIO_WATCHDOG=m -CONFIG_MENF21BMC_WATCHDOG=m -CONFIG_WM831X_WATCHDOG=m -CONFIG_WM8350_WATCHDOG=m -CONFIG_XILINX_WATCHDOG=m -CONFIG_ZIIRAVE_WATCHDOG=m +# CONFIG_XILINX_WATCHDOG is not set +# CONFIG_ZIIRAVE_WATCHDOG is not set CONFIG_RAVE_SP_WATCHDOG=m CONFIG_ARM_SP805_WATCHDOG=m CONFIG_ARM_SBSA_WATCHDOG=m -CONFIG_CADENCE_WATCHDOG=m -CONFIG_DW_WATCHDOG=m -CONFIG_RN5T618_WATCHDOG=m +# CONFIG_CADENCE_WATCHDOG is not set +# CONFIG_DW_WATCHDOG is not set CONFIG_SUNXI_WATCHDOG=y -CONFIG_TWL4030_WATCHDOG=m -CONFIG_MAX63XX_WATCHDOG=m -CONFIG_RETU_WATCHDOG=m -CONFIG_KEMPLD_WDT=m -CONFIG_MEN_A21_WDT=m -CONFIG_XEN_WDT=m +# CONFIG_MAX63XX_WATCHDOG is not set +# CONFIG_MEN_A21_WDT is not set # # USB-based Watchdog Cards # -CONFIG_USBPCWATCHDOG=m +# CONFIG_USBPCWATCHDOG is not set CONFIG_SSB_POSSIBLE=y CONFIG_SSB=m CONFIG_SSB_BLOCKIO=y CONFIG_SSB_SDIOHOST_POSSIBLE=y CONFIG_SSB_SDIOHOST=y -CONFIG_SSB_DRIVER_GPIO=y +# CONFIG_SSB_DRIVER_GPIO is not set CONFIG_BCMA_POSSIBLE=y CONFIG_BCMA=m CONFIG_BCMA_BLOCKIO=y -CONFIG_BCMA_HOST_SOC=y -CONFIG_BCMA_SFLASH=y -CONFIG_BCMA_DRIVER_GMAC_CMN=y -CONFIG_BCMA_DRIVER_GPIO=y +# CONFIG_BCMA_HOST_SOC is not set +# CONFIG_BCMA_DRIVER_GMAC_CMN is not set +# CONFIG_BCMA_DRIVER_GPIO is not set # CONFIG_BCMA_DEBUG is not set # @@ -3752,127 +3441,111 @@ CONFIG_BCMA_DRIVER_GPIO=y CONFIG_MFD_CORE=y # CONFIG_MFD_ACT8945A is not set CONFIG_MFD_SUN4I_GPADC=y -CONFIG_MFD_AS3711=y -CONFIG_MFD_AS3722=m -CONFIG_PMIC_ADP5520=y -CONFIG_MFD_AAT2870_CORE=y -CONFIG_MFD_ATMEL_FLEXCOM=m -CONFIG_MFD_ATMEL_HLCDC=m -CONFIG_MFD_BCM590XX=m +# CONFIG_MFD_AS3711 is not set +# CONFIG_MFD_AS3722 is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_ATMEL_FLEXCOM is not set +# CONFIG_MFD_ATMEL_HLCDC is not set +# CONFIG_MFD_BCM590XX is not set CONFIG_MFD_BD9571MWV=m -# CONFIG_MFD_AC100 is not set +CONFIG_MFD_AC100=m CONFIG_MFD_AC200=m CONFIG_MFD_AXP20X=y -CONFIG_MFD_AXP20X_I2C=m +CONFIG_MFD_AXP20X_I2C=y CONFIG_MFD_AXP20X_RSB=y CONFIG_MFD_MADERA=m CONFIG_MFD_MADERA_I2C=m -CONFIG_MFD_MADERA_SPI=m -CONFIG_MFD_CS47L15=y -CONFIG_MFD_CS47L35=y -CONFIG_MFD_CS47L85=y -CONFIG_MFD_CS47L90=y -CONFIG_MFD_CS47L92=y -CONFIG_PMIC_DA903X=y -CONFIG_PMIC_DA9052=y -CONFIG_MFD_DA9052_SPI=y -CONFIG_MFD_DA9052_I2C=y -CONFIG_MFD_DA9055=y -CONFIG_MFD_DA9062=m -CONFIG_MFD_DA9063=y -CONFIG_MFD_DA9150=m -CONFIG_MFD_DLN2=m -CONFIG_MFD_MC13XXX=m -CONFIG_MFD_MC13XXX_SPI=m -CONFIG_MFD_MC13XXX_I2C=m -CONFIG_MFD_HI6421_PMIC=y -CONFIG_HTC_PASIC3=m -CONFIG_HTC_I2CPLD=y -CONFIG_MFD_KEMPLD=m -CONFIG_MFD_88PM800=m -CONFIG_MFD_88PM805=m -CONFIG_MFD_88PM860X=y -CONFIG_MFD_MAX14577=y +# CONFIG_MFD_MADERA_SPI is not set +# CONFIG_MFD_CS47L15 is not set +# CONFIG_MFD_CS47L35 is not set +# CONFIG_MFD_CS47L85 is not set +# CONFIG_MFD_CS47L90 is not set +# CONFIG_MFD_CS47L92 is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9062 is not set +# CONFIG_MFD_DA9063 is not set +# CONFIG_MFD_DA9150 is not set +# CONFIG_MFD_DLN2 is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_MFD_HI6421_PMIC is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +CONFIG_MFD_IQS62X=m +# CONFIG_MFD_KEMPLD is not set +# CONFIG_MFD_88PM800 is not set +# CONFIG_MFD_88PM805 is not set +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_MAX14577 is not set # CONFIG_MFD_MAX77620 is not set CONFIG_MFD_MAX77650=m -CONFIG_MFD_MAX77686=m -CONFIG_MFD_MAX77693=y -CONFIG_MFD_MAX77843=y -CONFIG_MFD_MAX8907=m -CONFIG_MFD_MAX8925=y -CONFIG_MFD_MAX8997=y -CONFIG_MFD_MAX8998=y -CONFIG_MFD_MT6397=m -CONFIG_MFD_MENF21BMC=m -CONFIG_EZX_PCAP=y -CONFIG_MFD_CPCAP=m -CONFIG_MFD_VIPERBOARD=m -CONFIG_MFD_RETU=m -CONFIG_MFD_PCF50633=m -CONFIG_PCF50633_ADC=m -CONFIG_PCF50633_GPIO=m -CONFIG_UCB1400_CORE=m -CONFIG_MFD_RT5033=m -CONFIG_MFD_RC5T583=y -CONFIG_MFD_RK808=y -CONFIG_MFD_RN5T618=m +# CONFIG_MFD_MAX77686 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77843 is not set +# CONFIG_MFD_MAX8907 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6397 is not set +# CONFIG_MFD_MENF21BMC is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_CPCAP is not set +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_RT5033 is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_RK808 is not set +# CONFIG_MFD_RN5T618 is not set CONFIG_MFD_SEC_CORE=y -CONFIG_MFD_SI476X_CORE=m -CONFIG_MFD_SM501=m -CONFIG_MFD_SM501_GPIO=y -CONFIG_MFD_SKY81452=m -CONFIG_MFD_SMSC=y -CONFIG_ABX500_CORE=y -CONFIG_AB3100_CORE=y -CONFIG_AB3100_OTP=m +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set +# CONFIG_MFD_SMSC is not set +# CONFIG_ABX500_CORE is not set # CONFIG_MFD_STMPE is not set CONFIG_MFD_SUN6I_PRCM=y CONFIG_MFD_SYSCON=y -CONFIG_MFD_TI_AM335X_TSCADC=m -CONFIG_MFD_LP3943=m -CONFIG_MFD_LP8788=y -CONFIG_MFD_TI_LMU=m -CONFIG_MFD_PALMAS=y -CONFIG_TPS6105X=m -CONFIG_TPS65010=m -CONFIG_TPS6507X=m -CONFIG_MFD_TPS65086=m -CONFIG_MFD_TPS65090=y -CONFIG_MFD_TPS65217=m -CONFIG_MFD_TI_LP873X=m -CONFIG_MFD_TI_LP87565=m -CONFIG_MFD_TPS65218=m -CONFIG_MFD_TPS6586X=y -CONFIG_MFD_TPS65910=y -CONFIG_MFD_TPS65912=y -CONFIG_MFD_TPS65912_I2C=y -CONFIG_MFD_TPS65912_SPI=y -CONFIG_MFD_TPS80031=y -CONFIG_TWL4030_CORE=y -CONFIG_MFD_TWL4030_AUDIO=y -CONFIG_TWL6040_CORE=y +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_LP3943 is not set +# CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_TI_LMU is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65086 is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TI_LP873X is not set +# CONFIG_MFD_TI_LP87565 is not set +# CONFIG_MFD_TPS65218 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_MFD_TPS80031 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set CONFIG_MFD_WL1273_CORE=m -CONFIG_MFD_LM3533=m +# CONFIG_MFD_LM3533 is not set # CONFIG_MFD_TC3589X is not set CONFIG_MFD_TQMX86=m # CONFIG_MFD_LOCHNAGAR is not set -CONFIG_MFD_ARIZONA=y -CONFIG_MFD_ARIZONA_I2C=m -CONFIG_MFD_ARIZONA_SPI=m -CONFIG_MFD_CS47L24=y -CONFIG_MFD_WM5102=y -CONFIG_MFD_WM5110=y -CONFIG_MFD_WM8997=y -CONFIG_MFD_WM8998=y -CONFIG_MFD_WM8400=y -CONFIG_MFD_WM831X=y -CONFIG_MFD_WM831X_I2C=y -CONFIG_MFD_WM831X_SPI=y -CONFIG_MFD_WM8350=y -CONFIG_MFD_WM8350_I2C=y -CONFIG_MFD_WM8994=m +# CONFIG_MFD_ARIZONA_I2C is not set +# CONFIG_MFD_ARIZONA_SPI is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set CONFIG_MFD_ROHM_BD718XX=m # CONFIG_MFD_ROHM_BD70528 is not set +CONFIG_MFD_ROHM_BD71828=m # CONFIG_MFD_STPMIC1 is not set CONFIG_MFD_STMFX=m CONFIG_RAVE_SP_CORE=m @@ -3880,114 +3553,65 @@ CONFIG_RAVE_SP_CORE=m CONFIG_REGULATOR=y # CONFIG_REGULATOR_DEBUG is not set -CONFIG_REGULATOR_FIXED_VOLTAGE=m -CONFIG_REGULATOR_VIRTUAL_CONSUMER=m -CONFIG_REGULATOR_USERSPACE_CONSUMER=m +CONFIG_REGULATOR_FIXED_VOLTAGE=y +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set CONFIG_REGULATOR_USERSPACE_CONSUMER_OF=m CONFIG_REGULATOR_88PG86X=m -CONFIG_REGULATOR_88PM800=m -CONFIG_REGULATOR_88PM8607=m -CONFIG_REGULATOR_ACT8865=m -CONFIG_REGULATOR_AD5398=m -CONFIG_REGULATOR_ANATOP=m -CONFIG_REGULATOR_AAT2870=m -CONFIG_REGULATOR_AB3100=m -CONFIG_REGULATOR_ARIZONA_LDO1=m -CONFIG_REGULATOR_ARIZONA_MICSUPP=m -CONFIG_REGULATOR_AS3711=m -CONFIG_REGULATOR_AS3722=m -CONFIG_REGULATOR_AXP20X=m -CONFIG_REGULATOR_BCM590XX=m +# CONFIG_REGULATOR_ACT8865 is not set +# CONFIG_REGULATOR_AD5398 is not set +# CONFIG_REGULATOR_ARIZONA_LDO1 is not set +# CONFIG_REGULATOR_ARIZONA_MICSUPP is not set +CONFIG_REGULATOR_AXP20X=y +CONFIG_REGULATOR_BD71828=m CONFIG_REGULATOR_BD718XX=m CONFIG_REGULATOR_BD9571MWV=m -CONFIG_REGULATOR_CPCAP=m -CONFIG_REGULATOR_DA903X=m -CONFIG_REGULATOR_DA9052=m -CONFIG_REGULATOR_DA9055=m -CONFIG_REGULATOR_DA9062=m -CONFIG_REGULATOR_DA9063=m -CONFIG_REGULATOR_DA9210=m -CONFIG_REGULATOR_DA9211=m -CONFIG_REGULATOR_FAN53555=m -CONFIG_REGULATOR_GPIO=m -CONFIG_REGULATOR_HI6421=m -CONFIG_REGULATOR_HI6421V530=m -CONFIG_REGULATOR_ISL9305=m -CONFIG_REGULATOR_ISL6271A=m -CONFIG_REGULATOR_LM363X=m -CONFIG_REGULATOR_LP3971=m -CONFIG_REGULATOR_LP3972=m -CONFIG_REGULATOR_LP872X=m -CONFIG_REGULATOR_LP873X=m -CONFIG_REGULATOR_LP8755=m -CONFIG_REGULATOR_LP87565=m -CONFIG_REGULATOR_LP8788=m -CONFIG_REGULATOR_LTC3589=m -CONFIG_REGULATOR_LTC3676=m -CONFIG_REGULATOR_MAX14577=m -CONFIG_REGULATOR_MAX1586=m +# CONFIG_REGULATOR_DA9210 is not set +# CONFIG_REGULATOR_DA9211 is not set +# CONFIG_REGULATOR_FAN53555 is not set +CONFIG_REGULATOR_GPIO=y +# CONFIG_REGULATOR_ISL9305 is not set +# CONFIG_REGULATOR_ISL6271A is not set +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_LP3972 is not set +# CONFIG_REGULATOR_LP872X is not set +# CONFIG_REGULATOR_LP8755 is not set +# CONFIG_REGULATOR_LTC3589 is not set +# CONFIG_REGULATOR_LTC3676 is not set +# CONFIG_REGULATOR_MAX1586 is not set CONFIG_REGULATOR_MAX77650=m -CONFIG_REGULATOR_MAX8649=m -CONFIG_REGULATOR_MAX8660=m -CONFIG_REGULATOR_MAX8907=m -CONFIG_REGULATOR_MAX8925=m -CONFIG_REGULATOR_MAX8952=m +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_MAX8952 is not set # CONFIG_REGULATOR_MAX8973 is not set -CONFIG_REGULATOR_MAX8997=m -CONFIG_REGULATOR_MAX8998=m -CONFIG_REGULATOR_MAX77686=m -CONFIG_REGULATOR_MAX77693=m -CONFIG_REGULATOR_MAX77802=m -CONFIG_REGULATOR_MC13XXX_CORE=m -CONFIG_REGULATOR_MC13783=m -CONFIG_REGULATOR_MC13892=m CONFIG_REGULATOR_MCP16502=m -CONFIG_REGULATOR_MT6311=m -CONFIG_REGULATOR_MT6323=m -CONFIG_REGULATOR_MT6397=m -CONFIG_REGULATOR_PALMAS=m -CONFIG_REGULATOR_PCAP=m -CONFIG_REGULATOR_PCF50633=m -CONFIG_REGULATOR_PFUZE100=m -CONFIG_REGULATOR_PV88060=m -CONFIG_REGULATOR_PV88080=m -CONFIG_REGULATOR_PV88090=m -CONFIG_REGULATOR_PWM=m -CONFIG_REGULATOR_QCOM_SPMI=m -CONFIG_REGULATOR_RC5T583=m -CONFIG_REGULATOR_RK808=m -CONFIG_REGULATOR_RN5T618=m -CONFIG_REGULATOR_RT5033=m -CONFIG_REGULATOR_S2MPA01=m -CONFIG_REGULATOR_S2MPS11=m -CONFIG_REGULATOR_S5M8767=m -CONFIG_REGULATOR_SKY81452=m -CONFIG_REGULATOR_SLG51000=m +CONFIG_REGULATOR_MP5416=m +CONFIG_REGULATOR_MP8859=m +CONFIG_REGULATOR_MP886X=m +CONFIG_REGULATOR_MPQ7920=m +# CONFIG_REGULATOR_MT6311 is not set +# CONFIG_REGULATOR_PFUZE100 is not set +# CONFIG_REGULATOR_PV88060 is not set +# CONFIG_REGULATOR_PV88080 is not set +# CONFIG_REGULATOR_PV88090 is not set +# CONFIG_REGULATOR_PWM is not set +CONFIG_REGULATOR_QCOM_SPMI=y +CONFIG_REGULATOR_ROHM=m +# CONFIG_REGULATOR_S2MPA01 is not set +CONFIG_REGULATOR_S2MPS11=y +# CONFIG_REGULATOR_S5M8767 is not set +# CONFIG_REGULATOR_SLG51000 is not set CONFIG_REGULATOR_SY8106A=m CONFIG_REGULATOR_SY8824X=m -CONFIG_REGULATOR_TPS51632=m -CONFIG_REGULATOR_TPS6105X=m -CONFIG_REGULATOR_TPS62360=m -CONFIG_REGULATOR_TPS65023=m -CONFIG_REGULATOR_TPS6507X=m -CONFIG_REGULATOR_TPS65086=m -CONFIG_REGULATOR_TPS65090=m -CONFIG_REGULATOR_TPS65132=m -CONFIG_REGULATOR_TPS65217=m -CONFIG_REGULATOR_TPS65218=m -CONFIG_REGULATOR_TPS6524X=m -CONFIG_REGULATOR_TPS6586X=m -CONFIG_REGULATOR_TPS65910=m -CONFIG_REGULATOR_TPS65912=m -CONFIG_REGULATOR_TPS80031=m -CONFIG_REGULATOR_TWL4030=m -CONFIG_REGULATOR_VCTRL=m -CONFIG_REGULATOR_WM831X=m -CONFIG_REGULATOR_WM8350=m -CONFIG_REGULATOR_WM8400=m -CONFIG_REGULATOR_WM8994=m +# CONFIG_REGULATOR_TPS51632 is not set +# CONFIG_REGULATOR_TPS62360 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set +# CONFIG_REGULATOR_TPS65132 is not set +# CONFIG_REGULATOR_TPS6524X is not set +# CONFIG_REGULATOR_VCTRL is not set CONFIG_REGULATOR_TP65185X=m -CONFIG_CEC_CORE=m +CONFIG_CEC_CORE=y CONFIG_CEC_NOTIFIER=y CONFIG_CEC_PIN=y CONFIG_RC_CORE=m @@ -4006,25 +3630,24 @@ CONFIG_IR_XMP_DECODER=m CONFIG_IR_IMON_DECODER=m CONFIG_IR_RCMM_DECODER=m CONFIG_RC_DEVICES=y -CONFIG_RC_ATI_REMOTE=m -CONFIG_IR_HIX5HD2=m -CONFIG_IR_IMON=m +# CONFIG_RC_ATI_REMOTE is not set +# CONFIG_IR_HIX5HD2 is not set +# CONFIG_IR_IMON is not set CONFIG_IR_IMON_RAW=m -CONFIG_IR_MCEUSB=m -CONFIG_IR_REDRAT3=m +# CONFIG_IR_MCEUSB is not set +# CONFIG_IR_REDRAT3 is not set CONFIG_IR_SPI=m -CONFIG_IR_STREAMZAP=m -CONFIG_IR_IGORPLUGUSB=m -CONFIG_IR_IGUANA=m -CONFIG_IR_TTUSBIR=m -CONFIG_RC_LOOPBACK=m -CONFIG_IR_GPIO_CIR=m +# CONFIG_IR_STREAMZAP is not set +# CONFIG_IR_IGORPLUGUSB is not set +# CONFIG_IR_IGUANA is not set +# CONFIG_IR_TTUSBIR is not set +# CONFIG_RC_LOOPBACK is not set +# CONFIG_IR_GPIO_CIR is not set CONFIG_IR_GPIO_TX=m CONFIG_IR_PWM_TX=m CONFIG_IR_SUNXI=m -CONFIG_IR_SERIAL=m -CONFIG_IR_SERIAL_TRANSMITTER=y -CONFIG_IR_SIR=m +# CONFIG_IR_SERIAL is not set +# CONFIG_IR_SIR is not set CONFIG_RC_XBOX_DVD=m CONFIG_MEDIA_SUPPORT=m @@ -4036,30 +3659,30 @@ CONFIG_MEDIA_ANALOG_TV_SUPPORT=y CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y CONFIG_MEDIA_RADIO_SUPPORT=y CONFIG_MEDIA_SDR_SUPPORT=y -CONFIG_MEDIA_CEC_SUPPORT=y -# CONFIG_MEDIA_CEC_RC is not set -CONFIG_CEC_PIN_ERROR_INJ=y +# CONFIG_MEDIA_CEC_SUPPORT is not set +# CONFIG_CEC_PIN_ERROR_INJ is not set CONFIG_MEDIA_CONTROLLER=y CONFIG_MEDIA_CONTROLLER_DVB=y -# CONFIG_MEDIA_CONTROLLER_REQUEST_API is not set +CONFIG_MEDIA_CONTROLLER_REQUEST_API=y CONFIG_VIDEO_DEV=m CONFIG_VIDEO_V4L2_SUBDEV_API=y CONFIG_VIDEO_V4L2=m CONFIG_VIDEO_V4L2_I2C=y -CONFIG_VIDEO_ADV_DEBUG=y +# CONFIG_VIDEO_ADV_DEBUG is not set CONFIG_VIDEO_FIXED_MINOR_RANGES=y CONFIG_VIDEO_TUNER=m +CONFIG_V4L2_MEM2MEM_DEV=m CONFIG_V4L2_FWNODE=m CONFIG_VIDEOBUF_GEN=m CONFIG_VIDEOBUF_VMALLOC=m CONFIG_DVB_CORE=m -CONFIG_DVB_MMAP=y +# CONFIG_DVB_MMAP is not set CONFIG_DVB_NET=y CONFIG_TTPCI_EEPROM=m CONFIG_DVB_MAX_ADAPTERS=8 CONFIG_DVB_DYNAMIC_MINORS=y -CONFIG_DVB_DEMUX_SECTION_LOSS_LOG=y -CONFIG_DVB_ULE_DEBUG=y +# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set +# CONFIG_DVB_ULE_DEBUG is not set # # Media drivers @@ -4071,12 +3694,63 @@ CONFIG_MEDIA_USB_SUPPORT=y # CONFIG_USB_VIDEO_CLASS=m CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -# CONFIG_USB_GSPCA is not set -# CONFIG_USB_PWC is not set -# CONFIG_VIDEO_CPIA2 is not set -# CONFIG_USB_ZR364XX is not set -# CONFIG_USB_STKWEBCAM is not set -# CONFIG_USB_S2255 is not set +CONFIG_USB_GSPCA=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GL860=m +CONFIG_USB_GSPCA_BENQ=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_CPIA1=m +CONFIG_USB_GSPCA_DTCS033=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_JEILINJ=m +CONFIG_USB_GSPCA_JL2005BCD=m +CONFIG_USB_GSPCA_KINECT=m +CONFIG_USB_GSPCA_KONICA=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_MR97310A=m +CONFIG_USB_GSPCA_NW80X=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_GSPCA_OV534_9=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7302=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SE401=m +CONFIG_USB_GSPCA_SN9C2028=m +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_SPCA1528=m +CONFIG_USB_GSPCA_SQ905=m +CONFIG_USB_GSPCA_SQ905C=m +CONFIG_USB_GSPCA_SQ930X=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_STK1135=m +CONFIG_USB_GSPCA_STV0680=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TOPRO=m +CONFIG_USB_GSPCA_TOUPTEK=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_VICAM=m +CONFIG_USB_GSPCA_XIRLINK_CIT=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_PWC_INPUT_EVDEV=y +CONFIG_VIDEO_CPIA2=m +CONFIG_USB_ZR364XX=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_S2255=m CONFIG_VIDEO_USBTV=m # @@ -4087,13 +3761,9 @@ CONFIG_VIDEO_PVRUSB2_SYSFS=y CONFIG_VIDEO_PVRUSB2_DVB=y # CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set CONFIG_VIDEO_HDPVR=m -CONFIG_VIDEO_USBVISION=m CONFIG_VIDEO_STK1160_COMMON=m CONFIG_VIDEO_STK1160=m -CONFIG_VIDEO_GO7007=m -CONFIG_VIDEO_GO7007_USB=m -CONFIG_VIDEO_GO7007_LOADER=m -CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m +# CONFIG_VIDEO_GO7007 is not set # # Analog/digital TV USB devices @@ -4117,7 +3787,7 @@ CONFIG_DVB_USB=m CONFIG_DVB_USB_DIB3000MC=m CONFIG_DVB_USB_A800=m CONFIG_DVB_USB_DIBUSB_MB=m -# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y CONFIG_DVB_USB_DIBUSB_MC=m CONFIG_DVB_USB_DIB0700=m CONFIG_DVB_USB_UMT_010=m @@ -4174,12 +3844,6 @@ CONFIG_VIDEO_EM28XX_RC=m CONFIG_USB_AIRSPY=m CONFIG_USB_HACKRF=m CONFIG_USB_MSI2500=m - -# -# USB HDMI CEC adapters -# -CONFIG_USB_PULSE8_CEC=m -CONFIG_USB_RAINSHADOW_CEC=m CONFIG_V4L_PLATFORM_DRIVERS=y # CONFIG_VIDEO_CADENCE is not set CONFIG_VIDEO_ASPEED=m @@ -4192,7 +3856,6 @@ CONFIG_VIDEO_SUN6I_CSI=m # CONFIG_V4L_MEM2MEM_DRIVERS is not set # CONFIG_V4L_TEST_DRIVERS is not set CONFIG_DVB_PLATFORM_DRIVERS=y -CONFIG_CEC_PLATFORM_DRIVERS=y CONFIG_SDR_PLATFORM_DRIVERS=y # @@ -4203,7 +3866,6 @@ CONFIG_RADIO_ADAPTERS=y CONFIG_RADIO_TEA575X=m # CONFIG_RADIO_SI470X is not set # CONFIG_RADIO_SI4713 is not set -CONFIG_RADIO_SI476X=m # CONFIG_USB_MR800 is not set CONFIG_USB_DSBR=m CONFIG_RADIO_SHARK=m @@ -4243,185 +3905,73 @@ CONFIG_SMS_SIANO_RC=y # Media ancillary drivers (tuners, sensors, i2c, spi, frontends) # CONFIG_MEDIA_SUBDRV_AUTOSELECT=y +CONFIG_MEDIA_HIDE_ANCILLARY_SUBDRV=y CONFIG_MEDIA_ATTACH=y CONFIG_VIDEO_IR_I2C=m # -# I2C Encoders, decoders, sensors and other helper chips +# I2C drivers hidden by 'Autoselect ancillary drivers' # # # Audio decoders, processors and mixers # -CONFIG_VIDEO_TVAUDIO=m -CONFIG_VIDEO_TDA7432=m -CONFIG_VIDEO_TDA9840=m -CONFIG_VIDEO_TDA1997X=m -CONFIG_VIDEO_TEA6415C=m -CONFIG_VIDEO_TEA6420=m CONFIG_VIDEO_MSP3400=m -CONFIG_VIDEO_CS3308=m -CONFIG_VIDEO_CS5345=m CONFIG_VIDEO_CS53L32A=m -CONFIG_VIDEO_TLV320AIC23B=m -CONFIG_VIDEO_UDA1342=m CONFIG_VIDEO_WM8775=m -CONFIG_VIDEO_WM8739=m -CONFIG_VIDEO_VP27SMPX=m -CONFIG_VIDEO_SONY_BTF_MPX=m # # RDS decoders # -CONFIG_VIDEO_SAA6588=m # # Video decoders # -CONFIG_VIDEO_ADV7180=m -CONFIG_VIDEO_ADV7183=m -CONFIG_VIDEO_ADV748X=m -CONFIG_VIDEO_ADV7604=m -CONFIG_VIDEO_ADV7604_CEC=y -CONFIG_VIDEO_ADV7842=m -CONFIG_VIDEO_ADV7842_CEC=y -CONFIG_VIDEO_BT819=m -CONFIG_VIDEO_BT856=m -CONFIG_VIDEO_BT866=m -CONFIG_VIDEO_KS0127=m -CONFIG_VIDEO_ML86V7667=m -CONFIG_VIDEO_SAA7110=m CONFIG_VIDEO_SAA711X=m -CONFIG_VIDEO_TC358743=m -CONFIG_VIDEO_TC358743_CEC=y -CONFIG_VIDEO_TVP514X=m CONFIG_VIDEO_TVP5150=m -CONFIG_VIDEO_TVP7002=m -CONFIG_VIDEO_TW2804=m -CONFIG_VIDEO_TW9903=m -CONFIG_VIDEO_TW9906=m -CONFIG_VIDEO_TW9910=m -CONFIG_VIDEO_VPX3220=m # # Video and audio decoders # -CONFIG_VIDEO_SAA717X=m CONFIG_VIDEO_CX25840=m # # Video encoders # -CONFIG_VIDEO_SAA7127=m -CONFIG_VIDEO_SAA7185=m -CONFIG_VIDEO_ADV7170=m -CONFIG_VIDEO_ADV7175=m -CONFIG_VIDEO_ADV7343=m -CONFIG_VIDEO_ADV7393=m -CONFIG_VIDEO_ADV7511=m -CONFIG_VIDEO_ADV7511_CEC=y -CONFIG_VIDEO_AD9389B=m -CONFIG_VIDEO_AK881X=m -CONFIG_VIDEO_THS8200=m # # Camera sensor devices # -CONFIG_VIDEO_APTINA_PLL=m -CONFIG_VIDEO_SMIAPP_PLL=m -CONFIG_VIDEO_IMX214=m -CONFIG_VIDEO_IMX258=m -CONFIG_VIDEO_IMX274=m -CONFIG_VIDEO_IMX319=m -CONFIG_VIDEO_IMX355=m CONFIG_VIDEO_OV2640=m -CONFIG_VIDEO_OV2659=m -CONFIG_VIDEO_OV2680=m -CONFIG_VIDEO_OV2685=m -CONFIG_VIDEO_OV5640=m -CONFIG_VIDEO_OV5645=m -CONFIG_VIDEO_OV5647=m -CONFIG_VIDEO_OV6650=m -CONFIG_VIDEO_OV5670=m -CONFIG_VIDEO_OV5675=m -CONFIG_VIDEO_OV5695=m -CONFIG_VIDEO_OV7251=m -CONFIG_VIDEO_OV772X=m -CONFIG_VIDEO_OV7640=m -CONFIG_VIDEO_OV7670=m -CONFIG_VIDEO_OV7740=m -CONFIG_VIDEO_OV8856=m -CONFIG_VIDEO_OV9640=m -CONFIG_VIDEO_OV9650=m -CONFIG_VIDEO_OV13858=m -CONFIG_VIDEO_VS6624=m -CONFIG_VIDEO_MT9M001=m -CONFIG_VIDEO_MT9M032=m -CONFIG_VIDEO_MT9M111=m -CONFIG_VIDEO_MT9P031=m -CONFIG_VIDEO_MT9T001=m -CONFIG_VIDEO_MT9T112=m CONFIG_VIDEO_MT9V011=m -CONFIG_VIDEO_MT9V032=m -CONFIG_VIDEO_MT9V111=m -CONFIG_VIDEO_SR030PC30=m -CONFIG_VIDEO_NOON010PC30=m -CONFIG_VIDEO_M5MOLS=m -CONFIG_VIDEO_RJ54N1=m -CONFIG_VIDEO_S5K6AA=m -CONFIG_VIDEO_S5K6A3=m -CONFIG_VIDEO_S5K4ECGX=m -CONFIG_VIDEO_S5K5BAF=m -CONFIG_VIDEO_SMIAPP=m -CONFIG_VIDEO_ET8EK8=m -CONFIG_VIDEO_S5C73M3=m # # Lens drivers # -CONFIG_VIDEO_AD5820=m -CONFIG_VIDEO_AK7375=m -CONFIG_VIDEO_DW9714=m -CONFIG_VIDEO_DW9807_VCM=m -CONFIG_VIDEO_HM5065=m # # Flash devices # -CONFIG_VIDEO_ADP1653=m -CONFIG_VIDEO_LM3560=m -CONFIG_VIDEO_LM3646=m # # Video improvement chips # -CONFIG_VIDEO_UPD64031A=m -CONFIG_VIDEO_UPD64083=m # # Audio/Video compression chips # -CONFIG_VIDEO_SAA6752HS=m # # SDR tuner chips # -CONFIG_SDR_MAX2175=m # # Miscellaneous helper chips # -CONFIG_VIDEO_THS7303=m -CONFIG_VIDEO_M52790=m -CONFIG_VIDEO_I2C=m -CONFIG_VIDEO_ST_MIPID02=m -# end of I2C Encoders, decoders, sensors and other helper chips # -# SPI helper chips +# SPI drivers hidden by 'Autoselect ancillary drivers' # -CONFIG_VIDEO_GS1662=m -# end of SPI helper chips # # Media SPI Adapters @@ -4432,7 +3982,7 @@ CONFIG_CXD2880_SPI_DRV=m CONFIG_MEDIA_TUNER=m # -# Customize TV tuners +# Tuner drivers hidden by 'Autoselect ancillary drivers' # CONFIG_MEDIA_TUNER_SIMPLE=m CONFIG_MEDIA_TUNER_TDA18250=m @@ -4447,7 +3997,6 @@ CONFIG_MEDIA_TUNER_MT20XX=m CONFIG_MEDIA_TUNER_MT2060=m CONFIG_MEDIA_TUNER_MT2063=m CONFIG_MEDIA_TUNER_MT2266=m -CONFIG_MEDIA_TUNER_MT2131=m CONFIG_MEDIA_TUNER_QT1010=m CONFIG_MEDIA_TUNER_XC2028=m CONFIG_MEDIA_TUNER_XC5000=m @@ -4463,18 +4012,14 @@ CONFIG_MEDIA_TUNER_FC0013=m CONFIG_MEDIA_TUNER_TDA18212=m CONFIG_MEDIA_TUNER_E4000=m CONFIG_MEDIA_TUNER_FC2580=m -CONFIG_MEDIA_TUNER_M88RS6000T=m CONFIG_MEDIA_TUNER_TUA9001=m CONFIG_MEDIA_TUNER_SI2157=m CONFIG_MEDIA_TUNER_IT913X=m CONFIG_MEDIA_TUNER_R820T=m -CONFIG_MEDIA_TUNER_MXL301RF=m CONFIG_MEDIA_TUNER_QM1D1C0042=m -CONFIG_MEDIA_TUNER_QM1D1B0004=m -# end of Customize TV tuners # -# Customise DVB Frontends +# DVB Frontend drivers hidden by 'Autoselect ancillary drivers' # # @@ -4483,10 +4028,7 @@ CONFIG_MEDIA_TUNER_QM1D1B0004=m CONFIG_DVB_STB0899=m CONFIG_DVB_STB6100=m CONFIG_DVB_STV090x=m -CONFIG_DVB_STV0910=m CONFIG_DVB_STV6110x=m -CONFIG_DVB_STV6111=m -CONFIG_DVB_MXL5XX=m CONFIG_DVB_M88DS3103=m # @@ -4501,10 +4043,8 @@ CONFIG_DVB_MN88473=m # # DVB-S (satellite) frontends # -CONFIG_DVB_CX24110=m CONFIG_DVB_CX24123=m CONFIG_DVB_MT312=m -CONFIG_DVB_ZL10036=m CONFIG_DVB_ZL10039=m CONFIG_DVB_S5H1420=m CONFIG_DVB_STV0288=m @@ -4512,33 +4052,22 @@ CONFIG_DVB_STB6000=m CONFIG_DVB_STV0299=m CONFIG_DVB_STV6110=m CONFIG_DVB_STV0900=m -CONFIG_DVB_TDA8083=m CONFIG_DVB_TDA10086=m -CONFIG_DVB_TDA8261=m -CONFIG_DVB_VES1X93=m CONFIG_DVB_TUNER_ITD1000=m CONFIG_DVB_TUNER_CX24113=m CONFIG_DVB_TDA826X=m -CONFIG_DVB_TUA6100=m CONFIG_DVB_CX24116=m -CONFIG_DVB_CX24117=m CONFIG_DVB_CX24120=m CONFIG_DVB_SI21XX=m CONFIG_DVB_TS2020=m CONFIG_DVB_DS3000=m -CONFIG_DVB_MB86A16=m CONFIG_DVB_TDA10071=m # # DVB-T (terrestrial) frontends # -CONFIG_DVB_SP8870=m -CONFIG_DVB_SP887X=m -CONFIG_DVB_CX22700=m CONFIG_DVB_CX22702=m -CONFIG_DVB_S5H1432=m CONFIG_DVB_DRXD=m -CONFIG_DVB_L64781=m CONFIG_DVB_TDA1004X=m CONFIG_DVB_NXT6000=m CONFIG_DVB_MT352=m @@ -4547,11 +4076,9 @@ CONFIG_DVB_DIB3000MB=m CONFIG_DVB_DIB3000MC=m CONFIG_DVB_DIB7000M=m CONFIG_DVB_DIB7000P=m -CONFIG_DVB_DIB9000=m CONFIG_DVB_TDA10048=m CONFIG_DVB_AF9013=m CONFIG_DVB_EC100=m -CONFIG_DVB_STV0367=m CONFIG_DVB_CXD2820R=m CONFIG_DVB_CXD2841ER=m CONFIG_DVB_RTL2830=m @@ -4561,13 +4088,10 @@ CONFIG_DVB_SI2168=m CONFIG_DVB_AS102_FE=m CONFIG_DVB_ZD1301_DEMOD=m CONFIG_DVB_GP8PSK_FE=m -CONFIG_DVB_CXD2880=m # # DVB-C (cable) frontends # -CONFIG_DVB_VES1820=m -CONFIG_DVB_TDA10021=m CONFIG_DVB_TDA10023=m CONFIG_DVB_STV0297=m @@ -4575,8 +4099,6 @@ CONFIG_DVB_STV0297=m # ATSC (North American/Korean Terrestrial/Cable DTV) frontends # CONFIG_DVB_NXT200X=m -CONFIG_DVB_OR51211=m -CONFIG_DVB_OR51132=m CONFIG_DVB_BCM3510=m CONFIG_DVB_LGDT330X=m CONFIG_DVB_LGDT3305=m @@ -4599,7 +4121,6 @@ CONFIG_DVB_MB86A20S=m # ISDB-S (satellite) & ISDB-T (terrestrial) frontends # CONFIG_DVB_TC90522=m -CONFIG_DVB_MN88443X=m # # Digital terrestrial only tuners/PLL @@ -4612,36 +4133,25 @@ CONFIG_DVB_TUNER_DIB0090=m # SEC control devices for DVB-S # CONFIG_DVB_DRX39XYJ=m -CONFIG_DVB_LNBH25=m -CONFIG_DVB_LNBH29=m CONFIG_DVB_LNBP21=m CONFIG_DVB_LNBP22=m -CONFIG_DVB_ISL6405=m CONFIG_DVB_ISL6421=m CONFIG_DVB_ISL6423=m CONFIG_DVB_A8293=m -CONFIG_DVB_LGS8GL5=m CONFIG_DVB_LGS8GXX=m CONFIG_DVB_ATBM8830=m -CONFIG_DVB_TDA665x=m CONFIG_DVB_IX2505V=m CONFIG_DVB_M88RS2000=m CONFIG_DVB_AF9033=m -CONFIG_DVB_HORUS3A=m -CONFIG_DVB_ASCOT2E=m -CONFIG_DVB_HELENE=m # # Common Interface (EN50221) controller drivers # -CONFIG_DVB_CXD2099=m CONFIG_DVB_SP2=m # # Tools to develop new frontends # -CONFIG_DVB_DUMMY_FE=m -# end of Customise DVB Frontends # # Graphics support @@ -4651,12 +4161,10 @@ CONFIG_DRM_MIPI_DBI=m CONFIG_DRM_MIPI_DSI=y # CONFIG_DRM_DP_AUX_CHARDEV is not set # CONFIG_DRM_DEBUG_MM is not set -CONFIG_DRM_DEBUG_SELFTEST=m CONFIG_DRM_KMS_HELPER=y CONFIG_DRM_KMS_FB_HELPER=y CONFIG_DRM_FBDEV_EMULATION=y CONFIG_DRM_FBDEV_OVERALLOC=100 -# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set CONFIG_DRM_LOAD_EDID_FIRMWARE=y # CONFIG_DRM_DP_CEC is not set CONFIG_DRM_GEM_CMA_HELPER=y @@ -4681,25 +4189,20 @@ CONFIG_DRM_I2C_NXP_TDA9950=m CONFIG_DRM_KOMEDA=m # end of ARM devices -# -# ACP (Audio CoProcessor) Configuration -# -# end of ACP (Audio CoProcessor) Configuration - # CONFIG_DRM_VGEM is not set CONFIG_DRM_VKMS=m # CONFIG_DRM_UDL is not set # CONFIG_DRM_RCAR_DW_HDMI is not set CONFIG_DRM_RCAR_LVDS=m CONFIG_DRM_RCAR_WRITEBACK=y -CONFIG_DRM_SUN4I=m -CONFIG_DRM_SUN4I_HDMI=m +CONFIG_DRM_SUN4I=y +CONFIG_DRM_SUN4I_HDMI=y CONFIG_DRM_SUN4I_HDMI_CEC=y -CONFIG_DRM_SUN4I_BACKEND=m -CONFIG_DRM_SUN6I_DSI=m -CONFIG_DRM_SUN8I_DW_HDMI=m -CONFIG_DRM_SUN8I_MIXER=m -CONFIG_DRM_SUN8I_TCON_TOP=m +CONFIG_DRM_SUN4I_BACKEND=y +CONFIG_DRM_SUN6I_DSI=y +CONFIG_DRM_SUN8I_DW_HDMI=y +CONFIG_DRM_SUN8I_MIXER=y +CONFIG_DRM_SUN8I_TCON_TOP=y # CONFIG_DRM_VIRTIO_GPU is not set CONFIG_DRM_PANEL=y @@ -4707,18 +4210,24 @@ CONFIG_DRM_PANEL=y # Display Panels # CONFIG_DRM_PANEL_ARM_VERSATILE=m +CONFIG_DRM_PANEL_BOE_HIMAX8279D=m +# CONFIG_DRM_PANEL_BOE_TV101WUM_NL6 is not set CONFIG_DRM_PANEL_LVDS=m CONFIG_DRM_PANEL_SIMPLE=m +# CONFIG_DRM_PANEL_ELIDA_KD35T133 is not set +CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02=m CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D=m CONFIG_DRM_PANEL_ILITEK_IL9322=m CONFIG_DRM_PANEL_ILITEK_ILI9881C=m CONFIG_DRM_PANEL_INNOLUX_P079ZCA=m CONFIG_DRM_PANEL_JDI_LT070ME05000=m CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04=m +CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829=m # CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set CONFIG_DRM_PANEL_LG_LB035Q02=m # CONFIG_DRM_PANEL_LG_LG4573 is not set CONFIG_DRM_PANEL_NEC_NL8048HL11=m +CONFIG_DRM_PANEL_NOVATEK_NT35510=m CONFIG_DRM_PANEL_NOVATEK_NT39016=m CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO=m CONFIG_DRM_PANEL_ORISETECH_OTM8009A=m @@ -4733,18 +4242,23 @@ CONFIG_DRM_PANEL_SAMSUNG_S6D16D0=m CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2=m CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=m # CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set +CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01=m # CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set CONFIG_DRM_PANEL_SEIKO_43WVF1G=m CONFIG_DRM_PANEL_SHARP_LQ101R1SX01=m CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m CONFIG_DRM_PANEL_SHARP_LS043T1LE01=m CONFIG_DRM_PANEL_SITRONIX_ST7701=m +# CONFIG_DRM_PANEL_SITRONIX_ST7703 is not set # CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set +CONFIG_DRM_PANEL_SONY_ACX424AKP=m CONFIG_DRM_PANEL_SONY_ACX565AKM=m CONFIG_DRM_PANEL_TPO_TD028TTEC1=m CONFIG_DRM_PANEL_TPO_TD043MTEA1=m CONFIG_DRM_PANEL_TPO_TPG110=m CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m +CONFIG_DRM_PANEL_XINGBANGDA_XBD599=m +CONFIG_DRM_PANEL_XINPENG_XPP055C272=m # end of Display Panels CONFIG_DRM_BRIDGE=y @@ -4753,25 +4267,29 @@ CONFIG_DRM_PANEL_BRIDGE=y # # Display Interface Bridges # -CONFIG_DRM_ANALOGIX_ANX78XX=m CONFIG_DRM_CDNS_DSI=m -# CONFIG_DRM_DUMB_VGA_DAC is not set -# CONFIG_DRM_LVDS_ENCODER is not set +CONFIG_DRM_DISPLAY_CONNECTOR=m +CONFIG_DRM_LVDS_CODEC=m # CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set # CONFIG_DRM_NXP_PTN3460 is not set # CONFIG_DRM_PARADE_PS8622 is not set +CONFIG_DRM_PARADE_PS8640=m # CONFIG_DRM_SIL_SII8620 is not set # CONFIG_DRM_SII902X is not set CONFIG_DRM_SII9234=m +CONFIG_DRM_SIMPLE_BRIDGE=m CONFIG_DRM_THINE_THC63LVD1024=m CONFIG_DRM_TOSHIBA_TC358764=m # CONFIG_DRM_TOSHIBA_TC358767 is not set +CONFIG_DRM_TOSHIBA_TC358768=m # CONFIG_DRM_TI_TFP410 is not set CONFIG_DRM_TI_SN65DSI86=m +CONFIG_DRM_TI_TPD12S015=m CONFIG_DRM_ANALOGIX_ANX6345=m +CONFIG_DRM_ANALOGIX_ANX78XX=m CONFIG_DRM_ANALOGIX_DP=m # CONFIG_DRM_I2C_ADV7511 is not set -CONFIG_DRM_DW_HDMI=m +CONFIG_DRM_DW_HDMI=y CONFIG_DRM_DW_HDMI_AHB_AUDIO=m CONFIG_DRM_DW_HDMI_I2S_AUDIO=m CONFIG_DRM_DW_HDMI_CEC=m @@ -4786,17 +4304,17 @@ CONFIG_DRM_GM12U320=m CONFIG_TINYDRM_HX8357D=m CONFIG_TINYDRM_ILI9225=m CONFIG_TINYDRM_ILI9341=m +CONFIG_TINYDRM_ILI9486=m CONFIG_TINYDRM_MI0283QT=m CONFIG_TINYDRM_REPAPER=m CONFIG_TINYDRM_ST7586=m CONFIG_TINYDRM_ST7735R=m # CONFIG_DRM_PL111 is not set -# CONFIG_DRM_XEN is not set CONFIG_DRM_LIMA=m CONFIG_DRM_PANFROST=m +CONFIG_DRM_TIDSS=m # CONFIG_DRM_LEGACY is not set CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y -CONFIG_DRM_LIB_RANDOM=y # # Frame buffer Devices @@ -4804,7 +4322,7 @@ CONFIG_DRM_LIB_RANDOM=y CONFIG_FB_CMDLINE=y CONFIG_FB_NOTIFY=y CONFIG_FB=y -CONFIG_FIRMWARE_EDID=y +# CONFIG_FIRMWARE_EDID is not set CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y @@ -4823,16 +4341,13 @@ CONFIG_FB_MODE_HELPERS=y # # CONFIG_FB_ARMCLCD is not set # CONFIG_FB_UVESA is not set -# CONFIG_FB_EFI is not set # CONFIG_FB_OPENCORES is not set # CONFIG_FB_S1D13XXX is not set # CONFIG_FB_SUN5I_EINK is not set -CONFIG_FB_SM501=m # CONFIG_FB_SMSCUFX is not set # CONFIG_FB_UDL is not set # CONFIG_FB_IBM_GXT4500 is not set # CONFIG_FB_VIRTUAL is not set -CONFIG_XEN_FBDEV_FRONTEND=m # CONFIG_FB_METRONOME is not set CONFIG_FB_SIMPLE=y # CONFIG_FB_SSD1307 is not set @@ -4856,32 +4371,19 @@ CONFIG_LCD_CLASS_DEVICE=m CONFIG_LCD_OTM3225A=m CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BACKLIGHT_GENERIC=m -CONFIG_BACKLIGHT_LM3533=m CONFIG_BACKLIGHT_PWM=m -CONFIG_BACKLIGHT_DA903X=m -CONFIG_BACKLIGHT_DA9052=m -CONFIG_BACKLIGHT_MAX8925=m -# CONFIG_BACKLIGHT_PM8941_WLED is not set -CONFIG_BACKLIGHT_WM831X=m -CONFIG_BACKLIGHT_ADP5520=m +CONFIG_BACKLIGHT_QCOM_WLED=m # CONFIG_BACKLIGHT_ADP8860 is not set # CONFIG_BACKLIGHT_ADP8870 is not set -CONFIG_BACKLIGHT_88PM860X=m -CONFIG_BACKLIGHT_PCF50633=m -CONFIG_BACKLIGHT_AAT2870=m # CONFIG_BACKLIGHT_LM3630A is not set # CONFIG_BACKLIGHT_LM3639 is not set # CONFIG_BACKLIGHT_LP855X is not set -CONFIG_BACKLIGHT_LP8788=m -CONFIG_BACKLIGHT_PANDORA=m -CONFIG_BACKLIGHT_SKY81452=m -CONFIG_BACKLIGHT_TPS65217=m -CONFIG_BACKLIGHT_AS3711=m CONFIG_BACKLIGHT_GPIO=m # CONFIG_BACKLIGHT_LV5207LP is not set # CONFIG_BACKLIGHT_BD6107 is not set # CONFIG_BACKLIGHT_ARCXCNN is not set CONFIG_BACKLIGHT_RAVE_SP=m +CONFIG_BACKLIGHT_LED=m # end of Backlight & LCD device support CONFIG_VIDEOMODE_HELPERS=y @@ -4904,7 +4406,6 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set # CONFIG_LOGO_LINUX_CLUT224 is not set -CONFIG_LOGO_ARMBIAN_CLUT224=y # end of Graphics support CONFIG_SOUND=m @@ -4923,19 +4424,17 @@ CONFIG_SND_JACK_INPUT_DEV=y CONFIG_SND_PCM_TIMER=y # CONFIG_SND_HRTIMER is not set # CONFIG_SND_DYNAMIC_MINORS is not set -# CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_PROC_FS=y CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set -CONFIG_SND_VMASTER=y CONFIG_SND_SEQUENCER=m -CONFIG_SND_SEQ_DUMMY=m +# CONFIG_SND_SEQ_DUMMY is not set CONFIG_SND_SEQ_MIDI_EVENT=m CONFIG_SND_SEQ_MIDI=m CONFIG_SND_SEQ_VIRMIDI=m CONFIG_SND_MPU401_UART=m -CONFIG_SND_AC97_CODEC=m CONFIG_SND_DRIVERS=y CONFIG_SND_DUMMY=m CONFIG_SND_ALOOP=m @@ -4943,7 +4442,6 @@ CONFIG_SND_VIRMIDI=m CONFIG_SND_MTPAV=m CONFIG_SND_SERIAL_U16550=m CONFIG_SND_MPU401=m -# CONFIG_SND_AC97_POWER_SAVE is not set # # HD-Audio @@ -4951,28 +4449,25 @@ CONFIG_SND_MPU401=m # end of HD-Audio CONFIG_SND_HDA_PREALLOC_SIZE=64 -CONFIG_SND_SPI=y +# CONFIG_SND_SPI is not set CONFIG_SND_USB=y CONFIG_SND_USB_AUDIO=m CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y -CONFIG_SND_USB_UA101=m -CONFIG_SND_USB_CAIAQ=m -CONFIG_SND_USB_CAIAQ_INPUT=y -CONFIG_SND_USB_6FIRE=m -CONFIG_SND_USB_HIFACE=m -CONFIG_SND_BCD2000=m -CONFIG_SND_USB_LINE6=m -CONFIG_SND_USB_POD=m -CONFIG_SND_USB_PODHD=m -CONFIG_SND_USB_TONEPORT=m -CONFIG_SND_USB_VARIAX=m +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_6FIRE is not set +# CONFIG_SND_USB_HIFACE is not set +# CONFIG_SND_BCD2000 is not set +# CONFIG_SND_USB_POD is not set +# CONFIG_SND_USB_PODHD is not set +# CONFIG_SND_USB_TONEPORT is not set +# CONFIG_SND_USB_VARIAX is not set CONFIG_SND_SOC=m -CONFIG_SND_SOC_AC97_BUS=y CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y # CONFIG_SND_SOC_AMD_ACP is not set # CONFIG_SND_ATMEL_SOC is not set -CONFIG_SND_DESIGNWARE_I2S=m -# CONFIG_SND_DESIGNWARE_PCM is not set +CONFIG_SND_BCM63XX_I2S_WHISTLER=m +# CONFIG_SND_DESIGNWARE_I2S is not set # # SoC Audio for Freescale CPUs @@ -5023,166 +4518,154 @@ CONFIG_SND_SOC_I2C_AND_SPI=m # # CODEC drivers # -CONFIG_SND_SOC_AC97_CODEC=m -CONFIG_SND_SOC_ADAU_UTILS=m -CONFIG_SND_SOC_ADAU1701=m -CONFIG_SND_SOC_ADAU17X1=m -CONFIG_SND_SOC_ADAU1761=m -CONFIG_SND_SOC_ADAU1761_I2C=m -CONFIG_SND_SOC_ADAU1761_SPI=m -CONFIG_SND_SOC_ADAU7002=m -CONFIG_SND_SOC_AK4104=m +# CONFIG_SND_SOC_AC97_CODEC is not set +# CONFIG_SND_SOC_ADAU1701 is not set +# CONFIG_SND_SOC_ADAU1761_I2C is not set +# CONFIG_SND_SOC_ADAU1761_SPI is not set +# CONFIG_SND_SOC_ADAU7002 is not set +CONFIG_SND_SOC_ADAU7118=m +CONFIG_SND_SOC_ADAU7118_HW=m +CONFIG_SND_SOC_ADAU7118_I2C=m +# CONFIG_SND_SOC_AK4104 is not set CONFIG_SND_SOC_AK4118=m CONFIG_SND_SOC_AK4458=m -CONFIG_SND_SOC_AK4554=m -CONFIG_SND_SOC_AK4613=m -CONFIG_SND_SOC_AK4642=m -CONFIG_SND_SOC_AK5386=m +# CONFIG_SND_SOC_AK4554 is not set +# CONFIG_SND_SOC_AK4613 is not set +# CONFIG_SND_SOC_AK4642 is not set +# CONFIG_SND_SOC_AK5386 is not set CONFIG_SND_SOC_AK5558=m -CONFIG_SND_SOC_ALC5623=m +# CONFIG_SND_SOC_ALC5623 is not set CONFIG_SND_SOC_BD28623=m -CONFIG_SND_SOC_BT_SCO=m -CONFIG_SND_SOC_CPCAP=m -CONFIG_SND_SOC_CS35L32=m -CONFIG_SND_SOC_CS35L33=m -CONFIG_SND_SOC_CS35L34=m -CONFIG_SND_SOC_CS35L35=m +# CONFIG_SND_SOC_BT_SCO is not set +# CONFIG_SND_SOC_CS35L32 is not set +# CONFIG_SND_SOC_CS35L33 is not set +# CONFIG_SND_SOC_CS35L34 is not set +# CONFIG_SND_SOC_CS35L35 is not set CONFIG_SND_SOC_CS35L36=m -CONFIG_SND_SOC_CS42L42=m -CONFIG_SND_SOC_CS42L51=m -CONFIG_SND_SOC_CS42L51_I2C=m -CONFIG_SND_SOC_CS42L52=m -CONFIG_SND_SOC_CS42L56=m -CONFIG_SND_SOC_CS42L73=m -CONFIG_SND_SOC_CS4265=m -CONFIG_SND_SOC_CS4270=m -CONFIG_SND_SOC_CS4271=m -CONFIG_SND_SOC_CS4271_I2C=m -CONFIG_SND_SOC_CS4271_SPI=m -CONFIG_SND_SOC_CS42XX8=m -CONFIG_SND_SOC_CS42XX8_I2C=m +# CONFIG_SND_SOC_CS42L42 is not set +# CONFIG_SND_SOC_CS42L51_I2C is not set +# CONFIG_SND_SOC_CS42L52 is not set +# CONFIG_SND_SOC_CS42L56 is not set +# CONFIG_SND_SOC_CS42L73 is not set +# CONFIG_SND_SOC_CS4265 is not set +# CONFIG_SND_SOC_CS4270 is not set +# CONFIG_SND_SOC_CS4271_I2C is not set +# CONFIG_SND_SOC_CS4271_SPI is not set +# CONFIG_SND_SOC_CS42XX8_I2C is not set CONFIG_SND_SOC_CS43130=m CONFIG_SND_SOC_CS4341=m -CONFIG_SND_SOC_CS4349=m -CONFIG_SND_SOC_CS53L30=m -CONFIG_SND_SOC_CX2072X=m +# CONFIG_SND_SOC_CS4349 is not set +# CONFIG_SND_SOC_CS53L30 is not set +# CONFIG_SND_SOC_CX2072X is not set +CONFIG_SND_SOC_DA7213=m CONFIG_SND_SOC_DMIC=m CONFIG_SND_SOC_HDMI_CODEC=m -CONFIG_SND_SOC_ES7134=m +# CONFIG_SND_SOC_ES7134 is not set CONFIG_SND_SOC_ES7241=m -CONFIG_SND_SOC_ES8316=m -CONFIG_SND_SOC_ES8328=m -CONFIG_SND_SOC_ES8328_I2C=m -CONFIG_SND_SOC_ES8328_SPI=m -CONFIG_SND_SOC_GTM601=m -CONFIG_SND_SOC_INNO_RK3036=m +# CONFIG_SND_SOC_ES8316 is not set +# CONFIG_SND_SOC_ES8328_I2C is not set +# CONFIG_SND_SOC_ES8328_SPI is not set +# CONFIG_SND_SOC_GTM601 is not set +CONFIG_SND_SOC_EC25=m +# CONFIG_SND_SOC_INNO_RK3036 is not set CONFIG_SND_SOC_MAX98088=m # CONFIG_SND_SOC_MAX98357A is not set -CONFIG_SND_SOC_MAX98504=m +# CONFIG_SND_SOC_MAX98504 is not set CONFIG_SND_SOC_MAX9867=m -CONFIG_SND_SOC_MAX98927=m +# CONFIG_SND_SOC_MAX98927 is not set CONFIG_SND_SOC_MAX98373=m -CONFIG_SND_SOC_MAX9860=m -CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m -CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m -CONFIG_SND_SOC_PCM1681=m +# CONFIG_SND_SOC_MAX9860 is not set +# CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set +# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set +# CONFIG_SND_SOC_PCM1681 is not set CONFIG_SND_SOC_PCM1789=m CONFIG_SND_SOC_PCM1789_I2C=m -CONFIG_SND_SOC_PCM179X=m -CONFIG_SND_SOC_PCM179X_I2C=m -CONFIG_SND_SOC_PCM179X_SPI=m +# CONFIG_SND_SOC_PCM179X_I2C is not set +# CONFIG_SND_SOC_PCM179X_SPI is not set CONFIG_SND_SOC_PCM186X=m CONFIG_SND_SOC_PCM186X_I2C=m CONFIG_SND_SOC_PCM186X_SPI=m CONFIG_SND_SOC_PCM3060=m CONFIG_SND_SOC_PCM3060_I2C=m CONFIG_SND_SOC_PCM3060_SPI=m -CONFIG_SND_SOC_PCM3168A=m -CONFIG_SND_SOC_PCM3168A_I2C=m -CONFIG_SND_SOC_PCM3168A_SPI=m +# CONFIG_SND_SOC_PCM3168A_I2C is not set +# CONFIG_SND_SOC_PCM3168A_SPI is not set CONFIG_SND_SOC_PCM5102A=m -CONFIG_SND_SOC_PCM512x=m -CONFIG_SND_SOC_PCM512x_I2C=m -CONFIG_SND_SOC_PCM512x_SPI=m +# CONFIG_SND_SOC_PCM512x_I2C is not set +# CONFIG_SND_SOC_PCM512x_SPI is not set CONFIG_SND_SOC_RK3328=m -CONFIG_SND_SOC_RL6231=m -CONFIG_SND_SOC_RT5616=m -CONFIG_SND_SOC_RT5631=m -CONFIG_SND_SOC_SGTL5000=m -CONFIG_SND_SOC_SI476X=m -CONFIG_SND_SOC_SIGMADSP=m -CONFIG_SND_SOC_SIGMADSP_I2C=m -CONFIG_SND_SOC_SIGMADSP_REGMAP=m +# CONFIG_SND_SOC_RT5616 is not set +# CONFIG_SND_SOC_RT5631 is not set +# CONFIG_SND_SOC_SGTL5000 is not set CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m -CONFIG_SND_SOC_SIRF_AUDIO_CODEC=m +# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set CONFIG_SND_SOC_SPDIF=m CONFIG_SND_SOC_SSM2305=m -CONFIG_SND_SOC_SSM2602=m -CONFIG_SND_SOC_SSM2602_SPI=m -CONFIG_SND_SOC_SSM2602_I2C=m -CONFIG_SND_SOC_SSM4567=m -CONFIG_SND_SOC_STA32X=m -CONFIG_SND_SOC_STA350=m -CONFIG_SND_SOC_STI_SAS=m -CONFIG_SND_SOC_TAS2552=m -CONFIG_SND_SOC_TAS5086=m -CONFIG_SND_SOC_TAS571X=m -CONFIG_SND_SOC_TAS5720=m +# CONFIG_SND_SOC_SSM2602_SPI is not set +# CONFIG_SND_SOC_SSM2602_I2C is not set +# CONFIG_SND_SOC_SSM4567 is not set +# CONFIG_SND_SOC_STA32X is not set +# CONFIG_SND_SOC_STA350 is not set +# CONFIG_SND_SOC_STI_SAS is not set +# CONFIG_SND_SOC_TAS2552 is not set +CONFIG_SND_SOC_TAS2562=m +CONFIG_SND_SOC_TAS2770=m +# CONFIG_SND_SOC_TAS5086 is not set +# CONFIG_SND_SOC_TAS571X is not set +# CONFIG_SND_SOC_TAS5720 is not set CONFIG_SND_SOC_TAS6424=m CONFIG_SND_SOC_TDA7419=m -CONFIG_SND_SOC_TFA9879=m -CONFIG_SND_SOC_TLV320AIC23=m -CONFIG_SND_SOC_TLV320AIC23_I2C=m -CONFIG_SND_SOC_TLV320AIC23_SPI=m -CONFIG_SND_SOC_TLV320AIC31XX=m +# CONFIG_SND_SOC_TFA9879 is not set +# CONFIG_SND_SOC_TLV320AIC23_I2C is not set +# CONFIG_SND_SOC_TLV320AIC23_SPI is not set +# CONFIG_SND_SOC_TLV320AIC31XX is not set CONFIG_SND_SOC_TLV320AIC32X4=m CONFIG_SND_SOC_TLV320AIC32X4_I2C=m -CONFIG_SND_SOC_TLV320AIC32X4_SPI=m -CONFIG_SND_SOC_TLV320AIC3X=m -CONFIG_SND_SOC_TS3A227E=m -CONFIG_SND_SOC_TSCS42XX=m +# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set +# CONFIG_SND_SOC_TLV320AIC3X is not set +CONFIG_SND_SOC_TLV320ADCX140=m +# CONFIG_SND_SOC_TS3A227E is not set +# CONFIG_SND_SOC_TSCS42XX is not set CONFIG_SND_SOC_TSCS454=m CONFIG_SND_SOC_UDA1334=m -CONFIG_SND_SOC_WM8510=m -CONFIG_SND_SOC_WM8523=m +# CONFIG_SND_SOC_WM8510 is not set +# CONFIG_SND_SOC_WM8523 is not set CONFIG_SND_SOC_WM8524=m -CONFIG_SND_SOC_WM8580=m -CONFIG_SND_SOC_WM8711=m -CONFIG_SND_SOC_WM8728=m -CONFIG_SND_SOC_WM8731=m -CONFIG_SND_SOC_WM8737=m -CONFIG_SND_SOC_WM8741=m -CONFIG_SND_SOC_WM8750=m -CONFIG_SND_SOC_WM8753=m -CONFIG_SND_SOC_WM8770=m -CONFIG_SND_SOC_WM8776=m +# CONFIG_SND_SOC_WM8580 is not set +# CONFIG_SND_SOC_WM8711 is not set +# CONFIG_SND_SOC_WM8728 is not set +# CONFIG_SND_SOC_WM8731 is not set +# CONFIG_SND_SOC_WM8737 is not set +# CONFIG_SND_SOC_WM8741 is not set +# CONFIG_SND_SOC_WM8750 is not set +# CONFIG_SND_SOC_WM8753 is not set +# CONFIG_SND_SOC_WM8770 is not set +# CONFIG_SND_SOC_WM8776 is not set CONFIG_SND_SOC_WM8782=m -CONFIG_SND_SOC_WM8804=m -CONFIG_SND_SOC_WM8804_I2C=m -CONFIG_SND_SOC_WM8804_SPI=m -CONFIG_SND_SOC_WM8903=m +# CONFIG_SND_SOC_WM8804_I2C is not set +# CONFIG_SND_SOC_WM8804_SPI is not set +# CONFIG_SND_SOC_WM8903 is not set CONFIG_SND_SOC_WM8904=m -CONFIG_SND_SOC_WM8960=m -CONFIG_SND_SOC_WM8962=m -CONFIG_SND_SOC_WM8974=m -CONFIG_SND_SOC_WM8978=m -CONFIG_SND_SOC_WM8985=m -CONFIG_SND_SOC_ZX_AUD96P22=m +# CONFIG_SND_SOC_WM8960 is not set +# CONFIG_SND_SOC_WM8962 is not set +# CONFIG_SND_SOC_WM8974 is not set +# CONFIG_SND_SOC_WM8978 is not set +# CONFIG_SND_SOC_WM8985 is not set +# CONFIG_SND_SOC_ZX_AUD96P22 is not set CONFIG_SND_SOC_MAX9759=m CONFIG_SND_SOC_MT6351=m CONFIG_SND_SOC_MT6358=m -CONFIG_SND_SOC_NAU8540=m -CONFIG_SND_SOC_NAU8810=m +CONFIG_SND_SOC_MT6660=m +# CONFIG_SND_SOC_NAU8540 is not set +# CONFIG_SND_SOC_NAU8810 is not set CONFIG_SND_SOC_NAU8822=m -CONFIG_SND_SOC_NAU8824=m -CONFIG_SND_SOC_TPA6130A2=m +# CONFIG_SND_SOC_NAU8824 is not set +# CONFIG_SND_SOC_TPA6130A2 is not set # end of CODEC drivers CONFIG_SND_SIMPLE_CARD_UTILS=m CONFIG_SND_SIMPLE_CARD=m -CONFIG_SND_AUDIO_GRAPH_CARD=m -CONFIG_SND_XEN_FRONTEND=m -CONFIG_AC97_BUS=m +# CONFIG_SND_AUDIO_GRAPH_CARD is not set # # HID support @@ -5213,7 +4696,7 @@ CONFIG_HID_CORSAIR=m CONFIG_HID_COUGAR=m CONFIG_HID_MACALLY=m CONFIG_HID_PRODIKEYS=m -CONFIG_HID_CMEDIA=m +# CONFIG_HID_CMEDIA is not set CONFIG_HID_CP2112=m CONFIG_HID_CREATIVE_SB0540=m CONFIG_HID_CYPRESS=m @@ -5226,6 +4709,7 @@ CONFIG_HID_ELO=m CONFIG_HID_EZKEY=m CONFIG_HID_GEMBIRD=m CONFIG_HID_GFRM=m +CONFIG_HID_GLORIOUS=m CONFIG_HID_HOLTEK=m CONFIG_HOLTEK_FF=y CONFIG_HID_GT683R=m @@ -5236,8 +4720,8 @@ CONFIG_HID_WALTOP=m CONFIG_HID_VIEWSONIC=m CONFIG_HID_GYRATION=m CONFIG_HID_ICADE=m -CONFIG_HID_ITE=m -CONFIG_HID_JABRA=m +# CONFIG_HID_ITE is not set +# CONFIG_HID_JABRA is not set CONFIG_HID_TWINHAN=m CONFIG_HID_KENSINGTON=m CONFIG_HID_LCPOWER=m @@ -5272,7 +4756,7 @@ CONFIG_HID_PICOLCD_LEDS=y CONFIG_HID_PICOLCD_CIR=y CONFIG_HID_PLANTRONICS=m CONFIG_HID_PRIMAX=m -CONFIG_HID_RETRODE=m +# CONFIG_HID_RETRODE is not set CONFIG_HID_ROCCAT=m CONFIG_HID_SAITEK=m CONFIG_HID_SAMSUNG=m @@ -5292,8 +4776,7 @@ CONFIG_HID_TOPSEED=m CONFIG_HID_THINGM=m CONFIG_HID_THRUSTMASTER=m CONFIG_THRUSTMASTER_FF=y -CONFIG_HID_UDRAW_PS3=m -CONFIG_HID_U2FZERO=m +# CONFIG_HID_UDRAW_PS3 is not set CONFIG_HID_WACOM=m CONFIG_HID_WIIMOTE=m CONFIG_HID_XINMO=m @@ -5303,6 +4786,7 @@ CONFIG_HID_ZYDACRON=m CONFIG_HID_SENSOR_HUB=m CONFIG_HID_SENSOR_CUSTOM_SENSOR=m CONFIG_HID_ALPS=m +CONFIG_HID_MCP2221=m # end of Special HID drivers # @@ -5324,7 +4808,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_SUPPORT=y CONFIG_USB_COMMON=y CONFIG_USB_LED_TRIG=y -CONFIG_USB_ULPI_BUS=y +# CONFIG_USB_ULPI_BUS is not set CONFIG_USB_CONN_GPIO=m CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB=y @@ -5338,7 +4822,7 @@ CONFIG_USB_DEFAULT_PERSIST=y CONFIG_USB_OTG=y # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set -CONFIG_USB_OTG_FSM=m +# CONFIG_USB_OTG_FSM is not set CONFIG_USB_LEDS_TRIGGER_USBPORT=y CONFIG_USB_AUTOSUSPEND_DELAY=2 CONFIG_USB_MON=m @@ -5361,10 +4845,9 @@ CONFIG_USB_EHCI_HCD_PLATFORM=y # CONFIG_USB_MAX3421_HCD is not set CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y -CONFIG_USB_U132_HCD=m # CONFIG_USB_SL811_HCD is not set # CONFIG_USB_R8A66597_HCD is not set -CONFIG_USB_HCD_BCMA=m +# CONFIG_USB_HCD_BCMA is not set # CONFIG_USB_HCD_SSB is not set # CONFIG_USB_HCD_TEST_MODE is not set @@ -5374,7 +4857,7 @@ CONFIG_USB_HCD_BCMA=m CONFIG_USB_ACM=m CONFIG_USB_PRINTER=m CONFIG_USB_WDM=m -CONFIG_USB_TMC=m +# CONFIG_USB_TMC is not set # # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may @@ -5385,27 +4868,26 @@ CONFIG_USB_TMC=m # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set -CONFIG_USB_STORAGE_REALTEK=m -CONFIG_REALTEK_AUTOPM=y -CONFIG_USB_STORAGE_DATAFAB=m -CONFIG_USB_STORAGE_FREECOM=m -CONFIG_USB_STORAGE_ISD200=m -CONFIG_USB_STORAGE_USBAT=m -CONFIG_USB_STORAGE_SDDR09=m -CONFIG_USB_STORAGE_SDDR55=m -CONFIG_USB_STORAGE_JUMPSHOT=m -CONFIG_USB_STORAGE_ALAUDA=m -CONFIG_USB_STORAGE_ONETOUCH=m -CONFIG_USB_STORAGE_KARMA=m -CONFIG_USB_STORAGE_CYPRESS_ATACB=m -CONFIG_USB_STORAGE_ENE_UB6250=m +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set CONFIG_USB_UAS=m # # USB Imaging devices # -CONFIG_USB_MDC800=m -CONFIG_USB_MICROTEK=m +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set CONFIG_USBIP_CORE=m CONFIG_USBIP_VHCI_HCD=m CONFIG_USBIP_VHCI_HC_PORTS=8 @@ -5431,7 +4913,6 @@ CONFIG_USB_MUSB_SUNXI=y # # CONFIG_MUSB_PIO_ONLY is not set CONFIG_USB_DWC3=y -# CONFIG_USB_DWC3_ULPI is not set # CONFIG_USB_DWC3_HOST is not set # CONFIG_USB_DWC3_GADGET is not set CONFIG_USB_DWC3_DUAL_ROLE=y @@ -5450,16 +4931,8 @@ CONFIG_USB_DWC2=y CONFIG_USB_DWC2_DUAL_ROLE=y # CONFIG_USB_DWC2_DEBUG is not set # CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set -CONFIG_USB_CHIPIDEA=y -CONFIG_USB_CHIPIDEA_OF=y -CONFIG_USB_CHIPIDEA_UDC=y -CONFIG_USB_CHIPIDEA_HOST=y -CONFIG_USB_ISP1760=y -CONFIG_USB_ISP1760_HCD=y -CONFIG_USB_ISP1761_UDC=y -# CONFIG_USB_ISP1760_HOST_ROLE is not set -# CONFIG_USB_ISP1760_GADGET_ROLE is not set -CONFIG_USB_ISP1760_DUAL_ROLE=y +# CONFIG_USB_CHIPIDEA is not set +# CONFIG_USB_ISP1760 is not set # # USB port drivers @@ -5483,7 +4956,7 @@ CONFIG_USB_SERIAL_IR=m CONFIG_USB_SERIAL_EDGEPORT=m CONFIG_USB_SERIAL_EDGEPORT_TI=m CONFIG_USB_SERIAL_F81232=m -CONFIG_USB_SERIAL_F8153X=m +# CONFIG_USB_SERIAL_F8153X is not set CONFIG_USB_SERIAL_GARMIN=m CONFIG_USB_SERIAL_IPW=m CONFIG_USB_SERIAL_IUU=m @@ -5523,37 +4996,31 @@ CONFIG_USB_SERIAL_DEBUG=m # # USB Miscellaneous drivers # -CONFIG_USB_EMI62=m -CONFIG_USB_EMI26=m -CONFIG_USB_ADUTUX=m -CONFIG_USB_SEVSEG=m -CONFIG_USB_LEGOTOWER=m -CONFIG_USB_LCD=m -CONFIG_USB_CYPRESS_CY7C63=m -CONFIG_USB_CYTHERM=m -CONFIG_USB_IDMOUSE=m -CONFIG_USB_FTDI_ELAN=m -CONFIG_USB_APPLEDISPLAY=m -CONFIG_USB_SISUSBVGA=m -# CONFIG_USB_SISUSBVGA_CON is not set -CONFIG_USB_LD=m -CONFIG_USB_TRANCEVIBRATOR=m -CONFIG_USB_IOWARRIOR=m -CONFIG_USB_TEST=m -CONFIG_USB_EHSET_TEST_FIXTURE=m -CONFIG_USB_ISIGHTFW=m -CONFIG_USB_YUREX=m +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +CONFIG_APPLE_MFI_FASTCHARGE=m +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_EHSET_TEST_FIXTURE is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set CONFIG_USB_EZUSB_FX2=m CONFIG_USB_HUB_USB251XB=m -CONFIG_USB_HSIC_USB3503=y +# CONFIG_USB_HSIC_USB3503 is not set # CONFIG_USB_HSIC_USB4604 is not set -CONFIG_USB_LINK_LAYER_TEST=m -CONFIG_USB_CHAOSKEY=m -CONFIG_USB_ATM=m -CONFIG_USB_SPEEDTOUCH=m -CONFIG_USB_CXACRU=m -CONFIG_USB_UEAGLEATM=m -CONFIG_USB_XUSBATM=m +# CONFIG_USB_LINK_LAYER_TEST is not set # # USB Physical Layer drivers @@ -5561,15 +5028,11 @@ CONFIG_USB_XUSBATM=m CONFIG_USB_PHY=y CONFIG_NOP_USB_XCEIV=y # CONFIG_USB_GPIO_VBUS is not set -CONFIG_TAHVO_USB=m -# CONFIG_TAHVO_USB_HOST_BY_DEFAULT is not set # CONFIG_USB_ISP1301 is not set -CONFIG_USB_ULPI=y -CONFIG_USB_ULPI_VIEWPORT=y +# CONFIG_USB_ULPI is not set # end of USB Physical Layer drivers CONFIG_USB_GADGET=y -# CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FILES is not set # CONFIG_USB_GADGET_DEBUG_FS is not set CONFIG_USB_GADGET_VBUS_DRAW=2 @@ -5590,6 +5053,7 @@ CONFIG_U_SERIAL_CONSOLE=y # CONFIG_USB_BDC_UDC is not set # CONFIG_USB_NET2272 is not set # CONFIG_USB_GADGET_XILINX is not set +CONFIG_USB_MAX3420_UDC=m # CONFIG_USB_DUMMY_HCD is not set # end of USB Peripheral Controller @@ -5603,7 +5067,6 @@ CONFIG_USB_F_SERIAL=m CONFIG_USB_F_OBEX=m CONFIG_USB_F_NCM=m CONFIG_USB_F_ECM=m -CONFIG_USB_F_PHONET=m CONFIG_USB_F_EEM=m CONFIG_USB_F_SUBSET=m CONFIG_USB_F_RNDIS=m @@ -5624,7 +5087,6 @@ CONFIG_USB_CONFIGFS_ECM=y CONFIG_USB_CONFIGFS_ECM_SUBSET=y CONFIG_USB_CONFIGFS_RNDIS=y CONFIG_USB_CONFIGFS_EEM=y -# CONFIG_USB_CONFIGFS_PHONET is not set CONFIG_USB_CONFIGFS_MASS_STORAGE=y CONFIG_USB_CONFIGFS_F_LB_SS=y CONFIG_USB_CONFIGFS_F_FS=y @@ -5635,6 +5097,10 @@ CONFIG_USB_CONFIGFS_F_MIDI=y CONFIG_USB_CONFIGFS_F_HID=y CONFIG_USB_CONFIGFS_F_UVC=y CONFIG_USB_CONFIGFS_F_PRINTER=y + +# +# USB Gadget precomposed configurations +# CONFIG_USB_ZERO=m # CONFIG_USB_ZERO_HNPTEST is not set CONFIG_USB_AUDIO=m @@ -5653,7 +5119,6 @@ CONFIG_USB_G_SERIAL=m CONFIG_USB_MIDI_GADGET=m CONFIG_USB_G_PRINTER=m CONFIG_USB_CDC_COMPOSITE=m -CONFIG_USB_G_NOKIA=m CONFIG_USB_G_ACM_MS=m CONFIG_USB_G_MULTI=m CONFIG_USB_G_MULTI_RNDIS=y @@ -5661,13 +5126,14 @@ CONFIG_USB_G_MULTI_CDC=y CONFIG_USB_G_HID=m # CONFIG_USB_G_DBGP is not set CONFIG_USB_G_WEBCAM=m +CONFIG_USB_RAW_GADGET=m +# end of USB Gadget precomposed configurations + CONFIG_TYPEC=m -CONFIG_TYPEC_TCPM=m -CONFIG_TYPEC_TCPCI=m -CONFIG_TYPEC_RT1711H=m -CONFIG_TYPEC_FUSB302=m -CONFIG_TYPEC_UCSI=m -CONFIG_UCSI_CCG=m +# CONFIG_TYPEC_TCPM is not set +# CONFIG_TYPEC_UCSI is not set +CONFIG_TYPEC_ANX7688=m +CONFIG_TYPEC_HD3SS3220=m CONFIG_TYPEC_TPS6598X=m # @@ -5686,7 +5152,7 @@ CONFIG_TYPEC_DP_ALTMODE=m CONFIG_USB_ROLE_SWITCH=y CONFIG_MMC=y CONFIG_PWRSEQ_EMMC=y -CONFIG_PWRSEQ_SD8787=m +# CONFIG_PWRSEQ_SD8787 is not set CONFIG_PWRSEQ_SIMPLE=y CONFIG_MMC_BLOCK=y CONFIG_MMC_BLOCK_MINORS=32 @@ -5708,6 +5174,7 @@ CONFIG_MMC_SDHCI_OF_ASPEED=m # CONFIG_MMC_SDHCI_OF_DWCMSHC is not set # CONFIG_MMC_SDHCI_CADENCE is not set # CONFIG_MMC_SDHCI_F_SDH30 is not set +CONFIG_MMC_SDHCI_MILBEAUT=m CONFIG_MMC_SPI=y CONFIG_MMC_DW=y CONFIG_MMC_DW_PLTFM=y @@ -5719,7 +5186,8 @@ CONFIG_MMC_DW_K3=y # CONFIG_MMC_USHC is not set # CONFIG_MMC_USDHI6ROL0 is not set CONFIG_MMC_SUNXI=y -# CONFIG_MMC_CQHCI is not set +CONFIG_MMC_CQHCI=m +CONFIG_MMC_HSQ=m # CONFIG_MMC_MTK is not set # CONFIG_MMC_SDHCI_XENON is not set # CONFIG_MMC_SDHCI_OMAP is not set @@ -5733,18 +5201,15 @@ CONFIG_LEDS_CLASS=y # # LED drivers # -CONFIG_LEDS_88PM860X=m CONFIG_LEDS_AN30259A=m # CONFIG_LEDS_BCM6328 is not set # CONFIG_LEDS_BCM6358 is not set -CONFIG_LEDS_CPCAP=m CONFIG_LEDS_CR0014114=m +CONFIG_LEDS_EL15203000=m # CONFIG_LEDS_LM3530 is not set CONFIG_LEDS_LM3532=m -CONFIG_LEDS_LM3533=m # CONFIG_LEDS_LM3642 is not set CONFIG_LEDS_LM3692X=m -CONFIG_LEDS_MT6323=m # CONFIG_LEDS_PCA9532 is not set CONFIG_LEDS_GPIO=y # CONFIG_LEDS_LP3944 is not set @@ -5753,27 +5218,18 @@ CONFIG_LEDS_GPIO=y # CONFIG_LEDS_LP5523 is not set # CONFIG_LEDS_LP5562 is not set # CONFIG_LEDS_LP8501 is not set -CONFIG_LEDS_LP8788=m # CONFIG_LEDS_LP8860 is not set # CONFIG_LEDS_PCA955X is not set # CONFIG_LEDS_PCA963X is not set -CONFIG_LEDS_WM831X_STATUS=m -CONFIG_LEDS_WM8350=m -CONFIG_LEDS_DA903X=m -CONFIG_LEDS_DA9052=m # CONFIG_LEDS_DAC124S085 is not set CONFIG_LEDS_PWM=m CONFIG_LEDS_REGULATOR=m # CONFIG_LEDS_BD2802 is not set # CONFIG_LEDS_LT3593 is not set -CONFIG_LEDS_ADP5520=m -CONFIG_LEDS_MC13783=m # CONFIG_LEDS_TCA6507 is not set # CONFIG_LEDS_TLC591XX is not set CONFIG_LEDS_MAX77650=m -CONFIG_LEDS_MAX8997=m # CONFIG_LEDS_LM355x is not set -CONFIG_LEDS_MENF21BMC=m # CONFIG_LEDS_IS31FL319X is not set # CONFIG_LEDS_IS31FL32XX is not set @@ -5815,6 +5271,11 @@ CONFIG_LEDS_TRIGGER_AUDIO=m # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set CONFIG_EDAC_SUPPORT=y +CONFIG_EDAC=m +CONFIG_EDAC_LEGACY_SYSFS=y +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_XGENE=m +CONFIG_EDAC_DMC520=m CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y @@ -5828,7 +5289,7 @@ CONFIG_RTC_NVMEM=y # RTC interfaces # CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y +# CONFIG_RTC_INTF_PROC is not set CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set # CONFIG_RTC_DRV_TEST is not set @@ -5836,26 +5297,17 @@ CONFIG_RTC_INTF_DEV=y # # I2C RTC drivers # -CONFIG_RTC_DRV_88PM860X=m -CONFIG_RTC_DRV_88PM80X=m CONFIG_RTC_DRV_ABB5ZES3=m CONFIG_RTC_DRV_ABEOZ9=m CONFIG_RTC_DRV_ABX80X=m -CONFIG_RTC_DRV_AS3722=m +CONFIG_RTC_DRV_AC100=m CONFIG_RTC_DRV_DS1307=m CONFIG_RTC_DRV_DS1307_CENTURY=y CONFIG_RTC_DRV_DS1374=m CONFIG_RTC_DRV_DS1374_WDT=y CONFIG_RTC_DRV_DS1672=m CONFIG_RTC_DRV_HYM8563=m -CONFIG_RTC_DRV_LP8788=m CONFIG_RTC_DRV_MAX6900=m -CONFIG_RTC_DRV_MAX8907=m -CONFIG_RTC_DRV_MAX8925=m -CONFIG_RTC_DRV_MAX8998=m -CONFIG_RTC_DRV_MAX8997=m -CONFIG_RTC_DRV_MAX77686=m -CONFIG_RTC_DRV_RK808=m CONFIG_RTC_DRV_RS5C372=m CONFIG_RTC_DRV_ISL1208=m CONFIG_RTC_DRV_ISL12022=m @@ -5869,12 +5321,6 @@ CONFIG_RTC_DRV_PCF8583=m CONFIG_RTC_DRV_M41T80=m CONFIG_RTC_DRV_M41T80_WDT=y CONFIG_RTC_DRV_BQ32K=m -CONFIG_RTC_DRV_TWL4030=m -CONFIG_RTC_DRV_PALMAS=m -CONFIG_RTC_DRV_TPS6586X=m -CONFIG_RTC_DRV_TPS65910=m -CONFIG_RTC_DRV_TPS80031=m -CONFIG_RTC_DRV_RC5T583=m CONFIG_RTC_DRV_S35390A=m CONFIG_RTC_DRV_FM3130=m CONFIG_RTC_DRV_RX8010=m @@ -5924,10 +5370,6 @@ CONFIG_RTC_DRV_RV3029_HWMON=y # CONFIG_RTC_DRV_DS1685_FAMILY is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_DS2404 is not set -CONFIG_RTC_DRV_DA9052=m -CONFIG_RTC_DRV_DA9055=m -CONFIG_RTC_DRV_DA9063=m -CONFIG_RTC_DRV_EFI=m # CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set @@ -5936,10 +5378,6 @@ CONFIG_RTC_DRV_EFI=m # CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set -CONFIG_RTC_DRV_WM831X=m -CONFIG_RTC_DRV_WM8350=m -CONFIG_RTC_DRV_PCF50633=m -CONFIG_RTC_DRV_AB3100=m # CONFIG_RTC_DRV_ZYNQMP is not set # @@ -5950,17 +5388,12 @@ CONFIG_RTC_DRV_PL031=m CONFIG_RTC_DRV_SUN6I=y CONFIG_RTC_DRV_CADENCE=m # CONFIG_RTC_DRV_FTRTC010 is not set -CONFIG_RTC_DRV_PCAP=m -CONFIG_RTC_DRV_MC13XXX=m -# CONFIG_RTC_DRV_SNVS is not set -CONFIG_RTC_DRV_MT6397=m # CONFIG_RTC_DRV_R7301 is not set -CONFIG_RTC_DRV_CPCAP=m # # HID Sensor RTC drivers # -CONFIG_RTC_DRV_HID_SENSOR_TIME=m +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set CONFIG_DMADEVICES=y # CONFIG_DMADEVICES_DEBUG is not set @@ -5979,13 +5412,14 @@ CONFIG_DW_AXI_DMAC=m # CONFIG_FSL_EDMA is not set CONFIG_FSL_QDMA=m # CONFIG_INTEL_IDMA64 is not set -CONFIG_MV_XOR_V2=y -CONFIG_PL330_DMA=y +# CONFIG_MV_XOR_V2 is not set +# CONFIG_PL330_DMA is not set # CONFIG_XILINX_DMA is not set # CONFIG_XILINX_ZYNQMP_DMA is not set -CONFIG_QCOM_HIDMA_MGMT=y -CONFIG_QCOM_HIDMA=y +# CONFIG_QCOM_HIDMA_MGMT is not set +# CONFIG_QCOM_HIDMA is not set # CONFIG_DW_DMAC is not set +CONFIG_SF_PDMA=m # # DMA Clients @@ -6000,7 +5434,9 @@ CONFIG_DMA_ENGINE_RAID=y CONFIG_SYNC_FILE=y # CONFIG_SW_SYNC is not set # CONFIG_UDMABUF is not set +# CONFIG_DMABUF_MOVE_NOTIFY is not set CONFIG_DMABUF_SELFTESTS=m +# CONFIG_DMABUF_HEAPS is not set # end of DMABUF options # CONFIG_AUXDISPLAY is not set @@ -6013,47 +5449,27 @@ CONFIG_VIRTIO_BALLOON=y # CONFIG_VIRTIO_INPUT is not set CONFIG_VIRTIO_MMIO=y # CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set +# CONFIG_VDPA is not set +CONFIG_VHOST_DPN=y +CONFIG_VHOST_MENU=y +# CONFIG_VHOST_NET is not set +# CONFIG_VHOST_VSOCK is not set +# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set # # Microsoft Hyper-V guest support # # end of Microsoft Hyper-V guest support -# -# Xen driver support -# -CONFIG_XEN_BALLOON=y -CONFIG_XEN_SCRUB_PAGES_DEFAULT=y -CONFIG_XEN_DEV_EVTCHN=m -CONFIG_XEN_BACKEND=y -CONFIG_XENFS=m -CONFIG_XEN_COMPAT_XENFS=y -CONFIG_XEN_SYS_HYPERVISOR=y -CONFIG_XEN_XENBUS_FRONTEND=y -CONFIG_XEN_GNTDEV=m -CONFIG_XEN_GRANT_DEV_ALLOC=m -# CONFIG_XEN_GRANT_DMA_ALLOC is not set -CONFIG_SWIOTLB_XEN=y -# CONFIG_XEN_PVCALLS_FRONTEND is not set -# CONFIG_XEN_PVCALLS_BACKEND is not set -CONFIG_XEN_PRIVCMD=m -CONFIG_XEN_EFI=y -CONFIG_XEN_AUTO_XLATE=y -CONFIG_XEN_FRONT_PGDIR_SHBUF=m -# end of Xen driver support - # CONFIG_GREYBUS is not set CONFIG_STAGING=y # CONFIG_PRISM2_USB is not set # CONFIG_COMEDI is not set -CONFIG_RTLLIB=m -CONFIG_RTLLIB_CRYPTO_CCMP=m -CONFIG_RTLLIB_CRYPTO_TKIP=m -CONFIG_RTLLIB_CRYPTO_WEP=m +# CONFIG_RTLLIB is not set CONFIG_RTL8723BS=m CONFIG_R8712U=m # CONFIG_R8188EU is not set -CONFIG_VT6656=m +# CONFIG_VT6656 is not set # # IIO staging drivers @@ -6070,7 +5486,6 @@ CONFIG_VT6656=m # Analog to digital converters # # CONFIG_AD7816 is not set -# CONFIG_AD7192 is not set # CONFIG_AD7280 is not set # end of Analog to digital converters @@ -6121,10 +5536,12 @@ CONFIG_AD9834=m CONFIG_STAGING_MEDIA=y CONFIG_VIDEO_SUNXI=y +CONFIG_VIDEO_SUNXI_CEDRUS=m # # soc_camera sensor drivers # +CONFIG_VIDEO_USBVISION=m # # Android @@ -6154,6 +5571,7 @@ CONFIG_FB_TFT_PCD8544=m CONFIG_FB_TFT_RA8875=m CONFIG_FB_TFT_S6D02A1=m CONFIG_FB_TFT_S6D1121=m +CONFIG_FB_TFT_SEPS525=m CONFIG_FB_TFT_SH1106=m CONFIG_FB_TFT_SSD1289=m CONFIG_FB_TFT_SSD1305=m @@ -6170,7 +5588,7 @@ CONFIG_FB_TFT_UPD161704=m CONFIG_FB_TFT_WATTEROTT=m # CONFIG_WILC1000_SDIO is not set # CONFIG_WILC1000_SPI is not set -CONFIG_MOST=m +CONFIG_MOST_COMPONENTS=m # CONFIG_MOST_CDEV is not set # CONFIG_MOST_NET is not set # CONFIG_MOST_SOUND is not set @@ -6188,16 +5606,8 @@ CONFIG_MOST=m CONFIG_XIL_AXIS_FIFO=m # CONFIG_FIELDBUS_DEV is not set -# CONFIG_USB_WUSB_CBAF is not set -# CONFIG_UWB is not set -CONFIG_EXFAT_FS=m -CONFIG_EXFAT_DONT_MOUNT_VFAT=y -CONFIG_EXFAT_DISCARD=y -# CONFIG_EXFAT_DELAYED_SYNC is not set -# CONFIG_EXFAT_KERNEL_DEBUG is not set -# CONFIG_EXFAT_DEBUG_MSG is not set -CONFIG_EXFAT_DEFAULT_CODEPAGE=437 -CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" +CONFIG_WFX=m +CONFIG_RTL8723CS_NEW=m # CONFIG_GOLDFISH is not set # CONFIG_MFD_CROS_EC is not set # CONFIG_CHROME_PLATFORMS is not set @@ -6209,12 +5619,9 @@ CONFIG_COMMON_CLK=y # # Common Clock Framework # -CONFIG_COMMON_CLK_WM831X=m # CONFIG_COMMON_CLK_VERSATILE is not set # CONFIG_CLK_HSDK is not set -CONFIG_COMMON_CLK_MAX77686=m CONFIG_COMMON_CLK_MAX9485=m -CONFIG_COMMON_CLK_RK808=m # CONFIG_COMMON_CLK_SCMI is not set CONFIG_COMMON_CLK_SCPI=y # CONFIG_COMMON_CLK_SI5341 is not set @@ -6226,10 +5633,8 @@ CONFIG_COMMON_CLK_SI544=m # CONFIG_COMMON_CLK_CDCE925 is not set # CONFIG_COMMON_CLK_CS2000_CP is not set # CONFIG_COMMON_CLK_S2MPS11 is not set -CONFIG_CLK_TWL6040=m # CONFIG_CLK_QORIQ is not set # CONFIG_COMMON_CLK_XGENE is not set -CONFIG_COMMON_CLK_PALMAS=m # CONFIG_COMMON_CLK_PWM is not set # CONFIG_COMMON_CLK_VC5 is not set CONFIG_COMMON_CLK_BD718XX=m @@ -6260,14 +5665,15 @@ CONFIG_ARM_ARCH_TIMER=y CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y CONFIG_FSL_ERRATUM_A008585=y -CONFIG_HISILICON_ERRATUM_161010101=y -CONFIG_ARM64_ERRATUM_858921=y +# CONFIG_HISILICON_ERRATUM_161010101 is not set +# CONFIG_ARM64_ERRATUM_858921 is not set CONFIG_SUN50I_ERRATUM_UNKNOWN1=y +# CONFIG_MICROCHIP_PIT64B is not set # end of Clock Source drivers CONFIG_MAILBOX=y CONFIG_ARM_MHU=y -CONFIG_PLATFORM_MHU=y +# CONFIG_PLATFORM_MHU is not set # CONFIG_PL320_MBOX is not set # CONFIG_ALTERA_MBOX is not set # CONFIG_MAILBOX_TEST is not set @@ -6290,6 +5696,7 @@ CONFIG_IOMMU_IO_PGTABLE_LPAE=y CONFIG_OF_IOMMU=y CONFIG_IOMMU_DMA=y CONFIG_ARM_SMMU=y +# CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS is not set CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y # CONFIG_ARM_SMMU_V3 is not set # CONFIG_VIRTIO_IOMMU is not set @@ -6326,12 +5733,14 @@ CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y # # Broadcom SoC drivers # -CONFIG_SOC_BRCMSTB=y +# CONFIG_SOC_BRCMSTB is not set # end of Broadcom SoC drivers # # NXP/Freescale QorIQ SoC drivers # +# CONFIG_QUICC_ENGINE is not set +# CONFIG_FSL_RCPM is not set # end of NXP/Freescale QorIQ SoC drivers # @@ -6375,27 +5784,20 @@ CONFIG_EXTCON=y # Extcon Device Drivers # # CONFIG_EXTCON_ADC_JACK is not set -CONFIG_EXTCON_ARIZONA=m # CONFIG_EXTCON_FSA9480 is not set # CONFIG_EXTCON_GPIO is not set -CONFIG_EXTCON_MAX14577=m # CONFIG_EXTCON_MAX3355 is not set -CONFIG_EXTCON_MAX77693=m -CONFIG_EXTCON_MAX77843=m -CONFIG_EXTCON_MAX8997=m -CONFIG_EXTCON_PALMAS=m CONFIG_EXTCON_PTN5150=m # CONFIG_EXTCON_RT8973A is not set # CONFIG_EXTCON_SM5502 is not set CONFIG_EXTCON_USB_GPIO=y -CONFIG_MEMORY=y -# CONFIG_ARM_PL172_MPMC is not set -CONFIG_IIO=y +# CONFIG_MEMORY is not set +CONFIG_IIO=m CONFIG_IIO_BUFFER=y CONFIG_IIO_BUFFER_CB=m # CONFIG_IIO_BUFFER_HW_CONSUMER is not set -CONFIG_IIO_KFIFO_BUF=y -CONFIG_IIO_TRIGGERED_BUFFER=y +CONFIG_IIO_KFIFO_BUF=m +CONFIG_IIO_TRIGGERED_BUFFER=m CONFIG_IIO_CONFIGFS=m CONFIG_IIO_TRIGGER=y CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 @@ -6416,6 +5818,8 @@ CONFIG_ADXL372_SPI=m CONFIG_ADXL372_I2C=m CONFIG_BMA180=m CONFIG_BMA220=m +CONFIG_BMA400=m +CONFIG_BMA400_I2C=m CONFIG_BMC150_ACCEL=m CONFIG_BMC150_ACCEL_I2C=m CONFIG_BMC150_ACCEL_SPI=m @@ -6452,9 +5856,12 @@ CONFIG_STK8BA50=m # Analog to digital converters # CONFIG_AD_SIGMA_DELTA=m +CONFIG_AD7091R5=m CONFIG_AD7124=m +# CONFIG_AD7192 is not set CONFIG_AD7266=m CONFIG_AD7291=m +CONFIG_AD7292=m CONFIG_AD7298=m CONFIG_AD7476=m CONFIG_AD7606=m @@ -6472,16 +5879,13 @@ CONFIG_AD799X=m CONFIG_AXP20X_ADC=m CONFIG_AXP288_ADC=m CONFIG_CC10001_ADC=m -CONFIG_CPCAP_ADC=m -CONFIG_DA9150_GPADC=m -CONFIG_DLN2_ADC=m CONFIG_ENVELOPE_DETECTOR=m CONFIG_HI8435=m # CONFIG_HX711 is not set CONFIG_INA2XX_ADC=m -CONFIG_LP8788_ADC=m CONFIG_LTC2471=m CONFIG_LTC2485=m +CONFIG_LTC2496=m CONFIG_LTC2497=m CONFIG_MAX1027=m CONFIG_MAX11100=m @@ -6492,7 +5896,6 @@ CONFIG_MCP320X=m CONFIG_MCP3422=m CONFIG_MCP3911=m # CONFIG_NAU7802 is not set -CONFIG_PALMAS_GPADC=m CONFIG_QCOM_VADC_COMMON=m # CONFIG_QCOM_SPMI_IADC is not set # CONFIG_QCOM_SPMI_VADC is not set @@ -6511,12 +5914,8 @@ CONFIG_TI_ADS7950=m CONFIG_TI_ADS8344=m CONFIG_TI_ADS8688=m CONFIG_TI_ADS124S08=m -CONFIG_TI_AM335X_ADC=m CONFIG_TI_TLC4541=m -CONFIG_TWL4030_MADC=m -CONFIG_TWL6030_GPADC=m # CONFIG_VF610_ADC is not set -CONFIG_VIPERBOARD_ADC=m # CONFIG_XILINX_XADC is not set # end of Analog to digital converters @@ -6530,6 +5929,7 @@ CONFIG_VIPERBOARD_ADC=m # Amplifiers # # CONFIG_AD8366 is not set +CONFIG_HMC425=m # end of Amplifiers # @@ -6579,8 +5979,6 @@ CONFIG_IIO_ST_SENSORS_CORE=m # CONFIG_AD5593R is not set # CONFIG_AD5504 is not set # CONFIG_AD5624R_SPI is not set -CONFIG_LTC1660=m -# CONFIG_LTC2632 is not set CONFIG_AD5686=m CONFIG_AD5686_SPI=m CONFIG_AD5696_I2C=m @@ -6588,11 +5986,14 @@ CONFIG_AD5696_I2C=m CONFIG_AD5758=m # CONFIG_AD5761 is not set # CONFIG_AD5764 is not set +CONFIG_AD5770R=m # CONFIG_AD5791 is not set # CONFIG_AD7303 is not set # CONFIG_AD8801 is not set # CONFIG_DPOT_DAC is not set # CONFIG_DS4424 is not set +CONFIG_LTC1660=m +# CONFIG_LTC2632 is not set # CONFIG_M62332 is not set # CONFIG_MAX517 is not set # CONFIG_MAX5821 is not set @@ -6627,7 +6028,7 @@ CONFIG_IIO_SIMPLE_DUMMY=m # Phase-Locked Loop (PLL) frequency synthesizers # # CONFIG_ADF4350 is not set -CONFIG_ADF4371=m +# CONFIG_ADF4371 is not set # end of Phase-Locked Loop (PLL) frequency synthesizers # end of Frequency Synthesizers DDS/PLL @@ -6691,6 +6092,9 @@ CONFIG_ADIS16460=m # CONFIG_ADIS16480 is not set # CONFIG_BMI160_I2C is not set # CONFIG_BMI160_SPI is not set +CONFIG_FXOS8700=m +CONFIG_FXOS8700_I2C=m +CONFIG_FXOS8700_SPI=m # CONFIG_KMX61 is not set # CONFIG_INV_MPU6050_I2C is not set # CONFIG_INV_MPU6050_SPI is not set @@ -6704,6 +6108,8 @@ CONFIG_IIO_ADIS_LIB_BUFFER=y # Light sensors # CONFIG_ADJD_S311=m +CONFIG_ADUX1020=m +CONFIG_AL3010=m CONFIG_AL3320A=m CONFIG_APDS9300=m CONFIG_APDS9960=m @@ -6714,7 +6120,9 @@ CONFIG_CM3232=m CONFIG_CM3323=m CONFIG_CM3605=m CONFIG_CM36651=m +CONFIG_GP2AP002=m CONFIG_GP2AP020A00F=m +CONFIG_IQS621_ALS=m CONFIG_SENSORS_ISL29018=m CONFIG_SENSORS_ISL29028=m CONFIG_ISL29125=m @@ -6722,7 +6130,6 @@ CONFIG_HID_SENSOR_ALS=m CONFIG_HID_SENSOR_PROX=m CONFIG_JSA1212=m CONFIG_RPR0521=m -CONFIG_SENSORS_LM3533=m CONFIG_LTR501=m CONFIG_LV0104CS=m CONFIG_MAX44000=m @@ -6745,6 +6152,7 @@ CONFIG_TSL4531=m CONFIG_US5182D=m CONFIG_VCNL4000=m CONFIG_VCNL4035=m +CONFIG_VEML6030=m CONFIG_VEML6070=m CONFIG_VL6180=m CONFIG_ZOPT2201=m @@ -6790,16 +6198,22 @@ CONFIG_HID_SENSOR_DEVICE_ROTATION=m # Triggers - standalone # CONFIG_IIO_HRTIMER_TRIGGER=m -CONFIG_IIO_INTERRUPT_TRIGGER=m +# CONFIG_IIO_INTERRUPT_TRIGGER is not set CONFIG_IIO_TIGHTLOOP_TRIGGER=m -CONFIG_IIO_SYSFS_TRIGGER=m +# CONFIG_IIO_SYSFS_TRIGGER is not set # end of Triggers - standalone +# +# Linear and angular position sensors +# +CONFIG_IQS624_POS=m +# end of Linear and angular position sensors + # # Digital potentiometers # CONFIG_AD5272=m -# CONFIG_DS1803 is not set +CONFIG_DS1803=m CONFIG_MAX5432=m # CONFIG_MAX5481 is not set # CONFIG_MAX5487 is not set @@ -6823,9 +6237,11 @@ CONFIG_MCP41010=m CONFIG_BMP280=m CONFIG_BMP280_I2C=m CONFIG_BMP280_SPI=m -CONFIG_DPS310=m -CONFIG_HID_SENSOR_PRESS=m +CONFIG_DLHL60D=m +# CONFIG_DPS310 is not set +# CONFIG_HID_SENSOR_PRESS is not set # CONFIG_HP03 is not set +CONFIG_ICP10100=m # CONFIG_MPL115_I2C is not set # CONFIG_MPL115_SPI is not set # CONFIG_MPL3115 is not set @@ -6849,6 +6265,7 @@ CONFIG_HID_SENSOR_PRESS=m CONFIG_ISL29501=m # CONFIG_LIDAR_LITE_V2 is not set CONFIG_MB1232=m +CONFIG_PING=m # CONFIG_RFD77402 is not set # CONFIG_SRF04 is not set # CONFIG_SX9500 is not set @@ -6866,10 +6283,12 @@ CONFIG_VL53L0X_I2C=m # # Temperature sensors # +CONFIG_IQS620AT_TEMP=m +CONFIG_LTC2983=m CONFIG_MAXIM_THERMOCOUPLE=m CONFIG_HID_SENSOR_TEMP=m CONFIG_MLX90614=m -CONFIG_MLX90632=m +# CONFIG_MLX90632 is not set CONFIG_TMP006=m CONFIG_TMP007=m CONFIG_TSYS01=m @@ -6879,13 +6298,9 @@ CONFIG_MAX31856=m CONFIG_PWM=y CONFIG_PWM_SYSFS=y -CONFIG_PWM_ATMEL_HLCDC_PWM=m # CONFIG_PWM_FSL_FTM is not set -CONFIG_PWM_LP3943=m CONFIG_PWM_PCA9685=m CONFIG_PWM_SUN4I=m -CONFIG_PWM_TWL=m -CONFIG_PWM_TWL_LED=m # # IRQ chip support @@ -6903,6 +6318,8 @@ CONFIG_PARTITION_PERCPU=y # CONFIG_IPACK_BUS is not set CONFIG_ARCH_HAS_RESET_CONTROLLER=y CONFIG_RESET_CONTROLLER=y +# CONFIG_RESET_BRCMSTB_RESCAL is not set +# CONFIG_RESET_INTEL_GW is not set CONFIG_RESET_SCMI=y CONFIG_RESET_SIMPLE=y CONFIG_RESET_SUNXI=y @@ -6915,11 +6332,11 @@ CONFIG_GENERIC_PHY=y CONFIG_GENERIC_PHY_MIPI_DPHY=y # CONFIG_PHY_XGENE is not set CONFIG_PHY_SUN4I_USB=y -CONFIG_PHY_SUN6I_MIPI_DPHY=m +CONFIG_PHY_SUN6I_MIPI_DPHY=y CONFIG_PHY_SUN9I_USB=y CONFIG_PHY_SUN50I_USB3=y # CONFIG_BCM_KONA_USB2_PHY is not set -CONFIG_PHY_CADENCE_DP=m +CONFIG_PHY_CADENCE_TORRENT=m CONFIG_PHY_CADENCE_DPHY=m CONFIG_PHY_CADENCE_SIERRA=m CONFIG_PHY_FSL_IMX8MQ_USB=m @@ -6929,10 +6346,8 @@ CONFIG_PHY_FSL_IMX8MQ_USB=m # CONFIG_PHY_CPCAP_USB is not set CONFIG_PHY_MAPPHONE_MDM6600=m CONFIG_PHY_OCELOT_SERDES=m -CONFIG_PHY_QCOM_USB_HS=m -CONFIG_PHY_QCOM_USB_HSIC=m CONFIG_PHY_SAMSUNG_USB2=y -CONFIG_PHY_TUSB1210=m +CONFIG_PHY_INTEL_EMMC=m # end of PHY Subsystem # CONFIG_POWERCAP is not set @@ -6950,7 +6365,7 @@ CONFIG_ARM_DSU_PMU=m CONFIG_ARM_SPE_PMU=m # end of Performance monitor support -# CONFIG_RAS is not set +CONFIG_RAS=y # # Android @@ -6959,10 +6374,11 @@ CONFIG_ARM_SPE_PMU=m # end of Android # CONFIG_LIBNVDIMM is not set -CONFIG_DAX=y -CONFIG_DEV_DAX=m +CONFIG_DAX=m +# CONFIG_DEV_DAX is not set CONFIG_NVMEM=y CONFIG_NVMEM_SYSFS=y +CONFIG_NVMEM_SPMI_SDAM=m CONFIG_NVMEM_SUNXI_SID=y CONFIG_RAVE_SP_EEPROM=m @@ -6975,15 +6391,7 @@ CONFIG_RAVE_SP_EEPROM=m # CONFIG_FPGA is not set # CONFIG_FSI is not set -CONFIG_TEE=y - -# -# TEE drivers -# -CONFIG_OPTEE=y -CONFIG_OPTEE_SHM_NUM_PRIV_PAGES=1 -# end of TEE drivers - +# CONFIG_TEE is not set CONFIG_MULTIPLEXER=m # @@ -7001,6 +6409,7 @@ CONFIG_PM_OPP=y CONFIG_INTERCONNECT=m CONFIG_COUNTER=m CONFIG_FTM_QUADDEC=m +CONFIG_MOST=m # end of Device Drivers # @@ -7023,32 +6432,17 @@ CONFIG_EXT4_FS_SECURITY=y CONFIG_JBD2=y # CONFIG_JBD2_DEBUG is not set CONFIG_FS_MBCACHE=y -CONFIG_REISERFS_FS=m -# CONFIG_REISERFS_CHECK is not set -CONFIG_REISERFS_PROC_INFO=y -CONFIG_REISERFS_FS_XATTR=y -CONFIG_REISERFS_FS_POSIX_ACL=y -CONFIG_REISERFS_FS_SECURITY=y -CONFIG_JFS_FS=m -CONFIG_JFS_POSIX_ACL=y -CONFIG_JFS_SECURITY=y -# CONFIG_JFS_DEBUG is not set -CONFIG_JFS_STATISTICS=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set CONFIG_XFS_FS=m -CONFIG_XFS_QUOTA=y +# CONFIG_XFS_QUOTA is not set CONFIG_XFS_POSIX_ACL=y CONFIG_XFS_RT=y # CONFIG_XFS_ONLINE_SCRUB is not set # CONFIG_XFS_WARN is not set # CONFIG_XFS_DEBUG is not set -CONFIG_GFS2_FS=m -CONFIG_GFS2_FS_LOCKING_DLM=y -CONFIG_OCFS2_FS=m -CONFIG_OCFS2_FS_O2CB=m -CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m -CONFIG_OCFS2_FS_STATS=y -CONFIG_OCFS2_DEBUG_MASKLOG=y -# CONFIG_OCFS2_DEBUG_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set CONFIG_BTRFS_FS=y CONFIG_BTRFS_FS_POSIX_ACL=y # CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set @@ -7056,24 +6450,28 @@ CONFIG_BTRFS_FS_POSIX_ACL=y # CONFIG_BTRFS_DEBUG is not set # CONFIG_BTRFS_ASSERT is not set # CONFIG_BTRFS_FS_REF_VERIFY is not set -CONFIG_NILFS2_FS=m +# CONFIG_NILFS2_FS is not set CONFIG_F2FS_FS=y CONFIG_F2FS_STAT_FS=y CONFIG_F2FS_FS_XATTR=y CONFIG_F2FS_FS_POSIX_ACL=y CONFIG_F2FS_FS_SECURITY=y -CONFIG_F2FS_CHECK_FS=y +# CONFIG_F2FS_CHECK_FS is not set # CONFIG_F2FS_FAULT_INJECTION is not set -CONFIG_FS_DAX=y +CONFIG_F2FS_FS_COMPRESSION=y +CONFIG_F2FS_FS_LZO=y +CONFIG_F2FS_FS_LZ4=y +CONFIG_F2FS_FS_ZSTD=y +CONFIG_ZONEFS_FS=m +# CONFIG_FS_DAX is not set CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y CONFIG_EXPORTFS_BLOCK_OPS=y CONFIG_FILE_LOCKING=y CONFIG_MANDATORY_FILE_LOCKING=y CONFIG_FS_ENCRYPTION=y -CONFIG_FS_VERITY=y -# CONFIG_FS_VERITY_DEBUG is not set -CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y +CONFIG_FS_ENCRYPTION_ALGS=y +# CONFIG_FS_VERITY is not set CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y CONFIG_INOTIFY_USER=y @@ -7087,23 +6485,23 @@ CONFIG_QUOTA_TREE=m CONFIG_QFMT_V1=m CONFIG_QFMT_V2=m CONFIG_QUOTACTL=y -CONFIG_AUTOFS4_FS=m -CONFIG_AUTOFS_FS=m -CONFIG_FUSE_FS=y +CONFIG_AUTOFS4_FS=y +CONFIG_AUTOFS_FS=y +CONFIG_FUSE_FS=m CONFIG_CUSE=m CONFIG_VIRTIO_FS=m -CONFIG_OVERLAY_FS=y +CONFIG_OVERLAY_FS=m # CONFIG_OVERLAY_FS_REDIRECT_DIR is not set CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y # CONFIG_OVERLAY_FS_INDEX is not set -CONFIG_OVERLAY_FS_XINO_AUTO=y +# CONFIG_OVERLAY_FS_XINO_AUTO is not set # CONFIG_OVERLAY_FS_METACOPY is not set # # Caches # CONFIG_FSCACHE=m -CONFIG_FSCACHE_STATS=y +# CONFIG_FSCACHE_STATS is not set # CONFIG_FSCACHE_HISTOGRAM is not set # CONFIG_FSCACHE_DEBUG is not set # CONFIG_FSCACHE_OBJECT_LIST is not set @@ -7117,31 +6515,31 @@ CONFIG_CACHEFILES=m # CONFIG_ISO9660_FS=m CONFIG_JOLIET=y -CONFIG_ZISOFS=y +# CONFIG_ZISOFS is not set CONFIG_UDF_FS=m # end of CD-ROM/DVD Filesystems # -# DOS/FAT/NT Filesystems +# DOS/FAT/EXFAT/NT Filesystems # CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=m +# CONFIG_MSDOS_FS is not set CONFIG_VFAT_FS=y CONFIG_FAT_DEFAULT_CODEPAGE=437 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -CONFIG_FAT_DEFAULT_UTF8=y +# CONFIG_FAT_DEFAULT_UTF8 is not set +CONFIG_EXFAT_FS=m +CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" CONFIG_NTFS_FS=m # CONFIG_NTFS_DEBUG is not set -CONFIG_NTFS_RW=y -# end of DOS/FAT/NT Filesystems +# CONFIG_NTFS_RW is not set +# end of DOS/FAT/EXFAT/NT Filesystems # # Pseudo filesystems # CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -CONFIG_PROC_VMCORE=y -# CONFIG_PROC_VMCORE_DEVICE_DUMP is not set +CONFIG_PROC_KCORE=y CONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=y CONFIG_PROC_CHILDREN=y @@ -7155,7 +6553,6 @@ CONFIG_HUGETLB_PAGE=y CONFIG_MEMFD_CREATE=y CONFIG_ARCH_HAS_GIGANTIC_PAGE=y CONFIG_CONFIGFS_FS=y -CONFIG_EFIVAR_FS=m # end of Pseudo filesystems CONFIG_MISC_FILESYSTEMS=y @@ -7194,17 +6591,17 @@ CONFIG_CRAMFS_MTD=y CONFIG_SQUASHFS=y # CONFIG_SQUASHFS_FILE_CACHE is not set CONFIG_SQUASHFS_FILE_DIRECT=y -# CONFIG_SQUASHFS_DECOMP_SINGLE is not set +CONFIG_SQUASHFS_DECOMP_SINGLE=y # CONFIG_SQUASHFS_DECOMP_MULTI is not set -CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set CONFIG_SQUASHFS_XATTR=y CONFIG_SQUASHFS_ZLIB=y CONFIG_SQUASHFS_LZ4=y CONFIG_SQUASHFS_LZO=y CONFIG_SQUASHFS_XZ=y CONFIG_SQUASHFS_ZSTD=y -CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y -CONFIG_SQUASHFS_EMBEDDED=y +# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set +# CONFIG_SQUASHFS_EMBEDDED is not set CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 CONFIG_VXFS_FS=m CONFIG_MINIX_FS=m @@ -7222,19 +6619,18 @@ CONFIG_PSTORE=y CONFIG_PSTORE_DEFLATE_COMPRESS=y # CONFIG_PSTORE_LZO_COMPRESS is not set # CONFIG_PSTORE_LZ4_COMPRESS is not set -CONFIG_PSTORE_LZ4HC_COMPRESS=m +# CONFIG_PSTORE_LZ4HC_COMPRESS is not set # CONFIG_PSTORE_842_COMPRESS is not set # CONFIG_PSTORE_ZSTD_COMPRESS is not set CONFIG_PSTORE_COMPRESS=y CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y -# CONFIG_PSTORE_LZ4HC_COMPRESS_DEFAULT is not set CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" # CONFIG_PSTORE_CONSOLE is not set # CONFIG_PSTORE_PMSG is not set CONFIG_PSTORE_RAM=m CONFIG_SYSV_FS=m CONFIG_UFS_FS=m -CONFIG_UFS_FS_WRITE=y +# CONFIG_UFS_FS_WRITE is not set # CONFIG_UFS_DEBUG is not set CONFIG_EROFS_FS=m # CONFIG_EROFS_FS_DEBUG is not set @@ -7249,12 +6645,11 @@ CONFIG_AUFS_BRANCH_MAX_127=y # CONFIG_AUFS_BRANCH_MAX_32767 is not set CONFIG_AUFS_SBILIST=y # CONFIG_AUFS_HNOTIFY is not set -CONFIG_AUFS_EXPORT=y -CONFIG_AUFS_INO_T_64=y -CONFIG_AUFS_XATTR=y +# CONFIG_AUFS_EXPORT is not set +# CONFIG_AUFS_XATTR is not set # CONFIG_AUFS_FHSM is not set # CONFIG_AUFS_RDU is not set -CONFIG_AUFS_DIRREN=y +# CONFIG_AUFS_DIRREN is not set # CONFIG_AUFS_SHWH is not set # CONFIG_AUFS_BR_RAMFS is not set # CONFIG_AUFS_BR_FUSE is not set @@ -7280,7 +6675,8 @@ CONFIG_NFS_FSCACHE=y # CONFIG_NFS_USE_LEGACY_DNS is not set CONFIG_NFS_USE_KERNEL_DNS=y CONFIG_NFS_DEBUG=y -CONFIG_NFSD=m +CONFIG_NFS_DISABLE_UDP_SUPPORT=y +CONFIG_NFSD=y CONFIG_NFSD_V2_ACL=y CONFIG_NFSD_V3=y CONFIG_NFSD_V3_ACL=y @@ -7290,13 +6686,13 @@ CONFIG_NFSD_BLOCKLAYOUT=y CONFIG_NFSD_SCSILAYOUT=y CONFIG_NFSD_FLEXFILELAYOUT=y CONFIG_NFSD_V4_SECURITY_LABEL=y -CONFIG_GRACE_PERIOD=m -CONFIG_LOCKD=m +CONFIG_GRACE_PERIOD=y +CONFIG_LOCKD=y CONFIG_LOCKD_V4=y -CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_ACL_SUPPORT=y CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=m -CONFIG_SUNRPC_GSS=m +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y CONFIG_SUNRPC_BACKCHANNEL=y CONFIG_SUNRPC_SWAP=y CONFIG_RPCSEC_GSS_KRB5=m @@ -7307,7 +6703,7 @@ CONFIG_CEPH_FSCACHE=y CONFIG_CEPH_FS_POSIX_ACL=y CONFIG_CEPH_FS_SECURITY_LABEL=y CONFIG_CIFS=m -CONFIG_CIFS_STATS2=y +# CONFIG_CIFS_STATS2 is not set CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y CONFIG_CIFS_WEAK_PW_HASH=y CONFIG_CIFS_UPCALL=y @@ -7382,13 +6778,13 @@ CONFIG_DLM=m # CONFIG_DLM_DEBUG is not set CONFIG_UNICODE=y # CONFIG_UNICODE_NORMALIZATION_SELFTEST is not set +CONFIG_IO_WQ=y # end of File systems # # Security options # CONFIG_KEYS=y -CONFIG_KEYS_COMPAT=y CONFIG_KEYS_REQUEST_CACHE=y CONFIG_PERSISTENT_KEYRINGS=y CONFIG_BIG_KEYS=y @@ -7405,7 +6801,6 @@ CONFIG_LSM_MMAP_MIN_ADDR=0 CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y CONFIG_HARDENED_USERCOPY=y CONFIG_HARDENED_USERCOPY_FALLBACK=y -# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set CONFIG_FORTIFY_SOURCE=y # CONFIG_STATIC_USERMODEHELPER is not set CONFIG_SECURITY_SELINUX=y @@ -7414,6 +6809,8 @@ CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_DEVELOP=y CONFIG_SECURITY_SELINUX_AVC_STATS=y CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SELINUX_SIDTAB_HASH_BITS=9 +CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE=256 CONFIG_SECURITY_SMACK=y # CONFIG_SECURITY_SMACK_BRINGUP is not set CONFIG_SECURITY_SMACK_NETFILTER=y @@ -7442,11 +6839,36 @@ CONFIG_INTEGRITY_SIGNATURE=y CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y CONFIG_INTEGRITY_TRUSTED_KEYRING=y CONFIG_INTEGRITY_PLATFORM_KEYRING=y -CONFIG_LOAD_UEFI_KEYS=y CONFIG_INTEGRITY_AUDIT=y -# CONFIG_IMA is not set +CONFIG_IMA=y +CONFIG_IMA_MEASURE_PCR_IDX=10 +CONFIG_IMA_LSM_RULES=y +# CONFIG_IMA_TEMPLATE is not set +CONFIG_IMA_NG_TEMPLATE=y +# CONFIG_IMA_SIG_TEMPLATE is not set +CONFIG_IMA_DEFAULT_TEMPLATE="ima-ng" +CONFIG_IMA_DEFAULT_HASH_SHA1=y +# CONFIG_IMA_DEFAULT_HASH_SHA256 is not set +# CONFIG_IMA_DEFAULT_HASH_SHA512 is not set +CONFIG_IMA_DEFAULT_HASH="sha1" +# CONFIG_IMA_WRITE_POLICY is not set +# CONFIG_IMA_READ_POLICY is not set +CONFIG_IMA_APPRAISE=y +# CONFIG_IMA_ARCH_POLICY is not set +# CONFIG_IMA_APPRAISE_BUILD_POLICY is not set +CONFIG_IMA_APPRAISE_BOOTPARAM=y +# CONFIG_IMA_APPRAISE_MODSIG is not set +CONFIG_IMA_TRUSTED_KEYRING=y # CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY is not set -# CONFIG_EVM is not set +# CONFIG_IMA_BLACKLIST_KEYRING is not set +# CONFIG_IMA_LOAD_X509 is not set +CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS=y +CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS=y +CONFIG_EVM=y +CONFIG_EVM_ATTR_FSUUID=y +CONFIG_EVM_EXTRA_SMACK_XATTRS=y +# CONFIG_EVM_ADD_XATTRS is not set +# CONFIG_EVM_LOAD_X509 is not set # CONFIG_DEFAULT_SECURITY_SELINUX is not set # CONFIG_DEFAULT_SECURITY_SMACK is not set # CONFIG_DEFAULT_SECURITY_TOMOYO is not set @@ -7462,18 +6884,18 @@ CONFIG_LSM="lockdown,yama,integrity,apparmor" # Memory initialization # CONFIG_INIT_STACK_NONE=y -CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y +# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set # CONFIG_INIT_ON_FREE_DEFAULT_ON is not set # end of Memory initialization # end of Kernel hardening options # end of Security options CONFIG_XOR_BLOCKS=y -CONFIG_ASYNC_CORE=m -CONFIG_ASYNC_MEMCPY=m -CONFIG_ASYNC_XOR=m -CONFIG_ASYNC_PQ=m -CONFIG_ASYNC_RAID6_RECOV=m +CONFIG_ASYNC_CORE=y +CONFIG_ASYNC_MEMCPY=y +CONFIG_ASYNC_XOR=y +CONFIG_ASYNC_PQ=y +CONFIG_ASYNC_RAID6_RECOV=y CONFIG_CRYPTO=y # @@ -7483,8 +6905,8 @@ CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=y CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_SKCIPHER=y +CONFIG_CRYPTO_SKCIPHER2=y CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_HASH2=y CONFIG_CRYPTO_RNG=y @@ -7517,13 +6939,14 @@ CONFIG_CRYPTO_DH=y CONFIG_CRYPTO_ECC=m CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_ECRDSA=m +CONFIG_CRYPTO_CURVE25519=m # # Authenticated Encryption with Associated Data # -CONFIG_CRYPTO_CCM=y +CONFIG_CRYPTO_CCM=m CONFIG_CRYPTO_GCM=y -CONFIG_CRYPTO_CHACHA20POLY1305=y +CONFIG_CRYPTO_CHACHA20POLY1305=m CONFIG_CRYPTO_AEGIS128=m CONFIG_CRYPTO_AEGIS128_SIMD=y CONFIG_CRYPTO_SEQIV=y @@ -7559,35 +6982,34 @@ CONFIG_CRYPTO_VMAC=m # CONFIG_CRYPTO_CRC32C=y CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_XXHASH=m +CONFIG_CRYPTO_XXHASH=y +CONFIG_CRYPTO_BLAKE2B=y +CONFIG_CRYPTO_BLAKE2S=m CONFIG_CRYPTO_CRCT10DIF=y CONFIG_CRYPTO_GHASH=y -CONFIG_CRYPTO_POLY1305=y +CONFIG_CRYPTO_POLY1305=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_MICHAEL_MIC=y -CONFIG_CRYPTO_RMD128=y -CONFIG_CRYPTO_RMD160=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m CONFIG_CRYPTO_RMD256=m CONFIG_CRYPTO_RMD320=m CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_LIB_SHA256=y CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_SHA3=m CONFIG_CRYPTO_SM3=m CONFIG_CRYPTO_STREEBOG=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_WP512=y +CONFIG_CRYPTO_WP512=m # # Ciphers # -CONFIG_CRYPTO_LIB_AES=y CONFIG_CRYPTO_AES=y CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_LIB_ARC4=m CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_BLOWFISH_COMMON=m @@ -7595,18 +7017,17 @@ CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST_COMMON=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_LIB_DES=m -CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SALSA20=m -CONFIG_CRYPTO_CHACHA20=y +CONFIG_CRYPTO_CHACHA20=m CONFIG_CRYPTO_SEED=m -CONFIG_CRYPTO_SERPENT=y +CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_SM4=m CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_TWOFISH=y -CONFIG_CRYPTO_TWOFISH_COMMON=y +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m # # Compression @@ -7624,8 +7045,8 @@ CONFIG_CRYPTO_ZSTD=m CONFIG_CRYPTO_ANSI_CPRNG=m CONFIG_CRYPTO_DRBG_MENU=y CONFIG_CRYPTO_DRBG_HMAC=y -CONFIG_CRYPTO_DRBG_HASH=y -CONFIG_CRYPTO_DRBG_CTR=y +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set CONFIG_CRYPTO_DRBG=y CONFIG_CRYPTO_JITTERENTROPY=y CONFIG_CRYPTO_USER_API=m @@ -7633,17 +7054,45 @@ 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_STATS=y +# CONFIG_CRYPTO_STATS is not set CONFIG_CRYPTO_HASH_INFO=y + +# +# Crypto library routines +# +CONFIG_CRYPTO_LIB_AES=y +CONFIG_CRYPTO_LIB_ARC4=m +CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=m +CONFIG_CRYPTO_LIB_BLAKE2S=m +CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA=y +CONFIG_CRYPTO_LIB_CHACHA_GENERIC=y +CONFIG_CRYPTO_LIB_CHACHA=m +CONFIG_CRYPTO_LIB_CURVE25519_GENERIC=m +CONFIG_CRYPTO_LIB_CURVE25519=m +CONFIG_CRYPTO_LIB_DES=y +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 +CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_POLY1305_GENERIC=m +CONFIG_CRYPTO_LIB_POLY1305=m +CONFIG_CRYPTO_LIB_CHACHA20POLY1305=m +CONFIG_CRYPTO_LIB_SHA256=y CONFIG_CRYPTO_HW=y -CONFIG_CRYPTO_DEV_ATMEL_I2C=m -CONFIG_CRYPTO_DEV_ATMEL_ECC=m -CONFIG_CRYPTO_DEV_ATMEL_SHA204A=m +CONFIG_CRYPTO_DEV_ALLWINNER=y +CONFIG_CRYPTO_DEV_SUN4I_SS=m +# CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG is not set +CONFIG_CRYPTO_DEV_SUN8I_CE=m +# CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG is not set +CONFIG_CRYPTO_DEV_SUN8I_SS=m +# CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG is not set +# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set +# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set # CONFIG_CRYPTO_DEV_CCP is not set CONFIG_CRYPTO_DEV_VIRTIO=m CONFIG_CRYPTO_DEV_SAFEXCEL=m CONFIG_CRYPTO_DEV_CCREE=m -CONFIG_CRYPTO_DEV_HISI_SEC=m +# CONFIG_CRYPTO_DEV_HISI_SEC is not set +CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m +# CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG is not set CONFIG_ASYMMETRIC_KEY_TYPE=y CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE=m @@ -7679,7 +7128,6 @@ CONFIG_GENERIC_STRNCPY_FROM_USER=y CONFIG_GENERIC_STRNLEN_USER=y CONFIG_GENERIC_NET_UTILS=y CONFIG_CORDIC=m -CONFIG_PRIME_NUMBERS=m CONFIG_RATIONAL=y CONFIG_GENERIC_PCI_IOMAP=y CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y @@ -7711,7 +7159,7 @@ CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y CONFIG_LZO_COMPRESS=y CONFIG_LZO_DECOMPRESS=y -CONFIG_LZ4_COMPRESS=m +CONFIG_LZ4_COMPRESS=y CONFIG_LZ4HC_COMPRESS=m CONFIG_LZ4_DECOMPRESS=y CONFIG_ZSTD_COMPRESS=y @@ -7735,13 +7183,11 @@ CONFIG_GENERIC_ALLOCATOR=y CONFIG_REED_SOLOMON=m CONFIG_REED_SOLOMON_ENC8=y CONFIG_REED_SOLOMON_DEC8=y -CONFIG_REED_SOLOMON_ENC16=y CONFIG_REED_SOLOMON_DEC16=y CONFIG_TEXTSEARCH=y CONFIG_TEXTSEARCH_KMP=m CONFIG_TEXTSEARCH_BM=m CONFIG_TEXTSEARCH_FSM=m -CONFIG_INTERVAL_TREE=y CONFIG_XARRAY_MULTI=y CONFIG_ASSOCIATIVE_ARRAY=y CONFIG_HAS_IOMEM=y @@ -7755,8 +7201,8 @@ CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU=y CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y -CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN=y CONFIG_SWIOTLB=y +CONFIG_DMA_NONCOHERENT_MMAP=y CONFIG_DMA_REMAP=y CONFIG_DMA_DIRECT_REMAP=y CONFIG_DMA_CMA=y @@ -7775,7 +7221,7 @@ CONFIG_SGL_ALLOC=y CONFIG_CPU_RMAP=y CONFIG_DQL=y CONFIG_GLOB=y -CONFIG_GLOB_SELFTEST=m +# CONFIG_GLOB_SELFTEST is not set CONFIG_NLATTR=y CONFIG_LRU_CACHE=m CONFIG_CLZ_TAB=y @@ -7784,7 +7230,6 @@ CONFIG_MPILIB=y CONFIG_SIGNATURE=y CONFIG_LIBFDT=y CONFIG_OID_REGISTRY=y -CONFIG_UCS2_STRING=y CONFIG_HAVE_GENERIC_VDSO=y CONFIG_GENERIC_GETTIMEOFDAY=y CONFIG_FONT_SUPPORT=y @@ -7801,7 +7246,6 @@ CONFIG_FONT_6x10=y # CONFIG_FONT_SUN8x16 is not set # CONFIG_FONT_SUN12x22 is not set CONFIG_FONT_TER16x32=y -CONFIG_SG_SPLIT=y CONFIG_SG_POOL=y CONFIG_SBITMAP=y # CONFIG_STRING_SELFTEST is not set @@ -7819,53 +7263,51 @@ CONFIG_PRINTK_TIME=y CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 CONFIG_CONSOLE_LOGLEVEL_QUIET=4 CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -# CONFIG_BOOT_PRINTK_DELAY is not set CONFIG_DYNAMIC_DEBUG=y +CONFIG_SYMBOLIC_ERRNAME=y +CONFIG_DEBUG_BUGVERBOSE=y # end of printk and dmesg options # # Compile-time checks and compiler options # -# CONFIG_DEBUG_INFO is not set CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=1024 +CONFIG_FRAME_WARN=2048 # CONFIG_STRIP_ASM_SYMS is not set -# CONFIG_READABLE_ASM is not set -CONFIG_DEBUG_FS=y # CONFIG_HEADERS_INSTALL is not set -CONFIG_OPTIMIZE_INLINING=y # CONFIG_DEBUG_SECTION_MISMATCH is not set CONFIG_SECTION_MISMATCH_WARN_ONLY=y CONFIG_ARCH_WANT_FRAME_POINTERS=y CONFIG_FRAME_POINTER=y -# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set # end of Compile-time checks and compiler options +# +# Generic Kernel Debugging Instruments +# CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 CONFIG_MAGIC_SYSRQ_SERIAL=y -CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_MISC=y +CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="" +CONFIG_DEBUG_FS=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y +# CONFIG_UBSAN is not set +# end of Generic Kernel Debugging Instruments + +# CONFIG_DEBUG_KERNEL is not set # # Memory Debugging # # CONFIG_PAGE_EXTENSION is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_PAGE_OWNER is not set # CONFIG_PAGE_POISONING is not set # CONFIG_DEBUG_RODATA_TEST is not set -# CONFIG_DEBUG_OBJECTS is not set +CONFIG_GENERIC_PTDUMP=y # CONFIG_SLUB_DEBUG_ON is not set # CONFIG_SLUB_STATS is not set CONFIG_HAVE_DEBUG_KMEMLEAK=y -# CONFIG_DEBUG_KMEMLEAK is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_VM is not set CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y -# CONFIG_DEBUG_VIRTUAL is not set CONFIG_DEBUG_MEMORY_INIT=y -# CONFIG_DEBUG_PER_CPU_MAPS is not set CONFIG_HAVE_ARCH_KASAN=y CONFIG_HAVE_ARCH_KASAN_SW_TAGS=y CONFIG_CC_HAS_KASAN_GENERIC=y @@ -7873,94 +7315,84 @@ CONFIG_CC_HAS_KASAN_GENERIC=y CONFIG_KASAN_STACK=1 # end of Memory Debugging -CONFIG_ARCH_HAS_KCOV=y -CONFIG_CC_HAS_SANCOV_TRACE_PC=y -# CONFIG_KCOV is not set -# CONFIG_DEBUG_SHIRQ is not set - # -# Debug Lockups and Hangs +# Debug Oops, Lockups and Hangs # -# CONFIG_SOFTLOCKUP_DETECTOR is not set -# CONFIG_DETECT_HUNG_TASK is not set -# CONFIG_WQ_WATCHDOG is not set -# end of Debug Lockups and Hangs - # CONFIG_PANIC_ON_OOPS is not set CONFIG_PANIC_ON_OOPS_VALUE=0 CONFIG_PANIC_TIMEOUT=0 -CONFIG_SCHED_DEBUG=y +CONFIG_TEST_LOCKUP=m +# end of Debug Oops, Lockups and Hangs + +# +# Scheduler Debugging +# CONFIG_SCHED_INFO=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_SCHED_STACK_END_CHECK is not set +# end of Scheduler Debugging + # CONFIG_DEBUG_TIMEKEEPING is not set # # Lock Debugging (spinlocks, mutexes, etc...) # CONFIG_LOCK_DEBUGGING_SUPPORT=y -# CONFIG_PROVE_LOCKING is not set -# CONFIG_LOCK_STAT is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set -# CONFIG_DEBUG_RWSEMS is not set -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_DEBUG_ATOMIC_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_LOCK_TORTURE_TEST is not set # CONFIG_WW_MUTEX_SELFTEST is not set # end of Lock Debugging (spinlocks, mutexes, etc...) # CONFIG_STACKTRACE is not set # CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set -# CONFIG_DEBUG_KOBJECT is not set CONFIG_HAVE_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_BUGVERBOSE=y -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_PLIST is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_DEBUG_CREDENTIALS is not set + +# +# Debug kernel data structures +# +# CONFIG_BUG_ON_DATA_CORRUPTION is not set +# end of Debug kernel data structures # # RCU Debugging # -CONFIG_TORTURE_TEST=m -CONFIG_RCU_PERF_TEST=m -CONFIG_RCU_TORTURE_TEST=m CONFIG_RCU_CPU_STALL_TIMEOUT=60 -CONFIG_RCU_TRACE=y -# CONFIG_RCU_EQS_DEBUG is not set # end of RCU Debugging -# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set -# CONFIG_NOTIFIER_ERROR_INJECTION is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_TRACE_CLOCK=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set +# CONFIG_SAMPLES is not set +CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y +# CONFIG_STRICT_DEVMEM is not set + +# +# arm64 Debugging +# +# CONFIG_PID_IN_CONTEXTIDR is not set +# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set +# CONFIG_DEBUG_WX is not set +# CONFIG_ARM64_RELOC_TEST is not set +# CONFIG_CORESIGHT is not set +# end of arm64 Debugging + +# +# Kernel Testing and Coverage +# +# CONFIG_KUNIT is not set +CONFIG_ARCH_HAS_KCOV=y +CONFIG_CC_HAS_SANCOV_TRACE_PC=y +# CONFIG_KCOV is not set CONFIG_RUNTIME_TESTING_MENU=y # CONFIG_LKDTM is not set # CONFIG_TEST_LIST_SORT is not set +CONFIG_TEST_MIN_HEAP=m # CONFIG_TEST_SORT is not set -CONFIG_BACKTRACE_SELF_TEST=m -CONFIG_RBTREE_TEST=m -CONFIG_REED_SOLOMON_TEST=m -CONFIG_INTERVAL_TREE_TEST=m -CONFIG_PERCPU_TEST=m +# CONFIG_REED_SOLOMON_TEST is not set # CONFIG_ATOMIC64_SELFTEST is not set -CONFIG_ASYNC_RAID6_TEST=m +# CONFIG_ASYNC_RAID6_TEST is not set # CONFIG_TEST_HEXDUMP is not set # CONFIG_TEST_STRING_HELPERS is not set CONFIG_TEST_STRSCPY=m @@ -7975,7 +7407,7 @@ CONFIG_TEST_XARRAY=m # CONFIG_TEST_HASH is not set # CONFIG_TEST_IDA is not set # CONFIG_TEST_LKM is not set -CONFIG_TEST_VMALLOC=m +# CONFIG_TEST_VMALLOC is not set # CONFIG_TEST_USER_COPY is not set CONFIG_TEST_BPF=m CONFIG_TEST_BLACKHOLE_DEV=m @@ -7988,22 +7420,6 @@ CONFIG_TEST_BLACKHOLE_DEV=m CONFIG_TEST_MEMCAT_P=m CONFIG_TEST_STACKINIT=m # CONFIG_TEST_MEMINIT is not set -CONFIG_MEMTEST=y -# CONFIG_BUG_ON_DATA_CORRUPTION is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y -# CONFIG_UBSAN is not set -CONFIG_UBSAN_ALIGNMENT=y -CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y -CONFIG_STRICT_DEVMEM=y -# CONFIG_IO_STRICT_DEVMEM is not set -# CONFIG_ARM64_PTDUMP_DEBUGFS is not set -# CONFIG_PID_IN_CONTEXTIDR is not set -# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set -# CONFIG_DEBUG_WX is not set -# CONFIG_DEBUG_ALIGN_RODATA is not set -# CONFIG_ARM64_RELOC_TEST is not set -# CONFIG_CORESIGHT is not set +# CONFIG_MEMTEST is not set +# end of Kernel Testing and Coverage # end of Kernel hacking diff --git a/config/kernel/linux-sunxi64-legacy.config b/config/kernel/linux-sunxi64-legacy.config index 6e113a187..a1983fcc1 100644 --- a/config/kernel/linux-sunxi64-legacy.config +++ b/config/kernel/linux-sunxi64-legacy.config @@ -1,15 +1,17 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 4.19.67 Kernel Configuration +# Linux/arm64 5.4.51 Kernel Configuration # # -# Compiler: aarch64-linux-gnu-gcc (Linaro GCC 7.4-2019.02) 7.4.1 20181213 [linaro-7.4-2019.02 revision 56ec6f6b99cc167ff0c2f8e1a2eed33b1edc85d4] +# Compiler: aarch64-linux-gnu-gcc (GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36)) 8.3.0 # CONFIG_CC_IS_GCC=y -CONFIG_GCC_VERSION=70401 +CONFIG_GCC_VERSION=80300 CONFIG_CLANG_VERSION=0 +CONFIG_CC_CAN_LINK=y CONFIG_CC_HAS_ASM_GOTO=y +CONFIG_CC_HAS_ASM_INLINE=y CONFIG_IRQ_WORK=y CONFIG_BUILDTIME_EXTABLE_SORT=y CONFIG_THREAD_INFO_IN_TASK=y @@ -29,12 +31,10 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_CROSS_MEMORY_ATTACH=y -# CONFIG_USELIB is not set +CONFIG_USELIB=y CONFIG_AUDIT=y CONFIG_HAVE_ARCH_AUDITSYSCALL=y CONFIG_AUDITSYSCALL=y -CONFIG_AUDIT_WATCH=y -CONFIG_AUDIT_TREE=y # # IRQ subsystem @@ -47,13 +47,17 @@ CONFIG_GENERIC_IRQ_MIGRATION=y CONFIG_HARDIRQS_SW_RESEND=y CONFIG_GENERIC_IRQ_CHIP=y CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_SIM=y CONFIG_IRQ_DOMAIN_HIERARCHY=y CONFIG_GENERIC_MSI_IRQ=y CONFIG_GENERIC_MSI_IRQ_DOMAIN=y +CONFIG_IRQ_MSI_IOMMU=y CONFIG_HANDLE_DOMAIN_IRQ=y CONFIG_IRQ_FORCED_THREADING=y CONFIG_SPARSE_IRQ=y # CONFIG_GENERIC_IRQ_DEBUGFS is not set +# end of IRQ subsystem + CONFIG_GENERIC_IRQ_MULTI_HANDLER=y CONFIG_ARCH_CLOCKSOURCE_DATA=y CONFIG_GENERIC_TIME_VSYSCALL=y @@ -71,6 +75,8 @@ CONFIG_NO_HZ_IDLE=y # CONFIG_NO_HZ_FULL is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y +# end of Timers subsystem + CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -87,6 +93,9 @@ CONFIG_TASKSTATS=y CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y +# CONFIG_PSI is not set +# end of CPU/Task time and stats accounting + CONFIG_CPU_ISOLATION=y # @@ -96,18 +105,30 @@ CONFIG_TREE_RCU=y # CONFIG_RCU_EXPERT is not set CONFIG_SRCU=y CONFIG_TREE_SRCU=y +CONFIG_TASKS_RCU=y CONFIG_RCU_STALL_COMMON=y CONFIG_RCU_NEED_SEGCBLIST=y +# end of RCU Subsystem + CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +CONFIG_IKHEADERS=m CONFIG_LOG_BUF_SHIFT=14 CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 CONFIG_GENERIC_SCHED_CLOCK=y + +# +# Scheduler features +# +# CONFIG_UCLAMP_TASK is not set +# end of Scheduler features + CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y CONFIG_ARCH_SUPPORTS_INT128=y -# CONFIG_NUMA_BALANCING is not set +CONFIG_NUMA_BALANCING=y +CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y CONFIG_CGROUPS=y CONFIG_PAGE_COUNTER=y CONFIG_MEMCG=y @@ -115,7 +136,6 @@ CONFIG_MEMCG_SWAP=y CONFIG_MEMCG_SWAP_ENABLED=y CONFIG_MEMCG_KMEM=y CONFIG_BLK_CGROUP=y -# CONFIG_DEBUG_BLK_CGROUP is not set CONFIG_CGROUP_WRITEBACK=y CONFIG_CGROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y @@ -130,6 +150,8 @@ CONFIG_PROC_PID_CPUSET=y CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_BPF=y +# CONFIG_CGROUP_DEBUG is not set CONFIG_SOCK_CGROUP_DATA=y CONFIG_NAMESPACES=y CONFIG_UTS_NS=y @@ -138,7 +160,7 @@ CONFIG_USER_NS=y CONFIG_PID_NS=y CONFIG_NET_NS=y # CONFIG_CHECKPOINT_RESTORE is not set -# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_SCHED_AUTOGROUP=y # CONFIG_SYSFS_DEPRECATED is not set CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y @@ -152,14 +174,15 @@ CONFIG_RD_LZ4=y CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y CONFIG_HAVE_UID16=y CONFIG_SYSCTL_EXCEPTION_TRACE=y CONFIG_BPF=y -# CONFIG_EXPERT is not set +CONFIG_EXPERT=y CONFIG_UID16=y CONFIG_MULTIUSER=y +# CONFIG_SGETMASK_SYSCALL is not set CONFIG_SYSFS_SYSCALL=y +# CONFIG_SYSCTL_SYSCALL is not set CONFIG_FHANDLE=y CONFIG_POSIX_TIMERS=y CONFIG_PRINTK=y @@ -175,32 +198,45 @@ CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y +CONFIG_IO_URING=y CONFIG_ADVISE_SYSCALLS=y CONFIG_MEMBARRIER=y CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set CONFIG_KALLSYMS_BASE_RELATIVE=y -# CONFIG_BPF_SYSCALL is not set +CONFIG_BPF_SYSCALL=y +# CONFIG_BPF_JIT_ALWAYS_ON is not set # CONFIG_USERFAULTFD is not set CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y CONFIG_RSEQ=y +# CONFIG_DEBUG_RSEQ is not set # CONFIG_EMBEDDED is not set CONFIG_HAVE_PERF_EVENTS=y +# CONFIG_PC104 is not set # # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +# end of Kernel Performance Events And Counters + CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_MEMCG_SYSFS_ON is not set # CONFIG_COMPAT_BRK is not set # CONFIG_SLAB is not set CONFIG_SLUB=y +# CONFIG_SLOB is not set CONFIG_SLAB_MERGE_DEFAULT=y # CONFIG_SLAB_FREELIST_RANDOM is not set # CONFIG_SLAB_FREELIST_HARDENED is not set +# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set CONFIG_SLUB_CPU_PARTIAL=y CONFIG_SYSTEM_DATA_VERIFICATION=y -# CONFIG_PROFILING is not set +CONFIG_PROFILING=y +# end of General setup + CONFIG_ARM64=y CONFIG_64BIT=y CONFIG_MMU=y @@ -215,14 +251,13 @@ CONFIG_STACKTRACE_SUPPORT=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_LOCKDEP_SUPPORT=y CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CSUM=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ZONE_DMA32=y -CONFIG_HAVE_GENERIC_GUP=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_SMP=y CONFIG_KERNEL_MODE_NEON=y CONFIG_FIX_EARLYCON_MEM=y @@ -234,11 +269,13 @@ CONFIG_ARCH_PROC_KCORE_TEXT=y # Platform selection # # CONFIG_ARCH_ACTIONS is not set +# CONFIG_ARCH_AGILEX is not set CONFIG_ARCH_SUNXI=y # CONFIG_ARCH_ALPINE is not set # CONFIG_ARCH_BCM2835 is not set # CONFIG_ARCH_BCM_IPROC is not set # CONFIG_ARCH_BERLIN is not set +# CONFIG_ARCH_BITMAIN is not set # CONFIG_ARCH_BRCMSTB is not set # CONFIG_ARCH_EXYNOS is not set # CONFIG_ARCH_K3 is not set @@ -248,13 +285,14 @@ CONFIG_ARCH_SUNXI=y # CONFIG_ARCH_MEDIATEK is not set # CONFIG_ARCH_MESON is not set # CONFIG_ARCH_MVEBU is not set +# CONFIG_ARCH_MXC is not set # CONFIG_ARCH_QCOM is not set # CONFIG_ARCH_REALTEK is not set +# CONFIG_ARCH_RENESAS is not set # CONFIG_ARCH_ROCKCHIP is not set # CONFIG_ARCH_SEATTLE is not set -# CONFIG_ARCH_SYNQUACER is not set -# CONFIG_ARCH_RENESAS is not set # CONFIG_ARCH_STRATIX10 is not set +# CONFIG_ARCH_SYNQUACER is not set # CONFIG_ARCH_TEGRA is not set # CONFIG_ARCH_SPRD is not set # CONFIG_ARCH_THUNDER is not set @@ -264,16 +302,7 @@ CONFIG_ARCH_SUNXI=y # CONFIG_ARCH_XGENE is not set # CONFIG_ARCH_ZX is not set # CONFIG_ARCH_ZYNQMP is not set - -# -# Bus support -# -# CONFIG_PCI is not set - -# -# PCI Endpoint -# -# CONFIG_PCI_ENDPOINT is not set +# end of Platform selection # # Kernel Features @@ -282,26 +311,37 @@ CONFIG_ARCH_SUNXI=y # # ARM errata workarounds via the alternatives framework # +CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y CONFIG_ARM64_ERRATUM_826319=y CONFIG_ARM64_ERRATUM_827319=y CONFIG_ARM64_ERRATUM_824069=y CONFIG_ARM64_ERRATUM_819472=y -# CONFIG_ARM64_ERRATUM_832075 is not set +CONFIG_ARM64_ERRATUM_832075=y +CONFIG_ARM64_ERRATUM_834220=y CONFIG_ARM64_ERRATUM_845719=y CONFIG_ARM64_ERRATUM_843419=y CONFIG_ARM64_ERRATUM_1024718=y +CONFIG_ARM64_ERRATUM_1418040=y +CONFIG_ARM64_ERRATUM_1165522=y +CONFIG_ARM64_ERRATUM_1286807=y CONFIG_ARM64_ERRATUM_1463225=y -# CONFIG_CAVIUM_ERRATUM_22375 is not set +CONFIG_ARM64_ERRATUM_1542419=y +CONFIG_CAVIUM_ERRATUM_22375=y CONFIG_CAVIUM_ERRATUM_23144=y -# CONFIG_CAVIUM_ERRATUM_23154 is not set -# CONFIG_CAVIUM_ERRATUM_27456 is not set -# CONFIG_CAVIUM_ERRATUM_30115 is not set -# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set -# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set -# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set +CONFIG_CAVIUM_ERRATUM_23154=y +CONFIG_CAVIUM_ERRATUM_27456=y +CONFIG_CAVIUM_ERRATUM_30115=y +CONFIG_CAVIUM_TX2_ERRATUM_219=y +CONFIG_QCOM_FALKOR_ERRATUM_1003=y +CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y +CONFIG_QCOM_FALKOR_ERRATUM_1009=y +CONFIG_QCOM_QDF2400_ERRATUM_0065=y CONFIG_SOCIONEXT_SYNQUACER_PREITS=y CONFIG_HISILICON_ERRATUM_161600802=y CONFIG_QCOM_FALKOR_ERRATUM_E1041=y +CONFIG_FUJITSU_ERRATUM_010001=y +# end of ARM errata workarounds via the alternatives framework + CONFIG_ARM64_4K_PAGES=y # CONFIG_ARM64_16K_PAGES is not set # CONFIG_ARM64_64K_PAGES is not set @@ -313,7 +353,7 @@ CONFIG_ARM64_PA_BITS=48 # CONFIG_CPU_BIG_ENDIAN is not set CONFIG_SCHED_MC=y # CONFIG_SCHED_SMT is not set -CONFIG_NR_CPUS=8 +CONFIG_NR_CPUS=256 CONFIG_HOTPLUG_CPU=y CONFIG_NUMA=y CONFIG_NODES_SHIFT=2 @@ -328,7 +368,6 @@ CONFIG_HZ_250=y CONFIG_HZ=250 CONFIG_SCHED_HRTICK=y CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y -CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y @@ -337,22 +376,29 @@ CONFIG_HW_PERF_EVENTS=y CONFIG_SYS_SUPPORTS_HUGETLBFS=y CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y CONFIG_SECCOMP=y CONFIG_PARAVIRT=y # CONFIG_PARAVIRT_TIME_ACCOUNTING is not set -# CONFIG_KEXEC is not set -# CONFIG_CRASH_DUMP is not set -# CONFIG_XEN is not set +CONFIG_KEXEC=y +# CONFIG_KEXEC_FILE is not set +CONFIG_CRASH_DUMP=y +CONFIG_XEN_DOM0=y +CONFIG_XEN=y CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_UNMAP_KERNEL_AT_EL0=y CONFIG_HARDEN_BRANCH_PREDICTOR=y CONFIG_HARDEN_EL2_VECTORS=y CONFIG_ARM64_SSBD=y +CONFIG_RODATA_FULL_DEFAULT_ENABLED=y +# CONFIG_ARM64_SW_TTBR0_PAN is not set +CONFIG_ARM64_TAGGED_ADDR_ABI=y +CONFIG_COMPAT=y +CONFIG_KUSER_HELPERS=y CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y CONFIG_CP15_BARRIER_EMULATION=y CONFIG_SETEND_EMULATION=y -# CONFIG_ARM64_SW_TTBR0_PAN is not set # # ARMv8.1 architectural features @@ -361,6 +407,7 @@ CONFIG_ARM64_HW_AFDBM=y CONFIG_ARM64_PAN=y # CONFIG_ARM64_LSE_ATOMICS is not set CONFIG_ARM64_VHE=y +# end of ARMv8.1 architectural features # # ARMv8.2 architectural features @@ -368,25 +415,43 @@ CONFIG_ARM64_VHE=y CONFIG_ARM64_UAO=y # CONFIG_ARM64_PMEM is not set CONFIG_ARM64_RAS_EXTN=y +CONFIG_ARM64_CNP=y +# end of ARMv8.2 architectural features + +# +# ARMv8.3 architectural features +# +CONFIG_ARM64_PTR_AUTH=y +# end of ARMv8.3 architectural features + CONFIG_ARM64_SVE=y CONFIG_ARM64_MODULE_PLTS=y +# CONFIG_ARM64_PSEUDO_NMI is not set # CONFIG_RANDOMIZE_BASE is not set +# end of Kernel Features # # Boot options # CONFIG_CMDLINE="" # CONFIG_CMDLINE_FORCE is not set -# CONFIG_EFI is not set -CONFIG_COMPAT=y +CONFIG_EFI_STUB=y +CONFIG_EFI=y +CONFIG_DMI=y +# end of Boot options + CONFIG_SYSVIPC_COMPAT=y +CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y # # Power management options # CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y -# CONFIG_HIBERNATION is not set +# CONFIG_SUSPEND_SKIP_SYNC is not set +CONFIG_HIBERNATE_CALLBACKS=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="" CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y # CONFIG_PM_AUTOSLEEP is not set @@ -399,8 +464,11 @@ CONFIG_PM_GENERIC_DOMAINS=y CONFIG_PM_GENERIC_DOMAINS_SLEEP=y CONFIG_PM_GENERIC_DOMAINS_OF=y CONFIG_CPU_PM=y +# CONFIG_ENERGY_MODEL is not set CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_HIBERNATION_HEADER=y CONFIG_ARCH_SUSPEND_POSSIBLE=y +# end of Power management options # # CPU Power Management @@ -413,12 +481,16 @@ CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y # CONFIG_CPU_IDLE_GOV_LADDER is not set CONFIG_CPU_IDLE_GOV_MENU=y +# CONFIG_CPU_IDLE_GOV_TEO is not set CONFIG_DT_IDLE_STATES=y # # ARM CPU Idle Drivers # CONFIG_ARM_CPUIDLE=y +CONFIG_ARM_PSCI_CPUIDLE=y +# end of ARM CPU Idle Drivers +# end of CPU Idle # # CPU Frequency scaling @@ -445,73 +517,130 @@ CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y # CONFIG_CPUFREQ_DT=m CONFIG_CPUFREQ_DT_PLATDEV=y -CONFIG_ARM_BIG_LITTLE_CPUFREQ=m -# CONFIG_ARM_DT_BL_CPUFREQ is not set +CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=y CONFIG_ARM_SCPI_CPUFREQ=m # CONFIG_ARM_SCMI_CPUFREQ is not set # CONFIG_QORIQ_CPUFREQ is not set +# end of CPU Frequency scaling +# end of CPU Power Management # # Firmware Drivers # -CONFIG_ARM_PSCI_FW=y -# CONFIG_ARM_PSCI_CHECKER is not set CONFIG_ARM_SCMI_PROTOCOL=y CONFIG_ARM_SCMI_POWER_DOMAIN=y CONFIG_ARM_SCPI_PROTOCOL=y CONFIG_ARM_SCPI_POWER_DOMAIN=y # CONFIG_ARM_SDE_INTERFACE is not set +# CONFIG_FIRMWARE_MEMMAP is not set +CONFIG_DMIID=y +CONFIG_DMI_SYSFS=m CONFIG_HAVE_ARM_SMCCC=y +CONFIG_ARM_PSCI_FW=y +# CONFIG_ARM_PSCI_CHECKER is not set # CONFIG_GOOGLE_FIRMWARE is not set +# +# EFI (Extensible Firmware Interface) Support +# +CONFIG_EFI_VARS=m +CONFIG_EFI_ESRT=y +CONFIG_EFI_VARS_PSTORE=m +# CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE is not set +CONFIG_EFI_PARAMS_FROM_FDT=y +CONFIG_EFI_RUNTIME_WRAPPERS=y +CONFIG_EFI_ARMSTUB=y +CONFIG_EFI_ARMSTUB_DTB_LOADER=y +CONFIG_EFI_BOOTLOADER_CONTROL=m +CONFIG_EFI_CAPSULE_LOADER=m +CONFIG_EFI_TEST=m +# CONFIG_RESET_ATTACK_MITIGATION is not set +# end of EFI (Extensible Firmware Interface) Support + +CONFIG_EFI_EARLYCON=y + # # Tegra firmware driver # -# CONFIG_VIRTUALIZATION is not set +# end of Tegra firmware driver +# end of Firmware Drivers + +CONFIG_ARCH_SUPPORTS_ACPI=y +# CONFIG_ACPI is not set +CONFIG_HAVE_KVM_IRQCHIP=y +CONFIG_HAVE_KVM_IRQFD=y +CONFIG_HAVE_KVM_IRQ_ROUTING=y +CONFIG_HAVE_KVM_EVENTFD=y +CONFIG_KVM_MMIO=y +CONFIG_HAVE_KVM_MSI=y +CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y +CONFIG_KVM_VFIO=y +CONFIG_HAVE_KVM_ARCH_TLB_FLUSH_ALL=y +CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y +CONFIG_HAVE_KVM_IRQ_BYPASS=y +CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE=y +CONFIG_IRQ_BYPASS_MANAGER=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=y +CONFIG_KVM_ARM_HOST=y +CONFIG_KVM_ARM_PMU=y +CONFIG_KVM_INDIRECT_VECTORS=y +CONFIG_VHOST_NET=m +# CONFIG_VHOST_VSOCK is not set +CONFIG_VHOST=m +# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set CONFIG_ARM64_CRYPTO=y CONFIG_CRYPTO_SHA256_ARM64=y CONFIG_CRYPTO_SHA512_ARM64=y CONFIG_CRYPTO_SHA1_ARM64_CE=y CONFIG_CRYPTO_SHA2_ARM64_CE=y # CONFIG_CRYPTO_SHA512_ARM64_CE is not set -# CONFIG_CRYPTO_SHA3_ARM64 is not set -# CONFIG_CRYPTO_SM3_ARM64_CE is not set +CONFIG_CRYPTO_SHA3_ARM64=m +CONFIG_CRYPTO_SM3_ARM64_CE=m CONFIG_CRYPTO_SM4_ARM64_CE=m CONFIG_CRYPTO_GHASH_ARM64_CE=y # CONFIG_CRYPTO_CRCT10DIF_ARM64_CE is not set -CONFIG_CRYPTO_CRC32_ARM64_CE=y CONFIG_CRYPTO_AES_ARM64=y CONFIG_CRYPTO_AES_ARM64_CE=y CONFIG_CRYPTO_AES_ARM64_CE_CCM=y CONFIG_CRYPTO_AES_ARM64_CE_BLK=y CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y CONFIG_CRYPTO_CHACHA20_NEON=y +CONFIG_CRYPTO_NHPOLY1305_NEON=m CONFIG_CRYPTO_AES_ARM64_BS=y # # General architecture-dependent options # +CONFIG_CRASH_CORE=y +CONFIG_KEXEC_CORE=y # CONFIG_KPROBES is not set CONFIG_JUMP_LABEL=y # CONFIG_STATIC_KEYS_SELFTEST is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y CONFIG_HAVE_NMI=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_CONTIGUOUS=y CONFIG_GENERIC_SMP_IDLE_THREAD=y CONFIG_GENERIC_IDLE_POLL_SETUP=y CONFIG_ARCH_HAS_FORTIFY_SOURCE=y +CONFIG_ARCH_HAS_KEEPINITRD=y CONFIG_ARCH_HAS_SET_MEMORY=y +CONFIG_ARCH_HAS_SET_DIRECT_MAP=y CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y +CONFIG_HAVE_ASM_MODVERSIONS=y CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y CONFIG_HAVE_RSEQ=y +CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y CONFIG_HAVE_CLK=y CONFIG_HAVE_HW_BREAKPOINT=y CONFIG_HAVE_PERF_REGS=y CONFIG_HAVE_PERF_USER_STACK_DUMP=y CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y CONFIG_HAVE_RCU_TABLE_FREE=y CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y @@ -520,6 +649,7 @@ CONFIG_HAVE_CMPXCHG_DOUBLE=y CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y CONFIG_HAVE_ARCH_SECCOMP_FILTER=y CONFIG_SECCOMP_FILTER=y +CONFIG_HAVE_ARCH_STACKLEAK=y CONFIG_HAVE_STACKPROTECTOR=y CONFIG_CC_HAS_STACKPROTECTOR_NONE=y CONFIG_STACKPROTECTOR=y @@ -536,9 +666,12 @@ CONFIG_HAVE_ARCH_MMAP_RND_BITS=y CONFIG_ARCH_MMAP_RND_BITS=18 CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS=y CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 +CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y +CONFIG_HAVE_COPY_THREAD_TLS=y CONFIG_CLONE_BACKWARDS=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_COMPAT_OLD_SIGACTION=y +CONFIG_64BIT_TIME=y CONFIG_COMPAT_32BIT_TIME=y CONFIG_HAVE_ARCH_VMAP_STACK=y CONFIG_VMAP_STACK=y @@ -548,24 +681,41 @@ CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y CONFIG_STRICT_MODULE_RWX=y CONFIG_REFCOUNT_FULL=y CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y +CONFIG_ARCH_USE_MEMREMAP_PROT=y +# CONFIG_LOCK_EVENT_COUNTS is not set # # GCOV-based kernel profiling # # CONFIG_GCOV_KERNEL is not set CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +# end of GCOV-based kernel profiling + CONFIG_PLUGIN_HOSTCC="" CONFIG_HAVE_GCC_PLUGINS=y +# end of General architecture-dependent options + CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 +CONFIG_MODULE_SIG_FORMAT=y CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_MODULE_SIG is not set +CONFIG_MODULE_SIG=y +# CONFIG_MODULE_SIG_FORCE is not set +CONFIG_MODULE_SIG_ALL=y +CONFIG_MODULE_SIG_SHA1=y +# CONFIG_MODULE_SIG_SHA224 is not set +# CONFIG_MODULE_SIG_SHA256 is not set +# CONFIG_MODULE_SIG_SHA384 is not set +# CONFIG_MODULE_SIG_SHA512 is not set +CONFIG_MODULE_SIG_HASH="sha1" # CONFIG_MODULE_COMPRESS is not set +# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set +# CONFIG_UNUSED_SYMBOLS is not set # CONFIG_TRIM_UNUSED_KSYMS is not set CONFIG_MODULES_TREE_LOOKUP=y CONFIG_BLOCK=y @@ -579,7 +729,7 @@ CONFIG_BLK_DEV_THROTTLING=y # CONFIG_BLK_CMDLINE_PARSER is not set CONFIG_BLK_WBT=y # CONFIG_BLK_CGROUP_IOLATENCY is not set -CONFIG_BLK_WBT_SQ=y +# CONFIG_BLK_CGROUP_IOCOST is not set CONFIG_BLK_WBT_MQ=y # CONFIG_BLK_DEBUG_FS is not set # CONFIG_BLK_SED_OPAL is not set @@ -590,24 +740,23 @@ CONFIG_BLK_WBT_MQ=y # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y CONFIG_EFI_PARTITION=y +# end of Partition Types + CONFIG_BLOCK_COMPAT=y CONFIG_BLK_MQ_VIRTIO=y +CONFIG_BLK_PM=y # # IO Schedulers # -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_CFQ_GROUP_IOSCHED=y -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" CONFIG_MQ_IOSCHED_DEADLINE=y CONFIG_MQ_IOSCHED_KYBER=y CONFIG_IOSCHED_BFQ=y CONFIG_BFQ_GROUP_IOSCHED=y +# CONFIG_BFQ_CGROUP_DEBUG is not set +# end of IO Schedulers + +CONFIG_PREEMPT_NOTIFIERS=y CONFIG_PADATA=y CONFIG_ASN1=y CONFIG_ARCH_INLINE_SPIN_TRYLOCK=y @@ -682,6 +831,7 @@ CONFIG_ELFCORE=y CONFIG_BINFMT_SCRIPT=y CONFIG_BINFMT_MISC=y CONFIG_COREDUMP=y +# end of Executable file formats # # Memory Management options @@ -694,16 +844,19 @@ CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y CONFIG_SPARSEMEM_VMEMMAP=y -CONFIG_HAVE_MEMBLOCK=y CONFIG_HAVE_MEMBLOCK_NODE_MAP=y -CONFIG_NO_BOOTMEM=y +CONFIG_HAVE_FAST_GUP=y +CONFIG_ARCH_KEEP_MEMBLOCK=y CONFIG_MEMORY_ISOLATION=y +# CONFIG_MEMORY_HOTPLUG is not set CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MEMORY_BALLOON=y CONFIG_BALLOON_COMPACTION=y CONFIG_COMPACTION=y CONFIG_MIGRATION=y +CONFIG_CONTIG_ALLOC=y CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_MMU_NOTIFIER=y CONFIG_KSM=y CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y @@ -715,6 +868,7 @@ CONFIG_TRANSPARENT_HUGE_PAGECACHE=y CONFIG_CLEANCACHE=y CONFIG_FRONTSWAP=y CONFIG_CMA=y +# CONFIG_CMA_DEBUG is not set # CONFIG_CMA_DEBUGFS is not set CONFIG_CMA_AREAS=7 CONFIG_ZSWAP=y @@ -727,14 +881,20 @@ CONFIG_ZSMALLOC=y CONFIG_GENERIC_EARLY_IOREMAP=y # CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set CONFIG_IDLE_PAGE_TRACKING=y +CONFIG_ARCH_HAS_PTE_DEVMAP=y CONFIG_FRAME_VECTOR=y CONFIG_PERCPU_STATS=y # CONFIG_GUP_BENCHMARK is not set +# CONFIG_READ_ONLY_THP_FOR_FS is not set CONFIG_ARCH_HAS_PTE_SPECIAL=y +# end of Memory Management options + CONFIG_NET=y CONFIG_COMPAT_NETLINK_MESSAGES=y CONFIG_NET_INGRESS=y CONFIG_NET_EGRESS=y +CONFIG_NET_REDIRECT=y +CONFIG_SKB_EXTENSIONS=y # # Networking options @@ -742,20 +902,22 @@ CONFIG_NET_EGRESS=y CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y +CONFIG_UNIX_SCM=y CONFIG_UNIX_DIAG=m -CONFIG_TLS=y -# CONFIG_TLS_DEVICE is not set +CONFIG_TLS=m +CONFIG_TLS_DEVICE=y CONFIG_XFRM=y CONFIG_XFRM_OFFLOAD=y CONFIG_XFRM_ALGO=m CONFIG_XFRM_USER=m CONFIG_XFRM_INTERFACE=m -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_SUB_POLICY=y +CONFIG_XFRM_MIGRATE=y +CONFIG_XFRM_STATISTICS=y CONFIG_XFRM_IPCOMP=m CONFIG_NET_KEY=m -# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_KEY_MIGRATE=y +# CONFIG_XDP_SOCKETS is not set CONFIG_INET=y CONFIG_WIREGUARD=m # CONFIG_WIREGUARD_DEBUG is not set @@ -791,14 +953,11 @@ CONFIG_INET_ESP_OFFLOAD=m CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_TUNNEL=m CONFIG_INET_TUNNEL=m -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=m CONFIG_INET_DIAG=m CONFIG_INET_TCP_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_INET_RAW_DIAG=m -# CONFIG_INET_DIAG_DESTROY is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_TCP_CONG_ADVANCED=y CONFIG_TCP_CONG_BIC=m CONFIG_TCP_CONG_CUBIC=y @@ -815,10 +974,10 @@ CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_ILLINOIS=m CONFIG_TCP_CONG_DCTCP=m CONFIG_TCP_CONG_CDG=m -CONFIG_TCP_CONG_BBR=m -CONFIG_DEFAULT_CUBIC=y -# CONFIG_DEFAULT_RENO is not set -CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_CONG_BBR is not set +# CONFIG_DEFAULT_CUBIC is not set +CONFIG_DEFAULT_RENO=y +CONFIG_DEFAULT_TCP_CONG="reno" CONFIG_TCP_MD5SIG=y CONFIG_IPV6=y CONFIG_IPV6_ROUTER_PREF=y @@ -832,10 +991,6 @@ CONFIG_IPV6_MIP6=m CONFIG_IPV6_ILA=m CONFIG_INET6_XFRM_TUNNEL=m CONFIG_INET6_TUNNEL=m -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_VTI=m CONFIG_IPV6_SIT=m CONFIG_IPV6_SIT_6RD=y @@ -847,12 +1002,12 @@ CONFIG_IPV6_FOU_TUNNEL=m CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y -# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set -# CONFIG_IPV6_PIMSM_V2 is not set +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y CONFIG_IPV6_SEG6_LWTUNNEL=y CONFIG_IPV6_SEG6_HMAC=y CONFIG_IPV6_SEG6_BPF=y -# CONFIG_NETLABEL is not set +CONFIG_NETLABEL=y CONFIG_NETWORK_SECMARK=y CONFIG_NET_PTP_CLASSIFY=y CONFIG_NETWORK_PHY_TIMESTAMPING=y @@ -878,13 +1033,13 @@ CONFIG_NETFILTER_CONNCOUNT=m CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_ZONES=y -# CONFIG_NF_CONNTRACK_PROCFS is not set +CONFIG_NF_CONNTRACK_PROCFS=y CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CONNTRACK_TIMEOUT=y CONFIG_NF_CONNTRACK_TIMESTAMP=y CONFIG_NF_CONNTRACK_LABELS=y CONFIG_NF_CT_PROTO_DCCP=y -CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_GRE=y CONFIG_NF_CT_PROTO_SCTP=y CONFIG_NF_CT_PROTO_UDPLITE=y CONFIG_NF_CONNTRACK_AMANDA=m @@ -903,16 +1058,13 @@ CONFIG_NF_CT_NETLINK_TIMEOUT=m CONFIG_NF_CT_NETLINK_HELPER=m CONFIG_NETFILTER_NETLINK_GLUE_CT=y CONFIG_NF_NAT=m -CONFIG_NF_NAT_NEEDED=y -CONFIG_NF_NAT_PROTO_DCCP=y -CONFIG_NF_NAT_PROTO_UDPLITE=y -CONFIG_NF_NAT_PROTO_SCTP=y CONFIG_NF_NAT_AMANDA=m CONFIG_NF_NAT_FTP=m CONFIG_NF_NAT_IRC=m CONFIG_NF_NAT_SIP=m CONFIG_NF_NAT_TFTP=m CONFIG_NF_NAT_REDIRECT=y +CONFIG_NF_NAT_MASQUERADE=y CONFIG_NETFILTER_SYNPROXY=m CONFIG_NF_TABLES=m CONFIG_NF_TABLES_SET=m @@ -938,9 +1090,11 @@ CONFIG_NFT_COMPAT=m CONFIG_NFT_HASH=m CONFIG_NFT_FIB=m CONFIG_NFT_FIB_INET=m +CONFIG_NFT_XFRM=m CONFIG_NFT_SOCKET=m CONFIG_NFT_OSF=m CONFIG_NFT_TPROXY=m +CONFIG_NFT_SYNPROXY=m CONFIG_NF_DUP_NETDEV=m CONFIG_NFT_DUP_NETDEV=m CONFIG_NFT_FWD_NETDEV=m @@ -976,9 +1130,10 @@ CONFIG_NETFILTER_XT_NAT=m CONFIG_NETFILTER_XT_TARGET_NETMAP=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m CONFIG_NETFILTER_XT_TARGET_RATEEST=m CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m CONFIG_NETFILTER_XT_TARGET_TEE=m CONFIG_NETFILTER_XT_TARGET_TPROXY=m CONFIG_NETFILTER_XT_TARGET_TRACE=m @@ -1035,6 +1190,8 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m +# end of Core Netfilter Configuration + CONFIG_IP_SET=m CONFIG_IP_SET_MAX=256 CONFIG_IP_SET_BITMAP_IP=m @@ -1109,7 +1266,6 @@ CONFIG_NF_DEFRAG_IPV4=m CONFIG_NF_SOCKET_IPV4=m CONFIG_NF_TPROXY_IPV4=m CONFIG_NF_TABLES_IPV4=y -CONFIG_NFT_CHAIN_ROUTE_IPV4=m CONFIG_NFT_REJECT_IPV4=m CONFIG_NFT_DUP_IPV4=m CONFIG_NFT_FIB_IPV4=m @@ -1119,13 +1275,7 @@ CONFIG_NF_DUP_IPV4=m CONFIG_NF_LOG_ARP=m CONFIG_NF_LOG_IPV4=m CONFIG_NF_REJECT_IPV4=m -CONFIG_NF_NAT_IPV4=m -CONFIG_NF_NAT_MASQUERADE_IPV4=y -CONFIG_NFT_CHAIN_NAT_IPV4=m -CONFIG_NFT_MASQ_IPV4=m -CONFIG_NFT_REDIR_IPV4=m CONFIG_NF_NAT_SNMP_BASIC=m -CONFIG_NF_NAT_PROTO_GRE=m CONFIG_NF_NAT_PPTP=m CONFIG_NF_NAT_H323=m CONFIG_IP_NF_IPTABLES=m @@ -1149,6 +1299,7 @@ CONFIG_IP_NF_SECURITY=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m +# end of IP: Netfilter Configuration # # IPv6: Netfilter Configuration @@ -1156,10 +1307,6 @@ CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_SOCKET_IPV6=m CONFIG_NF_TPROXY_IPV6=m CONFIG_NF_TABLES_IPV6=y -CONFIG_NFT_CHAIN_ROUTE_IPV6=m -CONFIG_NFT_CHAIN_NAT_IPV6=m -CONFIG_NFT_MASQ_IPV6=m -CONFIG_NFT_REDIR_IPV6=m CONFIG_NFT_REJECT_IPV6=m CONFIG_NFT_DUP_IPV6=m CONFIG_NFT_FIB_IPV6=m @@ -1167,8 +1314,6 @@ CONFIG_NF_FLOW_TABLE_IPV6=m CONFIG_NF_DUP_IPV6=m CONFIG_NF_REJECT_IPV6=m CONFIG_NF_LOG_IPV6=m -CONFIG_NF_NAT_IPV6=m -CONFIG_NF_NAT_MASQUERADE_IPV6=y CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -1190,10 +1335,21 @@ CONFIG_IP6_NF_SECURITY=m CONFIG_IP6_NF_NAT=m CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_IP6_NF_TARGET_NPT=m +# end of IPv6: Netfilter Configuration + CONFIG_NF_DEFRAG_IPV6=m -CONFIG_NF_TABLES_BRIDGE=y + +# +# DECnet: Netfilter Configuration +# +CONFIG_DECNET_NF_GRABULATOR=m +# end of DECnet: Netfilter Configuration + +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_NFT_BRIDGE_META=m CONFIG_NFT_BRIDGE_REJECT=m CONFIG_NF_LOG_BRIDGE=m +CONFIG_NF_CONNTRACK_BRIDGE=m CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m @@ -1215,14 +1371,32 @@ CONFIG_BRIDGE_EBT_REDIRECT=m CONFIG_BRIDGE_EBT_SNAT=m CONFIG_BRIDGE_EBT_LOG=m CONFIG_BRIDGE_EBT_NFLOG=m -# CONFIG_BPFILTER is not set +CONFIG_BPFILTER=y +CONFIG_BPFILTER_UMH=m # CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_RDS is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set +CONFIG_IP_SCTP=m +CONFIG_SCTP_DBG_OBJCNT=y +CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set +CONFIG_SCTP_COOKIE_HMAC_MD5=y +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_INET_SCTP_DIAG=m +CONFIG_RDS=m +CONFIG_RDS_TCP=m +# CONFIG_RDS_DEBUG is not set +CONFIG_TIPC=m +CONFIG_TIPC_MEDIA_UDP=y +CONFIG_TIPC_DIAG=m +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +CONFIG_ATM_CLIP_NO_ICMP=y +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +CONFIG_ATM_BR2684_IPFILTER=y CONFIG_L2TP=m -# CONFIG_L2TP_DEBUGFS is not set +CONFIG_L2TP_DEBUGFS=m CONFIG_L2TP_V3=y CONFIG_L2TP_IP=m CONFIG_L2TP_ETH=m @@ -1234,17 +1408,33 @@ CONFIG_BRIDGE_IGMP_SNOOPING=y CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_HAVE_NET_DSA=y CONFIG_NET_DSA=m -CONFIG_NET_DSA_LEGACY=y +CONFIG_NET_DSA_TAG_8021Q=m +CONFIG_NET_DSA_TAG_BRCM_COMMON=m +CONFIG_NET_DSA_TAG_BRCM=m +CONFIG_NET_DSA_TAG_BRCM_PREPEND=m +CONFIG_NET_DSA_TAG_GSWIP=m +CONFIG_NET_DSA_TAG_DSA=m +CONFIG_NET_DSA_TAG_EDSA=m +CONFIG_NET_DSA_TAG_MTK=m +CONFIG_NET_DSA_TAG_KSZ=m +CONFIG_NET_DSA_TAG_QCA=m +CONFIG_NET_DSA_TAG_LAN9303=m +CONFIG_NET_DSA_TAG_SJA1105=m +CONFIG_NET_DSA_TAG_TRAILER=m CONFIG_VLAN_8021Q=y CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y -# CONFIG_DECNET is not set +CONFIG_DECNET=m +CONFIG_DECNET_ROUTER=y CONFIG_LLC=y -# CONFIG_LLC2 is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_PHONET is not set +CONFIG_LLC2=m +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +CONFIG_X25=m +CONFIG_LAPB=m +CONFIG_PHONET=m CONFIG_6LOWPAN=m # CONFIG_6LOWPAN_DEBUGFS is not set CONFIG_6LOWPAN_NHC=m @@ -1262,10 +1452,10 @@ CONFIG_6LOWPAN_NHC_UDP=m # CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG is not set # CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE is not set CONFIG_IEEE802154=m -# CONFIG_IEEE802154_NL802154_EXPERIMENTAL is not set +CONFIG_IEEE802154_NL802154_EXPERIMENTAL=y CONFIG_IEEE802154_SOCKET=m -# CONFIG_IEEE802154_6LOWPAN is not set -# CONFIG_MAC802154 is not set +CONFIG_IEEE802154_6LOWPAN=m +CONFIG_MAC802154=m CONFIG_NET_SCHED=y # @@ -1274,6 +1464,7 @@ CONFIG_NET_SCHED=y CONFIG_NET_SCH_CBQ=m CONFIG_NET_SCH_HTB=m CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m CONFIG_NET_SCH_PRIO=m CONFIG_NET_SCH_MULTIQ=m CONFIG_NET_SCH_RED=m @@ -1283,6 +1474,7 @@ CONFIG_NET_SCH_TEQL=m CONFIG_NET_SCH_TBF=m CONFIG_NET_SCH_CBS=m CONFIG_NET_SCH_ETF=m +CONFIG_NET_SCH_TAPRIO=m CONFIG_NET_SCH_GRED=m CONFIG_NET_SCH_DSMARK=m CONFIG_NET_SCH_NETEM=m @@ -1316,7 +1508,7 @@ CONFIG_NET_CLS_TCINDEX=m CONFIG_NET_CLS_ROUTE4=m CONFIG_NET_CLS_FW=m CONFIG_NET_CLS_U32=m -# CONFIG_CLS_U32_PERF is not set +CONFIG_CLS_U32_PERF=y CONFIG_CLS_U32_MARK=y CONFIG_NET_CLS_RSVP=m CONFIG_NET_CLS_RSVP6=m @@ -1347,16 +1539,19 @@ CONFIG_NET_ACT_PEDIT=m CONFIG_NET_ACT_SIMP=m CONFIG_NET_ACT_SKBEDIT=m CONFIG_NET_ACT_CSUM=m +CONFIG_NET_ACT_MPLS=m CONFIG_NET_ACT_VLAN=m CONFIG_NET_ACT_BPF=m CONFIG_NET_ACT_CONNMARK=m +CONFIG_NET_ACT_CTINFO=m CONFIG_NET_ACT_SKBMOD=m CONFIG_NET_ACT_IFE=m CONFIG_NET_ACT_TUNNEL_KEY=m +CONFIG_NET_ACT_CT=m CONFIG_NET_IFE_SKBMARK=m CONFIG_NET_IFE_SKBPRIO=m CONFIG_NET_IFE_SKBTCINDEX=m -CONFIG_NET_CLS_IND=y +# CONFIG_NET_TC_SKB_EXT is not set CONFIG_NET_SCH_FIFO=y CONFIG_DCB=y CONFIG_DNS_RESOLVER=y @@ -1368,6 +1563,7 @@ CONFIG_BATMAN_ADV_NC=y CONFIG_BATMAN_ADV_MCAST=y CONFIG_BATMAN_ADV_DEBUGFS=y CONFIG_BATMAN_ADV_DEBUG=y +CONFIG_BATMAN_ADV_SYSFS=y CONFIG_OPENVSWITCH=m CONFIG_OPENVSWITCH_GRE=m CONFIG_OPENVSWITCH_VXLAN=m @@ -1394,12 +1590,16 @@ CONFIG_CGROUP_NET_CLASSID=y CONFIG_NET_RX_BUSY_POLL=y CONFIG_BQL=y CONFIG_BPF_JIT=y +# CONFIG_BPF_STREAM_PARSER is not set CONFIG_NET_FLOW_LIMIT=y # # Network testing # -# CONFIG_NET_PKTGEN is not set +CONFIG_NET_PKTGEN=m +# end of Network testing +# end of Networking options + CONFIG_HAMRADIO=y # @@ -1419,10 +1619,13 @@ CONFIG_BPQETHER=m CONFIG_BAYCOM_SER_FDX=m CONFIG_BAYCOM_SER_HDX=m CONFIG_YAM=m +# end of AX.25 network device drivers + CONFIG_CAN=m CONFIG_CAN_RAW=m CONFIG_CAN_BCM=m CONFIG_CAN_GW=m +CONFIG_CAN_J1939=m # # CAN Device Drivers @@ -1432,6 +1635,7 @@ CONFIG_CAN_VXCAN=m CONFIG_CAN_SLCAN=m CONFIG_CAN_DEV=m CONFIG_CAN_CALC_BITTIMING=y +# CONFIG_CAN_FLEXCAN is not set CONFIG_CAN_GRCAN=m CONFIG_CAN_XILINXCAN=m CONFIG_CAN_C_CAN=m @@ -1441,6 +1645,8 @@ CONFIG_CAN_CC770_ISA=m CONFIG_CAN_CC770_PLATFORM=m # CONFIG_CAN_IFI_CANFD is not set CONFIG_CAN_M_CAN=m +CONFIG_CAN_M_CAN_PLATFORM=m +CONFIG_CAN_M_CAN_TCAN4X5X=m CONFIG_CAN_SJA1000=m CONFIG_CAN_SJA1000_ISA=m CONFIG_CAN_SJA1000_PLATFORM=m @@ -1451,6 +1657,7 @@ CONFIG_CAN_SOFTING=m # CONFIG_CAN_HI311X=m CONFIG_CAN_MCP251X=m +# end of CAN SPI interfaces # # CAN USB interfaces @@ -1463,7 +1670,11 @@ CONFIG_CAN_KVASER_USB=m CONFIG_CAN_MCBA_USB=m CONFIG_CAN_PEAK_USB=m CONFIG_CAN_UCAN=m +# end of CAN USB interfaces + # CONFIG_CAN_DEBUG_DEVICES is not set +# end of CAN Device Drivers + CONFIG_BT=m CONFIG_BT_BREDR=y CONFIG_BT_RFCOMM=m @@ -1474,8 +1685,9 @@ CONFIG_BT_BNEP_PROTO_FILTER=y CONFIG_BT_HIDP=m CONFIG_BT_HS=y CONFIG_BT_LE=y -# CONFIG_BT_6LOWPAN is not set +CONFIG_BT_6LOWPAN=m CONFIG_BT_LEDS=y +# CONFIG_BT_SELFTEST is not set CONFIG_BT_DEBUGFS=y # @@ -1488,6 +1700,7 @@ CONFIG_BT_QCA=m CONFIG_BT_HCIBTUSB=m # CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set CONFIG_BT_HCIBTUSB_BCM=y +CONFIG_BT_HCIBTUSB_MTK=y CONFIG_BT_HCIBTUSB_RTL=y CONFIG_BT_HCIBTSDIO=m CONFIG_BT_HCIUART=m @@ -1511,8 +1724,15 @@ CONFIG_BT_HCIVHCI=m CONFIG_BT_MRVL=m CONFIG_BT_MRVL_SDIO=m CONFIG_BT_ATH3K=m +CONFIG_BT_MTKSDIO=m CONFIG_BT_MTKUART=m -# CONFIG_AF_RXRPC is not set +# end of Bluetooth device drivers + +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_IPV6 is not set +# CONFIG_AF_RXRPC_INJECT_LOSS is not set +# CONFIG_AF_RXRPC_DEBUG is not set +# CONFIG_RXKAD is not set # CONFIG_AF_KCM is not set CONFIG_STREAM_PARSER=y CONFIG_FIB_RULES=y @@ -1524,6 +1744,7 @@ CONFIG_WEXT_PRIV=y CONFIG_CFG80211=m # CONFIG_NL80211_TESTMODE is not set # CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_CERTIFICATION_ONUS is not set CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y # CONFIG_CFG80211_DEFAULT_PS is not set @@ -1531,13 +1752,10 @@ CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y CONFIG_CFG80211_CRDA_SUPPORT=y CONFIG_CFG80211_WEXT=y CONFIG_LIB80211=m -CONFIG_LIB80211_CRYPT_WEP=m -CONFIG_LIB80211_CRYPT_CCMP=m # CONFIG_LIB80211_DEBUG is not set CONFIG_MAC80211=m CONFIG_MAC80211_HAS_RC=y CONFIG_MAC80211_RC_MINSTREL=y -CONFIG_MAC80211_RC_MINSTREL_HT=y CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" CONFIG_MAC80211_MESH=y @@ -1546,51 +1764,70 @@ CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_MESSAGE_TRACING is not set # CONFIG_MAC80211_DEBUG_MENU is not set CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 -# CONFIG_WIMAX is not set -CONFIG_RFKILL=y +CONFIG_WIMAX=m +CONFIG_WIMAX_DEBUG_LEVEL=8 +CONFIG_RFKILL=m CONFIG_RFKILL_LEDS=y CONFIG_RFKILL_INPUT=y -CONFIG_RFKILL_GPIO=y -CONFIG_NET_9P=y -CONFIG_NET_9P_VIRTIO=y +CONFIG_RFKILL_GPIO=m +CONFIG_NET_9P=m +CONFIG_NET_9P_VIRTIO=m +CONFIG_NET_9P_XEN=m # CONFIG_NET_9P_DEBUG is not set # CONFIG_CAIF is not set CONFIG_CEPH_LIB=m # CONFIG_CEPH_LIB_PRETTYDEBUG is not set -# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set +CONFIG_CEPH_LIB_USE_DNS_RESOLVER=y CONFIG_NFC=m -# CONFIG_NFC_DIGITAL is not set +CONFIG_NFC_DIGITAL=m CONFIG_NFC_NCI=m CONFIG_NFC_NCI_SPI=m CONFIG_NFC_NCI_UART=m -# CONFIG_NFC_HCI is not set +CONFIG_NFC_HCI=m +CONFIG_NFC_SHDLC=y # # Near Field Communication (NFC) devices # -# CONFIG_NFC_FDP is not set +CONFIG_NFC_TRF7970A=m +CONFIG_NFC_SIM=m +CONFIG_NFC_PORT100=m +CONFIG_NFC_FDP=m +CONFIG_NFC_FDP_I2C=m +CONFIG_NFC_PN544=m +CONFIG_NFC_PN544_I2C=m CONFIG_NFC_PN533=m CONFIG_NFC_PN533_USB=m CONFIG_NFC_PN533_I2C=m +CONFIG_NFC_MICROREAD=m +CONFIG_NFC_MICROREAD_I2C=m CONFIG_NFC_MRVL=m CONFIG_NFC_MRVL_USB=m CONFIG_NFC_MRVL_UART=m CONFIG_NFC_MRVL_I2C=m CONFIG_NFC_MRVL_SPI=m +CONFIG_NFC_ST21NFCA=m +CONFIG_NFC_ST21NFCA_I2C=m CONFIG_NFC_ST_NCI=m CONFIG_NFC_ST_NCI_I2C=m CONFIG_NFC_ST_NCI_SPI=m CONFIG_NFC_NXP_NCI=m CONFIG_NFC_NXP_NCI_I2C=m -# CONFIG_NFC_S3FWRN5_I2C is not set +CONFIG_NFC_S3FWRN5=m +CONFIG_NFC_S3FWRN5_I2C=m +CONFIG_NFC_ST95HF=m +# end of Near Field Communication (NFC) devices + CONFIG_PSAMPLE=m CONFIG_NET_IFE=m CONFIG_LWTUNNEL=y -# CONFIG_LWTUNNEL_BPF is not set +CONFIG_LWTUNNEL_BPF=y CONFIG_DST_CACHE=y CONFIG_GRO_CELLS=y -CONFIG_NET_DEVLINK=m -CONFIG_MAY_USE_DEVLINK=m +CONFIG_SOCK_VALIDATE_XMIT=y +CONFIG_NET_SOCK_MSG=y +CONFIG_NET_DEVLINK=y +CONFIG_PAGE_POOL=y CONFIG_FAILOVER=m CONFIG_HAVE_EBPF_JIT=y @@ -1598,6 +1835,9 @@ CONFIG_HAVE_EBPF_JIT=y # Device Drivers # CONFIG_ARM_AMBA=y +CONFIG_HAVE_PCI=y +# CONFIG_PCI is not set +# CONFIG_PCCARD is not set # # Generic Driver Options @@ -1615,57 +1855,63 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y CONFIG_EXTRA_FIRMWARE="" # CONFIG_FW_LOADER_USER_HELPER is not set +# CONFIG_FW_LOADER_COMPRESS is not set +# end of Firmware loader + CONFIG_WANT_DEV_COREDUMP=y CONFIG_ALLOW_DEV_COREDUMP=y CONFIG_DEV_COREDUMP=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set # CONFIG_TEST_ASYNC_DRIVER_PROBE is not set +CONFIG_SYS_HYPERVISOR=y CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_CPU_VULNERABILITIES=y +CONFIG_SOC_BUS=y CONFIG_REGMAP=y CONFIG_REGMAP_I2C=y CONFIG_REGMAP_SPI=y +CONFIG_REGMAP_SPMI=m CONFIG_REGMAP_W1=m CONFIG_REGMAP_MMIO=y CONFIG_REGMAP_IRQ=y +CONFIG_REGMAP_SCCB=m CONFIG_DMA_SHARED_BUFFER=y # CONFIG_DMA_FENCE_TRACE is not set -CONFIG_DMA_CMA=y - -# -# Default contiguous memory area size: -# -CONFIG_CMA_SIZE_MBYTES=128 -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_ALIGNMENT=8 CONFIG_GENERIC_ARCH_TOPOLOGY=y +# end of Generic Driver Options # # Bus devices # CONFIG_ARM_CCI=y -# CONFIG_BRCMSTB_GISB_ARB is not set +CONFIG_BRCMSTB_GISB_ARB=y +# CONFIG_MOXTET is not set # CONFIG_SIMPLE_PM_BUS is not set CONFIG_SUN50I_DE2_BUS=y CONFIG_SUNXI_RSB=y # CONFIG_VEXPRESS_CONFIG is not set +# end of Bus devices + CONFIG_CONNECTOR=m CONFIG_GNSS=m CONFIG_GNSS_SERIAL=m +CONFIG_GNSS_MTK_SERIAL=m CONFIG_GNSS_SIRF_SERIAL=m CONFIG_GNSS_UBX_SERIAL=m CONFIG_MTD=y # CONFIG_MTD_TESTS is not set -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set -# CONFIG_MTD_AFS_PARTS is not set -CONFIG_MTD_OF_PARTS=y -# CONFIG_MTD_AR7_PARTS is not set # # Partition parsers # +# CONFIG_MTD_AR7_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# end of Partition parsers # # User Modules And Translation Layers @@ -1694,27 +1940,27 @@ CONFIG_MTD_MAP_BANK_WIDTH_2=y CONFIG_MTD_MAP_BANK_WIDTH_4=y CONFIG_MTD_CFI_I1=y CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_INTELEXT is not set -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_STAA=m CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set +# end of RAM/ROM/Flash chip drivers # # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set # CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_PHYSMAP_OF is not set # CONFIG_MTD_PLATRAM is not set +# end of Mapping drivers for chip access # # Self-contained MTD device drivers # # CONFIG_MTD_DATAFLASH is not set -CONFIG_MTD_M25P80=y # CONFIG_MTD_MCHP23K256 is not set # CONFIG_MTD_SST25L is not set # CONFIG_MTD_SLRAM is not set @@ -1726,20 +1972,48 @@ CONFIG_MTD_M25P80=y # Disk-On-Chip Device Drivers # # CONFIG_MTD_DOCG3 is not set +# end of Self-contained MTD device drivers + CONFIG_MTD_NAND_CORE=m # CONFIG_MTD_ONENAND is not set -# CONFIG_MTD_NAND is not set +CONFIG_MTD_NAND_ECC_SW_HAMMING=m +# CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC is not set +CONFIG_MTD_RAW_NAND=m +# CONFIG_MTD_NAND_ECC_SW_BCH is not set + +# +# Raw/parallel NAND flash controllers +# +CONFIG_MTD_NAND_DENALI=m +CONFIG_MTD_NAND_DENALI_DT=m +CONFIG_MTD_NAND_BRCMNAND=m +CONFIG_MTD_NAND_SUNXI=m +CONFIG_MTD_NAND_MXIC=m +CONFIG_MTD_NAND_GPIO=m +CONFIG_MTD_NAND_PLATFORM=m + +# +# Misc +# +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set CONFIG_MTD_SPI_NAND=m # # LPDDR & LPDDR2 PCM memory drivers # # CONFIG_MTD_LPDDR is not set +# end of LPDDR & LPDDR2 PCM memory drivers + CONFIG_MTD_SPI_NOR=y -# CONFIG_MTD_MT81xx_NOR is not set CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y # CONFIG_SPI_CADENCE_QUADSPI is not set +CONFIG_SPI_MTK_QUADSPI=m # CONFIG_MTD_UBI is not set +# CONFIG_MTD_HYPERBUS is not set CONFIG_DTC=y CONFIG_OF=y # CONFIG_OF_UNITTEST is not set @@ -1765,15 +2039,17 @@ CONFIG_ZRAM_WRITEBACK=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 CONFIG_BLK_DEV_CRYPTOLOOP=m -# CONFIG_BLK_DEV_DRBD is not set -# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_DRBD=m +# CONFIG_DRBD_FAULT_INJECTION is not set +CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=m CONFIG_BLK_DEV_RAM_COUNT=8 CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_CDROM_PKTCDVD is not set CONFIG_ATA_OVER_ETH=m -CONFIG_VIRTIO_BLK=m -# CONFIG_VIRTIO_BLK_SCSI is not set +CONFIG_XEN_BLKDEV_FRONTEND=m +CONFIG_XEN_BLKDEV_BACKEND=m +# CONFIG_VIRTIO_BLK is not set CONFIG_BLK_DEV_RBD=m # @@ -1781,6 +2057,7 @@ CONFIG_BLK_DEV_RBD=m # # CONFIG_NVME_FC is not set # CONFIG_NVME_TARGET is not set +# end of NVME Support # # Misc devices @@ -1797,10 +2074,10 @@ CONFIG_BLK_DEV_RBD=m # CONFIG_SENSORS_APDS990X is not set # CONFIG_HMC6352 is not set # CONFIG_DS1682 is not set -# CONFIG_USB_SWITCH_FSA9480 is not set # CONFIG_LATTICE_ECP3_CONFIG is not set # CONFIG_SRAM is not set -CONFIG_MISC_RTSX=m +# CONFIG_XILINX_SDFEC is not set +CONFIG_PVPANIC=m # CONFIG_C2PORT is not set # @@ -1813,11 +2090,15 @@ CONFIG_EEPROM_LEGACY=m CONFIG_EEPROM_93CX6=m # CONFIG_EEPROM_93XX46 is not set # CONFIG_EEPROM_IDT_89HPESX is not set +CONFIG_EEPROM_EE1004=m +# end of EEPROM support # # Texas Instruments shared transport line discipline # # CONFIG_TI_ST is not set +# end of Texas Instruments shared transport line discipline + # CONFIG_SENSORS_LIS3_SPI is not set # CONFIG_SENSORS_LIS3_I2C is not set # CONFIG_ALTERA_STAPL is not set @@ -1837,6 +2118,7 @@ CONFIG_EEPROM_93CX6=m # # VOP Bus Driver # +# CONFIG_VOP_BUS is not set # # Intel MIC Host Driver @@ -1857,8 +2139,11 @@ CONFIG_EEPROM_93CX6=m # # VOP Driver # +# end of Intel MIC & related support + # CONFIG_ECHO is not set -CONFIG_MISC_RTSX_USB=m +# CONFIG_MISC_RTSX_USB is not set +# end of Misc devices # # SCSI device support @@ -1867,7 +2152,6 @@ CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y -# CONFIG_SCSI_MQ_DEFAULT is not set # CONFIG_SCSI_PROC_FS is not set # @@ -1875,7 +2159,6 @@ CONFIG_SCSI_DMA=y # CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set # CONFIG_BLK_DEV_SR is not set CONFIG_CHR_DEV_SG=y # CONFIG_CHR_DEV_SCH is not set @@ -1892,16 +2175,21 @@ CONFIG_SCSI_ISCSI_ATTRS=m CONFIG_SCSI_SAS_ATTRS=m # CONFIG_SCSI_SAS_LIBSAS is not set CONFIG_SCSI_SRP_ATTRS=m +# end of SCSI Transports + CONFIG_SCSI_LOWLEVEL=y CONFIG_ISCSI_TCP=m CONFIG_ISCSI_BOOT_SYSFS=m # CONFIG_SCSI_HISI_SAS is not set -# CONFIG_SCSI_UFSHCD is not set +CONFIG_SCSI_UFSHCD=m +# CONFIG_SCSI_UFSHCD_PLATFORM is not set +# CONFIG_SCSI_UFS_BSG is not set +CONFIG_XEN_SCSI_FRONTEND=m # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_VIRTIO is not set -# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set # CONFIG_SCSI_DH is not set -# CONFIG_SCSI_OSD_INITIATOR is not set +# end of SCSI device support + CONFIG_HAVE_PATA_PLATFORM=y CONFIG_ATA=m # CONFIG_ATA_VERBOSE_ERROR is not set @@ -1924,13 +2212,13 @@ CONFIG_MD_RAID10=m CONFIG_MD_RAID456=m CONFIG_MD_MULTIPATH=m CONFIG_MD_FAULTY=m -CONFIG_BCACHE=m +CONFIG_MD_CLUSTER=m +CONFIG_BCACHE=y # CONFIG_BCACHE_DEBUG is not set # CONFIG_BCACHE_CLOSURES_DEBUG is not set CONFIG_BLK_DEV_DM_BUILTIN=y CONFIG_BLK_DEV_DM=m -# CONFIG_DM_MQ_DEFAULT is not set -# CONFIG_DM_DEBUG is not set +CONFIG_DM_DEBUG=y CONFIG_DM_BUFIO=m # CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING is not set CONFIG_DM_BIO_PRISON=m @@ -1943,6 +2231,7 @@ CONFIG_DM_CACHE=m CONFIG_DM_CACHE_SMQ=m CONFIG_DM_WRITECACHE=m CONFIG_DM_ERA=m +CONFIG_DM_CLONE=m CONFIG_DM_MIRROR=m CONFIG_DM_LOG_USERSPACE=m CONFIG_DM_RAID=m @@ -1951,20 +2240,17 @@ CONFIG_DM_MULTIPATH=m CONFIG_DM_MULTIPATH_QL=m CONFIG_DM_MULTIPATH_ST=m CONFIG_DM_DELAY=m -# CONFIG_DM_UEVENT is not set +CONFIG_DM_DUST=m +CONFIG_DM_UEVENT=y CONFIG_DM_FLAKEY=m CONFIG_DM_VERITY=m -# CONFIG_DM_VERITY_FEC is not set +# CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG is not set +CONFIG_DM_VERITY_FEC=y CONFIG_DM_SWITCH=m CONFIG_DM_LOG_WRITES=m CONFIG_DM_INTEGRITY=m CONFIG_DM_ZONED=m -CONFIG_TARGET_CORE=m -CONFIG_TCM_IBLOCK=m -CONFIG_TCM_FILEIO=m -CONFIG_TCM_PSCSI=m -CONFIG_LOOPBACK_TARGET=m -CONFIG_ISCSI_TARGET=m +# CONFIG_TARGET_CORE is not set CONFIG_NETDEVICES=y CONFIG_MII=y CONFIG_NET_CORE=y @@ -1980,6 +2266,7 @@ CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m CONFIG_NET_TEAM_MODE_LOADBALANCE=m CONFIG_MACVLAN=m CONFIG_MACVTAP=m +CONFIG_IPVLAN_L3S=y CONFIG_IPVLAN=m CONFIG_IPVTAP=m CONFIG_VXLAN=m @@ -1987,16 +2274,19 @@ CONFIG_GENEVE=m CONFIG_GTP=m CONFIG_MACSEC=m CONFIG_NETCONSOLE=m -# CONFIG_NETCONSOLE_DYNAMIC is not set +CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_NETPOLL=y CONFIG_NET_POLL_CONTROLLER=y -CONFIG_TUN=m +CONFIG_TUN=y CONFIG_TAP=m -# CONFIG_TUN_VNET_CROSS_LE is not set +CONFIG_TUN_VNET_CROSS_LE=y CONFIG_VETH=m CONFIG_VIRTIO_NET=m CONFIG_NLMON=m -# CONFIG_NET_VRF is not set +CONFIG_NET_VRF=m +CONFIG_ATM_DRIVERS=y +CONFIG_ATM_DUMMY=m +CONFIG_ATM_TCP=m # # CAIF transport drivers @@ -2005,18 +2295,39 @@ CONFIG_NLMON=m # # Distributed Switch Architecture drivers # -# CONFIG_B53 is not set -# CONFIG_NET_DSA_BCM_SF2 is not set -# CONFIG_NET_DSA_LOOP is not set -# CONFIG_NET_DSA_MT7530 is not set -# CONFIG_NET_DSA_MV88E6060 is not set -# CONFIG_MICROCHIP_KSZ is not set -# CONFIG_NET_DSA_MV88E6XXX is not set -# CONFIG_NET_DSA_QCA8K is not set +CONFIG_B53=m +CONFIG_B53_SPI_DRIVER=m +CONFIG_B53_MDIO_DRIVER=m +CONFIG_B53_MMAP_DRIVER=m +CONFIG_B53_SRAB_DRIVER=m +CONFIG_B53_SERDES=m +CONFIG_NET_DSA_BCM_SF2=m +CONFIG_NET_DSA_LOOP=m +CONFIG_NET_DSA_LANTIQ_GSWIP=m +CONFIG_NET_DSA_MT7530=m +CONFIG_NET_DSA_MV88E6060=m +CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON=m +CONFIG_NET_DSA_MICROCHIP_KSZ9477=m +CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C=m +CONFIG_NET_DSA_MICROCHIP_KSZ9477_SPI=m +CONFIG_NET_DSA_MICROCHIP_KSZ8795=m +CONFIG_NET_DSA_MICROCHIP_KSZ8795_SPI=m +CONFIG_NET_DSA_MV88E6XXX=m +CONFIG_NET_DSA_MV88E6XXX_GLOBAL2=y +# CONFIG_NET_DSA_MV88E6XXX_PTP is not set +CONFIG_NET_DSA_SJA1105=m +# CONFIG_NET_DSA_SJA1105_PTP is not set +# CONFIG_NET_DSA_SJA1105_TAS is not set +CONFIG_NET_DSA_QCA8K=m CONFIG_NET_DSA_REALTEK_SMI=m -# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set -# CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set +CONFIG_NET_DSA_SMSC_LAN9303=m +CONFIG_NET_DSA_SMSC_LAN9303_I2C=m +CONFIG_NET_DSA_SMSC_LAN9303_MDIO=m CONFIG_NET_DSA_VITESSE_VSC73XX=m +CONFIG_NET_DSA_VITESSE_VSC73XX_SPI=m +CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM=m +# end of Distributed Switch Architecture drivers + CONFIG_ETHERNET=y CONFIG_NET_VENDOR_ALACRITECH=y CONFIG_NET_VENDOR_ALLWINNER=y @@ -2038,10 +2349,12 @@ CONFIG_NET_VENDOR_CORTINA=y # CONFIG_DNET is not set CONFIG_NET_VENDOR_EZCHIP=y # CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set +CONFIG_NET_VENDOR_GOOGLE=y CONFIG_NET_VENDOR_HISILICON=y # CONFIG_HIX5HD2_GMAC is not set # CONFIG_HISI_FEMAC is not set CONFIG_HIP04_ETH=m +# CONFIG_HI13X1_GMAC is not set CONFIG_HNS_MDIO=m # CONFIG_HNS is not set # CONFIG_HNS_DSAF is not set @@ -2052,7 +2365,10 @@ CONFIG_NET_VENDOR_HUAWEI=y CONFIG_NET_VENDOR_MELLANOX=y # CONFIG_MLXSW_CORE is not set # CONFIG_MLXFW is not set -# CONFIG_NET_VENDOR_MICREL is not set +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set CONFIG_NET_VENDOR_MICROCHIP=y CONFIG_ENC28J60=m CONFIG_ENC28J60_WRITEVERIFY=y @@ -2062,12 +2378,14 @@ CONFIG_NET_VENDOR_MICROSEMI=y # CONFIG_NET_VENDOR_NATSEMI is not set CONFIG_NET_VENDOR_NETRONOME=y CONFIG_NET_VENDOR_NI=y +CONFIG_NI_XGE_MANAGEMENT_ENET=m # CONFIG_ETHOC is not set +CONFIG_NET_VENDOR_PENSANDO=y CONFIG_NET_VENDOR_QUALCOMM=y CONFIG_QCA7000=m # CONFIG_QCA7000_SPI is not set CONFIG_QCA7000_UART=m -# CONFIG_QCOM_EMAC is not set +CONFIG_QCOM_EMAC=m # CONFIG_RMNET is not set CONFIG_NET_VENDOR_RENESAS=y CONFIG_NET_VENDOR_ROCKER=y @@ -2078,28 +2396,31 @@ CONFIG_NET_VENDOR_SOLARFLARE=y CONFIG_NET_VENDOR_SOCIONEXT=y CONFIG_NET_VENDOR_STMICRO=y CONFIG_STMMAC_ETH=y +# CONFIG_STMMAC_SELFTESTS is not set CONFIG_STMMAC_PLATFORM=y CONFIG_DWMAC_DWC_QOS_ETH=m CONFIG_DWMAC_GENERIC=y -CONFIG_DWMAC_SUNXI=y -CONFIG_DWMAC_SUN8I=y +CONFIG_DWMAC_SUNXI=m +CONFIG_DWMAC_SUN8I=m CONFIG_NET_VENDOR_SYNOPSYS=y # CONFIG_DWC_XLGMAC is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set CONFIG_MDIO_DEVICE=y CONFIG_MDIO_BUS=y -# CONFIG_MDIO_BCM_UNIMAC is not set +CONFIG_MDIO_BCM_UNIMAC=m CONFIG_MDIO_BITBANG=y -CONFIG_MDIO_BUS_MUX=y +CONFIG_MDIO_BUS_MUX=m # CONFIG_MDIO_BUS_MUX_GPIO is not set # CONFIG_MDIO_BUS_MUX_MMIOREG is not set +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m # CONFIG_MDIO_GPIO is not set # CONFIG_MDIO_HISI_FEMAC is not set +CONFIG_MDIO_I2C=m CONFIG_MDIO_MSCC_MIIM=m # CONFIG_MDIO_OCTEON is not set CONFIG_MDIO_SUN4I=y -CONFIG_PHYLINK=m +CONFIG_PHYLINK=y CONFIG_PHYLIB=y CONFIG_SWPHY=y CONFIG_LED_TRIGGER_PHY=y @@ -2107,12 +2428,14 @@ CONFIG_LED_TRIGGER_PHY=y # # MII PHY device drivers # -# CONFIG_SFP is not set +CONFIG_SFP=m +CONFIG_ADIN_PHY=m +CONFIG_AC200_PHY=m CONFIG_AMD_PHY=m CONFIG_AQUANTIA_PHY=m CONFIG_AX88796B_PHY=m CONFIG_AT803X_PHY=m -# CONFIG_BCM7XXX_PHY is not set +CONFIG_BCM7XXX_PHY=m CONFIG_BCM87XX_PHY=m CONFIG_BCM_NET_PHYLIB=m CONFIG_BROADCOM_PHY=m @@ -2129,19 +2452,20 @@ CONFIG_ICPLUS_PHY=m CONFIG_LSI_ET1011C_PHY=m CONFIG_LXT_PHY=m CONFIG_MARVELL_PHY=m -# CONFIG_MARVELL_10G_PHY is not set -CONFIG_MICREL_PHY=m +CONFIG_MARVELL_10G_PHY=m +CONFIG_MICREL_PHY=y CONFIG_MICROCHIP_PHY=m CONFIG_MICROCHIP_T1_PHY=m # CONFIG_MICROSEMI_PHY is not set CONFIG_NATIONAL_PHY=m +# CONFIG_NXP_TJA11XX_PHY is not set CONFIG_QSEMI_PHY=m CONFIG_REALTEK_PHY=m # CONFIG_RENESAS_PHY is not set -# CONFIG_ROCKCHIP_PHY is not set -CONFIG_SMSC_PHY=m -CONFIG_STE10XP=m -CONFIG_TERANETICS_PHY=m +CONFIG_ROCKCHIP_PHY=y +# CONFIG_SMSC_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_TERANETICS_PHY is not set CONFIG_VITESSE_PHY=m # CONFIG_XILINX_GMII2RGMII is not set # CONFIG_MICREL_KS8995MA is not set @@ -2151,6 +2475,7 @@ CONFIG_PPP_DEFLATE=m CONFIG_PPP_FILTER=y CONFIG_PPP_MPPE=m CONFIG_PPP_MULTILINK=y +CONFIG_PPPOATM=m CONFIG_PPPOE=m CONFIG_PPTP=m CONFIG_PPPOL2TP=m @@ -2161,7 +2486,7 @@ CONFIG_SLHC=m CONFIG_SLIP_COMPRESSED=y CONFIG_SLIP_SMART=y CONFIG_SLIP_MODE_SLIP6=y -CONFIG_USB_NET_DRIVERS=m +CONFIG_USB_NET_DRIVERS=y CONFIG_USB_CATC=m CONFIG_USB_KAWETH=m CONFIG_USB_PEGASUS=m @@ -2200,13 +2525,15 @@ CONFIG_USB_NET_KALMIA=m CONFIG_USB_NET_QMI_WWAN=m CONFIG_USB_HSO=m CONFIG_USB_NET_INT51X1=m +CONFIG_USB_CDC_PHONET=m CONFIG_USB_IPHETH=m CONFIG_USB_SIERRA_NET=m CONFIG_USB_VL600=m CONFIG_USB_NET_CH9200=m +CONFIG_USB_NET_AQC111=m CONFIG_WLAN=y -CONFIG_WLAN_VENDOR_ADMTEK=y -CONFIG_RTL8189ES=m +CONFIG_WIRELESS_WDS=y +# CONFIG_WLAN_VENDOR_ADMTEK is not set CONFIG_ATH_COMMON=m CONFIG_WLAN_VENDOR_ATH=y # CONFIG_ATH_DEBUG is not set @@ -2223,9 +2550,11 @@ CONFIG_ATH9K_RFKILL=y CONFIG_ATH9K_PCOEM=y CONFIG_ATH9K_HTC=m # CONFIG_ATH9K_HTC_DEBUGFS is not set +# CONFIG_ATH9K_HWRNG is not set CONFIG_CARL9170=m CONFIG_CARL9170_LEDS=y CONFIG_CARL9170_WPC=y +# CONFIG_CARL9170_HWRNG is not set # CONFIG_ATH6KL is not set CONFIG_AR5523=m CONFIG_ATH10K=m @@ -2251,9 +2580,11 @@ CONFIG_B43_PHY_N=y CONFIG_B43_PHY_LP=y CONFIG_B43_PHY_HT=y CONFIG_B43_LEDS=y +CONFIG_B43_HWRNG=y # CONFIG_B43_DEBUG is not set CONFIG_B43LEGACY=m CONFIG_B43LEGACY_LEDS=y +CONFIG_B43LEGACY_HWRNG=y CONFIG_B43LEGACY_DEBUG=y CONFIG_B43LEGACY_DMA=y CONFIG_B43LEGACY_PIO=y @@ -2268,24 +2599,20 @@ CONFIG_BRCMFMAC_SDIO=y # CONFIG_BRCMFMAC_USB is not set # CONFIG_BRCM_TRACING is not set # CONFIG_BRCMDBG is not set -CONFIG_WLAN_VENDOR_CISCO=y -CONFIG_WLAN_VENDOR_INTEL=y -CONFIG_WLAN_VENDOR_INTERSIL=y -# CONFIG_HOSTAP is not set -# CONFIG_P54_COMMON is not set -CONFIG_WLAN_VENDOR_MARVELL=y -# CONFIG_LIBERTAS is not set -CONFIG_LIBERTAS_THINFIRM=m -# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set -CONFIG_LIBERTAS_THINFIRM_USB=m -# CONFIG_MWIFIEX is not set +# CONFIG_WLAN_VENDOR_CISCO 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=y CONFIG_MT7601U=m CONFIG_MT76_CORE=m CONFIG_MT76_LEDS=y CONFIG_MT76_USB=m -CONFIG_MT76x2_COMMON=m +CONFIG_MT76x02_LIB=m +CONFIG_MT76x02_USB=m +CONFIG_MT76x0_COMMON=m CONFIG_MT76x0U=m +CONFIG_MT76x2_COMMON=m CONFIG_MT76x2U=m CONFIG_WLAN_VENDOR_RALINK=y CONFIG_RT2X00=m @@ -2297,7 +2624,7 @@ CONFIG_RT2800USB_RT35XX=y CONFIG_RT2800USB_RT3573=y CONFIG_RT2800USB_RT53XX=y CONFIG_RT2800USB_RT55XX=y -CONFIG_RT2800USB_UNKNOWN=y +# CONFIG_RT2800USB_UNKNOWN is not set CONFIG_RT2800_LIB=m CONFIG_RT2X00_LIB_USB=m CONFIG_RT2X00_LIB=m @@ -2308,7 +2635,6 @@ CONFIG_RT2X00_LIB_LEDS=y CONFIG_WLAN_VENDOR_REALTEK=y CONFIG_RTL8187=m CONFIG_RTL8187_LEDS=y -CONFIG_RTL8189FS=m CONFIG_RTL_CARDS=m CONFIG_RTL8192CU=m CONFIG_RTLWIFI=m @@ -2318,26 +2644,55 @@ CONFIG_RTL8192C_COMMON=m CONFIG_RTL8XXXU=m CONFIG_RTL8XXXU_UNTESTED=y CONFIG_RTL8723CS=m +CONFIG_RTW88=m # CONFIG_WLAN_VENDOR_RSI is not set # CONFIG_WLAN_VENDOR_ST is not set # CONFIG_WLAN_VENDOR_TI is not set +CONFIG_RTL8723DU=m +CONFIG_RTL8723DS=m CONFIG_RTL8822BU=m CONFIG_RTL8188EU=m -CONFIG_RTL8812AU=m +CONFIG_RTL8821CU=m # CONFIG_WLAN_VENDOR_XRADIO is not set -# CONFIG_WLAN_VENDOR_ZYDAS is not set +CONFIG_88XXAU=m +CONFIG_RTL8189FS=m +CONFIG_RTL8189ES=m +CONFIG_WLAN_VENDOR_ZYDAS=y +CONFIG_USB_ZD1201=m +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set CONFIG_WLAN_VENDOR_QUANTENNA=y # CONFIG_MAC80211_HWSIM is not set CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_VIRT_WIFI=m # -# Enable WiMAX (Networking options) to see the WiMAX drivers +# WiMAX Wireless Broadband devices # +CONFIG_WIMAX_I2400M=m +CONFIG_WIMAX_I2400M_USB=m +CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8 +# end of WiMAX Wireless Broadband devices + # CONFIG_WAN is not set CONFIG_IEEE802154_DRIVERS=m +CONFIG_IEEE802154_FAKELB=m +CONFIG_IEEE802154_AT86RF230=m +# CONFIG_IEEE802154_AT86RF230_DEBUGFS is not set +CONFIG_IEEE802154_MRF24J40=m +CONFIG_IEEE802154_CC2520=m +CONFIG_IEEE802154_ATUSB=m +CONFIG_IEEE802154_ADF7242=m +CONFIG_IEEE802154_CA8210=m +# CONFIG_IEEE802154_CA8210_DEBUGFS is not set +CONFIG_IEEE802154_MCR20A=m +CONFIG_IEEE802154_HWSIM=m +CONFIG_XEN_NETDEV_FRONTEND=m +CONFIG_XEN_NETDEV_BACKEND=m CONFIG_NETDEVSIM=m CONFIG_NET_FAILOVER=m # CONFIG_ISDN is not set +# CONFIG_NVM is not set # # Input device support @@ -2364,10 +2719,12 @@ CONFIG_INPUT_EVDEV=y # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y -# CONFIG_KEYBOARD_ADC is not set +CONFIG_KEYBOARD_ADC=m +CONFIG_KEYBOARD_ADP5520=m # CONFIG_KEYBOARD_ADP5588 is not set # CONFIG_KEYBOARD_ADP5589 is not set CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_QT1050=m # CONFIG_KEYBOARD_QT1070 is not set # CONFIG_KEYBOARD_QT2160 is not set # CONFIG_KEYBOARD_DLINK_DIR685 is not set @@ -2376,7 +2733,7 @@ CONFIG_KEYBOARD_GPIO=y # CONFIG_KEYBOARD_GPIO_POLLED is not set # CONFIG_KEYBOARD_TCA6416 is not set # CONFIG_KEYBOARD_TCA8418 is not set -CONFIG_KEYBOARD_MATRIX=m +# CONFIG_KEYBOARD_MATRIX is not set # CONFIG_KEYBOARD_LM8323 is not set # CONFIG_KEYBOARD_LM8333 is not set # CONFIG_KEYBOARD_MAX7359 is not set @@ -2387,12 +2744,14 @@ CONFIG_KEYBOARD_MATRIX=m # CONFIG_KEYBOARD_SAMSUNG is not set # CONFIG_KEYBOARD_STOWAWAY is not set # CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_SUN4I_LRADC is not set +CONFIG_KEYBOARD_SUN4I_LRADC=m # CONFIG_KEYBOARD_OMAP4 is not set # CONFIG_KEYBOARD_TM2_TOUCHKEY is not set +CONFIG_KEYBOARD_TWL4030=m # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_CAP11XX is not set # CONFIG_KEYBOARD_BCM is not set +CONFIG_KEYBOARD_MTK_PMIC=m CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y CONFIG_MOUSE_PS2_ALPS=y @@ -2420,6 +2779,7 @@ CONFIG_MOUSE_PS2_SMBUS=y # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_PROPERTIES=y +CONFIG_TOUCHSCREEN_88PM860X=m CONFIG_TOUCHSCREEN_ADS7846=m CONFIG_TOUCHSCREEN_AD7877=m CONFIG_TOUCHSCREEN_AD7879=m @@ -2428,31 +2788,33 @@ CONFIG_TOUCHSCREEN_AD7879_SPI=m CONFIG_TOUCHSCREEN_ADC=m CONFIG_TOUCHSCREEN_AR1021_I2C=m CONFIG_TOUCHSCREEN_ATMEL_MXT=m -# CONFIG_TOUCHSCREEN_ATMEL_MXT_T37 is not set -# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set -# CONFIG_TOUCHSCREEN_BU21013 is not set +CONFIG_TOUCHSCREEN_ATMEL_MXT_T37=y +CONFIG_TOUCHSCREEN_AUO_PIXCIR=m +CONFIG_TOUCHSCREEN_BU21013=m CONFIG_TOUCHSCREEN_BU21029=m # CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set # CONFIG_TOUCHSCREEN_CY8CTMG110 is not set # CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set # CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set +CONFIG_TOUCHSCREEN_DA9034=m +CONFIG_TOUCHSCREEN_DA9052=m # CONFIG_TOUCHSCREEN_DYNAPRO is not set # CONFIG_TOUCHSCREEN_HAMPSHIRE is not set # CONFIG_TOUCHSCREEN_EETI is not set # CONFIG_TOUCHSCREEN_EGALAX is not set # CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set CONFIG_TOUCHSCREEN_EXC3000=m -# CONFIG_TOUCHSCREEN_FUJITSU is not set +CONFIG_TOUCHSCREEN_FUJITSU=m CONFIG_TOUCHSCREEN_GOODIX=m CONFIG_TOUCHSCREEN_HIDEEP=m CONFIG_TOUCHSCREEN_ILI210X=m CONFIG_TOUCHSCREEN_S6SY761=m -# CONFIG_TOUCHSCREEN_GUNZE is not set -# CONFIG_TOUCHSCREEN_EKTF2127 is not set -# CONFIG_TOUCHSCREEN_ELAN is not set -# CONFIG_TOUCHSCREEN_ELO is not set -# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set -# CONFIG_TOUCHSCREEN_WACOM_I2C is not set +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_EKTF2127=m +CONFIG_TOUCHSCREEN_ELAN=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_WACOM_W8001=m +CONFIG_TOUCHSCREEN_WACOM_I2C=m CONFIG_TOUCHSCREEN_MAX11801=m # CONFIG_TOUCHSCREEN_MCS5000 is not set # CONFIG_TOUCHSCREEN_MMS114 is not set @@ -2465,9 +2827,17 @@ CONFIG_TOUCHSCREEN_MAX11801=m # CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set +CONFIG_TOUCHSCREEN_TI_AM335X_TSC=m +CONFIG_TOUCHSCREEN_UCB1400=m # CONFIG_TOUCHSCREEN_PIXCIR is not set # CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set +CONFIG_TOUCHSCREEN_WM831X=m +CONFIG_TOUCHSCREEN_WM97XX=m +CONFIG_TOUCHSCREEN_WM9705=y +CONFIG_TOUCHSCREEN_WM9712=y +CONFIG_TOUCHSCREEN_WM9713=y CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_MC13783=m CONFIG_TOUCHSCREEN_USB_EGALAX=y CONFIG_TOUCHSCREEN_USB_PANJIT=y CONFIG_TOUCHSCREEN_USB_3M=y @@ -2491,6 +2861,7 @@ CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y # CONFIG_TOUCHSCREEN_TSC2004 is not set # CONFIG_TOUCHSCREEN_TSC2005 is not set # CONFIG_TOUCHSCREEN_TSC2007 is not set +CONFIG_TOUCHSCREEN_PCAP=m # CONFIG_TOUCHSCREEN_RM_TS is not set CONFIG_TOUCHSCREEN_SILEAD=m # CONFIG_TOUCHSCREEN_SIS_I2C is not set @@ -2504,15 +2875,27 @@ CONFIG_TOUCHSCREEN_SILEAD=m # CONFIG_TOUCHSCREEN_ZET6223 is not set # CONFIG_TOUCHSCREEN_ZFORCE is not set # CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set +CONFIG_TOUCHSCREEN_IQS5XX=m CONFIG_INPUT_MISC=y +CONFIG_INPUT_88PM860X_ONKEY=m +CONFIG_INPUT_88PM80X_ONKEY=m # CONFIG_INPUT_AD714X is not set +CONFIG_INPUT_ARIZONA_HAPTICS=m # CONFIG_INPUT_ATMEL_CAPTOUCH is not set # CONFIG_INPUT_BMA150 is not set # CONFIG_INPUT_E3X0_BUTTON is not set +CONFIG_INPUT_MSM_VIBRATOR=m +CONFIG_INPUT_MAX77650_ONKEY=m +CONFIG_INPUT_MAX77693_HAPTIC=m +CONFIG_INPUT_MAX8925_ONKEY=m +CONFIG_INPUT_MAX8997_HAPTIC=m +CONFIG_INPUT_MC13783_PWRBUTTON=m # CONFIG_INPUT_MMA8450 is not set # CONFIG_INPUT_GP2A is not set # CONFIG_INPUT_GPIO_BEEPER is not set CONFIG_INPUT_GPIO_DECODER=m +CONFIG_INPUT_GPIO_VIBRA=m +CONFIG_INPUT_CPCAP_PWRBUTTON=m # CONFIG_INPUT_ATI_REMOTE2 is not set # CONFIG_INPUT_KEYSPAN_REMOTE is not set # CONFIG_INPUT_KXTJ9 is not set @@ -2520,16 +2903,29 @@ CONFIG_INPUT_GPIO_DECODER=m # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_CM109 is not set # CONFIG_INPUT_REGULATOR_HAPTIC is not set +CONFIG_INPUT_RETU_PWRBUTTON=m +CONFIG_INPUT_TPS65218_PWRBUTTON=m CONFIG_INPUT_AXP20X_PEK=y +CONFIG_INPUT_TWL4030_PWRBUTTON=m +CONFIG_INPUT_TWL4030_VIBRA=m +CONFIG_INPUT_TWL6040_VIBRA=m CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_PALMAS_PWRBUTTON=m +CONFIG_INPUT_PCF50633_PMU=m CONFIG_INPUT_PCF8574=m # CONFIG_INPUT_PWM_BEEPER is not set CONFIG_INPUT_PWM_VIBRA=m +CONFIG_INPUT_RK805_PWRKEY=m CONFIG_INPUT_GPIO_ROTARY_ENCODER=m +CONFIG_INPUT_DA9052_ONKEY=m +CONFIG_INPUT_DA9055_ONKEY=m +CONFIG_INPUT_DA9063_ONKEY=m +CONFIG_INPUT_WM831X_ON=m +CONFIG_INPUT_PCAP=m # CONFIG_INPUT_ADXL34X is not set # CONFIG_INPUT_IMS_PCU is not set # CONFIG_INPUT_CMA3000 is not set -# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set +CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m # CONFIG_INPUT_DRV260X_HAPTICS is not set # CONFIG_INPUT_DRV2665_HAPTICS is not set # CONFIG_INPUT_DRV2667_HAPTICS is not set @@ -2552,7 +2948,7 @@ CONFIG_RMI4_F30=y # Hardware I/O ports # CONFIG_SERIO=y -# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_SERPORT=m CONFIG_SERIO_AMBAKMI=y CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set @@ -2564,6 +2960,8 @@ CONFIG_SERIO_LIBPS2=y CONFIG_SERIO_GPIO_PS2=m # CONFIG_USERIO is not set # CONFIG_GAMEPORT is not set +# end of Hardware I/O ports +# end of Input device support # # Character devices @@ -2576,10 +2974,14 @@ CONFIG_VT_CONSOLE_SLEEP=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_N_GSM is not set -# CONFIG_TRACE_SINK is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=0 +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_N_HDLC=m +CONFIG_N_GSM=m +CONFIG_TRACE_ROUTER=m +CONFIG_TRACE_SINK=m +CONFIG_NULL_TTY=m CONFIG_LDISC_AUTOLOAD=y CONFIG_DEVMEM=y @@ -2588,14 +2990,15 @@ CONFIG_DEVMEM=y # CONFIG_SERIAL_EARLYCON=y CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y -# CONFIG_SERIAL_8250_FINTEK is not set +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_FINTEK=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_DMA=y -CONFIG_SERIAL_8250_NR_UARTS=6 -CONFIG_SERIAL_8250_RUNTIME_UARTS=6 +CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_RUNTIME_UARTS=8 # CONFIG_SERIAL_8250_EXTENDED is not set # CONFIG_SERIAL_8250_ASPEED_VUART is not set +CONFIG_SERIAL_8250_DWLIB=y CONFIG_SERIAL_8250_FSL=y CONFIG_SERIAL_8250_DW=y # CONFIG_SERIAL_8250_RT288X is not set @@ -2604,41 +3007,82 @@ CONFIG_SERIAL_OF_PLATFORM=y # # Non-8250 serial port support # -# CONFIG_SERIAL_AMBA_PL010 is not set -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_AMBA_PL010=m +CONFIG_SERIAL_AMBA_PL011=m # CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set -# CONFIG_SERIAL_MAX3100 is not set -# CONFIG_SERIAL_MAX310X is not set -# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_MAX3100=m +CONFIG_SERIAL_MAX310X=y +CONFIG_SERIAL_UARTLITE=m +CONFIG_SERIAL_UARTLITE_NR_UARTS=1 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_SCCNXP is not set +CONFIG_SERIAL_SIFIVE=m +CONFIG_SERIAL_SCCNXP=y +CONFIG_SERIAL_SCCNXP_CONSOLE=y CONFIG_SERIAL_SC16IS7XX_CORE=m CONFIG_SERIAL_SC16IS7XX=m CONFIG_SERIAL_SC16IS7XX_I2C=y -# CONFIG_SERIAL_SC16IS7XX_SPI is not set -# CONFIG_SERIAL_ALTERA_JTAGUART is not set -# CONFIG_SERIAL_ALTERA_UART is not set +CONFIG_SERIAL_SC16IS7XX_SPI=y +CONFIG_SERIAL_ALTERA_JTAGUART=m +CONFIG_SERIAL_ALTERA_UART=m +CONFIG_SERIAL_ALTERA_UART_MAXPORTS=4 +CONFIG_SERIAL_ALTERA_UART_BAUDRATE=115200 # CONFIG_SERIAL_IFX6X60 is not set CONFIG_SERIAL_XILINX_PS_UART=y CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y -# CONFIG_SERIAL_ARC is not set -# CONFIG_SERIAL_FSL_LPUART is not set -# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set -CONFIG_SERIAL_DEV_BUS=m +CONFIG_SERIAL_ARC=m +CONFIG_SERIAL_ARC_NR_PORTS=1 +CONFIG_SERIAL_FSL_LPUART=m +CONFIG_SERIAL_FSL_LINFLEXUART=m +CONFIG_SERIAL_CONEXANT_DIGICOLOR=m +# end of Serial drivers + +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SERIAL_DEV_BUS=y +CONFIG_SERIAL_DEV_CTRL_TTYPORT=y +CONFIG_TTY_PRINTK=m +CONFIG_TTY_PRINTK_LEVEL=6 CONFIG_HVC_DRIVER=y +CONFIG_HVC_IRQ=y +CONFIG_HVC_XEN=y +CONFIG_HVC_XEN_FRONTEND=y # CONFIG_HVC_DCC is not set CONFIG_VIRTIO_CONSOLE=y -# CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set +CONFIG_IPMI_HANDLER=m +CONFIG_IPMI_DMI_DECODE=y +CONFIG_IPMI_PLAT_DATA=y +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_SSIF=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m +CONFIG_IPMB_DEVICE_INTERFACE=m +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_TIMERIOMEM=m +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_HW_RANDOM_OPTEE=m +CONFIG_RAW_DRIVER=m +CONFIG_MAX_RAW_DEVS=256 +CONFIG_TCG_TPM=y +CONFIG_HW_RANDOM_TPM=y +CONFIG_TCG_TIS_CORE=y +CONFIG_TCG_TIS=y +CONFIG_TCG_TIS_SPI=m +CONFIG_TCG_TIS_I2C_ATMEL=m +CONFIG_TCG_TIS_I2C_INFINEON=m +CONFIG_TCG_TIS_I2C_NUVOTON=m +CONFIG_TCG_XEN=m +CONFIG_TCG_VTPM_PROXY=m +CONFIG_TCG_FTPM_TEE=m +CONFIG_TCG_TIS_ST33ZP24=m +CONFIG_TCG_TIS_ST33ZP24_I2C=m +CONFIG_TCG_TIS_ST33ZP24_SPI=m +CONFIG_XILLYBUS=m +CONFIG_XILLYBUS_OF=m +# end of Character devices -# -# PCMCIA character devices -# -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -# CONFIG_XILLYBUS is not set +CONFIG_RANDOM_TRUST_BOOTLOADER=y # # I2C support @@ -2647,7 +3091,7 @@ CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MUX=y +CONFIG_I2C_MUX=m # # Multiplexer I2C Chip support @@ -2656,15 +3100,18 @@ CONFIG_I2C_ARB_GPIO_CHALLENGE=m CONFIG_I2C_MUX_GPIO=m CONFIG_I2C_MUX_GPMUX=m CONFIG_I2C_MUX_LTC4306=m -# CONFIG_I2C_MUX_PCA9541 is not set -CONFIG_I2C_MUX_PCA954x=y -# CONFIG_I2C_MUX_PINCTRL is not set -# CONFIG_I2C_MUX_REG is not set -# CONFIG_I2C_DEMUX_PINCTRL is not set -# CONFIG_I2C_MUX_MLXCPLD is not set +CONFIG_I2C_MUX_PCA9541=m +CONFIG_I2C_MUX_PCA954x=m +CONFIG_I2C_MUX_PINCTRL=m +CONFIG_I2C_MUX_REG=m +CONFIG_I2C_DEMUX_PINCTRL=m +CONFIG_I2C_MUX_MLXCPLD=m +# end of Multiplexer I2C Chip support + CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_SMBUS=m CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_ALGOPCA=m # # I2C Hardware Bus support @@ -2673,75 +3120,102 @@ CONFIG_I2C_ALGOBIT=y # # I2C system bus drivers (mostly embedded / system-on-chip) # -# CONFIG_I2C_CADENCE is not set -# CONFIG_I2C_CBUS_GPIO is not set -CONFIG_I2C_DESIGNWARE_CORE=y -CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_I2C_CADENCE=m +CONFIG_I2C_CBUS_GPIO=m +CONFIG_I2C_DESIGNWARE_CORE=m +CONFIG_I2C_DESIGNWARE_PLATFORM=m # CONFIG_I2C_DESIGNWARE_SLAVE is not set -# CONFIG_I2C_EMEV2 is not set +CONFIG_I2C_EMEV2=m CONFIG_I2C_GPIO=m -CONFIG_I2C_GPIO_FAULT_INJECTOR=y -CONFIG_I2C_MV64XXX=y -# CONFIG_I2C_NOMADIK is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_RK3X is not set -# CONFIG_I2C_SIMTEC is not set -# CONFIG_I2C_XILINX is not set +# CONFIG_I2C_GPIO_FAULT_INJECTOR is not set +CONFIG_I2C_KEMPLD=m +CONFIG_I2C_MV64XXX=m +CONFIG_I2C_NOMADIK=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PCA_PLATFORM=m +CONFIG_I2C_RK3X=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_XILINX=m # # External I2C/SMBus adapter drivers # -# CONFIG_I2C_DIOLAN_U2C is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_ROBOTFUZZ_OSIF is not set -# CONFIG_I2C_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set +CONFIG_I2C_DIOLAN_U2C=m +CONFIG_I2C_DLN2=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_ROBOTFUZZ_OSIF=m +CONFIG_I2C_TAOS_EVM=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIPERBOARD=m # # Other I2C/SMBus bus drivers # -# CONFIG_I2C_STUB is not set +# end of I2C Hardware Bus support + +CONFIG_I2C_STUB=m CONFIG_I2C_SLAVE=y -# CONFIG_I2C_SLAVE_EEPROM is not set +CONFIG_I2C_SLAVE_EEPROM=m # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set +# end of I2C support + +CONFIG_I3C=m +CONFIG_CDNS_I3C_MASTER=m +CONFIG_DW_I3C_MASTER=m CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set CONFIG_SPI_MASTER=y CONFIG_SPI_MEM=y # # SPI Master Controller Drivers # -# CONFIG_SPI_ALTERA is not set -# CONFIG_SPI_AXI_SPI_ENGINE is not set +CONFIG_SPI_ALTERA=m +CONFIG_SPI_AXI_SPI_ENGINE=m CONFIG_SPI_BITBANG=m -# CONFIG_SPI_CADENCE is not set -# CONFIG_SPI_DESIGNWARE is not set +CONFIG_SPI_CADENCE=m +CONFIG_SPI_DESIGNWARE=m +CONFIG_SPI_DW_MMIO=m +CONFIG_SPI_DLN2=m +CONFIG_SPI_NXP_FLEXSPI=m CONFIG_SPI_GPIO=m -# CONFIG_SPI_FSL_SPI is not set -# CONFIG_SPI_OC_TINY is not set +CONFIG_SPI_FSL_LIB=m +CONFIG_SPI_FSL_SPI=m +CONFIG_SPI_OC_TINY=m CONFIG_SPI_PL022=y # CONFIG_SPI_ROCKCHIP is not set -# CONFIG_SPI_SC18IS602 is not set +CONFIG_SPI_SC18IS602=m +CONFIG_SPI_SIFIVE=m CONFIG_SPI_SUN4I=y CONFIG_SPI_SUN6I=y -# CONFIG_SPI_XCOMM is not set -# CONFIG_SPI_XILINX is not set -# CONFIG_SPI_ZYNQMP_GQSPI is not set +CONFIG_SPI_MXIC=m +CONFIG_SPI_XCOMM=m +CONFIG_SPI_XILINX=m +CONFIG_SPI_ZYNQMP_GQSPI=m # # SPI Protocol Masters # CONFIG_SPI_SPIDEV=m -# CONFIG_SPI_LOOPBACK_TEST is not set -# CONFIG_SPI_TLE62X0 is not set +CONFIG_SPI_LOOPBACK_TEST=m +CONFIG_SPI_TLE62X0=m CONFIG_SPI_SLAVE=y -# CONFIG_SPI_SLAVE_TIME is not set -# CONFIG_SPI_SLAVE_SYSTEM_CONTROL is not set -CONFIG_SPMI=y -# CONFIG_HSI is not set +CONFIG_SPI_SLAVE_TIME=m +CONFIG_SPI_SLAVE_SYSTEM_CONTROL=m +CONFIG_SPMI=m +CONFIG_HSI=m +CONFIG_HSI_BOARDINFO=y + +# +# HSI controllers +# + +# +# HSI clients +# +CONFIG_HSI_CHAR=m CONFIG_PPS=y # CONFIG_PPS_DEBUG is not set @@ -2760,90 +3234,155 @@ CONFIG_PPS_CLIENT_GPIO=m # PTP clock support # CONFIG_PTP_1588_CLOCK=y -# CONFIG_DP83640_PHY is not set +CONFIG_DP83640_PHY=m +# end of PTP clock support + CONFIG_PINCTRL=y CONFIG_GENERIC_PINCTRL_GROUPS=y CONFIG_PINMUX=y CONFIG_GENERIC_PINMUX_FUNCTIONS=y CONFIG_PINCONF=y CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +CONFIG_PINCTRL_AS3722=m CONFIG_PINCTRL_AXP209=m -# CONFIG_PINCTRL_AMD is not set -# CONFIG_PINCTRL_MCP23S08 is not set +CONFIG_PINCTRL_AMD=y +CONFIG_PINCTRL_MCP23S08=m CONFIG_PINCTRL_SINGLE=y -# CONFIG_PINCTRL_SX150X is not set +CONFIG_PINCTRL_SX150X=y +CONFIG_PINCTRL_STMFX=m +CONFIG_PINCTRL_PALMAS=m +CONFIG_PINCTRL_RK805=m +# CONFIG_PINCTRL_OCELOT is not set CONFIG_PINCTRL_SUNXI=y +# CONFIG_PINCTRL_SUN4I_A10 is not set +CONFIG_PINCTRL_SUN5I=y +CONFIG_PINCTRL_SUN6I_A31=y +CONFIG_PINCTRL_SUN6I_A31_R=y +CONFIG_PINCTRL_SUN8I_A23=y +CONFIG_PINCTRL_SUN8I_A33=y +CONFIG_PINCTRL_SUN8I_A83T=y +CONFIG_PINCTRL_SUN8I_A83T_R=y +CONFIG_PINCTRL_SUN8I_A23_R=y +CONFIG_PINCTRL_SUN8I_H3=y CONFIG_PINCTRL_SUN8I_H3_R=y +CONFIG_PINCTRL_SUN8I_V3S=y +CONFIG_PINCTRL_SUN9I_A80=y +CONFIG_PINCTRL_SUN9I_A80_R=y CONFIG_PINCTRL_SUN50I_A64=y CONFIG_PINCTRL_SUN50I_A64_R=y CONFIG_PINCTRL_SUN50I_H5=y CONFIG_PINCTRL_SUN50I_H6=y CONFIG_PINCTRL_SUN50I_H6_R=y CONFIG_PINCTRL_MADERA=m +CONFIG_PINCTRL_CS47L15=y +CONFIG_PINCTRL_CS47L35=y +CONFIG_PINCTRL_CS47L85=y +CONFIG_PINCTRL_CS47L90=y +CONFIG_PINCTRL_CS47L92=y CONFIG_GPIOLIB=y CONFIG_GPIOLIB_FASTPATH_LIMIT=512 CONFIG_OF_GPIO=y CONFIG_GPIOLIB_IRQCHIP=y +# CONFIG_DEBUG_GPIO is not set CONFIG_GPIO_SYSFS=y -CONFIG_GPIO_GENERIC=y +CONFIG_GPIO_GENERIC=m +CONFIG_GPIO_MAX730X=m # # Memory mapped GPIO drivers # -# CONFIG_GPIO_74XX_MMIO is not set -# CONFIG_GPIO_ALTERA is not set -CONFIG_GPIO_DWAPB=y +CONFIG_GPIO_74XX_MMIO=m +CONFIG_GPIO_ALTERA=m +CONFIG_GPIO_CADENCE=m +CONFIG_GPIO_DWAPB=m # CONFIG_GPIO_FTGPIO010 is not set -CONFIG_GPIO_GENERIC_PLATFORM=y -# CONFIG_GPIO_GRGPIO is not set +CONFIG_GPIO_GENERIC_PLATFORM=m +CONFIG_GPIO_GRGPIO=m CONFIG_GPIO_HLWD=m -# CONFIG_GPIO_MB86S7X is not set -# CONFIG_GPIO_MOCKUP is not set -# CONFIG_GPIO_PL061 is not set -# CONFIG_GPIO_SYSCON is not set +CONFIG_GPIO_MB86S7X=m +CONFIG_GPIO_PL061=y +CONFIG_GPIO_SAMA5D2_PIOBU=m +CONFIG_GPIO_SYSCON=m # CONFIG_GPIO_XGENE is not set -# CONFIG_GPIO_XILINX is not set +CONFIG_GPIO_XILINX=y +CONFIG_GPIO_AMD_FCH=m +# end of Memory mapped GPIO drivers # # I2C GPIO expanders # -# CONFIG_GPIO_ADP5588 is not set -# CONFIG_GPIO_ADNP is not set -# CONFIG_GPIO_MAX7300 is not set -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_GPIO_PCF857X is not set -# CONFIG_GPIO_TPIC2810 is not set +CONFIG_GPIO_ADP5588=m +CONFIG_GPIO_ADNP=m +CONFIG_GPIO_GW_PLD=m +CONFIG_GPIO_MAX7300=m +CONFIG_GPIO_MAX732X=m +CONFIG_GPIO_PCA953X=m +CONFIG_GPIO_PCF857X=m +CONFIG_GPIO_TPIC2810=m +# end of I2C GPIO expanders # # MFD GPIO expanders # -# CONFIG_GPIO_BD9571MWV is not set +CONFIG_GPIO_ADP5520=m +CONFIG_GPIO_ARIZONA=m +CONFIG_GPIO_BD9571MWV=m +CONFIG_GPIO_DA9052=m +CONFIG_GPIO_DA9055=m +CONFIG_GPIO_DLN2=m +CONFIG_GPIO_KEMPLD=m +CONFIG_GPIO_LP3943=m +CONFIG_GPIO_LP873X=m +CONFIG_GPIO_LP87565=m CONFIG_GPIO_MADERA=m +CONFIG_GPIO_MAX77650=m +CONFIG_GPIO_PALMAS=y +CONFIG_GPIO_RC5T583=y +CONFIG_GPIO_TPS65086=m +CONFIG_GPIO_TPS65218=m +CONFIG_GPIO_TPS6586X=y +CONFIG_GPIO_TPS65910=y +CONFIG_GPIO_TPS65912=m +CONFIG_GPIO_TQMX86=m +CONFIG_GPIO_TWL4030=m +CONFIG_GPIO_TWL6040=m +CONFIG_GPIO_UCB1400=m +CONFIG_GPIO_WM831X=m +CONFIG_GPIO_WM8350=m +CONFIG_GPIO_WM8994=m +# end of MFD GPIO expanders # # SPI GPIO expanders # -# CONFIG_GPIO_74X164 is not set -# CONFIG_GPIO_MAX3191X is not set -# CONFIG_GPIO_MAX7301 is not set -# CONFIG_GPIO_MC33880 is not set -# CONFIG_GPIO_PISOSR is not set -# CONFIG_GPIO_XRA1403 is not set +CONFIG_GPIO_74X164=m +CONFIG_GPIO_MAX3191X=m +CONFIG_GPIO_MAX7301=m +CONFIG_GPIO_MC33880=m +CONFIG_GPIO_PISOSR=m +CONFIG_GPIO_XRA1403=m +# end of SPI GPIO expanders # # USB GPIO expanders # +CONFIG_GPIO_VIPERBOARD=m +# end of USB GPIO expanders + +CONFIG_GPIO_MOCKUP=m CONFIG_W1=m CONFIG_W1_CON=y # # 1-wire Bus Masters # -# CONFIG_W1_MASTER_DS2490 is not set -# CONFIG_W1_MASTER_DS2482 is not set -# CONFIG_W1_MASTER_DS1WM is not set +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS1WM=m CONFIG_W1_MASTER_GPIO=m +CONFIG_W1_MASTER_SGI=m +# end of 1-wire Bus Masters # # 1-wire Slaves @@ -2860,59 +3399,93 @@ CONFIG_W1_SLAVE_DS2805=m CONFIG_W1_SLAVE_DS2431=m CONFIG_W1_SLAVE_DS2433=m # CONFIG_W1_SLAVE_DS2433_CRC is not set -# CONFIG_W1_SLAVE_DS2438 is not set -# CONFIG_W1_SLAVE_DS2780 is not set -# CONFIG_W1_SLAVE_DS2781 is not set -# CONFIG_W1_SLAVE_DS28E04 is not set +CONFIG_W1_SLAVE_DS2438=m +CONFIG_W1_SLAVE_DS250X=m +CONFIG_W1_SLAVE_DS2780=m +CONFIG_W1_SLAVE_DS2781=m +CONFIG_W1_SLAVE_DS28E04=m CONFIG_W1_SLAVE_DS28E17=m -# CONFIG_POWER_AVS is not set +# end of 1-wire Slaves + +CONFIG_POWER_AVS=y CONFIG_POWER_RESET=y +# CONFIG_POWER_RESET_AS3722 is not set # CONFIG_POWER_RESET_BRCMSTB is not set # CONFIG_POWER_RESET_GPIO is not set # CONFIG_POWER_RESET_GPIO_RESTART is not set # CONFIG_POWER_RESET_LTC2952 is not set -# CONFIG_POWER_RESET_RESTART is not set +CONFIG_POWER_RESET_RESTART=y # CONFIG_POWER_RESET_XGENE is not set CONFIG_POWER_RESET_SYSCON=y # CONFIG_POWER_RESET_SYSCON_POWEROFF is not set # CONFIG_SYSCON_REBOOT_MODE is not set +# CONFIG_NVMEM_REBOOT_MODE is not set CONFIG_POWER_SUPPLY=y # CONFIG_POWER_SUPPLY_DEBUG is not set -# CONFIG_PDA_POWER is not set -# CONFIG_GENERIC_ADC_BATTERY is not set -# CONFIG_TEST_POWER is not set +CONFIG_POWER_SUPPLY_HWMON=y +CONFIG_PDA_POWER=m +CONFIG_GENERIC_ADC_BATTERY=m +CONFIG_MAX8925_POWER=m +CONFIG_WM831X_BACKUP=m +CONFIG_WM831X_POWER=m +CONFIG_WM8350_POWER=m +CONFIG_TEST_POWER=m +CONFIG_BATTERY_88PM860X=m CONFIG_CHARGER_ADP5061=m +CONFIG_BATTERY_CPCAP=m CONFIG_BATTERY_DS2760=m -# CONFIG_BATTERY_DS2780 is not set -# CONFIG_BATTERY_DS2781 is not set -# CONFIG_BATTERY_DS2782 is not set -# CONFIG_BATTERY_LEGO_EV3 is not set -# CONFIG_BATTERY_SBS is not set -# CONFIG_CHARGER_SBS is not set +CONFIG_BATTERY_DS2780=m +CONFIG_BATTERY_DS2781=m +CONFIG_BATTERY_DS2782=m +CONFIG_BATTERY_LEGO_EV3=m +CONFIG_BATTERY_SBS=m +CONFIG_CHARGER_SBS=m CONFIG_MANAGER_SBS=m -# CONFIG_BATTERY_BQ27XXX is not set +CONFIG_BATTERY_BQ27XXX=m +CONFIG_BATTERY_BQ27XXX_I2C=m +CONFIG_BATTERY_BQ27XXX_HDQ=m +# CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM is not set +CONFIG_BATTERY_DA9030=m +CONFIG_BATTERY_DA9052=m +CONFIG_CHARGER_DA9150=m +CONFIG_BATTERY_DA9150=m CONFIG_CHARGER_AXP20X=m CONFIG_BATTERY_AXP20X=m CONFIG_AXP20X_POWER=m CONFIG_AXP288_FUEL_GAUGE=m -# CONFIG_BATTERY_MAX17040 is not set -# CONFIG_BATTERY_MAX17042 is not set +CONFIG_BATTERY_MAX17040=m +CONFIG_BATTERY_MAX17042=m CONFIG_BATTERY_MAX1721X=m -# CONFIG_CHARGER_ISP1704 is not set -# CONFIG_CHARGER_MAX8903 is not set -# CONFIG_CHARGER_LP8727 is not set -# CONFIG_CHARGER_GPIO is not set -# CONFIG_CHARGER_MANAGER is not set -# CONFIG_CHARGER_LTC3651 is not set -# CONFIG_CHARGER_DETECTOR_MAX14656 is not set -# CONFIG_CHARGER_BQ2415X is not set -# CONFIG_CHARGER_BQ24190 is not set -# CONFIG_CHARGER_BQ24257 is not set -# CONFIG_CHARGER_BQ24735 is not set -# CONFIG_CHARGER_BQ25890 is not set -# CONFIG_CHARGER_SMB347 is not set -# CONFIG_BATTERY_GAUGE_LTC2941 is not set -# CONFIG_CHARGER_RT9455 is not set +CONFIG_BATTERY_TWL4030_MADC=m +CONFIG_CHARGER_88PM860X=m +CONFIG_CHARGER_PCF50633=m +CONFIG_BATTERY_RX51=m +CONFIG_CHARGER_ISP1704=m +CONFIG_CHARGER_MAX8903=m +CONFIG_CHARGER_TWL4030=m +CONFIG_CHARGER_LP8727=m +CONFIG_CHARGER_LP8788=m +CONFIG_CHARGER_GPIO=m +CONFIG_CHARGER_MANAGER=y +CONFIG_CHARGER_LT3651=m +CONFIG_CHARGER_MAX14577=m +CONFIG_CHARGER_DETECTOR_MAX14656=m +CONFIG_CHARGER_MAX77650=m +CONFIG_CHARGER_MAX77693=m +CONFIG_CHARGER_MAX8997=m +CONFIG_CHARGER_MAX8998=m +CONFIG_CHARGER_BQ2415X=m +CONFIG_CHARGER_BQ24190=m +CONFIG_CHARGER_BQ24257=m +CONFIG_CHARGER_BQ24735=m +CONFIG_CHARGER_BQ25890=m +CONFIG_CHARGER_SMB347=m +CONFIG_CHARGER_TPS65090=m +CONFIG_CHARGER_TPS65217=m +CONFIG_BATTERY_GAUGE_LTC2941=m +CONFIG_BATTERY_RT5033=m +CONFIG_CHARGER_RT9455=m +CONFIG_CHARGER_UCS1002=m CONFIG_HWMON=y CONFIG_HWMON_VID=m # CONFIG_HWMON_DEBUG_CHIP is not set @@ -2936,16 +3509,20 @@ CONFIG_SENSORS_ADT7411=m CONFIG_SENSORS_ADT7462=m CONFIG_SENSORS_ADT7470=m CONFIG_SENSORS_ADT7475=m +CONFIG_SENSORS_AS370=m CONFIG_SENSORS_ASC7621=m CONFIG_SENSORS_ARM_SCMI=m CONFIG_SENSORS_ARM_SCPI=m -# CONFIG_SENSORS_ASPEED is not set +CONFIG_SENSORS_ASPEED=m CONFIG_SENSORS_ATXP1=m CONFIG_SENSORS_DS620=m CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_DA9052_ADC=m +CONFIG_SENSORS_DA9055=m CONFIG_SENSORS_F71805F=m CONFIG_SENSORS_F71882FG=m CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_MC13783_ADC=m CONFIG_SENSORS_FTSTEUTATES=m CONFIG_SENSORS_GL518SM=m CONFIG_SENSORS_GL520SM=m @@ -2953,7 +3530,9 @@ CONFIG_SENSORS_G760A=m CONFIG_SENSORS_G762=m CONFIG_SENSORS_GPIO_FAN=m CONFIG_SENSORS_HIH6130=m -# CONFIG_SENSORS_IIO_HWMON is not set +CONFIG_SENSORS_IBMAEM=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IIO_HWMON=m CONFIG_SENSORS_IT87=m CONFIG_SENSORS_JC42=m CONFIG_SENSORS_POWR1220=m @@ -2972,14 +3551,15 @@ CONFIG_SENSORS_MAX1619=m CONFIG_SENSORS_MAX1668=m CONFIG_SENSORS_MAX197=m CONFIG_SENSORS_MAX31722=m -# CONFIG_SENSORS_MAX6621 is not set +CONFIG_SENSORS_MAX6621=m CONFIG_SENSORS_MAX6639=m CONFIG_SENSORS_MAX6642=m CONFIG_SENSORS_MAX6650=m CONFIG_SENSORS_MAX6697=m CONFIG_SENSORS_MAX31790=m CONFIG_SENSORS_MCP3021=m -# CONFIG_SENSORS_TC654 is not set +CONFIG_SENSORS_TC654=m +CONFIG_SENSORS_MENF21BMC_HWMON=m CONFIG_SENSORS_ADCXX=m CONFIG_SENSORS_LM63=m CONFIG_SENSORS_LM70=m @@ -3005,21 +3585,28 @@ CONFIG_SENSORS_NCT6775=m CONFIG_SENSORS_NCT7802=m CONFIG_SENSORS_NCT7904=m CONFIG_SENSORS_NPCM7XX=m +CONFIG_SENSORS_OCC_P8_I2C=m +CONFIG_SENSORS_OCC=m CONFIG_SENSORS_PCF8591=m CONFIG_PMBUS=m CONFIG_SENSORS_PMBUS=m CONFIG_SENSORS_ADM1275=m -# CONFIG_SENSORS_IBM_CFFPS is not set +CONFIG_SENSORS_IBM_CFFPS=m +CONFIG_SENSORS_INSPUR_IPSPS=m CONFIG_SENSORS_IR35221=m +CONFIG_SENSORS_IR38064=m +CONFIG_SENSORS_IRPS5401=m +CONFIG_SENSORS_ISL68137=m CONFIG_SENSORS_LM25066=m CONFIG_SENSORS_LTC2978=m -# CONFIG_SENSORS_LTC2978_REGULATOR is not set +CONFIG_SENSORS_LTC2978_REGULATOR=y CONFIG_SENSORS_LTC3815=m CONFIG_SENSORS_MAX16064=m CONFIG_SENSORS_MAX20751=m CONFIG_SENSORS_MAX31785=m CONFIG_SENSORS_MAX34440=m CONFIG_SENSORS_MAX8688=m +CONFIG_SENSORS_PXE1610=m CONFIG_SENSORS_TPS40422=m CONFIG_SENSORS_TPS53679=m CONFIG_SENSORS_UCD9000=m @@ -3043,7 +3630,6 @@ CONFIG_SENSORS_SCH5636=m CONFIG_SENSORS_STTS751=m CONFIG_SENSORS_SMM665=m CONFIG_SENSORS_ADC128D818=m -CONFIG_SENSORS_ADS1015=m CONFIG_SENSORS_ADS7828=m CONFIG_SENSORS_ADS7871=m CONFIG_SENSORS_AMC6821=m @@ -3054,7 +3640,7 @@ CONFIG_SENSORS_TC74=m CONFIG_SENSORS_THMC50=m CONFIG_SENSORS_TMP102=m CONFIG_SENSORS_TMP103=m -# CONFIG_SENSORS_TMP108 is not set +CONFIG_SENSORS_TMP108=m CONFIG_SENSORS_TMP401=m CONFIG_SENSORS_TMP421=m CONFIG_SENSORS_VT1211=m @@ -3069,14 +3655,16 @@ CONFIG_SENSORS_W83L785TS=m CONFIG_SENSORS_W83L786NG=m CONFIG_SENSORS_W83627HF=m CONFIG_SENSORS_W83627EHF=m -CONFIG_THERMAL=m -# CONFIG_THERMAL_STATISTICS is not set +CONFIG_SENSORS_WM831X=m +CONFIG_SENSORS_WM8350=m +CONFIG_THERMAL=y +CONFIG_THERMAL_STATISTICS=y CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 CONFIG_THERMAL_HWMON=y CONFIG_THERMAL_OF=y CONFIG_THERMAL_WRITABLE_TRIPS=y -# CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE is not set -CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set # CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set CONFIG_THERMAL_GOV_FAIR_SHARE=y @@ -3088,57 +3676,74 @@ CONFIG_CPU_THERMAL=y CONFIG_CLOCK_THERMAL=y CONFIG_DEVFREQ_THERMAL=y CONFIG_THERMAL_EMULATION=y +CONFIG_THERMAL_MMIO=m # CONFIG_QORIQ_THERMAL is not set - -# -# ACPI INT340X thermal drivers -# -CONFIG_SUN8I_THS=m -# CONFIG_QCOM_SPMI_TEMP_ALARM is not set +CONFIG_SUN8I_THERMAL=y +CONFIG_DA9062_THERMAL=m CONFIG_GENERIC_ADC_THERMAL=m CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y # CONFIG_WATCHDOG_NOWAYOUT is not set CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y -# CONFIG_WATCHDOG_SYSFS is not set +CONFIG_WATCHDOG_OPEN_TIMEOUT=0 +CONFIG_WATCHDOG_SYSFS=y + +# +# Watchdog Pretimeout Governors +# +CONFIG_WATCHDOG_PRETIMEOUT_GOV=y +CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m +CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP=y +CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=m +CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP=y +# CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC is not set # # Watchdog Device Drivers # CONFIG_SOFT_WATCHDOG=m +CONFIG_SOFT_WATCHDOG_PRETIMEOUT=y +CONFIG_DA9052_WATCHDOG=m +CONFIG_DA9055_WATCHDOG=m +CONFIG_DA9063_WATCHDOG=m +CONFIG_DA9062_WATCHDOG=m CONFIG_GPIO_WATCHDOG=m -# CONFIG_XILINX_WATCHDOG is not set -# CONFIG_ZIIRAVE_WATCHDOG is not set +CONFIG_MENF21BMC_WATCHDOG=m +CONFIG_WM831X_WATCHDOG=m +CONFIG_WM8350_WATCHDOG=m +CONFIG_XILINX_WATCHDOG=m +CONFIG_ZIIRAVE_WATCHDOG=m CONFIG_RAVE_SP_WATCHDOG=m CONFIG_ARM_SP805_WATCHDOG=m CONFIG_ARM_SBSA_WATCHDOG=m -# CONFIG_CADENCE_WATCHDOG is not set -# CONFIG_DW_WATCHDOG is not set +CONFIG_CADENCE_WATCHDOG=m +CONFIG_DW_WATCHDOG=m +CONFIG_RN5T618_WATCHDOG=m CONFIG_SUNXI_WATCHDOG=y -# CONFIG_MAX63XX_WATCHDOG is not set -# CONFIG_MEN_A21_WDT is not set +CONFIG_TWL4030_WATCHDOG=m +CONFIG_MAX63XX_WATCHDOG=m +CONFIG_RETU_WATCHDOG=m +CONFIG_KEMPLD_WDT=m +CONFIG_MEN_A21_WDT=m +CONFIG_XEN_WDT=m # # USB-based Watchdog Cards # -# CONFIG_USBPCWATCHDOG is not set - -# -# Watchdog Pretimeout Governors -# -# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set +CONFIG_USBPCWATCHDOG=m CONFIG_SSB_POSSIBLE=y CONFIG_SSB=m CONFIG_SSB_BLOCKIO=y CONFIG_SSB_SDIOHOST_POSSIBLE=y CONFIG_SSB_SDIOHOST=y -# CONFIG_SSB_DRIVER_GPIO is not set +CONFIG_SSB_DRIVER_GPIO=y CONFIG_BCMA_POSSIBLE=y CONFIG_BCMA=m CONFIG_BCMA_BLOCKIO=y -# CONFIG_BCMA_HOST_SOC is not set -# CONFIG_BCMA_DRIVER_GMAC_CMN is not set -# CONFIG_BCMA_DRIVER_GPIO is not set +CONFIG_BCMA_HOST_SOC=y +CONFIG_BCMA_SFLASH=y +CONFIG_BCMA_DRIVER_GMAC_CMN=y +CONFIG_BCMA_DRIVER_GPIO=y # CONFIG_BCMA_DEBUG is not set # @@ -3147,151 +3752,241 @@ CONFIG_BCMA_BLOCKIO=y CONFIG_MFD_CORE=y # CONFIG_MFD_ACT8945A is not set CONFIG_MFD_SUN4I_GPADC=y -# CONFIG_MFD_AS3711 is not set -# CONFIG_MFD_AS3722 is not set -# CONFIG_PMIC_ADP5520 is not set -# CONFIG_MFD_AAT2870_CORE is not set -# CONFIG_MFD_ATMEL_FLEXCOM is not set -# CONFIG_MFD_ATMEL_HLCDC is not set -# CONFIG_MFD_BCM590XX is not set +CONFIG_MFD_AS3711=y +CONFIG_MFD_AS3722=m +CONFIG_PMIC_ADP5520=y +CONFIG_MFD_AAT2870_CORE=y +CONFIG_MFD_ATMEL_FLEXCOM=m +CONFIG_MFD_ATMEL_HLCDC=m +CONFIG_MFD_BCM590XX=m CONFIG_MFD_BD9571MWV=m # CONFIG_MFD_AC100 is not set +CONFIG_MFD_AC200=m CONFIG_MFD_AXP20X=y -CONFIG_MFD_AXP20X_I2C=y +CONFIG_MFD_AXP20X_I2C=m CONFIG_MFD_AXP20X_RSB=y -# CONFIG_MFD_CROS_EC is not set CONFIG_MFD_MADERA=m CONFIG_MFD_MADERA_I2C=m -# CONFIG_MFD_MADERA_SPI is not set -# CONFIG_MFD_CS47L35 is not set -# CONFIG_MFD_CS47L85 is not set -# CONFIG_MFD_CS47L90 is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_MFD_DA9052_SPI is not set -# CONFIG_MFD_DA9052_I2C is not set -# CONFIG_MFD_DA9055 is not set -# CONFIG_MFD_DA9062 is not set -# CONFIG_MFD_DA9063 is not set -# CONFIG_MFD_DA9150 is not set -# CONFIG_MFD_DLN2 is not set -# CONFIG_MFD_MC13XXX_SPI is not set -# CONFIG_MFD_MC13XXX_I2C is not set -# CONFIG_MFD_HI6421_PMIC is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_HTC_I2CPLD is not set -# CONFIG_MFD_KEMPLD is not set -# CONFIG_MFD_88PM800 is not set -# CONFIG_MFD_88PM805 is not set -# CONFIG_MFD_88PM860X is not set -# CONFIG_MFD_MAX14577 is not set +CONFIG_MFD_MADERA_SPI=m +CONFIG_MFD_CS47L15=y +CONFIG_MFD_CS47L35=y +CONFIG_MFD_CS47L85=y +CONFIG_MFD_CS47L90=y +CONFIG_MFD_CS47L92=y +CONFIG_PMIC_DA903X=y +CONFIG_PMIC_DA9052=y +CONFIG_MFD_DA9052_SPI=y +CONFIG_MFD_DA9052_I2C=y +CONFIG_MFD_DA9055=y +CONFIG_MFD_DA9062=m +CONFIG_MFD_DA9063=y +CONFIG_MFD_DA9150=m +CONFIG_MFD_DLN2=m +CONFIG_MFD_MC13XXX=m +CONFIG_MFD_MC13XXX_SPI=m +CONFIG_MFD_MC13XXX_I2C=m +CONFIG_MFD_HI6421_PMIC=y +CONFIG_HTC_PASIC3=m +CONFIG_HTC_I2CPLD=y +CONFIG_MFD_KEMPLD=m +CONFIG_MFD_88PM800=m +CONFIG_MFD_88PM805=m +CONFIG_MFD_88PM860X=y +CONFIG_MFD_MAX14577=y # CONFIG_MFD_MAX77620 is not set -# CONFIG_MFD_MAX77686 is not set -# CONFIG_MFD_MAX77693 is not set -# CONFIG_MFD_MAX77843 is not set -# CONFIG_MFD_MAX8907 is not set -# CONFIG_MFD_MAX8925 is not set -# CONFIG_MFD_MAX8997 is not set -# CONFIG_MFD_MAX8998 is not set -# CONFIG_MFD_MT6397 is not set -# CONFIG_MFD_MENF21BMC is not set -# CONFIG_EZX_PCAP is not set -# CONFIG_MFD_CPCAP is not set -# CONFIG_MFD_VIPERBOARD is not set -# CONFIG_MFD_RETU is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_MFD_RT5033 is not set -# CONFIG_MFD_RC5T583 is not set -# CONFIG_MFD_RK808 is not set -# CONFIG_MFD_RN5T618 is not set +CONFIG_MFD_MAX77650=m +CONFIG_MFD_MAX77686=m +CONFIG_MFD_MAX77693=y +CONFIG_MFD_MAX77843=y +CONFIG_MFD_MAX8907=m +CONFIG_MFD_MAX8925=y +CONFIG_MFD_MAX8997=y +CONFIG_MFD_MAX8998=y +CONFIG_MFD_MT6397=m +CONFIG_MFD_MENF21BMC=m +CONFIG_EZX_PCAP=y +CONFIG_MFD_CPCAP=m +CONFIG_MFD_VIPERBOARD=m +CONFIG_MFD_RETU=m +CONFIG_MFD_PCF50633=m +CONFIG_PCF50633_ADC=m +CONFIG_PCF50633_GPIO=m +CONFIG_UCB1400_CORE=m +CONFIG_MFD_RT5033=m +CONFIG_MFD_RC5T583=y +CONFIG_MFD_RK808=y +CONFIG_MFD_RN5T618=m CONFIG_MFD_SEC_CORE=y -# CONFIG_MFD_SI476X_CORE is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_MFD_SKY81452 is not set -# CONFIG_MFD_SMSC is not set -# CONFIG_ABX500_CORE is not set +CONFIG_MFD_SI476X_CORE=m +CONFIG_MFD_SM501=m +CONFIG_MFD_SM501_GPIO=y +CONFIG_MFD_SKY81452=m +CONFIG_MFD_SMSC=y +CONFIG_ABX500_CORE=y +CONFIG_AB3100_CORE=y +CONFIG_AB3100_OTP=m # CONFIG_MFD_STMPE is not set -# CONFIG_MFD_SUN6I_PRCM is not set +CONFIG_MFD_SUN6I_PRCM=y CONFIG_MFD_SYSCON=y -# CONFIG_MFD_TI_AM335X_TSCADC is not set -# CONFIG_MFD_LP3943 is not set -# CONFIG_MFD_LP8788 is not set -# CONFIG_MFD_TI_LMU is not set -# CONFIG_MFD_PALMAS is not set -# CONFIG_TPS6105X is not set -# CONFIG_TPS65010 is not set -# CONFIG_TPS6507X is not set -# CONFIG_MFD_TPS65086 is not set -# CONFIG_MFD_TPS65090 is not set -# CONFIG_MFD_TPS65217 is not set -# CONFIG_MFD_TI_LP873X is not set -# CONFIG_MFD_TI_LP87565 is not set -# CONFIG_MFD_TPS65218 is not set -# CONFIG_MFD_TPS6586X is not set -# CONFIG_MFD_TPS65910 is not set -# CONFIG_MFD_TPS65912_I2C is not set -# CONFIG_MFD_TPS65912_SPI is not set -# CONFIG_MFD_TPS80031 is not set -# CONFIG_TWL4030_CORE is not set -# CONFIG_TWL6040_CORE is not set +CONFIG_MFD_TI_AM335X_TSCADC=m +CONFIG_MFD_LP3943=m +CONFIG_MFD_LP8788=y +CONFIG_MFD_TI_LMU=m +CONFIG_MFD_PALMAS=y +CONFIG_TPS6105X=m +CONFIG_TPS65010=m +CONFIG_TPS6507X=m +CONFIG_MFD_TPS65086=m +CONFIG_MFD_TPS65090=y +CONFIG_MFD_TPS65217=m +CONFIG_MFD_TI_LP873X=m +CONFIG_MFD_TI_LP87565=m +CONFIG_MFD_TPS65218=m +CONFIG_MFD_TPS6586X=y +CONFIG_MFD_TPS65910=y +CONFIG_MFD_TPS65912=y +CONFIG_MFD_TPS65912_I2C=y +CONFIG_MFD_TPS65912_SPI=y +CONFIG_MFD_TPS80031=y +CONFIG_TWL4030_CORE=y +CONFIG_MFD_TWL4030_AUDIO=y +CONFIG_TWL6040_CORE=y CONFIG_MFD_WL1273_CORE=m -# CONFIG_MFD_LM3533 is not set +CONFIG_MFD_LM3533=m # CONFIG_MFD_TC3589X is not set -# CONFIG_MFD_ARIZONA_I2C is not set -# CONFIG_MFD_ARIZONA_SPI is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM831X_I2C is not set -# CONFIG_MFD_WM831X_SPI is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_WM8994 is not set +CONFIG_MFD_TQMX86=m +# CONFIG_MFD_LOCHNAGAR is not set +CONFIG_MFD_ARIZONA=y +CONFIG_MFD_ARIZONA_I2C=m +CONFIG_MFD_ARIZONA_SPI=m +CONFIG_MFD_CS47L24=y +CONFIG_MFD_WM5102=y +CONFIG_MFD_WM5110=y +CONFIG_MFD_WM8997=y +CONFIG_MFD_WM8998=y +CONFIG_MFD_WM8400=y +CONFIG_MFD_WM831X=y +CONFIG_MFD_WM831X_I2C=y +CONFIG_MFD_WM831X_SPI=y +CONFIG_MFD_WM8350=y +CONFIG_MFD_WM8350_I2C=y +CONFIG_MFD_WM8994=m CONFIG_MFD_ROHM_BD718XX=m +# CONFIG_MFD_ROHM_BD70528 is not set +# CONFIG_MFD_STPMIC1 is not set +CONFIG_MFD_STMFX=m CONFIG_RAVE_SP_CORE=m +# end of Multifunction device drivers + CONFIG_REGULATOR=y # CONFIG_REGULATOR_DEBUG is not set -CONFIG_REGULATOR_FIXED_VOLTAGE=y -# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set -# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +CONFIG_REGULATOR_FIXED_VOLTAGE=m +CONFIG_REGULATOR_VIRTUAL_CONSUMER=m +CONFIG_REGULATOR_USERSPACE_CONSUMER=m +CONFIG_REGULATOR_USERSPACE_CONSUMER_OF=m CONFIG_REGULATOR_88PG86X=m -# CONFIG_REGULATOR_ACT8865 is not set -# CONFIG_REGULATOR_AD5398 is not set -# CONFIG_REGULATOR_ANATOP is not set -CONFIG_REGULATOR_AXP20X=y +CONFIG_REGULATOR_88PM800=m +CONFIG_REGULATOR_88PM8607=m +CONFIG_REGULATOR_ACT8865=m +CONFIG_REGULATOR_AD5398=m +CONFIG_REGULATOR_ANATOP=m +CONFIG_REGULATOR_AAT2870=m +CONFIG_REGULATOR_AB3100=m +CONFIG_REGULATOR_ARIZONA_LDO1=m +CONFIG_REGULATOR_ARIZONA_MICSUPP=m +CONFIG_REGULATOR_AS3711=m +CONFIG_REGULATOR_AS3722=m +CONFIG_REGULATOR_AXP20X=m +CONFIG_REGULATOR_BCM590XX=m CONFIG_REGULATOR_BD718XX=m CONFIG_REGULATOR_BD9571MWV=m -# CONFIG_REGULATOR_DA9210 is not set -# CONFIG_REGULATOR_DA9211 is not set -# CONFIG_REGULATOR_FAN53555 is not set -CONFIG_REGULATOR_GPIO=y -# CONFIG_REGULATOR_ISL9305 is not set -# CONFIG_REGULATOR_ISL6271A is not set -# CONFIG_REGULATOR_LP3971 is not set -# CONFIG_REGULATOR_LP3972 is not set -# CONFIG_REGULATOR_LP872X is not set -# CONFIG_REGULATOR_LP8755 is not set -# CONFIG_REGULATOR_LTC3589 is not set -# CONFIG_REGULATOR_LTC3676 is not set -# CONFIG_REGULATOR_MAX1586 is not set -# CONFIG_REGULATOR_MAX8649 is not set -# CONFIG_REGULATOR_MAX8660 is not set -# CONFIG_REGULATOR_MAX8952 is not set +CONFIG_REGULATOR_CPCAP=m +CONFIG_REGULATOR_DA903X=m +CONFIG_REGULATOR_DA9052=m +CONFIG_REGULATOR_DA9055=m +CONFIG_REGULATOR_DA9062=m +CONFIG_REGULATOR_DA9063=m +CONFIG_REGULATOR_DA9210=m +CONFIG_REGULATOR_DA9211=m +CONFIG_REGULATOR_FAN53555=m +CONFIG_REGULATOR_GPIO=m +CONFIG_REGULATOR_HI6421=m +CONFIG_REGULATOR_HI6421V530=m +CONFIG_REGULATOR_ISL9305=m +CONFIG_REGULATOR_ISL6271A=m +CONFIG_REGULATOR_LM363X=m +CONFIG_REGULATOR_LP3971=m +CONFIG_REGULATOR_LP3972=m +CONFIG_REGULATOR_LP872X=m +CONFIG_REGULATOR_LP873X=m +CONFIG_REGULATOR_LP8755=m +CONFIG_REGULATOR_LP87565=m +CONFIG_REGULATOR_LP8788=m +CONFIG_REGULATOR_LTC3589=m +CONFIG_REGULATOR_LTC3676=m +CONFIG_REGULATOR_MAX14577=m +CONFIG_REGULATOR_MAX1586=m +CONFIG_REGULATOR_MAX77650=m +CONFIG_REGULATOR_MAX8649=m +CONFIG_REGULATOR_MAX8660=m +CONFIG_REGULATOR_MAX8907=m +CONFIG_REGULATOR_MAX8925=m +CONFIG_REGULATOR_MAX8952=m # CONFIG_REGULATOR_MAX8973 is not set -# CONFIG_REGULATOR_MT6311 is not set -# CONFIG_REGULATOR_PFUZE100 is not set -# CONFIG_REGULATOR_PV88060 is not set -# CONFIG_REGULATOR_PV88080 is not set -# CONFIG_REGULATOR_PV88090 is not set -# CONFIG_REGULATOR_PWM is not set -CONFIG_REGULATOR_QCOM_SPMI=y -# CONFIG_REGULATOR_S2MPA01 is not set -CONFIG_REGULATOR_S2MPS11=y -# CONFIG_REGULATOR_S5M8767 is not set +CONFIG_REGULATOR_MAX8997=m +CONFIG_REGULATOR_MAX8998=m +CONFIG_REGULATOR_MAX77686=m +CONFIG_REGULATOR_MAX77693=m +CONFIG_REGULATOR_MAX77802=m +CONFIG_REGULATOR_MC13XXX_CORE=m +CONFIG_REGULATOR_MC13783=m +CONFIG_REGULATOR_MC13892=m +CONFIG_REGULATOR_MCP16502=m +CONFIG_REGULATOR_MT6311=m +CONFIG_REGULATOR_MT6323=m +CONFIG_REGULATOR_MT6397=m +CONFIG_REGULATOR_PALMAS=m +CONFIG_REGULATOR_PCAP=m +CONFIG_REGULATOR_PCF50633=m +CONFIG_REGULATOR_PFUZE100=m +CONFIG_REGULATOR_PV88060=m +CONFIG_REGULATOR_PV88080=m +CONFIG_REGULATOR_PV88090=m +CONFIG_REGULATOR_PWM=m +CONFIG_REGULATOR_QCOM_SPMI=m +CONFIG_REGULATOR_RC5T583=m +CONFIG_REGULATOR_RK808=m +CONFIG_REGULATOR_RN5T618=m +CONFIG_REGULATOR_RT5033=m +CONFIG_REGULATOR_S2MPA01=m +CONFIG_REGULATOR_S2MPS11=m +CONFIG_REGULATOR_S5M8767=m +CONFIG_REGULATOR_SKY81452=m +CONFIG_REGULATOR_SLG51000=m CONFIG_REGULATOR_SY8106A=m -# CONFIG_REGULATOR_TPS51632 is not set -# CONFIG_REGULATOR_TPS62360 is not set -# CONFIG_REGULATOR_TPS65023 is not set -# CONFIG_REGULATOR_TPS6507X is not set -# CONFIG_REGULATOR_TPS65132 is not set -# CONFIG_REGULATOR_TPS6524X is not set -# CONFIG_REGULATOR_VCTRL is not set +CONFIG_REGULATOR_SY8824X=m +CONFIG_REGULATOR_TPS51632=m +CONFIG_REGULATOR_TPS6105X=m +CONFIG_REGULATOR_TPS62360=m +CONFIG_REGULATOR_TPS65023=m +CONFIG_REGULATOR_TPS6507X=m +CONFIG_REGULATOR_TPS65086=m +CONFIG_REGULATOR_TPS65090=m +CONFIG_REGULATOR_TPS65132=m +CONFIG_REGULATOR_TPS65217=m +CONFIG_REGULATOR_TPS65218=m +CONFIG_REGULATOR_TPS6524X=m +CONFIG_REGULATOR_TPS6586X=m +CONFIG_REGULATOR_TPS65910=m +CONFIG_REGULATOR_TPS65912=m +CONFIG_REGULATOR_TPS80031=m +CONFIG_REGULATOR_TWL4030=m +CONFIG_REGULATOR_VCTRL=m +CONFIG_REGULATOR_WM831X=m +CONFIG_REGULATOR_WM8350=m +CONFIG_REGULATOR_WM8400=m +CONFIG_REGULATOR_WM8994=m +CONFIG_REGULATOR_TP65185X=m CONFIG_CEC_CORE=m CONFIG_CEC_NOTIFIER=y CONFIG_CEC_PIN=y @@ -3309,25 +4004,28 @@ CONFIG_IR_SHARP_DECODER=m CONFIG_IR_MCE_KBD_DECODER=m CONFIG_IR_XMP_DECODER=m CONFIG_IR_IMON_DECODER=m +CONFIG_IR_RCMM_DECODER=m CONFIG_RC_DEVICES=y -# CONFIG_RC_ATI_REMOTE is not set -# CONFIG_IR_HIX5HD2 is not set -# CONFIG_IR_IMON is not set +CONFIG_RC_ATI_REMOTE=m +CONFIG_IR_HIX5HD2=m +CONFIG_IR_IMON=m CONFIG_IR_IMON_RAW=m -# CONFIG_IR_MCEUSB is not set -# CONFIG_IR_REDRAT3 is not set +CONFIG_IR_MCEUSB=m +CONFIG_IR_REDRAT3=m CONFIG_IR_SPI=m -# CONFIG_IR_STREAMZAP is not set -# CONFIG_IR_IGORPLUGUSB is not set -# CONFIG_IR_IGUANA is not set -# CONFIG_IR_TTUSBIR is not set -# CONFIG_RC_LOOPBACK is not set -# CONFIG_IR_GPIO_CIR is not set +CONFIG_IR_STREAMZAP=m +CONFIG_IR_IGORPLUGUSB=m +CONFIG_IR_IGUANA=m +CONFIG_IR_TTUSBIR=m +CONFIG_RC_LOOPBACK=m +CONFIG_IR_GPIO_CIR=m CONFIG_IR_GPIO_TX=m CONFIG_IR_PWM_TX=m CONFIG_IR_SUNXI=m -# CONFIG_IR_SERIAL is not set -# CONFIG_IR_SIR is not set +CONFIG_IR_SERIAL=m +CONFIG_IR_SERIAL_TRANSMITTER=y +CONFIG_IR_SIR=m +CONFIG_RC_XBOX_DVD=m CONFIG_MEDIA_SUPPORT=m # @@ -3338,27 +4036,30 @@ CONFIG_MEDIA_ANALOG_TV_SUPPORT=y CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y CONFIG_MEDIA_RADIO_SUPPORT=y CONFIG_MEDIA_SDR_SUPPORT=y -# CONFIG_MEDIA_CEC_SUPPORT is not set -# CONFIG_CEC_PIN_ERROR_INJ is not set +CONFIG_MEDIA_CEC_SUPPORT=y +# CONFIG_MEDIA_CEC_RC is not set +CONFIG_CEC_PIN_ERROR_INJ=y CONFIG_MEDIA_CONTROLLER=y -# CONFIG_MEDIA_CONTROLLER_DVB is not set +CONFIG_MEDIA_CONTROLLER_DVB=y +# CONFIG_MEDIA_CONTROLLER_REQUEST_API is not set CONFIG_VIDEO_DEV=m CONFIG_VIDEO_V4L2_SUBDEV_API=y CONFIG_VIDEO_V4L2=m -# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_V4L2_I2C=y +CONFIG_VIDEO_ADV_DEBUG=y CONFIG_VIDEO_FIXED_MINOR_RANGES=y CONFIG_VIDEO_TUNER=m CONFIG_V4L2_FWNODE=m CONFIG_VIDEOBUF_GEN=m CONFIG_VIDEOBUF_VMALLOC=m CONFIG_DVB_CORE=m -# CONFIG_DVB_MMAP is not set +CONFIG_DVB_MMAP=y CONFIG_DVB_NET=y CONFIG_TTPCI_EEPROM=m CONFIG_DVB_MAX_ADAPTERS=8 CONFIG_DVB_DYNAMIC_MINORS=y -# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set -# CONFIG_DVB_ULE_DEBUG is not set +CONFIG_DVB_DEMUX_SECTION_LOSS_LOG=y +CONFIG_DVB_ULE_DEBUG=y # # Media drivers @@ -3370,63 +4071,12 @@ CONFIG_MEDIA_USB_SUPPORT=y # CONFIG_USB_VIDEO_CLASS=m CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -CONFIG_USB_GSPCA=m -CONFIG_USB_M5602=m -CONFIG_USB_STV06XX=m -CONFIG_USB_GL860=m -CONFIG_USB_GSPCA_BENQ=m -CONFIG_USB_GSPCA_CONEX=m -CONFIG_USB_GSPCA_CPIA1=m -CONFIG_USB_GSPCA_DTCS033=m -CONFIG_USB_GSPCA_ETOMS=m -CONFIG_USB_GSPCA_FINEPIX=m -CONFIG_USB_GSPCA_JEILINJ=m -CONFIG_USB_GSPCA_JL2005BCD=m -CONFIG_USB_GSPCA_KINECT=m -CONFIG_USB_GSPCA_KONICA=m -CONFIG_USB_GSPCA_MARS=m -CONFIG_USB_GSPCA_MR97310A=m -CONFIG_USB_GSPCA_NW80X=m -CONFIG_USB_GSPCA_OV519=m -CONFIG_USB_GSPCA_OV534=m -CONFIG_USB_GSPCA_OV534_9=m -CONFIG_USB_GSPCA_PAC207=m -CONFIG_USB_GSPCA_PAC7302=m -CONFIG_USB_GSPCA_PAC7311=m -CONFIG_USB_GSPCA_SE401=m -CONFIG_USB_GSPCA_SN9C2028=m -CONFIG_USB_GSPCA_SN9C20X=m -CONFIG_USB_GSPCA_SONIXB=m -CONFIG_USB_GSPCA_SONIXJ=m -CONFIG_USB_GSPCA_SPCA500=m -CONFIG_USB_GSPCA_SPCA501=m -CONFIG_USB_GSPCA_SPCA505=m -CONFIG_USB_GSPCA_SPCA506=m -CONFIG_USB_GSPCA_SPCA508=m -CONFIG_USB_GSPCA_SPCA561=m -CONFIG_USB_GSPCA_SPCA1528=m -CONFIG_USB_GSPCA_SQ905=m -CONFIG_USB_GSPCA_SQ905C=m -CONFIG_USB_GSPCA_SQ930X=m -CONFIG_USB_GSPCA_STK014=m -CONFIG_USB_GSPCA_STK1135=m -CONFIG_USB_GSPCA_STV0680=m -CONFIG_USB_GSPCA_SUNPLUS=m -CONFIG_USB_GSPCA_T613=m -CONFIG_USB_GSPCA_TOPRO=m -CONFIG_USB_GSPCA_TOUPTEK=m -CONFIG_USB_GSPCA_TV8532=m -CONFIG_USB_GSPCA_VC032X=m -CONFIG_USB_GSPCA_VICAM=m -CONFIG_USB_GSPCA_XIRLINK_CIT=m -CONFIG_USB_GSPCA_ZC3XX=m -CONFIG_USB_PWC=m -# CONFIG_USB_PWC_DEBUG is not set -CONFIG_USB_PWC_INPUT_EVDEV=y -CONFIG_VIDEO_CPIA2=m -CONFIG_USB_ZR364XX=m -CONFIG_USB_STKWEBCAM=m -CONFIG_USB_S2255=m +# CONFIG_USB_GSPCA is not set +# CONFIG_USB_PWC is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set CONFIG_VIDEO_USBTV=m # @@ -3440,7 +4090,10 @@ CONFIG_VIDEO_HDPVR=m CONFIG_VIDEO_USBVISION=m CONFIG_VIDEO_STK1160_COMMON=m CONFIG_VIDEO_STK1160=m -# CONFIG_VIDEO_GO7007 is not set +CONFIG_VIDEO_GO7007=m +CONFIG_VIDEO_GO7007_USB=m +CONFIG_VIDEO_GO7007_LOADER=m +CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m # # Analog/digital TV USB devices @@ -3464,11 +4117,12 @@ CONFIG_DVB_USB=m CONFIG_DVB_USB_DIB3000MC=m CONFIG_DVB_USB_A800=m CONFIG_DVB_USB_DIBUSB_MB=m -CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set CONFIG_DVB_USB_DIBUSB_MC=m CONFIG_DVB_USB_DIB0700=m CONFIG_DVB_USB_UMT_010=m CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_CXUSB_ANALOG is not set CONFIG_DVB_USB_M920X=m CONFIG_DVB_USB_DIGITV=m CONFIG_DVB_USB_VP7045=m @@ -3520,17 +4174,25 @@ CONFIG_VIDEO_EM28XX_RC=m CONFIG_USB_AIRSPY=m CONFIG_USB_HACKRF=m CONFIG_USB_MSI2500=m + +# +# USB HDMI CEC adapters +# +CONFIG_USB_PULSE8_CEC=m +CONFIG_USB_RAINSHADOW_CEC=m CONFIG_V4L_PLATFORM_DRIVERS=y # CONFIG_VIDEO_CADENCE is not set +CONFIG_VIDEO_ASPEED=m CONFIG_VIDEO_MUX=m -# CONFIG_SOC_CAMERA is not set CONFIG_VIDEO_XILINX=m CONFIG_VIDEO_XILINX_TPG=m CONFIG_VIDEO_XILINX_VTC=m +CONFIG_VIDEO_SUN4I_CSI=m CONFIG_VIDEO_SUN6I_CSI=m # CONFIG_V4L_MEM2MEM_DRIVERS is not set # CONFIG_V4L_TEST_DRIVERS is not set CONFIG_DVB_PLATFORM_DRIVERS=y +CONFIG_CEC_PLATFORM_DRIVERS=y CONFIG_SDR_PLATFORM_DRIVERS=y # @@ -3541,6 +4203,7 @@ CONFIG_RADIO_ADAPTERS=y CONFIG_RADIO_TEA575X=m # CONFIG_RADIO_SI470X is not set # CONFIG_RADIO_SI4713 is not set +CONFIG_RADIO_SI476X=m # CONFIG_USB_MR800 is not set CONFIG_USB_DSBR=m CONFIG_RADIO_SHARK=m @@ -3556,6 +4219,8 @@ CONFIG_RADIO_WL1273=m # # Texas Instruments WL128x FM driver (ST based) # +# end of Texas Instruments WL128x FM driver (ST based) + CONFIG_MEDIA_COMMON_OPTIONS=y # @@ -3581,67 +4246,194 @@ CONFIG_MEDIA_SUBDRV_AUTOSELECT=y CONFIG_MEDIA_ATTACH=y CONFIG_VIDEO_IR_I2C=m +# +# I2C Encoders, decoders, sensors and other helper chips +# + # # Audio decoders, processors and mixers # +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA1997X=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS3308=m +CONFIG_VIDEO_CS5345=m CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_TLV320AIC23B=m +CONFIG_VIDEO_UDA1342=m CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_VP27SMPX=m +CONFIG_VIDEO_SONY_BTF_MPX=m # # RDS decoders # +CONFIG_VIDEO_SAA6588=m # # Video decoders # +CONFIG_VIDEO_ADV7180=m +CONFIG_VIDEO_ADV7183=m +CONFIG_VIDEO_ADV748X=m +CONFIG_VIDEO_ADV7604=m +CONFIG_VIDEO_ADV7604_CEC=y +CONFIG_VIDEO_ADV7842=m +CONFIG_VIDEO_ADV7842_CEC=y +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_ML86V7667=m +CONFIG_VIDEO_SAA7110=m CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_TC358743=m +CONFIG_VIDEO_TC358743_CEC=y +CONFIG_VIDEO_TVP514X=m CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_TVP7002=m +CONFIG_VIDEO_TW2804=m +CONFIG_VIDEO_TW9903=m +CONFIG_VIDEO_TW9906=m +CONFIG_VIDEO_TW9910=m +CONFIG_VIDEO_VPX3220=m # # Video and audio decoders # +CONFIG_VIDEO_SAA717X=m CONFIG_VIDEO_CX25840=m # # Video encoders # +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +CONFIG_VIDEO_ADV7343=m +CONFIG_VIDEO_ADV7393=m +CONFIG_VIDEO_ADV7511=m +CONFIG_VIDEO_ADV7511_CEC=y +CONFIG_VIDEO_AD9389B=m +CONFIG_VIDEO_AK881X=m +CONFIG_VIDEO_THS8200=m # # Camera sensor devices # +CONFIG_VIDEO_APTINA_PLL=m +CONFIG_VIDEO_SMIAPP_PLL=m +CONFIG_VIDEO_IMX214=m +CONFIG_VIDEO_IMX258=m +CONFIG_VIDEO_IMX274=m +CONFIG_VIDEO_IMX319=m +CONFIG_VIDEO_IMX355=m CONFIG_VIDEO_OV2640=m +CONFIG_VIDEO_OV2659=m +CONFIG_VIDEO_OV2680=m +CONFIG_VIDEO_OV2685=m +CONFIG_VIDEO_OV5640=m +CONFIG_VIDEO_OV5645=m +CONFIG_VIDEO_OV5647=m +CONFIG_VIDEO_OV6650=m +CONFIG_VIDEO_OV5670=m +CONFIG_VIDEO_OV5675=m +CONFIG_VIDEO_OV5695=m +CONFIG_VIDEO_OV7251=m +CONFIG_VIDEO_OV772X=m +CONFIG_VIDEO_OV7640=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OV7740=m +CONFIG_VIDEO_OV8856=m +CONFIG_VIDEO_OV9640=m +CONFIG_VIDEO_OV9650=m +CONFIG_VIDEO_OV13858=m +CONFIG_VIDEO_VS6624=m +CONFIG_VIDEO_MT9M001=m +CONFIG_VIDEO_MT9M032=m +CONFIG_VIDEO_MT9M111=m +CONFIG_VIDEO_MT9P031=m +CONFIG_VIDEO_MT9T001=m +CONFIG_VIDEO_MT9T112=m CONFIG_VIDEO_MT9V011=m +CONFIG_VIDEO_MT9V032=m +CONFIG_VIDEO_MT9V111=m +CONFIG_VIDEO_SR030PC30=m +CONFIG_VIDEO_NOON010PC30=m +CONFIG_VIDEO_M5MOLS=m +CONFIG_VIDEO_RJ54N1=m +CONFIG_VIDEO_S5K6AA=m +CONFIG_VIDEO_S5K6A3=m +CONFIG_VIDEO_S5K4ECGX=m +CONFIG_VIDEO_S5K5BAF=m +CONFIG_VIDEO_SMIAPP=m +CONFIG_VIDEO_ET8EK8=m +CONFIG_VIDEO_S5C73M3=m + +# +# Lens drivers +# +CONFIG_VIDEO_AD5820=m +CONFIG_VIDEO_AK7375=m +CONFIG_VIDEO_DW9714=m +CONFIG_VIDEO_DW9807_VCM=m +CONFIG_VIDEO_HM5065=m # # Flash devices # +CONFIG_VIDEO_ADP1653=m +CONFIG_VIDEO_LM3560=m +CONFIG_VIDEO_LM3646=m # # Video improvement chips # +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m # # Audio/Video compression chips # +CONFIG_VIDEO_SAA6752HS=m # # SDR tuner chips # +CONFIG_SDR_MAX2175=m # # Miscellaneous helper chips # +CONFIG_VIDEO_THS7303=m +CONFIG_VIDEO_M52790=m +CONFIG_VIDEO_I2C=m +CONFIG_VIDEO_ST_MIPID02=m +# end of I2C Encoders, decoders, sensors and other helper chips # -# Sensors used on soc_camera driver +# SPI helper chips # +CONFIG_VIDEO_GS1662=m +# end of SPI helper chips # # Media SPI Adapters # CONFIG_CXD2880_SPI_DRV=m +# end of Media SPI Adapters + CONFIG_MEDIA_TUNER=m + +# +# Customize TV tuners +# CONFIG_MEDIA_TUNER_SIMPLE=m CONFIG_MEDIA_TUNER_TDA18250=m CONFIG_MEDIA_TUNER_TDA8290=m @@ -3655,6 +4447,7 @@ CONFIG_MEDIA_TUNER_MT20XX=m CONFIG_MEDIA_TUNER_MT2060=m CONFIG_MEDIA_TUNER_MT2063=m CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MT2131=m CONFIG_MEDIA_TUNER_QT1010=m CONFIG_MEDIA_TUNER_XC2028=m CONFIG_MEDIA_TUNER_XC5000=m @@ -3670,11 +4463,19 @@ CONFIG_MEDIA_TUNER_FC0013=m CONFIG_MEDIA_TUNER_TDA18212=m CONFIG_MEDIA_TUNER_E4000=m CONFIG_MEDIA_TUNER_FC2580=m +CONFIG_MEDIA_TUNER_M88RS6000T=m CONFIG_MEDIA_TUNER_TUA9001=m CONFIG_MEDIA_TUNER_SI2157=m CONFIG_MEDIA_TUNER_IT913X=m CONFIG_MEDIA_TUNER_R820T=m +CONFIG_MEDIA_TUNER_MXL301RF=m CONFIG_MEDIA_TUNER_QM1D1C0042=m +CONFIG_MEDIA_TUNER_QM1D1B0004=m +# end of Customize TV tuners + +# +# Customise DVB Frontends +# # # Multistandard (satellite) frontends @@ -3682,7 +4483,10 @@ CONFIG_MEDIA_TUNER_QM1D1C0042=m CONFIG_DVB_STB0899=m CONFIG_DVB_STB6100=m CONFIG_DVB_STV090x=m +CONFIG_DVB_STV0910=m CONFIG_DVB_STV6110x=m +CONFIG_DVB_STV6111=m +CONFIG_DVB_MXL5XX=m CONFIG_DVB_M88DS3103=m # @@ -3697,8 +4501,10 @@ CONFIG_DVB_MN88473=m # # DVB-S (satellite) frontends # +CONFIG_DVB_CX24110=m CONFIG_DVB_CX24123=m CONFIG_DVB_MT312=m +CONFIG_DVB_ZL10036=m CONFIG_DVB_ZL10039=m CONFIG_DVB_S5H1420=m CONFIG_DVB_STV0288=m @@ -3706,22 +4512,33 @@ CONFIG_DVB_STB6000=m CONFIG_DVB_STV0299=m CONFIG_DVB_STV6110=m CONFIG_DVB_STV0900=m +CONFIG_DVB_TDA8083=m CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8261=m +CONFIG_DVB_VES1X93=m CONFIG_DVB_TUNER_ITD1000=m CONFIG_DVB_TUNER_CX24113=m CONFIG_DVB_TDA826X=m +CONFIG_DVB_TUA6100=m CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24117=m CONFIG_DVB_CX24120=m CONFIG_DVB_SI21XX=m CONFIG_DVB_TS2020=m CONFIG_DVB_DS3000=m +CONFIG_DVB_MB86A16=m CONFIG_DVB_TDA10071=m # # DVB-T (terrestrial) frontends # +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_CX22700=m CONFIG_DVB_CX22702=m +CONFIG_DVB_S5H1432=m CONFIG_DVB_DRXD=m +CONFIG_DVB_L64781=m CONFIG_DVB_TDA1004X=m CONFIG_DVB_NXT6000=m CONFIG_DVB_MT352=m @@ -3730,10 +4547,13 @@ CONFIG_DVB_DIB3000MB=m CONFIG_DVB_DIB3000MC=m CONFIG_DVB_DIB7000M=m CONFIG_DVB_DIB7000P=m +CONFIG_DVB_DIB9000=m CONFIG_DVB_TDA10048=m CONFIG_DVB_AF9013=m CONFIG_DVB_EC100=m +CONFIG_DVB_STV0367=m CONFIG_DVB_CXD2820R=m +CONFIG_DVB_CXD2841ER=m CONFIG_DVB_RTL2830=m CONFIG_DVB_RTL2832=m CONFIG_DVB_RTL2832_SDR=m @@ -3741,10 +4561,13 @@ CONFIG_DVB_SI2168=m CONFIG_DVB_AS102_FE=m CONFIG_DVB_ZD1301_DEMOD=m CONFIG_DVB_GP8PSK_FE=m +CONFIG_DVB_CXD2880=m # # DVB-C (cable) frontends # +CONFIG_DVB_VES1820=m +CONFIG_DVB_TDA10021=m CONFIG_DVB_TDA10023=m CONFIG_DVB_STV0297=m @@ -3752,6 +4575,8 @@ CONFIG_DVB_STV0297=m # ATSC (North American/Korean Terrestrial/Cable DTV) frontends # CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_OR51132=m CONFIG_DVB_BCM3510=m CONFIG_DVB_LGDT330X=m CONFIG_DVB_LGDT3305=m @@ -3774,6 +4599,7 @@ CONFIG_DVB_MB86A20S=m # ISDB-S (satellite) & ISDB-T (terrestrial) frontends # CONFIG_DVB_TC90522=m +CONFIG_DVB_MN88443X=m # # Digital terrestrial only tuners/PLL @@ -3786,66 +4612,86 @@ CONFIG_DVB_TUNER_DIB0090=m # SEC control devices for DVB-S # CONFIG_DVB_DRX39XYJ=m +CONFIG_DVB_LNBH25=m +CONFIG_DVB_LNBH29=m CONFIG_DVB_LNBP21=m CONFIG_DVB_LNBP22=m +CONFIG_DVB_ISL6405=m CONFIG_DVB_ISL6421=m CONFIG_DVB_ISL6423=m CONFIG_DVB_A8293=m +CONFIG_DVB_LGS8GL5=m CONFIG_DVB_LGS8GXX=m CONFIG_DVB_ATBM8830=m +CONFIG_DVB_TDA665x=m CONFIG_DVB_IX2505V=m CONFIG_DVB_M88RS2000=m CONFIG_DVB_AF9033=m +CONFIG_DVB_HORUS3A=m +CONFIG_DVB_ASCOT2E=m +CONFIG_DVB_HELENE=m # # Common Interface (EN50221) controller drivers # +CONFIG_DVB_CXD2099=m CONFIG_DVB_SP2=m # # Tools to develop new frontends # +CONFIG_DVB_DUMMY_FE=m +# end of Customise DVB Frontends # # Graphics support # CONFIG_DRM=y +CONFIG_DRM_MIPI_DBI=m CONFIG_DRM_MIPI_DSI=y # CONFIG_DRM_DP_AUX_CHARDEV is not set # CONFIG_DRM_DEBUG_MM is not set +CONFIG_DRM_DEBUG_SELFTEST=m CONFIG_DRM_KMS_HELPER=y CONFIG_DRM_KMS_FB_HELPER=y CONFIG_DRM_FBDEV_EMULATION=y CONFIG_DRM_FBDEV_OVERALLOC=100 +# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set CONFIG_DRM_LOAD_EDID_FIRMWARE=y # CONFIG_DRM_DP_CEC is not set -CONFIG_DRM_TTM=m CONFIG_DRM_GEM_CMA_HELPER=y CONFIG_DRM_KMS_CMA_HELPER=y +CONFIG_DRM_GEM_SHMEM_HELPER=y CONFIG_DRM_SCHED=m # # I2C encoder or helper chips # -# CONFIG_DRM_I2C_CH7006 is not set -# CONFIG_DRM_I2C_SIL164 is not set +CONFIG_DRM_I2C_CH7006=m +CONFIG_DRM_I2C_SIL164=m # CONFIG_DRM_I2C_NXP_TDA998X is not set CONFIG_DRM_I2C_NXP_TDA9950=m +# end of I2C encoder or helper chips + +# +# ARM devices +# # CONFIG_DRM_HDLCD is not set # CONFIG_DRM_MALI_DISPLAY is not set +CONFIG_DRM_KOMEDA=m +# end of ARM devices # # ACP (Audio CoProcessor) Configuration # +# end of ACP (Audio CoProcessor) Configuration -# -# AMD Library routines -# # CONFIG_DRM_VGEM is not set CONFIG_DRM_VKMS=m # CONFIG_DRM_UDL is not set # CONFIG_DRM_RCAR_DW_HDMI is not set CONFIG_DRM_RCAR_LVDS=m +CONFIG_DRM_RCAR_WRITEBACK=y CONFIG_DRM_SUN4I=m CONFIG_DRM_SUN4I_HDMI=m CONFIG_DRM_SUN4I_HDMI_CEC=y @@ -3863,29 +4709,51 @@ CONFIG_DRM_PANEL=y CONFIG_DRM_PANEL_ARM_VERSATILE=m CONFIG_DRM_PANEL_LVDS=m CONFIG_DRM_PANEL_SIMPLE=m +CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D=m CONFIG_DRM_PANEL_ILITEK_IL9322=m CONFIG_DRM_PANEL_ILITEK_ILI9881C=m CONFIG_DRM_PANEL_INNOLUX_P079ZCA=m CONFIG_DRM_PANEL_JDI_LT070ME05000=m +CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04=m # CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set +CONFIG_DRM_PANEL_LG_LB035Q02=m # CONFIG_DRM_PANEL_LG_LG4573 is not set +CONFIG_DRM_PANEL_NEC_NL8048HL11=m +CONFIG_DRM_PANEL_NOVATEK_NT39016=m +CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO=m CONFIG_DRM_PANEL_ORISETECH_OTM8009A=m +# CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS is not set CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00=m CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN=m +CONFIG_DRM_PANEL_RAYDIUM_RM67191=m CONFIG_DRM_PANEL_RAYDIUM_RM68200=m +CONFIG_DRM_PANEL_ROCKTECH_JH057N00900=m +CONFIG_DRM_PANEL_RONBO_RB070D30=m +CONFIG_DRM_PANEL_SAMSUNG_S6D16D0=m CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2=m CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=m +# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set # CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set CONFIG_DRM_PANEL_SEIKO_43WVF1G=m CONFIG_DRM_PANEL_SHARP_LQ101R1SX01=m +CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m CONFIG_DRM_PANEL_SHARP_LS043T1LE01=m +CONFIG_DRM_PANEL_SITRONIX_ST7701=m # CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set +CONFIG_DRM_PANEL_SONY_ACX565AKM=m +CONFIG_DRM_PANEL_TPO_TD028TTEC1=m +CONFIG_DRM_PANEL_TPO_TD043MTEA1=m +CONFIG_DRM_PANEL_TPO_TPG110=m +CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m +# end of Display Panels + CONFIG_DRM_BRIDGE=y CONFIG_DRM_PANEL_BRIDGE=y # # Display Interface Bridges # +CONFIG_DRM_ANALOGIX_ANX78XX=m CONFIG_DRM_CDNS_DSI=m # CONFIG_DRM_DUMB_VGA_DAC is not set # CONFIG_DRM_LVDS_ENCODER is not set @@ -3896,32 +4764,47 @@ CONFIG_DRM_CDNS_DSI=m # CONFIG_DRM_SII902X is not set CONFIG_DRM_SII9234=m CONFIG_DRM_THINE_THC63LVD1024=m +CONFIG_DRM_TOSHIBA_TC358764=m # CONFIG_DRM_TOSHIBA_TC358767 is not set # CONFIG_DRM_TI_TFP410 is not set -CONFIG_DRM_ANALOGIX_DP_I2C=m -CONFIG_DRM_ANALOGIX_ANX78XX=m +CONFIG_DRM_TI_SN65DSI86=m CONFIG_DRM_ANALOGIX_ANX6345=m +CONFIG_DRM_ANALOGIX_DP=m # CONFIG_DRM_I2C_ADV7511 is not set CONFIG_DRM_DW_HDMI=m CONFIG_DRM_DW_HDMI_AHB_AUDIO=m CONFIG_DRM_DW_HDMI_I2S_AUDIO=m CONFIG_DRM_DW_HDMI_CEC=m +# end of Display Interface Bridges + +CONFIG_DRM_ETNAVIV=m +CONFIG_DRM_ETNAVIV_THERMAL=y # CONFIG_DRM_ARCPGU is not set # CONFIG_DRM_HISI_KIRIN is not set # CONFIG_DRM_MXSFB is not set -# CONFIG_DRM_TINYDRM is not set +CONFIG_DRM_GM12U320=m +CONFIG_TINYDRM_HX8357D=m +CONFIG_TINYDRM_ILI9225=m +CONFIG_TINYDRM_ILI9341=m +CONFIG_TINYDRM_MI0283QT=m +CONFIG_TINYDRM_REPAPER=m +CONFIG_TINYDRM_ST7586=m +CONFIG_TINYDRM_ST7735R=m # CONFIG_DRM_PL111 is not set +# CONFIG_DRM_XEN is not set CONFIG_DRM_LIMA=m +CONFIG_DRM_PANFROST=m # CONFIG_DRM_LEGACY is not set CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y +CONFIG_DRM_LIB_RANDOM=y # # Frame buffer Devices # -CONFIG_FB=y -# CONFIG_FIRMWARE_EDID is not set CONFIG_FB_CMDLINE=y CONFIG_FB_NOTIFY=y +CONFIG_FB=y +CONFIG_FIRMWARE_EDID=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y @@ -3931,7 +4814,7 @@ CONFIG_FB_SYS_IMAGEBLIT=y # CONFIG_FB_FOREIGN_ENDIAN is not set CONFIG_FB_SYS_FOPS=y CONFIG_FB_DEFERRED_IO=y -CONFIG_FB_BACKLIGHT=y +CONFIG_FB_BACKLIGHT=m CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set @@ -3940,17 +4823,24 @@ CONFIG_FB_MODE_HELPERS=y # # CONFIG_FB_ARMCLCD is not set # CONFIG_FB_UVESA is not set +# CONFIG_FB_EFI is not set # CONFIG_FB_OPENCORES is not set # CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_SUN5I_EINK is not set +CONFIG_FB_SM501=m # CONFIG_FB_SMSCUFX is not set # CONFIG_FB_UDL is not set # CONFIG_FB_IBM_GXT4500 is not set # CONFIG_FB_VIRTUAL is not set +CONFIG_XEN_FBDEV_FRONTEND=m # CONFIG_FB_METRONOME is not set -# CONFIG_FB_BROADSHEET is not set CONFIG_FB_SIMPLE=y # CONFIG_FB_SSD1307 is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y +# end of Frame buffer Devices + +# +# Backlight & LCD device support +# CONFIG_LCD_CLASS_DEVICE=m # CONFIG_LCD_L4F00242T03 is not set # CONFIG_LCD_LMS283GF05 is not set @@ -3960,26 +4850,40 @@ CONFIG_LCD_CLASS_DEVICE=m # CONFIG_LCD_TDO24M is not set # CONFIG_LCD_VGG2432A4 is not set # CONFIG_LCD_PLATFORM is not set -# CONFIG_LCD_S6E63M0 is not set -# CONFIG_LCD_LD9040 is not set # CONFIG_LCD_AMS369FG06 is not set # CONFIG_LCD_LMS501KF03 is not set # CONFIG_LCD_HX8357 is not set CONFIG_LCD_OTM3225A=m CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BACKLIGHT_GENERIC=m +CONFIG_BACKLIGHT_LM3533=m CONFIG_BACKLIGHT_PWM=m +CONFIG_BACKLIGHT_DA903X=m +CONFIG_BACKLIGHT_DA9052=m +CONFIG_BACKLIGHT_MAX8925=m # CONFIG_BACKLIGHT_PM8941_WLED is not set +CONFIG_BACKLIGHT_WM831X=m +CONFIG_BACKLIGHT_ADP5520=m # CONFIG_BACKLIGHT_ADP8860 is not set # CONFIG_BACKLIGHT_ADP8870 is not set +CONFIG_BACKLIGHT_88PM860X=m +CONFIG_BACKLIGHT_PCF50633=m +CONFIG_BACKLIGHT_AAT2870=m # CONFIG_BACKLIGHT_LM3630A is not set # CONFIG_BACKLIGHT_LM3639 is not set # CONFIG_BACKLIGHT_LP855X is not set +CONFIG_BACKLIGHT_LP8788=m +CONFIG_BACKLIGHT_PANDORA=m +CONFIG_BACKLIGHT_SKY81452=m +CONFIG_BACKLIGHT_TPS65217=m +CONFIG_BACKLIGHT_AS3711=m CONFIG_BACKLIGHT_GPIO=m # CONFIG_BACKLIGHT_LV5207LP is not set # CONFIG_BACKLIGHT_BD6107 is not set # CONFIG_BACKLIGHT_ARCXCNN is not set CONFIG_BACKLIGHT_RAVE_SP=m +# end of Backlight & LCD device support + CONFIG_VIDEOMODE_HELPERS=y CONFIG_HDMI=y @@ -3993,11 +4897,16 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y # CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set +CONFIG_BOOTSPLASH=y +# end of Console display driver support + CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set # CONFIG_LOGO_LINUX_CLUT224 is not set CONFIG_LOGO_ARMBIAN_CLUT224=y +# end of Graphics support + CONFIG_SOUND=m CONFIG_SND=m CONFIG_SND_TIMER=m @@ -4014,35 +4923,41 @@ CONFIG_SND_JACK_INPUT_DEV=y CONFIG_SND_PCM_TIMER=y # CONFIG_SND_HRTIMER is not set # CONFIG_SND_DYNAMIC_MINORS is not set -CONFIG_SND_SUPPORT_OLD_API=y +# CONFIG_SND_SUPPORT_OLD_API is not set CONFIG_SND_PROC_FS=y CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set CONFIG_SND_VMASTER=y CONFIG_SND_SEQUENCER=m -# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_SEQ_DUMMY=m CONFIG_SND_SEQ_MIDI_EVENT=m CONFIG_SND_SEQ_MIDI=m CONFIG_SND_SEQ_VIRMIDI=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_AC97_CODEC=m CONFIG_SND_DRIVERS=y CONFIG_SND_DUMMY=m CONFIG_SND_ALOOP=m CONFIG_SND_VIRMIDI=m -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set +CONFIG_SND_MTPAV=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +# CONFIG_SND_AC97_POWER_SAVE is not set # # HD-Audio # +# end of HD-Audio + CONFIG_SND_HDA_PREALLOC_SIZE=64 -# CONFIG_SND_SPI is not set +CONFIG_SND_SPI=y CONFIG_SND_USB=y CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y CONFIG_SND_USB_UA101=m CONFIG_SND_USB_CAIAQ=m -# CONFIG_SND_USB_CAIAQ_INPUT is not set +CONFIG_SND_USB_CAIAQ_INPUT=y CONFIG_SND_USB_6FIRE=m CONFIG_SND_USB_HIFACE=m CONFIG_SND_BCD2000=m @@ -4052,10 +4967,12 @@ CONFIG_SND_USB_PODHD=m CONFIG_SND_USB_TONEPORT=m CONFIG_SND_USB_VARIAX=m CONFIG_SND_SOC=m +CONFIG_SND_SOC_AC97_BUS=y CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y # CONFIG_SND_SOC_AMD_ACP is not set # CONFIG_SND_ATMEL_SOC is not set -# CONFIG_SND_DESIGNWARE_I2S is not set +CONFIG_SND_DESIGNWARE_I2S=m +# CONFIG_SND_DESIGNWARE_PCM is not set # # SoC Audio for Freescale CPUs @@ -4066,16 +4983,23 @@ CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y # # CONFIG_SND_SOC_FSL_ASRC is not set # CONFIG_SND_SOC_FSL_SAI is not set +CONFIG_SND_SOC_FSL_AUDMIX=m # CONFIG_SND_SOC_FSL_SSI is not set # CONFIG_SND_SOC_FSL_SPDIF is not set # CONFIG_SND_SOC_FSL_ESAI is not set +CONFIG_SND_SOC_FSL_MICFIL=m # CONFIG_SND_SOC_IMX_AUDMUX is not set +# end of SoC Audio for Freescale CPUs + # CONFIG_SND_I2S_HI6210_I2S is not set # CONFIG_SND_SOC_IMG is not set +CONFIG_SND_SOC_MTK_BTCVSD=m +# CONFIG_SND_SOC_SOF_TOPLEVEL is not set # # STMicroelectronics STM32 SOC audio support # +# end of STMicroelectronics STM32 SOC audio support # # Allwinner SoC Audio support @@ -4087,6 +5011,11 @@ CONFIG_SND_SUN50I_CODEC_ANALOG=m CONFIG_SND_SUN4I_I2S=m CONFIG_SND_SUN4I_SPDIF=m CONFIG_SND_SUN8I_ADDA_PR_REGMAP=m +# end of Allwinner SoC Audio support + +CONFIG_SND_SOC_XILINX_I2S=m +CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER=m +CONFIG_SND_SOC_XILINX_SPDIF=m # CONFIG_SND_SOC_XTFPGA_I2S is not set # CONFIG_ZX_TDM is not set CONFIG_SND_SOC_I2C_AND_SPI=m @@ -4094,7 +5023,7 @@ CONFIG_SND_SOC_I2C_AND_SPI=m # # CODEC drivers # -# CONFIG_SND_SOC_AC97_CODEC is not set +CONFIG_SND_SOC_AC97_CODEC=m CONFIG_SND_SOC_ADAU_UTILS=m CONFIG_SND_SOC_ADAU1701=m CONFIG_SND_SOC_ADAU17X1=m @@ -4103,6 +5032,7 @@ CONFIG_SND_SOC_ADAU1761_I2C=m CONFIG_SND_SOC_ADAU1761_SPI=m CONFIG_SND_SOC_ADAU7002=m CONFIG_SND_SOC_AK4104=m +CONFIG_SND_SOC_AK4118=m CONFIG_SND_SOC_AK4458=m CONFIG_SND_SOC_AK4554=m CONFIG_SND_SOC_AK4613=m @@ -4112,10 +5042,12 @@ CONFIG_SND_SOC_AK5558=m CONFIG_SND_SOC_ALC5623=m CONFIG_SND_SOC_BD28623=m CONFIG_SND_SOC_BT_SCO=m +CONFIG_SND_SOC_CPCAP=m CONFIG_SND_SOC_CS35L32=m CONFIG_SND_SOC_CS35L33=m CONFIG_SND_SOC_CS35L34=m CONFIG_SND_SOC_CS35L35=m +CONFIG_SND_SOC_CS35L36=m CONFIG_SND_SOC_CS42L42=m CONFIG_SND_SOC_CS42L51=m CONFIG_SND_SOC_CS42L51_I2C=m @@ -4130,8 +5062,11 @@ CONFIG_SND_SOC_CS4271_SPI=m CONFIG_SND_SOC_CS42XX8=m CONFIG_SND_SOC_CS42XX8_I2C=m CONFIG_SND_SOC_CS43130=m +CONFIG_SND_SOC_CS4341=m CONFIG_SND_SOC_CS4349=m CONFIG_SND_SOC_CS53L30=m +CONFIG_SND_SOC_CX2072X=m +CONFIG_SND_SOC_DMIC=m CONFIG_SND_SOC_HDMI_CODEC=m CONFIG_SND_SOC_ES7134=m CONFIG_SND_SOC_ES7241=m @@ -4139,60 +5074,75 @@ CONFIG_SND_SOC_ES8316=m CONFIG_SND_SOC_ES8328=m CONFIG_SND_SOC_ES8328_I2C=m CONFIG_SND_SOC_ES8328_SPI=m -# CONFIG_SND_SOC_GTM601 is not set -# CONFIG_SND_SOC_INNO_RK3036 is not set -# CONFIG_SND_SOC_MAX98504 is not set +CONFIG_SND_SOC_GTM601=m +CONFIG_SND_SOC_INNO_RK3036=m +CONFIG_SND_SOC_MAX98088=m +# CONFIG_SND_SOC_MAX98357A is not set +CONFIG_SND_SOC_MAX98504=m CONFIG_SND_SOC_MAX9867=m -# CONFIG_SND_SOC_MAX98927 is not set +CONFIG_SND_SOC_MAX98927=m CONFIG_SND_SOC_MAX98373=m -# CONFIG_SND_SOC_MAX9860 is not set -# CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set -# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set -# CONFIG_SND_SOC_PCM1681 is not set +CONFIG_SND_SOC_MAX9860=m +CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m +CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m +CONFIG_SND_SOC_PCM1681=m CONFIG_SND_SOC_PCM1789=m CONFIG_SND_SOC_PCM1789_I2C=m -# CONFIG_SND_SOC_PCM179X_I2C is not set -# CONFIG_SND_SOC_PCM179X_SPI is not set +CONFIG_SND_SOC_PCM179X=m +CONFIG_SND_SOC_PCM179X_I2C=m +CONFIG_SND_SOC_PCM179X_SPI=m CONFIG_SND_SOC_PCM186X=m CONFIG_SND_SOC_PCM186X_I2C=m CONFIG_SND_SOC_PCM186X_SPI=m -# CONFIG_SND_SOC_PCM3168A_I2C is not set -# CONFIG_SND_SOC_PCM3168A_SPI is not set -# CONFIG_SND_SOC_PCM512x_I2C is not set -# CONFIG_SND_SOC_PCM512x_SPI is not set -# CONFIG_SND_SOC_RT5616 is not set -# CONFIG_SND_SOC_RT5631 is not set -# CONFIG_SND_SOC_SGTL5000 is not set +CONFIG_SND_SOC_PCM3060=m +CONFIG_SND_SOC_PCM3060_I2C=m +CONFIG_SND_SOC_PCM3060_SPI=m +CONFIG_SND_SOC_PCM3168A=m +CONFIG_SND_SOC_PCM3168A_I2C=m +CONFIG_SND_SOC_PCM3168A_SPI=m +CONFIG_SND_SOC_PCM5102A=m +CONFIG_SND_SOC_PCM512x=m +CONFIG_SND_SOC_PCM512x_I2C=m +CONFIG_SND_SOC_PCM512x_SPI=m +CONFIG_SND_SOC_RK3328=m +CONFIG_SND_SOC_RL6231=m +CONFIG_SND_SOC_RT5616=m +CONFIG_SND_SOC_RT5631=m +CONFIG_SND_SOC_SGTL5000=m +CONFIG_SND_SOC_SI476X=m CONFIG_SND_SOC_SIGMADSP=m CONFIG_SND_SOC_SIGMADSP_I2C=m CONFIG_SND_SOC_SIGMADSP_REGMAP=m CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m -# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set +CONFIG_SND_SOC_SIRF_AUDIO_CODEC=m CONFIG_SND_SOC_SPDIF=m CONFIG_SND_SOC_SSM2305=m -# CONFIG_SND_SOC_SSM2602_SPI is not set -# CONFIG_SND_SOC_SSM2602_I2C is not set -# CONFIG_SND_SOC_SSM4567 is not set -# CONFIG_SND_SOC_STA32X is not set -# CONFIG_SND_SOC_STA350 is not set -# CONFIG_SND_SOC_STI_SAS is not set -# CONFIG_SND_SOC_TAS2552 is not set -# CONFIG_SND_SOC_TAS5086 is not set -# CONFIG_SND_SOC_TAS571X is not set -# CONFIG_SND_SOC_TAS5720 is not set +CONFIG_SND_SOC_SSM2602=m +CONFIG_SND_SOC_SSM2602_SPI=m +CONFIG_SND_SOC_SSM2602_I2C=m +CONFIG_SND_SOC_SSM4567=m +CONFIG_SND_SOC_STA32X=m +CONFIG_SND_SOC_STA350=m +CONFIG_SND_SOC_STI_SAS=m +CONFIG_SND_SOC_TAS2552=m +CONFIG_SND_SOC_TAS5086=m +CONFIG_SND_SOC_TAS571X=m +CONFIG_SND_SOC_TAS5720=m CONFIG_SND_SOC_TAS6424=m CONFIG_SND_SOC_TDA7419=m -# CONFIG_SND_SOC_TFA9879 is not set -# CONFIG_SND_SOC_TLV320AIC23_I2C is not set -# CONFIG_SND_SOC_TLV320AIC23_SPI is not set -# CONFIG_SND_SOC_TLV320AIC31XX is not set +CONFIG_SND_SOC_TFA9879=m +CONFIG_SND_SOC_TLV320AIC23=m +CONFIG_SND_SOC_TLV320AIC23_I2C=m +CONFIG_SND_SOC_TLV320AIC23_SPI=m +CONFIG_SND_SOC_TLV320AIC31XX=m CONFIG_SND_SOC_TLV320AIC32X4=m CONFIG_SND_SOC_TLV320AIC32X4_I2C=m -# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set -# CONFIG_SND_SOC_TLV320AIC3X is not set -# CONFIG_SND_SOC_TS3A227E is not set -# CONFIG_SND_SOC_TSCS42XX is not set +CONFIG_SND_SOC_TLV320AIC32X4_SPI=m +CONFIG_SND_SOC_TLV320AIC3X=m +CONFIG_SND_SOC_TS3A227E=m +CONFIG_SND_SOC_TSCS42XX=m CONFIG_SND_SOC_TSCS454=m +CONFIG_SND_SOC_UDA1334=m CONFIG_SND_SOC_WM8510=m CONFIG_SND_SOC_WM8523=m CONFIG_SND_SOC_WM8524=m @@ -4211,23 +5161,28 @@ CONFIG_SND_SOC_WM8804=m CONFIG_SND_SOC_WM8804_I2C=m CONFIG_SND_SOC_WM8804_SPI=m CONFIG_SND_SOC_WM8903=m +CONFIG_SND_SOC_WM8904=m CONFIG_SND_SOC_WM8960=m CONFIG_SND_SOC_WM8962=m CONFIG_SND_SOC_WM8974=m CONFIG_SND_SOC_WM8978=m CONFIG_SND_SOC_WM8985=m -# CONFIG_SND_SOC_ZX_AUD96P22 is not set +CONFIG_SND_SOC_ZX_AUD96P22=m CONFIG_SND_SOC_MAX9759=m CONFIG_SND_SOC_MT6351=m -# CONFIG_SND_SOC_NAU8540 is not set -# CONFIG_SND_SOC_NAU8810 is not set -# CONFIG_SND_SOC_NAU8824 is not set -# CONFIG_SND_SOC_TPA6130A2 is not set +CONFIG_SND_SOC_MT6358=m +CONFIG_SND_SOC_NAU8540=m +CONFIG_SND_SOC_NAU8810=m +CONFIG_SND_SOC_NAU8822=m +CONFIG_SND_SOC_NAU8824=m +CONFIG_SND_SOC_TPA6130A2=m +# end of CODEC drivers + CONFIG_SND_SIMPLE_CARD_UTILS=m CONFIG_SND_SIMPLE_CARD=m -CONFIG_SND_SIMPLE_SCU_CARD=m -# CONFIG_SND_AUDIO_GRAPH_CARD is not set -# CONFIG_SND_AUDIO_GRAPH_SCU_CARD is not set +CONFIG_SND_AUDIO_GRAPH_CARD=m +CONFIG_SND_XEN_FRONTEND=m +CONFIG_AC97_BUS=m # # HID support @@ -4251,13 +5206,16 @@ CONFIG_HID_APPLEIR=m CONFIG_HID_AUREAL=m CONFIG_HID_BELKIN=m CONFIG_HID_BETOP_FF=m +CONFIG_HID_BIGBEN_FF=m CONFIG_HID_CHERRY=m CONFIG_HID_CHICONY=m CONFIG_HID_CORSAIR=m CONFIG_HID_COUGAR=m +CONFIG_HID_MACALLY=m CONFIG_HID_PRODIKEYS=m -# CONFIG_HID_CMEDIA is not set +CONFIG_HID_CMEDIA=m CONFIG_HID_CP2112=m +CONFIG_HID_CREATIVE_SB0540=m CONFIG_HID_CYPRESS=m CONFIG_HID_DRAGONRISE=m CONFIG_DRAGONRISE_FF=y @@ -4270,16 +5228,16 @@ CONFIG_HID_GEMBIRD=m CONFIG_HID_GFRM=m CONFIG_HID_HOLTEK=m CONFIG_HOLTEK_FF=y -CONFIG_HID_GOOGLE_HAMMER=m CONFIG_HID_GT683R=m CONFIG_HID_KEYTOUCH=m CONFIG_HID_KYE=m CONFIG_HID_UCLOGIC=m CONFIG_HID_WALTOP=m +CONFIG_HID_VIEWSONIC=m CONFIG_HID_GYRATION=m CONFIG_HID_ICADE=m -# CONFIG_HID_ITE is not set -# CONFIG_HID_JABRA is not set +CONFIG_HID_ITE=m +CONFIG_HID_JABRA=m CONFIG_HID_TWINHAN=m CONFIG_HID_KENSINGTON=m CONFIG_HID_LCPOWER=m @@ -4293,6 +5251,7 @@ CONFIG_LOGIRUMBLEPAD2_FF=y CONFIG_LOGIG940_FF=y CONFIG_LOGIWHEELS_FF=y CONFIG_HID_MAGICMOUSE=m +CONFIG_HID_MALTRON=m # CONFIG_HID_MAYFLASH is not set CONFIG_HID_REDRAGON=m CONFIG_HID_MICROSOFT=m @@ -4313,7 +5272,7 @@ CONFIG_HID_PICOLCD_LEDS=y CONFIG_HID_PICOLCD_CIR=y CONFIG_HID_PLANTRONICS=m CONFIG_HID_PRIMAX=m -# CONFIG_HID_RETRODE is not set +CONFIG_HID_RETRODE=m CONFIG_HID_ROCCAT=m CONFIG_HID_SAITEK=m CONFIG_HID_SAMSUNG=m @@ -4333,7 +5292,8 @@ CONFIG_HID_TOPSEED=m CONFIG_HID_THINGM=m CONFIG_HID_THRUSTMASTER=m CONFIG_THRUSTMASTER_FF=y -# CONFIG_HID_UDRAW_PS3 is not set +CONFIG_HID_UDRAW_PS3=m +CONFIG_HID_U2FZERO=m CONFIG_HID_WACOM=m CONFIG_HID_WIIMOTE=m CONFIG_HID_XINMO=m @@ -4343,6 +5303,7 @@ CONFIG_HID_ZYDACRON=m CONFIG_HID_SENSOR_HUB=m CONFIG_HID_SENSOR_CUSTOM_SENSOR=m CONFIG_HID_ALPS=m +# end of Special HID drivers # # USB HID support @@ -4350,14 +5311,21 @@ CONFIG_HID_ALPS=m CONFIG_USB_HID=y CONFIG_HID_PID=y CONFIG_USB_HIDDEV=y +# end of USB HID support # # I2C HID support # CONFIG_I2C_HID=m +# end of I2C HID support +# end of HID support + CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_SUPPORT=y CONFIG_USB_COMMON=y +CONFIG_USB_LED_TRIG=y +CONFIG_USB_ULPI_BUS=y +CONFIG_USB_CONN_GPIO=m CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y @@ -4370,10 +5338,10 @@ CONFIG_USB_DEFAULT_PERSIST=y CONFIG_USB_OTG=y # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set -# CONFIG_USB_OTG_FSM is not set +CONFIG_USB_OTG_FSM=m CONFIG_USB_LEDS_TRIGGER_USBPORT=y +CONFIG_USB_AUTOSUSPEND_DELAY=2 CONFIG_USB_MON=m -# CONFIG_USB_WUSB_CBAF is not set # # USB Host Controller Drivers @@ -4385,6 +5353,7 @@ CONFIG_USB_XHCI_PLATFORM=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_EHCI_FSL is not set CONFIG_USB_EHCI_HCD_PLATFORM=y # CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set @@ -4392,9 +5361,10 @@ CONFIG_USB_EHCI_HCD_PLATFORM=y # CONFIG_USB_MAX3421_HCD is not set CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_U132_HCD=m # CONFIG_USB_SL811_HCD is not set # CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_HCD_BCMA is not set +CONFIG_USB_HCD_BCMA=m # CONFIG_USB_HCD_SSB is not set # CONFIG_USB_HCD_TEST_MODE is not set @@ -4404,7 +5374,7 @@ CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_ACM=m CONFIG_USB_PRINTER=m CONFIG_USB_WDM=m -# CONFIG_USB_TMC is not set +CONFIG_USB_TMC=m # # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may @@ -4415,26 +5385,27 @@ CONFIG_USB_WDM=m # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_REALTEK is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_STORAGE_ENE_UB6250 is not set +CONFIG_USB_STORAGE_REALTEK=m +CONFIG_REALTEK_AUTOPM=y +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +CONFIG_USB_STORAGE_ENE_UB6250=m CONFIG_USB_UAS=m # # USB Imaging devices # -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m CONFIG_USBIP_CORE=m CONFIG_USBIP_VHCI_HCD=m CONFIG_USBIP_VHCI_HC_PORTS=8 @@ -4442,6 +5413,9 @@ CONFIG_USBIP_VHCI_NR_HCS=1 CONFIG_USBIP_HOST=m CONFIG_USBIP_VUDC=m # CONFIG_USBIP_DEBUG is not set +CONFIG_USB_CDNS3=m +# CONFIG_USB_CDNS3_GADGET is not set +# CONFIG_USB_CDNS3_HOST is not set CONFIG_USB_MUSB_HDRC=y # CONFIG_USB_MUSB_HOST is not set # CONFIG_USB_MUSB_GADGET is not set @@ -4457,6 +5431,7 @@ CONFIG_USB_MUSB_SUNXI=y # # CONFIG_MUSB_PIO_ONLY is not set CONFIG_USB_DWC3=y +# CONFIG_USB_DWC3_ULPI is not set # CONFIG_USB_DWC3_HOST is not set # CONFIG_USB_DWC3_GADGET is not set CONFIG_USB_DWC3_DUAL_ROLE=y @@ -4475,8 +5450,16 @@ CONFIG_USB_DWC2=y CONFIG_USB_DWC2_DUAL_ROLE=y # CONFIG_USB_DWC2_DEBUG is not set # CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set -# CONFIG_USB_CHIPIDEA is not set -# CONFIG_USB_ISP1760 is not set +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_OF=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_USB_ISP1760=y +CONFIG_USB_ISP1760_HCD=y +CONFIG_USB_ISP1761_UDC=y +# CONFIG_USB_ISP1760_HOST_ROLE is not set +# CONFIG_USB_ISP1760_GADGET_ROLE is not set +CONFIG_USB_ISP1760_DUAL_ROLE=y # # USB port drivers @@ -4540,31 +5523,37 @@ CONFIG_USB_SERIAL_DEBUG=m # # USB Miscellaneous drivers # -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_EHSET_TEST_FIXTURE is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_YUREX is not set +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_TEST=m +CONFIG_USB_EHSET_TEST_FIXTURE=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_YUREX=m CONFIG_USB_EZUSB_FX2=m CONFIG_USB_HUB_USB251XB=m -# CONFIG_USB_HSIC_USB3503 is not set +CONFIG_USB_HSIC_USB3503=y # CONFIG_USB_HSIC_USB4604 is not set -# CONFIG_USB_LINK_LAYER_TEST is not set +CONFIG_USB_LINK_LAYER_TEST=m +CONFIG_USB_CHAOSKEY=m +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m # # USB Physical Layer drivers @@ -4572,9 +5561,15 @@ CONFIG_USB_HUB_USB251XB=m CONFIG_USB_PHY=y CONFIG_NOP_USB_XCEIV=y # CONFIG_USB_GPIO_VBUS is not set +CONFIG_TAHVO_USB=m +# CONFIG_TAHVO_USB_HOST_BY_DEFAULT is not set # CONFIG_USB_ISP1301 is not set -# CONFIG_USB_ULPI is not set +CONFIG_USB_ULPI=y +CONFIG_USB_ULPI_VIEWPORT=y +# end of USB Physical Layer drivers + CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FILES is not set # CONFIG_USB_GADGET_DEBUG_FS is not set CONFIG_USB_GADGET_VBUS_DRAW=2 @@ -4596,6 +5591,8 @@ CONFIG_U_SERIAL_CONSOLE=y # CONFIG_USB_NET2272 is not set # CONFIG_USB_GADGET_XILINX is not set # CONFIG_USB_DUMMY_HCD is not set +# end of USB Peripheral Controller + CONFIG_USB_LIBCOMPOSITE=m CONFIG_USB_F_ACM=m CONFIG_USB_F_SS_LB=m @@ -4606,6 +5603,7 @@ CONFIG_USB_F_SERIAL=m CONFIG_USB_F_OBEX=m CONFIG_USB_F_NCM=m CONFIG_USB_F_ECM=m +CONFIG_USB_F_PHONET=m CONFIG_USB_F_EEM=m CONFIG_USB_F_SUBSET=m CONFIG_USB_F_RNDIS=m @@ -4626,6 +5624,7 @@ CONFIG_USB_CONFIGFS_ECM=y CONFIG_USB_CONFIGFS_ECM_SUBSET=y CONFIG_USB_CONFIGFS_RNDIS=y CONFIG_USB_CONFIGFS_EEM=y +# CONFIG_USB_CONFIGFS_PHONET is not set CONFIG_USB_CONFIGFS_MASS_STORAGE=y CONFIG_USB_CONFIGFS_F_LB_SS=y CONFIG_USB_CONFIGFS_F_FS=y @@ -4654,6 +5653,7 @@ CONFIG_USB_G_SERIAL=m CONFIG_USB_MIDI_GADGET=m CONFIG_USB_G_PRINTER=m CONFIG_USB_CDC_COMPOSITE=m +CONFIG_USB_G_NOKIA=m CONFIG_USB_G_ACM_MS=m CONFIG_USB_G_MULTI=m CONFIG_USB_G_MULTI_RNDIS=y @@ -4662,26 +5662,31 @@ CONFIG_USB_G_HID=m # CONFIG_USB_G_DBGP is not set CONFIG_USB_G_WEBCAM=m CONFIG_TYPEC=m -# CONFIG_TYPEC_TCPM is not set -# CONFIG_TYPEC_UCSI is not set +CONFIG_TYPEC_TCPM=m +CONFIG_TYPEC_TCPCI=m +CONFIG_TYPEC_RT1711H=m +CONFIG_TYPEC_FUSB302=m +CONFIG_TYPEC_UCSI=m +CONFIG_UCSI_CCG=m CONFIG_TYPEC_TPS6598X=m # # USB Type-C Multiplexer/DeMultiplexer Switch support # CONFIG_TYPEC_MUX_PI3USB30532=m +# end of USB Type-C Multiplexer/DeMultiplexer Switch support # # USB Type-C Alternate Mode drivers # CONFIG_TYPEC_DP_ALTMODE=m -CONFIG_USB_ROLE_SWITCH=m -CONFIG_USB_LED_TRIG=y -# CONFIG_USB_ULPI_BUS is not set -# CONFIG_UWB is not set +# CONFIG_TYPEC_NVIDIA_ALTMODE is not set +# end of USB Type-C Alternate Mode drivers + +CONFIG_USB_ROLE_SWITCH=y CONFIG_MMC=y CONFIG_PWRSEQ_EMMC=y -# CONFIG_PWRSEQ_SD8787 is not set +CONFIG_PWRSEQ_SD8787=m CONFIG_PWRSEQ_SIMPLE=y CONFIG_MMC_BLOCK=y CONFIG_MMC_BLOCK_MINORS=32 @@ -4693,9 +5698,12 @@ CONFIG_MMC_BLOCK_MINORS=32 # # CONFIG_MMC_DEBUG is not set CONFIG_MMC_ARMMMCI=y +CONFIG_MMC_STM32_SDMMC=y CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_IO_ACCESSORS=y CONFIG_MMC_SDHCI_PLTFM=y # CONFIG_MMC_SDHCI_OF_ARASAN is not set +CONFIG_MMC_SDHCI_OF_ASPEED=m # CONFIG_MMC_SDHCI_OF_AT91 is not set # CONFIG_MMC_SDHCI_OF_DWCMSHC is not set # CONFIG_MMC_SDHCI_CADENCE is not set @@ -4710,12 +5718,12 @@ CONFIG_MMC_DW_K3=y # CONFIG_MMC_VUB300 is not set # CONFIG_MMC_USHC is not set # CONFIG_MMC_USDHI6ROL0 is not set -CONFIG_MMC_REALTEK_USB=m CONFIG_MMC_SUNXI=y # CONFIG_MMC_CQHCI is not set # CONFIG_MMC_MTK is not set # CONFIG_MMC_SDHCI_XENON is not set # CONFIG_MMC_SDHCI_OMAP is not set +CONFIG_MMC_SDHCI_AM654=m # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y @@ -4725,12 +5733,18 @@ CONFIG_LEDS_CLASS=y # # LED drivers # +CONFIG_LEDS_88PM860X=m +CONFIG_LEDS_AN30259A=m # CONFIG_LEDS_BCM6328 is not set # CONFIG_LEDS_BCM6358 is not set +CONFIG_LEDS_CPCAP=m CONFIG_LEDS_CR0014114=m # CONFIG_LEDS_LM3530 is not set +CONFIG_LEDS_LM3532=m +CONFIG_LEDS_LM3533=m # CONFIG_LEDS_LM3642 is not set CONFIG_LEDS_LM3692X=m +CONFIG_LEDS_MT6323=m # CONFIG_LEDS_PCA9532 is not set CONFIG_LEDS_GPIO=y # CONFIG_LEDS_LP3944 is not set @@ -4739,17 +5753,27 @@ CONFIG_LEDS_GPIO=y # CONFIG_LEDS_LP5523 is not set # CONFIG_LEDS_LP5562 is not set # CONFIG_LEDS_LP8501 is not set +CONFIG_LEDS_LP8788=m # CONFIG_LEDS_LP8860 is not set # CONFIG_LEDS_PCA955X is not set # CONFIG_LEDS_PCA963X is not set +CONFIG_LEDS_WM831X_STATUS=m +CONFIG_LEDS_WM8350=m +CONFIG_LEDS_DA903X=m +CONFIG_LEDS_DA9052=m # CONFIG_LEDS_DAC124S085 is not set CONFIG_LEDS_PWM=m CONFIG_LEDS_REGULATOR=m # CONFIG_LEDS_BD2802 is not set # CONFIG_LEDS_LT3593 is not set +CONFIG_LEDS_ADP5520=m +CONFIG_LEDS_MC13783=m # CONFIG_LEDS_TCA6507 is not set # CONFIG_LEDS_TLC591XX is not set +CONFIG_LEDS_MAX77650=m +CONFIG_LEDS_MAX8997=m # CONFIG_LEDS_LM355x is not set +CONFIG_LEDS_MENF21BMC=m # CONFIG_LEDS_IS31FL319X is not set # CONFIG_LEDS_IS31FL32XX is not set @@ -4760,6 +5784,8 @@ CONFIG_LEDS_REGULATOR=m CONFIG_LEDS_SYSCON=y CONFIG_LEDS_MLXREG=m CONFIG_LEDS_USER=y +# CONFIG_LEDS_SPI_BYTE is not set +# CONFIG_LEDS_TI_LMU_COMMON is not set CONFIG_LEDS_AXP20X=m # @@ -4784,6 +5810,8 @@ CONFIG_LEDS_TRIGGER_TRANSIENT=m CONFIG_LEDS_TRIGGER_CAMERA=m CONFIG_LEDS_TRIGGER_PANIC=y CONFIG_LEDS_TRIGGER_NETDEV=m +CONFIG_LEDS_TRIGGER_PATTERN=m +CONFIG_LEDS_TRIGGER_AUDIO=m # CONFIG_ACCESSIBILITY is not set # CONFIG_INFINIBAND is not set CONFIG_EDAC_SUPPORT=y @@ -4800,7 +5828,7 @@ CONFIG_RTC_NVMEM=y # RTC interfaces # CONFIG_RTC_INTF_SYSFS=y -# CONFIG_RTC_INTF_PROC is not set +CONFIG_RTC_INTF_PROC=y CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set # CONFIG_RTC_DRV_TEST is not set @@ -4808,15 +5836,26 @@ CONFIG_RTC_INTF_DEV=y # # I2C RTC drivers # +CONFIG_RTC_DRV_88PM860X=m +CONFIG_RTC_DRV_88PM80X=m CONFIG_RTC_DRV_ABB5ZES3=m +CONFIG_RTC_DRV_ABEOZ9=m CONFIG_RTC_DRV_ABX80X=m +CONFIG_RTC_DRV_AS3722=m CONFIG_RTC_DRV_DS1307=m CONFIG_RTC_DRV_DS1307_CENTURY=y CONFIG_RTC_DRV_DS1374=m CONFIG_RTC_DRV_DS1374_WDT=y CONFIG_RTC_DRV_DS1672=m CONFIG_RTC_DRV_HYM8563=m +CONFIG_RTC_DRV_LP8788=m CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX8907=m +CONFIG_RTC_DRV_MAX8925=m +CONFIG_RTC_DRV_MAX8998=m +CONFIG_RTC_DRV_MAX8997=m +CONFIG_RTC_DRV_MAX77686=m +CONFIG_RTC_DRV_RK808=m CONFIG_RTC_DRV_RS5C372=m CONFIG_RTC_DRV_ISL1208=m CONFIG_RTC_DRV_ISL12022=m @@ -4830,14 +5869,22 @@ CONFIG_RTC_DRV_PCF8583=m CONFIG_RTC_DRV_M41T80=m CONFIG_RTC_DRV_M41T80_WDT=y CONFIG_RTC_DRV_BQ32K=m +CONFIG_RTC_DRV_TWL4030=m +CONFIG_RTC_DRV_PALMAS=m +CONFIG_RTC_DRV_TPS6586X=m +CONFIG_RTC_DRV_TPS65910=m +CONFIG_RTC_DRV_TPS80031=m +CONFIG_RTC_DRV_RC5T583=m CONFIG_RTC_DRV_S35390A=m CONFIG_RTC_DRV_FM3130=m CONFIG_RTC_DRV_RX8010=m CONFIG_RTC_DRV_RX8581=m CONFIG_RTC_DRV_RX8025=m CONFIG_RTC_DRV_EM3027=m +CONFIG_RTC_DRV_RV3028=m CONFIG_RTC_DRV_RV8803=m CONFIG_RTC_DRV_S5M=m +CONFIG_RTC_DRV_SD3078=m # # SPI RTC drivers @@ -4877,6 +5924,10 @@ CONFIG_RTC_DRV_RV3029_HWMON=y # CONFIG_RTC_DRV_DS1685_FAMILY is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_DS2404 is not set +CONFIG_RTC_DRV_DA9052=m +CONFIG_RTC_DRV_DA9055=m +CONFIG_RTC_DRV_DA9063=m +CONFIG_RTC_DRV_EFI=m # CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set @@ -4885,6 +5936,10 @@ CONFIG_RTC_DRV_RV3029_HWMON=y # CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set +CONFIG_RTC_DRV_WM831X=m +CONFIG_RTC_DRV_WM8350=m +CONFIG_RTC_DRV_PCF50633=m +CONFIG_RTC_DRV_AB3100=m # CONFIG_RTC_DRV_ZYNQMP is not set # @@ -4893,20 +5948,26 @@ CONFIG_RTC_DRV_RV3029_HWMON=y CONFIG_RTC_DRV_PL030=m CONFIG_RTC_DRV_PL031=m CONFIG_RTC_DRV_SUN6I=y +CONFIG_RTC_DRV_CADENCE=m # CONFIG_RTC_DRV_FTRTC010 is not set +CONFIG_RTC_DRV_PCAP=m +CONFIG_RTC_DRV_MC13XXX=m # CONFIG_RTC_DRV_SNVS is not set +CONFIG_RTC_DRV_MT6397=m # CONFIG_RTC_DRV_R7301 is not set +CONFIG_RTC_DRV_CPCAP=m # # HID Sensor RTC drivers # -# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set +CONFIG_RTC_DRV_HID_SENSOR_TIME=m CONFIG_DMADEVICES=y # CONFIG_DMADEVICES_DEBUG is not set # # DMA Devices # +CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y CONFIG_DMA_ENGINE=y CONFIG_DMA_VIRTUAL_CHANNELS=y CONFIG_DMA_OF=y @@ -4916,13 +5977,14 @@ CONFIG_ALTERA_MSGDMA=m CONFIG_DMA_SUN6I=y CONFIG_DW_AXI_DMAC=m # CONFIG_FSL_EDMA is not set +CONFIG_FSL_QDMA=m # CONFIG_INTEL_IDMA64 is not set -# CONFIG_MV_XOR_V2 is not set -# CONFIG_PL330_DMA is not set +CONFIG_MV_XOR_V2=y +CONFIG_PL330_DMA=y # CONFIG_XILINX_DMA is not set # CONFIG_XILINX_ZYNQMP_DMA is not set -# CONFIG_QCOM_HIDMA_MGMT is not set -# CONFIG_QCOM_HIDMA is not set +CONFIG_QCOM_HIDMA_MGMT=y +CONFIG_QCOM_HIDMA=y # CONFIG_DW_DMAC is not set # @@ -4930,12 +5992,17 @@ CONFIG_DW_AXI_DMAC=m # # CONFIG_ASYNC_TX_DMA is not set # CONFIG_DMATEST is not set +CONFIG_DMA_ENGINE_RAID=y # # DMABUF options # CONFIG_SYNC_FILE=y # CONFIG_SW_SYNC is not set +# CONFIG_UDMABUF is not set +CONFIG_DMABUF_SELFTESTS=m +# end of DMABUF options + # CONFIG_AUXDISPLAY is not set # CONFIG_UIO is not set # CONFIG_VFIO is not set @@ -4950,14 +6017,43 @@ CONFIG_VIRTIO_MMIO=y # # Microsoft Hyper-V guest support # +# end of Microsoft Hyper-V guest support + +# +# Xen driver support +# +CONFIG_XEN_BALLOON=y +CONFIG_XEN_SCRUB_PAGES_DEFAULT=y +CONFIG_XEN_DEV_EVTCHN=m +CONFIG_XEN_BACKEND=y +CONFIG_XENFS=m +CONFIG_XEN_COMPAT_XENFS=y +CONFIG_XEN_SYS_HYPERVISOR=y +CONFIG_XEN_XENBUS_FRONTEND=y +CONFIG_XEN_GNTDEV=m +CONFIG_XEN_GRANT_DEV_ALLOC=m +# CONFIG_XEN_GRANT_DMA_ALLOC is not set +CONFIG_SWIOTLB_XEN=y +# CONFIG_XEN_PVCALLS_FRONTEND is not set +# CONFIG_XEN_PVCALLS_BACKEND is not set +CONFIG_XEN_PRIVCMD=m +CONFIG_XEN_EFI=y +CONFIG_XEN_AUTO_XLATE=y +CONFIG_XEN_FRONT_PGDIR_SHBUF=m +# end of Xen driver support + +# CONFIG_GREYBUS is not set CONFIG_STAGING=y # CONFIG_PRISM2_USB is not set # CONFIG_COMEDI is not set -# CONFIG_RTLLIB is not set +CONFIG_RTLLIB=m +CONFIG_RTLLIB_CRYPTO_CCMP=m +CONFIG_RTLLIB_CRYPTO_TKIP=m +CONFIG_RTLLIB_CRYPTO_WEP=m CONFIG_RTL8723BS=m CONFIG_R8712U=m # CONFIG_R8188EU is not set -# CONFIG_VT6656 is not set +CONFIG_VT6656=m # # IIO staging drivers @@ -4968,59 +6064,73 @@ CONFIG_R8712U=m # # CONFIG_ADIS16203 is not set # CONFIG_ADIS16240 is not set +# end of Accelerometers # # Analog to digital converters # -# CONFIG_AD7606 is not set -# CONFIG_AD7780 is not set # CONFIG_AD7816 is not set # CONFIG_AD7192 is not set # CONFIG_AD7280 is not set +# end of Analog to digital converters # # Analog digital bi-direction converters # # CONFIG_ADT7316 is not set +# end of Analog digital bi-direction converters # # Capacitance to digital converters # # CONFIG_AD7150 is not set -# CONFIG_AD7152 is not set # CONFIG_AD7746 is not set +# end of Capacitance to digital converters # # Direct Digital Synthesis # CONFIG_AD9832=m CONFIG_AD9834=m +# end of Direct Digital Synthesis # # Network Analyzer, Impedance Converters # # CONFIG_AD5933 is not set +# end of Network Analyzer, Impedance Converters # # Active energy metering IC # # CONFIG_ADE7854 is not set +# end of Active energy metering IC # # Resolver to digital converters # -# CONFIG_AD2S90 is not set # CONFIG_AD2S1210 is not set +# end of Resolver to digital converters +# end of IIO staging drivers # # Speakup console speech # # CONFIG_SPEAKUP is not set -# CONFIG_STAGING_MEDIA is not set +# end of Speakup console speech + +CONFIG_STAGING_MEDIA=y +CONFIG_VIDEO_SUNXI=y + +# +# soc_camera sensor drivers +# # # Android # +# end of Android + # CONFIG_STAGING_BOARD is not set # CONFIG_LTE_GDM724X is not set # CONFIG_GS_FPGABOOT is not set @@ -5058,8 +6168,6 @@ CONFIG_FB_TFT_UC1611=m CONFIG_FB_TFT_UC1701=m CONFIG_FB_TFT_UPD161704=m CONFIG_FB_TFT_WATTEROTT=m -CONFIG_FB_FLEX=m -CONFIG_FB_TFT_FBTFT_DEVICE=m # CONFIG_WILC1000_SDIO is not set # CONFIG_WILC1000_SPI is not set CONFIG_MOST=m @@ -5071,19 +6179,29 @@ CONFIG_MOST=m # CONFIG_MOST_I2C is not set # CONFIG_MOST_USB is not set # CONFIG_KS7010 is not set -# CONFIG_GREYBUS is not set # CONFIG_PI433 is not set -CONFIG_MTK_MMC=m -# CONFIG_MTK_AEE_KDUMP is not set -# CONFIG_MTK_MMC_CD_POLL is not set # # Gasket devices # +# end of Gasket devices + CONFIG_XIL_AXIS_FIFO=m -# CONFIG_EROFS_FS is not set +# CONFIG_FIELDBUS_DEV is not set +# CONFIG_USB_WUSB_CBAF is not set +# CONFIG_UWB is not set +CONFIG_EXFAT_FS=m +CONFIG_EXFAT_DONT_MOUNT_VFAT=y +CONFIG_EXFAT_DISCARD=y +# CONFIG_EXFAT_DELAYED_SYNC is not set +# CONFIG_EXFAT_KERNEL_DEBUG is not set +# CONFIG_EXFAT_DEBUG_MSG is not set +CONFIG_EXFAT_DEFAULT_CODEPAGE=437 +CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8" # CONFIG_GOLDFISH is not set +# CONFIG_MFD_CROS_EC is not set # CONFIG_CHROME_PLATFORMS is not set +# CONFIG_MELLANOX_PLATFORM is not set CONFIG_CLKDEV_LOOKUP=y CONFIG_HAVE_CLK_PREPARE=y CONFIG_COMMON_CLK=y @@ -5091,11 +6209,15 @@ CONFIG_COMMON_CLK=y # # Common Clock Framework # +CONFIG_COMMON_CLK_WM831X=m # CONFIG_COMMON_CLK_VERSATILE is not set # CONFIG_CLK_HSDK is not set +CONFIG_COMMON_CLK_MAX77686=m CONFIG_COMMON_CLK_MAX9485=m +CONFIG_COMMON_CLK_RK808=m # CONFIG_COMMON_CLK_SCMI is not set CONFIG_COMMON_CLK_SCPI=y +# CONFIG_COMMON_CLK_SI5341 is not set # CONFIG_COMMON_CLK_SI5351 is not set # CONFIG_COMMON_CLK_SI514 is not set CONFIG_COMMON_CLK_SI544=m @@ -5104,10 +6226,19 @@ CONFIG_COMMON_CLK_SI544=m # CONFIG_COMMON_CLK_CDCE925 is not set # CONFIG_COMMON_CLK_CS2000_CP is not set # CONFIG_COMMON_CLK_S2MPS11 is not set +CONFIG_CLK_TWL6040=m # CONFIG_CLK_QORIQ is not set # CONFIG_COMMON_CLK_XGENE is not set +CONFIG_COMMON_CLK_PALMAS=m # CONFIG_COMMON_CLK_PWM is not set # CONFIG_COMMON_CLK_VC5 is not set +CONFIG_COMMON_CLK_BD718XX=m +# CONFIG_COMMON_CLK_FIXED_MMIO is not set +CONFIG_CLK_SUNXI=y +CONFIG_CLK_SUNXI_CLOCKS=y +CONFIG_CLK_SUNXI_PRCM_SUN6I=y +CONFIG_CLK_SUNXI_PRCM_SUN8I=y +CONFIG_CLK_SUNXI_PRCM_SUN9I=y CONFIG_SUNXI_CCU=y CONFIG_SUN50I_A64_CCU=y CONFIG_SUN50I_H6_CCU=y @@ -5116,6 +6247,8 @@ CONFIG_SUN8I_A83T_CCU=y CONFIG_SUN8I_H3_CCU=y CONFIG_SUN8I_DE2_CCU=y CONFIG_SUN8I_R_CCU=y +# end of Common Clock Framework + # CONFIG_HWSPINLOCK is not set # @@ -5127,16 +6260,19 @@ CONFIG_ARM_ARCH_TIMER=y CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y CONFIG_FSL_ERRATUM_A008585=y -# CONFIG_HISILICON_ERRATUM_161010101 is not set -# CONFIG_ARM64_ERRATUM_858921 is not set +CONFIG_HISILICON_ERRATUM_161010101=y +CONFIG_ARM64_ERRATUM_858921=y CONFIG_SUN50I_ERRATUM_UNKNOWN1=y -# CONFIG_ARM_TIMER_SP804 is not set +# end of Clock Source drivers + CONFIG_MAILBOX=y CONFIG_ARM_MHU=y -# CONFIG_PLATFORM_MHU is not set +CONFIG_PLATFORM_MHU=y # CONFIG_PL320_MBOX is not set # CONFIG_ALTERA_MBOX is not set # CONFIG_MAILBOX_TEST is not set +CONFIG_SUN6I_MSGBOX=y +CONFIG_IOMMU_IOVA=y CONFIG_IOMMU_API=y CONFIG_IOMMU_SUPPORT=y @@ -5147,24 +6283,30 @@ CONFIG_IOMMU_IO_PGTABLE=y CONFIG_IOMMU_IO_PGTABLE_LPAE=y # CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST is not set # CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set +# end of Generic IOMMU Pagetable Support + # CONFIG_IOMMU_DEBUGFS is not set # CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set -CONFIG_IOMMU_IOVA=y CONFIG_OF_IOMMU=y CONFIG_IOMMU_DMA=y CONFIG_ARM_SMMU=y +CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y # CONFIG_ARM_SMMU_V3 is not set +# CONFIG_VIRTIO_IOMMU is not set # # Remoteproc drivers # # CONFIG_REMOTEPROC is not set +# end of Remoteproc drivers # # Rpmsg drivers # # CONFIG_RPMSG_QCOM_GLINK_RPM is not set # CONFIG_RPMSG_VIRTIO is not set +# end of Rpmsg drivers + # CONFIG_SOUNDWIRE is not set # @@ -5174,23 +6316,34 @@ CONFIG_ARM_SMMU=y # # Amlogic SoC drivers # +# end of Amlogic SoC drivers + +# +# Aspeed SoC drivers +# +# end of Aspeed SoC drivers # # Broadcom SoC drivers # -# CONFIG_SOC_BRCMSTB is not set +CONFIG_SOC_BRCMSTB=y +# end of Broadcom SoC drivers # # NXP/Freescale QorIQ SoC drivers # +# end of NXP/Freescale QorIQ SoC drivers # # i.MX SoC drivers # +# end of i.MX SoC drivers # # Qualcomm SoC drivers # +# end of Qualcomm SoC drivers + CONFIG_SUNXI_SRAM=y # CONFIG_SOC_TI is not set @@ -5198,16 +6351,19 @@ CONFIG_SUNXI_SRAM=y # Xilinx SoC drivers # # CONFIG_XILINX_VCU is not set +# end of Xilinx SoC drivers +# end of SOC (System On Chip) specific Drivers + CONFIG_PM_DEVFREQ=y # # DEVFREQ Governors # CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y -CONFIG_DEVFREQ_GOV_PERFORMANCE=y -CONFIG_DEVFREQ_GOV_POWERSAVE=y -CONFIG_DEVFREQ_GOV_USERSPACE=y -CONFIG_DEVFREQ_GOV_PASSIVE=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=m +CONFIG_DEVFREQ_GOV_POWERSAVE=m +CONFIG_DEVFREQ_GOV_USERSPACE=m +CONFIG_DEVFREQ_GOV_PASSIVE=m # # DEVFREQ Drivers @@ -5219,18 +6375,27 @@ CONFIG_EXTCON=y # Extcon Device Drivers # # CONFIG_EXTCON_ADC_JACK is not set +CONFIG_EXTCON_ARIZONA=m +# CONFIG_EXTCON_FSA9480 is not set # CONFIG_EXTCON_GPIO is not set +CONFIG_EXTCON_MAX14577=m # CONFIG_EXTCON_MAX3355 is not set +CONFIG_EXTCON_MAX77693=m +CONFIG_EXTCON_MAX77843=m +CONFIG_EXTCON_MAX8997=m +CONFIG_EXTCON_PALMAS=m +CONFIG_EXTCON_PTN5150=m # CONFIG_EXTCON_RT8973A is not set # CONFIG_EXTCON_SM5502 is not set CONFIG_EXTCON_USB_GPIO=y -# CONFIG_MEMORY is not set -CONFIG_IIO=m +CONFIG_MEMORY=y +# CONFIG_ARM_PL172_MPMC is not set +CONFIG_IIO=y CONFIG_IIO_BUFFER=y CONFIG_IIO_BUFFER_CB=m # CONFIG_IIO_BUFFER_HW_CONSUMER is not set -CONFIG_IIO_KFIFO_BUF=m -CONFIG_IIO_TRIGGERED_BUFFER=m +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_TRIGGERED_BUFFER=y CONFIG_IIO_CONFIGFS=m CONFIG_IIO_TRIGGER=y CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 @@ -5246,6 +6411,9 @@ CONFIG_ADIS16209=m CONFIG_ADXL345=m CONFIG_ADXL345_I2C=m CONFIG_ADXL345_SPI=m +CONFIG_ADXL372=m +CONFIG_ADXL372_SPI=m +CONFIG_ADXL372_I2C=m CONFIG_BMA180=m CONFIG_BMA220=m CONFIG_BMC150_ACCEL=m @@ -5257,7 +6425,6 @@ CONFIG_DMARD06=m CONFIG_DMARD09=m CONFIG_DMARD10=m CONFIG_HID_SENSOR_ACCEL_3D=m -CONFIG_IIO_CROS_EC_ACCEL_LEGACY=m CONFIG_IIO_ST_ACCEL_3AXIS=m CONFIG_IIO_ST_ACCEL_I2C_3AXIS=m CONFIG_IIO_ST_ACCEL_SPI_3AXIS=m @@ -5279,28 +6446,40 @@ CONFIG_MXC6255=m CONFIG_SCA3000=m CONFIG_STK8312=m CONFIG_STK8BA50=m +# end of Accelerometers # # Analog to digital converters # CONFIG_AD_SIGMA_DELTA=m +CONFIG_AD7124=m CONFIG_AD7266=m CONFIG_AD7291=m CONFIG_AD7298=m CONFIG_AD7476=m +CONFIG_AD7606=m +CONFIG_AD7606_IFACE_PARALLEL=m +CONFIG_AD7606_IFACE_SPI=m CONFIG_AD7766=m +CONFIG_AD7768_1=m +# CONFIG_AD7780 is not set CONFIG_AD7791=m CONFIG_AD7793=m CONFIG_AD7887=m CONFIG_AD7923=m +CONFIG_AD7949=m CONFIG_AD799X=m CONFIG_AXP20X_ADC=m CONFIG_AXP288_ADC=m CONFIG_CC10001_ADC=m +CONFIG_CPCAP_ADC=m +CONFIG_DA9150_GPADC=m +CONFIG_DLN2_ADC=m CONFIG_ENVELOPE_DETECTOR=m CONFIG_HI8435=m # CONFIG_HX711 is not set CONFIG_INA2XX_ADC=m +CONFIG_LP8788_ADC=m CONFIG_LTC2471=m CONFIG_LTC2485=m CONFIG_LTC2497=m @@ -5311,9 +6490,13 @@ CONFIG_MAX1363=m CONFIG_MAX9611=m CONFIG_MCP320X=m CONFIG_MCP3422=m +CONFIG_MCP3911=m # CONFIG_NAU7802 is not set +CONFIG_PALMAS_GPADC=m +CONFIG_QCOM_VADC_COMMON=m # CONFIG_QCOM_SPMI_IADC is not set # CONFIG_QCOM_SPMI_VADC is not set +CONFIG_QCOM_SPMI_ADC5=m # CONFIG_SD_ADC_MODULATOR is not set CONFIG_SUN4I_GPADC=m CONFIG_TI_ADC081C=m @@ -5325,19 +6508,29 @@ CONFIG_TI_ADC128S052=m CONFIG_TI_ADC161S626=m CONFIG_TI_ADS1015=m CONFIG_TI_ADS7950=m +CONFIG_TI_ADS8344=m CONFIG_TI_ADS8688=m +CONFIG_TI_ADS124S08=m +CONFIG_TI_AM335X_ADC=m CONFIG_TI_TLC4541=m +CONFIG_TWL4030_MADC=m +CONFIG_TWL6030_GPADC=m # CONFIG_VF610_ADC is not set +CONFIG_VIPERBOARD_ADC=m +# CONFIG_XILINX_XADC is not set +# end of Analog to digital converters # # Analog Front Ends # # CONFIG_IIO_RESCALE is not set +# end of Analog Front Ends # # Amplifiers # # CONFIG_AD8366 is not set +# end of Amplifiers # # Chemical Sensors @@ -5348,27 +6541,31 @@ CONFIG_BME680_I2C=m CONFIG_BME680_SPI=m # CONFIG_CCS811 is not set # CONFIG_IAQCORE is not set +CONFIG_PMS7003=m +CONFIG_SENSIRION_SGP30=m +CONFIG_SPS30=m # CONFIG_VZ89X is not set +# end of Chemical Sensors # # Hid Sensor IIO Common # CONFIG_HID_SENSOR_IIO_COMMON=m CONFIG_HID_SENSOR_IIO_TRIGGER=m +# end of Hid Sensor IIO Common + CONFIG_IIO_MS_SENSORS_I2C=m # # SSP Sensor Common # # CONFIG_IIO_SSP_SENSORHUB is not set +# end of SSP Sensor Common + CONFIG_IIO_ST_SENSORS_I2C=m CONFIG_IIO_ST_SENSORS_SPI=m CONFIG_IIO_ST_SENSORS_CORE=m -# -# Counters -# - # # Digital to analog converters # @@ -5382,6 +6579,7 @@ CONFIG_IIO_ST_SENSORS_CORE=m # CONFIG_AD5593R is not set # CONFIG_AD5504 is not set # CONFIG_AD5624R_SPI is not set +CONFIG_LTC1660=m # CONFIG_LTC2632 is not set CONFIG_AD5686=m CONFIG_AD5686_SPI=m @@ -5402,7 +6600,10 @@ CONFIG_AD5758=m # CONFIG_MCP4922 is not set # CONFIG_TI_DAC082S085 is not set CONFIG_TI_DAC5571=m +CONFIG_TI_DAC7311=m +CONFIG_TI_DAC7612=m # CONFIG_VF610_DAC is not set +# end of Digital to analog converters # # IIO dummy driver @@ -5410,6 +6611,7 @@ CONFIG_TI_DAC5571=m CONFIG_IIO_SIMPLE_DUMMY=m # CONFIG_IIO_SIMPLE_DUMMY_EVENTS is not set # CONFIG_IIO_SIMPLE_DUMMY_BUFFER is not set +# end of IIO dummy driver # # Frequency Synthesizers DDS/PLL @@ -5419,11 +6621,15 @@ CONFIG_IIO_SIMPLE_DUMMY=m # Clock Generator/Distribution # # CONFIG_AD9523 is not set +# end of Clock Generator/Distribution # # Phase-Locked Loop (PLL) frequency synthesizers # # CONFIG_ADF4350 is not set +CONFIG_ADF4371=m +# end of Phase-Locked Loop (PLL) frequency synthesizers +# end of Frequency Synthesizers DDS/PLL # # Digital gyroscope sensors @@ -5436,6 +6642,9 @@ CONFIG_ADXRS450=m CONFIG_BMG160=m CONFIG_BMG160_I2C=m CONFIG_BMG160_SPI=m +CONFIG_FXAS21002C=m +CONFIG_FXAS21002C_I2C=m +CONFIG_FXAS21002C_SPI=m CONFIG_HID_SENSOR_GYRO_3D=m CONFIG_MPU3050=m CONFIG_MPU3050_I2C=m @@ -5443,6 +6652,7 @@ CONFIG_IIO_ST_GYRO_3AXIS=m CONFIG_IIO_ST_GYRO_I2C_3AXIS=m CONFIG_IIO_ST_GYRO_SPI_3AXIS=m CONFIG_ITG3200=m +# end of Digital gyroscope sensors # # Health Sensors @@ -5455,6 +6665,8 @@ CONFIG_ITG3200=m # CONFIG_AFE4404 is not set # CONFIG_MAX30100 is not set # CONFIG_MAX30102 is not set +# end of Heart Rate Monitors +# end of Health Sensors # # Humidity sensors @@ -5469,11 +6681,13 @@ CONFIG_HTS221_SPI=m CONFIG_HTU21=m CONFIG_SI7005=m CONFIG_SI7020=m +# end of Humidity sensors # # Inertial measurement units # # CONFIG_ADIS16400 is not set +CONFIG_ADIS16460=m # CONFIG_ADIS16480 is not set # CONFIG_BMI160_I2C is not set # CONFIG_BMI160_SPI is not set @@ -5481,6 +6695,8 @@ CONFIG_SI7020=m # CONFIG_INV_MPU6050_I2C is not set # CONFIG_INV_MPU6050_SPI is not set # CONFIG_IIO_ST_LSM6DSX is not set +# end of Inertial measurement units + CONFIG_IIO_ADIS_LIB=m CONFIG_IIO_ADIS_LIB_BUFFER=y @@ -5506,9 +6722,12 @@ CONFIG_HID_SENSOR_ALS=m CONFIG_HID_SENSOR_PROX=m CONFIG_JSA1212=m CONFIG_RPR0521=m +CONFIG_SENSORS_LM3533=m CONFIG_LTR501=m CONFIG_LV0104CS=m CONFIG_MAX44000=m +CONFIG_MAX44009=m +CONFIG_NOA1305=m CONFIG_OPT3001=m CONFIG_PA12203001=m CONFIG_SI1133=m @@ -5525,9 +6744,11 @@ CONFIG_TSL2772=m CONFIG_TSL4531=m CONFIG_US5182D=m CONFIG_VCNL4000=m +CONFIG_VCNL4035=m CONFIG_VEML6070=m CONFIG_VL6180=m CONFIG_ZOPT2201=m +# end of Light sensors # # Magnetometer sensors @@ -5547,42 +6768,53 @@ CONFIG_IIO_ST_MAGN_SPI_3AXIS=m CONFIG_SENSORS_HMC5843=m CONFIG_SENSORS_HMC5843_I2C=m CONFIG_SENSORS_HMC5843_SPI=m +CONFIG_SENSORS_RM3100=m +CONFIG_SENSORS_RM3100_I2C=m +CONFIG_SENSORS_RM3100_SPI=m +# end of Magnetometer sensors # # Multiplexers # # CONFIG_IIO_MUX is not set +# end of Multiplexers # # Inclinometer sensors # CONFIG_HID_SENSOR_INCLINOMETER_3D=m CONFIG_HID_SENSOR_DEVICE_ROTATION=m +# end of Inclinometer sensors # # Triggers - standalone # CONFIG_IIO_HRTIMER_TRIGGER=m -# CONFIG_IIO_INTERRUPT_TRIGGER is not set +CONFIG_IIO_INTERRUPT_TRIGGER=m CONFIG_IIO_TIGHTLOOP_TRIGGER=m -# CONFIG_IIO_SYSFS_TRIGGER is not set +CONFIG_IIO_SYSFS_TRIGGER=m +# end of Triggers - standalone # # Digital potentiometers # CONFIG_AD5272=m # CONFIG_DS1803 is not set +CONFIG_MAX5432=m # CONFIG_MAX5481 is not set # CONFIG_MAX5487 is not set CONFIG_MCP4018=m # CONFIG_MCP4131 is not set # CONFIG_MCP4531 is not set +CONFIG_MCP41010=m # CONFIG_TPL0102 is not set +# end of Digital potentiometers # # Digital potentiostats # # CONFIG_LMP91000 is not set +# end of Digital potentiostats # # Pressure sensors @@ -5591,7 +6823,8 @@ CONFIG_MCP4018=m CONFIG_BMP280=m CONFIG_BMP280_I2C=m CONFIG_BMP280_SPI=m -# CONFIG_HID_SENSOR_PRESS is not set +CONFIG_DPS310=m +CONFIG_HID_SENSOR_PRESS=m # CONFIG_HP03 is not set # CONFIG_MPL115_I2C is not set # CONFIG_MPL115_SPI is not set @@ -5602,26 +6835,33 @@ CONFIG_BMP280_SPI=m # CONFIG_T5403 is not set # CONFIG_HP206C is not set # CONFIG_ZPA2326 is not set +# end of Pressure sensors # # Lightning sensors # # CONFIG_AS3935 is not set +# end of Lightning sensors # # Proximity and distance sensors # CONFIG_ISL29501=m # CONFIG_LIDAR_LITE_V2 is not set +CONFIG_MB1232=m # CONFIG_RFD77402 is not set # CONFIG_SRF04 is not set # CONFIG_SX9500 is not set # CONFIG_SRF08 is not set +CONFIG_VL53L0X_I2C=m +# end of Proximity and distance sensors # # Resolver to digital converters # +# CONFIG_AD2S90 is not set # CONFIG_AD2S1200 is not set +# end of Resolver to digital converters # # Temperature sensors @@ -5629,16 +6869,23 @@ CONFIG_ISL29501=m CONFIG_MAXIM_THERMOCOUPLE=m CONFIG_HID_SENSOR_TEMP=m CONFIG_MLX90614=m -# CONFIG_MLX90632 is not set +CONFIG_MLX90632=m CONFIG_TMP006=m CONFIG_TMP007=m CONFIG_TSYS01=m CONFIG_TSYS02D=m +CONFIG_MAX31856=m +# end of Temperature sensors + CONFIG_PWM=y CONFIG_PWM_SYSFS=y +CONFIG_PWM_ATMEL_HLCDC_PWM=m # CONFIG_PWM_FSL_FTM is not set +CONFIG_PWM_LP3943=m CONFIG_PWM_PCA9685=m CONFIG_PWM_SUN4I=m +CONFIG_PWM_TWL=m +CONFIG_PWM_TWL_LED=m # # IRQ chip support @@ -5648,29 +6895,46 @@ CONFIG_ARM_GIC=y CONFIG_ARM_GIC_MAX_NR=1 CONFIG_ARM_GIC_V3=y CONFIG_ARM_GIC_V3_ITS=y +# CONFIG_AL_FIC is not set +CONFIG_MADERA_IRQ=m CONFIG_PARTITION_PERCPU=y +# end of IRQ chip support + # CONFIG_IPACK_BUS is not set CONFIG_ARCH_HAS_RESET_CONTROLLER=y CONFIG_RESET_CONTROLLER=y +CONFIG_RESET_SCMI=y CONFIG_RESET_SIMPLE=y CONFIG_RESET_SUNXI=y # CONFIG_RESET_TI_SYSCON is not set -# CONFIG_FMC is not set # # PHY Subsystem # CONFIG_GENERIC_PHY=y +CONFIG_GENERIC_PHY_MIPI_DPHY=y # CONFIG_PHY_XGENE is not set CONFIG_PHY_SUN4I_USB=y +CONFIG_PHY_SUN6I_MIPI_DPHY=m CONFIG_PHY_SUN9I_USB=y CONFIG_PHY_SUN50I_USB3=y # CONFIG_BCM_KONA_USB2_PHY is not set +CONFIG_PHY_CADENCE_DP=m +CONFIG_PHY_CADENCE_DPHY=m +CONFIG_PHY_CADENCE_SIERRA=m +CONFIG_PHY_FSL_IMX8MQ_USB=m +# CONFIG_PHY_MIXEL_MIPI_DPHY is not set # CONFIG_PHY_PXA_28NM_HSIC is not set # CONFIG_PHY_PXA_28NM_USB2 is not set # CONFIG_PHY_CPCAP_USB is not set CONFIG_PHY_MAPPHONE_MDM6600=m +CONFIG_PHY_OCELOT_SERDES=m +CONFIG_PHY_QCOM_USB_HS=m +CONFIG_PHY_QCOM_USB_HSIC=m CONFIG_PHY_SAMSUNG_USB2=y +CONFIG_PHY_TUSB1210=m +# end of PHY Subsystem + # CONFIG_POWERCAP is not set # CONFIG_MCB is not set @@ -5684,16 +6948,21 @@ CONFIG_ARM_CCI_PMU=m CONFIG_ARM_PMU=y CONFIG_ARM_DSU_PMU=m CONFIG_ARM_SPE_PMU=m +# end of Performance monitor support + # CONFIG_RAS is not set # # Android # # CONFIG_ANDROID is not set +# end of Android + # CONFIG_LIBNVDIMM is not set -CONFIG_DAX=m -# CONFIG_DEV_DAX is not set +CONFIG_DAX=y +CONFIG_DEV_DAX=m CONFIG_NVMEM=y +CONFIG_NVMEM_SYSFS=y CONFIG_NVMEM_SUNXI_SID=y CONFIG_RAVE_SP_EEPROM=m @@ -5702,50 +6971,84 @@ CONFIG_RAVE_SP_EEPROM=m # # CONFIG_STM is not set # CONFIG_INTEL_TH is not set +# end of HW tracing support + # CONFIG_FPGA is not set # CONFIG_FSI is not set -# CONFIG_TEE is not set +CONFIG_TEE=y + +# +# TEE drivers +# +CONFIG_OPTEE=y +CONFIG_OPTEE_SHM_NUM_PRIV_PAGES=1 +# end of TEE drivers + CONFIG_MULTIPLEXER=m # # Multiplexer drivers # -# CONFIG_MUX_ADG792A is not set +CONFIG_MUX_ADG792A=m CONFIG_MUX_ADGS1408=m -# CONFIG_MUX_GPIO is not set -# CONFIG_MUX_MMIO is not set +CONFIG_MUX_GPIO=m +CONFIG_MUX_MMIO=m +# end of Multiplexer drivers + CONFIG_PM_OPP=y # CONFIG_SIOX is not set # CONFIG_SLIMBUS is not set +CONFIG_INTERCONNECT=m +CONFIG_COUNTER=m +CONFIG_FTM_QUADDEC=m +# end of Device Drivers # # File systems # CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_VALIDATE_FS_PARSER=y CONFIG_FS_IOMAP=y -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set +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_EXT4_FS=y -CONFIG_EXT4_USE_FOR_EXT2=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y -CONFIG_EXT4_ENCRYPTION=y -CONFIG_EXT4_FS_ENCRYPTION=y # CONFIG_EXT4_DEBUG is not set CONFIG_JBD2=y # CONFIG_JBD2_DEBUG is not set CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_STATISTICS=y CONFIG_XFS_FS=m -# CONFIG_XFS_QUOTA is not set +CONFIG_XFS_QUOTA=y CONFIG_XFS_POSIX_ACL=y CONFIG_XFS_RT=y # CONFIG_XFS_ONLINE_SCRUB is not set # CONFIG_XFS_WARN is not set # CONFIG_XFS_DEBUG is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=y +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_DEBUG_MASKLOG=y +# CONFIG_OCFS2_DEBUG_FS is not set CONFIG_BTRFS_FS=y CONFIG_BTRFS_FS_POSIX_ACL=y # CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set @@ -5753,22 +7056,24 @@ CONFIG_BTRFS_FS_POSIX_ACL=y # CONFIG_BTRFS_DEBUG is not set # CONFIG_BTRFS_ASSERT is not set # CONFIG_BTRFS_FS_REF_VERIFY is not set -# CONFIG_NILFS2_FS is not set +CONFIG_NILFS2_FS=m CONFIG_F2FS_FS=y CONFIG_F2FS_STAT_FS=y CONFIG_F2FS_FS_XATTR=y CONFIG_F2FS_FS_POSIX_ACL=y CONFIG_F2FS_FS_SECURITY=y -# CONFIG_F2FS_CHECK_FS is not set -CONFIG_F2FS_FS_ENCRYPTION=y +CONFIG_F2FS_CHECK_FS=y # CONFIG_F2FS_FAULT_INJECTION is not set -# CONFIG_FS_DAX is not set +CONFIG_FS_DAX=y CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y CONFIG_EXPORTFS_BLOCK_OPS=y CONFIG_FILE_LOCKING=y CONFIG_MANDATORY_FILE_LOCKING=y CONFIG_FS_ENCRYPTION=y +CONFIG_FS_VERITY=y +# CONFIG_FS_VERITY_DEBUG is not set +CONFIG_FS_VERITY_BUILTIN_SIGNATURES=y CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y CONFIG_INOTIFY_USER=y @@ -5778,61 +7083,68 @@ CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_PRINT_QUOTA_WARNING=y # CONFIG_QUOTA_DEBUG is not set +CONFIG_QUOTA_TREE=m CONFIG_QFMT_V1=m CONFIG_QFMT_V2=m CONFIG_QUOTACTL=y -CONFIG_AUTOFS4_FS=y -CONFIG_AUTOFS_FS=y -CONFIG_FUSE_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_FUSE_FS=y CONFIG_CUSE=m -CONFIG_OVERLAY_FS=m +CONFIG_VIRTIO_FS=m +CONFIG_OVERLAY_FS=y # CONFIG_OVERLAY_FS_REDIRECT_DIR is not set CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y # CONFIG_OVERLAY_FS_INDEX is not set -# CONFIG_OVERLAY_FS_XINO_AUTO is not set +CONFIG_OVERLAY_FS_XINO_AUTO=y # CONFIG_OVERLAY_FS_METACOPY is not set # # Caches # CONFIG_FSCACHE=m -# CONFIG_FSCACHE_STATS is not set +CONFIG_FSCACHE_STATS=y # CONFIG_FSCACHE_HISTOGRAM is not set # CONFIG_FSCACHE_DEBUG is not set # CONFIG_FSCACHE_OBJECT_LIST is not set CONFIG_CACHEFILES=m # CONFIG_CACHEFILES_DEBUG is not set # CONFIG_CACHEFILES_HISTOGRAM is not set +# end of Caches # # CD-ROM/DVD Filesystems # CONFIG_ISO9660_FS=m CONFIG_JOLIET=y -# CONFIG_ZISOFS is not set +CONFIG_ZISOFS=y CONFIG_UDF_FS=m +# end of CD-ROM/DVD Filesystems # # DOS/FAT/NT Filesystems # CONFIG_FAT_FS=y -# CONFIG_MSDOS_FS is not set +CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=y CONFIG_FAT_DEFAULT_CODEPAGE=437 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_FAT_DEFAULT_UTF8 is not set +CONFIG_FAT_DEFAULT_UTF8=y CONFIG_NTFS_FS=m # CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set +CONFIG_NTFS_RW=y +# end of DOS/FAT/NT Filesystems # # Pseudo filesystems # CONFIG_PROC_FS=y # CONFIG_PROC_KCORE is not set +CONFIG_PROC_VMCORE=y +# CONFIG_PROC_VMCORE_DEVICE_DUMP is not set CONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=y -# CONFIG_PROC_CHILDREN is not set +CONFIG_PROC_CHILDREN=y CONFIG_KERNFS=y CONFIG_SYSFS=y CONFIG_TMPFS=y @@ -5843,22 +7155,45 @@ CONFIG_HUGETLB_PAGE=y CONFIG_MEMFD_CREATE=y CONFIG_ARCH_HAS_GIGANTIC_PAGE=y CONFIG_CONFIGFS_FS=y +CONFIG_EFIVAR_FS=m +# end of Pseudo filesystems + CONFIG_MISC_FILESYSTEMS=y -# CONFIG_ORANGEFS_FS is not set -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -CONFIG_ECRYPT_FS=m -# CONFIG_ECRYPT_FS_MESSAGING is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS2_FS is not set -# CONFIG_CRAMFS is not set +CONFIG_ORANGEFS_FS=m +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=y +CONFIG_ECRYPT_FS_MESSAGING=y +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_FS_POSIX_ACL=y +CONFIG_JFFS2_FS_SECURITY=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +CONFIG_CRAMFS=m +CONFIG_CRAMFS_BLOCKDEV=y +CONFIG_CRAMFS_MTD=y CONFIG_SQUASHFS=y -CONFIG_SQUASHFS_FILE_CACHE=y -# CONFIG_SQUASHFS_FILE_DIRECT is not set +# CONFIG_SQUASHFS_FILE_CACHE is not set +CONFIG_SQUASHFS_FILE_DIRECT=y # CONFIG_SQUASHFS_DECOMP_SINGLE is not set # CONFIG_SQUASHFS_DECOMP_MULTI is not set CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y @@ -5868,19 +7203,45 @@ CONFIG_SQUASHFS_LZ4=y CONFIG_SQUASHFS_LZO=y CONFIG_SQUASHFS_XZ=y CONFIG_SQUASHFS_ZSTD=y -# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y CONFIG_SQUASHFS_EMBEDDED=y CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_OMFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX6FS_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_PSTORE is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set +CONFIG_VXFS_FS=m +CONFIG_MINIX_FS=m +CONFIG_OMFS_FS=m +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +CONFIG_QNX6FS_FS=m +# CONFIG_QNX6FS_DEBUG is not set +CONFIG_ROMFS_FS=m +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y +CONFIG_PSTORE=y +CONFIG_PSTORE_DEFLATE_COMPRESS=y +# CONFIG_PSTORE_LZO_COMPRESS is not set +# CONFIG_PSTORE_LZ4_COMPRESS is not set +CONFIG_PSTORE_LZ4HC_COMPRESS=m +# CONFIG_PSTORE_842_COMPRESS is not set +# CONFIG_PSTORE_ZSTD_COMPRESS is not set +CONFIG_PSTORE_COMPRESS=y +CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y +# CONFIG_PSTORE_LZ4HC_COMPRESS_DEFAULT is not set +CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" +# CONFIG_PSTORE_CONSOLE is not set +# CONFIG_PSTORE_PMSG is not set +CONFIG_PSTORE_RAM=m +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +CONFIG_UFS_FS_WRITE=y +# CONFIG_UFS_DEBUG is not set +CONFIG_EROFS_FS=m +# CONFIG_EROFS_FS_DEBUG is not set +CONFIG_EROFS_FS_XATTR=y +CONFIG_EROFS_FS_POSIX_ACL=y +CONFIG_EROFS_FS_SECURITY=y +# CONFIG_EROFS_FS_ZIP is not set CONFIG_AUFS_FS=m CONFIG_AUFS_BRANCH_MAX_127=y # CONFIG_AUFS_BRANCH_MAX_511 is not set @@ -5888,35 +7249,38 @@ CONFIG_AUFS_BRANCH_MAX_127=y # CONFIG_AUFS_BRANCH_MAX_32767 is not set CONFIG_AUFS_SBILIST=y # CONFIG_AUFS_HNOTIFY is not set -# CONFIG_AUFS_EXPORT is not set -# CONFIG_AUFS_XATTR is not set +CONFIG_AUFS_EXPORT=y +CONFIG_AUFS_INO_T_64=y +CONFIG_AUFS_XATTR=y # CONFIG_AUFS_FHSM is not set # CONFIG_AUFS_RDU is not set -# CONFIG_AUFS_DIRREN is not set +CONFIG_AUFS_DIRREN=y # CONFIG_AUFS_SHWH is not set # CONFIG_AUFS_BR_RAMFS is not set # CONFIG_AUFS_BR_FUSE is not set +CONFIG_AUFS_BR_HFSPLUS=y CONFIG_AUFS_BDEV_LOOP=y # CONFIG_AUFS_DEBUG is not set CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V2=y -CONFIG_NFS_V3=y +CONFIG_NFS_FS=m +CONFIG_NFS_V2=m +CONFIG_NFS_V3=m CONFIG_NFS_V3_ACL=y -CONFIG_NFS_V4=y -# CONFIG_NFS_SWAP is not set +CONFIG_NFS_V4=m +CONFIG_NFS_SWAP=y CONFIG_NFS_V4_1=y CONFIG_NFS_V4_2=y -CONFIG_PNFS_FILE_LAYOUT=y +CONFIG_PNFS_FILE_LAYOUT=m CONFIG_PNFS_BLOCK=m CONFIG_PNFS_FLEXFILE_LAYOUT=m CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" -# CONFIG_NFS_V4_1_MIGRATION is not set +CONFIG_NFS_V4_1_MIGRATION=y CONFIG_NFS_V4_SECURITY_LABEL=y -CONFIG_ROOT_NFS=y +CONFIG_NFS_FSCACHE=y # CONFIG_NFS_USE_LEGACY_DNS is not set CONFIG_NFS_USE_KERNEL_DNS=y -CONFIG_NFSD=y +CONFIG_NFS_DEBUG=y +CONFIG_NFSD=m CONFIG_NFSD_V2_ACL=y CONFIG_NFSD_V3=y CONFIG_NFSD_V3_ACL=y @@ -5926,37 +7290,45 @@ CONFIG_NFSD_BLOCKLAYOUT=y CONFIG_NFSD_SCSILAYOUT=y CONFIG_NFSD_FLEXFILELAYOUT=y CONFIG_NFSD_V4_SECURITY_LABEL=y -CONFIG_GRACE_PERIOD=y -CONFIG_LOCKD=y +CONFIG_GRACE_PERIOD=m +CONFIG_LOCKD=m CONFIG_LOCKD_V4=y -CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_ACL_SUPPORT=m CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m CONFIG_SUNRPC_BACKCHANNEL=y +CONFIG_SUNRPC_SWAP=y CONFIG_RPCSEC_GSS_KRB5=m -# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES is not set +CONFIG_SUNRPC_DEBUG=y CONFIG_CEPH_FS=m CONFIG_CEPH_FSCACHE=y CONFIG_CEPH_FS_POSIX_ACL=y +CONFIG_CEPH_FS_SECURITY_LABEL=y CONFIG_CIFS=m -# CONFIG_CIFS_STATS2 is not set +CONFIG_CIFS_STATS2=y CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y -# CONFIG_CIFS_WEAK_PW_HASH is not set +CONFIG_CIFS_WEAK_PW_HASH=y CONFIG_CIFS_UPCALL=y CONFIG_CIFS_XATTR=y CONFIG_CIFS_POSIX=y -CONFIG_CIFS_ACL=y -# CONFIG_CIFS_DEBUG is not set -# CONFIG_CIFS_DFS_UPCALL is not set +CONFIG_CIFS_DEBUG=y +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DEBUG_DUMP_KEYS is not set +CONFIG_CIFS_DFS_UPCALL=y CONFIG_CIFS_FSCACHE=y -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -CONFIG_9P_FS=y -# CONFIG_9P_FS_POSIX_ACL is not set -# CONFIG_9P_FS_SECURITY is not set +CONFIG_CODA_FS=m +CONFIG_AFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FSCACHE=y +# CONFIG_AFS_DEBUG_CURSOR is not set +CONFIG_9P_FS=m +CONFIG_9P_FSCACHE=y +CONFIG_9P_FS_POSIX_ACL=y +CONFIG_9P_FS_SECURITY=y CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_DEFAULT="utf8" CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m CONFIG_NLS_CODEPAGE_775=m @@ -5981,7 +7353,7 @@ CONFIG_NLS_ISO8859_8=m CONFIG_NLS_CODEPAGE_1250=m CONFIG_NLS_CODEPAGE_1251=m CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_1=m CONFIG_NLS_ISO8859_2=m CONFIG_NLS_ISO8859_3=m CONFIG_NLS_ISO8859_4=m @@ -6005,54 +7377,97 @@ CONFIG_NLS_MAC_ICELAND=m CONFIG_NLS_MAC_INUIT=m CONFIG_NLS_MAC_ROMANIAN=m CONFIG_NLS_MAC_TURKISH=m -CONFIG_NLS_UTF8=y -# CONFIG_DLM is not set +CONFIG_NLS_UTF8=m +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_UNICODE=y +# CONFIG_UNICODE_NORMALIZATION_SELFTEST is not set +# end of File systems # # Security options # CONFIG_KEYS=y CONFIG_KEYS_COMPAT=y -# CONFIG_PERSISTENT_KEYRINGS is not set -# CONFIG_BIG_KEYS is not set +CONFIG_KEYS_REQUEST_CACHE=y +CONFIG_PERSISTENT_KEYRINGS=y +CONFIG_BIG_KEYS=y +CONFIG_TRUSTED_KEYS=y CONFIG_ENCRYPTED_KEYS=y -# CONFIG_KEY_DH_OPERATIONS is not set +CONFIG_KEY_DH_OPERATIONS=y # CONFIG_SECURITY_DMESG_RESTRICT is not set CONFIG_SECURITY=y CONFIG_SECURITYFS=y CONFIG_SECURITY_NETWORK=y -# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_NETWORK_XFRM=y CONFIG_SECURITY_PATH=y -CONFIG_LSM_MMAP_MIN_ADDR=32768 +CONFIG_LSM_MMAP_MIN_ADDR=0 CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y -# CONFIG_HARDENED_USERCOPY is not set -# CONFIG_FORTIFY_SOURCE is not set +CONFIG_HARDENED_USERCOPY=y +CONFIG_HARDENED_USERCOPY_FALLBACK=y +# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set +CONFIG_FORTIFY_SOURCE=y # CONFIG_STATIC_USERMODEHELPER is not set CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y -CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 # CONFIG_SECURITY_SELINUX_DISABLE is not set CONFIG_SECURITY_SELINUX_DEVELOP=y CONFIG_SECURITY_SELINUX_AVC_STATS=y -CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=0 -# CONFIG_SECURITY_SMACK is not set -# CONFIG_SECURITY_TOMOYO is not set +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SMACK=y +# CONFIG_SECURITY_SMACK_BRINGUP is not set +CONFIG_SECURITY_SMACK_NETFILTER=y +CONFIG_SECURITY_SMACK_APPEND_SIGNALS=y +CONFIG_SECURITY_TOMOYO=y +CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY=2048 +CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG=1024 +# CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER is not set +CONFIG_SECURITY_TOMOYO_POLICY_LOADER="/sbin/tomoyo-init" +CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER="/sbin/init" +# CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING is not set CONFIG_SECURITY_APPARMOR=y -CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=0 CONFIG_SECURITY_APPARMOR_HASH=y CONFIG_SECURITY_APPARMOR_HASH_DEFAULT=y # CONFIG_SECURITY_APPARMOR_DEBUG is not set # CONFIG_SECURITY_LOADPIN is not set -# CONFIG_SECURITY_YAMA is not set +CONFIG_SECURITY_YAMA=y +CONFIG_SECURITY_SAFESETID=y +CONFIG_SECURITY_LOCKDOWN_LSM=y +CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y +CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y +# CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY is not set +# CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY is not set CONFIG_INTEGRITY=y -# CONFIG_INTEGRITY_SIGNATURE is not set +CONFIG_INTEGRITY_SIGNATURE=y +CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y +CONFIG_INTEGRITY_TRUSTED_KEYRING=y +CONFIG_INTEGRITY_PLATFORM_KEYRING=y +CONFIG_LOAD_UEFI_KEYS=y CONFIG_INTEGRITY_AUDIT=y # CONFIG_IMA is not set +# CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY is not set # CONFIG_EVM is not set # CONFIG_DEFAULT_SECURITY_SELINUX is not set -# CONFIG_DEFAULT_SECURITY_APPARMOR is not set -CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_DEFAULT_SECURITY="" +# CONFIG_DEFAULT_SECURITY_SMACK is not set +# CONFIG_DEFAULT_SECURITY_TOMOYO is not set +CONFIG_DEFAULT_SECURITY_APPARMOR=y +# CONFIG_DEFAULT_SECURITY_DAC is not set +CONFIG_LSM="lockdown,yama,integrity,apparmor" + +# +# Kernel hardening options +# + +# +# Memory initialization +# +CONFIG_INIT_STACK_NONE=y +CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y +# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set +# end of Memory initialization +# end of Kernel hardening options +# end of Security options + CONFIG_XOR_BLOCKS=y CONFIG_ASYNC_CORE=m CONFIG_ASYNC_MEMCPY=m @@ -6080,38 +7495,39 @@ CONFIG_CRYPTO_AKCIPHER=y CONFIG_CRYPTO_KPP2=y CONFIG_CRYPTO_KPP=y CONFIG_CRYPTO_ACOMP2=y -CONFIG_CRYPTO_RSA=y -CONFIG_CRYPTO_DH=y -CONFIG_CRYPTO_ECDH=y CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_USER=y +CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y CONFIG_CRYPTO_GF128MUL=y CONFIG_CRYPTO_NULL=y CONFIG_CRYPTO_NULL2=y -CONFIG_CRYPTO_PCRYPT=y -CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_CRYPTO_PCRYPT=m CONFIG_CRYPTO_CRYPTD=y -CONFIG_CRYPTO_MCRYPTD=y CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_SIMD=y CONFIG_CRYPTO_ENGINE=m +# +# Public-key cryptography +# +CONFIG_CRYPTO_RSA=y +CONFIG_CRYPTO_DH=y +CONFIG_CRYPTO_ECC=m +CONFIG_CRYPTO_ECDH=m +CONFIG_CRYPTO_ECRDSA=m + # # Authenticated Encryption with Associated Data # -CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_CCM=y CONFIG_CRYPTO_GCM=y -CONFIG_CRYPTO_CHACHA20POLY1305=m +CONFIG_CRYPTO_CHACHA20POLY1305=y CONFIG_CRYPTO_AEGIS128=m -CONFIG_CRYPTO_AEGIS128L=m -CONFIG_CRYPTO_AEGIS256=m -CONFIG_CRYPTO_MORUS640=m -CONFIG_CRYPTO_MORUS1280=m +CONFIG_CRYPTO_AEGIS128_SIMD=y CONFIG_CRYPTO_SEQIV=y -CONFIG_CRYPTO_ECHAINIV=y +CONFIG_CRYPTO_ECHAINIV=m # # Block modes @@ -6122,47 +7538,56 @@ CONFIG_CRYPTO_CTR=y CONFIG_CRYPTO_CTS=y CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_OFB=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=y CONFIG_CRYPTO_KEYWRAP=m +CONFIG_CRYPTO_NHPOLY1305=m +CONFIG_CRYPTO_ADIANTUM=m +CONFIG_CRYPTO_ESSIV=m # # Hash modes # -CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_CMAC=m CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_XCBC=y -CONFIG_CRYPTO_VMAC=y +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_VMAC=m # # Digest # CONFIG_CRYPTO_CRC32C=y CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_XXHASH=m CONFIG_CRYPTO_CRCT10DIF=y CONFIG_CRYPTO_GHASH=y -CONFIG_CRYPTO_POLY1305=m -CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_POLY1305=y +CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_MICHAEL_MIC is not set +CONFIG_CRYPTO_MICHAEL_MIC=y CONFIG_CRYPTO_RMD128=y CONFIG_CRYPTO_RMD160=y -CONFIG_CRYPTO_RMD256=y -CONFIG_CRYPTO_RMD320=y +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_LIB_SHA256=y CONFIG_CRYPTO_SHA256=y -CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_SHA3=m CONFIG_CRYPTO_SM3=m +CONFIG_CRYPTO_STREEBOG=m CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=y # # Ciphers # +CONFIG_CRYPTO_LIB_AES=y CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_TI=y +CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_LIB_ARC4=m CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_BLOWFISH_COMMON=m @@ -6170,6 +7595,7 @@ CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST_COMMON=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_LIB_DES=m CONFIG_CRYPTO_DES=m CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_KHAZAD=m @@ -6179,66 +7605,82 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=y CONFIG_CRYPTO_SM4=m CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_TWOFISH_COMMON=y # # Compression # -CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_LZO=y CONFIG_CRYPTO_842=m -CONFIG_CRYPTO_LZ4=y -CONFIG_CRYPTO_LZ4HC=y +CONFIG_CRYPTO_LZ4=m +CONFIG_CRYPTO_LZ4HC=m CONFIG_CRYPTO_ZSTD=m # # Random Number Generation # -CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_ANSI_CPRNG=m CONFIG_CRYPTO_DRBG_MENU=y CONFIG_CRYPTO_DRBG_HMAC=y -# CONFIG_CRYPTO_DRBG_HASH is not set -# CONFIG_CRYPTO_DRBG_CTR is not set +CONFIG_CRYPTO_DRBG_HASH=y +CONFIG_CRYPTO_DRBG_CTR=y CONFIG_CRYPTO_DRBG=y CONFIG_CRYPTO_JITTERENTROPY=y -CONFIG_CRYPTO_USER_API=y -CONFIG_CRYPTO_USER_API_HASH=y -CONFIG_CRYPTO_USER_API_SKCIPHER=y -CONFIG_CRYPTO_USER_API_RNG=y -CONFIG_CRYPTO_USER_API_AEAD=y +CONFIG_CRYPTO_USER_API=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_STATS=y CONFIG_CRYPTO_HASH_INFO=y CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_DEV_ATMEL_I2C=m +CONFIG_CRYPTO_DEV_ATMEL_ECC=m +CONFIG_CRYPTO_DEV_ATMEL_SHA204A=m # CONFIG_CRYPTO_DEV_CCP is not set CONFIG_CRYPTO_DEV_VIRTIO=m +CONFIG_CRYPTO_DEV_SAFEXCEL=m CONFIG_CRYPTO_DEV_CCREE=m -# CONFIG_CRYPTO_DEV_HISI_SEC is not set +CONFIG_CRYPTO_DEV_HISI_SEC=m CONFIG_ASYMMETRIC_KEY_TYPE=y CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE=m CONFIG_X509_CERTIFICATE_PARSER=y +CONFIG_PKCS8_PRIVATE_KEY_PARSER=m +CONFIG_TPM_KEY_PARSER=m CONFIG_PKCS7_MESSAGE_PARSER=y -# CONFIG_PKCS7_TEST_KEY is not set -# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set +CONFIG_PKCS7_TEST_KEY=m +CONFIG_SIGNED_PE_FILE_VERIFICATION=y # # Certificates for signature checking # +CONFIG_MODULE_SIG_KEY="certs/signing_key.pem" CONFIG_SYSTEM_TRUSTED_KEYRING=y CONFIG_SYSTEM_TRUSTED_KEYS="" -# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set -# CONFIG_SECONDARY_TRUSTED_KEYRING is not set -# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set +CONFIG_SYSTEM_EXTRA_CERTIFICATE=y +CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE=4096 +CONFIG_SECONDARY_TRUSTED_KEYRING=y +CONFIG_SYSTEM_BLACKLIST_KEYRING=y +CONFIG_SYSTEM_BLACKLIST_HASH_LIST="" +# end of Certificates for signature checking # # Library routines # CONFIG_RAID6_PQ=y +CONFIG_RAID6_PQ_BENCHMARK=y +CONFIG_PACKING=y CONFIG_BITREVERSE=y CONFIG_HAVE_ARCH_BITREVERSE=y -CONFIG_RATIONAL=y CONFIG_GENERIC_STRNCPY_FROM_USER=y CONFIG_GENERIC_STRNLEN_USER=y CONFIG_GENERIC_NET_UTILS=y +CONFIG_CORDIC=m +CONFIG_PRIME_NUMBERS=m +CONFIG_RATIONAL=y CONFIG_GENERIC_PCI_IOMAP=y CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y CONFIG_ARCH_HAS_FAST_MULTIPLIER=y @@ -6253,11 +7695,11 @@ CONFIG_CRC32_SLICEBY8=y # CONFIG_CRC32_SLICEBY4 is not set # CONFIG_CRC32_SARWATE is not set # CONFIG_CRC32_BIT is not set -CONFIG_CRC64=m -CONFIG_CRC4=y +CONFIG_CRC64=y +CONFIG_CRC4=m CONFIG_CRC7=y CONFIG_LIBCRC32C=y -CONFIG_CRC8=y +CONFIG_CRC8=m CONFIG_XXHASH=y CONFIG_AUDIT_GENERIC=y CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y @@ -6269,8 +7711,8 @@ CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y CONFIG_LZO_COMPRESS=y CONFIG_LZO_DECOMPRESS=y -CONFIG_LZ4_COMPRESS=y -CONFIG_LZ4HC_COMPRESS=y +CONFIG_LZ4_COMPRESS=m +CONFIG_LZ4HC_COMPRESS=m CONFIG_LZ4_DECOMPRESS=y CONFIG_ZSTD_COMPRESS=y CONFIG_ZSTD_DECOMPRESS=y @@ -6282,7 +7724,7 @@ CONFIG_XZ_DEC_ARM=y CONFIG_XZ_DEC_ARMTHUMB=y CONFIG_XZ_DEC_SPARC=y CONFIG_XZ_DEC_BCJ=y -# CONFIG_XZ_DEC_TEST is not set +CONFIG_XZ_DEC_TEST=m CONFIG_DECOMPRESS_GZIP=y CONFIG_DECOMPRESS_BZIP2=y CONFIG_DECOMPRESS_LZMA=y @@ -6290,41 +7732,80 @@ CONFIG_DECOMPRESS_XZ=y CONFIG_DECOMPRESS_LZO=y CONFIG_DECOMPRESS_LZ4=y CONFIG_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_ENC8=y +CONFIG_REED_SOLOMON_DEC8=y +CONFIG_REED_SOLOMON_ENC16=y +CONFIG_REED_SOLOMON_DEC16=y CONFIG_TEXTSEARCH=y CONFIG_TEXTSEARCH_KMP=m CONFIG_TEXTSEARCH_BM=m CONFIG_TEXTSEARCH_FSM=m -CONFIG_RADIX_TREE_MULTIORDER=y +CONFIG_INTERVAL_TREE=y +CONFIG_XARRAY_MULTI=y CONFIG_ASSOCIATIVE_ARRAY=y CONFIG_HAS_IOMEM=y CONFIG_HAS_DMA=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_NEED_DMA_MAP_STATE=y CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_DMA_DIRECT_OPS=y +CONFIG_DMA_DECLARE_COHERENT=y +CONFIG_ARCH_HAS_SETUP_DMA_OPS=y +CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS=y +CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y +CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU=y +CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y +CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN=y CONFIG_SWIOTLB=y +CONFIG_DMA_REMAP=y +CONFIG_DMA_DIRECT_REMAP=y +CONFIG_DMA_CMA=y + +# +# Default contiguous memory area size: +# +CONFIG_CMA_SIZE_MBYTES=128 +CONFIG_CMA_SIZE_SEL_MBYTES=y +# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set +# CONFIG_CMA_SIZE_SEL_MIN is not set +# CONFIG_CMA_SIZE_SEL_MAX is not set +CONFIG_CMA_ALIGNMENT=8 +# CONFIG_DMA_API_DEBUG is not set CONFIG_SGL_ALLOC=y CONFIG_CPU_RMAP=y CONFIG_DQL=y CONFIG_GLOB=y -# CONFIG_GLOB_SELFTEST is not set +CONFIG_GLOB_SELFTEST=m CONFIG_NLATTR=y +CONFIG_LRU_CACHE=m CONFIG_CLZ_TAB=y -CONFIG_CORDIC=m -# CONFIG_DDR is not set -# CONFIG_IRQ_POLL is not set +CONFIG_IRQ_POLL=y CONFIG_MPILIB=y +CONFIG_SIGNATURE=y CONFIG_LIBFDT=y CONFIG_OID_REGISTRY=y +CONFIG_UCS2_STRING=y +CONFIG_HAVE_GENERIC_VDSO=y +CONFIG_GENERIC_GETTIMEOFDAY=y CONFIG_FONT_SUPPORT=y -# CONFIG_FONTS is not set +CONFIG_FONTS=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +CONFIG_FONT_ACORN_8x8=y +# CONFIG_FONT_MINI_4x6 is not set +CONFIG_FONT_6x10=y +# CONFIG_FONT_10x18 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +CONFIG_FONT_TER16x32=y +CONFIG_SG_SPLIT=y CONFIG_SG_POOL=y -CONFIG_ARCH_HAS_SG_CHAIN=y CONFIG_SBITMAP=y # CONFIG_STRING_SELFTEST is not set +# end of Library routines # # Kernel hacking @@ -6334,115 +7815,195 @@ CONFIG_SBITMAP=y # printk and dmesg options # CONFIG_PRINTK_TIME=y -CONFIG_CONSOLE_LOGLEVEL_DEFAULT=1 +# CONFIG_PRINTK_CALLER is not set +CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 CONFIG_CONSOLE_LOGLEVEL_QUIET=4 CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 -# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_DYNAMIC_DEBUG=y +# end of printk and dmesg options # # Compile-time checks and compiler options # +# CONFIG_DEBUG_INFO is not set CONFIG_ENABLE_MUST_CHECK=y -CONFIG_FRAME_WARN=2048 +CONFIG_FRAME_WARN=1024 # CONFIG_STRIP_ASM_SYMS is not set -# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_READABLE_ASM is not set CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set +# CONFIG_HEADERS_INSTALL is not set +CONFIG_OPTIMIZE_INLINING=y # CONFIG_DEBUG_SECTION_MISMATCH is not set CONFIG_SECTION_MISMATCH_WARN_ONLY=y CONFIG_ARCH_WANT_FRAME_POINTERS=y CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# end of Compile-time checks and compiler options + CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 CONFIG_MAGIC_SYSRQ_SERIAL=y -# CONFIG_DEBUG_KERNEL is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_MISC=y # # Memory Debugging # # CONFIG_PAGE_EXTENSION is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_PAGE_OWNER is not set # CONFIG_PAGE_POISONING is not set # CONFIG_DEBUG_RODATA_TEST is not set +# CONFIG_DEBUG_OBJECTS is not set # CONFIG_SLUB_DEBUG_ON is not set # CONFIG_SLUB_STATS is not set CONFIG_HAVE_DEBUG_KMEMLEAK=y +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VM is not set CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y +# CONFIG_DEBUG_VIRTUAL is not set CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_PER_CPU_MAPS is not set CONFIG_HAVE_ARCH_KASAN=y +CONFIG_HAVE_ARCH_KASAN_SW_TAGS=y +CONFIG_CC_HAS_KASAN_GENERIC=y # CONFIG_KASAN is not set +CONFIG_KASAN_STACK=1 +# end of Memory Debugging + CONFIG_ARCH_HAS_KCOV=y CONFIG_CC_HAS_SANCOV_TRACE_PC=y # CONFIG_KCOV is not set +# CONFIG_DEBUG_SHIRQ is not set # # Debug Lockups and Hangs # +# CONFIG_SOFTLOCKUP_DETECTOR is not set +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_WQ_WATCHDOG is not set +# end of Debug Lockups and Hangs + # CONFIG_PANIC_ON_OOPS is not set CONFIG_PANIC_ON_OOPS_VALUE=0 CONFIG_PANIC_TIMEOUT=0 +CONFIG_SCHED_DEBUG=y CONFIG_SCHED_INFO=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_SCHED_STACK_END_CHECK is not set # CONFIG_DEBUG_TIMEKEEPING is not set # # Lock Debugging (spinlocks, mutexes, etc...) # CONFIG_LOCK_DEBUGGING_SUPPORT=y +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_LOCK_TORTURE_TEST is not set # CONFIG_WW_MUTEX_SELFTEST is not set +# end of Lock Debugging (spinlocks, mutexes, etc...) + # CONFIG_STACKTRACE is not set # CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set +# CONFIG_DEBUG_KOBJECT is not set CONFIG_HAVE_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_PLIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set # # RCU Debugging # -CONFIG_RCU_CPU_STALL_TIMEOUT=21 +CONFIG_TORTURE_TEST=m +CONFIG_RCU_PERF_TEST=m +CONFIG_RCU_TORTURE_TEST=m +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +CONFIG_RCU_TRACE=y +# CONFIG_RCU_EQS_DEBUG is not set +# end of RCU Debugging + +# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set +# CONFIG_NOTIFIER_ERROR_INJECTION is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACE_CLOCK=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set -# CONFIG_DMA_API_DEBUG is not set CONFIG_RUNTIME_TESTING_MENU=y # CONFIG_LKDTM is not set # CONFIG_TEST_LIST_SORT is not set # CONFIG_TEST_SORT is not set +CONFIG_BACKTRACE_SELF_TEST=m +CONFIG_RBTREE_TEST=m +CONFIG_REED_SOLOMON_TEST=m +CONFIG_INTERVAL_TREE_TEST=m +CONFIG_PERCPU_TEST=m # CONFIG_ATOMIC64_SELFTEST is not set -# CONFIG_ASYNC_RAID6_TEST is not set +CONFIG_ASYNC_RAID6_TEST=m # CONFIG_TEST_HEXDUMP is not set # CONFIG_TEST_STRING_HELPERS is not set +CONFIG_TEST_STRSCPY=m # CONFIG_TEST_KSTRTOX is not set # CONFIG_TEST_PRINTF is not set # CONFIG_TEST_BITMAP is not set # CONFIG_TEST_BITFIELD is not set # CONFIG_TEST_UUID is not set +CONFIG_TEST_XARRAY=m # CONFIG_TEST_OVERFLOW is not set # CONFIG_TEST_RHASHTABLE is not set # CONFIG_TEST_HASH is not set # CONFIG_TEST_IDA is not set # CONFIG_TEST_LKM is not set +CONFIG_TEST_VMALLOC=m # CONFIG_TEST_USER_COPY is not set -# CONFIG_TEST_BPF is not set +CONFIG_TEST_BPF=m +CONFIG_TEST_BLACKHOLE_DEV=m # CONFIG_FIND_BIT_BENCHMARK is not set # CONFIG_TEST_FIRMWARE is not set # CONFIG_TEST_SYSCTL is not set # CONFIG_TEST_UDELAY is not set # CONFIG_TEST_STATIC_KEYS is not set # CONFIG_TEST_KMOD is not set -# CONFIG_MEMTEST is not set +CONFIG_TEST_MEMCAT_P=m +CONFIG_TEST_STACKINIT=m +# CONFIG_TEST_MEMINIT is not set +CONFIG_MEMTEST=y # CONFIG_BUG_ON_DATA_CORRUPTION is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y # CONFIG_UBSAN is not set +CONFIG_UBSAN_ALIGNMENT=y CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y -# CONFIG_STRICT_DEVMEM is not set +CONFIG_STRICT_DEVMEM=y +# CONFIG_IO_STRICT_DEVMEM is not set +# CONFIG_ARM64_PTDUMP_DEBUGFS is not set # CONFIG_PID_IN_CONTEXTIDR is not set # CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set # CONFIG_DEBUG_WX is not set # CONFIG_DEBUG_ALIGN_RODATA is not set # CONFIG_ARM64_RELOC_TEST is not set # CONFIG_CORESIGHT is not set +# end of Kernel hacking diff --git a/config/sources/families/include/sunxi64_common.inc b/config/sources/families/include/sunxi64_common.inc index ed5edc050..4fe9ef443 100644 --- a/config/sources/families/include/sunxi64_common.inc +++ b/config/sources/families/include/sunxi64_common.inc @@ -10,14 +10,16 @@ LINUXFAMILY=sunxi64 case $BRANCH in legacy) - KERNELBRANCH='branch:linux-4.19.y' + KERNELSOURCE="https://github.com/megous/linux" + KERNELBRANCH="branch:orange-pi-5.4" KERNELPATCHDIR='sunxi-'$BRANCH + ;; current) KERNELSOURCE="https://github.com/megous/linux" - KERNELBRANCH="branch:orange-pi-5.4" + KERNELBRANCH="branch:orange-pi-5.7" KERNELPATCHDIR='sunxi-'$BRANCH ;; diff --git a/config/sources/families/include/sunxi_common.inc b/config/sources/families/include/sunxi_common.inc index 367d45ad4..06f04e766 100644 --- a/config/sources/families/include/sunxi_common.inc +++ b/config/sources/families/include/sunxi_common.inc @@ -12,14 +12,16 @@ GOVERNOR=ondemand case $BRANCH in legacy) - KERNELBRANCH='branch:linux-4.19.y' + KERNELSOURCE="https://github.com/megous/linux" + KERNELBRANCH="branch:orange-pi-5.4" KERNELPATCHDIR='sunxi-'$BRANCH + ;; current) KERNELSOURCE="https://github.com/megous/linux" - KERNELBRANCH="branch:orange-pi-5.4" + KERNELBRANCH="branch:orange-pi-5.7" KERNELPATCHDIR='sunxi-'$BRANCH ;; diff --git a/patch/kernel/sunxi-current/0001-general-armbian-boot-logo.patch b/patch/kernel/sunxi-current/0001-general-armbian-boot-logo.patch.disabled similarity index 100% rename from patch/kernel/sunxi-current/0001-general-armbian-boot-logo.patch rename to patch/kernel/sunxi-current/0001-general-armbian-boot-logo.patch.disabled diff --git a/patch/kernel/sunxi-current/0001-mfd-Add-support-for-AC200.patch b/patch/kernel/sunxi-current/0001-mfd-Add-support-for-AC200.patch new file mode 100644 index 000000000..f74e3c209 --- /dev/null +++ b/patch/kernel/sunxi-current/0001-mfd-Add-support-for-AC200.patch @@ -0,0 +1,440 @@ +From d98aa318aabd4aba05328f9c832b23bdf2e1677a Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Fri, 16 Aug 2019 16:38:21 +0200 +Subject: [PATCH 1/4] mfd: Add support for AC200 + +Signed-off-by: Jernej Skrabec +--- + drivers/mfd/Kconfig | 9 ++ + drivers/mfd/Makefile | 1 + + drivers/mfd/ac200.c | 170 +++++++++++++++++++++++++++++++ + include/linux/mfd/ac200.h | 208 ++++++++++++++++++++++++++++++++++++++ + 4 files changed, 388 insertions(+) + create mode 100644 drivers/mfd/ac200.c + create mode 100644 include/linux/mfd/ac200.h + +diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig +index 420900852166..a45e7c88ac9b 100644 +--- a/drivers/mfd/Kconfig ++++ b/drivers/mfd/Kconfig +@@ -178,6 +178,15 @@ config MFD_AC100 + This driver include only the core APIs. You have to select individual + components like codecs or RTC under the corresponding menus. + ++config MFD_AC200 ++ tristate "X-Powers AC200" ++ select MFD_CORE ++ depends on I2C ++ help ++ If you say Y here you get support for the X-Powers AC200 IC. ++ This driver include only the core APIs. You have to select individual ++ components like Ethernet PHY or RTC under the corresponding menus. ++ + config MFD_AXP20X + tristate + select MFD_CORE +diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile +index aed99f08739f..4431a4cf19ca 100644 +--- a/drivers/mfd/Makefile ++++ b/drivers/mfd/Makefile +@@ -141,6 +141,7 @@ obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o + obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o + + obj-$(CONFIG_MFD_AC100) += ac100.o ++obj-$(CONFIG_MFD_AC200) += ac200.o + obj-$(CONFIG_MFD_AXP20X) += axp20x.o + obj-$(CONFIG_MFD_AXP20X_I2C) += axp20x-i2c.o + obj-$(CONFIG_MFD_AXP20X_RSB) += axp20x-rsb.o +diff --git a/drivers/mfd/ac200.c b/drivers/mfd/ac200.c +new file mode 100644 +index 000000000000..570573790d91 +--- /dev/null ++++ b/drivers/mfd/ac200.c +@@ -0,0 +1,170 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * MFD core driver for X-Powers' AC200 IC ++ * ++ * The AC200 is a chip which is co-packaged with Allwinner H6 SoC and ++ * includes analog audio codec, analog TV encoder, ethernet PHY, eFuse ++ * and RTC. ++ * ++ * Copyright (c) 2020 Jernej Skrabec ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Interrupts */ ++#define AC200_IRQ_RTC 0 ++#define AC200_IRQ_EPHY 1 ++#define AC200_IRQ_TVE 2 ++ ++/* IRQ enable register */ ++#define AC200_SYS_IRQ_ENABLE_OUT_EN BIT(15) ++#define AC200_SYS_IRQ_ENABLE_RTC BIT(12) ++#define AC200_SYS_IRQ_ENABLE_EPHY BIT(8) ++#define AC200_SYS_IRQ_ENABLE_TVE BIT(4) ++ ++static const struct regmap_range_cfg ac200_range_cfg[] = { ++ { ++ .range_min = AC200_SYS_VERSION, ++ .range_max = AC200_IC_CHARA1, ++ .selector_reg = AC200_TWI_REG_ADDR_H, ++ .selector_mask = 0xff, ++ .selector_shift = 0, ++ .window_start = 0, ++ .window_len = 256, ++ } ++}; ++ ++static const struct regmap_config ac200_regmap_config = { ++ .reg_bits = 8, ++ .val_bits = 16, ++ .ranges = ac200_range_cfg, ++ .num_ranges = ARRAY_SIZE(ac200_range_cfg), ++ .max_register = AC200_IC_CHARA1, ++}; ++ ++static const struct regmap_irq ac200_regmap_irqs[] = { ++ REGMAP_IRQ_REG(AC200_IRQ_RTC, 0, AC200_SYS_IRQ_ENABLE_RTC), ++ REGMAP_IRQ_REG(AC200_IRQ_EPHY, 0, AC200_SYS_IRQ_ENABLE_EPHY), ++ REGMAP_IRQ_REG(AC200_IRQ_TVE, 0, AC200_SYS_IRQ_ENABLE_TVE), ++}; ++ ++static const struct regmap_irq_chip ac200_regmap_irq_chip = { ++ .name = "ac200_irq_chip", ++ .status_base = AC200_SYS_IRQ_STATUS, ++ .mask_base = AC200_SYS_IRQ_ENABLE, ++ .mask_invert = true, ++ .irqs = ac200_regmap_irqs, ++ .num_irqs = ARRAY_SIZE(ac200_regmap_irqs), ++ .num_regs = 1, ++}; ++ ++static const struct resource ephy_resource[] = { ++ DEFINE_RES_IRQ(AC200_IRQ_EPHY), ++}; ++ ++static const struct mfd_cell ac200_cells[] = { ++ { ++ .name = "ac200-ephy", ++ .num_resources = ARRAY_SIZE(ephy_resource), ++ .resources = ephy_resource, ++ .of_compatible = "x-powers,ac200-ephy", ++ }, ++}; ++ ++static int ac200_i2c_probe(struct i2c_client *i2c, ++ const struct i2c_device_id *id) ++{ ++ struct device *dev = &i2c->dev; ++ struct ac200_dev *ac200; ++ int ret; ++ ++ ac200 = devm_kzalloc(dev, sizeof(*ac200), GFP_KERNEL); ++ if (!ac200) ++ return -ENOMEM; ++ ++ i2c_set_clientdata(i2c, ac200); ++ ++ ac200->regmap = devm_regmap_init_i2c(i2c, &ac200_regmap_config); ++ if (IS_ERR(ac200->regmap)) { ++ ret = PTR_ERR(ac200->regmap); ++ dev_err(dev, "regmap init failed: %d\n", ret); ++ return ret; ++ } ++ ++ /* do a reset to put chip in a known state */ ++ ++ ret = regmap_write(ac200->regmap, AC200_SYS_CONTROL, 0); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ac200->regmap, AC200_SYS_CONTROL, 1); ++ if (ret) ++ return ret; ++ ++ /* enable interrupt pin */ ++ ++ ret = regmap_write(ac200->regmap, AC200_SYS_IRQ_ENABLE, ++ AC200_SYS_IRQ_ENABLE_OUT_EN); ++ if (ret) ++ return ret; ++ ++ ret = regmap_add_irq_chip(ac200->regmap, i2c->irq, IRQF_ONESHOT, 0, ++ &ac200_regmap_irq_chip, &ac200->regmap_irqc); ++ if (ret) ++ return ret; ++ ++ ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, ac200_cells, ++ ARRAY_SIZE(ac200_cells), NULL, 0, NULL); ++ if (ret) { ++ dev_err(dev, "failed to add MFD devices: %d\n", ret); ++ regmap_del_irq_chip(i2c->irq, ac200->regmap_irqc); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int ac200_i2c_remove(struct i2c_client *i2c) ++{ ++ struct ac200_dev *ac200 = i2c_get_clientdata(i2c); ++ ++ regmap_write(ac200->regmap, AC200_SYS_CONTROL, 0); ++ ++ mfd_remove_devices(&i2c->dev); ++ regmap_del_irq_chip(i2c->irq, ac200->regmap_irqc); ++ ++ return 0; ++} ++ ++static const struct i2c_device_id ac200_ids[] = { ++ { "ac200", }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(i2c, ac200_ids); ++ ++static const struct of_device_id ac200_of_match[] = { ++ { .compatible = "x-powers,ac200" }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, ac200_of_match); ++ ++static struct i2c_driver ac200_i2c_driver = { ++ .driver = { ++ .name = "ac200", ++ .of_match_table = of_match_ptr(ac200_of_match), ++ }, ++ .probe = ac200_i2c_probe, ++ .remove = ac200_i2c_remove, ++ .id_table = ac200_ids, ++}; ++module_i2c_driver(ac200_i2c_driver); ++ ++MODULE_DESCRIPTION("MFD core driver for AC200"); ++MODULE_AUTHOR("Jernej Skrabec "); ++MODULE_LICENSE("GPL v2"); +diff --git a/include/linux/mfd/ac200.h b/include/linux/mfd/ac200.h +new file mode 100644 +index 000000000000..0c677094a5b3 +--- /dev/null ++++ b/include/linux/mfd/ac200.h +@@ -0,0 +1,208 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * AC200 register list ++ * ++ * Copyright (C) 2019 Jernej Skrabec ++ */ ++ ++#ifndef __LINUX_MFD_AC200_H ++#define __LINUX_MFD_AC200_H ++ ++#include ++ ++/* interface registers (can be accessed from any page) */ ++#define AC200_TWI_CHANGE_TO_RSB 0x3E ++#define AC200_TWI_PAD_DELAY 0xC4 ++#define AC200_TWI_REG_ADDR_H 0xFE ++ ++/* General registers */ ++#define AC200_SYS_VERSION 0x0000 ++#define AC200_SYS_CONTROL 0x0002 ++#define AC200_SYS_IRQ_ENABLE 0x0004 ++#define AC200_SYS_IRQ_STATUS 0x0006 ++#define AC200_SYS_CLK_CTL 0x0008 ++#define AC200_SYS_DLDO_OSC_CTL 0x000A ++#define AC200_SYS_PLL_CTL0 0x000C ++#define AC200_SYS_PLL_CTL1 0x000E ++#define AC200_SYS_AUDIO_CTL0 0x0010 ++#define AC200_SYS_AUDIO_CTL1 0x0012 ++#define AC200_SYS_EPHY_CTL0 0x0014 ++#define AC200_SYS_EPHY_CTL1 0x0016 ++#define AC200_SYS_TVE_CTL0 0x0018 ++#define AC200_SYS_TVE_CTL1 0x001A ++ ++/* Audio Codec registers */ ++#define AC200_AC_SYS_CLK_CTL 0x2000 ++#define AC200_SYS_MOD_RST 0x2002 ++#define AC200_SYS_SAMP_CTL 0x2004 ++#define AC200_I2S_CTL 0x2100 ++#define AC200_I2S_CLK 0x2102 ++#define AC200_I2S_FMT0 0x2104 ++#define AC200_I2S_FMT1 0x2108 ++#define AC200_I2S_MIX_SRC 0x2114 ++#define AC200_I2S_MIX_GAIN 0x2116 ++#define AC200_I2S_DACDAT_DVC 0x2118 ++#define AC200_I2S_ADCDAT_DVC 0x211A ++#define AC200_AC_DAC_DPC 0x2200 ++#define AC200_AC_DAC_MIX_SRC 0x2202 ++#define AC200_AC_DAC_MIX_GAIN 0x2204 ++#define AC200_DACA_OMIXER_CTRL 0x2220 ++#define AC200_OMIXER_SR 0x2222 ++#define AC200_LINEOUT_CTRL 0x2224 ++#define AC200_AC_ADC_DPC 0x2300 ++#define AC200_MBIAS_CTRL 0x2310 ++#define AC200_ADC_MIC_CTRL 0x2320 ++#define AC200_ADCMIXER_SR 0x2322 ++#define AC200_ANALOG_TUNING0 0x232A ++#define AC200_ANALOG_TUNING1 0x232C ++#define AC200_AC_AGC_SEL 0x2480 ++#define AC200_ADC_DAPLCTRL 0x2500 ++#define AC200_ADC_DAPRCTRL 0x2502 ++#define AC200_ADC_DAPLSTA 0x2504 ++#define AC200_ADC_DAPRSTA 0x2506 ++#define AC200_ADC_DAPLTL 0x2508 ++#define AC200_ADC_DAPRTL 0x250A ++#define AC200_ADC_DAPLHAC 0x250C ++#define AC200_ADC_DAPLLAC 0x250E ++#define AC200_ADC_DAPRHAC 0x2510 ++#define AC200_ADC_DAPRLAC 0x2512 ++#define AC200_ADC_DAPLDT 0x2514 ++#define AC200_ADC_DAPLAT 0x2516 ++#define AC200_ADC_DAPRDT 0x2518 ++#define AC200_ADC_DAPRAT 0x251A ++#define AC200_ADC_DAPNTH 0x251C ++#define AC200_ADC_DAPLHNAC 0x251E ++#define AC200_ADC_DAPLLNAC 0x2520 ++#define AC200_ADC_DAPRHNAC 0x2522 ++#define AC200_ADC_DAPRLNAC 0x2524 ++#define AC200_AC_DAPHHPFC 0x2526 ++#define AC200_AC_DAPLHPFC 0x2528 ++#define AC200_AC_DAPOPT 0x252A ++#define AC200_AC_DAC_DAPCTRL 0x3000 ++#define AC200_AC_DRC_HHPFC 0x3002 ++#define AC200_AC_DRC_LHPFC 0x3004 ++#define AC200_AC_DRC_CTRL 0x3006 ++#define AC200_AC_DRC_LPFHAT 0x3008 ++#define AC200_AC_DRC_LPFLAT 0x300A ++#define AC200_AC_DRC_RPFHAT 0x300C ++#define AC200_AC_DRC_RPFLAT 0x300E ++#define AC200_AC_DRC_LPFHRT 0x3010 ++#define AC200_AC_DRC_LPFLRT 0x3012 ++#define AC200_AC_DRC_RPFHRT 0x3014 ++#define AC200_AC_DRC_RPFLRT 0x3016 ++#define AC200_AC_DRC_LRMSHAT 0x3018 ++#define AC200_AC_DRC_LRMSLAT 0x301A ++#define AC200_AC_DRC_RRMSHAT 0x301C ++#define AC200_AC_DRC_RRMSLAT 0x301E ++#define AC200_AC_DRC_HCT 0x3020 ++#define AC200_AC_DRC_LCT 0x3022 ++#define AC200_AC_DRC_HKC 0x3024 ++#define AC200_AC_DRC_LKC 0x3026 ++#define AC200_AC_DRC_HOPC 0x3028 ++#define AC200_AC_DRC_LOPC 0x302A ++#define AC200_AC_DRC_HLT 0x302C ++#define AC200_AC_DRC_LLT 0x302E ++#define AC200_AC_DRC_HKI 0x3030 ++#define AC200_AC_DRC_LKI 0x3032 ++#define AC200_AC_DRC_HOPL 0x3034 ++#define AC200_AC_DRC_LOPL 0x3036 ++#define AC200_AC_DRC_HET 0x3038 ++#define AC200_AC_DRC_LET 0x303A ++#define AC200_AC_DRC_HKE 0x303C ++#define AC200_AC_DRC_LKE 0x303E ++#define AC200_AC_DRC_HOPE 0x3040 ++#define AC200_AC_DRC_LOPE 0x3042 ++#define AC200_AC_DRC_HKN 0x3044 ++#define AC200_AC_DRC_LKN 0x3046 ++#define AC200_AC_DRC_SFHAT 0x3048 ++#define AC200_AC_DRC_SFLAT 0x304A ++#define AC200_AC_DRC_SFHRT 0x304C ++#define AC200_AC_DRC_SFLRT 0x304E ++#define AC200_AC_DRC_MXGHS 0x3050 ++#define AC200_AC_DRC_MXGLS 0x3052 ++#define AC200_AC_DRC_MNGHS 0x3054 ++#define AC200_AC_DRC_MNGLS 0x3056 ++#define AC200_AC_DRC_EPSHC 0x3058 ++#define AC200_AC_DRC_EPSLC 0x305A ++#define AC200_AC_DRC_HPFHGAIN 0x305E ++#define AC200_AC_DRC_HPFLGAIN 0x3060 ++#define AC200_AC_DRC_BISTCR 0x3100 ++#define AC200_AC_DRC_BISTST 0x3102 ++ ++/* TVE registers */ ++#define AC200_TVE_CTL0 0x4000 ++#define AC200_TVE_CTL1 0x4002 ++#define AC200_TVE_MOD0 0x4004 ++#define AC200_TVE_MOD1 0x4006 ++#define AC200_TVE_DAC_CFG0 0x4008 ++#define AC200_TVE_DAC_CFG1 0x400A ++#define AC200_TVE_YC_DELAY 0x400C ++#define AC200_TVE_YC_FILTER 0x400E ++#define AC200_TVE_BURST_FRQ0 0x4010 ++#define AC200_TVE_BURST_FRQ1 0x4012 ++#define AC200_TVE_FRONT_PORCH 0x4014 ++#define AC200_TVE_BACK_PORCH 0x4016 ++#define AC200_TVE_TOTAL_LINE 0x401C ++#define AC200_TVE_FIRST_ACTIVE 0x401E ++#define AC200_TVE_BLACK_LEVEL 0x4020 ++#define AC200_TVE_BLANK_LEVEL 0x4022 ++#define AC200_TVE_PLUG_EN 0x4030 ++#define AC200_TVE_PLUG_IRQ_EN 0x4032 ++#define AC200_TVE_PLUG_IRQ_STA 0x4034 ++#define AC200_TVE_PLUG_STA 0x4038 ++#define AC200_TVE_PLUG_DEBOUNCE 0x4040 ++#define AC200_TVE_DAC_TEST 0x4042 ++#define AC200_TVE_PLUG_PULSE_LEVEL 0x40F4 ++#define AC200_TVE_PLUG_PULSE_START 0x40F8 ++#define AC200_TVE_PLUG_PULSE_PERIOD 0x40FA ++#define AC200_TVE_IF_CTL 0x5000 ++#define AC200_TVE_IF_TIM0 0x5008 ++#define AC200_TVE_IF_TIM1 0x500A ++#define AC200_TVE_IF_TIM2 0x500C ++#define AC200_TVE_IF_TIM3 0x500E ++#define AC200_TVE_IF_SYNC0 0x5010 ++#define AC200_TVE_IF_SYNC1 0x5012 ++#define AC200_TVE_IF_SYNC2 0x5014 ++#define AC200_TVE_IF_TIM4 0x5016 ++#define AC200_TVE_IF_STATUS 0x5018 ++ ++/* EPHY registers */ ++#define AC200_EPHY_CTL 0x6000 ++#define AC200_EPHY_BIST 0x6002 ++ ++/* eFuse registers (0x8000 - 0x9FFF, layout unknown) */ ++ ++/* RTC registers */ ++#define AC200_LOSC_CTRL0 0xA000 ++#define AC200_LOSC_CTRL1 0xA002 ++#define AC200_LOSC_AUTO_SWT_STA 0xA004 ++#define AC200_INTOSC_CLK_PRESCAL 0xA008 ++#define AC200_RTC_YY_MM_DD0 0xA010 ++#define AC200_RTC_YY_MM_DD1 0xA012 ++#define AC200_RTC_HH_MM_SS0 0xA014 ++#define AC200_RTC_HH_MM_SS1 0xA016 ++#define AC200_ALARM0_CUR_VLU0 0xA024 ++#define AC200_ALARM0_CUR_VLU1 0xA026 ++#define AC200_ALARM0_ENABLE 0xA028 ++#define AC200_ALARM0_IRQ_EN 0xA02C ++#define AC200_ALARM0_IRQ_STA 0xA030 ++#define AC200_ALARM1_WK_HH_MM_SS0 0xA040 ++#define AC200_ALARM1_WK_HH_MM_SS1 0xA042 ++#define AC200_ALARM1_ENABLE 0xA044 ++#define AC200_ALARM1_IRQ_EN 0xA048 ++#define AC200_ALARM1_IRQ_STA 0xA04C ++#define AC200_ALARM_CONFIG 0xA050 ++#define AC200_LOSC_OUT_GATING 0xA060 ++#define AC200_GP_DATA(x) (0xA100 + (x) * 2) ++#define AC200_RTC_DEB 0xA170 ++#define AC200_GPL_HOLD_OUTPUT 0xA180 ++#define AC200_VDD_RTC 0xA190 ++#define AC200_IC_CHARA0 0xA1F0 ++#define AC200_IC_CHARA1 0xA1F2 ++ ++struct ac200_dev { ++ struct regmap *regmap; ++ struct regmap_irq_chip_data *regmap_irqc; ++}; ++ ++#endif /* __LINUX_MFD_AC200_H */ +-- +2.20.1 + diff --git a/patch/kernel/sunxi-current/0002-net-phy-Add-support-for-AC200-EPHY.patch b/patch/kernel/sunxi-current/0002-net-phy-Add-support-for-AC200-EPHY.patch new file mode 100644 index 000000000..ff87c895f --- /dev/null +++ b/patch/kernel/sunxi-current/0002-net-phy-Add-support-for-AC200-EPHY.patch @@ -0,0 +1,272 @@ +From 1b528543ea41a9837d39e9ab621631c77122f1aa Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Fri, 16 Aug 2019 16:38:57 +0200 +Subject: [PATCH 2/4] net: phy: Add support for AC200 EPHY + +Signed-off-by: Jernej Skrabec +--- + drivers/net/phy/Kconfig | 7 ++ + drivers/net/phy/Makefile | 1 + + drivers/net/phy/ac200.c | 220 +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 228 insertions(+) + create mode 100644 drivers/net/phy/ac200.c + +diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig +index 2e016271e126..248d9384091c 100644 +--- a/drivers/net/phy/Kconfig ++++ b/drivers/net/phy/Kconfig +@@ -266,6 +266,13 @@ config ADIN_PHY + - ADIN1300 - Robust,Industrial, Low Latency 10/100/1000 Gigabit + Ethernet PHY + ++config AC200_PHY ++ tristate "AC200 EPHY" ++ depends on NVMEM ++ depends on OF ++ help ++ Fast ethernet PHY as found in X-Powers AC200 multi-function device. ++ + config AMD_PHY + tristate "AMD PHYs" + ---help--- +diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile +index fe5badf13b65..2143587f010e 100644 +--- a/drivers/net/phy/Makefile ++++ b/drivers/net/phy/Makefile +@@ -49,6 +49,7 @@ obj-$(CONFIG_SFP) += sfp.o + sfp-obj-$(CONFIG_SFP) += sfp-bus.o + obj-y += $(sfp-obj-y) $(sfp-obj-m) + ++obj-$(CONFIG_AC200_PHY) += ac200.o + obj-$(CONFIG_ADIN_PHY) += adin.o + obj-$(CONFIG_AMD_PHY) += amd.o + aquantia-objs += aquantia_main.o +diff --git a/drivers/net/phy/ac200.c b/drivers/net/phy/ac200.c +new file mode 100644 +index 000000000000..cb713188f7ec +--- /dev/null ++++ b/drivers/net/phy/ac200.c +@@ -0,0 +1,220 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/** ++ * Driver for AC200 Ethernet PHY ++ * ++ * Copyright (c) 2020 Jernej Skrabec ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define AC200_EPHY_ID 0x00441400 ++#define AC200_EPHY_ID_MASK 0x0ffffff0 ++ ++/* macros for system ephy control 0 register */ ++#define AC200_EPHY_RESET_INVALID BIT(0) ++#define AC200_EPHY_SYSCLK_GATING BIT(1) ++ ++/* macros for system ephy control 1 register */ ++#define AC200_EPHY_E_EPHY_MII_IO_EN BIT(0) ++#define AC200_EPHY_E_LNK_LED_IO_EN BIT(1) ++#define AC200_EPHY_E_SPD_LED_IO_EN BIT(2) ++#define AC200_EPHY_E_DPX_LED_IO_EN BIT(3) ++ ++/* macros for ephy control register */ ++#define AC200_EPHY_SHUTDOWN BIT(0) ++#define AC200_EPHY_LED_POL BIT(1) ++#define AC200_EPHY_CLK_SEL BIT(2) ++#define AC200_EPHY_ADDR(x) (((x) & 0x1F) << 4) ++#define AC200_EPHY_XMII_SEL BIT(11) ++#define AC200_EPHY_CALIB(x) (((x) & 0xF) << 12) ++ ++struct ac200_ephy_dev { ++ struct clk *clk; ++ struct phy_driver *ephy; ++ struct regmap *regmap; ++}; ++ ++static char *ac200_phy_name = "AC200 EPHY"; ++ ++static int ac200_ephy_config_init(struct phy_device *phydev) ++{ ++ const struct ac200_ephy_dev *priv = phydev->drv->driver_data; ++ unsigned int value; ++ int ret; ++ ++ phy_write(phydev, 0x1f, 0x0100); /* Switch to Page 1 */ ++ phy_write(phydev, 0x12, 0x4824); /* Disable APS */ ++ ++ phy_write(phydev, 0x1f, 0x0200); /* Switch to Page 2 */ ++ phy_write(phydev, 0x18, 0x0000); /* PHYAFE TRX optimization */ ++ ++ phy_write(phydev, 0x1f, 0x0600); /* Switch to Page 6 */ ++ phy_write(phydev, 0x14, 0x708f); /* PHYAFE TX optimization */ ++ phy_write(phydev, 0x13, 0xF000); /* PHYAFE RX optimization */ ++ phy_write(phydev, 0x15, 0x1530); ++ ++ phy_write(phydev, 0x1f, 0x0800); /* Switch to Page 6 */ ++ phy_write(phydev, 0x18, 0x00bc); /* PHYAFE TRX optimization */ ++ ++ phy_write(phydev, 0x1f, 0x0100); /* switch to page 1 */ ++ phy_clear_bits(phydev, 0x17, BIT(3)); /* disable intelligent IEEE */ ++ ++ /* next two blocks disable 802.3az IEEE */ ++ phy_write(phydev, 0x1f, 0x0200); /* switch to page 2 */ ++ phy_write(phydev, 0x18, 0x0000); ++ ++ phy_write(phydev, 0x1f, 0x0000); /* switch to page 0 */ ++ phy_clear_bits_mmd(phydev, 0x7, 0x3c, BIT(1)); ++ ++ if (phydev->interface == PHY_INTERFACE_MODE_RMII) ++ value = AC200_EPHY_XMII_SEL; ++ else ++ value = 0; ++ ++ ret = regmap_update_bits(priv->regmap, AC200_EPHY_CTL, ++ AC200_EPHY_XMII_SEL, value); ++ if (ret) ++ return ret; ++ ++ /* FIXME: This is H6 specific */ ++ phy_set_bits(phydev, 0x13, BIT(12)); ++ ++ return 0; ++} ++ ++static int ac200_ephy_probe(struct platform_device *pdev) ++{ ++ struct ac200_dev *ac200 = dev_get_drvdata(pdev->dev.parent); ++ struct device *dev = &pdev->dev; ++ struct ac200_ephy_dev *priv; ++ struct nvmem_cell *calcell; ++ struct phy_driver *ephy; ++ u16 *caldata, calib; ++ size_t callen; ++ int ret; ++ ++ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ ephy = devm_kzalloc(dev, sizeof(*ephy), GFP_KERNEL); ++ if (!ephy) ++ return -ENOMEM; ++ ++ priv->clk = devm_clk_get(dev, NULL); ++ if (IS_ERR(priv->clk)) { ++ dev_err(dev, "Can't obtain the clock!\n"); ++ return PTR_ERR(priv->clk); ++ } ++ ++ calcell = devm_nvmem_cell_get(dev, "calibration"); ++ if (IS_ERR(calcell)) { ++ dev_err(dev, "Unable to find calibration data!\n"); ++ return PTR_ERR(calcell); ++ } ++ ++ caldata = nvmem_cell_read(calcell, &callen); ++ if (IS_ERR(caldata)) { ++ dev_err(dev, "Unable to read calibration data!\n"); ++ return PTR_ERR(caldata); ++ } ++ ++ if (callen != 2) { ++ dev_err(dev, "Calibration data has wrong length: 2 != %zu\n", ++ callen); ++ kfree(caldata); ++ return -EINVAL; ++ } ++ ++ calib = *caldata + 3; ++ kfree(caldata); ++ ++ ret = clk_prepare_enable(priv->clk); ++ if (ret) ++ return ret; ++ ++ ephy->phy_id = AC200_EPHY_ID; ++ ephy->phy_id_mask = AC200_EPHY_ID_MASK; ++ ephy->name = ac200_phy_name; ++ ephy->driver_data = priv; ++ ephy->soft_reset = genphy_soft_reset; ++ ephy->config_init = ac200_ephy_config_init; ++ ephy->suspend = genphy_suspend; ++ ephy->resume = genphy_resume; ++ ++ priv->ephy = ephy; ++ priv->regmap = ac200->regmap; ++ platform_set_drvdata(pdev, priv); ++ ++ ret = regmap_write(ac200->regmap, AC200_SYS_EPHY_CTL0, ++ AC200_EPHY_RESET_INVALID | ++ AC200_EPHY_SYSCLK_GATING); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ac200->regmap, AC200_SYS_EPHY_CTL1, ++ AC200_EPHY_E_EPHY_MII_IO_EN | ++ AC200_EPHY_E_LNK_LED_IO_EN | ++ AC200_EPHY_E_SPD_LED_IO_EN | ++ AC200_EPHY_E_DPX_LED_IO_EN); ++ if (ret) ++ return ret; ++ ++ ret = regmap_write(ac200->regmap, AC200_EPHY_CTL, ++ AC200_EPHY_LED_POL | ++ AC200_EPHY_CLK_SEL | ++ AC200_EPHY_ADDR(1) | ++ AC200_EPHY_CALIB(calib)); ++ if (ret) ++ return ret; ++ ++ ret = phy_driver_register(priv->ephy, THIS_MODULE); ++ if (ret) { ++ dev_err(dev, "Unable to register phy\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int ac200_ephy_remove(struct platform_device *pdev) ++{ ++ struct ac200_ephy_dev *priv = platform_get_drvdata(pdev); ++ ++ phy_driver_unregister(priv->ephy); ++ ++ regmap_write(priv->regmap, AC200_EPHY_CTL, AC200_EPHY_SHUTDOWN); ++ regmap_write(priv->regmap, AC200_SYS_EPHY_CTL1, 0); ++ regmap_write(priv->regmap, AC200_SYS_EPHY_CTL0, 0); ++ ++ clk_disable_unprepare(priv->clk); ++ ++ return 0; ++} ++ ++static const struct of_device_id ac200_ephy_match[] = { ++ { .compatible = "x-powers,ac200-ephy" }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, ac200_ephy_match); ++ ++static struct platform_driver ac200_ephy_driver = { ++ .probe = ac200_ephy_probe, ++ .remove = ac200_ephy_remove, ++ .driver = { ++ .name = "ac200-ephy", ++ .of_match_table = ac200_ephy_match, ++ }, ++}; ++module_platform_driver(ac200_ephy_driver); ++ ++MODULE_AUTHOR("Jernej Skrabec "); ++MODULE_DESCRIPTION("AC200 Ethernet PHY driver"); ++MODULE_LICENSE("GPL"); +-- +2.20.1 + diff --git a/patch/kernel/sunxi-current/0003-arm64-dts-allwinner-h6-Add-AC200-EPHY-related-nodes.patch b/patch/kernel/sunxi-current/0003-arm64-dts-allwinner-h6-Add-AC200-EPHY-related-nodes.patch new file mode 100644 index 000000000..c837c245b --- /dev/null +++ b/patch/kernel/sunxi-current/0003-arm64-dts-allwinner-h6-Add-AC200-EPHY-related-nodes.patch @@ -0,0 +1,122 @@ +From 1b08baab634bebd4ef94ca449b81d7550c91abf0 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 12 Jan 2020 12:09:12 +0100 +Subject: [PATCH 3/4] arm64: dts: allwinner: h6: Add AC200 EPHY related nodes + +Signed-off-by: Jernej Skrabec +--- + arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 63 ++++++++++++++++++++ + 1 file changed, 63 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +index 3329283e38ab..81caf1e96407 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +@@ -16,6 +16,16 @@ + #address-cells = <1>; + #size-cells = <1>; + ++ ac200_pwm_clk: ac200_clk { ++ compatible = "pwm-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <24000000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm1_pin>; ++ pwms = <&pwm 1 42 0>; ++ status = "disabled"; ++ }; ++ + cpus { + #address-cells = <1>; + #size-cells = <0>; +@@ -248,6 +258,10 @@ + ths_calibration: thermal-sensor-calibration@14 { + reg = <0x14 0x8>; + }; ++ ++ ephy_calibration: ephy-calibration@2c { ++ reg = <0x2c 0x2>; ++ }; + }; + + watchdog: watchdog@30090a0 { +@@ -291,6 +305,14 @@ + function = "emac"; + drive-strength = <40>; + }; ++ ++ /omit-if-no-ref/ ++ ext_rmii_pins: rmii_pins { ++ pins = "PA0", "PA1", "PA2", "PA3", "PA4", ++ "PA5", "PA6", "PA7", "PA8", "PA9"; ++ function = "emac"; ++ drive-strength = <40>; ++ }; + + hdmi_pins: hdmi-pins { + pins = "PH8", "PH9", "PH10"; +@@ -311,6 +333,11 @@ + pins = "PD23", "PD24"; + function = "i2c2"; + }; ++ ++ i2c3_pins: i2c3-pins { ++ pins = "PB17", "PB18"; ++ function = "i2c3"; ++ }; + + mmc0_pins: mmc0-pins { + pins = "PF0", "PF1", "PF2", "PF3", +@@ -329,6 +356,11 @@ + bias-pull-up; + }; + ++ pwm1_pin: pwm1-pin { ++ pins = "PB19"; ++ function = "pwm1"; ++ }; ++ + mmc2_pins: mmc2-pins { + pins = "PC1", "PC4", "PC5", "PC6", + "PC7", "PC8", "PC9", "PC10", +@@ -504,6 +536,37 @@ + #size-cells = <0>; + }; + ++ i2c3: i2c@5002c00 { ++ compatible = "allwinner,sun50i-h6-i2c", ++ "allwinner,sun6i-a31-i2c"; ++ reg = <0x05002c00 0x400>; ++ interrupts = ; ++ clocks = <&ccu CLK_BUS_I2C3>; ++ resets = <&ccu RST_BUS_I2C3>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c3_pins>; ++ status = "disabled"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ac200: mfd@10 { ++ compatible = "x-powers,ac200"; ++ reg = <0x10>; ++ interrupt-parent = <&pio>; ++ interrupts = <1 20 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-controller; ++ #interrupt-cells = <1>; ++ ++ ac200_ephy: phy { ++ compatible = "x-powers,ac200-ephy"; ++ clocks = <&ac200_pwm_clk>; ++ nvmem-cells = <&ephy_calibration>; ++ nvmem-cell-names = "calibration"; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ + emac: ethernet@5020000 { + compatible = "allwinner,sun50i-h6-emac", + "allwinner,sun50i-a64-emac"; +-- +2.20.1 + diff --git a/patch/kernel/sunxi-current/0004-arm64-dts-allwinner-h6-tanix-tx6-Enable-ethernet.patch b/patch/kernel/sunxi-current/0004-arm64-dts-allwinner-h6-tanix-tx6-Enable-ethernet.patch new file mode 100644 index 000000000..d69f2ae6b --- /dev/null +++ b/patch/kernel/sunxi-current/0004-arm64-dts-allwinner-h6-tanix-tx6-Enable-ethernet.patch @@ -0,0 +1,84 @@ +From 15a2214233c38b98cb76e7214c83fbc26068a909 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sun, 12 Jan 2020 12:19:51 +0100 +Subject: [PATCH 4/4] arm64: dts: allwinner: h6: tanix-tx6: Enable ethernet + +Signed-off-by: Jernej Skrabec +--- + .../dts/allwinner/sun50i-h6-tanix-tx6.dts | 32 +++++++++++++++++++ + 1 file changed, 32 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts +index 83e6cb0e59ce..41a2e3454be5 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts +@@ -12,6 +12,7 @@ + compatible = "oranth,tanix-tx6", "allwinner,sun50i-h6"; + + aliases { ++ ethernet0 = &emac; + serial0 = &uart0; + }; + +@@ -39,6 +40,14 @@ + }; + }; + ++&ac200_ephy { ++ status = "okay"; ++}; ++ ++&ac200_pwm_clk { ++ status = "okay"; ++}; ++ + &de { + status = "okay"; + }; +@@ -47,6 +56,14 @@ + status = "okay"; + }; + ++&emac { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ext_rmii_pins>; ++ phy-mode = "rmii"; ++ phy-handle = <&ext_rmii_phy>; ++ status = "okay"; ++}; ++ + &ehci0 { + status = "okay"; + }; +@@ -69,6 +86,17 @@ + }; + }; + ++&i2c3 { ++ status = "okay"; ++}; ++ ++&mdio { ++ ext_rmii_phy: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <1>; ++ }; ++}; ++ + &mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; +@@ -86,6 +114,10 @@ + status = "okay"; + }; + ++&pwm { ++ status = "okay"; ++}; ++ + &r_ir { + linux,rc-map-name = "rc-tanix-tx5max"; + status = "okay"; +-- +2.20.1 + diff --git a/patch/kernel/sunxi-current/0004-sun4i-i2s-improvements.patch.disabled b/patch/kernel/sunxi-current/0004-sun4i-i2s-improvements.patch.disabled new file mode 100644 index 000000000..3d9599fa9 --- /dev/null +++ b/patch/kernel/sunxi-current/0004-sun4i-i2s-improvements.patch.disabled @@ -0,0 +1,751 @@ +From b5cb1681a065bd03b0eb84ca243bc50ab0fa54c1 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Tue, 17 Sep 2019 17:55:07 +0200 +Subject: [PATCH] WIP: I2S improvements (to be mainlined) + +Work done by Marcus Cooper (codekipper) +--- + sound/soc/sunxi/sun4i-i2s.c | 454 ++++++++++++++++++++++++++++++++---- + 1 file changed, 412 insertions(+), 42 deletions(-) + +diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c +index d0a8d5810c0a..9a715a6bdbf9 100644 +--- a/sound/soc/sunxi/sun4i-i2s.c ++++ b/sound/soc/sunxi/sun4i-i2s.c +@@ -23,7 +23,7 @@ + + #define SUN4I_I2S_CTRL_REG 0x00 + #define SUN4I_I2S_CTRL_SDO_EN_MASK GENMASK(11, 8) +-#define SUN4I_I2S_CTRL_SDO_EN(sdo) BIT(8 + (sdo)) ++#define SUN4I_I2S_CTRL_SDO_EN(lines) (((1 << (lines)) - 1) << 8) + #define SUN4I_I2S_CTRL_MODE_MASK BIT(5) + #define SUN4I_I2S_CTRL_MODE_SLAVE (1 << 5) + #define SUN4I_I2S_CTRL_MODE_MASTER (0 << 5) +@@ -48,6 +48,9 @@ + #define SUN4I_I2S_FMT0_FMT_I2S (0 << 0) + + #define SUN4I_I2S_FMT1_REG 0x08 ++#define SUN4I_I2S_FMT1_REG_SEXT_MASK BIT(8) ++#define SUN4I_I2S_FMT1_REG_SEXT(sext) ((sext) << 8) ++ + #define SUN4I_I2S_FIFO_TX_REG 0x0c + #define SUN4I_I2S_FIFO_RX_REG 0x10 + +@@ -100,22 +100,25 @@ + #define SUN8I_I2S_CTRL_MODE_PCM (0 << 4) + + #define SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK BIT(19) +-#define SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED (1 << 19) +-#define SUN8I_I2S_FMT0_LRCLK_POLARITY_NORMAL (0 << 19) ++#define SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED (1 << 19) ++#define SUN8I_I2S_FMT0_LRCLK_POLARITY_NORMAL (0 << 19) + #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK GENMASK(17, 8) + #define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8) + #define SUN8I_I2S_FMT0_BCLK_POLARITY_MASK BIT(7) +-#define SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED (1 << 7) +-#define SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL (0 << 7) ++#define SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED (1 << 7) ++#define SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL (0 << 7) ++ ++#define SUN8I_I2S_FMT1_REG_SEXT_MASK GENMASK(5, 4) ++#define SUN8I_I2S_FMT1_REG_SEXT(sext) ((sext) << 4) + + #define SUN8I_I2S_INT_STA_REG 0x0c + #define SUN8I_I2S_FIFO_TX_REG 0x20 + + #define SUN8I_I2S_CHAN_CFG_REG 0x30 + #define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK GENMASK(6, 4) +-#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan) ((chan - 1) << 4) ++#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan) (((chan) - 1) << 4) + #define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK GENMASK(2, 0) +-#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan) (chan - 1) ++#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan) ((chan) - 1) + + #define SUN8I_I2S_TX_CHAN_MAP_REG 0x44 + #define SUN8I_I2S_TX_CHAN_SEL_REG 0x34 +@@ -123,10 +126,27 @@ + #define SUN8I_I2S_TX_CHAN_OFFSET(offset) ((offset) << 12) + #define SUN8I_I2S_TX_CHAN_EN_MASK GENMASK(11, 4) + #define SUN8I_I2S_TX_CHAN_EN(num_chan) (((1 << num_chan) - 1) << 4) ++#define SUN8I_I2S_TX_CHAN_SEL_MASK GENMASK(2, 0) ++#define SUN8I_I2S_TX_CHAN_SEL(chan) ((chan) - 1) + + #define SUN8I_I2S_RX_CHAN_SEL_REG 0x54 + #define SUN8I_I2S_RX_CHAN_MAP_REG 0x58 + ++/* Defines required for sun50i-h6 support */ ++#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK GENMASK(21, 20) ++#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset) ((offset) << 20) ++#define SUN50I_H6_I2S_TX_CHAN_SEL_MASK GENMASK(19, 16) ++#define SUN50I_H6_I2S_TX_CHAN_SEL(chan) (((chan) - 1) << 16) ++#define SUN50I_H6_I2S_TX_CHAN_EN_MASK GENMASK(15, 0) ++#define SUN50I_H6_I2S_TX_CHAN_EN(num_chan) (((1 << (num_chan)) - 1)) ++ ++#define SUN50I_H6_I2S_TX_CHAN_MAP0_REG 0x44 ++#define SUN50I_H6_I2S_TX_CHAN_MAP1_REG 0x48 ++ ++#define SUN50I_H6_I2S_RX_CHAN_SEL_REG 0x64 ++#define SUN50I_H6_I2S_RX_CHAN_MAP0_REG 0x68 ++#define SUN50I_H6_I2S_RX_CHAN_MAP1_REG 0x6C ++ + struct sun4i_i2s; + + /** +@@ -156,7 +179,16 @@ struct sun4i_i2s_quirks { + s8 (*get_wss)(const struct sun4i_i2s *, int); + int (*set_chan_cfg)(const struct sun4i_i2s *, + const struct snd_pcm_hw_params *); +- int (*set_fmt)(const struct sun4i_i2s *, unsigned int); ++ int (*set_fmt)(struct sun4i_i2s *, unsigned int); ++ void (*set_fmt_sext)(const struct sun4i_i2s *, unsigned int); ++ void (*set_txchanoffset)(const struct sun4i_i2s *, int); ++ void (*set_rxchanoffset)(const struct sun4i_i2s *); ++ void (*set_txchanen)(const struct sun4i_i2s *, int, int); ++ void (*set_rxchanen)(const struct sun4i_i2s *, int); ++ void (*set_txchansel)(const struct sun4i_i2s *, int, int); ++ void (*set_rxchansel)(const struct sun4i_i2s *, int); ++ void (*set_txchanmap)(const struct sun4i_i2s *, int, int); ++ void (*set_rxchanmap)(const struct sun4i_i2s *, int); + }; + + struct sun4i_i2s { +@@ -169,6 +201,7 @@ struct sun4i_i2s { + unsigned int mclk_freq; + unsigned int slots; + unsigned int slot_width; ++ unsigned int offset; + + struct snd_dmaengine_dai_dma_data capture_dma_data; + struct snd_dmaengine_dai_dma_data playback_dma_data; +@@ -354,6 +387,9 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai, + + regmap_field_write(i2s->field_clkdiv_mclk_en, 1); + ++ /* Set sign extension to pad out LSB with 0 */ ++ i2s->variant->set_fmt_sext(i2s, 0); ++ + return 0; + } + +@@ -396,8 +432,8 @@ static int sun4i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s, + unsigned int channels = params_channels(params); + + /* Map the channels for playback and capture */ +- regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210); +- regmap_write(i2s->regmap, SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210); ++ i2s->variant->set_txchanmap(i2s, 0, 0x76543210); ++ i2s->variant->set_rxchanmap(i2s, 0x3210); + + /* Configure the channels */ + regmap_update_bits(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG, +@@ -421,16 +457,12 @@ static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s, + slots = i2s->slots; + + /* Map the channels for playback and capture */ +- regmap_write(i2s->regmap, SUN8I_I2S_TX_CHAN_MAP_REG, 0x76543210); +- regmap_write(i2s->regmap, SUN8I_I2S_RX_CHAN_MAP_REG, 0x76543210); ++ i2s->variant->set_txchanmap(i2s, 0, 0x76543210); ++ i2s->variant->set_rxchanmap(i2s, 0x3210); + + /* Configure the channels */ +- regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG, +- SUN4I_I2S_CHAN_SEL_MASK, +- SUN4I_I2S_CHAN_SEL(channels)); +- regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG, +- SUN4I_I2S_CHAN_SEL_MASK, +- SUN4I_I2S_CHAN_SEL(channels)); ++ i2s->variant->set_txchansel(i2s, 0, channels); ++ i2s->variant->set_rxchansel(i2s, channels); + + regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, + SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK, +@@ -448,7 +480,10 @@ static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s, + break; + + case SND_SOC_DAIFMT_I2S: +- lrck_period = params_physical_width(params); ++ if (i2s->slot_width) ++ lrck_period = i2s->slot_width; ++ else ++ lrck_period = params_physical_width(params); + break; + + default: +@@ -466,6 +501,166 @@ static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s, + return 0; + } + ++static void sun8i_i2s_set_txchanoffset(const struct sun4i_i2s *i2s, int output) ++{ ++ if (output >= 0 && output < 4) ++ regmap_update_bits(i2s->regmap, ++ SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4), ++ SUN8I_I2S_TX_CHAN_OFFSET_MASK, ++ SUN8I_I2S_TX_CHAN_OFFSET(i2s->offset)); ++} ++ ++static void sun8i_i2s_set_rxchanoffset(const struct sun4i_i2s *i2s) ++{ ++ regmap_update_bits(i2s->regmap, ++ SUN8I_I2S_RX_CHAN_SEL_REG, ++ SUN8I_I2S_TX_CHAN_OFFSET_MASK, ++ SUN8I_I2S_TX_CHAN_OFFSET(i2s->offset)); ++} ++ ++static void sun50i_h6_i2s_set_txchanoffset(const struct sun4i_i2s *i2s, int output) ++{ ++ if (output >= 0 && output < 4) ++ regmap_update_bits(i2s->regmap, ++ SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4), ++ SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK, ++ SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(i2s->offset)); ++} ++ ++static void sun50i_h6_i2s_set_rxchanoffset(const struct sun4i_i2s *i2s) ++{ ++ regmap_update_bits(i2s->regmap, ++ SUN50I_H6_I2S_RX_CHAN_SEL_REG, ++ SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK, ++ SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(i2s->offset)); ++} ++ ++static void sun8i_i2s_set_txchanen(const struct sun4i_i2s *i2s, int output, ++ int channel) ++{ ++ if (output >= 0 && output < 4) ++ regmap_update_bits(i2s->regmap, ++ SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4), ++ SUN8I_I2S_TX_CHAN_EN_MASK, ++ SUN8I_I2S_TX_CHAN_EN(channel)); ++} ++ ++static void sun8i_i2s_set_rxchanen(const struct sun4i_i2s *i2s, int channel) ++{ ++ regmap_update_bits(i2s->regmap, ++ SUN8I_I2S_RX_CHAN_SEL_REG, ++ SUN8I_I2S_TX_CHAN_EN_MASK, ++ SUN8I_I2S_TX_CHAN_EN(channel)); ++} ++ ++static void sun50i_h6_i2s_set_txchanen(const struct sun4i_i2s *i2s, int output, ++ int channel) ++{ ++ if (output >= 0 && output < 4) ++ regmap_update_bits(i2s->regmap, ++ SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4), ++ SUN50I_H6_I2S_TX_CHAN_EN_MASK, ++ SUN50I_H6_I2S_TX_CHAN_EN(channel)); ++} ++ ++static void sun50i_h6_i2s_set_rxchanen(const struct sun4i_i2s *i2s, int channel) ++{ ++ regmap_update_bits(i2s->regmap, ++ SUN50I_H6_I2S_RX_CHAN_SEL_REG, ++ SUN50I_H6_I2S_TX_CHAN_EN_MASK, ++ SUN50I_H6_I2S_TX_CHAN_EN(channel)); ++} ++ ++static void sun4i_i2s_set_txchansel(const struct sun4i_i2s *i2s, int output, ++ int channel) ++{ ++ /* Configure the channels */ ++ regmap_write(i2s->regmap, ++ SUN4I_I2S_TX_CHAN_SEL_REG, ++ SUN4I_I2S_CHAN_SEL(channel)); ++} ++ ++static void sun8i_i2s_set_txchansel(const struct sun4i_i2s *i2s, int output, ++ int channel) ++{ ++ if (output >= 0 && output < 4) ++ regmap_update_bits(i2s->regmap, ++ SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4), ++ SUN8I_I2S_TX_CHAN_SEL_MASK, ++ SUN8I_I2S_TX_CHAN_SEL(channel)); ++} ++ ++static void sun4i_i2s_set_rxchansel(const struct sun4i_i2s *i2s, int channel) ++{ ++ /* Configure the channels */ ++ regmap_write(i2s->regmap, ++ SUN4I_I2S_RX_CHAN_SEL_REG, ++ SUN4I_I2S_CHAN_SEL(channel)); ++} ++ ++static void sun8i_i2s_set_rxchansel(const struct sun4i_i2s *i2s, int channel) ++{ ++ regmap_update_bits(i2s->regmap, ++ SUN8I_I2S_RX_CHAN_SEL_REG, ++ SUN8I_I2S_TX_CHAN_SEL_MASK, ++ SUN8I_I2S_TX_CHAN_SEL(channel)); ++} ++ ++static void sun50i_h6_i2s_set_txchansel(const struct sun4i_i2s *i2s, int output, ++ int channel) ++{ ++ if (output >= 0 && output < 4) ++ regmap_update_bits(i2s->regmap, ++ SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4), ++ SUN50I_H6_I2S_TX_CHAN_SEL_MASK, ++ SUN50I_H6_I2S_TX_CHAN_SEL(channel)); ++} ++ ++static void sun50i_h6_i2s_set_rxchansel(const struct sun4i_i2s *i2s, int channel) ++{ ++ regmap_update_bits(i2s->regmap, ++ SUN50I_H6_I2S_RX_CHAN_SEL_REG, ++ SUN50I_H6_I2S_TX_CHAN_SEL_MASK, ++ SUN50I_H6_I2S_TX_CHAN_SEL(channel)); ++} ++ ++static void sun4i_i2s_set_txchanmap(const struct sun4i_i2s *i2s, int output, ++ int channel) ++{ ++ regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG, channel); ++} ++ ++static void sun8i_i2s_set_txchanmap(const struct sun4i_i2s *i2s, int output, ++ int channel) ++{ ++ if (output >= 0 && output < 4) ++ regmap_write(i2s->regmap, ++ SUN8I_I2S_TX_CHAN_MAP_REG + (output * 4), channel); ++} ++ ++static void sun4i_i2s_set_rxchanmap(const struct sun4i_i2s *i2s, int channel) ++{ ++ regmap_write(i2s->regmap, SUN4I_I2S_RX_CHAN_MAP_REG, channel); ++} ++ ++static void sun8i_i2s_set_rxchanmap(const struct sun4i_i2s *i2s, int channel) ++{ ++ regmap_write(i2s->regmap, SUN8I_I2S_RX_CHAN_MAP_REG, channel); ++} ++ ++static void sun50i_h6_i2s_set_txchanmap(const struct sun4i_i2s *i2s, int output, ++ int channel) ++{ ++ if (output >= 0 && output < 4) ++ regmap_write(i2s->regmap, ++ SUN50I_H6_I2S_TX_CHAN_MAP1_REG + (output * 8), channel); ++} ++ ++static void sun50i_h6_i2s_set_rxchanmap(const struct sun4i_i2s *i2s, int channel) ++{ ++ regmap_write(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_MAP1_REG, channel); ++} ++ + static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +@@ -477,6 +672,7 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, + unsigned int slots = channels; + int ret, sr, wss; + u32 width; ++ int lines; + + if (i2s->slots) + slots = i2s->slots; +@@ -490,10 +686,82 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, + return ret; + } + ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ if (channels > dai->driver->playback.channels_max || ++ channels < dai->driver->playback.channels_min) { ++ dev_err(dai->dev, "Unsupported number of channels: %d\n", ++ channels); ++ return -EINVAL; ++ } ++ ++ lines = (channels + 1) / 2; ++ ++ /* Enable the required output lines */ ++ regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, ++ SUN4I_I2S_CTRL_SDO_EN_MASK, ++ SUN4I_I2S_CTRL_SDO_EN(lines)); ++ ++ i2s->variant->set_txchanmap(i2s, 0, 0x10); ++ i2s->variant->set_txchansel(i2s, 0, channels > 1 ? 2 : 1); ++ ++ if (i2s->variant->set_txchanen) ++ i2s->variant->set_txchanen(i2s, 0, 2); ++ ++ if (i2s->variant->set_txchanoffset) { ++ regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, ++ SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK, ++ SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels)); ++ ++ if (channels > 2) { ++ i2s->variant->set_txchanmap(i2s, 1, 0x32); ++ i2s->variant->set_txchanoffset(i2s, 1); ++ i2s->variant->set_txchansel(i2s, 1, ++ channels > 3 ? 2 : 1); ++ i2s->variant->set_txchanen(i2s, 1, 2); ++ } ++ if (channels > 4) { ++ i2s->variant->set_txchanmap(i2s, 2, 0x54); ++ i2s->variant->set_txchanoffset(i2s, 2); ++ i2s->variant->set_txchansel(i2s, 2, ++ channels > 5 ? 2 : 1); ++ i2s->variant->set_txchanen(i2s, 2, 2); ++ } ++ if (channels > 6) { ++ i2s->variant->set_txchanmap(i2s, 3, 0x76); ++ i2s->variant->set_txchanoffset(i2s, 3); ++ i2s->variant->set_txchansel(i2s, 3, ++ channels > 6 ? 2 : 1); ++ i2s->variant->set_txchanen(i2s, 3, 2); ++ } ++ } ++ } else { ++ if (channels > dai->driver->capture.channels_max || ++ channels < dai->driver->capture.channels_min) { ++ dev_err(dai->dev, "Unsupported number of channels: %d\n", ++ channels); ++ return -EINVAL; ++ } ++ ++ /* Map the channels for capture */ ++ i2s->variant->set_rxchanmap(i2s, 0x10); ++ i2s->variant->set_rxchansel(i2s, channels); ++ ++ if (i2s->variant->set_rxchanen) ++ i2s->variant->set_rxchanen(i2s, channels); ++ ++ if (i2s->variant->set_rxchanoffset) ++ regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, ++ SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK, ++ SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels)); ++ } ++ + switch (params_physical_width(params)) { + case 16: + width = DMA_SLAVE_BUSWIDTH_2_BYTES; + break; ++ case 32: ++ width = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ break; + default: + dev_err(dai->dev, "Unsupported physical sample width: %d\n", + params_physical_width(params)); +@@ -516,7 +784,7 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, + slots, slot_width); + } + +-static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, ++static int sun4i_i2s_set_soc_fmt(struct sun4i_i2s *i2s, + unsigned int fmt) + { + u32 val; +@@ -589,11 +857,10 @@ static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, + return 0; + } + +-static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, ++static int sun8i_i2s_set_soc_fmt(struct sun4i_i2s *i2s, + unsigned int fmt) + { + u32 mode, val; +- u8 offset; + + /* + * DAI clock polarity +@@ -632,27 +899,27 @@ static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + mode = SUN8I_I2S_CTRL_MODE_PCM; +- offset = 1; ++ i2s->offset = 1; + break; + + case SND_SOC_DAIFMT_DSP_B: + mode = SUN8I_I2S_CTRL_MODE_PCM; +- offset = 0; ++ i2s->offset = 0; + break; + + case SND_SOC_DAIFMT_I2S: + mode = SUN8I_I2S_CTRL_MODE_LEFT; +- offset = 1; ++ i2s->offset = 1; + break; + + case SND_SOC_DAIFMT_LEFT_J: + mode = SUN8I_I2S_CTRL_MODE_LEFT; +- offset = 0; ++ i2s->offset = 0; + break; + + case SND_SOC_DAIFMT_RIGHT_J: + mode = SUN8I_I2S_CTRL_MODE_RIGHT; +- offset = 0; ++ i2s->offset = 0; + break; + + default: +@@ -913,12 +933,8 @@ static int sun8i_i2s_set_soc_fmt(struct sun4i_i2s *i2s, + + regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, + SUN8I_I2S_CTRL_MODE_MASK, mode); +- regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG, +- SUN8I_I2S_TX_CHAN_OFFSET_MASK, +- SUN8I_I2S_TX_CHAN_OFFSET(offset)); +- regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG, +- SUN8I_I2S_TX_CHAN_OFFSET_MASK, +- SUN8I_I2S_TX_CHAN_OFFSET(offset)); ++ i2s->variant->set_txchanoffset(i2s, 0); ++ i2s->variant->set_rxchanoffset(i2s); + + /* DAI clock master masks */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { +@@ -691,6 +954,22 @@ static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, + return 0; + } + ++static void sun4i_i2s_set_fmt_sext(const struct sun4i_i2s *i2s, ++ unsigned int sext) ++{ ++ regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG, ++ SUN4I_I2S_FMT1_REG_SEXT_MASK, ++ SUN4I_I2S_FMT1_REG_SEXT(sext)); ++} ++ ++static void sun8i_i2s_set_fmt_sext(const struct sun4i_i2s *i2s, ++ unsigned int sext) ++{ ++ regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG, ++ SUN8I_I2S_FMT1_REG_SEXT_MASK, ++ SUN8I_I2S_FMT1_REG_SEXT(sext)); ++} ++ + static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) + { + struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); +@@ -717,9 +996,9 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) + static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s) + { + /* Flush RX FIFO */ +- regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG, +- SUN4I_I2S_FIFO_CTRL_FLUSH_RX, +- SUN4I_I2S_FIFO_CTRL_FLUSH_RX); ++ regmap_write_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG, ++ SUN4I_I2S_FIFO_CTRL_FLUSH_RX, ++ SUN4I_I2S_FIFO_CTRL_FLUSH_RX); + + /* Clear RX counter */ + regmap_write(i2s->regmap, SUN4I_I2S_RX_CNT_REG, 0); +@@ -738,9 +1017,9 @@ static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s) + static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s) + { + /* Flush TX FIFO */ +- regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG, +- SUN4I_I2S_FIFO_CTRL_FLUSH_TX, +- SUN4I_I2S_FIFO_CTRL_FLUSH_TX); ++ regmap_write_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG, ++ SUN4I_I2S_FIFO_CTRL_FLUSH_TX, ++ SUN4I_I2S_FIFO_CTRL_FLUSH_TX); + + /* Clear TX counter */ + regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0); +@@ -862,6 +1141,10 @@ static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai) + return 0; + } + ++#define SUN4I_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ ++ SNDRV_PCM_FMTBIT_S20_LE | \ ++ SNDRV_PCM_FMTBIT_S24_LE) ++ + static struct snd_soc_dai_driver sun4i_i2s_dai = { + .probe = sun4i_i2s_dai_probe, + .capture = { +@@ -869,14 +1152,14 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = { + .channels_min = 1, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_8000_192000, +- .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ .formats = SUN4I_FORMATS, + }, + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_8000_192000, +- .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ .formats = SUN4I_FORMATS, + }, + .ops = &sun4i_i2s_dai_ops, + .symmetric_rates = 1, +@@ -971,6 +1254,22 @@ static const struct reg_default sun8i_i2s_reg_defaults[] = { + { SUN8I_I2S_RX_CHAN_MAP_REG, 0x00000000 }, + }; + ++static const struct reg_default sun50i_i2s_reg_defaults[] = { ++ { SUN4I_I2S_CTRL_REG, 0x00060000 }, ++ { SUN4I_I2S_FMT0_REG, 0x00000033 }, ++ { SUN4I_I2S_FMT1_REG, 0x00000030 }, ++ { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 }, ++ { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 }, ++ { SUN4I_I2S_CLK_DIV_REG, 0x00000000 }, ++ { SUN8I_I2S_CHAN_CFG_REG, 0x00000000 }, ++ { SUN8I_I2S_TX_CHAN_SEL_REG, 0x00000000 }, ++ { SUN50I_H6_I2S_TX_CHAN_MAP0_REG, 0x00000000 }, ++ { SUN50I_H6_I2S_TX_CHAN_MAP1_REG, 0x00000000 }, ++ { SUN50I_H6_I2S_RX_CHAN_SEL_REG, 0x00000000 }, ++ { SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0x00000000 }, ++ { SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x00000000 }, ++}; ++ + static const struct regmap_config sun4i_i2s_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, +@@ -998,6 +1297,19 @@ static const struct regmap_config sun8i_i2s_regmap_config = { + .volatile_reg = sun8i_i2s_volatile_reg, + }; + ++static const struct regmap_config sun50i_i2s_regmap_config = { ++ .reg_bits = 32, ++ .reg_stride = 4, ++ .val_bits = 32, ++ .max_register = SUN50I_H6_I2S_RX_CHAN_MAP1_REG, ++ .cache_type = REGCACHE_FLAT, ++ .reg_defaults = sun50i_i2s_reg_defaults, ++ .num_reg_defaults = ARRAY_SIZE(sun50i_i2s_reg_defaults), ++ .writeable_reg = sun4i_i2s_wr_reg, ++ .readable_reg = sun8i_i2s_rd_reg, ++ .volatile_reg = sun8i_i2s_volatile_reg, ++}; ++ + static int sun4i_i2s_runtime_resume(struct device *dev) + { + struct sun4i_i2s *i2s = dev_get_drvdata(dev); +@@ -1077,6 +1389,11 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { + .get_wss = sun4i_i2s_get_wss, + .set_chan_cfg = sun4i_i2s_set_chan_cfg, + .set_fmt = sun4i_i2s_set_soc_fmt, ++ .set_fmt_sext = sun4i_i2s_set_fmt_sext, ++ .set_txchansel = sun4i_i2s_set_txchansel, ++ .set_rxchansel = sun4i_i2s_set_rxchansel, ++ .set_txchanmap = sun4i_i2s_set_txchanmap, ++ .set_rxchanmap = sun4i_i2s_set_rxchanmap, + }; + + static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { +@@ -1095,6 +1412,11 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { + .get_wss = sun4i_i2s_get_wss, + .set_chan_cfg = sun4i_i2s_set_chan_cfg, + .set_fmt = sun4i_i2s_set_soc_fmt, ++ .set_fmt_sext = sun4i_i2s_set_fmt_sext, ++ .set_txchansel = sun4i_i2s_set_txchansel, ++ .set_rxchansel = sun4i_i2s_set_rxchansel, ++ .set_txchanmap = sun4i_i2s_set_txchanmap, ++ .set_rxchanmap = sun4i_i2s_set_rxchanmap, + }; + + /* +@@ -1118,6 +1440,9 @@ static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = { + .get_wss = sun4i_i2s_get_wss, + .set_chan_cfg = sun4i_i2s_set_chan_cfg, + .set_fmt = sun4i_i2s_set_soc_fmt, ++ .set_fmt_sext = sun4i_i2s_set_fmt_sext, ++ .set_txchansel = sun4i_i2s_set_txchansel, ++ .set_rxchansel = sun4i_i2s_set_rxchansel, + }; + + static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { +@@ -1136,6 +1461,15 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { + .get_wss = sun8i_i2s_get_sr_wss, + .set_chan_cfg = sun8i_i2s_set_chan_cfg, + .set_fmt = sun8i_i2s_set_soc_fmt, ++ .set_fmt_sext = sun8i_i2s_set_fmt_sext, ++ .set_txchanoffset = sun8i_i2s_set_txchanoffset, ++ .set_rxchanoffset = sun8i_i2s_set_rxchanoffset, ++ .set_txchanen = sun8i_i2s_set_txchanen, ++ .set_rxchanen = sun8i_i2s_set_rxchanen, ++ .set_txchansel = sun8i_i2s_set_txchansel, ++ .set_rxchansel = sun8i_i2s_set_rxchansel, ++ .set_txchanmap = sun8i_i2s_set_txchanmap, ++ .set_rxchanmap = sun8i_i2s_set_rxchanmap, + }; + + static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = { +@@ -1154,6 +1488,38 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = { + .get_wss = sun4i_i2s_get_wss, + .set_chan_cfg = sun4i_i2s_set_chan_cfg, + .set_fmt = sun4i_i2s_set_soc_fmt, ++ .set_fmt_sext = sun4i_i2s_set_fmt_sext, ++ .set_txchansel = sun4i_i2s_set_txchansel, ++ .set_rxchansel = sun4i_i2s_set_rxchansel, ++ .set_txchanmap = sun4i_i2s_set_txchanmap, ++ .set_rxchanmap = sun4i_i2s_set_rxchanmap, ++}; ++ ++static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = { ++ .has_reset = true, ++ .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, ++ .sun4i_i2s_regmap = &sun50i_i2s_regmap_config, ++ .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8), ++ .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2), ++ .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6), ++ .bclk_dividers = sun8i_i2s_clk_div, ++ .num_bclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div), ++ .mclk_dividers = sun8i_i2s_clk_div, ++ .num_mclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div), ++ .get_bclk_parent_rate = sun8i_i2s_get_bclk_parent_rate, ++ .get_sr = sun8i_i2s_get_sr_wss, ++ .get_wss = sun8i_i2s_get_sr_wss, ++ .set_chan_cfg = sun8i_i2s_set_chan_cfg, ++ .set_fmt = sun8i_i2s_set_soc_fmt, ++ .set_fmt_sext = sun8i_i2s_set_fmt_sext, ++ .set_txchanoffset = sun50i_h6_i2s_set_txchanoffset, ++ .set_rxchanoffset = sun50i_h6_i2s_set_rxchanoffset, ++ .set_txchanen = sun50i_h6_i2s_set_txchanen, ++ .set_rxchanen = sun50i_h6_i2s_set_rxchanen, ++ .set_txchansel = sun50i_h6_i2s_set_txchansel, ++ .set_rxchansel = sun50i_h6_i2s_set_rxchansel, ++ .set_txchanmap = sun50i_h6_i2s_set_txchanmap, ++ .set_rxchanmap = sun50i_h6_i2s_set_rxchanmap, + }; + + static int sun4i_i2s_init_regmap_fields(struct device *dev, +@@ -1325,6 +1691,10 @@ static const struct of_device_id sun4i_i2s_match[] = { + .compatible = "allwinner,sun50i-a64-codec-i2s", + .data = &sun50i_a64_codec_i2s_quirks, + }, ++ { ++ .compatible = "allwinner,sun50i-h6-i2s", ++ .data = &sun50i_h6_i2s_quirks, ++ }, + {} + }; + MODULE_DEVICE_TABLE(of, sun4i_i2s_match); +-- +2.23.0 + +From 2da43795f6191505b2dd6e30938c3af4c90bf745 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Thu, 7 Nov 2019 07:36:11 +0100 +Subject: [PATCH] sound: soc: sun4i-i2s: Fix rate calculation + +Signed-off-by: Jernej Skrabec +--- + sound/soc/sunxi/sun4i-i2s.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c +index d0a8d5810c0a..6c4241cb6509 100644 +--- a/sound/soc/sunxi/sun4i-i2s.c ++++ b/sound/soc/sunxi/sun4i-i2s.c +@@ -334,6 +334,9 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai, + return -EINVAL; + } + ++ if (i2s->slot_width) ++ slot_width = i2s->slot_width; ++ + bclk_parent_rate = i2s->variant->get_bclk_parent_rate(i2s); + bclk_div = sun4i_i2s_get_bclk_div(i2s, bclk_parent_rate, + rate, slots, slot_width); +-- +2.24.0 + diff --git a/patch/kernel/sunxi-current/0007-Add-sopine-HDMI-sound-and-WiFi-support.patch b/patch/kernel/sunxi-current/0007-Add-sopine-HDMI-sound-and-WiFi-support.patch index a36bdba3a..23ec306a5 100644 --- a/patch/kernel/sunxi-current/0007-Add-sopine-HDMI-sound-and-WiFi-support.patch +++ b/patch/kernel/sunxi-current/0007-Add-sopine-HDMI-sound-and-WiFi-support.patch @@ -44,53 +44,11 @@ index c21f2331add6..8161895dde52 100644 vcc-hdmi-supply = <®_dldo1>; }; -+&sound_hdmi { ++&hdmi_sound { + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -index 0f69f3593975..0b44018361cb 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -@@ -727,6 +727,35 @@ - status = "disabled"; - }; - -+ i2s2: i2s@1c22800 { -+ #sound-dai-cells = <0>; -+ compatible = "allwinner,sun8i-h3-i2s"; -+ reg = <0x01c22800 0x400>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_I2S2>, <&ccu CLK_I2S2>; -+ clock-names = "apb", "mod"; -+ dmas = <&dma 27>; -+ resets = <&ccu RST_BUS_I2S2>; -+ dma-names = "tx"; -+ status = "disabled"; -+ }; -+ -+ sound_hdmi: sound_hdmi { -+ compatible = "simple-audio-card"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,name = "allwinner,hdmi"; -+ simple-audio-card,mclk-fs = <256>; -+ status = "disabled"; -+ -+ simple-audio-card,codec { -+ sound-dai = <&hdmi>; -+ }; -+ -+ simple-audio-card,cpu { -+ sound-dai = <&i2s2>; -+ }; -+ }; -+ - rtc: rtc@1f00000 { - compatible = "allwinner,sun6i-a31-rtc"; - reg = <0x01f00000 0x54>; --- -2.17.1 diff --git a/patch/kernel/sunxi-current/0008-arm64-dts-sun50i-a64-pine64-add-HDMI-audio-nodes.patch b/patch/kernel/sunxi-current/0008-arm64-dts-sun50i-a64-pine64-add-HDMI-audio-nodes.patch deleted file mode 100644 index cf4c3c14d..000000000 --- a/patch/kernel/sunxi-current/0008-arm64-dts-sun50i-a64-pine64-add-HDMI-audio-nodes.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 887b96d878bb0e261bc19062dc73d193c75bc56a Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Tue, 26 Dec 2017 15:53:53 -0800 -Subject: [PATCH 008/146] arm64: dts: sun50i-a64-pine64: add HDMI audio nodes - -Signed-off-by: Vasily Khoruzhick ---- - arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts -index d06b5b88f60e..8c5dd99cc9ac 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts -@@ -97,6 +97,10 @@ - bias-pull-up; - }; - -+&i2s2 { -+ status = "okay"; -+}; -+ - &mdio { - ext_rmii_phy1: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; -@@ -254,6 +258,10 @@ - status = "disabled"; - }; - -+&sound_hdmi { -+ status = "okay"; -+}; -+ - /* On Exp and Euler connectors */ - &uart0 { - pinctrl-names = "default"; --- -2.17.1 - diff --git a/patch/kernel/sunxi-current/0010-general-h6-add-dma-i2c-ir-spi-uart.patch b/patch/kernel/sunxi-current/0010-general-h6-add-dma-i2c-ir-spi-uart.patch index 56e4523ab..77cb4dabf 100644 --- a/patch/kernel/sunxi-current/0010-general-h6-add-dma-i2c-ir-spi-uart.patch +++ b/patch/kernel/sunxi-current/0010-general-h6-add-dma-i2c-ir-spi-uart.patch @@ -2,19 +2,6 @@ diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/ index dc785da9c..141fd186b 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -@@ -113,6 +113,12 @@ - clock-latency-ns = <244144>; /* 8 32k periods */ - }; - -+ opp@1640000000 { -+ opp-hz = /bits/ 64 <1640000000>; -+ opp-microvolt = <1160000 1160000 1160000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ - opp@1800000000 { - opp-hz = /bits/ 64 <1800000000>; - opp-microvolt = <1160000 1160000 1160000>; @@ -374,6 +381,17 @@ #dma-cells = <1>; }; @@ -49,23 +36,6 @@ index dc785da9c..141fd186b 100644 mmc2_pins: mmc2-pins { pins = "PC1", "PC4", "PC5", "PC6", "PC7", "PC8", "PC9", "PC10", -@@ -318,6 +364,16 @@ - bias-pull-up; - }; - -+ spi0_pins: spi0-pins { -+ pins = "PC2", "PC3", "PC0", "PC5"; -+ function = "spi0"; -+ }; -+ -+ spi1_pins: spi1-pins { -+ pins = "PH5", "PH6", "PH4", "PH3"; -+ function = "spi1"; -+ }; -+ - uart0_ph_pins: uart0-ph-pins { - pins = "PH0", "PH1"; - function = "uart0"; @@ -511,17 +540,26 @@ pins = "PG8", "PG9"; function = "uart1"; @@ -103,45 +73,6 @@ index dc785da9c..141fd186b 100644 }; mmc0: mmc@4020000 { -@@ -391,6 +495,38 @@ - #size-cells = <0>; - }; - -+ spi0: spi@5010000 { -+ compatible = "allwinner,sun8i-h3-spi"; -+ reg = <0x05010000 0x1000>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>; -+ clock-names = "ahb", "mod"; -+ dmas = <&dma 22>, <&dma 22>; -+ dma-names = "rx", "tx"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; -+ resets = <&ccu RST_BUS_SPI0>; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ spi1: spi@5011000 { -+ compatible = "allwinner,sun8i-h3-spi"; -+ reg = <0x05011000 0x1000>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>; -+ clock-names = "ahb", "mod"; -+ dmas = <&dma 23>, <&dma 23>; -+ dma-names = "rx", "tx"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_pins>; -+ resets = <&ccu RST_BUS_SPI1>; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ - uart0: serial@5000000 { - compatible = "snps,dw-apb-uart"; - reg = <0x05000000 0x400>; @@ -963,6 +1033,19 @@ }; }; diff --git a/patch/kernel/sunxi-current/0101-arm64-dts-allwinner-a64-Enable-HDMI-output-on-A64-bo.patch b/patch/kernel/sunxi-current/0101-arm64-dts-allwinner-a64-Enable-HDMI-output-on-A64-bo.patch deleted file mode 100644 index 56ed5643c..000000000 --- a/patch/kernel/sunxi-current/0101-arm64-dts-allwinner-a64-Enable-HDMI-output-on-A64-bo.patch +++ /dev/null @@ -1,78 +0,0 @@ -From e7623ac862573d231eea2ec77d393adbf2db3392 Mon Sep 17 00:00:00 2001 -From: Jagan Teki -Date: Tue, 4 Sep 2018 12:40:53 +0800 -Subject: [PATCH 101/146] arm64: dts: allwinner: a64: Enable HDMI output on A64 - boards w/ HDMI - -Enable all necessary device tree nodes and add connector node to device -trees for all supported A64 boards with HDMI. - -Signed-off-by: Jagan Teki -[Icenowy: squash all board patches altogether and change supply name] -Signed-off-by: Icenowy Zheng -Tested-by: Jagan Teki # BPI-M64, OPI-Win, -Tested-by: Vasily Khoruzhick ---- - .../dts/allwinner/sun50i-a64-bananapi-m64.dts | 26 ++++++++++++++++++ - .../dts/allwinner/sun50i-a64-nanopi-a64.dts | 27 +++++++++++++++++++ - .../dts/allwinner/sun50i-a64-olinuxino.dts | 26 ++++++++++++++++++ - .../dts/allwinner/sun50i-a64-orangepi-win.dts | 27 +++++++++++++++++++ - .../boot/dts/allwinner/sun50i-a64-pine64.dts | 27 +++++++++++++++++++ - .../dts/allwinner/sun50i-a64-pinebook.dts | 26 ++++++++++++++++++ - .../allwinner/sun50i-a64-sopine-baseboard.dts | 26 ++++++++++++++++++ - 7 files changed, 185 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -index b3698a8bb1d3..52cbb3052588 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -@@ -53,6 +53,17 @@ - }; - }; - -+ hdmi-connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_con_in: endpoint { -+ remote-endpoint = <&hdmi_out_con>; -+ }; -+ }; -+ }; -+ - reg_vcc3v3: vcc3v3 { - compatible = "regulator-fixed"; - regulator-name = "vcc3v3"; -@@ -70,6 +81,10 @@ - cpu-supply = <®_dcdc2>; - }; - -+&de { -+ status = "okay"; -+}; -+ - &ehci0 { - phys = <&usbphy 0>; - phy-names = "usb"; -@@ -80,6 +95,17 @@ - status = "okay"; - }; - -+&hdmi { -+ hvcc-supply = <®_dldo1>; -+ status = "okay"; -+}; -+ -+&hdmi_out { -+ hdmi_out_con: endpoint { -+ remote-endpoint = <&hdmi_con_in>; -+ }; -+}; -+ - &mmc0 { - pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins>; --- -2.17.1 - diff --git a/patch/kernel/sunxi-current/0126-drm-bridge-move-ANA78xx-driver-to-analogix-subdirect.patch b/patch/kernel/sunxi-current/0126-drm-bridge-move-ANA78xx-driver-to-analogix-subdirect.patch deleted file mode 100644 index d58ce1bca..000000000 --- a/patch/kernel/sunxi-current/0126-drm-bridge-move-ANA78xx-driver-to-analogix-subdirect.patch +++ /dev/null @@ -1,32 +0,0 @@ -From c66953710d4c7205c380bf9c5a7e296bef3d4948 Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Thu, 18 Oct 2018 15:33:19 +0800 -Subject: [PATCH 126/146] drm/bridge: move ANA78xx driver to analogix - subdirectory - -As ANA78xx chips are designed and produced by Analogix Semiconductor, -Inc, move their driver codes into analogix subdirectory. - -Signed-off-by: Icenowy Zheng -Reviewed-by: Laurent Pinchart ---- - drivers/gpu/drm/bridge/Kconfig | 10 ---------- - drivers/gpu/drm/bridge/Makefile | 4 ++-- - drivers/gpu/drm/bridge/analogix/Kconfig | 10 ++++++++++ - drivers/gpu/drm/bridge/analogix/Makefile | 1 + - .../gpu/drm/bridge/{ => analogix}/analogix-anx78xx.c | 0 - .../gpu/drm/bridge/{ => analogix}/analogix-anx78xx.h | 0 - 6 files changed, 13 insertions(+), 12 deletions(-) - rename drivers/gpu/drm/bridge/{ => analogix}/analogix-anx78xx.c (100%) - rename drivers/gpu/drm/bridge/{ => analogix}/analogix-anx78xx.h (100%) - -diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile -index 4934fcf..729a806 100644 ---- a/drivers/gpu/drm/bridge/Makefile -+++ b/drivers/gpu/drm/bridge/Makefile -@@ -1,5 +1,4 @@ - # SPDX-License-Identifier: GPL-2.0 --obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o - obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o - obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o - obj-$(CONFIG_DRM_LVDS_ENCODER) += lvds-encoder.o diff --git a/patch/kernel/sunxi-legacy/0128-drm-bridge-extract-some-Analogix-I2C-DP-common-code.patch b/patch/kernel/sunxi-current/0128-drm-bridge-extract-some-Analogix-I2C-DP-common-code.patch-disabled similarity index 99% rename from patch/kernel/sunxi-legacy/0128-drm-bridge-extract-some-Analogix-I2C-DP-common-code.patch rename to patch/kernel/sunxi-current/0128-drm-bridge-extract-some-Analogix-I2C-DP-common-code.patch-disabled index 08c54137b..8adb43416 100644 --- a/patch/kernel/sunxi-legacy/0128-drm-bridge-extract-some-Analogix-I2C-DP-common-code.patch +++ b/patch/kernel/sunxi-current/0128-drm-bridge-extract-some-Analogix-I2C-DP-common-code.patch-disabled @@ -230,7 +230,7 @@ index 000000000000..9cb30962032e +#include + +#include -+#include ++#include +#include + +#include "analogix-i2c-dptx.h" diff --git a/patch/kernel/sunxi-legacy/0130-drm-bridge-Add-Analogix-anx6345-support.patch b/patch/kernel/sunxi-current/0130-drm-bridge-Add-Analogix-anx6345-support.patch-disabled similarity index 99% rename from patch/kernel/sunxi-legacy/0130-drm-bridge-Add-Analogix-anx6345-support.patch rename to patch/kernel/sunxi-current/0130-drm-bridge-Add-Analogix-anx6345-support.patch-disabled index bbe395f57..dc8de6a67 100644 --- a/patch/kernel/sunxi-legacy/0130-drm-bridge-Add-Analogix-anx6345-support.patch +++ b/patch/kernel/sunxi-current/0130-drm-bridge-Add-Analogix-anx6345-support.patch-disabled @@ -52,7 +52,7 @@ new file mode 100644 index 000000000000..81676407aa6d --- /dev/null +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c -@@ -0,0 +1,862 @@ +@@ -0,0 +1,863 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright(c) Icenowy Zheng @@ -72,10 +72,11 @@ index 000000000000..81676407aa6d +#include +#include + -+#include ++#include +#include +#include +#include ++#include +#include +#include + @@ -603,7 +604,7 @@ index 000000000000..81676407aa6d + if (!anx6345->edid) { + err = anx6345_probe_edid_from_of(anx6345); + if (err) { -+ DRM_ERROR("Failed to probe EDID from device tree: %d\n", err); ++ DRM_ERROR("Failed to probe EDID from device tree: &d\n", err); + goto unlock; + } + } @@ -716,8 +717,8 @@ index 000000000000..81676407aa6d +} + +static void anx6345_bridge_mode_set(struct drm_bridge *bridge, -+ struct drm_display_mode *mode, -+ struct drm_display_mode *adjusted_mode) ++ const struct drm_display_mode *mode, ++ const struct drm_display_mode *adjusted_mode) +{ + struct anx6345 *anx6345 = bridge_to_anx6345(bridge); + diff --git a/patch/kernel/sunxi-current/0136-hdmi-audio-fixup.patch b/patch/kernel/sunxi-current/0136-hdmi-audio-fixup.patch deleted file mode 100644 index 01a7dd5ff..000000000 --- a/patch/kernel/sunxi-current/0136-hdmi-audio-fixup.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 2c38da8ed7cc1f7dabe72c4d455ba25e0ba18fe7 Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Sun, 28 Oct 2018 19:06:28 -0700 -Subject: [PATCH 136/146] hdmi audio fixup - ---- - arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -index 0f5b412cfc81..f507bb1d8c3d 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -@@ -1044,6 +1044,7 @@ - }; - - hdmi: hdmi@1ee0000 { -+ #sound-dai-cells = <0>; - compatible = "allwinner,sun50i-a64-dw-hdmi", - "allwinner,sun8i-a83t-dw-hdmi"; - reg = <0x01ee0000 0x10000>; --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0137-Pinebook-HDMI-audio.patch b/patch/kernel/sunxi-current/0137-Pinebook-HDMI-audio.patch similarity index 98% rename from patch/kernel/sunxi-legacy/0137-Pinebook-HDMI-audio.patch rename to patch/kernel/sunxi-current/0137-Pinebook-HDMI-audio.patch index 2a881647f..fcba9bb70 100644 --- a/patch/kernel/sunxi-legacy/0137-Pinebook-HDMI-audio.patch +++ b/patch/kernel/sunxi-current/0137-Pinebook-HDMI-audio.patch @@ -27,7 +27,7 @@ index 8c9bd4dfbbba..0f788400ece0 100644 "MIC2", "Internal Microphone Right"; }; -+&sound_hdmi { ++&hdmi_sound { + status = "okay"; +}; + diff --git a/patch/kernel/sunxi-current/0139-Bluetooth-Add-new-quirk-for-broken-local-ext-feature.patch b/patch/kernel/sunxi-current/0139-Bluetooth-Add-new-quirk-for-broken-local-ext-feature.patch deleted file mode 100644 index d7912e20a..000000000 --- a/patch/kernel/sunxi-current/0139-Bluetooth-Add-new-quirk-for-broken-local-ext-feature.patch +++ /dev/null @@ -1,54 +0,0 @@ -From e4a72ee5f7717daaa2928b3d18a5327739c8b180 Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Wed, 31 Oct 2018 19:40:18 -0700 -Subject: [PATCH 139/146] Bluetooth: Add new quirk for broken local ext - features max_page - -Some adapters (e.g. RTL8723CS) advertise that they have more than -2 pages for local ext features, but they don't support any features -declared in these pages. RTL8723CS reports max_page = 2 and declares -support for sync train and secure connection, but it responds with -either garbage or with error in status on corresponding commands. - -Signed-off-by: Vasily Khoruzhick ---- - include/net/bluetooth/hci.h | 7 +++++++ - net/bluetooth/hci_event.c | 4 +++- - 2 files changed, 10 insertions(+), 1 deletion(-) - -diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h -index cdd9f1fe7cfa..32b9195f6fca 100644 ---- a/include/net/bluetooth/hci.h -+++ b/include/net/bluetooth/hci.h -@@ -192,6 +192,13 @@ enum { - * - */ - HCI_QUIRK_NON_PERSISTENT_SETUP, -+ -+ /* When this quirk is set, max_page for local extended features -+ * is set to 1, even if controller reports higher number. Some -+ * controllers (e.g. RTL8723CS) report more pages, but they -+ * don't actually support features declared there. -+ */ -+ HCI_QUIRK_BROKEN_LOCAL_EXT_FTR_MAX_PAGE, - }; - - /* HCI device flags */ -diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c -index f12555f23a49..3eb289711dea 100644 ---- a/net/bluetooth/hci_event.c -+++ b/net/bluetooth/hci_event.c -@@ -639,7 +639,9 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev, - if (rp->status) - return; - -- if (hdev->max_page < rp->max_page) -+ if (!test_bit(HCI_QUIRK_BROKEN_LOCAL_EXT_FTR_MAX_PAGE, -+ &hdev->quirks) && -+ hdev->max_page < rp->max_page) - hdev->max_page = rp->max_page; - - if (rp->page < HCI_MAX_PAGES) --- -2.17.1 - diff --git a/patch/kernel/sunxi-current/0140-Bluetooth-hci_h5-Add-support-for-reset-GPIO.patch b/patch/kernel/sunxi-current/0140-Bluetooth-hci_h5-Add-support-for-reset-GPIO.patch deleted file mode 100644 index f82a5cde8..000000000 --- a/patch/kernel/sunxi-current/0140-Bluetooth-hci_h5-Add-support-for-reset-GPIO.patch +++ /dev/null @@ -1,57 +0,0 @@ -From e8a404daea8d869304fdf810ac502cda8fbb4999 Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Wed, 31 Oct 2018 19:48:25 -0700 -Subject: [PATCH 140/146] Bluetooth: hci_h5: Add support for reset GPIO - -Some boards (e.g. Pine64 and Pinebook) wire a GPIO to reset pin of -RTL8723BS - -Signed-off-by: Vasily Khoruzhick ---- - drivers/bluetooth/hci_h5.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c -index 8eede1197cd2..6e047df4f475 100644 ---- a/drivers/bluetooth/hci_h5.c -+++ b/drivers/bluetooth/hci_h5.c -@@ -107,6 +107,7 @@ struct h5 { - const struct h5_vnd *vnd; - const char *id; - -+ struct gpio_desc *reset_gpio; - struct gpio_desc *enable_gpio; - struct gpio_desc *device_wake_gpio; - }; -@@ -831,6 +832,10 @@ static int h5_serdev_probe(struct serdev_device *serdev) - if (IS_ERR(h5->device_wake_gpio)) - return PTR_ERR(h5->device_wake_gpio); - -+ h5->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); -+ if (IS_ERR(h5->reset_gpio)) -+ return PTR_ERR(h5->reset_gpio); -+ - return hci_uart_register_device(&h5->serdev_hu, &h5p); - } - -@@ -897,6 +902,9 @@ static void h5_btrtl_open(struct h5 *h5) - - /* The controller needs up to 500ms to wakeup */ - gpiod_set_value_cansleep(h5->enable_gpio, 1); -+ /* Take it out of reset */ -+ gpiod_set_value_cansleep(h5->reset_gpio, 0); -+ msleep(100); - gpiod_set_value_cansleep(h5->device_wake_gpio, 1); - msleep(500); - } -@@ -904,6 +912,7 @@ static void h5_btrtl_open(struct h5 *h5) - static void h5_btrtl_close(struct h5 *h5) - { - gpiod_set_value_cansleep(h5->device_wake_gpio, 0); -+ gpiod_set_value_cansleep(h5->reset_gpio, 1); - gpiod_set_value_cansleep(h5->enable_gpio, 0); - } - --- -2.17.1 - diff --git a/patch/kernel/sunxi-current/0142-Bluetooth-hci_h5-Add-support-for-binding-RTL8723BS-w.patch b/patch/kernel/sunxi-current/0142-Bluetooth-hci_h5-Add-support-for-binding-RTL8723BS-w.patch deleted file mode 100644 index 5dae8ea6b..000000000 --- a/patch/kernel/sunxi-current/0142-Bluetooth-hci_h5-Add-support-for-binding-RTL8723BS-w.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 38caa52f547c63c9cd7aa19259bb6806cff7d50d Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Wed, 31 Oct 2018 20:07:41 -0700 -Subject: [PATCH 142/146] Bluetooth: hci_h5: Add support for binding RTL8723BS - with device tree - -RTL8723BS is often used in ARM boards, so add ability to bind it -using device tree. - -Signed-off-by: Vasily Khoruzhick ---- - drivers/bluetooth/hci_h5.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c -index 6e047df4f475..9cc10e299fa8 100644 ---- a/drivers/bluetooth/hci_h5.c -+++ b/drivers/bluetooth/hci_h5.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -821,6 +822,11 @@ static int h5_serdev_probe(struct serdev_device *serdev) - if (h5->vnd->acpi_gpio_map) - devm_acpi_dev_add_driver_gpios(dev, - h5->vnd->acpi_gpio_map); -+ } else { -+ h5->vnd = (const struct h5_vnd *) -+ of_device_get_match_data(&serdev->dev); -+ of_property_read_string(serdev->dev.of_node, -+ "firmware-postfix", &h5->id); - } - - h5->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW); -@@ -944,13 +950,27 @@ static const struct acpi_device_id h5_acpi_match[] = { - MODULE_DEVICE_TABLE(acpi, h5_acpi_match); - #endif - -+static struct h5_vnd rtl8723_of_vnd = { -+ .setup = h5_btrtl_setup, -+ .open = h5_btrtl_open, -+ .close = h5_btrtl_close, -+}; -+ -+static const struct of_device_id h5_of_match[] = { -+ { .compatible = "realtek,rtl8723bs-bt", .data = &rtl8723_of_vnd }, -+ { .compatible = "realtek,rtl8723cs-bt", .data = &rtl8723_of_vnd }, -+ { /* sentinel */ }, -+}; -+MODULE_DEVICE_TABLE(of, h5_of_match); -+ - static struct serdev_device_driver h5_serdev_driver = { - .probe = h5_serdev_probe, - .remove = h5_serdev_remove, - .driver = { - .name = "hci_uart_h5", - .acpi_match_table = ACPI_PTR(h5_acpi_match), - .pm = &h5_serdev_pm_ops, -+ .of_match_table = of_match_ptr(h5_of_match), - }, - }; - --- -2.17.1 - diff --git a/patch/kernel/sunxi-current/0143-Bluetooth-btrtl-add-support-for-the-RTL8723CS.patch b/patch/kernel/sunxi-current/0143-Bluetooth-btrtl-add-support-for-the-RTL8723CS.patch deleted file mode 100644 index 22cea18cc..000000000 --- a/patch/kernel/sunxi-current/0143-Bluetooth-btrtl-add-support-for-the-RTL8723CS.patch +++ /dev/null @@ -1,311 +0,0 @@ -From 08c47cbb508e40e5e404055f77653474d5793e27 Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Wed, 31 Oct 2018 20:33:22 -0700 -Subject: [PATCH 143/146] Bluetooth: btrtl: add support for the RTL8723CS - -The Realtek RTL8723CS is SDIO WiFi chip. It also contains a Bluetooth -module which is connected via UART to the host. - -It shares lmp subversion with 8703B, so Realtek's userspace -initialization tool (rtk_hciattach) differentiates varieties of RTL8723CS -(CG, VF, XX) with RTL8703B using vendor's command to read chip type. - -Also this chip declares support for some features it doesn't support -so add a quirk to indicate that these features are broken. - -Signed-off-by: Vasily Khoruzhick ---- - drivers/bluetooth/btrtl.c | 128 ++++++++++++++++++++++++++++++++++++- - drivers/bluetooth/btrtl.h | 12 ++++ - drivers/bluetooth/hci_h5.c | 4 ++ - 3 files changed, 141 insertions(+), 3 deletions(-) - -diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c -index 7f9ea8e4c1b2..f9474e78bcfa 100644 ---- a/drivers/bluetooth/btrtl.c -+++ b/drivers/bluetooth/btrtl.c -@@ -27,8 +27,12 @@ - - #define VERSION "0.1" - -+#define RTL_CHIP_8723CS_CG 3 -+#define RTL_CHIP_8723CS_VF 4 -+#define RTL_CHIP_8723CS_XX 5 - #define RTL_EPATCH_SIGNATURE "Realtech" - #define RTL_ROM_LMP_3499 0x3499 -+#define RTL_ROM_LMP_8703B 0x8703 - #define RTL_ROM_LMP_8723A 0x1200 - #define RTL_ROM_LMP_8723B 0x8723 - #define RTL_ROM_LMP_8821A 0x8821 -@@ -40,6 +44,7 @@ - #define IC_MATCH_FL_HCIREV (1 << 1) - #define IC_MATCH_FL_HCIVER (1 << 2) - #define IC_MATCH_FL_HCIBUS (1 << 3) -+#define IC_MATCH_FL_CHIP_TYPE (1 << 4) - #define IC_INFO(lmps, hcir) \ - .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV, \ - .lmp_subver = (lmps), \ -@@ -51,6 +56,7 @@ struct id_table { - __u16 hci_rev; - __u8 hci_ver; - __u8 hci_bus; -+ __u8 chip_type; - bool config_needed; - bool has_rom_version; - char *fw_name; -@@ -98,6 +104,39 @@ static const struct id_table ic_id_table[] = { - .fw_name = "rtl_bt/rtl8723b_fw.bin", - .cfg_name = "rtl_bt/rtl8723b_config" }, - -+ /* 8723CS-CG */ -+ { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE | -+ IC_MATCH_FL_HCIBUS, -+ .lmp_subver = RTL_ROM_LMP_8703B, -+ .chip_type = RTL_CHIP_8723CS_CG, -+ .hci_bus = HCI_UART, -+ .config_needed = true, -+ .has_rom_version = true, -+ .fw_name = "rtl_bt/rtl8723cs_cg_fw.bin", -+ .cfg_name = "rtl_bt/rtl8723cs_cg_config" }, -+ -+ /* 8723CS-VF */ -+ { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE | -+ IC_MATCH_FL_HCIBUS, -+ .lmp_subver = RTL_ROM_LMP_8703B, -+ .chip_type = RTL_CHIP_8723CS_VF, -+ .hci_bus = HCI_UART, -+ .config_needed = true, -+ .has_rom_version = true, -+ .fw_name = "rtl_bt/rtl8723cs_vf_fw.bin", -+ .cfg_name = "rtl_bt/rtl8723cs_vf_config" }, -+ -+ /* 8723CS-XX */ -+ { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE | -+ IC_MATCH_FL_HCIBUS, -+ .lmp_subver = RTL_ROM_LMP_8703B, -+ .chip_type = RTL_CHIP_8723CS_XX, -+ .hci_bus = HCI_UART, -+ .config_needed = true, -+ .has_rom_version = true, -+ .fw_name = "rtl_bt/rtl8723cs_xx_fw.bin", -+ .cfg_name = "rtl_bt/rtl8723cs_xx_config" }, -+ - /* 8723D */ - { IC_INFO(RTL_ROM_LMP_8723B, 0xd), - .config_needed = true, -@@ -147,7 +186,8 @@ static const struct id_table ic_id_table[] = { - }; - - static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev, -- u8 hci_ver, u8 hci_bus) -+ u8 hci_ver, u8 hci_bus, -+ u8 chip_type) - { - int i; - -@@ -164,6 +204,9 @@ static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev, - if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIBUS) && - (ic_id_table[i].hci_bus != hci_bus)) - continue; -+ if ((ic_id_table[i].match_flags & IC_MATCH_FL_CHIP_TYPE) && -+ (ic_id_table[i].chip_type != chip_type)) -+ continue; - - break; - } -@@ -225,6 +268,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev, - { RTL_ROM_LMP_8723B, 1 }, - { RTL_ROM_LMP_8821A, 2 }, - { RTL_ROM_LMP_8761A, 3 }, -+ { RTL_ROM_LMP_8703B, 7 }, - { RTL_ROM_LMP_8822B, 8 }, - { RTL_ROM_LMP_8723B, 9 }, /* 8723D */ - { RTL_ROM_LMP_8821A, 10 }, /* 8821C */ -@@ -499,6 +543,48 @@ static struct sk_buff *btrtl_read_local_version(struct hci_dev *hdev) - return skb; - } - -+static bool rtl_has_chip_type(u16 lmp_subver) -+{ -+ switch (lmp_subver) { -+ case RTL_ROM_LMP_8703B: -+ return true; -+ default: -+ break; -+ } -+ -+ return false; -+} -+ -+static int rtl_read_chip_type(struct hci_dev *hdev, u8 *type) -+{ -+ struct rtl_chip_type_evt *chip_type; -+ struct sk_buff *skb; -+ const unsigned char cmd_buf[] = {0x00, 0x94, 0xa0, 0x00, 0xb0}; -+ -+ /* Read RTL chip type command */ -+ skb = __hci_cmd_sync(hdev, 0xfc61, 5, cmd_buf, HCI_INIT_TIMEOUT); -+ if (IS_ERR(skb)) { -+ rtl_dev_err(hdev, "Read chip type failed (%ld)", -+ PTR_ERR(skb)); -+ return PTR_ERR(skb); -+ } -+ -+ if (skb->len != sizeof(*chip_type)) { -+ rtl_dev_err(hdev, "RTL chip type event length mismatch"); -+ kfree_skb(skb); -+ return -EIO; -+ } -+ -+ chip_type = (struct rtl_chip_type_evt *)skb->data; -+ rtl_dev_info(hdev, "chip_type status=%x type=%x", -+ chip_type->status, chip_type->type); -+ -+ *type = chip_type->type & 0x0f; -+ -+ kfree_skb(skb); -+ return 0; -+} -+ - void btrtl_free(struct btrtl_device_info *btrtl_dev) - { - kfree(btrtl_dev->fw_data); -@@ -515,7 +601,7 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, - struct hci_rp_read_local_version *resp; - char cfg_name[40]; - u16 hci_rev, lmp_subver; -- u8 hci_ver; -+ u8 hci_ver, chip_type = 0; - int ret; - - btrtl_dev = kzalloc(sizeof(*btrtl_dev), GFP_KERNEL); -@@ -540,8 +626,14 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, - lmp_subver = le16_to_cpu(resp->lmp_subver); - kfree_skb(skb); - -+ if (rtl_has_chip_type(lmp_subver)) { -+ ret = rtl_read_chip_type(hdev, &chip_type); -+ if (ret) -+ goto err_free; -+ } -+ - btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, hci_ver, -- hdev->bus); -+ hdev->bus, chip_type); - - if (!btrtl_dev->ic_info) { - rtl_dev_err(hdev, "rtl: unknown IC info, lmp subver %04x, hci rev %04x, hci ver %04x", -@@ -610,6 +702,7 @@ int btrtl_download_firmware(struct hci_dev *hdev, - case RTL_ROM_LMP_8821A: - case RTL_ROM_LMP_8761A: - case RTL_ROM_LMP_8822B: -+ case RTL_ROM_LMP_8703B: - return btrtl_setup_rtl8723b(hdev, btrtl_dev); - default: - rtl_dev_info(hdev, "rtl: assuming no firmware upload needed\n"); -@@ -628,7 +721,12 @@ int btrtl_setup_realtek(struct hci_dev *hdev) - return PTR_ERR(btrtl_dev); - - ret = btrtl_download_firmware(hdev, btrtl_dev); -+ if (ret) -+ goto out_free; - -+ btrtl_apply_quirks(hdev, btrtl_dev); -+ -+out_free: - btrtl_free(btrtl_dev); - - return ret; -@@ -743,6 +841,24 @@ int btrtl_get_uart_settings(struct hci_dev *hdev, - } - EXPORT_SYMBOL_GPL(btrtl_get_uart_settings); - -+void btrtl_apply_quirks(struct hci_dev *hdev, -+ struct btrtl_device_info *btrtl_dev) -+{ -+ switch (btrtl_dev->ic_info->lmp_subver) { -+ case RTL_ROM_LMP_8703B: -+ /* 8723CS reports two pages for local ext features, -+ * but it doesn't support any features from page 2 - -+ * it either responds with garbage or with error status -+ */ -+ set_bit(HCI_QUIRK_BROKEN_LOCAL_EXT_FTR_MAX_PAGE, -+ &hdev->quirks); -+ break; -+ default: -+ break; -+ } -+} -+EXPORT_SYMBOL_GPL(btrtl_apply_quirks); -+ - MODULE_AUTHOR("Daniel Drake "); - MODULE_DESCRIPTION("Bluetooth support for Realtek devices ver " VERSION); - MODULE_VERSION(VERSION); -@@ -752,6 +868,12 @@ MODULE_FIRMWARE("rtl_bt/rtl8723b_fw.bin"); - MODULE_FIRMWARE("rtl_bt/rtl8723b_config.bin"); - MODULE_FIRMWARE("rtl_bt/rtl8723bs_fw.bin"); - MODULE_FIRMWARE("rtl_bt/rtl8723bs_config.bin"); -+MODULE_FIRMWARE("rtl_bt/rtl8723cs_cg_fw.bin"); -+MODULE_FIRMWARE("rtl_bt/rtl8723cs_cg_config.bin"); -+MODULE_FIRMWARE("rtl_bt/rtl8723cs_vf_fw.bin"); -+MODULE_FIRMWARE("rtl_bt/rtl8723cs_vf_config.bin"); -+MODULE_FIRMWARE("rtl_bt/rtl8723cs_xx_fw.bin"); -+MODULE_FIRMWARE("rtl_bt/rtl8723cs_xx_config.bin"); - MODULE_FIRMWARE("rtl_bt/rtl8723ds_fw.bin"); - MODULE_FIRMWARE("rtl_bt/rtl8723ds_config.bin"); - MODULE_FIRMWARE("rtl_bt/rtl8761a_fw.bin"); -diff --git a/drivers/bluetooth/btrtl.h b/drivers/bluetooth/btrtl.h -index f5e36f3993a8..db4e4a1542b7 100644 ---- a/drivers/bluetooth/btrtl.h -+++ b/drivers/bluetooth/btrtl.h -@@ -24,6 +24,11 @@ - - struct btrtl_device_info; - -+struct rtl_chip_type_evt { -+ __u8 status; -+ __u8 type; -+} __packed; -+ - struct rtl_download_cmd { - __u8 index; - __u8 data[RTL_FRAG_LEN]; -@@ -69,6 +74,8 @@ int btrtl_get_uart_settings(struct hci_dev *hdev, - struct btrtl_device_info *btrtl_dev, - unsigned int *controller_baudrate, - u32 *device_baudrate, bool *flow_control); -+void btrtl_apply_quirks(struct hci_dev *hdev, -+ struct btrtl_device_info *btrtl_dev); - - #else - -@@ -100,6 +107,11 @@ static inline int btrtl_get_uart_settings(struct hci_dev *hdev, - bool *flow_control) - { - return -ENOENT; -+ -+static inline void btrtl_apply_quirks(struct hci_dev *hdev, -+ struct btrtl_device_info *btrtl_dev) -+{ -+} - } - - #endif -diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c -index 9cc10e299fa8..7d72e092ce9d 100644 ---- a/drivers/bluetooth/hci_h5.c -+++ b/drivers/bluetooth/hci_h5.c -@@ -892,6 +892,10 @@ static int h5_btrtl_setup(struct h5 *h5) - err = btrtl_download_firmware(h5->hu->hdev, btrtl_dev); - /* Give the device some time before the hci-core sends it a reset */ - usleep_range(10000, 20000); -+ if (err) -+ goto out_free; -+ -+ btrtl_apply_quirks(h5->hu->hdev, btrtl_dev); - - out_free: - btrtl_free(btrtl_dev); --- -2.17.1 - diff --git a/patch/kernel/sunxi-current/Revert_BT_HCIUART_RTL_ACPI_dependency.patch b/patch/kernel/sunxi-current/Revert_BT_HCIUART_RTL_ACPI_dependency.patch deleted file mode 100644 index 28757da2f..000000000 --- a/patch/kernel/sunxi-current/Revert_BT_HCIUART_RTL_ACPI_dependency.patch +++ /dev/null @@ -1,18 +0,0 @@ -Reverts Bluetooth: Make BT_HCIUART_RTL configuration option depend on ACPI - -https://github.com/anarsoul/linux-2.6/commit/51474eff2bc2777061ab3658e014a37dc9d7a775 - -otherwise it breaks the compilation - -diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig -index 845b0314c..2df11cc08 100644 ---- a/drivers/bluetooth/Kconfig -+++ b/drivers/bluetooth/Kconfig -@@ -200,7 +200,6 @@ config BT_HCIUART_RTL - depends on BT_HCIUART - depends on BT_HCIUART_SERDEV - depends on GPIOLIB -- depends on ACPI - select BT_HCIUART_3WIRE - select BT_RTL - help diff --git a/patch/kernel/sunxi-current/add-missing-ext_osc32k-on-H6.patch b/patch/kernel/sunxi-current/add-missing-ext_osc32k-on-H6.patch new file mode 100644 index 000000000..ddcf5a318 --- /dev/null +++ b/patch/kernel/sunxi-current/add-missing-ext_osc32k-on-H6.patch @@ -0,0 +1,26 @@ +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +index f55879b..c3621dd 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +@@ -70,6 +80,13 @@ + clock-output-names = "osc24M"; + }; + ++ ext_osc32k: ext_osc32k_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <32768>; ++ clock-output-names = "ext_osc32k"; ++ }; ++ + pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = , +@@ -922,6 +1050,7 @@ + interrupts = <5 IRQ_TYPE_LEVEL_HIGH>, + <6 IRQ_TYPE_LEVEL_HIGH>; + clock-output-names = "osc32k", "osc32k-out", "iosc"; ++ clocks = <&ext_osc32k>; + #clock-cells = <1>; + }; + diff --git a/patch/kernel/sunxi-current/add-more-uart-pins-to-sun8i-r40.patch b/patch/kernel/sunxi-current/add-more-uart-pins-to-sun8i-r40.patch new file mode 100644 index 000000000..f0e9abd16 --- /dev/null +++ b/patch/kernel/sunxi-current/add-more-uart-pins-to-sun8i-r40.patch @@ -0,0 +1,40 @@ +diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi +index 421dfbb..ae64248 100644 +--- a/arch/arm/boot/dts/sun8i-r40.dtsi ++++ b/arch/arm/boot/dts/sun8i-r40.dtsi +@@ -403,6 +420,11 @@ + function = "uart0"; + }; + ++ uart2_pi_pins: uart2-pi-pins { ++ pins = "PI18", "PI19"; ++ function = "uart2"; ++ }; ++ + uart3_pg_pins: uart3-pg-pins { + pins = "PG6", "PG7"; + function = "uart3"; +@@ -412,6 +463,23 @@ + pins = "PG8", "PG9"; + function = "uart3"; + }; ++ ++ uart4_ph_pins: uart4-ph-pins { ++ pins = "PH4", "PH5"; ++ function = "uart4"; ++ }; ++ ++ ++ uart5_ph_pins: uart5-ph-pins { ++ pins = "PH6", "PH7"; ++ function = "uart5"; ++ }; ++ ++ uart7_pi_pins: uart7-pi-pins { ++ pins = "PI20", "PI21"; ++ function = "uart7"; ++ }; ++ + }; + + wdt: watchdog@1c20c90 { diff --git a/patch/kernel/sunxi-current/add-more-uarts-bpim2ultra-bpim2berry.patch b/patch/kernel/sunxi-current/add-more-uarts-bpim2ultra-bpim2berry.patch new file mode 100644 index 000000000..a8c17a8e0 --- /dev/null +++ b/patch/kernel/sunxi-current/add-more-uarts-bpim2ultra-bpim2berry.patch @@ -0,0 +1,84 @@ +diff --git a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts +index 42d62d1..35bba4e 100644 +--- a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts ++++ b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts +@@ -305,6 +305,12 @@ + status = "okay"; + }; + ++&uart2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pi_pins>; ++ status = "disabled"; ++}; ++ + &uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pg_pins>, <&uart3_rts_cts_pg_pins>; +@@ -324,6 +330,24 @@ + }; + }; + ++&uart4 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart4_ph_pins>; ++ status = "disabled"; ++}; ++ ++&uart5 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart5_ph_pins>; ++ status = "disabled"; ++}; ++ ++&uart7 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart7_pi_pins>; ++ status = "disabled"; ++}; ++ + &usbphy { + usb1_vbus-supply = <®_vcc5v0>; + usb2_vbus-supply = <®_vcc5v0>; +diff --git a/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts b/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts +index 15c22b0..967833c 100644 +--- a/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts ++++ b/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts +@@ -280,6 +280,12 @@ + status = "okay"; + }; + ++&uart2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pi_pins>; ++ status = "disabled"; ++}; ++ + &uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pg_pins>, <&uart3_rts_cts_pg_pins>; +@@ -299,6 +305,24 @@ + }; + }; + ++&uart4 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart4_ph_pins>; ++ status = "disabled"; ++}; ++ ++&uart5 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart5_ph_pins>; ++ status = "disabled"; ++}; ++ ++&uart7 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart7_pi_pins>; ++ status = "disabled"; ++}; ++ + &usbphy { + usb1_vbus-supply = <®_vcc5v0>; + status = "okay"; diff --git a/patch/kernel/sunxi-current/add-orangepi-zeroplus2.patch b/patch/kernel/sunxi-current/add-orangepi-zeroplus2.patch index 7993e083a..c372283e4 100644 --- a/patch/kernel/sunxi-current/add-orangepi-zeroplus2.patch +++ b/patch/kernel/sunxi-current/add-orangepi-zeroplus2.patch @@ -48,7 +48,7 @@ index b8f46e2..24cb8b9 100644 }; }; -+&sound_hdmi { ++&hdmi_sound { + status = "okay"; +}; + diff --git a/patch/kernel/sunxi-current/board-h5-add-0003-nanopi-m1-plus2.patch b/patch/kernel/sunxi-current/board-h5-add-0003-nanopi-m1-plus2.patch index 9da4d1192..933242431 100644 --- a/patch/kernel/sunxi-current/board-h5-add-0003-nanopi-m1-plus2.patch +++ b/patch/kernel/sunxi-current/board-h5-add-0003-nanopi-m1-plus2.patch @@ -231,7 +231,7 @@ index 0000000..a6bf32d + }; +}; + -+&sound_hdmi { ++&hdmi_sound { + status = "okay"; +}; + diff --git a/patch/kernel/sunxi-current/board-h6-improve-thermals.patch b/patch/kernel/sunxi-current/board-h6-improve-thermals.patch new file mode 100644 index 000000000..f9cd2f5af --- /dev/null +++ b/patch/kernel/sunxi-current/board-h6-improve-thermals.patch @@ -0,0 +1,106 @@ +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi +index bef3f50b1..90e4d1764 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: (GPL-2.0+ OR MIT) + // Copyright (C) 2020 Ondrej Jirman + // Copyright (C) 2020 Clément Péron ++// Copyright (C) 2020 Igor Pecovnik + + / { + cpu_opp_table: cpu-opp-table { +@@ -122,26 +123,67 @@ + + &cpu_thermal { + trips { +- cpu_hot_trip: cpu-hot { ++ cpu_warm: cpu_warm { ++ temperature = <75000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ cpu_hot_pre: cpu_hot_pre { + temperature = <80000>; + hysteresis = <2000>; + type = "passive"; + }; ++ ++ cpu_hot: cpu_hot { ++ temperature = <85000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ cpu_very_hot_pre: cpu_very_hot_pre { ++ temperature = <90000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; + +- cpu_very_hot_trip: cpu-very-hot { +- temperature = <100000>; +- hysteresis = <0>; ++ cpu_very_hot: cpu_very_hot { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ cpu_crit: cpu_crit { ++ temperature = <105000>; ++ hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { +- cpu-hot-limit { +- trip = <&cpu_hot_trip>; +- cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cpu_warm_limit_cpu { ++ trip = <&cpu_warm>; ++ cooling-device = <&cpu0 THERMAL_NO_LIMIT 2>; ++ }; ++ ++ cpu_hot_pre_limit_cpu { ++ trip = <&cpu_hot_pre>; ++ cooling-device = <&cpu0 2 3>; ++ }; ++ ++ cpu_hot_limit_cpu { ++ trip = <&cpu_hot>; ++ cooling-device = <&cpu0 3 4>; ++ }; ++ ++ cpu_very_hot_pre_limit_cpu { ++ trip = <&cpu_very_hot_pre>; ++ cooling-device = <&cpu0 5 6>; ++ }; ++ ++ cpu_very_hot_limit_cpu { ++ trip = <&cpu_very_hot>; ++ cooling-device = <&cpu0 7 THERMAL_NO_LIMIT>; + }; + }; + }; +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +index 82cc1e5fe..00ebb89fc 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +@@ -1147,8 +1147,9 @@ + + thermal-zones { + cpu_thermal: cpu-thermal { +- polling-delay-passive = <0>; +- polling-delay = <0>; ++ /* milliseconds */ ++ polling-delay-passive = <250>; ++ polling-delay = <1000>; + thermal-sensors = <&ths 0>; + }; + diff --git a/patch/kernel/sunxi-current/board-h6-orangepi-lite2-fix-missing-all.patch b/patch/kernel/sunxi-current/board-h6-orangepi-lite2-fix-missing-all.patch index 18a3b1048..e018541b4 100644 --- a/patch/kernel/sunxi-current/board-h6-orangepi-lite2-fix-missing-all.patch +++ b/patch/kernel/sunxi-current/board-h6-orangepi-lite2-fix-missing-all.patch @@ -2,7 +2,7 @@ diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts b/arch/a index e098a2475..6c481b547 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts -@@ -3,9 +3,344 @@ +@@ -3,9 +3,350 @@ * Copyright (C) 2018 Jagan Teki */ @@ -98,6 +98,11 @@ index e098a2475..6c481b547 100644 + status = "okay"; +}; + ++&gpu { ++ mali-supply = <®_dcdcc>; ++ status = "okay"; ++}; ++ +&hdmi { + status = "okay"; +}; @@ -244,6 +249,7 @@ index e098a2475..6c481b547 100644 + }; + + reg_dcdcc: dcdcc { ++ regulator-enable-ramp-delay = <32000>; + regulator-min-microvolt = <810000>; + regulator-max-microvolt = <1080000>; + regulator-name = "vdd-gpu"; diff --git a/patch/kernel/sunxi-current/board-orangepizeroplus2-missing-otg-bits.patch b/patch/kernel/sunxi-current/board-orangepizeroplus2-missing-otg-bits.patch index 32f2c0a2d..169a5bc3d 100644 --- a/patch/kernel/sunxi-current/board-orangepizeroplus2-missing-otg-bits.patch +++ b/patch/kernel/sunxi-current/board-orangepizeroplus2-missing-otg-bits.patch @@ -2,13 +2,6 @@ diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts b/a index e1ee1cd09..522a08d6c 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts -@@ -1,5 +1,6 @@ - /* - * Copyright (C) 2017 Jagan Teki -+ * Copyright (C) 2019 Adopted by Igor - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual @@ -180,3 +181,12 @@ pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; status = "okay"; diff --git a/patch/kernel/sunxi-current/add-BergMicro-SPI-flashes.patch b/patch/kernel/sunxi-current/check/add-BergMicro-SPI-flashes.patch similarity index 100% rename from patch/kernel/sunxi-current/add-BergMicro-SPI-flashes.patch rename to patch/kernel/sunxi-current/check/add-BergMicro-SPI-flashes.patch diff --git a/patch/kernel/sunxi-current/check/general-sunxi-overlays.patch b/patch/kernel/sunxi-current/check/general-sunxi-overlays.patch new file mode 100644 index 000000000..2b15fc211 --- /dev/null +++ b/patch/kernel/sunxi-current/check/general-sunxi-overlays.patch @@ -0,0 +1,7138 @@ +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index 965a7c0..71a672e 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -1213,3 +1213,5 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ + aspeed-bmc-opp-zaius.dtb \ + aspeed-bmc-portwell-neptune.dtb \ + aspeed-bmc-quanta-q71l.dtb ++ ++subdir-y := overlay +diff --git a/arch/arm/boot/dts/overlay/Makefile b/arch/arm/boot/dts/overlay/Makefile +new file mode 100644 +index 0000000..39d6a27 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/Makefile +@@ -0,0 +1,97 @@ ++# SPDX-License-Identifier: GPL-2.0 ++dtbo-$(CONFIG_MACH_SUN4I) += \ ++ sun4i-a10-analog-codec.dtbo \ ++ sun4i-a10-can.dtbo \ ++ sun4i-a10-i2c1.dtbo \ ++ sun4i-a10-i2c2.dtbo \ ++ sun4i-a10-nand.dtbo \ ++ sun4i-a10-pps-gpio.dtbo \ ++ sun4i-a10-pwm.dtbo \ ++ sun4i-a10-spdif-out.dtbo \ ++ sun4i-a10-spi-jedec-nor.dtbo \ ++ sun4i-a10-spi-spidev.dtbo \ ++ sun4i-a10-uart2.dtbo \ ++ sun4i-a10-uart3.dtbo \ ++ sun4i-a10-uart4.dtbo \ ++ sun4i-a10-uart5.dtbo \ ++ sun4i-a10-uart6.dtbo \ ++ sun4i-a10-uart7.dtbo \ ++ sun4i-a10-w1-gpio.dtbo ++ ++dtbo-$(CONFIG_MACH_SUN5I) += \ ++ sun5i-a13-analog-codec.dtbo \ ++ sun5i-a13-i2c1.dtbo \ ++ sun5i-a13-i2c2.dtbo \ ++ sun5i-a13-nand.dtbo \ ++ sun5i-a13-pwm.dtbo \ ++ sun5i-a13-spi0.dtbo \ ++ sun5i-a13-spi1.dtbo \ ++ sun5i-a13-spi2.dtbo \ ++ sun5i-a13-spi-jedec-nor.dtbo \ ++ sun5i-a13-spi-spidev.dtbo \ ++ sun5i-a13-uart0.dtbo \ ++ sun5i-a13-uart1.dtbo \ ++ sun5i-a13-uart2.dtbo \ ++ sun5i-a13-uart3.dtbo ++ ++dtbo-$(CONFIG_MACH_SUN7I) += \ ++ sun7i-a20-analog-codec.dtbo \ ++ sun7i-a20-can.dtbo \ ++ sun7i-a20-i2c1.dtbo \ ++ sun7i-a20-i2c2.dtbo \ ++ sun7i-a20-i2c3.dtbo \ ++ sun7i-a20-i2c4.dtbo \ ++ sun7i-a20-mmc2.dtbo \ ++ sun7i-a20-nand.dtbo \ ++ sun7i-a20-pps-gpio.dtbo \ ++ sun7i-a20-pwm.dtbo \ ++ sun7i-a20-spdif-out.dtbo \ ++ sun7i-a20-spi-add-cs1.dtbo \ ++ sun7i-a20-spi-jedec-nor.dtbo \ ++ sun7i-a20-spi-spidev.dtbo \ ++ sun7i-a20-uart2.dtbo \ ++ sun7i-a20-uart3.dtbo \ ++ sun7i-a20-uart4.dtbo \ ++ sun7i-a20-uart5.dtbo \ ++ sun7i-a20-uart6.dtbo \ ++ sun7i-a20-uart7.dtbo \ ++ sun7i-a20-w1-gpio.dtbo ++ ++dtbo-$(CONFIG_MACH_SUN8I) += \ ++ sun8i-h3-analog-codec.dtbo \ ++ sun8i-h3-cir.dtbo \ ++ sun8i-h3-i2c0.dtbo \ ++ sun8i-h3-i2c1.dtbo \ ++ sun8i-h3-i2c2.dtbo \ ++ sun8i-h3-pps-gpio.dtbo \ ++ sun8i-h3-pwm.dtbo \ ++ sun8i-h3-spdif-out.dtbo \ ++ sun8i-h3-spi-add-cs1.dtbo \ ++ sun8i-h3-spi-jedec-nor.dtbo \ ++ sun8i-h3-spi-spidev.dtbo \ ++ sun8i-h3-uart1.dtbo \ ++ sun8i-h3-uart2.dtbo \ ++ sun8i-h3-uart3.dtbo \ ++ sun8i-h3-usbhost0.dtbo \ ++ sun8i-h3-usbhost1.dtbo \ ++ sun8i-h3-usbhost2.dtbo \ ++ sun8i-h3-usbhost3.dtbo \ ++ sun8i-h3-w1-gpio.dtbo \ ++ sun8i-r40-i2c2.dtbo \ ++ sun8i-r40-i2c3.dtbo \ ++ sun8i-r40-spi-spidev0.dtbo \ ++ sun8i-r40-spi-spidev1.dtbo \ ++ sun8i-r40-uart2.dtbo \ ++ sun8i-r40-uart4.dtbo \ ++ sun8i-r40-uart5.dtbo \ ++ sun8i-r40-uart7.dtbo ++ ++scr-$(CONFIG_MACH_SUN4I) += sun4i-a10-fixup.scr ++scr-$(CONFIG_MACH_SUN5I) += sun5i-a13-fixup.scr ++scr-$(CONFIG_MACH_SUN7I) += sun7i-a20-fixup.scr ++scr-$(CONFIG_MACH_SUN8I) += sun8i-h3-fixup.scr ++ ++dtbotxt-$(CONFIG_MACH_SUN4I) += README.sun4i-a10-overlays ++dtbotxt-$(CONFIG_MACH_SUN5I) += README.sun5i-a13-overlays ++dtbotxt-$(CONFIG_MACH_SUN7I) += README.sun7i-a20-overlays ++dtbotxt-$(CONFIG_MACH_SUN8I) += README.sun8i-h3-overlays +diff --git a/arch/arm/boot/dts/overlay/README.sun4i-a10-overlays b/arch/arm/boot/dts/overlay/README.sun4i-a10-overlays +new file mode 100644 +index 0000000..e0795f1 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/README.sun4i-a10-overlays +@@ -0,0 +1,278 @@ ++This document describes overlays provided in the kernel packages ++For generic Armbian overlays documentation please see ++https://docs.armbian.com/User-Guide_Allwinner_overlays/ ++ ++### Platform: ++ ++sun4i-a10 (Allwinner A10) ++ ++### Platform details: ++ ++Supported pin banks: PB, PC, PD, PE, PG, PH, PI ++ ++SPI controller 0 have 2 exposed hardware CS, ++other SPI controllers have only one hardware CS ++Reference: A10 User manual section 17.4.13, A10 datasheet section 5.2 ++ ++I2C bus 0 is used for the AXP209 PMIC ++ ++### Provided overlays: ++ ++- analog-codec ++- can ++- i2c1 ++- i2c2 ++- nand ++- pps-gpio ++- pwm ++- spdif-out ++- spi0 ++- spi1 ++- spi2 ++- spi-jedec-nor ++- spi-spidev ++- uart1 ++- uart2 ++- uart3 ++- uart4 ++- uart5 ++- uart6 ++- uart7 ++- w1-gpio ++ ++### Overlay details: ++ ++### analog-codec ++ ++Activates SoC analog codec driver that provides Line Out and Mic In ++functionality ++ ++## can ++ ++Activates SoC CAN controller ++ ++CAN pins (TX, RX): PH20, PH21 ++ ++### i2c1 ++ ++Activates TWI/I2C bus 1 ++ ++I2C1 pins (SCL, SDA): PB18, PB19 ++ ++### i2c2 ++ ++Activates TWI/I2C bus 2 ++ ++I2C2 pins (SCL, SDA): PB20, PB21 ++ ++### nand ++ ++Activates NAND controller ++ ++This overlay should not be used until mainline MLC NAND support ++allows using NAND storage reliably ++ ++### pps-gpio ++ ++Activates pulse-per-second GPIO client ++ ++Parameters: ++ ++param_pps_pin (pin) ++ Pin PPS source is connected to ++ Optional ++ Default: PI15 ++ ++param_pps_falling_edge (bool) ++ Assert by falling edge ++ Optional ++ Default: 0 ++ When set (to 1), assert is indicated by a falling edge ++ (instead of by a rising edge) ++ ++### pwm ++ ++Activates hardware PWM controller ++ ++PWM pins (PWM0, PWM1): PB2, PI3 ++ ++Parameters: ++ ++param_pwm_pins (string) ++ PWM pins activated with this overlay ++ Optional ++ Default: both ++ Supported values: 0, 1, both ++ If set to 0 only PWM0 can be used, ++ if set to 1 then only PWM1 can be used, ++ if set to both (default), both PWM0 and PWM1 can be used ++ ++### spdif-out ++ ++Activates SPDIF/Toslink audio output ++ ++SPDIF pin: PB13 ++ ++### spi0 ++ ++Activates SPI controller 0 to use it with other overlays and sets up the pin multiplexing for it ++ ++SPI 0 pins (MOSI, MISO, SCK, CS0, CS1): PI12, PI13, PI11, PI10, PI14 ++ ++### spi1 ++ ++Activates SPI controller 1 to use it with other overlays and sets up the pin multiplexing for it ++ ++SPI 1 pins (MOSI, MISO, SCK, CS0): PI18, PI19, PI17, PI16 ++ ++### spi2 ++ ++Activates SPI controller 2 to use it with other overlays and sets up the pin multiplexing for it ++ ++SPI 2 pins a (MOSI, MISO, SCK, CS0): PC21, PC22, PC20, PC19 ++SPI 2 pins b (MOSI, MISO, SCK, CS0): PB16, PB17, PB15, PB14 ++ ++Parameters: ++ ++param_spi2_bus_pins (char) ++ SPI bus 2 pinmux variant ++ Optional ++ Default: a ++ Supported values: a, b ++ Determines what pins SPI bus 2 is exposed on if SPI 2 is used ++ ++ ++### spi-jedec-nor ++ ++Activates MTD support for JEDEC compatible SPI NOR flash chips on SPI bus ++supported by the kernel SPI NOR driver ++ ++SPI 0 pins (MOSI, MISO, SCK, CS0, CS1): PI12, PI13, PI11, PI10, PI14 ++SPI 1 pins (MOSI, MISO, SCK, CS0): PI18, PI19, PI17, PI16 ++SPI 2 pins a (MOSI, MISO, SCK, CS0): PC21, PC22, PC20, PC19 ++SPI 2 pins b (MOSI, MISO, SCK, CS0): PB16, PB17, PB15, PB14 ++ ++Parameters: ++ ++param_spinor_spi_bus (int) ++ SPI bus to activate SPI NOR flash support on ++ Required ++ Supported values: 0, 1, 2 ++ ++param_spinor_max_freq (int) ++ Maximum SPI frequency ++ Optional ++ Default: 1000000 ++ Range: 3000 - 100000000 ++ ++### spi-spidev ++ ++Activates SPIdev device node (/dev/spidevX.Y) for userspace SPI access, ++where X is the bus number and Y is the CS number ++ ++SPI 0 pins (MOSI, MISO, SCK, CS0, CS1): PI12, PI13, PI11, PI10, PI14 ++SPI 1 pins (MOSI, MISO, SCK, CS0): PI18, PI19, PI17, PI16 ++SPI 2 pins a (MOSI, MISO, SCK, CS0): PC21, PC22, PC20, PC19 ++SPI 2 pins b (MOSI, MISO, SCK, CS0): PB16, PB17, PB15, PB14 ++ ++Parameters: ++ ++param_spidev_spi_bus (int) ++ SPI bus to activate mcp2515 support on ++ Required ++ Supported values: 0, 1, 2 ++ ++param_spidev_max_freq (int) ++ Maximum SPIdev frequency ++ Optional ++ Default: 1000000 ++ Range: 3000 - 100000000 ++ ++### uart2 ++ ++Activates serial port 2 (/dev/ttyS2) ++ ++UART 2 pins (TX, RX, RTS, CTS): PI18, PI19, PI16, PI17 ++ ++Parameters: ++ ++param_uart2_rtscts (bool) ++ Enable RTS and CTS pins ++ Optional ++ Default: 0 ++ Set to 1 to enable CTS and RTS pins ++ ++### uart3 ++ ++Activates serial port 3 (/dev/ttyS3) ++ ++UART 3 pins a (TX, RX, RTS, CTS): PG6, PG7, PG8, PG9 ++UART 3 pins b (TX, RX, RTS, CTS): PH0, PH1, PH2, PH3 ++ ++Parameters: ++ ++param_uart3_pins (char) ++ Determines what pins UART 3 is exposed on ++ Optional ++ Default: a ++ Supported values: a, b ++ ++param_uart3_rtscts (bool) ++ Enable RTS and CTS pins ++ Optional ++ Default: 0 ++ Set to 1 to enable CTS and RTS pins ++ ++### uart4 ++ ++Activates serial port 4 (/dev/ttyS4) ++ ++UART 4 pins a (TX, RX): PG10, PG11 ++UART 4 pins b (TX, RX): PH4, PH5 ++ ++Parameters: ++ ++param_uart4_pins (char) ++ Determines what pins UART 4 is exposed on ++ Optional ++ Default: a ++ Supported values: a, b ++ ++### uart 5 ++ ++Activates serial port 5 (/dev/ttyS5) ++ ++UART 5 pins (TX, RX): PH6, PH7 ++ ++### uart 6 ++ ++Activates serial port 6 (/dev/ttyS6) ++ ++UART 6 pins (TX, RX): PI12, PI13 ++ ++### uart 7 ++ ++Activates serial port 7 (/dev/ttyS7) ++ ++UART 7 pins (TX, RX): PI20, PI21 ++ ++### w1-gpio ++ ++Activates 1-Wire GPIO master ++Requires an external pull-up resistor on the data pin ++or enabling the internal pull-up ++ ++Parameters: ++ ++param_w1_pin (pin) ++ Data pin for 1-Wire master ++ Optional ++ Default: PI15 ++ ++param_w1_pin_int_pullup (bool) ++ Enable internal pull-up for the data pin ++ Optional ++ Default: 0 ++ Set to 1 to enable the pull-up ++ This option should not be used with multiple sensors or long wires - ++ please use external pull-up resistor instead +diff --git a/arch/arm/boot/dts/overlay/README.sun5i-a13-overlays b/arch/arm/boot/dts/overlay/README.sun5i-a13-overlays +new file mode 100644 +index 0000000..9f9653f +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/README.sun5i-a13-overlays +@@ -0,0 +1,172 @@ ++This document describes overlays provided in the kernel packages ++For generic Armbian overlays documentation please see ++https://docs.armbian.com/User-Guide_Allwinner_overlays/ ++ ++### Platform: ++ ++sun5i-a13 (Allwinner A13) ++ ++### Platform details: ++ ++I2C bus 0 is used for the AXP209 PMIC ++ ++### Provided overlays: ++ ++- analog-codec ++- i2c1 ++- i2c2 ++- nand ++- pwm ++- spi0 ++- spi1 ++- spi2 ++- spi-jedec-nor ++- spi-spidev ++- uart0 ++- uart1 ++- uart2 ++- uart3 ++ ++### Overlay details: ++ ++### analog-codec ++ ++Activates SoC analog codec driver that provides HP Out and Mic In ++functionality ++ ++### i2c1 ++ ++Activates TWI/I2C bus 1 ++ ++I2C1 pins (SCL, SDA): PB15, PB16 ++ ++### i2c2 ++ ++Activates TWI/I2C bus 2 ++ ++I2C2 pins (SCL, SDA): PB17, PB18 ++ ++### nand ++ ++Activates NAND controller ++ ++This overlay should not be used until mainline MLC NAND support ++allows using NAND storage reliably ++ ++### pwm ++ ++Activates hardware PWM controller ++ ++PWM pins (PWM0): PB2 ++ ++### spi0 ++ ++Activates SPI controller 0 to use it with other overlays and sets up the pin multiplexing for it ++ ++SPI 0 pins (MOSI, MISO, SCK, CS0): PC0, PC1, PC2, PC3 ++ ++### spi1 ++ ++Activates SPI controller 1 to use it with other overlays and sets up the pin multiplexing for it ++ ++SPI 1 pins (MOSI, MISO, SCK, CS0): PG11, PG12, PG10, PG9 ++ ++### spi2 ++ ++Activates SPI controller 2 to use it with other overlays and sets up the pin multiplexing for it ++ ++SPI 2 pins (MOSI, MISO, SCK, CS0): PE2, PE3, PE1, PE0 ++ ++### spi-jedec-nor ++ ++Activates MTD support for JEDEC compatible SPI NOR flash chips on SPI bus ++supported by the kernel SPI NOR driver ++ ++SPI 0 pins (MOSI, MISO, SCK, CS0): PC0, PC1, PC2, PC3 ++SPI 1 pins (MOSI, MISO, SCK, CS0): PG11, PG12, PG10, PG9 ++SPI 2 pins (MOSI, MISO, SCK, CS0): PE2, PE3, PE1, PE0 ++ ++Parameters: ++ ++param_spinor_spi_bus (int) ++ SPI bus to activate SPI NOR flash support on ++ Required ++ Supported values: 0, 1, 2 ++ ++param_spinor_max_freq (int) ++ Maximum SPI frequency ++ Optional ++ Default: 1000000 ++ Range: 3000 - 100000000 ++ ++### spi-spidev ++ ++Activates SPIdev device node (/dev/spidevX.Y) for userspace SPI access, ++where X is the bus number and Y is the CS number ++ ++SPI 0 pins (MOSI, MISO, SCK, CS0): PC0, PC1, PC2, PC3 ++SPI 1 pins (MOSI, MISO, SCK, CS0): PG11, PG12, PG10, PG9 ++SPI 2 pins (MOSI, MISO, SCK, CS0): PE2, PE3, PE1, PE0 ++ ++Parameters: ++ ++param_spidev_spi_bus (int) ++ SPI bus to activate mcp2515 support on ++ Required ++ Supported values: 0, 1, 2 ++ ++param_spidev_max_freq (int) ++ Maximum SPIdev frequency ++ Optional ++ Default: 1000000 ++ Range: 3000 - 100000000 ++ ++### uart 0 ++ ++Activates serial port 0 (/dev/ttyS0) ++ ++UART 0 pins (TX, RX): PF2, PF4 ++ ++### uart 1 ++ ++Activates serial port 1 (/dev/ttyS1) ++ ++UART 1 pins a (TX, RX): PE10, PE11 ++UART 1 pins b (TX, RX): PG3, PG4 ++ ++Parameters: ++ ++param_uart1_pins (char) ++ UART 1 pinmux variant ++ Optional ++ Default: a ++ Supported values: a, b ++ Determines what pins UART 1 is exposed on if UART 1 is used ++ ++### uart2 ++ ++Activates serial port 2 (/dev/ttyS2) ++ ++UART 2 pins (TX, RX, RTS, CTS): PD2, PD3, PD4, PD5 ++ ++Parameters: ++ ++param_uart2_rtscts (bool) ++ Enable RTS and CTS pins ++ Optional ++ Default: 0 ++ Set to 1 to enable CTS and RTS pins ++ ++### uart3 ++ ++Activates serial port 3 (/dev/ttyS3) ++ ++UART 3 pins (TX, RX, RTS, CTS): PG9, PG10, PG12, PG11 ++ ++Parameters: ++ ++param_uart3_rtscts (bool) ++ Enable RTS and CTS pins ++ Optional ++ Default: 0 ++ Set to 1 to enable CTS and RTS pins +diff --git a/arch/arm/boot/dts/overlay/README.sun7i-a20-overlays b/arch/arm/boot/dts/overlay/README.sun7i-a20-overlays +new file mode 100644 +index 0000000..362f879 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/README.sun7i-a20-overlays +@@ -0,0 +1,348 @@ ++This document describes overlays provided in the kernel packages ++For generic Armbian overlays documentation please see ++https://docs.armbian.com/User-Guide_Allwinner_overlays/ ++ ++### Platform: ++ ++sun7i-a20 (Allwinner A20) ++ ++### Platform details: ++ ++Supported pin banks: PB, PC, PD, PE, PG, PH, PI ++ ++SPI controller 0 have 2 exposed hardware CS, ++other SPI controllers have only one hardware CS ++Reference: A20 Datasheet sections 6.3.5.1, 1.19.2 ++ ++I2C bus 0 is used for the AXP209 PMIC ++ ++### Provided overlays: ++ ++- analog-codec ++- can ++- i2c1 ++- i2c2 ++- i2c3 ++- i2c4 ++- i2s0 ++- i2s1 ++- mmc2 ++- nand ++- pps-gpio ++- pwm ++- spdif-out ++- spi0 ++- spi1 ++- spi2 ++- spi-add-cs1 ++- spi-jedec-nor ++- spi-spidev ++- uart1 ++- uart2 ++- uart3 ++- uart4 ++- uart5 ++- uart6 ++- uart7 ++- w1-gpio ++ ++### Overlay details: ++ ++### analog-codec ++ ++Activates SoC analog codec driver that provides Line Out and Mic In ++functionality ++ ++## can ++ ++Activates SoC CAN controller ++ ++CAN pins (TX, RX): PH20, PH21 ++ ++### i2c1 ++ ++Activates TWI/I2C bus 1 ++ ++I2C1 pins (SCL, SDA): PB18, PB19 ++ ++### i2c2 ++ ++Activates TWI/I2C bus 2 ++ ++I2C2 pins (SCL, SDA): PB20, PB21 ++ ++### i2c3 ++ ++Activates TWI/I2C bus 3 ++ ++I2C3 pins (SCL, SDA): PI0, PI1 ++ ++### i2c4 ++ ++Activates TWI/I2C bus 4 ++ ++I2C4 pins (SCL, SDA): PI2, PI3 ++ ++### i2s0 ++ ++Activates SoC I2S controller 0 ++ ++I2S0 pins (MCLK, BCLK, LRCK, DO0, DO1, DO2, DO3, DI): PB5, PB6, PB7, PB8, PB9, PB10, PB11, PB12 ++ ++### i2s1 ++ ++Activates SoC I2S controller 1 ++ ++I2S1 pins (MCLK, BCLK, LRCK, DO, DI): PA9, PA14, PA15, PA16, PA17 ++ ++### mmc2 ++ ++Activates SD/MMC controller 2. To be used on boards with second SD slot, eMMC ++or tSD instead of NAND storage. ++ ++MMC2 pins: PC6, PC7, PC8, PC9, PC10, PC11 ++ ++Parameters: ++ ++param_mmc2_cd_pin (pin) ++ SD/MMC 2 card detect pin ++ Optional ++ Default: PH0 ++ ++param_mmc2_non_removable (bool) ++ Option for non-removable storage options on MMC 2 controller (eMMC or tSD) ++ Optional ++ Default: 0 ++ Set to 1 to use this option ++ ++### nand ++ ++Activates NAND controller ++ ++This overlay should not be used until mainline MLC NAND support ++allows using NAND storage reliably ++ ++### pps-gpio ++ ++Activates pulse-per-second GPIO client ++ ++Parameters: ++ ++param_pps_pin (pin) ++ Pin PPS source is connected to ++ Optional ++ Default: PI15 ++ ++param_pps_falling_edge (bool) ++ Assert by falling edge ++ Optional ++ Default: 0 ++ When set (to 1), assert is indicated by a falling edge ++ (instead of by a rising edge) ++ ++### pwm ++ ++Activates hardware PWM controller ++ ++PWM pins (PWM0, PWM1): PB2, PI3 ++ ++Parameters: ++ ++param_pwm_pins (string) ++ PWM pins activated with this overlay ++ Optional ++ Default: both ++ Supported values: 0, 1, both ++ If set to 0 only PWM0 can be used, ++ if set to 1 then only PWM1 can be used, ++ if set to both (default), both PWM0 and PWM1 can be used ++ ++### spdif-out ++ ++Activates SPDIF/Toslink audio output ++ ++SPDIF pin: PB13 ++ ++### spi0 ++ ++Activates SPI controller 0 to use it with other overlays and sets up the pin multiplexing for it ++ ++SPI 0 pins (MOSI, MISO, SCK, CS0, CS1): PI12, PI13, PI11, PI10, PI14 ++ ++### spi1 ++ ++Activates SPI controller 1 to use it with other overlays and sets up the pin multiplexing for it ++ ++SPI 1 pins (MOSI, MISO, SCK, CS0): PI18, PI19, PI17, PI16 ++ ++### spi2 ++ ++Activates SPI controller 2 to use it with other overlays and sets up the pin multiplexing for it ++ ++SPI 2 pins a (MOSI, MISO, SCK, CS0): PC21, PC22, PC20, PC19 ++SPI 2 pins b (MOSI, MISO, SCK, CS0): PB16, PB17, PB15, PB14 ++ ++Parameters: ++ ++param_spi2_bus_pins (char) ++ SPI bus 2 pinmux variant ++ Optional ++ Default: a ++ Supported values: a, b ++ Determines what pins SPI bus 2 is exposed on if SPI 2 is used ++ ++### spi-add-cs1 ++ ++Activates SPI chip select 1 on SPI controller 0 ++This overlay is required for using chip select 1 with other SPI overlays ++ ++SPI 0 CS1 pin: PI14 ++ ++### spi-jedec-nor ++ ++Activates MTD support for JEDEC compatible SPI NOR flash chips on SPI bus ++supported by the kernel SPI NOR driver ++ ++SPI 0 pins (MOSI, MISO, SCK, CS0, CS1): PI12, PI13, PI11, PI10, PI14 ++SPI 1 pins (MOSI, MISO, SCK, CS0): PI18, PI19, PI17, PI16 ++SPI 2 pins a (MOSI, MISO, SCK, CS0): PC21, PC22, PC20, PC19 ++SPI 2 pins b (MOSI, MISO, SCK, CS0): PB16, PB17, PB15, PB14 ++ ++Parameters: ++ ++param_spinor_spi_bus (int) ++ SPI bus to activate SPI NOR flash support on ++ Required ++ Supported values: 0, 1, 2 ++ ++param_spinor_spi_cs (int) ++ SPI chip select number for SPI NOR connected to SPI bus 0 ++ Optional ++ Default: 0 ++ Supported values: 0, 1 ++ Using chip select 1 on SPI 0 requires using "spi-add-cs1" overlay ++ ++param_spinor_max_freq (int) ++ Maximum SPI frequency ++ Optional ++ Default: 1000000 ++ Range: 3000 - 100000000 ++ ++### spi-spidev ++ ++Activates SPIdev device node (/dev/spidevX.Y) for userspace SPI access, ++where X is the bus number and Y is the CS number ++ ++SPI 0 pins (MOSI, MISO, SCK, CS0, CS1): PI12, PI13, PI11, PI10, PI14 ++SPI 1 pins (MOSI, MISO, SCK, CS0): PI18, PI19, PI17, PI16 ++SPI 2 pins a (MOSI, MISO, SCK, CS0): PC21, PC22, PC20, PC19 ++SPI 2 pins b (MOSI, MISO, SCK, CS0): PB16, PB17, PB15, PB14 ++ ++Parameters: ++ ++param_spidev_spi_bus (int) ++ SPI bus to activate mcp2515 support on ++ Required ++ Supported values: 0, 1, 2 ++ ++param_spidev_spi_cs (int) ++ SPI chip select number for SPIdev on SPI bus 0 ++ Optional ++ Default: 0 ++ Supported values: 0, 1 ++ Using chip select 1 on SPI 0 requires using "spi-add-cs1" overlay ++ ++param_spidev_max_freq (int) ++ Maximum SPIdev frequency ++ Optional ++ Default: 1000000 ++ Range: 3000 - 100000000 ++ ++### uart2 ++ ++Activates serial port 2 (/dev/ttyS2) ++ ++UART 2 pins (TX, RX, RTS, CTS): PI18, PI19, PI16, PI17 ++ ++Parameters: ++ ++param_uart2_rtscts (bool) ++ Enable RTS and CTS pins ++ Optional ++ Default: 0 ++ Set to 1 to enable CTS and RTS pins ++ ++### uart3 ++ ++Activates serial port 3 (/dev/ttyS3) ++ ++UART 3 pins a (TX, RX, RTS, CTS): PG6, PG7, PG8, PG9 ++UART 3 pins b (TX, RX, RTS, CTS): PH0, PH1, PH2, PH3 ++ ++Parameters: ++ ++param_uart3_pins (char) ++ Determines what pins UART 3 is exposed on ++ Optional ++ Default: a ++ Supported values: a, b ++ ++param_uart3_rtscts (bool) ++ Enable RTS and CTS pins ++ Optional ++ Default: 0 ++ Set to 1 to enable CTS and RTS pins ++ ++### uart4 ++ ++Activates serial port 4 (/dev/ttyS4) ++ ++UART 4 pins a (TX, RX): PG10, PG11 ++UART 4 pins b (TX, RX): PH4, PH5 ++ ++Parameters: ++ ++param_uart4_pins (char) ++ Determines what pins UART 4 is exposed on ++ Optional ++ Default: a ++ Supported values: a, b ++ ++### uart 5 ++ ++Activates serial port 5 (/dev/ttyS5) ++ ++UART 5 pins (TX, RX): PH6, PH7 ++ ++### uart 6 ++ ++Activates serial port 6 (/dev/ttyS6) ++ ++UART 6 pins (TX, RX): PI12, PI13 ++ ++### uart 7 ++ ++Activates serial port 7 (/dev/ttyS7) ++ ++UART 7 pins (TX, RX): PI20, PI21 ++ ++### w1-gpio ++ ++Activates 1-Wire GPIO master ++Requires an external pull-up resistor on the data pin ++or enabling the internal pull-up ++ ++Parameters: ++ ++param_w1_pin (pin) ++ Data pin for 1-Wire master ++ Optional ++ Default: PI15 ++ ++param_w1_pin_int_pullup (bool) ++ Enable internal pull-up for the data pin ++ Optional ++ Default: 0 ++ Set to 1 to enable the pull-up ++ This option should not be used with multiple sensors or long wires - ++ please use external pull-up resistor instead +diff --git a/arch/arm/boot/dts/overlay/README.sun8i-h3-overlays b/arch/arm/boot/dts/overlay/README.sun8i-h3-overlays +new file mode 100644 +index 0000000..3029734 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/README.sun8i-h3-overlays +@@ -0,0 +1,250 @@ ++This document describes overlays provided in the kernel packages ++For generic Armbian overlays documentation please see ++https://docs.armbian.com/User-Guide_Allwinner_overlays/ ++ ++### Platform: ++ ++sun8i-h3 (Allwinner H3) ++ ++### Platform details: ++ ++Supported pin banks: PA, PC, PD, PG ++ ++Both SPI controllers have only one hardware CS pin exposed, ++adding fixed software (GPIO) chip selects is possible with a separate overlay ++ ++### Provided overlays: ++ ++- analog-codec ++- cir ++- i2c0 ++- i2c1 ++- i2c2 ++- pps-gpio ++- pwm ++- spdif-out ++- spi-add-cs1 ++- spi-jedec-nor ++- spi-spidev ++- uart1 ++- uart2 ++- uart3 ++- usbhost0 ++- usbhost1 ++- usbhost2 ++- usbhost3 ++- w1-gpio ++ ++### Overlay details: ++ ++### analog-codec ++ ++Activates SoC analog codec driver that provides Line Out and Mic In ++functionality ++ ++### cir ++ ++Activates CIR (Infrared remote) receiver ++ ++CIR pin: PL11 ++ ++### i2c0 ++ ++Activates TWI/I2C bus 0 ++ ++I2C0 pins (SCL, SDA): PA11, PA12 ++ ++### i2c1 ++ ++Activates TWI/I2C bus 1 ++ ++I2C1 pins (SCL, SDA): PA18, PA19 ++ ++### i2c2 ++ ++Activates TWI/I2C bus 2 ++ ++I2C2 pins (SCL, SDA): PE12, PE13 ++ ++On most board this bus is wired to Camera (CSI) socket ++ ++### pps-gpio ++ ++Activates pulse-per-second GPIO client ++ ++Parameters: ++ ++param_pps_pin (pin) ++ Pin PPS source is connected to ++ Optional ++ Default: PD14 ++ ++param_pps_falling_edge (bool) ++ Assert by falling edge ++ Optional ++ Default: 0 ++ When set (to 1), assert is indicated by a falling edge ++ (instead of by a rising edge) ++ ++### pwm ++ ++Activates hardware PWM controller ++ ++PWM pin: PA5 ++ ++Pin PA5 is used as UART0 RX by default, so if this overlay is activated, ++UART0 and kernel console on ttyS0 will be disabled ++ ++### spdif-out ++ ++Activates SPDIF/Toslink audio output ++ ++SPDIF pin: PA17 ++ ++### spi-add-cs1 ++ ++Adds support for using SPI chip select 1 with GPIO for both SPI controllers ++Respective GPIO will be claimed only if controller is enabled by another ++overlay ++This overlay is required for using chip select 1 with other SPI overlays ++Due to the u-boot limitations CS1 pin can't be customized by a parameter, but ++it can be changed by using an edited copy of this overlay ++A total of 4 chip selects can be used with custom overlays (1 HW + 3 GPIO) ++ ++SPI 0 pins (CS1): PA21 ++SPI 1 pins (CS1): PA10 ++ ++### spi-jedec-nor ++ ++Activates MTD support for JEDEC compatible SPI NOR flash chips on SPI bus ++supported by the kernel SPI NOR driver ++ ++SPI 0 pins (MOSI, MISO, SCK, CS): PC0, PC1, PC2, PC3 ++SPI 1 pins (MOSI, MISO, SCK, CS): PA15, PA16, PA14, PA13 ++ ++Parameters: ++ ++param_spinor_spi_bus (int) ++ SPI bus to activate SPI NOR flash support on ++ Required ++ Supported values: 0, 1 ++ ++param_spinor_spi_cs (int) ++ SPI chip select number ++ Optional ++ Default: 0 ++ Supported values: 0, 1 ++ Using chip select 1 requires using "spi-add-cs1" overlay ++ ++param_spinor_max_freq (int) ++ Maximum SPI frequency ++ Optional ++ Default: 1000000 ++ Range: 3000 - 100000000 ++ ++### spi-spidev ++ ++Activates SPIdev device node (/dev/spidevX.Y) for userspace SPI access, ++where X is the bus number and Y is the CS number ++ ++SPI 0 pins (MOSI, MISO, SCK, CS): PC0, PC1, PC2, PC3 ++SPI 1 pins (MOSI, MISO, SCK, CS): PA15, PA16, PA14, PA13 ++ ++Parameters: ++ ++param_spidev_spi_bus (int) ++ SPI bus to activate SPIdev support on ++ Required ++ Supported values: 0, 1 ++ ++param_spidev_spi_cs (int) ++ SPI chip select number ++ Optional ++ Default: 0 ++ Supported values: 0, 1 ++ Using chip select 1 requires using "spi-add-cs1" overlay ++ ++param_spidev_max_freq (int) ++ Maximum SPIdev frequency ++ Optional ++ Default: 1000000 ++ Range: 3000 - 100000000 ++ ++### uart1 ++ ++Activates serial port 1 (/dev/ttyS1) ++ ++UART 1 pins (TX, RX, RTS, CTS): PG6, PG7, PG8, PG9 ++ ++Parameters: ++ ++param_uart1_rtscts (bool) ++ Enable RTS and CTS pins ++ Optional ++ Default: 0 ++ Set to 1 to enable ++ ++### uart2 ++ ++Activates serial port 2 (/dev/ttyS2) ++ ++UART 2 pins (TX, RX, RTS, CTS): PA0, PA1, PA2, PA3 ++ ++Parameters: ++ ++param_uart2_rtscts (bool) ++ Enable RTS and CTS pins ++ Optional ++ Default: 0 ++ Set to 1 to enable CTS and RTS pins ++ ++### uart3 ++ ++Activates serial port 3 (/dev/ttyS3) ++ ++UART 3 pins (TX, RX, RTS, CTS): PA13, PA14, PA15, PA16 ++ ++Parameters: ++ ++param_uart3_rtscts (bool) ++ Enable RTS and CTS pins ++ Optional ++ Default: 0 ++ Set to 1 to enable CTS and RTS pins ++ ++### usbhost0 ++ ++Activates USB host controller 0 ++ ++### usbhost1 ++ ++Activates USB host controller 1 ++ ++### usbhost2 ++ ++Activates USB host controller 2 ++ ++### usbhost3 ++ ++Activates USB host controller 3 ++ ++### w1-gpio ++ ++Activates 1-Wire GPIO master ++Requires an external pull-up resistor on the data pin ++or enabling the internal pull-up ++ ++Parameters: ++ ++param_w1_pin (pin) ++ Data pin for 1-Wire master ++ Optional ++ Default: PD14 ++ ++param_w1_pin_int_pullup (bool) ++ Enable internal pull-up for the data pin ++ Optional ++ Default: 0 ++ Set to 1 to enable the pull-up ++ This option should not be used with multiple devices, parasite power setup ++ or long wires - please use external pull-up resistor instead +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-analog-codec.dts b/arch/arm/boot/dts/overlay/sun4i-a10-analog-codec.dts +new file mode 100644 +index 0000000..9254e22 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-analog-codec.dts +@@ -0,0 +1,13 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a10"; ++ ++ fragment@0 { ++ target = <&codec>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-can.dts b/arch/arm/boot/dts/overlay/sun4i-a10-can.dts +new file mode 100644 +index 0000000..1a9511d +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-can.dts +@@ -0,0 +1,15 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a10"; ++ ++ fragment@0 { ++ target = <&can0>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&can0_ph_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-fixup.scr-cmd b/arch/arm/boot/dts/overlay/sun4i-a10-fixup.scr-cmd +new file mode 100644 +index 0000000..d80f2fc +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-fixup.scr-cmd +@@ -0,0 +1,124 @@ ++# overlays fixup script ++# implements (or rather substitutes) overlay arguments functionality ++# using u-boot scripting, environment variables and "fdt" command ++ ++# setexpr test_var ${tmp_bank} - A ++# works only for hex numbers (A-F) ++ ++setenv decompose_pin 'setexpr tmp_bank sub "P(B|C|D|E|G|H|I)\\d+" "\\1"; ++setexpr tmp_pin sub "P\\S(\\d+)" "\\1"; ++test "${tmp_bank}" = "B" && setenv tmp_bank 1; ++test "${tmp_bank}" = "C" && setenv tmp_bank 2; ++test "${tmp_bank}" = "D" && setenv tmp_bank 3; ++test "${tmp_bank}" = "E" && setenv tmp_bank 4; ++test "${tmp_bank}" = "G" && setenv tmp_bank 6; ++test "${tmp_bank}" = "H" && setenv tmp_bank 7; ++test "${tmp_bank}" = "I" && setenv tmp_bank 8' ++ ++if test -n "${param_spinor_spi_bus}"; then ++ test "${param_spinor_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c05000" ++ test "${param_spinor_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c06000" ++ test "${param_spinor_spi_bus}" = "2" && setenv tmp_spi_path "spi@1c17000" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spiflash status "okay" ++ if test -n "${param_spinor_max_freq}"; then ++ fdt set /soc/${tmp_spi_path}/spiflash spi-max-frequency "<${param_spinor_max_freq}>" ++ fi ++ env delete tmp_spi_path ++fi ++ ++if test -n "${param_spidev_spi_bus}"; then ++ test "${param_spidev_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c05000" ++ test "${param_spidev_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c06000" ++ test "${param_spidev_spi_bus}" = "2" && setenv tmp_spi_path "spi@1c17000" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spidev status "okay" ++ if test -n "${param_spidev_max_freq}"; then ++ fdt set /soc/${tmp_spi_path}/spidev spi-max-frequency "<${param_spidev_max_freq}>" ++ fi ++ env delete tmp_spi_path ++fi ++ ++if test "${param_spi2_bus_pins}" = "b"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/spi2@1 phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/spi2_cs0@1 phandle ++ fdt set /soc/spi@1c17000 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/spi@1c17000 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++fi ++ ++if test -n "${param_pps_pin}"; then ++ setenv tmp_bank "${param_pps_pin}" ++ setenv tmp_pin "${param_pps_pin}" ++ run decompose_pin ++ fdt set /soc/pinctrl@1c20800/pps_pins pins "${param_pps_pin}" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800 phandle ++ fdt set /pps@0 gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 0>" ++ env delete tmp_pin tmp_bank tmp_phandle ++fi ++ ++if test "${param_pps_falling_edge}" = "1"; then ++ fdt set /pps@0 assert-falling-edge ++fi ++ ++if test "${param_pwm_pins}" = "0"; then ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/pwm0@0 ++ fdt set /soc/pwm@1c20e00 pinctrl-0 "<${tmp_phandle}>" ++ env delete tmp_phandle ++fi ++ ++if test "${param_pwm_pins}" = "1"; then ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/pwm1@0 ++ fdt set /soc/pwm@1c20e00 pinctrl-0 "<${tmp_phandle}>" ++ env delete tmp_phandle ++fi ++ ++if test -n "${param_w1_pin}"; then ++ setenv tmp_bank "${param_w1_pin}" ++ setenv tmp_pin "${param_w1_pin}" ++ run decompose_pin ++ fdt set /soc/pinctrl@1c20800/w1_pins pins "${param_w1_pin}" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800 phandle ++ fdt set /onewire@0 gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 0>" ++ env delete tmp_pin tmp_bank tmp_phandle ++fi ++ ++if test "${param_w1_pin_int_pullup}" = "1"; then ++ fdt set /soc/pinctrl@1c20800/w1_pins bias-pull-up ++fi ++ ++if test "${param_uart2_rtscts}" = "1"; then ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/uart2@0 phandle ++ fdt set /soc/serial@1c28800 pinctrl-0 "<${tmp_phandle}>" ++ env delete tmp_phandle ++fi ++ ++if test "${param_uart3_pins}" = "b"; then ++ if test "${param_uart3_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart3_pins_b phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart3_pins_b_rts_cts phandle ++ fdt set /soc/serial@1c28c00 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@1c28c00 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++ else ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/uart3_pins_b phandle ++ fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle}>" ++ env delete tmp_phandle ++ fi ++else ++ if test "${param_uart3_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart3_pins_a phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart3_pins_a_rts_cts phandle ++ fdt set /soc/serial@1c28c00 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@1c28c00 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++ fi ++fi ++ ++if test "${param_uart4_pins}" = "b"; then ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/uart4@1 phandle ++ fdt set /soc/serial@1c29000 pinctrl-0 "<${tmp_phandle}>" ++ env delete tmp_phandle ++fi +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-i2c1.dts b/arch/arm/boot/dts/overlay/sun4i-a10-i2c1.dts +new file mode 100644 +index 0000000..4c104bf +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-i2c1.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a10"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c1 = "/soc@1c00000/i2c@1c2b000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-i2c2.dts b/arch/arm/boot/dts/overlay/sun4i-a10-i2c2.dts +new file mode 100644 +index 0000000..1c2c3e9 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-i2c2.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a10"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c2 = "/soc@1c00000/i2c@1c2b400"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c2>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c2_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-nand.dts b/arch/arm/boot/dts/overlay/sun4i-a10-nand.dts +new file mode 100644 +index 0000000..f0d4c2f +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-nand.dts +@@ -0,0 +1,103 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a10"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ nand_pins_a: nand_pins@0 { ++ pins = "PC0", "PC1", "PC2", ++ "PC5", "PC8", "PC9", "PC10", ++ "PC11", "PC12", "PC13", "PC14", ++ "PC15", "PC16"; ++ function = "nand0"; ++ }; ++ ++ nand_cs0_pins_a: nand_cs@0 { ++ pins = "PC4"; ++ function = "nand0"; ++ }; ++ ++ nand_cs1_pins_a: nand_cs@1 { ++ pins = "PC3"; ++ function = "nand0"; ++ }; ++ ++ nand_cs2_pins_a: nand_cs@2 { ++ pins = "PC17"; ++ function = "nand0"; ++ }; ++ ++ nand_cs3_pins_a: nand_cs@3 { ++ pins = "PC18"; ++ function = "nand0"; ++ }; ++ ++ nand_rb0_pins_a: nand_rb@0 { ++ pins = "PC6"; ++ function = "nand0"; ++ }; ++ ++ nand_rb1_pins_a: nand_rb@1 { ++ pins = "PC7"; ++ function = "nand0"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&nfc>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&nand_pins_a>, <&nand_cs0_pins_a>, <&nand_rb0_pins_a>; ++ status = "okay"; ++ ++ nand@0 { ++ reg = <0>; ++ allwinner,rb = <0>; ++ nand-ecc-mode = "hw"; ++ nand-on-flash-bbt; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ++ partition@0 { ++ label = "SPL"; ++ reg = <0x0 0x0 0x0 0x400000>; ++ }; ++ ++ partition@400000 { ++ label = "SPL.backup"; ++ reg = <0x0 0x400000 0x0 0x400000>; ++ }; ++ ++ partition@800000 { ++ label = "U-Boot"; ++ reg = <0x0 0x800000 0x0 0x400000>; ++ }; ++ ++ partition@c00000 { ++ label = "U-Boot.backup"; ++ reg = <0x0 0xc00000 0x0 0x400000>; ++ }; ++ ++ partition@1000000 { ++ label = "env"; ++ reg = <0x0 0x1000000 0x0 0x400000>; ++ }; ++ ++ partition@1400000 { ++ label = "rootfs"; ++ reg = <0x0 0xa00000 0x01 0xff000000>; ++ }; ++ }; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-pps-gpio.dts b/arch/arm/boot/dts/overlay/sun4i-a10-pps-gpio.dts +new file mode 100644 +index 0000000..6031fc5 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-pps-gpio.dts +@@ -0,0 +1,29 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a10"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ pps_pins: pps_pins { ++ pins = "PI15"; ++ function = "gpio_in"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ pps@0 { ++ compatible = "pps-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pps_pins>; ++ gpios = <&pio 8 15 0>; /* PI15 */ ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-pwm.dts b/arch/arm/boot/dts/overlay/sun4i-a10-pwm.dts +new file mode 100644 +index 0000000..ba88500 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-pwm.dts +@@ -0,0 +1,15 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a10"; ++ ++ fragment@0 { ++ target = <&pwm>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm0_pin>, <&pwm1_pin>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-spdif-out.dts b/arch/arm/boot/dts/overlay/sun4i-a10-spdif-out.dts +new file mode 100644 +index 0000000..234dfc8 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-spdif-out.dts +@@ -0,0 +1,38 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a10"; ++ ++ fragment@0 { ++ target = <&spdif>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spdif_tx_pin>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "On-board SPDIF"; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; ++ }; ++ ++ simple-audio-card,codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ ++ spdif_out: spdif-out { ++ #sound-dai-cells = <0>; ++ compatible = "linux,spdif-dit"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-spi-jedec-nor.dts b/arch/arm/boot/dts/overlay/sun4i-a10-spi-jedec-nor.dts +new file mode 100644 +index 0000000..ee4ff6f +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-spi-jedec-nor.dts +@@ -0,0 +1,57 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a10"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc@1c00000/spi@1c05000"; ++ spi1 = "/soc@1c00000/spi@1c06000"; ++ spi2 = "/soc@1c00000/spi@1c17000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&spi2>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-spi-spidev.dts b/arch/arm/boot/dts/overlay/sun4i-a10-spi-spidev.dts +new file mode 100644 +index 0000000..5667aec +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-spi-spidev.dts +@@ -0,0 +1,57 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a10"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc@1c00000/spi@1c05000"; ++ spi1 = "/soc@1c00000/spi@1c06000"; ++ spi2 = "/soc@1c00000/spi@1c17000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&spi2>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-spi0.dts b/arch/arm/boot/dts/overlay/sun4i-a10-spi0.dts +new file mode 100644 +index 0000000..cad50d8 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-spi0.dts +@@ -0,0 +1,23 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc@1c00000/spi@1c05000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-names = "default", "default"; ++ pinctrl-0 = <&spi0_pi_pins>; ++ pinctrl-1 = <&spi0_cs0_pi_pin>; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-spi1.dts b/arch/arm/boot/dts/overlay/sun4i-a10-spi1.dts +new file mode 100644 +index 0000000..8c606d6 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-spi1.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi1 = "/soc@1c00000/spi@1c06000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi1>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi1_pins>, <&spi1_cs0_pin>; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-spi2.dts b/arch/arm/boot/dts/overlay/sun4i-a10-spi2.dts +new file mode 100644 +index 0000000..145f285 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-spi2.dts +@@ -0,0 +1,23 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi2 = "/soc@1c00000/spi@1c17000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi2>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-names = "default", "default"; ++ pinctrl-0 = <&spi2_pins_a>; ++ pinctrl-1 = <&spi2_cs0_pins_a>; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-uart2.dts b/arch/arm/boot/dts/overlay/sun4i-a10-uart2.dts +new file mode 100644 +index 0000000..89bb44d +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-uart2.dts +@@ -0,0 +1,37 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a10"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial2 = "/soc@1c00000/serial@1c28800"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart2_pins_a: uart2@0 { ++ pins = "PI16", "PI17", "PI18", "PI19"; ++ function = "uart2"; ++ }; ++ ++ uart2_pins_a_2: uart2@1 { ++ pins = "PI18", "PI19"; ++ function = "uart2"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart2>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pins_a_2>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-uart3.dts b/arch/arm/boot/dts/overlay/sun4i-a10-uart3.dts +new file mode 100644 +index 0000000..f599d92 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-uart3.dts +@@ -0,0 +1,47 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a10"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial3 = "/soc@1c00000/serial@1c28c00"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart3_pins_a: uart3@0 { ++ pins = "PG6", "PG7"; ++ function = "uart3"; ++ }; ++ ++ uart3_pins_a_rts_cts: uart3@1 { ++ pins = "PG8", "PG9"; ++ function = "uart3"; ++ }; ++ ++ uart3_pins_b: uart3@2 { ++ pins = "PH0", "PH1"; ++ function = "uart3"; ++ }; ++ ++ uart3_pins_b_rts_cts: uart3@3 { ++ pins = "PH2", "PH3"; ++ function = "uart3"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart3>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart3_pins_a>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-uart4.dts b/arch/arm/boot/dts/overlay/sun4i-a10-uart4.dts +new file mode 100644 +index 0000000..b5e562a +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-uart4.dts +@@ -0,0 +1,37 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a10"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial4 = "/soc@1c00000/serial@1c29000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart4_pins_a: uart4@0 { ++ pins = "PG10", "PG11"; ++ function = "uart4"; ++ }; ++ ++ uart4_pins_b: uart4@1 { ++ pins = "PH4", "PH5"; ++ function = "uart4"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart4>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart4_pins_a>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-uart5.dts b/arch/arm/boot/dts/overlay/sun4i-a10-uart5.dts +new file mode 100644 +index 0000000..12c3f96 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-uart5.dts +@@ -0,0 +1,32 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a10"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial5 = "/soc@1c00000/serial@1c29400"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart5_pins_a: uart5@0 { ++ pins = "PH6", "PH7"; ++ function = "uart5"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart5>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart5_pins_a>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-uart6.dts b/arch/arm/boot/dts/overlay/sun4i-a10-uart6.dts +new file mode 100644 +index 0000000..6be41d5 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-uart6.dts +@@ -0,0 +1,32 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a10"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial6 = "/soc@1c00000/serial@1c29800"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart6_pins_a: uart6@0 { ++ pins = "PI12", "PI13"; ++ function = "uart6"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart6>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart6_pins_a>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-uart7.dts b/arch/arm/boot/dts/overlay/sun4i-a10-uart7.dts +new file mode 100644 +index 0000000..967f6af +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-uart7.dts +@@ -0,0 +1,32 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a10"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial7 = "/soc@1c00000/serial@1c29c00"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart7_pins_a: uart7@0 { ++ pins = "PI20", "PI21"; ++ function = "uart7"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart7>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart7_pins_a>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-w1-gpio.dts b/arch/arm/boot/dts/overlay/sun4i-a10-w1-gpio.dts +new file mode 100644 +index 0000000..41da08c +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun4i-a10-w1-gpio.dts +@@ -0,0 +1,29 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a10"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ w1_pins: w1_pins { ++ pins = "PI15"; ++ function = "gpio_in"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ onewire@0 { ++ compatible = "w1-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&w1_pins>; ++ gpios = <&pio 8 15 0>; /* PI15 */ ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-analog-codec.dts b/arch/arm/boot/dts/overlay/sun5i-a13-analog-codec.dts +new file mode 100644 +index 0000000..60e2717 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun5i-a13-analog-codec.dts +@@ -0,0 +1,13 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun4i-a13"; ++ ++ fragment@0 { ++ target = <&codec>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-fixup.scr-cmd b/arch/arm/boot/dts/overlay/sun5i-a13-fixup.scr-cmd +new file mode 100644 +index 0000000..9589767 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun5i-a13-fixup.scr-cmd +@@ -0,0 +1,48 @@ ++# overlays fixup script ++# implements (or rather substitutes) overlay arguments functionality ++# using u-boot scripting, environment variables and "fdt" command ++ ++if test -n "${param_spinor_spi_bus}"; then ++ test "${param_spinor_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c05000" ++ test "${param_spinor_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c06000" ++ test "${param_spinor_spi_bus}" = "2" && setenv tmp_spi_path "spi@1c17000" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spiflash status "okay" ++ if test -n "${param_spinor_max_freq}"; then ++ fdt set /soc/${tmp_spi_path}/spiflash spi-max-frequency "<${param_spinor_max_freq}>" ++ fi ++ env delete tmp_spi_path ++fi ++ ++if test -n "${param_spidev_spi_bus}"; then ++ test "${param_spidev_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c05000" ++ test "${param_spidev_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c06000" ++ test "${param_spidev_spi_bus}" = "2" && setenv tmp_spi_path "spi@1c17000" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spidev status "okay" ++ if test -n "${param_spidev_max_freq}"; then ++ fdt set /soc/${tmp_spi_path}/spidev spi-max-frequency "<${param_spidev_max_freq}>" ++ fi ++ env delete tmp_spi_path ++fi ++ ++if test "${param_uart1_pins}" = "b"; then ++ fdt get value tmp_phandle /soc/pinctrl@1c28400/uart1@1 phandle ++ fdt set /soc/serial@1c28400 pinctrl-0 "<${tmp_phandle}>" ++ env delete tmp_phandle ++fi ++ ++if test "${param_uart2_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart2@0 phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart2-cts-rts@0 phandle ++ fdt set /soc/serial@1c28800 pinctrl-0 "<${tmp_phandle1}>, <${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++fi ++ ++if test "${param_uart3_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart3@0 phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart3-cts-rts@0 phandle ++ fdt set /soc/serial@1c28c00 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>, <${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++fi +diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-i2c1.dts b/arch/arm/boot/dts/overlay/sun5i-a13-i2c1.dts +new file mode 100644 +index 0000000..444c32c +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun5i-a13-i2c1.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun5i-a13"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c1 = "/soc@1c00000/i2c@1c2b000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-i2c2.dts b/arch/arm/boot/dts/overlay/sun5i-a13-i2c2.dts +new file mode 100644 +index 0000000..7a30681 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun5i-a13-i2c2.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun5i-a13"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c2 = "/soc@1c00000/i2c@1c2b400"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c2>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c2_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-nand.dts b/arch/arm/boot/dts/overlay/sun5i-a13-nand.dts +new file mode 100644 +index 0000000..0c5fc89 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun5i-a13-nand.dts +@@ -0,0 +1,60 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun5i-a13"; ++ ++ fragment@0 { ++ target = <&nfc>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&nand_pins>, <&nand_cs0_pin>, <&nand_rb0_pin>; ++ status = "okay"; ++ ++ nand@0 { ++ reg = <0>; ++ allwinner,rb = <0>; ++ nand-ecc-mode = "hw"; ++ nand-on-flash-bbt; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ++ partition@0 { ++ label = "SPL"; ++ reg = <0x0 0x0 0x0 0x400000>; ++ }; ++ ++ partition@400000 { ++ label = "SPL.backup"; ++ reg = <0x0 0x400000 0x0 0x400000>; ++ }; ++ ++ partition@800000 { ++ label = "U-Boot"; ++ reg = <0x0 0x800000 0x0 0x400000>; ++ }; ++ ++ partition@c00000 { ++ label = "U-Boot.backup"; ++ reg = <0x0 0xc00000 0x0 0x400000>; ++ }; ++ ++ partition@1000000 { ++ label = "env"; ++ reg = <0x0 0x1000000 0x0 0x400000>; ++ }; ++ ++ partition@1400000 { ++ label = "rootfs"; ++ reg = <0x0 0xa00000 0x01 0xff000000>; ++ }; ++ }; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-pwm.dts b/arch/arm/boot/dts/overlay/sun5i-a13-pwm.dts +new file mode 100644 +index 0000000..54f5d51 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun5i-a13-pwm.dts +@@ -0,0 +1,15 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun5i-a13"; ++ ++ fragment@0 { ++ target = <&pwm>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm0_pin>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-spi-jedec-nor.dts b/arch/arm/boot/dts/overlay/sun5i-a13-spi-jedec-nor.dts +new file mode 100644 +index 0000000..8cebb0b +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun5i-a13-spi-jedec-nor.dts +@@ -0,0 +1,57 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun5i-a13"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc/spi@1c05000"; ++ spi1 = "/soc/spi@1c06000"; ++ spi2 = "/soc/spi@1c17000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&spi2>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-spi-spidev.dts b/arch/arm/boot/dts/overlay/sun5i-a13-spi-spidev.dts +new file mode 100644 +index 0000000..ced1a0e +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun5i-a13-spi-spidev.dts +@@ -0,0 +1,57 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun5i-a10"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc/spi@1c05000"; ++ spi1 = "/soc/spi@1c06000"; ++ spi2 = "/soc/spi@1c17000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&spi2>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-spi0.dts b/arch/arm/boot/dts/overlay/sun5i-a13-spi0.dts +new file mode 100644 +index 0000000..b23a754 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun5i-a13-spi0.dts +@@ -0,0 +1,38 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun5i-a13"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc/spi@1c05000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ spi0_pins_a: spi0@0 { ++ pins = "PC0", "PC1", "PC2"; ++ function = "spi0"; ++ }; ++ ++ spi0_cs0_pins_a: spi0-cs0@0 { ++ pins = "PC3"; ++ function = "spi0"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-names = "default", "default"; ++ pinctrl-0 = <&spi0_pins_a>; ++ pinctrl-1 = <&spi0_cs0_pins_a>; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-spi1.dts b/arch/arm/boot/dts/overlay/sun5i-a13-spi1.dts +new file mode 100644 +index 0000000..cc0af5d +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun5i-a13-spi1.dts +@@ -0,0 +1,39 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun5i-a13"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi1 = "/soc/spi@1c06000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ spi1_pins_a: spi1@0 { ++ pins = "PG10", "PG11", "PG12"; ++ function = "spi1"; ++ }; ++ ++ spi1_cs0_pins_a: spi1-cs0@0 { ++ pins = "PG9"; ++ function = "spi1"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi1_pins_a>, <&spi1_cs0_pins_a>; ++ }; ++ }; ++ ++ ++}; +diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-spi2.dts b/arch/arm/boot/dts/overlay/sun5i-a13-spi2.dts +new file mode 100644 +index 0000000..6cf5c41 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun5i-a13-spi2.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun5i-a13"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi2 = "/soc/spi@1c17000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi2>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi2_pe_pins>, <&spi2_cs0_pe_pin>; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-uart0.dts b/arch/arm/boot/dts/overlay/sun5i-a13-uart0.dts +new file mode 100644 +index 0000000..6edad42 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun5i-a13-uart0.dts +@@ -0,0 +1,32 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun5i-a13"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ uart0 = "/soc@1c00000/serial@1c28000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart0_pa_pins: uart0@0 { ++ pins = "PF2", "PF4"; ++ function = "uart0"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart0>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pa_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-uart1.dts b/arch/arm/boot/dts/overlay/sun5i-a13-uart1.dts +new file mode 100644 +index 0000000..675b701 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun5i-a13-uart1.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun5i-a13"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ uart1 = "/soc@1c00000/serial@1c28400"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pe_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-uart2.dts b/arch/arm/boot/dts/overlay/sun5i-a13-uart2.dts +new file mode 100644 +index 0000000..b3c4e3d +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun5i-a13-uart2.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun5i-a13"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ uart2 = "/soc@1c00000/serial@1c28800"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart2>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pd_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-uart3.dts b/arch/arm/boot/dts/overlay/sun5i-a13-uart3.dts +new file mode 100644 +index 0000000..15c25d0 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun5i-a13-uart3.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun5i-a13"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ uart3 = "/soc@1c00000/serial@1c28c00"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart3>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart3_pg_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-analog-codec.dts b/arch/arm/boot/dts/overlay/sun7i-a20-analog-codec.dts +new file mode 100644 +index 0000000..e1a70c5 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-analog-codec.dts +@@ -0,0 +1,13 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target = <&codec>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-can.dts b/arch/arm/boot/dts/overlay/sun7i-a20-can.dts +new file mode 100644 +index 0000000..65aebcd +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-can.dts +@@ -0,0 +1,15 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target = <&can0>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&can0_pins_a>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-fixup.scr-cmd b/arch/arm/boot/dts/overlay/sun7i-a20-fixup.scr-cmd +new file mode 100644 +index 0000000..db3cec8 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-fixup.scr-cmd +@@ -0,0 +1,143 @@ ++# overlays fixup script ++# implements (or rather substitutes) overlay arguments functionality ++# using u-boot scripting, environment variables and "fdt" command ++ ++# setexpr test_var ${tmp_bank} - A ++# works only for hex numbers (A-F) ++ ++setenv decompose_pin 'setexpr tmp_bank sub "P(B|C|D|E|G|H|I)\\d+" "\\1"; ++setexpr tmp_pin sub "P\\S(\\d+)" "\\1"; ++test "${tmp_bank}" = "B" && setenv tmp_bank 1; ++test "${tmp_bank}" = "C" && setenv tmp_bank 2; ++test "${tmp_bank}" = "D" && setenv tmp_bank 3; ++test "${tmp_bank}" = "E" && setenv tmp_bank 4; ++test "${tmp_bank}" = "G" && setenv tmp_bank 6; ++test "${tmp_bank}" = "H" && setenv tmp_bank 7; ++test "${tmp_bank}" = "I" && setenv tmp_bank 8' ++ ++if test -n "${param_spinor_spi_bus}"; then ++ test "${param_spinor_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c05000" ++ test "${param_spinor_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c06000" ++ test "${param_spinor_spi_bus}" = "2" && setenv tmp_spi_path "spi@1c17000" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spiflash status "okay" ++ if test -n "${param_spinor_max_freq}"; then ++ fdt set /soc/${tmp_spi_path}/spiflash spi-max-frequency "<${param_spinor_max_freq}>" ++ fi ++ if test "${param_spinor_spi_bus}" = "0" && test "${param_spinor_spi_cs}" = "1"; then ++ fdt set /soc/${tmp_spi_path}/spiflash reg "<1>" ++ fi ++ env delete tmp_spi_path ++fi ++ ++if test -n "${param_spidev_spi_bus}"; then ++ test "${param_spidev_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c05000" ++ test "${param_spidev_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c06000" ++ test "${param_spidev_spi_bus}" = "2" && setenv tmp_spi_path "spi@1c17000" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spidev status "okay" ++ if test -n "${param_spidev_max_freq}"; then ++ fdt set /soc/${tmp_spi_path}/spidev spi-max-frequency "<${param_spidev_max_freq}>" ++ fi ++ if test "${param_spidev_spi_bus}" = "0" && test "${param_spidev_spi_cs}" = "1"; then ++ fdt set /soc/${tmp_spi_path}/spidev reg "<1>" ++ fi ++ env delete tmp_spi_path ++fi ++ ++if test "${param_spi2_bus_pins}" = "b"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/spi2@1 phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/spi2_cs0@1 phandle ++ fdt set /soc/spi@1c17000 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/spi@1c17000 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++fi ++ ++if test -n "${param_pps_pin}"; then ++ setenv tmp_bank "${param_pps_pin}" ++ setenv tmp_pin "${param_pps_pin}" ++ run decompose_pin ++ fdt set /soc/pinctrl@1c20800/pps_pins pins "${param_pps_pin}" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800 phandle ++ fdt set /pps@0 gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 0>" ++ env delete tmp_pin tmp_bank tmp_phandle ++fi ++ ++if test "${param_pps_falling_edge}" = "1"; then ++ fdt set /pps@0 assert-falling-edge ++fi ++ ++if test "${param_pwm_pins}" = "0"; then ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/pwm0@0 ++ fdt set /soc/pwm@1c20e00 pinctrl-0 "<${tmp_phandle}>" ++ env delete tmp_phandle ++fi ++ ++if test "${param_pwm_pins}" = "1"; then ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/pwm1@0 ++ fdt set /soc/pwm@1c20e00 pinctrl-0 "<${tmp_phandle}>" ++ env delete tmp_phandle ++fi ++ ++if test -n "${param_w1_pin}"; then ++ setenv tmp_bank "${param_w1_pin}" ++ setenv tmp_pin "${param_w1_pin}" ++ run decompose_pin ++ fdt set /soc/pinctrl@1c20800/w1_pins pins "${param_w1_pin}" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800 phandle ++ fdt set /onewire@0 gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 0>" ++ env delete tmp_pin tmp_bank tmp_phandle ++fi ++ ++if test -n "${param_mmc2_cd_pin}"; then ++ setenv tmp_bank "${param_mmc2_cd_pin}" ++ setenv tmp_pin "${param_mmc2_cd_pin}" ++ run decompose_pin ++ fdt get value tmp_phandle /soc/pinctrl@1c20800 phandle ++ fdt set /soc/mmc@1c11000 cd-gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 1>" ++fi ++ ++if test "${param_mmc2_non_removable}" = "1"; then ++ fdt rm /soc/mmc@1c11000 cd-gpios ++ fdt set /soc/mmc@1c11000 non-removable ++fi ++ ++if test "${param_w1_pin_int_pullup}" = "1"; then ++ fdt set /soc/pinctrl@1c20800/w1_pins bias-pull-up ++fi ++ ++if test "${param_uart2_rtscts}" = "1"; then ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/uart2-pi-pins phandle ++ fdt set /soc/serial@1c28800 pinctrl-0 "<${tmp_phandle}>" ++ env delete tmp_phandle ++fi ++ ++if test "${param_uart3_pins}" = "b"; then ++ if test "${param_uart3_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart3-ph-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart3-cts-rts-ph-pins phandle ++ fdt set /soc/serial@1c28c00 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@1c28c00 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++ else ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/uart3-ph-pins phandle ++ fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle}>" ++ env delete tmp_phandle ++ fi ++else ++ if test "${param_uart3_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart3-pg-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart3-cts-rts-pg-pins phandle ++ fdt set /soc/serial@1c28c00 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@1c28c00 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++ fi ++fi ++ ++if test "${param_uart4_pins}" = "b"; then ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/uart4-pg-pins phandle ++ fdt set /soc/serial@1c29000 pinctrl-0 "<${tmp_phandle}>" ++ env delete tmp_phandle ++fi +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-i2c1.dts b/arch/arm/boot/dts/overlay/sun7i-a20-i2c1.dts +new file mode 100644 +index 0000000..c5f6e97 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-i2c1.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c1 = "/soc@1c00000/i2c@1c2b000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-i2c2.dts b/arch/arm/boot/dts/overlay/sun7i-a20-i2c2.dts +new file mode 100644 +index 0000000..fa93d1e +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-i2c2.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c2 = "/soc@1c00000/i2c@1c2b400"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c2>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c2_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-i2c3.dts b/arch/arm/boot/dts/overlay/sun7i-a20-i2c3.dts +new file mode 100644 +index 0000000..945795c +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-i2c3.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c3 = "/soc@1c00000/i2c@1c2b800"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c3>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c3_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-i2c4.dts b/arch/arm/boot/dts/overlay/sun7i-a20-i2c4.dts +new file mode 100644 +index 0000000..4fcf08c +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-i2c4.dts +@@ -0,0 +1,32 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c4 = "/soc@1c00000/i2c@1c2c000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ i2c4_pins_a: i2c4@0 { ++ pins = "PI2", "PI3"; ++ function = "i2c4"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c4>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c4_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-i2s0.dts b/arch/arm/boot/dts/overlay/sun7i-a20-i2s0.dts +new file mode 100644 +index 0000000..1a19a24 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-i2s0.dts +@@ -0,0 +1,25 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ i2s0_pins: i2s0 { ++ pins = "PB5", "PB6", "PB7", "PB8", "PB9", "PB10", "PB11", "PB12"; ++ function = "i2s0"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s0>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s0_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-i2s1.dts b/arch/arm/boot/dts/overlay/sun7i-a20-i2s1.dts +new file mode 100644 +index 0000000..e6f0a22 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-i2s1.dts +@@ -0,0 +1,25 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ i2s1_pins: i2s1 { ++ pins = "PA9", "PA14", "PA15", "PA16", "PA17"; ++ function = "i2s1"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s1_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-mmc2.dts b/arch/arm/boot/dts/overlay/sun7i-a20-mmc2.dts +new file mode 100644 +index 0000000..ede92f2 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-mmc2.dts +@@ -0,0 +1,18 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target = <&mmc2>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc2_pins>; ++ vmmc-supply = <®_vcc3v3>; ++ bus-width = <4>; ++ cd-gpios = <&pio 7 0 1>; /* PH0, active low */ ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-nand.dts b/arch/arm/boot/dts/overlay/sun7i-a20-nand.dts +new file mode 100644 +index 0000000..ffa49cc +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-nand.dts +@@ -0,0 +1,103 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ nand_pins_a: nand_pins@0 { ++ pins = "PC0", "PC1", "PC2", ++ "PC5", "PC8", "PC9", "PC10", ++ "PC11", "PC12", "PC13", "PC14", ++ "PC15", "PC16"; ++ function = "nand0"; ++ }; ++ ++ nand_cs0_pins_a: nand_cs@0 { ++ pins = "PC4"; ++ function = "nand0"; ++ }; ++ ++ nand_cs1_pins_a: nand_cs@1 { ++ pins = "PC3"; ++ function = "nand0"; ++ }; ++ ++ nand_cs2_pins_a: nand_cs@2 { ++ pins = "PC17"; ++ function = "nand0"; ++ }; ++ ++ nand_cs3_pins_a: nand_cs@3 { ++ pins = "PC18"; ++ function = "nand0"; ++ }; ++ ++ nand_rb0_pins_a: nand_rb@0 { ++ pins = "PC6"; ++ function = "nand0"; ++ }; ++ ++ nand_rb1_pins_a: nand_rb@1 { ++ pins = "PC7"; ++ function = "nand0"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&nfc>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&nand_pins_a>, <&nand_cs0_pins_a>, <&nand_rb0_pins_a>; ++ status = "okay"; ++ ++ nand@0 { ++ reg = <0>; ++ allwinner,rb = <0>; ++ nand-ecc-mode = "hw"; ++ nand-on-flash-bbt; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ++ partition@0 { ++ label = "SPL"; ++ reg = <0x0 0x0 0x0 0x400000>; ++ }; ++ ++ partition@400000 { ++ label = "SPL.backup"; ++ reg = <0x0 0x400000 0x0 0x400000>; ++ }; ++ ++ partition@800000 { ++ label = "U-Boot"; ++ reg = <0x0 0x800000 0x0 0x400000>; ++ }; ++ ++ partition@c00000 { ++ label = "U-Boot.backup"; ++ reg = <0x0 0xc00000 0x0 0x400000>; ++ }; ++ ++ partition@1000000 { ++ label = "env"; ++ reg = <0x0 0x1000000 0x0 0x400000>; ++ }; ++ ++ partition@1400000 { ++ label = "rootfs"; ++ reg = <0x0 0xa00000 0x01 0xff000000>; ++ }; ++ }; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-pps-gpio.dts b/arch/arm/boot/dts/overlay/sun7i-a20-pps-gpio.dts +new file mode 100644 +index 0000000..fe3e2bd +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-pps-gpio.dts +@@ -0,0 +1,29 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ pps_pins: pps_pins { ++ pins = "PI15"; ++ function = "gpio_in"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ pps@0 { ++ compatible = "pps-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pps_pins>; ++ gpios = <&pio 8 15 0>; /* PI15 */ ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-pwm.dts b/arch/arm/boot/dts/overlay/sun7i-a20-pwm.dts +new file mode 100644 +index 0000000..b0cfe4d +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-pwm.dts +@@ -0,0 +1,15 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target = <&pwm>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm0_pin>, <&pwm1_pin>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-spdif-out.dts b/arch/arm/boot/dts/overlay/sun7i-a20-spdif-out.dts +new file mode 100644 +index 0000000..11a0939 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-spdif-out.dts +@@ -0,0 +1,38 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target = <&spdif>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spdif_tx_pin>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "On-board SPDIF"; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; ++ }; ++ ++ simple-audio-card,codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ ++ spdif_out: spdif-out { ++ #sound-dai-cells = <0>; ++ compatible = "linux,spdif-dit"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-spi-add-cs1.dts b/arch/arm/boot/dts/overlay/sun7i-a20-spi-add-cs1.dts +new file mode 100644 +index 0000000..c0a4ba2 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-spi-add-cs1.dts +@@ -0,0 +1,16 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ pinctrl-names = "default", "default", "default"; ++ pinctrl-0 = <&spi0_pi_pins>; ++ pinctrl-1 = <&spi0_cs0_pi_pin>; ++ pinctrl-2 = <&spi0_cs1_pi_pin>; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-spi-jedec-nor.dts b/arch/arm/boot/dts/overlay/sun7i-a20-spi-jedec-nor.dts +new file mode 100644 +index 0000000..b91097e +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-spi-jedec-nor.dts +@@ -0,0 +1,57 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc@1c00000/spi@1c05000"; ++ spi1 = "/soc@1c00000/spi@1c06000"; ++ spi2 = "/soc@1c00000/spi@1c17000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&spi2>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-spi-spidev.dts b/arch/arm/boot/dts/overlay/sun7i-a20-spi-spidev.dts +new file mode 100644 +index 0000000..a3073b2 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-spi-spidev.dts +@@ -0,0 +1,57 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc@1c00000/spi@1c05000"; ++ spi1 = "/soc@1c00000/spi@1c06000"; ++ spi2 = "/soc@1c00000/spi@1c17000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&spi2>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-spi0.dts b/arch/arm/boot/dts/overlay/sun7i-a20-spi0.dts +new file mode 100644 +index 0000000..cad50d8 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-spi0.dts +@@ -0,0 +1,23 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc@1c00000/spi@1c05000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-names = "default", "default"; ++ pinctrl-0 = <&spi0_pi_pins>; ++ pinctrl-1 = <&spi0_cs0_pi_pin>; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-spi1.dts b/arch/arm/boot/dts/overlay/sun7i-a20-spi1.dts +new file mode 100644 +index 0000000..f0218eb +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-spi1.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi1 = "/soc@1c00000/spi@1c06000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi1>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi1_pi_pins>, <&spi1_cs0_pi_pin>; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-spi2.dts b/arch/arm/boot/dts/overlay/sun7i-a20-spi2.dts +new file mode 100644 +index 0000000..effba42 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-spi2.dts +@@ -0,0 +1,23 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi2 = "/soc@1c00000/spi@1c17000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi2>; ++ __overlay__ { ++ status = "okay"; ++ pinctrl-names = "default", "default"; ++ pinctrl-0 = <&spi2_pb_pins>; ++ pinctrl-1 = <&spi2_pb_cs0_pin>; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-uart2.dts b/arch/arm/boot/dts/overlay/sun7i-a20-uart2.dts +new file mode 100644 +index 0000000..79d1dca +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-uart2.dts +@@ -0,0 +1,32 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial2 = "/soc@1c00000/serial@1c28800"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart2_pins_a_2: uart2@1 { ++ pins = "PI18", "PI19"; ++ function = "uart2"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart2>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pins_a_2>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-uart3.dts b/arch/arm/boot/dts/overlay/sun7i-a20-uart3.dts +new file mode 100644 +index 0000000..703acbc +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-uart3.dts +@@ -0,0 +1,42 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial3 = "/soc@1c00000/serial@1c28c00"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart3_pins_a_2: uart3@2 { ++ pins = "PG6", "PG7"; ++ function = "uart3"; ++ }; ++ ++ uart3_pins_a_rts_cts: uart3@1 { ++ pins = "PG8", "PG9"; ++ function = "uart3"; ++ }; ++ ++ uart3_pins_b_rts_cts: uart3@3 { ++ pins = "PH2", "PH3"; ++ function = "uart3"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart3>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart3_pins_a_2>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-uart4.dts b/arch/arm/boot/dts/overlay/sun7i-a20-uart4.dts +new file mode 100644 +index 0000000..1918034 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-uart4.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial4 = "/soc@1c00000/serial@1c29000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart4>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart4_pg_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-uart5.dts b/arch/arm/boot/dts/overlay/sun7i-a20-uart5.dts +new file mode 100644 +index 0000000..a1369ee +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-uart5.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial5 = "/soc@1c00000/serial@1c29400"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart5>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart5_pi_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-uart6.dts b/arch/arm/boot/dts/overlay/sun7i-a20-uart6.dts +new file mode 100644 +index 0000000..fb9efe2 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-uart6.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial6 = "/soc@1c00000/serial@1c29800"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart6>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart6_pi_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-uart7.dts b/arch/arm/boot/dts/overlay/sun7i-a20-uart7.dts +new file mode 100644 +index 0000000..bbdca3e +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-uart7.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial7 = "/soc@1c00000/serial@1c29c00"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart7>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart7_pi_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-w1-gpio.dts b/arch/arm/boot/dts/overlay/sun7i-a20-w1-gpio.dts +new file mode 100644 +index 0000000..7d77606 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun7i-a20-w1-gpio.dts +@@ -0,0 +1,29 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun7i-a20"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ w1_pins: w1_pins { ++ pins = "PI15"; ++ function = "gpio_in"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ onewire@0 { ++ compatible = "w1-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&w1_pins>; ++ gpios = <&pio 8 15 0>; /* PI15 */ ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-analog-codec.dts b/arch/arm/boot/dts/overlay/sun8i-h3-analog-codec.dts +new file mode 100644 +index 0000000..36dbc31 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-analog-codec.dts +@@ -0,0 +1,17 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target = <&codec>; ++ __overlay__ { ++ allwinner,audio-routing = ++ "Line Out", "LINEOUT", ++ "MIC1", "Mic", ++ "Mic", "MBIAS"; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-cir.dts b/arch/arm/boot/dts/overlay/sun8i-h3-cir.dts +new file mode 100644 +index 0000000..bf4a0ea +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-cir.dts +@@ -0,0 +1,15 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target = <&ir>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&r_ir_rx_pin>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-fixup.scr-cmd b/arch/arm/boot/dts/overlay/sun8i-h3-fixup.scr-cmd +new file mode 100644 +index 0000000..142b7e5 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-fixup.scr-cmd +@@ -0,0 +1,110 @@ ++# overlays fixup script ++# implements (or rather substitutes) overlay arguments functionality ++# using u-boot scripting, environment variables and "fdt" command ++ ++# setexpr test_var ${tmp_bank} - A ++# works only for hex numbers (A-F) ++ ++setenv decompose_pin 'setexpr tmp_bank sub "P(A|C|D|G)\\d+" "\\1"; ++setexpr tmp_pin sub "P\\S(\\d+)" "\\1"; ++test "${tmp_bank}" = "A" && setenv tmp_bank 0; ++test "${tmp_bank}" = "C" && setenv tmp_bank 2; ++test "${tmp_bank}" = "D" && setenv tmp_bank 3; ++test "${tmp_bank}" = "G" && setenv tmp_bank 6' ++ ++if test -n "${param_spinor_spi_bus}"; then ++ test "${param_spinor_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c68000" ++ test "${param_spinor_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c69000" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spiflash status "okay" ++ if test -n "${param_spinor_max_freq}"; then ++ fdt set /soc/${tmp_spi_path}/spiflash spi-max-frequency "<${param_spinor_max_freq}>" ++ fi ++ if test "${param_spinor_spi_cs}" = "1"; then ++ fdt set /soc/${tmp_spi_path}/spiflash reg "<1>" ++ fi ++ env delete tmp_spi_path ++fi ++ ++if test -n "${param_spidev_spi_bus}"; then ++ test "${param_spidev_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c68000" ++ test "${param_spidev_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c69000" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spidev status "okay" ++ if test -n "${param_spidev_max_freq}"; then ++ fdt set /soc/${tmp_spi_path}/spidev spi-max-frequency "<${param_spidev_max_freq}>" ++ fi ++ if test "${param_spidev_spi_cs}" = "1"; then ++ fdt set /soc/${tmp_spi_path}/spidev reg "<1>" ++ fi ++ env delete tmp_spi_path ++fi ++ ++if test -n "${param_pps_pin}"; then ++ setenv tmp_bank "${param_pps_pin}" ++ setenv tmp_pin "${param_pps_pin}" ++ run decompose_pin ++ fdt set /soc/pinctrl@1c20800/pps_pins pins "${param_pps_pin}" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800 phandle ++ fdt set /pps@0 gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 0>" ++ env delete tmp_pin tmp_bank tmp_phandle ++fi ++ ++if test "${param_pps_falling_edge}" = "1"; then ++ fdt set /pps@0 assert-falling-edge ++fi ++ ++for f in ${overlays}; do ++ if test "${f}" = "pwm"; then ++ setenv bootargs_new "" ++ for arg in ${bootargs}; do ++ if test "${arg}" = "console=ttyS0,115200"; then ++ echo "Warning: Disabling ttyS0 console due to enabled PWM overlay" ++ else ++ setenv bootargs_new "${bootargs_new} ${arg}" ++ fi ++ done ++ setenv bootargs "${bootargs_new}" ++ fi ++done ++ ++if test -n "${param_w1_pin}"; then ++ setenv tmp_bank "${param_w1_pin}" ++ setenv tmp_pin "${param_w1_pin}" ++ run decompose_pin ++ fdt set /soc/pinctrl@1c20800/w1_pins pins "${param_w1_pin}" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800 phandle ++ fdt set /onewire@0 gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 0>" ++ env delete tmp_pin tmp_bank tmp_phandle ++fi ++ ++if test "${param_w1_pin_int_pullup}" = "1"; then ++ fdt set /soc/pinctrl@1c20800/w1_pins bias-pull-up ++fi ++ ++if test "${param_uart1_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart1-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart1-rts-cts-pins phandle ++ fdt set /soc/serial@1c28400 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28400 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@1c28400 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++fi ++ ++if test "${param_uart2_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart2-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart2-rts-cts-pins phandle ++ fdt set /soc/serial@1c28800 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28800 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@1c28800 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++fi ++ ++if test "${param_uart3_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart3-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart3-rts-cts-pins phandle ++ fdt set /soc/serial@1c28c00 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@1c28c00 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++fi +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-i2c0.dts b/arch/arm/boot/dts/overlay/sun8i-h3-i2c0.dts +new file mode 100644 +index 0000000..a36ac86 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-i2c0.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c0 = "/soc/i2c@1c2ac00"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c0>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-i2c1.dts b/arch/arm/boot/dts/overlay/sun8i-h3-i2c1.dts +new file mode 100644 +index 0000000..258c86d +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-i2c1.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c1 = "/soc/i2c@1c2b000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c1>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-i2c2.dts b/arch/arm/boot/dts/overlay/sun8i-h3-i2c2.dts +new file mode 100644 +index 0000000..a1e3284 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-i2c2.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c2 = "/soc/i2c@1c2b400"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c2>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-pps-gpio.dts b/arch/arm/boot/dts/overlay/sun8i-h3-pps-gpio.dts +new file mode 100644 +index 0000000..16a737b +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-pps-gpio.dts +@@ -0,0 +1,29 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ pps_pins: pps_pins { ++ pins = "PD14"; ++ function = "gpio_in"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ pps@0 { ++ compatible = "pps-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pps_pins>; ++ gpios = <&pio 3 14 0>; /* PD14 */ ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-pwm.dts b/arch/arm/boot/dts/overlay/sun8i-h3-pwm.dts +new file mode 100644 +index 0000000..ed3b8e6 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-pwm.dts +@@ -0,0 +1,39 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target-path = "/chosen"; ++ __overlay__ { ++ /delete-property/ stdout-path; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&pio>; ++ __overlay__ { ++ pwm0_pin: pwm0 { ++ pins = "PA5"; ++ function = "pwm0"; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&pwm>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm0_pin>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-spdif-out.dts b/arch/arm/boot/dts/overlay/sun8i-h3-spdif-out.dts +new file mode 100644 +index 0000000..35b2d56 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-spdif-out.dts +@@ -0,0 +1,38 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target = <&spdif>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spdif_tx_pin>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "On-board SPDIF"; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; ++ }; ++ ++ simple-audio-card,codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ ++ spdif_out: spdif-out { ++ #sound-dai-cells = <0>; ++ compatible = "linux,spdif-dit"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-spi-add-cs1.dts b/arch/arm/boot/dts/overlay/sun8i-h3-spi-add-cs1.dts +new file mode 100644 +index 0000000..bd8e256 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-spi-add-cs1.dts +@@ -0,0 +1,41 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ spi0_cs1: spi0_cs1 { ++ pins = "PA21"; ++ function = "gpio_out"; ++ output-high; ++ }; ++ ++ spi1_cs1: spi1_cs1 { ++ pins = "PA10"; ++ function = "gpio_out"; ++ output-high; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ pinctrl-names = "default", "default"; ++ pinctrl-1 = <&spi0_cs1>; ++ cs-gpios = <0>, <&pio 0 21 0>; /* PA21 */ ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ pinctrl-names = "default", "default"; ++ pinctrl-1 = <&spi1_cs1>; ++ cs-gpios = <0>, <&pio 0 10 0>; /* PA10 */ ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-spi-jedec-nor.dts b/arch/arm/boot/dts/overlay/sun8i-h3-spi-jedec-nor.dts +new file mode 100644 +index 0000000..95fa5f2 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-spi-jedec-nor.dts +@@ -0,0 +1,42 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc/spi@1c68000"; ++ spi1 = "/soc/spi@1c69000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-spi-spidev.dts b/arch/arm/boot/dts/overlay/sun8i-h3-spi-spidev.dts +new file mode 100644 +index 0000000..575c970 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-spi-spidev.dts +@@ -0,0 +1,42 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc/spi@1c68000"; ++ spi1 = "/soc/spi@1c69000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-uart1.dts b/arch/arm/boot/dts/overlay/sun8i-h3-uart1.dts +new file mode 100644 +index 0000000..3c10d4d +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-uart1.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial1 = "/soc/serial@1c28400"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-uart2.dts b/arch/arm/boot/dts/overlay/sun8i-h3-uart2.dts +new file mode 100644 +index 0000000..f16e618 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-uart2.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial2 = "/soc/serial@1c28800"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart2>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-uart3.dts b/arch/arm/boot/dts/overlay/sun8i-h3-uart3.dts +new file mode 100644 +index 0000000..b1aef57 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-uart3.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial3 = "/soc/serial@1c28c00"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart3>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart3_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-usbhost0.dts b/arch/arm/boot/dts/overlay/sun8i-h3-usbhost0.dts +new file mode 100644 +index 0000000..6bd8aed +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-usbhost0.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target = <&ehci0>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&ohci0>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&usbphy>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-usbhost1.dts b/arch/arm/boot/dts/overlay/sun8i-h3-usbhost1.dts +new file mode 100644 +index 0000000..4c7222b +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-usbhost1.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target = <&ehci1>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&ohci1>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&usbphy>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-usbhost2.dts b/arch/arm/boot/dts/overlay/sun8i-h3-usbhost2.dts +new file mode 100644 +index 0000000..2b83ec9 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-usbhost2.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target = <&ehci2>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&ohci2>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&usbphy>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-usbhost3.dts b/arch/arm/boot/dts/overlay/sun8i-h3-usbhost3.dts +new file mode 100644 +index 0000000..e2f28ab +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-usbhost3.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target = <&ehci3>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&ohci3>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&usbphy>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-w1-gpio.dts b/arch/arm/boot/dts/overlay/sun8i-h3-w1-gpio.dts +new file mode 100644 +index 0000000..f4ccb7f +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-h3-w1-gpio.dts +@@ -0,0 +1,29 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ w1_pins: w1_pins { ++ pins = "PD14"; ++ function = "gpio_in"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ onewire@0 { ++ compatible = "w1-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&w1_pins>; ++ gpios = <&pio 3 14 0>; /* PD14 */ ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-i2c2.dts b/arch/arm/boot/dts/overlay/sun8i-r40-i2c2.dts +new file mode 100644 +index 0000000..a1e3284 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-r40-i2c2.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c2 = "/soc/i2c@1c2b400"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c2>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-i2c3.dts b/arch/arm/boot/dts/overlay/sun8i-r40-i2c3.dts +new file mode 100644 +index 0000000..a1e3284 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-r40-i2c3.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c3 = "/soc/i2c@1c2b800"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c3>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev0.dts b/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev0.dts +new file mode 100644 +index 0000000..734a9a8 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev0.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/ { ++ compatible = "allwinner,sun8i-r40"; ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc/spi@1c05000"; ++ }; ++ }; ++ fragment@1 { ++ target = <0xffffffff>; ++ __overlay__ { ++ #address-cells = <0x00000001>; ++ #size-cells = <0x00000000>; ++ status = "okay"; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "okay"; ++ reg = <0x00000000>; ++ spi-max-frequency = <0x000f4240>; ++ }; ++ }; ++ }; ++ __fixups__ { ++ spi0 = "/fragment@1:target:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev1.dts b/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev1.dts +new file mode 100644 +index 0000000..d1d637c +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev1.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/ { ++ compatible = "allwinner,sun8i-r40"; ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi1 = "/soc/spi@1c06000"; ++ }; ++ }; ++ fragment@1 { ++ target = <0xffffffff>; ++ __overlay__ { ++ #address-cells = <0x00000001>; ++ #size-cells = <0x00000000>; ++ status = "okay"; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "okay"; ++ reg = <0x00000000>; ++ spi-max-frequency = <0x000f4240>; ++ }; ++ }; ++ }; ++ __fixups__ { ++ spi1 = "/fragment@1:target:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-uart2.dts b/arch/arm/boot/dts/overlay/sun8i-r40-uart2.dts +new file mode 100644 +index 0000000..65e946d +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-r40-uart2.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/ { ++ compatible = "allwinner,sun8i-r40"; ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial2 = "/soc/serial@1c28800"; ++ }; ++ }; ++ fragment@1 { ++ target = <0xffffffff>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <0xffffffff>; ++ status = "okay"; ++ }; ++ }; ++ __fixups__ { ++ uart2 = "/fragment@1:target:0"; ++ uart2_pi_pins = "/fragment@1/__overlay__:pinctrl-0:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-uart4.dts b/arch/arm/boot/dts/overlay/sun8i-r40-uart4.dts +new file mode 100644 +index 0000000..65e946d +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-r40-uart4.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/ { ++ compatible = "allwinner,sun8i-r40"; ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial4 = "/soc/serial@1c29000"; ++ }; ++ }; ++ fragment@1 { ++ target = <0xffffffff>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <0xffffffff>; ++ status = "okay"; ++ }; ++ }; ++ __fixups__ { ++ uart4 = "/fragment@1:target:0"; ++ uart4_ph_pins = "/fragment@1/__overlay__:pinctrl-0:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-uart5.dts b/arch/arm/boot/dts/overlay/sun8i-r40-uart5.dts +new file mode 100644 +index 0000000..65e946d +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-r40-uart5.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/ { ++ compatible = "allwinner,sun8i-r40"; ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial5 = "/soc/serial@1c29400"; ++ }; ++ }; ++ fragment@1 { ++ target = <0xffffffff>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <0xffffffff>; ++ status = "okay"; ++ }; ++ }; ++ __fixups__ { ++ uart5 = "/fragment@1:target:0"; ++ uart5_ph_pins = "/fragment@1/__overlay__:pinctrl-0:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-uart7.dts b/arch/arm/boot/dts/overlay/sun8i-r40-uart7.dts +new file mode 100644 +index 0000000..65e946d +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-r40-uart7.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/ { ++ compatible = "allwinner,sun8i-r40"; ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial7 = "/soc/serial@1c29c00"; ++ }; ++ }; ++ fragment@1 { ++ target = <0xffffffff>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <0xffffffff>; ++ status = "okay"; ++ }; ++ }; ++ __fixups__ { ++ uart7 = "/fragment@1:target:0"; ++ uart7_pi_pins = "/fragment@1/__overlay__:pinctrl-0:0"; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile +index fa35163..89df4ff 100644 +--- a/arch/arm64/boot/dts/allwinner/Makefile ++++ b/arch/arm64/boot/dts/allwinner/Makefile +@@ -31,3 +31,5 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-lite2.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-one-plus.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6.dtb ++ ++subdir-y := $(dts-dirs) overlay +diff --git a/arch/arm64/boot/dts/allwinner/overlay/Makefile b/arch/arm64/boot/dts/allwinner/overlay/Makefile +new file mode 100644 +index 0000000..9b6528e +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/Makefile +@@ -0,0 +1,58 @@ ++# SPDX-License-Identifier: GPL-2.0 ++dtbo-$(CONFIG_ARCH_SUNXI) += \ ++ sun50i-a64-i2c0.dtbo \ ++ sun50i-a64-i2c1.dtbo \ ++ sun50i-a64-pps-gpio.dtbo \ ++ sun50i-a64-spi-add-cs1.dtbo \ ++ sun50i-a64-spi-jedec-nor.dtbo \ ++ sun50i-a64-spi-spidev.dtbo \ ++ sun50i-a64-uart1.dtbo \ ++ sun50i-a64-uart2.dtbo \ ++ sun50i-a64-uart3.dtbo \ ++ sun50i-a64-uart4.dtbo \ ++ sun50i-a64-w1-gpio.dtbo \ ++ sun50i-h5-analog-codec.dtbo \ ++ sun50i-h5-cir.dtbo \ ++ sun50i-h5-i2c0.dtbo \ ++ sun50i-h5-i2c1.dtbo \ ++ sun50i-h5-i2c2.dtbo \ ++ sun50i-h5-pps-gpio.dtbo \ ++ sun50i-h5-pwm.dtbo \ ++ sun50i-h5-spdif-out.dtbo \ ++ sun50i-h5-spi-add-cs1.dtbo \ ++ sun50i-h5-spi-jedec-nor.dtbo \ ++ sun50i-h5-spi-spidev.dtbo \ ++ sun50i-h5-uart1.dtbo \ ++ sun50i-h5-uart2.dtbo \ ++ sun50i-h5-uart3.dtbo \ ++ sun50i-h5-usbhost0.dtbo \ ++ sun50i-h5-usbhost1.dtbo \ ++ sun50i-h5-usbhost2.dtbo \ ++ sun50i-h5-usbhost3.dtbo \ ++ sun50i-h5-w1-gpio.dtbo \ ++ sun50i-h6-i2c0.dtbo \ ++ sun50i-h6-i2c1.dtbo \ ++ sun50i-h6-i2c2.dtbo \ ++ sun50i-h6-ruart.dtbo \ ++ sun50i-h6-spi-add-cs1.dtbo \ ++ sun50i-h6-spi-jedec-nor.dtbo \ ++ sun50i-h6-spi-spidev.dtbo \ ++ sun50i-h6-spi-spidev1.dtbo \ ++ sun50i-h6-uart1.dtbo \ ++ sun50i-h6-uart2.dtbo \ ++ sun50i-h6-uart3.dtbo \ ++ sun50i-h6-w1-gpio.dtbo ++ ++scr-$(CONFIG_ARCH_SUNXI) += \ ++ sun50i-a64-fixup.scr \ ++ sun50i-h5-fixup.scr \ ++ sun50i-h6-fixup.scr ++ ++dtbotxt-$(CONFIG_ARCH_SUNXI) += \ ++ README.sun50i-a64-overlays \ ++ README.sun50i-h5-overlays ++ ++targets += $(dtbo-y) $(scr-y) $(dtbotxt-y) ++ ++always := $(dtbo-y) $(scr-y) $(dtbotxt-y) ++clean-files := *.dtbo *.scr +diff --git a/arch/arm64/boot/dts/allwinner/overlay/README.sun50i-a64-overlays b/arch/arm64/boot/dts/allwinner/overlay/README.sun50i-a64-overlays +new file mode 100644 +index 0000000..cd9dbc6 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/README.sun50i-a64-overlays +@@ -0,0 +1,196 @@ ++This document describes overlays provided in the kernel packages ++For generic Armbian overlays documentation please see ++https://docs.armbian.com/Hardware_Allwinner_overlays/ ++ ++### Platform: ++ ++sun50i-a64 (Allwinner A64) ++ ++### Platform details: ++ ++Supported pin banks: PB, PC, PD, PH ++ ++Both SPI controllers have only one hardware CS pin exposed, ++adding fixed software (GPIO) chip selects is possible with a separate overlay ++ ++I2C controller 2 (PE14, PE15) pins are used for non-I2C CSI functions or are not available ++on supported boards, so this controller is not supported in provided overlays ++ ++### Provided overlays: ++ ++- i2c0 ++- i2c1 ++- pps-gpio ++- spi-add-cs1 ++- spi-jedec-nor ++- spi-spidev ++- uart1 ++- uart2 ++- uart3 ++- uart4 ++- w1-gpio ++ ++### Overlay details: ++ ++### i2c0 ++ ++Activates TWI/I2C bus 0 ++ ++I2C0 pins (SCL, SDA): PH0, PH1 ++ ++### i2c1 ++ ++Activates TWI/I2C bus 1 ++ ++I2C1 pins (SCL, SDA): PH2, PH3 ++ ++### pps-gpio ++ ++Activates pulse-per-second GPIO client ++ ++Parameters: ++ ++param_pps_pin (pin) ++ Pin PPS source is connected to ++ Optional ++ Default: PD4 ++ ++param_pps_falling_edge (bool) ++ Assert by falling edge ++ Optional ++ Default: 0 ++ When set (to 1), assert is indicated by a falling edge ++ (instead of by a rising edge) ++ ++### spi-add-cs1 ++ ++Adds support for using SPI chip select 1 with GPIO for both SPI controllers ++Respective GPIO will be claimed only if controller is enabled by another overlay ++This overlay is required for using chip select 1 with other SPI overlays ++ ++SPI 0 pins (CS1): PB6 ++SPI 1 pins (CS1): PD6 ++ ++### spi-jedec-nor ++ ++Activates MTD support for JEDEC compatible SPI NOR flash chips on SPI bus ++supported by the kernel SPI NOR driver ++ ++SPI 0 pins (MOSI, MISO, SCK, CS): PC0, PC1, PC2, PC3 ++SPI 1 pins (MOSI, MISO, SCK, CS): PD2, PD3, PD1, PD0 ++ ++Parameters: ++ ++param_spinor_spi_bus (int) ++ SPI bus to activate SPI NOR flash support on ++ Required ++ Supported values: 0, 1 ++ ++param_spinor_spi_cs (int) ++ SPI chip select number ++ Optional ++ Default: 0 ++ Supported values: 0, 1 ++ Using chip select 1 requires using "spi-add-cs1" overlay ++ ++param_spinor_max_freq (int) ++ Maximum SPI frequency ++ Optional ++ Default: 1000000 ++ Range: 3000 - 100000000 ++ ++### spi-spidev ++ ++Activates SPIdev device node (/dev/spidevX.Y) for userspace SPI access, ++where X is the bus number and Y is the CS number ++ ++SPI 0 pins (MOSI, MISO, SCK, CS): PC0, PC1, PC2, PC3 ++SPI 1 pins (MOSI, MISO, SCK, CS): PD2, PD3, PD1, PD0 ++ ++Parameters: ++ ++param_spidev_spi_bus (int) ++ SPI bus to activate SPIdev support on ++ Required ++ Supported values: 0, 1 ++ ++param_spidev_spi_cs (int) ++ SPI chip select number ++ Optional ++ Default: 0 ++ Supported values: 0, 1 ++ Using chip select 1 requires using "spi-add-cs1" overlay ++ ++param_spidev_max_freq (int) ++ Maximum SPIdev frequency ++ Optional ++ Default: 1000000 ++ Range: 3000 - 100000000 ++ ++### uart1 ++ ++Activates serial port 1 (/dev/ttyS1) ++ ++UART 1 pins (TX, RX, RTS, CTS): PG6, PG7, PG8, PG9 ++ ++Parameters: ++ ++param_uart1_rtscts (bool) ++ Enable RTS and CTS pins ++ Optional ++ Default: 0 ++ Set to 1 to enable ++ ++### uart2 ++ ++Activates serial port 2 (/dev/ttyS2) ++ ++UART 2 pins (TX, RX, RTS, CTS): PB0, PB1, PB2, PB3 ++ ++Parameters: ++ ++param_uart2_rtscts (bool) ++ Enable RTS and CTS pins ++ Optional ++ Default: 0 ++ Set to 1 to enable CTS and RTS pins ++ ++### uart3 ++ ++Activates serial port 3 (/dev/ttyS3) ++ ++UART 3 pins (TX, RX): PD0, PD1 ++ ++### uart4 ++ ++Activates serial port 4 (/dev/ttyS4) ++ ++UART 4 pins (TX, RX, RTS, CTS): PD2, PD3, PD4, PD5 ++ ++Parameters: ++ ++param_uart2_rtscts (bool) ++ Enable RTS and CTS pins ++ Optional ++ Default: 0 ++ Set to 1 to enable CTS and RTS pins ++ ++### w1-gpio ++ ++Activates 1-Wire GPIO master ++Requires external pull-up resistor on data pin ++ ++Parameters: ++ ++param_w1_pin (pin) ++ Data pin for 1-Wire master ++ Optional ++ Default: PD4 ++ ++param_w1_pin_int_pullup (bool) ++ Enable internal pull-up for the data pin ++ Optional ++ Default: 0 ++ Set to 1 to enable the pull-up ++ This option should not be used with multiple devices, parasite power setup ++ or long wires - please use external pull-up resistor instead +diff --git a/arch/arm64/boot/dts/allwinner/overlay/README.sun50i-h5-overlays b/arch/arm64/boot/dts/allwinner/overlay/README.sun50i-h5-overlays +new file mode 100644 +index 0000000..1ac7fbc +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/README.sun50i-h5-overlays +@@ -0,0 +1,250 @@ ++This document describes overlays provided in the kernel packages ++For generic Armbian overlays documentation please see ++https://docs.armbian.com/User-Guide_Allwinner_overlays/ ++ ++### Platform: ++ ++sun50i-h5 (Allwinner H5) ++ ++### Platform details: ++ ++Supported pin banks: PA, PC, PD, PG ++ ++Both SPI controllers have only one hardware CS pin exposed, ++adding fixed software (GPIO) chip selects is possible with a separate overlay ++ ++### Provided overlays: ++ ++- analog-codec ++- cir ++- i2c0 ++- i2c1 ++- i2c2 ++- pps-gpio ++- pwm ++- spdif-out ++- spi-add-cs1 ++- spi-jedec-nor ++- spi-spidev ++- uart1 ++- uart2 ++- uart3 ++- usbhost0 ++- usbhost1 ++- usbhost2 ++- usbhost3 ++- w1-gpio ++ ++### Overlay details: ++ ++### analog-codec ++ ++Activates SoC analog codec driver that provides Line Out and Mic In ++functionality ++ ++### cir ++ ++Activates CIR (Infrared remote) receiver ++ ++CIR pin: PL11 ++ ++### i2c0 ++ ++Activates TWI/I2C bus 0 ++ ++I2C0 pins (SCL, SDA): PA11, PA12 ++ ++### i2c1 ++ ++Activates TWI/I2C bus 1 ++ ++I2C1 pins (SCL, SDA): PA18, PA19 ++ ++### i2c2 ++ ++Activates TWI/I2C bus 2 ++ ++I2C2 pins (SCL, SDA): PE12, PE13 ++ ++On most board this bus is wired to Camera (CSI) socket ++ ++### pps-gpio ++ ++Activates pulse-per-second GPIO client ++ ++Parameters: ++ ++param_pps_pin (pin) ++ Pin PPS source is connected to ++ Optional ++ Default: PD14 ++ ++param_pps_falling_edge (bool) ++ Assert by falling edge ++ Optional ++ Default: 0 ++ When set (to 1), assert is indicated by a falling edge ++ (instead of by a rising edge) ++ ++### pwm ++ ++Activates hardware PWM controller ++ ++PWM pin: PA5 ++ ++Pin PA5 is used as UART0 RX by default, so if this overlay is activated, ++UART0 and kernel console on ttyS0 will be disabled ++ ++### spdif-out ++ ++Activates SPDIF/Toslink audio output ++ ++SPDIF pin: PA17 ++ ++### spi-add-cs1 ++ ++Adds support for using SPI chip select 1 with GPIO for both SPI controllers ++Respective GPIO will be claimed only if controller is enabled by another ++overlay ++This overlay is required for using chip select 1 with other SPI overlays ++Due to the u-boot limitations CS1 pin can't be customized by a parameter, but ++it can be changed by using an edited copy of this overlay ++A total of 4 chip selects can be used with custom overlays (1 HW + 3 GPIO) ++ ++SPI 0 pins (CS1): PA21 ++SPI 1 pins (CS1): PA10 ++ ++### spi-jedec-nor ++ ++Activates MTD support for JEDEC compatible SPI NOR flash chips on SPI bus ++supported by the kernel SPI NOR driver ++ ++SPI 0 pins (MOSI, MISO, SCK, CS): PC0, PC1, PC2, PC3 ++SPI 1 pins (MOSI, MISO, SCK, CS): PA15, PA16, PA14, PA13 ++ ++Parameters: ++ ++param_spinor_spi_bus (int) ++ SPI bus to activate SPI NOR flash support on ++ Required ++ Supported values: 0, 1 ++ ++param_spinor_spi_cs (int) ++ SPI chip select number ++ Optional ++ Default: 0 ++ Supported values: 0, 1 ++ Using chip select 1 requires using "spi-add-cs1" overlay ++ ++param_spinor_max_freq (int) ++ Maximum SPI frequency ++ Optional ++ Default: 1000000 ++ Range: 3000 - 100000000 ++ ++### spi-spidev ++ ++Activates SPIdev device node (/dev/spidevX.Y) for userspace SPI access, ++where X is the bus number and Y is the CS number ++ ++SPI 0 pins (MOSI, MISO, SCK, CS): PC0, PC1, PC2, PC3 ++SPI 1 pins (MOSI, MISO, SCK, CS): PA15, PA16, PA14, PA13 ++ ++Parameters: ++ ++param_spidev_spi_bus (int) ++ SPI bus to activate SPIdev support on ++ Required ++ Supported values: 0, 1 ++ ++param_spidev_spi_cs (int) ++ SPI chip select number ++ Optional ++ Default: 0 ++ Supported values: 0, 1 ++ Using chip select 1 requires using "spi-add-cs1" overlay ++ ++param_spidev_max_freq (int) ++ Maximum SPIdev frequency ++ Optional ++ Default: 1000000 ++ Range: 3000 - 100000000 ++ ++### uart1 ++ ++Activates serial port 1 (/dev/ttyS1) ++ ++UART 1 pins (TX, RX, RTS, CTS): PG6, PG7, PG8, PG9 ++ ++Parameters: ++ ++param_uart1_rtscts (bool) ++ Enable RTS and CTS pins ++ Optional ++ Default: 0 ++ Set to 1 to enable ++ ++### uart2 ++ ++Activates serial port 2 (/dev/ttyS2) ++ ++UART 2 pins (TX, RX, RTS, CTS): PA0, PA1, PA2, PA3 ++ ++Parameters: ++ ++param_uart2_rtscts (bool) ++ Enable RTS and CTS pins ++ Optional ++ Default: 0 ++ Set to 1 to enable CTS and RTS pins ++ ++### uart3 ++ ++Activates serial port 3 (/dev/ttyS3) ++ ++UART 3 pins (TX, RX, RTS, CTS): PA13, PA14, PA15, PA16 ++ ++Parameters: ++ ++param_uart3_rtscts (bool) ++ Enable RTS and CTS pins ++ Optional ++ Default: 0 ++ Set to 1 to enable CTS and RTS pins ++ ++### usbhost0 ++ ++Activates USB host controller 0 ++ ++### usbhost1 ++ ++Activates USB host controller 1 ++ ++### usbhost2 ++ ++Activates USB host controller 2 ++ ++### usbhost3 ++ ++Activates USB host controller 3 ++ ++### w1-gpio ++ ++Activates 1-Wire GPIO master ++Requires an external pull-up resistor on the data pin ++or enabling the internal pull-up ++ ++Parameters: ++ ++param_w1_pin (pin) ++ Data pin for 1-Wire master ++ Optional ++ Default: PD14 ++ ++param_w1_pin_int_pullup (bool) ++ Enable internal pull-up for the data pin ++ Optional ++ Default: 0 ++ Set to 1 to enable the pull-up ++ This option should not be used with multiple devices, parasite power setup ++ or long wires - please use external pull-up resistor instead +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-fixup.scr-cmd b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-fixup.scr-cmd +new file mode 100644 +index 0000000..36df83c +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-fixup.scr-cmd +@@ -0,0 +1,95 @@ ++# overlays fixup script ++# implements (or rather substitutes) overlay arguments functionality ++# using u-boot scripting, environment variables and "fdt" command ++ ++# setexpr test_var ${tmp_bank} - A ++# works only for hex numbers (A-F) ++ ++setenv decompose_pin 'setexpr tmp_bank sub "P(B|C|D|H)\\d+" "\\1"; ++setexpr tmp_pin sub "P\\S(\\d+)" "\\1"; ++test "${tmp_bank}" = "B" && setenv tmp_bank 1; ++test "${tmp_bank}" = "C" && setenv tmp_bank 2; ++test "${tmp_bank}" = "D" && setenv tmp_bank 3; ++test "${tmp_bank}" = "H" && setenv tmp_bank 7' ++ ++if test -n "${param_spinor_spi_bus}"; then ++ test "${param_spinor_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c68000" ++ test "${param_spinor_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c69000" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spiflash@0 status "okay" ++ if test -n "${param_spinor_max_freq}"; then ++ fdt set /soc/${tmp_spi_path}/spiflash@0 spi-max-frequency "<${param_spinor_max_freq}>" ++ fi ++ if test "${param_spinor_spi_cs}" = "1"; then ++ fdt set /soc/${tmp_spi_path}/spiflash@0 reg "<1>"; ++ fi ++ env delete tmp_spi_path ++fi ++ ++if test -n "${param_spidev_spi_bus}"; then ++ test "${param_spidev_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c68000" ++ test "${param_spidev_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c69000" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spidev status "okay" ++ if test -n "${param_spidev_max_freq}"; then ++ fdt set /soc/${tmp_spi_path}/spidev spi-max-frequency "<${param_spidev_max_freq}>" ++ fi ++ if test "${param_spidev_spi_cs}" = "1"; then ++ fdt set /soc/${tmp_spi_path}/spidev reg "<1>"; ++ fi ++fi ++ ++if test -n "${param_pps_pin}"; then ++ setenv tmp_bank "${param_pps_pin}" ++ setenv tmp_pin "${param_pps_pin}" ++ run decompose_pin ++ fdt set /soc/pinctrl@1c20800/pps_pins pins "${param_pps_pin}" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800 phandle ++ fdt set /pps@0 gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 0>" ++ env delete tmp_pin tmp_bank tmp_phandle ++fi ++ ++if test "${param_pps_falling_edge}" = "1"; then ++ fdt set /pps@0 assert-falling-edge ++fi ++ ++if test -n "${param_w1_pin}"; then ++ setenv tmp_bank "${param_w1_pin}" ++ setenv tmp_pin "${param_w1_pin}" ++ run decompose_pin ++ fdt set /soc/pinctrl@1c20800/w1_pins pins "${param_w1_pin}" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800 phandle ++ fdt set /onewire@0 gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 0>" ++ env delete tmp_pin tmp_bank tmp_phandle ++fi ++ ++if test "${param_w1_pin_int_pullup}" = "1"; then ++ fdt set /soc/pinctrl@1c20800/w1_pins bias-pull-up ++fi ++ ++if test "${param_uart1_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart1-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart1-rts-cts-pins phandle ++ fdt set /soc/serial@1c28400 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28400 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@1c28400 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++fi ++ ++if test "${param_uart2_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart2-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart2-rts-cts-pins phandle ++ fdt set /soc/serial@1c28800 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28800 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@1c28800 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++fi ++ ++if test "${param_uart4_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart4-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart4-rts-cts-pins phandle ++ fdt set /soc/serial@1c29000 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c29000 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@1c29000 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++fi +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-i2c0.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-i2c0.dts +new file mode 100644 +index 0000000..37bdb2c +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-i2c0.dts +@@ -0,0 +1,32 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-a64"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c0 = "/soc/i2c@1c2ac00"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ i2c0_pins: i2c0_pins { ++ pins = "PH0", "PH1"; ++ function = "i2c0"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c0>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-i2c1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-i2c1.dts +new file mode 100644 +index 0000000..b2483c9 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-i2c1.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-a64"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c1 = "/soc/i2c@1c2b000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-pps-gpio.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-pps-gpio.dts +new file mode 100644 +index 0000000..5fa161c +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-pps-gpio.dts +@@ -0,0 +1,29 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-a64"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ pps_pins: pps_pins { ++ pins = "PD4"; ++ function = "gpio_in"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ pps@0 { ++ compatible = "pps-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pps_pins>; ++ gpios = <&pio 3 4 0>; /* PD4 */ ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-spi-add-cs1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-spi-add-cs1.dts +new file mode 100644 +index 0000000..4432aac +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-spi-add-cs1.dts +@@ -0,0 +1,41 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-a64"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ spi0_cs1: spi0_cs1 { ++ pins = "PB6"; ++ function = "gpio_out"; ++ output-high; ++ }; ++ ++ spi1_cs1: spi1_cs1 { ++ pins = "PD6"; ++ function = "gpio_out"; ++ output-high; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ pinctrl-names = "default", "default"; ++ pinctrl-1 = <&spi0_cs1>; ++ cs-gpios = <0>, <&pio 1 6 0>; /* PB6 */ ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ pinctrl-names = "default", "default"; ++ pinctrl-1 = <&spi1_cs1>; ++ cs-gpios = <0>, <&pio 3 6 0>; /* PD6 */ ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-spi-jedec-nor.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-spi-jedec-nor.dts +new file mode 100644 +index 0000000..31d73e5 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-spi-jedec-nor.dts +@@ -0,0 +1,34 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-a64"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-spi-spidev.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-spi-spidev.dts +new file mode 100644 +index 0000000..70d90a2 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-spi-spidev.dts +@@ -0,0 +1,42 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-a64"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc/spi@1c68000"; ++ spi1 = "/soc/spi@1c69000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-uart1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-uart1.dts +new file mode 100644 +index 0000000..4d8dac1 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-uart1.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-a64"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial1 = "/soc/serial@1c28800"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-uart2.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-uart2.dts +new file mode 100644 +index 0000000..36475fd +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-uart2.dts +@@ -0,0 +1,37 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-a64"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial2 = "/soc/serial@1c28800"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart2_pins: uart2-pins { ++ pins = "PB0", "PB1"; ++ function = "uart2"; ++ }; ++ ++ uart2_rts_cts_pins: uart2-rts-cts-pins { ++ pins = "PB2", "PB3"; ++ function = "uart2"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart2>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-uart3.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-uart3.dts +new file mode 100644 +index 0000000..a103a75 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-uart3.dts +@@ -0,0 +1,32 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-a64"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial3 = "/soc/serial@1c28c00"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart3_pins: uart3-pins { ++ pins = "PD0", "PD1"; ++ function = "uart3"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart3>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart3_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-uart4.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-uart4.dts +new file mode 100644 +index 0000000..6e4702b +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-uart4.dts +@@ -0,0 +1,37 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-a64"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial4 = "/soc/serial@1c29000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart4_pins: uart4-pins { ++ pins = "PD2", "PD3"; ++ function = "uart4"; ++ }; ++ ++ uart4_rts_cts_pins: uart4-rts-cts-pins { ++ pins = "PD4", "PD5"; ++ function = "uart4"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart4>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart4_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-w1-gpio.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-w1-gpio.dts +new file mode 100644 +index 0000000..d230469 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-w1-gpio.dts +@@ -0,0 +1,29 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-a64"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ w1_pins: w1_pins { ++ pins = "PD4"; ++ function = "gpio_in"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ onewire@0 { ++ compatible = "w1-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&w1_pins>; ++ gpios = <&pio 3 4 0>; /* PD4 */ ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-analog-codec.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-analog-codec.dts +new file mode 100644 +index 0000000..aaa66d5 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-analog-codec.dts +@@ -0,0 +1,17 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target = <&codec>; ++ __overlay__ { ++ allwinner,audio-routing = ++ "Line Out", "LINEOUT", ++ "MIC1", "Mic", ++ "Mic", "MBIAS"; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-cir.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-cir.dts +new file mode 100644 +index 0000000..90c264a +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-cir.dts +@@ -0,0 +1,15 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target = <&ir>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&r_ir_rx_pin>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-fixup.scr-cmd b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-fixup.scr-cmd +new file mode 100644 +index 0000000..f7b89ae +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-fixup.scr-cmd +@@ -0,0 +1,110 @@ ++# overlays fixup script ++# implements (or rather substitutes) overlay arguments functionality ++# using u-boot scripting, environment variables and "fdt" command ++ ++# setexpr test_var ${tmp_bank} - A ++# works only for hex numbers (A-F) ++ ++setenv decompose_pin 'setexpr tmp_bank sub "P(A|C|D|G)\\d+" "\\1"; ++setexpr tmp_pin sub "P\\S(\\d+)" "\\1"; ++test "${tmp_bank}" = "A" && setenv tmp_bank 0; ++test "${tmp_bank}" = "C" && setenv tmp_bank 2; ++test "${tmp_bank}" = "D" && setenv tmp_bank 3; ++test "${tmp_bank}" = "G" && setenv tmp_bank 6' ++ ++if test -n "${param_spinor_spi_bus}"; then ++ test "${param_spinor_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c68000" ++ test "${param_spinor_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c69000" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spiflash@0 status "okay" ++ if test -n "${param_spinor_max_freq}"; then ++ fdt set /soc/${tmp_spi_path}/spiflash@0 spi-max-frequency "<${param_spinor_max_freq}>" ++ fi ++ if test "${param_spinor_spi_cs}" = "1"; then ++ fdt set /soc/${tmp_spi_path}/spiflash@0 reg "<1>" ++ fi ++ env delete tmp_spi_path ++fi ++ ++if test -n "${param_spidev_spi_bus}"; then ++ test "${param_spidev_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c68000" ++ test "${param_spidev_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c69000" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spidev status "okay" ++ if test -n "${param_spidev_max_freq}"; then ++ fdt set /soc/${tmp_spi_path}/spidev spi-max-frequency "<${param_spidev_max_freq}>" ++ fi ++ if test "${param_spidev_spi_cs}" = "1"; then ++ fdt set /soc/${tmp_spi_path}/spidev reg "<1>" ++ fi ++ env delete tmp_spi_path ++fi ++ ++if test -n "${param_pps_pin}"; then ++ setenv tmp_bank "${param_pps_pin}" ++ setenv tmp_pin "${param_pps_pin}" ++ run decompose_pin ++ fdt set /soc/pinctrl@1c20800/pps_pins pins "${param_pps_pin}" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800 phandle ++ fdt set /pps@0 gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 0>" ++ env delete tmp_pin tmp_bank tmp_phandle ++fi ++ ++if test "${param_pps_falling_edge}" = "1"; then ++ fdt set /pps@0 assert-falling-edge ++fi ++ ++for f in ${overlays}; do ++ if test "${f}" = "pwm"; then ++ setenv bootargs_new "" ++ for arg in ${bootargs}; do ++ if test "${arg}" = "console=ttyS0,115200"; then ++ echo "Warning: Disabling ttyS0 console due to enabled PWM overlay" ++ else ++ setenv bootargs_new "${bootargs_new} ${arg}" ++ fi ++ done ++ setenv bootargs "${bootargs_new}" ++ fi ++done ++ ++if test -n "${param_w1_pin}"; then ++ setenv tmp_bank "${param_w1_pin}" ++ setenv tmp_pin "${param_w1_pin}" ++ run decompose_pin ++ fdt set /soc/pinctrl@1c20800/w1_pins pins "${param_w1_pin}" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800 phandle ++ fdt set /onewire@0 gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 0>" ++ env delete tmp_pin tmp_bank tmp_phandle ++fi ++ ++if test "${param_w1_pin_int_pullup}" = "1"; then ++ fdt set /soc/pinctrl@1c20800/w1_pins bias-pull-up ++fi ++ ++if test "${param_uart1_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart1-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart1-rts-cts-pins phandle ++ fdt set /soc/serial@1c28400 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28400 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@1c28400 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++fi ++ ++if test "${param_uart2_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart2-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart2-rts-cts-pins phandle ++ fdt set /soc/serial@1c28800 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28800 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@1c28800 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++fi ++ ++if test "${param_uart3_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart3-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart3-rts-cts-pins phandle ++ fdt set /soc/serial@1c28c00 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@1c28c00 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++fi +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c0.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c0.dts +new file mode 100644 +index 0000000..87fbd7e +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c0.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c0 = "/soc/i2c@1c2ac00"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c0>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c1.dts +new file mode 100644 +index 0000000..6008b9a +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c1.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c1 = "/soc/i2c@1c2b000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c1>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c2.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c2.dts +new file mode 100644 +index 0000000..2980dbf +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c2.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c2 = "/soc/i2c@1c2b400"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c2>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-pps-gpio.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-pps-gpio.dts +new file mode 100644 +index 0000000..46e0675 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-pps-gpio.dts +@@ -0,0 +1,29 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ pps_pins: pps_pins { ++ pins = "PD14"; ++ function = "gpio_in"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ pps@0 { ++ compatible = "pps-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pps_pins>; ++ gpios = <&pio 3 14 0>; /* PD14 */ ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-pwm.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-pwm.dts +new file mode 100644 +index 0000000..6d12e84 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-pwm.dts +@@ -0,0 +1,39 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target-path = "/chosen"; ++ __overlay__ { ++ /delete-property/ stdout-path; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart0>; ++ __overlay__ { ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&pio>; ++ __overlay__ { ++ pwm0_pin: pwm0 { ++ pins = "PA5"; ++ function = "pwm0"; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&pwm>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm0_pin>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spdif-out.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spdif-out.dts +new file mode 100644 +index 0000000..65bc51b +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spdif-out.dts +@@ -0,0 +1,38 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target = <&spdif>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spdif_tx_pin>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "On-board SPDIF"; ++ ++ simple-audio-card,cpu { ++ sound-dai = <&spdif>; ++ }; ++ ++ simple-audio-card,codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ ++ spdif_out: spdif-out { ++ #sound-dai-cells = <0>; ++ compatible = "linux,spdif-dit"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spi-add-cs1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spi-add-cs1.dts +new file mode 100644 +index 0000000..8e3eab2 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spi-add-cs1.dts +@@ -0,0 +1,41 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ spi0_cs1: spi0_cs1 { ++ pins = "PA21"; ++ function = "gpio_out"; ++ output-high; ++ }; ++ ++ spi1_cs1: spi1_cs1 { ++ pins = "PA10"; ++ function = "gpio_out"; ++ output-high; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ pinctrl-names = "default", "default"; ++ pinctrl-1 = <&spi0_cs1>; ++ cs-gpios = <0>, <&pio 0 21 0>; /* PA21 */ ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ pinctrl-names = "default", "default"; ++ pinctrl-1 = <&spi1_cs1>; ++ cs-gpios = <0>, <&pio 0 10 0>; /* PA10 */ ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spi-jedec-nor.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spi-jedec-nor.dts +new file mode 100644 +index 0000000..5a45808 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spi-jedec-nor.dts +@@ -0,0 +1,42 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc/spi@1c68000"; ++ spi1 = "/soc/spi@1c69000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spi-spidev.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spi-spidev.dts +new file mode 100644 +index 0000000..9b5b0f2 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spi-spidev.dts +@@ -0,0 +1,42 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc/spi@1c68000"; ++ spi1 = "/soc/spi@1c69000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart1.dts +new file mode 100644 +index 0000000..92e3eb4 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart1.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial1 = "/soc/serial@1c28400"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart2.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart2.dts +new file mode 100644 +index 0000000..521a01d +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart2.dts +@@ -0,0 +1,32 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial2 = "/soc/serial@1c28800"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart2_rts_cts: uart2-rts-cts-pins { ++ pins = "PA2", "PA3"; ++ function = "uart2"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart2>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart3.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart3.dts +new file mode 100644 +index 0000000..639e15d +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart3.dts +@@ -0,0 +1,32 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial3 = "/soc/serial@1c28c00"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart3_rts_cts: uart3-rts-cts-pins { ++ pins = "PA15", "PA16"; ++ function = "uart3"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart3>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart3_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-usbhost0.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-usbhost0.dts +new file mode 100644 +index 0000000..c1d79c2 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-usbhost0.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target = <&ehci0>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&ohci0>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&usbphy>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-usbhost1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-usbhost1.dts +new file mode 100644 +index 0000000..2b4f245 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-usbhost1.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target = <&ehci1>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&ohci1>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&usbphy>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-usbhost2.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-usbhost2.dts +new file mode 100644 +index 0000000..54800e7 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-usbhost2.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target = <&ehci2>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&ohci2>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&usbphy>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-usbhost3.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-usbhost3.dts +new file mode 100644 +index 0000000..a99524e +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-usbhost3.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target = <&ehci3>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&ohci3>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&usbphy>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-w1-gpio.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-w1-gpio.dts +new file mode 100644 +index 0000000..6e99626 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-w1-gpio.dts +@@ -0,0 +1,29 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h5"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ w1_pins: w1_pins { ++ pins = "PD14"; ++ function = "gpio_in"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ onewire@0 { ++ compatible = "w1-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&w1_pins>; ++ gpios = <&pio 3 14 0>; /* PD14 */ ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-fixup.scr-cmd b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-fixup.scr-cmd +new file mode 100644 +index 0000000..5f00458 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-fixup.scr-cmd +@@ -0,0 +1,110 @@ ++# overlays fixup script ++# implements (or rather substitutes) overlay arguments functionality ++# using u-boot scripting, environment variables and "fdt" command ++ ++# setexpr test_var ${tmp_bank} - A ++# works only for hex numbers (A-F) ++ ++setenv decompose_pin 'setexpr tmp_bank sub "P(A|C|D|G)\\d+" "\\1"; ++setexpr tmp_pin sub "P\\S(\\d+)" "\\1"; ++test "${tmp_bank}" = "A" && setenv tmp_bank 0; ++test "${tmp_bank}" = "C" && setenv tmp_bank 2; ++test "${tmp_bank}" = "D" && setenv tmp_bank 3; ++test "${tmp_bank}" = "G" && setenv tmp_bank 6' ++ ++if test -n "${param_spinor_spi_bus}"; then ++ test "${param_spinor_spi_bus}" = "0" && setenv tmp_spi_path "spi@5010000" ++ test "${param_spinor_spi_bus}" = "1" && setenv tmp_spi_path "spi@5011000" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spiflash@0 status "okay" ++ if test -n "${param_spinor_max_freq}"; then ++ fdt set /soc/${tmp_spi_path}/spiflash@0 spi-max-frequency "<${param_spinor_max_freq}>" ++ fi ++ if test "${param_spinor_spi_cs}" = "1"; then ++ fdt set /soc/${tmp_spi_path}/spiflash@0 reg "<1>" ++ fi ++ env delete tmp_spi_path ++fi ++ ++if test -n "${param_spidev_spi_bus}"; then ++ test "${param_spidev_spi_bus}" = "0" && setenv tmp_spi_path "spi@5010000" ++ test "${param_spidev_spi_bus}" = "1" && setenv tmp_spi_path "spi@5011000" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spidev status "okay" ++ if test -n "${param_spidev_max_freq}"; then ++ fdt set /soc/${tmp_spi_path}/spidev spi-max-frequency "<${param_spidev_max_freq}>" ++ fi ++ if test "${param_spidev_spi_cs}" = "1"; then ++ fdt set /soc/${tmp_spi_path}/spidev reg "<1>" ++ fi ++ env delete tmp_spi_path ++fi ++ ++if test -n "${param_pps_pin}"; then ++ setenv tmp_bank "${param_pps_pin}" ++ setenv tmp_pin "${param_pps_pin}" ++ run decompose_pin ++ fdt set /soc/pinctrl@300b000/pps_pins pins "${param_pps_pin}" ++ fdt get value tmp_phandle /soc/pinctrl@300b000 phandle ++ fdt set /pps@0 gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 0>" ++ env delete tmp_pin tmp_bank tmp_phandle ++fi ++ ++if test "${param_pps_falling_edge}" = "1"; then ++ fdt set /pps@0 assert-falling-edge ++fi ++ ++for f in ${overlays}; do ++ if test "${f}" = "pwm"; then ++ setenv bootargs_new "" ++ for arg in ${bootargs}; do ++ if test "${arg}" = "console=ttyS0,115200"; then ++ echo "Warning: Disabling ttyS0 console due to enabled PWM overlay" ++ else ++ setenv bootargs_new "${bootargs_new} ${arg}" ++ fi ++ done ++ setenv bootargs "${bootargs_new}" ++ fi ++done ++ ++if test -n "${param_w1_pin}"; then ++ setenv tmp_bank "${param_w1_pin}" ++ setenv tmp_pin "${param_w1_pin}" ++ run decompose_pin ++ fdt set /soc/pinctrl@300b000/w1_pins pins "${param_w1_pin}" ++ fdt get value tmp_phandle /soc/pinctrl@300b000 phandle ++ fdt set /onewire@0 gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 0>" ++ env delete tmp_pin tmp_bank tmp_phandle ++fi ++ ++if test "${param_w1_pin_int_pullup}" = "1"; then ++ fdt set /soc/pinctrl@300b000/w1_pins bias-pull-up ++fi ++ ++if test "${param_uart1_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@300b000/uart1-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@300b000/uart1-rts-cts-pins phandle ++ fdt set /soc/serial@5000400 pinctrl-names "default" "default" ++ fdt set /soc/serial@5000400 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@5000400 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++fi ++ ++if test "${param_uart2_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@300b000/uart2-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@300b000/uart2-rts-cts-pins phandle ++ fdt set /soc/serial@5000800 pinctrl-names "default" "default" ++ fdt set /soc/serial@5000800 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@5000800 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++fi ++ ++if test "${param_uart3_rtscts}" = "1"; then ++ fdt get value tmp_phandle1 /soc/pinctrl@300b000/uart3-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@300b000/uart3-rts-cts-pins phandle ++ fdt set /soc/serial@5000c00 pinctrl-names "default" "default" ++ fdt set /soc/serial@5000c00 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@5000c00 pinctrl-1 "<${tmp_phandle2}>" ++ env delete tmp_phandle1 tmp_phandle2 ++fi +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c0.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c0.dts +new file mode 100644 +index 0000000..7e7ee8c +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c0.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c0 = "/soc/i2c@5002000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c0>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c1.dts +new file mode 100644 +index 0000000..1117698 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c1.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c1 = "/soc/i2c@5002400"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c1>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c2.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c2.dts +new file mode 100644 +index 0000000..b627529 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c2.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c2 = "/soc/i2c@5002800"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c2>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-ruart.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-ruart.dts +new file mode 100644 +index 0000000..6430cb0 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-ruart.dts +@@ -0,0 +1,13 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target = <&r_uart>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-add-cs1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-add-cs1.dts +new file mode 100644 +index 0000000..0fa060f +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-add-cs1.dts +@@ -0,0 +1,41 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ spi0_cs1: spi0_cs1 { ++ pins = "PA10"; ++ function = "gpio_out"; ++ output-high; ++ }; ++ ++ spi1_cs1: spi1_cs1 { ++ pins = "PA21"; ++ function = "gpio_out"; ++ output-high; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ pinctrl-names = "default", "default"; ++ pinctrl-1 = <&spi0_cs1>; ++ cs-gpios = <0>, <&pio 0 10 0>; /* PA10 */ ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ pinctrl-names = "default", "default"; ++ pinctrl-1 = <&spi1_cs1>; ++ cs-gpios = <0>, <&pio 0 21 0>; /* PA21 */ ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-jedec-nor.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-jedec-nor.dts +new file mode 100644 +index 0000000..4f81dbb +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-jedec-nor.dts +@@ -0,0 +1,42 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc/spi@5010000"; ++ spi1 = "/soc/spi@5011000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-spidev.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-spidev.dts +new file mode 100644 +index 0000000..bac3adc +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-spidev.dts +@@ -0,0 +1,42 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc/spi@5010000"; ++ spi1 = "/soc/spi@5011000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-spidev1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-spidev1.dts +new file mode 100644 +index 0000000..e194484 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-spidev1.dts +@@ -0,0 +1,30 @@ ++// Enable the spidev interface ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ /* Path to the SPI controller nodes */ ++ spi1 = "/soc/spi@5011000"; ++ }; ++ }; ++ fragment@1 { ++ target = <&spi1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi1_pins>; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ reg = <0x0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart1.dts +new file mode 100644 +index 0000000..44aa94e +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart1.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial1 = "/soc/serial@5000400"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart2.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart2.dts +new file mode 100644 +index 0000000..7a1860e +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart2.dts +@@ -0,0 +1,32 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial2 = "/soc/serial@5000800"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart2_rts_cts: uart2-rts-cts-pins { ++ pins = "PD21", "PD22"; ++ function = "uart2"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart2>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart3.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart3.dts +new file mode 100644 +index 0000000..770219a +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart3.dts +@@ -0,0 +1,32 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial3 = "/soc/serial@5000c00"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart3_rts_cts: uart3-rts-cts-pins { ++ pins = "PD25", "PD26"; ++ function = "uart3"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart3>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart3_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-w1-gpio.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-w1-gpio.dts +new file mode 100644 +index 0000000..3043c87 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-w1-gpio.dts +@@ -0,0 +1,29 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ w1_pins: w1_pins { ++ pins = "PC9"; ++ function = "gpio_in"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ onewire@0 { ++ compatible = "w1-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&w1_pins>; ++ gpios = <&pio 2 9 0>; /* PC9 */ ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib +index 26e6af4..65b9435 100644 +--- a/scripts/Makefile.lib ++++ b/scripts/Makefile.lib +@@ -65,6 +65,9 @@ real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y) + extra-y += $(dtb-y) + extra-$(CONFIG_OF_ALL_DTBS) += $(dtb-) + ++# Overlay targets ++extra-y += $(dtbo-y) $(scr-y) $(dtbotxt-y) ++ + # Add subdir path + + extra-y := $(addprefix $(obj)/,$(extra-y)) + diff --git a/patch/kernel/sunxi-current/sunxi-h5-add-gpio-regulator-overclock.patch b/patch/kernel/sunxi-current/check/sunxi-h5-add-gpio-regulator-overclock.patch similarity index 100% rename from patch/kernel/sunxi-current/sunxi-h5-add-gpio-regulator-overclock.patch rename to patch/kernel/sunxi-current/check/sunxi-h5-add-gpio-regulator-overclock.patch diff --git a/patch/kernel/sunxi-current/x-board-pinebook-boe-hb140wx-501-overlay.patch b/patch/kernel/sunxi-current/check/x-board-pinebook-boe-hb140wx-501-overlay.patch similarity index 100% rename from patch/kernel/sunxi-current/x-board-pinebook-boe-hb140wx-501-overlay.patch rename to patch/kernel/sunxi-current/check/x-board-pinebook-boe-hb140wx-501-overlay.patch diff --git a/patch/kernel/sunxi-current/general-add-overlay-compilation-support.patch b/patch/kernel/sunxi-current/general-add-overlay-compilation-support.patch index bd6256c98..521a138d3 100644 --- a/patch/kernel/sunxi-current/general-add-overlay-compilation-support.patch +++ b/patch/kernel/sunxi-current/general-add-overlay-compilation-support.patch @@ -9,40 +9,60 @@ index 3c79f859..4e5c1d59 100644 +*.dtb* +*.scr diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst -index 34614a48..8a8313d6 100644 +index 50d580d77..a08f9bee3 100644 --- a/scripts/Makefile.dtbinst +++ b/scripts/Makefile.dtbinst -@@ -20,6 +20,9 @@ include scripts/Kbuild.include +@@ -13,24 +13,40 @@ src := $(obj) + PHONY := __dtbs_install + __dtbs_install: + ++export dtbinst_root ?= $(obj) ++ + include include/config/auto.conf + include scripts/Kbuild.include include $(src)/Makefile - - dtbinst-files := $(sort $(dtb-y) $(if $(CONFIG_OF_ALL_DTBS), $(dtb-))) + +-dtbs := $(addprefix $(dst)/, $(dtb-y) $(if $(CONFIG_OF_ALL_DTBS),$(dtb-))) +-subdirs := $(addprefix $(obj)/, $(subdir-y) $(subdir-m)) ++dtbinst-files := $(sort $(dtb-y) $(if $(CONFIG_OF_ALL_DTBS), $(dtb-))) +dtboinst-files := $(dtbo-y) +script-files := $(scr-y) +readme-files := $(dtbotxt-y) - dtbinst-dirs := $(subdir-y) $(subdir-m) - - # Helper targets for Installing DTBs into the boot directory -@@ -32,10 +35,19 @@ install-dir = $(patsubst $(dtbinst-root)%,$(INSTALL_DTBS_PATH)%,$(obj)) - $(dtbinst-files): %.dtb: $(obj)/%.dtb - $(call cmd,dtb_install,$(install-dir)) - ++dtbinst-dirs := $(subdir-y) $(subdir-m) ++ ++# Helper targets for Installing DTBs into the boot directory ++quiet_cmd_dtb_install = INSTALL $< ++ cmd_dtb_install = mkdir -p $(2); cp $< $(2) ++ ++install-dir = $(patsubst $(dtbinst_root)%,$(INSTALL_DTBS_PATH)%,$(obj)) ++ ++$(dtbinst-files): %.dtb: $(obj)/%.dtb ++ $(call cmd,dtb_install,$(install-dir)) ++ +$(dtboinst-files): %.dtbo: $(obj)/%.dtbo + $(call cmd,dtb_install,$(install-dir)) -+ + +-__dtbs_install: $(dtbs) $(subdirs) +- @: +$(script-files): %.scr: $(obj)/%.scr + $(call cmd,dtb_install,$(install-dir)) -+ + +-quiet_cmd_dtb_install = INSTALL $@ +- cmd_dtb_install = install -D $< $@ +$(readme-files): %: $(src)/% + $(call cmd,dtb_install,$(install-dir)) -+ - $(dtbinst-dirs): - $(Q)$(MAKE) $(dtbinst)=$(obj)/$@ - --PHONY += $(dtbinst-files) $(dtbinst-dirs) --__dtbs_install: $(dtbinst-files) $(dtbinst-dirs) + +-$(dst)/%.dtb: $(obj)/%.dtb +- $(call cmd,dtb_install) ++$(dtbinst-dirs): ++ $(Q)$(MAKE) $(dtbinst)=$(obj)/$@ + +-PHONY += $(subdirs) +-$(subdirs): +- $(Q)$(MAKE) $(dtbinst)=$@ dst=$(patsubst $(obj)/%,$(dst)/%,$@) +PHONY += $(dtbinst-files) $(dtboinst-files) $(script-files) $(readme-files) $(dtbinst-dirs) +__dtbs_install: $(dtbinst-files) $(dtboinst-files) $(script-files) $(readme-files) $(dtbinst-dirs) - + .PHONY: $(PHONY) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 58c05e5d..2b95dda9 100644 diff --git a/patch/kernel/sunxi-current/general-fix-cs_gpio-spi-support.patch b/patch/kernel/sunxi-current/general-fix-cs_gpio-spi-support.patch index 4588287dc..5ceba8b49 100644 --- a/patch/kernel/sunxi-current/general-fix-cs_gpio-spi-support.patch +++ b/patch/kernel/sunxi-current/general-fix-cs_gpio-spi-support.patch @@ -1,8 +1,8 @@ diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c -index 9a7def7..08c6a05 100644 +index 5e4c453..028ef66 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c -@@ -2884,6 +2884,19 @@ int spi_setup(struct spi_device *spi) +@@ -3262,6 +3262,19 @@ int spi_setup(struct spi_device *spi) if (spi->controller->setup) status = spi->controller->setup(spi); @@ -19,6 +19,6 @@ index 9a7def7..08c6a05 100644 + } + } + - spi_set_cs(spi, false); - - dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s%u bits/w, %u Hz max --> %d\n", + if (spi->controller->auto_runtime_pm && spi->controller->set_cs) { + status = pm_runtime_get_sync(spi->controller->dev.parent); + if (status < 0) { diff --git a/patch/kernel/sunxi-current/general-sunxi-overlays.patch b/patch/kernel/sunxi-current/general-sunxi-overlays.patch index 934587d45..2b15fc211 100644 --- a/patch/kernel/sunxi-current/general-sunxi-overlays.patch +++ b/patch/kernel/sunxi-current/general-sunxi-overlays.patch @@ -13,7 +13,7 @@ new file mode 100644 index 0000000..39d6a27 --- /dev/null +++ b/arch/arm/boot/dts/overlay/Makefile -@@ -0,0 +1,89 @@ +@@ -0,0 +1,97 @@ +# SPDX-License-Identifier: GPL-2.0 +dtbo-$(CONFIG_MACH_SUN4I) += \ + sun4i-a10-analog-codec.dtbo \ @@ -92,7 +92,15 @@ index 0000000..39d6a27 + sun8i-h3-usbhost1.dtbo \ + sun8i-h3-usbhost2.dtbo \ + sun8i-h3-usbhost3.dtbo \ -+ sun8i-h3-w1-gpio.dtbo ++ sun8i-h3-w1-gpio.dtbo \ ++ sun8i-r40-i2c2.dtbo \ ++ sun8i-r40-i2c3.dtbo \ ++ sun8i-r40-spi-spidev0.dtbo \ ++ sun8i-r40-spi-spidev1.dtbo \ ++ sun8i-r40-uart2.dtbo \ ++ sun8i-r40-uart4.dtbo \ ++ sun8i-r40-uart5.dtbo \ ++ sun8i-r40-uart7.dtbo + +scr-$(CONFIG_MACH_SUN4I) += sun4i-a10-fixup.scr +scr-$(CONFIG_MACH_SUN5I) += sun5i-a13-fixup.scr @@ -4520,6 +4528,236 @@ index 0000000..f4ccb7f + }; + }; +}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-i2c2.dts b/arch/arm/boot/dts/overlay/sun8i-r40-i2c2.dts +new file mode 100644 +index 0000000..a1e3284 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-r40-i2c2.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c2 = "/soc/i2c@1c2b400"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c2>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-i2c3.dts b/arch/arm/boot/dts/overlay/sun8i-r40-i2c3.dts +new file mode 100644 +index 0000000..a1e3284 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-r40-i2c3.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h3"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c3 = "/soc/i2c@1c2b800"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c3>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev0.dts b/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev0.dts +new file mode 100644 +index 0000000..734a9a8 +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev0.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/ { ++ compatible = "allwinner,sun8i-r40"; ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc/spi@1c05000"; ++ }; ++ }; ++ fragment@1 { ++ target = <0xffffffff>; ++ __overlay__ { ++ #address-cells = <0x00000001>; ++ #size-cells = <0x00000000>; ++ status = "okay"; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "okay"; ++ reg = <0x00000000>; ++ spi-max-frequency = <0x000f4240>; ++ }; ++ }; ++ }; ++ __fixups__ { ++ spi0 = "/fragment@1:target:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev1.dts b/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev1.dts +new file mode 100644 +index 0000000..d1d637c +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev1.dts +@@ -0,0 +1,27 @@ ++/dts-v1/; ++/ { ++ compatible = "allwinner,sun8i-r40"; ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi1 = "/soc/spi@1c06000"; ++ }; ++ }; ++ fragment@1 { ++ target = <0xffffffff>; ++ __overlay__ { ++ #address-cells = <0x00000001>; ++ #size-cells = <0x00000000>; ++ status = "okay"; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "okay"; ++ reg = <0x00000000>; ++ spi-max-frequency = <0x000f4240>; ++ }; ++ }; ++ }; ++ __fixups__ { ++ spi1 = "/fragment@1:target:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-uart2.dts b/arch/arm/boot/dts/overlay/sun8i-r40-uart2.dts +new file mode 100644 +index 0000000..65e946d +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-r40-uart2.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/ { ++ compatible = "allwinner,sun8i-r40"; ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial2 = "/soc/serial@1c28800"; ++ }; ++ }; ++ fragment@1 { ++ target = <0xffffffff>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <0xffffffff>; ++ status = "okay"; ++ }; ++ }; ++ __fixups__ { ++ uart2 = "/fragment@1:target:0"; ++ uart2_pi_pins = "/fragment@1/__overlay__:pinctrl-0:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-uart4.dts b/arch/arm/boot/dts/overlay/sun8i-r40-uart4.dts +new file mode 100644 +index 0000000..65e946d +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-r40-uart4.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/ { ++ compatible = "allwinner,sun8i-r40"; ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial4 = "/soc/serial@1c29000"; ++ }; ++ }; ++ fragment@1 { ++ target = <0xffffffff>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <0xffffffff>; ++ status = "okay"; ++ }; ++ }; ++ __fixups__ { ++ uart4 = "/fragment@1:target:0"; ++ uart4_ph_pins = "/fragment@1/__overlay__:pinctrl-0:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-uart5.dts b/arch/arm/boot/dts/overlay/sun8i-r40-uart5.dts +new file mode 100644 +index 0000000..65e946d +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-r40-uart5.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/ { ++ compatible = "allwinner,sun8i-r40"; ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial5 = "/soc/serial@1c29400"; ++ }; ++ }; ++ fragment@1 { ++ target = <0xffffffff>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <0xffffffff>; ++ status = "okay"; ++ }; ++ }; ++ __fixups__ { ++ uart5 = "/fragment@1:target:0"; ++ uart5_ph_pins = "/fragment@1/__overlay__:pinctrl-0:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-uart7.dts b/arch/arm/boot/dts/overlay/sun8i-r40-uart7.dts +new file mode 100644 +index 0000000..65e946d +--- /dev/null ++++ b/arch/arm/boot/dts/overlay/sun8i-r40-uart7.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/ { ++ compatible = "allwinner,sun8i-r40"; ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial7 = "/soc/serial@1c29c00"; ++ }; ++ }; ++ fragment@1 { ++ target = <0xffffffff>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <0xffffffff>; ++ status = "okay"; ++ }; ++ }; ++ __fixups__ { ++ uart7 = "/fragment@1:target:0"; ++ uart7_pi_pins = "/fragment@1/__overlay__:pinctrl-0:0"; ++ }; ++}; diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile index fa35163..89df4ff 100644 --- a/arch/arm64/boot/dts/allwinner/Makefile diff --git a/patch/kernel/sunxi-current/npi-a64-only-audio-usb.patch b/patch/kernel/sunxi-current/npi-a64-only-audio-usb.patch index 5d5beca50..1a29262cf 100644 --- a/patch/kernel/sunxi-current/npi-a64-only-audio-usb.patch +++ b/patch/kernel/sunxi-current/npi-a64-only-audio-usb.patch @@ -2,7 +2,7 @@ diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts b/arch/arm6 index ec0296a85..ad2c64d51 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts -@@ -293,3 +293,36 @@ &uart0 { +@@ -293,3 +293,32 @@ &uart0 { &usbphy { status = "okay"; }; @@ -11,7 +11,7 @@ index ec0296a85..ad2c64d51 100644 +status = "okay"; +}; + -+&sound_hdmi { ++&hdmi_sound { +status = "okay"; +}; + @@ -20,10 +20,6 @@ index ec0296a85..ad2c64d51 100644 +status = "okay"; +}; + -+&i2s1 { -+status = "okay"; -+}; -+ +&i2s2 { +status = "okay"; +}; diff --git a/patch/kernel/sunxi-current/ruart-alias.patch b/patch/kernel/sunxi-current/ruart-alias.patch new file mode 100644 index 000000000..79669999b --- /dev/null +++ b/patch/kernel/sunxi-current/ruart-alias.patch @@ -0,0 +1,12 @@ +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +index afee79f..7a8f8c6 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +@@ -16,6 +16,7 @@ + aliases { + serial0 = &uart0; + serial1 = &uart1; ++ serial9 = &r_uart; + ethernet0 = &emac; + }; + diff --git a/patch/kernel/sunxi-current/sound-soc-codecs-enable-pcm5102a.patch b/patch/kernel/sunxi-current/sound-soc-codecs-enable-pcm5102a.patch index 7fab56de6..27f832987 100644 --- a/patch/kernel/sunxi-current/sound-soc-codecs-enable-pcm5102a.patch +++ b/patch/kernel/sunxi-current/sound-soc-codecs-enable-pcm5102a.patch @@ -1,6 +1,6 @@ --- a/sound/soc/codecs/Kconfig 2020-02-13 23:44:47.394937509 +0100 +++ b/sound/soc/codecs/Kconfig 2020-02-13 23:47:11.571103180 +0100 -@@ -880,7 +880,7 @@ +@@ -917,7 +917,7 @@ select REGMAP_SPI config SND_SOC_PCM5102A diff --git a/patch/kernel/sunxi-current/sun50i-h6-drm_panfrost-1-missing-remove-opp-table-in-case-of-failure.patch b/patch/kernel/sunxi-current/sun50i-h6-drm_panfrost-1-missing-remove-opp-table-in-case-of-failure.patch new file mode 100644 index 000000000..7c9527f68 --- /dev/null +++ b/patch/kernel/sunxi-current/sun50i-h6-drm_panfrost-1-missing-remove-opp-table-in-case-of-failure.patch @@ -0,0 +1,47 @@ +--- + drivers/gpu/drm/panfrost/panfrost_devfreq.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c +index 413987038fbf..62541f4edd81 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c ++++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c +@@ -90,8 +90,11 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) + cur_freq = clk_get_rate(pfdev->clock); + + opp = devfreq_recommended_opp(dev, &cur_freq, 0); +- if (IS_ERR(opp)) +- return PTR_ERR(opp); ++ if (IS_ERR(opp)) { ++ DRM_DEV_ERROR(dev, "Failed to set recommended OPP\n"); ++ ret = PTR_ERR(opp); ++ goto err_opp; ++ } + + panfrost_devfreq_profile.initial_freq = cur_freq; + dev_pm_opp_put(opp); +@@ -100,8 +103,8 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) + DEVFREQ_GOV_SIMPLE_ONDEMAND, NULL); + if (IS_ERR(devfreq)) { + DRM_DEV_ERROR(dev, "Couldn't initialize GPU devfreq\n"); +- dev_pm_opp_of_remove_table(dev); +- return PTR_ERR(devfreq); ++ ret = PTR_ERR(devfreq); ++ goto err_opp; + } + pfdev->devfreq.devfreq = devfreq; + +@@ -112,6 +115,11 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) + pfdev->devfreq.cooling = cooling; + + return 0; ++ ++err_opp: ++ dev_pm_opp_of_remove_table(dev); ++ ++ return ret; + } + + void panfrost_devfreq_fini(struct panfrost_device *pfdev) +-- +2.20.1 diff --git a/patch/kernel/sunxi-current/sun50i-h6-drm_panfrost-2-add-devfreq-regulator-support.patch b/patch/kernel/sunxi-current/sun50i-h6-drm_panfrost-2-add-devfreq-regulator-support.patch new file mode 100644 index 000000000..4be929618 --- /dev/null +++ b/patch/kernel/sunxi-current/sun50i-h6-drm_panfrost-2-add-devfreq-regulator-support.patch @@ -0,0 +1,81 @@ +--- + drivers/gpu/drm/panfrost/panfrost_devfreq.c | 34 ++++++++++++++++++--- + drivers/gpu/drm/panfrost/panfrost_device.h | 1 + + 2 files changed, 31 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c +index 62541f4edd81..2dc8e2355358 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c ++++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c +@@ -78,12 +78,26 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) + struct device *dev = &pfdev->pdev->dev; + struct devfreq *devfreq; + struct thermal_cooling_device *cooling; ++ const char *mali = "mali"; ++ struct opp_table *opp_table = NULL; ++ ++ /* Regulator is optional */ ++ opp_table = dev_pm_opp_set_regulators(dev, &mali, 1); ++ if (IS_ERR(opp_table)) { ++ ret = PTR_ERR(opp_table); ++ if (ret != -ENODEV) { ++ DRM_DEV_ERROR(dev, "Failed to set regulator: %d\n", ret); ++ return ret; ++ } ++ } ++ pfdev->devfreq.opp_table = opp_table; + + ret = dev_pm_opp_of_add_table(dev); +- if (ret == -ENODEV) /* Optional, continue without devfreq */ +- return 0; +- else if (ret) +- return ret; ++ if (ret) { ++ if (ret == -ENODEV) /* Optional, continue without devfreq */ ++ ret = 0; ++ goto err_opp_reg; ++ } + + panfrost_devfreq_reset(pfdev); + +@@ -119,6 +133,12 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) + err_opp: + dev_pm_opp_of_remove_table(dev); + ++err_opp_reg: ++ if (pfdev->devfreq.opp_table) { ++ dev_pm_opp_put_regulators(pfdev->devfreq.opp_table); ++ pfdev->devfreq.opp_table = NULL; ++ } ++ + return ret; + } + +@@ -126,7 +146,13 @@ void panfrost_devfreq_fini(struct panfrost_device *pfdev) + { + if (pfdev->devfreq.cooling) + devfreq_cooling_unregister(pfdev->devfreq.cooling); ++ + dev_pm_opp_of_remove_table(&pfdev->pdev->dev); ++ ++ if (pfdev->devfreq.opp_table) { ++ dev_pm_opp_put_regulators(pfdev->devfreq.opp_table); ++ pfdev->devfreq.opp_table = NULL; ++ } + } + + void panfrost_devfreq_resume(struct panfrost_device *pfdev) +diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h +index 06713811b92c..f6b0c779dfe5 100644 +--- a/drivers/gpu/drm/panfrost/panfrost_device.h ++++ b/drivers/gpu/drm/panfrost/panfrost_device.h +@@ -86,6 +86,7 @@ struct panfrost_device { + struct { + struct devfreq *devfreq; + struct thermal_cooling_device *cooling; ++ struct opp_table *opp_table; + ktime_t busy_time; + ktime_t idle_time; + ktime_t time_last_update; +-- +2.20.1 diff --git a/patch/kernel/sunxi-current/timekeeping32-tweaks-for-5.0.y.patch b/patch/kernel/sunxi-current/timekeeping32-tweaks-for-5.0.y.patch index fd6935461..9157cd8e6 100644 --- a/patch/kernel/sunxi-current/timekeeping32-tweaks-for-5.0.y.patch +++ b/patch/kernel/sunxi-current/timekeeping32-tweaks-for-5.0.y.patch @@ -1,11 +1,44 @@ diff --git a/include/linux/timekeeping32.h b/include/linux/timekeeping32.h -index cc59cc9..a0f5143 100644 +index 266017f..4444cec 100644 --- a/include/linux/timekeeping32.h +++ b/include/linux/timekeeping32.h -@@ -43,4 +43,15 @@ static inline void getboottime(struct timespec *ts) - *ts = timespec64_to_timespec(ts64); +@@ -11,4 +11,48 @@ static inline unsigned long get_seconds(void) + return ktime_get_real_seconds(); } ++/* Map the ktime_t to timespec conversion to ns_to_timespec function */ ++#define ktime_to_timespec(kt) ns_to_timespec((kt)) ++#define timespec old_timespec32 ++ ++static inline struct timespec ns_to_timespec(const s64 nsec) ++{ ++ struct timespec ts; ++ s32 rem; ++ if (!nsec) ++ return (struct timespec) {0, 0}; ++ ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem); ++ if (unlikely(rem < 0)) { ++ ts.tv_sec--; ++ rem += NSEC_PER_SEC; ++ } ++ ts.tv_nsec = rem; ++ return ts; ++} ++ ++/* timespec64 is defined as timespec here */ ++static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64) ++{ ++ return *(const struct timespec *)&ts64; ++} ++ ++static inline void getboottime(struct timespec *ts) ++{ ++ struct timespec64 ts64; ++ ++ getboottime64(&ts64); ++ *ts = timespec64_to_timespec(ts64); ++} ++ +static inline void get_monotonic_boottime(struct timespec *ts) +{ + *ts = ktime_to_timespec(ktime_get_boottime()); diff --git a/patch/kernel/sunxi-current/update-correct-h3-h5-thermal-zones.patch b/patch/kernel/sunxi-current/update-correct-h3-h5-thermal-zones.patch index 7515934e3..700b7c01e 100644 --- a/patch/kernel/sunxi-current/update-correct-h3-h5-thermal-zones.patch +++ b/patch/kernel/sunxi-current/update-correct-h3-h5-thermal-zones.patch @@ -89,11 +89,11 @@ index f4af3fdcc..3b1f50791 100644 }; }; diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi -index ae3f37720..74e6b3b82 100644 +index a79956f7b..b4891d31f 100644 --- a/arch/arm/boot/dts/sun8i-h3.dtsi +++ b/arch/arm/boot/dts/sun8i-h3.dtsi -@@ -89,15 +89,6 @@ - }; +@@ -98,15 +98,6 @@ + interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; }; - thermal-zones { @@ -105,10 +105,10 @@ index ae3f37720..74e6b3b82 100644 - }; - }; - - pmu { - compatible = "arm,cortex-a7-pmu"; - interrupts = , -@@ -188,32 +179,74 @@ + timer { + compatible = "arm,armv7-timer"; + interrupts = , +@@ -210,32 +201,74 @@ }; thermal-zones { @@ -120,17 +120,16 @@ index ae3f37720..74e6b3b82 100644 + /* milliseconds */ + polling-delay-passive = <250>; + polling-delay = <1000>; -+ thermal-sensors = <&ths>; -+ -+ trips { ++ thermal-sensors = <&ths>; + + trips { +- cpu_hot_trip: cpu-hot { + cpu_warm: cpu_warm { + temperature = <75000>; + hysteresis = <2000>; + type = "passive"; + }; - -- trips { -- cpu_hot_trip: cpu-hot { ++ + cpu_hot_pre: cpu_hot_pre { temperature = <80000>; hysteresis = <2000>; @@ -165,14 +164,13 @@ index ae3f37720..74e6b3b82 100644 }; }; -- cooling-maps { + cooling-maps { - cpu-hot-limit { - trip = <&cpu_hot_trip>; - cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -+ cooling-maps { + cpu_warm_limit_cpu { + trip = <&cpu_warm>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT 2>; diff --git a/patch/kernel/sunxi-legacy/v3-1-2-si2168-Set-TS-clock-mode-and-frequency.patch b/patch/kernel/sunxi-current/v3-1-2-si2168-Set-TS-clock-mode-and-frequency.patch-disabled similarity index 100% rename from patch/kernel/sunxi-legacy/v3-1-2-si2168-Set-TS-clock-mode-and-frequency.patch rename to patch/kernel/sunxi-current/v3-1-2-si2168-Set-TS-clock-mode-and-frequency.patch-disabled diff --git a/patch/kernel/sunxi-legacy/v3-2-2-dvbsky-Add-support-for-MyGica-T230C-v2.patch b/patch/kernel/sunxi-current/v3-2-2-dvbsky-Add-support-for-MyGica-T230C-v2.patch-disabled similarity index 97% rename from patch/kernel/sunxi-legacy/v3-2-2-dvbsky-Add-support-for-MyGica-T230C-v2.patch rename to patch/kernel/sunxi-current/v3-2-2-dvbsky-Add-support-for-MyGica-T230C-v2.patch-disabled index 8760a8a94..9395aac58 100644 --- a/patch/kernel/sunxi-legacy/v3-2-2-dvbsky-Add-support-for-MyGica-T230C-v2.patch +++ b/patch/kernel/sunxi-current/v3-2-2-dvbsky-Add-support-for-MyGica-T230C-v2.patch-disabled @@ -134,11 +134,12 @@ diff --git a/include/media/dvb-usb-ids.h b/include/media/dvb-usb-ids.h index f9e73b4..d606248 100644 --- a/include/media/dvb-usb-ids.h +++ b/include/media/dvb-usb-ids.h -@@ -387,6 +387,7 @@ +@@ -387,7 +387,8 @@ #define USB_PID_MYGICA_D689 0xd811 #define USB_PID_MYGICA_T230 0xc688 #define USB_PID_MYGICA_T230C 0xc689 -+#define USB_PID_MYGICA_T230C_V2 0xc68a + #define USB_PID_MYGICA_T230C2 0xc68a ++#define USB_PID_MYGICA_T230C_V2 0xc68a #define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011 #define USB_PID_ELGATO_EYETV_DTT 0x0021 #define USB_PID_ELGATO_EYETV_DTT_2 0x003f diff --git a/patch/kernel/sunxi-current/wifi-4002-add-realtek-8723cs.patch b/patch/kernel/sunxi-current/wifi-4002-add-realtek-8723cs.patch index 69d37ec09..6f6d83280 100644 --- a/patch/kernel/sunxi-current/wifi-4002-add-realtek-8723cs.patch +++ b/patch/kernel/sunxi-current/wifi-4002-add-realtek-8723cs.patch @@ -340458,10 +340458,10 @@ index 00000000..7c349e79 + diff --git a/drivers/net/wireless/realtek/rtl8723cs/os_dep/linux/rtw_proc.c b/drivers/net/wireless/realtek/rtl8723cs/os_dep/linux/rtw_proc.c new file mode 100644 -index 00000000..cee446fa +index 0000000..77d6e90 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl8723cs/os_dep/linux/rtw_proc.c -@@ -0,0 +1,2038 @@ +@@ -0,0 +1,2072 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2013 Realtek Corporation. All rights reserved. @@ -340532,8 +340532,15 @@ index 00000000..cee446fa + return entry; +} + -+inline struct proc_dir_entry *rtw_proc_create_entry(const char *name, struct proc_dir_entry *parent, -+ const struct file_operations *fops, void * data) ++inline struct proc_dir_entry *rtw_proc_create_entry(const char *name, struct proc_dir_entry *parent, ++#if 1 //(LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)) ++ #pragma message "Greater or equal 5.6.0" ++ const struct proc_ops *fops, ++#else ++ #pragma message "Lower than 5.6.0 : " LINUX_VERSION_CODE ++ const struct file_operations *fops, ++#endif ++ void * data) +{ + struct proc_dir_entry *entry; + @@ -340598,13 +340605,13 @@ index 00000000..cee446fa + } else { + return -EFAULT; + } -+ ++ + return count; +} + +#ifdef DBG_MEM_ALLOC +static int proc_get_mstat(struct seq_file *m, void *v) -+{ ++{ + rtw_mstat_dump(m); + return 0; +} @@ -340652,13 +340659,22 @@ index 00000000..cee446fa + ssize_t index = (ssize_t)PDE_DATA(file_inode(file)); + const struct rtw_proc_hdl *hdl = drv_proc_hdls+index; + ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *, void *) = hdl->write; -+ ++ + if (write) + return write(file, buffer, count, pos, NULL); + + return -EROFS; +} + ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)) ++static const struct proc_ops rtw_drv_proc_fops = { ++ .proc_open = rtw_drv_proc_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_release = single_release, ++ .proc_write = rtw_drv_proc_write, ++}; ++#else +static const struct file_operations rtw_drv_proc_fops = { + .owner = THIS_MODULE, + .open = rtw_drv_proc_open, @@ -340667,6 +340683,7 @@ index 00000000..cee446fa + .release = single_release, + .write = rtw_drv_proc_write, +}; ++#endif + +int rtw_drv_proc_init(void) +{ @@ -340782,9 +340799,9 @@ index 00000000..cee446fa +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); -+ char tmp[32]={0}; ++ char tmp[32]={0}; + int num=0,gpio_pin=0,gpio_mode=0;//gpio_mode:0 input 1:output; -+ ++ + if (count < 2) + return -EFAULT; + @@ -340796,21 +340813,20 @@ index 00000000..cee446fa + if (buffer && !copy_from_user(tmp, buffer, count)) { + num =sscanf(tmp, "%d %d",&gpio_pin,&gpio_mode); + DBG_871X("num=%d gpio_pin=%d mode=%d\n",num,gpio_pin,gpio_mode); -+ padapter->pre_gpio_pin=gpio_pin; -+ ++ padapter->pre_gpio_pin=gpio_pin; + if(gpio_mode==0 || gpio_mode==1 ) -+ rtw_hal_config_gpio(padapter, gpio_pin,gpio_mode); ++ rtw_hal_config_gpio(padapter, gpio_pin,gpio_mode); + } + return count; -+ +} ++ +static ssize_t proc_set_gpio_output_value(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); -+ char tmp[32]={0}; ++ char tmp[32]={0}; + int num=0,gpio_pin=0,pin_mode=0;//pin_mode: 1 high 0:low -+ ++ + if (count < 2) + return -EFAULT; + @@ -340823,33 +340839,33 @@ index 00000000..cee446fa + num =sscanf(tmp, "%d %d",&gpio_pin,&pin_mode); + DBG_871X("num=%d gpio_pin=%d pin_high=%d\n",num,gpio_pin,pin_mode); + padapter->pre_gpio_pin=gpio_pin; -+ + if(pin_mode==0 || pin_mode==1 ) -+ rtw_hal_set_gpio_output_value(padapter, gpio_pin,pin_mode); ++ rtw_hal_set_gpio_output_value(padapter, gpio_pin,pin_mode); + } + return count; +} ++ +static int proc_get_gpio(struct seq_file *m, void *v) +{ + u8 gpioreturnvalue=0; + struct net_device *dev = m->private; -+ ++ + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); -+ if(!padapter) ++ if(!padapter) + return -EFAULT; + gpioreturnvalue = rtw_hal_get_gpio(padapter, padapter->pre_gpio_pin); + DBG_871X_SEL_NL(m, "get_gpio %d:%d \n",padapter->pre_gpio_pin ,gpioreturnvalue); -+ -+ return 0; + ++ return 0; +} ++ +static ssize_t proc_set_gpio(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) +{ + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); -+ char tmp[32]={0}; ++ char tmp[32]={0}; + int num=0,gpio_pin=0; -+ ++ + if (count < 1) + return -EFAULT; + @@ -340862,10 +340878,10 @@ index 00000000..cee446fa + num =sscanf(tmp, "%d",&gpio_pin); + DBG_871X("num=%d gpio_pin=%d\n",num,gpio_pin); + padapter->pre_gpio_pin=gpio_pin; -+ + } -+ return count; ++ return count; +} ++ +#endif + + @@ -340873,9 +340889,8 @@ index 00000000..cee446fa +{ + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); -+ if(padapter) ++ if(padapter) + DBG_871X_SEL_NL(m, "linked_info_dump :%s \n", (padapter->bLinkInfoDump)?"enable":"disable"); -+ + return 0; +} + @@ -340884,9 +340899,9 @@ index 00000000..cee446fa + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + -+ char tmp[32]={0}; ++ char tmp[32]={0}; + int mode=0,pre_mode=0; -+ int num=0; ++ int num=0; + + if (count < 1) + return -EFAULT; @@ -340907,18 +340922,17 @@ index 00000000..cee446fa + if(num!=1) + { + DBG_871X("argument number is wrong\n"); -+ return -EFAULT; ++ return -EFAULT; + } -+ ++ + if(mode==1 || (mode==0 && pre_mode==1) ) //not consider pwr_saving 0: + { -+ padapter->bLinkInfoDump = mode; -+ ++ padapter->bLinkInfoDump = mode; + } + else if( (mode==2 ) || (mode==0 && pre_mode==2))//consider power_saving -+ { ++ { + //DBG_871X("linked_info_dump =%s \n", (padapter->bLinkInfoDump)?"enable":"disable") -+ linked_info_dump(padapter,mode); ++ linked_info_dump(padapter,mode); + } + } + return count; @@ -340939,7 +340953,7 @@ index 00000000..cee446fa + struct net_device *dev = m->private; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct registry_priv *pregpriv = &padapter->registrypriv; -+ ++ + DBG_871X_SEL_NL(m,"wifi_spec=%d\n",pregpriv->wifi_spec); + return 0; +} @@ -340968,7 +340982,7 @@ index 00000000..cee446fa + { + DBG_871X("argument size is less than 1\n"); + return -EFAULT; -+ } ++ } + + if (count > sizeof(tmp)) { + rtw_warn_on(1); @@ -341066,7 +341080,7 @@ index 00000000..cee446fa + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct recv_priv *precvpriv = &(padapter->recvpriv); + -+ DBG_871X_SEL_NL(m,"%d\n",precvpriv->sink_udpport); ++ DBG_871X_SEL_NL(m,"%d\n",precvpriv->sink_udpport); + return 0; +} +static ssize_t proc_set_udpport(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) @@ -341074,10 +341088,10 @@ index 00000000..cee446fa + struct net_device *dev = data; + _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); + struct recv_priv *precvpriv = &(padapter->recvpriv); -+ int sink_udpport = 0; ++ int sink_udpport = 0; + char tmp[32]; -+ -+ ++ ++ + if (!padapter) + return -EFAULT; + @@ -341085,7 +341099,7 @@ index 00000000..cee446fa + { + DBG_871X("argument size is less than 1\n"); + return -EFAULT; -+ } ++ } + + if (count > sizeof(tmp)) { + rtw_warn_on(1); @@ -341103,7 +341117,7 @@ index 00000000..cee446fa + + } + precvpriv->sink_udpport = sink_udpport; -+ ++ + return count; + +} @@ -341559,7 +341573,7 @@ index 00000000..cee446fa + int num = 0; + + _rtw_memset(btinfo, 0, 8); -+ ++ + num = sscanf(tmp, "%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx" + , &btinfo[0], &btinfo[1], &btinfo[2], &btinfo[3] + , &btinfo[4], &btinfo[5], &btinfo[6], &btinfo[7]); @@ -341571,7 +341585,7 @@ index 00000000..cee446fa + + rtw_btinfo_cmd(padapter, btinfo, btinfo[1]+2); + } -+ ++ + return count; +} + @@ -341853,7 +341867,7 @@ index 00000000..cee446fa + if (buffer && !copy_from_user(tmp, buffer, count)) { + + int num = sscanf(tmp, "%hhu", &acs_satae); -+ ++ + if (num < 1) + return -EINVAL; + @@ -341891,7 +341905,7 @@ index 00000000..cee446fa + {"ht_option", proc_get_ht_option, NULL}, + {"rf_info", proc_get_rf_info, NULL}, + {"scan_param", proc_get_scan_param, proc_set_scan_param}, -+ {"scan_abort", proc_get_scan_abort, NULL}, ++ {"scan_abort", proc_get_scan_abort, NULL}, +#ifdef CONFIG_SCAN_BACKOP + {"backop_flags_sta", proc_get_backop_flags_sta, proc_set_backop_flags_sta}, + {"backop_flags_ap", proc_get_backop_flags_ap, proc_set_backop_flags_ap}, @@ -341925,7 +341939,7 @@ index 00000000..cee446fa + {"mac_reg_dump", proc_get_mac_reg_dump, NULL}, + {"bb_reg_dump", proc_get_bb_reg_dump, NULL}, + {"rf_reg_dump", proc_get_rf_reg_dump, NULL}, -+ ++ +#ifdef CONFIG_AP_MODE + {"all_sta_info", proc_get_all_sta_info, NULL}, +#endif /* CONFIG_AP_MODE */ @@ -341949,7 +341963,7 @@ index 00000000..cee446fa + {"rx_ampdu", proc_get_rx_ampdu, proc_set_rx_ampdu}, + {"rx_ampdu_factor",proc_get_rx_ampdu_factor,proc_set_rx_ampdu_factor}, + {"rx_ampdu_density",proc_get_rx_ampdu_density,proc_set_rx_ampdu_density}, -+ {"tx_ampdu_density",proc_get_tx_ampdu_density,proc_set_tx_ampdu_density}, ++ {"tx_ampdu_density",proc_get_tx_ampdu_density,proc_set_tx_ampdu_density}, +#endif /* CONFIG_80211N_HT */ + + {"en_fwps", proc_get_en_fwps, proc_set_en_fwps}, @@ -342004,7 +342018,7 @@ index 00000000..cee446fa + {"sink_udpport",proc_get_udpport,proc_set_udpport}, +#ifdef DBG_RX_COUNTER_DUMP + {"dump_rx_cnt_mode",proc_get_rx_cnt_dump,proc_set_rx_cnt_dump}, -+#endif ++#endif + {"change_bss_chbw", NULL, proc_set_change_bss_chbw}, + {"target_tx_power", proc_get_target_tx_power, NULL}, + {"tx_power_by_rate", proc_get_tx_power_by_rate, NULL}, @@ -342061,6 +342075,15 @@ index 00000000..cee446fa + return -EROFS; +} + ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)) ++static const struct proc_ops rtw_adapter_proc_fops = { ++ .proc_open = rtw_adapter_proc_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_release = single_release, ++ .proc_write = rtw_adapter_proc_write, ++}; ++#else +static const struct file_operations rtw_adapter_proc_fops = { + .owner = THIS_MODULE, + .open = rtw_adapter_proc_open, @@ -342069,6 +342092,7 @@ index 00000000..cee446fa + .release = single_release, + .write = rtw_adapter_proc_write, +}; ++#endif + +int proc_get_odm_dbg_comp(struct seq_file *m, void *v) +{ @@ -342225,7 +342249,7 @@ index 00000000..cee446fa + + rtw_odm_adaptivity_parm_set(padapter, (s8)TH_L2H_ini, TH_EDCCA_HL_diff, (s8)TH_L2H_ini_mode2, TH_EDCCA_HL_diff_mode2, EDCCA_enable); + } -+ ++ + return count; +} + @@ -342328,13 +342352,22 @@ index 00000000..cee446fa + ssize_t index = (ssize_t)PDE_DATA(file_inode(file)); + const struct rtw_proc_hdl *hdl = odm_proc_hdls+index; + ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *, void *) = hdl->write; -+ ++ + if (write) + return write(file, buffer, count, pos, ((struct seq_file *)file->private_data)->private); + + return -EROFS; +} + ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)) ++static const struct proc_ops rtw_odm_proc_fops = { ++ .proc_open = rtw_odm_proc_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_release = single_release, ++ .proc_write = rtw_odm_proc_write, ++}; ++#else +static const struct file_operations rtw_odm_proc_fops = { + .owner = THIS_MODULE, + .open = rtw_odm_proc_open, @@ -342343,6 +342376,7 @@ index 00000000..cee446fa + .release = single_release, + .write = rtw_odm_proc_write, +}; ++#endif + +struct proc_dir_entry *rtw_odm_proc_init(struct net_device *dev) +{ diff --git a/patch/kernel/sunxi-current/xxx-add-bananapim2-zero-z2-HDMI-audio-out.patch b/patch/kernel/sunxi-current/xxx-add-bananapim2-zero-z2-HDMI-audio-out.patch index 4200a2312..1da6bc291 100644 --- a/patch/kernel/sunxi-current/xxx-add-bananapim2-zero-z2-HDMI-audio-out.patch +++ b/patch/kernel/sunxi-current/xxx-add-bananapim2-zero-z2-HDMI-audio-out.patch @@ -30,6 +30,6 @@ index 9051a1097258..0b702168981c 100644 + status = "okay"; +}; + -+&sound_hdmi { ++&hdmi_sound { + status = "okay"; +}; diff --git a/patch/kernel/sunxi-current/xxx-add-nanopi-r1-and-duo2.patch b/patch/kernel/sunxi-current/xxx-add-nanopi-r1-and-duo2.patch index f2fa900e9..02b5ba5e4 100644 --- a/patch/kernel/sunxi-current/xxx-add-nanopi-r1-and-duo2.patch +++ b/patch/kernel/sunxi-current/xxx-add-nanopi-r1-and-duo2.patch @@ -16,7 +16,7 @@ new file mode 100644 index 000000000..731c705a4 --- /dev/null +++ b/arch/arm/boot/dts/sun8i-h3-nanopi-r1.dts -@@ -0,0 +1,190 @@ +@@ -0,0 +1,170 @@ +/* + * Copyright (C) 2019 Igor Pecovnik + * @@ -88,22 +88,6 @@ index 000000000..731c705a4 + gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; + }; + -+ vdd_cpux: gpio-regulator { -+ compatible = "regulator-gpio"; -+ pinctrl-names = "default"; -+ regulator-name = "vdd-cpux"; -+ regulator-type = "voltage"; -+ regulator-boot-on; -+ regulator-always-on; -+ regulator-min-microvolt = <1100000>; -+ regulator-max-microvolt = <1300000>; -+ regulator-ramp-delay = <50>; /* 4ms */ -+ gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */ -+ gpios-states = <0x1>; -+ states = <1100000 0x0 -+ 1300000 0x1>; -+ }; -+ + leds { + /delete-node/ status; + /delete-node/ pwr; @@ -143,10 +127,6 @@ index 000000000..731c705a4 + }; +}; + -+&cpu0 { -+ cpu-supply = <&vdd_cpux>; -+}; -+ +&emac { + pinctrl-names = "default"; + pinctrl-0 = <&emac_rgmii_pins>; diff --git a/patch/kernel/sunxi-current/xxx-olinuxino-battery-audio.patch b/patch/kernel/sunxi-current/xxx-olinuxino-battery-audio.patch index 39f9a336c..834d4b43c 100644 --- a/patch/kernel/sunxi-current/xxx-olinuxino-battery-audio.patch +++ b/patch/kernel/sunxi-current/xxx-olinuxino-battery-audio.patch @@ -77,7 +77,7 @@ index 3792566cd..42b838b1f 100644 + "MIC2", "Internal Microphone Right"; +}; + -+&sound_hdmi { ++&hdmi_sound { + status = "okay"; +}; + diff --git a/patch/kernel/sunxi-current/xxx-teres-fixed.patch.disabled b/patch/kernel/sunxi-current/xxx-teres-fixed.patch.disabled new file mode 100644 index 000000000..3969f4517 --- /dev/null +++ b/patch/kernel/sunxi-current/xxx-teres-fixed.patch.disabled @@ -0,0 +1,155 @@ +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts +index 1069e70..8fbdab7 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts +@@ -19,6 +19,15 @@ + + aliases { + serial0 = &uart0; ++ ethernet0 = &rtl8723bs; ++ }; ++ ++ backlight: backlight { ++ compatible = "pwm-backlight"; ++ pwms = <&pwm 0 50000 0>; ++ brightness-levels = <0 5 10 15 20 30 40 55 70 85 100>; ++ default-brightness-level = <2>; ++ enable-gpios = <&pio 3 23 GPIO_ACTIVE_HIGH>; /* PD23 */ + }; + + backlight: backlight { +@@ -51,6 +60,17 @@ + }; + }; + ++ hdmi-connector { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ + leds { + compatible = "gpio-leds"; + +@@ -100,6 +120,16 @@ + status = "okay"; + }; + ++&de { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ phys = <&usbphy 0>; ++ phy-names = "usb"; ++ status = "okay"; ++}; ++ + &ehci1 { + status = "okay"; + }; +@@ -133,6 +163,21 @@ + }; + }; + ++&hdmi { ++ hvcc-supply = <®_dldo1>; ++ status = "okay"; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ ++&i2s2 { ++ status = "okay"; ++}; ++ + &mixer0 { + status = "okay"; + }; +@@ -153,6 +216,12 @@ + status = "okay"; + }; + ++&ohci0 { ++ phys = <&usbphy 0>; ++ phy-names = "usb"; ++ status = "okay"; ++}; ++ + &ohci1 { + status = "okay"; + }; +@@ -173,6 +242,29 @@ + }; + }; + ++&sound { ++ status = "okay"; ++ simple-audio-card,aux-devs = <&codec_analog>, <&speaker_amp>; ++ simple-audio-card,widgets = "Microphone", "Internal Microphone Left", ++ "Microphone", "Internal Microphone Right", ++ "Headphone", "Headphone Jack", ++ "Speaker", "Internal Speaker"; ++ simple-audio-card,routing = ++ "Left DAC", "AIF1 Slot 0 Left", ++ "Right DAC", "AIF1 Slot 0 Right", ++ "Speaker Amp INL", "LINEOUT", ++ "Speaker Amp INR", "LINEOUT", ++ "Internal Speaker", "Speaker Amp OUTL", ++ "Internal Speaker", "Speaker Amp OUTR", ++ "Headphone Jack", "HP", ++ "AIF1 Slot 0 Left ADC", "Left ADC", ++ "AIF1 Slot 0 Right ADC", "Right ADC", ++ "Internal Microphone Left", "MBIAS", ++ "MIC1", "Internal Microphone Left", ++ "Internal Microphone Right", "HBIAS", ++ "MIC2", "Internal Microphone Right"; ++}; ++ + #include "axp803.dtsi" + + &ac_power_supply { +@@ -319,12 +411,34 @@ + status = "okay"; + }; + ++&hdmi_sound { ++ status = "okay"; ++}; ++ + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pb_pins>; + status = "okay"; + }; + ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; ++ status = "okay"; ++ ++ bluetooth { ++ compatible = "realtek,rtl8723bs-bt"; ++ reset-gpios = <&r_pio 0 4 GPIO_ACTIVE_LOW>; /* PL4 */ ++ device-wake-gpios = <&r_pio 0 5 GPIO_ACTIVE_HIGH>; /* PL5 */ ++ host-wake-gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */ ++ firmware-postfix = "teres"; ++ }; ++}; ++ ++&usb_otg { ++ dr_mode = "host"; ++}; ++ + &usbphy { + usb1_vbus-supply = <®_usb1_vbus>; + status = "okay"; diff --git a/patch/kernel/sunxi-legacy/0000-0001-clk-sunxi-ng-Set-maximum-M-1-for-H3-pll-cpux-clock.patch b/patch/kernel/sunxi-legacy/0000-0001-clk-sunxi-ng-Set-maximum-M-1-for-H3-pll-cpux-clock.patch deleted file mode 100644 index be8172384..000000000 --- a/patch/kernel/sunxi-legacy/0000-0001-clk-sunxi-ng-Set-maximum-M-1-for-H3-pll-cpux-clock.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 5b367397da1947fcbf6ed1091c351808218e59bc Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Thu, 12 Jan 2017 16:34:57 +0100 -Subject: [PATCH 01/82] clk: sunxi-ng: Set maximum M = 1 for H3 pll-cpux clock - -When using M factor greater than 1 system is experiencing -occasional lockups. - -This change was verified to fix lockups with PLL stress -tester available at https://github.com/megous/h3-firmware. - -Note that M factor must not be used outside the kernel -either, so for example u-boot needs a similar patch. ---- - drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 24 +++++++++++++++--------- - 1 file changed, 15 insertions(+), 9 deletions(-) - -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c -index 77ed0b0ba681..8d47742def49 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c -@@ -30,15 +30,21 @@ - - #include "ccu-sun8i-h3.h" - --static SUNXI_CCU_NKMP_WITH_GATE_LOCK(pll_cpux_clk, "pll-cpux", -- "osc24M", 0x000, -- 8, 5, /* N */ -- 4, 2, /* K */ -- 0, 2, /* M */ -- 16, 2, /* P */ -- BIT(31), /* gate */ -- BIT(28), /* lock */ -- CLK_SET_RATE_UNGATE); -+static struct ccu_nkmp pll_cpux_clk = { -+ .enable = BIT(31), -+ .lock = BIT(28), -+ .n = _SUNXI_CCU_MULT(8, 5), -+ .k = _SUNXI_CCU_MULT(4, 2), -+ .m = _SUNXI_CCU_DIV_MAX(0, 2, 1), -+ .p = _SUNXI_CCU_DIV(16, 2), -+ .common = { -+ .reg = 0x000, -+ .hw.init = CLK_HW_INIT("pll-cpux", -+ "osc24M", -+ &ccu_nkmp_ops, -+ CLK_SET_RATE_UNGATE), -+ }, -+}; - - /* - * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0002-clk-sunxi-ng-Allow-to-limit-the-use-of-NKMP-clock-s-.patch b/patch/kernel/sunxi-legacy/0000-0002-clk-sunxi-ng-Allow-to-limit-the-use-of-NKMP-clock-s-.patch deleted file mode 100644 index 4c14bff6d..000000000 --- a/patch/kernel/sunxi-legacy/0000-0002-clk-sunxi-ng-Allow-to-limit-the-use-of-NKMP-clock-s-.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 9b15c5248e430f418621414f876170f08ca0a2cd Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Thu, 12 Jan 2017 16:37:24 +0100 -Subject: [PATCH 02/82] clk: sunxi-ng: Allow to limit the use of NKMP clock's P - factor - -Some SoCs mandate the maximum clock rate for which the use -of postdivider P factor is allowed. Allow to configure maximum -clock rate. - -Signed-off-by: Ondrej Jirman ---- - drivers/clk/sunxi-ng/ccu_nkmp.c | 13 ++++++++----- - drivers/clk/sunxi-ng/ccu_nkmp.h | 1 + - 2 files changed, 9 insertions(+), 5 deletions(-) - -diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c -index 1ad53d1016a3..080bf4a4ace6 100644 ---- a/drivers/clk/sunxi-ng/ccu_nkmp.c -+++ b/drivers/clk/sunxi-ng/ccu_nkmp.c -@@ -33,16 +33,19 @@ static unsigned long ccu_nkmp_calc_rate(unsigned long parent, - } - - static void ccu_nkmp_find_best(unsigned long parent, unsigned long rate, -- struct _ccu_nkmp *nkmp) -+ struct _ccu_nkmp *nkmp, struct ccu_nkmp *_nkmp) - { - unsigned long best_rate = 0; - unsigned long best_n = 0, best_k = 0, best_m = 0, best_p = 0; -- unsigned long _n, _k, _m, _p; -+ unsigned long _n, _k, _m, _p, _max_p; -+ -+ _max_p = (_nkmp->max_rate_for_p == 0 || rate <= _nkmp->max_rate_for_p) ? -+ nkmp->max_p : nkmp->min_p; - - for (_k = nkmp->min_k; _k <= nkmp->max_k; _k++) { - for (_n = nkmp->min_n; _n <= nkmp->max_n; _n++) { - for (_m = nkmp->min_m; _m <= nkmp->max_m; _m++) { -- for (_p = nkmp->min_p; _p <= nkmp->max_p; _p <<= 1) { -+ for (_p = nkmp->min_p; _p <= _max_p; _p <<= 1) { - unsigned long tmp_rate; - - tmp_rate = ccu_nkmp_calc_rate(parent, -@@ -146,7 +149,7 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, - _nkmp.min_p = 1; - _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1); - -- ccu_nkmp_find_best(*parent_rate, rate, &_nkmp); -+ ccu_nkmp_find_best(*parent_rate, rate, &_nkmp, nkmp); - - rate = ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k, - _nkmp.m, _nkmp.p); -@@ -177,7 +180,7 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, - _nkmp.min_p = 1; - _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1); - -- ccu_nkmp_find_best(parent_rate, rate, &_nkmp); -+ ccu_nkmp_find_best(parent_rate, rate, &_nkmp, nkmp); - - if (nkmp->n.width) - n_mask = GENMASK(nkmp->n.width + nkmp->n.shift - 1, -diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.h b/drivers/clk/sunxi-ng/ccu_nkmp.h -index 6940503e7fc4..bbea3e5ed6fb 100644 ---- a/drivers/clk/sunxi-ng/ccu_nkmp.h -+++ b/drivers/clk/sunxi-ng/ccu_nkmp.h -@@ -33,6 +33,7 @@ struct ccu_nkmp { - struct ccu_mult_internal k; - struct ccu_div_internal m; - struct ccu_div_internal p; -+ unsigned long max_rate_for_p; - - unsigned int fixed_post_div; - --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0003-clk-sunxi-ng-Limit-pll_cpux-P-factor-for-rates-288MH.patch b/patch/kernel/sunxi-legacy/0000-0003-clk-sunxi-ng-Limit-pll_cpux-P-factor-for-rates-288MH.patch deleted file mode 100644 index 6fb8fdf96..000000000 --- a/patch/kernel/sunxi-legacy/0000-0003-clk-sunxi-ng-Limit-pll_cpux-P-factor-for-rates-288MH.patch +++ /dev/null @@ -1,29 +0,0 @@ -From d46f1f53618ceffa33a5920802a9247337fd3ff3 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Wed, 5 Apr 2017 15:43:48 +0200 -Subject: [PATCH 03/82] clk: sunxi-ng: Limit pll_cpux P factor for rates > - 288MHz on H3 - -Datasheet for H3 mandates that CPUX PLL must not use postdivider -(P factor must be 1) for clock rates above 288MHz. - -Signed-off-by: Ondrej Jirman ---- - drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c -index 8d47742def49..7cc9467f373f 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c -@@ -37,6 +37,7 @@ static struct ccu_nkmp pll_cpux_clk = { - .k = _SUNXI_CCU_MULT(4, 2), - .m = _SUNXI_CCU_DIV_MAX(0, 2, 1), - .p = _SUNXI_CCU_DIV(16, 2), -+ .max_rate_for_p = 288000000, - .common = { - .reg = 0x000, - .hw.init = CLK_HW_INIT("pll-cpux", --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0004-thermal-sun8i_ths-Add-support-for-the-thermal-sensor.patch b/patch/kernel/sunxi-legacy/0000-0004-thermal-sun8i_ths-Add-support-for-the-thermal-sensor.patch deleted file mode 100644 index 8d38b5dda..000000000 --- a/patch/kernel/sunxi-legacy/0000-0004-thermal-sun8i_ths-Add-support-for-the-thermal-sensor.patch +++ /dev/null @@ -1,295 +0,0 @@ -From e4092ba9553a4680f2b28334f87e2c97a084f95e Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sat, 25 Jun 2016 21:51:05 +0200 -Subject: [PATCH 04/82] thermal: sun8i_ths: Add support for the thermal sensor - on Allwinner H3 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch adds support for the sun8i thermal sensor on -Allwinner H3 SoC. - -Signed-off-by: Ondřej Jirman ---- - drivers/thermal/Kconfig | 7 ++ - drivers/thermal/Makefile | 1 + - drivers/thermal/sun8i_ths.c | 239 ++++++++++++++++++++++++++++++++++++ - 3 files changed, 247 insertions(+) - create mode 100644 drivers/thermal/sun8i_ths.c - -diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig -index 0e69edc77d18..5125c5e8f7ce 100644 ---- a/drivers/thermal/Kconfig -+++ b/drivers/thermal/Kconfig -@@ -420,6 +420,13 @@ depends on ARCH_BCM || ARCH_BRCMSTB || ARCH_BCM2835 || COMPILE_TEST - source "drivers/thermal/broadcom/Kconfig" - endmenu - -+config SUN8I_THS -+ tristate "Thermal sensor driver for Allwinner H3" -+ depends on MACH_SUN8I || (ARM64 && ARCH_SUNXI) -+ depends on OF -+ help -+ Enable this to support thermal reporting on some newer Allwinner SoCs. -+ - menu "Texas Instruments thermal drivers" - depends on ARCH_HAS_BANDGAP || COMPILE_TEST - depends on HAS_IOMEM -diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile -index 610344eb3e03..dc8a24fddba9 100644 ---- a/drivers/thermal/Makefile -+++ b/drivers/thermal/Makefile -@@ -61,3 +61,4 @@ obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o - obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o - obj-$(CONFIG_ZX2967_THERMAL) += zx2967_thermal.o - obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o -+obj-$(CONFIG_SUN8I_THS) += sun8i_ths.o -diff --git a/drivers/thermal/sun8i_ths.c b/drivers/thermal/sun8i_ths.c -new file mode 100644 -index 000000000000..cfe7d1073b8c ---- /dev/null -+++ b/drivers/thermal/sun8i_ths.c -@@ -0,0 +1,239 @@ -+/* -+ * Thermal sensor driver for Allwinner H3 SoC -+ * -+ * Copyright (C) 2016 Ondřej Jirman -+ * Based on the work of Josef Gajdusek -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define THS_H3_CTRL0 0x00 -+#define THS_H3_CTRL2 0x40 -+#define THS_H3_INT_CTRL 0x44 -+#define THS_H3_STAT 0x48 -+#define THS_H3_FILTER 0x70 -+#define THS_H3_CDATA 0x74 -+#define THS_H3_DATA 0x80 -+ -+#define THS_H3_CTRL0_SENSOR_ACQ0(x) (x) -+#define THS_H3_CTRL2_SENSE_EN BIT(0) -+#define THS_H3_CTRL2_SENSOR_ACQ1(x) ((x) << 16) -+#define THS_H3_INT_CTRL_DATA_IRQ_EN BIT(8) -+#define THS_H3_INT_CTRL_THERMAL_PER(x) ((x) << 12) -+#define THS_H3_STAT_DATA_IRQ_STS BIT(8) -+#define THS_H3_FILTER_TYPE(x) ((x) << 0) -+#define THS_H3_FILTER_EN BIT(2) -+ -+#define THS_H3_CLK_IN 40000000 /* Hz */ -+#define THS_H3_DATA_PERIOD 330 /* ms */ -+ -+#define THS_H3_FILTER_TYPE_VALUE 2 /* average over 2^(n+1) samples */ -+#define THS_H3_FILTER_DIV (1 << (THS_H3_FILTER_TYPE_VALUE + 1)) -+#define THS_H3_INT_CTRL_THERMAL_PER_VALUE \ -+ (THS_H3_DATA_PERIOD * (THS_H3_CLK_IN / 1000) / THS_H3_FILTER_DIV / 4096 - 1) -+#define THS_H3_CTRL0_SENSOR_ACQ0_VALUE 0x3f /* 16us */ -+#define THS_H3_CTRL2_SENSOR_ACQ1_VALUE 0x3f -+ -+struct sun8i_ths_data { -+ struct reset_control *reset; -+ struct clk *clk; -+ struct clk *busclk; -+ void __iomem *regs; -+ struct thermal_zone_device *tzd; -+ u32 temp; -+}; -+ -+static int sun8i_ths_get_temp(void *_data, int *out) -+{ -+ struct sun8i_ths_data *data = _data; -+ -+ if (data->temp == 0) -+ return -EBUSY; -+ -+ /* Formula and parameters from the Allwinner 3.4 kernel */ -+ *out = 217000 - (int)((data->temp * 1000000) / 8253); -+ return 0; -+} -+ -+static irqreturn_t sun8i_ths_irq_thread(int irq, void *_data) -+{ -+ struct sun8i_ths_data *data = _data; -+ -+ writel(THS_H3_STAT_DATA_IRQ_STS, data->regs + THS_H3_STAT); -+ -+ data->temp = readl(data->regs + THS_H3_DATA); -+ if (data->temp) -+ thermal_zone_device_update(data->tzd, THERMAL_EVENT_TEMP_SAMPLE); -+ -+ return IRQ_HANDLED; -+} -+ -+static void sun8i_ths_h3_init(struct sun8i_ths_data *data) -+{ -+ writel(THS_H3_CTRL0_SENSOR_ACQ0(THS_H3_CTRL0_SENSOR_ACQ0_VALUE), -+ data->regs + THS_H3_CTRL0); -+ writel(THS_H3_FILTER_EN | THS_H3_FILTER_TYPE(THS_H3_FILTER_TYPE_VALUE), -+ data->regs + THS_H3_FILTER); -+ writel(THS_H3_CTRL2_SENSOR_ACQ1(THS_H3_CTRL2_SENSOR_ACQ1_VALUE) | -+ THS_H3_CTRL2_SENSE_EN, -+ data->regs + THS_H3_CTRL2); -+ writel(THS_H3_INT_CTRL_THERMAL_PER(THS_H3_INT_CTRL_THERMAL_PER_VALUE) | -+ THS_H3_INT_CTRL_DATA_IRQ_EN, -+ data->regs + THS_H3_INT_CTRL); -+} -+ -+static const struct thermal_zone_of_device_ops sun8i_ths_thermal_ops = { -+ .get_temp = sun8i_ths_get_temp, -+}; -+ -+static int sun8i_ths_probe(struct platform_device *pdev) -+{ -+ struct sun8i_ths_data *data; -+ struct resource *res; -+ int ret; -+ int irq; -+ -+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "no memory resources defined\n"); -+ return -EINVAL; -+ } -+ -+ data->regs = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(data->regs)) { -+ ret = PTR_ERR(data->regs); -+ dev_err(&pdev->dev, "failed to ioremap THS registers: %d\n", ret); -+ return ret; -+ } -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) { -+ dev_err(&pdev->dev, "failed to get IRQ: %d\n", irq); -+ return irq; -+ } -+ -+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, -+ sun8i_ths_irq_thread, IRQF_ONESHOT, -+ dev_name(&pdev->dev), data); -+ if (ret) -+ return ret; -+ -+ data->busclk = devm_clk_get(&pdev->dev, "ahb"); -+ if (IS_ERR(data->busclk)) { -+ ret = PTR_ERR(data->busclk); -+ dev_err(&pdev->dev, "failed to get ahb clk: %d\n", ret); -+ return ret; -+ } -+ -+ data->clk = devm_clk_get(&pdev->dev, "ths"); -+ if (IS_ERR(data->clk)) { -+ ret = PTR_ERR(data->clk); -+ dev_err(&pdev->dev, "failed to get ths clk: %d\n", ret); -+ return ret; -+ } -+ -+ data->reset = devm_reset_control_get(&pdev->dev, "ahb"); -+ if (IS_ERR(data->reset)) { -+ ret = PTR_ERR(data->reset); -+ dev_err(&pdev->dev, "failed to get reset: %d\n", ret); -+ return ret; -+ } -+ -+ ret = reset_control_deassert(data->reset); -+ if (ret) { -+ dev_err(&pdev->dev, "reset deassert failed: %d\n", ret); -+ return ret; -+ } -+ -+ ret = clk_prepare_enable(data->busclk); -+ if (ret) { -+ dev_err(&pdev->dev, "failed to enable bus clk: %d\n", ret); -+ goto err_assert_reset; -+ } -+ -+ ret = clk_prepare_enable(data->clk); -+ if (ret) { -+ dev_err(&pdev->dev, "failed to enable ths clk: %d\n", ret); -+ goto err_disable_bus; -+ } -+ -+ ret = clk_set_rate(data->clk, THS_H3_CLK_IN); -+ if (ret) -+ goto err_disable_ths; -+ -+ data->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, data, -+ &sun8i_ths_thermal_ops); -+ if (IS_ERR(data->tzd)) { -+ ret = PTR_ERR(data->tzd); -+ dev_err(&pdev->dev, "failed to register thermal zone: %d\n", -+ ret); -+ goto err_disable_ths; -+ } -+ -+ sun8i_ths_h3_init(data); -+ -+ platform_set_drvdata(pdev, data); -+ return 0; -+ -+err_disable_ths: -+ clk_disable_unprepare(data->clk); -+err_disable_bus: -+ clk_disable_unprepare(data->busclk); -+err_assert_reset: -+ reset_control_assert(data->reset); -+ return ret; -+} -+ -+static int sun8i_ths_remove(struct platform_device *pdev) -+{ -+ struct sun8i_ths_data *data = platform_get_drvdata(pdev); -+ -+ reset_control_assert(data->reset); -+ clk_disable_unprepare(data->clk); -+ clk_disable_unprepare(data->busclk); -+ return 0; -+} -+ -+static const struct of_device_id sun8i_ths_id_table[] = { -+ { .compatible = "allwinner,sun8i-h3-ths", }, -+ { /* sentinel */ }, -+}; -+MODULE_DEVICE_TABLE(of, sun8i_ths_id_table); -+ -+static struct platform_driver sun8i_ths_driver = { -+ .probe = sun8i_ths_probe, -+ .remove = sun8i_ths_remove, -+ .driver = { -+ .name = "sun8i_ths", -+ .of_match_table = sun8i_ths_id_table, -+ }, -+}; -+ -+module_platform_driver(sun8i_ths_driver); -+ -+MODULE_AUTHOR("Ondřej Jirman "); -+MODULE_DESCRIPTION("Thermal sensor driver for Allwinner H3 SoC"); -+MODULE_LICENSE("GPL v2"); --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0005-thermal-sun8i-Add-support-for-A83T-thermal-sensors.patch b/patch/kernel/sunxi-legacy/0000-0005-thermal-sun8i-Add-support-for-A83T-thermal-sensors.patch deleted file mode 100644 index 4707269d6..000000000 --- a/patch/kernel/sunxi-legacy/0000-0005-thermal-sun8i-Add-support-for-A83T-thermal-sensors.patch +++ /dev/null @@ -1,498 +0,0 @@ -From 9da4c28e6a7963f67e2ca05098683445a1571538 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Tue, 14 Nov 2017 17:15:54 +0100 -Subject: [PATCH 05/82] thermal: sun8i: Add support for A83T thermal sensors - -Signed-off-by: Ondrej Jirman ---- - drivers/thermal/sun8i_ths.c | 371 ++++++++++++++++++++++++++---------- - 1 file changed, 274 insertions(+), 97 deletions(-) - -diff --git a/drivers/thermal/sun8i_ths.c b/drivers/thermal/sun8i_ths.c -index cfe7d1073b8c..2fda940da4cc 100644 ---- a/drivers/thermal/sun8i_ths.c -+++ b/drivers/thermal/sun8i_ths.c -@@ -1,5 +1,5 @@ - /* -- * Thermal sensor driver for Allwinner H3 SoC -+ * Thermal sensor driver for Allwinner SUN8I SoC - * - * Copyright (C) 2016 Ondřej Jirman - * Based on the work of Josef Gajdusek -@@ -26,79 +26,174 @@ - #include - #include - --#define THS_H3_CTRL0 0x00 --#define THS_H3_CTRL2 0x40 --#define THS_H3_INT_CTRL 0x44 --#define THS_H3_STAT 0x48 --#define THS_H3_FILTER 0x70 --#define THS_H3_CDATA 0x74 --#define THS_H3_DATA 0x80 -- --#define THS_H3_CTRL0_SENSOR_ACQ0(x) (x) --#define THS_H3_CTRL2_SENSE_EN BIT(0) --#define THS_H3_CTRL2_SENSOR_ACQ1(x) ((x) << 16) --#define THS_H3_INT_CTRL_DATA_IRQ_EN BIT(8) --#define THS_H3_INT_CTRL_THERMAL_PER(x) ((x) << 12) --#define THS_H3_STAT_DATA_IRQ_STS BIT(8) --#define THS_H3_FILTER_TYPE(x) ((x) << 0) --#define THS_H3_FILTER_EN BIT(2) -- --#define THS_H3_CLK_IN 40000000 /* Hz */ --#define THS_H3_DATA_PERIOD 330 /* ms */ -- --#define THS_H3_FILTER_TYPE_VALUE 2 /* average over 2^(n+1) samples */ --#define THS_H3_FILTER_DIV (1 << (THS_H3_FILTER_TYPE_VALUE + 1)) --#define THS_H3_INT_CTRL_THERMAL_PER_VALUE \ -- (THS_H3_DATA_PERIOD * (THS_H3_CLK_IN / 1000) / THS_H3_FILTER_DIV / 4096 - 1) --#define THS_H3_CTRL0_SENSOR_ACQ0_VALUE 0x3f /* 16us */ --#define THS_H3_CTRL2_SENSOR_ACQ1_VALUE 0x3f -+#define THS_SUN8I_CTRL0 0x00 -+#define THS_SUN8I_CTRL2 0x40 -+#define THS_SUN8I_INT_CTRL 0x44 -+#define THS_SUN8I_STAT 0x48 -+#define THS_SUN8I_FILTER 0x70 -+#define THS_SUN8I_CDATA01 0x74 -+#define THS_SUN8I_CDATA2 0x78 -+#define THS_SUN8I_DATA0 0x80 -+#define THS_SUN8I_DATA1 0x84 -+#define THS_SUN8I_DATA2 0x88 -+ -+#define THS_SUN8I_CTRL0_SENSOR_ACQ0(x) (x) -+#define THS_SUN8I_CTRL2_SENSE_EN0 BIT(0) -+#define THS_SUN8I_CTRL2_SENSE_EN1 BIT(1) -+#define THS_SUN8I_CTRL2_SENSE_EN2 BIT(2) -+#define THS_SUN8I_CTRL2_SENSOR_ACQ1(x) ((x) << 16) -+#define THS_SUN8I_INT_CTRL_DATA0_IRQ_EN BIT(8) -+#define THS_SUN8I_INT_CTRL_DATA1_IRQ_EN BIT(9) -+#define THS_SUN8I_INT_CTRL_DATA2_IRQ_EN BIT(10) -+#define THS_SUN8I_INT_CTRL_THERMAL_PER(x) ((x) << 12) -+#define THS_SUN8I_STAT_DATA0_IRQ_STS BIT(8) -+#define THS_SUN8I_STAT_DATA1_IRQ_STS BIT(9) -+#define THS_SUN8I_STAT_DATA2_IRQ_STS BIT(10) -+#define THS_SUN8I_STAT_CLEAR 0x777 -+#define THS_SUN8I_FILTER_TYPE(x) ((x) << 0) -+#define THS_SUN8I_FILTER_EN BIT(2) -+ -+#define THS_SUN8I_CLK_IN 40000000 /* Hz */ -+#define THS_SUN8I_DATA_PERIOD 330 /* ms */ -+#define THS_SUN8I_FILTER_TYPE_VALUE 2 /* average over 2^(n+1) samples */ -+ -+//XXX: this formula doesn't work for A83T very well -+//XXX: A83T is getting slower readings out of this (1s interval?) -+//perhaps configure this in sun8i_ths_desc -+#define THS_SUN8I_FILTER_DIV (1 << (THS_SUN8I_FILTER_TYPE_VALUE + 1)) -+#define THS_SUN8I_INT_CTRL_THERMAL_PER_VALUE \ -+ (THS_SUN8I_DATA_PERIOD * (THS_SUN8I_CLK_IN / 1000) / \ -+ THS_SUN8I_FILTER_DIV / 4096 - 1) -+ -+#define THS_SUN8I_CTRL0_SENSOR_ACQ0_VALUE 0x3f /* 16us */ -+#define THS_SUN8I_CTRL2_SENSOR_ACQ1_VALUE 0x3f -+ -+#define SUN8I_THS_MAX_TZDS 3 -+ -+struct sun8i_ths_sensor_desc { -+ u32 data_int_en; -+ u32 data_int_flag; -+ u32 data_offset; -+ u32 sense_en; -+}; -+ -+struct sun8i_ths_desc { -+ int num_sensors; -+ struct sun8i_ths_sensor_desc *sensors; -+ int (*calc_temp)(u32 reg_val); -+ bool has_cal1; -+}; -+ -+struct sun8i_ths_tzd { -+ struct sun8i_ths_data *data; -+ struct thermal_zone_device *tzd; -+ u32 temp; -+}; - - struct sun8i_ths_data { -+ struct device *dev; - struct reset_control *reset; - struct clk *clk; - struct clk *busclk; - void __iomem *regs; -- struct thermal_zone_device *tzd; -- u32 temp; -+ void __iomem *cal_regs; -+ struct sun8i_ths_desc *desc; -+ struct sun8i_ths_tzd tzds[SUN8I_THS_MAX_TZDS]; - }; - -+static int sun8i_ths_calc_temp_h3(u32 reg_val) -+{ -+ uint64_t temp = (uint64_t)reg_val * 1000000ll; -+ -+ do_div(temp, 8253); -+ -+ return 217000 - (int)temp; -+} -+ -+static int sun8i_ths_calc_temp_a83t(u32 reg_val) -+{ -+ uint64_t temp = (uint64_t)reg_val * 1000000ll; -+ -+ do_div(temp, 14186); -+ -+ return 192000 - (int)temp; -+} -+ - static int sun8i_ths_get_temp(void *_data, int *out) - { -- struct sun8i_ths_data *data = _data; -+ struct sun8i_ths_tzd *tzd = _data; -+ struct sun8i_ths_data *data = tzd->data; - -- if (data->temp == 0) -+ if (tzd->temp == 0) - return -EBUSY; - -- /* Formula and parameters from the Allwinner 3.4 kernel */ -- *out = 217000 - (int)((data->temp * 1000000) / 8253); -+ *out = data->desc->calc_temp(tzd->temp); - return 0; - } - - static irqreturn_t sun8i_ths_irq_thread(int irq, void *_data) - { - struct sun8i_ths_data *data = _data; -- -- writel(THS_H3_STAT_DATA_IRQ_STS, data->regs + THS_H3_STAT); -- -- data->temp = readl(data->regs + THS_H3_DATA); -- if (data->temp) -- thermal_zone_device_update(data->tzd, THERMAL_EVENT_TEMP_SAMPLE); -+ struct sun8i_ths_tzd *tzd; -+ struct sun8i_ths_sensor_desc *zdesc; -+ int i; -+ u32 status; -+ -+ status = readl(data->regs + THS_SUN8I_STAT); -+ writel(THS_SUN8I_STAT_CLEAR, data->regs + THS_SUN8I_STAT); -+ -+ for (i = 0; i < data->desc->num_sensors; i++) { -+ tzd = &data->tzds[i]; -+ zdesc = &data->desc->sensors[i]; -+ -+ if (status & zdesc->data_int_flag) { -+ tzd->temp = readl(data->regs + zdesc->data_offset); -+ if (tzd->temp) -+ thermal_zone_device_update(tzd->tzd, -+ THERMAL_EVENT_TEMP_SAMPLE); -+ } -+ } - - return IRQ_HANDLED; - } - --static void sun8i_ths_h3_init(struct sun8i_ths_data *data) -+static void sun8i_ths_init(struct sun8i_ths_data *data) - { -- writel(THS_H3_CTRL0_SENSOR_ACQ0(THS_H3_CTRL0_SENSOR_ACQ0_VALUE), -- data->regs + THS_H3_CTRL0); -- writel(THS_H3_FILTER_EN | THS_H3_FILTER_TYPE(THS_H3_FILTER_TYPE_VALUE), -- data->regs + THS_H3_FILTER); -- writel(THS_H3_CTRL2_SENSOR_ACQ1(THS_H3_CTRL2_SENSOR_ACQ1_VALUE) | -- THS_H3_CTRL2_SENSE_EN, -- data->regs + THS_H3_CTRL2); -- writel(THS_H3_INT_CTRL_THERMAL_PER(THS_H3_INT_CTRL_THERMAL_PER_VALUE) | -- THS_H3_INT_CTRL_DATA_IRQ_EN, -- data->regs + THS_H3_INT_CTRL); -+ int i; -+ u32 int_ctrl = 0; -+ u32 ctrl2 = 0; -+ -+ writel(THS_SUN8I_CTRL0_SENSOR_ACQ0(THS_SUN8I_CTRL0_SENSOR_ACQ0_VALUE), -+ data->regs + THS_SUN8I_CTRL0); -+ writel(THS_SUN8I_FILTER_EN | THS_SUN8I_FILTER_TYPE(THS_SUN8I_FILTER_TYPE_VALUE), -+ data->regs + THS_SUN8I_FILTER); -+ -+ ctrl2 |= THS_SUN8I_CTRL2_SENSOR_ACQ1(THS_SUN8I_CTRL2_SENSOR_ACQ1_VALUE); -+ int_ctrl |= THS_SUN8I_INT_CTRL_THERMAL_PER(THS_SUN8I_INT_CTRL_THERMAL_PER_VALUE); -+ -+ for (i = 0; i < data->desc->num_sensors; i++) { -+ ctrl2 |= data->desc->sensors[i].sense_en; -+ int_ctrl |= data->desc->sensors[i].data_int_en; -+ } -+ -+ if (data->cal_regs) { -+ u32 cal0, cal1; -+ -+ cal0 = readl(data->cal_regs); -+ if (cal0) -+ writel(cal0, data->regs + THS_SUN8I_CDATA01); -+ -+ if (data->desc->has_cal1) { -+ cal1 = readl(data->cal_regs + 4); -+ if (cal1) -+ writel(cal1, data->regs + THS_SUN8I_CDATA2); -+ } -+ } -+ -+ writel(ctrl2, data->regs + THS_SUN8I_CTRL2); -+ -+ /* enable interrupts */ -+ writel(int_ctrl, data->regs + THS_SUN8I_INT_CTRL); - } - - static const struct thermal_zone_of_device_ops sun8i_ths_thermal_ops = { -@@ -108,100 +203,135 @@ static const struct thermal_zone_of_device_ops sun8i_ths_thermal_ops = { - static int sun8i_ths_probe(struct platform_device *pdev) - { - struct sun8i_ths_data *data; -+ struct device *dev = &pdev->dev; - struct resource *res; -- int ret; -- int irq; -+ int ret, irq, i; - -- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); -+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ data->desc = (struct sun8i_ths_desc *)of_device_get_match_data(dev); -+ if (data->desc == NULL) -+ return -EINVAL; -+ -+ data->dev = dev; -+ platform_set_drvdata(pdev, data); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ths"); - if (!res) { -- dev_err(&pdev->dev, "no memory resources defined\n"); -+ dev_err(dev, "no memory resources defined\n"); - return -EINVAL; - } - -- data->regs = devm_ioremap_resource(&pdev->dev, res); -+ data->regs = devm_ioremap_resource(dev, res); - if (IS_ERR(data->regs)) { - ret = PTR_ERR(data->regs); -- dev_err(&pdev->dev, "failed to ioremap THS registers: %d\n", ret); -+ dev_err(dev, "failed to ioremap THS registers: %d\n", ret); - return ret; - } - -+ /*XXX: use SRAM device in the future, instead of direct access to regs */ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "calibration"); -+ if (res) { -+ data->cal_regs = devm_ioremap_resource(dev, res); -+ if (IS_ERR(data->cal_regs)) { -+ ret = PTR_ERR(data->cal_regs); -+ dev_err(dev, "failed to ioremap calibration SRAM: %d\n", ret); -+ return ret; -+ } -+ } -+ - irq = platform_get_irq(pdev, 0); - if (irq < 0) { -- dev_err(&pdev->dev, "failed to get IRQ: %d\n", irq); -+ dev_err(dev, "failed to get IRQ: %d\n", irq); - return irq; - } - -- ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, -+ ret = devm_request_threaded_irq(dev, irq, NULL, - sun8i_ths_irq_thread, IRQF_ONESHOT, -- dev_name(&pdev->dev), data); -+ dev_name(dev), data); - if (ret) - return ret; - -- data->busclk = devm_clk_get(&pdev->dev, "ahb"); -+ data->busclk = devm_clk_get(dev, "ahb"); - if (IS_ERR(data->busclk)) { - ret = PTR_ERR(data->busclk); -- dev_err(&pdev->dev, "failed to get ahb clk: %d\n", ret); -- return ret; -+ if (ret != -ENOENT) { -+ dev_err(dev, "failed to get ahb clk: %d\n", ret); -+ return ret; -+ } -+ -+ data->busclk = NULL; - } - -- data->clk = devm_clk_get(&pdev->dev, "ths"); -+ data->clk = devm_clk_get(dev, "ths"); - if (IS_ERR(data->clk)) { - ret = PTR_ERR(data->clk); -- dev_err(&pdev->dev, "failed to get ths clk: %d\n", ret); -- return ret; -+ if (ret != -ENOENT) { -+ dev_err(dev, "failed to get ths clk: %d\n", ret); -+ return ret; -+ } -+ -+ data->clk = NULL; - } - -- data->reset = devm_reset_control_get(&pdev->dev, "ahb"); -+ data->reset = devm_reset_control_get_optional(dev, "ahb"); - if (IS_ERR(data->reset)) { - ret = PTR_ERR(data->reset); -- dev_err(&pdev->dev, "failed to get reset: %d\n", ret); -+ dev_err(dev, "failed to get reset: %d\n", ret); - return ret; - } - - ret = reset_control_deassert(data->reset); - if (ret) { -- dev_err(&pdev->dev, "reset deassert failed: %d\n", ret); -+ dev_err(dev, "reset deassert failed: %d\n", ret); - return ret; - } - -- ret = clk_prepare_enable(data->busclk); -- if (ret) { -- dev_err(&pdev->dev, "failed to enable bus clk: %d\n", ret); -- goto err_assert_reset; -+ if (data->busclk) { -+ ret = clk_prepare_enable(data->busclk); -+ if (ret) { -+ dev_err(dev, "failed to enable bus clk: %d\n", ret); -+ goto err_assert_reset; -+ } - } - -- ret = clk_prepare_enable(data->clk); -- if (ret) { -- dev_err(&pdev->dev, "failed to enable ths clk: %d\n", ret); -- goto err_disable_bus; -- } -+ if (data->clk) { -+ ret = clk_prepare_enable(data->clk); -+ if (ret) { -+ dev_err(dev, "failed to enable ths clk: %d\n", ret); -+ goto err_disable_bus; -+ } - -- ret = clk_set_rate(data->clk, THS_H3_CLK_IN); -- if (ret) -- goto err_disable_ths; -- -- data->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, data, -- &sun8i_ths_thermal_ops); -- if (IS_ERR(data->tzd)) { -- ret = PTR_ERR(data->tzd); -- dev_err(&pdev->dev, "failed to register thermal zone: %d\n", -- ret); -- goto err_disable_ths; -+ ret = clk_set_rate(data->clk, THS_SUN8I_CLK_IN); -+ if (ret) -+ goto err_disable_ths; - } - -- sun8i_ths_h3_init(data); -+ for (i = 0; i < data->desc->num_sensors; i++) { -+ data->tzds[i].data = data; -+ data->tzds[i].tzd = -+ devm_thermal_zone_of_sensor_register(dev, i, -+ &data->tzds[i], -+ &sun8i_ths_thermal_ops); -+ if (IS_ERR(data->tzds[i].tzd)) { -+ ret = PTR_ERR(data->tzds[i].tzd); -+ dev_err(dev, -+ "failed to register thermal zone: %d\n", ret); -+ goto err_disable_ths; -+ } -+ } - -- platform_set_drvdata(pdev, data); -+ sun8i_ths_init(data); - return 0; - - err_disable_ths: -- clk_disable_unprepare(data->clk); -+ if (data->clk) -+ clk_disable_unprepare(data->clk); - err_disable_bus: -- clk_disable_unprepare(data->busclk); -+ if (data->busclk) -+ clk_disable_unprepare(data->busclk); - err_assert_reset: - reset_control_assert(data->reset); - return ret; -@@ -212,13 +342,60 @@ static int sun8i_ths_remove(struct platform_device *pdev) - struct sun8i_ths_data *data = platform_get_drvdata(pdev); - - reset_control_assert(data->reset); -- clk_disable_unprepare(data->clk); -- clk_disable_unprepare(data->busclk); -+ if (data->clk) -+ clk_disable_unprepare(data->clk); -+ if (data->busclk) -+ clk_disable_unprepare(data->busclk); - return 0; - } - -+struct sun8i_ths_sensor_desc sun8i_ths_h3_sensors[] = { -+ { -+ .data_int_en = THS_SUN8I_INT_CTRL_DATA0_IRQ_EN, -+ .data_int_flag = THS_SUN8I_STAT_DATA0_IRQ_STS, -+ .data_offset = THS_SUN8I_DATA0, -+ .sense_en = THS_SUN8I_CTRL2_SENSE_EN0, -+ }, -+}; -+ -+struct sun8i_ths_sensor_desc sun8i_ths_a83t_sensors[] = { -+ { -+ .data_int_en = THS_SUN8I_INT_CTRL_DATA0_IRQ_EN, -+ .data_int_flag = THS_SUN8I_STAT_DATA0_IRQ_STS, -+ .data_offset = THS_SUN8I_DATA0, -+ .sense_en = THS_SUN8I_CTRL2_SENSE_EN0, -+ }, -+ { -+ .data_int_en = THS_SUN8I_INT_CTRL_DATA1_IRQ_EN, -+ .data_int_flag = THS_SUN8I_STAT_DATA1_IRQ_STS, -+ .data_offset = THS_SUN8I_DATA1, -+ .sense_en = THS_SUN8I_CTRL2_SENSE_EN1, -+ }, -+ { -+ .data_int_en = THS_SUN8I_INT_CTRL_DATA2_IRQ_EN, -+ .data_int_flag = THS_SUN8I_STAT_DATA2_IRQ_STS, -+ .data_offset = THS_SUN8I_DATA2, -+ .sense_en = THS_SUN8I_CTRL2_SENSE_EN2, -+ }, -+}; -+ -+static const struct sun8i_ths_desc sun8i_ths_h3_desc = { -+ .num_sensors = ARRAY_SIZE(sun8i_ths_h3_sensors), -+ .sensors = sun8i_ths_h3_sensors, -+ .calc_temp = sun8i_ths_calc_temp_h3, -+ .has_cal1 = false, -+}; -+ -+static const struct sun8i_ths_desc sun8i_ths_a83t_desc = { -+ .num_sensors = ARRAY_SIZE(sun8i_ths_a83t_sensors), -+ .sensors = sun8i_ths_a83t_sensors, -+ .calc_temp = sun8i_ths_calc_temp_a83t, -+ .has_cal1 = true, -+}; -+ - static const struct of_device_id sun8i_ths_id_table[] = { -- { .compatible = "allwinner,sun8i-h3-ths", }, -+ { .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_ths_h3_desc }, -+ { .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_ths_a83t_desc }, - { /* sentinel */ }, - }; - MODULE_DEVICE_TABLE(of, sun8i_ths_id_table); -@@ -235,5 +412,5 @@ static struct platform_driver sun8i_ths_driver = { - module_platform_driver(sun8i_ths_driver); - - MODULE_AUTHOR("Ondřej Jirman "); --MODULE_DESCRIPTION("Thermal sensor driver for Allwinner H3 SoC"); -+MODULE_DESCRIPTION("Thermal sensor driver for Allwinner SUN8I SoCs"); - MODULE_LICENSE("GPL v2"); --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0006-dt-bindings-document-sun8i_ths-H3-thermal-sensor-dri.patch b/patch/kernel/sunxi-legacy/0000-0006-dt-bindings-document-sun8i_ths-H3-thermal-sensor-dri.patch deleted file mode 100644 index 8e3f1ee1d..000000000 --- a/patch/kernel/sunxi-legacy/0000-0006-dt-bindings-document-sun8i_ths-H3-thermal-sensor-dri.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 4e3d17aa91541ce9ad705432e6ef353efabeb06e Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sat, 25 Jun 2016 00:02:04 +0200 -Subject: [PATCH 06/82] dt-bindings: document sun8i_ths - H3 thermal sensor - driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch adds the binding documentation for the -sun8i_ths driver. This is a driver for thermal sensor -found in Allwinner H3 SoC. - -Signed-off-by: Ondřej Jirman ---- - .../devicetree/bindings/thermal/sun8i-ths.txt | 24 +++++++++++++++++++ - 1 file changed, 24 insertions(+) - create mode 100644 Documentation/devicetree/bindings/thermal/sun8i-ths.txt - -diff --git a/Documentation/devicetree/bindings/thermal/sun8i-ths.txt b/Documentation/devicetree/bindings/thermal/sun8i-ths.txt -new file mode 100644 -index 000000000000..ba1288165e90 ---- /dev/null -+++ b/Documentation/devicetree/bindings/thermal/sun8i-ths.txt -@@ -0,0 +1,24 @@ -+* Thermal sensor driver for Allwinner H3 SoC -+ -+Required properties: -+- compatible : "allwinner,sun8i-h3-ths" -+- reg : Address range of the thermal sensor registers -+- resets : Must contain phandles to reset controls matching the entries -+ of the names -+- reset-names : Must include the name "ahb" -+- clocks : Must contain phandles to clock controls matching the entries -+ of the names -+- clock-names : Must contain "ahb" for the bus gate and "ths" for the THS -+ clock -+ -+Example: -+ths: ths@01c25000 { -+ #thermal-sensor-cells = <0>; -+ compatible = "allwinner,sun8i-h3-ths"; -+ reg = <0x01c25000 0x400>; -+ interrupts = ; -+ resets = <&bus_rst 136>; -+ reset-names = "ahb"; -+ clocks = <&bus_gates 72>, <&ths_clk>; -+ clock-names = "ahb", "ths"; -+}; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0007-ARM-dts-sunxi-h3-h5-Add-thermal-sensor-node-to-H3-H5.patch b/patch/kernel/sunxi-legacy/0000-0007-ARM-dts-sunxi-h3-h5-Add-thermal-sensor-node-to-H3-H5.patch deleted file mode 100644 index 2e136ce0a..000000000 --- a/patch/kernel/sunxi-legacy/0000-0007-ARM-dts-sunxi-h3-h5-Add-thermal-sensor-node-to-H3-H5.patch +++ /dev/null @@ -1,50 +0,0 @@ -From af866a2756362500a2e7a4d0cf600e266b5f5c4c Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sun, 26 Feb 2017 16:05:58 +0100 -Subject: [PATCH 07/82] ARM: dts: sunxi-h3-h5: Add thermal sensor node to H3/H5 - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sunxi-h3-h5.dtsi | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - -diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -index fc6131315c47..13fe5e316136 100644 ---- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi -+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -@@ -488,6 +488,19 @@ - }; - }; - -+ ths: ths@1c25000 { -+ #thermal-sensor-cells = <0>; -+ compatible = "allwinner,sun8i-h3-ths"; -+ reg = <0x01c25000 0x400>, -+ <0x01c14234 0x4>; -+ reg-names = "ths", "calibration"; -+ interrupts = ; -+ resets = <&ccu RST_BUS_THS>; -+ reset-names = "ahb"; -+ clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_THS>; -+ clock-names = "ahb", "ths"; -+ }; -+ - timer@1c20c00 { - compatible = "allwinner,sun4i-a10-timer"; - reg = <0x01c20c00 0xa0>; -@@ -855,4 +868,12 @@ - }; - }; - }; -+ -+ thermal-zones { -+ cpu_thermal: cpu_thermal { -+ polling-delay-passive = <330>; -+ polling-delay = <1000>; -+ thermal-sensors = <&ths 0>; -+ }; -+ }; - }; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0008-cpufreq-dt-platdev-Add-allwinner-sun50i-h5-compatibl.patch b/patch/kernel/sunxi-legacy/0000-0008-cpufreq-dt-platdev-Add-allwinner-sun50i-h5-compatibl.patch deleted file mode 100644 index 69844c216..000000000 --- a/patch/kernel/sunxi-legacy/0000-0008-cpufreq-dt-platdev-Add-allwinner-sun50i-h5-compatibl.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 1d78fb6bf60b011bd60ebc9d6ef9499f91c29267 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Thu, 30 Mar 2017 12:58:43 +0200 -Subject: [PATCH 08/82] cpufreq: dt-platdev: Add allwinner,sun50i-h5 compatible - ---- - drivers/cpufreq/cpufreq-dt-platdev.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c -index fe14c57de6ca..afb511aa5050 100644 ---- a/drivers/cpufreq/cpufreq-dt-platdev.c -+++ b/drivers/cpufreq/cpufreq-dt-platdev.c -@@ -29,6 +29,7 @@ static const struct of_device_id whitelist[] __initconst = { - { .compatible = "allwinner,sun8i-a23", }, - { .compatible = "allwinner,sun8i-a83t", }, - { .compatible = "allwinner,sun8i-h3", }, -+ { .compatible = "allwinner,sun50i-h5", }, - - { .compatible = "apm,xgene-shadowcat", }, - --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0009-ARM-dts-sun8i-Increase-max-CPUX-voltage-to-1.4V-on-O.patch b/patch/kernel/sunxi-legacy/0000-0009-ARM-dts-sun8i-Increase-max-CPUX-voltage-to-1.4V-on-O.patch deleted file mode 100644 index d747a6bdf..000000000 --- a/patch/kernel/sunxi-legacy/0000-0009-ARM-dts-sun8i-Increase-max-CPUX-voltage-to-1.4V-on-O.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 3ef8fd9d164316d26eb99afec111e0431c2f2c69 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sun, 13 May 2018 21:00:43 +0200 -Subject: [PATCH 09/82] ARM: dts: sun8i: Increase max CPUX voltage to 1.4V on - Orange Pi PC - -When using thermal regulation we can afford to go higher. Also add -regulator-ramp-delay, because regulator takes some time to change -voltage. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts -index 46240334128f..83f1866ed9e7 100644 ---- a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts -+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts -@@ -204,7 +204,8 @@ - * Use 1.0V as the minimum voltage instead. - */ - regulator-min-microvolt = <1000000>; -- regulator-max-microvolt = <1300000>; -+ regulator-max-microvolt = <1400000>; -+ regulator-ramp-delay = <200>; - regulator-boot-on; - regulator-always-on; - }; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0010-ARM-dts-sun8i-h3-Add-clock-frequency.patch b/patch/kernel/sunxi-legacy/0000-0010-ARM-dts-sun8i-h3-Add-clock-frequency.patch deleted file mode 100644 index 280d74330..000000000 --- a/patch/kernel/sunxi-legacy/0000-0010-ARM-dts-sun8i-h3-Add-clock-frequency.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0d1194aaf2b2ebc571cf01d2353d252c12146d2e Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Mon, 27 Jun 2016 16:08:26 +0200 -Subject: [PATCH 10/82] ARM: dts: sun8i-h3: Add clock-frequency - -To avoid error messages during boot. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-h3.dtsi | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi -index f0096074a467..cb19ff797606 100644 ---- a/arch/arm/boot/dts/sun8i-h3.dtsi -+++ b/arch/arm/boot/dts/sun8i-h3.dtsi -@@ -78,6 +78,7 @@ - clock-names = "cpu"; - operating-points-v2 = <&cpu0_opp_table>; - #cooling-cells = <2>; -+ clock-frequency = <1200000000>; - }; - - cpu@1 { -@@ -88,6 +89,7 @@ - clock-names = "cpu"; - operating-points-v2 = <&cpu0_opp_table>; - #cooling-cells = <2>; -+ clock-frequency = <1200000000>; - }; - - cpu@2 { -@@ -98,6 +100,7 @@ - clock-names = "cpu"; - operating-points-v2 = <&cpu0_opp_table>; - #cooling-cells = <2>; -+ clock-frequency = <1200000000>; - }; - - cpu@3 { -@@ -108,6 +111,7 @@ - clock-names = "cpu"; - operating-points-v2 = <&cpu0_opp_table>; - #cooling-cells = <2>; -+ clock-frequency = <1200000000>; - }; - }; - --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0011-arm64-dts-sun50i-h5-Add-clock-frequency.patch b/patch/kernel/sunxi-legacy/0000-0011-arm64-dts-sun50i-h5-Add-clock-frequency.patch deleted file mode 100644 index 07ea95e36..000000000 --- a/patch/kernel/sunxi-legacy/0000-0011-arm64-dts-sun50i-h5-Add-clock-frequency.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 6328da39df61f962190870089aaa171a7f8aab2c Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Thu, 30 Mar 2017 13:04:25 +0200 -Subject: [PATCH 11/82] arm64: dts: sun50i-h5: Add clock-frequency - -To avoid error messages during boot. - -Signed-off-by: Ondrej Jirman ---- - arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -index 62d646baac3c..4452ab873dec 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -@@ -52,6 +52,7 @@ - device_type = "cpu"; - reg = <0>; - enable-method = "psci"; -+ clock-frequency = <1200000000>; - }; - - cpu@1 { -@@ -59,6 +60,7 @@ - device_type = "cpu"; - reg = <1>; - enable-method = "psci"; -+ clock-frequency = <1200000000>; - }; - - cpu@2 { -@@ -66,6 +68,7 @@ - device_type = "cpu"; - reg = <2>; - enable-method = "psci"; -+ clock-frequency = <1200000000>; - }; - - cpu@3 { -@@ -73,6 +76,7 @@ - device_type = "cpu"; - reg = <3>; - enable-method = "psci"; -+ clock-frequency = <1200000000>; - }; - }; - --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0012-ARM-dts-sunxi-h3-h5-Move-CPU-OPP-table-to-dtsi-share.patch b/patch/kernel/sunxi-legacy/0000-0012-ARM-dts-sunxi-h3-h5-Move-CPU-OPP-table-to-dtsi-share.patch deleted file mode 100644 index 210c39b08..000000000 --- a/patch/kernel/sunxi-legacy/0000-0012-ARM-dts-sunxi-h3-h5-Move-CPU-OPP-table-to-dtsi-share.patch +++ /dev/null @@ -1,85 +0,0 @@ -From d4028daf51824eb792fb3c9cc77553ff1edc5d68 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Mon, 14 May 2018 00:56:50 +0200 -Subject: [PATCH 12/82] ARM: dts: sunxi-h3-h5: Move CPU OPP table to dtsi - shared by H3/H5 - -It is identical for H3 and H5, so it better live there. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-h3.dtsi | 23 ----------------------- - arch/arm/boot/dts/sunxi-h3-h5.dtsi | 23 +++++++++++++++++++++++ - 2 files changed, 23 insertions(+), 23 deletions(-) - -diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi -index cb19ff797606..261ca0356358 100644 ---- a/arch/arm/boot/dts/sun8i-h3.dtsi -+++ b/arch/arm/boot/dts/sun8i-h3.dtsi -@@ -43,29 +43,6 @@ - #include "sunxi-h3-h5.dtsi" - - / { -- cpu0_opp_table: opp_table0 { -- compatible = "operating-points-v2"; -- opp-shared; -- -- opp-648000000 { -- opp-hz = /bits/ 64 <648000000>; -- opp-microvolt = <1040000 1040000 1300000>; -- clock-latency-ns = <244144>; /* 8 32k periods */ -- }; -- -- opp-816000000 { -- opp-hz = /bits/ 64 <816000000>; -- opp-microvolt = <1100000 1100000 1300000>; -- clock-latency-ns = <244144>; /* 8 32k periods */ -- }; -- -- opp-1008000000 { -- opp-hz = /bits/ 64 <1008000000>; -- opp-microvolt = <1200000 1200000 1300000>; -- clock-latency-ns = <244144>; /* 8 32k periods */ -- }; -- }; -- - cpus { - #address-cells = <1>; - #size-cells = <0>; -diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -index 13fe5e316136..539b69fecbe9 100644 ---- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi -+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -@@ -105,6 +105,29 @@ - }; - }; - -+ cpu0_opp_table: opp_table0 { -+ compatible = "operating-points-v2"; -+ opp-shared; -+ -+ opp@648000000 { -+ opp-hz = /bits/ 64 <648000000>; -+ opp-microvolt = <1040000 1040000 1300000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ -+ opp@816000000 { -+ opp-hz = /bits/ 64 <816000000>; -+ opp-microvolt = <1100000 1100000 1300000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ -+ opp@1008000000 { -+ opp-hz = /bits/ 64 <1008000000>; -+ opp-microvolt = <1200000 1200000 1300000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ }; -+ - de: display-engine { - compatible = "allwinner,sun8i-h3-display-engine"; - allwinner,pipelines = <&mixer0>; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0013-ARM-dts-sunxi-h3-h5-Add-more-CPU-OPP-for-H3-H5.patch b/patch/kernel/sunxi-legacy/0000-0013-ARM-dts-sunxi-h3-h5-Add-more-CPU-OPP-for-H3-H5.patch deleted file mode 100644 index 94226481a..000000000 --- a/patch/kernel/sunxi-legacy/0000-0013-ARM-dts-sunxi-h3-h5-Add-more-CPU-OPP-for-H3-H5.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 9e05f3d014b05df39a55dfd6a08d4bd18a301307 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Mon, 14 May 2018 01:13:01 +0200 -Subject: [PATCH 13/82] ARM: dts: sunxi-h3-h5: Add more CPU OPP for H3/H5 - -These OPPs can be used with better cooling and/or thermal regulation. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sunxi-h3-h5.dtsi | 78 ++++++++++++++++++++++++++++++ - 1 file changed, 78 insertions(+) - -diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -index 539b69fecbe9..f47c22b622f9 100644 ---- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi -+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -@@ -109,6 +109,24 @@ - compatible = "operating-points-v2"; - opp-shared; - -+ opp@120000000 { -+ opp-hz = /bits/ 64 <120000000>; -+ opp-microvolt = <1040000 1040000 1300000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ -+ opp@240000000 { -+ opp-hz = /bits/ 64 <240000000>; -+ opp-microvolt = <1040000 1040000 1300000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ -+ opp@480000000 { -+ opp-hz = /bits/ 64 <480000000>; -+ opp-microvolt = <1040000 1040000 1300000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ - opp@648000000 { - opp-hz = /bits/ 64 <648000000>; - opp-microvolt = <1040000 1040000 1300000>; -@@ -121,11 +139,71 @@ - clock-latency-ns = <244144>; /* 8 32k periods */ - }; - -+ opp@960000000 { -+ opp-hz = /bits/ 64 <960000000>; -+ opp-microvolt = <1200000 1200000 1300000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ - opp@1008000000 { - opp-hz = /bits/ 64 <1008000000>; - opp-microvolt = <1200000 1200000 1300000>; - clock-latency-ns = <244144>; /* 8 32k periods */ - }; -+ -+ opp@1056000000 { -+ opp-hz = /bits/ 64 <1056000000>; -+ opp-microvolt = <1320000 1320000 1320000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ -+ opp@1104000000 { -+ opp-hz = /bits/ 64 <1104000000>; -+ opp-microvolt = <1320000 1320000 1320000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ -+ opp@1152000000 { -+ opp-hz = /bits/ 64 <1152000000>; -+ opp-microvolt = <1320000 1320000 1320000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ -+ opp@1200000000 { -+ opp-hz = /bits/ 64 <1200000000>; -+ opp-microvolt = <1320000 1320000 1320000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ -+ opp@1224000000 { -+ opp-hz = /bits/ 64 <1224000000>; -+ opp-microvolt = <1340000 1340000 1340000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ -+ opp@1248000000 { -+ opp-hz = /bits/ 64 <1248000000>; -+ opp-microvolt = <1340000 1340000 1340000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ -+ opp@1296000000 { -+ opp-hz = /bits/ 64 <1296000000>; -+ opp-microvolt = <1340000 1340000 1340000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ -+ opp@1344000000 { -+ opp-hz = /bits/ 64 <1344000000>; -+ opp-microvolt = <1400000 1400000 1400000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ -+ opp@1368000000 { -+ opp-hz = /bits/ 64 <1368000000>; -+ opp-microvolt = <1400000 1400000 1400000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; - }; - - de: display-engine { --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0014-ARM-dts-sunxi-h3-h5-Add-thermal-zone-trip-points.patch b/patch/kernel/sunxi-legacy/0000-0014-ARM-dts-sunxi-h3-h5-Add-thermal-zone-trip-points.patch deleted file mode 100644 index 5c6e0b7f8..000000000 --- a/patch/kernel/sunxi-legacy/0000-0014-ARM-dts-sunxi-h3-h5-Add-thermal-zone-trip-points.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 6914945e888f1206df560ff36375e7257ce38970 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Mon, 14 May 2018 01:16:06 +0200 -Subject: [PATCH 14/82] ARM: dts: sunxi-h3-h5: Add thermal zone trip points - -This enables passive cooling by downregulating CPU voltage/frequency. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-h3.dtsi | 4 +++- - arch/arm/boot/dts/sunxi-h3-h5.dtsi | 21 ++++++++++++++++++++ - arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 3 +++ - 3 files changed, 27 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi -index 261ca0356358..af76a6d250b3 100644 ---- a/arch/arm/boot/dts/sun8i-h3.dtsi -+++ b/arch/arm/boot/dts/sun8i-h3.dtsi -@@ -54,8 +54,10 @@ - clocks = <&ccu CLK_CPUX>; - clock-names = "cpu"; - operating-points-v2 = <&cpu0_opp_table>; -- #cooling-cells = <2>; - clock-frequency = <1200000000>; -+ #cooling-cells = <2>; -+ cooling-min-level = <0>; -+ cooling-max-level = <15>; - }; - - cpu@1 { -diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -index f47c22b622f9..3b8b2234ab4d 100644 ---- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi -+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -@@ -47,6 +47,7 @@ - #include - #include - #include -+#include - - / { - interrupt-parent = <&gic>; -@@ -975,6 +976,26 @@ - polling-delay-passive = <330>; - polling-delay = <1000>; - thermal-sensors = <&ths 0>; -+ -+ trips { -+ cpu_hot_trip: cpu-warm { -+ temperature = <65000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ cpu_very_hot_trip: cpu-very-hot { -+ temperature = <90000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ -+ cooling-maps { -+ cpu-warm-limit { -+ trip = <&cpu_hot_trip>; -+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -+ }; -+ }; - }; - }; - }; -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -index 4452ab873dec..60fc84a1fb44 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -@@ -53,6 +53,9 @@ - reg = <0>; - enable-method = "psci"; - clock-frequency = <1200000000>; -+ #cooling-cells = <2>; -+ cooling-min-level = <0>; -+ cooling-max-level = <15>; - }; - - cpu@1 { --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0015-arm64-dts-sun50i-h5-Enable-cpufreq-dt-on-H5-CPU.patch b/patch/kernel/sunxi-legacy/0000-0015-arm64-dts-sun50i-h5-Enable-cpufreq-dt-on-H5-CPU.patch deleted file mode 100644 index 19219d521..000000000 --- a/patch/kernel/sunxi-legacy/0000-0015-arm64-dts-sun50i-h5-Enable-cpufreq-dt-on-H5-CPU.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 25be6ff78bebfd869a3be0017715f101bd75bb64 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Mon, 14 May 2018 01:19:06 +0200 -Subject: [PATCH 15/82] arm64: dts: sun50i-h5: Enable cpufreq-dt on H5 CPU - -Uses OPPs shared with H3. - -Signed-off-by: Ondrej Jirman ---- - arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -index 60fc84a1fb44..acd90f390e88 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -@@ -52,6 +52,9 @@ - device_type = "cpu"; - reg = <0>; - enable-method = "psci"; -+ clocks = <&ccu CLK_CPUX>; -+ clock-names = "cpu"; -+ operating-points-v2 = <&cpu0_opp_table>; - clock-frequency = <1200000000>; - #cooling-cells = <2>; - cooling-min-level = <0>; -@@ -63,6 +66,7 @@ - device_type = "cpu"; - reg = <1>; - enable-method = "psci"; -+ operating-points-v2 = <&cpu0_opp_table>; - clock-frequency = <1200000000>; - }; - -@@ -71,6 +75,7 @@ - device_type = "cpu"; - reg = <2>; - enable-method = "psci"; -+ operating-points-v2 = <&cpu0_opp_table>; - clock-frequency = <1200000000>; - }; - -@@ -79,6 +84,7 @@ - device_type = "cpu"; - reg = <3>; - enable-method = "psci"; -+ operating-points-v2 = <&cpu0_opp_table>; - clock-frequency = <1200000000>; - }; - }; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0016-arm64-dts-sun50i-h5-orange-pi-pc2-Setup-CPUX-voltage.patch b/patch/kernel/sunxi-legacy/0000-0016-arm64-dts-sun50i-h5-orange-pi-pc2-Setup-CPUX-voltage.patch deleted file mode 100644 index 426fc2cf8..000000000 --- a/patch/kernel/sunxi-legacy/0000-0016-arm64-dts-sun50i-h5-orange-pi-pc2-Setup-CPUX-voltage.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 2f3ebd02a475c51f0ee4ac20fd9462f7f8cad314 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Thu, 30 Mar 2017 13:01:10 +0200 -Subject: [PATCH 16/82] arm64: dts: sun50i-h5-orange-pi-pc2: Setup CPUX voltage - regulator - -Orange Pi PC2 features sy8106a regulator just like Orange Pi PC. - -Signed-off-by: Ondrej Jirman ---- - .../dts/allwinner/sun50i-h5-orangepi-pc2.dts | 29 +++++++++++++++++++ - 1 file changed, 29 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts -index 3e0d5a9c096d..af8e3fe26e20 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts -@@ -124,6 +124,10 @@ - }; - }; - -+&cpu0 { -+ cpu-supply = <®_vdd_cpux>; -+}; -+ - &codec { - allwinner,audio-routing = - "Line Out", "LINEOUT", -@@ -219,6 +223,31 @@ - }; - }; - -+&r_i2c { -+ status = "okay"; -+ -+ reg_vdd_cpux: regulator@65 { -+ compatible = "silergy,sy8106a"; -+ reg = <0x65>; -+ regulator-name = "vdd-cpux"; -+ silergy,fixed-microvolt = <1200000>; -+ /* -+ * The datasheet uses 1.1V as the minimum value of VDD-CPUX, -+ * however both the Armbian DVFS table and the official one -+ * have operating points with voltage under 1.1V, and both -+ * DVFS table are known to work properly at the lowest -+ * operating point. -+ * -+ * Use 1.0V as the minimum voltage instead. -+ */ -+ regulator-min-microvolt = <1000000>; -+ regulator-max-microvolt = <1400000>; -+ regulator-ramp-delay = <200>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+}; -+ - &uart0 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0017-Input-edt-ft5x06-Add-support-for-regulator.patch b/patch/kernel/sunxi-legacy/0000-0017-Input-edt-ft5x06-Add-support-for-regulator.patch deleted file mode 100644 index 73082c593..000000000 --- a/patch/kernel/sunxi-legacy/0000-0017-Input-edt-ft5x06-Add-support-for-regulator.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 997e53ee52efc4a0602bf298125a7c9758abf15c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= -Date: Wed, 25 Jul 2018 09:34:08 +0200 -Subject: [PATCH 17/82] Input: edt-ft5x06 - Add support for regulator -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add the support of regulator to use it as VCC source. - -Signed-off-by: Mylène Josserand -Reviewed-by: Rob Herring ---- - .../bindings/input/touchscreen/edt-ft5x06.txt | 1 + - drivers/input/touchscreen/edt-ft5x06.c | 43 +++++++++++++++++++ - 2 files changed, 44 insertions(+) - -diff --git a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt -index da2dc5d6c98b..987faeb2fe4a 100644 ---- a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt -+++ b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt -@@ -28,6 +28,7 @@ Required properties: - Optional properties: - - reset-gpios: GPIO specification for the RESET input - - wake-gpios: GPIO specification for the WAKE input -+ - vcc-supply: Regulator that supplies the touchscreen - - - pinctrl-names: should be "default" - - pinctrl-0: a phandle pointing to the pin settings for the -diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c -index 1e18ca0d1b4e..dcde719094f7 100644 ---- a/drivers/input/touchscreen/edt-ft5x06.c -+++ b/drivers/input/touchscreen/edt-ft5x06.c -@@ -39,6 +39,7 @@ - #include - #include - #include -+#include - - #define WORK_REGISTER_THRESHOLD 0x00 - #define WORK_REGISTER_REPORT_RATE 0x08 -@@ -91,6 +92,7 @@ struct edt_ft5x06_ts_data { - struct touchscreen_properties prop; - u16 num_x; - u16 num_y; -+ struct regulator *vcc; - - struct gpio_desc *reset_gpio; - struct gpio_desc *wake_gpio; -@@ -963,6 +965,13 @@ edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata) - } - } - -+static void edt_ft5x06_disable_regulator(void *arg) -+{ -+ struct edt_ft5x06_ts_data *data = arg; -+ -+ regulator_disable(data->vcc); -+} -+ - static int edt_ft5x06_ts_probe(struct i2c_client *client, - const struct i2c_device_id *id) - { -@@ -991,6 +1000,28 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, - - tsdata->max_support_points = chip_data->max_support_points; - -+ tsdata->vcc = devm_regulator_get(&client->dev, "vcc"); -+ if (IS_ERR(tsdata->vcc)) { -+ error = PTR_ERR(tsdata->vcc); -+ if (error != -EPROBE_DEFER) -+ dev_err(&client->dev, "failed to request regulator: %d\n", -+ error); -+ return error; -+ } -+ -+ error = regulator_enable(tsdata->vcc); -+ if (error < 0) { -+ dev_err(&client->dev, "failed to enable vcc: %d\n", -+ error); -+ return error; -+ } -+ -+ error = devm_add_action_or_reset(&client->dev, -+ edt_ft5x06_disable_regulator, -+ tsdata); -+ if (error) -+ return error; -+ - tsdata->reset_gpio = devm_gpiod_get_optional(&client->dev, - "reset", GPIOD_OUT_HIGH); - if (IS_ERR(tsdata->reset_gpio)) { -@@ -1120,9 +1151,12 @@ static int edt_ft5x06_ts_remove(struct i2c_client *client) - static int __maybe_unused edt_ft5x06_ts_suspend(struct device *dev) - { - struct i2c_client *client = to_i2c_client(dev); -+ struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client); - - if (device_may_wakeup(dev)) - enable_irq_wake(client->irq); -+ else -+ regulator_disable(tsdata->vcc); - - return 0; - } -@@ -1130,9 +1164,18 @@ static int __maybe_unused edt_ft5x06_ts_suspend(struct device *dev) - static int __maybe_unused edt_ft5x06_ts_resume(struct device *dev) - { - struct i2c_client *client = to_i2c_client(dev); -+ struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client); -+ int ret; - - if (device_may_wakeup(dev)) - disable_irq_wake(client->irq); -+ else { -+ ret = regulator_enable(tsdata->vcc); -+ if (ret < 0) { -+ dev_err(dev, "failed to enable vcc: %d\n", ret); -+ return ret; -+ } -+ } - - return 0; - } --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0018-Input-edt-ft5x06-Set-wake-reset-values-on-resume-sus.patch b/patch/kernel/sunxi-legacy/0000-0018-Input-edt-ft5x06-Set-wake-reset-values-on-resume-sus.patch deleted file mode 100644 index 03cbf5b68..000000000 --- a/patch/kernel/sunxi-legacy/0000-0018-Input-edt-ft5x06-Set-wake-reset-values-on-resume-sus.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 6ff7153330ff8a6c3427e6445e5015620d687c81 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= -Date: Wed, 25 Jul 2018 09:34:09 +0200 -Subject: [PATCH 18/82] Input: edt-ft5x06 - Set wake/reset values on - resume/suspend -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -On resume and suspend, set the value of wake and reset gpios -to be sure that we are in a know state after suspending/resuming. - -Signed-off-by: Mylène Josserand ---- - drivers/input/touchscreen/edt-ft5x06.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c -index dcde719094f7..dad2f1f8bf89 100644 ---- a/drivers/input/touchscreen/edt-ft5x06.c -+++ b/drivers/input/touchscreen/edt-ft5x06.c -@@ -1158,6 +1158,12 @@ static int __maybe_unused edt_ft5x06_ts_suspend(struct device *dev) - else - regulator_disable(tsdata->vcc); - -+ if (tsdata->wake_gpio) -+ gpiod_set_value(tsdata->wake_gpio, 0); -+ -+ if (tsdata->reset_gpio) -+ gpiod_set_value(tsdata->reset_gpio, 1); -+ - return 0; - } - -@@ -1177,6 +1183,12 @@ static int __maybe_unused edt_ft5x06_ts_resume(struct device *dev) - } - } - -+ if (tsdata->wake_gpio) -+ gpiod_set_value(tsdata->wake_gpio, 1); -+ -+ if (tsdata->reset_gpio) -+ gpiod_set_value(tsdata->reset_gpio, 0); -+ - return 0; - } - --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0019-arm-dts-sun8i-a83t-a711-Add-touchscreen-node.patch b/patch/kernel/sunxi-legacy/0000-0019-arm-dts-sun8i-a83t-a711-Add-touchscreen-node.patch deleted file mode 100644 index a56e04f77..000000000 --- a/patch/kernel/sunxi-legacy/0000-0019-arm-dts-sun8i-a83t-a711-Add-touchscreen-node.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0e03253586345216dfb55cdd9b8f038023e0d9bc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= -Date: Wed, 25 Jul 2018 09:34:10 +0200 -Subject: [PATCH 19/82] arm: dts: sun8i: a83t: a711: Add touchscreen node -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Tha A711 tablet has a FocalTech EDT-FT5x06 Polytouch touchscreen. -It is connected via I2C0. The reset line is PD5, the interrupt -line is PL7 and the VCC supply is the ldo_io0 regulator. - -Signed-off-by: Mylène Josserand ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index 1537ce148cc1..dc7b94a6c068 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -156,6 +156,22 @@ - status = "okay"; - }; - -+&i2c0 { -+ clock-frequency = <400000>; -+ status = "okay"; -+ -+ touchscreen@38 { -+ compatible = "edt,edt-ft5x06"; -+ reg = <0x38>; -+ interrupt-parent = <&r_pio>; -+ interrupts = <0 7 IRQ_TYPE_EDGE_FALLING>; -+ reset-gpios = <&pio 3 5 GPIO_ACTIVE_LOW>; -+ vcc-supply = <®_ldo_io0>; -+ touchscreen-size-x = <1024>; -+ touchscreen-size-y = <600>; -+ }; -+}; -+ - &mmc0 { - vmmc-supply = <®_dcdc1>; - pinctrl-names = "default"; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0020-power-supply-axp20x_usb_power-add-function-to-get-ma.patch b/patch/kernel/sunxi-legacy/0000-0020-power-supply-axp20x_usb_power-add-function-to-get-ma.patch deleted file mode 100644 index c15b24c35..000000000 --- a/patch/kernel/sunxi-legacy/0000-0020-power-supply-axp20x_usb_power-add-function-to-get-ma.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 84a6ce439660f26a06219cdf1613f87a6395fdbd Mon Sep 17 00:00:00 2001 -From: Quentin Schulz -Date: Wed, 23 Aug 2017 14:15:59 +0200 -Subject: [PATCH 20/82] power: supply: axp20x_usb_power: add function to get - max current - -To prepare for a new PMIC, factor out the code responsible of returning -the maximum current to axp20x_get_current_max. - -Signed-off-by: Quentin Schulz ---- - drivers/power/supply/axp20x_usb_power.c | 51 ++++++++++++++----------- - 1 file changed, 29 insertions(+), 22 deletions(-) - -diff --git a/drivers/power/supply/axp20x_usb_power.c b/drivers/power/supply/axp20x_usb_power.c -index 42001df4bd13..464d4abd3798 100644 ---- a/drivers/power/supply/axp20x_usb_power.c -+++ b/drivers/power/supply/axp20x_usb_power.c -@@ -63,6 +63,34 @@ static irqreturn_t axp20x_usb_power_irq(int irq, void *devid) - return IRQ_HANDLED; - } - -+static int axp20x_get_current_max(struct axp20x_usb_power *power, int *val) -+{ -+ unsigned int v; -+ int ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v); -+ -+ if (ret) -+ return ret; -+ -+ switch (v & AXP20X_VBUS_CLIMIT_MASK) { -+ case AXP20X_VBUC_CLIMIT_100mA: -+ if (power->axp20x_id == AXP221_ID) -+ *val = -1; /* No 100mA limit */ -+ else -+ *val = 100000; -+ break; -+ case AXP20X_VBUC_CLIMIT_500mA: -+ *val = 500000; -+ break; -+ case AXP20X_VBUC_CLIMIT_900mA: -+ *val = 900000; -+ break; -+ case AXP20X_VBUC_CLIMIT_NONE: -+ *val = -1; -+ break; -+ } -+ return 0; -+} -+ - static int axp20x_usb_power_get_property(struct power_supply *psy, - enum power_supply_property psp, union power_supply_propval *val) - { -@@ -101,28 +129,7 @@ static int axp20x_usb_power_get_property(struct power_supply *psy, - val->intval = ret * 1700; /* 1 step = 1.7 mV */ - return 0; - case POWER_SUPPLY_PROP_CURRENT_MAX: -- ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v); -- if (ret) -- return ret; -- -- switch (v & AXP20X_VBUS_CLIMIT_MASK) { -- case AXP20X_VBUC_CLIMIT_100mA: -- if (power->axp20x_id == AXP221_ID) -- val->intval = -1; /* No 100mA limit */ -- else -- val->intval = 100000; -- break; -- case AXP20X_VBUC_CLIMIT_500mA: -- val->intval = 500000; -- break; -- case AXP20X_VBUC_CLIMIT_900mA: -- val->intval = 900000; -- break; -- case AXP20X_VBUC_CLIMIT_NONE: -- val->intval = -1; -- break; -- } -- return 0; -+ return axp20x_get_current_max(power, &val->intval); - case POWER_SUPPLY_PROP_CURRENT_NOW: - if (IS_ENABLED(CONFIG_AXP20X_ADC)) { - ret = iio_read_channel_processed(power->vbus_i, --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0021-power-supply-axp20x_usb_power-add-support-for-AXP813.patch b/patch/kernel/sunxi-legacy/0000-0021-power-supply-axp20x_usb_power-add-support-for-AXP813.patch deleted file mode 100644 index 7d91de5e8..000000000 --- a/patch/kernel/sunxi-legacy/0000-0021-power-supply-axp20x_usb_power-add-support-for-AXP813.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 5c2f08f5428ed5239b5e90a308e2f77cbc8238b0 Mon Sep 17 00:00:00 2001 -From: Quentin Schulz -Date: Wed, 23 Aug 2017 15:03:42 +0200 -Subject: [PATCH 21/82] power: supply: axp20x_usb_power: add support for AXP813 - -This adds support for AXP813 PMIC. It is almost the same as AXP22X but -has a different current limit. - -Signed-off-by: Quentin Schulz ---- - drivers/power/supply/axp20x_usb_power.c | 66 ++++++++++++++++++++++++- - 1 file changed, 65 insertions(+), 1 deletion(-) - -diff --git a/drivers/power/supply/axp20x_usb_power.c b/drivers/power/supply/axp20x_usb_power.c -index 464d4abd3798..4b04fb8f496c 100644 ---- a/drivers/power/supply/axp20x_usb_power.c -+++ b/drivers/power/supply/axp20x_usb_power.c -@@ -40,6 +40,11 @@ - #define AXP20X_VBUC_CLIMIT_100mA 2 - #define AXP20X_VBUC_CLIMIT_NONE 3 - -+#define AXP813_VBUC_CLIMIT_900mA 0 -+#define AXP813_VBUC_CLIMIT_1500mA 1 -+#define AXP813_VBUC_CLIMIT_2000mA 2 -+#define AXP813_VBUC_CLIMIT_2500mA 3 -+ - #define AXP20X_ADC_EN1_VBUS_CURR BIT(2) - #define AXP20X_ADC_EN1_VBUS_VOLT BIT(3) - -@@ -63,6 +68,31 @@ static irqreturn_t axp20x_usb_power_irq(int irq, void *devid) - return IRQ_HANDLED; - } - -+static int axp813_get_current_max(struct axp20x_usb_power *power, int *val) -+{ -+ unsigned int v; -+ int ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v); -+ -+ if (ret) -+ return ret; -+ -+ switch (v & AXP20X_VBUS_CLIMIT_MASK) { -+ case AXP813_VBUC_CLIMIT_900mA: -+ *val = 900000; -+ break; -+ case AXP813_VBUC_CLIMIT_1500mA: -+ *val = 1500000; -+ break; -+ case AXP813_VBUC_CLIMIT_2000mA: -+ *val = 2000000; -+ break; -+ case AXP813_VBUC_CLIMIT_2500mA: -+ *val = 2500000; -+ break; -+ } -+ return 0; -+} -+ - static int axp20x_get_current_max(struct axp20x_usb_power *power, int *val) - { - unsigned int v; -@@ -129,6 +159,8 @@ static int axp20x_usb_power_get_property(struct power_supply *psy, - val->intval = ret * 1700; /* 1 step = 1.7 mV */ - return 0; - case POWER_SUPPLY_PROP_CURRENT_MAX: -+ if (power->axp20x_id == AXP813_ID) -+ return axp813_get_current_max(power, &val->intval); - return axp20x_get_current_max(power, &val->intval); - case POWER_SUPPLY_PROP_CURRENT_NOW: - if (IS_ENABLED(CONFIG_AXP20X_ADC)) { -@@ -220,6 +252,31 @@ static int axp20x_usb_power_set_voltage_min(struct axp20x_usb_power *power, - return -EINVAL; - } - -+static int axp813_usb_power_set_current_max(struct axp20x_usb_power *power, -+ int intval) -+{ -+ int val; -+ -+ switch (intval) { -+ case 900000: -+ return regmap_update_bits(power->regmap, -+ AXP20X_VBUS_IPSOUT_MGMT, -+ AXP20X_VBUS_CLIMIT_MASK, -+ AXP813_VBUC_CLIMIT_900mA); -+ case 1500000: -+ case 2000000: -+ case 2500000: -+ val = (intval - 1000000) / 500000; -+ return regmap_update_bits(power->regmap, -+ AXP20X_VBUS_IPSOUT_MGMT, -+ AXP20X_VBUS_CLIMIT_MASK, val); -+ default: -+ return -EINVAL; -+ } -+ -+ return -EINVAL; -+} -+ - static int axp20x_usb_power_set_current_max(struct axp20x_usb_power *power, - int intval) - { -@@ -254,6 +311,9 @@ static int axp20x_usb_power_set_property(struct power_supply *psy, - return axp20x_usb_power_set_voltage_min(power, val->intval); - - case POWER_SUPPLY_PROP_CURRENT_MAX: -+ if (power->axp20x_id == AXP813_ID) -+ return axp813_usb_power_set_current_max(power, -+ val->intval); - return axp20x_usb_power_set_current_max(power, val->intval); - - default: -@@ -388,7 +448,8 @@ static int axp20x_usb_power_probe(struct platform_device *pdev) - usb_power_desc = &axp20x_usb_power_desc; - irq_names = axp20x_irq_names; - } else if (power->axp20x_id == AXP221_ID || -- power->axp20x_id == AXP223_ID) { -+ power->axp20x_id == AXP223_ID || -+ power->axp20x_id == AXP813_ID) { - usb_power_desc = &axp22x_usb_power_desc; - irq_names = axp22x_irq_names; - } else { -@@ -434,6 +495,9 @@ static const struct of_device_id axp20x_usb_power_match[] = { - }, { - .compatible = "x-powers,axp223-usb-power-supply", - .data = (void *)AXP223_ID, -+ }, { -+ .compatible = "x-powers,axp813-usb-power-supply", -+ .data = (void *)AXP813_ID, - }, { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, axp20x_usb_power_match); --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0022-ARM-dtsi-axp813-add-USB-power-supply-node.patch b/patch/kernel/sunxi-legacy/0000-0022-ARM-dtsi-axp813-add-USB-power-supply-node.patch deleted file mode 100644 index 97ae0187d..000000000 --- a/patch/kernel/sunxi-legacy/0000-0022-ARM-dtsi-axp813-add-USB-power-supply-node.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 8d81c934be105c53309f66057cabaf5cb496aec7 Mon Sep 17 00:00:00 2001 -From: Quentin Schulz -Date: Wed, 23 Aug 2017 15:06:28 +0200 -Subject: [PATCH 22/82] ARM: dtsi: axp813: add USB power supply node - -Signed-off-by: Quentin Schulz ---- - arch/arm/boot/dts/axp81x.dtsi | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm/boot/dts/axp81x.dtsi b/arch/arm/boot/dts/axp81x.dtsi -index 043c717dcef1..f32a8ba53b85 100644 ---- a/arch/arm/boot/dts/axp81x.dtsi -+++ b/arch/arm/boot/dts/axp81x.dtsi -@@ -166,4 +166,8 @@ - status = "disabled"; - }; - }; -+ -+ usb_power_supply: usb-power-supply { -+ compatible = "x-powers,axp813-usb-power-supply"; -+ }; - }; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0023-mfd-axp20x-add-USB-power-supply-mfd-cell-to-AXP813.patch b/patch/kernel/sunxi-legacy/0000-0023-mfd-axp20x-add-USB-power-supply-mfd-cell-to-AXP813.patch deleted file mode 100644 index e54d205f8..000000000 --- a/patch/kernel/sunxi-legacy/0000-0023-mfd-axp20x-add-USB-power-supply-mfd-cell-to-AXP813.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 95a44a737d3a50a67eabad266aeb7b8d763ef5d2 Mon Sep 17 00:00:00 2001 -From: Quentin Schulz -Date: Wed, 23 Aug 2017 15:07:14 +0200 -Subject: [PATCH 23/82] mfd: axp20x: add USB power supply mfd cell to AXP813 - -Signed-off-by: Quentin Schulz ---- - drivers/mfd/axp20x.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c -index f8e0fa97bb31..ac8da970bdfe 100644 ---- a/drivers/mfd/axp20x.c -+++ b/drivers/mfd/axp20x.c -@@ -787,6 +787,9 @@ static const struct mfd_cell axp813_cells[] = { - }, { - .name = "axp20x-battery-power-supply", - .of_compatible = "x-powers,axp813-battery-power-supply", -+ }, { -+ .name = "axp20x-usb-power-supply", -+ .of_compatible = "x-powers,axp813-usb-power-supply", - }, { - .name = "axp20x-ac-power-supply", - .of_compatible = "x-powers,axp813-ac-power-supply", --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0024-mfd-axp20x-add-regulator-userspace-consumer-to-mfd-c.patch b/patch/kernel/sunxi-legacy/0000-0024-mfd-axp20x-add-regulator-userspace-consumer-to-mfd-c.patch deleted file mode 100644 index 27a8f45b7..000000000 --- a/patch/kernel/sunxi-legacy/0000-0024-mfd-axp20x-add-regulator-userspace-consumer-to-mfd-c.patch +++ /dev/null @@ -1,54 +0,0 @@ -From b77e60c6a2797ada240b1d42b896b70853e2b1af Mon Sep 17 00:00:00 2001 -From: Quentin Schulz -Date: Thu, 10 Aug 2017 09:40:21 +0200 -Subject: [PATCH 24/82] mfd: axp20x: add regulator-userspace-consumer to mfd - cells of AXP813 - -Signed-off-by: Quentin Schulz ---- - drivers/mfd/axp20x.c | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c -index ac8da970bdfe..95f36a7e3cd4 100644 ---- a/drivers/mfd/axp20x.c -+++ b/drivers/mfd/axp20x.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -771,6 +772,16 @@ static const struct mfd_cell axp809_cells[] = { - }, - }; - -+static struct regulator_bulk_data vcc_vb = { -+ .supply = "vcc-vb", -+}; -+ -+static struct regulator_userspace_consumer_data vcc_vb_data = { -+ .name = "vcc-vb", -+ .num_supplies = 1, -+ .supplies = &vcc_vb, -+}; -+ - static const struct mfd_cell axp813_cells[] = { - { - .name = "axp221-pek", -@@ -790,6 +801,10 @@ static const struct mfd_cell axp813_cells[] = { - }, { - .name = "axp20x-usb-power-supply", - .of_compatible = "x-powers,axp813-usb-power-supply", -+ }, { -+ .name = "reg-userspace-consumer", -+ .platform_data = &vcc_vb_data, -+ .pdata_size = sizeof(vcc_vb_data), - }, { - .name = "axp20x-ac-power-supply", - .of_compatible = "x-powers,axp813-ac-power-supply", --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0025-power-supply-axp20x-usb-power-Support-input-current-.patch b/patch/kernel/sunxi-legacy/0000-0025-power-supply-axp20x-usb-power-Support-input-current-.patch deleted file mode 100644 index 7b7deb4cc..000000000 --- a/patch/kernel/sunxi-legacy/0000-0025-power-supply-axp20x-usb-power-Support-input-current-.patch +++ /dev/null @@ -1,188 +0,0 @@ -From 49675ccdafd63d0eee2fb0a57bd39fcb07a83bae Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Tue, 14 Nov 2017 02:09:43 +0100 -Subject: [PATCH 25/82] power: supply: axp20x-usb-power: Support input current - limit - -Allow to set input current limit directly when autodetection fails -on incorrectly wired tablets, like TBS A711, that don't have -D+/D- pins connected, and can't detect the usb power supply type. - -Signed-off-by: Ondrej Jirman ---- - drivers/power/supply/axp20x_usb_power.c | 104 +++++++++++++++++++++++- - include/linux/mfd/axp20x.h | 1 + - 2 files changed, 104 insertions(+), 1 deletion(-) - -diff --git a/drivers/power/supply/axp20x_usb_power.c b/drivers/power/supply/axp20x_usb_power.c -index 4b04fb8f496c..3bc2e1f7ab83 100644 ---- a/drivers/power/supply/axp20x_usb_power.c -+++ b/drivers/power/supply/axp20x_usb_power.c -@@ -49,6 +49,8 @@ - #define AXP20X_ADC_EN1_VBUS_VOLT BIT(3) - - #define AXP20X_VBUS_MON_VBUS_VALID BIT(3) -+#define AXP813_CHRG_CTRL3_VBUS_CUR_LIMIT_MASK GENMASK(7, 4) -+#define AXP813_CHRG_CTRL3_VBUS_CUR_LIMIT_OFFSET 4 - - struct axp20x_usb_power { - struct device_node *np; -@@ -93,6 +95,50 @@ static int axp813_get_current_max(struct axp20x_usb_power *power, int *val) - return 0; - } - -+static int -+axp813_usb_power_get_input_current_limit(struct axp20x_usb_power *power, -+ int *intval) -+{ -+ unsigned int v; -+ int ret = regmap_read(power->regmap, AXP813_CHRG_CTRL3, &v); -+ -+ if (ret) -+ return ret; -+ -+ v &= AXP813_CHRG_CTRL3_VBUS_CUR_LIMIT_MASK; -+ v >>= AXP813_CHRG_CTRL3_VBUS_CUR_LIMIT_OFFSET; -+ -+ switch (v) { -+ case 0: -+ *intval = 100000; -+ return 0; -+ case 1: -+ *intval = 500000; -+ return 0; -+ case 2: -+ *intval = 900000; -+ return 0; -+ case 3: -+ *intval = 1500000; -+ return 0; -+ case 4: -+ *intval = 2000000; -+ return 0; -+ case 5: -+ *intval = 2500000; -+ return 0; -+ case 6: -+ *intval = 3000000; -+ return 0; -+ case 7: -+ *intval = 3500000; -+ return 0; -+ default: -+ *intval = 4000000; -+ return 0; -+ } -+} -+ - static int axp20x_get_current_max(struct axp20x_usb_power *power, int *val) - { - unsigned int v; -@@ -219,6 +265,11 @@ static int axp20x_usb_power_get_property(struct power_supply *psy, - case POWER_SUPPLY_PROP_ONLINE: - val->intval = !!(input & AXP20X_PWR_STATUS_VBUS_USED); - break; -+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: -+ if (power->axp20x_id == AXP813_ID) -+ return axp813_usb_power_get_input_current_limit(power, -+ &val->intval); -+ /* fallthrough */ - default: - return -EINVAL; - } -@@ -252,6 +303,50 @@ static int axp20x_usb_power_set_voltage_min(struct axp20x_usb_power *power, - return -EINVAL; - } - -+static int -+axp813_usb_power_set_input_current_limit(struct axp20x_usb_power *power, -+ int intval) -+{ -+ unsigned int reg; -+ -+ switch (intval) { -+ case 100000: -+ reg = 0; -+ break; -+ case 500000: -+ reg = 1; -+ break; -+ case 900000: -+ reg = 2; -+ break; -+ case 1500000: -+ reg = 3; -+ break; -+ case 2000000: -+ reg = 4; -+ break; -+ case 2500000: -+ reg = 5; -+ break; -+ case 3000000: -+ reg = 6; -+ break; -+ case 3500000: -+ reg = 7; -+ break; -+ case 4000000: -+ reg = 8; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return regmap_update_bits(power->regmap, -+ AXP813_CHRG_CTRL3, -+ AXP813_CHRG_CTRL3_VBUS_CUR_LIMIT_MASK, -+ reg << AXP813_CHRG_CTRL3_VBUS_CUR_LIMIT_OFFSET); -+} -+ - static int axp813_usb_power_set_current_max(struct axp20x_usb_power *power, - int intval) - { -@@ -316,6 +411,11 @@ static int axp20x_usb_power_set_property(struct power_supply *psy, - val->intval); - return axp20x_usb_power_set_current_max(power, val->intval); - -+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: -+ if (power->axp20x_id == AXP813_ID) -+ return axp813_usb_power_set_input_current_limit(power, -+ val->intval); -+ /* fallthrough */ - default: - return -EINVAL; - } -@@ -327,7 +427,8 @@ static int axp20x_usb_power_prop_writeable(struct power_supply *psy, - enum power_supply_property psp) - { - return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN || -- psp == POWER_SUPPLY_PROP_CURRENT_MAX; -+ psp == POWER_SUPPLY_PROP_CURRENT_MAX || -+ psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT; - } - - static enum power_supply_property axp20x_usb_power_properties[] = { -@@ -346,6 +447,7 @@ static enum power_supply_property axp22x_usb_power_properties[] = { - POWER_SUPPLY_PROP_ONLINE, - POWER_SUPPLY_PROP_VOLTAGE_MIN, - POWER_SUPPLY_PROP_CURRENT_MAX, -+ POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, - }; - - static const struct power_supply_desc axp20x_usb_power_desc = { -diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h -index 517e60eecbcb..1c968a2e31f7 100644 ---- a/include/linux/mfd/axp20x.h -+++ b/include/linux/mfd/axp20x.h -@@ -133,6 +133,7 @@ enum axp20x_variants { - - /* Other DCDC regulator control registers are the same as AXP803 */ - #define AXP813_DCDC7_V_OUT 0x26 -+#define AXP813_CHRG_CTRL3 0x35 - - /* Interrupt */ - #define AXP152_IRQ1_EN 0x40 --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0026-mfd-axp20x-Make-AXP22X_CHRG_CTRL3-because-it-is-upda.patch b/patch/kernel/sunxi-legacy/0000-0026-mfd-axp20x-Make-AXP22X_CHRG_CTRL3-because-it-is-upda.patch deleted file mode 100644 index f4c8fedc4..000000000 --- a/patch/kernel/sunxi-legacy/0000-0026-mfd-axp20x-Make-AXP22X_CHRG_CTRL3-because-it-is-upda.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 22b15d77f99612906a02c96b9b926233d187605f Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Thu, 16 Nov 2017 00:30:19 +0100 -Subject: [PATCH 26/82] mfd: axp20x: Make AXP22X_CHRG_CTRL3 because it is - updated by charger det. - -Charger detection updates this to reflect allowed current. - -Signed-off-by: Ondrej Jirman ---- - drivers/mfd/axp20x.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c -index 95f36a7e3cd4..81bf6ee4d8bb 100644 ---- a/drivers/mfd/axp20x.c -+++ b/drivers/mfd/axp20x.c -@@ -131,6 +131,7 @@ static const struct regmap_range axp288_volatile_ranges[] = { - regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL), - regmap_reg_range(AXP288_BC_DET_STAT, AXP288_BC_DET_STAT), - regmap_reg_range(AXP20X_CHRG_BAK_CTRL, AXP20X_CHRG_BAK_CTRL), -+ regmap_reg_range(AXP22X_CHRG_CTRL3, AXP22X_CHRG_CTRL3), - regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L), - regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL), - regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE), --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0027-arm-dts-sun8i-a83t-a711-update-brightness-levels-to-.patch b/patch/kernel/sunxi-legacy/0000-0027-arm-dts-sun8i-a83t-a711-update-brightness-levels-to-.patch deleted file mode 100644 index b096ca563..000000000 --- a/patch/kernel/sunxi-legacy/0000-0027-arm-dts-sun8i-a83t-a711-update-brightness-levels-to-.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 5e76e10095d6370a3c7235543acda9b4f256d246 Mon Sep 17 00:00:00 2001 -From: Tomas Novotny -Date: Tue, 24 Oct 2017 15:07:42 +0200 -Subject: [PATCH 27/82] arm: dts: sun8i: a83t: a711: update brightness levels - to fit the device - -The function is exponential with base of 1.32 and some offset and -tweaks. The lowest values produce no output, so we are starting at 8. -The default brigtness is a bit lower than maximum to boot with reduced -backlight. - -Signed-off-by: Tomas Novotny ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index dc7b94a6c068..bd7e231e3aba 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -65,8 +65,11 @@ - pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>; - enable-gpios = <&pio 3 29 GPIO_ACTIVE_HIGH>; - -- brightness-levels = <0 1 2 4 8 16 32 64 128 255>; -- default-brightness-level = <9>; -+ brightness-levels = <0 8 9 10 11 13 15 17 19 21 23 25 28 -+ 31 34 37 40 44 48 52 56 61 67 72 78 -+ 84 91 98 106 115 124 133 143 154 -+ 166 179 192 207 223 239 255>; -+ default-brightness-level = <39>; - }; - - panel { --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0028-media-sun6i-csi-Add-support-for-Allwinner-CSI.patch b/patch/kernel/sunxi-legacy/0000-0028-media-sun6i-csi-Add-support-for-Allwinner-CSI.patch deleted file mode 100644 index 93b51fe2b..000000000 --- a/patch/kernel/sunxi-legacy/0000-0028-media-sun6i-csi-Add-support-for-Allwinner-CSI.patch +++ /dev/null @@ -1,2406 +0,0 @@ -From 438feaa4594948fe66ed88232d56223229f9bffc Mon Sep 17 00:00:00 2001 -From: Yong Deng -Date: Thu, 27 Jul 2017 13:01:35 +0800 -Subject: [PATCH 28/82] media: sun6i-csi: Add support for Allwinner CSI - -Allwinner V3s SoC has two CSI modules. CSI0 is used for MIPI interface -and CSI1 is used for parallel interface. This is not documented in -datasheet but it was found by testing and guessing. - -This patch implements a v4l2 framework driver for it. - -Currently, the driver only support the parallel interface. MIPI-CSI2, -ISP's support are not included in this patch. - -This patch was cleaned up and extended to support A83T by Ondrej Jirman. - -Signed-off-by: Yong Deng -Signed-off-by: Ondrej Jirman ---- - drivers/media/platform/Kconfig | 1 + - drivers/media/platform/Makefile | 2 + - drivers/media/platform/sun6i-csi/Kconfig | 9 + - drivers/media/platform/sun6i-csi/Makefile | 3 + - drivers/media/platform/sun6i-csi/sun6i_csi.c | 1077 +++++++++++++++++ - drivers/media/platform/sun6i-csi/sun6i_csi.h | 202 ++++ - .../media/platform/sun6i-csi/sun6i_csi_v3s.c | 776 ++++++++++++ - .../media/platform/sun6i-csi/sun6i_csi_v3s.h | 243 ++++ - 8 files changed, 2313 insertions(+) - create mode 100644 drivers/media/platform/sun6i-csi/Kconfig - create mode 100644 drivers/media/platform/sun6i-csi/Makefile - create mode 100644 drivers/media/platform/sun6i-csi/sun6i_csi.c - create mode 100644 drivers/media/platform/sun6i-csi/sun6i_csi.h - create mode 100644 drivers/media/platform/sun6i-csi/sun6i_csi_v3s.c - create mode 100644 drivers/media/platform/sun6i-csi/sun6i_csi_v3s.h - -diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig -index 54fe90acb5b2..643c8671a621 100644 ---- a/drivers/media/platform/Kconfig -+++ b/drivers/media/platform/Kconfig -@@ -137,6 +137,7 @@ source "drivers/media/platform/am437x/Kconfig" - source "drivers/media/platform/xilinx/Kconfig" - source "drivers/media/platform/rcar-vin/Kconfig" - source "drivers/media/platform/atmel/Kconfig" -+source "drivers/media/platform/sun6i-csi/Kconfig" - - config VIDEO_TI_CAL - tristate "TI CAL (Camera Adaptation Layer) driver" -diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile -index 41322ab65802..e7938f293e0c 100644 ---- a/drivers/media/platform/Makefile -+++ b/drivers/media/platform/Makefile -@@ -96,3 +96,5 @@ obj-$(CONFIG_VIDEO_QCOM_VENUS) += qcom/venus/ - obj-y += meson/ - - obj-y += cros-ec-cec/ -+ -+obj-$(CONFIG_VIDEO_SUN6I_CSI) += sun6i-csi/ -diff --git a/drivers/media/platform/sun6i-csi/Kconfig b/drivers/media/platform/sun6i-csi/Kconfig -new file mode 100644 -index 000000000000..314188aae2c2 ---- /dev/null -+++ b/drivers/media/platform/sun6i-csi/Kconfig -@@ -0,0 +1,9 @@ -+config VIDEO_SUN6I_CSI -+ tristate "Allwinner V3s Camera Sensor Interface driver" -+ depends on VIDEO_V4L2 && COMMON_CLK && VIDEO_V4L2_SUBDEV_API && HAS_DMA -+ depends on ARCH_SUNXI || COMPILE_TEST -+ select VIDEOBUF2_DMA_CONTIG -+ select REGMAP_MMIO -+ select V4L2_FWNODE -+ ---help--- -+ Support for the Allwinner Camera Sensor Interface Controller on V3s. -diff --git a/drivers/media/platform/sun6i-csi/Makefile b/drivers/media/platform/sun6i-csi/Makefile -new file mode 100644 -index 000000000000..7def1914cae1 ---- /dev/null -+++ b/drivers/media/platform/sun6i-csi/Makefile -@@ -0,0 +1,3 @@ -+sun6i-csi-y += sun6i_csi.o sun6i_csi_v3s.o -+ -+obj-$(CONFIG_VIDEO_SUN6I_CSI) += sun6i-csi.o -diff --git a/drivers/media/platform/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sun6i-csi/sun6i_csi.c -new file mode 100644 -index 000000000000..8cfccc5782b1 ---- /dev/null -+++ b/drivers/media/platform/sun6i-csi/sun6i_csi.c -@@ -0,0 +1,1077 @@ -+/* -+ * Copyright (c) 2017 Magewell Electronics Co., Ltd. (Nanjing). -+ * All rights reserved. -+ * Author: Yong Deng -+ * Copyright (c) 2017 Ondrej Jirman -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#define DEBUG -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "sun6i_csi.h" -+ -+// {{{ utils -+ -+static struct sun6i_csi_subdev * -+sun6i_get_enabled_subdev(struct sun6i_csi *csi) -+{ -+ struct media_pad *remote; -+ -+ remote = media_entity_remote_pad(&csi->pad); -+ -+ if (!remote || !is_media_entity_v4l2_subdev(remote->entity)) -+ return NULL; -+ -+ return v4l2_get_subdev_hostdata( -+ media_entity_to_v4l2_subdev(remote->entity)); -+} -+ -+static struct sun6i_csi_format * -+sun6i_find_format_by_fourcc(struct sun6i_csi *csi, u32 fourcc) -+{ -+ int i; -+ -+ for (i = 0; i < csi->num_formats; i++) -+ if (csi->formats[i].fourcc == fourcc) -+ return &csi->formats[i]; -+ -+ return NULL; -+} -+ -+// }}} -+// {{{ vb2 -+ -+struct sun6i_csi_buffer { -+ struct vb2_v4l2_buffer vb; -+ struct list_head list; -+ -+ dma_addr_t dma_addr; -+}; -+ -+static int sun6i_video_queue_setup(struct vb2_queue *vq, -+ unsigned int *nbuffers, unsigned int *nplanes, -+ unsigned int sizes[], -+ struct device *alloc_devs[]) -+{ -+ struct sun6i_csi *csi = vb2_get_drv_priv(vq); -+ unsigned int size = csi->fmt.fmt.pix.sizeimage; -+ -+ if (*nplanes) -+ return sizes[0] < size ? -EINVAL : 0; -+ -+ *nplanes = 1; -+ sizes[0] = size; -+ -+ return 0; -+} -+ -+static int sun6i_video_buffer_prepare(struct vb2_buffer *vb) -+{ -+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); -+ struct sun6i_csi_buffer *buf = -+ container_of(vbuf, struct sun6i_csi_buffer, vb); -+ struct sun6i_csi *csi = vb2_get_drv_priv(vb->vb2_queue); -+ unsigned long size = csi->fmt.fmt.pix.sizeimage; -+ -+ if (vb2_plane_size(vb, 0) < size) { -+ v4l2_err(csi->vdev.v4l2_dev, "buffer too small (%lu < %lu)\n", -+ vb2_plane_size(vb, 0), size); -+ return -EINVAL; -+ } -+ -+ vb2_set_plane_payload(vb, 0, size); -+ buf->dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0); -+ vbuf->field = csi->fmt.fmt.pix.field; -+ -+ return 0; -+} -+ -+static int sun6i_sources_set_stream(struct sun6i_csi *csi, bool enable) -+{ -+ struct media_entity *entity; -+ struct media_pad *pad; -+ struct v4l2_subdev *subdev; -+ int ret; -+ -+ entity = &csi->vdev.entity; -+ while (1) { -+ pad = &entity->pads[0]; -+ if (!(pad->flags & MEDIA_PAD_FL_SINK)) -+ break; -+ -+ pad = media_entity_remote_pad(pad); -+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) -+ break; -+ -+ entity = pad->entity; -+ subdev = media_entity_to_v4l2_subdev(entity); -+ -+ ret = v4l2_subdev_call(subdev, video, s_stream, enable); -+ if (enable && ret < 0 && ret != -ENOIOCTLCMD) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int sun6i_csi_apply_config(struct sun6i_csi *csi) -+{ -+ struct sun6i_csi_subdev *csi_sd; -+ -+ csi_sd = sun6i_get_enabled_subdev(csi); -+ if (csi_sd == NULL) -+ return -ENXIO; -+ -+ if (csi->ops != NULL && csi->ops->apply_config != NULL) -+ return csi->ops->apply_config(csi, csi_sd); -+ -+ return -ENOIOCTLCMD; -+} -+ -+static int sun6i_video_start_streaming(struct vb2_queue *vq, unsigned int count) -+{ -+ struct sun6i_csi *csi = vb2_get_drv_priv(vq); -+ struct sun6i_csi_buffer *buf; -+ unsigned long flags; -+ int ret; -+ -+ ret = media_pipeline_start(&csi->vdev.entity, &csi->vdev.pipe); -+ if (ret < 0) -+ goto err_queue_buffers; -+ -+ ret = sun6i_csi_apply_config(csi); -+ if (ret < 0) -+ goto err_stop_media_pipeline; -+ -+ spin_lock_irqsave(&csi->dma_queue_lock, flags); -+ csi->sequence = 0; -+ csi->skip_first_interrupt = true; -+ buf = list_first_entry(&csi->dma_queue, struct sun6i_csi_buffer, list); -+ ret = sun6i_csi_update_buf_addr(csi, buf->dma_addr); -+ spin_unlock_irqrestore(&csi->dma_queue_lock, flags); -+ if (ret < 0) -+ goto err_stop_media_pipeline; -+ -+ ret = sun6i_csi_set_stream(csi, true); -+ if (ret < 0) -+ goto err_stop_media_pipeline; -+ -+ ret = sun6i_sources_set_stream(csi, true); -+ if (ret < 0) -+ goto err_stop_stream; -+ -+ return 0; -+ -+err_stop_stream: -+ sun6i_sources_set_stream(csi, false); -+err_stop_media_pipeline: -+ media_pipeline_stop(&csi->vdev.entity); -+err_queue_buffers: -+ spin_lock_irqsave(&csi->dma_queue_lock, flags); -+ list_for_each_entry(buf, &csi->dma_queue, list) -+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED); -+ INIT_LIST_HEAD(&csi->dma_queue); -+ spin_unlock_irqrestore(&csi->dma_queue_lock, flags); -+ -+ return ret; -+} -+ -+static void sun6i_video_stop_streaming(struct vb2_queue *vq) -+{ -+ struct sun6i_csi *csi = vb2_get_drv_priv(vq); -+ unsigned long flags; -+ struct sun6i_csi_buffer *buf; -+ -+ sun6i_csi_set_stream(csi, false); -+ sun6i_sources_set_stream(csi, false); -+ media_pipeline_stop(&csi->vdev.entity); -+ -+ /* Release all active buffers */ -+ spin_lock_irqsave(&csi->dma_queue_lock, flags); -+ list_for_each_entry(buf, &csi->dma_queue, list) -+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); -+ INIT_LIST_HEAD(&csi->dma_queue); -+ spin_unlock_irqrestore(&csi->dma_queue_lock, flags); -+} -+ -+static void sun6i_video_buffer_queue(struct vb2_buffer *vb) -+{ -+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); -+ struct sun6i_csi_buffer *buf = -+ container_of(vbuf, struct sun6i_csi_buffer, vb); -+ struct sun6i_csi *csi = vb2_get_drv_priv(vb->vb2_queue); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&csi->dma_queue_lock, flags); -+ list_add_tail(&buf->list, &csi->dma_queue); -+ spin_unlock_irqrestore(&csi->dma_queue_lock, flags); -+} -+ -+void sun6i_video_frame_done(struct sun6i_csi *csi) -+{ -+ struct sun6i_csi_buffer *buf; -+ struct sun6i_csi_buffer *next_buf; -+ bool can_dequeue; -+ -+ spin_lock(&csi->dma_queue_lock); -+ -+ if (!vb2_is_streaming(&csi->vb2_vidq)) -+ goto out_unlock; -+ -+ /* we always keep two buffers in the queue and expect the third */ -+ buf = list_first_entry(&csi->dma_queue, struct sun6i_csi_buffer, list); -+ next_buf = list_next_entry(buf, list); -+ can_dequeue = !list_is_last(&next_buf->list, &csi->dma_queue); -+ -+ if (csi->skip_first_interrupt) { -+ csi->skip_first_interrupt = false; -+ sun6i_csi_update_buf_addr(csi, next_buf->dma_addr); -+ goto out_unlock; -+ } else if (!can_dequeue) { -+ csi->skip_first_interrupt = true; -+ } else { -+ struct vb2_v4l2_buffer *vbuf = &buf->vb; -+ struct vb2_buffer *vb = &vbuf->vb2_buf; -+ -+ vb->timestamp = ktime_get_ns(); -+ vbuf->sequence = csi->sequence++; -+ vb2_buffer_done(vb, VB2_BUF_STATE_DONE); -+ -+ list_del(&buf->list); -+ -+ next_buf = list_next_entry(next_buf, list); -+ sun6i_csi_update_buf_addr(csi, next_buf->dma_addr); -+ } -+ -+out_unlock: -+ spin_unlock(&csi->dma_queue_lock); -+} -+ -+static struct vb2_ops sun6i_csi_vb2_ops = { -+ .queue_setup = sun6i_video_queue_setup, -+ .wait_prepare = vb2_ops_wait_prepare, -+ .wait_finish = vb2_ops_wait_finish, -+ .buf_prepare = sun6i_video_buffer_prepare, -+ .start_streaming = sun6i_video_start_streaming, -+ .stop_streaming = sun6i_video_stop_streaming, -+ .buf_queue = sun6i_video_buffer_queue, -+}; -+ -+// }}} -+// {{{ videodev ioct -+ -+static int sun6i_video_set_fmt(struct sun6i_csi *csi, struct v4l2_format *f, -+ bool try_only) -+{ -+ struct v4l2_subdev_format sd_fmt; -+ struct v4l2_subdev_pad_config padconf; -+ struct v4l2_pix_format *pixfmt = &f->fmt.pix; -+ struct sun6i_csi_format *csi_fmt; -+ struct sun6i_csi_subdev *csi_sd; -+ int ret; -+ -+ if (csi->num_formats == 0) -+ return -EINVAL; -+ -+ csi_fmt = sun6i_find_format_by_fourcc(csi, pixfmt->pixelformat); -+ if (csi_fmt == NULL) -+ csi_fmt = &csi->formats[0]; -+ pixfmt->pixelformat = csi_fmt->fourcc; -+ -+ csi_sd = sun6i_get_enabled_subdev(csi); -+ if (csi_sd == NULL) -+ return -ENXIO; -+ -+ sd_fmt.pad = csi_sd->pad; -+ sd_fmt.which = V4L2_SUBDEV_FORMAT_TRY; -+ v4l2_fill_mbus_format(&sd_fmt.format, pixfmt, csi_fmt->mbus_code); -+ ret = v4l2_subdev_call(csi_sd->sd, pad, set_fmt, &padconf, &sd_fmt); -+ if (ret) -+ return ret; -+ -+ v4l2_fill_pix_format(pixfmt, &sd_fmt.format); -+ pixfmt->bytesperline = (pixfmt->width * csi_fmt->bpp) / 8; -+ pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; -+ pixfmt->flags = 0; -+ -+ if (!try_only) { -+ sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; -+ ret = v4l2_subdev_call(csi_sd->sd, pad, set_fmt, NULL, &sd_fmt); -+ if (ret) -+ return ret; -+ -+ //XXX: check that we got an expected format -+ -+ csi->fmt = *f; -+ csi->current_fmt = csi_fmt; -+ } -+ -+ return 0; -+} -+ -+static int sun6i_querycap(struct file *file, void *priv, -+ struct v4l2_capability *cap) -+{ -+ struct sun6i_csi *csi = video_drvdata(file); -+ -+ strlcpy(cap->driver, "sun6i-video", sizeof(cap->driver)); -+ strlcpy(cap->card, csi->vdev.name, sizeof(cap->card)); -+ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", -+ csi->dev->of_node->name); -+ -+ return 0; -+} -+ -+static int sun6i_try_fmt_vid_cap(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct sun6i_csi *csi = video_drvdata(file); -+ -+ return sun6i_video_set_fmt(csi, f, true); -+} -+ -+static int sun6i_g_fmt_vid_cap(struct file *file, void *priv, -+ struct v4l2_format *fmt) -+{ -+ struct sun6i_csi *csi = video_drvdata(file); -+ -+ *fmt = csi->fmt; -+ -+ return 0; -+} -+ -+static int sun6i_s_fmt_vid_cap(struct file *file, void *priv, -+ struct v4l2_format *f) -+{ -+ struct sun6i_csi *csi = video_drvdata(file); -+ -+ if (vb2_is_streaming(&csi->vb2_vidq)) -+ return -EBUSY; -+ -+ return sun6i_video_set_fmt(csi, f, false); -+} -+ -+static int sun6i_enum_fmt_vid_cap(struct file *file, void *priv, -+ struct v4l2_fmtdesc *f) -+{ -+ struct sun6i_csi *csi = video_drvdata(file); -+ -+ if (f->index >= csi->num_formats) -+ return -EINVAL; -+ -+ f->flags = 0; -+ f->description[0] = '\0'; -+ f->pixelformat = csi->formats[f->index].fourcc; -+ -+ return 0; -+} -+ -+static int sun6i_enum_framesizes(struct file *file, void *priv, -+ struct v4l2_frmsizeenum *fsize) -+{ -+ struct sun6i_csi *csi = video_drvdata(file); -+ struct sun6i_csi_format *csi_fmt; -+ struct sun6i_csi_subdev *csi_sd; -+ struct v4l2_subdev_frame_size_enum fse = { -+ .index = fsize->index, -+ .which = V4L2_SUBDEV_FORMAT_ACTIVE, -+ }; -+ int ret; -+ -+ csi_fmt = sun6i_find_format_by_fourcc(csi, fsize->pixel_format); -+ if (!csi_fmt) -+ return -EINVAL; -+ -+ fse.code = csi_fmt->mbus_code; -+ -+ csi_sd = sun6i_get_enabled_subdev(csi); -+ if (csi_sd == NULL) -+ return -ENXIO; -+ -+ ret = v4l2_subdev_call(csi_sd->sd, pad, enum_frame_size, NULL, &fse); -+ if (ret) -+ return ret; -+ -+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; -+ fsize->discrete.width = fse.max_width; -+ fsize->discrete.height = fse.max_height; -+ -+ return 0; -+} -+ -+static int sun6i_enum_frameintervals(struct file *file, void *priv, -+ struct v4l2_frmivalenum *fival) -+{ -+ struct sun6i_csi *csi = video_drvdata(file); -+ struct sun6i_csi_format *csi_fmt; -+ struct sun6i_csi_subdev *csi_sd; -+ struct v4l2_subdev_frame_interval_enum fie = { -+ .index = fival->index, -+ .width = fival->width, -+ .height = fival->height, -+ .which = V4L2_SUBDEV_FORMAT_ACTIVE, -+ }; -+ int ret; -+ -+ csi_fmt = sun6i_find_format_by_fourcc(csi, fival->pixel_format); -+ if (!csi_fmt) -+ return -EINVAL; -+ -+ fie.code = csi_fmt->mbus_code; -+ -+ csi_sd = sun6i_get_enabled_subdev(csi); -+ if (csi_sd == NULL) -+ return -ENXIO; -+ -+ ret = v4l2_subdev_call(csi_sd->sd, pad, -+ enum_frame_interval, NULL, &fie); -+ if (ret) -+ return ret; -+ -+ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; -+ fival->discrete = fie.interval; -+ -+ return 0; -+} -+ -+ -+static int sun6i_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) -+{ -+ struct sun6i_csi *csi = video_drvdata(file); -+ struct sun6i_csi_subdev *csi_sd; -+ -+ if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) -+ return -EINVAL; -+ -+ csi_sd = sun6i_get_enabled_subdev(csi); -+ if (csi_sd == NULL) -+ return -ENXIO; -+ -+ a->parm.capture.readbuffers = 0; -+ return v4l2_subdev_call(csi_sd->sd, video, g_parm, a); -+} -+ -+static int sun6i_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) -+{ -+ struct sun6i_csi *csi = video_drvdata(file); -+ struct sun6i_csi_subdev *csi_sd; -+ -+ if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) -+ return -EINVAL; -+ -+ csi_sd = sun6i_get_enabled_subdev(csi); -+ if (csi_sd == NULL) -+ return -ENXIO; -+ -+ a->parm.capture.readbuffers = 0; -+ return v4l2_subdev_call(csi_sd->sd, video, s_parm, a); -+} -+ -+static int sun6i_enum_input(struct file *file, void *priv, -+ struct v4l2_input *i) -+{ -+ struct sun6i_csi *csi = video_drvdata(file); -+ struct v4l2_subdev *subdev; -+ int ret, s, idx; -+ -+ idx = 0; -+ for (s = 0; s < SUN6I_CSI_NUM_SENSORS; s++) { -+ subdev = csi->sensors[s].sd; -+ if (!subdev) -+ continue; -+ -+ if (idx == i->index) { -+ ret = v4l2_subdev_call(subdev, video, g_input_status, -+ &i->status); -+ if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) -+ return ret; -+ -+ i->type = V4L2_INPUT_TYPE_CAMERA; -+ strlcpy(i->name, "Camera", sizeof(i->name)); -+ return 0; -+ } -+ -+ idx++; -+ } -+ -+ return -EINVAL; -+} -+ -+static int sun6i_g_input(struct file *file, void *priv, unsigned int *i) -+{ -+ //XXX: get index of the enabled input -+ -+ *i = 0; -+ -+ return 0; -+} -+ -+static int sun6i_s_input(struct file *file, void *priv, unsigned int i) -+{ -+ //XXX: enable link -+ -+ if (i > 0) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static const struct v4l2_ioctl_ops sun6i_video_ioctl_ops = { -+ .vidioc_querycap = sun6i_querycap, -+ -+ .vidioc_try_fmt_vid_cap = sun6i_try_fmt_vid_cap, -+ .vidioc_g_fmt_vid_cap = sun6i_g_fmt_vid_cap, -+ .vidioc_s_fmt_vid_cap = sun6i_s_fmt_vid_cap, -+ .vidioc_enum_fmt_vid_cap = sun6i_enum_fmt_vid_cap, -+ -+ .vidioc_g_parm = sun6i_g_parm, -+ .vidioc_s_parm = sun6i_s_parm, -+ .vidioc_enum_framesizes = sun6i_enum_framesizes, -+ .vidioc_enum_frameintervals = sun6i_enum_frameintervals, -+ -+ .vidioc_enum_input = sun6i_enum_input, -+ .vidioc_g_input = sun6i_g_input, -+ .vidioc_s_input = sun6i_s_input, -+ -+ .vidioc_reqbufs = vb2_ioctl_reqbufs, -+ .vidioc_querybuf = vb2_ioctl_querybuf, -+ .vidioc_qbuf = vb2_ioctl_qbuf, -+ .vidioc_expbuf = vb2_ioctl_expbuf, -+ .vidioc_dqbuf = vb2_ioctl_dqbuf, -+ .vidioc_create_bufs = vb2_ioctl_create_bufs, -+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf, -+ .vidioc_streamon = vb2_ioctl_streamon, -+ .vidioc_streamoff = vb2_ioctl_streamoff, -+ -+ .vidioc_log_status = v4l2_ctrl_log_status, -+}; -+ -+// }}} -+// {{{ videodev fops -+ -+/* ----------------------------------------------------------------------------- -+ * V4L2 file operations -+ */ -+static int sun6i_video_open(struct file *file) -+{ -+ struct sun6i_csi *csi = video_drvdata(file); -+ struct v4l2_format format; -+ int ret; -+ -+ if (mutex_lock_interruptible(&csi->lock)) -+ return -ERESTARTSYS; -+ -+ ret = v4l2_fh_open(file); -+ if (ret < 0) -+ goto unlock; -+ -+ ret = v4l2_pipeline_pm_use(&csi->vdev.entity, 1); -+ if (ret < 0) -+ goto fh_release; -+ -+ if (!v4l2_fh_is_singular_file(file)) -+ goto unlock; -+ -+ ret = sun6i_csi_set_power(csi, true); -+ if (ret < 0) -+ goto fh_release; -+ -+ /* setup default format */ -+ if (csi->num_formats > 0) { -+ format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ format.fmt.pix.width = 1280; -+ format.fmt.pix.height = 720; -+ format.fmt.pix.pixelformat = csi->formats[0].fourcc; -+ sun6i_video_set_fmt(csi, &format, false); -+ } -+ -+ mutex_unlock(&csi->lock); -+ return 0; -+ -+fh_release: -+ v4l2_fh_release(file); -+unlock: -+ mutex_unlock(&csi->lock); -+ return ret; -+} -+ -+static int sun6i_video_close(struct file *file) -+{ -+ struct sun6i_csi *csi = video_drvdata(file); -+ bool last_fh; -+ -+ mutex_lock(&csi->lock); -+ -+ last_fh = v4l2_fh_is_singular_file(file); -+ -+ _vb2_fop_release(file, NULL); -+ -+ v4l2_pipeline_pm_use(&csi->vdev.entity, 0); -+ -+ if (last_fh) -+ sun6i_csi_set_power(csi, false); -+ -+ mutex_unlock(&csi->lock); -+ -+ return 0; -+} -+ -+static const struct v4l2_file_operations sun6i_video_fops = { -+ .owner = THIS_MODULE, -+ .open = sun6i_video_open, -+ .release = sun6i_video_close, -+ .unlocked_ioctl = video_ioctl2, -+ .mmap = vb2_fop_mmap, -+ .poll = vb2_fop_poll -+}; -+ -+// }}} -+// {{{ media ops -+ -+/* ----------------------------------------------------------------------------- -+ * Media Operations -+ */ -+ -+static bool -+sun6i_csi_is_format_support(struct sun6i_csi *csi, u32 pixformat, u32 mbus_code, -+ struct sun6i_csi_subdev *csi_sd) -+{ -+ if (csi->ops != NULL && csi->ops->is_format_support != NULL) -+ return csi->ops->is_format_support(csi, pixformat, mbus_code, -+ csi_sd); -+ -+ return -ENOIOCTLCMD; -+} -+ -+static int sun6i_video_formats_init(struct sun6i_csi *csi) -+{ -+ struct v4l2_subdev_mbus_code_enum mbus_code = { 0 }; -+ struct sun6i_csi_subdev *csi_sd; -+ const u32 *pixformats; -+ int pixformat_count = 0; -+ u32 subdev_codes[32]; -+ int codes_count = 0; -+ int num_fmts = 0; -+ int i, j; -+ -+ csi_sd = sun6i_get_enabled_subdev(csi); -+ if (csi_sd == NULL) -+ return -ENXIO; -+ -+ /* Get supported pixformats of CSI */ -+ pixformat_count = sun6i_csi_get_supported_pixformats(csi, &pixformats); -+ if (pixformat_count <= 0) -+ return -ENXIO; -+ -+ /* Get subdev formats codes */ -+ mbus_code.pad = csi_sd->pad; -+ mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE; -+ while (codes_count < ARRAY_SIZE(subdev_codes) && -+ !v4l2_subdev_call(csi_sd->sd, pad, enum_mbus_code, NULL, -+ &mbus_code)) { -+ subdev_codes[codes_count] = mbus_code.code; -+ codes_count++; -+ mbus_code.index++; -+ } -+ -+ if (!codes_count) -+ return -ENXIO; -+ -+ /* Get supported formats count */ -+ for (j = 0; j < pixformat_count; j++) { -+ for (i = 0; i < codes_count; i++) { -+ if (!sun6i_csi_is_format_support(csi, pixformats[j], -+ subdev_codes[i], csi_sd)) -+ continue; -+ num_fmts++; -+ break; -+ } -+ } -+ -+ if (!num_fmts) -+ return -ENXIO; -+ -+ if (csi->formats) -+ devm_kfree(csi->dev, csi->formats); -+ -+ csi->num_formats = num_fmts; -+ csi->formats = devm_kcalloc(csi->dev, num_fmts, -+ sizeof(struct sun6i_csi_format), GFP_KERNEL); -+ if (!csi->formats) -+ return -ENOMEM; -+ -+ /* Get supported formats */ -+ num_fmts = 0; -+ for (j = 0; j < pixformat_count; j++) { -+ for (i = 0; i < codes_count; i++) { -+ if (!sun6i_csi_is_format_support(csi, pixformats[j], -+ subdev_codes[i], csi_sd)) -+ continue; -+ -+ dev_dbg(csi->dev, "supported format: pix=%d:bus=%d\n", -+ pixformats[j], subdev_codes[i]); -+ -+ csi->formats[num_fmts].fourcc = pixformats[j]; -+ csi->formats[num_fmts].mbus_code = subdev_codes[i]; -+ csi->formats[num_fmts].bpp = -+ v4l2_pixformat_get_bpp(pixformats[j]); -+ num_fmts++; -+ break; -+ } -+ } -+ -+ return 0; -+} -+ -+static int sun6i_video_link_setup(struct media_entity *entity, -+ const struct media_pad *local, -+ const struct media_pad *remote, u32 flags) -+{ -+ struct video_device *vdev = media_entity_to_video_device(entity); -+ struct sun6i_csi *csi = video_get_drvdata(vdev); -+ -+ if (WARN_ON(csi == NULL)) -+ return 0; -+ -+ return sun6i_video_formats_init(csi); -+} -+ -+static const struct media_entity_operations sun6i_video_media_ops = { -+ .link_setup = sun6i_video_link_setup, -+}; -+ -+// }}} -+// {{{ sun6i_csi video init/cleanup -+ -+static void sun6i_video_cleanup(struct sun6i_csi *csi) -+{ -+ if (video_is_registered(&csi->vdev)) -+ video_unregister_device(&csi->vdev); -+ -+ media_entity_cleanup(&csi->vdev.entity); -+} -+ -+static int sun6i_video_init(struct sun6i_csi *csi, const char *name) -+{ -+ struct video_device *vdev = &csi->vdev; -+ struct vb2_queue *vidq = &csi->vb2_vidq; -+ int ret; -+ -+ /* Initialize the media entity... */ -+ csi->pad.flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT; -+ vdev->entity.ops = &sun6i_video_media_ops; -+ ret = media_entity_pads_init(&vdev->entity, 1, &csi->pad); -+ if (ret < 0) -+ return ret; -+ -+ mutex_init(&csi->lock); -+ -+ INIT_LIST_HEAD(&csi->dma_queue); -+ spin_lock_init(&csi->dma_queue_lock); -+ -+ csi->sequence = 0; -+ csi->num_formats = 0; -+ -+ /* Initialize videobuf2 queue */ -+ vidq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; -+ vidq->io_modes = VB2_MMAP | VB2_DMABUF; -+ vidq->drv_priv = csi; -+ vidq->buf_struct_size = sizeof(struct sun6i_csi_buffer); -+ vidq->ops = &sun6i_csi_vb2_ops; -+ vidq->mem_ops = &vb2_dma_contig_memops; -+ vidq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; -+ vidq->lock = &csi->lock; -+ vidq->min_buffers_needed = 2; -+ vidq->dev = csi->dev; -+ -+ ret = vb2_queue_init(vidq); -+ if (ret) { -+ v4l2_err(&csi->v4l2_dev, "vb2_queue_init failed: %d\n", ret); -+ goto error; -+ } -+ -+ /* Register video device */ -+ strlcpy(vdev->name, name, sizeof(vdev->name)); -+ vdev->release = video_device_release_empty; -+ vdev->fops = &sun6i_video_fops; -+ vdev->ioctl_ops = &sun6i_video_ioctl_ops; -+ vdev->vfl_type = VFL_TYPE_GRABBER; -+ vdev->vfl_dir = VFL_DIR_RX; -+ vdev->v4l2_dev = &csi->v4l2_dev; -+ vdev->queue = vidq; -+ vdev->lock = &csi->lock; -+ vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE; -+ video_set_drvdata(vdev, csi); -+ -+ ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); -+ if (ret < 0) { -+ v4l2_err(&csi->v4l2_dev, -+ "video_register_device failed: %d\n", ret); -+ goto error; -+ } -+ -+ return 0; -+ -+error: -+ sun6i_video_cleanup(csi); -+ return ret; -+} -+ -+// }}} -+// {{{ sun6i_csi init/cleanup - DT parsing/subdev setup -+ -+struct sun6i_csi_async_subdev { -+ struct v4l2_async_subdev asd; /* must be first */ -+ unsigned int ep_id; -+ enum v4l2_mbus_type bus_type; -+ struct v4l2_fwnode_bus_parallel parallel; -+}; -+ -+#define notifier_to_csi(n) container_of(n, struct sun6i_csi, notifier) -+#define asd_to_csi_asd(a) container_of(a, struct sun6i_csi_async_subdev, asd) -+ -+static int sun6i_csi_notify_bound(struct v4l2_async_notifier *notifier, -+ struct v4l2_subdev *subdev, -+ struct v4l2_async_subdev *asd) -+{ -+ struct sun6i_csi *csi = notifier_to_csi(notifier); -+ struct sun6i_csi_async_subdev *csi_asd = asd_to_csi_asd(asd); -+ unsigned int i; -+ -+ dev_dbg(csi->dev, "bound subdev %s\n", subdev->name); -+ -+ if (subdev->entity.function != MEDIA_ENT_F_CAM_SENSOR) { -+ dev_err(csi->dev, "subdev %s must be a camera sensor\n", -+ subdev->name); -+ return -EINVAL; -+ } -+ -+ for (i = 0; i < SUN6I_CSI_NUM_SENSORS; i++) { -+ if (csi->sensors[i].sd == NULL) { -+ csi->sensors[i].sd = subdev; -+ csi->sensors[i].ep_id = csi_asd->ep_id; -+ csi->sensors[i].bus_type = csi_asd->bus_type; -+ csi->sensors[i].parallel = csi_asd->parallel; -+ v4l2_set_subdev_hostdata(subdev, &csi->sensors[i]); -+ return 0; -+ } -+ } -+ -+ dev_err(csi->dev, "subdev %s not bound, not enough sensor slots\n", -+ subdev->name); -+ return -ENOMEM; -+} -+ -+static void sun6i_csi_notify_unbind(struct v4l2_async_notifier *notifier, -+ struct v4l2_subdev *subdev, -+ struct v4l2_async_subdev *asd) -+{ -+ struct sun6i_csi *csi = notifier_to_csi(notifier); -+ //struct sun6i_csi_async_subdev *csi_asd = asd_to_csi_asd(asd); -+ unsigned int i; -+ -+ dev_err(csi->dev, "unbind subdev %s\n", subdev->name); -+ -+ for (i = 0; i < SUN6I_CSI_NUM_SENSORS; i++) { -+ if (csi->sensors[i].sd == subdev) { -+ csi->sensors[i].sd = NULL; -+ v4l2_set_subdev_hostdata(subdev, NULL); -+ return; -+ } -+ } -+} -+ -+static int sun6i_csi_notify_complete(struct v4l2_async_notifier *notifier) -+{ -+ struct sun6i_csi *csi = notifier_to_csi(notifier); -+ struct v4l2_subdev *subdev; -+ struct media_entity *sink = &csi->vdev.entity; -+ struct media_entity *source; -+ unsigned int pad; -+ unsigned int i; -+ int ret; -+ bool first_sensor = true; -+ -+ dev_dbg(csi->dev, "notify complete, all subdevs bound\n"); -+ -+ for (i = 0; i < SUN6I_CSI_NUM_SENSORS; i++) { -+ subdev = csi->sensors[i].sd; -+ if (subdev == NULL) -+ continue; -+ -+ source = &subdev->entity; -+ -+ for (pad = 0; pad < source->num_pads; pad++) { -+ if (!(source->pads[pad].flags & MEDIA_PAD_FL_SOURCE)) -+ continue; -+ -+ csi->sensors[i].pad = pad; -+ -+ ret = media_create_pad_link(source, pad, sink, -+ 0, first_sensor ? -+ MEDIA_LNK_FL_ENABLED : 0); -+ if (ret) -+ return ret; -+ -+ dev_dbg(csi->dev, "created pad link %s:%u -> %s:0\n", -+ subdev->name, pad, csi->vdev.name); -+ -+ if (first_sensor) { -+ ret = media_entity_call(sink, link_setup, -+ &sink->pads[0], -+ &source->pads[pad], 0); -+ if (ret) -+ return ret; -+ } -+ -+ first_sensor = false; -+ goto next_sensor; -+ } -+ -+ dev_err(csi->dev, "subdev %s - no source pad found\n", -+ subdev->name); -+ return -EINVAL; -+next_sensor:; -+ } -+ -+ ret = v4l2_device_register_subdev_nodes(&csi->v4l2_dev); -+ if (ret < 0) { -+ dev_err(csi->dev, "failed to register subdev nodes\n"); -+ return ret; -+ } -+ -+ dev_dbg(csi->dev, "registering media device\n"); -+ -+ return media_device_register(&csi->media_dev); -+} -+ -+// this is called for each controller endpoint -+static int sun6i_csi_parse_subdev_endpoint(struct device *dev, -+ struct v4l2_fwnode_endpoint *vep, -+ struct v4l2_async_subdev *asd) -+{ -+ //struct sun6i_csi *csi = dev_get_drvdata(dev); -+ struct sun6i_csi_async_subdev *csi_asd = asd_to_csi_asd(asd); -+ -+ if (vep->base.port) { -+ dev_err(dev, "CSI has only one port\n"); -+ return -ENOTCONN; -+ } -+ -+ switch (vep->bus_type) { -+ case V4L2_MBUS_PARALLEL: -+ case V4L2_MBUS_BT656: -+ csi_asd->ep_id = vep->base.id; -+ csi_asd->bus_type = vep->bus_type; -+ csi_asd->parallel = vep->bus.parallel; -+ return 0; -+ default: -+ dev_err(dev, "Unsupported media bus type\n"); -+ return -ENOTCONN; -+ } -+} -+ -+static const struct v4l2_async_notifier_operations sun6i_csi_notifier_ops = { -+ .bound = sun6i_csi_notify_bound, -+ .unbind = sun6i_csi_notify_unbind, -+ .complete = sun6i_csi_notify_complete, -+}; -+ -+int sun6i_csi_init(struct sun6i_csi *csi) -+{ -+ int ret; -+ -+ csi->media_dev.dev = csi->dev; -+ strlcpy(csi->media_dev.model, "Allwinner Video Capture Device", -+ sizeof(csi->media_dev.model)); -+ media_device_init(&csi->media_dev); -+ -+ ret = v4l2_ctrl_handler_init(&csi->ctrl_handler, 0); -+ if (ret) { -+ dev_err(csi->dev, "V4L2 controls handler init failed (%d)\n", -+ ret); -+ goto media_clean; -+ } -+ -+ csi->v4l2_dev.mdev = &csi->media_dev; -+ csi->v4l2_dev.ctrl_handler = &csi->ctrl_handler; -+ ret = v4l2_device_register(csi->dev, &csi->v4l2_dev); -+ if (ret < 0) { -+ dev_err(csi->dev, "V4L2 device registration failed (%d)\n", -+ ret); -+ goto ctrls_clean; -+ } -+ -+ ret = sun6i_video_init(csi, "sun6i-csi"); -+ if (ret < 0) -+ goto v4l2_clean; -+ -+ // Parse DT and build notifier.subdevs (struct v4l2_async_subdev) list -+ // that will be used to match and bind/unbind subdevices (sensors) to -+ // the csi->v4l2_dev when they are probed and registered by their own -+ // drivers. sun6i_csi_parse_subdev_endpoint callback can be used to: -+ // - exclude certain subdev endpoints from being watched -+ // - parse subdev DT endpoint properties and pass them later to bound -+ // callback via internediate struct sun6i_csi_async_subdev -+ ret = v4l2_async_notifier_parse_fwnode_endpoints( -+ csi->dev, &csi->notifier, sizeof(struct sun6i_csi_async_subdev), -+ sun6i_csi_parse_subdev_endpoint); -+ if (ret) -+ goto video_clean; -+ -+ csi->notifier.ops = &sun6i_csi_notifier_ops; -+ ret = v4l2_async_notifier_register(&csi->v4l2_dev, &csi->notifier); -+ if (ret < 0) { -+ dev_err(csi->dev, "Notifier registration failed\n"); -+ goto notifier_clean; -+ } -+ -+ return 0; -+ -+notifier_clean: -+ v4l2_async_notifier_cleanup(&csi->notifier); -+video_clean: -+ sun6i_video_cleanup(csi); -+v4l2_clean: -+ v4l2_device_unregister(&csi->v4l2_dev); -+ media_device_unregister(&csi->media_dev); -+ctrls_clean: -+ v4l2_ctrl_handler_free(&csi->ctrl_handler); -+media_clean: -+ media_device_cleanup(&csi->media_dev); -+ return ret; -+} -+ -+int sun6i_csi_cleanup(struct sun6i_csi *csi) -+{ -+ v4l2_async_notifier_unregister(&csi->notifier); -+ v4l2_async_notifier_cleanup(&csi->notifier); -+ sun6i_video_cleanup(csi); -+ v4l2_device_unregister(&csi->v4l2_dev); -+ v4l2_ctrl_handler_free(&csi->ctrl_handler); -+ media_device_unregister(&csi->media_dev); -+ media_device_cleanup(&csi->media_dev); -+ -+ return 0; -+} -+ -+// }}} -diff --git a/drivers/media/platform/sun6i-csi/sun6i_csi.h b/drivers/media/platform/sun6i-csi/sun6i_csi.h -new file mode 100644 -index 000000000000..f6c7d852b15f ---- /dev/null -+++ b/drivers/media/platform/sun6i-csi/sun6i_csi.h -@@ -0,0 +1,202 @@ -+/* -+ * Copyright (c) 2017 Yong Deng -+ * Copyright (c) 2017 Ondrej Jirman -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __SUN6I_VIDEO_H__ -+#define __SUN6I_VIDEO_H__ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define SUN6I_CSI_NUM_SENSORS 4 -+ -+/* -+ * struct sun6i_csi_format - CSI media bus format information -+ * @fourcc: Fourcc code for this format -+ * @mbus_code: V4L2 media bus format code. -+ * @bpp: Bytes per pixel (when stored in memory) -+ */ -+struct sun6i_csi_format { -+ u32 fourcc; -+ u32 mbus_code; -+ u8 bpp; -+}; -+ -+struct sun6i_csi_subdev { -+ struct v4l2_subdev *sd; -+ unsigned int pad; -+ unsigned int ep_id; -+ enum v4l2_mbus_type bus_type; -+ struct v4l2_fwnode_bus_parallel parallel; -+}; -+ -+struct sun6i_csi; -+ -+struct sun6i_csi_ops { -+ int (*get_supported_pixformats)(struct sun6i_csi *csi, -+ const u32 **pixformats); -+ bool (*is_format_support)(struct sun6i_csi *csi, u32 pixformat, -+ u32 mbus_code, -+ struct sun6i_csi_subdev *csi_sd); -+ int (*s_power)(struct sun6i_csi *csi, bool enable); -+ int (*apply_config)(struct sun6i_csi *csi, -+ struct sun6i_csi_subdev *csi_sd); -+ int (*update_buf_addr)(struct sun6i_csi *csi, dma_addr_t addr); -+ int (*s_stream)(struct sun6i_csi *csi, bool enable); -+}; -+ -+struct sun6i_csi { -+ struct v4l2_device v4l2_dev; -+ struct v4l2_ctrl_handler ctrl_handler; -+ struct v4l2_async_notifier notifier; -+ struct video_device vdev; -+ struct media_device media_dev; -+ struct media_pad pad; -+ struct device *dev; -+ -+ struct sun6i_csi_subdev sensors[SUN6I_CSI_NUM_SENSORS]; -+ -+ struct sun6i_csi_ops *ops; -+ -+ struct mutex lock; -+ -+ struct vb2_queue vb2_vidq; -+ spinlock_t dma_queue_lock; -+ struct list_head dma_queue; -+ unsigned int sequence; -+ bool skip_first_interrupt; -+ -+ struct sun6i_csi_format *formats; -+ unsigned int num_formats; -+ struct sun6i_csi_format *current_fmt; -+ struct v4l2_format fmt; -+}; -+ -+void sun6i_video_frame_done(struct sun6i_csi *video); -+ -+int sun6i_csi_init(struct sun6i_csi *csi); -+int sun6i_csi_cleanup(struct sun6i_csi *csi); -+ -+/** -+ * sun6i_csi_get_supported_pixformats() - get csi supported pixformats -+ * @csi: pointer to the csi -+ * @pixformats: supported pixformats return from csi -+ * -+ * @return the count of pixformats or error(< 0) -+ */ -+static inline int -+sun6i_csi_get_supported_pixformats(struct sun6i_csi *csi, -+ const u32 **pixformats) -+{ -+ if (csi->ops != NULL && csi->ops->get_supported_pixformats != NULL) -+ return csi->ops->get_supported_pixformats(csi, pixformats); -+ -+ return -ENOIOCTLCMD; -+} -+ -+/** -+ * sun6i_csi_is_format_support() - check if the format supported by csi -+ * @csi: pointer to the csi -+ * @pixformat: v4l2 pixel format (V4L2_PIX_FMT_*) -+ * @mbus_code: media bus format code (MEDIA_BUS_FMT_*) -+ */ -+ -+/** -+ * sun6i_csi_set_power() - power on/off the csi -+ * @csi: pointer to the csi -+ * @enable: on/off -+ */ -+static inline int sun6i_csi_set_power(struct sun6i_csi *csi, bool enable) -+{ -+ if (csi->ops != NULL && csi->ops->s_power != NULL) -+ return csi->ops->s_power(csi, enable); -+ -+ return -ENOIOCTLCMD; -+} -+ -+/** -+ * sun6i_csi_update_buf_addr() - update the csi frame buffer address -+ * @csi: pointer to the csi -+ * @addr: frame buffer's physical address -+ */ -+static inline int sun6i_csi_update_buf_addr(struct sun6i_csi *csi, -+ dma_addr_t addr) -+{ -+ if (csi->ops != NULL && csi->ops->update_buf_addr != NULL) -+ return csi->ops->update_buf_addr(csi, addr); -+ -+ return -ENOIOCTLCMD; -+} -+ -+/** -+ * sun6i_csi_set_stream() - start/stop csi streaming -+ * @csi: pointer to the csi -+ * @enable: start/stop -+ */ -+static inline int sun6i_csi_set_stream(struct sun6i_csi *csi, bool enable) -+{ -+ if (csi->ops != NULL && csi->ops->s_stream != NULL) -+ return csi->ops->s_stream(csi, enable); -+ -+ return -ENOIOCTLCMD; -+} -+ -+static inline int v4l2_pixformat_get_bpp(unsigned int pixformat) -+{ -+ switch (pixformat) { -+ case V4L2_PIX_FMT_SBGGR8: -+ case V4L2_PIX_FMT_SGBRG8: -+ case V4L2_PIX_FMT_SGRBG8: -+ case V4L2_PIX_FMT_SRGGB8: -+ return 8; -+ case V4L2_PIX_FMT_SBGGR10: -+ case V4L2_PIX_FMT_SGBRG10: -+ case V4L2_PIX_FMT_SGRBG10: -+ case V4L2_PIX_FMT_SRGGB10: -+ return 10; -+ case V4L2_PIX_FMT_SBGGR12: -+ case V4L2_PIX_FMT_SGBRG12: -+ case V4L2_PIX_FMT_SGRBG12: -+ case V4L2_PIX_FMT_SRGGB12: -+ case V4L2_PIX_FMT_HM12: -+ case V4L2_PIX_FMT_NV12: -+ case V4L2_PIX_FMT_NV21: -+ case V4L2_PIX_FMT_YUV420: -+ case V4L2_PIX_FMT_YVU420: -+ return 12; -+ case V4L2_PIX_FMT_YUYV: -+ case V4L2_PIX_FMT_YVYU: -+ case V4L2_PIX_FMT_UYVY: -+ case V4L2_PIX_FMT_VYUY: -+ case V4L2_PIX_FMT_RGB565: -+ case V4L2_PIX_FMT_RGB555: -+ case V4L2_PIX_FMT_NV16: -+ case V4L2_PIX_FMT_NV61: -+ case V4L2_PIX_FMT_YUV422P: -+ return 16; -+ case V4L2_PIX_FMT_RGB24: -+ case V4L2_PIX_FMT_BGR24: -+ return 24; -+ case V4L2_PIX_FMT_RGB32: -+ case V4L2_PIX_FMT_BGR32: -+ return 32; -+ } -+ -+ return 0; -+} -+ -+#endif /* __SUN6I_VIDEO_H__ */ -diff --git a/drivers/media/platform/sun6i-csi/sun6i_csi_v3s.c b/drivers/media/platform/sun6i-csi/sun6i_csi_v3s.c -new file mode 100644 -index 000000000000..0d882866b336 ---- /dev/null -+++ b/drivers/media/platform/sun6i-csi/sun6i_csi_v3s.c -@@ -0,0 +1,776 @@ -+/* -+ * Copyright (c) 2017 Magewell Electronics Co., Ltd. (Nanjing). -+ * All rights reserved. -+ * Author: Yong Deng -+ * Copyright (c) 2017 Ondrej Jirman -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#define DEBUG -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "sun6i_csi.h" -+#include "sun6i_csi_v3s.h" -+ -+#define MODULE_NAME "sun6i-csi" -+ -+struct sun6i_csi_cfg { -+ bool has_bt1120_if; -+ bool has_16bit_yuv422_if; -+}; -+ -+struct sun6i_csi_dev { -+ struct sun6i_csi csi; /* must be first */ -+ const struct sun6i_csi_cfg *cfg; -+ -+ struct regmap *regmap; -+ struct clk *clk_ahb; -+ struct clk *clk_mod; -+ struct clk *clk_ram; -+ struct reset_control *rstc_ahb; -+ -+ int planar_offset[3]; -+}; -+ -+static inline struct sun6i_csi_dev *sun6i_csi_to_dev(struct sun6i_csi *csi) -+{ -+ return container_of(csi, struct sun6i_csi_dev, csi); -+} -+ -+static const u32 supported_pixformats[] = { -+ V4L2_PIX_FMT_SBGGR8, -+ V4L2_PIX_FMT_SGBRG8, -+ V4L2_PIX_FMT_SGRBG8, -+ V4L2_PIX_FMT_SRGGB8, -+ V4L2_PIX_FMT_SBGGR10, -+ V4L2_PIX_FMT_SGBRG10, -+ V4L2_PIX_FMT_SGRBG10, -+ V4L2_PIX_FMT_SRGGB10, -+ V4L2_PIX_FMT_SBGGR12, -+ V4L2_PIX_FMT_SGBRG12, -+ V4L2_PIX_FMT_SGRBG12, -+ V4L2_PIX_FMT_SRGGB12, -+ V4L2_PIX_FMT_YUYV, -+ V4L2_PIX_FMT_YVYU, -+ V4L2_PIX_FMT_UYVY, -+ V4L2_PIX_FMT_VYUY, -+ V4L2_PIX_FMT_RGB565, -+ V4L2_PIX_FMT_RGB555, -+ V4L2_PIX_FMT_HM12, -+ V4L2_PIX_FMT_NV12, -+ V4L2_PIX_FMT_NV21, -+ V4L2_PIX_FMT_YUV420, -+ V4L2_PIX_FMT_YVU420, -+ V4L2_PIX_FMT_NV16, -+ V4L2_PIX_FMT_NV61, -+ V4L2_PIX_FMT_YUV422P, -+}; -+ -+static int get_supported_pixformats(struct sun6i_csi *csi, -+ const u32 **pixformats) -+{ -+ if (pixformats != NULL) -+ *pixformats = supported_pixformats; -+ -+ return ARRAY_SIZE(supported_pixformats); -+} -+ -+/* TODO add 10&12 bit YUV, RGB support */ -+static bool is_format_support(struct sun6i_csi *csi, u32 pixformat, -+ u32 mbus_code, struct sun6i_csi_subdev *csi_sd) -+{ -+ //struct sun6i_csi_dev *sdev = sun6i_csi_to_dev(csi); -+ enum v4l2_mbus_type bus_type = csi_sd->bus_type; -+ bool is_parallel = bus_type == V4L2_MBUS_PARALLEL || -+ bus_type == V4L2_MBUS_BT656; -+ -+ /* -+ * Some video receiver have capability both 8bit and 16bit. -+ * Identify the media bus format from device tree. -+ */ -+ if ((is_parallel && csi_sd->parallel.bus_width == 16) || -+ bus_type == V4L2_MBUS_CSI2) { -+ switch (pixformat) { -+ case V4L2_PIX_FMT_HM12: -+ case V4L2_PIX_FMT_NV12: -+ case V4L2_PIX_FMT_NV21: -+ case V4L2_PIX_FMT_NV16: -+ case V4L2_PIX_FMT_NV61: -+ case V4L2_PIX_FMT_YUV420: -+ case V4L2_PIX_FMT_YVU420: -+ case V4L2_PIX_FMT_YUV422P: -+ switch (mbus_code) { -+ case MEDIA_BUS_FMT_UYVY8_1X16: -+ case MEDIA_BUS_FMT_VYUY8_1X16: -+ case MEDIA_BUS_FMT_YUYV8_1X16: -+ case MEDIA_BUS_FMT_YVYU8_1X16: -+ return true; -+ } -+ break; -+ } -+ return false; -+ } -+ -+ switch (pixformat) { -+ case V4L2_PIX_FMT_SBGGR8: -+ return mbus_code == MEDIA_BUS_FMT_SBGGR8_1X8; -+ case V4L2_PIX_FMT_SGBRG8: -+ return mbus_code == MEDIA_BUS_FMT_SGBRG8_1X8; -+ case V4L2_PIX_FMT_SGRBG8: -+ return mbus_code == MEDIA_BUS_FMT_SGRBG8_1X8; -+ case V4L2_PIX_FMT_SRGGB8: -+ return mbus_code == MEDIA_BUS_FMT_SRGGB8_1X8; -+ case V4L2_PIX_FMT_SBGGR10: -+ return mbus_code == MEDIA_BUS_FMT_SBGGR10_1X10; -+ case V4L2_PIX_FMT_SGBRG10: -+ return mbus_code == MEDIA_BUS_FMT_SGBRG10_1X10; -+ case V4L2_PIX_FMT_SGRBG10: -+ return mbus_code == MEDIA_BUS_FMT_SGRBG10_1X10; -+ case V4L2_PIX_FMT_SRGGB10: -+ return mbus_code == MEDIA_BUS_FMT_SRGGB10_1X10; -+ case V4L2_PIX_FMT_SBGGR12: -+ return mbus_code == MEDIA_BUS_FMT_SBGGR12_1X12; -+ case V4L2_PIX_FMT_SGBRG12: -+ return mbus_code == MEDIA_BUS_FMT_SGBRG12_1X12; -+ case V4L2_PIX_FMT_SGRBG12: -+ return mbus_code == MEDIA_BUS_FMT_SGRBG12_1X12; -+ case V4L2_PIX_FMT_SRGGB12: -+ return mbus_code == MEDIA_BUS_FMT_SRGGB12_1X12; -+ -+ case V4L2_PIX_FMT_RGB565: -+ return mbus_code == MEDIA_BUS_FMT_RGB565_2X8_LE; -+ case V4L2_PIX_FMT_RGB555: -+ return mbus_code == MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE; -+ -+ case V4L2_PIX_FMT_YUYV: -+ return mbus_code == MEDIA_BUS_FMT_YUYV8_2X8; -+ case V4L2_PIX_FMT_YVYU: -+ return mbus_code == MEDIA_BUS_FMT_YVYU8_2X8; -+ case V4L2_PIX_FMT_UYVY: -+ return mbus_code == MEDIA_BUS_FMT_UYVY8_2X8; -+ case V4L2_PIX_FMT_VYUY: -+ return mbus_code == MEDIA_BUS_FMT_VYUY8_2X8; -+ -+ case V4L2_PIX_FMT_HM12: -+ case V4L2_PIX_FMT_NV12: -+ case V4L2_PIX_FMT_NV21: -+ case V4L2_PIX_FMT_NV16: -+ case V4L2_PIX_FMT_NV61: -+ case V4L2_PIX_FMT_YUV420: -+ case V4L2_PIX_FMT_YVU420: -+ case V4L2_PIX_FMT_YUV422P: -+ switch (mbus_code) { -+ case MEDIA_BUS_FMT_UYVY8_2X8: -+ case MEDIA_BUS_FMT_VYUY8_2X8: -+ case MEDIA_BUS_FMT_YUYV8_2X8: -+ case MEDIA_BUS_FMT_YVYU8_2X8: -+ return true; -+ } -+ break; -+ } -+ -+ return false; -+} -+ -+static enum csi_input_fmt get_csi_input_format(u32 mbus_code, u32 pixformat) -+{ -+ /* bayer */ -+ if ((mbus_code & 0xF000) == 0x3000) -+ return CSI_INPUT_FORMAT_RAW; -+ -+ switch (pixformat) { -+ case V4L2_PIX_FMT_YUYV: -+ case V4L2_PIX_FMT_YVYU: -+ case V4L2_PIX_FMT_UYVY: -+ case V4L2_PIX_FMT_VYUY: -+ case V4L2_PIX_FMT_RGB565: -+ case V4L2_PIX_FMT_RGB555: -+ return CSI_INPUT_FORMAT_RAW; -+ } -+ -+ /* not support YUV420 input format yet */ -+ return CSI_INPUT_FORMAT_YUV422; -+} -+ -+static enum csi_output_fmt get_csi_output_format(u32 pixformat, u32 field) -+{ -+ bool buf_interlaced = false; -+ -+ if (field == V4L2_FIELD_INTERLACED || -+ field == V4L2_FIELD_INTERLACED_TB || -+ field == V4L2_FIELD_INTERLACED_BT) -+ buf_interlaced = true; -+ -+ switch (pixformat) { -+ case V4L2_PIX_FMT_SBGGR8: -+ case V4L2_PIX_FMT_SGBRG8: -+ case V4L2_PIX_FMT_SGRBG8: -+ case V4L2_PIX_FMT_SRGGB8: -+ return buf_interlaced ? CSI_FRAME_RAW_8 : CSI_FIELD_RAW_8; -+ case V4L2_PIX_FMT_SBGGR10: -+ case V4L2_PIX_FMT_SGBRG10: -+ case V4L2_PIX_FMT_SGRBG10: -+ case V4L2_PIX_FMT_SRGGB10: -+ return buf_interlaced ? CSI_FRAME_RAW_10 : CSI_FIELD_RAW_10; -+ case V4L2_PIX_FMT_SBGGR12: -+ case V4L2_PIX_FMT_SGBRG12: -+ case V4L2_PIX_FMT_SGRBG12: -+ case V4L2_PIX_FMT_SRGGB12: -+ return buf_interlaced ? CSI_FRAME_RAW_12 : CSI_FIELD_RAW_12; -+ -+ case V4L2_PIX_FMT_YUYV: -+ case V4L2_PIX_FMT_YVYU: -+ case V4L2_PIX_FMT_UYVY: -+ case V4L2_PIX_FMT_VYUY: -+ case V4L2_PIX_FMT_RGB565: -+ case V4L2_PIX_FMT_RGB555: -+ return buf_interlaced ? CSI_FRAME_RAW_8 : CSI_FIELD_RAW_8; -+ -+ case V4L2_PIX_FMT_HM12: -+ return buf_interlaced ? CSI_FRAME_MB_YUV420 : -+ CSI_FIELD_MB_YUV420; -+ case V4L2_PIX_FMT_NV12: -+ case V4L2_PIX_FMT_NV21: -+ return buf_interlaced ? CSI_FRAME_UV_CB_YUV420 : -+ CSI_FIELD_UV_CB_YUV420; -+ case V4L2_PIX_FMT_YUV420: -+ case V4L2_PIX_FMT_YVU420: -+ return buf_interlaced ? CSI_FRAME_PLANAR_YUV420 : -+ CSI_FIELD_PLANAR_YUV420; -+ case V4L2_PIX_FMT_NV16: -+ case V4L2_PIX_FMT_NV61: -+ return buf_interlaced ? CSI_FRAME_UV_CB_YUV422 : -+ CSI_FIELD_UV_CB_YUV422; -+ case V4L2_PIX_FMT_YUV422P: -+ return buf_interlaced ? CSI_FRAME_PLANAR_YUV422 : -+ CSI_FIELD_PLANAR_YUV422; -+ } -+ -+ return 0; -+} -+ -+static enum csi_input_seq get_csi_input_seq(u32 mbus_code, u32 pixformat) -+{ -+ -+ switch (pixformat) { -+ case V4L2_PIX_FMT_HM12: -+ case V4L2_PIX_FMT_NV12: -+ case V4L2_PIX_FMT_NV16: -+ case V4L2_PIX_FMT_YUV420: -+ case V4L2_PIX_FMT_YUV422P: -+ switch (mbus_code) { -+ case MEDIA_BUS_FMT_UYVY8_2X8: -+ case MEDIA_BUS_FMT_UYVY8_1X16: -+ return CSI_INPUT_SEQ_UYVY; -+ case MEDIA_BUS_FMT_VYUY8_2X8: -+ case MEDIA_BUS_FMT_VYUY8_1X16: -+ return CSI_INPUT_SEQ_VYUY; -+ case MEDIA_BUS_FMT_YUYV8_2X8: -+ case MEDIA_BUS_FMT_YUYV8_1X16: -+ return CSI_INPUT_SEQ_YUYV; -+ case MEDIA_BUS_FMT_YVYU8_1X16: -+ case MEDIA_BUS_FMT_YVYU8_2X8: -+ return CSI_INPUT_SEQ_YVYU; -+ } -+ break; -+ case V4L2_PIX_FMT_NV21: -+ case V4L2_PIX_FMT_NV61: -+ case V4L2_PIX_FMT_YVU420: -+ switch (mbus_code) { -+ case MEDIA_BUS_FMT_UYVY8_2X8: -+ case MEDIA_BUS_FMT_UYVY8_1X16: -+ return CSI_INPUT_SEQ_VYUY; -+ case MEDIA_BUS_FMT_VYUY8_2X8: -+ case MEDIA_BUS_FMT_VYUY8_1X16: -+ return CSI_INPUT_SEQ_UYVY; -+ case MEDIA_BUS_FMT_YUYV8_2X8: -+ case MEDIA_BUS_FMT_YUYV8_1X16: -+ return CSI_INPUT_SEQ_YVYU; -+ case MEDIA_BUS_FMT_YVYU8_1X16: -+ case MEDIA_BUS_FMT_YVYU8_2X8: -+ return CSI_INPUT_SEQ_YUYV; -+ } -+ break; -+ } -+ -+ return CSI_INPUT_SEQ_YUYV; -+} -+ -+static void sun6i_csi_setup_bus(struct sun6i_csi_dev *sdev, -+ struct sun6i_csi_subdev *csi_sd) -+{ -+ unsigned char bus_width = csi_sd->parallel.bus_width; -+ u32 flags = csi_sd->parallel.flags; -+ u32 cfg; -+ -+ regmap_read(sdev->regmap, CSI_IF_CFG_REG, &cfg); -+ -+ cfg &= ~(CSI_IF_CFG_CSI_IF_MASK | CSI_IF_CFG_MIPI_IF_MASK | -+ CSI_IF_CFG_IF_DATA_WIDTH_MASK | -+ CSI_IF_CFG_CLK_POL_MASK | CSI_IF_CFG_VREF_POL_MASK | -+ CSI_IF_CFG_HREF_POL_MASK | CSI_IF_CFG_FIELD_MASK); -+ -+ switch (csi_sd->bus_type) { -+#if 0 -+ case V4L2_MBUS_CSI2: -+ cfg |= CSI_IF_CFG_MIPI_IF_MIPI; -+ break; -+#endif -+ case V4L2_MBUS_PARALLEL: -+ cfg |= CSI_IF_CFG_MIPI_IF_CSI; -+ -+ cfg |= (bus_width == 16) ? CSI_IF_CFG_CSI_IF_YUV422_16BIT : -+ CSI_IF_CFG_CSI_IF_YUV422_INTLV; -+ -+ if (flags & V4L2_MBUS_FIELD_EVEN_LOW) -+ cfg |= CSI_IF_CFG_FIELD_POSITIVE; -+ -+ if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) -+ cfg |= CSI_IF_CFG_VREF_POL_POSITIVE; -+ if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) -+ cfg |= CSI_IF_CFG_HREF_POL_POSITIVE; -+ -+ if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) -+ cfg |= CSI_IF_CFG_CLK_POL_FALLING_EDGE; -+ break; -+ case V4L2_MBUS_BT656: -+ cfg |= CSI_IF_CFG_MIPI_IF_CSI; -+ -+ cfg |= (bus_width == 16) ? CSI_IF_CFG_CSI_IF_BT1120 : -+ CSI_IF_CFG_CSI_IF_BT656; -+ -+ if (flags & V4L2_MBUS_FIELD_EVEN_LOW) -+ cfg |= CSI_IF_CFG_FIELD_POSITIVE; -+ -+ if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) -+ cfg |= CSI_IF_CFG_CLK_POL_FALLING_EDGE; -+ break; -+ default: -+ BUG(); -+ break; -+ } -+ -+ switch (bus_width) { -+ case 8: -+ cfg |= CSI_IF_CFG_IF_DATA_WIDTH_8BIT; -+ break; -+ case 10: -+ cfg |= CSI_IF_CFG_IF_DATA_WIDTH_10BIT; -+ break; -+ case 12: -+ cfg |= CSI_IF_CFG_IF_DATA_WIDTH_12BIT; -+ break; -+ default: -+ break; -+ } -+ -+ regmap_write(sdev->regmap, CSI_IF_CFG_REG, cfg); -+} -+ -+static void sun6i_csi_set_format(struct sun6i_csi_dev *sdev) -+{ -+ struct sun6i_csi *csi = &sdev->csi; -+ u32 cfg; -+ u32 val; -+ -+ regmap_read(sdev->regmap, CSI_CH_CFG_REG, &cfg); -+ -+ cfg &= ~(CSI_CH_CFG_INPUT_FMT_MASK | -+ CSI_CH_CFG_OUTPUT_FMT_MASK | CSI_CH_CFG_VFLIP_EN | -+ CSI_CH_CFG_HFLIP_EN | CSI_CH_CFG_FIELD_SEL_MASK | -+ CSI_CH_CFG_INPUT_SEQ_MASK); -+ -+ val = get_csi_input_format(csi->current_fmt->mbus_code, -+ csi->fmt.fmt.pix.pixelformat); -+ cfg |= CSI_CH_CFG_INPUT_FMT(val); -+ -+ val = get_csi_output_format(csi->current_fmt->mbus_code, -+ csi->fmt.fmt.pix.field); -+ cfg |= CSI_CH_CFG_OUTPUT_FMT(val); -+ -+ val = get_csi_input_seq(csi->current_fmt->mbus_code, -+ csi->fmt.fmt.pix.pixelformat); -+ cfg |= CSI_CH_CFG_INPUT_SEQ(val); -+ -+ if (csi->fmt.fmt.pix.field == V4L2_FIELD_TOP) -+ cfg |= CSI_CH_CFG_FIELD_SEL_FIELD0; -+ else if (csi->fmt.fmt.pix.field == V4L2_FIELD_BOTTOM) -+ cfg |= CSI_CH_CFG_FIELD_SEL_FIELD1; -+ else -+ cfg |= CSI_CH_CFG_FIELD_SEL_BOTH; -+ -+ regmap_write(sdev->regmap, CSI_CH_CFG_REG, cfg); -+} -+ -+static void sun6i_csi_set_window(struct sun6i_csi_dev *sdev) -+{ -+ struct sun6i_csi *csi = &sdev->csi; -+ u32 bytesperline_y; -+ u32 bytesperline_c; -+ int *planar_offset = sdev->planar_offset; -+ u32 width = csi->fmt.fmt.pix.width; -+ u32 height = csi->fmt.fmt.pix.height; -+ u32 hor_len = width; -+ -+ switch (csi->fmt.fmt.pix.pixelformat) { -+ case V4L2_PIX_FMT_YUYV: -+ case V4L2_PIX_FMT_YVYU: -+ case V4L2_PIX_FMT_UYVY: -+ case V4L2_PIX_FMT_VYUY: -+ case V4L2_PIX_FMT_RGB565: -+ case V4L2_PIX_FMT_RGB555: -+ hor_len *= 2; -+ break; -+ } -+ -+ regmap_write(sdev->regmap, CSI_CH_HSIZE_REG, -+ CSI_CH_HSIZE_HOR_LEN(hor_len) | -+ CSI_CH_HSIZE_HOR_START(0)); -+ regmap_write(sdev->regmap, CSI_CH_VSIZE_REG, -+ CSI_CH_VSIZE_VER_LEN(height) | -+ CSI_CH_VSIZE_VER_START(0)); -+ -+ planar_offset[0] = 0; -+ -+ switch (csi->fmt.fmt.pix.pixelformat) { -+ case V4L2_PIX_FMT_HM12: -+ case V4L2_PIX_FMT_NV12: -+ case V4L2_PIX_FMT_NV21: -+ case V4L2_PIX_FMT_NV16: -+ case V4L2_PIX_FMT_NV61: -+ bytesperline_y = width; -+ bytesperline_c = width; -+ planar_offset[1] = bytesperline_y * height; -+ planar_offset[2] = -1; -+ break; -+ case V4L2_PIX_FMT_YUV420: -+ case V4L2_PIX_FMT_YVU420: -+ bytesperline_y = width; -+ bytesperline_c = width / 2; -+ planar_offset[1] = bytesperline_y * height; -+ planar_offset[2] = planar_offset[1] + -+ bytesperline_c * height / 2; -+ break; -+ case V4L2_PIX_FMT_YUV422P: -+ bytesperline_y = width; -+ bytesperline_c = width / 2; -+ planar_offset[1] = bytesperline_y * height; -+ planar_offset[2] = planar_offset[1] + -+ bytesperline_c * height; -+ break; -+ default: /* raw */ -+ bytesperline_y = (csi->current_fmt->bpp * width) / 8; -+ bytesperline_c = 0; -+ planar_offset[1] = -1; -+ planar_offset[2] = -1; -+ break; -+ } -+ -+ regmap_write(sdev->regmap, CSI_CH_BUF_LEN_REG, -+ CSI_CH_BUF_LEN_BUF_LEN_C(bytesperline_c) | -+ CSI_CH_BUF_LEN_BUF_LEN_Y(bytesperline_y)); -+} -+ -+static int set_power(struct sun6i_csi *csi, bool enable) -+{ -+ struct sun6i_csi_dev *sdev = sun6i_csi_to_dev(csi); -+ struct regmap *regmap = sdev->regmap; -+ int ret; -+ -+ if (!enable) { -+ regmap_update_bits(regmap, CSI_EN_REG, CSI_EN_CSI_EN, 0); -+ -+ clk_disable_unprepare(sdev->clk_ram); -+ clk_disable_unprepare(sdev->clk_mod); -+ clk_disable_unprepare(sdev->clk_ahb); -+ reset_control_assert(sdev->rstc_ahb); -+ return 0; -+ } -+ -+ ret = clk_prepare_enable(sdev->clk_ahb); -+ if (ret) { -+ dev_err(csi->dev, "Enable ahb clk err %d\n", ret); -+ return ret; -+ } -+ -+ ret = clk_prepare_enable(sdev->clk_mod); -+ if (ret) { -+ dev_err(csi->dev, "Enable csi clk err %d\n", ret); -+ return ret; -+ } -+ -+ ret = clk_prepare_enable(sdev->clk_ram); -+ if (ret) { -+ dev_err(csi->dev, "Enable clk_dram_csi clk err %d\n", ret); -+ return ret; -+ } -+ -+ if (!IS_ERR_OR_NULL(sdev->rstc_ahb)) { -+ ret = reset_control_deassert(sdev->rstc_ahb); -+ if (ret) { -+ dev_err(csi->dev, "reset err %d\n", ret); -+ return ret; -+ } -+ } -+ -+ regmap_update_bits(regmap, CSI_EN_REG, CSI_EN_CSI_EN, CSI_EN_CSI_EN); -+ -+ return 0; -+} -+ -+static int apply_config(struct sun6i_csi *csi, struct sun6i_csi_subdev *csi_sd) -+{ -+ struct sun6i_csi_dev *sdev = sun6i_csi_to_dev(csi); -+ -+ sun6i_csi_setup_bus(sdev, csi_sd); -+ sun6i_csi_set_format(sdev); -+ sun6i_csi_set_window(sdev); -+ -+ return 0; -+} -+ -+static int update_buf_addr(struct sun6i_csi *csi, dma_addr_t addr) -+{ -+ struct sun6i_csi_dev *sdev = sun6i_csi_to_dev(csi); -+ /* transform physical address to bus address */ -+ dma_addr_t bus_addr = addr - 0x40000000; -+ -+ regmap_write(sdev->regmap, CSI_CH_F0_BUFA_REG, -+ (bus_addr + sdev->planar_offset[0]) >> 2); -+ if (sdev->planar_offset[1] != -1) -+ regmap_write(sdev->regmap, CSI_CH_F1_BUFA_REG, -+ (bus_addr + sdev->planar_offset[1]) >> 2); -+ if (sdev->planar_offset[2] != -1) -+ regmap_write(sdev->regmap, CSI_CH_F2_BUFA_REG, -+ (bus_addr + sdev->planar_offset[2]) >> 2); -+ -+ return 0; -+} -+ -+static int set_stream(struct sun6i_csi *csi, bool enable) -+{ -+ struct sun6i_csi_dev *sdev = sun6i_csi_to_dev(csi); -+ struct regmap *regmap = sdev->regmap; -+ -+ if (!enable) { -+ regmap_update_bits(regmap, CSI_CAP_REG, CSI_CAP_CH0_VCAP_ON, 0); -+ regmap_write(regmap, CSI_CH_INT_EN_REG, 0); -+ regmap_update_bits(regmap, CSI_EN_REG, CSI_EN_CSI_EN, 0); -+ return 0; -+ } -+ -+ /* reset */ -+ regmap_update_bits(regmap, CSI_EN_REG, CSI_EN_CSI_EN, CSI_EN_CSI_EN); -+ regmap_update_bits(regmap, CSI_EN_REG, CSI_EN_CSI_EN, 0); -+ regmap_update_bits(regmap, CSI_EN_REG, CSI_EN_CSI_EN, CSI_EN_CSI_EN); -+ -+ regmap_write(regmap, CSI_CH_INT_STA_REG, 0xFF); -+ regmap_write(regmap, CSI_CH_INT_EN_REG, -+ CSI_CH_INT_EN_HB_OF_INT_EN | -+ CSI_CH_INT_EN_FIFO2_OF_INT_EN | -+ CSI_CH_INT_EN_FIFO1_OF_INT_EN | -+ CSI_CH_INT_EN_FIFO0_OF_INT_EN | -+ CSI_CH_INT_EN_FD_INT_EN | -+ CSI_CH_INT_EN_CD_INT_EN); -+ -+ regmap_update_bits(regmap, CSI_CAP_REG, CSI_CAP_CH0_VCAP_ON, -+ CSI_CAP_CH0_VCAP_ON); -+ -+ return 0; -+} -+ -+static struct sun6i_csi_ops csi_ops = { -+ .get_supported_pixformats = get_supported_pixformats, -+ .is_format_support = is_format_support, -+ .s_power = set_power, -+ .apply_config = apply_config, -+ .update_buf_addr = update_buf_addr, -+ .s_stream = set_stream, -+}; -+ -+static irqreturn_t sun6i_csi_isr(int irq, void *dev_id) -+{ -+ struct sun6i_csi_dev *sdev = (struct sun6i_csi_dev *)dev_id; -+ struct regmap *regmap = sdev->regmap; -+ u32 status; -+ -+ regmap_read(regmap, CSI_CH_INT_STA_REG, &status); -+ -+ if ((status & CSI_CH_INT_STA_FIFO0_OF_PD) || -+ (status & CSI_CH_INT_STA_FIFO1_OF_PD) || -+ (status & CSI_CH_INT_STA_FIFO2_OF_PD) || -+ (status & CSI_CH_INT_STA_HB_OF_PD)) { -+ regmap_write(regmap, CSI_CH_INT_STA_REG, 0xff); -+ regmap_update_bits(regmap, CSI_EN_REG, CSI_EN_CSI_EN, 0); -+ regmap_update_bits(regmap, CSI_EN_REG, CSI_EN_CSI_EN, -+ CSI_EN_CSI_EN); -+ return IRQ_HANDLED; -+ } -+ -+ if (status & CSI_CH_INT_STA_FD_PD) -+ sun6i_video_frame_done(&sdev->csi); -+ -+ regmap_write(regmap, CSI_CH_INT_STA_REG, 0xff); -+ return IRQ_HANDLED; -+} -+ -+static const struct regmap_config sun6i_csi_regmap_config = { -+ .reg_bits = 32, -+ .reg_stride = 4, -+ .val_bits = 32, -+ .max_register = 0x1000, -+}; -+ -+static int sun6i_csi_resource_request(struct sun6i_csi_dev *sdev, -+ struct platform_device *pdev) -+{ -+ struct resource *res; -+ void __iomem *io_base; -+ int ret; -+ int irq; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ io_base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(io_base)) -+ return PTR_ERR(io_base); -+ -+ sdev->regmap = devm_regmap_init_mmio(&pdev->dev, io_base, -+ &sun6i_csi_regmap_config); -+ if (IS_ERR(sdev->regmap)) { -+ dev_err(&pdev->dev, "Failed to init register map\n"); -+ return PTR_ERR(sdev->regmap); -+ } -+ -+ sdev->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); -+ if (IS_ERR(sdev->clk_ahb)) { -+ dev_err(&pdev->dev, "Unable to acquire ahb clock\n"); -+ return PTR_ERR(sdev->clk_ahb); -+ } -+ -+ sdev->clk_mod = devm_clk_get(&pdev->dev, "mod"); -+ if (IS_ERR(sdev->clk_mod)) { -+ dev_err(&pdev->dev, "Unable to acquire csi clock\n"); -+ return PTR_ERR(sdev->clk_mod); -+ } -+ -+ sdev->clk_ram = devm_clk_get(&pdev->dev, "ram"); -+ if (IS_ERR(sdev->clk_ram)) { -+ dev_err(&pdev->dev, "Unable to acquire dram-csi clock\n"); -+ return PTR_ERR(sdev->clk_ram); -+ } -+ -+ sdev->rstc_ahb = devm_reset_control_get_optional_shared(&pdev->dev, -+ NULL); -+ if (IS_ERR(sdev->rstc_ahb)) { -+ dev_err(&pdev->dev, "Cannot get reset controller\n"); -+ return PTR_ERR(sdev->rstc_ahb); -+ } -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) { -+ dev_err(&pdev->dev, "No csi IRQ specified\n"); -+ ret = -ENXIO; -+ return ret; -+ } -+ -+ ret = devm_request_irq(&pdev->dev, irq, sun6i_csi_isr, 0, MODULE_NAME, -+ sdev); -+ if (ret) { -+ dev_err(&pdev->dev, "Cannot request csi IRQ\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int sun6i_csi_probe(struct platform_device *pdev) -+{ -+ struct sun6i_csi_dev *sdev; -+ int ret; -+ -+ sdev = devm_kzalloc(&pdev->dev, sizeof(*sdev), GFP_KERNEL); -+ if (!sdev) -+ return -ENOMEM; -+ -+ sdev->csi.dev = &pdev->dev; -+ platform_set_drvdata(pdev, sdev); -+ -+ sdev->cfg = of_device_get_match_data(&pdev->dev); -+ -+ ret = sun6i_csi_resource_request(sdev, pdev); -+ if (ret) -+ return ret; -+ -+ sdev->csi.ops = &csi_ops; -+ ret = sun6i_csi_init(&sdev->csi); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static int sun6i_csi_remove(struct platform_device *pdev) -+{ -+ struct sun6i_csi_dev *sdev = platform_get_drvdata(pdev); -+ -+ sun6i_csi_cleanup(&sdev->csi); -+ -+ return 0; -+} -+ -+static const struct sun6i_csi_cfg sun8i_v3s_cfg = { -+ .has_bt1120_if = true, -+ .has_16bit_yuv422_if = true, -+}; -+ -+static const struct sun6i_csi_cfg sun8i_a83t_cfg = { -+ .has_bt1120_if = false, -+ .has_16bit_yuv422_if = false, -+}; -+ -+static const struct of_device_id sun6i_csi_of_match[] = { -+ { .compatible = "allwinner,sun8i-v3s-csi", .data = &sun8i_v3s_cfg }, -+ { .compatible = "allwinner,sun8i-a83t-csi", .data = &sun8i_a83t_cfg }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, sun6i_csi_of_match); -+ -+static struct platform_driver sun6i_csi_platform_driver = { -+ .probe = sun6i_csi_probe, -+ .remove = sun6i_csi_remove, -+ .driver = { -+ .name = MODULE_NAME, -+ .of_match_table = of_match_ptr(sun6i_csi_of_match), -+ }, -+}; -+module_platform_driver(sun6i_csi_platform_driver); -+ -+MODULE_DESCRIPTION("Allwinner V3s Camera Sensor Interface driver"); -+MODULE_AUTHOR("Yong Deng "); -+MODULE_LICENSE("GPL v2"); -diff --git a/drivers/media/platform/sun6i-csi/sun6i_csi_v3s.h b/drivers/media/platform/sun6i-csi/sun6i_csi_v3s.h -new file mode 100644 -index 000000000000..4916d23c064f ---- /dev/null -+++ b/drivers/media/platform/sun6i-csi/sun6i_csi_v3s.h -@@ -0,0 +1,243 @@ -+/* -+ * Copyright (c) 2017 Yong Deng -+ * Copyright (c) 2017 Ondrej Jirman -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __SUN6I_CSI_V3S_H__ -+#define __SUN6I_CSI_V3S_H__ -+ -+#include -+ -+#define CSI_EN_REG 0x0 -+#define CSI_EN_VER_EN BIT(30) -+#define CSI_EN_CSI_EN BIT(0) -+ -+#define CSI_IF_CFG_REG 0x4 -+ -+#define CSI_IF_CFG_SRC_TYPE_MASK BIT(21) -+#define CSI_IF_CFG_SRC_TYPE_PROGRESSED 0 -+#define CSI_IF_CFG_SRC_TYPE_INTERLACED BIT(21) -+ -+#define CSI_IF_CFG_FPS_DS_EN BIT(20) -+ -+#define CSI_IF_CFG_FIELD_MASK BIT(19) -+#define CSI_IF_CFG_FIELD_NEGATIVE 0 -+#define CSI_IF_CFG_FIELD_POSITIVE BIT(19) -+ -+#define CSI_IF_CFG_VREF_POL_MASK BIT(18) -+#define CSI_IF_CFG_VREF_POL_NEGATIVE 0 -+#define CSI_IF_CFG_VREF_POL_POSITIVE BIT(18) -+ -+#define CSI_IF_CFG_HREF_POL_MASK BIT(17) -+#define CSI_IF_CFG_HREF_POL_NEGATIVE 0 -+#define CSI_IF_CFG_HREF_POL_POSITIVE BIT(17) -+ -+#define CSI_IF_CFG_CLK_POL_MASK BIT(16) -+#define CSI_IF_CFG_CLK_POL_RISING_EDGE 0 -+#define CSI_IF_CFG_CLK_POL_FALLING_EDGE BIT(16) -+ -+//megi: A83T does haveg GENMASK(9, 8) and fewer options, though it is compatible -+//#define CSI_IF_CFG_IF_DATA_WIDTH_MASK GENMASK(10, 8) -+#define CSI_IF_CFG_IF_DATA_WIDTH_MASK GENMASK(9, 8) -+#define CSI_IF_CFG_IF_DATA_WIDTH_8BIT (0 << 8) -+#define CSI_IF_CFG_IF_DATA_WIDTH_10BIT (1 << 8) -+#define CSI_IF_CFG_IF_DATA_WIDTH_12BIT (2 << 8) -+//megi: A83T only -+#define CSI_IF_CFG_IF_DATA_WIDTH_8P2BIT (3 << 8) -+ -+#define CSI_IF_CFG_MIPI_IF_MASK BIT(7) -+#define CSI_IF_CFG_MIPI_IF_CSI 0 -+#define CSI_IF_CFG_MIPI_IF_MIPI BIT(7) -+ -+#define CSI_IF_CFG_CSI_IF_MASK GENMASK(4, 0) -+#define CSI_IF_CFG_CSI_IF_YUV422_INTLV 0 -+//megi: not supported by A83T: -+#define CSI_IF_CFG_CSI_IF_YUV422_16BIT 1 -+#define CSI_IF_CFG_CSI_IF_BT656 4 -+//megi: not supported by A83T: -+#define CSI_IF_CFG_CSI_IF_BT1120 5 -+ -+#define CSI_CAP_REG 0x8 -+#define CSI_CAP_CH0_CAP_MASK_MASK GENMASK(5, 2) -+#define CSI_CAP_CH0_CAP_MASK(count) ((count << 2) & \ -+ CSI_CAP_CH0_CAP_MASK_MASK) -+#define CSI_CAP_CH0_VCAP_ON BIT(1) -+#define CSI_CAP_CH0_SCAP_ON BIT(0) -+ -+#define CSI_SYNC_CNT_REG 0xc -+#define CSI_FIFO_THRS_REG 0x10 -+//megi: missing from A83T docs: (BT656 muti-channel mode not supported?) -+#define CSI_BT656_HEAD_CFG_REG 0x14 -+#define CSI_PTN_LEN_REG 0x30 -+#define CSI_PTN_ADDR_REG 0x34 -+#define CSI_VER_REG 0x3c -+ -+//megi: called CSI0_C0_* in A83T -+#define CSI_CH_CFG_REG 0x44 -+#define CSI_CH_CFG_INPUT_FMT_MASK GENMASK(23, 20) -+#define CSI_CH_CFG_INPUT_FMT(fmt) ((fmt << 20) & \ -+ CSI_CH_CFG_INPUT_FMT_MASK) -+#define CSI_CH_CFG_OUTPUT_FMT_MASK GENMASK(19, 16) -+#define CSI_CH_CFG_OUTPUT_FMT(fmt) ((fmt << 16) & \ -+ CSI_CH_CFG_OUTPUT_FMT_MASK) -+#define CSI_CH_CFG_VFLIP_EN BIT(13) -+#define CSI_CH_CFG_HFLIP_EN BIT(12) -+#define CSI_CH_CFG_FIELD_SEL_MASK GENMASK(11, 10) -+#define CSI_CH_CFG_FIELD_SEL_FIELD0 (0 << 10) -+#define CSI_CH_CFG_FIELD_SEL_FIELD1 (1 << 10) -+#define CSI_CH_CFG_FIELD_SEL_BOTH (2 << 10) -+#define CSI_CH_CFG_INPUT_SEQ_MASK GENMASK(9, 8) -+#define CSI_CH_CFG_INPUT_SEQ(seq) ((seq << 8) & \ -+ CSI_CH_CFG_INPUT_SEQ_MASK) -+ -+#define CSI_CH_SCALE_REG 0x4c -+#define CSI_CH_SCALE_QUART_EN BIT(0) -+ -+#define CSI_CH_F0_BUFA_REG 0x50 -+ -+#define CSI_CH_F1_BUFA_REG 0x58 -+ -+#define CSI_CH_F2_BUFA_REG 0x60 -+ -+//megi: called CAP_STA register in A83T manual -+#define CSI_CH_STA_REG 0x6c -+#define CSI_CH_STA_FIELD_STA_MASK BIT(2) -+#define CSI_CH_STA_FIELD_STA_FIELD0 0 -+#define CSI_CH_STA_FIELD_STA_FIELD1 BIT(2) -+#define CSI_CH_STA_VCAP_STA BIT(1) -+#define CSI_CH_STA_SCAP_STA BIT(0) -+ -+#define CSI_CH_INT_EN_REG 0x70 -+#define CSI_CH_INT_EN_VS_INT_EN BIT(7) -+#define CSI_CH_INT_EN_HB_OF_INT_EN BIT(6) -+#define CSI_CH_INT_EN_MUL_ERR_INT_EN BIT(5) -+#define CSI_CH_INT_EN_FIFO2_OF_INT_EN BIT(4) -+#define CSI_CH_INT_EN_FIFO1_OF_INT_EN BIT(3) -+#define CSI_CH_INT_EN_FIFO0_OF_INT_EN BIT(2) -+#define CSI_CH_INT_EN_FD_INT_EN BIT(1) -+#define CSI_CH_INT_EN_CD_INT_EN BIT(0) -+ -+#define CSI_CH_INT_STA_REG 0x74 -+#define CSI_CH_INT_STA_VS_PD BIT(7) -+#define CSI_CH_INT_STA_HB_OF_PD BIT(6) -+#define CSI_CH_INT_STA_MUL_ERR_PD BIT(5) -+#define CSI_CH_INT_STA_FIFO2_OF_PD BIT(4) -+#define CSI_CH_INT_STA_FIFO1_OF_PD BIT(3) -+#define CSI_CH_INT_STA_FIFO0_OF_PD BIT(2) -+#define CSI_CH_INT_STA_FD_PD BIT(1) -+#define CSI_CH_INT_STA_CD_PD BIT(0) -+ -+#define CSI_CH_FLD1_VSIZE_REG 0x78 -+ -+#define CSI_CH_HSIZE_REG 0x80 -+#define CSI_CH_HSIZE_HOR_LEN_MASK GENMASK(28, 16) -+#define CSI_CH_HSIZE_HOR_LEN(len) ((len << 16) & \ -+ CSI_CH_HSIZE_HOR_LEN_MASK) -+#define CSI_CH_HSIZE_HOR_START_MASK GENMASK(12, 0) -+#define CSI_CH_HSIZE_HOR_START(start) ((start << 0) & \ -+ CSI_CH_HSIZE_HOR_START_MASK) -+ -+#define CSI_CH_VSIZE_REG 0x84 -+#define CSI_CH_VSIZE_VER_LEN_MASK GENMASK(28, 16) -+#define CSI_CH_VSIZE_VER_LEN(len) ((len << 16) & \ -+ CSI_CH_VSIZE_VER_LEN_MASK) -+#define CSI_CH_VSIZE_VER_START_MASK GENMASK(12, 0) -+#define CSI_CH_VSIZE_VER_START(start) ((start << 0) & \ -+ CSI_CH_VSIZE_VER_START_MASK) -+ -+#define CSI_CH_BUF_LEN_REG 0x88 -+#define CSI_CH_BUF_LEN_BUF_LEN_C_MASK GENMASK(29, 16) -+#define CSI_CH_BUF_LEN_BUF_LEN_C(len) ((len << 16) & \ -+ CSI_CH_BUF_LEN_BUF_LEN_C_MASK) -+#define CSI_CH_BUF_LEN_BUF_LEN_Y_MASK GENMASK(13, 0) -+#define CSI_CH_BUF_LEN_BUF_LEN_Y(len) ((len << 0) & \ -+ CSI_CH_BUF_LEN_BUF_LEN_Y_MASK) -+ -+#define CSI_CH_FLIP_SIZE_REG 0x8c -+#define CSI_CH_FLIP_SIZE_VER_LEN_MASK GENMASK(28, 16) -+#define CSI_CH_FLIP_SIZE_VER_LEN(len) ((len << 16) & \ -+ CSI_CH_FLIP_SIZE_VER_LEN_MASK) -+#define CSI_CH_FLIP_SIZE_VALID_LEN_MASK GENMASK(12, 0) -+#define CSI_CH_FLIP_SIZE_VALID_LEN(len) ((len << 0) & \ -+ CSI_CH_FLIP_SIZE_VALID_LEN_MASK) -+ -+#define CSI_CH_FRM_CLK_CNT_REG 0x90 -+#define CSI_CH_ACC_ITNL_CLK_CNT_REG 0x94 -+#define CSI_CH_FIFO_STAT_REG 0x98 -+#define CSI_CH_PCLK_STAT_REG 0x9c -+ -+/* -+ * csi input data format -+ */ -+enum csi_input_fmt { -+ CSI_INPUT_FORMAT_RAW = 0, -+ CSI_INPUT_FORMAT_YUV422 = 3, -+ CSI_INPUT_FORMAT_YUV420 = 4, -+}; -+ -+/* -+ * csi output data format -+ */ -+enum csi_output_fmt { -+ /* only when input format is RAW */ -+ CSI_FIELD_RAW_8 = 0, -+ CSI_FIELD_RAW_10 = 1, -+ CSI_FIELD_RAW_12 = 2, -+ CSI_FIELD_RGB565 = 4, -+ CSI_FIELD_RGB888 = 5, -+ CSI_FIELD_PRGB888 = 6, -+ -+ //megi: A83T only -+ CSI_FIELD_UV_COMBINED = 7, -+ -+ CSI_FRAME_RAW_8 = 8, -+ CSI_FRAME_RAW_10 = 9, -+ CSI_FRAME_RAW_12 = 10, -+ CSI_FRAME_RGB565 = 12, -+ CSI_FRAME_RGB888 = 13, -+ CSI_FRAME_PRGB888 = 14, -+ -+ //megi: A83T only -+ CSI_FRAME_UV_COMBINED = 15, -+ -+ /* only when input format is YUV422/YUV420 */ -+ //megi: when input format is 420, only 420 output formats are available -+ //from below -+ CSI_FIELD_PLANAR_YUV422 = 0, -+ CSI_FIELD_PLANAR_YUV420 = 1, -+ CSI_FRAME_PLANAR_YUV420 = 2, -+ CSI_FRAME_PLANAR_YUV422 = 3, -+ CSI_FIELD_UV_CB_YUV422 = 4, -+ CSI_FIELD_UV_CB_YUV420 = 5, -+ CSI_FRAME_UV_CB_YUV420 = 6, -+ CSI_FRAME_UV_CB_YUV422 = 7, -+ CSI_FIELD_MB_YUV422 = 8, -+ CSI_FIELD_MB_YUV420 = 9, -+ CSI_FRAME_MB_YUV420 = 10, -+ CSI_FRAME_MB_YUV422 = 11, -+ CSI_FIELD_UV_CB_YUV422_10 = 12, -+ CSI_FIELD_UV_CB_YUV420_10 = 13, -+}; -+ -+/* -+ * csi YUV input data sequence -+ */ -+enum csi_input_seq { -+ /* only when input format is YUV422 */ -+ CSI_INPUT_SEQ_YUYV = 0, -+ CSI_INPUT_SEQ_YVYU, -+ CSI_INPUT_SEQ_UYVY, -+ CSI_INPUT_SEQ_VYUY, -+}; -+ -+#endif /* __SUN6I_CSI_V3S_H__ */ --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0029-MAINTAINERS-Add-entry-for-Himax-HM5065.patch b/patch/kernel/sunxi-legacy/0000-0029-MAINTAINERS-Add-entry-for-Himax-HM5065.patch deleted file mode 100644 index 22d8589d6..000000000 --- a/patch/kernel/sunxi-legacy/0000-0029-MAINTAINERS-Add-entry-for-Himax-HM5065.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 143f5c46be05234ca2618eb4515b9b1d2f329770 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sat, 30 Sep 2017 21:31:35 +0200 -Subject: [PATCH 29/82] MAINTAINERS: Add entry for Himax HM5065 - -Signed-off-by: Ondrej Jirman ---- - MAINTAINERS | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/MAINTAINERS b/MAINTAINERS -index 11a59e82d92e..93f4ff7d6eba 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -6611,6 +6611,12 @@ S: Supported - F: Documentation/scsi/hptiop.txt - F: drivers/scsi/hptiop.c - -+HIMAX HM5065 SENSOR DRIVER -+M: Ondrej Jirman -+L: linux-media@vger.kernel.org -+S: Supported -+F: drivers/media/i2c/hm5065.c -+ - HIPPI - M: Jes Sorensen - L: linux-hippi@sunsite.dk --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0030-media-dt-bindings-Add-bindings-for-Himax-HM5065-came.patch b/patch/kernel/sunxi-legacy/0000-0030-media-dt-bindings-Add-bindings-for-Himax-HM5065-came.patch deleted file mode 100644 index 2fc9f87ba..000000000 --- a/patch/kernel/sunxi-legacy/0000-0030-media-dt-bindings-Add-bindings-for-Himax-HM5065-came.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 086f56910cfcc26939c56dfd143c7ee3dc24cff1 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sat, 30 Sep 2017 02:30:39 +0200 -Subject: [PATCH 30/82] media: dt-bindings: Add bindings for Himax HM5065 - camera sensor - -HM5065 is 5MP CMOS sensor... - -Signed-off-by: Ondrej Jirman ---- - .../devicetree/bindings/media/i2c/hm5065.txt | 48 +++++++++++++++++++ - 1 file changed, 48 insertions(+) - create mode 100644 Documentation/devicetree/bindings/media/i2c/hm5065.txt - -diff --git a/Documentation/devicetree/bindings/media/i2c/hm5065.txt b/Documentation/devicetree/bindings/media/i2c/hm5065.txt -new file mode 100644 -index 000000000000..68ad7f529e18 ---- /dev/null -+++ b/Documentation/devicetree/bindings/media/i2c/hm5065.txt -@@ -0,0 +1,48 @@ -+* Himax HM5065 CSI camera sensor -+ -+Required Properties: -+- compatible: should be "himax,hm5065" -+- clocks: reference to the external input clock for the sensor. -+- clock-names: should be "xclk". -+- IOVDD-supply: Digital I/O voltage supply, 2.8 volts -+- AVDD-supply: Analog voltage supply, 2.8 volts -+- DVDD-supply: Digital core voltage supply, 1.8 volts -+- AFVDD-supply: Auto focus voltage supply, 2.8 volts -+ -+Optional Properties (one or both must be configured): -+- reset-gpios: reference to the GPIO connected to the reset pin, if any. -+ This is an active low signal to the HM5065. -+- chipenable-gpios: reference to the GPIO connected to the CE pin, -+ if any. This is an active high signal to the HM5065. -+ -+The device node must contain one 'port' child node for its digital output -+video port, in accordance with the video interface bindings defined in -+Documentation/devicetree/bindings/media/video-interfaces.txt. -+ -+Example: -+ -+&i2c1 { -+ hm5065: camera@1f { -+ compatible = "himax,hm5065"; -+ reg = <0x1f>; -+ clocks = <&ccu CLK_CSI_MCLK>; -+ clock-names = "xclk"; -+ IOVDD-supply = <®_dldo3>; -+ AVDD-supply = <®_dldo4>; -+ DVDD-supply = <®_eldo3>; -+ AFVDD-supply = <®_dldo3>; -+ reset-gpios = <&pio 4 18 GPIO_ACTIVE_LOW>; /* PE18 */ -+ chipenable-gpios = <&pio 4 19 GPIO_ACTIVE_HIGH>; /* PE19 */ -+ -+ port { -+ hm5065_ep: endpoint { -+ remote-endpoint = <&csi0_hm5065_ep>; -+ bus-width = <8>; -+ hsync-active = <1>; -+ vsync-active = <1>; -+ data-active = <1>; -+ pclk-sample = <1>; -+ }; -+ }; -+ }; -+}; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0031-ARM-dts-sun8i-a83t-Add-CSI0-node-for-cmos-sensor-int.patch b/patch/kernel/sunxi-legacy/0000-0031-ARM-dts-sun8i-a83t-Add-CSI0-node-for-cmos-sensor-int.patch deleted file mode 100644 index 07e0b0921..000000000 --- a/patch/kernel/sunxi-legacy/0000-0031-ARM-dts-sun8i-a83t-Add-CSI0-node-for-cmos-sensor-int.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 7fe79d7ef105939f10903d87c44b8ea4da3bc4ae Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sat, 30 Sep 2017 02:46:55 +0200 -Subject: [PATCH 31/82] ARM: dts: sun8i-a83t: Add CSI0 node for cmos sensor - interface driver - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t.dtsi | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi -index 00a02b037320..66f035ead79a 100644 ---- a/arch/arm/boot/dts/sun8i-a83t.dtsi -+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi -@@ -636,6 +636,20 @@ - #reset-cells = <1>; - }; - -+ csi0: csi@01cb0000 { -+ compatible = "allwinner,sun8i-a83t-csi"; -+ reg = <0x01cb0000 0x1000>; /* manual says 0x40000 size */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_CSI>, -+ <&ccu CLK_CSI_SCLK>, -+ <&ccu CLK_DRAM_CSI>; -+ clock-names = "ahb", "mod", "ram"; -+ resets = <&ccu RST_BUS_CSI>; -+ status = "disabled"; -+ }; -+ - pio: pinctrl@1c20800 { - compatible = "allwinner,sun8i-a83t-pinctrl"; - interrupts = , -@@ -649,6 +663,13 @@ - #interrupt-cells = <3>; - #gpio-cells = <3>; - -+ csi0_pins: csi0-pins { -+ pins = "PE0", "PE1", "PE2", "PE3", "PE4", -+ "PE5", "PE6", "PE7", "PE8", "PE9", -+ "PE10", "PE11", "PE12", "PE13"; -+ function = "csi"; -+ }; -+ - emac_rgmii_pins: emac-rgmii-pins { - pins = "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", - "PD11", "PD12", "PD13", "PD14", "PD18", --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0032-ARM-dts-sun8i-a83t-tbs-a711-Force-dvdd-csi-r-f-regul.patch b/patch/kernel/sunxi-legacy/0000-0032-ARM-dts-sun8i-a83t-tbs-a711-Force-dvdd-csi-r-f-regul.patch deleted file mode 100644 index 30e3505b3..000000000 --- a/patch/kernel/sunxi-legacy/0000-0032-ARM-dts-sun8i-a83t-tbs-a711-Force-dvdd-csi-r-f-regul.patch +++ /dev/null @@ -1,38 +0,0 @@ -From ac8826aeb1f157a76b1f1d31b13eb557d3f96108 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sat, 30 Sep 2017 02:53:26 +0200 -Subject: [PATCH 32/82] ARM: dts: sun8i-a83t-tbs-a711: Force dvdd-csi-r/f - regulators to 1.8V - -This is required by camera sensors that are connected to them. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index bd7e231e3aba..7936405862c1 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -353,7 +353,7 @@ - }; - - ®_eldo1 { -- regulator-min-microvolt = <1200000>; -+ regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-name = "dvdd-csi-r"; - }; -@@ -365,7 +365,7 @@ - }; - - ®_eldo3 { -- regulator-min-microvolt = <1200000>; -+ regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-name = "dvdd-csi-f"; - }; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0033-ARM-dts-sun8i-a83t-tbs-a711-Use-i2c-gpio-to-communic.patch b/patch/kernel/sunxi-legacy/0000-0033-ARM-dts-sun8i-a83t-tbs-a711-Use-i2c-gpio-to-communic.patch deleted file mode 100644 index 0b632bc9a..000000000 --- a/patch/kernel/sunxi-legacy/0000-0033-ARM-dts-sun8i-a83t-tbs-a711-Use-i2c-gpio-to-communic.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0ba507d286fc521e71ba048d81c7d1d751012bb8 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sat, 30 Sep 2017 02:51:09 +0200 -Subject: [PATCH 33/82] ARM: dts: sun8i-a83t-tbs-a711: Use i2c-gpio to - communicate with cameras - -Camera sensors are connected via I2C to PE14/PE15 pins on A83T. -Unfortunately while the A83T datasheet suggests TWI2 I2C controller -can be configured to have SDA/SCL on these pins, this configuration -doesn't work in reality. We need to either use CCI I2C controller -that is part of the CSI module, or as is done in this patch, use GPIO -based bitbanging I2C driver. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index 7936405862c1..8a0a8d39eb21 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -72,6 +72,16 @@ - default-brightness-level = <39>; - }; - -+ i2c_gpio: i2c-gpio { -+ compatible = "i2c-gpio"; -+ /* PE15 = sda, PE14 = scl */ -+ sda-gpios = <&pio 4 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; -+ scl-gpios = <&pio 4 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; -+ i2c-gpio,delay-us = <1>; /* ~100 kHz */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ - panel { - compatible = "tbs,a711-panel", "panel-lvds"; - backlight = <&backlight>; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0034-ARM-dts-sun8i-a83t-tbs-a711-Add-rear-camera-sensor-H.patch b/patch/kernel/sunxi-legacy/0000-0034-ARM-dts-sun8i-a83t-tbs-a711-Add-rear-camera-sensor-H.patch deleted file mode 100644 index b32565281..000000000 --- a/patch/kernel/sunxi-legacy/0000-0034-ARM-dts-sun8i-a83t-tbs-a711-Add-rear-camera-sensor-H.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 5436d28adbf6268496e20b4c43c43a59f597c340 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Tue, 10 Oct 2017 05:26:49 +0200 -Subject: [PATCH 34/82] ARM: dts: sun8i-a83t-tbs-a711: Add rear camera sensor - (HM5065) - -Sensor is connected via parallel bus to CSI0 and via I2C bus to -PE14/PE15 pins. Enable CSI0 module and add the node for HM5065 -camera sensor. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 43 +++++++++++++++++++++++ - 1 file changed, 43 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index 8a0a8d39eb21..9a87ce651224 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -149,6 +149,23 @@ - cpu-supply = <®_dcdc3>; - }; - -+&csi0 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&csi0_pins>; -+ -+ port { -+ csi0_hm5065_ep: endpoint { -+ remote-endpoint = <&hm5065_ep>; -+ bus-width = <8>; -+ data-active = <1>; -+ pclk-sample = <1>; -+ hsync-active = <1>; -+ vsync-active = <0>; -+ }; -+ }; -+}; -+ - &de { - status = "okay"; - }; -@@ -185,6 +202,32 @@ - }; - }; - -+&i2c_gpio { -+ hm5065: camera@1f { -+ compatible = "himax,hm5065"; -+ reg = <0x1f>; -+ clocks = <&ccu CLK_CSI_MCLK>; -+ clock-names = "xclk"; -+ IOVDD-supply = <®_dldo3>; -+ AVDD-supply = <®_dldo4>; -+ DVDD-supply = <®_eldo3>; -+ AFVDD-supply = <®_dldo3>; -+ reset-gpios = <&pio 4 18 GPIO_ACTIVE_LOW>; /* PE18 */ -+ chipenable-gpios = <&pio 4 19 GPIO_ACTIVE_HIGH>; /* PE19 */ -+ -+ port { -+ hm5065_ep: endpoint { -+ remote-endpoint = <&csi0_hm5065_ep>; -+ bus-width = <8>; -+ data-active = <1>; -+ pclk-sample = <1>; -+ hsync-active = <1>; -+ vsync-active = <0>; -+ }; -+ }; -+ }; -+}; -+ - &mmc0 { - vmmc-supply = <®_dcdc1>; - pinctrl-names = "default"; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0035-ARM-dts-sun8i-a83t-tbs-a711-Reduce-camera-IOVDD-volt.patch b/patch/kernel/sunxi-legacy/0000-0035-ARM-dts-sun8i-a83t-tbs-a711-Reduce-camera-IOVDD-volt.patch deleted file mode 100644 index c81b34249..000000000 --- a/patch/kernel/sunxi-legacy/0000-0035-ARM-dts-sun8i-a83t-tbs-a711-Reduce-camera-IOVDD-volt.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0f0c62c90fc072355b2118d118715492710b8735 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Wed, 8 Nov 2017 04:55:15 +0100 -Subject: [PATCH 35/82] ARM: dts: sun8i-a83t-tbs-a711: Reduce camera IOVDD - voltage - ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index 9a87ce651224..1a711a28f682 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -389,8 +389,8 @@ - }; - - ®_dldo3 { -- regulator-min-microvolt = <2800000>; -- regulator-max-microvolt = <2800000>; -+ regulator-min-microvolt = <2600000>; -+ regulator-max-microvolt = <2600000>; - regulator-name = "vdd-csi"; - }; - --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0036-ARM-dts-sun8i-a83t-tbs-a711-Add-flash-led-support.patch b/patch/kernel/sunxi-legacy/0000-0036-ARM-dts-sun8i-a83t-tbs-a711-Add-flash-led-support.patch deleted file mode 100644 index a1ceeb4b0..000000000 --- a/patch/kernel/sunxi-legacy/0000-0036-ARM-dts-sun8i-a83t-tbs-a711-Add-flash-led-support.patch +++ /dev/null @@ -1,32 +0,0 @@ -From acfec807289ebf7c2af8aaf75aaa67159d549734 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Wed, 8 Nov 2017 21:57:45 +0100 -Subject: [PATCH 36/82] ARM: dts: sun8i-a83t-tbs-a711: Add flash led support - ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index 1a711a28f682..c8278e173f50 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -60,6 +60,15 @@ - stdout-path = "serial0:115200n8"; - }; - -+ leds { -+ compatible = "gpio-leds"; -+ -+ flash_led { -+ label = "flash"; -+ gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; -+ }; -+ }; -+ - backlight: backlight { - compatible = "pwm-backlight"; - pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0037-media-hm5065-Add-subdev-driver-for-Himax-HM5065-came.patch b/patch/kernel/sunxi-legacy/0000-0037-media-hm5065-Add-subdev-driver-for-Himax-HM5065-came.patch deleted file mode 100644 index 1623dff39..000000000 --- a/patch/kernel/sunxi-legacy/0000-0037-media-hm5065-Add-subdev-driver-for-Himax-HM5065-came.patch +++ /dev/null @@ -1,2380 +0,0 @@ -From ccce0cdb4297c0d2986a2f4b85302f1d3a4c2666 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sat, 30 Sep 2017 02:39:48 +0200 -Subject: [PATCH 37/82] media: hm5065: Add subdev driver for Himax HM5065 - camera sensor - -HM5065 is 5MP CMOS sensor. This driver implements support for -V4L2_MBUS_PARALLEL bus type only. The driver Other features: - -- External clock rates support from 6-27MHz (discrete values) -- Resolution support from 2592x1944 to 88x72 -- Frame rates are available depending on the PCLK frequency - (from VGA@120 to 2592x1944@8) -- Support for several YUV and RGB media bus formats - -Signed-off-by: Ondrej Jirman ---- - drivers/media/i2c/Kconfig | 7 + - drivers/media/i2c/Makefile | 1 + - drivers/media/i2c/hm5065.c | 2297 ++++++++++++++++++ - drivers/media/platform/sun6i-csi/sun6i_csi.c | 3 + - 4 files changed, 2308 insertions(+) - create mode 100644 drivers/media/i2c/hm5065.c - -diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig -index 63c9ac2c6a5f..a02a673b3b07 100644 ---- a/drivers/media/i2c/Kconfig -+++ b/drivers/media/i2c/Kconfig -@@ -956,6 +956,13 @@ config VIDEO_S5C73M3 - This is a V4L2 sensor driver for Samsung S5C73M3 - 8 Mpixel camera. - -+config VIDEO_HM5065 -+ tristate "Himax HM5065 sensor support" -+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API -+ ---help--- -+ This is a V4L2 sensor-level driver for Himax HM5065 -+ 5 Mpixel camera. -+ - comment "Flash devices" - - config VIDEO_ADP1653 -diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile -index 520b3c3bf48c..1ca049cfa26d 100644 ---- a/drivers/media/i2c/Makefile -+++ b/drivers/media/i2c/Makefile -@@ -108,5 +108,6 @@ obj-$(CONFIG_VIDEO_OV2659) += ov2659.o - obj-$(CONFIG_VIDEO_TC358743) += tc358743.o - obj-$(CONFIG_VIDEO_IMX258) += imx258.o - obj-$(CONFIG_VIDEO_IMX274) += imx274.o -+obj-$(CONFIG_VIDEO_HM5065) += hm5065.o - - obj-$(CONFIG_SDR_MAX2175) += max2175.o -diff --git a/drivers/media/i2c/hm5065.c b/drivers/media/i2c/hm5065.c -new file mode 100644 -index 000000000000..1f0896bd8dff ---- /dev/null -+++ b/drivers/media/i2c/hm5065.c -@@ -0,0 +1,2297 @@ -+/* -+ * Himax HM5065 driver. -+ * Copyright (C) 2017 Ondřej Jirman . -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define HM5065_AF_FIRMWARE "hm5065-af.bin" -+#define HM5065_FIRMWARE_PARAMETERS "hm5065-init.bin" -+ -+#define HM5065_SENSOR_WIDTH 2592 -+#define HM5065_SENSOR_HEIGHT 1944 -+ -+/* {{{ Register definitions */ -+ -+/* registers are assumed to be u8 unless otherwise specified */ -+ -+/* device parameters */ -+#define HM5065_REG_DEVICE_ID 0x0000 /* u16 */ -+#define HM5065_REG_DEVICE_ID_VALUE 0x039e -+#define HM5065_REG_FIRMWARE_VSN 0x0002 -+#define HM5065_REG_PATCH_VSN 0x0003 -+#define HM5065_REG_EXCLOCKLUT 0x0009 /* standby */ -+ -+#define HM5065_REG_INT_EVENT_FLAG 0x000a -+#define HM5065_REG_INT_EVENT_FLAG_OP_MODE BIT(0) -+#define HM5065_REG_INT_EVENT_FLAG_CAM_MODE BIT(1) -+#define HM5065_REG_INT_EVENT_FLAG_JPEG_STATUS BIT(2) -+#define HM5065_REG_INT_EVENT_FLAG_NUM_FRAMES BIT(3) -+#define HM5065_REG_INT_EVENT_FLAG_AF_LOCKED BIT(4) -+ -+/* mode manager */ -+#define HM5065_REG_USER_COMMAND 0x0010 -+#define HM5065_REG_USER_COMMAND_STOP 0x00 -+#define HM5065_REG_USER_COMMAND_RUN 0x01 -+#define HM5065_REG_USER_COMMAND_POWEROFF 0x02 -+ -+#define HM5065_REG_STATE 0x0011 -+#define HM5065_REG_STATE_RAW 0x10 -+#define HM5065_REG_STATE_IDLE 0x20 -+#define HM5065_REG_STATE_RUNNING 0x30 -+ -+#define HM5065_REG_ACTIVE_PIPE_SETUP_BANK 0x0012 -+#define HM5065_REG_ACTIVE_PIPE_SETUP_BANK_0 0x00 -+#define HM5065_REG_ACTIVE_PIPE_SETUP_BANK_1 0x01 -+ -+#define HM5065_REG_NUMBER_OF_FRAMES_STREAMED 0x0014 /* ro */ -+#define HM5065_REG_REQUIRED_STREAM_LENGTH 0x0015 -+ -+#define HM5065_REG_CSI_ENABLE 0x0016 /* standby */ -+#define HM5065_REG_CSI_ENABLE_DISABLE 0x00 -+#define HM5065_REG_CSI_ENABLE_CSI2_1LANE 0x01 -+#define HM5065_REG_CSI_ENABLE_CSI2_2LANE 0x02 -+ -+/* pipe setup bank 0 */ -+#define HM5065_REG_P0_SENSOR_MODE 0x0040 -+#define HM5065_REG_SENSOR_MODE_FULLSIZE 0x00 -+#define HM5065_REG_SENSOR_MODE_BINNING_2X2 0x01 -+#define HM5065_REG_SENSOR_MODE_BINNING_4X4 0x02 -+#define HM5065_REG_SENSOR_MODE_SUBSAMPLING_2X2 0x03 -+#define HM5065_REG_SENSOR_MODE_SUBSAMPLING_4X4 0x04 -+ -+#define HM5065_REG_P0_IMAGE_SIZE 0x0041 -+#define HM5065_REG_IMAGE_SIZE_5MP 0x00 -+#define HM5065_REG_IMAGE_SIZE_UXGA 0x01 -+#define HM5065_REG_IMAGE_SIZE_SXGA 0x02 -+#define HM5065_REG_IMAGE_SIZE_SVGA 0x03 -+#define HM5065_REG_IMAGE_SIZE_VGA 0x04 -+#define HM5065_REG_IMAGE_SIZE_CIF 0x05 -+#define HM5065_REG_IMAGE_SIZE_QVGA 0x06 -+#define HM5065_REG_IMAGE_SIZE_QCIF 0x07 -+#define HM5065_REG_IMAGE_SIZE_QQVGA 0x08 -+#define HM5065_REG_IMAGE_SIZE_QQCIF 0x09 -+#define HM5065_REG_IMAGE_SIZE_MANUAL 0x0a -+ -+#define HM5065_REG_P0_MANUAL_HSIZE 0x0042 /* u16 */ -+#define HM5065_REG_P0_MANUAL_VSIZE 0x0044 /* u16 */ -+ -+#define HM5065_REG_P0_DATA_FORMAT 0x0046 -+#define HM5065_REG_DATA_FORMAT_YCBCR_JFIF 0x00 -+#define HM5065_REG_DATA_FORMAT_YCBCR_REC601 0x01 -+#define HM5065_REG_DATA_FORMAT_YCBCR_CUSTOM 0x02 -+#define HM5065_REG_DATA_FORMAT_RGB_565 0x03 -+#define HM5065_REG_DATA_FORMAT_RGB_565_CUSTOM 0x04 -+#define HM5065_REG_DATA_FORMAT_RGB_444 0x05 -+#define HM5065_REG_DATA_FORMAT_RGB_555 0x06 -+#define HM5065_REG_DATA_FORMAT_RAW10ITU10 0x07 -+#define HM5065_REG_DATA_FORMAT_RAW10ITU8 0x08 -+#define HM5065_REG_DATA_FORMAT_JPEG 0x09 -+ -+#define HM5065_REG_P0_GAMMA_GAIN 0x0049 /* 0-31 */ -+#define HM5065_REG_P0_GAMMA_INTERPOLATION 0x004a /* 0-16 */ -+#define HM5065_REG_P0_PEAKING_GAIN 0x004c /* 0-63 */ -+ -+#define HM5065_REG_P0_JPEG_SQUEEZE_MODE 0x004d -+#define HM5065_REG_JPEG_SQUEEZE_MODE_USER 0x00 -+#define HM5065_REG_JPEG_SQUEEZE_MODE_AUTO 0x01 -+ -+#define HM5065_REG_P0_JPEG_TARGET_FILE_SIZE 0x004e /* u16, kB */ -+#define HM5065_REG_P0_JPEG_IMAGE_QUALITY 0x0050 -+#define HM5065_REG_JPEG_IMAGE_QUALITY_HIGH 0x00 -+#define HM5065_REG_JPEG_IMAGE_QUALITY_MEDIUM 0x01 -+#define HM5065_REG_JPEG_IMAGE_QUALITY_LOW 0x02 -+ -+/* pipe setup bank 1 (only register indexes) */ -+#define HM5065_REG_P1_SENSOR_MODE 0x0060 -+#define HM5065_REG_P1_IMAGE_SIZE 0x0061 -+#define HM5065_REG_P1_MANUAL_HSIZE 0x0062 /* u16 */ -+#define HM5065_REG_P1_MANUAL_VSIZE 0x0064 /* u16 */ -+#define HM5065_REG_P1_DATA_FORMAT 0x0066 -+#define HM5065_REG_P1_GAMMA_GAIN 0x0069 /* 0-31 */ -+#define HM5065_REG_P1_GAMMA_INTERPOLATION 0x006a /* 0-16 */ -+#define HM5065_REG_P1_PEAKING_GAIN 0x006c /* 0-63 */ -+#define HM5065_REG_P1_JPEG_SQUEEZE_MODE 0x006d -+#define HM5065_REG_P1_JPEG_TARGET_FILE_SIZE 0x006e /* u16, kB */ -+#define HM5065_REG_P1_JPEG_IMAGE_QUALITY 0x0070 -+ -+/* pipe setup - common registers */ -+#define HM5065_REG_CONTRAST 0x0080 /* 0-200 */ -+#define HM5065_REG_COLOR_SATURATION 0x0081 /* 0-200 */ -+#define HM5065_REG_BRIGHTNESS 0x0082 /* 0-200 */ -+#define HM5065_REG_HORIZONTAL_MIRROR 0x0083 /* 0,1 */ -+#define HM5065_REG_VERTICAL_FLIP 0x0084 /* 0,1 */ -+ -+#define HM5065_REG_YCRCB_ORDER 0x0085 -+#define HM5065_REG_YCRCB_ORDER_CB_Y_CR_Y 0x00 -+#define HM5065_REG_YCRCB_ORDER_CR_Y_CB_Y 0x01 -+#define HM5065_REG_YCRCB_ORDER_Y_CB_Y_CR 0x02 -+#define HM5065_REG_YCRCB_ORDER_Y_CR_Y_CB 0x03 -+ -+/* clock chain parameter inputs (floating point) */ -+#define HM5065_REG_EXTERNAL_CLOCK_FREQ_MHZ 0x00b0 /* fp16, 6-27, standby */ -+#define HM5065_REG_TARGET_PLL_OUTPUT 0x00b2 /* fp16, 450-1000, standby */ -+ -+/* static frame rate control */ -+#define HM5065_REG_DESIRED_FRAME_RATE_NUM 0x00c8 /* u16 */ -+#define HM5065_REG_DESIRED_FRAME_RATE_DEN 0x00ca -+ -+/* static frame rate status */ -+#define HM5065_REG_REQUESTED_FRAME_RATE_HZ 0x00d8 /* fp16 */ -+#define HM5065_REG_MAX_FRAME_RATE_HZ 0x00da /* fp16 */ -+#define HM5065_REG_MIN_FRAME_RATE_HZ 0x00dc /* fp16 */ -+ -+/* exposure controls */ -+#define HM5065_REG_EXPOSURE_MODE 0x0128 -+#define HM5065_REG_EXPOSURE_MODE_AUTO 0x00 -+#define HM5065_REG_EXPOSURE_MODE_COMPILED_MANUAL 0x01 -+#define HM5065_REG_EXPOSURE_MODE_DIRECT_MANUAL 0x02 -+ -+#define HM5065_REG_EXPOSURE_METERING 0x0129 -+#define HM5065_REG_EXPOSURE_METERING_FLAT 0x00 -+#define HM5065_REG_EXPOSURE_METERING_BACKLIT 0x01 -+#define HM5065_REG_EXPOSURE_METERING_CENTERED 0x02 -+ -+#define HM5065_REG_MANUAL_EXPOSURE_TIME_NUM 0x012a -+#define HM5065_REG_MANUAL_EXPOSURE_TIME_DEN 0x012b -+#define HM5065_REG_MANUAL_EXPOSURE_TIME_US 0x012c /* fp16 */ -+#define HM5065_REG_COLD_START_DESIRED_TIME_US 0x012e /* fp16, standby */ -+#define HM5065_REG_EXPOSURE_COMPENSATION 0x0130 /* s8, -7 - +7 */ -+ -+#define HM5065_REG_DIRECT_MODE_COARSE_INTEGRATION_LINES 0x0132 /* u16 */ -+#define HM5065_REG_DIRECT_MODE_FINE_INTEGRATION_PIXELS 0x0134 /* u16 */ -+#define HM5065_REG_DIRECT_MODE_CODED_ANALOG_GAIN 0x0136 /* u16 */ -+#define HM5065_REG_DIRECT_MODE_DIGITAL_GAIN 0x0138 /* fp16 */ -+#define HM5065_REG_FREEZE_AUTO_EXPOSURE 0x0142 /* 0,1 */ -+#define HM5065_REG_USER_MAXIMUM_INTEGRATION_TIME_US 0x0143 /* fp16 */ -+#define HM5065_REG_ANTI_FLICKER_MODE 0x0148 /* 0,1 */ -+ -+/* exposure algorithm controls */ -+#define HM5065_REG_DIGITAL_GAIN_FLOOR 0x015c /* fp16 */ -+#define HM5065_REG_DIGITAL_GAIN_CEILING 0x015e /* fp16 */ -+#define HM5065_REG_ANALOG_GAIN_FLOOR 0x02c0 /* u16 */ -+#define HM5065_REG_ANALOG_GAIN_CEILING 0x02c2 /* u16 */ -+ -+/* exposure status */ -+#define HM5065_REG_COARSE_INTEGRATION 0x017c /* u16 */ -+#define HM5065_REG_FINE_INTEGRATION_PENDING_PIXELS 0x017e /* u16 */ -+#define HM5065_REG_ANALOG_GAIN_PENDING 0x0180 /* fp16 */ -+#define HM5065_REG_DIGITAL_GAIN_PENDING 0x0182 /* fp16 */ -+#define HM5065_REG_DESIRED_EXPOSURE_TIME_US 0x0184 /* fp16 */ -+#define HM5065_REG_COMPILED_EXPOSURE_TIME_US 0x0186 /* fp16 */ -+#define HM5065_REG_USER_MAXIMUM_INTEGRATION_LINES 0x0189 /* u16 */ -+#define HM5065_REG_TOTAL_INTEGRATION_TIME_PENDING_US 0x018b /* fp16 */ -+#define HM5065_REG_CODED_ANALOG_GAIN_PENDING 0x018d /* u16 */ -+ -+/* flicker detect */ -+#define HM5065_REG_FD_ENABLE_DETECT 0x0190 /* 0,1 */ -+#define HM5065_REG_FD_DETECTION_START 0x0191 /* 0,1 */ -+#define HM5065_REG_FD_MAX_NUMBER_ATTEMP 0x0192 /* 0-255, 0 = continuous */ -+#define HM5065_REG_FD_FLICKER_IDENTIFICATION_THRESHOLD 0x0193 /* u16 */ -+#define HM5065_REG_FD_WIN_TIMES 0x0195 -+#define HM5065_REG_FD_FRAME_RATE_SHIFT_NUMBER 0x0196 -+#define HM5065_REG_FD_MANUAL_FREF_ENABLE 0x0197 /* 0,1 */ -+#define HM5065_REG_FD_MANU_FREF_100 0x0198 /* u16 */ -+#define HM5065_REG_FD_MANU_FREF_120 0x019a /* u16 */ -+#define HM5065_REG_FD_FLICKER_FREQUENCY 0x019c /* fp16 */ -+ -+/* white balance control */ -+#define HM5065_REG_WB_MODE 0x01a0 -+#define HM5065_REG_WB_MODE_OFF 0x00 -+#define HM5065_REG_WB_MODE_AUTOMATIC 0x01 -+#define HM5065_REG_WB_MODE_AUTO_INSTANT 0x02 -+#define HM5065_REG_WB_MODE_MANUAL_RGB 0x03 -+#define HM5065_REG_WB_MODE_CLOUDY_PRESET 0x04 -+#define HM5065_REG_WB_MODE_SUNNY_PRESET 0x05 -+#define HM5065_REG_WB_MODE_LED_PRESET 0x06 -+#define HM5065_REG_WB_MODE_FLUORESCENT_PRESET 0x07 -+#define HM5065_REG_WB_MODE_TUNGSTEN_PRESET 0x08 -+#define HM5065_REG_WB_MODE_HORIZON_PRESET 0x09 -+ -+#define HM5065_REG_WB_MANUAL_RED_GAIN 0x01a1 -+#define HM5065_REG_WB_MANUAL_GREEN_GAIN 0x01a2 -+#define HM5065_REG_WB_MANUAL_BLUE_GAIN 0x01a3 -+ -+#define HM5065_REG_WB_MISC_SETTINGS 0x01a4 -+#define HM5065_REG_WB_MISC_SETTINGS_FREEZE_ALGO BIT(2) -+ -+#define HM5065_REG_WB_HUE_R_BIAS 0x01a5 /* fp16 */ -+#define HM5065_REG_WB_HUE_B_BIAS 0x01a7 /* fp16 */ -+ -+#define HM5065_REG_WB_STATUS 0x01c0 -+#define HM5065_REG_WB_STATUS_STABLE BIT(0) -+ -+#define HM5065_REG_WB_NORM_RED_GAIN 0x01c8 /* fp16 */ -+#define HM5065_REG_WB_PART_RED_GAIN 0x01e0 /* fp16 */ -+#define HM5065_REG_WB_PART_GREEN_GAIN 0x01e2 /* fp16 */ -+#define HM5065_REG_WB_PART_BLUE_GAIN 0x01e4 /* fp16 */ -+ -+/* image stability status */ -+#define HM5065_REG_WHITE_BALANCE_STABLE 0x0291 /* 0,1 */ -+#define HM5065_REG_EXPOSURE_STABLE 0x0292 /* 0,1 */ -+#define HM5065_REG_STABLE 0x0294 /* 0,1 */ -+ -+/* special effects */ -+#define HM5065_REG_EFFECTS_NEGATIVE 0x0380 /* 0,1 */ -+#define HM5065_REG_EFFECTS_SOLARISING 0x0381 /* 0,1 */ -+#define HM5065_REG_EFFECTS_SKECTH 0x0382 /* 0,1 */ -+ -+#define HM5065_REG_EFFECTS_COLOR 0x0384 -+#define HM5065_REG_EFFECTS_COLOR_NORMAL 0x00 -+#define HM5065_REG_EFFECTS_COLOR_RED_ONLY 0x01 -+#define HM5065_REG_EFFECTS_COLOR_YELLOW_ONLY 0x02 -+#define HM5065_REG_EFFECTS_COLOR_GREEN_ONLY 0x03 -+#define HM5065_REG_EFFECTS_COLOR_BLUE_ONLY 0x04 -+#define HM5065_REG_EFFECTS_COLOR_BLACK_WHITE 0x05 -+#define HM5065_REG_EFFECTS_COLOR_SEPIA 0x06 -+#define HM5065_REG_EFFECTS_COLOR_ANTIQUE 0x07 -+#define HM5065_REG_EFFECTS_COLOR_AQUA 0x08 -+#define HM5065_REG_EFFECTS_COLOR_MANUAL_MATRIX 0x09 -+ -+/* anti-vignete, otp flash (skipped), page 79-89 */ -+ -+/* flash control */ -+#define HM5065_REG_FLASH_MODE 0x02d0 /* 0,1 */ -+#define HM5065_REG_FLASH_RECOMMENDED 0x02d1 /* 0,1 */ -+ -+/* test pattern */ -+#define HM5065_REG_ENABLE_TEST_PATTERN 0x05d8 /* 0,1 */ -+ -+#define HM5065_REG_TEST_PATTERN 0x05d9 -+#define HM5065_REG_TEST_PATTERN_NONE 0x00 -+#define HM5065_REG_TEST_PATTERN_HORIZONTAL_GREY_SCALE 0x01 -+#define HM5065_REG_TEST_PATTERN_VERTICAL_GREY_SCALE 0x02 -+#define HM5065_REG_TEST_PATTERN_DIAGONAL_GREY_SCALE 0x03 -+#define HM5065_REG_TEST_PATTERN_PN28 0x04 -+#define HM5065_REG_TEST_PATTERN_PN9 0x05 -+#define HM5065_REG_TEST_PATTERN_SOLID_COLOR 0x06 -+#define HM5065_REG_TEST_PATTERN_COLOR_BARS 0x07 -+#define HM5065_REG_TEST_PATTERN_GRADUATED_COLOR_BARS 0x08 -+ -+#define HM5065_REG_TESTDATA_RED 0x4304 /* u16, 0-1023 */ -+#define HM5065_REG_TESTDATA_GREEN_R 0x4308 /* u16, 0-1023 */ -+#define HM5065_REG_TESTDATA_BLUE 0x430c /* u16, 0-1023 */ -+#define HM5065_REG_TESTDATA_GREEN_B 0x4310 /* u16, 0-1023 */ -+ -+/* contrast stretch */ -+#define HM5065_REG_CS_ENABLE 0x05e8 /* 0,1 */ -+#define HM5065_REG_CS_GAIN_CEILING 0x05e9 /* fp16 */ -+#define HM5065_REG_CS_BLACK_OFFSET_CEILING 0x05eb -+#define HM5065_REG_CS_WHITE_PIX_TARGET 0x05ec /* fp16 */ -+#define HM5065_REG_CS_BLACK_PIX_TARGET 0x05ee /* fp16 */ -+#define HM5065_REG_CS_ENABLED 0x05f8 /* 0,1 */ -+#define HM5065_REG_CS_TOTAL_PIXEL 0x05f9 /* fp16 */ -+#define HM5065_REG_CS_W_TARGET 0x05fb /* u32 */ -+#define HM5065_REG_CS_B_TARGET 0x05ff /* u32 */ -+#define HM5065_REG_CS_GAIN 0x0603 /* fp16 */ -+#define HM5065_REG_CS_BLACK_OFFSET 0x0605 -+#define HM5065_REG_CS_WHITE_LIMIT 0x0606 -+ -+/* preset controls */ -+#define HM5065_REG_PRESET_LOADER_ENABLE 0x0638 /* 0,1, standby */ -+ -+#define HM5065_REG_INDIVIDUAL_PRESET 0x0639 /* standby */ -+#define HM5065_REG_INDIVIDUAL_PRESET_ANTIVIGNETTE BIT(0) -+#define HM5065_REG_INDIVIDUAL_PRESET_WHITE_BALANCE BIT(1) -+#define HM5065_REG_INDIVIDUAL_PRESET_VCM BIT(4) -+ -+/* jpeg control parameters*/ -+#define HM5065_REG_JPEG_STATUS 0x0649 -+#define HM5065_REG_JPEG_RESTART 0x064a -+#define HM5065_REG_JPEG_HI_SQUEEZE_VALUE 0x064b /* 5-255 (5 = max q.) */ -+#define HM5065_REG_JPEG_MED_SQUEEZE_VALUE 0x064c /* 5-255 */ -+#define HM5065_REG_JPEG_LOW_SQUEEZE_VALUE 0x064d /* 5-255 */ -+#define HM5065_REG_JPEG_LINE_LENGTH 0x064e /* u16, standby */ -+#define HM5065_REG_JPEG_CLOCK_RATIO 0x0650 /* 1-8, standby */ -+#define HM5065_REG_JPEG_THRES 0x0651 /* u16, standby */ -+#define HM5065_REG_JPEG_BYTE_SENT 0x0653 /* u32 */ -+ -+/* autofocus */ -+ -+#define HM5065_REG_AF_WINDOWS_SYSTEM 0x065a -+#define HM5065_REG_AF_WINDOWS_SYSTEM_7_ZONES 0x00 -+#define HM5065_REG_AF_WINDOWS_SYSTEM_1_ZONE 0x01 -+ -+#define HM5065_REG_AF_H_RATIO_NUM 0x065b -+#define HM5065_REG_AF_H_RATIO_DEN 0x065c -+#define HM5065_REG_AF_V_RATIO_NUM 0x065d -+#define HM5065_REG_AF_V_RATIO_DEN 0x065e -+ -+#define HM5065_REG_AF_RANGE 0x0709 -+#define HM5065_REG_AF_RANGE_FULL 0x00 -+#define HM5065_REG_AF_RANGE_LANDSCAPE 0x01 -+#define HM5065_REG_AF_RANGE_MACRO 0x02 -+ -+#define HM5065_REG_AF_MODE 0x070a -+#define HM5065_REG_AF_MODE_MANUAL 0x00 -+#define HM5065_REG_AF_MODE_CONTINUOUS 0x01 -+#define HM5065_REG_AF_MODE_SINGLE 0x03 -+ -+#define HM5065_REG_AF_MODE_STATUS 0x0720 -+ -+#define HM5065_REG_AF_COMMAND 0x070b -+#define HM5065_REG_AF_COMMAND_NULL 0x00 -+#define HM5065_REG_AF_COMMAND_RELEASED_BUTTON 0x01 -+#define HM5065_REG_AF_COMMAND_HALF_BUTTON 0x02 -+#define HM5065_REG_AF_COMMAND_TAKE_SNAPSHOT 0x03 -+#define HM5065_REG_AF_COMMAND_REFOCUS 0x04 -+ -+#define HM5065_REG_AF_LENS_COMMAND 0x070c -+#define HM5065_REG_AF_LENS_COMMAND_NULL 0x00 -+#define HM5065_REG_AF_LENS_COMMAND_MOVE_STEP_TO_INFINITY 0x01 -+#define HM5065_REG_AF_LENS_COMMAND_MOVE_STEP_TO_MACRO 0x02 -+#define HM5065_REG_AF_LENS_COMMAND_GOTO_INFINITY 0x03 -+#define HM5065_REG_AF_LENS_COMMAND_GOTO_MACRO 0x04 -+#define HM5065_REG_AF_LENS_COMMAND_GOTO_RECOVERY 0x05 -+#define HM5065_REG_AF_LENS_COMMAND_GOTO_TARGET_POSITION 0x07 -+#define HM5065_REG_AF_LENS_COMMAND_GOTO_HYPERFOCAL 0x0C -+ -+#define HM5065_REG_AF_MANUAL_STEP_SIZE 0x070d -+#define HM5065_REG_AF_FACE_LOCATION_CTRL_ENABLE 0x0714 -+#define HM5065_REG_AF_FACE_LOCATION_CTRL_ENABLE_AF BIT(0) -+#define HM5065_REG_AF_FACE_LOCATION_CTRL_ENABLE_AE BIT(1) -+#define HM5065_REG_AF_FACE_LOCATION_CTRL_ENABLE_AWB BIT(2) -+#define HM5065_REG_AF_FACE_LOCATION_X_START 0x0715 /* u16 */ -+#define HM5065_REG_AF_FACE_LOCATION_X_SIZE 0x0717 /* u16 */ -+#define HM5065_REG_AF_FACE_LOCATION_Y_START 0x0719 /* u16 */ -+#define HM5065_REG_AF_FACE_LOCATION_Y_SIZE 0x071b /* u16 */ -+ -+#define HM5065_REG_AF_IN_FOCUS 0x07ae /* ro 0,1 */ -+#define HM5065_REG_AF_IS_STABLE 0x0725 /* ro 0,1 */ -+ -+/* reverse engineered registers */ -+#define HM5065_REG_BUS_DATA_FORMAT 0x7000 -+#define HM5065_REG_COLORSPACE 0x5200 -+#define HM5065_REG_BUS_CONFIG 0x7101 -+#define HM5065_REG_BUS_CONFIG_BT656 0x24 -+#define HM5065_REG_BUS_CONFIG_PARALLEL_HH_VL 0x44 -+ -+/* }}} */ -+ -+struct reg_value { -+ u16 addr; -+ u8 value; -+} __packed; -+ -+/* -+ * Sensor has various pre-defined PLL configurations for a set of -+ * external clock frequencies. -+ */ -+struct hm5065_clk_lut { -+ unsigned long clk_freq; -+ u8 lut_id; -+}; -+ -+static const struct hm5065_clk_lut hm5065_clk_luts[] = { -+ { .clk_freq = 12000000, .lut_id = 0x10 }, -+ { .clk_freq = 13000000, .lut_id = 0x11 }, -+ { .clk_freq = 13500000, .lut_id = 0x12 }, -+ { .clk_freq = 14400000, .lut_id = 0x13 }, -+ { .clk_freq = 18000000, .lut_id = 0x14 }, -+ { .clk_freq = 19200000, .lut_id = 0x15 }, -+ { .clk_freq = 24000000, .lut_id = 0x16 }, -+ { .clk_freq = 26000000, .lut_id = 0x17 }, -+ { .clk_freq = 27000000, .lut_id = 0x18 }, -+}; -+ -+static const struct hm5065_clk_lut *hm5065_find_clk_lut(unsigned long freq) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(hm5065_clk_luts); i++) -+ if (hm5065_clk_luts[i].clk_freq == freq) -+ return &hm5065_clk_luts[i]; -+ -+ return NULL; -+} -+ -+struct hm5065_frame_size { -+ u32 width; -+ u32 height; -+ u8 max_fps; /* for a case without binning enabled */ -+} __packed; -+ -+/* must be sorted by frame area */ -+static const struct hm5065_frame_size hm5065_frame_sizes[] = { -+ { .width = 2592, .height = 1944, .max_fps = 5 }, -+ { .width = 1920, .height = 1080, .max_fps = 5 }, -+ { .width = 1600, .height = 1200, .max_fps = 5 }, -+ { .width = 1280, .height = 1024, .max_fps = 10 }, -+ { .width = 1280, .height = 720, .max_fps = 10 }, -+ { .width = 1024, .height = 768, .max_fps = 10 }, -+ { .width = 1024, .height = 600, .max_fps = 12 }, -+ { .width = 800, .height = 600, .max_fps = 15 }, -+ { .width = 640, .height = 480, .max_fps = 20 }, -+ { .width = 352, .height = 288, .max_fps = 30 }, -+ { .width = 320, .height = 240, .max_fps = 30 }, -+ { .width = 176, .height = 144, .max_fps = 30 }, -+ { .width = 160, .height = 120, .max_fps = 30 }, -+ { .width = 88, .height = 72, .max_fps = 30 }, -+}; -+ -+#define HM5065_NUM_FRAME_SIZES ARRAY_SIZE(hm5065_frame_sizes) -+#define HM5065_DEFAULT_FRAME_SIZE 4 -+ -+struct hm5065_pixfmt { -+ u32 code; -+ u32 colorspace; -+ u8 data_fmt; -+ u8 ycbcr_order; -+ u8 fmt_setup; -+}; -+ -+//XXX: identify colrorspace correctly, see datasheet page 40 -+static const struct hm5065_pixfmt hm5065_formats[] = { -+ { -+ .code = MEDIA_BUS_FMT_UYVY8_2X8, -+ .colorspace = V4L2_COLORSPACE_SRGB, -+ .data_fmt = HM5065_REG_DATA_FORMAT_YCBCR_CUSTOM, -+ .ycbcr_order = HM5065_REG_YCRCB_ORDER_CB_Y_CR_Y, -+ .fmt_setup = 0x08 -+ }, -+ { -+ .code = MEDIA_BUS_FMT_VYUY8_2X8, -+ .colorspace = V4L2_COLORSPACE_SRGB, -+ .data_fmt = HM5065_REG_DATA_FORMAT_YCBCR_CUSTOM, -+ .ycbcr_order = HM5065_REG_YCRCB_ORDER_CR_Y_CB_Y, -+ .fmt_setup = 0x08 -+ }, -+ { -+ .code = MEDIA_BUS_FMT_YUYV8_2X8, -+ .colorspace = V4L2_COLORSPACE_SRGB, -+ .data_fmt = HM5065_REG_DATA_FORMAT_YCBCR_CUSTOM, -+ .ycbcr_order = HM5065_REG_YCRCB_ORDER_Y_CB_Y_CR, -+ .fmt_setup = 0x08 -+ }, -+ { -+ .code = MEDIA_BUS_FMT_YVYU8_2X8, -+ .colorspace = V4L2_COLORSPACE_SRGB, -+ .data_fmt = HM5065_REG_DATA_FORMAT_YCBCR_CUSTOM, -+ .ycbcr_order = HM5065_REG_YCRCB_ORDER_Y_CR_Y_CB, -+ .fmt_setup = 0x08 -+ }, -+ { -+ .code = MEDIA_BUS_FMT_RGB565_2X8_LE, -+ .colorspace = V4L2_COLORSPACE_SRGB, -+ .data_fmt = HM5065_REG_DATA_FORMAT_RGB_565, -+ .ycbcr_order = HM5065_REG_YCRCB_ORDER_Y_CR_Y_CB, -+ .fmt_setup = 0x02 -+ }, -+ { -+ .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, -+ .colorspace = V4L2_COLORSPACE_SRGB, -+ .data_fmt = HM5065_REG_DATA_FORMAT_RGB_555, -+ .ycbcr_order = HM5065_REG_YCRCB_ORDER_Y_CR_Y_CB, -+ .fmt_setup = 0x02 -+ }, -+}; -+ -+#define HM5065_NUM_FORMATS ARRAY_SIZE(hm5065_formats) -+ -+static const struct hm5065_pixfmt *hm5065_find_format(u32 code) -+{ -+ int i; -+ -+ for (i = 0; i < HM5065_NUM_FORMATS; i++) -+ if (hm5065_formats[i].code == code) -+ return &hm5065_formats[i]; -+ -+ return NULL; -+} -+ -+/* regulator supplies */ -+static const char * const hm5065_supply_name[] = { -+ "IOVDD", /* Digital I/O (2.8V) suppply */ -+ "AFVDD", /* Autofocus (2.8V) supply */ -+ "DVDD", /* Digital Core (1.8V) supply */ -+ "AVDD", /* Analog (2.8V) supply */ -+}; -+ -+#define HM5065_NUM_SUPPLIES ARRAY_SIZE(hm5065_supply_name) -+ -+struct hm5065_ctrls { -+ struct v4l2_ctrl_handler handler; -+ struct { -+ struct v4l2_ctrl *auto_exposure; -+ struct v4l2_ctrl *exposure; -+ struct v4l2_ctrl *d_gain; -+ struct v4l2_ctrl *a_gain; -+ }; -+ struct v4l2_ctrl *metering; -+ struct v4l2_ctrl *exposure_bias; -+ struct { -+ struct v4l2_ctrl *wb; -+ struct v4l2_ctrl *blue_balance; -+ struct v4l2_ctrl *red_balance; -+ }; -+ struct { -+ struct v4l2_ctrl *focus_auto; -+ struct v4l2_ctrl *af_start; -+ struct v4l2_ctrl *af_stop; -+ struct v4l2_ctrl *af_status; -+ struct v4l2_ctrl *af_distance; -+ struct v4l2_ctrl *focus_relative; -+ }; -+ struct v4l2_ctrl *aaa_lock; -+ struct v4l2_ctrl *hflip; -+ struct v4l2_ctrl *vflip; -+ struct v4l2_ctrl *pl_freq; -+ struct v4l2_ctrl *colorfx; -+ struct v4l2_ctrl *brightness; -+ struct v4l2_ctrl *saturation; -+ struct v4l2_ctrl *contrast; -+ struct v4l2_ctrl *gamma; -+ struct v4l2_ctrl *test_pattern; -+ struct v4l2_ctrl *test_data[4]; -+}; -+ -+struct hm5065_dev { -+ struct i2c_client *i2c_client; -+ struct v4l2_subdev sd; -+ struct media_pad pad; -+ struct v4l2_fwnode_endpoint ep; /* the parsed DT endpoint info */ -+ struct clk *xclk; /* external clock for HM5065 */ -+ -+ struct regulator_bulk_data supplies[HM5065_NUM_SUPPLIES]; -+ struct gpio_desc *reset_gpio; // nrst pin -+ struct gpio_desc *chipenable_gpio; // ce pin -+ -+ /* lock to protect all members below */ -+ struct mutex lock; -+ -+ struct v4l2_mbus_framefmt fmt; -+ struct v4l2_fract frame_interval; -+ struct hm5065_ctrls ctrls; -+ int max_frame_rate; -+ -+ bool pending_mode_change; -+ bool powered; -+ bool streaming; -+}; -+ -+static inline struct hm5065_dev *to_hm5065_dev(struct v4l2_subdev *sd) -+{ -+ return container_of(sd, struct hm5065_dev, sd); -+} -+ -+static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl) -+{ -+ return &container_of(ctrl->handler, struct hm5065_dev, -+ ctrls.handler)->sd; -+} -+ -+/* {{{ Register access helpers */ -+ -+static int hm5065_write_regs(struct hm5065_dev *sensor, u16 start_index, -+ u8 *data, int data_size) -+{ -+ struct i2c_client *client = sensor->i2c_client; -+ struct i2c_msg msg; -+ u8 buf[data_size + 2]; -+ int ret; -+ -+ buf[0] = start_index >> 8; -+ buf[1] = start_index & 0xff; -+ memcpy(buf + 2, data, data_size); -+ -+ msg.addr = client->addr; -+ msg.flags = client->flags; -+ msg.buf = buf; -+ msg.len = data_size + 2; -+ -+ dev_dbg(&sensor->i2c_client->dev, "wr: %04x <= %*ph\n", -+ (u32)start_index, data_size, data); -+ -+ ret = i2c_transfer(client->adapter, &msg, 1); -+ if (ret < 0) { -+ v4l2_err(&sensor->sd, -+ "%s: error %d: start_index=%x, data=%*ph\n", -+ __func__, ret, (u32)start_index, data_size, data); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int hm5065_read_regs(struct hm5065_dev *sensor, u16 start_index, -+ u8 *data, int data_size) -+{ -+ struct i2c_client *client = sensor->i2c_client; -+ struct i2c_msg msg[2]; -+ u8 buf[2]; -+ int ret; -+ -+ buf[0] = start_index >> 8; -+ buf[1] = start_index & 0xff; -+ -+ msg[0].addr = client->addr; -+ msg[0].flags = client->flags; -+ msg[0].buf = buf; -+ msg[0].len = sizeof(buf); -+ -+ msg[1].addr = client->addr; -+ msg[1].flags = client->flags | I2C_M_RD; -+ msg[1].buf = data; -+ msg[1].len = data_size; -+ -+ ret = i2c_transfer(client->adapter, msg, 2); -+ if (ret < 0) { -+ v4l2_err(&sensor->sd, -+ "%s: error %d: start_index=%x, data_size=%d\n", -+ __func__, ret, (u32)start_index, data_size); -+ return ret; -+ } -+ -+ dev_dbg(&sensor->i2c_client->dev, "rd: %04x => %*ph\n", -+ (u32)start_index, data_size, data); -+ -+ return 0; -+} -+ -+static int hm5065_read(struct hm5065_dev *sensor, u16 reg, u8 *val) -+{ -+ return hm5065_read_regs(sensor, reg, val, 1); -+} -+ -+static int hm5065_write(struct hm5065_dev *sensor, u16 reg, u8 val) -+{ -+ return hm5065_write_regs(sensor, reg, &val, 1); -+} -+ -+static int hm5065_read16(struct hm5065_dev *sensor, u16 reg, u16 *val) -+{ -+ int ret; -+ -+ ret = hm5065_read_regs(sensor, reg, (u8 *)val, sizeof(*val)); -+ if (ret) -+ return ret; -+ -+ *val = be16_to_cpu(*val); -+ return 0; -+} -+ -+static int hm5065_write16(struct hm5065_dev *sensor, u16 reg, u16 val) -+{ -+ u16 tmp = cpu_to_be16(val); -+ -+ return hm5065_write_regs(sensor, reg, (u8 *)&tmp, sizeof(tmp)); -+} -+ -+/* -+ * The firmware format: -+ * , ..., -+ * "record" is a 2-byte register address (big endian) followed by 1-byte data -+ */ -+static int hm5065_load_firmware(struct hm5065_dev *sensor, const char *name) -+{ -+ int ret = 0, i = 0, list_size; -+ const struct firmware *fw; -+ struct reg_value *list; -+ u16 start, len; -+ u8 buf[128]; -+ -+ ret = request_firmware(&fw, name, sensor->sd.v4l2_dev->dev); -+ if (ret) { -+ v4l2_warn(&sensor->sd, -+ "Failed to read firmware %s, continuing anyway...\n", -+ name); -+ return 1; -+ } -+ -+ if (fw->size == 0) -+ return 1; -+ -+ if (fw->size % 3 != 0) { -+ v4l2_err(&sensor->sd, "Firmware image %s has invalid size\n", -+ name); -+ ret = -EINVAL; -+ goto err_release; -+ } -+ -+ list_size = fw->size / 3; -+ list = (struct reg_value *)fw->data; -+ -+ /* we speed up I2C communication via auto-increment functionality */ -+ while (i < list_size) { -+ start = be16_to_cpu(list[i].addr); -+ len = 0; -+ -+ while (i < list_size && -+ be16_to_cpu(list[i].addr) == (start + len) && -+ len < sizeof(buf)) -+ buf[len++] = list[i++].value; -+ -+ ret = hm5065_write_regs(sensor, start, buf, len); -+ if (ret) -+ goto err_release; -+ } -+ -+err_release: -+ release_firmware(fw); -+ return ret; -+} -+ -+/* -+ * Sensor uses ST Float900 format to represent floating point numbers. -+ * Binary floating point number: * (s ? -1 : 0) * 1.mmmmmmmmm * 2^eeeeee -+ * -+ * Following functions convert long value to and from the floating point format. -+ * -+ * Example: -+ * mili variant: val = 123456 => fp_val = 123.456 -+ * micro variant: val = -12345678 => fp_val = -12.345678 -+ */ -+static s64 hm5065_mili_from_fp16(u16 fp_val) -+{ -+ s64 val; -+ s64 mantisa = fp_val & 0x1ff; -+ int exp = (int)((fp_val >> 9) & 0x3f) - 31; -+ -+ val = (1000 * (mantisa | 0x200)); -+ if (exp > 0) -+ val <<= exp; -+ else if (exp < 0) -+ val >>= -exp; -+ val >>= 9; -+ -+ if (fp_val & 0x8000) -+ val = -val; -+ -+ return val; -+} -+ -+static u16 hm5065_mili_to_fp16(s32 val) -+{ -+ int fls; -+ u16 e, m, s = 0; -+ u64 v, rem; -+ -+ if (val == 0) -+ return 0; -+ -+ if (val < 0) { -+ val = -val; -+ s = 0x8000; -+ } -+ -+ v = (u64)val * 1024; -+ rem = do_div(v, 1000); -+ if (rem >= 500) -+ v++; -+ -+ fls = fls64(v) - 1; -+ e = 31 + fls - 10; -+ m = fls > 9 ? v >> (fls - 9) : v << (9 - fls); -+ -+ return s | (m & 0x1ff) | (e << 9); -+} -+ -+/* }}} */ -+/* {{{ Controls */ -+ -+static int hm5065_get_af_status(struct hm5065_dev *sensor) -+{ -+ struct hm5065_ctrls *ctrls = &sensor->ctrls; -+ u8 is_stable, mode; -+ int ret; -+ -+ ret = hm5065_read(sensor, HM5065_REG_AF_MODE_STATUS, &mode); -+ if (ret) -+ return ret; -+ -+ if (mode == HM5065_REG_AF_MODE_MANUAL) { -+ ctrls->af_status->val = V4L2_AUTO_FOCUS_STATUS_IDLE; -+ return 0; -+ } -+ -+ ret = hm5065_read(sensor, HM5065_REG_AF_IS_STABLE, &is_stable); -+ if (ret) -+ return ret; -+ -+ if (is_stable) -+ ctrls->af_status->val = V4L2_AUTO_FOCUS_STATUS_REACHED; -+ else if (!is_stable && mode == HM5065_REG_AF_MODE_CONTINUOUS) -+ ctrls->af_status->val = V4L2_AUTO_FOCUS_STATUS_BUSY; -+ else -+ ctrls->af_status->val = V4L2_AUTO_FOCUS_STATUS_IDLE; -+ -+ return 0; -+} -+ -+static int hm5065_get_exposure(struct hm5065_dev *sensor) -+{ -+ struct hm5065_ctrls *ctrls = &sensor->ctrls; -+ u16 again, dgain, exp; -+ int ret; -+ -+ ret = hm5065_read16(sensor, HM5065_REG_CODED_ANALOG_GAIN_PENDING, -+ &again); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_read16(sensor, HM5065_REG_DIGITAL_GAIN_PENDING, &dgain); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_read16(sensor, HM5065_REG_COARSE_INTEGRATION, &exp); -+ if (ret) -+ return ret; -+ -+ ctrls->exposure->val = exp; -+ ctrls->d_gain->val = clamp(hm5065_mili_from_fp16(dgain), 1000ll, -+ 4000ll); -+ ctrls->a_gain->val = again; -+ -+ return 0; -+} -+ -+static int hm5065_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -+{ -+ struct v4l2_subdev *sd = ctrl_to_sd(ctrl); -+ struct hm5065_dev *sensor = to_hm5065_dev(sd); -+ int ret; -+ -+ /* v4l2_ctrl_lock() locks our own mutex */ -+ -+ if (!sensor->powered) -+ return -EIO; -+ -+ switch (ctrl->id) { -+ case V4L2_CID_FOCUS_AUTO: -+ ret = hm5065_get_af_status(sensor); -+ if (ret) -+ return ret; -+ break; -+ case V4L2_CID_EXPOSURE_AUTO: -+ ret = hm5065_get_exposure(sensor); -+ if (ret) -+ return ret; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static const u8 hm5065_wb_opts[][2] = { -+ { V4L2_WHITE_BALANCE_MANUAL, HM5065_REG_WB_MODE_OFF }, -+ { V4L2_WHITE_BALANCE_INCANDESCENT, HM5065_REG_WB_MODE_TUNGSTEN_PRESET }, -+ { V4L2_WHITE_BALANCE_FLUORESCENT, -+ HM5065_REG_WB_MODE_FLUORESCENT_PRESET }, -+ { V4L2_WHITE_BALANCE_HORIZON, HM5065_REG_WB_MODE_HORIZON_PRESET }, -+ { V4L2_WHITE_BALANCE_CLOUDY, HM5065_REG_WB_MODE_CLOUDY_PRESET }, -+ { V4L2_WHITE_BALANCE_DAYLIGHT, HM5065_REG_WB_MODE_SUNNY_PRESET }, -+ { V4L2_WHITE_BALANCE_AUTO, HM5065_REG_WB_MODE_AUTOMATIC }, -+}; -+ -+static int hm5065_set_power_line_frequency(struct hm5065_dev *sensor, s32 val) -+{ -+ u16 freq; -+ int ret; -+ -+ switch (val) { -+ case V4L2_CID_POWER_LINE_FREQUENCY_DISABLED: -+ ret = hm5065_write(sensor, HM5065_REG_ANTI_FLICKER_MODE, 0); -+ if (ret) -+ return ret; -+ -+ return hm5065_write(sensor, HM5065_REG_FD_ENABLE_DETECT, 0); -+ case V4L2_CID_POWER_LINE_FREQUENCY_50HZ: -+ case V4L2_CID_POWER_LINE_FREQUENCY_60HZ: -+ ret = hm5065_write(sensor, HM5065_REG_ANTI_FLICKER_MODE, 1); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write(sensor, HM5065_REG_FD_ENABLE_DETECT, 0); -+ if (ret) -+ return ret; -+ -+ freq = (val == V4L2_CID_POWER_LINE_FREQUENCY_50HZ) ? -+ 0x4b20 : 0x4bc0; -+ -+ return hm5065_write16(sensor, HM5065_REG_FD_FLICKER_FREQUENCY, -+ freq); -+ case V4L2_CID_POWER_LINE_FREQUENCY_AUTO: -+ ret = hm5065_write(sensor, HM5065_REG_FD_ENABLE_DETECT, 1); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write(sensor, HM5065_REG_ANTI_FLICKER_MODE, 1); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write16(sensor, HM5065_REG_FD_MAX_NUMBER_ATTEMP, -+ 100); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write16(sensor, HM5065_REG_FD_FLICKER_FREQUENCY, -+ 0); -+ if (ret) -+ return ret; -+ -+ return hm5065_write(sensor, HM5065_REG_FD_DETECTION_START, 1); -+ default: -+ return -EINVAL; -+ } -+} -+ -+static int hm5065_set_colorfx(struct hm5065_dev *sensor, s32 val) -+{ -+ int ret; -+ -+ ret = hm5065_write(sensor, HM5065_REG_EFFECTS_COLOR, -+ HM5065_REG_EFFECTS_COLOR_NORMAL); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write(sensor, HM5065_REG_EFFECTS_NEGATIVE, 0); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write(sensor, HM5065_REG_EFFECTS_SOLARISING, 0); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write(sensor, HM5065_REG_EFFECTS_SKECTH, 0); -+ if (ret) -+ return ret; -+ -+ switch (val) { -+ case V4L2_COLORFX_NONE: -+ return 0; -+ case V4L2_COLORFX_NEGATIVE: -+ return hm5065_write(sensor, HM5065_REG_EFFECTS_NEGATIVE, 1); -+ case V4L2_COLORFX_SOLARIZATION: -+ return hm5065_write(sensor, HM5065_REG_EFFECTS_SOLARISING, 1); -+ case V4L2_COLORFX_SKETCH: -+ return hm5065_write(sensor, HM5065_REG_EFFECTS_SKECTH, 1); -+ case V4L2_COLORFX_ANTIQUE: -+ return hm5065_write(sensor, HM5065_REG_EFFECTS_COLOR, -+ HM5065_REG_EFFECTS_COLOR_ANTIQUE); -+ case V4L2_COLORFX_SEPIA: -+ return hm5065_write(sensor, HM5065_REG_EFFECTS_COLOR, -+ HM5065_REG_EFFECTS_COLOR_SEPIA); -+ case V4L2_COLORFX_AQUA: -+ return hm5065_write(sensor, HM5065_REG_EFFECTS_COLOR, -+ HM5065_REG_EFFECTS_COLOR_AQUA); -+ case V4L2_COLORFX_BW: -+ return hm5065_write(sensor, HM5065_REG_EFFECTS_COLOR, -+ HM5065_REG_EFFECTS_COLOR_BLACK_WHITE); -+ default: -+ return -EINVAL; -+ } -+} -+ -+#define AE_BIAS_MENU_DEFAULT_VALUE_INDEX 7 -+static const s64 ae_bias_menu_values[] = { -+ -2100, -1800, -1500, -1200, -900, -600, -300, -+ 0, 300, 600, 900, 1200, 1500, 1800, 2100 -+}; -+ -+static const s8 ae_bias_menu_reg_values[] = { -+ -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7 -+}; -+ -+static int hm5065_set_exposure(struct hm5065_dev *sensor) -+{ -+ struct hm5065_ctrls *ctrls = &sensor->ctrls; -+ bool is_auto = (ctrls->auto_exposure->val != V4L2_EXPOSURE_MANUAL); -+ int ret = 0; -+ -+ if (ctrls->auto_exposure->is_new) { -+ ret = hm5065_write(sensor, HM5065_REG_EXPOSURE_MODE, -+ is_auto ? -+ HM5065_REG_EXPOSURE_MODE_AUTO : -+ HM5065_REG_EXPOSURE_MODE_DIRECT_MANUAL); -+ if (ret) -+ return ret; -+ -+ if (ctrls->auto_exposure->cur.val != ctrls->auto_exposure->val && -+ !is_auto) { -+ /* -+ * Hack: At this point, there are current volatile -+ * values in val, but control framework will not -+ * update the cur values for our autocluster, as it -+ * should. I couldn't find the reason. This fixes -+ * it for our driver. Remove this after the kernel -+ * is fixed. -+ */ -+ ctrls->exposure->cur.val = ctrls->exposure->val; -+ ctrls->d_gain->cur.val = ctrls->d_gain->val; -+ ctrls->a_gain->cur.val = ctrls->a_gain->val; -+ } -+ } -+ -+ if (!is_auto && ctrls->exposure->is_new) { -+ ret = hm5065_write16(sensor, -+ HM5065_REG_DIRECT_MODE_COARSE_INTEGRATION_LINES, -+ ctrls->exposure->val); -+ if (ret) -+ return ret; -+ } -+ -+ if (!is_auto && ctrls->d_gain->is_new) { -+ ret = hm5065_write16(sensor, -+ HM5065_REG_DIRECT_MODE_DIGITAL_GAIN, -+ hm5065_mili_to_fp16(ctrls->d_gain->val)); -+ if (ret) -+ return ret; -+ } -+ -+ if (!is_auto && ctrls->a_gain->is_new) -+ ret = hm5065_write16(sensor, -+ HM5065_REG_DIRECT_MODE_CODED_ANALOG_GAIN, -+ ctrls->a_gain->val); -+ -+ return ret; -+} -+ -+static int hm5065_3a_lock(struct hm5065_dev *sensor, struct v4l2_ctrl *ctrl) -+{ -+ bool awb_lock = ctrl->val & V4L2_LOCK_WHITE_BALANCE; -+ bool ae_lock = ctrl->val & V4L2_LOCK_EXPOSURE; -+ int ret = 0; -+ -+ if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_EXPOSURE -+ && sensor->ctrls.auto_exposure->val == V4L2_EXPOSURE_AUTO) { -+ ret = hm5065_write(sensor, HM5065_REG_FREEZE_AUTO_EXPOSURE, -+ ae_lock); -+ if (ret) -+ return ret; -+ } -+ -+ if (((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_WHITE_BALANCE) -+ && sensor->ctrls.wb->val == V4L2_WHITE_BALANCE_AUTO) { -+ ret = hm5065_write(sensor, HM5065_REG_WB_MISC_SETTINGS, -+ awb_lock ? -+ HM5065_REG_WB_MISC_SETTINGS_FREEZE_ALGO : 0); -+ if (ret) -+ return ret; -+ } -+ -+ return ret; -+} -+ -+static int hm5065_set_auto_focus(struct hm5065_dev *sensor) -+{ -+ struct hm5065_ctrls *ctrls = &sensor->ctrls; -+ bool auto_focus = ctrls->focus_auto->val; -+ int ret = 0; -+ u8 range; -+ -+ if (auto_focus && ctrls->af_distance->is_new) { -+ switch (ctrls->af_distance->val) { -+ case V4L2_AUTO_FOCUS_RANGE_MACRO: -+ range = HM5065_REG_AF_RANGE_MACRO; -+ break; -+ case V4L2_AUTO_FOCUS_RANGE_AUTO: -+ range = HM5065_REG_AF_RANGE_FULL; -+ break; -+ case V4L2_AUTO_FOCUS_RANGE_INFINITY: -+ range = HM5065_REG_AF_RANGE_LANDSCAPE; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ ret = hm5065_write(sensor, HM5065_REG_AF_RANGE, range); -+ if (ret) -+ return ret; -+ } -+ -+ if (ctrls->focus_auto->is_new) { -+ v4l2_ctrl_activate(ctrls->af_start, !auto_focus); -+ v4l2_ctrl_activate(ctrls->af_stop, !auto_focus); -+ v4l2_ctrl_activate(ctrls->focus_relative, !auto_focus); -+ -+ ret = hm5065_write(sensor, HM5065_REG_AF_MODE, -+ auto_focus ? -+ HM5065_REG_AF_MODE_CONTINUOUS : -+ HM5065_REG_AF_MODE_SINGLE); -+ if (ret) -+ return ret; -+ -+ if (!auto_focus) { -+ ret = hm5065_write(sensor, HM5065_REG_AF_COMMAND, -+ HM5065_REG_AF_COMMAND_RELEASED_BUTTON); -+ if (ret) -+ return ret; -+ } -+ } -+ -+ if (!auto_focus && ctrls->af_start->is_new) { -+ ret = hm5065_write(sensor, HM5065_REG_AF_MODE, -+ HM5065_REG_AF_MODE_SINGLE); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write(sensor, HM5065_REG_AF_COMMAND, -+ HM5065_REG_AF_COMMAND_RELEASED_BUTTON); -+ if (ret) -+ return ret; -+ -+ usleep_range(190000, 200000); -+ -+ ret = hm5065_write(sensor, HM5065_REG_AF_COMMAND, -+ HM5065_REG_AF_COMMAND_HALF_BUTTON); -+ if (ret) -+ return ret; -+ } -+ -+ if (!auto_focus && ctrls->af_stop->is_new) { -+ ret = hm5065_write(sensor, HM5065_REG_AF_COMMAND, -+ HM5065_REG_AF_COMMAND_RELEASED_BUTTON); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write(sensor, HM5065_REG_AF_MODE, -+ HM5065_REG_AF_MODE_MANUAL); -+ if (ret) -+ return ret; -+ } -+ -+ if (!auto_focus && ctrls->focus_relative->is_new && -+ ctrls->focus_relative->val) { -+ u8 cmd = 0xff; -+ s32 step = ctrls->focus_relative->val; -+ -+ ctrls->focus_relative->val = 0; -+ -+ ret = hm5065_write(sensor, HM5065_REG_AF_MODE, -+ HM5065_REG_AF_MODE_MANUAL); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write(sensor, HM5065_REG_AF_MANUAL_STEP_SIZE, -+ abs(step)); -+ if (ret) -+ return ret; -+ -+ if (step < 0) -+ cmd = HM5065_REG_AF_LENS_COMMAND_MOVE_STEP_TO_INFINITY; -+ else if (step > 0) -+ cmd = HM5065_REG_AF_LENS_COMMAND_MOVE_STEP_TO_MACRO; -+ -+ if (cmd != 0xff) -+ ret = hm5065_write(sensor, HM5065_REG_AF_LENS_COMMAND, -+ cmd); -+ -+ if (ret) -+ return ret; -+ } -+ -+ return ret; -+} -+ -+static int hm5065_set_white_balance(struct hm5065_dev *sensor) -+{ -+ struct hm5065_ctrls *ctrls = &sensor->ctrls; -+ bool manual_wb = ctrls->wb->val == V4L2_WHITE_BALANCE_MANUAL; -+ int ret = 0, i; -+ s32 val; -+ -+ if (ctrls->wb->is_new) { -+ for (i = 0; i < ARRAY_SIZE(hm5065_wb_opts); i++) { -+ if (hm5065_wb_opts[i][0] != ctrls->wb->val) -+ continue; -+ -+ ret = hm5065_write(sensor, HM5065_REG_WB_MODE, -+ hm5065_wb_opts[i][1]); -+ if (ret) -+ return ret; -+ goto next; -+ } -+ -+ return -EINVAL; -+ } -+ -+next: -+ if (ctrls->wb->is_new || ctrls->blue_balance->is_new) { -+ val = manual_wb ? ctrls->blue_balance->val : 1000; -+ ret = hm5065_write16(sensor, HM5065_REG_WB_HUE_B_BIAS, -+ hm5065_mili_to_fp16(val)); -+ if (ret) -+ return ret; -+ } -+ -+ if (ctrls->wb->is_new || ctrls->red_balance->is_new) { -+ val = manual_wb ? ctrls->red_balance->val : 1000; -+ ret = hm5065_write16(sensor, HM5065_REG_WB_HUE_R_BIAS, -+ hm5065_mili_to_fp16(val)); -+ } -+ -+ return ret; -+} -+ -+static int hm5065_s_ctrl(struct v4l2_ctrl *ctrl) -+{ -+ struct v4l2_subdev *sd = ctrl_to_sd(ctrl); -+ struct hm5065_dev *sensor = to_hm5065_dev(sd); -+ struct hm5065_ctrls *ctrls = &sensor->ctrls; -+ s32 val = ctrl->val; -+ unsigned int i; -+ int ret; -+ u8 reg; -+ -+ /* v4l2_ctrl_lock() locks our own mutex */ -+ -+ /* -+ * If the device is not powered up by the host driver do -+ * not apply any controls to H/W at this time. Instead -+ * the controls will be restored right after power-up. -+ */ -+ if (!sensor->powered) -+ return 0; -+ -+ switch (ctrl->id) { -+ case V4L2_CID_EXPOSURE_AUTO: -+ return hm5065_set_exposure(sensor); -+ -+ case V4L2_CID_EXPOSURE_METERING: -+ if (val == V4L2_EXPOSURE_METERING_AVERAGE) -+ reg = HM5065_REG_EXPOSURE_METERING_FLAT; -+ else if (val == V4L2_EXPOSURE_METERING_CENTER_WEIGHTED) -+ reg = HM5065_REG_EXPOSURE_METERING_CENTERED; -+ else -+ return -EINVAL; -+ -+ return hm5065_write(sensor, HM5065_REG_EXPOSURE_METERING, reg); -+ -+ case V4L2_CID_AUTO_EXPOSURE_BIAS: -+ if (val < 0 || val >= ARRAY_SIZE(ae_bias_menu_reg_values)) -+ return -EINVAL; -+ -+ return hm5065_write(sensor, HM5065_REG_EXPOSURE_COMPENSATION, -+ (u8)ae_bias_menu_reg_values[val]); -+ -+ case V4L2_CID_FOCUS_AUTO: -+ return hm5065_set_auto_focus(sensor); -+ -+ case V4L2_CID_CONTRAST: -+ return hm5065_write(sensor, HM5065_REG_CONTRAST, val); -+ -+ case V4L2_CID_SATURATION: -+ return hm5065_write(sensor, HM5065_REG_COLOR_SATURATION, val); -+ -+ case V4L2_CID_BRIGHTNESS: -+ return hm5065_write(sensor, HM5065_REG_BRIGHTNESS, val); -+ -+ case V4L2_CID_POWER_LINE_FREQUENCY: -+ return hm5065_set_power_line_frequency(sensor, val); -+ -+ case V4L2_CID_GAMMA: -+ return hm5065_write(sensor, HM5065_REG_P0_GAMMA_GAIN, val); -+ -+ case V4L2_CID_VFLIP: -+ return hm5065_write(sensor, HM5065_REG_VERTICAL_FLIP, -+ val ? 1 : 0); -+ -+ case V4L2_CID_HFLIP: -+ return hm5065_write(sensor, HM5065_REG_HORIZONTAL_MIRROR, -+ val ? 1 : 0); -+ -+ case V4L2_CID_COLORFX: -+ return hm5065_set_colorfx(sensor, val); -+ -+ case V4L2_CID_3A_LOCK: -+ return hm5065_3a_lock(sensor, ctrl); -+ -+ case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: -+ return hm5065_set_white_balance(sensor); -+ -+ case V4L2_CID_TEST_PATTERN_RED: -+ return hm5065_write16(sensor, HM5065_REG_TESTDATA_RED, val); -+ -+ case V4L2_CID_TEST_PATTERN_GREENR: -+ return hm5065_write16(sensor, HM5065_REG_TESTDATA_GREEN_R, val); -+ -+ case V4L2_CID_TEST_PATTERN_BLUE: -+ return hm5065_write16(sensor, HM5065_REG_TESTDATA_BLUE, val); -+ -+ case V4L2_CID_TEST_PATTERN_GREENB: -+ return hm5065_write16(sensor, HM5065_REG_TESTDATA_GREEN_B, val); -+ -+ case V4L2_CID_TEST_PATTERN: -+ for (i = 0; i < ARRAY_SIZE(ctrls->test_data); i++) -+ v4l2_ctrl_activate(ctrls->test_data[i], -+ val == 6); /* solid color */ -+ -+ ret = hm5065_write(sensor, HM5065_REG_ENABLE_TEST_PATTERN, -+ val == 0 ? 0 : 1); -+ if (ret) -+ return ret; -+ -+ return hm5065_write(sensor, HM5065_REG_TEST_PATTERN, val); -+ -+ default: -+ return -EINVAL; -+ } -+} -+ -+static const struct v4l2_ctrl_ops hm5065_ctrl_ops = { -+ .g_volatile_ctrl = hm5065_g_volatile_ctrl, -+ .s_ctrl = hm5065_s_ctrl, -+}; -+ -+static const char * const test_pattern_menu[] = { -+ "Disabled", -+ "Horizontal gray scale", -+ "Vertical gray scale", -+ "Diagonal gray scale", -+ "PN28", -+ "PN9 (bus test)", -+ "Solid color", -+ "Color bars", -+ "Graduated color bars", -+}; -+ -+static int hm5065_init_controls(struct hm5065_dev *sensor) -+{ -+ const struct v4l2_ctrl_ops *ops = &hm5065_ctrl_ops; -+ struct hm5065_ctrls *ctrls = &sensor->ctrls; -+ struct v4l2_ctrl_handler *hdl = &ctrls->handler; -+ u8 wb_max = 0; -+ u64 wb_mask = 0; -+ unsigned int i; -+ int ret; -+ -+ v4l2_ctrl_handler_init(hdl, 32); -+ -+ /* we can use our own mutex for the ctrl lock */ -+ hdl->lock = &sensor->lock; -+ -+ ctrls->auto_exposure = v4l2_ctrl_new_std_menu(hdl, ops, -+ V4L2_CID_EXPOSURE_AUTO, -+ V4L2_EXPOSURE_MANUAL, 0, -+ V4L2_EXPOSURE_AUTO); -+ ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, -+ V4L2_CID_EXPOSURE, -+ 1, HM5065_SENSOR_HEIGHT, 1, 30); -+ ctrls->d_gain = v4l2_ctrl_new_std(hdl, ops, -+ V4L2_CID_DIGITAL_GAIN, -+ 1000, 4000, 1, 1000); -+ -+ ctrls->a_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN, -+ 0, 0xf4, 1, 0); -+ -+ ctrls->metering = -+ v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_EXPOSURE_METERING, -+ V4L2_EXPOSURE_METERING_CENTER_WEIGHTED, -+ 0, V4L2_EXPOSURE_METERING_AVERAGE); -+ ctrls->exposure_bias = -+ v4l2_ctrl_new_int_menu(hdl, ops, -+ V4L2_CID_AUTO_EXPOSURE_BIAS, -+ ARRAY_SIZE(ae_bias_menu_values) - 1, -+ AE_BIAS_MENU_DEFAULT_VALUE_INDEX, -+ ae_bias_menu_values); -+ -+ for (i = 0; i < ARRAY_SIZE(hm5065_wb_opts); i++) { -+ if (wb_max < hm5065_wb_opts[i][0]) -+ wb_max = hm5065_wb_opts[i][0]; -+ wb_mask |= BIT(hm5065_wb_opts[i][0]); -+ } -+ -+ ctrls->wb = v4l2_ctrl_new_std_menu(hdl, ops, -+ V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE, -+ wb_max, ~wb_mask, V4L2_WHITE_BALANCE_AUTO); -+ -+ ctrls->blue_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BLUE_BALANCE, -+ 0, 4000, 1, 1000); -+ ctrls->red_balance = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_RED_BALANCE, -+ 0, 4000, 1, 1000); -+ -+ ctrls->gamma = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAMMA, -+ 0, 31, 1, 20); -+ -+ ctrls->colorfx = -+ v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_COLORFX, 15, -+ ~(BIT(V4L2_COLORFX_NONE) | -+ BIT(V4L2_COLORFX_NEGATIVE) | -+ BIT(V4L2_COLORFX_SOLARIZATION) | -+ BIT(V4L2_COLORFX_SKETCH) | -+ BIT(V4L2_COLORFX_SEPIA) | -+ BIT(V4L2_COLORFX_ANTIQUE) | -+ BIT(V4L2_COLORFX_AQUA) | -+ BIT(V4L2_COLORFX_BW)), -+ V4L2_COLORFX_NONE); -+ -+ ctrls->pl_freq = -+ v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_POWER_LINE_FREQUENCY, -+ V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0, -+ V4L2_CID_POWER_LINE_FREQUENCY_50HZ); -+ -+ ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, -+ V4L2_CID_HFLIP, 0, 1, 1, 0); -+ ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, -+ V4L2_CID_VFLIP, 0, 1, 1, 0); -+ -+ ctrls->focus_auto = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_AUTO, -+ 0, 1, 1, 1); -+ -+ ctrls->af_start = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_FOCUS_START, -+ 0, 1, 1, 0); -+ -+ ctrls->af_stop = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_FOCUS_STOP, -+ 0, 1, 1, 0); -+ -+ ctrls->af_status = v4l2_ctrl_new_std(hdl, ops, -+ V4L2_CID_AUTO_FOCUS_STATUS, 0, -+ (V4L2_AUTO_FOCUS_STATUS_BUSY | -+ V4L2_AUTO_FOCUS_STATUS_REACHED | -+ V4L2_AUTO_FOCUS_STATUS_FAILED), -+ 0, V4L2_AUTO_FOCUS_STATUS_IDLE); -+ -+ ctrls->af_distance = -+ v4l2_ctrl_new_std_menu(hdl, ops, -+ V4L2_CID_AUTO_FOCUS_RANGE, -+ V4L2_AUTO_FOCUS_RANGE_MACRO, -+ ~(BIT(V4L2_AUTO_FOCUS_RANGE_AUTO) | -+ BIT(V4L2_AUTO_FOCUS_RANGE_INFINITY) | -+ BIT(V4L2_AUTO_FOCUS_RANGE_MACRO)), -+ V4L2_AUTO_FOCUS_RANGE_AUTO); -+ -+ ctrls->focus_relative = v4l2_ctrl_new_std(hdl, ops, -+ V4L2_CID_FOCUS_RELATIVE, -+ -100, 100, 1, 0); -+ -+ ctrls->brightness = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -+ 0, 200, 1, 90); -+ ctrls->saturation = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, -+ 0, 200, 1, 110); -+ ctrls->contrast = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -+ 0, 200, 1, 108); -+ -+ ctrls->aaa_lock = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_3A_LOCK, -+ 0, 0x7, 0, 0); -+ -+ ctrls->test_pattern = -+ v4l2_ctrl_new_std_menu_items(hdl, ops, V4L2_CID_TEST_PATTERN, -+ ARRAY_SIZE(test_pattern_menu) - 1, -+ 0, 0, test_pattern_menu); -+ for (i = 0; i < ARRAY_SIZE(ctrls->test_data); i++) -+ ctrls->test_data[i] = -+ v4l2_ctrl_new_std(hdl, ops, -+ V4L2_CID_TEST_PATTERN_RED + i, -+ 0, 1023, 1, 0); -+ -+ if (hdl->error) { -+ ret = hdl->error; -+ goto free_ctrls; -+ } -+ -+ ctrls->af_status->flags |= V4L2_CTRL_FLAG_VOLATILE | -+ V4L2_CTRL_FLAG_READ_ONLY; -+ -+ v4l2_ctrl_auto_cluster(3, &ctrls->wb, V4L2_WHITE_BALANCE_MANUAL, false); -+ v4l2_ctrl_auto_cluster(4, &ctrls->auto_exposure, V4L2_EXPOSURE_MANUAL, -+ true); -+ v4l2_ctrl_cluster(6, &ctrls->focus_auto); -+ -+ sensor->sd.ctrl_handler = hdl; -+ return 0; -+ -+free_ctrls: -+ v4l2_ctrl_handler_free(hdl); -+ return ret; -+} -+ -+/* }}} */ -+/* {{{ Video ops */ -+ -+static int hm5065_g_frame_interval(struct v4l2_subdev *sd, -+ struct v4l2_subdev_frame_interval *fi) -+{ -+ struct hm5065_dev *sensor = to_hm5065_dev(sd); -+ -+ if (fi->pad != 0) -+ return -EINVAL; -+ -+ mutex_lock(&sensor->lock); -+ fi->interval = sensor->frame_interval; -+ mutex_unlock(&sensor->lock); -+ -+ return 0; -+} -+ -+static int hm5065_s_frame_interval(struct v4l2_subdev *sd, -+ struct v4l2_subdev_frame_interval *fi) -+{ -+ struct hm5065_dev *sensor = to_hm5065_dev(sd); -+ int ret = 0, fps; -+ -+ if (fi->pad != 0) -+ return -EINVAL; -+ -+ mutex_lock(&sensor->lock); -+ -+ /* user requested infinite frame rate */ -+ if (fi->interval.numerator == 0) -+ fps = sensor->max_frame_rate; -+ else -+ fps = DIV_ROUND_CLOSEST(fi->interval.denominator, -+ fi->interval.numerator); -+ -+ fps = clamp(fps, 1, sensor->max_frame_rate); -+ -+ sensor->frame_interval.numerator = 1; -+ sensor->frame_interval.denominator = fps; -+ fi->interval = sensor->frame_interval; -+ -+ if (sensor->streaming) { -+ ret = hm5065_write16(sensor, HM5065_REG_DESIRED_FRAME_RATE_NUM, -+ fps); -+ if (ret) -+ goto err_unlock; -+ -+ ret = hm5065_write(sensor, HM5065_REG_DESIRED_FRAME_RATE_DEN, -+ 1); -+ if (ret) -+ goto err_unlock; -+ } -+ -+err_unlock: -+ mutex_unlock(&sensor->lock); -+ return ret; -+} -+ -+static int hm5065_get_max_binning(int width, int height) -+{ -+ if (width < HM5065_SENSOR_WIDTH / 4 && -+ height < HM5065_SENSOR_HEIGHT / 4) -+ return 4; -+ else if (width < HM5065_SENSOR_WIDTH / 2 && -+ height < HM5065_SENSOR_HEIGHT / 2) -+ return 2; -+ -+ return 1; -+} -+ -+static int hm5065_setup_mode(struct hm5065_dev *sensor) -+{ -+ int ret; -+ const struct hm5065_pixfmt *pix_fmt; -+ u8 sensor_mode; -+ -+ pix_fmt = hm5065_find_format(sensor->fmt.code); -+ if (!pix_fmt) { -+ dev_err(&sensor->i2c_client->dev, -+ "pixel format not supported %u\n", sensor->fmt.code); -+ return -EINVAL; -+ } -+ -+ ret = hm5065_write(sensor, HM5065_REG_USER_COMMAND, -+ HM5065_REG_USER_COMMAND_POWEROFF); -+ if (ret) -+ return ret; -+ -+ switch (hm5065_get_max_binning(sensor->fmt.width, sensor->fmt.height)) { -+ case 4: -+ sensor_mode = HM5065_REG_SENSOR_MODE_BINNING_4X4; -+ break; -+ case 2: -+ sensor_mode = HM5065_REG_SENSOR_MODE_BINNING_2X2; -+ break; -+ default: -+ sensor_mode = HM5065_REG_SENSOR_MODE_FULLSIZE; -+ } -+ -+ ret = hm5065_write(sensor, HM5065_REG_P0_SENSOR_MODE, sensor_mode); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write16(sensor, HM5065_REG_P0_MANUAL_HSIZE, -+ sensor->fmt.width); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write16(sensor, HM5065_REG_P0_MANUAL_VSIZE, -+ sensor->fmt.height); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write(sensor, HM5065_REG_P0_IMAGE_SIZE, -+ HM5065_REG_IMAGE_SIZE_MANUAL); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write(sensor, HM5065_REG_P0_DATA_FORMAT, -+ pix_fmt->data_fmt); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write(sensor, HM5065_REG_YCRCB_ORDER, -+ pix_fmt->ycbcr_order); -+ if (ret) -+ return ret; -+ -+ /* without this, brightness, contrast and saturation will not work */ -+ ret = hm5065_write(sensor, 0x5200, 9); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write(sensor, HM5065_REG_BUS_DATA_FORMAT, -+ pix_fmt->fmt_setup); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write16(sensor, HM5065_REG_DESIRED_FRAME_RATE_NUM, -+ sensor->frame_interval.denominator); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_write(sensor, HM5065_REG_DESIRED_FRAME_RATE_DEN, -+ 1); -+ if (ret) -+ return ret; -+ -+ return 0; -+} -+ -+static int hm5065_set_stream(struct hm5065_dev *sensor, int enable) -+{ -+ return hm5065_write(sensor, HM5065_REG_USER_COMMAND, enable ? -+ HM5065_REG_USER_COMMAND_RUN : -+ HM5065_REG_USER_COMMAND_STOP); -+} -+ -+static int hm5065_s_stream(struct v4l2_subdev *sd, int enable) -+{ -+ struct hm5065_dev *sensor = to_hm5065_dev(sd); -+ int ret = 0; -+ -+ mutex_lock(&sensor->lock); -+ -+ if (sensor->streaming == !enable) { -+ if (enable && sensor->pending_mode_change) { -+ ret = hm5065_setup_mode(sensor); -+ if (ret) -+ goto out; -+ } -+ -+ ret = hm5065_set_stream(sensor, enable); -+ if (ret) -+ goto out; -+ -+ if (enable && sensor->ctrls.focus_auto->cur.val) { -+ msleep(100); -+ -+ /* checking error here is not super important */ -+ hm5065_write(sensor, HM5065_REG_AF_MODE, -+ HM5065_REG_AF_MODE_CONTINUOUS); -+ } -+ -+ sensor->streaming = !!enable; -+ } -+ -+out: -+ mutex_unlock(&sensor->lock); -+ return ret; -+} -+ -+/* }}} */ -+/* {{{ Pad ops */ -+ -+static int hm5065_enum_mbus_code(struct v4l2_subdev *sd, -+ struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_mbus_code_enum *code) -+{ -+ if (code->pad != 0) -+ return -EINVAL; -+ if (code->index >= HM5065_NUM_FORMATS) -+ return -EINVAL; -+ -+ code->code = hm5065_formats[code->index].code; -+ -+ return 0; -+} -+ -+static int hm5065_enum_frame_size(struct v4l2_subdev *sd, -+ struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_frame_size_enum *fse) -+{ -+ if (fse->pad != 0) -+ return -EINVAL; -+ if (fse->index >= HM5065_NUM_FRAME_SIZES * 2) -+ return -EINVAL; -+ -+ if (fse->index < HM5065_NUM_FRAME_SIZES) { -+ fse->min_width = fse->max_width = -+ hm5065_frame_sizes[fse->index].width; -+ fse->min_height = fse->max_height = -+ hm5065_frame_sizes[fse->index].height; -+ } else { -+ /* swap sides */ -+ int off = fse->index - HM5065_NUM_FRAME_SIZES; -+ -+ fse->min_width = fse->max_width = -+ hm5065_frame_sizes[off].height; -+ fse->min_height = fse->max_height = -+ hm5065_frame_sizes[off].width; -+ } -+ -+ return 0; -+} -+ -+static int hm5065_enum_frame_interval( -+ struct v4l2_subdev *sd, -+ struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_frame_interval_enum *fie) -+{ -+ struct v4l2_fract tpf; -+ int max_fps, i; -+ -+ if (fie->pad != 0) -+ return -EINVAL; -+ -+ /* find the max frame rate for the resolution */ -+ for (i = 0; i < HM5065_NUM_FRAME_SIZES; i++) { -+ const struct hm5065_frame_size *fs = &hm5065_frame_sizes[i]; -+ int width, height; -+ -+ if (fie->width < fie->height) { -+ width = fs->height; -+ height = fs->width; -+ } else { -+ width = fs->width; -+ height = fs->height; -+ } -+ -+ max_fps = fs->max_fps * hm5065_get_max_binning(width, height); -+ -+ if (width == fie->width && height == fie->height) -+ goto found; -+ } -+ -+ return -EINVAL; -+ -+found: -+ if (fie->index + 1 > max_fps) -+ return -EINVAL; -+ -+ tpf.numerator = 1; -+ tpf.denominator = fie->index + 1; -+ fie->interval = tpf; -+ return 0; -+} -+ -+static int hm5065_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) -+{ -+ struct v4l2_captureparm *cp = &parms->parm.capture; -+ struct v4l2_subdev_frame_interval fi; -+ int ret; -+ -+ if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) -+ return -EINVAL; -+ -+ cp->capability = V4L2_CAP_TIMEPERFRAME; -+ fi.pad = 0; -+ ret = hm5065_g_frame_interval(sd, &fi); -+ if (ret) -+ return ret; -+ -+ cp->timeperframe = fi.interval; -+ return 0; -+} -+ -+static int hm5065_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) -+{ -+ struct v4l2_captureparm *cp = &parms->parm.capture; -+ struct v4l2_subdev_frame_interval fi; -+ int ret; -+ -+ if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) -+ return -EINVAL; -+ -+ fi.pad = 0; -+ fi.interval = cp->timeperframe; -+ cp->capability = V4L2_CAP_TIMEPERFRAME; -+ -+ ret = hm5065_s_frame_interval(sd, &fi); -+ if (ret) -+ return ret; -+ -+ cp->timeperframe = fi.interval; -+ return 0; -+} -+ -+static int hm5065_get_fmt(struct v4l2_subdev *sd, -+ struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_format *format) -+{ -+ struct hm5065_dev *sensor = to_hm5065_dev(sd); -+ struct v4l2_mbus_framefmt *mf; -+ -+ if (format->pad != 0) -+ return -EINVAL; -+ -+ if (format->which == V4L2_SUBDEV_FORMAT_TRY) { -+ mf = v4l2_subdev_get_try_format(sd, cfg, format->pad); -+ format->format = *mf; -+ return 0; -+ } -+ -+ mutex_lock(&sensor->lock); -+ format->format = sensor->fmt; -+ mutex_unlock(&sensor->lock); -+ -+ return 0; -+} -+ -+static int hm5065_set_fmt(struct v4l2_subdev *sd, -+ struct v4l2_subdev_pad_config *cfg, -+ struct v4l2_subdev_format *format) -+{ -+ struct hm5065_dev *sensor = to_hm5065_dev(sd); -+ struct v4l2_mbus_framefmt *mf = &format->format; -+ const struct hm5065_pixfmt *pixfmt; -+ int ret = 0, i, width, height, max_fps; -+ -+ if (format->pad != 0) -+ return -EINVAL; -+ -+ /* check if we support requested mbus fmt */ -+ pixfmt = hm5065_find_format(mf->code); -+ if (!pixfmt) -+ pixfmt = &hm5065_formats[0]; -+ -+ mf->code = pixfmt->code; -+ mf->colorspace = pixfmt->colorspace; -+ mf->xfer_func = V4L2_XFER_FUNC_DEFAULT; -+ mf->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; -+ mf->quantization = V4L2_QUANTIZATION_DEFAULT; -+ mf->field = V4L2_FIELD_NONE; -+ -+ mutex_lock(&sensor->lock); -+ -+ /* find highest resolution possible for the currently used frame rate */ -+ for (i = 0; i < HM5065_NUM_FRAME_SIZES; i++) { -+ const struct hm5065_frame_size *fs = &hm5065_frame_sizes[i]; -+ -+ if (mf->width < mf->height) { -+ width = fs->height; -+ height = fs->width; -+ } else { -+ width = fs->width; -+ height = fs->height; -+ } -+ -+ max_fps = fs->max_fps * hm5065_get_max_binning(width, height); -+ -+ if (width <= mf->width && height <= mf->height) -+ break; -+ } -+ -+ sensor->max_frame_rate = max_fps; -+ mf->width = width; -+ mf->height = height; -+ -+ if (format->which == V4L2_SUBDEV_FORMAT_TRY) { -+ struct v4l2_mbus_framefmt *try_mf; -+ -+ try_mf = v4l2_subdev_get_try_format(sd, cfg, format->pad); -+ *try_mf = *mf; -+ goto out; -+ } -+ -+ if (sensor->streaming) { -+ ret = -EBUSY; -+ goto out; -+ } -+ -+ sensor->fmt = *mf; -+ sensor->pending_mode_change = true; -+out: -+ mutex_unlock(&sensor->lock); -+ return ret; -+} -+ -+/* }}} */ -+/* {{{ Core Ops */ -+ -+static void hm5065_chip_enable(struct hm5065_dev *sensor, bool enable) -+{ -+ gpiod_set_value(sensor->chipenable_gpio, enable ? 1 : 0); -+ gpiod_set_value(sensor->reset_gpio, enable ? 0 : 1); -+} -+ -+static int hm5065_configure(struct hm5065_dev *sensor) -+{ -+ int ret; -+ u16 device_id; -+ const struct hm5065_clk_lut *lut; -+ unsigned long xclk_freq; -+ -+ ret = hm5065_read16(sensor, HM5065_REG_DEVICE_ID, &device_id); -+ if (ret) -+ return ret; -+ -+ if (device_id != HM5065_REG_DEVICE_ID_VALUE) { -+ dev_err(&sensor->i2c_client->dev, -+ "unsupported device id: 0x%04x\n", -+ (unsigned int)device_id); -+ return -EINVAL; -+ } -+ -+ xclk_freq = clk_get_rate(sensor->xclk); -+ lut = hm5065_find_clk_lut(xclk_freq); -+ if (!lut) { -+ dev_err(&sensor->i2c_client->dev, -+ "xclk frequency out of range: %lu Hz\n", xclk_freq); -+ return -EINVAL; -+ } -+ -+ ret = hm5065_write(sensor, HM5065_REG_EXCLOCKLUT, lut->lut_id); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_load_firmware(sensor, HM5065_AF_FIRMWARE); -+ if (ret < 0) -+ return ret; -+ -+ if (ret == 0) /* ret == 1 means firmware file missing */ -+ mdelay(200); -+ -+ ret = hm5065_load_firmware(sensor, HM5065_FIRMWARE_PARAMETERS); -+ if (ret < 0) -+ return ret; -+ -+ if (sensor->ep.bus_type == V4L2_MBUS_BT656) { -+ ret = hm5065_write(sensor, HM5065_REG_BUS_CONFIG, -+ HM5065_REG_BUS_CONFIG_BT656); -+ ret = 0; -+ } else { -+ ret = hm5065_write(sensor, HM5065_REG_BUS_CONFIG, -+ HM5065_REG_BUS_CONFIG_PARALLEL_HH_VL); -+ } -+ -+ return ret; -+} -+ -+static int hm5065_set_power(struct hm5065_dev *sensor, bool on) -+{ -+ int ret = 0; -+ -+ if (on) { -+ ret = regulator_bulk_enable(HM5065_NUM_SUPPLIES, -+ sensor->supplies); -+ if (ret) -+ return ret; -+ -+ ret = clk_prepare_enable(sensor->xclk); -+ if (ret) -+ goto power_off; -+ -+ ret = clk_set_rate(sensor->xclk, 24000000); -+ if (ret) -+ goto xclk_off; -+ -+ usleep_range(1000, 2000); -+ hm5065_chip_enable(sensor, false); -+ usleep_range(1000, 2000); -+ hm5065_chip_enable(sensor, true); -+ usleep_range(50000, 70000); -+ -+ ret = hm5065_configure(sensor); -+ if (ret) -+ goto xclk_off; -+ -+ ret = hm5065_setup_mode(sensor); -+ if (ret) -+ goto xclk_off; -+ -+ return 0; -+ } -+ -+xclk_off: -+ clk_disable_unprepare(sensor->xclk); -+power_off: -+ hm5065_chip_enable(sensor, false); -+ regulator_bulk_disable(HM5065_NUM_SUPPLIES, sensor->supplies); -+ return ret; -+} -+ -+static int hm5065_s_power(struct v4l2_subdev *sd, int on) -+{ -+ struct hm5065_dev *sensor = to_hm5065_dev(sd); -+ bool power_up, power_down; -+ int ret = 0; -+ -+ mutex_lock(&sensor->lock); -+ -+ power_up = on && !sensor->powered; -+ power_down = !on && sensor->powered; -+ -+ if (power_up || power_down) { -+ ret = hm5065_set_power(sensor, power_up); -+ if (!ret) -+ sensor->powered = on; -+ } -+ -+ mutex_unlock(&sensor->lock); -+ -+ if (!ret && power_up) { -+ /* restore controls */ -+ ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler); -+ } -+ -+ return ret; -+} -+ -+#ifdef CONFIG_VIDEO_ADV_DEBUG -+static int hm5065_g_register(struct v4l2_subdev *sd, -+ struct v4l2_dbg_register *reg) -+{ -+ struct hm5065_dev *sensor = to_hm5065_dev(sd); -+ int ret; -+ u8 val = 0; -+ -+ if (reg->reg > 0xffff) -+ return -EINVAL; -+ -+ reg->size = 1; -+ -+ mutex_lock(&sensor->lock); -+ ret = hm5065_read(sensor, reg->reg, &val); -+ mutex_unlock(&sensor->lock); -+ if (ret) -+ return -EIO; -+ -+ reg->val = val; -+ return 0; -+} -+ -+static int hm5065_s_register(struct v4l2_subdev *sd, -+ const struct v4l2_dbg_register *reg) -+{ -+ struct hm5065_dev *sensor = to_hm5065_dev(sd); -+ int ret; -+ -+ if (reg->reg > 0xffff || reg->val > 0xff) -+ return -EINVAL; -+ -+ mutex_lock(&sensor->lock); -+ ret = hm5065_write(sensor, reg->reg, reg->val); -+ mutex_unlock(&sensor->lock); -+ -+ return ret; -+} -+#endif -+ -+/* }}} */ -+ -+static const struct v4l2_subdev_core_ops hm5065_core_ops = { -+ .s_power = hm5065_s_power, -+#ifdef CONFIG_VIDEO_ADV_DEBUG -+ .g_register = hm5065_g_register, -+ .s_register = hm5065_s_register, -+#endif -+}; -+ -+static const struct v4l2_subdev_pad_ops hm5065_pad_ops = { -+ .enum_mbus_code = hm5065_enum_mbus_code, -+ .enum_frame_size = hm5065_enum_frame_size, -+ .enum_frame_interval = hm5065_enum_frame_interval, -+ .get_fmt = hm5065_get_fmt, -+ .set_fmt = hm5065_set_fmt, -+}; -+ -+static const struct v4l2_subdev_video_ops hm5065_video_ops = { -+ .g_frame_interval = hm5065_g_frame_interval, -+ .s_frame_interval = hm5065_s_frame_interval, -+ .g_parm = hm5065_g_parm, -+ .s_parm = hm5065_s_parm, -+ .s_stream = hm5065_s_stream, -+}; -+ -+static const struct v4l2_subdev_ops hm5065_subdev_ops = { -+ .core = &hm5065_core_ops, -+ .pad = &hm5065_pad_ops, -+ .video = &hm5065_video_ops, -+}; -+ -+static int hm5065_get_regulators(struct hm5065_dev *sensor) -+{ -+ int i; -+ -+ for (i = 0; i < HM5065_NUM_SUPPLIES; i++) -+ sensor->supplies[i].supply = hm5065_supply_name[i]; -+ -+ return devm_regulator_bulk_get(&sensor->i2c_client->dev, -+ HM5065_NUM_SUPPLIES, -+ sensor->supplies); -+} -+ -+#define HM5065_PARALLEL_SUPPORT_FLAGS \ -+ (V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | \ -+ V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_DATA_ACTIVE_HIGH) -+ -+static int hm5065_probe(struct i2c_client *client, -+ const struct i2c_device_id *id) -+{ -+ struct device *dev = &client->dev; -+ struct fwnode_handle *endpoint; -+ struct hm5065_dev *sensor; -+ int ret; -+ -+ sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL); -+ if (!sensor) -+ return -ENOMEM; -+ -+ sensor->i2c_client = client; -+ -+ sensor->fmt.code = hm5065_formats[0].code; -+ sensor->fmt.width = hm5065_frame_sizes[HM5065_DEFAULT_FRAME_SIZE].width; -+ sensor->fmt.height = -+ hm5065_frame_sizes[HM5065_DEFAULT_FRAME_SIZE].height; -+ sensor->fmt.field = V4L2_FIELD_NONE; -+ sensor->frame_interval.numerator = 1; -+ sensor->frame_interval.denominator = 5; -+ sensor->max_frame_rate = -+ hm5065_frame_sizes[HM5065_DEFAULT_FRAME_SIZE].max_fps * -+ hm5065_get_max_binning(sensor->fmt.width, sensor->fmt.height); -+ sensor->pending_mode_change = true; -+ -+ endpoint = fwnode_graph_get_next_endpoint( -+ of_fwnode_handle(client->dev.of_node), NULL); -+ if (!endpoint) { -+ dev_err(dev, "endpoint node not found\n"); -+ return -EINVAL; -+ } -+ -+ ret = v4l2_fwnode_endpoint_parse(endpoint, &sensor->ep); -+ fwnode_handle_put(endpoint); -+ if (ret) { -+ dev_err(dev, "could not parse endpoint\n"); -+ return ret; -+ } -+ -+ /* -+ * We don't know how to configure the camera for any other parallel -+ * Wode. -+ */ -+ if (sensor->ep.bus_type != V4L2_MBUS_BT656 && -+ !(sensor->ep.bus_type == V4L2_MBUS_PARALLEL && -+ (sensor->ep.bus.parallel.flags & HM5065_PARALLEL_SUPPORT_FLAGS) == -+ HM5065_PARALLEL_SUPPORT_FLAGS)) { -+ dev_err(dev, "unsupported bus configuration\n"); -+ return -EINVAL; -+ } -+ -+ /* get system clock (xclk) */ -+ sensor->xclk = devm_clk_get(dev, "xclk"); -+ if (IS_ERR(sensor->xclk)) { -+ dev_err(dev, "failed to get xclk\n"); -+ return PTR_ERR(sensor->xclk); -+ } -+ -+ sensor->chipenable_gpio = devm_gpiod_get_optional(dev, "chipenable", -+ GPIOD_OUT_LOW); -+ sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset", -+ GPIOD_OUT_HIGH); -+ -+ if (!sensor->chipenable_gpio && !sensor->reset_gpio) { -+ dev_err(dev, -+ "either chip enable or reset pin must be configured\n"); -+ return ret; -+ } -+ -+ v4l2_i2c_subdev_init(&sensor->sd, client, &hm5065_subdev_ops); -+ -+ sensor->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; -+ sensor->pad.flags = MEDIA_PAD_FL_SOURCE; -+ sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; -+ ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad); -+ if (ret) -+ return ret; -+ -+ ret = hm5065_get_regulators(sensor); -+ if (ret) -+ return ret; -+ -+ mutex_init(&sensor->lock); -+ -+ ret = hm5065_init_controls(sensor); -+ if (ret) -+ goto entity_cleanup; -+ -+ ret = v4l2_async_register_subdev(&sensor->sd); -+ if (ret) -+ goto free_ctrls; -+ -+ return 0; -+ -+free_ctrls: -+ v4l2_ctrl_handler_free(&sensor->ctrls.handler); -+entity_cleanup: -+ mutex_destroy(&sensor->lock); -+ media_entity_cleanup(&sensor->sd.entity); -+ return ret; -+} -+ -+static int hm5065_remove(struct i2c_client *client) -+{ -+ struct v4l2_subdev *sd = i2c_get_clientdata(client); -+ struct hm5065_dev *sensor = to_hm5065_dev(sd); -+ -+ v4l2_async_unregister_subdev(&sensor->sd); -+ mutex_destroy(&sensor->lock); -+ media_entity_cleanup(&sensor->sd.entity); -+ v4l2_ctrl_handler_free(&sensor->ctrls.handler); -+ -+ return 0; -+} -+ -+static const struct i2c_device_id hm5065_id[] = { -+ {"hm5065", 0}, -+ {}, -+}; -+MODULE_DEVICE_TABLE(i2c, hm5065_id); -+ -+static const struct of_device_id hm5065_dt_ids[] = { -+ { .compatible = "himax,hm5065" }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, hm5065_dt_ids); -+ -+static struct i2c_driver hm5065_i2c_driver = { -+ .driver = { -+ .name = "hm5065", -+ .of_match_table = hm5065_dt_ids, -+ }, -+ .id_table = hm5065_id, -+ .probe = hm5065_probe, -+ .remove = hm5065_remove, -+}; -+ -+module_i2c_driver(hm5065_i2c_driver); -+ -+MODULE_AUTHOR("Ondrej Jirman "); -+MODULE_DESCRIPTION("HM5065 Camera Subdev Driver"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/platform/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sun6i-csi/sun6i_csi.c -index 8cfccc5782b1..2bd746c3efc4 100644 ---- a/drivers/media/platform/sun6i-csi/sun6i_csi.c -+++ b/drivers/media/platform/sun6i-csi/sun6i_csi.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -563,6 +564,8 @@ static const struct v4l2_ioctl_ops sun6i_video_ioctl_ops = { - .vidioc_streamoff = vb2_ioctl_streamoff, - - .vidioc_log_status = v4l2_ctrl_log_status, -+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, -+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe, - }; - - // }}} --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0038-arm-dts-sun8i-a83t-a711-Enable-I2C1.patch b/patch/kernel/sunxi-legacy/0000-0038-arm-dts-sun8i-a83t-a711-Enable-I2C1.patch deleted file mode 100644 index 01bf3c149..000000000 --- a/patch/kernel/sunxi-legacy/0000-0038-arm-dts-sun8i-a83t-a711-Enable-I2C1.patch +++ /dev/null @@ -1,34 +0,0 @@ -From dd149592ded2be2ebbe64ee83bcb34054470cf07 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Thu, 9 Nov 2017 23:05:13 +0100 -Subject: [PATCH 38/82] arm: dts: sun8i: a83t: a711: Enable I2C1 - -The A711 has some sensors connected to I2C1. Enable only the bus for the -moment. - -Signed-off-by: Tomas Novotny ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index c8278e173f50..8e9f0de3d0c0 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -237,6 +237,13 @@ - }; - }; - -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <400000>; -+ status = "okay"; -+}; -+ - &mmc0 { - vmmc-supply = <®_dcdc1>; - pinctrl-names = "default"; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0039-ARM-dts-sun8i-a83t-tbs-a711-Enable-BMA250-accelerome.patch b/patch/kernel/sunxi-legacy/0000-0039-ARM-dts-sun8i-a83t-tbs-a711-Enable-BMA250-accelerome.patch deleted file mode 100644 index 55d0cb594..000000000 --- a/patch/kernel/sunxi-legacy/0000-0039-ARM-dts-sun8i-a83t-tbs-a711-Enable-BMA250-accelerome.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 69c8e0651bb68ab80b0fc4033b8ca5e87b8bb164 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Fri, 10 Nov 2017 13:20:43 +0100 -Subject: [PATCH 39/82] ARM: dts: sun8i-a83t-tbs-a711: Enable BMA250 - accelerometer IIO - -It's already supported in mainline kernel. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index 8e9f0de3d0c0..2427bf3461d7 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -242,6 +242,14 @@ - pinctrl-0 = <&i2c1_pins>; - clock-frequency = <400000>; - status = "okay"; -+ -+ /* Accelerometer */ -+ bma250@18 { -+ compatible = "bosch,bma250"; -+ reg = <0x18>; -+ interrupt-parent = <&pio>; -+ interrupts = <7 10 IRQ_TYPE_EDGE_RISING>; /* PH10 / EINT10 */ -+ }; - }; - - &mmc0 { --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0040-ARM-dts-sun8i-a83t-tbs-a711-Enable-LTR-501-ALS-IIO.patch b/patch/kernel/sunxi-legacy/0000-0040-ARM-dts-sun8i-a83t-tbs-a711-Enable-LTR-501-ALS-IIO.patch deleted file mode 100644 index e39124bd4..000000000 --- a/patch/kernel/sunxi-legacy/0000-0040-ARM-dts-sun8i-a83t-tbs-a711-Enable-LTR-501-ALS-IIO.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 113d3049c946e68e32fdec6f64672fe4cd181cc8 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Fri, 10 Nov 2017 13:21:55 +0100 -Subject: [PATCH 40/82] ARM: dts: sun8i-a83t-tbs-a711: Enable LTR-501-ALS IIO - -It's already supported in mainline kernel. Though, the driver didn't -have OF compativles table. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index 2427bf3461d7..6acc678d1b5b 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -250,6 +250,15 @@ - interrupt-parent = <&pio>; - interrupts = <7 10 IRQ_TYPE_EDGE_RISING>; /* PH10 / EINT10 */ - }; -+ -+ /* Light Sensor */ -+ ltr501: ltr501@23 { -+ status = "disabled"; /* no output */ -+ compatible = "ltr,ltr501"; -+ reg = <0x23>; -+ interrupt-parent = <&pio>; -+ interrupts = <6 12 IRQ_TYPE_EDGE_FALLING>; /* PG12 */ -+ }; - }; - - &mmc0 { --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0041-iio-ltr501-Add-OF-compatibles.patch b/patch/kernel/sunxi-legacy/0000-0041-iio-ltr501-Add-OF-compatibles.patch deleted file mode 100644 index 99ef5b9c6..000000000 --- a/patch/kernel/sunxi-legacy/0000-0041-iio-ltr501-Add-OF-compatibles.patch +++ /dev/null @@ -1,68 +0,0 @@ -From e4548a8a5ad34919a94b282369212b661e1d4382 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Fri, 10 Nov 2017 13:23:01 +0100 -Subject: [PATCH 41/82] iio: ltr501: Add OF compatibles - -So that driver can be configured from DTS. - -Signed-off-by: Ondrej Jirman ---- - drivers/iio/light/ltr501.c | 18 ++++++++++++++++-- - 1 file changed, 16 insertions(+), 2 deletions(-) - -diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c -index 830a2d45aa4d..bdb296dcb7c0 100644 ---- a/drivers/iio/light/ltr501.c -+++ b/drivers/iio/light/ltr501.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -1558,6 +1559,7 @@ static int ltr501_resume(struct device *dev) - - static SIMPLE_DEV_PM_OPS(ltr501_pm_ops, ltr501_suspend, ltr501_resume); - -+#ifdef CONFIG_ACPI - static const struct acpi_device_id ltr_acpi_match[] = { - {"LTER0501", ltr501}, - {"LTER0559", ltr559}, -@@ -1565,6 +1567,7 @@ static const struct acpi_device_id ltr_acpi_match[] = { - { }, - }; - MODULE_DEVICE_TABLE(acpi, ltr_acpi_match); -+#endif - - static const struct i2c_device_id ltr501_id[] = { - { "ltr501", ltr501}, -@@ -1574,11 +1577,22 @@ static const struct i2c_device_id ltr501_id[] = { - }; - MODULE_DEVICE_TABLE(i2c, ltr501_id); - -+#ifdef CONFIG_OF -+static const struct of_device_id ltr501_of_match[] = { -+ { .compatible = "ltr,ltr501", .data = (void*)ltr501 }, -+ { .compatible = "ltr,ltr559", .data = (void*)ltr559 }, -+ { .compatible = "ltr,ltr301", .data = (void*)ltr301 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, ltr501_of_match); -+#endif -+ - static struct i2c_driver ltr501_driver = { - .driver = { -- .name = LTR501_DRV_NAME, -- .pm = <r501_pm_ops, -+ .name = LTR501_DRV_NAME, -+ .pm = <r501_pm_ops, - .acpi_match_table = ACPI_PTR(ltr_acpi_match), -+ .of_match_table = of_match_ptr(ltr501_of_match) - }, - .probe = ltr501_probe, - .remove = ltr501_remove, --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0042-ARM-dts-sun8i-a83t-tbs-a711-Enable-AK8963-magnetomet.patch b/patch/kernel/sunxi-legacy/0000-0042-ARM-dts-sun8i-a83t-tbs-a711-Enable-AK8963-magnetomet.patch deleted file mode 100644 index 276353ed0..000000000 --- a/patch/kernel/sunxi-legacy/0000-0042-ARM-dts-sun8i-a83t-tbs-a711-Enable-AK8963-magnetomet.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 2a3460a07d4ef36bd754c83dce9b6b7ea9844aa3 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Fri, 10 Nov 2017 13:24:58 +0100 -Subject: [PATCH 42/82] ARM: dts: sun8i-a83t-tbs-a711: Enable AK8963 - magnetometer - -Though the chip is probably broken on my tablet. It doesn't respond -on I2C 0x0d address. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index 6acc678d1b5b..ec986498114e 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -251,6 +251,24 @@ - interrupts = <7 10 IRQ_TYPE_EDGE_RISING>; /* PH10 / EINT10 */ - }; - -+ /* Magnetic Sensor */ -+ ak8963: ak8963@0d { -+ status = "disabled"; /* broken */ -+ compatible = "asahi-kasei,ak8963"; -+ reg = <0x0d>; -+ interrupt-parent = <&pio>; -+ interrupts = <1 2 IRQ_TYPE_EDGE_RISING>; /* PB2 */ -+ mount-matrix = /* x0 */ "-0.984807753012208", -+ /* y0 */ "0", -+ /* z0 */ "-0.173648177666930", -+ /* x1 */ "0", -+ /* y1 */ "-1", -+ /* z1 */ "0", -+ /* x2 */ "-0.173648177666930", -+ /* y2 */ "0", -+ /* z2 */ "0.984807753012208"; -+ }; -+ - /* Light Sensor */ - ltr501: ltr501@23 { - status = "disabled"; /* no output */ --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0043-nfc-pn544-Add-support-for-VBAT-PVDD-regulators.patch b/patch/kernel/sunxi-legacy/0000-0043-nfc-pn544-Add-support-for-VBAT-PVDD-regulators.patch deleted file mode 100644 index a2a2d2006..000000000 --- a/patch/kernel/sunxi-legacy/0000-0043-nfc-pn544-Add-support-for-VBAT-PVDD-regulators.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 8df4a460c0459b0ba6a20634adc4ecb60b8e89d5 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Fri, 10 Nov 2017 14:29:26 +0100 -Subject: [PATCH 43/82] nfc: pn544: Add support for VBAT/PVDD regulators - -Regulators are required, so this can't go into mainline as is. - -Signed-off-by: Ondrej Jirman ---- - drivers/nfc/pn544/i2c.c | 29 +++++++++++++++++++++++++++-- - 1 file changed, 27 insertions(+), 2 deletions(-) - -diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c -index d0207f8e68b7..5d0a20d3f9c8 100644 ---- a/drivers/nfc/pn544/i2c.c -+++ b/drivers/nfc/pn544/i2c.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - - #include - -@@ -70,6 +71,14 @@ MODULE_DEVICE_TABLE(acpi, pn544_hci_i2c_acpi_match); - - #define PN544_HCI_I2C_DRIVER_NAME "pn544_hci_i2c" - -+/* regulator supplies */ -+static const char * const pn544_supply_names[] = { -+ "PVDD", /* Digital Core (1.8V) supply */ -+ "VBAT", /* Analog (2.9V-5.5V) supply */ -+}; -+ -+#define PN544_NUM_SUPPLIES ARRAY_SIZE(pn544_supply_names) -+ - /* - * Exposed through the 4 most significant bytes - * from the HCI SW_VERSION first byte, a.k.a. -@@ -161,6 +170,7 @@ struct pn544_i2c_phy { - struct i2c_client *i2c_dev; - struct nfc_hci_dev *hdev; - -+ struct regulator_bulk_data supplies[PN544_NUM_SUPPLIES]; - struct gpio_desc *gpiod_en; - struct gpio_desc *gpiod_fw; - -@@ -250,9 +260,14 @@ static void pn544_hci_i2c_enable_mode(struct pn544_i2c_phy *phy, int run_mode) - static int pn544_hci_i2c_enable(void *phy_id) - { - struct pn544_i2c_phy *phy = phy_id; -+ int ret; - - pr_info("%s\n", __func__); - -+ ret = regulator_bulk_enable(PN544_NUM_SUPPLIES, phy->supplies); -+ if (ret) -+ return ret; -+ - pn544_hci_i2c_enable_mode(phy, PN544_HCI_MODE); - - phy->powered = 1; -@@ -274,6 +289,8 @@ static void pn544_hci_i2c_disable(void *phy_id) - gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity); - usleep_range(10000, 15000); - -+ regulator_bulk_disable(PN544_NUM_SUPPLIES, phy->supplies); -+ - phy->powered = 0; - } - -@@ -380,7 +397,7 @@ static int pn544_hci_i2c_read(struct pn544_i2c_phy *phy, struct sk_buff **skb) - - if ((len < (PN544_HCI_I2C_LLC_MIN_SIZE - 1)) || - (len > (PN544_HCI_I2C_LLC_MAX_SIZE - 1))) { -- nfc_err(&client->dev, "invalid len byte\n"); -+ nfc_err(&client->dev, "invalid len byte %hhx\n", len); - r = -EBADMSG; - goto flush; - } -@@ -883,7 +900,7 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, - { - struct device *dev = &client->dev; - struct pn544_i2c_phy *phy; -- int r = 0; -+ int r = 0, i; - - dev_dbg(&client->dev, "%s\n", __func__); - dev_dbg(&client->dev, "IRQ: %d\n", client->irq); -@@ -908,6 +925,14 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, - if (r) - dev_dbg(dev, "Unable to add GPIO mapping table\n"); - -+ for (i = 0; i < PN544_NUM_SUPPLIES; i++) -+ phy->supplies[i].supply = pn544_supply_names[i]; -+ -+ r = devm_regulator_bulk_get(&client->dev, PN544_NUM_SUPPLIES, -+ phy->supplies); -+ if (r) -+ return r; -+ - /* Get EN GPIO */ - phy->gpiod_en = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); - if (IS_ERR(phy->gpiod_en)) { --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0044-ARM-dts-sun8i-a83t-tbs-a711-Add-PN544-NFC-support.patch b/patch/kernel/sunxi-legacy/0000-0044-ARM-dts-sun8i-a83t-tbs-a711-Add-PN544-NFC-support.patch deleted file mode 100644 index 2c7daf38d..000000000 --- a/patch/kernel/sunxi-legacy/0000-0044-ARM-dts-sun8i-a83t-tbs-a711-Add-PN544-NFC-support.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 69eafa62d60b993ba9500f56af568357b16b1504 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Fri, 10 Nov 2017 14:33:28 +0100 -Subject: [PATCH 44/82] ARM: dts: sun8i-a83t-tbs-a711: Add PN544 NFC support - -Regulators on the schematic are named incorrectly. Both cameras are -is in fact connected to the dvdd-csi-f regulator and dvdd-csi-r is -in reality used for digital pad supply for NFC chip. - -At the same time vcc-mipi regulator is not used for MIPI, but for NFC -VBAT power. - -Interpreting schematics is an art form! :D - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 18 +++++++++++++++--- - 1 file changed, 15 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index ec986498114e..787277f4d455 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -277,6 +277,16 @@ - interrupt-parent = <&pio>; - interrupts = <6 12 IRQ_TYPE_EDGE_FALLING>; /* PG12 */ - }; -+ -+ /* NFC (NPC 100) */ -+ npc100: nfc@28 { -+ compatible = "nxp,nxp-nci-i2c"; -+ reg = <0x28>; -+ interrupt-parent = <&r_pio>; -+ interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>; /* PL6 */ -+ enable-gpios = <&pio 3 2 GPIO_ACTIVE_HIGH>; /* PD2 */ -+ firmware-gpios = <&pio 3 3 GPIO_ACTIVE_HIGH>; /* PD3 */ -+ }; - }; - - &mmc0 { -@@ -434,9 +444,10 @@ - }; - - ®_dldo2 { -- regulator-min-microvolt = <2800000>; -+ regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <4200000>; -- regulator-name = "vcc-mipi"; -+ regulator-name = "vbat-nfc"; -+ regulator-always-on; - }; - - ®_dldo3 { -@@ -459,7 +470,8 @@ - ®_eldo1 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; -- regulator-name = "dvdd-csi-r"; -+ regulator-name = "pvdd-nfc"; -+ regulator-always-on; - }; - - ®_eldo2 { --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0045-input-sun4i-a10-lradc-keys-Add-support-for-A83T.patch b/patch/kernel/sunxi-legacy/0000-0045-input-sun4i-a10-lradc-keys-Add-support-for-A83T.patch deleted file mode 100644 index a52eb122d..000000000 --- a/patch/kernel/sunxi-legacy/0000-0045-input-sun4i-a10-lradc-keys-Add-support-for-A83T.patch +++ /dev/null @@ -1,104 +0,0 @@ -From df802a8e12f7600dea15f67314bb1bfd7a981949 Mon Sep 17 00:00:00 2001 -From: Ziping Chen -Date: Mon, 13 Nov 2017 16:49:37 +0100 -Subject: [PATCH 45/82] input: sun4i-a10-lradc-keys: Add support for A83T - -Allwinner A83T SoC has a low res adc like the one -in Allwinner A10 SoC, however, the A10 SoC's vref -of lradc internally is divided by 2/3 and the A83T -SoC's vref of lradc internally is divided by 3/4, -thus add a hardware variant for it to be compatible -with various devices. - -Signed-off-by: Ziping Chen ---- - drivers/input/keyboard/sun4i-lradc-keys.c | 38 ++++++++++++++++++++--- - 1 file changed, 34 insertions(+), 4 deletions(-) - -diff --git a/drivers/input/keyboard/sun4i-lradc-keys.c b/drivers/input/keyboard/sun4i-lradc-keys.c -index a37c172452e6..bfd2038a9047 100644 ---- a/drivers/input/keyboard/sun4i-lradc-keys.c -+++ b/drivers/input/keyboard/sun4i-lradc-keys.c -@@ -46,6 +46,7 @@ - #define CONTINUE_TIME_SEL(x) ((x) << 16) /* 4 bits */ - #define KEY_MODE_SEL(x) ((x) << 12) /* 2 bits */ - #define LEVELA_B_CNT(x) ((x) << 8) /* 4 bits */ -+#define HOLD_KEY_EN(x) ((x) << 7) - #define HOLD_EN(x) ((x) << 6) - #define LEVELB_VOL(x) ((x) << 4) /* 2 bits */ - #define SAMPLE_RATE(x) ((x) << 2) /* 2 bits */ -@@ -63,6 +64,25 @@ - #define CHAN0_KEYDOWN_IRQ BIT(1) - #define CHAN0_DATA_IRQ BIT(0) - -+/* struct lradc_variant - Describe sun4i-a10-lradc-keys hardware variant -+ * @divisor_numerator: The numerator of lradc Vref internally divisor -+ * @divisor_denominator: The denominator of lradc Vref internally divisor -+ */ -+struct lradc_variant { -+ u8 divisor_numerator; -+ u8 divisor_denominator; -+}; -+ -+static const struct lradc_variant lradc_variant_a10 = { -+ .divisor_numerator = 2, -+ .divisor_denominator = 3 -+}; -+ -+static const struct lradc_variant r_lradc_variant_a83t = { -+ .divisor_numerator = 3, -+ .divisor_denominator = 4 -+}; -+ - struct sun4i_lradc_keymap { - u32 voltage; - u32 keycode; -@@ -74,6 +94,7 @@ struct sun4i_lradc_data { - void __iomem *base; - struct regulator *vref_supply; - struct sun4i_lradc_keymap *chan0_map; -+ const struct lradc_variant *variant; - u32 chan0_map_count; - u32 chan0_keycode; - u32 vref; -@@ -128,9 +149,9 @@ static int sun4i_lradc_open(struct input_dev *dev) - if (error) - return error; - -- /* lradc Vref internally is divided by 2/3 */ -- lradc->vref = regulator_get_voltage(lradc->vref_supply) * 2 / 3; -- -+ lradc->vref = regulator_get_voltage(lradc->vref_supply) * -+ lradc->variant->divisor_numerator / -+ lradc->variant->divisor_denominator; - /* - * Set sample time to 4 ms / 250 Hz. Wait 2 * 4 ms for key to - * stabilize on press, wait (1 + 1) * 4 ms for key release -@@ -222,6 +243,12 @@ static int sun4i_lradc_probe(struct platform_device *pdev) - if (error) - return error; - -+ lradc->variant = of_device_get_match_data(&pdev->dev); -+ if (!lradc->variant) { -+ dev_err(&pdev->dev, "Missing sun4i-a10-lradc-keys variant\n"); -+ return -EINVAL; -+ } -+ - lradc->vref_supply = devm_regulator_get(dev, "vref"); - if (IS_ERR(lradc->vref_supply)) - return PTR_ERR(lradc->vref_supply); -@@ -265,7 +292,10 @@ static int sun4i_lradc_probe(struct platform_device *pdev) - } - - static const struct of_device_id sun4i_lradc_of_match[] = { -- { .compatible = "allwinner,sun4i-a10-lradc-keys", }, -+ { .compatible = "allwinner,sun4i-a10-lradc-keys", -+ .data = &lradc_variant_a10 }, -+ { .compatible = "allwinner,sun8i-a83t-r-lradc-keys", -+ .data = &r_lradc_variant_a83t }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, sun4i_lradc_of_match); --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0046-ARM-dts-sun8i-a83t-Add-lradc.patch b/patch/kernel/sunxi-legacy/0000-0046-ARM-dts-sun8i-a83t-Add-lradc.patch deleted file mode 100644 index d8595ba7d..000000000 --- a/patch/kernel/sunxi-legacy/0000-0046-ARM-dts-sun8i-a83t-Add-lradc.patch +++ /dev/null @@ -1,31 +0,0 @@ -From b804df86f96f4bdc74abab55404a0bdcc7526f8b Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sun, 12 Nov 2017 06:25:17 +0100 -Subject: [PATCH 46/82] ARM: dts: sun8i-a83t: Add lradc - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t.dtsi | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi -index 66f035ead79a..d9074f050a9c 100644 ---- a/arch/arm/boot/dts/sun8i-a83t.dtsi -+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi -@@ -627,6 +627,13 @@ - status = "disabled"; - }; - -+ lradc: lradc@1f03c00 { -+ compatible = "allwinner,sun4i-a10-lradc-keys"; -+ reg = <0x01f03c00 0x100>; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ - ccu: clock@1c20000 { - compatible = "allwinner,sun8i-a83t-ccu"; - reg = <0x01c20000 0x400>; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0047-ARM-dts-sun8i-a83t-tbs-a711-Add-support-for-volume-k.patch b/patch/kernel/sunxi-legacy/0000-0047-ARM-dts-sun8i-a83t-tbs-a711-Add-support-for-volume-k.patch deleted file mode 100644 index 88ea7c16e..000000000 --- a/patch/kernel/sunxi-legacy/0000-0047-ARM-dts-sun8i-a83t-tbs-a711-Add-support-for-volume-k.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 8c120e82a6cd86742dbdfd5c0a17d88737a74394 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sun, 12 Nov 2017 06:25:59 +0100 -Subject: [PATCH 47/82] ARM: dts: sun8i-a83t-tbs-a711: Add support for volume - keys input - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index 787277f4d455..ab4dce4b1e67 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -46,6 +46,7 @@ - - #include - #include -+#include - - / { - model = "TBS A711 Tablet"; -@@ -289,6 +290,25 @@ - }; - }; - -+&lradc { -+ vref-supply = <®_aldo2>; -+ status = "okay"; -+ -+ button@200 { -+ label = "Volume Up"; -+ linux,code = ; -+ channel = <0>; -+ voltage = <210000>; -+ }; -+ -+ button@400 { -+ label = "Volume Down"; -+ linux,code = ; -+ channel = <0>; -+ voltage = <410000>; -+ }; -+}; -+ - &mmc0 { - vmmc-supply = <®_dcdc1>; - pinctrl-names = "default"; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0048-misc-tbs-a711-Power-manager-and-wakeup-monitoring-dr.patch b/patch/kernel/sunxi-legacy/0000-0048-misc-tbs-a711-Power-manager-and-wakeup-monitoring-dr.patch deleted file mode 100644 index 64f63cedb..000000000 --- a/patch/kernel/sunxi-legacy/0000-0048-misc-tbs-a711-Power-manager-and-wakeup-monitoring-dr.patch +++ /dev/null @@ -1,544 +0,0 @@ -From 050ae3acc34834c56ee0a95ed2e96143e4f885b5 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sun, 12 Nov 2017 02:10:15 +0100 -Subject: [PATCH 48/82] misc: tbs-a711: Power manager and wakeup monitoring - driver - -This driver allows for powering/resetting devices that are otherwise -handled by other subsytems (USB). It also has mechanismsm for polling -from userspace on device->SoC wakeup events via GPIO. - -Signed-off-by: Ondrej Jirman ---- - drivers/misc/Makefile | 1 + - drivers/misc/tbs-a711.c | 509 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 510 insertions(+) - create mode 100644 drivers/misc/tbs-a711.c - -diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index af22bbc3d00c..4b09a5b406e0 100644 ---- a/drivers/misc/Makefile -+++ b/drivers/misc/Makefile -@@ -58,3 +58,4 @@ obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o - obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o - obj-$(CONFIG_OCXL) += ocxl/ - obj-$(CONFIG_MISC_RTSX) += cardreader/ -+obj-y += tbs-a711.o -diff --git a/drivers/misc/tbs-a711.c b/drivers/misc/tbs-a711.c -new file mode 100644 -index 000000000000..05fe2ed76429 ---- /dev/null -+++ b/drivers/misc/tbs-a711.c -@@ -0,0 +1,509 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_NAME "tbs_a711" -+ -+#define A711_IOCTL_RESET _IO('A', 0) -+#define A711_IOCTL_POWERUP _IO('A', 1) -+#define A711_IOCTL_POWERDN _IO('A', 2) -+#define A711_IOCTL_STATUS _IOR('A', 3, int) -+ -+enum { -+ A711_REQ_NONE = 0, -+ A711_REQ_RESET, -+ A711_REQ_PWDN, -+ A711_REQ_PWUP, -+}; -+ -+struct a711_dev { -+ struct device *dev; -+ -+ struct gpio_desc *enable_gpio; -+ struct gpio_desc *reset_gpio; -+ struct gpio_desc *wakeup_gpio; -+ struct regulator *regulator; -+ int wakeup_irq; -+ u32 reset_duration; -+ struct cdev cdev; -+ dev_t major; -+ -+ // change -+ spinlock_t lock; -+ wait_queue_head_t waitqueue; -+ int got_wakeup; -+ int is_open; -+ struct work_struct work; -+ int last_request; -+ int is_enabled; -+}; -+ -+static void a711_reset(struct a711_dev* a711) -+{ -+ struct device *dev = a711->dev; -+ -+ if (!a711->is_enabled) -+ return; -+ -+ if (!a711->reset_gpio) { -+ dev_err(dev, "reset is not configured for this device"); -+ return; -+ } -+ -+ dev_info(dev, "resetting"); -+ -+ gpiod_set_value(a711->reset_gpio, 1); -+ msleep(a711->reset_duration); -+ gpiod_set_value(a711->reset_gpio, 0); -+} -+ -+static void a711_power_down(struct a711_dev* a711) -+{ -+ struct device *dev = a711->dev; -+ -+ if (!a711->is_enabled) -+ return; -+ -+ dev_info(dev, "powering down"); -+ -+ gpiod_set_value(a711->enable_gpio, 0); -+ if (a711->regulator) -+ regulator_disable(a711->regulator); -+ else -+ gpiod_set_value(a711->reset_gpio, 1); -+ a711->is_enabled = 0; -+} -+ -+static void a711_power_up(struct a711_dev* a711) -+{ -+ struct device *dev = a711->dev; -+ int ret; -+ -+ if (a711->is_enabled) -+ return; -+ -+ dev_info(dev, "powering up"); -+ -+ // power up -+ if (a711->regulator) { -+ ret = regulator_enable(a711->regulator); -+ if (ret < 0) { -+ dev_err(dev, "can't enable power supply err=%d", ret); -+ return; -+ } -+ } -+ -+ gpiod_set_value(a711->enable_gpio, 1); -+ gpiod_set_value(a711->reset_gpio, 1); -+ msleep(a711->reset_duration); -+ gpiod_set_value(a711->reset_gpio, 0); -+ a711->is_enabled = 1; -+} -+ -+static struct class* a711_class; -+ -+static void a711_work_handler(struct work_struct *work) -+{ -+ struct a711_dev *a711 = container_of(work, struct a711_dev, work); -+ int last_request; -+ -+ spin_lock(&a711->lock); -+ last_request = a711->last_request; -+ a711->last_request = 0; -+ spin_unlock(&a711->lock); -+ -+ if (last_request == A711_REQ_RESET) { -+ a711_reset(a711); -+ } else if (last_request == A711_REQ_PWDN) { -+ a711_power_down(a711); -+ } else if (last_request == A711_REQ_PWUP) { -+ a711_power_up(a711); -+ } -+} -+ -+static bool a711_has_wakeup(struct a711_dev* a711) -+{ -+ bool got_wakeup; -+ spin_lock(&a711->lock); -+ got_wakeup = a711->got_wakeup; -+ spin_unlock(&a711->lock); -+ return got_wakeup; -+} -+ -+static ssize_t a711_read(struct file *fp, char __user *buf, size_t len, -+ loff_t *off) -+{ -+ struct a711_dev* a711 = fp->private_data; -+ int ret; -+ char tmp_buf[1] = {1}; -+ int got_wakeup; -+ int non_blocking = fp->f_flags & O_NONBLOCK; -+ -+ // first handle non-blocking path -+ if (non_blocking && !a711_has_wakeup(a711)) -+ return -EWOULDBLOCK; -+ -+ // wait for availability of wakeup -+ ret = wait_event_interruptible(a711->waitqueue, -+ a711_has_wakeup(a711)); -+ if (ret) -+ return ret; -+ -+ spin_lock(&a711->lock); -+ -+ got_wakeup = a711->got_wakeup; -+ a711->got_wakeup = 0; -+ -+ if (!got_wakeup) { -+ ret = -EIO; -+ } else { -+ if (copy_to_user(buf, tmp_buf, 1)) -+ ret = -EFAULT; -+ else -+ ret = 1; -+ } -+ -+ spin_unlock(&a711->lock); -+ return ret; -+} -+ -+static ssize_t a711_write(struct file *fp, const char __user *buf, -+ size_t len, loff_t *off) -+{ -+ struct a711_dev* a711 = fp->private_data; -+ int ret; -+ char tmp_buf[1]; -+ int update = 0; -+ -+ if (len == 0) -+ return 0; -+ -+ ret = copy_from_user(tmp_buf, buf, 1); -+ if (ret) -+ return -EFAULT; -+ -+ spin_lock(&a711->lock); -+ -+ switch (tmp_buf[0]) { -+ case 'r': -+ a711->last_request = A711_REQ_RESET; -+ break; -+ case 'u': -+ a711->last_request = A711_REQ_PWUP; -+ break; -+ case 'd': -+ a711->last_request = A711_REQ_PWDN; -+ break; -+ default: -+ a711->last_request = A711_REQ_NONE; -+ break; -+ } -+ -+ update = a711->last_request != 0; -+ -+ spin_unlock(&a711->lock); -+ -+ if (update) -+ schedule_work(&a711->work); -+ -+ return 1; -+} -+ -+static unsigned int a711_poll(struct file *fp, poll_table *wait) -+{ -+ struct a711_dev* a711 = fp->private_data; -+ int ret = 0; -+ -+ poll_wait(fp, &a711->waitqueue, wait); -+ -+ spin_lock(&a711->lock); -+ if (a711->got_wakeup) -+ ret |= POLLIN | POLLRDNORM; -+ spin_unlock(&a711->lock); -+ -+ return ret; -+} -+ -+static long a711_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) -+{ -+ struct a711_dev* a711 = fp->private_data; -+ unsigned long flags; -+ int ret = -ENOSYS; -+ void __user *parg = (void __user *)arg; -+ int powered; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EACCES; -+ -+ spin_lock_irqsave(&a711->lock, flags); -+ -+ switch (cmd) { -+ case A711_IOCTL_RESET: -+ a711->last_request = A711_REQ_RESET; -+ ret = 0; -+ break; -+ case A711_IOCTL_POWERUP: -+ a711->last_request = A711_REQ_PWUP; -+ ret = 0; -+ break; -+ case A711_IOCTL_POWERDN: -+ a711->last_request = A711_REQ_PWDN; -+ ret = 0; -+ break; -+ case A711_IOCTL_STATUS: -+ powered = a711->is_enabled || a711->last_request == A711_REQ_PWUP; -+ spin_unlock_irqrestore(&a711->lock, flags); -+ -+ if (copy_to_user(parg, &powered, sizeof powered)) -+ return -EFAULT; -+ -+ return 0; -+ } -+ -+ spin_unlock_irqrestore(&a711->lock, flags); -+ -+ if (ret == 0) -+ schedule_work(&a711->work); -+ -+ return ret; -+} -+ -+static int a711_release(struct inode *ip, struct file *fp) -+{ -+ struct a711_dev* a711 = fp->private_data; -+ -+ spin_lock(&a711->lock); -+ a711->is_open = 0; -+ spin_unlock(&a711->lock); -+ -+ return 0; -+} -+ -+static int a711_open(struct inode *ip, struct file *fp) -+{ -+ struct a711_dev* a711 = container_of(ip->i_cdev, struct a711_dev, cdev); -+ -+ fp->private_data = a711; -+ -+ spin_lock(&a711->lock); -+ if (a711->is_open) { -+ spin_unlock(&a711->lock); -+ return -EBUSY; -+ } -+ -+ a711->is_open = 1; -+ spin_unlock(&a711->lock); -+ -+ nonseekable_open(ip, fp); -+ return 0; -+} -+ -+static const struct file_operations a711_fops = { -+ .owner = THIS_MODULE, -+ .read = a711_read, -+ .write = a711_write, -+ .poll = a711_poll, -+ .unlocked_ioctl = a711_ioctl, -+ .open = a711_open, -+ .release = a711_release, -+ .llseek = noop_llseek, -+}; -+ -+static irqreturn_t a711_wakeup_isr(int irq, void *dev_id) -+{ -+ struct a711_dev *a711 = dev_id; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&a711->lock, flags); -+ a711->got_wakeup = 1; -+ spin_unlock_irqrestore(&a711->lock, flags); -+ -+ wake_up_interruptible(&a711->waitqueue); -+ -+ return IRQ_HANDLED; -+} -+ -+static int a711_probe(struct platform_device *pdev) -+{ -+ struct a711_dev *a711; -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ struct device *sdev; -+ const char* cdev_name = NULL; -+ int ret; -+ -+ a711 = devm_kzalloc(dev, sizeof(*a711), GFP_KERNEL); -+ if (!a711) -+ return -ENOMEM; -+ -+ a711->dev = dev; -+ platform_set_drvdata(pdev, a711); -+ init_waitqueue_head(&a711->waitqueue); -+ spin_lock_init(&a711->lock); -+ INIT_WORK(&a711->work, &a711_work_handler); -+ -+ // get device name and reset time from device tree -+ ret = of_property_read_u32_index(np, "reset-duration-ms", 0, -+ &a711->reset_duration); -+ if (ret) { -+ a711->reset_duration = 10; -+ } -+ -+ ret = of_property_read_string(np, "char-device-name", &cdev_name); -+ if (ret) { -+ dev_err(dev, "char-device-name is not configured"); -+ return -EINVAL; -+ } -+ -+ a711->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH); -+ if (IS_ERR(a711->enable_gpio)) { -+ dev_err(dev, "can't get enable gpio err=%ld", -+ PTR_ERR(a711->enable_gpio)); -+ return PTR_ERR(a711->enable_gpio); -+ } -+ -+ a711->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); -+ if (IS_ERR(a711->reset_gpio)) { -+ dev_err(dev, "can't get reset gpio err=%ld", -+ PTR_ERR(a711->reset_gpio)); -+ return PTR_ERR(a711->reset_gpio); -+ } -+ -+ a711->wakeup_gpio = devm_gpiod_get_optional(dev, "wakeup", GPIOD_IN); -+ if (IS_ERR(a711->wakeup_gpio)) { -+ dev_err(dev, "can't get wakeup gpio err=%ld", -+ PTR_ERR(a711->wakeup_gpio)); -+ return PTR_ERR(a711->wakeup_gpio); -+ } -+ -+ a711->wakeup_irq = gpiod_to_irq(a711->wakeup_gpio); -+ if (a711->wakeup_irq > 0) { -+ ret = devm_request_irq(dev, a711->wakeup_irq, -+ a711_wakeup_isr, -+ IRQF_TRIGGER_RISING | -+ IRQF_TRIGGER_FALLING, -+ "a711-wakeup", a711); -+ if (ret) { -+ dev_err(dev, "error requesting wakeup-irq: %d", ret); -+ return ret; -+ } -+ } -+ -+ a711->regulator = devm_regulator_get_optional(dev, "power"); -+ if (IS_ERR(a711->regulator)) { -+ ret = PTR_ERR(a711->regulator); -+ if (ret != -ENODEV) { -+ dev_err(dev, "can't get power supply err=%d", ret); -+ return ret; -+ } -+ -+ a711->regulator = NULL; -+ } -+ -+ // create char device -+ ret = alloc_chrdev_region(&a711->major, 0, 1, "a711"); -+ if (ret) { -+ dev_err(dev, "can't allocate chrdev region"); -+ goto err_disable_regulator; -+ } -+ -+ cdev_init(&a711->cdev, &a711_fops); -+ a711->cdev.owner = THIS_MODULE; -+ ret = cdev_add(&a711->cdev, a711->major, 1); -+ if (ret) { -+ dev_err(dev, "can't add cdev"); -+ goto err_unreg_chrev_region; -+ } -+ -+ sdev = device_create(a711_class, dev, a711->major, a711, cdev_name); -+ if (IS_ERR(sdev)) { -+ ret = PTR_ERR(sdev); -+ goto err_del_cdev; -+ } -+ -+ gpiod_set_value(a711->enable_gpio, 0); -+ if (!a711->regulator) -+ gpiod_set_value(a711->reset_gpio, 1); -+ -+ dev_info(dev, "initialized TBS A711 platform driver"); -+ -+ return 0; -+ -+err_del_cdev: -+ cdev_del(&a711->cdev); -+err_unreg_chrev_region: -+ unregister_chrdev(a711->major, "a711"); -+err_disable_regulator: -+ cancel_work_sync(&a711->work); -+ return ret; -+} -+ -+static int a711_remove(struct platform_device *pdev) -+{ -+ struct a711_dev *a711 = platform_get_drvdata(pdev); -+ -+ a711_power_down(a711); -+ -+ cancel_work_sync(&a711->work); -+ -+ device_destroy(a711_class, a711->major); -+ cdev_del(&a711->cdev); -+ unregister_chrdev(a711->major, "a711"); -+ -+ if (a711->wakeup_irq > 0) -+ devm_free_irq(a711->dev, a711->wakeup_irq, a711); -+ -+ return 0; -+} -+ -+static const struct of_device_id a711_of_match[] = { -+ { .compatible = "custom,power-manager" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, a711_of_match); -+ -+static struct platform_driver a711_platform_driver = { -+ .probe = a711_probe, -+ .remove = a711_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .of_match_table = a711_of_match, -+ }, -+}; -+ -+static int __init a711_driver_init(void) -+{ -+ int ret; -+ -+ a711_class = class_create(THIS_MODULE, "a711"); -+ -+ ret = platform_driver_register(&a711_platform_driver); -+ if (ret) -+ class_destroy(a711_class); -+ -+ return ret; -+} -+ -+static void __exit a711_driver_exit(void) -+{ -+ platform_driver_unregister(&a711_platform_driver); -+ class_destroy(a711_class); -+} -+ -+module_init(a711_driver_init); -+module_exit(a711_driver_exit); -+ -+MODULE_VERSION("1.0.0"); -+MODULE_DESCRIPTION("TBS A711 Tablet Platform Driver"); -+MODULE_AUTHOR("Ondrej Jirman "); -+MODULE_LICENSE("GPL v2"); --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0049-ARM-dts-sun8i-a83t-Add-uart2-uart4.patch b/patch/kernel/sunxi-legacy/0000-0049-ARM-dts-sun8i-a83t-Add-uart2-uart4.patch deleted file mode 100644 index 64b025ed2..000000000 --- a/patch/kernel/sunxi-legacy/0000-0049-ARM-dts-sun8i-a83t-Add-uart2-uart4.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 1b732183172780283b7311bf0959b7ba7d4a4153 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Fri, 10 Nov 2017 22:21:29 +0100 -Subject: [PATCH 49/82] ARM: dts: sun8i-a83t: Add uart2-uart4 - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t.dtsi | 33 +++++++++++++++++++++++++++++++ - 1 file changed, 33 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi -index d9074f050a9c..788ecf540f55 100644 ---- a/arch/arm/boot/dts/sun8i-a83t.dtsi -+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi -@@ -880,6 +880,39 @@ - status = "disabled"; - }; - -+ uart2: serial@01c28800 { -+ compatible = "snps,dw-apb-uart"; -+ reg = <0x01c28800 0x400>; -+ interrupts = ; -+ reg-shift = <2>; -+ reg-io-width = <4>; -+ clocks = <&ccu CLK_BUS_UART2>; -+ resets = <&ccu RST_BUS_UART2>; -+ status = "disabled"; -+ }; -+ -+ uart3: serial@01c28c00 { -+ compatible = "snps,dw-apb-uart"; -+ reg = <0x01c28c00 0x400>; -+ interrupts = ; -+ reg-shift = <2>; -+ reg-io-width = <4>; -+ clocks = <&ccu CLK_BUS_UART3>; -+ resets = <&ccu RST_BUS_UART3>; -+ status = "disabled"; -+ }; -+ -+ uart4: serial@01c29000 { -+ compatible = "snps,dw-apb-uart"; -+ reg = <0x01c29000 0x400>; -+ interrupts = ; -+ reg-shift = <2>; -+ reg-io-width = <4>; -+ clocks = <&ccu CLK_BUS_UART4>; -+ resets = <&ccu RST_BUS_UART4>; -+ status = "disabled"; -+ }; -+ - i2c0: i2c@1c2ac00 { - compatible = "allwinner,sun8i-a83t-i2c", - "allwinner,sun6i-a31-i2c"; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0050-ARM-dts-sun8i-a83t-Add-uart2-PB-pins.patch b/patch/kernel/sunxi-legacy/0000-0050-ARM-dts-sun8i-a83t-Add-uart2-PB-pins.patch deleted file mode 100644 index 5b804e745..000000000 --- a/patch/kernel/sunxi-legacy/0000-0050-ARM-dts-sun8i-a83t-Add-uart2-PB-pins.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 8921a3bf53f233c746f591c58b2840963cee88a2 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Fri, 10 Nov 2017 22:22:44 +0100 -Subject: [PATCH 50/82] ARM: dts: sun8i-a83t: Add uart2 PB pins - -These are used on TBS A83T A711 tablet for GPS serial port. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t.dtsi | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi -index 788ecf540f55..a8ff7a8efe71 100644 ---- a/arch/arm/boot/dts/sun8i-a83t.dtsi -+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi -@@ -775,6 +775,11 @@ - pins = "PG8", "PG9"; - function = "uart1"; - }; -+ -+ uart2_pb_pins: uart2-pb-pins { -+ pins = "PB0", "PB1"; -+ function = "uart2"; -+ }; - }; - - timer@1c20c00 { --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0051-ARM-dts-sun8i-a83t-tbs-a711-Enable-uart2-and-add-gps.patch b/patch/kernel/sunxi-legacy/0000-0051-ARM-dts-sun8i-a83t-tbs-a711-Enable-uart2-and-add-gps.patch deleted file mode 100644 index 8a0da4658..000000000 --- a/patch/kernel/sunxi-legacy/0000-0051-ARM-dts-sun8i-a83t-tbs-a711-Enable-uart2-and-add-gps.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 9e45d6dd4dfcc8706081ee992b24acab372d845a Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Fri, 10 Nov 2017 22:24:15 +0100 -Subject: [PATCH 51/82] ARM: dts: sun8i-a83t-tbs-a711: Enable uart2 and add gps - regulator - -Now we can use tbs-a711 driver for power/reset control for GPS module. -Enable this. This allows access to u-blox NEO-6M connected to uart2. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index ab4dce4b1e67..b0a94cf13740 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -121,6 +121,15 @@ - }; - }; - -+ reg_gps: reg-gps { -+ compatible = "regulator-fixed"; -+ regulator-name = "gps"; -+ regulator-min-microvolt = <3000000>; -+ regulator-max-microvolt = <3000000>; -+ enable-active-high; -+ gpio = <&pio 3 4 GPIO_ACTIVE_HIGH>; /* PD4 */ -+ }; -+ - reg_vbat: reg-vbat { - compatible = "regulator-fixed"; - regulator-name = "vbat"; -@@ -149,6 +158,13 @@ - clocks = <&ac100_rtc 1>; - clock-names = "ext_clock"; - }; -+ -+ gps { -+ compatible = "custom,power-manager"; -+ power-supply = <®_gps>; -+ reset-duration-ms = <5>; -+ char-device-name = "pwr-gps"; -+ }; - }; - - &cpu0 { -@@ -564,6 +580,13 @@ - status = "okay"; - }; - -+/* GPS NEO-6M */ -+&uart2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart2_pb_pins>; -+ status = "okay"; -+}; -+ - &usb_otg { - dr_mode = "otg"; - status = "okay"; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0052-ARM-dts-sun8i-a83t-tbs-a711-Add-powerup-down-support.patch b/patch/kernel/sunxi-legacy/0000-0052-ARM-dts-sun8i-a83t-tbs-a711-Add-powerup-down-support.patch deleted file mode 100644 index 338c02251..000000000 --- a/patch/kernel/sunxi-legacy/0000-0052-ARM-dts-sun8i-a83t-tbs-a711-Add-powerup-down-support.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 747a078b6546e1bd51aa994a4b4da8d2a7b16882 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= - -Date: Thu, 6 Jul 2017 10:57:55 +0200 -Subject: [PATCH 52/82] ARM: dts: sun8i-a83t-tbs-a711: Add powerup/down support - for the 3G modem -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The modem needs tree gpios to be powered-up: - - PL10 = reset - - PL8 = On/Off - - PL9 = vbat -Because of that, the PL9 corresponds to the regulator's gpio whereas -the PL8 (on/off) will be a power-gpio of the power sequence. - -Thanks to that, the modem is powered up: - # lsusb - Bus 001 Device 004: ID 19d2:ffeb - -Signed-off-by: Ondrej Jirman -Signed-off-by: Mylène Josserand ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 17 ++++++++++++++++- - 1 file changed, 16 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index b0a94cf13740..f22da26557f2 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -142,8 +142,10 @@ - regulator-name = "vmain"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; -- gpio = <&r_pio 0 9 GPIO_ACTIVE_HIGH>; -+ gpio = <&r_pio 0 9 GPIO_ACTIVE_HIGH>; /* PL9 */ - enable-active-high; -+ //megi: See modem for comments -+ regulator-always-on; - vin-supply = <®_vbat>; - }; - -@@ -159,6 +161,19 @@ - clock-names = "ext_clock"; - }; - -+ modem { -+ compatible = "custom,power-manager"; -+ //megi: switching Q5 MOSFET probably leads to brownouts on -+ //VBAT due to larger capacities on VMAIN. Only use PL8 to -+ //enable/disable the modem -+ //power-supply = <®_vmain>; -+ enable-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */ -+ reset-gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; /* PL10 */ -+ wakeup-gpios = <&r_pio 0 11 GPIO_ACTIVE_HIGH>; /* PL11 */ -+ reset-duration-ms = <5>; -+ char-device-name = "pwr-modem"; -+ }; -+ - gps { - compatible = "custom,power-manager"; - power-supply = <®_gps>; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0053-ARM-dts-suni-a83t-Add-support-for-I2S-controller.patch b/patch/kernel/sunxi-legacy/0000-0053-ARM-dts-suni-a83t-Add-support-for-I2S-controller.patch deleted file mode 100644 index 0000e04ef..000000000 --- a/patch/kernel/sunxi-legacy/0000-0053-ARM-dts-suni-a83t-Add-support-for-I2S-controller.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 7e268d45be35f4355b8088980820da1858058d2b Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sun, 12 Nov 2017 19:03:08 +0100 -Subject: [PATCH 53/82] ARM: dts: suni-a83t: Add support for I2S controller - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t.dtsi | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi -index a8ff7a8efe71..147f76a66a28 100644 ---- a/arch/arm/boot/dts/sun8i-a83t.dtsi -+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi -@@ -304,6 +304,19 @@ - #size-cells = <1>; - ranges; - -+ dai: dai@01c23000 { -+ #sound-dai-cells = <0>; -+ compatible = "allwinner,sun8i-a83t-i2s"; -+ reg = <0x01c23000 0x200>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_TDM>, <&ccu CLK_TDM>; -+ clock-names = "apb", "mod"; -+ resets = <&ccu RST_BUS_TDM>; -+ dmas = <&dma 28>, <&dma 28>; -+ dma-names = "rx", "tx"; -+ status = "disabled"; -+ }; -+ - display_clocks: clock@1000000 { - compatible = "allwinner,sun8i-a83t-de2-clk"; - reg = <0x01000000 0x100000>; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0054-ARM-dts-suni-a83t-Add-i2s0-pins.patch b/patch/kernel/sunxi-legacy/0000-0054-ARM-dts-suni-a83t-Add-i2s0-pins.patch deleted file mode 100644 index 9f4e0e1af..000000000 --- a/patch/kernel/sunxi-legacy/0000-0054-ARM-dts-suni-a83t-Add-i2s0-pins.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0cd8e96aad9dde4264e30208d50abde35e1a8afa Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sun, 12 Nov 2017 19:03:39 +0100 -Subject: [PATCH 54/82] ARM: dts: suni-a83t: Add i2s0 pins - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t.dtsi | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi -index 147f76a66a28..c79f5a678e62 100644 ---- a/arch/arm/boot/dts/sun8i-a83t.dtsi -+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi -@@ -769,6 +769,11 @@ - function = "spdif"; - }; - -+ i2s0_pins: i2s0-pins { -+ pins = "PB4", "PB5", "PB6", "PB7", "PB8"; -+ function = "i2s0"; -+ }; -+ - uart0_pb_pins: uart0-pb-pins { - pins = "PB9", "PB10"; - function = "uart0"; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0055-ARM-dts-suni-a83t-tbs-a711-Enable-I2S0-for-communica.patch b/patch/kernel/sunxi-legacy/0000-0055-ARM-dts-suni-a83t-tbs-a711-Enable-I2S0-for-communica.patch deleted file mode 100644 index fdb28df47..000000000 --- a/patch/kernel/sunxi-legacy/0000-0055-ARM-dts-suni-a83t-tbs-a711-Enable-I2S0-for-communica.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 35ac1469ce7641092c44fb3bc0c6d4b0248e0597 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sun, 12 Nov 2017 19:04:55 +0100 -Subject: [PATCH 55/82] ARM: dts: suni-a83t-tbs-a711: Enable I2S0 for - communication with AC100 - -This will allow for sound playback after AC100 audio codec is -implemented. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index f22da26557f2..bc08c3c281c1 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -207,6 +207,12 @@ - }; - }; - -+&dai { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s0_pins>; -+}; -+ - &de { - status = "okay"; - }; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0056-sound-soc-ac100-codec-Initial-implementation.patch b/patch/kernel/sunxi-legacy/0000-0056-sound-soc-ac100-codec-Initial-implementation.patch deleted file mode 100644 index 4c6c5c9dd..000000000 --- a/patch/kernel/sunxi-legacy/0000-0056-sound-soc-ac100-codec-Initial-implementation.patch +++ /dev/null @@ -1,349 +0,0 @@ -From f45ece9d10522312ec1bfe2e564b1638644b2c1b Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sun, 12 Nov 2017 23:09:14 +0100 -Subject: [PATCH 56/82] sound: soc: ac100-codec: Initial implementation - -This driver provides AC100 codec controls. - -Note: This does not yet provide anything, it's just a skeleton -for a future driver. - -Signed-off-by: Ondrej Jirman ---- - sound/soc/sunxi/Kconfig | 11 ++ - sound/soc/sunxi/Makefile | 1 + - sound/soc/sunxi/ac100-codec.c | 291 ++++++++++++++++++++++++++++++++++ - 3 files changed, 303 insertions(+) - create mode 100644 sound/soc/sunxi/ac100-codec.c - -diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig -index 22408bc2d6ec..e276cc94a8c5 100644 ---- a/sound/soc/sunxi/Kconfig -+++ b/sound/soc/sunxi/Kconfig -@@ -20,6 +20,17 @@ config SND_SUN8I_CODEC - - Say Y or M if you want to add sun8i digital audio codec support. - -+config SND_AC100_CODEC -+ tristate "Allwinner (X-Powers) AC100 audio codec" -+ depends on OF -+ depends on MACH_SUN8I || COMPILE_TEST -+ select REGMAP_MMIO -+ help -+ This option enables the audio codec support for Allwinner (X-Powers) -+ AC100 chip. -+ -+ Say Y or M if you want to add AC100 audio codec support. -+ - config SND_SUN8I_CODEC_ANALOG - tristate "Allwinner sun8i Codec Analog Controls Support" - depends on MACH_SUN8I || (ARM64 && ARCH_SUNXI) || COMPILE_TEST -diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile -index 4a9ef67386ca..83461fdbfaa2 100644 ---- a/sound/soc/sunxi/Makefile -+++ b/sound/soc/sunxi/Makefile -@@ -4,3 +4,4 @@ obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o - obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o - obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o - obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o -+obj-$(CONFIG_SND_AC100_CODEC) += ac100-codec.o -diff --git a/sound/soc/sunxi/ac100-codec.c b/sound/soc/sunxi/ac100-codec.c -new file mode 100644 -index 000000000000..d5438815be75 ---- /dev/null -+++ b/sound/soc/sunxi/ac100-codec.c -@@ -0,0 +1,291 @@ -+/* -+ * This driver supports the controls for X-Powers (Allwinner) -+ * AC100 audio codec. This codec is co-packaged with AXP81x PMICs. -+ * -+ * (C) Copyright 2017 Ondrej Jirman -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+/* -+ * Reasearch -+ * --------- -+ * -+ * Features: -+ * 2 A/D -+ * 2 D/A -+ * 2 I2S/PCM #1 and #2 -+ * 1 PCM mono #3 muxable with I2S #2 -+ * 3 mic inputs (mic #2 and #3 exclusively muxable at input) -+ * 1 line in (directly or through amp) -+ * 1 aux input -+ * all input signals mixable directly into output (bypass AD/DA) -+ * -+ * outputs: -+ * HPOUTL - headphone left -+ * HPOUTR - headphone right -+ * LINEOUT - line out differential -+ * EAROUT - earpeiece differential -+ * SPKOUT1 - SPOL left speaker differnetial -+ * SPKOUT2 - SPOR right speaker differnetial -+ * -+ * Power up: -+ * LDOIN - 1.5-3.3V external power -+ * AVCC - analog power 3V -+ * CPVDD - 1.8V -+ * VDD-IO1 - power for I2S #1 and #2 1.8/3V -+ * VDD-IO2 - power for I2S #3 1.8/3V -+ * VCC-RTC - power for RTC 1.8/3V -+ * -+ * Clocks: page 28 -+ * SYSCLK must be 24576000 Hz (48kHz) or 22579200 Hz (44.1kHz) -+ * - Source I2S1CLK/MCLK1 -+ * - If SRC# module is used SYSCLK must be generated by PLL -+ * -+ * A/D: -+ * ADC_APC_CTRL B15 B11 enable/disable A/D to save power -+ * ADC_APC_CTRL B14-12 B10-8 volume control for A/D -+ * ADC_DIG_CTRL B15 enable/disable digital A/D to save power -+ * ADDA_FS_I2S1 ADDA_FS_I2S2 - select sample rate -+ * -+ * D/A: -+ * OMIXER_DACA_CTRL B15-14 enable/disable D/A channels -+ * DAC_DIG_CTRL B15 enable/disable digital D/A -+ * -+ * Mixer: -+ * - 2 channels DAC Output mixers -+ * - inputs: -+ * - LINEINL/R -+ * - AXIL/R -+ * - MIC1P/N,MIC2P/N -+ * - Stereo DAC output -+ * - 2 channels ADC Record mixers -+ * - inputs: -+ * - LINEINL/R -+ * - AXIL/R -+ * - MIC1P/N,MIC2P/N -+ * - Stereo DAC output -+ * - Digital mixers -+ * - avaliable on: -+ * - before stereo DAC - DAC_MXR_SRC -+ * - I2S1 output - I2S1_MXR_SRC -+ * - I2S2 output - I2S2_MXR_SRC -+ * - Analogue inputs -+ * - LINEINL/R - 1 ch. mono -+ * - can be mixed into ADC record mixer or DAC output mixer -+ * - -9dB to 12dB in 1.5dB step by LINEIN_DIFF_PREG -+ * - AXIL/R - 2 ch. stereo -+ * - can be mixed into ADC record mixer or DAC output mixer -+ * - programmable volume level adj. and mute -+ * - -9dB to 12dB in 1.5dB steps by AXI_PREG -+ * - MIC1P/N - has preamp -+ * - MIC2P/N - has preamp -+ * - MIC3P/N - has preamp muxed with MIC2 (sel by ADC_SRCBST_CTRL B7) -+ * - can be mixed into ADC record mixer or DAC output mixer -+ * - preamps enable at ADC_SRCBST_CTRL B15 and B11 -+ * - preamp gain at MIC1BOOST MIC2BOOST -+ * - Analogue outputs: -+ * - HPOUTL/R, HPOUTFB - 2ch. headphones -+ * - sources output mixer or directly from DAC -+ * - sel HPOUT_CTRL B15 B14 -+ * - mute HPOUT_CTRL B13 B12 -+ * - power amp -+ * - powerdown/up HPOUT_CTRL B11 -+ * - volume HP_VOL[5:0] - 64dB range in 1dB step from 0dB to -62dB -+ * - mute by using 0 for HP_VOL[5:0] -+ * - DC offset cancellation (POP noise) HP_DCRM_EN -+ * - This bit must be set 0xf before headphone PA enabled, and this bit -+ * must be set 0x0 before headphone PA disabled. -+ * - zero cross to prevent noise/clicsk on volume change ZCROSS_EN -+ * - SPOLP/N, SPORP/N 2 ch. speakers (mono/stereo) -+ * - source for SPOLP -+ * - left output mixer or (left+right) output mixer -+ * - source for SPORP -+ * - right output mixer or (left+right) output mixer -+ * - volume 43.5dB rang in 1.5dB step from -43.5dB to 0dB -+ * - amp enable SPKOUT_CTRL B11 B7 -+ * - EAROUTP/N - 1 ch earpeice -+ * - source left DAC, right DAC, left output mixer or right output mixer -+ * - volume ERPOUT_CTRL[4:0] 43.5dB range in 1.5dB step from -43.5dB to 0dB -+ * - power amp enable ERPOUT_CTRL B5 -+ * - LINEOUTP/N - 1ch line out -+ * - source MIC1 preamp, MIC2 preamp, left output mix or right output mix -+ * - volume 10.5dB range in 1.5dB step from -4.5dB to 6dB -+ * - out buffer power up/down LOUT_CTRL B4 -+ * -+ * Jack insert detection: -+ * - HBIAS current detection -+ * - 5bit ADC sample rate 16/32/64/128Hz -+ * - HMIC_STATUS[12:8] - ADC value -+ * - 2 thresholds TH1 for plug connection, TH2 for key press -+ * - can periodically trigger interrupts during key press (HBIAS above TH2) -+ * -+ * Interrupts: -+ * - FALLING_EDGE -+ * - for: -+ * - KEYDOWN -+ * - KEYUP -+ * - PLUG_IN -+ * - PLUG_OUT -+ * - HMIC_DATA -+ * -+ * High Pass Filter: -+ * - remove DC offset, can be disabled -+ * -+ * AGC: -+ * - automatic gain control before ADC input channels -+ * - params: -+ * - attack, decay time - 32/fs to 2^15*32/fs -+ * - target gain - –1dB to –30dB relative to a full-scale signal -+ * - noise threshold - –30dB to –90dB of full-scale (mute if input below this level) -+ * - max gain 0dB to 40dB in steps of 0.5dB -+ * - hysteresis - for noise detection in terms of signal level -+ * - debounce time - hysteresis for noise det in terms of time -+ * - also provides some output flags: -+ * - noise threshold reached -+ * - current gain -+ * - agc saturated (gain could get higher for the given input, but limited by -+ * params) -+ * - adc saturated - clipping at ADC input stage -+ * -+ * DRC: -+ * - dynamic range control for digital playback path -+ * - energy filter -+ * - compressor -+ * - smooth filter -+ * - can be disabled -+ */ -+ -+#define AC100_HMIC_DATA_MASK GENMASK(12, 8) -+#define AC100_HMIC_DATA_OFF 8 -+#define AC100_HMIC_PULLOUT_PENDING BIT(4) -+#define AC100_HMIC_PLUGIN_PENDING BIT(3) -+#define AC100_HMIC_KEYUP_PENDING BIT(2) -+#define AC100_HMIC_KEYDOWN_PENDING BIT(1) -+#define AC100_HMIC_DATA_PENDING BIT(0) -+ -+struct ac100_codec { -+ struct device *dev; -+ struct regmap *regmap; -+ int irq; -+}; -+ -+static irqreturn_t ac100_codec_irq(int irq, void *data) -+{ -+ struct ac100_codec *codec = data; -+ unsigned int val = 0; -+ int ret; -+ -+ /* read status */ -+ ret = regmap_read(codec->regmap, AC100_HMIC_STATUS, &val); -+ if (ret) -+ return IRQ_HANDLED; -+ -+ if (val & AC100_HMIC_PULLOUT_PENDING) { -+ dev_info(codec->dev, "IRQ: Pull out"); -+ } -+ -+ if (val & AC100_HMIC_PLUGIN_PENDING) { -+ dev_info(codec->dev, "IRQ: Plug in"); -+ } -+ -+ if (val & AC100_HMIC_KEYUP_PENDING) { -+ dev_info(codec->dev, "IRQ: Key up"); -+ } -+ -+ if (val & AC100_HMIC_KEYDOWN_PENDING) { -+ dev_info(codec->dev, "IRQ: Key down"); -+ } -+ -+ if (val & AC100_HMIC_DATA_PENDING) { -+ dev_info(codec->dev, "IRQ: Data"); -+ } -+ -+ /* clear status */ -+ ret = regmap_write(codec->regmap, AC100_HMIC_STATUS, 0); -+ if (ret) -+ return IRQ_HANDLED; -+ -+ return IRQ_HANDLED; -+} -+ -+static int ac100_codec_probe(struct platform_device *pdev) -+{ -+ struct ac100_dev *ac100 = dev_get_drvdata(pdev->dev.parent); -+ struct ac100_codec *codec; -+ int ret; -+ -+ codec = devm_kzalloc(&pdev->dev, sizeof(*codec), GFP_KERNEL); -+ if (!codec) -+ return -ENOMEM; -+ -+ platform_set_drvdata(pdev, codec); -+ codec->dev = &pdev->dev; -+ codec->regmap = ac100->regmap; -+ -+ codec->irq = platform_get_irq(pdev, 0); -+ if (codec->irq < 0) { -+ dev_err(&pdev->dev, "No IRQ resource\n"); -+ return codec->irq; -+ } -+ -+ ret = devm_request_threaded_irq(&pdev->dev, codec->irq, NULL, -+ ac100_codec_irq, -+ IRQF_SHARED | IRQF_ONESHOT, -+ dev_name(&pdev->dev), codec); -+ if (ret) { -+ dev_err(&pdev->dev, "Could not request IRQ\n"); -+ return ret; -+ } -+ -+ return ret; -+} -+ -+static int ac100_codec_remove(struct platform_device *pdev) -+{ -+ struct snd_soc_card *card = platform_get_drvdata(pdev); -+ struct ac100_codec *codec = snd_soc_card_get_drvdata(card); -+ -+ return 0; -+} -+ -+static const struct of_device_id ac100_codec_of_match[] = { -+ { .compatible = "x-powers,ac100-codec" }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, ac100_codec_of_match); -+ -+static struct platform_driver ac100_codec_driver = { -+ .driver = { -+ .name = "ac100-codec", -+ .of_match_table = ac100_codec_of_match, -+ }, -+ .probe = ac100_codec_probe, -+ .remove = ac100_codec_remove, -+}; -+module_platform_driver(ac100_codec_driver); -+ -+MODULE_DESCRIPTION("X-Powers AC100 codec driver"); -+MODULE_AUTHOR("Ondrej Jirman "); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:ac100-codec"); --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0057-leds-axp20x-Support-leds-on-AXP20x-like-PMICs-AXP813.patch b/patch/kernel/sunxi-legacy/0000-0057-leds-axp20x-Support-leds-on-AXP20x-like-PMICs-AXP813.patch deleted file mode 100644 index 017a439b5..000000000 --- a/patch/kernel/sunxi-legacy/0000-0057-leds-axp20x-Support-leds-on-AXP20x-like-PMICs-AXP813.patch +++ /dev/null @@ -1,209 +0,0 @@ -From fc9173d7b8adaa12f8abd125bde351fe17add031 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Tue, 14 Nov 2017 02:47:19 +0100 -Subject: [PATCH 57/82] leds: axp20x: Support leds on AXP20x like PMICs, AXP813 - at first - -There is single led that can be turned on and off. - -Signed-off-by: Ondrej Jirman ---- - drivers/leds/Kconfig | 8 +++ - drivers/leds/Makefile | 1 + - drivers/leds/leds-axp20x.c | 138 +++++++++++++++++++++++++++++++++++++ - drivers/mfd/axp20x.c | 3 + - 4 files changed, 150 insertions(+) - create mode 100644 drivers/leds/leds-axp20x.c - -diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig -index 44097a3e0fcc..a0cbdbb2c450 100644 ---- a/drivers/leds/Kconfig -+++ b/drivers/leds/Kconfig -@@ -756,6 +756,14 @@ config LEDS_NIC78BX - To compile this driver as a module, choose M here: the module - will be called leds-nic78bx. - -+config LEDS_AXP20X -+ tristate "LED support for AXP20X-like PMICs (AXP813, ...)" -+ depends on LEDS_CLASS && MFD_AXP20X -+ help -+ This option enables support for on-chip LED drivers on -+ AXP20X-like PMICs. -+ -+ - comment "LED Triggers" - source "drivers/leds/trigger/Kconfig" - -diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile -index 420b5d2cfa62..a8149fb6e2d4 100644 ---- a/drivers/leds/Makefile -+++ b/drivers/leds/Makefile -@@ -78,6 +78,7 @@ obj-$(CONFIG_LEDS_MT6323) += leds-mt6323.o - obj-$(CONFIG_LEDS_LM3692X) += leds-lm3692x.o - obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o - obj-$(CONFIG_LEDS_LM3601X) += leds-lm3601x.o -+obj-$(CONFIG_LEDS_AXP20X) += leds-axp20x.o - - # LED SPI Drivers - obj-$(CONFIG_LEDS_CR0014114) += leds-cr0014114.o -diff --git a/drivers/leds/leds-axp20x.c b/drivers/leds/leds-axp20x.c -new file mode 100644 -index 000000000000..de33c1d83054 ---- /dev/null -+++ b/drivers/leds/leds-axp20x.c -@@ -0,0 +1,138 @@ -+/* -+ * LED Driver for X-Powers AXP813 PMIC. -+ * -+ * Copyright(c) 2017 Ondrej Jirman -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define AXP813_CHGLED_CTRL_MASK BIT(3) -+#define AXP813_CHGLED_CTRL_CHARGER BIT(3) -+#define AXP813_CHGLED_CTRL_USER 0 -+ -+#define AXP813_CHGLED_USER_STATE_MASK GENMASK(5, 4) -+#define AXP813_CHGLED_USER_STATE_OFFSET 4 -+#define AXP813_CHGLED_USER_STATE_OFF 0 -+#define AXP813_CHGLED_USER_STATE_BLINK_SLOW 1 -+#define AXP813_CHGLED_USER_STATE_BLINK_FAST 2 -+#define AXP813_CHGLED_USER_STATE_ON 3 -+ -+struct axp20x_led { -+ struct led_classdev cdev; -+ struct regmap *regmap; -+}; -+ -+static int axp20x_led_set(struct led_classdev *led_cdev, -+ enum led_brightness value) -+{ -+ struct axp20x_led *led = -+ container_of(led_cdev, struct axp20x_led, cdev); -+ unsigned int val; -+ -+ val = value == LED_OFF ? AXP813_CHGLED_USER_STATE_OFF : -+ AXP813_CHGLED_USER_STATE_ON; -+ -+ return regmap_update_bits(led->regmap, AXP20X_OFF_CTRL, -+ AXP813_CHGLED_USER_STATE_MASK, -+ val << AXP813_CHGLED_USER_STATE_OFFSET); -+ -+} -+ -+static int axp20x_led_probe(struct platform_device *pdev) -+{ -+ struct axp20x_dev *axp20x; -+ struct axp20x_led *led; -+ int ret; -+ -+ if (!of_device_is_available(pdev->dev.of_node)) -+ return -ENODEV; -+ -+ axp20x = dev_get_drvdata(pdev->dev.parent); -+ if (!axp20x) -+ return -EINVAL; -+ -+ led = devm_kzalloc(&pdev->dev, -+ sizeof(struct axp20x_led), -+ GFP_KERNEL); -+ if (!led) -+ return -ENOMEM; -+ -+ led->regmap = axp20x->regmap; -+ -+ led->cdev.name = "chgled"; -+ led->cdev.brightness_set_blocking = axp20x_led_set; -+ led->cdev.brightness = LED_OFF; -+ led->cdev.max_brightness = 1; -+ -+ ret = led_classdev_register(pdev->dev.parent, &led->cdev); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to register led %s\n", -+ led->cdev.name); -+ return ret; -+ } -+ -+ ret = regmap_update_bits(led->regmap, AXP20X_OFF_CTRL, -+ AXP813_CHGLED_CTRL_MASK, -+ AXP813_CHGLED_CTRL_USER); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to enable user cnotrol\n"); -+ } -+ -+ ret = axp20x_led_set(&led->cdev, led->cdev.brightness); -+ if (ret) { -+ dev_err(&pdev->dev, "Failed to init led %s\n", -+ led->cdev.name); -+ } -+ -+ platform_set_drvdata(pdev, led); -+ return 0; -+} -+ -+static int axp20x_led_remove(struct platform_device *pdev) -+{ -+ struct axp20x_led *led = platform_get_drvdata(pdev); -+ -+ axp20x_led_set(&led->cdev, LED_OFF); -+ -+ regmap_update_bits(led->regmap, AXP20X_OFF_CTRL, -+ AXP813_CHGLED_CTRL_MASK, -+ AXP813_CHGLED_CTRL_CHARGER); -+ -+ led_classdev_unregister(&led->cdev); -+ -+ return 0; -+} -+ -+static const struct of_device_id axp20x_leds_of_match[] = { -+ { .compatible = "x-powers,axp813-leds", }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, axp20x_leds_of_match); -+ -+static struct platform_driver axp20x_led_driver = { -+ .driver = { -+ .name = "axp20x-leds", -+ .of_match_table = axp20x_leds_of_match, -+ }, -+ .probe = axp20x_led_probe, -+ .remove = axp20x_led_remove, -+}; -+ -+module_platform_driver(axp20x_led_driver); -+ -+MODULE_AUTHOR("Ondrej Jirman "); -+MODULE_DESCRIPTION("LED driver for AXP813 PMIC"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:leds-axp20x"); -diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c -index 81bf6ee4d8bb..ba616c1f28db 100644 ---- a/drivers/mfd/axp20x.c -+++ b/drivers/mfd/axp20x.c -@@ -802,6 +802,9 @@ static const struct mfd_cell axp813_cells[] = { - }, { - .name = "axp20x-usb-power-supply", - .of_compatible = "x-powers,axp813-usb-power-supply", -+ }, { -+ .name = "axp20x-leds", -+ .of_compatible = "x-powers,axp813-leds", - }, { - .name = "reg-userspace-consumer", - .platform_data = &vcc_vb_data, --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0058-ARM-dts-axp813-Enable-power-supply-led-control.patch b/patch/kernel/sunxi-legacy/0000-0058-ARM-dts-axp813-Enable-power-supply-led-control.patch deleted file mode 100644 index 8d588a50f..000000000 --- a/patch/kernel/sunxi-legacy/0000-0058-ARM-dts-axp813-Enable-power-supply-led-control.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 4bfe82217af51730d9d3dfe04509f7d415de7d53 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Tue, 14 Nov 2017 02:47:51 +0100 -Subject: [PATCH 58/82] ARM: dts: axp813: Enable power supply led control - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/axp81x.dtsi | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm/boot/dts/axp81x.dtsi b/arch/arm/boot/dts/axp81x.dtsi -index f32a8ba53b85..6f4ea939b6ea 100644 ---- a/arch/arm/boot/dts/axp81x.dtsi -+++ b/arch/arm/boot/dts/axp81x.dtsi -@@ -170,4 +170,8 @@ - usb_power_supply: usb-power-supply { - compatible = "x-powers,axp813-usb-power-supply"; - }; -+ -+ power_supply_leds: power-supply-leds { -+ compatible = "x-powers,axp813-leds"; -+ }; - }; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0059-ARM-dts-sun8i-a83t-Describe-A83T-thermal-zones.patch b/patch/kernel/sunxi-legacy/0000-0059-ARM-dts-sun8i-a83t-Describe-A83T-thermal-zones.patch deleted file mode 100644 index 468b7a94b..000000000 --- a/patch/kernel/sunxi-legacy/0000-0059-ARM-dts-sun8i-a83t-Describe-A83T-thermal-zones.patch +++ /dev/null @@ -1,82 +0,0 @@ -From fcf4b68c77f7ce86a1976322cbb1f861962f8a66 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Tue, 14 Nov 2017 17:16:45 +0100 -Subject: [PATCH 59/82] ARM: dts: sun8i-a83t: Describe A83T thermal zones - -There are three sensors, two for CPU, one for GPU. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t.dtsi | 36 +++++++++++++++++++++++++++++++ - 1 file changed, 36 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi -index c79f5a678e62..bffcee058627 100644 ---- a/arch/arm/boot/dts/sun8i-a83t.dtsi -+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi -@@ -50,6 +50,7 @@ - #include - #include - #include -+#include - - / { - interrupt-parent = <&gic>; -@@ -69,6 +70,9 @@ - cci-control-port = <&cci_control0>; - enable-method = "allwinner,sun8i-a83t-smp"; - reg = <0>; -+ #cooling-cells = <2>; -+ cooling-min-level = <0>; -+ cooling-max-level = <7>; - }; - - cpu@1 { -@@ -107,6 +111,9 @@ - cci-control-port = <&cci_control1>; - enable-method = "allwinner,sun8i-a83t-smp"; - reg = <0x100>; -+ #cooling-cells = <2>; -+ cooling-min-level = <0>; -+ cooling-max-level = <7>; - }; - - cpu@101 { -@@ -1108,5 +1115,34 @@ - #address-cells = <1>; - #size-cells = <0>; - }; -+ -+ ths: ths@1f04000 { -+ #thermal-sensor-cells = <1>; -+ compatible = "allwinner,sun8i-a83t-ths"; -+ reg = <0x01f04000 0x100 0x01c14234 0x8>; -+ reg-names = "ths", "calibration"; -+ interrupts = ; -+ status = "disabled"; -+ }; -+ }; -+ -+ thermal-zones { -+ cpu0_thermal: cpu0-thermal { -+ polling-delay-passive = <330>; -+ polling-delay = <1000>; -+ thermal-sensors = <&ths 0>; -+ }; -+ -+ cpu1_thermal: cpu1-thermal { -+ polling-delay-passive = <330>; -+ polling-delay = <1000>; -+ thermal-sensors = <&ths 1>; -+ }; -+ -+ gpu_thermal: gpu-thermal { -+ polling-delay-passive = <330>; -+ polling-delay = <1000>; -+ thermal-sensors = <&ths 2>; -+ }; - }; - }; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0060-ARM-dts-sun8i-a83t-tbs-a711-Enable-thermal-sensor.patch b/patch/kernel/sunxi-legacy/0000-0060-ARM-dts-sun8i-a83t-tbs-a711-Enable-thermal-sensor.patch deleted file mode 100644 index 93f07c7c4..000000000 --- a/patch/kernel/sunxi-legacy/0000-0060-ARM-dts-sun8i-a83t-tbs-a711-Enable-thermal-sensor.patch +++ /dev/null @@ -1,28 +0,0 @@ -From a73c51c6adf95985d02f22670f45bc8d6a84739c Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Tue, 14 Nov 2017 17:17:14 +0100 -Subject: [PATCH 60/82] ARM: dts: sun8i-a83t-tbs-a711: Enable thermal sensor - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index bc08c3c281c1..ed59185b9105 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -588,6 +588,10 @@ - }; - }; - -+&ths { -+ status = "okay"; -+}; -+ - &uart0 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pb_pins>; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0061-ARM-dts-sun8i-a83t-tbs-a711-Enable-thermal-regulatio.patch b/patch/kernel/sunxi-legacy/0000-0061-ARM-dts-sun8i-a83t-tbs-a711-Enable-thermal-regulatio.patch deleted file mode 100644 index 625d88c92..000000000 --- a/patch/kernel/sunxi-legacy/0000-0061-ARM-dts-sun8i-a83t-tbs-a711-Enable-thermal-regulatio.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 387b028e45a8c5a2fde464aba13138eb6b8df532 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Tue, 14 Nov 2017 17:18:35 +0100 -Subject: [PATCH 61/82] ARM: dts: sun8i-a83t-tbs-a711: Enable thermal - regulation of CPU frequency - -Not very well tested for it's thermal properties, yet. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 44 +++++++++++++++++++++++ - 1 file changed, 44 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index ed59185b9105..99c5df15b036 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -190,6 +190,50 @@ - cpu-supply = <®_dcdc3>; - }; - -+&cpu0_thermal { -+ trips { -+ cpu0_hot: cpu_hot { -+ temperature = <65000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ cpu0_very_hot: cpu_very_hot { -+ temperature = <90000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ -+ cooling-maps { -+ cpu_hot_limit { -+ trip = <&cpu0_hot>; -+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -+ }; -+ }; -+}; -+ -+&cpu1_thermal { -+ trips { -+ cpu1_hot: cpu_hot { -+ temperature = <65000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ cpu1_very_hot: cpu_very_hot { -+ temperature = <90000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ -+ cooling-maps { -+ cpu_hot_limit { -+ trip = <&cpu1_hot>; -+ cooling-device = <&cpu100 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -+ }; -+ }; -+}; -+ - &csi0 { - status = "okay"; - pinctrl-names = "default"; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0062-ARM-dts-sun8i-a83t-tbs-Increase-voltage-on-the-vibra.patch b/patch/kernel/sunxi-legacy/0000-0062-ARM-dts-sun8i-a83t-tbs-Increase-voltage-on-the-vibra.patch deleted file mode 100644 index 22a49d37d..000000000 --- a/patch/kernel/sunxi-legacy/0000-0062-ARM-dts-sun8i-a83t-tbs-Increase-voltage-on-the-vibra.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 379fee744cb1fa4370ac692bc890e5e1182e337d Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Fri, 8 Dec 2017 12:44:22 +0100 -Subject: [PATCH 62/82] ARM: dts: sun8i-a83t-tbs: Increase voltage on the - vibrator - -To make it less sluggish. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index 99c5df15b036..ea7b8bf4d327 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -608,8 +608,8 @@ - }; - - ®_ldo_io1 { -- regulator-min-microvolt = <3100000>; -- regulator-max-microvolt = <3100000>; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; - regulator-name = "vcc-vb"; - status = "okay"; - }; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0063-phy-sun4i-usb-Add-DT-property-to-force-ID-VBUS-polli.patch b/patch/kernel/sunxi-legacy/0000-0063-phy-sun4i-usb-Add-DT-property-to-force-ID-VBUS-polli.patch deleted file mode 100644 index ae6705aff..000000000 --- a/patch/kernel/sunxi-legacy/0000-0063-phy-sun4i-usb-Add-DT-property-to-force-ID-VBUS-polli.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 9a7e926353d5aea2d78ce507ae5bb3537cbccbed Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Tue, 12 Dec 2017 14:04:19 +0100 -Subject: [PATCH 63/82] phy: sun4i-usb: Add DT property to force ID/VBUS - polling - -In some cases interrupts on GPIO don't fire for whatever reason. -Allow to force polling of ID/VBUS detection pins from DT. - -Signed-off-by: Ondrej Jirman ---- - drivers/phy/allwinner/phy-sun4i-usb.c | 44 ++++++++++++++------------- - 1 file changed, 23 insertions(+), 21 deletions(-) - -diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c -index 1f8809bab002..1cbb01c41d8d 100644 ---- a/drivers/phy/allwinner/phy-sun4i-usb.c -+++ b/drivers/phy/allwinner/phy-sun4i-usb.c -@@ -816,29 +816,31 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) - phy_set_drvdata(phy->phy, &data->phys[i]); - } - -- data->id_det_irq = gpiod_to_irq(data->id_det_gpio); -- if (data->id_det_irq > 0) { -- ret = devm_request_irq(dev, data->id_det_irq, -- sun4i_usb_phy0_id_vbus_det_irq, -- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -- "usb0-id-det", data); -- if (ret) { -- dev_err(dev, "Err requesting id-det-irq: %d\n", ret); -- return ret; -+ if (!of_find_property(np, "force-poll-vbus-id-det", NULL)) { -+ data->id_det_irq = gpiod_to_irq(data->id_det_gpio); -+ if (data->id_det_irq > 0) { -+ ret = devm_request_irq(dev, data->id_det_irq, -+ sun4i_usb_phy0_id_vbus_det_irq, -+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -+ "usb0-id-det", data); -+ if (ret) { -+ dev_err(dev, "Err requesting id-det-irq: %d\n", ret); -+ return ret; -+ } - } -- } - -- data->vbus_det_irq = gpiod_to_irq(data->vbus_det_gpio); -- if (data->vbus_det_irq > 0) { -- ret = devm_request_irq(dev, data->vbus_det_irq, -- sun4i_usb_phy0_id_vbus_det_irq, -- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -- "usb0-vbus-det", data); -- if (ret) { -- dev_err(dev, "Err requesting vbus-det-irq: %d\n", ret); -- data->vbus_det_irq = -1; -- sun4i_usb_phy_remove(pdev); /* Stop detect work */ -- return ret; -+ data->vbus_det_irq = gpiod_to_irq(data->vbus_det_gpio); -+ if (data->vbus_det_irq > 0) { -+ ret = devm_request_irq(dev, data->vbus_det_irq, -+ sun4i_usb_phy0_id_vbus_det_irq, -+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, -+ "usb0-vbus-det", data); -+ if (ret) { -+ dev_err(dev, "Err requesting vbus-det-irq: %d\n", ret); -+ data->vbus_det_irq = -1; -+ sun4i_usb_phy_remove(pdev); /* Stop detect work */ -+ return ret; -+ } - } - } - --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0064-ARM-dts-sun8i-a83t-tbs-a711-Enable-force-poll-vbus-i.patch b/patch/kernel/sunxi-legacy/0000-0064-ARM-dts-sun8i-a83t-tbs-a711-Enable-force-poll-vbus-i.patch deleted file mode 100644 index f01e29a68..000000000 --- a/patch/kernel/sunxi-legacy/0000-0064-ARM-dts-sun8i-a83t-tbs-a711-Enable-force-poll-vbus-i.patch +++ /dev/null @@ -1,27 +0,0 @@ -From a279c17434fbeaf040a553b6ce856ccbd00580f7 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Tue, 12 Dec 2017 14:06:13 +0100 -Subject: [PATCH 64/82] ARM: dts: sun8i-a83t-tbs-a711: Enable - force-poll-vbus-id-det on usbphy - -A83T doesn't fire interrupts on PH11. Force polling. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index ea7b8bf4d327..028dd29e13d7 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -666,5 +666,6 @@ - usb0_vbus-supply = <®_drivevbus>; - usb1_vbus_supply = <®_vmain>; - usb2_vbus_supply = <®_vmain>; -+ force-poll-vbus-id-det; - status = "okay"; - }; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0065-arm-dts-sun8i-a83t-tbs-a711-GPS-regulator-is-apparen.patch b/patch/kernel/sunxi-legacy/0000-0065-arm-dts-sun8i-a83t-tbs-a711-GPS-regulator-is-apparen.patch deleted file mode 100644 index fdad06e70..000000000 --- a/patch/kernel/sunxi-legacy/0000-0065-arm-dts-sun8i-a83t-tbs-a711-GPS-regulator-is-apparen.patch +++ /dev/null @@ -1,29 +0,0 @@ -From f8b601516e29a67496d98414b2477928d79eb3eb Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Tue, 12 Dec 2017 16:15:26 +0100 -Subject: [PATCH 65/82] arm: dts: sun8i-a83t-tbs-a711: GPS regulator is - apparently fixed - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index 028dd29e13d7..027c6a76627f 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -127,7 +127,9 @@ - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; - enable-active-high; -- gpio = <&pio 3 4 GPIO_ACTIVE_HIGH>; /* PD4 */ -+ /*XXX: this doesn't control GPS regulator, shematics show FLAG -+ * pin */ -+ //gpio = <&pio 3 4 GPIO_ACTIVE_HIGH>; /* PD4 */ - }; - - reg_vbat: reg-vbat { --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0066-WIP-Figure-out-how-to-use-new-bluetooth-OF-driver-bi.patch b/patch/kernel/sunxi-legacy/0000-0066-WIP-Figure-out-how-to-use-new-bluetooth-OF-driver-bi.patch deleted file mode 100644 index cea784c8e..000000000 --- a/patch/kernel/sunxi-legacy/0000-0066-WIP-Figure-out-how-to-use-new-bluetooth-OF-driver-bi.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 8a91463b53e778e876ca296882fd3285e02d129f Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Mon, 25 Dec 2017 22:05:19 +0100 -Subject: [PATCH 66/82] WIP: Figure out how to use new bluetooth/OF driver - binding for BT chip - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index 027c6a76627f..8bba9ccd2592 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -649,6 +649,16 @@ - pinctrl-names = "default"; - pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; - status = "okay"; -+ -+/* -+ bluetooth { -+ compatible = "brcm,bcm43438-bt"; -+ //max-speed = <921600>; -+ shutdown-gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; -+ device-wakeup-gpios = <&pio 7 5 GPIO_ACTIVE_HIGH>; -+ //host-wakeup-gpios = <&r_pio 0 5 GPIO_ACTIVE_HIGH>; -+ }; -+ */ - }; - - /* GPS NEO-6M */ --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0067-mmc-add-delay-after-power-class-selection.patch b/patch/kernel/sunxi-legacy/0000-0067-mmc-add-delay-after-power-class-selection.patch deleted file mode 100644 index 93ff36776..000000000 --- a/patch/kernel/sunxi-legacy/0000-0067-mmc-add-delay-after-power-class-selection.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 2fecbde6fd1e7de568f19caaed3e0db75ac2d585 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Fri, 16 Mar 2018 20:31:55 +0100 -Subject: [PATCH 67/82] mmc: add delay after power class selection - -This seems to fix issue with sporadic ETIMEOUT in eMMC cache -initialization on second generation TBS A711 tablet. - -Signed-off-by: Ondrej Jirman ---- - drivers/mmc/core/mmc.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c -index f1fe446eee66..b29991135375 100644 ---- a/drivers/mmc/core/mmc.c -+++ b/drivers/mmc/core/mmc.c -@@ -1770,6 +1770,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, - */ - mmc_select_powerclass(card); - -+ msleep(20); -+ - /* - * Enable HPI feature (if supported) - */ -@@ -1789,6 +1791,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, - } - } - -+ msleep(20); -+ - /* - * If cache size is higher than 0, this indicates the existence of cache - * and it can be turned on. Note that some eMMCs from Micron has been --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0068-ARM-dts-sun8i-a83t-Add-clock-frequency-to-avoid-boot.patch b/patch/kernel/sunxi-legacy/0000-0068-ARM-dts-sun8i-a83t-Add-clock-frequency-to-avoid-boot.patch deleted file mode 100644 index b92a181aa..000000000 --- a/patch/kernel/sunxi-legacy/0000-0068-ARM-dts-sun8i-a83t-Add-clock-frequency-to-avoid-boot.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 0ab580b2eac299d7f73c2ff3e7bf590a3fc7ea6d Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Fri, 20 Apr 2018 04:05:28 +0200 -Subject: [PATCH 68/82] ARM: dts: sun8i-a83t: Add clock-frequency to avoid boot - warnings - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t.dtsi | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi -index bffcee058627..c09d8ee2f7c5 100644 ---- a/arch/arm/boot/dts/sun8i-a83t.dtsi -+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi -@@ -65,6 +65,7 @@ - clocks = <&ccu CLK_C0CPUX>; - clock-names = "cpu"; - compatible = "arm,cortex-a7"; -+ clock-frequency = <1200000000>; - device_type = "cpu"; - operating-points-v2 = <&cpu0_opp_table>; - cci-control-port = <&cci_control0>; -@@ -77,6 +78,7 @@ - - cpu@1 { - compatible = "arm,cortex-a7"; -+ clock-frequency = <1200000000>; - device_type = "cpu"; - operating-points-v2 = <&cpu0_opp_table>; - cci-control-port = <&cci_control0>; -@@ -86,6 +88,7 @@ - - cpu@2 { - compatible = "arm,cortex-a7"; -+ clock-frequency = <1200000000>; - device_type = "cpu"; - operating-points-v2 = <&cpu0_opp_table>; - cci-control-port = <&cci_control0>; -@@ -95,6 +98,7 @@ - - cpu@3 { - compatible = "arm,cortex-a7"; -+ clock-frequency = <1200000000>; - device_type = "cpu"; - operating-points-v2 = <&cpu0_opp_table>; - cci-control-port = <&cci_control0>; -@@ -106,6 +110,7 @@ - clocks = <&ccu CLK_C1CPUX>; - clock-names = "cpu"; - compatible = "arm,cortex-a7"; -+ clock-frequency = <1200000000>; - device_type = "cpu"; - operating-points-v2 = <&cpu1_opp_table>; - cci-control-port = <&cci_control1>; -@@ -118,6 +123,7 @@ - - cpu@101 { - compatible = "arm,cortex-a7"; -+ clock-frequency = <1200000000>; - device_type = "cpu"; - operating-points-v2 = <&cpu1_opp_table>; - cci-control-port = <&cci_control1>; -@@ -127,6 +133,7 @@ - - cpu@102 { - compatible = "arm,cortex-a7"; -+ clock-frequency = <1200000000>; - device_type = "cpu"; - operating-points-v2 = <&cpu1_opp_table>; - cci-control-port = <&cci_control1>; -@@ -136,6 +143,7 @@ - - cpu@103 { - compatible = "arm,cortex-a7"; -+ clock-frequency = <1200000000>; - device_type = "cpu"; - operating-points-v2 = <&cpu1_opp_table>; - cci-control-port = <&cci_control1>; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0069-media-hm5065-Port-to-4.17-drop-use-of-s_parm-g_parm-.patch b/patch/kernel/sunxi-legacy/0000-0069-media-hm5065-Port-to-4.17-drop-use-of-s_parm-g_parm-.patch deleted file mode 100644 index 6a4b25027..000000000 --- a/patch/kernel/sunxi-legacy/0000-0069-media-hm5065-Port-to-4.17-drop-use-of-s_parm-g_parm-.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 46beb097c9452520035e13c03c4ec0a66288c56b Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Fri, 20 Apr 2018 04:02:26 +0200 -Subject: [PATCH 69/82] media: hm5065: Port to 4.17 - drop use of s_parm/g_parm - callbacks - ---- - drivers/media/i2c/hm5065.c | 42 -------------------------------------- - 1 file changed, 42 deletions(-) - -diff --git a/drivers/media/i2c/hm5065.c b/drivers/media/i2c/hm5065.c -index 1f0896bd8dff..07308e190494 100644 ---- a/drivers/media/i2c/hm5065.c -+++ b/drivers/media/i2c/hm5065.c -@@ -1801,46 +1801,6 @@ static int hm5065_enum_frame_interval( - return 0; - } - --static int hm5065_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) --{ -- struct v4l2_captureparm *cp = &parms->parm.capture; -- struct v4l2_subdev_frame_interval fi; -- int ret; -- -- if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) -- return -EINVAL; -- -- cp->capability = V4L2_CAP_TIMEPERFRAME; -- fi.pad = 0; -- ret = hm5065_g_frame_interval(sd, &fi); -- if (ret) -- return ret; -- -- cp->timeperframe = fi.interval; -- return 0; --} -- --static int hm5065_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) --{ -- struct v4l2_captureparm *cp = &parms->parm.capture; -- struct v4l2_subdev_frame_interval fi; -- int ret; -- -- if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) -- return -EINVAL; -- -- fi.pad = 0; -- fi.interval = cp->timeperframe; -- cp->capability = V4L2_CAP_TIMEPERFRAME; -- -- ret = hm5065_s_frame_interval(sd, &fi); -- if (ret) -- return ret; -- -- cp->timeperframe = fi.interval; -- return 0; --} -- - static int hm5065_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *format) -@@ -2125,8 +2085,6 @@ static const struct v4l2_subdev_pad_ops hm5065_pad_ops = { - static const struct v4l2_subdev_video_ops hm5065_video_ops = { - .g_frame_interval = hm5065_g_frame_interval, - .s_frame_interval = hm5065_s_frame_interval, -- .g_parm = hm5065_g_parm, -- .s_parm = hm5065_s_parm, - .s_stream = hm5065_s_stream, - }; - --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0070-media-sun6i-csi-Port-to-4.17-use-v4l2_g_parm_cap-v4l.patch b/patch/kernel/sunxi-legacy/0000-0070-media-sun6i-csi-Port-to-4.17-use-v4l2_g_parm_cap-v4l.patch deleted file mode 100644 index 09959dfe0..000000000 --- a/patch/kernel/sunxi-legacy/0000-0070-media-sun6i-csi-Port-to-4.17-use-v4l2_g_parm_cap-v4l.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0499b2f267962ce5e4c56d9be15f1366a524bb88 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Fri, 20 Apr 2018 04:03:28 +0200 -Subject: [PATCH 70/82] media: sun6i-csi: Port to 4.17 - use - v4l2_g_parm_cap/v4l2_s_parm_cap helpers - -Signed-off-by: Ondrej Jirman ---- - drivers/media/platform/sun6i-csi/sun6i_csi.c | 13 ++----------- - 1 file changed, 2 insertions(+), 11 deletions(-) - -diff --git a/drivers/media/platform/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sun6i-csi/sun6i_csi.c -index 2bd746c3efc4..3d13e26b2312 100644 ---- a/drivers/media/platform/sun6i-csi/sun6i_csi.c -+++ b/drivers/media/platform/sun6i-csi/sun6i_csi.c -@@ -454,21 +454,16 @@ static int sun6i_enum_frameintervals(struct file *file, void *priv, - return 0; - } - -- - static int sun6i_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) - { - struct sun6i_csi *csi = video_drvdata(file); - struct sun6i_csi_subdev *csi_sd; - -- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) -- return -EINVAL; -- - csi_sd = sun6i_get_enabled_subdev(csi); - if (csi_sd == NULL) - return -ENXIO; - -- a->parm.capture.readbuffers = 0; -- return v4l2_subdev_call(csi_sd->sd, video, g_parm, a); -+ return v4l2_g_parm_cap(video_devdata(file), csi_sd->sd, a); - } - - static int sun6i_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) -@@ -476,15 +471,11 @@ static int sun6i_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) - struct sun6i_csi *csi = video_drvdata(file); - struct sun6i_csi_subdev *csi_sd; - -- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) -- return -EINVAL; -- - csi_sd = sun6i_get_enabled_subdev(csi); - if (csi_sd == NULL) - return -ENXIO; - -- a->parm.capture.readbuffers = 0; -- return v4l2_subdev_call(csi_sd->sd, video, s_parm, a); -+ return v4l2_g_parm_cap(video_devdata(file), csi_sd->sd, a); - } - - static int sun6i_enum_input(struct file *file, void *priv, --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0071-ARM-dts-sun8i-a83t-Add-missing-clock-properties-to-c.patch b/patch/kernel/sunxi-legacy/0000-0071-ARM-dts-sun8i-a83t-Add-missing-clock-properties-to-c.patch deleted file mode 100644 index abd3dd1d6..000000000 --- a/patch/kernel/sunxi-legacy/0000-0071-ARM-dts-sun8i-a83t-Add-missing-clock-properties-to-c.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 3bfe739a6da69c2a51dbd6d4288975bedaee04f8 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sat, 30 Jun 2018 07:58:15 +0200 -Subject: [PATCH 71/82] ARM: dts: sun8i-a83t: Add missing clock properties to - cpu nodes - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t.dtsi | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi -index c09d8ee2f7c5..17371e0614e2 100644 ---- a/arch/arm/boot/dts/sun8i-a83t.dtsi -+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi -@@ -77,6 +77,8 @@ - }; - - cpu@1 { -+ clocks = <&ccu CLK_C0CPUX>; -+ clock-names = "cpu"; - compatible = "arm,cortex-a7"; - clock-frequency = <1200000000>; - device_type = "cpu"; -@@ -87,6 +89,8 @@ - }; - - cpu@2 { -+ clocks = <&ccu CLK_C0CPUX>; -+ clock-names = "cpu"; - compatible = "arm,cortex-a7"; - clock-frequency = <1200000000>; - device_type = "cpu"; -@@ -97,6 +101,8 @@ - }; - - cpu@3 { -+ clocks = <&ccu CLK_C0CPUX>; -+ clock-names = "cpu"; - compatible = "arm,cortex-a7"; - clock-frequency = <1200000000>; - device_type = "cpu"; -@@ -122,6 +128,8 @@ - }; - - cpu@101 { -+ clocks = <&ccu CLK_C1CPUX>; -+ clock-names = "cpu"; - compatible = "arm,cortex-a7"; - clock-frequency = <1200000000>; - device_type = "cpu"; -@@ -132,6 +140,8 @@ - }; - - cpu@102 { -+ clocks = <&ccu CLK_C1CPUX>; -+ clock-names = "cpu"; - compatible = "arm,cortex-a7"; - clock-frequency = <1200000000>; - device_type = "cpu"; -@@ -142,6 +152,8 @@ - }; - - cpu@103 { -+ clocks = <&ccu CLK_C1CPUX>; -+ clock-names = "cpu"; - compatible = "arm,cortex-a7"; - clock-frequency = <1200000000>; - device_type = "cpu"; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0072-ARM-dts-sun8i-a83t-Add-missing-cooling-cells-propert.patch b/patch/kernel/sunxi-legacy/0000-0072-ARM-dts-sun8i-a83t-Add-missing-cooling-cells-propert.patch deleted file mode 100644 index fd4e10f3a..000000000 --- a/patch/kernel/sunxi-legacy/0000-0072-ARM-dts-sun8i-a83t-Add-missing-cooling-cells-propert.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 6352f285dc5071be981ac30d72b4fbd11bed7fcd Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sat, 30 Jun 2018 07:58:54 +0200 -Subject: [PATCH 72/82] ARM: dts: sun8i-a83t: Add missing cooling-cells - properties to cpu nodes - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t.dtsi | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi -index 17371e0614e2..cb0607580d04 100644 ---- a/arch/arm/boot/dts/sun8i-a83t.dtsi -+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi -@@ -72,8 +72,6 @@ - enable-method = "allwinner,sun8i-a83t-smp"; - reg = <0>; - #cooling-cells = <2>; -- cooling-min-level = <0>; -- cooling-max-level = <7>; - }; - - cpu@1 { -@@ -86,6 +84,7 @@ - cci-control-port = <&cci_control0>; - enable-method = "allwinner,sun8i-a83t-smp"; - reg = <1>; -+ #cooling-cells = <2>; - }; - - cpu@2 { -@@ -98,6 +97,7 @@ - cci-control-port = <&cci_control0>; - enable-method = "allwinner,sun8i-a83t-smp"; - reg = <2>; -+ #cooling-cells = <2>; - }; - - cpu@3 { -@@ -110,6 +110,7 @@ - cci-control-port = <&cci_control0>; - enable-method = "allwinner,sun8i-a83t-smp"; - reg = <3>; -+ #cooling-cells = <2>; - }; - - cpu100: cpu@100 { -@@ -123,8 +124,6 @@ - enable-method = "allwinner,sun8i-a83t-smp"; - reg = <0x100>; - #cooling-cells = <2>; -- cooling-min-level = <0>; -- cooling-max-level = <7>; - }; - - cpu@101 { -@@ -137,6 +136,7 @@ - cci-control-port = <&cci_control1>; - enable-method = "allwinner,sun8i-a83t-smp"; - reg = <0x101>; -+ #cooling-cells = <2>; - }; - - cpu@102 { -@@ -149,6 +149,7 @@ - cci-control-port = <&cci_control1>; - enable-method = "allwinner,sun8i-a83t-smp"; - reg = <0x102>; -+ #cooling-cells = <2>; - }; - - cpu@103 { -@@ -161,6 +162,7 @@ - cci-control-port = <&cci_control1>; - enable-method = "allwinner,sun8i-a83t-smp"; - reg = <0x103>; -+ #cooling-cells = <2>; - }; - }; - --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0073-ARM-dts-sun8i-a83t-Add-labels-to-all-cpu-nodes.patch b/patch/kernel/sunxi-legacy/0000-0073-ARM-dts-sun8i-a83t-Add-labels-to-all-cpu-nodes.patch deleted file mode 100644 index 67d01e55b..000000000 --- a/patch/kernel/sunxi-legacy/0000-0073-ARM-dts-sun8i-a83t-Add-labels-to-all-cpu-nodes.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 99c501a975040dd3a233d5ec6193c5a9f32d7b2e Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sat, 30 Jun 2018 07:59:21 +0200 -Subject: [PATCH 73/82] ARM: dts: sun8i-a83t: Add labels to all cpu nodes - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t.dtsi | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi -index cb0607580d04..7b87029904bc 100644 ---- a/arch/arm/boot/dts/sun8i-a83t.dtsi -+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi -@@ -74,7 +74,7 @@ - #cooling-cells = <2>; - }; - -- cpu@1 { -+ cpu1: cpu@1 { - clocks = <&ccu CLK_C0CPUX>; - clock-names = "cpu"; - compatible = "arm,cortex-a7"; -@@ -87,7 +87,7 @@ - #cooling-cells = <2>; - }; - -- cpu@2 { -+ cpu2: cpu@2 { - clocks = <&ccu CLK_C0CPUX>; - clock-names = "cpu"; - compatible = "arm,cortex-a7"; -@@ -100,7 +100,7 @@ - #cooling-cells = <2>; - }; - -- cpu@3 { -+ cpu3: cpu@3 { - clocks = <&ccu CLK_C0CPUX>; - clock-names = "cpu"; - compatible = "arm,cortex-a7"; -@@ -126,7 +126,7 @@ - #cooling-cells = <2>; - }; - -- cpu@101 { -+ cpu101: cpu@101 { - clocks = <&ccu CLK_C1CPUX>; - clock-names = "cpu"; - compatible = "arm,cortex-a7"; -@@ -139,7 +139,7 @@ - #cooling-cells = <2>; - }; - -- cpu@102 { -+ cpu102: cpu@102 { - clocks = <&ccu CLK_C1CPUX>; - clock-names = "cpu"; - compatible = "arm,cortex-a7"; -@@ -152,7 +152,7 @@ - #cooling-cells = <2>; - }; - -- cpu@103 { -+ cpu103: cpu@103 { - clocks = <&ccu CLK_C1CPUX>; - clock-names = "cpu"; - compatible = "arm,cortex-a7"; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0074-Allow-to-disable-cluster2-on-A83T-permanently.patch b/patch/kernel/sunxi-legacy/0000-0074-Allow-to-disable-cluster2-on-A83T-permanently.patch deleted file mode 100644 index 8ad924da5..000000000 --- a/patch/kernel/sunxi-legacy/0000-0074-Allow-to-disable-cluster2-on-A83T-permanently.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 177d470754881e3cff95d90e6b6d79d96ae92ccd Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sat, 28 Jul 2018 00:42:25 +0200 -Subject: [PATCH 74/82] Allow to disable cluster2 on A83T permanently - -Hotplug is broken for now. Therfore this. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 8 ++++++++ - arch/arm/boot/dts/sun8i-a83t.dtsi | 4 ++++ - 2 files changed, 12 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index 8bba9ccd2592..7a1b6154cda9 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -41,6 +41,8 @@ - * OTHER DEALINGS IN THE SOFTWARE. - */ - -+#define A83T_C1_DISABLE -+ - /dts-v1/; - #include "sun8i-a83t.dtsi" - -@@ -188,9 +190,11 @@ - cpu-supply = <®_dcdc2>; - }; - -+#ifndef A83T_C1_DISABLE - &cpu100 { - cpu-supply = <®_dcdc3>; - }; -+#endif - - &cpu0_thermal { - trips { -@@ -214,6 +218,7 @@ - }; - }; - -+#ifndef A83T_C1_DISABLE - &cpu1_thermal { - trips { - cpu1_hot: cpu_hot { -@@ -235,6 +240,7 @@ - }; - }; - }; -+#endif - - &csi0 { - status = "okay"; -@@ -516,7 +522,9 @@ - ®_dcdc3 { - regulator-min-microvolt = <700000>; - regulator-max-microvolt = <1100000>; -+#ifndef A83T_C1_DISABLE - regulator-always-on; -+#endif - regulator-name = "vdd-cpu-B"; - }; - -diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi -index 7b87029904bc..0bc7482744d7 100644 ---- a/arch/arm/boot/dts/sun8i-a83t.dtsi -+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi -@@ -113,6 +113,7 @@ - #cooling-cells = <2>; - }; - -+#ifndef A83T_C1_DISABLE - cpu100: cpu@100 { - clocks = <&ccu CLK_C1CPUX>; - clock-names = "cpu"; -@@ -164,6 +165,7 @@ - reg = <0x103>; - #cooling-cells = <2>; - }; -+#endif - }; - - timer { -@@ -274,6 +276,7 @@ - }; - }; - -+#ifndef A83T_C1_DISABLE - cpu1_opp_table: opp_table1 { - compatible = "operating-points-v2"; - opp-shared; -@@ -326,6 +329,7 @@ - clock-latency-ns = <244144>; /* 8 32k periods */ - }; - }; -+#endif - - soc { - compatible = "simple-bus"; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0075-Make-microbuttons-on-Orange-Pi-PC-and-PC-2-work-as-p.patch b/patch/kernel/sunxi-legacy/0000-0075-Make-microbuttons-on-Orange-Pi-PC-and-PC-2-work-as-p.patch deleted file mode 100644 index d1a66e964..000000000 --- a/patch/kernel/sunxi-legacy/0000-0075-Make-microbuttons-on-Orange-Pi-PC-and-PC-2-work-as-p.patch +++ /dev/null @@ -1,54 +0,0 @@ -From dc476b21de3ab98df3b94514d995bf4fc0fa0db4 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Fri, 18 Aug 2017 13:55:48 +0200 -Subject: [PATCH 75/82] Make microbuttons on Orange Pi PC and PC 2 work as - power off buttons - ---- - arch/arm/boot/dts/sun8i-h3-orangepi-one.dts | 2 +- - arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts | 2 +- - arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-one.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-one.dts -index 245fd658defb..a30c4fae5466 100644 ---- a/arch/arm/boot/dts/sun8i-h3-orangepi-one.dts -+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-one.dts -@@ -95,7 +95,7 @@ - - sw4 { - label = "sw4"; -- linux,code = ; -+ linux,code = ; - gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>; - }; - }; -diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts -index 83f1866ed9e7..056cb587f3c0 100644 ---- a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts -+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts -@@ -95,7 +95,7 @@ - - sw4 { - label = "sw4"; -- linux,code = ; -+ linux,code = ; - gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>; - }; - }; -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts -index af8e3fe26e20..4846d76dd908 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts -@@ -98,7 +98,7 @@ - - sw4 { - label = "sw4"; -- linux,code = ; -+ linux,code = ; - gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>; - }; - }; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0076-arm64-dts-sun50i-h5-Add-mali-GPU-node.patch b/patch/kernel/sunxi-legacy/0000-0076-arm64-dts-sun50i-h5-Add-mali-GPU-node.patch deleted file mode 100644 index 0e931f60d..000000000 --- a/patch/kernel/sunxi-legacy/0000-0076-arm64-dts-sun50i-h5-Add-mali-GPU-node.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 30bbeb66d0f9cc6f49cc95e60443eeca952b119c Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sat, 30 Jun 2018 07:55:34 +0200 -Subject: [PATCH 76/82] arm64: dts: sun50i-h5: Add mali GPU node - -https://github.com/jernejsk/LibreELEC.tv/blob/aw_h5_init/projects/Allwinner/devices/H5/patches/linux/20-add-mali-node.patch ---- - arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 38 ++++++++++++++++++++ - 1 file changed, 38 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -index acd90f390e88..67e2246a6374 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -@@ -94,6 +94,44 @@ - method = "smc"; - }; - -+ soc { -+ mali: gpu@1280000 { -+ compatible = "allwinner,sun50i-h5-mali", -+ "arm,mali-450"; -+ reg = <0x01e80000 0x30000>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ interrupt-names = "gp", -+ "gpmmu", -+ "pmu", -+ "pp", -+ "pp0", -+ "ppmmu0", -+ "pp1", -+ "ppmmu1", -+ "pp2", -+ "ppmmu2", -+ "pp3", -+ "ppmmu3"; -+ clocks = <&ccu CLK_BUS_GPU>, <&ccu CLK_GPU>; -+ clock-names = "bus", "core"; -+ resets = <&ccu RST_BUS_GPU>; -+ -+ assigned-clocks = <&ccu CLK_GPU>; -+ assigned-clock-rates = <384000000>; -+ }; -+ }; -+ - timer { - compatible = "arm,armv8-timer"; - interrupts = -Date: Thu, 8 Mar 2018 17:16:22 +0100 -Subject: [PATCH 77/82] drm/bridge/synopsys: dw_hdmi: Add a quirk to - automatically set CTS - -On some SoCs with DW HDMI, like Allwinner H3, HDMI audio doesn't work -well if CTS is not set automatically. Add a quirk for it. - -Signed-off-by: Jernej Skrabec ---- - drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 26 ++++++++++++++--------- - include/drm/bridge/dw_hdmi.h | 2 ++ - 2 files changed, 18 insertions(+), 10 deletions(-) - -diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -index 5971976284bf..822d0093a990 100644 ---- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -@@ -424,16 +424,22 @@ static struct i2c_adapter *dw_hdmi_i2c_adapter(struct dw_hdmi *hdmi) - static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts, - unsigned int n) - { -- /* Must be set/cleared first */ -- hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); -- -- /* nshift factor = 0 */ -- hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3); -- -- hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) | -- HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); -- hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2); -- hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1); -+ if (!hdmi->plat_data->auto_cts) { -+ /* Must be set/cleared first */ -+ hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); -+ -+ /* nshift factor = 0 */ -+ hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3); -+ -+ hdmi_writeb(hdmi, -+ ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) | -+ HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); -+ hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2); -+ hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1); -+ } else { -+ /* set automatic CTS calculation */ -+ hdmi_writeb(hdmi, 0x00, HDMI_AUD_CTS3); -+ } - - hdmi_writeb(hdmi, (n >> 16) & 0x0f, HDMI_AUD_N3); - hdmi_writeb(hdmi, (n >> 8) & 0xff, HDMI_AUD_N2); -diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h -index ccb5aa8468e0..b6a878455364 100644 ---- a/include/drm/bridge/dw_hdmi.h -+++ b/include/drm/bridge/dw_hdmi.h -@@ -129,6 +129,8 @@ struct dw_hdmi_plat_data { - unsigned long input_bus_format; - unsigned long input_bus_encoding; - -+ bool auto_cts; -+ - /* Vendor PHY support */ - const struct dw_hdmi_phy_ops *phy_ops; - const char *phy_name; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0078-drm-sun4i-Enable-auto_cts-quirk-for-DW-HDMI.patch b/patch/kernel/sunxi-legacy/0000-0078-drm-sun4i-Enable-auto_cts-quirk-for-DW-HDMI.patch deleted file mode 100644 index f0747e6ff..000000000 --- a/patch/kernel/sunxi-legacy/0000-0078-drm-sun4i-Enable-auto_cts-quirk-for-DW-HDMI.patch +++ /dev/null @@ -1,30 +0,0 @@ -From aab02e1c386fa2ab761aea583b59ce72824f70c4 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Thu, 8 Mar 2018 17:21:29 +0100 -Subject: [PATCH 78/82] drm/sun4i: Enable auto_cts quirk for DW HDMI - -Allwinner SoCs with DW HDMI don't output any sound if auto CTS option is -not enabled. - -Enable it. - -Signed-off-by: Jernej Skrabec ---- - drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c -index 31875b636434..9aaec57f7441 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c -+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c -@@ -156,6 +156,7 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, - - sun8i_hdmi_phy_init(hdmi->phy); - -+ plat_data->auto_cts = true; - plat_data->mode_valid = &sun8i_dw_hdmi_mode_valid; - plat_data->phy_ops = sun8i_hdmi_phy_get_ops(); - plat_data->phy_name = "sun8i_dw_hdmi_phy"; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0079-HACK-Enable-HDMI-audio-on-H3-H5.patch b/patch/kernel/sunxi-legacy/0000-0079-HACK-Enable-HDMI-audio-on-H3-H5.patch deleted file mode 100644 index 86cb0ca1a..000000000 --- a/patch/kernel/sunxi-legacy/0000-0079-HACK-Enable-HDMI-audio-on-H3-H5.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0bc585fb429d295cd9ff0f35326e52e212053af2 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Thu, 8 Mar 2018 17:23:01 +0100 -Subject: [PATCH 79/82] HACK: Enable HDMI audio on H3/H5 - -This is quick way to enable HDMI audio, but it is not a proper way to do -it. - -Signed-off-by: Jernej Skrabec ---- - arch/arm/boot/dts/sunxi-h3-h5.dtsi | 30 ++++++++++++++++++++++++++++++ - 1 file changed, 30 insertions(+) - -diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -index 3b8b2234ab4d..586ce53fc058 100644 ---- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi -+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -@@ -743,6 +743,35 @@ - status = "disabled"; - }; - -+ i2s2: i2s@1c22800 { -+ #sound-dai-cells = <0>; -+ compatible = "allwinner,sun8i-h3-i2s"; -+ reg = <0x01c22800 0x400>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_I2S2>, <&ccu CLK_I2S2>; -+ clock-names = "apb", "mod"; -+ dmas = <&dma 27>; -+ resets = <&ccu RST_BUS_I2S2>; -+ dma-names = "tx"; -+ //status = "disabled"; -+ }; -+ -+ sound_hdmi: sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,name = "allwinner,hdmi"; -+ simple-audio-card,mclk-fs = <256>; -+ //status = "disabled"; -+ -+ simple-audio-card,codec { -+ sound-dai = <&hdmi>; -+ }; -+ -+ simple-audio-card,cpu { -+ sound-dai = <&i2s2>; -+ }; -+ }; -+ - codec: codec@1c22c00 { - #sound-dai-cells = <0>; - compatible = "allwinner,sun8i-h3-codec"; -@@ -860,6 +889,7 @@ - }; - - hdmi: hdmi@1ee0000 { -+ #sound-dai-cells = <0>; - compatible = "allwinner,sun8i-h3-dw-hdmi", - "allwinner,sun8i-a83t-dw-hdmi"; - reg = <0x01ee0000 0x10000>; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0080-Add-support-for-my-private-Sapomat-device.patch b/patch/kernel/sunxi-legacy/0000-0080-Add-support-for-my-private-Sapomat-device.patch deleted file mode 100644 index 785a7d05b..000000000 --- a/patch/kernel/sunxi-legacy/0000-0080-Add-support-for-my-private-Sapomat-device.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 75347dd025a7da146944c69c724dbd6d24e10100 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Fri, 18 Aug 2017 13:56:06 +0200 -Subject: [PATCH 80/82] Add support for my private Sapomat device - ---- - arch/arm/boot/dts/Makefile | 1 + - .../boot/dts/sun8i-h3-orangepi-pc-sapomat.dts | 34 +++++++++++++++++++ - 2 files changed, 35 insertions(+) - create mode 100644 arch/arm/boot/dts/sun8i-h3-orangepi-pc-sapomat.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index b5bd3de87c33..c3720b0ffbe1 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -1043,6 +1043,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \ - sun8i-h3-orangepi-lite.dtb \ - sun8i-h3-orangepi-one.dtb \ - sun8i-h3-orangepi-pc.dtb \ -+ sun8i-h3-orangepi-pc-sapomat.dtb \ - sun8i-h3-orangepi-pc-plus.dtb \ - sun8i-h3-orangepi-plus.dtb \ - sun8i-h3-orangepi-plus2e.dtb \ -diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-pc-sapomat.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-pc-sapomat.dts -new file mode 100644 -index 000000000000..55c82d5fb63f ---- /dev/null -+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-pc-sapomat.dts -@@ -0,0 +1,34 @@ -+#include -+#include -+#include "sun8i-h3-orangepi-pc.dts" -+ -+/ { -+ model = "Xunlong Orange Pi PC Sapomat"; -+ -+ sapomat_gpio_keys { -+ compatible = "gpio-keys-polled"; -+ poll-interval = <50>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sapomat_btn_pins>; -+ -+ red_btn { -+ label = "Red Button"; -+ linux,code = ; -+ gpios = <&pio 2 4 GPIO_ACTIVE_LOW>; /* PC4 */ -+ }; -+ -+ green_btn { -+ label = "Green Button"; -+ linux,code = ; -+ gpios = <&pio 2 7 GPIO_ACTIVE_LOW>; /* PC7 */ -+ }; -+ }; -+}; -+ -+&pio { -+ sapomat_btn_pins: btn_pins@0 { -+ pins = "PC4", "PC7"; -+ function = "gpio_in"; -+ bias-pull-up; -+ }; -+}; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0081-Support-Castles-Vega5000-PoS-terminal-USB.patch b/patch/kernel/sunxi-legacy/0000-0081-Support-Castles-Vega5000-PoS-terminal-USB.patch deleted file mode 100644 index 7ecff2eab..000000000 --- a/patch/kernel/sunxi-legacy/0000-0081-Support-Castles-Vega5000-PoS-terminal-USB.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 499a575b5a0eb15899fdf3d79292b44e030d542a Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Sat, 24 Mar 2018 19:30:22 +0100 -Subject: [PATCH 81/82] Support Castles Vega5000 PoS terminal USB - -Signed-off-by: Ondrej Jirman ---- - drivers/usb/class/cdc-acm.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c -index 5b442bc68a76..7352548a7e6f 100644 ---- a/drivers/usb/class/cdc-acm.c -+++ b/drivers/usb/class/cdc-acm.c -@@ -1769,6 +1769,9 @@ static const struct usb_device_id acm_ids[] = { - { USB_DEVICE(0x22b8, 0x2d9a), /* modem + AT port + diagnostics + NMEA */ - .driver_info = NO_UNION_NORMAL, /* handle only modem interface */ - }, -+ { USB_DEVICE(0x0ca6, 0xa050), /* Castles Technology VEGA 5000 */ -+ .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ -+ }, - - { USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */ - .driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-0082-ARM-dts-sun8i-a83t-tbs-a711-Change-MMC0-bus-width-to.patch b/patch/kernel/sunxi-legacy/0000-0082-ARM-dts-sun8i-a83t-tbs-a711-Change-MMC0-bus-width-to.patch deleted file mode 100644 index 52420836d..000000000 --- a/patch/kernel/sunxi-legacy/0000-0082-ARM-dts-sun8i-a83t-tbs-a711-Change-MMC0-bus-width-to.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 81f714ab3bd523c7d8644e8d7b85544252c12dc4 Mon Sep 17 00:00:00 2001 -From: Ondrej Jirman -Date: Mon, 15 Oct 2018 04:28:07 +0200 -Subject: [PATCH 82/82] ARM: dts: sun8i-a83t-tbs-a711: Change MMC0 bus-width to - 4 - -The actual hardware has 4 data lines. Use them. - -Signed-off-by: Ondrej Jirman ---- - arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -index 7a1b6154cda9..f320f915b413 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts -@@ -402,6 +402,7 @@ - vmmc-supply = <®_dcdc1>; - pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins>; -+ bus-width = <4>; - cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; - status = "okay"; - }; --- -2.20.1 - diff --git a/patch/kernel/sunxi-legacy/0000-remove-old-ths-node.patch b/patch/kernel/sunxi-legacy/0000-remove-old-ths-node.patch deleted file mode 100644 index ca2a2b658..000000000 --- a/patch/kernel/sunxi-legacy/0000-remove-old-ths-node.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -index 586ce53fc..e72c24470 100644 ---- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi -+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -@@ -590,19 +590,6 @@ - }; - }; - -- ths: ths@1c25000 { -- #thermal-sensor-cells = <0>; -- compatible = "allwinner,sun8i-h3-ths"; -- reg = <0x01c25000 0x400>, -- <0x01c14234 0x4>; -- reg-names = "ths", "calibration"; -- interrupts = ; -- resets = <&ccu RST_BUS_THS>; -- reset-names = "ahb"; -- clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_THS>; -- clock-names = "ahb", "ths"; -- }; -- - timer@1c20c00 { - compatible = "allwinner,sun4i-a10-timer"; - reg = <0x01c20c00 0xa0>; diff --git a/patch/kernel/sunxi-legacy/0000-unlock-h5-dvfs.patch b/patch/kernel/sunxi-legacy/0000-unlock-h5-dvfs.patch deleted file mode 100644 index d72287335..000000000 --- a/patch/kernel/sunxi-legacy/0000-unlock-h5-dvfs.patch +++ /dev/null @@ -1,46 +0,0 @@ -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -index 67e2246a6..e37d779f8 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -@@ -55,7 +55,6 @@ - clocks = <&ccu CLK_CPUX>; - clock-names = "cpu"; - operating-points-v2 = <&cpu0_opp_table>; -- clock-frequency = <1200000000>; - #cooling-cells = <2>; - cooling-min-level = <0>; - cooling-max-level = <15>; -@@ -67,7 +66,6 @@ - reg = <1>; - enable-method = "psci"; - operating-points-v2 = <&cpu0_opp_table>; -- clock-frequency = <1200000000>; - }; - - cpu@2 { -@@ -76,7 +74,6 @@ - reg = <2>; - enable-method = "psci"; - operating-points-v2 = <&cpu0_opp_table>; -- clock-frequency = <1200000000>; - }; - - cpu@3 { -@@ -85,10 +82,16 @@ - reg = <3>; - enable-method = "psci"; - operating-points-v2 = <&cpu0_opp_table>; -- clock-frequency = <1200000000>; - }; - }; - -+ reg_cpu_fallback: reg_cpu_fallback { -+ compatible = "regulator-fixed"; -+ regulator-name = "vdd-cpux-dummy"; -+ regulator-min-microvolt = <1100000>; -+ regulator-max-microvolt = <1100000>; -+ }; -+ - psci { - compatible = "arm,psci-0.2"; - method = "smc"; diff --git a/patch/kernel/sunxi-legacy/0001-arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch b/patch/kernel/sunxi-legacy/0001-arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch deleted file mode 100644 index 9a3d73933..000000000 --- a/patch/kernel/sunxi-legacy/0001-arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 55ec26d6a4241363fa94f15377ebd8f1116fbfd7 Mon Sep 17 00:00:00 2001 -From: Samuel Holland -Date: Sat, 12 Jan 2019 20:17:19 -0600 -Subject: [PATCH] arm64: dts: allwinner: a64: Enable A64 timer workaround - -As instability in the architectural timer has been observed on multiple -devices using this SoC, inluding the Pine64 and the Orange Pi Win, -enable the workaround in the SoC's device tree. - -Acked-by: Maxime Ripard -Signed-off-by: Samuel Holland -Signed-off-by: Chen-Yu Tsai ---- - arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -index bf9b719481c4..8171c0a7f265 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -@@ -200,6 +200,7 @@ - - timer { - compatible = "arm,armv8-timer"; -+ allwinner,erratum-unknown1; - interrupts = , - +Date: Sun, 25 Aug 2019 14:40:10 +0200 +Subject: [PATCH] arm64: dts: allwinner: a64: pine64-plus: Add PHY regulator + delay + +Depending on kernel and bootloader configuration, it's possible that +Realtek ethernet PHY isn't powered on properly. It needs some time +before it can be used. + +Fix that by adding 100ms ramp delay to regulator responsible for +powering PHY. + +Fixes: 94dcfdc77fc5 ("arm64: allwinner: pine64-plus: Enable dwmac-sun8i") +Signed-off-by: Jernej Skrabec +--- + arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts +index 24f1aac366d6..9612a34c1762 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts +@@ -63,3 +63,7 @@ + reg = <1>; + }; + }; ++ ++®_dc1sw { ++ regulator-enable-ramp-delay = <100000>; ++}; +-- +2.23.0 diff --git a/patch/kernel/sunxi-legacy/general-armbian-boot-logo-on-screen-center.patch b/patch/kernel/sunxi-legacy/0001-general-armbian-boot-logo.patch similarity index 99% rename from patch/kernel/sunxi-legacy/general-armbian-boot-logo-on-screen-center.patch rename to patch/kernel/sunxi-legacy/0001-general-armbian-boot-logo.patch index a8a303213..bdbea4cab 100644 --- a/patch/kernel/sunxi-legacy/general-armbian-boot-logo-on-screen-center.patch +++ b/patch/kernel/sunxi-legacy/0001-general-armbian-boot-logo.patch @@ -1,10 +1,43 @@ +From 1fa37c48f592bc30be247207cb596573249ad3da Mon Sep 17 00:00:00 2001 +From: Zhang Ning <832666+zhangn1985@users.noreply.github.com> +Date: Tue, 23 Jul 2019 16:22:33 +0800 +Subject: [PATCH] general: armbian boot logo + +logo center is controlled by fbcon=logo-pos:center + +but hardcode to center + +Signed-off-by: Zhang Ning <832666+zhangn1985@users.noreply.github.com> +--- + drivers/video/fbdev/core/fbmem.c | 2 +- + drivers/video/logo/Kconfig | 4 + + drivers/video/logo/Makefile | 1 + + drivers/video/logo/logo.c | 6 + + drivers/video/logo/logo_armbian_clut224.ppm | 12963 ++++++++++++++++++ + 5 files changed, 12975 insertions(+), 1 deletion(-) + create mode 100644 drivers/video/logo/logo_armbian_clut224.ppm + +diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c +index d1949c92be98..322b196c603f 100644 +--- a/drivers/video/fbdev/core/fbmem.c ++++ b/drivers/video/fbdev/core/fbmem.c +@@ -53,7 +53,7 @@ EXPORT_SYMBOL(registered_fb); + int num_registered_fb __read_mostly; + EXPORT_SYMBOL(num_registered_fb); + +-bool fb_center_logo __read_mostly; ++bool fb_center_logo __read_mostly = true; + EXPORT_SYMBOL(fb_center_logo); + + static struct fb_info *get_fb_info(unsigned int idx) diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig +index 6d6f8c08792d..35b3afac33b1 100644 --- a/drivers/video/logo/Kconfig +++ b/drivers/video/logo/Kconfig -@@ -52,6 +52,10 @@ config LOGO_SUN_CLUT224 +@@ -53,6 +53,10 @@ config LOGO_SUN_CLUT224 depends on SPARC default y - + +config LOGO_ARMBIAN_CLUT224 + bool "Standard 224-color Armbian logo" + default y @@ -13,6 +46,7 @@ diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig bool "Black and white SuperH Linux logo" depends on SUPERH diff --git a/drivers/video/logo/Makefile b/drivers/video/logo/Makefile +index 228a89b9bdd1..d3219eed6eb6 100644 --- a/drivers/video/logo/Makefile +++ b/drivers/video/logo/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_LOGO_SGI_CLUT224) += logo_sgi_clut224.o @@ -21,80 +55,35 @@ diff --git a/drivers/video/logo/Makefile b/drivers/video/logo/Makefile obj-$(CONFIG_LOGO_SUPERH_VGA16) += logo_superh_vga16.o +obj-$(CONFIG_LOGO_ARMBIAN_CLUT224) += logo_armbian_clut224.o obj-$(CONFIG_LOGO_SUPERH_CLUT224) += logo_superh_clut224.o - + obj-$(CONFIG_SPU_BASE) += logo_spe_clut224.o diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c +index 141f15a9a459..b0c6ee3d759f 100644 --- a/drivers/video/logo/logo.c +++ b/drivers/video/logo/logo.c -@@ -1,4 +1,3 @@ -- - /* - * Linux logo to be displayed on boot - * -@@ -36,6 +35,8 @@ static int __init fb_logo_late_init(void) - - late_initcall(fb_logo_late_init); - +@@ -37,6 +37,8 @@ static int __init fb_logo_late_init(void) + + late_initcall_sync(fb_logo_late_init); + +extern const struct linux_logo logo_armbian_clut224; + /* logo's are marked __initdata. Use __ref to tell * modpost that it is intended that this function uses data * marked __initdata. -@@ -111,6 +112,10 @@ const struct linux_logo * __ref fb_find_logo(int depth) - /* M32R Linux logo */ - logo = &logo_m32r_clut224; - #endif +@@ -99,6 +101,10 @@ const struct linux_logo * __ref fb_find_logo(int depth) + #ifdef CONFIG_LOGO_SUPERH_CLUT224 + /* SuperH Linux logo */ + logo = &logo_superh_clut224; ++#endif +#ifdef CONFIG_LOGO_ARMBIAN_CLUT224 + /* Armadeus Linux logo */ + logo = &logo_armbian_clut224; -+#endif + #endif } return logo; - } -diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c ---- a/drivers/video/fbdev/core/fbmem.c -+++ b/drivers/video/fbdev/core/fbmem.c -@@ -489,8 +489,7 @@ static int fb_show_logo_line(struct fb_info *info, int rotate, - } - - if (fb_logo.depth <= 4) { -- logo_new = kmalloc_array(logo->width, logo->height, -- GFP_KERNEL); -+ logo_new = kmalloc(info->var.xres * info->var.yres, GFP_KERNEL); - if (logo_new == NULL) { - kfree(palette); - if (saved_pseudo_palette) -@@ -498,8 +498,9 @@ static int fb_show_logo_line(struct fb_info *info, int rotate, - fb_set_logo(info, logo, logo_new, fb_logo.depth); - } - -- image.dx = 0; -- image.dy = y; -+ image.dx = (info->var.xres - logo->width) / 2; -+ image.dy = (info->var.yres - logo->height) / 2; -+ - image.width = logo->width; - image.height = logo->height; - -@@ -657,15 +658,14 @@ int fb_prepare_logo(struct fb_info *info, int rotate) - } - } - -- return fb_prepare_extra_logos(info, fb_logo.logo->height, yres); -+ return fb_prepare_extra_logos(info, info->var.yres, yres); - } - - int fb_show_logo(struct fb_info *info, int rotate) - { - int y; - -- y = fb_show_logo_line(info, rotate, fb_logo.logo, 0, -- num_online_cpus()); -+ y = fb_show_logo_line(info, rotate, fb_logo.logo, 0, 1); - y = fb_show_extra_logos(info, y, rotate); - - return y; diff --git a/drivers/video/logo/logo_armbian_clut224.ppm b/drivers/video/logo/logo_armbian_clut224.ppm +new file mode 100644 +index 000000000000..0e0caf229e55 --- /dev/null +++ b/drivers/video/logo/logo_armbian_clut224.ppm @@ -0,0 +1,12963 @@ @@ -13061,3 +13050,6 @@ diff --git a/drivers/video/logo/logo_armbian_clut224.ppm b/drivers/video/logo/lo +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 +-- +2.20.1 + diff --git a/patch/kernel/sunxi-current/0001-move_ANA78xx_driver_to_analogix_subdirectory.patch b/patch/kernel/sunxi-legacy/0001-move_ANA78xx_driver_to_analogix_subdirectory.patch similarity index 100% rename from patch/kernel/sunxi-current/0001-move_ANA78xx_driver_to_analogix_subdirectory.patch rename to patch/kernel/sunxi-legacy/0001-move_ANA78xx_driver_to_analogix_subdirectory.patch diff --git a/patch/kernel/sunxi-legacy/0002-arm64-allwinner-a64-add-Mali-device-node.patch b/patch/kernel/sunxi-legacy/0002-arm64-allwinner-a64-add-Mali-device-node.patch-DISABLED similarity index 100% rename from patch/kernel/sunxi-legacy/0002-arm64-allwinner-a64-add-Mali-device-node.patch rename to patch/kernel/sunxi-legacy/0002-arm64-allwinner-a64-add-Mali-device-node.patch-DISABLED diff --git a/patch/kernel/sunxi-current/0002-split_some_definitions_of_ANX78xx_to_dedicated_headers.patch b/patch/kernel/sunxi-legacy/0002-split_some_definitions_of_ANX78xx_to_dedicated_headers.patch similarity index 100% rename from patch/kernel/sunxi-current/0002-split_some_definitions_of_ANX78xx_to_dedicated_headers.patch rename to patch/kernel/sunxi-legacy/0002-split_some_definitions_of_ANX78xx_to_dedicated_headers.patch diff --git a/patch/kernel/sunxi-current/0003-extract_some_Analogix_I2C_DP_common_code.patch b/patch/kernel/sunxi-legacy/0003-extract_some_Analogix_I2C_DP_common_code.patch similarity index 100% rename from patch/kernel/sunxi-current/0003-extract_some_Analogix_I2C_DP_common_code.patch rename to patch/kernel/sunxi-legacy/0003-extract_some_Analogix_I2C_DP_common_code.patch diff --git a/patch/kernel/sunxi-current/0004-prepare-analogix-support.patch b/patch/kernel/sunxi-legacy/0004-prepare-analogix-support.patch similarity index 100% rename from patch/kernel/sunxi-current/0004-prepare-analogix-support.patch rename to patch/kernel/sunxi-legacy/0004-prepare-analogix-support.patch diff --git a/patch/kernel/sunxi-current/0004-sun4i-i2s-improvements.patch b/patch/kernel/sunxi-legacy/0004-sun4i-i2s-improvements.patch similarity index 100% rename from patch/kernel/sunxi-current/0004-sun4i-i2s-improvements.patch rename to patch/kernel/sunxi-legacy/0004-sun4i-i2s-improvements.patch diff --git a/patch/kernel/sunxi-current/0005-add_nalogix_anx6345_support.patch b/patch/kernel/sunxi-legacy/0005-add_nalogix_anx6345_support.patch similarity index 100% rename from patch/kernel/sunxi-current/0005-add_nalogix_anx6345_support.patch rename to patch/kernel/sunxi-legacy/0005-add_nalogix_anx6345_support.patch diff --git a/patch/kernel/sunxi-current/0006-add-anx6345-DP-eDP-bridge-for-Olimex-Teres-I.patch b/patch/kernel/sunxi-legacy/0006-add-anx6345-DP-eDP-bridge-for-Olimex-Teres-I.patch similarity index 100% rename from patch/kernel/sunxi-current/0006-add-anx6345-DP-eDP-bridge-for-Olimex-Teres-I.patch rename to patch/kernel/sunxi-legacy/0006-add-anx6345-DP-eDP-bridge-for-Olimex-Teres-I.patch diff --git a/patch/kernel/sunxi-current/0007-anx6345_fix_acquisition_of_the_regulators.patch b/patch/kernel/sunxi-legacy/0007-anx6345_fix_acquisition_of_the_regulators.patch similarity index 100% rename from patch/kernel/sunxi-current/0007-anx6345_fix_acquisition_of_the_regulators.patch rename to patch/kernel/sunxi-legacy/0007-anx6345_fix_acquisition_of_the_regulators.patch diff --git a/patch/kernel/sunxi-current/0009-add-a64-cyrpto.patch b/patch/kernel/sunxi-legacy/0009-add-a64-cyrpto.patch similarity index 100% rename from patch/kernel/sunxi-current/0009-add-a64-cyrpto.patch rename to patch/kernel/sunxi-legacy/0009-add-a64-cyrpto.patch diff --git a/patch/kernel/sunxi-legacy/0009-dt-bindings-update-the-Allwinner-GPADC-device-tree-b.patch b/patch/kernel/sunxi-legacy/0009-dt-bindings-update-the-Allwinner-GPADC-device-tree-b.patch deleted file mode 100644 index 49df63b00..000000000 --- a/patch/kernel/sunxi-legacy/0009-dt-bindings-update-the-Allwinner-GPADC-device-tree-b.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 92e5c7876cef2b53ed3d1701169fcd93b73e0e33 Mon Sep 17 00:00:00 2001 -From: Philipp Rossak -Date: Sat, 20 Jan 2018 13:25:21 +0100 -Subject: [PATCH 009/146] dt-bindings: update the Allwinner GPADC device tree - binding for H3 & A83T - -Allwinner H3 features a thermal sensor like the one in A33, but has its -register re-arranged, the clock divider moved to CCU (originally the -clock divider is in ADC) and added a pair of bus clock and reset. - -Allwinner A83T features a thermal sensor similar to the H3, the ths clock, -the bus clock and the reset was removed from the CCU. The THS in A83T -has a clock that is directly connected and runs with 24 MHz. - -Update the binding document to cover H3 and A83T. - -Signed-off-by: Philipp Rossak ---- - .../devicetree/bindings/mfd/sun4i-gpadc.txt | 50 +++++++++++++++++-- - 1 file changed, 47 insertions(+), 3 deletions(-) - -diff --git a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt -index 86dd8191b04c..f6b939617a6d 100644 ---- a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt -+++ b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt -@@ -4,12 +4,35 @@ The Allwinner SoCs all have an ADC that can also act as a thermal sensor - and sometimes as a touchscreen controller. - - Required properties: -- - compatible: "allwinner,sun8i-a33-ths", -+ - compatible: must contain one of the following compatibles: -+ - "allwinner,sun8i-a33-ths" -+ - "allwinner,sun8i-h3-ths" -+ - "allwinner,sun8i-a83t-ths" - - reg: mmio address range of the chip, -- - #thermal-sensor-cells: shall be 0, -+ - #thermal-sensor-cells: shall be 0 or 1, - - #io-channel-cells: shall be 0, - --Example: -+Required properties for the following compatibles: -+ - "allwinner,sun8i-h3-ths" -+ - "allwinner,sun8i-a83t-ths" -+ - interrupts: the sampling interrupt of the ADC, -+ -+Required properties for the following compatibles: -+ - "allwinner,sun8i-h3-ths" -+ - clocks: the bus clock and the input clock of the ADC, -+ - clock-names: should be "bus" and "mod", -+ - resets: the bus reset of the ADC, -+ -+Optional properties for the following compatibles: -+ - "allwinner,sun8i-h3-ths" -+ - nvmem-cells: A phandle to the calibration data provided by a nvmem device. -+ If unspecified default values shall be used. The size should -+ be 0x4 or 0x8, depending on the amount of CDATA registers. -+ - nvmem-cell-names: Should be "calibration". -+ -+Details see: bindings/nvmem/nvmem.txt -+ -+Example for A33: - ths: ths@1c25000 { - compatible = "allwinner,sun8i-a33-ths"; - reg = <0x01c25000 0x100>; -@@ -17,6 +40,27 @@ Example: - #io-channel-cells = <0>; - }; - -+Example for H3: -+ ths: thermal-sensor@1c25000 { -+ compatible = "allwinner,sun8i-h3-ths"; -+ reg = <0x01c25000 0x400>; -+ clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_THS>; -+ clock-names = "bus", "mod"; -+ resets = <&ccu RST_BUS_THS>; -+ interrupts = ; -+ #thermal-sensor-cells = <0>; -+ #io-channel-cells = <0>; -+ }; -+ -+Example for A83T: -+ ths: thermal-sensor@1f04000 { -+ compatible = "allwinner,sun8i-a83t-ths"; -+ reg = <0x01f04000 0x100>; -+ interrupts = ; -+ #thermal-sensor-cells = <1>; -+ #io-channel-cells = <0>; -+ }; -+ - sun4i, sun5i and sun6i SoCs are also supported via the older binding: - - sun4i resistive touchscreen controller --- -2.17.1 - diff --git a/patch/kernel/sunxi-current/0009-enable_anx6345_bridge_pinebook.patch b/patch/kernel/sunxi-legacy/0009-enable_anx6345_bridge_pinebook.patch similarity index 100% rename from patch/kernel/sunxi-current/0009-enable_anx6345_bridge_pinebook.patch rename to patch/kernel/sunxi-legacy/0009-enable_anx6345_bridge_pinebook.patch diff --git a/patch/kernel/sunxi-current/0010-add-mipi-dsi-pipeline.patch b/patch/kernel/sunxi-legacy/0010-add-mipi-dsi-pipeline.patch similarity index 100% rename from patch/kernel/sunxi-current/0010-add-mipi-dsi-pipeline.patch rename to patch/kernel/sunxi-legacy/0010-add-mipi-dsi-pipeline.patch diff --git a/patch/kernel/sunxi-legacy/0010-general-h6-add-dma-i2c-ir-spi-uart.patch b/patch/kernel/sunxi-legacy/0010-general-h6-add-dma-i2c-ir-spi-uart.patch new file mode 100644 index 000000000..56e4523ab --- /dev/null +++ b/patch/kernel/sunxi-legacy/0010-general-h6-add-dma-i2c-ir-spi-uart.patch @@ -0,0 +1,176 @@ +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +index dc785da9c..141fd186b 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +@@ -113,6 +113,12 @@ + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + ++ opp@1640000000 { ++ opp-hz = /bits/ 64 <1640000000>; ++ opp-microvolt = <1160000 1160000 1160000>; ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ }; ++ + opp@1800000000 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <1160000 1160000 1160000>; +@@ -374,6 +381,17 @@ + #dma-cells = <1>; + }; + ++ gic: interrupt-controller@3021000 { ++ compatible = "arm,gic-400"; ++ reg = <0x03021000 0x1000>, ++ <0x03022000 0x2000>, ++ <0x03024000 0x2000>, ++ <0x03026000 0x2000>; ++ interrupts = ; ++ interrupt-controller; ++ #interrupt-cells = <3>; ++ }; ++ + sid: efuse@3006000 { + compatible = "allwinner,sun50i-h6-sid"; + reg = <0x03006000 0x400>; +@@ -279,6 +305,7 @@ + interrupt-controller; + #interrupt-cells = <3>; + ++ /omit-if-no-ref/ + ext_rgmii_pins: rgmii-pins { + pins = "PD0", "PD1", "PD2", "PD3", "PD4", + "PD5", "PD7", "PD8", "PD9", "PD10", +@@ -309,6 +354,7 @@ + bias-pull-up; + }; + ++ /omit-if-no-ref/ + mmc2_pins: mmc2-pins { + pins = "PC1", "PC4", "PC5", "PC6", + "PC7", "PC8", "PC9", "PC10", +@@ -318,6 +364,16 @@ + bias-pull-up; + }; + ++ spi0_pins: spi0-pins { ++ pins = "PC2", "PC3", "PC0", "PC5"; ++ function = "spi0"; ++ }; ++ ++ spi1_pins: spi1-pins { ++ pins = "PH5", "PH6", "PH4", "PH3"; ++ function = "spi1"; ++ }; ++ + uart0_ph_pins: uart0-ph-pins { + pins = "PH0", "PH1"; + function = "uart0"; +@@ -511,17 +540,26 @@ + pins = "PG8", "PG9"; + function = "uart1"; + }; +- }; + +- gic: interrupt-controller@3021000 { +- compatible = "arm,gic-400"; +- reg = <0x03021000 0x1000>, +- <0x03022000 0x2000>, +- <0x03024000 0x2000>, +- <0x03026000 0x2000>; +- interrupts = ; +- interrupt-controller; +- #interrupt-cells = <3>; ++ uart2_pins: uart2-pins { ++ pins = "PD19", "PD20"; ++ function = "uart2"; ++ }; ++ ++ uart2_rts_cts_pins: uart2-rts-cts-pins { ++ pins = "PD21", "PD22"; ++ function = "uart2"; ++ }; ++ ++ uart3_pins: uart3-pins { ++ pins = "PD23", "PD24"; ++ function = "uart3"; ++ }; ++ ++ uart3_rts_cts_pins: uart3-rts-cts-pins { ++ pins = "PD25", "PD26"; ++ function = "uart3"; ++ }; + }; + + mmc0: mmc@4020000 { +@@ -391,6 +495,38 @@ + #size-cells = <0>; + }; + ++ spi0: spi@5010000 { ++ compatible = "allwinner,sun8i-h3-spi"; ++ reg = <0x05010000 0x1000>; ++ interrupts = ; ++ clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>; ++ clock-names = "ahb", "mod"; ++ dmas = <&dma 22>, <&dma 22>; ++ dma-names = "rx", "tx"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins>; ++ resets = <&ccu RST_BUS_SPI0>; ++ status = "disabled"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ spi1: spi@5011000 { ++ compatible = "allwinner,sun8i-h3-spi"; ++ reg = <0x05011000 0x1000>; ++ interrupts = ; ++ clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>; ++ clock-names = "ahb", "mod"; ++ dmas = <&dma 23>, <&dma 23>; ++ dma-names = "rx", "tx"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi1_pins>; ++ resets = <&ccu RST_BUS_SPI1>; ++ status = "disabled"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ + uart0: serial@5000000 { + compatible = "snps,dw-apb-uart"; + reg = <0x05000000 0x400>; +@@ -963,6 +1033,19 @@ + }; + }; + ++ r_uart: serial@7080000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x07080000 0x400>; ++ interrupts = ; ++ reg-shift = <2>; ++ reg-io-width = <4>; ++ clocks = <&r_ccu CLK_R_APB2_UART>; ++ resets = <&r_ccu RST_R_APB2_UART>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&r_uart_pins>; ++ status = "disabled"; ++ }; ++ + rtc: rtc@7000000 { + compatible = "allwinner,sun50i-h6-rtc"; + reg = <0x07000000 0x400>; +@@ -1021,6 +1104,11 @@ + pins = "PL9"; + function = "s_cir_rx"; + }; ++ ++ r_uart_pins: r-uart-pins { ++ pins = "PL2", "PL3"; ++ function = "s_uart"; ++ }; + }; + + r_ir: ir@7040000 { diff --git a/patch/kernel/sunxi-current/0010-media-v4l2-add_CID_UNIT_CELL_SIZE-control.patch b/patch/kernel/sunxi-legacy/0010-media-v4l2-add_CID_UNIT_CELL_SIZE-control.patch similarity index 100% rename from patch/kernel/sunxi-current/0010-media-v4l2-add_CID_UNIT_CELL_SIZE-control.patch rename to patch/kernel/sunxi-legacy/0010-media-v4l2-add_CID_UNIT_CELL_SIZE-control.patch diff --git a/patch/kernel/sunxi-current/0011-add-thermal-sensors-a64.patch b/patch/kernel/sunxi-legacy/0011-add-thermal-sensors-a64.patch similarity index 100% rename from patch/kernel/sunxi-current/0011-add-thermal-sensors-a64.patch rename to patch/kernel/sunxi-legacy/0011-add-thermal-sensors-a64.patch diff --git a/patch/kernel/sunxi-current/0011-media-v4l2-add_CTRL_TYPE_AREA-control-type.patch b/patch/kernel/sunxi-legacy/0011-media-v4l2-add_CTRL_TYPE_AREA-control-type.patch similarity index 100% rename from patch/kernel/sunxi-current/0011-media-v4l2-add_CTRL_TYPE_AREA-control-type.patch rename to patch/kernel/sunxi-legacy/0011-media-v4l2-add_CTRL_TYPE_AREA-control-type.patch diff --git a/patch/kernel/sunxi-current/0012-a64-use-macros.patch b/patch/kernel/sunxi-legacy/0012-a64-use-macros.patch similarity index 100% rename from patch/kernel/sunxi-current/0012-a64-use-macros.patch rename to patch/kernel/sunxi-legacy/0012-a64-use-macros.patch diff --git a/patch/kernel/sunxi-current/0012-media-v4l2-add-definitions-for-HEVC-stateless-decoding.patch b/patch/kernel/sunxi-legacy/0012-media-v4l2-add-definitions-for-HEVC-stateless-decoding.patch similarity index 100% rename from patch/kernel/sunxi-current/0012-media-v4l2-add-definitions-for-HEVC-stateless-decoding.patch rename to patch/kernel/sunxi-legacy/0012-media-v4l2-add-definitions-for-HEVC-stateless-decoding.patch diff --git a/patch/kernel/sunxi-current/0013-add-cpu-clocks-to-nodes.patch b/patch/kernel/sunxi-legacy/0013-add-cpu-clocks-to-nodes.patch similarity index 100% rename from patch/kernel/sunxi-current/0013-add-cpu-clocks-to-nodes.patch rename to patch/kernel/sunxi-legacy/0013-add-cpu-clocks-to-nodes.patch diff --git a/patch/kernel/sunxi-current/0013-media-v4l2-add-mem2mem-support-held-capture-buffers.patch b/patch/kernel/sunxi-legacy/0013-media-v4l2-add-mem2mem-support-held-capture-buffers.patch similarity index 100% rename from patch/kernel/sunxi-current/0013-media-v4l2-add-mem2mem-support-held-capture-buffers.patch rename to patch/kernel/sunxi-legacy/0013-media-v4l2-add-mem2mem-support-held-capture-buffers.patch diff --git a/patch/kernel/sunxi-current/0014-a64-enable-dvfs-and-tripping-points.patch b/patch/kernel/sunxi-legacy/0014-a64-enable-dvfs-and-tripping-points.patch similarity index 100% rename from patch/kernel/sunxi-current/0014-a64-enable-dvfs-and-tripping-points.patch rename to patch/kernel/sunxi-legacy/0014-a64-enable-dvfs-and-tripping-points.patch diff --git a/patch/kernel/sunxi-current/0014-media-v4l2-add-mem2mem-add-stateless_try_decoder_cmd-ioctl.patch b/patch/kernel/sunxi-legacy/0014-media-v4l2-add-mem2mem-add-stateless_try_decoder_cmd-ioctl.patch similarity index 100% rename from patch/kernel/sunxi-current/0014-media-v4l2-add-mem2mem-add-stateless_try_decoder_cmd-ioctl.patch rename to patch/kernel/sunxi-legacy/0014-media-v4l2-add-mem2mem-add-stateless_try_decoder_cmd-ioctl.patch diff --git a/patch/kernel/sunxi-current/0015-add_dtsi_with_CPU_operating_points.patch b/patch/kernel/sunxi-legacy/0015-add_dtsi_with_CPU_operating_points.patch similarity index 100% rename from patch/kernel/sunxi-current/0015-add_dtsi_with_CPU_operating_points.patch rename to patch/kernel/sunxi-legacy/0015-add_dtsi_with_CPU_operating_points.patch diff --git a/patch/kernel/sunxi-current/0015-media-v4l2-add-mem2mem-add-new_frame-detection.patch b/patch/kernel/sunxi-legacy/0015-media-v4l2-add-mem2mem-add-new_frame-detection.patch similarity index 100% rename from patch/kernel/sunxi-current/0015-media-v4l2-add-mem2mem-add-new_frame-detection.patch rename to patch/kernel/sunxi-legacy/0015-media-v4l2-add-mem2mem-add-new_frame-detection.patch diff --git a/patch/kernel/sunxi-current/0016-media-v4l2-add-V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF.patch b/patch/kernel/sunxi-legacy/0016-media-v4l2-add-V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF.patch similarity index 100% rename from patch/kernel/sunxi-current/0016-media-v4l2-add-V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF.patch rename to patch/kernel/sunxi-legacy/0016-media-v4l2-add-V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF.patch diff --git a/patch/kernel/sunxi-current/0017-media-v4l2-videodev2.h-add-V4L2_DEC_CMD_FLUSH.patch b/patch/kernel/sunxi-legacy/0017-media-v4l2-videodev2.h-add-V4L2_DEC_CMD_FLUSH.patch similarity index 100% rename from patch/kernel/sunxi-current/0017-media-v4l2-videodev2.h-add-V4L2_DEC_CMD_FLUSH.patch rename to patch/kernel/sunxi-legacy/0017-media-v4l2-videodev2.h-add-V4L2_DEC_CMD_FLUSH.patch diff --git a/patch/kernel/sunxi-current/0018-media-v4l2-add-mem2mem-Fix-hold-buf-flag-checks.patch b/patch/kernel/sunxi-legacy/0018-media-v4l2-add-mem2mem-Fix-hold-buf-flag-checks.patch similarity index 100% rename from patch/kernel/sunxi-current/0018-media-v4l2-add-mem2mem-Fix-hold-buf-flag-checks.patch rename to patch/kernel/sunxi-legacy/0018-media-v4l2-add-mem2mem-Fix-hold-buf-flag-checks.patch diff --git a/patch/kernel/sunxi-legacy/0019-arm-dts-sunxi-h3-h5-add-support-for-the-thermal-sens.patch b/patch/kernel/sunxi-legacy/0019-arm-dts-sunxi-h3-h5-add-support-for-the-thermal-sens.patch deleted file mode 100644 index 9133319ea..000000000 --- a/patch/kernel/sunxi-legacy/0019-arm-dts-sunxi-h3-h5-add-support-for-the-thermal-sens.patch +++ /dev/null @@ -1,39 +0,0 @@ -From f1b96d20375eb192d017999740c0055f2efbf576 Mon Sep 17 00:00:00 2001 -From: Philipp Rossak -Date: Fri, 26 Jan 2018 01:01:34 +0100 -Subject: [PATCH 019/146] arm: dts: sunxi-h3-h5: add support for the thermal - sensor in H3 and H5 - -As we have gained the support for the thermal sensor in H3 and H5, -we can now add its device nodes to the device tree. The H3 and H5 share -most of its compatible. The compatible and the thermal sensor cells -will be added in an additional patch per device. - -Signed-off-by: Philipp Rossak ---- - arch/arm/boot/dts/sunxi-h3-h5.dtsi | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -index fc6131315c47..8fde0f6c16e4 100644 ---- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi -+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -@@ -488,6 +488,15 @@ - }; - }; - -+ ths: thermal-sensor@1c25000 { -+ reg = <0x01c25000 0x100>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_THS>; -+ clock-names = "bus", "mod"; -+ resets = <&ccu RST_BUS_THS>; -+ #io-channel-cells = <0>; -+ }; -+ - timer@1c20c00 { - compatible = "allwinner,sun4i-a10-timer"; - reg = <0x01c20c00 0xa0>; --- -2.17.1 - diff --git a/patch/kernel/sunxi-current/0019-media-uapi-h264-Add-DPB-entry-field-reference-flags.patch b/patch/kernel/sunxi-legacy/0019-media-uapi-h264-Add-DPB-entry-field-reference-flags.patch similarity index 100% rename from patch/kernel/sunxi-current/0019-media-uapi-h264-Add-DPB-entry-field-reference-flags.patch rename to patch/kernel/sunxi-legacy/0019-media-uapi-h264-Add-DPB-entry-field-reference-flags.patch diff --git a/patch/kernel/sunxi-current/0020-media-v4l2-mem2mem-mark-DONE-any-OUTPUT-queued-buffer-after-CMD_STOP-v2.patch b/patch/kernel/sunxi-legacy/0020-media-v4l2-mem2mem-mark-DONE-any-OUTPUT-queued-buffer-after-CMD_STOP-v2.patch similarity index 100% rename from patch/kernel/sunxi-current/0020-media-v4l2-mem2mem-mark-DONE-any-OUTPUT-queued-buffer-after-CMD_STOP-v2.patch rename to patch/kernel/sunxi-legacy/0020-media-v4l2-mem2mem-mark-DONE-any-OUTPUT-queued-buffer-after-CMD_STOP-v2.patch diff --git a/patch/kernel/sunxi-legacy/0034-dts-a64-ths.patch b/patch/kernel/sunxi-legacy/0034-dts-a64-ths.patch deleted file mode 100644 index 6f550c3f2..000000000 --- a/patch/kernel/sunxi-legacy/0034-dts-a64-ths.patch +++ /dev/null @@ -1,62 +0,0 @@ -From ff4436bd3de240a1d0796d4c6f8bd676ff0925e1 Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Mon, 23 Apr 2018 23:24:41 -0700 -Subject: [PATCH 034/146] dts: a64 ths - ---- - arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 32 +++++++++++++++++++ - 1 file changed, 32 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -index 0b44018361cb..0eb482eb58b7 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -@@ -171,6 +171,27 @@ - }; - }; - -+ thermal-zones { -+ cpu_thermal: cpu0-thermal { -+ /* milliseconds */ -+ polling-delay-passive = <250>; -+ polling-delay = <1000>; -+ thermal-sensors = <&ths 0>; -+ }; -+ gpu0_thermal: gpu0-thermal { -+ /* milliseconds */ -+ polling-delay-passive = <250>; -+ polling-delay = <1000>; -+ thermal-sensors = <&ths 1>; -+ }; -+ gpu1_thermal: gpu1-thermal { -+ /* milliseconds */ -+ polling-delay-passive = <250>; -+ polling-delay = <1000>; -+ thermal-sensors = <&ths 2>; -+ }; -+ }; -+ - timer { - compatible = "arm,armv8-timer"; - interrupts = ; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_THS>; -+ clock-names = "bus", "mod"; -+ resets = <&ccu RST_BUS_THS>; -+ #io-channel-cells = <0>; -+ #thermal-sensor-cells = <1>; -+ }; -+ - uart0: serial@1c28000 { - compatible = "snps,dw-apb-uart"; - reg = <0x01c28000 0x400>; --- -2.17.1 - diff --git a/patch/kernel/sunxi-current/0035-clk-sunxi-ng-add-mux-and-pll-notifiers-for-A64-CPU-c.patch.disabled b/patch/kernel/sunxi-legacy/0035-clk-sunxi-ng-add-mux-and-pll-notifiers-for-A64-CPU-c.patch.disabled similarity index 100% rename from patch/kernel/sunxi-current/0035-clk-sunxi-ng-add-mux-and-pll-notifiers-for-A64-CPU-c.patch.disabled rename to patch/kernel/sunxi-legacy/0035-clk-sunxi-ng-add-mux-and-pll-notifiers-for-A64-CPU-c.patch.disabled diff --git a/patch/kernel/sunxi-legacy/0037-a64-dvfs-wip.patch b/patch/kernel/sunxi-legacy/0037-a64-dvfs-wip.patch deleted file mode 100644 index b3d7d9a3d..000000000 --- a/patch/kernel/sunxi-legacy/0037-a64-dvfs-wip.patch +++ /dev/null @@ -1,256 +0,0 @@ -From b07dd371b1a1203a013f91da750259f7a2467fce Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Tue, 24 Apr 2018 22:21:27 -0700 -Subject: [PATCH 037/146] a64 dvfs wip - -Changed: Igor - ---- - .../boot/dts/allwinner/sun50i-a64-pine64.dts | 4 + - .../dts/allwinner/sun50i-a64-pinebook.dts | 4 + - .../allwinner/sun50i-a64-sopine-baseboard.dts | 4 + - arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 111 ++++++++++++++++-- - drivers/clk/sunxi-ng/ccu-sun50i-a64.h | 1 - - include/dt-bindings/clock/sun50i-a64-ccu.h | 1 + - 6 files changed, 112 insertions(+), 13 deletions(-) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts -index 8c5dd99cc9ac..cdf5169f2a1a 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts -@@ -69,6 +69,10 @@ - }; - }; - -+&cpu0 { -+ cpu-supply = <®_dcdc2>; -+}; -+ - &ehci0 { - status = "okay"; - }; -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -index 897e60cbe38d..b3698a8bb1d3 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -@@ -66,6 +66,10 @@ - }; - }; - -+&cpu0 { -+ cpu-supply = <®_dcdc2>; -+}; -+ - &ehci0 { - phys = <&usbphy 0>; - phy-names = "usb"; -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts -index 8161895dde52..dc728b3b5556 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts -@@ -69,6 +69,10 @@ - }; - }; - -+&cpu0 { -+ cpu-supply = <®_dcdc2>; -+}; -+ - &ehci0 { - status = "okay"; - }; -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -index 0eb482eb58b7..62b880f68d6a 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -@@ -49,6 +49,7 @@ - #include - #include - #include -+#include - - / { - interrupt-parent = <&gic>; -@@ -79,6 +80,52 @@ - }; - }; - -+ cpu0_opp_table: opp_table0 { -+ compatible = "operating-points-v2"; -+ opp-shared; -+ -+ opp-120000000 { -+ opp-hz = /bits/ 64 <120000000>; -+ opp-microvolt = <1040000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ opp-648000000 { -+ opp-hz = /bits/ 64 <648000000>; -+ opp-microvolt = <1040000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ opp-816000000 { -+ opp-hz = /bits/ 64 <816000000>; -+ opp-microvolt = <1100000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ opp-912000000 { -+ opp-hz = /bits/ 64 <912000000>; -+ opp-microvolt = <1120000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ opp-960000000 { -+ opp-hz = /bits/ 64 <960000000>; -+ opp-microvolt = <1160000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ opp-1008000000 { -+ opp-hz = /bits/ 64 <1008000000>; -+ opp-microvolt = <1200000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ opp-1056000000 { -+ opp-hz = /bits/ 64 <1056000000>; -+ opp-microvolt = <1240000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ opp-1104000000 { -+ opp-hz = /bits/ 64 <1104000000>; -+ opp-microvolt = <1300000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -88,6 +135,10 @@ - device_type = "cpu"; - reg = <0>; - enable-method = "psci"; -+ clocks = <&ccu CLK_CPUX>; -+ clock-names = "cpu"; -+ operating-points-v2 = <&cpu0_opp_table>; -+ #cooling-cells = <2>; - }; - - cpu1: cpu@1 { -@@ -95,6 +146,7 @@ - device_type = "cpu"; - reg = <1>; - enable-method = "psci"; -+ operating-points-v2 = <&cpu0_opp_table>; - }; - - cpu2: cpu@2 { -@@ -102,6 +154,7 @@ - device_type = "cpu"; - reg = <2>; - enable-method = "psci"; -+ operating-points-v2 = <&cpu0_opp_table>; - }; - - cpu3: cpu@3 { -@@ -109,6 +162,7 @@ - device_type = "cpu"; - reg = <3>; - enable-method = "psci"; -+ operating-points-v2 = <&cpu0_opp_table>; - }; - }; - -@@ -173,22 +227,55 @@ - - thermal-zones { - cpu_thermal: cpu0-thermal { -- /* milliseconds */ -- polling-delay-passive = <250>; -- polling-delay = <1000>; -- thermal-sensors = <&ths 0>; -+ /* milliseconds */ -+ polling-delay-passive = <250>; -+ polling-delay = <1000>; -+ thermal-sensors = <&ths 0>; -+ -+ cooling-maps { -+ map0 { -+ trip = <&cpu_alert0>; -+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -+ }; -+ map1 { -+ trip = <&cpu_alert1>; -+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -+ }; -+ }; -+ trips { -+ cpu_alert0: cpu_alert0 { -+ /* milliCelsius */ -+ temperature = <75000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ cpu_alert1: cpu_alert1 { -+ /* milliCelsius */ -+ temperature = <90000>; -+ hysteresis = <2000>; -+ type = "hot"; -+ }; -+ -+ cpu_crit: cpu_crit { -+ /* milliCelsius */ -+ temperature = <110000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; - }; - gpu0_thermal: gpu0-thermal { -- /* milliseconds */ -- polling-delay-passive = <250>; -- polling-delay = <1000>; -- thermal-sensors = <&ths 1>; -+ /* milliseconds */ -+ polling-delay-passive = <250>; -+ polling-delay = <1000>; -+ thermal-sensors = <&ths 1>; - }; - gpu1_thermal: gpu1-thermal { -- /* milliseconds */ -- polling-delay-passive = <250>; -- polling-delay = <1000>; -- thermal-sensors = <&ths 2>; -+ /* milliseconds */ -+ polling-delay-passive = <250>; -+ polling-delay = <1000>; -+ thermal-sensors = <&ths 2>; - }; - }; - -diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h -index 061b6fbb4f95..91f79512cee4 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h -+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h -@@ -43,7 +43,6 @@ - #define CLK_PLL_HSIC 18 - #define CLK_PLL_DE 19 - #define CLK_PLL_DDR1 20 --#define CLK_CPUX 21 - #define CLK_AXI 22 - #define CLK_APB 23 - #define CLK_AHB1 24 -diff --git a/include/dt-bindings/clock/sun50i-a64-ccu.h b/include/dt-bindings/clock/sun50i-a64-ccu.h -index d66432c6e675..d7f42dd22663 100644 ---- a/include/dt-bindings/clock/sun50i-a64-ccu.h -+++ b/include/dt-bindings/clock/sun50i-a64-ccu.h -@@ -45,6 +45,7 @@ - - #define CLK_PLL_PERIPH0 11 - -+#define CLK_CPUX 21 - #define CLK_BUS_MIPI_DSI 28 - #define CLK_BUS_CE 29 - #define CLK_BUS_DMA 30 --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0039-dt-bindings-add-switch-delay-property-for-mali-utgar.patch b/patch/kernel/sunxi-legacy/0039-dt-bindings-add-switch-delay-property-for-mali-utgar.patch deleted file mode 100644 index bd3091916..000000000 --- a/patch/kernel/sunxi-legacy/0039-dt-bindings-add-switch-delay-property-for-mali-utgar.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 93a9dff30ace06dceba2a84eb709433d5e08c7bc Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Wed, 21 Mar 2018 14:58:02 +0800 -Subject: [PATCH 039/146] dt-bindings: add switch-delay property for - mali-utgard - -Signed-off-by: Qiang Yu ---- - Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt b/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt -index 63cd91176a68..3e2590162d4f 100644 ---- a/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt -+++ b/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt -@@ -58,6 +58,10 @@ Optional properties: - A power domain consumer specifier as defined in - Documentation/devicetree/bindings/power/power_domain.txt - -+ - switch-delay: -+ This value is the number of Mali clock cycles it takes to -+ enable the power gates and turn on the power mesh. -+ - Vendor-specific bindings - ------------------------ - --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0042-drm-lima-add-lima-uapi-header.patch b/patch/kernel/sunxi-legacy/0042-drm-lima-add-lima-uapi-header.patch deleted file mode 100644 index 6fa7b1295..000000000 --- a/patch/kernel/sunxi-legacy/0042-drm-lima-add-lima-uapi-header.patch +++ /dev/null @@ -1,215 +0,0 @@ -From e59461ae51787ed4ba778ca32b6bde432552da96 Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Mon, 14 May 2018 20:53:38 +0800 -Subject: [PATCH 042/146] drm/lima: add lima uapi header - -Signed-off-by: Qiang Yu ---- - include/uapi/drm/lima_drm.h | 195 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 195 insertions(+) - create mode 100644 include/uapi/drm/lima_drm.h - -diff --git a/include/uapi/drm/lima_drm.h b/include/uapi/drm/lima_drm.h -new file mode 100644 -index 000000000000..9df95e46fb2c ---- /dev/null -+++ b/include/uapi/drm/lima_drm.h -@@ -0,0 +1,195 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef __LIMA_DRM_H__ -+#define __LIMA_DRM_H__ -+ -+#include "drm.h" -+ -+#if defined(__cplusplus) -+extern "C" { -+#endif -+ -+#define LIMA_INFO_GPU_MALI400 0x00 -+#define LIMA_INFO_GPU_MALI450 0x01 -+ -+struct drm_lima_info { -+ __u32 gpu_id; /* out */ -+ __u32 num_pp; /* out */ -+ __u64 va_start; /* out */ -+ __u64 va_end; /* out */ -+}; -+ -+struct drm_lima_gem_create { -+ __u32 size; /* in */ -+ __u32 flags; /* in */ -+ __u32 handle; /* out */ -+ __u32 pad; -+}; -+ -+struct drm_lima_gem_info { -+ __u32 handle; /* in */ -+ __u32 pad; -+ __u64 offset; /* out */ -+}; -+ -+#define LIMA_VA_OP_MAP 1 -+#define LIMA_VA_OP_UNMAP 2 -+ -+struct drm_lima_gem_va { -+ __u32 handle; /* in */ -+ __u32 op; /* in */ -+ __u32 flags; /* in */ -+ __u32 va; /* in */ -+}; -+ -+#define LIMA_SUBMIT_BO_READ 0x01 -+#define LIMA_SUBMIT_BO_WRITE 0x02 -+ -+struct drm_lima_gem_submit_bo { -+ __u32 handle; /* in */ -+ __u32 flags; /* in */ -+}; -+ -+#define LIMA_SUBMIT_DEP_FENCE 0x00 -+#define LIMA_SUBMIT_DEP_SYNC_FD 0x01 -+ -+struct drm_lima_gem_submit_dep_fence { -+ __u32 type; -+ __u32 ctx; -+ __u32 pipe; -+ __u32 seq; -+}; -+ -+struct drm_lima_gem_submit_dep_sync_fd { -+ __u32 type; -+ __u32 fd; -+}; -+ -+union drm_lima_gem_submit_dep { -+ __u32 type; -+ struct drm_lima_gem_submit_dep_fence fence; -+ struct drm_lima_gem_submit_dep_sync_fd sync_fd; -+}; -+ -+#define LIMA_GP_FRAME_REG_NUM 6 -+ -+struct drm_lima_gp_frame { -+ __u32 frame[LIMA_GP_FRAME_REG_NUM]; -+}; -+ -+#define LIMA_PP_FRAME_REG_NUM 23 -+#define LIMA_PP_WB_REG_NUM 12 -+ -+struct drm_lima_m400_pp_frame { -+ __u32 frame[LIMA_PP_FRAME_REG_NUM]; -+ __u32 num_pp; -+ __u32 wb[3 * LIMA_PP_WB_REG_NUM]; -+ __u32 plbu_array_address[4]; -+ __u32 fragment_stack_address[4]; -+}; -+ -+struct drm_lima_m450_pp_frame { -+ __u32 frame[LIMA_PP_FRAME_REG_NUM]; -+ __u32 _pad; -+ __u32 wb[3 * LIMA_PP_WB_REG_NUM]; -+ __u32 dlbu_regs[4]; -+ __u32 fragment_stack_address[8]; -+}; -+ -+#define LIMA_PIPE_GP 0x00 -+#define LIMA_PIPE_PP 0x01 -+ -+#define LIMA_SUBMIT_FLAG_EXPLICIT_FENCE (1 << 0) -+#define LIMA_SUBMIT_FLAG_SYNC_FD_OUT (1 << 1) -+ -+struct drm_lima_gem_submit_in { -+ __u32 ctx; -+ __u32 pipe; -+ __u32 nr_bos; -+ __u32 frame_size; -+ __u64 bos; -+ __u64 frame; -+ __u64 deps; -+ __u32 nr_deps; -+ __u32 flags; -+}; -+ -+struct drm_lima_gem_submit_out { -+ __u32 fence; -+ __u32 done; -+ __u32 sync_fd; -+ __u32 _pad; -+}; -+ -+union drm_lima_gem_submit { -+ struct drm_lima_gem_submit_in in; -+ struct drm_lima_gem_submit_out out; -+}; -+ -+struct drm_lima_wait_fence { -+ __u32 ctx; /* in */ -+ __u32 pipe; /* in */ -+ __u64 timeout_ns; /* in */ -+ __u32 seq; /* in */ -+ __u32 _pad; -+}; -+ -+#define LIMA_GEM_WAIT_READ 0x01 -+#define LIMA_GEM_WAIT_WRITE 0x02 -+ -+struct drm_lima_gem_wait { -+ __u32 handle; /* in */ -+ __u32 op; /* in */ -+ __u64 timeout_ns; /* in */ -+}; -+ -+#define LIMA_CTX_OP_CREATE 1 -+#define LIMA_CTX_OP_FREE 2 -+ -+struct drm_lima_ctx { -+ __u32 op; /* in */ -+ __u32 id; /* in/out */ -+}; -+ -+#define DRM_LIMA_INFO 0x00 -+#define DRM_LIMA_GEM_CREATE 0x01 -+#define DRM_LIMA_GEM_INFO 0x02 -+#define DRM_LIMA_GEM_VA 0x03 -+#define DRM_LIMA_GEM_SUBMIT 0x04 -+#define DRM_LIMA_WAIT_FENCE 0x05 -+#define DRM_LIMA_GEM_WAIT 0x06 -+#define DRM_LIMA_CTX 0x07 -+ -+#define DRM_IOCTL_LIMA_INFO DRM_IOR(DRM_COMMAND_BASE + DRM_LIMA_INFO, struct drm_lima_info) -+#define DRM_IOCTL_LIMA_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_LIMA_GEM_CREATE, struct drm_lima_gem_create) -+#define DRM_IOCTL_LIMA_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_LIMA_GEM_INFO, struct drm_lima_gem_info) -+#define DRM_IOCTL_LIMA_GEM_VA DRM_IOW(DRM_COMMAND_BASE + DRM_LIMA_GEM_VA, struct drm_lima_gem_va) -+#define DRM_IOCTL_LIMA_GEM_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_LIMA_GEM_SUBMIT, union drm_lima_gem_submit) -+#define DRM_IOCTL_LIMA_WAIT_FENCE DRM_IOW(DRM_COMMAND_BASE + DRM_LIMA_WAIT_FENCE, struct drm_lima_wait_fence) -+#define DRM_IOCTL_LIMA_GEM_WAIT DRM_IOW(DRM_COMMAND_BASE + DRM_LIMA_GEM_WAIT, struct drm_lima_gem_wait) -+#define DRM_IOCTL_LIMA_CTX DRM_IOWR(DRM_COMMAND_BASE + DRM_LIMA_CTX, struct drm_lima_ctx) -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* __LIMA_DRM_H__ */ --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0043-drm-lima-add-mali-4xx-GPU-hardware-regs.patch b/patch/kernel/sunxi-legacy/0043-drm-lima-add-mali-4xx-GPU-hardware-regs.patch deleted file mode 100644 index d000d8228..000000000 --- a/patch/kernel/sunxi-legacy/0043-drm-lima-add-mali-4xx-GPU-hardware-regs.patch +++ /dev/null @@ -1,325 +0,0 @@ -From 68dcb878e43a65cc7129d7a1535da3b133e0e446 Mon Sep 17 00:00:00 2001 -From: Lima Project Developers -Date: Mon, 14 May 2018 21:14:31 +0800 -Subject: [PATCH 043/146] drm/lima: add mali 4xx GPU hardware regs - -Signed-off-by: Qiang Yu -Signed-off-by: Heiko Stuebner ---- - drivers/gpu/drm/lima/lima_regs.h | 304 +++++++++++++++++++++++++++++++ - 1 file changed, 304 insertions(+) - create mode 100644 drivers/gpu/drm/lima/lima_regs.h - -diff --git a/drivers/gpu/drm/lima/lima_regs.h b/drivers/gpu/drm/lima/lima_regs.h -new file mode 100644 -index 000000000000..ea4a37d69b98 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_regs.h -@@ -0,0 +1,304 @@ -+/* -+ * Copyright (C) 2010-2017 ARM Limited. All rights reserved. -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * This program is free software and is provided to you under -+ * the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation, and any use by -+ * you of this program is subject to the terms of such GNU -+ * licence. -+ * -+ * A copy of the licence is included with the program, and -+ * can also be obtained from Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#ifndef __LIMA_REGS_H__ -+#define __LIMA_REGS_H__ -+ -+/* PMU regs */ -+#define LIMA_PMU_POWER_UP 0x00 -+#define LIMA_PMU_POWER_DOWN 0x04 -+#define LIMA_PMU_POWER_GP0_MASK (1 << 0) -+#define LIMA_PMU_POWER_L2_MASK (1 << 1) -+#define LIMA_PMU_POWER_PP_MASK(i) (1 << (2 + i)) -+ -+/* -+ * On Mali450 each block automatically starts up its corresponding L2 -+ * and the PPs are not fully independent controllable. -+ * Instead PP0, PP1-3 and PP4-7 can be turned on or off. -+ */ -+#define LIMA450_PMU_POWER_PP0_MASK BIT(1) -+#define LIMA450_PMU_POWER_PP13_MASK BIT(2) -+#define LIMA450_PMU_POWER_PP47_MASK BIT(3) -+ -+#define LIMA_PMU_STATUS 0x08 -+#define LIMA_PMU_INT_MASK 0x0C -+#define LIMA_PMU_INT_RAWSTAT 0x10 -+#define LIMA_PMU_INT_CLEAR 0x18 -+#define LIMA_PMU_INT_CMD_MASK (1 << 0) -+#define LIMA_PMU_SW_DELAY 0x1C -+ -+/* L2 cache regs */ -+#define LIMA_L2_CACHE_SIZE 0x0004 -+#define LIMA_L2_CACHE_STATUS 0x0008 -+#define LIMA_L2_CACHE_STATUS_COMMAND_BUSY (1 << 0) -+#define LIMA_L2_CACHE_STATUS_DATA_BUSY (1 << 1) -+#define LIMA_L2_CACHE_COMMAND 0x0010 -+#define LIMA_L2_CACHE_COMMAND_CLEAR_ALL (1 << 0) -+#define LIMA_L2_CACHE_CLEAR_PAGE 0x0014 -+#define LIMA_L2_CACHE_MAX_READS 0x0018 -+#define LIMA_L2_CACHE_ENABLE 0x001C -+#define LIMA_L2_CACHE_ENABLE_ACCESS (1 << 0) -+#define LIMA_L2_CACHE_ENABLE_READ_ALLOCATE (1 << 1) -+#define LIMA_L2_CACHE_PERFCNT_SRC0 0x0020 -+#define LIMA_L2_CACHE_PERFCNT_VAL0 0x0024 -+#define LIMA_L2_CACHE_PERFCNT_SRC1 0x0028 -+#define LIMA_L2_CACHE_ERFCNT_VAL1 0x002C -+ -+/* GP regs */ -+#define LIMA_GP_VSCL_START_ADDR 0x00 -+#define LIMA_GP_VSCL_END_ADDR 0x04 -+#define LIMA_GP_PLBUCL_START_ADDR 0x08 -+#define LIMA_GP_PLBUCL_END_ADDR 0x0c -+#define LIMA_GP_PLBU_ALLOC_START_ADDR 0x10 -+#define LIMA_GP_PLBU_ALLOC_END_ADDR 0x14 -+#define LIMA_GP_CMD 0x20 -+#define LIMA_GP_CMD_START_VS (1 << 0) -+#define LIMA_GP_CMD_START_PLBU (1 << 1) -+#define LIMA_GP_CMD_UPDATE_PLBU_ALLOC (1 << 4) -+#define LIMA_GP_CMD_RESET (1 << 5) -+#define LIMA_GP_CMD_FORCE_HANG (1 << 6) -+#define LIMA_GP_CMD_STOP_BUS (1 << 9) -+#define LIMA_GP_CMD_SOFT_RESET (1 << 10) -+#define LIMA_GP_INT_RAWSTAT 0x24 -+#define LIMA_GP_INT_CLEAR 0x28 -+#define LIMA_GP_INT_MASK 0x2C -+#define LIMA_GP_INT_STAT 0x30 -+#define LIMA_GP_IRQ_VS_END_CMD_LST (1 << 0) -+#define LIMA_GP_IRQ_PLBU_END_CMD_LST (1 << 1) -+#define LIMA_GP_IRQ_PLBU_OUT_OF_MEM (1 << 2) -+#define LIMA_GP_IRQ_VS_SEM_IRQ (1 << 3) -+#define LIMA_GP_IRQ_PLBU_SEM_IRQ (1 << 4) -+#define LIMA_GP_IRQ_HANG (1 << 5) -+#define LIMA_GP_IRQ_FORCE_HANG (1 << 6) -+#define LIMA_GP_IRQ_PERF_CNT_0_LIMIT (1 << 7) -+#define LIMA_GP_IRQ_PERF_CNT_1_LIMIT (1 << 8) -+#define LIMA_GP_IRQ_WRITE_BOUND_ERR (1 << 9) -+#define LIMA_GP_IRQ_SYNC_ERROR (1 << 10) -+#define LIMA_GP_IRQ_AXI_BUS_ERROR (1 << 11) -+#define LIMA_GP_IRQ_AXI_BUS_STOPPED (1 << 12) -+#define LIMA_GP_IRQ_VS_INVALID_CMD (1 << 13) -+#define LIMA_GP_IRQ_PLB_INVALID_CMD (1 << 14) -+#define LIMA_GP_IRQ_RESET_COMPLETED (1 << 19) -+#define LIMA_GP_IRQ_SEMAPHORE_UNDERFLOW (1 << 20) -+#define LIMA_GP_IRQ_SEMAPHORE_OVERFLOW (1 << 21) -+#define LIMA_GP_IRQ_PTR_ARRAY_OUT_OF_BOUNDS (1 << 22) -+#define LIMA_GP_WRITE_BOUND_LOW 0x34 -+#define LIMA_GP_PERF_CNT_0_ENABLE 0x3C -+#define LIMA_GP_PERF_CNT_1_ENABLE 0x40 -+#define LIMA_GP_PERF_CNT_0_SRC 0x44 -+#define LIMA_GP_PERF_CNT_1_SRC 0x48 -+#define LIMA_GP_PERF_CNT_0_VALUE 0x4C -+#define LIMA_GP_PERF_CNT_1_VALUE 0x50 -+#define LIMA_GP_PERF_CNT_0_LIMIT 0x54 -+#define LIMA_GP_STATUS 0x68 -+#define LIMA_GP_STATUS_VS_ACTIVE (1 << 1) -+#define LIMA_GP_STATUS_BUS_STOPPED (1 << 2) -+#define LIMA_GP_STATUS_PLBU_ACTIVE (1 << 3) -+#define LIMA_GP_STATUS_BUS_ERROR (1 << 6) -+#define LIMA_GP_STATUS_WRITE_BOUND_ERR (1 << 8) -+#define LIMA_GP_VERSION 0x6C -+#define LIMA_GP_VSCL_START_ADDR_READ 0x80 -+#define LIMA_GP_PLBCL_START_ADDR_READ 0x84 -+#define LIMA_GP_CONTR_AXI_BUS_ERROR_STAT 0x94 -+ -+#define LIMA_GP_IRQ_MASK_ALL \ -+ ( \ -+ LIMA_GP_IRQ_VS_END_CMD_LST | \ -+ LIMA_GP_IRQ_PLBU_END_CMD_LST | \ -+ LIMA_GP_IRQ_PLBU_OUT_OF_MEM | \ -+ LIMA_GP_IRQ_VS_SEM_IRQ | \ -+ LIMA_GP_IRQ_PLBU_SEM_IRQ | \ -+ LIMA_GP_IRQ_HANG | \ -+ LIMA_GP_IRQ_FORCE_HANG | \ -+ LIMA_GP_IRQ_PERF_CNT_0_LIMIT | \ -+ LIMA_GP_IRQ_PERF_CNT_1_LIMIT | \ -+ LIMA_GP_IRQ_WRITE_BOUND_ERR | \ -+ LIMA_GP_IRQ_SYNC_ERROR | \ -+ LIMA_GP_IRQ_AXI_BUS_ERROR | \ -+ LIMA_GP_IRQ_AXI_BUS_STOPPED | \ -+ LIMA_GP_IRQ_VS_INVALID_CMD | \ -+ LIMA_GP_IRQ_PLB_INVALID_CMD | \ -+ LIMA_GP_IRQ_RESET_COMPLETED | \ -+ LIMA_GP_IRQ_SEMAPHORE_UNDERFLOW | \ -+ LIMA_GP_IRQ_SEMAPHORE_OVERFLOW | \ -+ LIMA_GP_IRQ_PTR_ARRAY_OUT_OF_BOUNDS) -+ -+#define LIMA_GP_IRQ_MASK_ERROR \ -+ ( \ -+ LIMA_GP_IRQ_PLBU_OUT_OF_MEM | \ -+ LIMA_GP_IRQ_FORCE_HANG | \ -+ LIMA_GP_IRQ_WRITE_BOUND_ERR | \ -+ LIMA_GP_IRQ_SYNC_ERROR | \ -+ LIMA_GP_IRQ_AXI_BUS_ERROR | \ -+ LIMA_GP_IRQ_VS_INVALID_CMD | \ -+ LIMA_GP_IRQ_PLB_INVALID_CMD | \ -+ LIMA_GP_IRQ_SEMAPHORE_UNDERFLOW | \ -+ LIMA_GP_IRQ_SEMAPHORE_OVERFLOW | \ -+ LIMA_GP_IRQ_PTR_ARRAY_OUT_OF_BOUNDS) -+ -+#define LIMA_GP_IRQ_MASK_USED \ -+ ( \ -+ LIMA_GP_IRQ_VS_END_CMD_LST | \ -+ LIMA_GP_IRQ_PLBU_END_CMD_LST | \ -+ LIMA_GP_IRQ_MASK_ERROR) -+ -+/* PP regs */ -+#define LIMA_PP_FRAME 0x0000 -+#define LIMA_PP_RSW 0x0004 -+#define LIMA_PP_STACK 0x0030 -+#define LIMA_PP_STACK_SIZE 0x0034 -+#define LIMA_PP_ORIGIN_OFFSET_X 0x0040 -+#define LIMA_PP_WB(i) (0x0100 * (i + 1)) -+#define LIMA_PP_WB_SOURCE_SELECT 0x0000 -+#define LIMA_PP_WB_SOURCE_ADDR 0x0004 -+ -+#define LIMA_PP_VERSION 0x1000 -+#define LIMA_PP_CURRENT_REND_LIST_ADDR 0x1004 -+#define LIMA_PP_STATUS 0x1008 -+#define LIMA_PP_STATUS_RENDERING_ACTIVE (1 << 0) -+#define LIMA_PP_STATUS_BUS_STOPPED (1 << 4) -+#define LIMA_PP_CTRL 0x100c -+#define LIMA_PP_CTRL_STOP_BUS (1 << 0) -+#define LIMA_PP_CTRL_FLUSH_CACHES (1 << 3) -+#define LIMA_PP_CTRL_FORCE_RESET (1 << 5) -+#define LIMA_PP_CTRL_START_RENDERING (1 << 6) -+#define LIMA_PP_CTRL_SOFT_RESET (1 << 7) -+#define LIMA_PP_INT_RAWSTAT 0x1020 -+#define LIMA_PP_INT_CLEAR 0x1024 -+#define LIMA_PP_INT_MASK 0x1028 -+#define LIMA_PP_INT_STATUS 0x102c -+#define LIMA_PP_IRQ_END_OF_FRAME (1 << 0) -+#define LIMA_PP_IRQ_END_OF_TILE (1 << 1) -+#define LIMA_PP_IRQ_HANG (1 << 2) -+#define LIMA_PP_IRQ_FORCE_HANG (1 << 3) -+#define LIMA_PP_IRQ_BUS_ERROR (1 << 4) -+#define LIMA_PP_IRQ_BUS_STOP (1 << 5) -+#define LIMA_PP_IRQ_CNT_0_LIMIT (1 << 6) -+#define LIMA_PP_IRQ_CNT_1_LIMIT (1 << 7) -+#define LIMA_PP_IRQ_WRITE_BOUNDARY_ERROR (1 << 8) -+#define LIMA_PP_IRQ_INVALID_PLIST_COMMAND (1 << 9) -+#define LIMA_PP_IRQ_CALL_STACK_UNDERFLOW (1 << 10) -+#define LIMA_PP_IRQ_CALL_STACK_OVERFLOW (1 << 11) -+#define LIMA_PP_IRQ_RESET_COMPLETED (1 << 12) -+#define LIMA_PP_WRITE_BOUNDARY_LOW 0x1044 -+#define LIMA_PP_BUS_ERROR_STATUS 0x1050 -+#define LIMA_PP_PERF_CNT_0_ENABLE 0x1080 -+#define LIMA_PP_PERF_CNT_0_SRC 0x1084 -+#define LIMA_PP_PERF_CNT_0_LIMIT 0x1088 -+#define LIMA_PP_PERF_CNT_0_VALUE 0x108c -+#define LIMA_PP_PERF_CNT_1_ENABLE 0x10a0 -+#define LIMA_PP_PERF_CNT_1_SRC 0x10a4 -+#define LIMA_PP_PERF_CNT_1_LIMIT 0x10a8 -+#define LIMA_PP_PERF_CNT_1_VALUE 0x10ac -+#define LIMA_PP_PERFMON_CONTR 0x10b0 -+#define LIMA_PP_PERFMON_BASE 0x10b4 -+ -+#define LIMA_PP_IRQ_MASK_ALL \ -+ ( \ -+ LIMA_PP_IRQ_END_OF_FRAME | \ -+ LIMA_PP_IRQ_END_OF_TILE | \ -+ LIMA_PP_IRQ_HANG | \ -+ LIMA_PP_IRQ_FORCE_HANG | \ -+ LIMA_PP_IRQ_BUS_ERROR | \ -+ LIMA_PP_IRQ_BUS_STOP | \ -+ LIMA_PP_IRQ_CNT_0_LIMIT | \ -+ LIMA_PP_IRQ_CNT_1_LIMIT | \ -+ LIMA_PP_IRQ_WRITE_BOUNDARY_ERROR | \ -+ LIMA_PP_IRQ_INVALID_PLIST_COMMAND | \ -+ LIMA_PP_IRQ_CALL_STACK_UNDERFLOW | \ -+ LIMA_PP_IRQ_CALL_STACK_OVERFLOW | \ -+ LIMA_PP_IRQ_RESET_COMPLETED) -+ -+#define LIMA_PP_IRQ_MASK_ERROR \ -+ ( \ -+ LIMA_PP_IRQ_FORCE_HANG | \ -+ LIMA_PP_IRQ_BUS_ERROR | \ -+ LIMA_PP_IRQ_WRITE_BOUNDARY_ERROR | \ -+ LIMA_PP_IRQ_INVALID_PLIST_COMMAND | \ -+ LIMA_PP_IRQ_CALL_STACK_UNDERFLOW | \ -+ LIMA_PP_IRQ_CALL_STACK_OVERFLOW) -+ -+#define LIMA_PP_IRQ_MASK_USED \ -+ ( \ -+ LIMA_PP_IRQ_END_OF_FRAME | \ -+ LIMA_PP_IRQ_MASK_ERROR) -+ -+/* MMU regs */ -+#define LIMA_MMU_DTE_ADDR 0x0000 -+#define LIMA_MMU_STATUS 0x0004 -+#define LIMA_MMU_STATUS_PAGING_ENABLED (1 << 0) -+#define LIMA_MMU_STATUS_PAGE_FAULT_ACTIVE (1 << 1) -+#define LIMA_MMU_STATUS_STALL_ACTIVE (1 << 2) -+#define LIMA_MMU_STATUS_IDLE (1 << 3) -+#define LIMA_MMU_STATUS_REPLAY_BUFFER_EMPTY (1 << 4) -+#define LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE (1 << 5) -+#define LIMA_MMU_STATUS_BUS_ID(x) ((x >> 6) & 0x1F) -+#define LIMA_MMU_COMMAND 0x0008 -+#define LIMA_MMU_COMMAND_ENABLE_PAGING 0x00 -+#define LIMA_MMU_COMMAND_DISABLE_PAGING 0x01 -+#define LIMA_MMU_COMMAND_ENABLE_STALL 0x02 -+#define LIMA_MMU_COMMAND_DISABLE_STALL 0x03 -+#define LIMA_MMU_COMMAND_ZAP_CACHE 0x04 -+#define LIMA_MMU_COMMAND_PAGE_FAULT_DONE 0x05 -+#define LIMA_MMU_COMMAND_HARD_RESET 0x06 -+#define LIMA_MMU_PAGE_FAULT_ADDR 0x000C -+#define LIMA_MMU_ZAP_ONE_LINE 0x0010 -+#define LIMA_MMU_INT_RAWSTAT 0x0014 -+#define LIMA_MMU_INT_CLEAR 0x0018 -+#define LIMA_MMU_INT_MASK 0x001C -+#define LIMA_MMU_INT_PAGE_FAULT 0x01 -+#define LIMA_MMU_INT_READ_BUS_ERROR 0x02 -+#define LIMA_MMU_INT_STATUS 0x0020 -+ -+#define LIMA_VM_FLAG_PRESENT (1 << 0) -+#define LIMA_VM_FLAG_READ_PERMISSION (1 << 1) -+#define LIMA_VM_FLAG_WRITE_PERMISSION (1 << 2) -+#define LIMA_VM_FLAG_OVERRIDE_CACHE (1 << 3) -+#define LIMA_VM_FLAG_WRITE_CACHEABLE (1 << 4) -+#define LIMA_VM_FLAG_WRITE_ALLOCATE (1 << 5) -+#define LIMA_VM_FLAG_WRITE_BUFFERABLE (1 << 6) -+#define LIMA_VM_FLAG_READ_CACHEABLE (1 << 7) -+#define LIMA_VM_FLAG_READ_ALLOCATE (1 << 8) -+#define LIMA_VM_FLAG_MASK 0x1FF -+ -+#define LIMA_VM_FLAGS_CACHE ( \ -+ LIMA_VM_FLAG_PRESENT | \ -+ LIMA_VM_FLAG_READ_PERMISSION | \ -+ LIMA_VM_FLAG_WRITE_PERMISSION | \ -+ LIMA_VM_FLAG_OVERRIDE_CACHE | \ -+ LIMA_VM_FLAG_WRITE_CACHEABLE | \ -+ LIMA_VM_FLAG_WRITE_BUFFERABLE | \ -+ LIMA_VM_FLAG_READ_CACHEABLE | \ -+ LIMA_VM_FLAG_READ_ALLOCATE ) -+ -+#define LIMA_VM_FLAGS_UNCACHE ( \ -+ LIMA_VM_FLAG_PRESENT | \ -+ LIMA_VM_FLAG_READ_PERMISSION | \ -+ LIMA_VM_FLAG_WRITE_PERMISSION ) -+ -+/* DLBU regs */ -+#define LIMA_DLBU_MASTER_TLLIST_PHYS_ADDR 0x0000 -+#define LIMA_DLBU_MASTER_TLLIST_VADDR 0x0004 -+#define LIMA_DLBU_TLLIST_VBASEADDR 0x0008 -+#define LIMA_DLBU_FB_DIM 0x000C -+#define LIMA_DLBU_TLLIST_CONF 0x0010 -+#define LIMA_DLBU_START_TILE_POS 0x0014 -+#define LIMA_DLBU_PP_ENABLE_MASK 0x0018 -+ -+/* BCAST regs */ -+#define LIMA_BCAST_BROADCAST_MASK 0x0 -+#define LIMA_BCAST_INTERRUPT_MASK 0x4 -+ -+#endif --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0044-drm-lima-add-lima-core-driver.patch b/patch/kernel/sunxi-legacy/0044-drm-lima-add-lima-core-driver.patch deleted file mode 100644 index 91ada2a2d..000000000 --- a/patch/kernel/sunxi-legacy/0044-drm-lima-add-lima-core-driver.patch +++ /dev/null @@ -1,573 +0,0 @@ -From 3cce83eb3e3b54e3ffc668724722736cf7a72055 Mon Sep 17 00:00:00 2001 -From: Lima Project Developers -Date: Mon, 14 May 2018 21:32:02 +0800 -Subject: [PATCH 044/146] drm/lima: add lima core driver - -Signed-off-by: Qiang Yu -Signed-off-by: Heiko Stuebner -Signed-off-by: Erico Nunes ---- - drivers/gpu/drm/lima/lima_drv.c | 466 ++++++++++++++++++++++++++++++++ - drivers/gpu/drm/lima/lima_drv.h | 77 ++++++ - 2 files changed, 543 insertions(+) - create mode 100644 drivers/gpu/drm/lima/lima_drv.c - create mode 100644 drivers/gpu/drm/lima/lima_drv.h - -diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c -new file mode 100644 -index 000000000000..4df24a6cfff3 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_drv.c -@@ -0,0 +1,466 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "lima_drv.h" -+#include "lima_gem.h" -+#include "lima_gem_prime.h" -+#include "lima_vm.h" -+ -+int lima_sched_timeout_ms = 0; -+int lima_sched_max_tasks = 32; -+int lima_max_mem = -1; -+ -+MODULE_PARM_DESC(sched_timeout_ms, "task run timeout in ms (0 = no timeout (default))"); -+module_param_named(sched_timeout_ms, lima_sched_timeout_ms, int, 0444); -+ -+MODULE_PARM_DESC(sched_max_tasks, "max queued task num in a context (default 32)"); -+module_param_named(sched_max_tasks, lima_sched_max_tasks, int, 0444); -+ -+MODULE_PARM_DESC(max_mem, "Max memory size in MB can be used (<0 = auto)"); -+module_param_named(max_mem, lima_max_mem, int, 0444); -+ -+static int lima_ioctl_info(struct drm_device *dev, void *data, struct drm_file *file) -+{ -+ struct drm_lima_info *info = data; -+ struct lima_device *ldev = to_lima_dev(dev); -+ -+ switch (ldev->id) { -+ case lima_gpu_mali400: -+ info->gpu_id = LIMA_INFO_GPU_MALI400; -+ break; -+ case lima_gpu_mali450: -+ info->gpu_id = LIMA_INFO_GPU_MALI450; -+ break; -+ default: -+ return -ENODEV; -+ } -+ info->num_pp = ldev->pipe[lima_pipe_pp].num_processor; -+ info->va_start = ldev->va_start; -+ info->va_end = ldev->va_end; -+ return 0; -+} -+ -+static int lima_ioctl_gem_create(struct drm_device *dev, void *data, struct drm_file *file) -+{ -+ struct drm_lima_gem_create *args = data; -+ -+ if (args->flags) -+ return -EINVAL; -+ -+ if (args->size == 0) -+ return -EINVAL; -+ -+ return lima_gem_create_handle(dev, file, args->size, args->flags, &args->handle); -+} -+ -+static int lima_ioctl_gem_info(struct drm_device *dev, void *data, struct drm_file *file) -+{ -+ struct drm_lima_gem_info *args = data; -+ -+ return lima_gem_mmap_offset(file, args->handle, &args->offset); -+} -+ -+static int lima_ioctl_gem_va(struct drm_device *dev, void *data, struct drm_file *file) -+{ -+ struct drm_lima_gem_va *args = data; -+ -+ switch (args->op) { -+ case LIMA_VA_OP_MAP: -+ return lima_gem_va_map(file, args->handle, args->flags, args->va); -+ case LIMA_VA_OP_UNMAP: -+ return lima_gem_va_unmap(file, args->handle, args->va); -+ default: -+ return -EINVAL; -+ } -+} -+ -+static int lima_ioctl_gem_submit(struct drm_device *dev, void *data, struct drm_file *file) -+{ -+ struct drm_lima_gem_submit_in *args = data; -+ struct lima_device *ldev = to_lima_dev(dev); -+ struct lima_drm_priv *priv = file->driver_priv; -+ struct drm_lima_gem_submit_bo *bos; -+ struct ttm_validate_buffer *vbs; -+ union drm_lima_gem_submit_dep *deps = NULL; -+ struct lima_sched_pipe *pipe; -+ struct lima_sched_task *task; -+ struct lima_ctx *ctx; -+ struct lima_submit submit = {0}; -+ int err = 0, size; -+ -+ if (args->pipe >= lima_pipe_num || args->nr_bos == 0) -+ return -EINVAL; -+ -+ if (args->flags & ~(LIMA_SUBMIT_FLAG_EXPLICIT_FENCE | -+ LIMA_SUBMIT_FLAG_SYNC_FD_OUT)) -+ return -EINVAL; -+ -+ pipe = ldev->pipe + args->pipe; -+ if (args->frame_size != pipe->frame_size) -+ return -EINVAL; -+ -+ size = args->nr_bos * (sizeof(*submit.bos) + sizeof(*submit.vbs)) + -+ args->nr_deps * sizeof(*submit.deps); -+ bos = kzalloc(size, GFP_KERNEL); -+ if (!bos) -+ return -ENOMEM; -+ -+ size = args->nr_bos * sizeof(*submit.bos); -+ if (copy_from_user(bos, u64_to_user_ptr(args->bos), size)) { -+ err = -EFAULT; -+ goto out0; -+ } -+ -+ vbs = (void *)bos + size; -+ -+ if (args->nr_deps) { -+ deps = (void *)vbs + args->nr_bos * sizeof(*submit.vbs); -+ size = args->nr_deps * sizeof(*submit.deps); -+ if (copy_from_user(deps, u64_to_user_ptr(args->deps), size)) { -+ err = -EFAULT; -+ goto out0; -+ } -+ } -+ -+ task = kmem_cache_zalloc(pipe->task_slab, GFP_KERNEL); -+ if (!task) { -+ err = -ENOMEM; -+ goto out0; -+ } -+ -+ task->frame = task + 1; -+ if (copy_from_user(task->frame, u64_to_user_ptr(args->frame), args->frame_size)) { -+ err = -EFAULT; -+ goto out1; -+ } -+ -+ err = pipe->task_validate(pipe, task); -+ if (err) -+ goto out1; -+ -+ ctx = lima_ctx_get(&priv->ctx_mgr, args->ctx); -+ if (!ctx) { -+ err = -ENOENT; -+ goto out1; -+ } -+ -+ submit.pipe = args->pipe; -+ submit.bos = bos; -+ submit.vbs = vbs; -+ submit.nr_bos = args->nr_bos; -+ submit.task = task; -+ submit.ctx = ctx; -+ submit.deps = deps; -+ submit.nr_deps = args->nr_deps; -+ submit.flags = args->flags; -+ -+ err = lima_gem_submit(file, &submit); -+ if (!err) { -+ struct drm_lima_gem_submit_out *out = data; -+ out->fence = submit.fence; -+ out->done = submit.done; -+ out->sync_fd = submit.sync_fd; -+ } -+ -+ lima_ctx_put(ctx); -+out1: -+ if (err) -+ kmem_cache_free(pipe->task_slab, task); -+out0: -+ kfree(bos); -+ return err; -+} -+ -+static int lima_wait_fence(struct dma_fence *fence, u64 timeout_ns) -+{ -+ signed long ret; -+ -+ if (!timeout_ns) -+ ret = dma_fence_is_signaled(fence) ? 0 : -EBUSY; -+ else { -+ unsigned long timeout = lima_timeout_to_jiffies(timeout_ns); -+ -+ /* must use long for result check because in 64bit arch int -+ * will overflow if timeout is too large and get <0 result -+ */ -+ ret = dma_fence_wait_timeout(fence, true, timeout); -+ if (ret == 0) -+ ret = timeout ? -ETIMEDOUT : -EBUSY; -+ else if (ret > 0) -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+static int lima_ioctl_wait_fence(struct drm_device *dev, void *data, struct drm_file *file) -+{ -+ struct drm_lima_wait_fence *args = data; -+ struct lima_drm_priv *priv = file->driver_priv; -+ struct dma_fence *fence; -+ int err = 0; -+ -+ fence = lima_ctx_get_native_fence(&priv->ctx_mgr, args->ctx, -+ args->pipe, args->seq); -+ if (IS_ERR(fence)) -+ return PTR_ERR(fence); -+ -+ if (fence) { -+ err = lima_wait_fence(fence, args->timeout_ns); -+ dma_fence_put(fence); -+ } -+ -+ return err; -+} -+ -+static int lima_ioctl_gem_wait(struct drm_device *dev, void *data, struct drm_file *file) -+{ -+ struct drm_lima_gem_wait *args = data; -+ -+ if (!(args->op & (LIMA_GEM_WAIT_READ|LIMA_GEM_WAIT_WRITE))) -+ return -EINVAL; -+ -+ return lima_gem_wait(file, args->handle, args->op, args->timeout_ns); -+} -+ -+static int lima_ioctl_ctx(struct drm_device *dev, void *data, struct drm_file *file) -+{ -+ struct drm_lima_ctx *args = data; -+ struct lima_drm_priv *priv = file->driver_priv; -+ struct lima_device *ldev = to_lima_dev(dev); -+ -+ if (args->op == LIMA_CTX_OP_CREATE) -+ return lima_ctx_create(ldev, &priv->ctx_mgr, &args->id); -+ else if (args->op == LIMA_CTX_OP_FREE) -+ return lima_ctx_free(&priv->ctx_mgr, args->id); -+ -+ return -EINVAL; -+} -+ -+static int lima_drm_driver_open(struct drm_device *dev, struct drm_file *file) -+{ -+ int err; -+ struct lima_drm_priv *priv; -+ struct lima_device *ldev = to_lima_dev(dev); -+ -+ priv = kzalloc(sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->vm = lima_vm_create(ldev); -+ if (!priv->vm) { -+ err = -ENOMEM; -+ goto err_out0; -+ } -+ -+ lima_ctx_mgr_init(&priv->ctx_mgr); -+ -+ file->driver_priv = priv; -+ return 0; -+ -+err_out0: -+ kfree(priv); -+ return err; -+} -+ -+static void lima_drm_driver_preclose(struct drm_device *dev, struct drm_file *file) -+{ -+ struct lima_drm_priv *priv = file->driver_priv; -+ -+ lima_ctx_mgr_fini(&priv->ctx_mgr); -+} -+ -+static void lima_drm_driver_postclose(struct drm_device *dev, struct drm_file *file) -+{ -+ struct lima_drm_priv *priv = file->driver_priv; -+ -+ lima_vm_put(priv->vm); -+ kfree(priv); -+} -+ -+static const struct drm_ioctl_desc lima_drm_driver_ioctls[] = { -+ DRM_IOCTL_DEF_DRV(LIMA_INFO, lima_ioctl_info, DRM_AUTH|DRM_RENDER_ALLOW), -+ DRM_IOCTL_DEF_DRV(LIMA_GEM_CREATE, lima_ioctl_gem_create, DRM_AUTH|DRM_RENDER_ALLOW), -+ DRM_IOCTL_DEF_DRV(LIMA_GEM_INFO, lima_ioctl_gem_info, DRM_AUTH|DRM_RENDER_ALLOW), -+ DRM_IOCTL_DEF_DRV(LIMA_GEM_VA, lima_ioctl_gem_va, DRM_AUTH|DRM_RENDER_ALLOW), -+ DRM_IOCTL_DEF_DRV(LIMA_GEM_SUBMIT, lima_ioctl_gem_submit, DRM_AUTH|DRM_RENDER_ALLOW), -+ DRM_IOCTL_DEF_DRV(LIMA_WAIT_FENCE, lima_ioctl_wait_fence, DRM_AUTH|DRM_RENDER_ALLOW), -+ DRM_IOCTL_DEF_DRV(LIMA_GEM_WAIT, lima_ioctl_gem_wait, DRM_AUTH|DRM_RENDER_ALLOW), -+ DRM_IOCTL_DEF_DRV(LIMA_CTX, lima_ioctl_ctx, DRM_AUTH|DRM_RENDER_ALLOW), -+}; -+ -+static const struct file_operations lima_drm_driver_fops = { -+ .owner = THIS_MODULE, -+ .open = drm_open, -+ .release = drm_release, -+ .unlocked_ioctl = drm_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = drm_compat_ioctl, -+#endif -+ .mmap = lima_gem_mmap, -+}; -+ -+static struct drm_driver lima_drm_driver = { -+ .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_PRIME, -+ .open = lima_drm_driver_open, -+ .preclose = lima_drm_driver_preclose, -+ .postclose = lima_drm_driver_postclose, -+ .ioctls = lima_drm_driver_ioctls, -+ .num_ioctls = ARRAY_SIZE(lima_drm_driver_ioctls), -+ .fops = &lima_drm_driver_fops, -+ .gem_free_object_unlocked = lima_gem_free_object, -+ .gem_open_object = lima_gem_object_open, -+ .gem_close_object = lima_gem_object_close, -+ .name = "lima", -+ .desc = "lima DRM", -+ .date = "20170325", -+ .major = 1, -+ .minor = 0, -+ .patchlevel = 0, -+ -+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle, -+ .gem_prime_import = drm_gem_prime_import, -+ .gem_prime_import_sg_table = lima_gem_prime_import_sg_table, -+ .prime_handle_to_fd = drm_gem_prime_handle_to_fd, -+ .gem_prime_export = drm_gem_prime_export, -+ .gem_prime_res_obj = lima_gem_prime_res_obj, -+ .gem_prime_get_sg_table = lima_gem_prime_get_sg_table, -+}; -+ -+static int lima_pdev_probe(struct platform_device *pdev) -+{ -+ struct lima_device *ldev; -+ struct drm_device *ddev; -+ int err; -+ -+ ldev = devm_kzalloc(&pdev->dev, sizeof(*ldev), GFP_KERNEL); -+ if (!ldev) -+ return -ENOMEM; -+ -+ ldev->pdev = pdev; -+ ldev->dev = &pdev->dev; -+ ldev->id = (enum lima_gpu_id)of_device_get_match_data(&pdev->dev); -+ -+ platform_set_drvdata(pdev, ldev); -+ -+ /* Allocate and initialize the DRM device. */ -+ ddev = drm_dev_alloc(&lima_drm_driver, &pdev->dev); -+ if (IS_ERR(ddev)) -+ return PTR_ERR(ddev); -+ -+ ddev->dev_private = ldev; -+ ldev->ddev = ddev; -+ -+ err = lima_device_init(ldev); -+ if (err) { -+ dev_err(&pdev->dev, "Fatal error during GPU init\n"); -+ goto err_out0; -+ } -+ -+ /* -+ * Register the DRM device with the core and the connectors with -+ * sysfs. -+ */ -+ err = drm_dev_register(ddev, 0); -+ if (err < 0) -+ goto err_out1; -+ -+ return 0; -+ -+err_out1: -+ lima_device_fini(ldev); -+err_out0: -+ drm_dev_unref(ddev); -+ return err; -+} -+ -+static int lima_pdev_remove(struct platform_device *pdev) -+{ -+ struct lima_device *ldev = platform_get_drvdata(pdev); -+ struct drm_device *ddev = ldev->ddev; -+ -+ drm_dev_unregister(ddev); -+ lima_device_fini(ldev); -+ drm_dev_unref(ddev); -+ return 0; -+} -+ -+static const struct of_device_id dt_match[] = { -+ { .compatible = "arm,mali-400", .data = (void *)lima_gpu_mali400 }, -+ { .compatible = "arm,mali-450", .data = (void *)lima_gpu_mali450 }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, dt_match); -+ -+static struct platform_driver lima_platform_driver = { -+ .probe = lima_pdev_probe, -+ .remove = lima_pdev_remove, -+ .driver = { -+ .name = "lima", -+ .of_match_table = dt_match, -+ }, -+}; -+ -+static void lima_check_module_param(void) -+{ -+ if (lima_sched_max_tasks < 4) -+ lima_sched_max_tasks = 4; -+ else -+ lima_sched_max_tasks = roundup_pow_of_two(lima_sched_max_tasks); -+ -+ if (lima_max_mem < 32) -+ lima_max_mem = -1; -+} -+ -+static int __init lima_init(void) -+{ -+ int ret; -+ -+ lima_check_module_param(); -+ ret = lima_sched_slab_init(); -+ if (ret) -+ return ret; -+ -+ ret = platform_driver_register(&lima_platform_driver); -+ if (ret) -+ lima_sched_slab_fini(); -+ -+ return ret; -+} -+module_init(lima_init); -+ -+static void __exit lima_exit(void) -+{ -+ platform_driver_unregister(&lima_platform_driver); -+ lima_sched_slab_fini(); -+} -+module_exit(lima_exit); -+ -+MODULE_AUTHOR("Lima Project Developers"); -+MODULE_DESCRIPTION("Lima DRM Driver"); -+MODULE_LICENSE("GPL v2"); -diff --git a/drivers/gpu/drm/lima/lima_drv.h b/drivers/gpu/drm/lima/lima_drv.h -new file mode 100644 -index 000000000000..2f5f51da21db ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_drv.h -@@ -0,0 +1,77 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef __LIMA_DRV_H__ -+#define __LIMA_DRV_H__ -+ -+#include -+#include -+ -+#include "lima_ctx.h" -+ -+extern int lima_sched_timeout_ms; -+extern int lima_sched_max_tasks; -+extern int lima_max_mem; -+ -+struct lima_vm; -+struct lima_bo; -+struct lima_sched_task; -+ -+struct drm_lima_gem_submit_bo; -+ -+#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) -+ -+struct lima_drm_priv { -+ struct lima_vm *vm; -+ struct lima_ctx_mgr ctx_mgr; -+}; -+ -+struct lima_submit { -+ struct lima_ctx *ctx; -+ int pipe; -+ u32 flags; -+ -+ struct drm_lima_gem_submit_bo *bos; -+ struct ttm_validate_buffer *vbs; -+ u32 nr_bos; -+ -+ struct ttm_validate_buffer vm_pd_vb; -+ struct ww_acquire_ctx ticket; -+ struct list_head duplicates; -+ struct list_head validated; -+ -+ union drm_lima_gem_submit_dep *deps; -+ u32 nr_deps; -+ -+ struct lima_sched_task *task; -+ -+ uint32_t fence; -+ uint32_t done; -+ int sync_fd; -+}; -+ -+static inline struct lima_drm_priv * -+to_lima_drm_priv(struct drm_file *file) -+{ -+ return file->driver_priv; -+} -+ -+#endif --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0045-drm-lima-add-GPU-device-functions.patch b/patch/kernel/sunxi-legacy/0045-drm-lima-add-GPU-device-functions.patch deleted file mode 100644 index e8761b325..000000000 --- a/patch/kernel/sunxi-legacy/0045-drm-lima-add-GPU-device-functions.patch +++ /dev/null @@ -1,573 +0,0 @@ -From 1656622231f4fc9ba6260ad1c0a44e574793a04c Mon Sep 17 00:00:00 2001 -From: Lima Project Developers -Date: Mon, 14 May 2018 21:41:53 +0800 -Subject: [PATCH 045/146] drm/lima: add GPU device functions - -Signed-off-by: Qiang Yu -Signed-off-by: Simon Shields -Signed-off-by: Heiko Stuebner ---- - drivers/gpu/drm/lima/lima_device.c | 407 +++++++++++++++++++++++++++++ - drivers/gpu/drm/lima/lima_device.h | 136 ++++++++++ - 2 files changed, 543 insertions(+) - create mode 100644 drivers/gpu/drm/lima/lima_device.c - create mode 100644 drivers/gpu/drm/lima/lima_device.h - -diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c -new file mode 100644 -index 000000000000..a6c3905a0c85 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_device.c -@@ -0,0 +1,407 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#include "lima_device.h" -+#include "lima_gp.h" -+#include "lima_pp.h" -+#include "lima_mmu.h" -+#include "lima_pmu.h" -+#include "lima_l2_cache.h" -+#include "lima_dlbu.h" -+#include "lima_bcast.h" -+#include "lima_vm.h" -+ -+struct lima_ip_desc { -+ char *name; -+ char *irq_name; -+ bool must_have[lima_gpu_num]; -+ int offset[lima_gpu_num]; -+ -+ int (*init)(struct lima_ip *); -+ void (*fini)(struct lima_ip *); -+}; -+ -+#define LIMA_IP_DESC(ipname, mst0, mst1, off0, off1, func, irq) \ -+ [lima_ip_##ipname] = { \ -+ .name = #ipname, \ -+ .irq_name = irq, \ -+ .must_have = { \ -+ [lima_gpu_mali400] = mst0, \ -+ [lima_gpu_mali450] = mst1, \ -+ }, \ -+ .offset = { \ -+ [lima_gpu_mali400] = off0, \ -+ [lima_gpu_mali450] = off1, \ -+ }, \ -+ .init = lima_##func##_init, \ -+ .fini = lima_##func##_fini, \ -+ } -+ -+static struct lima_ip_desc lima_ip_desc[lima_ip_num] = { -+ LIMA_IP_DESC(pmu, false, false, 0x02000, 0x02000, pmu, "pmu"), -+ LIMA_IP_DESC(l2_cache0, true, true, 0x01000, 0x10000, l2_cache, NULL), -+ LIMA_IP_DESC(l2_cache1, false, true, -1, 0x01000, l2_cache, NULL), -+ LIMA_IP_DESC(l2_cache2, false, false, -1, 0x11000, l2_cache, NULL), -+ LIMA_IP_DESC(gp, true, true, 0x00000, 0x00000, gp, "gp"), -+ LIMA_IP_DESC(pp0, true, true, 0x08000, 0x08000, pp, "pp0"), -+ LIMA_IP_DESC(pp1, false, false, 0x0A000, 0x0A000, pp, "pp1"), -+ LIMA_IP_DESC(pp2, false, false, 0x0C000, 0x0C000, pp, "pp2"), -+ LIMA_IP_DESC(pp3, false, false, 0x0E000, 0x0E000, pp, "pp3"), -+ LIMA_IP_DESC(pp4, false, false, -1, 0x28000, pp, "pp4"), -+ LIMA_IP_DESC(pp5, false, false, -1, 0x2A000, pp, "pp5"), -+ LIMA_IP_DESC(pp6, false, false, -1, 0x2C000, pp, "pp6"), -+ LIMA_IP_DESC(pp7, false, false, -1, 0x2E000, pp, "pp7"), -+ LIMA_IP_DESC(gpmmu, true, true, 0x03000, 0x03000, mmu, "gpmmu"), -+ LIMA_IP_DESC(ppmmu0, true, true, 0x04000, 0x04000, mmu, "ppmmu0"), -+ LIMA_IP_DESC(ppmmu1, false, false, 0x05000, 0x05000, mmu, "ppmmu1"), -+ LIMA_IP_DESC(ppmmu2, false, false, 0x06000, 0x06000, mmu, "ppmmu2"), -+ LIMA_IP_DESC(ppmmu3, false, false, 0x07000, 0x07000, mmu, "ppmmu3"), -+ LIMA_IP_DESC(ppmmu4, false, false, -1, 0x1C000, mmu, "ppmmu4"), -+ LIMA_IP_DESC(ppmmu5, false, false, -1, 0x1D000, mmu, "ppmmu5"), -+ LIMA_IP_DESC(ppmmu6, false, false, -1, 0x1E000, mmu, "ppmmu6"), -+ LIMA_IP_DESC(ppmmu7, false, false, -1, 0x1F000, mmu, "ppmmu7"), -+ LIMA_IP_DESC(dlbu, false, true, -1, 0x14000, dlbu, NULL), -+ LIMA_IP_DESC(bcast, false, true, -1, 0x13000, bcast, NULL), -+ LIMA_IP_DESC(pp_bcast, false, true, -1, 0x16000, pp_bcast, "pp"), -+ LIMA_IP_DESC(ppmmu_bcast, false, true, -1, 0x15000, mmu, NULL), -+}; -+ -+const char *lima_ip_name(struct lima_ip *ip) -+{ -+ return lima_ip_desc[ip->id].name; -+} -+ -+static int lima_clk_init(struct lima_device *dev) -+{ -+ int err; -+ unsigned long bus_rate, gpu_rate; -+ -+ dev->clk_bus = devm_clk_get(dev->dev, "bus"); -+ if (IS_ERR(dev->clk_bus)) { -+ dev_err(dev->dev, "get bus clk failed %ld\n", PTR_ERR(dev->clk_bus)); -+ return PTR_ERR(dev->clk_bus); -+ } -+ -+ dev->clk_gpu = devm_clk_get(dev->dev, "core"); -+ if (IS_ERR(dev->clk_gpu)) { -+ dev_err(dev->dev, "get core clk failed %ld\n", PTR_ERR(dev->clk_gpu)); -+ return PTR_ERR(dev->clk_gpu); -+ } -+ -+ bus_rate = clk_get_rate(dev->clk_bus); -+ dev_info(dev->dev, "bus rate = %lu\n", bus_rate); -+ -+ gpu_rate = clk_get_rate(dev->clk_gpu); -+ dev_info(dev->dev, "mod rate = %lu", gpu_rate); -+ -+ if ((err = clk_prepare_enable(dev->clk_bus))) -+ return err; -+ if ((err = clk_prepare_enable(dev->clk_gpu))) -+ goto error_out0; -+ -+ dev->reset = devm_reset_control_get_optional(dev->dev, NULL); -+ if (IS_ERR(dev->reset)) { -+ err = PTR_ERR(dev->reset); -+ goto error_out1; -+ } else if (dev->reset != NULL) { -+ if ((err = reset_control_deassert(dev->reset))) -+ goto error_out1; -+ } -+ -+ return 0; -+ -+error_out1: -+ clk_disable_unprepare(dev->clk_gpu); -+error_out0: -+ clk_disable_unprepare(dev->clk_bus); -+ return err; -+} -+ -+static void lima_clk_fini(struct lima_device *dev) -+{ -+ if (dev->reset != NULL) -+ reset_control_assert(dev->reset); -+ clk_disable_unprepare(dev->clk_gpu); -+ clk_disable_unprepare(dev->clk_bus); -+} -+ -+static int lima_regulator_init(struct lima_device *dev) -+{ -+ int ret; -+ dev->regulator = devm_regulator_get_optional(dev->dev, "mali"); -+ if (IS_ERR(dev->regulator)) { -+ ret = PTR_ERR(dev->regulator); -+ dev->regulator = NULL; -+ if (ret == -ENODEV) -+ return 0; -+ dev_err(dev->dev, "failed to get regulator: %ld\n", PTR_ERR(dev->regulator)); -+ return ret; -+ } -+ -+ ret = regulator_enable(dev->regulator); -+ if (ret < 0) { -+ dev_err(dev->dev, "failed to enable regulator: %d\n", ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void lima_regulator_fini(struct lima_device *dev) -+{ -+ if (dev->regulator) -+ regulator_disable(dev->regulator); -+} -+ -+static int lima_init_ip(struct lima_device *dev, int index) -+{ -+ struct lima_ip_desc *desc = lima_ip_desc + index; -+ struct lima_ip *ip = dev->ip + index; -+ int offset = desc->offset[dev->id]; -+ bool must = desc->must_have[dev->id]; -+ int err; -+ -+ if (offset < 0) -+ return 0; -+ -+ ip->dev = dev; -+ ip->id = index; -+ ip->iomem = dev->iomem + offset; -+ if (desc->irq_name) { -+ err = platform_get_irq_byname(dev->pdev, desc->irq_name); -+ if (err < 0) -+ goto out; -+ ip->irq = err; -+ } -+ -+ err = desc->init(ip); -+ if (!err) { -+ ip->present = true; -+ return 0; -+ } -+ -+out: -+ return must ? err : 0; -+} -+ -+static void lima_fini_ip(struct lima_device *ldev, int index) -+{ -+ struct lima_ip_desc *desc = lima_ip_desc + index; -+ struct lima_ip *ip = ldev->ip + index; -+ -+ if (ip->present) -+ desc->fini(ip); -+} -+ -+static int lima_init_gp_pipe(struct lima_device *dev) -+{ -+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp; -+ int err; -+ -+ if ((err = lima_sched_pipe_init(pipe, "gp"))) -+ return err; -+ -+ pipe->l2_cache[pipe->num_l2_cache++] = dev->ip + lima_ip_l2_cache0; -+ pipe->mmu[pipe->num_mmu++] = dev->ip + lima_ip_gpmmu; -+ pipe->processor[pipe->num_processor++] = dev->ip + lima_ip_gp; -+ -+ if ((err = lima_gp_pipe_init(dev))) { -+ lima_sched_pipe_fini(pipe); -+ return err; -+ } -+ -+ return 0; -+} -+ -+static void lima_fini_gp_pipe(struct lima_device *dev) -+{ -+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp; -+ -+ lima_gp_pipe_fini(dev); -+ lima_sched_pipe_fini(pipe); -+} -+ -+static int lima_init_pp_pipe(struct lima_device *dev) -+{ -+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; -+ int err, i; -+ -+ if ((err = lima_sched_pipe_init(pipe, "pp"))) -+ return err; -+ -+ for (i = 0; i < LIMA_SCHED_PIPE_MAX_PROCESSOR; i++) { -+ struct lima_ip *pp = dev->ip + lima_ip_pp0 + i; -+ struct lima_ip *ppmmu = dev->ip + lima_ip_ppmmu0 + i; -+ struct lima_ip *l2_cache; -+ -+ if (dev->id == lima_gpu_mali400) -+ l2_cache = dev->ip + lima_ip_l2_cache0; -+ else -+ l2_cache = dev->ip + lima_ip_l2_cache1 + (i >> 2); -+ -+ if (pp->present && ppmmu->present && l2_cache->present) { -+ pipe->mmu[pipe->num_mmu++] = ppmmu; -+ pipe->processor[pipe->num_processor++] = pp; -+ if (!pipe->l2_cache[i >> 2]) -+ pipe->l2_cache[pipe->num_l2_cache++] = l2_cache; -+ } -+ } -+ -+ if (dev->ip[lima_ip_bcast].present) { -+ pipe->bcast_processor = dev->ip + lima_ip_pp_bcast; -+ pipe->bcast_mmu = dev->ip + lima_ip_ppmmu_bcast; -+ } -+ -+ if ((err = lima_pp_pipe_init(dev))) { -+ lima_sched_pipe_fini(pipe); -+ return err; -+ } -+ -+ return 0; -+} -+ -+static void lima_fini_pp_pipe(struct lima_device *dev) -+{ -+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; -+ -+ lima_pp_pipe_fini(dev); -+ lima_sched_pipe_fini(pipe); -+} -+ -+int lima_device_init(struct lima_device *ldev) -+{ -+ int err, i; -+ struct resource *res; -+ -+ dma_set_coherent_mask(ldev->dev, DMA_BIT_MASK(32)); -+ -+ err = lima_clk_init(ldev); -+ if (err) { -+ dev_err(ldev->dev, "clk init fail %d\n", err); -+ return err; -+ } -+ -+ if ((err = lima_regulator_init(ldev))) { -+ dev_err(ldev->dev, "regulator init fail %d\n", err); -+ goto err_out0; -+ } -+ -+ err = lima_ttm_init(ldev); -+ if (err) -+ goto err_out1; -+ -+ ldev->empty_vm = lima_vm_create(ldev); -+ if (!ldev->empty_vm) { -+ err = -ENOMEM; -+ goto err_out2; -+ } -+ -+ ldev->va_start = 0; -+ if (ldev->id == lima_gpu_mali450) { -+ ldev->va_end = LIMA_VA_RESERVE_START; -+ ldev->dlbu_cpu = dma_alloc_wc( -+ ldev->dev, LIMA_PAGE_SIZE, -+ &ldev->dlbu_dma, GFP_KERNEL); -+ if (!ldev->dlbu_cpu) { -+ err = -ENOMEM; -+ goto err_out3; -+ } -+ } -+ else -+ ldev->va_end = LIMA_VA_RESERVE_END; -+ -+ res = platform_get_resource(ldev->pdev, IORESOURCE_MEM, 0); -+ ldev->iomem = devm_ioremap_resource(ldev->dev, res); -+ if (IS_ERR(ldev->iomem)) { -+ dev_err(ldev->dev, "fail to ioremap iomem\n"); -+ err = PTR_ERR(ldev->iomem); -+ goto err_out4; -+ } -+ -+ for (i = 0; i < lima_ip_num; i++) { -+ err = lima_init_ip(ldev, i); -+ if (err) -+ goto err_out5; -+ } -+ -+ err = lima_init_gp_pipe(ldev); -+ if (err) -+ goto err_out5; -+ -+ err = lima_init_pp_pipe(ldev); -+ if (err) -+ goto err_out6; -+ -+ if (ldev->id == lima_gpu_mali450) { -+ lima_dlbu_enable(ldev); -+ lima_bcast_enable(ldev); -+ } -+ -+ return 0; -+ -+err_out6: -+ lima_fini_gp_pipe(ldev); -+err_out5: -+ while (--i >= 0) -+ lima_fini_ip(ldev, i); -+err_out4: -+ if (ldev->dlbu_cpu) -+ dma_free_wc(ldev->dev, LIMA_PAGE_SIZE, -+ ldev->dlbu_cpu, ldev->dlbu_dma); -+err_out3: -+ lima_vm_put(ldev->empty_vm); -+err_out2: -+ lima_ttm_fini(ldev); -+err_out1: -+ lima_regulator_fini(ldev); -+err_out0: -+ lima_clk_fini(ldev); -+ return err; -+} -+ -+void lima_device_fini(struct lima_device *ldev) -+{ -+ int i; -+ -+ lima_fini_pp_pipe(ldev); -+ lima_fini_gp_pipe(ldev); -+ -+ for (i = lima_ip_num - 1; i >= 0; i--) -+ lima_fini_ip(ldev, i); -+ -+ if (ldev->dlbu_cpu) -+ dma_free_wc(ldev->dev, LIMA_PAGE_SIZE, -+ ldev->dlbu_cpu, ldev->dlbu_dma); -+ -+ lima_vm_put(ldev->empty_vm); -+ -+ lima_ttm_fini(ldev); -+ -+ lima_regulator_fini(ldev); -+ -+ lima_clk_fini(ldev); -+} -diff --git a/drivers/gpu/drm/lima/lima_device.h b/drivers/gpu/drm/lima/lima_device.h -new file mode 100644 -index 000000000000..6c9c26b9e122 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_device.h -@@ -0,0 +1,136 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef __LIMA_DEVICE_H__ -+#define __LIMA_DEVICE_H__ -+ -+#include -+ -+#include "lima_sched.h" -+#include "lima_ttm.h" -+ -+enum lima_gpu_id { -+ lima_gpu_mali400 = 0, -+ lima_gpu_mali450, -+ lima_gpu_num, -+}; -+ -+enum lima_ip_id { -+ lima_ip_pmu, -+ lima_ip_gpmmu, -+ lima_ip_ppmmu0, -+ lima_ip_ppmmu1, -+ lima_ip_ppmmu2, -+ lima_ip_ppmmu3, -+ lima_ip_ppmmu4, -+ lima_ip_ppmmu5, -+ lima_ip_ppmmu6, -+ lima_ip_ppmmu7, -+ lima_ip_gp, -+ lima_ip_pp0, -+ lima_ip_pp1, -+ lima_ip_pp2, -+ lima_ip_pp3, -+ lima_ip_pp4, -+ lima_ip_pp5, -+ lima_ip_pp6, -+ lima_ip_pp7, -+ lima_ip_l2_cache0, -+ lima_ip_l2_cache1, -+ lima_ip_l2_cache2, -+ lima_ip_dlbu, -+ lima_ip_bcast, -+ lima_ip_pp_bcast, -+ lima_ip_ppmmu_bcast, -+ lima_ip_num, -+}; -+ -+struct lima_device; -+ -+struct lima_ip { -+ struct lima_device *dev; -+ enum lima_ip_id id; -+ bool present; -+ -+ void __iomem *iomem; -+ int irq; -+ -+ union { -+ /* pmu */ -+ unsigned switch_delay; -+ /* gp/pp */ -+ bool async_reset; -+ /* l2 cache */ -+ spinlock_t lock; -+ } data; -+}; -+ -+enum lima_pipe_id { -+ lima_pipe_gp, -+ lima_pipe_pp, -+ lima_pipe_num, -+}; -+ -+struct lima_device { -+ struct device *dev; -+ struct drm_device *ddev; -+ struct platform_device *pdev; -+ -+ enum lima_gpu_id id; -+ int num_pp; -+ -+ void __iomem *iomem; -+ struct clk *clk_bus; -+ struct clk *clk_gpu; -+ struct reset_control *reset; -+ struct regulator *regulator; -+ -+ struct lima_ip ip[lima_ip_num]; -+ struct lima_sched_pipe pipe[lima_pipe_num]; -+ -+ struct lima_mman mman; -+ -+ struct lima_vm *empty_vm; -+ uint64_t va_start; -+ uint64_t va_end; -+ -+ u32 *dlbu_cpu; -+ dma_addr_t dlbu_dma; -+}; -+ -+static inline struct lima_device * -+to_lima_dev(struct drm_device *dev) -+{ -+ return dev->dev_private; -+} -+ -+static inline struct lima_device * -+ttm_to_lima_dev(struct ttm_bo_device *dev) -+{ -+ return container_of(dev, struct lima_device, mman.bdev); -+} -+ -+int lima_device_init(struct lima_device *ldev); -+void lima_device_fini(struct lima_device *ldev); -+ -+const char *lima_ip_name(struct lima_ip *ip); -+ -+#endif --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0046-drm-lima-add-PMU-related-functions.patch b/patch/kernel/sunxi-legacy/0046-drm-lima-add-PMU-related-functions.patch deleted file mode 100644 index 9222ac9b7..000000000 --- a/patch/kernel/sunxi-legacy/0046-drm-lima-add-PMU-related-functions.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 399e0d92074e30643eee980e744b6cac64bef7a2 Mon Sep 17 00:00:00 2001 -From: Lima Project Developers -Date: Mon, 14 May 2018 21:47:28 +0800 -Subject: [PATCH 046/146] drm/lima: add PMU related functions - -Signed-off-by: Qiang Yu -Signed-off-by: Heiko Stuebner ---- - drivers/gpu/drm/lima/lima_pmu.c | 85 +++++++++++++++++++++++++++++++++ - drivers/gpu/drm/lima/lima_pmu.h | 30 ++++++++++++ - 2 files changed, 115 insertions(+) - create mode 100644 drivers/gpu/drm/lima/lima_pmu.c - create mode 100644 drivers/gpu/drm/lima/lima_pmu.h - -diff --git a/drivers/gpu/drm/lima/lima_pmu.c b/drivers/gpu/drm/lima/lima_pmu.c -new file mode 100644 -index 000000000000..255a64e9f265 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_pmu.c -@@ -0,0 +1,85 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include -+#include -+#include -+ -+#include "lima_device.h" -+#include "lima_pmu.h" -+#include "lima_regs.h" -+ -+#define pmu_write(reg, data) writel(data, ip->iomem + LIMA_PMU_##reg) -+#define pmu_read(reg) readl(ip->iomem + LIMA_PMU_##reg) -+ -+static int lima_pmu_wait_cmd(struct lima_ip *ip) -+{ -+ struct lima_device *dev = ip->dev; -+ u32 stat, timeout; -+ -+ for (timeout = 1000000; timeout > 0; timeout--) { -+ stat = pmu_read(INT_RAWSTAT); -+ if (stat & LIMA_PMU_INT_CMD_MASK) -+ break; -+ } -+ -+ if (!timeout) { -+ dev_err(dev->dev, "timeout wait pmd cmd\n"); -+ return -ETIMEDOUT; -+ } -+ -+ pmu_write(INT_CLEAR, LIMA_PMU_INT_CMD_MASK); -+ return 0; -+} -+ -+int lima_pmu_init(struct lima_ip *ip) -+{ -+ int err; -+ u32 stat; -+ struct lima_device *dev = ip->dev; -+ struct device_node *np = dev->dev->of_node; -+ -+ /* If this value is too low, when in high GPU clk freq, -+ * GPU will be in unstable state. */ -+ if (of_property_read_u32(np, "switch-delay", &ip->data.switch_delay)) -+ ip->data.switch_delay = 0xff; -+ -+ pmu_write(INT_MASK, 0); -+ pmu_write(SW_DELAY, ip->data.switch_delay); -+ -+ /* status reg 1=off 0=on */ -+ stat = pmu_read(STATUS); -+ -+ /* power up all ip */ -+ if (stat) { -+ pmu_write(POWER_UP, stat); -+ err = lima_pmu_wait_cmd(ip); -+ if (err) -+ return err; -+ } -+ return 0; -+} -+ -+void lima_pmu_fini(struct lima_ip *ip) -+{ -+ -+} -diff --git a/drivers/gpu/drm/lima/lima_pmu.h b/drivers/gpu/drm/lima/lima_pmu.h -new file mode 100644 -index 000000000000..fb68a7059a37 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_pmu.h -@@ -0,0 +1,30 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef __LIMA_PMU_H__ -+#define __LIMA_PMU_H__ -+ -+struct lima_ip; -+ -+int lima_pmu_init(struct lima_ip *ip); -+void lima_pmu_fini(struct lima_ip *ip); -+ -+#endif --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0047-drm-lima-add-L2-cache-functions.patch b/patch/kernel/sunxi-legacy/0047-drm-lima-add-L2-cache-functions.patch deleted file mode 100644 index 95e46a4a9..000000000 --- a/patch/kernel/sunxi-legacy/0047-drm-lima-add-L2-cache-functions.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 821cfa3044859b50d6d2f2f1fdbd1761bb53099b Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Mon, 14 May 2018 22:03:24 +0800 -Subject: [PATCH 047/146] drm/lima: add L2 cache functions - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_l2_cache.c | 98 ++++++++++++++++++++++++++++ - drivers/gpu/drm/lima/lima_l2_cache.h | 32 +++++++++ - 2 files changed, 130 insertions(+) - create mode 100644 drivers/gpu/drm/lima/lima_l2_cache.c - create mode 100644 drivers/gpu/drm/lima/lima_l2_cache.h - -diff --git a/drivers/gpu/drm/lima/lima_l2_cache.c b/drivers/gpu/drm/lima/lima_l2_cache.c -new file mode 100644 -index 000000000000..a9b85de5c51a ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_l2_cache.c -@@ -0,0 +1,98 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include -+#include -+ -+#include "lima_device.h" -+#include "lima_l2_cache.h" -+#include "lima_regs.h" -+ -+#define l2_cache_write(reg, data) writel(data, ip->iomem + LIMA_L2_CACHE_##reg) -+#define l2_cache_read(reg) readl(ip->iomem + LIMA_L2_CACHE_##reg) -+ -+static int lima_l2_cache_wait_idle(struct lima_ip *ip) -+{ -+ int timeout; -+ struct lima_device *dev = ip->dev; -+ -+ for (timeout = 100000; timeout > 0; timeout--) { -+ if (!(l2_cache_read(STATUS) & LIMA_L2_CACHE_STATUS_COMMAND_BUSY)) -+ break; -+ } -+ if (!timeout) { -+ dev_err(dev->dev, "l2 cache wait command timeout\n"); -+ return -ETIMEDOUT; -+ } -+ return 0; -+} -+ -+int lima_l2_cache_flush(struct lima_ip *ip) -+{ -+ int ret; -+ -+ spin_lock(&ip->data.lock); -+ l2_cache_write(COMMAND, LIMA_L2_CACHE_COMMAND_CLEAR_ALL); -+ ret = lima_l2_cache_wait_idle(ip); -+ spin_unlock(&ip->data.lock); -+ return ret; -+} -+ -+int lima_l2_cache_init(struct lima_ip *ip) -+{ -+ int i, err; -+ u32 size; -+ struct lima_device *dev = ip->dev; -+ -+ /* l2_cache2 only exists when one of PP4-7 present */ -+ if (ip->id == lima_ip_l2_cache2) { -+ for (i = lima_ip_pp4; i <= lima_ip_pp7; i++) { -+ if (dev->ip[i].present) -+ break; -+ } -+ if (i > lima_ip_pp7) -+ return -ENODEV; -+ } -+ -+ spin_lock_init(&ip->data.lock); -+ -+ size = l2_cache_read(SIZE); -+ dev_info(dev->dev, "l2 cache %uK, %u-way, %ubyte cache line, %ubit external bus\n", -+ 1 << (((size >> 16) & 0xff) - 10), -+ 1 << ((size >> 8) & 0xff), -+ 1 << (size & 0xff), -+ 1 << ((size >> 24) & 0xff)); -+ -+ err = lima_l2_cache_flush(ip); -+ if (err) -+ return err; -+ -+ l2_cache_write(ENABLE, LIMA_L2_CACHE_ENABLE_ACCESS | LIMA_L2_CACHE_ENABLE_READ_ALLOCATE); -+ l2_cache_write(MAX_READS, 0x1c); -+ -+ return 0; -+} -+ -+void lima_l2_cache_fini(struct lima_ip *ip) -+{ -+ -+} -diff --git a/drivers/gpu/drm/lima/lima_l2_cache.h b/drivers/gpu/drm/lima/lima_l2_cache.h -new file mode 100644 -index 000000000000..4a35725bf38d ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_l2_cache.h -@@ -0,0 +1,32 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef __LIMA_L2_CACHE_H__ -+#define __LIMA_L2_CACHE_H__ -+ -+struct lima_ip; -+ -+int lima_l2_cache_init(struct lima_ip *ip); -+void lima_l2_cache_fini(struct lima_ip *ip); -+ -+int lima_l2_cache_flush(struct lima_ip *ip); -+ -+#endif --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0048-drm-lima-add-GP-related-functions.patch b/patch/kernel/sunxi-legacy/0048-drm-lima-add-GP-related-functions.patch deleted file mode 100644 index ae6e7692b..000000000 --- a/patch/kernel/sunxi-legacy/0048-drm-lima-add-GP-related-functions.patch +++ /dev/null @@ -1,358 +0,0 @@ -From ddd7da175a64f80b659132f6d9e0fac616d6bf6d Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Mon, 14 May 2018 22:05:37 +0800 -Subject: [PATCH 048/146] drm/lima: add GP related functions - -GP is a processor for OpenGL vertex shader -processing. - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_gp.c | 293 +++++++++++++++++++++++++++++++++ - drivers/gpu/drm/lima/lima_gp.h | 34 ++++ - 2 files changed, 327 insertions(+) - create mode 100644 drivers/gpu/drm/lima/lima_gp.c - create mode 100644 drivers/gpu/drm/lima/lima_gp.h - -diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c -new file mode 100644 -index 000000000000..8fb49986418a ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_gp.c -@@ -0,0 +1,293 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "lima_device.h" -+#include "lima_gp.h" -+#include "lima_regs.h" -+ -+#define gp_write(reg, data) writel(data, ip->iomem + LIMA_GP_##reg) -+#define gp_read(reg) readl(ip->iomem + LIMA_GP_##reg) -+ -+static irqreturn_t lima_gp_irq_handler(int irq, void *data) -+{ -+ struct lima_ip *ip = data; -+ struct lima_device *dev = ip->dev; -+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp; -+ u32 state = gp_read(INT_STAT); -+ u32 status = gp_read(STATUS); -+ bool done = false; -+ -+ /* for shared irq case */ -+ if (!state) -+ return IRQ_NONE; -+ -+ if (state & LIMA_GP_IRQ_MASK_ERROR) { -+ dev_err(dev->dev, "gp error irq state=%x status=%x\n", -+ state, status); -+ -+ /* mask all interrupts before hard reset */ -+ gp_write(INT_MASK, 0); -+ -+ pipe->error = true; -+ done = true; -+ } -+ else { -+ bool valid = state & (LIMA_GP_IRQ_VS_END_CMD_LST | -+ LIMA_GP_IRQ_PLBU_END_CMD_LST); -+ bool active = status & (LIMA_GP_STATUS_VS_ACTIVE | -+ LIMA_GP_STATUS_PLBU_ACTIVE); -+ done = valid && !active; -+ } -+ -+ gp_write(INT_CLEAR, state); -+ -+ if (done) -+ lima_sched_pipe_task_done(pipe); -+ -+ return IRQ_HANDLED; -+} -+ -+static void lima_gp_soft_reset_async(struct lima_ip *ip) -+{ -+ if (ip->data.async_reset) -+ return; -+ -+ gp_write(INT_MASK, 0); -+ gp_write(INT_CLEAR, LIMA_GP_IRQ_RESET_COMPLETED); -+ gp_write(CMD, LIMA_GP_CMD_SOFT_RESET); -+ ip->data.async_reset = true; -+} -+ -+static int lima_gp_soft_reset_async_wait(struct lima_ip *ip) -+{ -+ struct lima_device *dev = ip->dev; -+ int timeout; -+ -+ if (!ip->data.async_reset) -+ return 0; -+ -+ for (timeout = 1000; timeout > 0; timeout--) { -+ if (gp_read(INT_RAWSTAT) & LIMA_GP_IRQ_RESET_COMPLETED) -+ break; -+ } -+ if (!timeout) { -+ dev_err(dev->dev, "gp soft reset time out\n"); -+ return -ETIMEDOUT; -+ } -+ -+ gp_write(INT_CLEAR, LIMA_GP_IRQ_MASK_ALL); -+ gp_write(INT_MASK, LIMA_GP_IRQ_MASK_USED); -+ -+ ip->data.async_reset = false; -+ return 0; -+} -+ -+static int lima_gp_task_validate(struct lima_sched_pipe *pipe, -+ struct lima_sched_task *task) -+{ -+ struct drm_lima_gp_frame *frame = task->frame; -+ u32 *f = frame->frame; -+ (void)pipe; -+ -+ if (f[LIMA_GP_VSCL_START_ADDR >> 2] > -+ f[LIMA_GP_VSCL_END_ADDR >> 2] || -+ f[LIMA_GP_PLBUCL_START_ADDR >> 2] > -+ f[LIMA_GP_PLBUCL_END_ADDR >> 2] || -+ f[LIMA_GP_PLBU_ALLOC_START_ADDR >> 2] > -+ f[LIMA_GP_PLBU_ALLOC_END_ADDR >> 2]) -+ return -EINVAL; -+ -+ if (f[LIMA_GP_VSCL_START_ADDR >> 2] == -+ f[LIMA_GP_VSCL_END_ADDR >> 2] && -+ f[LIMA_GP_PLBUCL_START_ADDR >> 2] == -+ f[LIMA_GP_PLBUCL_END_ADDR >> 2]) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static void lima_gp_task_run(struct lima_sched_pipe *pipe, -+ struct lima_sched_task *task) -+{ -+ struct lima_ip *ip = pipe->processor[0]; -+ struct drm_lima_gp_frame *frame = task->frame; -+ u32 *f = frame->frame; -+ u32 cmd = 0; -+ int i; -+ -+ if (f[LIMA_GP_VSCL_START_ADDR >> 2] != -+ f[LIMA_GP_VSCL_END_ADDR >> 2]) -+ cmd |= LIMA_GP_CMD_START_VS; -+ if (f[LIMA_GP_PLBUCL_START_ADDR >> 2] != -+ f[LIMA_GP_PLBUCL_END_ADDR >> 2]) -+ cmd |= LIMA_GP_CMD_START_PLBU; -+ -+ /* before any hw ops, wait last success task async soft reset */ -+ lima_gp_soft_reset_async_wait(ip); -+ -+ for (i = 0; i < LIMA_GP_FRAME_REG_NUM; i++) -+ writel(f[i], ip->iomem + LIMA_GP_VSCL_START_ADDR + i * 4); -+ -+ gp_write(CMD, LIMA_GP_CMD_UPDATE_PLBU_ALLOC); -+ gp_write(CMD, cmd); -+} -+ -+static int lima_gp_hard_reset(struct lima_ip *ip) -+{ -+ struct lima_device *dev = ip->dev; -+ int timeout; -+ -+ gp_write(PERF_CNT_0_LIMIT, 0xC0FFE000); -+ gp_write(INT_MASK, 0); -+ gp_write(CMD, LIMA_GP_CMD_RESET); -+ for (timeout = 1000; timeout > 0; timeout--) { -+ gp_write(PERF_CNT_0_LIMIT, 0xC01A0000); -+ if (gp_read(PERF_CNT_0_LIMIT) == 0xC01A0000) -+ break; -+ } -+ if (!timeout) { -+ dev_err(dev->dev, "gp hard reset timeout\n"); -+ return -ETIMEDOUT; -+ } -+ -+ gp_write(PERF_CNT_0_LIMIT, 0); -+ gp_write(INT_CLEAR, LIMA_GP_IRQ_MASK_ALL); -+ gp_write(INT_MASK, LIMA_GP_IRQ_MASK_USED); -+ return 0; -+} -+ -+static void lima_gp_task_fini(struct lima_sched_pipe *pipe) -+{ -+ lima_gp_soft_reset_async(pipe->processor[0]); -+} -+ -+static void lima_gp_task_error(struct lima_sched_pipe *pipe) -+{ -+ lima_gp_hard_reset(pipe->processor[0]); -+} -+ -+static void lima_gp_task_mmu_error(struct lima_sched_pipe *pipe) -+{ -+ lima_sched_pipe_task_done(pipe); -+} -+ -+static void lima_gp_print_version(struct lima_ip *ip) -+{ -+ u32 version, major, minor; -+ char *name; -+ -+ version = gp_read(VERSION); -+ major = (version >> 8) & 0xFF; -+ minor = version & 0xFF; -+ switch (version >> 16) { -+ case 0xA07: -+ name = "mali200"; -+ break; -+ case 0xC07: -+ name = "mali300"; -+ break; -+ case 0xB07: -+ name = "mali400"; -+ break; -+ case 0xD07: -+ name = "mali450"; -+ break; -+ default: -+ name = "unknow"; -+ break; -+ } -+ dev_info(ip->dev->dev, "%s - %s version major %d minor %d\n", -+ lima_ip_name(ip), name, major, minor); -+} -+ -+static struct kmem_cache *lima_gp_task_slab = NULL; -+static int lima_gp_task_slab_refcnt = 0; -+ -+int lima_gp_init(struct lima_ip *ip) -+{ -+ struct lima_device *dev = ip->dev; -+ int err; -+ -+ lima_gp_print_version(ip); -+ -+ ip->data.async_reset = false; -+ lima_gp_soft_reset_async(ip); -+ err = lima_gp_soft_reset_async_wait(ip); -+ if (err) -+ return err; -+ -+ err = devm_request_irq(dev->dev, ip->irq, lima_gp_irq_handler, 0, -+ lima_ip_name(ip), ip); -+ if (err) { -+ dev_err(dev->dev, "gp %s fail to request irq\n", -+ lima_ip_name(ip)); -+ return err; -+ } -+ -+ return 0; -+} -+ -+void lima_gp_fini(struct lima_ip *ip) -+{ -+ -+} -+ -+int lima_gp_pipe_init(struct lima_device *dev) -+{ -+ int frame_size = sizeof(struct drm_lima_gp_frame); -+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp; -+ -+ if (!lima_gp_task_slab) { -+ lima_gp_task_slab = kmem_cache_create( -+ "lima_gp_task", sizeof(struct lima_sched_task) + frame_size, -+ 0, SLAB_HWCACHE_ALIGN, NULL); -+ if (!lima_gp_task_slab) -+ return -ENOMEM; -+ } -+ lima_gp_task_slab_refcnt++; -+ -+ pipe->frame_size = frame_size; -+ pipe->task_slab = lima_gp_task_slab; -+ -+ pipe->task_validate = lima_gp_task_validate; -+ pipe->task_run = lima_gp_task_run; -+ pipe->task_fini = lima_gp_task_fini; -+ pipe->task_error = lima_gp_task_error; -+ pipe->task_mmu_error = lima_gp_task_mmu_error; -+ -+ return 0; -+} -+ -+void lima_gp_pipe_fini(struct lima_device *dev) -+{ -+ if (!--lima_gp_task_slab_refcnt) { -+ kmem_cache_destroy(lima_gp_task_slab); -+ lima_gp_task_slab = NULL; -+ } -+} -diff --git a/drivers/gpu/drm/lima/lima_gp.h b/drivers/gpu/drm/lima/lima_gp.h -new file mode 100644 -index 000000000000..8354911e50ce ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_gp.h -@@ -0,0 +1,34 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef __LIMA_GP_H__ -+#define __LIMA_GP_H__ -+ -+struct lima_ip; -+struct lima_device; -+ -+int lima_gp_init(struct lima_ip *ip); -+void lima_gp_fini(struct lima_ip *ip); -+ -+int lima_gp_pipe_init(struct lima_device *dev); -+void lima_gp_pipe_fini(struct lima_device *dev); -+ -+#endif --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0049-drm-lima-add-PP-related-functions.patch b/patch/kernel/sunxi-legacy/0049-drm-lima-add-PP-related-functions.patch deleted file mode 100644 index aedea81fd..000000000 --- a/patch/kernel/sunxi-legacy/0049-drm-lima-add-PP-related-functions.patch +++ /dev/null @@ -1,487 +0,0 @@ -From f3a488deb6ebf451b0a1f928e5692ea3d1af4410 Mon Sep 17 00:00:00 2001 -From: Lima Project Developers -Date: Mon, 14 May 2018 22:10:48 +0800 -Subject: [PATCH 049/146] drm/lima: add PP related functions - -PP is a processor used for OpenGL fragment shader -processing. - -Signed-off-by: Qiang Yu -Signed-off-by: Heiko Stuebner ---- - drivers/gpu/drm/lima/lima_pp.c | 418 +++++++++++++++++++++++++++++++++ - drivers/gpu/drm/lima/lima_pp.h | 37 +++ - 2 files changed, 455 insertions(+) - create mode 100644 drivers/gpu/drm/lima/lima_pp.c - create mode 100644 drivers/gpu/drm/lima/lima_pp.h - -diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c -new file mode 100644 -index 000000000000..371d6b70c271 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_pp.c -@@ -0,0 +1,418 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "lima_device.h" -+#include "lima_pp.h" -+#include "lima_dlbu.h" -+#include "lima_bcast.h" -+#include "lima_vm.h" -+#include "lima_regs.h" -+ -+#define pp_write(reg, data) writel(data, ip->iomem + LIMA_PP_##reg) -+#define pp_read(reg) readl(ip->iomem + LIMA_PP_##reg) -+ -+static void lima_pp_handle_irq(struct lima_ip *ip, u32 state) -+{ -+ struct lima_device *dev = ip->dev; -+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; -+ -+ if (state & LIMA_PP_IRQ_MASK_ERROR) { -+ u32 status = pp_read(STATUS); -+ -+ dev_err(dev->dev, "pp error irq state=%x status=%x\n", -+ state, status); -+ -+ pipe->error = true; -+ -+ /* mask all interrupts before hard reset */ -+ pp_write(INT_MASK, 0); -+ } -+ -+ pp_write(INT_CLEAR, state); -+} -+ -+static irqreturn_t lima_pp_irq_handler(int irq, void *data) -+{ -+ struct lima_ip *ip = data; -+ struct lima_device *dev = ip->dev; -+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; -+ u32 state = pp_read(INT_STATUS); -+ -+ /* for shared irq case */ -+ if (!state) -+ return IRQ_NONE; -+ -+ lima_pp_handle_irq(ip, state); -+ -+ if (atomic_dec_and_test(&pipe->task)) -+ lima_sched_pipe_task_done(pipe); -+ -+ return IRQ_HANDLED; -+} -+ -+static irqreturn_t lima_pp_bcast_irq_handler(int irq, void *data) -+{ -+ int i; -+ irqreturn_t ret = IRQ_NONE; -+ struct lima_ip *pp_bcast = data; -+ struct lima_device *dev = pp_bcast->dev; -+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; -+ -+ for (i = 0; i < pipe->num_processor; i++) { -+ struct lima_ip *ip = pipe->processor[i]; -+ u32 status, state; -+ -+ if (pipe->done & (1 << i)) -+ continue; -+ -+ /* status read first in case int state change in the middle -+ * which may miss the interrupt handling */ -+ status = pp_read(STATUS); -+ state = pp_read(INT_STATUS); -+ -+ if (state) { -+ lima_pp_handle_irq(ip, state); -+ ret = IRQ_HANDLED; -+ } -+ else { -+ if (status & LIMA_PP_STATUS_RENDERING_ACTIVE) -+ continue; -+ } -+ -+ pipe->done |= (1 << i); -+ if (atomic_dec_and_test(&pipe->task)) -+ lima_sched_pipe_task_done(pipe); -+ } -+ -+ return ret; -+} -+ -+static void lima_pp_soft_reset_async(struct lima_ip *ip) -+{ -+ if (ip->data.async_reset) -+ return; -+ -+ pp_write(INT_MASK, 0); -+ pp_write(INT_RAWSTAT, LIMA_PP_IRQ_MASK_ALL); -+ pp_write(CTRL, LIMA_PP_CTRL_SOFT_RESET); -+ ip->data.async_reset = true; -+} -+ -+static int lima_pp_soft_reset_async_wait_one(struct lima_ip *ip) -+{ -+ struct lima_device *dev = ip->dev; -+ int timeout; -+ -+ for (timeout = 1000; timeout > 0; timeout--) { -+ if (!(pp_read(STATUS) & LIMA_PP_STATUS_RENDERING_ACTIVE) && -+ pp_read(INT_RAWSTAT) == LIMA_PP_IRQ_RESET_COMPLETED) -+ break; -+ } -+ if (!timeout) { -+ dev_err(dev->dev, "pp %s reset time out\n", lima_ip_name(ip)); -+ return -ETIMEDOUT; -+ } -+ -+ pp_write(INT_CLEAR, LIMA_PP_IRQ_MASK_ALL); -+ pp_write(INT_MASK, LIMA_PP_IRQ_MASK_USED); -+ return 0; -+} -+ -+static int lima_pp_soft_reset_async_wait(struct lima_ip *ip) -+{ -+ int i, err = 0; -+ -+ if (!ip->data.async_reset) -+ return 0; -+ -+ if (ip->id == lima_ip_pp_bcast) { -+ struct lima_device *dev = ip->dev; -+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; -+ for (i = 0; i < pipe->num_processor; i++) -+ err |= lima_pp_soft_reset_async_wait_one(pipe->processor[i]); -+ } -+ else -+ err = lima_pp_soft_reset_async_wait_one(ip); -+ -+ ip->data.async_reset = false; -+ return err; -+} -+ -+static void lima_pp_start_task(struct lima_ip *ip, u32 *frame, u32 *wb, -+ bool skip_stack_addr) -+{ -+ int i, j, n = 0; -+ -+ for (i = 0; i < LIMA_PP_FRAME_REG_NUM; i++) { -+ if (skip_stack_addr && i * 4 == LIMA_PP_STACK) -+ continue; -+ -+ writel(frame[i], ip->iomem + LIMA_PP_FRAME + i * 4); -+ } -+ -+ for (i = 0; i < 3; i++) { -+ for (j = 0; j < LIMA_PP_WB_REG_NUM; j++) -+ writel(wb[n++], ip->iomem + LIMA_PP_WB(i) + j * 4); -+ } -+ -+ pp_write(CTRL, LIMA_PP_CTRL_START_RENDERING); -+} -+ -+static int lima_pp_hard_reset(struct lima_ip *ip) -+{ -+ struct lima_device *dev = ip->dev; -+ int timeout; -+ -+ pp_write(PERF_CNT_0_LIMIT, 0xC0FFE000); -+ pp_write(INT_MASK, 0); -+ pp_write(CTRL, LIMA_PP_CTRL_FORCE_RESET); -+ for (timeout = 1000; timeout > 0; timeout--) { -+ pp_write(PERF_CNT_0_LIMIT, 0xC01A0000); -+ if (pp_read(PERF_CNT_0_LIMIT) == 0xC01A0000) -+ break; -+ } -+ if (!timeout) { -+ dev_err(dev->dev, "pp hard reset timeout\n"); -+ return -ETIMEDOUT; -+ } -+ -+ pp_write(PERF_CNT_0_LIMIT, 0); -+ pp_write(INT_CLEAR, LIMA_PP_IRQ_MASK_ALL); -+ pp_write(INT_MASK, LIMA_PP_IRQ_MASK_USED); -+ return 0; -+} -+ -+static void lima_pp_print_version(struct lima_ip *ip) -+{ -+ u32 version, major, minor; -+ char *name; -+ -+ version = pp_read(VERSION); -+ major = (version >> 8) & 0xFF; -+ minor = version & 0xFF; -+ switch (version >> 16) { -+ case 0xC807: -+ name = "mali200"; -+ break; -+ case 0xCE07: -+ name = "mali300"; -+ break; -+ case 0xCD07: -+ name = "mali400"; -+ break; -+ case 0xCF07: -+ name = "mali450"; -+ break; -+ default: -+ name = "unknow"; -+ break; -+ } -+ dev_info(ip->dev->dev, "%s - %s version major %d minor %d\n", -+ lima_ip_name(ip), name, major, minor); -+} -+ -+int lima_pp_init(struct lima_ip *ip) -+{ -+ struct lima_device *dev = ip->dev; -+ int err; -+ -+ lima_pp_print_version(ip); -+ -+ ip->data.async_reset = false; -+ lima_pp_soft_reset_async(ip); -+ err = lima_pp_soft_reset_async_wait(ip); -+ if (err) -+ return err; -+ -+ err = devm_request_irq(dev->dev, ip->irq, lima_pp_irq_handler, -+ IRQF_SHARED, lima_ip_name(ip), ip); -+ if (err) { -+ dev_err(dev->dev, "pp %s fail to request irq\n", -+ lima_ip_name(ip)); -+ return err; -+ } -+ -+ return 0; -+} -+ -+void lima_pp_fini(struct lima_ip *ip) -+{ -+ -+} -+ -+int lima_pp_bcast_init(struct lima_ip *ip) -+{ -+ struct lima_device *dev = ip->dev; -+ int err; -+ -+ err = devm_request_irq(dev->dev, ip->irq, lima_pp_bcast_irq_handler, -+ IRQF_SHARED, lima_ip_name(ip), ip); -+ if (err) { -+ dev_err(dev->dev, "pp %s fail to request irq\n", -+ lima_ip_name(ip)); -+ return err; -+ } -+ -+ return 0; -+} -+ -+void lima_pp_bcast_fini(struct lima_ip *ip) -+{ -+ -+} -+ -+static int lima_pp_task_validate(struct lima_sched_pipe *pipe, -+ struct lima_sched_task *task) -+{ -+ if (!pipe->bcast_processor) { -+ struct drm_lima_m400_pp_frame *f = task->frame; -+ -+ if (f->num_pp > pipe->num_processor) -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static void lima_pp_task_run(struct lima_sched_pipe *pipe, -+ struct lima_sched_task *task) -+{ -+ if (pipe->bcast_processor) { -+ struct drm_lima_m450_pp_frame *frame = task->frame; -+ struct lima_device *dev = pipe->bcast_processor->dev; -+ int i; -+ -+ pipe->done = 0; -+ atomic_set(&pipe->task, pipe->num_processor); -+ -+ frame->frame[LIMA_PP_FRAME >> 2] = LIMA_VA_RESERVE_DLBU; -+ lima_dlbu_set_reg(dev->ip + lima_ip_dlbu, frame->dlbu_regs); -+ -+ lima_pp_soft_reset_async_wait(pipe->bcast_processor); -+ -+ for (i = 0; i < pipe->num_processor; i++) { -+ struct lima_ip *ip = pipe->processor[i]; -+ pp_write(STACK, frame->fragment_stack_address[i]); -+ } -+ -+ lima_pp_start_task(pipe->bcast_processor, frame->frame, -+ frame->wb, true); -+ } -+ else { -+ struct drm_lima_m400_pp_frame *frame = task->frame; -+ int i; -+ -+ atomic_set(&pipe->task, frame->num_pp); -+ -+ for (i = 0; i < frame->num_pp; i++) { -+ frame->frame[LIMA_PP_FRAME >> 2] = -+ frame->plbu_array_address[i]; -+ frame->frame[LIMA_PP_STACK >> 2] = -+ frame->fragment_stack_address[i]; -+ -+ lima_pp_soft_reset_async_wait(pipe->processor[i]); -+ -+ lima_pp_start_task(pipe->processor[i], frame->frame, -+ frame->wb, false); -+ } -+ } -+} -+ -+static void lima_pp_task_fini(struct lima_sched_pipe *pipe) -+{ -+ if (pipe->bcast_processor) -+ lima_pp_soft_reset_async(pipe->bcast_processor); -+ else { -+ int i; -+ for (i = 0; i < pipe->num_processor; i++) -+ lima_pp_soft_reset_async(pipe->processor[i]); -+ } -+} -+ -+static void lima_pp_task_error(struct lima_sched_pipe *pipe) -+{ -+ int i; -+ -+ if (pipe->bcast_processor) -+ lima_bcast_disable(pipe->bcast_processor->dev); -+ -+ for (i = 0; i < pipe->num_processor; i++) -+ lima_pp_hard_reset(pipe->processor[i]); -+ -+ if (pipe->bcast_processor) -+ lima_bcast_enable(pipe->bcast_processor->dev); -+} -+ -+static void lima_pp_task_mmu_error(struct lima_sched_pipe *pipe) -+{ -+ if (atomic_dec_and_test(&pipe->task)) -+ lima_sched_pipe_task_done(pipe); -+} -+ -+static struct kmem_cache *lima_pp_task_slab = NULL; -+static int lima_pp_task_slab_refcnt = 0; -+ -+int lima_pp_pipe_init(struct lima_device *dev) -+{ -+ int frame_size; -+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; -+ -+ if (dev->id == lima_gpu_mali400) -+ frame_size = sizeof(struct drm_lima_m400_pp_frame); -+ else -+ frame_size = sizeof(struct drm_lima_m450_pp_frame); -+ -+ if (!lima_pp_task_slab) { -+ lima_pp_task_slab = kmem_cache_create( -+ "lima_pp_task", sizeof(struct lima_sched_task) + frame_size, -+ 0, SLAB_HWCACHE_ALIGN, NULL); -+ if (!lima_pp_task_slab) -+ return -ENOMEM; -+ } -+ lima_pp_task_slab_refcnt++; -+ -+ pipe->frame_size = frame_size; -+ pipe->task_slab = lima_pp_task_slab; -+ -+ pipe->task_validate = lima_pp_task_validate; -+ pipe->task_run = lima_pp_task_run; -+ pipe->task_fini = lima_pp_task_fini; -+ pipe->task_error = lima_pp_task_error; -+ pipe->task_mmu_error = lima_pp_task_mmu_error; -+ -+ return 0; -+} -+ -+void lima_pp_pipe_fini(struct lima_device *dev) -+{ -+ if (!--lima_pp_task_slab_refcnt) { -+ kmem_cache_destroy(lima_pp_task_slab); -+ lima_pp_task_slab = NULL; -+ } -+} -diff --git a/drivers/gpu/drm/lima/lima_pp.h b/drivers/gpu/drm/lima/lima_pp.h -new file mode 100644 -index 000000000000..4bd1d9fcbcdf ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_pp.h -@@ -0,0 +1,37 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef __LIMA_PP_H__ -+#define __LIMA_PP_H__ -+ -+struct lima_ip; -+struct lima_device; -+ -+int lima_pp_init(struct lima_ip *ip); -+void lima_pp_fini(struct lima_ip *ip); -+ -+int lima_pp_bcast_init(struct lima_ip *ip); -+void lima_pp_bcast_fini(struct lima_ip *ip); -+ -+int lima_pp_pipe_init(struct lima_device *dev); -+void lima_pp_pipe_fini(struct lima_device *dev); -+ -+#endif --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0050-drm-lima-add-MMU-related-functions.patch b/patch/kernel/sunxi-legacy/0050-drm-lima-add-MMU-related-functions.patch deleted file mode 100644 index 640317bcf..000000000 --- a/patch/kernel/sunxi-legacy/0050-drm-lima-add-MMU-related-functions.patch +++ /dev/null @@ -1,218 +0,0 @@ -From ae47294de5185d599b64565ff1ca2d47277eecec Mon Sep 17 00:00:00 2001 -From: Lima Project Developers -Date: Mon, 14 May 2018 22:13:51 +0800 -Subject: [PATCH 050/146] drm/lima: add MMU related functions - -Signed-off-by: Qiang Yu -Signed-off-by: Marek Vasut -Signed-off-by: Heiko Stuebner ---- - drivers/gpu/drm/lima/lima_mmu.c | 154 ++++++++++++++++++++++++++++++++ - drivers/gpu/drm/lima/lima_mmu.h | 34 +++++++ - 2 files changed, 188 insertions(+) - create mode 100644 drivers/gpu/drm/lima/lima_mmu.c - create mode 100644 drivers/gpu/drm/lima/lima_mmu.h - -diff --git a/drivers/gpu/drm/lima/lima_mmu.c b/drivers/gpu/drm/lima/lima_mmu.c -new file mode 100644 -index 000000000000..22ac4db07849 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_mmu.c -@@ -0,0 +1,154 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include -+#include -+#include -+ -+#include "lima_device.h" -+#include "lima_mmu.h" -+#include "lima_vm.h" -+#include "lima_object.h" -+#include "lima_regs.h" -+ -+#define mmu_write(reg, data) writel(data, ip->iomem + LIMA_MMU_##reg) -+#define mmu_read(reg) readl(ip->iomem + LIMA_MMU_##reg) -+ -+#define lima_mmu_send_command(command, condition) \ -+({ \ -+ int __timeout, __ret = 0; \ -+ \ -+ mmu_write(COMMAND, command); \ -+ for (__timeout = 1000; __timeout > 0; __timeout--) { \ -+ if (condition) \ -+ break; \ -+ } \ -+ if (!__timeout) { \ -+ dev_err(dev->dev, "mmu command %x timeout\n", command); \ -+ __ret = -ETIMEDOUT; \ -+ } \ -+ __ret; \ -+}) -+ -+static irqreturn_t lima_mmu_irq_handler(int irq, void *data) -+{ -+ struct lima_ip *ip = data; -+ struct lima_device *dev = ip->dev; -+ u32 status = mmu_read(INT_STATUS); -+ struct lima_sched_pipe *pipe; -+ -+ /* for shared irq case */ -+ if (!status) -+ return IRQ_NONE; -+ -+ if (status & LIMA_MMU_INT_PAGE_FAULT) { -+ u32 fault = mmu_read(PAGE_FAULT_ADDR); -+ dev_err(dev->dev, "mmu page fault at 0x%x from bus id %d of type %s on %s\n", -+ fault, LIMA_MMU_STATUS_BUS_ID(status), -+ status & LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE ? "write" : "read", -+ lima_ip_name(ip)); -+ } -+ -+ if (status & LIMA_MMU_INT_READ_BUS_ERROR) { -+ dev_err(dev->dev, "mmu %s irq bus error\n", lima_ip_name(ip)); -+ } -+ -+ /* mask all interrupts before resume */ -+ mmu_write(INT_MASK, 0); -+ mmu_write(INT_CLEAR, status); -+ -+ pipe = dev->pipe + (ip->id == lima_ip_gpmmu ? lima_pipe_gp : lima_pipe_pp); -+ lima_sched_pipe_mmu_error(pipe); -+ -+ return IRQ_HANDLED; -+} -+ -+int lima_mmu_init(struct lima_ip *ip) -+{ -+ struct lima_device *dev = ip->dev; -+ int err; -+ -+ if (ip->id == lima_ip_ppmmu_bcast) -+ return 0; -+ -+ mmu_write(DTE_ADDR, 0xCAFEBABE); -+ if (mmu_read(DTE_ADDR) != 0xCAFEB000) { -+ dev_err(dev->dev, "mmu %s dte write test fail\n", lima_ip_name(ip)); -+ return -EIO; -+ } -+ -+ err = lima_mmu_send_command(LIMA_MMU_COMMAND_HARD_RESET, mmu_read(DTE_ADDR) == 0); -+ if (err) -+ return err; -+ -+ err = devm_request_irq(dev->dev, ip->irq, lima_mmu_irq_handler, -+ IRQF_SHARED, lima_ip_name(ip), ip); -+ if (err) { -+ dev_err(dev->dev, "mmu %s fail to request irq\n", lima_ip_name(ip)); -+ return err; -+ } -+ -+ mmu_write(INT_MASK, LIMA_MMU_INT_PAGE_FAULT | LIMA_MMU_INT_READ_BUS_ERROR); -+ mmu_write(DTE_ADDR, *lima_bo_get_pages(dev->empty_vm->pd)); -+ return lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_PAGING, -+ mmu_read(STATUS) & LIMA_MMU_STATUS_PAGING_ENABLED); -+} -+ -+void lima_mmu_fini(struct lima_ip *ip) -+{ -+ -+} -+ -+void lima_mmu_switch_vm(struct lima_ip *ip, struct lima_vm *vm) -+{ -+ struct lima_device *dev = ip->dev; -+ -+ lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_STALL, -+ mmu_read(STATUS) & LIMA_MMU_STATUS_STALL_ACTIVE); -+ -+ if (vm) -+ mmu_write(DTE_ADDR, *lima_bo_get_pages(vm->pd)); -+ -+ /* flush the TLB */ -+ mmu_write(COMMAND, LIMA_MMU_COMMAND_ZAP_CACHE); -+ -+ lima_mmu_send_command(LIMA_MMU_COMMAND_DISABLE_STALL, -+ !(mmu_read(STATUS) & LIMA_MMU_STATUS_STALL_ACTIVE)); -+} -+ -+void lima_mmu_page_fault_resume(struct lima_ip *ip) -+{ -+ struct lima_device *dev = ip->dev; -+ u32 status = mmu_read(STATUS); -+ -+ if (status & LIMA_MMU_STATUS_PAGE_FAULT_ACTIVE) { -+ dev_info(dev->dev, "mmu resume\n"); -+ -+ mmu_write(INT_MASK, 0); -+ mmu_write(DTE_ADDR, 0xCAFEBABE); -+ lima_mmu_send_command(LIMA_MMU_COMMAND_HARD_RESET, mmu_read(DTE_ADDR) == 0); -+ mmu_write(INT_MASK, LIMA_MMU_INT_PAGE_FAULT | LIMA_MMU_INT_READ_BUS_ERROR); -+ mmu_write(DTE_ADDR, *lima_bo_get_pages(dev->empty_vm->pd)); -+ lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_PAGING, -+ mmu_read(STATUS) & LIMA_MMU_STATUS_PAGING_ENABLED); -+ } -+} -diff --git a/drivers/gpu/drm/lima/lima_mmu.h b/drivers/gpu/drm/lima/lima_mmu.h -new file mode 100644 -index 000000000000..9930521ddfa1 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_mmu.h -@@ -0,0 +1,34 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef __LIMA_MMU_H__ -+#define __LIMA_MMU_H__ -+ -+struct lima_ip; -+struct lima_vm; -+ -+int lima_mmu_init(struct lima_ip *ip); -+void lima_mmu_fini(struct lima_ip *ip); -+ -+void lima_mmu_switch_vm(struct lima_ip *ip, struct lima_vm *vm); -+void lima_mmu_page_fault_resume(struct lima_ip *ip); -+ -+#endif --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0051-drm-lima-add-BCAST-related-function.patch b/patch/kernel/sunxi-legacy/0051-drm-lima-add-BCAST-related-function.patch deleted file mode 100644 index ad20df5e0..000000000 --- a/patch/kernel/sunxi-legacy/0051-drm-lima-add-BCAST-related-function.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 7fe721b0e0c72de29b4cfe9b3d6aa80a64f1603d Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Mon, 14 May 2018 22:17:43 +0800 -Subject: [PATCH 051/146] drm/lima: add BCAST related function - -BCAST is a hardware module to broadcast register -read/write for PPs. It can also merge IRQs from -different PPs into one IRQ. - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_bcast.c | 65 +++++++++++++++++++++++++++++++ - drivers/gpu/drm/lima/lima_bcast.h | 34 ++++++++++++++++ - 2 files changed, 99 insertions(+) - create mode 100644 drivers/gpu/drm/lima/lima_bcast.c - create mode 100644 drivers/gpu/drm/lima/lima_bcast.h - -diff --git a/drivers/gpu/drm/lima/lima_bcast.c b/drivers/gpu/drm/lima/lima_bcast.c -new file mode 100644 -index 000000000000..32012a61ea6a ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_bcast.c -@@ -0,0 +1,65 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include -+#include -+ -+#include "lima_device.h" -+#include "lima_bcast.h" -+#include "lima_regs.h" -+ -+#define bcast_write(reg, data) writel(data, ip->iomem + LIMA_BCAST_##reg) -+#define bcast_read(reg) readl(ip->iomem + LIMA_BCAST_##reg) -+ -+void lima_bcast_enable(struct lima_device *dev) -+{ -+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; -+ struct lima_ip *ip = dev->ip + lima_ip_bcast; -+ int i, mask = 0; -+ -+ for (i = 0; i < pipe->num_processor; i++) { -+ struct lima_ip *pp = pipe->processor[i]; -+ mask |= 1 << (pp->id - lima_ip_pp0); -+ } -+ -+ bcast_write(BROADCAST_MASK, (mask << 16) | mask); -+ bcast_write(INTERRUPT_MASK, mask); -+} -+ -+void lima_bcast_disable(struct lima_device *dev) -+{ -+ struct lima_ip *ip = dev->ip + lima_ip_bcast; -+ -+ bcast_write(BROADCAST_MASK, 0); -+ bcast_write(INTERRUPT_MASK, 0); -+} -+ -+int lima_bcast_init(struct lima_ip *ip) -+{ -+ return 0; -+} -+ -+void lima_bcast_fini(struct lima_ip *ip) -+{ -+ -+} -+ -diff --git a/drivers/gpu/drm/lima/lima_bcast.h b/drivers/gpu/drm/lima/lima_bcast.h -new file mode 100644 -index 000000000000..abafd4f613c7 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_bcast.h -@@ -0,0 +1,34 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#ifndef __LIMA_BCAST_H__ -+#define __LIMA_BCAST_H__ -+ -+struct lima_ip; -+ -+int lima_bcast_init(struct lima_ip *ip); -+void lima_bcast_fini(struct lima_ip *ip); -+ -+void lima_bcast_enable(struct lima_device *dev); -+void lima_bcast_disable(struct lima_device *dev); -+ -+#endif --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0052-drm-lima-add-DLBU-related-functions.patch b/patch/kernel/sunxi-legacy/0052-drm-lima-add-DLBU-related-functions.patch deleted file mode 100644 index a0c20cd19..000000000 --- a/patch/kernel/sunxi-legacy/0052-drm-lima-add-DLBU-related-functions.patch +++ /dev/null @@ -1,142 +0,0 @@ -From ec275c7f186f53de7bf00ced46c8f0bbb3338e8d Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Mon, 14 May 2018 22:21:19 +0800 -Subject: [PATCH 052/146] drm/lima: add DLBU related functions - -DLBU is used to balance load among PPs. - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_dlbu.c | 75 ++++++++++++++++++++++++++++++++ - drivers/gpu/drm/lima/lima_dlbu.h | 37 ++++++++++++++++ - 2 files changed, 112 insertions(+) - create mode 100644 drivers/gpu/drm/lima/lima_dlbu.c - create mode 100644 drivers/gpu/drm/lima/lima_dlbu.h - -diff --git a/drivers/gpu/drm/lima/lima_dlbu.c b/drivers/gpu/drm/lima/lima_dlbu.c -new file mode 100644 -index 000000000000..5281dd3c0417 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_dlbu.c -@@ -0,0 +1,75 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include -+#include -+ -+#include "lima_device.h" -+#include "lima_dlbu.h" -+#include "lima_vm.h" -+#include "lima_regs.h" -+ -+#define dlbu_write(reg, data) writel(data, ip->iomem + LIMA_DLBU_##reg) -+#define dlbu_read(reg) readl(ip->iomem + LIMA_DLBU_##reg) -+ -+void lima_dlbu_enable(struct lima_device *dev) -+{ -+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; -+ struct lima_ip *ip = dev->ip + lima_ip_dlbu; -+ int i, mask = 0; -+ -+ for (i = 0; i < pipe->num_processor; i++) { -+ struct lima_ip *pp = pipe->processor[i]; -+ mask |= 1 << (pp->id - lima_ip_pp0); -+ } -+ -+ dlbu_write(PP_ENABLE_MASK, mask); -+} -+ -+void lima_dlbu_disable(struct lima_device *dev) -+{ -+ struct lima_ip *ip = dev->ip + lima_ip_dlbu; -+ dlbu_write(PP_ENABLE_MASK, 0); -+} -+ -+void lima_dlbu_set_reg(struct lima_ip *ip, u32 *reg) -+{ -+ dlbu_write(TLLIST_VBASEADDR, reg[0]); -+ dlbu_write(FB_DIM, reg[1]); -+ dlbu_write(TLLIST_CONF, reg[2]); -+ dlbu_write(START_TILE_POS, reg[3]); -+} -+ -+int lima_dlbu_init(struct lima_ip *ip) -+{ -+ struct lima_device *dev = ip->dev; -+ -+ dlbu_write(MASTER_TLLIST_PHYS_ADDR, dev->dlbu_dma | 1); -+ dlbu_write(MASTER_TLLIST_VADDR, LIMA_VA_RESERVE_DLBU); -+ -+ return 0; -+} -+ -+void lima_dlbu_fini(struct lima_ip *ip) -+{ -+ -+} -diff --git a/drivers/gpu/drm/lima/lima_dlbu.h b/drivers/gpu/drm/lima/lima_dlbu.h -new file mode 100644 -index 000000000000..4521a5dda9e0 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_dlbu.h -@@ -0,0 +1,37 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#ifndef __LIMA_DLBU_H__ -+#define __LIMA_DLBU_H__ -+ -+struct lima_ip; -+struct lima_device; -+ -+void lima_dlbu_enable(struct lima_device *dev); -+void lima_dlbu_disable(struct lima_device *dev); -+ -+void lima_dlbu_set_reg(struct lima_ip *ip, u32 *reg); -+ -+int lima_dlbu_init(struct lima_ip *ip); -+void lima_dlbu_fini(struct lima_ip *ip); -+ -+#endif --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0053-drm-lima-add-GPU-virtual-memory-space-handing.patch b/patch/kernel/sunxi-legacy/0053-drm-lima-add-GPU-virtual-memory-space-handing.patch deleted file mode 100644 index 666cafcac..000000000 --- a/patch/kernel/sunxi-legacy/0053-drm-lima-add-GPU-virtual-memory-space-handing.patch +++ /dev/null @@ -1,414 +0,0 @@ -From 643a121d5e299aef668f8a87a7858b7f52e735d6 Mon Sep 17 00:00:00 2001 -From: Lima Project Developers -Date: Mon, 14 May 2018 22:24:16 +0800 -Subject: [PATCH 053/146] drm/lima: add GPU virtual memory space handing - -Signed-off-by: Qiang Yu -Signed-off-by: Vasily Khoruzhick ---- - drivers/gpu/drm/lima/lima_vm.c | 312 +++++++++++++++++++++++++++++++++ - drivers/gpu/drm/lima/lima_vm.h | 73 ++++++++ - 2 files changed, 385 insertions(+) - create mode 100644 drivers/gpu/drm/lima/lima_vm.c - create mode 100644 drivers/gpu/drm/lima/lima_vm.h - -diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c -new file mode 100644 -index 000000000000..00a3f6b59a33 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_vm.c -@@ -0,0 +1,312 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include -+#include -+#include -+ -+#include "lima_device.h" -+#include "lima_vm.h" -+#include "lima_object.h" -+#include "lima_regs.h" -+ -+struct lima_bo_va_mapping { -+ struct list_head list; -+ struct rb_node rb; -+ uint32_t start; -+ uint32_t last; -+ uint32_t __subtree_last; -+}; -+ -+struct lima_bo_va { -+ struct list_head list; -+ unsigned ref_count; -+ -+ struct list_head mapping; -+ -+ struct lima_vm *vm; -+}; -+ -+#define LIMA_PDE(va) (va >> 22) -+#define LIMA_PTE(va) ((va & 0x3FFFFF) >> 12) -+ -+#define START(node) ((node)->start) -+#define LAST(node) ((node)->last) -+ -+INTERVAL_TREE_DEFINE(struct lima_bo_va_mapping, rb, uint32_t, __subtree_last, -+ START, LAST, static, lima_vm_it) -+ -+#undef START -+#undef LAST -+ -+static void lima_vm_unmap_page_table(struct lima_vm *vm, u32 start, u32 end) -+{ -+ u32 addr; -+ -+ for (addr = start; addr <= end; addr += LIMA_PAGE_SIZE) { -+ u32 pde = LIMA_PDE(addr); -+ u32 pte = LIMA_PTE(addr); -+ u32 *pt; -+ -+ pt = lima_bo_kmap(vm->pt[pde]); -+ pt[pte] = 0; -+ } -+} -+ -+static int lima_vm_map_page_table(struct lima_vm *vm, dma_addr_t *dma, -+ u32 start, u32 end) -+{ -+ u64 addr; -+ int err, i = 0; -+ -+ for (addr = start; addr <= end; addr += LIMA_PAGE_SIZE) { -+ u32 pde = LIMA_PDE(addr); -+ u32 pte = LIMA_PTE(addr); -+ u32 *pd, *pt; -+ -+ if (vm->pt[pde]) -+ pt = lima_bo_kmap(vm->pt[pde]); -+ else { -+ vm->pt[pde] = lima_bo_create( -+ vm->dev, LIMA_PAGE_SIZE, 0, ttm_bo_type_kernel, -+ NULL, vm->pd->tbo.resv); -+ if (IS_ERR(vm->pt[pde])) { -+ err = PTR_ERR(vm->pt[pde]); -+ goto err_out; -+ } -+ -+ pt = lima_bo_kmap(vm->pt[pde]); -+ if (IS_ERR(pt)) { -+ err = PTR_ERR(pt); -+ goto err_out; -+ } -+ -+ pd = lima_bo_kmap(vm->pd); -+ pd[pde] = *lima_bo_get_pages(vm->pt[pde]) | LIMA_VM_FLAG_PRESENT; -+ } -+ -+ pt[pte] = dma[i++] | LIMA_VM_FLAGS_CACHE; -+ } -+ -+ return 0; -+ -+err_out: -+ if (addr != start) -+ lima_vm_unmap_page_table(vm, start, addr - 1); -+ return err; -+} -+ -+static struct lima_bo_va * -+lima_vm_bo_find(struct lima_vm *vm, struct lima_bo *bo) -+{ -+ struct lima_bo_va *bo_va, *ret = NULL; -+ -+ list_for_each_entry(bo_va, &bo->va, list) { -+ if (bo_va->vm == vm) { -+ ret = bo_va; -+ break; -+ } -+ } -+ -+ return ret; -+} -+ -+int lima_vm_bo_map(struct lima_vm *vm, struct lima_bo *bo, u32 start) -+{ -+ int err; -+ struct lima_bo_va_mapping *it, *mapping; -+ u32 end = start + bo->gem.size - 1; -+ dma_addr_t *pages_dma = lima_bo_get_pages(bo); -+ struct lima_bo_va *bo_va; -+ -+ it = lima_vm_it_iter_first(&vm->va, start, end); -+ if (it) { -+ dev_dbg(bo->gem.dev->dev, "lima vm map va overlap %x-%x %x-%x\n", -+ start, end, it->start, it->last); -+ return -EINVAL; -+ } -+ -+ mapping = kmalloc(sizeof(*mapping), GFP_KERNEL); -+ if (!mapping) -+ return -ENOMEM; -+ mapping->start = start; -+ mapping->last = end; -+ -+ err = lima_vm_map_page_table(vm, pages_dma, start, end); -+ if (err) { -+ kfree(mapping); -+ return err; -+ } -+ -+ lima_vm_it_insert(mapping, &vm->va); -+ -+ bo_va = lima_vm_bo_find(vm, bo); -+ list_add_tail(&mapping->list, &bo_va->mapping); -+ -+ return 0; -+} -+ -+static void lima_vm_unmap(struct lima_vm *vm, -+ struct lima_bo_va_mapping *mapping) -+{ -+ lima_vm_it_remove(mapping, &vm->va); -+ -+ lima_vm_unmap_page_table(vm, mapping->start, mapping->last); -+ -+ list_del(&mapping->list); -+ kfree(mapping); -+} -+ -+int lima_vm_bo_unmap(struct lima_vm *vm, struct lima_bo *bo, u32 start) -+{ -+ struct lima_bo_va *bo_va; -+ struct lima_bo_va_mapping *mapping; -+ -+ bo_va = lima_vm_bo_find(vm, bo); -+ list_for_each_entry(mapping, &bo_va->mapping, list) { -+ if (mapping->start == start) { -+ lima_vm_unmap(vm, mapping); -+ break; -+ } -+ } -+ -+ return 0; -+} -+ -+int lima_vm_bo_add(struct lima_vm *vm, struct lima_bo *bo) -+{ -+ struct lima_bo_va *bo_va; -+ -+ bo_va = lima_vm_bo_find(vm, bo); -+ if (bo_va) { -+ bo_va->ref_count++; -+ return 0; -+ } -+ -+ bo_va = kmalloc(sizeof(*bo_va), GFP_KERNEL); -+ if (!bo_va) -+ return -ENOMEM; -+ -+ bo_va->vm = vm; -+ bo_va->ref_count = 1; -+ INIT_LIST_HEAD(&bo_va->mapping); -+ list_add_tail(&bo_va->list, &bo->va); -+ return 0; -+} -+ -+int lima_vm_bo_del(struct lima_vm *vm, struct lima_bo *bo) -+{ -+ struct lima_bo_va *bo_va; -+ struct lima_bo_va_mapping *mapping, *tmp; -+ -+ bo_va = lima_vm_bo_find(vm, bo); -+ if (--bo_va->ref_count > 0) -+ return 0; -+ -+ list_for_each_entry_safe(mapping, tmp, &bo_va->mapping, list) { -+ lima_vm_unmap(vm, mapping); -+ } -+ list_del(&bo_va->list); -+ kfree(bo_va); -+ return 0; -+} -+ -+struct lima_vm *lima_vm_create(struct lima_device *dev) -+{ -+ struct lima_vm *vm; -+ void *pd; -+ -+ vm = kzalloc(sizeof(*vm), GFP_KERNEL); -+ if (!vm) -+ return NULL; -+ -+ vm->dev = dev; -+ vm->va = RB_ROOT_CACHED; -+ kref_init(&vm->refcount); -+ -+ vm->pd = lima_bo_create(dev, LIMA_PAGE_SIZE, 0, -+ ttm_bo_type_kernel, NULL, NULL); -+ if (IS_ERR(vm->pd)) -+ goto err_out0; -+ -+ pd = lima_bo_kmap(vm->pd); -+ if (IS_ERR(pd)) -+ goto err_out1; -+ -+ if (dev->dlbu_cpu) { -+ int err = lima_vm_map_page_table( -+ vm, &dev->dlbu_dma, LIMA_VA_RESERVE_DLBU, -+ LIMA_VA_RESERVE_DLBU + LIMA_PAGE_SIZE - 1); -+ if (err) -+ goto err_out1; -+ } -+ -+ return vm; -+ -+err_out1: -+ lima_bo_unref(vm->pd); -+err_out0: -+ kfree(vm); -+ return NULL; -+} -+ -+void lima_vm_release(struct kref *kref) -+{ -+ struct lima_vm *vm = container_of(kref, struct lima_vm, refcount); -+ struct lima_device *dev = vm->dev; -+ int i; -+ -+ if (!RB_EMPTY_ROOT(&vm->va.rb_root)) { -+ dev_err(dev->dev, "still active bo inside vm\n"); -+ } -+ -+ for (i = 0; i < LIMA_PAGE_ENT_NUM; i++) { -+ if (vm->pt[i]) -+ lima_bo_unref(vm->pt[i]); -+ } -+ -+ if (vm->pd) -+ lima_bo_unref(vm->pd); -+ -+ kfree(vm); -+} -+ -+void lima_vm_print(struct lima_vm *vm) -+{ -+ int i, j; -+ u32 *pd = lima_bo_kmap(vm->pd); -+ -+ /* to avoid the defined by not used warning */ -+ (void)&lima_vm_it_iter_next; -+ -+ for (i = 0; i < LIMA_PAGE_ENT_NUM; i++) { -+ if (pd[i]) { -+ u32 *pt = lima_bo_kmap(vm->pt[i]); -+ -+ printk(KERN_INFO "lima vm pd %03x:%08x\n", i, pd[i]); -+ for (j = 0; j < LIMA_PAGE_ENT_NUM; j++) { -+ if (pt[j]) -+ printk(KERN_INFO " pt %03x:%08x\n", j, pt[j]); -+ } -+ } -+ } -+} -diff --git a/drivers/gpu/drm/lima/lima_vm.h b/drivers/gpu/drm/lima/lima_vm.h -new file mode 100644 -index 000000000000..20506459def0 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_vm.h -@@ -0,0 +1,73 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef __LIMA_VM_H__ -+#define __LIMA_VM_H__ -+ -+#include -+#include -+ -+#define LIMA_PAGE_SIZE 4096 -+#define LIMA_PAGE_MASK (LIMA_PAGE_SIZE - 1) -+#define LIMA_PAGE_ENT_NUM (LIMA_PAGE_SIZE / sizeof(u32)) -+ -+#define LIMA_VA_RESERVE_START 0xFFF00000 -+#define LIMA_VA_RESERVE_DLBU LIMA_VA_RESERVE_START -+#define LIMA_VA_RESERVE_END 0x100000000 -+ -+struct lima_bo; -+struct lima_device; -+ -+struct lima_vm { -+ struct kref refcount; -+ -+ /* tree of virtual addresses mapped */ -+ struct rb_root_cached va; -+ -+ struct lima_device *dev; -+ -+ struct lima_bo *pd; -+ struct lima_bo *pt[LIMA_PAGE_ENT_NUM]; -+}; -+ -+int lima_vm_bo_map(struct lima_vm *vm, struct lima_bo *bo, u32 start); -+int lima_vm_bo_unmap(struct lima_vm *vm, struct lima_bo *bo, u32 start); -+ -+int lima_vm_bo_add(struct lima_vm *vm, struct lima_bo *bo); -+int lima_vm_bo_del(struct lima_vm *vm, struct lima_bo *bo); -+ -+struct lima_vm *lima_vm_create(struct lima_device *dev); -+void lima_vm_release(struct kref *kref); -+ -+static inline struct lima_vm *lima_vm_get(struct lima_vm *vm) -+{ -+ kref_get(&vm->refcount); -+ return vm; -+} -+ -+static inline void lima_vm_put(struct lima_vm *vm) -+{ -+ kref_put(&vm->refcount, lima_vm_release); -+} -+ -+void lima_vm_print(struct lima_vm *vm); -+ -+#endif --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0054-drm-lima-add-TTM-subsystem-functions.patch b/patch/kernel/sunxi-legacy/0054-drm-lima-add-TTM-subsystem-functions.patch deleted file mode 100644 index b7faced92..000000000 --- a/patch/kernel/sunxi-legacy/0054-drm-lima-add-TTM-subsystem-functions.patch +++ /dev/null @@ -1,481 +0,0 @@ -From f31bbd84c9aab62a0aee72e540d9d8c9d998a958 Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Mon, 14 May 2018 22:28:36 +0800 -Subject: [PATCH 054/146] drm/lima: add TTM subsystem functions - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_ttm.c | 409 ++++++++++++++++++++++++++++++++ - drivers/gpu/drm/lima/lima_ttm.h | 44 ++++ - 2 files changed, 453 insertions(+) - create mode 100644 drivers/gpu/drm/lima/lima_ttm.c - create mode 100644 drivers/gpu/drm/lima/lima_ttm.h - -diff --git a/drivers/gpu/drm/lima/lima_ttm.c b/drivers/gpu/drm/lima/lima_ttm.c -new file mode 100644 -index 000000000000..5325f3f48ae7 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_ttm.c -@@ -0,0 +1,409 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include -+#include -+ -+#include "lima_drv.h" -+#include "lima_device.h" -+#include "lima_object.h" -+ -+ -+static int lima_ttm_mem_global_init(struct drm_global_reference *ref) -+{ -+ return ttm_mem_global_init(ref->object); -+} -+ -+static void lima_ttm_mem_global_release(struct drm_global_reference *ref) -+{ -+ ttm_mem_global_release(ref->object); -+} -+ -+static int lima_ttm_global_init(struct lima_device *dev) -+{ -+ struct drm_global_reference *global_ref; -+ int err; -+ -+ dev->mman.mem_global_referenced = false; -+ global_ref = &dev->mman.mem_global_ref; -+ global_ref->global_type = DRM_GLOBAL_TTM_MEM; -+ global_ref->size = sizeof(struct ttm_mem_global); -+ global_ref->init = &lima_ttm_mem_global_init; -+ global_ref->release = &lima_ttm_mem_global_release; -+ -+ err = drm_global_item_ref(global_ref); -+ if (err != 0) { -+ dev_err(dev->dev, "Failed setting up TTM memory accounting " -+ "subsystem.\n"); -+ return err; -+ } -+ -+ dev->mman.bo_global_ref.mem_glob = -+ dev->mman.mem_global_ref.object; -+ global_ref = &dev->mman.bo_global_ref.ref; -+ global_ref->global_type = DRM_GLOBAL_TTM_BO; -+ global_ref->size = sizeof(struct ttm_bo_global); -+ global_ref->init = &ttm_bo_global_init; -+ global_ref->release = &ttm_bo_global_release; -+ err = drm_global_item_ref(global_ref); -+ if (err != 0) { -+ dev_err(dev->dev, "Failed setting up TTM BO subsystem.\n"); -+ drm_global_item_unref(&dev->mman.mem_global_ref); -+ return err; -+ } -+ -+ dev->mman.mem_global_referenced = true; -+ return 0; -+} -+ -+static void lima_ttm_global_fini(struct lima_device *dev) -+{ -+ if (dev->mman.mem_global_referenced) { -+ drm_global_item_unref(&dev->mman.bo_global_ref.ref); -+ drm_global_item_unref(&dev->mman.mem_global_ref); -+ dev->mman.mem_global_referenced = false; -+ } -+} -+ -+struct lima_tt_mgr { -+ spinlock_t lock; -+ unsigned long available; -+}; -+ -+static int lima_ttm_bo_man_init(struct ttm_mem_type_manager *man, -+ unsigned long p_size) -+{ -+ struct lima_tt_mgr *mgr; -+ -+ mgr = kmalloc(sizeof(*mgr), GFP_KERNEL); -+ if (!mgr) -+ return -ENOMEM; -+ -+ spin_lock_init(&mgr->lock); -+ mgr->available = p_size; -+ man->priv = mgr; -+ return 0; -+} -+ -+static int lima_ttm_bo_man_takedown(struct ttm_mem_type_manager *man) -+{ -+ struct lima_tt_mgr *mgr = man->priv; -+ -+ kfree(mgr); -+ man->priv = NULL; -+ return 0; -+} -+ -+static int lima_ttm_bo_man_get_node(struct ttm_mem_type_manager *man, -+ struct ttm_buffer_object *bo, -+ const struct ttm_place *place, -+ struct ttm_mem_reg *mem) -+{ -+ struct lima_tt_mgr *mgr = man->priv; -+ -+ /* don't exceed the mem limit */ -+ spin_lock(&mgr->lock); -+ if (mgr->available < mem->num_pages) { -+ spin_unlock(&mgr->lock); -+ return 0; -+ } -+ mgr->available -= mem->num_pages; -+ spin_unlock(&mgr->lock); -+ -+ /* just fake a non-null pointer to tell caller success */ -+ mem->mm_node = (void *)1; -+ return 0; -+} -+ -+static void lima_ttm_bo_man_put_node(struct ttm_mem_type_manager *man, -+ struct ttm_mem_reg *mem) -+{ -+ struct lima_tt_mgr *mgr = man->priv; -+ -+ spin_lock(&mgr->lock); -+ mgr->available += mem->num_pages; -+ spin_unlock(&mgr->lock); -+ -+ mem->mm_node = NULL; -+} -+ -+static void lima_ttm_bo_man_debug(struct ttm_mem_type_manager *man, -+ struct drm_printer *printer) -+{ -+} -+ -+static const struct ttm_mem_type_manager_func lima_bo_manager_func = { -+ .init = lima_ttm_bo_man_init, -+ .takedown = lima_ttm_bo_man_takedown, -+ .get_node = lima_ttm_bo_man_get_node, -+ .put_node = lima_ttm_bo_man_put_node, -+ .debug = lima_ttm_bo_man_debug -+}; -+ -+static int lima_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, -+ struct ttm_mem_type_manager *man) -+{ -+ struct lima_device *dev = ttm_to_lima_dev(bdev); -+ -+ switch (type) { -+ case TTM_PL_SYSTEM: -+ /* System memory */ -+ man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; -+ man->available_caching = TTM_PL_MASK_CACHING; -+ man->default_caching = TTM_PL_FLAG_CACHED; -+ break; -+ case TTM_PL_TT: -+ man->func = &lima_bo_manager_func; -+ man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; -+ man->available_caching = TTM_PL_MASK_CACHING; -+ man->default_caching = TTM_PL_FLAG_CACHED; -+ break; -+ default: -+ dev_err(dev->dev, "Unsupported memory type %u\n", -+ (unsigned int)type); -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static int lima_ttm_backend_bind(struct ttm_tt *ttm, -+ struct ttm_mem_reg *bo_mem) -+{ -+ return 0; -+} -+ -+static int lima_ttm_backend_unbind(struct ttm_tt *ttm) -+{ -+ return 0; -+} -+ -+static void lima_ttm_backend_destroy(struct ttm_tt *ttm) -+{ -+ struct lima_ttm_tt *tt = (void *)ttm; -+ -+ ttm_dma_tt_fini(&tt->ttm); -+ kfree(tt); -+} -+ -+static struct ttm_backend_func lima_ttm_backend_func = { -+ .bind = &lima_ttm_backend_bind, -+ .unbind = &lima_ttm_backend_unbind, -+ .destroy = &lima_ttm_backend_destroy, -+}; -+ -+static struct ttm_tt *lima_ttm_tt_create(struct ttm_buffer_object *bo, -+ uint32_t page_flags) -+{ -+ struct lima_ttm_tt *tt; -+ -+ tt = kzalloc(sizeof(struct lima_ttm_tt), GFP_KERNEL); -+ if (tt == NULL) -+ return NULL; -+ -+ tt->ttm.ttm.func = &lima_ttm_backend_func; -+ -+ if (ttm_sg_tt_init(&tt->ttm, bo, page_flags)) { -+ kfree(tt); -+ return NULL; -+ } -+ -+ return &tt->ttm.ttm; -+} -+ -+static int lima_ttm_tt_populate(struct ttm_tt *ttm, -+ struct ttm_operation_ctx *ctx) -+{ -+ struct lima_device *dev = ttm_to_lima_dev(ttm->bdev); -+ struct lima_ttm_tt *tt = (void *)ttm; -+ bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); -+ -+ if (slave) { -+ drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, -+ tt->ttm.dma_address, -+ ttm->num_pages); -+ ttm->state = tt_unbound; -+ return 0; -+ } -+ -+ return ttm_populate_and_map_pages(dev->dev, &tt->ttm, ctx); -+} -+ -+static void lima_ttm_tt_unpopulate(struct ttm_tt *ttm) -+{ -+ struct lima_device *dev = ttm_to_lima_dev(ttm->bdev); -+ struct lima_ttm_tt *tt = (void *)ttm; -+ bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); -+ -+ if (slave) -+ return; -+ -+ ttm_unmap_and_unpopulate_pages(dev->dev, &tt->ttm); -+} -+ -+static int lima_invalidate_caches(struct ttm_bo_device *bdev, -+ uint32_t flags) -+{ -+ struct lima_device *dev = ttm_to_lima_dev(bdev); -+ -+ dev_err(dev->dev, "%s not implemented\n", __FUNCTION__); -+ return 0; -+} -+ -+static void lima_evict_flags(struct ttm_buffer_object *tbo, -+ struct ttm_placement *placement) -+{ -+ struct lima_bo *bo = ttm_to_lima_bo(tbo); -+ struct lima_device *dev = to_lima_dev(bo->gem.dev); -+ -+ dev_err(dev->dev, "%s not implemented\n", __FUNCTION__); -+} -+ -+static int lima_verify_access(struct ttm_buffer_object *tbo, -+ struct file *filp) -+{ -+ struct lima_bo *bo = ttm_to_lima_bo(tbo); -+ -+ return drm_vma_node_verify_access(&bo->gem.vma_node, -+ filp->private_data); -+} -+ -+static int lima_ttm_io_mem_reserve(struct ttm_bo_device *bdev, -+ struct ttm_mem_reg *mem) -+{ -+ struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; -+ -+ mem->bus.addr = NULL; -+ mem->bus.offset = 0; -+ mem->bus.size = mem->num_pages << PAGE_SHIFT; -+ mem->bus.base = 0; -+ mem->bus.is_iomem = false; -+ -+ if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE)) -+ return -EINVAL; -+ -+ switch (mem->mem_type) { -+ case TTM_PL_SYSTEM: -+ case TTM_PL_TT: -+ return 0; -+ default: -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static void lima_ttm_io_mem_free(struct ttm_bo_device *bdev, -+ struct ttm_mem_reg *mem) -+{ -+ -+} -+ -+static void lima_bo_move_notify(struct ttm_buffer_object *tbo, bool evict, -+ struct ttm_mem_reg *new_mem) -+{ -+ struct lima_bo *bo = ttm_to_lima_bo(tbo); -+ struct lima_device *dev = to_lima_dev(bo->gem.dev); -+ -+ if (evict) -+ dev_err(dev->dev, "%s not implemented\n", __FUNCTION__); -+} -+ -+static void lima_bo_swap_notify(struct ttm_buffer_object *tbo) -+{ -+ struct lima_bo *bo = ttm_to_lima_bo(tbo); -+ struct lima_device *dev = to_lima_dev(bo->gem.dev); -+ -+ dev_err(dev->dev, "%s not implemented\n", __FUNCTION__); -+} -+ -+static struct ttm_bo_driver lima_bo_driver = { -+ .ttm_tt_create = lima_ttm_tt_create, -+ .ttm_tt_populate = lima_ttm_tt_populate, -+ .ttm_tt_unpopulate = lima_ttm_tt_unpopulate, -+ .invalidate_caches = lima_invalidate_caches, -+ .init_mem_type = lima_init_mem_type, -+ .eviction_valuable = ttm_bo_eviction_valuable, -+ .evict_flags = lima_evict_flags, -+ .verify_access = lima_verify_access, -+ .io_mem_reserve = lima_ttm_io_mem_reserve, -+ .io_mem_free = lima_ttm_io_mem_free, -+ .move_notify = lima_bo_move_notify, -+ .swap_notify = lima_bo_swap_notify, -+}; -+ -+int lima_ttm_init(struct lima_device *dev) -+{ -+ int err; -+ bool need_dma32; -+ u64 gtt_size; -+ -+ err = lima_ttm_global_init(dev); -+ if (err) -+ return err; -+ -+#if defined(CONFIG_ARM) && !defined(CONFIG_ARM_LPAE) -+ need_dma32 = false; -+#else -+ need_dma32 = true; -+#endif -+ -+ err = ttm_bo_device_init(&dev->mman.bdev, -+ dev->mman.bo_global_ref.ref.object, -+ &lima_bo_driver, -+ dev->ddev->anon_inode->i_mapping, -+ DRM_FILE_PAGE_OFFSET, -+ need_dma32); -+ if (err) { -+ dev_err(dev->dev, "failed initializing buffer object " -+ "driver(%d).\n", err); -+ goto err_out0; -+ } -+ -+ if (lima_max_mem < 0) { -+ struct sysinfo si; -+ si_meminfo(&si); -+ /* TODO: better to have lower 32 mem size */ -+ gtt_size = min(((u64)si.totalram * si.mem_unit * 3/4), -+ 0x100000000ULL); -+ } -+ else -+ gtt_size = (u64)lima_max_mem << 20; -+ -+ err = ttm_bo_init_mm(&dev->mman.bdev, TTM_PL_TT, gtt_size >> PAGE_SHIFT); -+ if (err) { -+ dev_err(dev->dev, "Failed initializing GTT heap.\n"); -+ goto err_out1; -+ } -+ return 0; -+ -+err_out1: -+ ttm_bo_device_release(&dev->mman.bdev); -+err_out0: -+ lima_ttm_global_fini(dev); -+ return err; -+} -+ -+void lima_ttm_fini(struct lima_device *dev) -+{ -+ ttm_bo_device_release(&dev->mman.bdev); -+ lima_ttm_global_fini(dev); -+ dev_info(dev->dev, "ttm finalized\n"); -+} -diff --git a/drivers/gpu/drm/lima/lima_ttm.h b/drivers/gpu/drm/lima/lima_ttm.h -new file mode 100644 -index 000000000000..1d36d06a47a3 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_ttm.h -@@ -0,0 +1,44 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef __LIMA_TTM_H__ -+#define __LIMA_TTM_H__ -+ -+#include -+ -+struct lima_mman { -+ struct ttm_bo_global_ref bo_global_ref; -+ struct drm_global_reference mem_global_ref; -+ struct ttm_bo_device bdev; -+ bool mem_global_referenced; -+}; -+ -+struct lima_ttm_tt { -+ struct ttm_dma_tt ttm; -+}; -+ -+struct lima_device; -+struct lima_bo; -+ -+int lima_ttm_init(struct lima_device *dev); -+void lima_ttm_fini(struct lima_device *dev); -+ -+#endif --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0055-drm-lima-add-buffer-object-functions.patch b/patch/kernel/sunxi-legacy/0055-drm-lima-add-buffer-object-functions.patch deleted file mode 100644 index b9542191c..000000000 --- a/patch/kernel/sunxi-legacy/0055-drm-lima-add-buffer-object-functions.patch +++ /dev/null @@ -1,235 +0,0 @@ -From bde1f6b4f2fc7c20343e175ea9f1ef18f0aaedfa Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Wed, 16 May 2018 10:31:44 +0800 -Subject: [PATCH 055/146] drm/lima: add buffer object functions - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_object.c | 120 +++++++++++++++++++++++++++++ - drivers/gpu/drm/lima/lima_object.h | 87 +++++++++++++++++++++ - 2 files changed, 207 insertions(+) - create mode 100644 drivers/gpu/drm/lima/lima_object.c - create mode 100644 drivers/gpu/drm/lima/lima_object.h - -diff --git a/drivers/gpu/drm/lima/lima_object.c b/drivers/gpu/drm/lima/lima_object.c -new file mode 100644 -index 000000000000..5a22b235626b ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_object.c -@@ -0,0 +1,120 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include -+ -+#include "lima_object.h" -+ -+static void lima_bo_init_placement(struct lima_bo *bo) -+{ -+ struct ttm_placement *placement = &bo->placement; -+ struct ttm_place *place = &bo->place; -+ -+ place->fpfn = 0; -+ place->lpfn = 0; -+ place->flags = TTM_PL_FLAG_TT | TTM_PL_FLAG_WC; -+ -+ /* pin all bo for now */ -+ place->flags |= TTM_PL_FLAG_NO_EVICT; -+ -+ placement->num_placement = 1; -+ placement->placement = place; -+ -+ placement->num_busy_placement = 1; -+ placement->busy_placement = place; -+} -+ -+static void lima_bo_destroy(struct ttm_buffer_object *tbo) -+{ -+ struct lima_bo *bo = ttm_to_lima_bo(tbo); -+ -+ if (bo->gem.import_attach) -+ drm_prime_gem_destroy(&bo->gem, bo->tbo.sg); -+ drm_gem_object_release(&bo->gem); -+ kfree(bo); -+} -+ -+struct lima_bo *lima_bo_create(struct lima_device *dev, u64 size, -+ u32 flags, enum ttm_bo_type type, -+ struct sg_table *sg, -+ struct reservation_object *resv) -+{ -+ struct lima_bo *bo; -+ struct ttm_mem_type_manager *man; -+ size_t acc_size; -+ int err; -+ -+ size = PAGE_ALIGN(size); -+ man = dev->mman.bdev.man + TTM_PL_TT; -+ if (size >= (man->size << PAGE_SHIFT)) -+ return ERR_PTR(-ENOMEM); -+ -+ acc_size = ttm_bo_dma_acc_size(&dev->mman.bdev, size, -+ sizeof(struct lima_bo)); -+ -+ bo = kzalloc(sizeof(*bo), GFP_KERNEL); -+ if (!bo) -+ return ERR_PTR(-ENOMEM); -+ -+ drm_gem_private_object_init(dev->ddev, &bo->gem, size); -+ -+ INIT_LIST_HEAD(&bo->va); -+ -+ bo->tbo.bdev = &dev->mman.bdev; -+ -+ lima_bo_init_placement(bo); -+ -+ err = ttm_bo_init(&dev->mman.bdev, &bo->tbo, size, type, -+ &bo->placement, 0, type != ttm_bo_type_kernel, -+ acc_size, sg, resv, &lima_bo_destroy); -+ if (err) -+ goto err_out; -+ -+ return bo; -+ -+err_out: -+ kfree(bo); -+ return ERR_PTR(err); -+} -+ -+dma_addr_t *lima_bo_get_pages(struct lima_bo *bo) -+{ -+ struct lima_ttm_tt *ttm = (void *)bo->tbo.ttm; -+ return ttm->ttm.dma_address; -+} -+ -+void *lima_bo_kmap(struct lima_bo *bo) -+{ -+ bool is_iomem; -+ void *ret; -+ int err; -+ -+ ret = ttm_kmap_obj_virtual(&bo->kmap, &is_iomem); -+ if (ret) -+ return ret; -+ -+ err = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages, &bo->kmap); -+ if (err) -+ return ERR_PTR(err); -+ -+ return ttm_kmap_obj_virtual(&bo->kmap, &is_iomem); -+} -diff --git a/drivers/gpu/drm/lima/lima_object.h b/drivers/gpu/drm/lima/lima_object.h -new file mode 100644 -index 000000000000..2b8b8fcb9063 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_object.h -@@ -0,0 +1,87 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef __LIMA_OBJECT_H__ -+#define __LIMA_OBJECT_H__ -+ -+#include -+#include -+#include -+ -+#include "lima_device.h" -+ -+struct lima_bo { -+ struct drm_gem_object gem; -+ -+ struct ttm_place place; -+ struct ttm_placement placement; -+ struct ttm_buffer_object tbo; -+ struct ttm_bo_kmap_obj kmap; -+ -+ struct list_head va; -+}; -+ -+static inline struct lima_bo * -+to_lima_bo(struct drm_gem_object *obj) -+{ -+ return container_of(obj, struct lima_bo, gem); -+} -+ -+static inline struct lima_bo * -+ttm_to_lima_bo(struct ttm_buffer_object *tbo) -+{ -+ return container_of(tbo, struct lima_bo, tbo); -+} -+ -+static inline int lima_bo_reserve(struct lima_bo *bo, bool intr) -+{ -+ struct lima_device *dev = ttm_to_lima_dev(bo->tbo.bdev); -+ int r; -+ -+ r = ttm_bo_reserve(&bo->tbo, intr, false, NULL); -+ if (unlikely(r != 0)) { -+ if (r != -ERESTARTSYS) -+ dev_err(dev->dev, "%p reserve failed\n", bo); -+ return r; -+ } -+ return 0; -+} -+ -+static inline void lima_bo_unreserve(struct lima_bo *bo) -+{ -+ ttm_bo_unreserve(&bo->tbo); -+} -+ -+struct lima_bo *lima_bo_create(struct lima_device *dev, u64 size, -+ u32 flags, enum ttm_bo_type type, -+ struct sg_table *sg, -+ struct reservation_object *resv); -+ -+static inline void lima_bo_unref(struct lima_bo *bo) -+{ -+ struct ttm_buffer_object *tbo = &bo->tbo; -+ ttm_bo_unref(&tbo); -+} -+ -+dma_addr_t *lima_bo_get_pages(struct lima_bo *bo); -+void *lima_bo_kmap(struct lima_bo *bo); -+ -+#endif --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0056-drm-lima-add-GEM-related-functions.patch b/patch/kernel/sunxi-legacy/0056-drm-lima-add-GEM-related-functions.patch deleted file mode 100644 index 2cc84aa11..000000000 --- a/patch/kernel/sunxi-legacy/0056-drm-lima-add-GEM-related-functions.patch +++ /dev/null @@ -1,530 +0,0 @@ -From fda6ccdbd4930361a5a1dce1d2adf0998f63441e Mon Sep 17 00:00:00 2001 -From: Lima Project Developers -Date: Wed, 16 May 2018 10:34:29 +0800 -Subject: [PATCH 056/146] drm/lima: add GEM related functions - -Signed-off-by: Qiang Yu -Signed-off-by: Erico Nunes -Signed-off-by: Heiko Stuebner ---- - drivers/gpu/drm/lima/lima_gem.c | 459 ++++++++++++++++++++++++++++++++ - drivers/gpu/drm/lima/lima_gem.h | 41 +++ - 2 files changed, 500 insertions(+) - create mode 100644 drivers/gpu/drm/lima/lima_gem.c - create mode 100644 drivers/gpu/drm/lima/lima_gem.h - -diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c -new file mode 100644 -index 000000000000..1ad3f38ddfde ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_gem.c -@@ -0,0 +1,459 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "lima_drv.h" -+#include "lima_gem.h" -+#include "lima_vm.h" -+#include "lima_object.h" -+ -+int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, -+ u32 size, u32 flags, u32 *handle) -+{ -+ int err; -+ struct lima_bo *bo; -+ struct lima_device *ldev = to_lima_dev(dev); -+ -+ bo = lima_bo_create(ldev, size, flags, ttm_bo_type_device, NULL, NULL); -+ if (IS_ERR(bo)) -+ return PTR_ERR(bo); -+ -+ err = drm_gem_handle_create(file, &bo->gem, handle); -+ -+ /* drop reference from allocate - handle holds it now */ -+ drm_gem_object_put_unlocked(&bo->gem); -+ -+ return err; -+} -+ -+void lima_gem_free_object(struct drm_gem_object *obj) -+{ -+ struct lima_bo *bo = to_lima_bo(obj); -+ -+ if (!list_empty(&bo->va)) -+ dev_err(obj->dev->dev, "lima gem free bo still has va\n"); -+ -+ lima_bo_unref(bo); -+} -+ -+int lima_gem_object_open(struct drm_gem_object *obj, struct drm_file *file) -+{ -+ struct lima_bo *bo = to_lima_bo(obj); -+ struct lima_drm_priv *priv = to_lima_drm_priv(file); -+ struct lima_vm *vm = priv->vm; -+ int err; -+ -+ err = lima_bo_reserve(bo, true); -+ if (err) -+ return err; -+ -+ err = lima_vm_bo_add(vm, bo); -+ -+ lima_bo_unreserve(bo); -+ return err; -+} -+ -+void lima_gem_object_close(struct drm_gem_object *obj, struct drm_file *file) -+{ -+ struct lima_bo *bo = to_lima_bo(obj); -+ struct lima_device *dev = to_lima_dev(obj->dev); -+ struct lima_drm_priv *priv = to_lima_drm_priv(file); -+ struct lima_vm *vm = priv->vm; -+ -+ LIST_HEAD(list); -+ struct ttm_validate_buffer tv_bo, tv_pd; -+ struct ww_acquire_ctx ticket; -+ int r; -+ -+ tv_bo.bo = &bo->tbo; -+ tv_bo.shared = true; -+ list_add(&tv_bo.head, &list); -+ -+ tv_pd.bo = &vm->pd->tbo; -+ tv_pd.shared = true; -+ list_add(&tv_pd.head, &list); -+ -+ r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL); -+ if (r) { -+ dev_err(dev->dev, "leeking bo va because we " -+ "fail to reserve bo (%d)\n", r); -+ return; -+ } -+ -+ lima_vm_bo_del(vm, bo); -+ -+ ttm_eu_backoff_reservation(&ticket, &list); -+} -+ -+int lima_gem_mmap_offset(struct drm_file *file, u32 handle, u64 *offset) -+{ -+ struct drm_gem_object *obj; -+ struct lima_bo *bo; -+ -+ obj = drm_gem_object_lookup(file, handle); -+ if (!obj) -+ return -ENOENT; -+ -+ bo = to_lima_bo(obj); -+ *offset = drm_vma_node_offset_addr(&bo->tbo.vma_node); -+ -+ drm_gem_object_put_unlocked(obj); -+ return 0; -+} -+ -+int lima_gem_mmap(struct file *filp, struct vm_area_struct *vma) -+{ -+ struct drm_file *file_priv; -+ struct lima_device *dev; -+ -+ if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) -+ return -EINVAL; -+ -+ file_priv = filp->private_data; -+ dev = file_priv->minor->dev->dev_private; -+ if (dev == NULL) -+ return -EINVAL; -+ -+ return ttm_bo_mmap(filp, vma, &dev->mman.bdev); -+} -+ -+int lima_gem_va_map(struct drm_file *file, u32 handle, u32 flags, u32 va) -+{ -+ struct lima_drm_priv *priv = to_lima_drm_priv(file); -+ struct lima_vm *vm = priv->vm; -+ struct drm_gem_object *obj; -+ struct lima_bo *bo; -+ struct lima_device *dev; -+ int err; -+ -+ LIST_HEAD(list); -+ struct ttm_validate_buffer tv_bo, tv_pd; -+ struct ww_acquire_ctx ticket; -+ -+ if (!PAGE_ALIGNED(va)) -+ return -EINVAL; -+ -+ obj = drm_gem_object_lookup(file, handle); -+ if (!obj) -+ return -ENOENT; -+ -+ bo = to_lima_bo(obj); -+ dev = to_lima_dev(obj->dev); -+ -+ /* carefully handle overflow when calculate range */ -+ if (va < dev->va_start || dev->va_end - obj->size < va) { -+ err = -EINVAL; -+ goto out; -+ } -+ -+ tv_bo.bo = &bo->tbo; -+ tv_bo.shared = true; -+ list_add(&tv_bo.head, &list); -+ -+ tv_pd.bo = &vm->pd->tbo; -+ tv_pd.shared = true; -+ list_add(&tv_pd.head, &list); -+ -+ err = ttm_eu_reserve_buffers(&ticket, &list, false, NULL); -+ if (err) -+ goto out; -+ -+ err = lima_vm_bo_map(vm, bo, va); -+ -+ ttm_eu_backoff_reservation(&ticket, &list); -+out: -+ drm_gem_object_put_unlocked(obj); -+ return err; -+} -+ -+int lima_gem_va_unmap(struct drm_file *file, u32 handle, u32 va) -+{ -+ struct lima_drm_priv *priv = to_lima_drm_priv(file); -+ struct lima_vm *vm = priv->vm; -+ struct drm_gem_object *obj; -+ struct lima_bo *bo; -+ int err; -+ -+ LIST_HEAD(list); -+ struct ttm_validate_buffer tv_bo, tv_pd; -+ struct ww_acquire_ctx ticket; -+ -+ if (!PAGE_ALIGNED(va)) -+ return -EINVAL; -+ -+ obj = drm_gem_object_lookup(file, handle); -+ if (!obj) -+ return -ENOENT; -+ -+ bo = to_lima_bo(obj); -+ -+ tv_bo.bo = &bo->tbo; -+ tv_bo.shared = true; -+ list_add(&tv_bo.head, &list); -+ -+ tv_pd.bo = &vm->pd->tbo; -+ tv_pd.shared = true; -+ list_add(&tv_pd.head, &list); -+ -+ err = ttm_eu_reserve_buffers(&ticket, &list, false, NULL); -+ if (err) -+ goto out; -+ -+ err = lima_vm_bo_unmap(vm, bo, va); -+ -+ ttm_eu_backoff_reservation(&ticket, &list); -+out: -+ drm_gem_object_put_unlocked(obj); -+ return err; -+} -+ -+static int lima_gem_sync_bo(struct lima_sched_task *task, struct lima_bo *bo, -+ bool write, bool explicit) -+{ -+ int i, err; -+ struct dma_fence *f; -+ u64 context = task->base.s_fence->finished.context; -+ -+ if (!write) { -+ err = reservation_object_reserve_shared(bo->tbo.resv); -+ if (err) -+ return err; -+ } -+ -+ /* explicit sync use user passed dep fence */ -+ if (explicit) -+ return 0; -+ -+ /* implicit sync use bo fence in resv obj */ -+ if (write) { -+ struct reservation_object_list *fobj = -+ reservation_object_get_list(bo->tbo.resv); -+ -+ if (fobj && fobj->shared_count > 0) { -+ for (i = 0; i < fobj->shared_count; i++) { -+ f = rcu_dereference_protected( -+ fobj->shared[i], -+ reservation_object_held(bo->tbo.resv)); -+ if (f->context != context) { -+ err = lima_sched_task_add_dep(task, f); -+ if (err) -+ return err; -+ } -+ } -+ } -+ } -+ -+ f = reservation_object_get_excl(bo->tbo.resv); -+ if (f) { -+ err = lima_sched_task_add_dep(task, f); -+ if (err) -+ return err; -+ } -+ -+ return 0; -+} -+ -+static int lima_gem_add_deps(struct lima_ctx_mgr *mgr, struct lima_submit *submit) -+{ -+ int i, err = 0; -+ -+ for (i = 0; i < submit->nr_deps; i++) { -+ union drm_lima_gem_submit_dep *dep = submit->deps + i; -+ struct dma_fence *fence; -+ -+ if (dep->type == LIMA_SUBMIT_DEP_FENCE) { -+ fence = lima_ctx_get_native_fence( -+ mgr, dep->fence.ctx, dep->fence.pipe, -+ dep->fence.seq); -+ if (IS_ERR(fence)) { -+ err = PTR_ERR(fence); -+ break; -+ } -+ } -+ else if (dep->type == LIMA_SUBMIT_DEP_SYNC_FD) { -+ fence = sync_file_get_fence(dep->sync_fd.fd); -+ if (!fence) { -+ err = -EINVAL; -+ break; -+ } -+ } -+ else { -+ err = -EINVAL; -+ break; -+ } -+ -+ if (fence) { -+ err = lima_sched_task_add_dep(submit->task, fence); -+ dma_fence_put(fence); -+ if (err) -+ break; -+ } -+ } -+ -+ return err; -+} -+ -+static int lima_gem_get_sync_fd(struct dma_fence *fence) -+{ -+ struct sync_file *sync_file; -+ int fd; -+ -+ fd = get_unused_fd_flags(O_CLOEXEC); -+ if (fd < 0) -+ return fd; -+ -+ sync_file = sync_file_create(fence); -+ if (!sync_file) { -+ put_unused_fd(fd); -+ return -ENOMEM; -+ } -+ -+ fd_install(fd, sync_file->file); -+ return fd; -+} -+ -+int lima_gem_submit(struct drm_file *file, struct lima_submit *submit) -+{ -+ int i, err = 0; -+ struct lima_drm_priv *priv = to_lima_drm_priv(file); -+ struct lima_vm *vm = priv->vm; -+ -+ INIT_LIST_HEAD(&submit->validated); -+ INIT_LIST_HEAD(&submit->duplicates); -+ -+ for (i = 0; i < submit->nr_bos; i++) { -+ struct drm_gem_object *obj; -+ struct drm_lima_gem_submit_bo *bo = submit->bos + i; -+ struct ttm_validate_buffer *vb = submit->vbs + i; -+ -+ obj = drm_gem_object_lookup(file, bo->handle); -+ if (!obj) { -+ err = -ENOENT; -+ goto out0; -+ } -+ -+ vb->bo = &to_lima_bo(obj)->tbo; -+ vb->shared = !(bo->flags & LIMA_SUBMIT_BO_WRITE); -+ list_add_tail(&vb->head, &submit->validated); -+ } -+ -+ submit->vm_pd_vb.bo = &vm->pd->tbo; -+ submit->vm_pd_vb.shared = true; -+ list_add(&submit->vm_pd_vb.head, &submit->validated); -+ -+ err = ttm_eu_reserve_buffers(&submit->ticket, &submit->validated, -+ true, &submit->duplicates); -+ if (err) -+ goto out0; -+ -+ err = lima_sched_task_init( -+ submit->task, submit->ctx->context + submit->pipe, vm); -+ if (err) -+ goto out1; -+ -+ err = lima_gem_add_deps(&priv->ctx_mgr, submit); -+ if (err) -+ goto out2; -+ -+ for (i = 0; i < submit->nr_bos; i++) { -+ struct ttm_validate_buffer *vb = submit->vbs + i; -+ struct lima_bo *bo = ttm_to_lima_bo(vb->bo); -+ err = lima_gem_sync_bo( -+ submit->task, bo, !vb->shared, -+ submit->flags & LIMA_SUBMIT_FLAG_EXPLICIT_FENCE); -+ if (err) -+ goto out2; -+ } -+ -+ if (submit->flags & LIMA_SUBMIT_FLAG_SYNC_FD_OUT) { -+ int fd = lima_gem_get_sync_fd( -+ &submit->task->base.s_fence->finished); -+ if (fd < 0) { -+ err = fd; -+ goto out2; -+ } -+ submit->sync_fd = fd; -+ } -+ -+ submit->fence = lima_sched_context_queue_task( -+ submit->ctx->context + submit->pipe, submit->task, -+ &submit->done); -+ -+ ttm_eu_fence_buffer_objects(&submit->ticket, &submit->validated, -+ &submit->task->base.s_fence->finished); -+ -+out2: -+ if (err) -+ lima_sched_task_fini(submit->task); -+out1: -+ if (err) -+ ttm_eu_backoff_reservation(&submit->ticket, &submit->validated); -+out0: -+ for (i = 0; i < submit->nr_bos; i++) { -+ struct ttm_validate_buffer *vb = submit->vbs + i; -+ if (!vb->bo) -+ break; -+ drm_gem_object_put_unlocked(&ttm_to_lima_bo(vb->bo)->gem); -+ } -+ return err; -+} -+ -+int lima_gem_wait(struct drm_file *file, u32 handle, u32 op, u64 timeout_ns) -+{ -+ bool write = op & LIMA_GEM_WAIT_WRITE; -+ struct drm_gem_object *obj; -+ struct lima_bo *bo; -+ signed long ret; -+ unsigned long timeout; -+ -+ obj = drm_gem_object_lookup(file, handle); -+ if (!obj) -+ return -ENOENT; -+ -+ bo = to_lima_bo(obj); -+ -+ timeout = timeout_ns ? lima_timeout_to_jiffies(timeout_ns) : 0; -+ -+ ret = lima_bo_reserve(bo, true); -+ if (ret) -+ goto out; -+ -+ /* must use long for result check because in 64bit arch int -+ * will overflow if timeout is too large and get <0 result -+ */ -+ ret = reservation_object_wait_timeout_rcu(bo->tbo.resv, write, true, timeout); -+ if (ret == 0) -+ ret = timeout ? -ETIMEDOUT : -EBUSY; -+ else if (ret > 0) -+ ret = 0; -+ -+ lima_bo_unreserve(bo); -+out: -+ drm_gem_object_put_unlocked(obj); -+ return ret; -+} -diff --git a/drivers/gpu/drm/lima/lima_gem.h b/drivers/gpu/drm/lima/lima_gem.h -new file mode 100644 -index 000000000000..8e3c4110825d ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_gem.h -@@ -0,0 +1,41 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef __LIMA_GEM_H__ -+#define __LIMA_GEM_H__ -+ -+struct lima_bo; -+struct lima_submit; -+ -+struct lima_bo *lima_gem_create_bo(struct drm_device *dev, u32 size, u32 flags); -+int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, -+ u32 size, u32 flags, u32 *handle); -+void lima_gem_free_object(struct drm_gem_object *obj); -+int lima_gem_object_open(struct drm_gem_object *obj, struct drm_file *file); -+void lima_gem_object_close(struct drm_gem_object *obj, struct drm_file *file); -+int lima_gem_mmap_offset(struct drm_file *file, u32 handle, u64 *offset); -+int lima_gem_mmap(struct file *filp, struct vm_area_struct *vma); -+int lima_gem_va_map(struct drm_file *file, u32 handle, u32 flags, u32 va); -+int lima_gem_va_unmap(struct drm_file *file, u32 handle, u32 va); -+int lima_gem_submit(struct drm_file *file, struct lima_submit *submit); -+int lima_gem_wait(struct drm_file *file, u32 handle, u32 op, u64 timeout_ns); -+ -+#endif --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0057-drm-lima-add-GEM-Prime-related-functions.patch b/patch/kernel/sunxi-legacy/0057-drm-lima-add-GEM-Prime-related-functions.patch deleted file mode 100644 index 3bce77c6c..000000000 --- a/patch/kernel/sunxi-legacy/0057-drm-lima-add-GEM-Prime-related-functions.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 2a5a3ab8cf45c868fa158fb2766f7a9707d187b0 Mon Sep 17 00:00:00 2001 -From: Lima Project Developers -Date: Wed, 16 May 2018 10:38:28 +0800 -Subject: [PATCH 057/146] drm/lima: add GEM Prime related functions - -Signed-off-by: Qiang Yu -Signed-off-by: Erico Nunes ---- - drivers/gpu/drm/lima/lima_gem_prime.c | 66 +++++++++++++++++++++++++++ - drivers/gpu/drm/lima/lima_gem_prime.h | 31 +++++++++++++ - 2 files changed, 97 insertions(+) - create mode 100644 drivers/gpu/drm/lima/lima_gem_prime.c - create mode 100644 drivers/gpu/drm/lima/lima_gem_prime.h - -diff --git a/drivers/gpu/drm/lima/lima_gem_prime.c b/drivers/gpu/drm/lima/lima_gem_prime.c -new file mode 100644 -index 000000000000..74da43a4378f ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_gem_prime.c -@@ -0,0 +1,66 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include -+#include -+ -+#include "lima_device.h" -+#include "lima_object.h" -+#include "lima_gem_prime.h" -+ -+struct drm_gem_object *lima_gem_prime_import_sg_table( -+ struct drm_device *dev, struct dma_buf_attachment *attach, -+ struct sg_table *sgt) -+{ -+ struct reservation_object *resv = attach->dmabuf->resv; -+ struct lima_device *ldev = to_lima_dev(dev); -+ struct lima_bo *bo; -+ -+ ww_mutex_lock(&resv->lock, NULL); -+ -+ bo = lima_bo_create(ldev, attach->dmabuf->size, 0, -+ ttm_bo_type_sg, sgt, resv); -+ if (IS_ERR(bo)) -+ goto err_out; -+ -+ ww_mutex_unlock(&resv->lock); -+ return &bo->gem; -+ -+err_out: -+ ww_mutex_unlock(&resv->lock); -+ return (void *)bo; -+} -+ -+struct reservation_object *lima_gem_prime_res_obj(struct drm_gem_object *obj) -+{ -+ struct lima_bo *bo = to_lima_bo(obj); -+ -+ return bo->tbo.resv; -+} -+ -+struct sg_table *lima_gem_prime_get_sg_table(struct drm_gem_object *obj) -+{ -+ struct lima_bo *bo = to_lima_bo(obj); -+ int npages = bo->tbo.num_pages; -+ -+ return drm_prime_pages_to_sg(bo->tbo.ttm->pages, npages); -+} -diff --git a/drivers/gpu/drm/lima/lima_gem_prime.h b/drivers/gpu/drm/lima/lima_gem_prime.h -new file mode 100644 -index 000000000000..023bf5ba2d7b ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_gem_prime.h -@@ -0,0 +1,31 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef __LIMA_GEM_PRIME_H__ -+#define __LIMA_GEM_PRIME_H__ -+ -+struct drm_gem_object *lima_gem_prime_import_sg_table( -+ struct drm_device *dev, struct dma_buf_attachment *attach, -+ struct sg_table *sgt); -+struct sg_table *lima_gem_prime_get_sg_table(struct drm_gem_object *obj); -+struct reservation_object *lima_gem_prime_res_obj(struct drm_gem_object *obj); -+ -+#endif --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0058-drm-lima-add-GPU-schedule-using-DRM_SCHED.patch b/patch/kernel/sunxi-legacy/0058-drm-lima-add-GPU-schedule-using-DRM_SCHED.patch deleted file mode 100644 index 12d5c8f82..000000000 --- a/patch/kernel/sunxi-legacy/0058-drm-lima-add-GPU-schedule-using-DRM_SCHED.patch +++ /dev/null @@ -1,651 +0,0 @@ -From f76c22d3c634633a1d27dce98d042f211f0ac35e Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Wed, 16 May 2018 10:40:58 +0800 -Subject: [PATCH 058/146] drm/lima: add GPU schedule using DRM_SCHED - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_sched.c | 497 ++++++++++++++++++++++++++++++ - drivers/gpu/drm/lima/lima_sched.h | 126 ++++++++ - 2 files changed, 623 insertions(+) - create mode 100644 drivers/gpu/drm/lima/lima_sched.c - create mode 100644 drivers/gpu/drm/lima/lima_sched.h - -diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c -new file mode 100644 -index 000000000000..190932955e9b ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_sched.c -@@ -0,0 +1,497 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include -+#include -+ -+#include "lima_drv.h" -+#include "lima_sched.h" -+#include "lima_vm.h" -+#include "lima_mmu.h" -+#include "lima_l2_cache.h" -+ -+struct lima_fence { -+ struct dma_fence base; -+ struct lima_sched_pipe *pipe; -+}; -+ -+static struct kmem_cache *lima_fence_slab = NULL; -+ -+int lima_sched_slab_init(void) -+{ -+ lima_fence_slab = kmem_cache_create( -+ "lima_fence", sizeof(struct lima_fence), 0, -+ SLAB_HWCACHE_ALIGN, NULL); -+ if (!lima_fence_slab) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+void lima_sched_slab_fini(void) -+{ -+ if (lima_fence_slab) -+ kmem_cache_destroy(lima_fence_slab); -+} -+ -+static inline struct lima_fence *to_lima_fence(struct dma_fence *fence) -+{ -+ return container_of(fence, struct lima_fence, base); -+} -+ -+static const char *lima_fence_get_driver_name(struct dma_fence *fence) -+{ -+ return "lima"; -+} -+ -+static const char *lima_fence_get_timeline_name(struct dma_fence *fence) -+{ -+ struct lima_fence *f = to_lima_fence(fence); -+ -+ return f->pipe->base.name; -+} -+ -+static bool lima_fence_enable_signaling(struct dma_fence *fence) -+{ -+ return true; -+} -+ -+static void lima_fence_release_rcu(struct rcu_head *rcu) -+{ -+ struct dma_fence *f = container_of(rcu, struct dma_fence, rcu); -+ struct lima_fence *fence = to_lima_fence(f); -+ -+ kmem_cache_free(lima_fence_slab, fence); -+} -+ -+static void lima_fence_release(struct dma_fence *fence) -+{ -+ struct lima_fence *f = to_lima_fence(fence); -+ -+ call_rcu(&f->base.rcu, lima_fence_release_rcu); -+} -+ -+static const struct dma_fence_ops lima_fence_ops = { -+ .get_driver_name = lima_fence_get_driver_name, -+ .get_timeline_name = lima_fence_get_timeline_name, -+ .enable_signaling = lima_fence_enable_signaling, -+ .wait = dma_fence_default_wait, -+ .release = lima_fence_release, -+}; -+ -+static struct lima_fence *lima_fence_create(struct lima_sched_pipe *pipe) -+{ -+ struct lima_fence *fence; -+ -+ fence = kmem_cache_zalloc(lima_fence_slab, GFP_KERNEL); -+ if (!fence) -+ return NULL; -+ -+ fence->pipe = pipe; -+ dma_fence_init(&fence->base, &lima_fence_ops, &pipe->fence_lock, -+ pipe->fence_context, ++pipe->fence_seqno); -+ -+ return fence; -+} -+ -+static inline struct lima_sched_task *to_lima_task(struct drm_sched_job *job) -+{ -+ return container_of(job, struct lima_sched_task, base); -+} -+ -+static inline struct lima_sched_pipe *to_lima_pipe(struct drm_gpu_scheduler *sched) -+{ -+ return container_of(sched, struct lima_sched_pipe, base); -+} -+ -+int lima_sched_task_init(struct lima_sched_task *task, -+ struct lima_sched_context *context, -+ struct lima_vm *vm) -+{ -+ int err; -+ -+ err = drm_sched_job_init(&task->base, context->base.sched, -+ &context->base, context); -+ if (err) -+ return err; -+ -+ task->vm = lima_vm_get(vm); -+ return 0; -+} -+ -+void lima_sched_task_fini(struct lima_sched_task *task) -+{ -+ dma_fence_put(&task->base.s_fence->finished); -+ lima_vm_put(task->vm); -+} -+ -+int lima_sched_task_add_dep(struct lima_sched_task *task, struct dma_fence *fence) -+{ -+ int i, new_dep = 4; -+ -+ if (task->dep && task->num_dep == task->max_dep) -+ new_dep = task->max_dep * 2; -+ -+ if (task->max_dep < new_dep) { -+ void *dep = krealloc(task->dep, sizeof(*task->dep) * new_dep, GFP_KERNEL); -+ if (!dep) -+ return -ENOMEM; -+ task->max_dep = new_dep; -+ task->dep = dep; -+ } -+ -+ dma_fence_get(fence); -+ for (i = 0; i < task->num_dep; i++) { -+ if (task->dep[i]->context == fence->context && -+ dma_fence_is_later(fence, task->dep[i])) { -+ dma_fence_put(task->dep[i]); -+ task->dep[i] = fence; -+ return 0; -+ } -+ } -+ -+ task->dep[task->num_dep++] = fence; -+ return 0; -+} -+ -+int lima_sched_context_init(struct lima_sched_pipe *pipe, -+ struct lima_sched_context *context, -+ atomic_t *guilty) -+{ -+ struct drm_sched_rq *rq = pipe->base.sched_rq + DRM_SCHED_PRIORITY_NORMAL; -+ int err; -+ -+ context->fences = -+ kzalloc(sizeof(*context->fences) * lima_sched_max_tasks, GFP_KERNEL); -+ if (!context->fences) -+ return -ENOMEM; -+ -+ mutex_init(&context->lock); -+ err = drm_sched_entity_init(&pipe->base, &context->base, rq, -+ lima_sched_max_tasks, guilty); -+ if (err) { -+ kfree(context->fences); -+ context->fences = NULL; -+ return err; -+ } -+ -+ return 0; -+} -+ -+void lima_sched_context_fini(struct lima_sched_pipe *pipe, -+ struct lima_sched_context *context) -+{ -+ drm_sched_entity_fini(&pipe->base, &context->base); -+ -+ mutex_destroy(&context->lock); -+ -+ if (context->fences) -+ kfree(context->fences); -+} -+ -+static uint32_t lima_sched_context_add_fence(struct lima_sched_context *context, -+ struct dma_fence *fence, -+ uint32_t *done) -+{ -+ uint32_t seq, idx, i; -+ struct dma_fence *other; -+ -+ mutex_lock(&context->lock); -+ -+ seq = context->sequence; -+ idx = seq & (lima_sched_max_tasks - 1); -+ other = context->fences[idx]; -+ -+ if (other) { -+ int err = dma_fence_wait(other, false); -+ if (err) -+ DRM_ERROR("Error %d waiting context fence\n", err); -+ } -+ -+ context->fences[idx] = dma_fence_get(fence); -+ context->sequence++; -+ -+ /* get finished fence offset from seq */ -+ for (i = 1; i < lima_sched_max_tasks; i++) { -+ idx = (seq - i) & (lima_sched_max_tasks - 1); -+ if (!context->fences[idx] || -+ dma_fence_is_signaled(context->fences[idx])) -+ break; -+ } -+ -+ mutex_unlock(&context->lock); -+ -+ dma_fence_put(other); -+ -+ *done = i; -+ return seq; -+} -+ -+struct dma_fence *lima_sched_context_get_fence( -+ struct lima_sched_context *context, uint32_t seq) -+{ -+ struct dma_fence *fence; -+ int idx; -+ uint32_t max, min; -+ -+ mutex_lock(&context->lock); -+ -+ max = context->sequence - 1; -+ min = context->sequence - lima_sched_max_tasks; -+ -+ /* handle overflow case */ -+ if ((min < max && (seq < min || seq > max)) || -+ (min > max && (seq < min && seq > max))) { -+ fence = NULL; -+ goto out; -+ } -+ -+ idx = seq & (lima_sched_max_tasks - 1); -+ fence = dma_fence_get(context->fences[idx]); -+ -+out: -+ mutex_unlock(&context->lock); -+ -+ return fence; -+} -+ -+uint32_t lima_sched_context_queue_task(struct lima_sched_context *context, -+ struct lima_sched_task *task, -+ uint32_t *done) -+{ -+ uint32_t seq = lima_sched_context_add_fence( -+ context, &task->base.s_fence->finished, done); -+ drm_sched_entity_push_job(&task->base, &context->base); -+ return seq; -+} -+ -+static struct dma_fence *lima_sched_dependency(struct drm_sched_job *job, -+ struct drm_sched_entity *entity) -+{ -+ struct lima_sched_task *task = to_lima_task(job); -+ int i; -+ -+ for (i = 0; i < task->num_dep; i++) { -+ struct dma_fence *fence = task->dep[i]; -+ -+ if (!task->dep[i]) -+ continue; -+ -+ task->dep[i] = NULL; -+ -+ if (!dma_fence_is_signaled(fence)) -+ return fence; -+ -+ dma_fence_put(fence); -+ } -+ -+ return NULL; -+} -+ -+static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) -+{ -+ struct lima_sched_task *task = to_lima_task(job); -+ struct lima_sched_pipe *pipe = to_lima_pipe(job->sched); -+ struct lima_fence *fence; -+ struct dma_fence *ret; -+ struct lima_vm *vm = NULL, *last_vm = NULL; -+ int i; -+ -+ /* after GPU reset */ -+ if (job->s_fence->finished.error < 0) -+ return NULL; -+ -+ fence = lima_fence_create(pipe); -+ if (!fence) -+ return NULL; -+ task->fence = &fence->base; -+ -+ /* for caller usage of the fence, otherwise irq handler -+ * may consume the fence before caller use it */ -+ ret = dma_fence_get(task->fence); -+ -+ pipe->current_task = task; -+ -+ /* this is needed for MMU to work correctly, otherwise GP/PP -+ * will hang or page fault for unknown reason after running for -+ * a while. -+ * -+ * Need to investigate: -+ * 1. is it related to TLB -+ * 2. how much performance will be affected by L2 cache flush -+ * 3. can we reduce the calling of this function because all -+ * GP/PP use the same L2 cache on mali400 -+ * -+ * TODO: -+ * 1. move this to task fini to save some wait time? -+ * 2. when GP/PP use different l2 cache, need PP wait GP l2 -+ * cache flush? -+ */ -+ for (i = 0; i < pipe->num_l2_cache; i++) -+ lima_l2_cache_flush(pipe->l2_cache[i]); -+ -+ if (task->vm != pipe->current_vm) { -+ vm = lima_vm_get(task->vm); -+ last_vm = pipe->current_vm; -+ pipe->current_vm = task->vm; -+ } -+ -+ if (pipe->bcast_mmu) -+ lima_mmu_switch_vm(pipe->bcast_mmu, vm); -+ else { -+ for (i = 0; i < pipe->num_mmu; i++) -+ lima_mmu_switch_vm(pipe->mmu[i], vm); -+ } -+ -+ if (last_vm) -+ lima_vm_put(last_vm); -+ -+ pipe->error = false; -+ pipe->task_run(pipe, task); -+ -+ return task->fence; -+} -+ -+static void lima_sched_handle_error_task(struct lima_sched_pipe *pipe, -+ struct lima_sched_task *task) -+{ -+ kthread_park(pipe->base.thread); -+ drm_sched_hw_job_reset(&pipe->base, &task->base); -+ -+ pipe->task_error(pipe); -+ -+ if (pipe->bcast_mmu) -+ lima_mmu_page_fault_resume(pipe->bcast_mmu); -+ else { -+ int i; -+ for (i = 0; i < pipe->num_mmu; i++) -+ lima_mmu_page_fault_resume(pipe->mmu[i]); -+ } -+ -+ if (pipe->current_vm) -+ lima_vm_put(pipe->current_vm); -+ -+ pipe->current_vm = NULL; -+ pipe->current_task = NULL; -+ -+ drm_sched_job_recovery(&pipe->base); -+ kthread_unpark(pipe->base.thread); -+} -+ -+static void lima_sched_timedout_job(struct drm_sched_job *job) -+{ -+ struct lima_sched_pipe *pipe = to_lima_pipe(job->sched); -+ struct lima_sched_task *task = to_lima_task(job); -+ -+ lima_sched_handle_error_task(pipe, task); -+} -+ -+static void lima_sched_free_job(struct drm_sched_job *job) -+{ -+ struct lima_sched_task *task = to_lima_task(job); -+ struct lima_sched_pipe *pipe = to_lima_pipe(job->sched); -+ int i; -+ -+ dma_fence_put(task->fence); -+ -+ for (i = 0; i < task->num_dep; i++) { -+ if (task->dep[i]) -+ dma_fence_put(task->dep[i]); -+ } -+ -+ if (task->dep) -+ kfree(task->dep); -+ -+ lima_vm_put(task->vm); -+ kmem_cache_free(pipe->task_slab, task); -+} -+ -+const struct drm_sched_backend_ops lima_sched_ops = { -+ .dependency = lima_sched_dependency, -+ .run_job = lima_sched_run_job, -+ .timedout_job = lima_sched_timedout_job, -+ .free_job = lima_sched_free_job, -+}; -+ -+static void lima_sched_error_work(struct work_struct *work) -+{ -+ struct lima_sched_pipe *pipe = -+ container_of(work, struct lima_sched_pipe, error_work); -+ struct lima_sched_task *task = pipe->current_task; -+ -+ lima_sched_handle_error_task(pipe, task); -+} -+ -+int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name) -+{ -+ long timeout; -+ -+ if (lima_sched_timeout_ms <= 0) -+ timeout = MAX_SCHEDULE_TIMEOUT; -+ else -+ timeout = msecs_to_jiffies(lima_sched_timeout_ms); -+ -+ pipe->fence_context = dma_fence_context_alloc(1); -+ spin_lock_init(&pipe->fence_lock); -+ -+ INIT_WORK(&pipe->error_work, lima_sched_error_work); -+ -+ return drm_sched_init(&pipe->base, &lima_sched_ops, 1, 0, timeout, name); -+} -+ -+void lima_sched_pipe_fini(struct lima_sched_pipe *pipe) -+{ -+ drm_sched_fini(&pipe->base); -+} -+ -+unsigned long lima_timeout_to_jiffies(u64 timeout_ns) -+{ -+ unsigned long timeout_jiffies; -+ ktime_t timeout; -+ -+ /* clamp timeout if it's to large */ -+ if (((s64)timeout_ns) < 0) -+ return MAX_SCHEDULE_TIMEOUT; -+ -+ timeout = ktime_sub(ns_to_ktime(timeout_ns), ktime_get()); -+ if (ktime_to_ns(timeout) < 0) -+ return 0; -+ -+ timeout_jiffies = nsecs_to_jiffies(ktime_to_ns(timeout)); -+ /* clamp timeout to avoid unsigned-> signed overflow */ -+ if (timeout_jiffies > MAX_SCHEDULE_TIMEOUT ) -+ return MAX_SCHEDULE_TIMEOUT; -+ -+ return timeout_jiffies; -+} -+ -+void lima_sched_pipe_task_done(struct lima_sched_pipe *pipe) -+{ -+ if (pipe->error) -+ schedule_work(&pipe->error_work); -+ else { -+ struct lima_sched_task *task = pipe->current_task; -+ -+ pipe->task_fini(pipe); -+ dma_fence_signal(task->fence); -+ } -+} -diff --git a/drivers/gpu/drm/lima/lima_sched.h b/drivers/gpu/drm/lima/lima_sched.h -new file mode 100644 -index 000000000000..b93b7b4eded4 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_sched.h -@@ -0,0 +1,126 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef __LIMA_SCHED_H__ -+#define __LIMA_SCHED_H__ -+ -+#include -+ -+struct lima_vm; -+ -+struct lima_sched_task { -+ struct drm_sched_job base; -+ -+ struct lima_vm *vm; -+ void *frame; -+ -+ struct dma_fence **dep; -+ int num_dep; -+ int max_dep; -+ -+ /* pipe fence */ -+ struct dma_fence *fence; -+}; -+ -+struct lima_sched_context { -+ struct drm_sched_entity base; -+ struct mutex lock; -+ struct dma_fence **fences; -+ uint32_t sequence; -+}; -+ -+#define LIMA_SCHED_PIPE_MAX_MMU 8 -+#define LIMA_SCHED_PIPE_MAX_L2_CACHE 2 -+#define LIMA_SCHED_PIPE_MAX_PROCESSOR 8 -+ -+struct lima_ip; -+ -+struct lima_sched_pipe { -+ struct drm_gpu_scheduler base; -+ -+ u64 fence_context; -+ u32 fence_seqno; -+ spinlock_t fence_lock; -+ -+ struct lima_sched_task *current_task; -+ struct lima_vm *current_vm; -+ -+ struct lima_ip *mmu[LIMA_SCHED_PIPE_MAX_MMU]; -+ int num_mmu; -+ -+ struct lima_ip *l2_cache[LIMA_SCHED_PIPE_MAX_L2_CACHE]; -+ int num_l2_cache; -+ -+ struct lima_ip *processor[LIMA_SCHED_PIPE_MAX_PROCESSOR]; -+ int num_processor; -+ -+ struct lima_ip *bcast_processor; -+ struct lima_ip *bcast_mmu; -+ -+ u32 done; -+ bool error; -+ atomic_t task; -+ -+ int frame_size; -+ struct kmem_cache *task_slab; -+ -+ int (*task_validate)(struct lima_sched_pipe *pipe, struct lima_sched_task *task); -+ void (*task_run)(struct lima_sched_pipe *pipe, struct lima_sched_task *task); -+ void (*task_fini)(struct lima_sched_pipe *pipe); -+ void (*task_error)(struct lima_sched_pipe *pipe); -+ void (*task_mmu_error)(struct lima_sched_pipe *pipe); -+ -+ struct work_struct error_work; -+}; -+ -+int lima_sched_task_init(struct lima_sched_task *task, -+ struct lima_sched_context *context, -+ struct lima_vm *vm); -+void lima_sched_task_fini(struct lima_sched_task *task); -+int lima_sched_task_add_dep(struct lima_sched_task *task, struct dma_fence *fence); -+ -+int lima_sched_context_init(struct lima_sched_pipe *pipe, -+ struct lima_sched_context *context, -+ atomic_t *guilty); -+void lima_sched_context_fini(struct lima_sched_pipe *pipe, -+ struct lima_sched_context *context); -+uint32_t lima_sched_context_queue_task(struct lima_sched_context *context, -+ struct lima_sched_task *task, -+ uint32_t *done); -+struct dma_fence *lima_sched_context_get_fence( -+ struct lima_sched_context *context, uint32_t seq); -+ -+int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name); -+void lima_sched_pipe_fini(struct lima_sched_pipe *pipe); -+void lima_sched_pipe_task_done(struct lima_sched_pipe *pipe); -+ -+static inline void lima_sched_pipe_mmu_error(struct lima_sched_pipe *pipe) -+{ -+ pipe->error = true; -+ pipe->task_mmu_error(pipe); -+} -+ -+int lima_sched_slab_init(void); -+void lima_sched_slab_fini(void); -+ -+unsigned long lima_timeout_to_jiffies(u64 timeout_ns); -+ -+#endif --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0059-drm-lima-add-context-related-functions.patch b/patch/kernel/sunxi-legacy/0059-drm-lima-add-context-related-functions.patch deleted file mode 100644 index 2f45be14f..000000000 --- a/patch/kernel/sunxi-legacy/0059-drm-lima-add-context-related-functions.patch +++ /dev/null @@ -1,222 +0,0 @@ -From fcfa6c7b5a84fac51109efd86b4edf5085359485 Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Wed, 16 May 2018 11:14:41 +0800 -Subject: [PATCH 059/146] drm/lima: add context related functions - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_ctx.c | 143 ++++++++++++++++++++++++++++++++ - drivers/gpu/drm/lima/lima_ctx.h | 51 ++++++++++++ - 2 files changed, 194 insertions(+) - create mode 100644 drivers/gpu/drm/lima/lima_ctx.c - create mode 100644 drivers/gpu/drm/lima/lima_ctx.h - -diff --git a/drivers/gpu/drm/lima/lima_ctx.c b/drivers/gpu/drm/lima/lima_ctx.c -new file mode 100644 -index 000000000000..7243861760b4 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_ctx.c -@@ -0,0 +1,143 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include -+ -+#include "lima_device.h" -+#include "lima_ctx.h" -+ -+int lima_ctx_create(struct lima_device *dev, struct lima_ctx_mgr *mgr, u32 *id) -+{ -+ struct lima_ctx *ctx; -+ int i, err; -+ -+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); -+ if (!ctx) -+ return -ENOMEM; -+ ctx->dev = dev; -+ kref_init(&ctx->refcnt); -+ -+ for (i = 0; i < lima_pipe_num; i++) { -+ err = lima_sched_context_init(dev->pipe + i, ctx->context + i, &ctx->guilty); -+ if (err) -+ goto err_out0; -+ } -+ -+ idr_preload(GFP_KERNEL); -+ spin_lock(&mgr->lock); -+ err = idr_alloc(&mgr->handles, ctx, 1, 0, GFP_ATOMIC); -+ spin_unlock(&mgr->lock); -+ idr_preload_end(); -+ if (err < 0) -+ goto err_out0; -+ -+ *id = err; -+ return 0; -+ -+err_out0: -+ for (i--; i >= 0; i--) -+ lima_sched_context_fini(dev->pipe + i, ctx->context + i); -+ kfree(ctx); -+ return err; -+} -+ -+static void lima_ctx_do_release(struct kref *ref) -+{ -+ struct lima_ctx *ctx = container_of(ref, struct lima_ctx, refcnt); -+ int i; -+ -+ for (i = 0; i < lima_pipe_num; i++) -+ lima_sched_context_fini(ctx->dev->pipe + i, ctx->context + i); -+ kfree(ctx); -+} -+ -+int lima_ctx_free(struct lima_ctx_mgr *mgr, u32 id) -+{ -+ struct lima_ctx *ctx; -+ -+ spin_lock(&mgr->lock); -+ ctx = idr_remove(&mgr->handles, id); -+ spin_unlock(&mgr->lock); -+ -+ if (ctx) { -+ kref_put(&ctx->refcnt, lima_ctx_do_release); -+ return 0; -+ } -+ return -EINVAL; -+} -+ -+struct lima_ctx *lima_ctx_get(struct lima_ctx_mgr *mgr, u32 id) -+{ -+ struct lima_ctx *ctx; -+ -+ spin_lock(&mgr->lock); -+ ctx = idr_find(&mgr->handles, id); -+ if (ctx) -+ kref_get(&ctx->refcnt); -+ spin_unlock(&mgr->lock); -+ return ctx; -+} -+ -+void lima_ctx_put(struct lima_ctx *ctx) -+{ -+ kref_put(&ctx->refcnt, lima_ctx_do_release); -+} -+ -+void lima_ctx_mgr_init(struct lima_ctx_mgr *mgr) -+{ -+ spin_lock_init(&mgr->lock); -+ idr_init(&mgr->handles); -+} -+ -+void lima_ctx_mgr_fini(struct lima_ctx_mgr *mgr) -+{ -+ struct lima_ctx *ctx; -+ struct idr *idp; -+ uint32_t id; -+ -+ idp = &mgr->handles; -+ -+ idr_for_each_entry(idp, ctx, id) { -+ kref_put(&ctx->refcnt, lima_ctx_do_release); -+ } -+ -+ idr_destroy(&mgr->handles); -+} -+ -+struct dma_fence *lima_ctx_get_native_fence(struct lima_ctx_mgr *mgr, -+ u32 ctx, u32 pipe, u32 seq) -+{ -+ struct lima_ctx *c; -+ struct dma_fence *ret; -+ -+ if (pipe >= lima_pipe_num) -+ return ERR_PTR(-EINVAL); -+ -+ c = lima_ctx_get(mgr, ctx); -+ if (!c) -+ return ERR_PTR(-ENOENT); -+ -+ ret = lima_sched_context_get_fence(c->context + pipe, seq); -+ -+ lima_ctx_put(c); -+ return ret; -+} -diff --git a/drivers/gpu/drm/lima/lima_ctx.h b/drivers/gpu/drm/lima/lima_ctx.h -new file mode 100644 -index 000000000000..591f64532772 ---- /dev/null -+++ b/drivers/gpu/drm/lima/lima_ctx.h -@@ -0,0 +1,51 @@ -+/* -+ * Copyright (C) 2017-2018 Lima Project -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef __LIMA_CTX_H__ -+#define __LIMA_CTX_H__ -+ -+#include -+ -+#include "lima_device.h" -+ -+struct lima_ctx { -+ struct kref refcnt; -+ struct lima_device *dev; -+ struct lima_sched_context context[lima_pipe_num]; -+ atomic_t guilty; -+}; -+ -+struct lima_ctx_mgr { -+ spinlock_t lock; -+ struct idr handles; -+}; -+ -+int lima_ctx_create(struct lima_device *dev, struct lima_ctx_mgr *mgr, u32 *id); -+int lima_ctx_free(struct lima_ctx_mgr *mgr, u32 id); -+struct lima_ctx *lima_ctx_get(struct lima_ctx_mgr *mgr, u32 id); -+void lima_ctx_put(struct lima_ctx *ctx); -+void lima_ctx_mgr_init(struct lima_ctx_mgr *mgr); -+void lima_ctx_mgr_fini(struct lima_ctx_mgr *mgr); -+ -+struct dma_fence *lima_ctx_get_native_fence(struct lima_ctx_mgr *mgr, -+ u32 ctx, u32 pipe, u32 seq); -+ -+#endif --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0060-drm-lima-add-makefile-and-kconfig.patch b/patch/kernel/sunxi-legacy/0060-drm-lima-add-makefile-and-kconfig.patch deleted file mode 100644 index f77ea4d29..000000000 --- a/patch/kernel/sunxi-legacy/0060-drm-lima-add-makefile-and-kconfig.patch +++ /dev/null @@ -1,83 +0,0 @@ -From f7f324da0402ba4efe3656e68d573fb649fd60f5 Mon Sep 17 00:00:00 2001 -From: Lima Project Developers -Date: Wed, 16 May 2018 11:17:06 +0800 -Subject: [PATCH 060/146] drm/lima: add makefile and kconfig - -Signed-off-by: Qiang Yu -Signed-off-by: Neil Armstrong -Signed-off-by: Simon Shields -Signed-off-by: Heiko Stuebner ---- - drivers/gpu/drm/Kconfig | 2 ++ - drivers/gpu/drm/Makefile | 1 + - drivers/gpu/drm/lima/Kconfig | 9 +++++++++ - drivers/gpu/drm/lima/Makefile | 19 +++++++++++++++++++ - 4 files changed, 31 insertions(+) - create mode 100644 drivers/gpu/drm/lima/Kconfig - create mode 100644 drivers/gpu/drm/lima/Makefile - -diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig -index cb88528e7b10..145c093c3dec 100644 ---- a/drivers/gpu/drm/Kconfig -+++ b/drivers/gpu/drm/Kconfig -@@ -315,6 +315,8 @@ source "drivers/gpu/drm/tve200/Kconfig" - - source "drivers/gpu/drm/xen/Kconfig" - -+source "drivers/gpu/drm/lima/Kconfig" -+ - # Keep legacy drivers last - - menuconfig DRM_LEGACY -diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile -index a6771cef85e2..302b4c8e7cf0 100644 ---- a/drivers/gpu/drm/Makefile -+++ b/drivers/gpu/drm/Makefile -@@ -107,3 +107,4 @@ obj-$(CONFIG_DRM_TINYDRM) += tinydrm/ - obj-$(CONFIG_DRM_PL111) += pl111/ - obj-$(CONFIG_DRM_TVE200) += tve200/ - obj-$(CONFIG_DRM_XEN) += xen/ -+obj-$(CONFIG_DRM_LIMA) += lima/ -diff --git a/drivers/gpu/drm/lima/Kconfig b/drivers/gpu/drm/lima/Kconfig -new file mode 100644 -index 000000000000..4ce9ac2e8204 ---- /dev/null -+++ b/drivers/gpu/drm/lima/Kconfig -@@ -0,0 +1,9 @@ -+ -+config DRM_LIMA -+ tristate "LIMA (DRM support for ARM Mali 400/450 GPU)" -+ depends on DRM -+ depends on ARCH_SUNXI || ARCH_ROCKCHIP || ARCH_EXYNOS || ARCH_MESON -+ select DRM_SCHED -+ select DRM_TTM -+ help -+ DRM driver for ARM Mali 400/450 GPUs. -diff --git a/drivers/gpu/drm/lima/Makefile b/drivers/gpu/drm/lima/Makefile -new file mode 100644 -index 000000000000..0a1d6605f164 ---- /dev/null -+++ b/drivers/gpu/drm/lima/Makefile -@@ -0,0 +1,19 @@ -+lima-y := \ -+ lima_drv.o \ -+ lima_device.o \ -+ lima_pmu.o \ -+ lima_l2_cache.o \ -+ lima_mmu.o \ -+ lima_gp.o \ -+ lima_pp.o \ -+ lima_gem.o \ -+ lima_vm.o \ -+ lima_sched.o \ -+ lima_ctx.o \ -+ lima_gem_prime.o \ -+ lima_dlbu.o \ -+ lima_bcast.o \ -+ lima_ttm.o \ -+ lima_object.o -+ -+obj-$(CONFIG_DRM_LIMA) += lima.o --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0061-drm-lima-use-SPDX-identifiers-and-change-copyright.patch b/patch/kernel/sunxi-legacy/0061-drm-lima-use-SPDX-identifiers-and-change-copyright.patch deleted file mode 100644 index a413dca0e..000000000 --- a/patch/kernel/sunxi-legacy/0061-drm-lima-use-SPDX-identifiers-and-change-copyright.patch +++ /dev/null @@ -1,1115 +0,0 @@ -From ff22535cdf89a99b126778945fa5c952fdfe75fa Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Mon, 21 May 2018 18:00:43 +0800 -Subject: [PATCH 061/146] drm/lima: use SPDX identifiers and change copyright - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/Kconfig | 2 ++ - drivers/gpu/drm/lima/Makefile | 3 +++ - drivers/gpu/drm/lima/lima_bcast.c | 22 ++-------------------- - drivers/gpu/drm/lima/lima_bcast.h | 22 ++-------------------- - drivers/gpu/drm/lima/lima_ctx.c | 22 ++-------------------- - drivers/gpu/drm/lima/lima_ctx.h | 23 +++-------------------- - drivers/gpu/drm/lima/lima_device.c | 23 +++-------------------- - drivers/gpu/drm/lima/lima_device.h | 23 +++-------------------- - drivers/gpu/drm/lima/lima_dlbu.c | 22 ++-------------------- - drivers/gpu/drm/lima/lima_dlbu.h | 22 ++-------------------- - drivers/gpu/drm/lima/lima_drv.c | 22 ++-------------------- - drivers/gpu/drm/lima/lima_drv.h | 23 +++-------------------- - drivers/gpu/drm/lima/lima_gem.c | 22 ++-------------------- - drivers/gpu/drm/lima/lima_gem.h | 23 +++-------------------- - drivers/gpu/drm/lima/lima_gem_prime.c | 22 ++-------------------- - drivers/gpu/drm/lima/lima_gem_prime.h | 23 +++-------------------- - drivers/gpu/drm/lima/lima_gp.c | 22 ++-------------------- - drivers/gpu/drm/lima/lima_gp.h | 23 +++-------------------- - drivers/gpu/drm/lima/lima_l2_cache.c | 22 ++-------------------- - drivers/gpu/drm/lima/lima_l2_cache.h | 23 +++-------------------- - drivers/gpu/drm/lima/lima_mmu.c | 22 ++-------------------- - drivers/gpu/drm/lima/lima_mmu.h | 23 +++-------------------- - drivers/gpu/drm/lima/lima_object.c | 22 ++-------------------- - drivers/gpu/drm/lima/lima_object.h | 23 +++-------------------- - drivers/gpu/drm/lima/lima_pmu.c | 22 ++-------------------- - drivers/gpu/drm/lima/lima_pmu.h | 23 +++-------------------- - drivers/gpu/drm/lima/lima_pp.c | 22 ++-------------------- - drivers/gpu/drm/lima/lima_pp.h | 23 +++-------------------- - drivers/gpu/drm/lima/lima_regs.h | 16 +++------------- - drivers/gpu/drm/lima/lima_sched.c | 22 ++-------------------- - drivers/gpu/drm/lima/lima_sched.h | 23 +++-------------------- - drivers/gpu/drm/lima/lima_ttm.c | 22 ++-------------------- - drivers/gpu/drm/lima/lima_ttm.h | 23 +++-------------------- - drivers/gpu/drm/lima/lima_vm.c | 22 ++-------------------- - drivers/gpu/drm/lima/lima_vm.h | 23 +++-------------------- - include/uapi/drm/lima_drm.h | 23 +++-------------------- - 36 files changed, 90 insertions(+), 673 deletions(-) - -diff --git a/drivers/gpu/drm/lima/Kconfig b/drivers/gpu/drm/lima/Kconfig -index 4ce9ac2e8204..7256625aee04 100644 ---- a/drivers/gpu/drm/lima/Kconfig -+++ b/drivers/gpu/drm/lima/Kconfig -@@ -1,3 +1,5 @@ -+# Copyright 2017-2018 Qiang Yu -+# SPDX-License-Identifier: MIT - - config DRM_LIMA - tristate "LIMA (DRM support for ARM Mali 400/450 GPU)" -diff --git a/drivers/gpu/drm/lima/Makefile b/drivers/gpu/drm/lima/Makefile -index 0a1d6605f164..848310557e42 100644 ---- a/drivers/gpu/drm/lima/Makefile -+++ b/drivers/gpu/drm/lima/Makefile -@@ -1,3 +1,6 @@ -+# Copyright 2017-2018 Qiang Yu -+# SPDX-License-Identifier: MIT -+ - lima-y := \ - lima_drv.o \ - lima_device.o \ -diff --git a/drivers/gpu/drm/lima/lima_bcast.c b/drivers/gpu/drm/lima/lima_bcast.c -index 32012a61ea6a..0786336d3c77 100644 ---- a/drivers/gpu/drm/lima/lima_bcast.c -+++ b/drivers/gpu/drm/lima/lima_bcast.c -@@ -1,23 +1,5 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ - - #include -diff --git a/drivers/gpu/drm/lima/lima_bcast.h b/drivers/gpu/drm/lima/lima_bcast.h -index abafd4f613c7..f1ba32852742 100644 ---- a/drivers/gpu/drm/lima/lima_bcast.h -+++ b/drivers/gpu/drm/lima/lima_bcast.h -@@ -1,23 +1,5 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ - - #ifndef __LIMA_BCAST_H__ -diff --git a/drivers/gpu/drm/lima/lima_ctx.c b/drivers/gpu/drm/lima/lima_ctx.c -index 7243861760b4..3c8f0aba0169 100644 ---- a/drivers/gpu/drm/lima/lima_ctx.c -+++ b/drivers/gpu/drm/lima/lima_ctx.c -@@ -1,23 +1,5 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ - - #include -diff --git a/drivers/gpu/drm/lima/lima_ctx.h b/drivers/gpu/drm/lima/lima_ctx.h -index 591f64532772..f3bee2e1893a 100644 ---- a/drivers/gpu/drm/lima/lima_ctx.h -+++ b/drivers/gpu/drm/lima/lima_ctx.h -@@ -1,24 +1,7 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ -+ - #ifndef __LIMA_CTX_H__ - #define __LIMA_CTX_H__ - -diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c -index a6c3905a0c85..8611ed466a29 100644 ---- a/drivers/gpu/drm/lima/lima_device.c -+++ b/drivers/gpu/drm/lima/lima_device.c -@@ -1,24 +1,7 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ -+ - #include - #include - #include -diff --git a/drivers/gpu/drm/lima/lima_device.h b/drivers/gpu/drm/lima/lima_device.h -index 6c9c26b9e122..29501f8361d9 100644 ---- a/drivers/gpu/drm/lima/lima_device.h -+++ b/drivers/gpu/drm/lima/lima_device.h -@@ -1,24 +1,7 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ -+ - #ifndef __LIMA_DEVICE_H__ - #define __LIMA_DEVICE_H__ - -diff --git a/drivers/gpu/drm/lima/lima_dlbu.c b/drivers/gpu/drm/lima/lima_dlbu.c -index 5281dd3c0417..0b612149accb 100644 ---- a/drivers/gpu/drm/lima/lima_dlbu.c -+++ b/drivers/gpu/drm/lima/lima_dlbu.c -@@ -1,23 +1,5 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ - - #include -diff --git a/drivers/gpu/drm/lima/lima_dlbu.h b/drivers/gpu/drm/lima/lima_dlbu.h -index 4521a5dda9e0..bc441dccb1ba 100644 ---- a/drivers/gpu/drm/lima/lima_dlbu.h -+++ b/drivers/gpu/drm/lima/lima_dlbu.h -@@ -1,23 +1,5 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ - - #ifndef __LIMA_DLBU_H__ -diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c -index 4df24a6cfff3..7f2e47da6801 100644 ---- a/drivers/gpu/drm/lima/lima_drv.c -+++ b/drivers/gpu/drm/lima/lima_drv.c -@@ -1,23 +1,5 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ - - #include -diff --git a/drivers/gpu/drm/lima/lima_drv.h b/drivers/gpu/drm/lima/lima_drv.h -index 2f5f51da21db..d7dba79950d6 100644 ---- a/drivers/gpu/drm/lima/lima_drv.h -+++ b/drivers/gpu/drm/lima/lima_drv.h -@@ -1,24 +1,7 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ -+ - #ifndef __LIMA_DRV_H__ - #define __LIMA_DRV_H__ - -diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c -index 1ad3f38ddfde..d9c15acb7cf8 100644 ---- a/drivers/gpu/drm/lima/lima_gem.c -+++ b/drivers/gpu/drm/lima/lima_gem.c -@@ -1,23 +1,5 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ - - #include -diff --git a/drivers/gpu/drm/lima/lima_gem.h b/drivers/gpu/drm/lima/lima_gem.h -index 8e3c4110825d..35098b692b2e 100644 ---- a/drivers/gpu/drm/lima/lima_gem.h -+++ b/drivers/gpu/drm/lima/lima_gem.h -@@ -1,24 +1,7 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ -+ - #ifndef __LIMA_GEM_H__ - #define __LIMA_GEM_H__ - -diff --git a/drivers/gpu/drm/lima/lima_gem_prime.c b/drivers/gpu/drm/lima/lima_gem_prime.c -index 74da43a4378f..9a401a6a039b 100644 ---- a/drivers/gpu/drm/lima/lima_gem_prime.c -+++ b/drivers/gpu/drm/lima/lima_gem_prime.c -@@ -1,23 +1,5 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ - - #include -diff --git a/drivers/gpu/drm/lima/lima_gem_prime.h b/drivers/gpu/drm/lima/lima_gem_prime.h -index 023bf5ba2d7b..407482f1a7c0 100644 ---- a/drivers/gpu/drm/lima/lima_gem_prime.h -+++ b/drivers/gpu/drm/lima/lima_gem_prime.h -@@ -1,24 +1,7 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ -+ - #ifndef __LIMA_GEM_PRIME_H__ - #define __LIMA_GEM_PRIME_H__ - -diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c -index 8fb49986418a..280a40d857f4 100644 ---- a/drivers/gpu/drm/lima/lima_gp.c -+++ b/drivers/gpu/drm/lima/lima_gp.c -@@ -1,23 +1,5 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ - - #include -diff --git a/drivers/gpu/drm/lima/lima_gp.h b/drivers/gpu/drm/lima/lima_gp.h -index 8354911e50ce..45e654737767 100644 ---- a/drivers/gpu/drm/lima/lima_gp.h -+++ b/drivers/gpu/drm/lima/lima_gp.h -@@ -1,24 +1,7 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ -+ - #ifndef __LIMA_GP_H__ - #define __LIMA_GP_H__ - -diff --git a/drivers/gpu/drm/lima/lima_l2_cache.c b/drivers/gpu/drm/lima/lima_l2_cache.c -index a9b85de5c51a..25313ab5fe92 100644 ---- a/drivers/gpu/drm/lima/lima_l2_cache.c -+++ b/drivers/gpu/drm/lima/lima_l2_cache.c -@@ -1,23 +1,5 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ - - #include -diff --git a/drivers/gpu/drm/lima/lima_l2_cache.h b/drivers/gpu/drm/lima/lima_l2_cache.h -index 4a35725bf38d..6ecc07e33430 100644 ---- a/drivers/gpu/drm/lima/lima_l2_cache.h -+++ b/drivers/gpu/drm/lima/lima_l2_cache.h -@@ -1,24 +1,7 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ -+ - #ifndef __LIMA_L2_CACHE_H__ - #define __LIMA_L2_CACHE_H__ - -diff --git a/drivers/gpu/drm/lima/lima_mmu.c b/drivers/gpu/drm/lima/lima_mmu.c -index 22ac4db07849..7de3935b5cc6 100644 ---- a/drivers/gpu/drm/lima/lima_mmu.c -+++ b/drivers/gpu/drm/lima/lima_mmu.c -@@ -1,23 +1,5 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ - - #include -diff --git a/drivers/gpu/drm/lima/lima_mmu.h b/drivers/gpu/drm/lima/lima_mmu.h -index 9930521ddfa1..ac32f620e3d9 100644 ---- a/drivers/gpu/drm/lima/lima_mmu.h -+++ b/drivers/gpu/drm/lima/lima_mmu.h -@@ -1,24 +1,7 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ -+ - #ifndef __LIMA_MMU_H__ - #define __LIMA_MMU_H__ - -diff --git a/drivers/gpu/drm/lima/lima_object.c b/drivers/gpu/drm/lima/lima_object.c -index 5a22b235626b..6ca17ef2e701 100644 ---- a/drivers/gpu/drm/lima/lima_object.c -+++ b/drivers/gpu/drm/lima/lima_object.c -@@ -1,23 +1,5 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ - - #include -diff --git a/drivers/gpu/drm/lima/lima_object.h b/drivers/gpu/drm/lima/lima_object.h -index 2b8b8fcb9063..ae67de9d2565 100644 ---- a/drivers/gpu/drm/lima/lima_object.h -+++ b/drivers/gpu/drm/lima/lima_object.h -@@ -1,24 +1,7 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ -+ - #ifndef __LIMA_OBJECT_H__ - #define __LIMA_OBJECT_H__ - -diff --git a/drivers/gpu/drm/lima/lima_pmu.c b/drivers/gpu/drm/lima/lima_pmu.c -index 255a64e9f265..f4548c90b6b7 100644 ---- a/drivers/gpu/drm/lima/lima_pmu.c -+++ b/drivers/gpu/drm/lima/lima_pmu.c -@@ -1,23 +1,5 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ - - #include -diff --git a/drivers/gpu/drm/lima/lima_pmu.h b/drivers/gpu/drm/lima/lima_pmu.h -index fb68a7059a37..b807e9f42928 100644 ---- a/drivers/gpu/drm/lima/lima_pmu.h -+++ b/drivers/gpu/drm/lima/lima_pmu.h -@@ -1,24 +1,7 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ -+ - #ifndef __LIMA_PMU_H__ - #define __LIMA_PMU_H__ - -diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c -index 371d6b70c271..8db3d134e244 100644 ---- a/drivers/gpu/drm/lima/lima_pp.c -+++ b/drivers/gpu/drm/lima/lima_pp.c -@@ -1,23 +1,5 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ - - #include -diff --git a/drivers/gpu/drm/lima/lima_pp.h b/drivers/gpu/drm/lima/lima_pp.h -index 4bd1d9fcbcdf..b928f9516d30 100644 ---- a/drivers/gpu/drm/lima/lima_pp.h -+++ b/drivers/gpu/drm/lima/lima_pp.h -@@ -1,24 +1,7 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ -+ - #ifndef __LIMA_PP_H__ - #define __LIMA_PP_H__ - -diff --git a/drivers/gpu/drm/lima/lima_regs.h b/drivers/gpu/drm/lima/lima_regs.h -index ea4a37d69b98..0d8dced21633 100644 ---- a/drivers/gpu/drm/lima/lima_regs.h -+++ b/drivers/gpu/drm/lima/lima_regs.h -@@ -1,16 +1,6 @@ --/* -- * Copyright (C) 2010-2017 ARM Limited. All rights reserved. -- * Copyright (C) 2017-2018 Lima Project -- * -- * This program is free software and is provided to you under -- * the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation, and any use by -- * you of this program is subject to the terms of such GNU -- * licence. -- * -- * A copy of the licence is included with the program, and -- * can also be obtained from Free Software Foundation, Inc., -- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+/* Copyright 2010-2017 ARM Limited. All rights reserved. -+ * Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: GPL-2.0 - */ - - #ifndef __LIMA_REGS_H__ -diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c -index 190932955e9b..3b5ea2e4674d 100644 ---- a/drivers/gpu/drm/lima/lima_sched.c -+++ b/drivers/gpu/drm/lima/lima_sched.c -@@ -1,23 +1,5 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ - - #include -diff --git a/drivers/gpu/drm/lima/lima_sched.h b/drivers/gpu/drm/lima/lima_sched.h -index b93b7b4eded4..581b8601fe81 100644 ---- a/drivers/gpu/drm/lima/lima_sched.h -+++ b/drivers/gpu/drm/lima/lima_sched.h -@@ -1,24 +1,7 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ -+ - #ifndef __LIMA_SCHED_H__ - #define __LIMA_SCHED_H__ - -diff --git a/drivers/gpu/drm/lima/lima_ttm.c b/drivers/gpu/drm/lima/lima_ttm.c -index 5325f3f48ae7..4be441b02f6c 100644 ---- a/drivers/gpu/drm/lima/lima_ttm.c -+++ b/drivers/gpu/drm/lima/lima_ttm.c -@@ -1,23 +1,5 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ - - #include -diff --git a/drivers/gpu/drm/lima/lima_ttm.h b/drivers/gpu/drm/lima/lima_ttm.h -index 1d36d06a47a3..42af0b136ffb 100644 ---- a/drivers/gpu/drm/lima/lima_ttm.h -+++ b/drivers/gpu/drm/lima/lima_ttm.h -@@ -1,24 +1,7 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ -+ - #ifndef __LIMA_TTM_H__ - #define __LIMA_TTM_H__ - -diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c -index 00a3f6b59a33..11eb3c278df2 100644 ---- a/drivers/gpu/drm/lima/lima_vm.c -+++ b/drivers/gpu/drm/lima/lima_vm.c -@@ -1,23 +1,5 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ - - #include -diff --git a/drivers/gpu/drm/lima/lima_vm.h b/drivers/gpu/drm/lima/lima_vm.h -index 20506459def0..c891a1ee95df 100644 ---- a/drivers/gpu/drm/lima/lima_vm.h -+++ b/drivers/gpu/drm/lima/lima_vm.h -@@ -1,24 +1,7 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ -+ - #ifndef __LIMA_VM_H__ - #define __LIMA_VM_H__ - -diff --git a/include/uapi/drm/lima_drm.h b/include/uapi/drm/lima_drm.h -index 9df95e46fb2c..a489bba517c7 100644 ---- a/include/uapi/drm/lima_drm.h -+++ b/include/uapi/drm/lima_drm.h -@@ -1,24 +1,7 @@ --/* -- * Copyright (C) 2017-2018 Lima Project -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -+/* Copyright 2017-2018 Qiang Yu -+ * SPDX-License-Identifier: MIT - */ -+ - #ifndef __LIMA_DRM_H__ - #define __LIMA_DRM_H__ - --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0062-drm-lima-lima_reg.h-use-BIT.patch b/patch/kernel/sunxi-legacy/0062-drm-lima-lima_reg.h-use-BIT.patch deleted file mode 100644 index 84fc7ea12..000000000 --- a/patch/kernel/sunxi-legacy/0062-drm-lima-lima_reg.h-use-BIT.patch +++ /dev/null @@ -1,306 +0,0 @@ -From 7e7c821aec6eb45f26b40f3ec2f3d8408ec58300 Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Mon, 21 May 2018 18:47:02 +0800 -Subject: [PATCH 062/146] drm/lima: lima_reg.h use BIT() - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_regs.h | 238 +++++++++++++++---------------- - 1 file changed, 119 insertions(+), 119 deletions(-) - -diff --git a/drivers/gpu/drm/lima/lima_regs.h b/drivers/gpu/drm/lima/lima_regs.h -index 0d8dced21633..91ae9d6c197b 100644 ---- a/drivers/gpu/drm/lima/lima_regs.h -+++ b/drivers/gpu/drm/lima/lima_regs.h -@@ -9,9 +9,9 @@ - /* PMU regs */ - #define LIMA_PMU_POWER_UP 0x00 - #define LIMA_PMU_POWER_DOWN 0x04 --#define LIMA_PMU_POWER_GP0_MASK (1 << 0) --#define LIMA_PMU_POWER_L2_MASK (1 << 1) --#define LIMA_PMU_POWER_PP_MASK(i) (1 << (2 + i)) -+#define LIMA_PMU_POWER_GP0_MASK BIT(0) -+#define LIMA_PMU_POWER_L2_MASK BIT(1) -+#define LIMA_PMU_POWER_PP_MASK(i) BIT(2 + i) - - /* - * On Mali450 each block automatically starts up its corresponding L2 -@@ -26,25 +26,25 @@ - #define LIMA_PMU_INT_MASK 0x0C - #define LIMA_PMU_INT_RAWSTAT 0x10 - #define LIMA_PMU_INT_CLEAR 0x18 --#define LIMA_PMU_INT_CMD_MASK (1 << 0) -+#define LIMA_PMU_INT_CMD_MASK BIT(0) - #define LIMA_PMU_SW_DELAY 0x1C - - /* L2 cache regs */ --#define LIMA_L2_CACHE_SIZE 0x0004 --#define LIMA_L2_CACHE_STATUS 0x0008 --#define LIMA_L2_CACHE_STATUS_COMMAND_BUSY (1 << 0) --#define LIMA_L2_CACHE_STATUS_DATA_BUSY (1 << 1) --#define LIMA_L2_CACHE_COMMAND 0x0010 --#define LIMA_L2_CACHE_COMMAND_CLEAR_ALL (1 << 0) --#define LIMA_L2_CACHE_CLEAR_PAGE 0x0014 --#define LIMA_L2_CACHE_MAX_READS 0x0018 --#define LIMA_L2_CACHE_ENABLE 0x001C --#define LIMA_L2_CACHE_ENABLE_ACCESS (1 << 0) --#define LIMA_L2_CACHE_ENABLE_READ_ALLOCATE (1 << 1) --#define LIMA_L2_CACHE_PERFCNT_SRC0 0x0020 --#define LIMA_L2_CACHE_PERFCNT_VAL0 0x0024 --#define LIMA_L2_CACHE_PERFCNT_SRC1 0x0028 --#define LIMA_L2_CACHE_ERFCNT_VAL1 0x002C -+#define LIMA_L2_CACHE_SIZE 0x0004 -+#define LIMA_L2_CACHE_STATUS 0x0008 -+#define LIMA_L2_CACHE_STATUS_COMMAND_BUSY BIT(0) -+#define LIMA_L2_CACHE_STATUS_DATA_BUSY BIT(1) -+#define LIMA_L2_CACHE_COMMAND 0x0010 -+#define LIMA_L2_CACHE_COMMAND_CLEAR_ALL BIT(0) -+#define LIMA_L2_CACHE_CLEAR_PAGE 0x0014 -+#define LIMA_L2_CACHE_MAX_READS 0x0018 -+#define LIMA_L2_CACHE_ENABLE 0x001C -+#define LIMA_L2_CACHE_ENABLE_ACCESS BIT(0) -+#define LIMA_L2_CACHE_ENABLE_READ_ALLOCATE BIT(1) -+#define LIMA_L2_CACHE_PERFCNT_SRC0 0x0020 -+#define LIMA_L2_CACHE_PERFCNT_VAL0 0x0024 -+#define LIMA_L2_CACHE_PERFCNT_SRC1 0x0028 -+#define LIMA_L2_CACHE_ERFCNT_VAL1 0x002C - - /* GP regs */ - #define LIMA_GP_VSCL_START_ADDR 0x00 -@@ -54,36 +54,36 @@ - #define LIMA_GP_PLBU_ALLOC_START_ADDR 0x10 - #define LIMA_GP_PLBU_ALLOC_END_ADDR 0x14 - #define LIMA_GP_CMD 0x20 --#define LIMA_GP_CMD_START_VS (1 << 0) --#define LIMA_GP_CMD_START_PLBU (1 << 1) --#define LIMA_GP_CMD_UPDATE_PLBU_ALLOC (1 << 4) --#define LIMA_GP_CMD_RESET (1 << 5) --#define LIMA_GP_CMD_FORCE_HANG (1 << 6) --#define LIMA_GP_CMD_STOP_BUS (1 << 9) --#define LIMA_GP_CMD_SOFT_RESET (1 << 10) -+#define LIMA_GP_CMD_START_VS BIT(0) -+#define LIMA_GP_CMD_START_PLBU BIT(1) -+#define LIMA_GP_CMD_UPDATE_PLBU_ALLOC BIT(4) -+#define LIMA_GP_CMD_RESET BIT(5) -+#define LIMA_GP_CMD_FORCE_HANG BIT(6) -+#define LIMA_GP_CMD_STOP_BUS BIT(9) -+#define LIMA_GP_CMD_SOFT_RESET BIT(10) - #define LIMA_GP_INT_RAWSTAT 0x24 - #define LIMA_GP_INT_CLEAR 0x28 - #define LIMA_GP_INT_MASK 0x2C - #define LIMA_GP_INT_STAT 0x30 --#define LIMA_GP_IRQ_VS_END_CMD_LST (1 << 0) --#define LIMA_GP_IRQ_PLBU_END_CMD_LST (1 << 1) --#define LIMA_GP_IRQ_PLBU_OUT_OF_MEM (1 << 2) --#define LIMA_GP_IRQ_VS_SEM_IRQ (1 << 3) --#define LIMA_GP_IRQ_PLBU_SEM_IRQ (1 << 4) --#define LIMA_GP_IRQ_HANG (1 << 5) --#define LIMA_GP_IRQ_FORCE_HANG (1 << 6) --#define LIMA_GP_IRQ_PERF_CNT_0_LIMIT (1 << 7) --#define LIMA_GP_IRQ_PERF_CNT_1_LIMIT (1 << 8) --#define LIMA_GP_IRQ_WRITE_BOUND_ERR (1 << 9) --#define LIMA_GP_IRQ_SYNC_ERROR (1 << 10) --#define LIMA_GP_IRQ_AXI_BUS_ERROR (1 << 11) --#define LIMA_GP_IRQ_AXI_BUS_STOPPED (1 << 12) --#define LIMA_GP_IRQ_VS_INVALID_CMD (1 << 13) --#define LIMA_GP_IRQ_PLB_INVALID_CMD (1 << 14) --#define LIMA_GP_IRQ_RESET_COMPLETED (1 << 19) --#define LIMA_GP_IRQ_SEMAPHORE_UNDERFLOW (1 << 20) --#define LIMA_GP_IRQ_SEMAPHORE_OVERFLOW (1 << 21) --#define LIMA_GP_IRQ_PTR_ARRAY_OUT_OF_BOUNDS (1 << 22) -+#define LIMA_GP_IRQ_VS_END_CMD_LST BIT(0) -+#define LIMA_GP_IRQ_PLBU_END_CMD_LST BIT(1) -+#define LIMA_GP_IRQ_PLBU_OUT_OF_MEM BIT(2) -+#define LIMA_GP_IRQ_VS_SEM_IRQ BIT(3) -+#define LIMA_GP_IRQ_PLBU_SEM_IRQ BIT(4) -+#define LIMA_GP_IRQ_HANG BIT(5) -+#define LIMA_GP_IRQ_FORCE_HANG BIT(6) -+#define LIMA_GP_IRQ_PERF_CNT_0_LIMIT BIT(7) -+#define LIMA_GP_IRQ_PERF_CNT_1_LIMIT BIT(8) -+#define LIMA_GP_IRQ_WRITE_BOUND_ERR BIT(9) -+#define LIMA_GP_IRQ_SYNC_ERROR BIT(10) -+#define LIMA_GP_IRQ_AXI_BUS_ERROR BIT(11) -+#define LIMA_GP_IRQ_AXI_BUS_STOPPED BIT(12) -+#define LIMA_GP_IRQ_VS_INVALID_CMD BIT(13) -+#define LIMA_GP_IRQ_PLB_INVALID_CMD BIT(14) -+#define LIMA_GP_IRQ_RESET_COMPLETED BIT(19) -+#define LIMA_GP_IRQ_SEMAPHORE_UNDERFLOW BIT(20) -+#define LIMA_GP_IRQ_SEMAPHORE_OVERFLOW BIT(21) -+#define LIMA_GP_IRQ_PTR_ARRAY_OUT_OF_BOUNDS BIT(22) - #define LIMA_GP_WRITE_BOUND_LOW 0x34 - #define LIMA_GP_PERF_CNT_0_ENABLE 0x3C - #define LIMA_GP_PERF_CNT_1_ENABLE 0x40 -@@ -93,11 +93,11 @@ - #define LIMA_GP_PERF_CNT_1_VALUE 0x50 - #define LIMA_GP_PERF_CNT_0_LIMIT 0x54 - #define LIMA_GP_STATUS 0x68 --#define LIMA_GP_STATUS_VS_ACTIVE (1 << 1) --#define LIMA_GP_STATUS_BUS_STOPPED (1 << 2) --#define LIMA_GP_STATUS_PLBU_ACTIVE (1 << 3) --#define LIMA_GP_STATUS_BUS_ERROR (1 << 6) --#define LIMA_GP_STATUS_WRITE_BOUND_ERR (1 << 8) -+#define LIMA_GP_STATUS_VS_ACTIVE BIT(1) -+#define LIMA_GP_STATUS_BUS_STOPPED BIT(2) -+#define LIMA_GP_STATUS_PLBU_ACTIVE BIT(3) -+#define LIMA_GP_STATUS_BUS_ERROR BIT(6) -+#define LIMA_GP_STATUS_WRITE_BOUND_ERR BIT(8) - #define LIMA_GP_VERSION 0x6C - #define LIMA_GP_VSCL_START_ADDR_READ 0x80 - #define LIMA_GP_PLBCL_START_ADDR_READ 0x84 -@@ -156,42 +156,42 @@ - - #define LIMA_PP_VERSION 0x1000 - #define LIMA_PP_CURRENT_REND_LIST_ADDR 0x1004 --#define LIMA_PP_STATUS 0x1008 --#define LIMA_PP_STATUS_RENDERING_ACTIVE (1 << 0) --#define LIMA_PP_STATUS_BUS_STOPPED (1 << 4) --#define LIMA_PP_CTRL 0x100c --#define LIMA_PP_CTRL_STOP_BUS (1 << 0) --#define LIMA_PP_CTRL_FLUSH_CACHES (1 << 3) --#define LIMA_PP_CTRL_FORCE_RESET (1 << 5) --#define LIMA_PP_CTRL_START_RENDERING (1 << 6) --#define LIMA_PP_CTRL_SOFT_RESET (1 << 7) --#define LIMA_PP_INT_RAWSTAT 0x1020 --#define LIMA_PP_INT_CLEAR 0x1024 --#define LIMA_PP_INT_MASK 0x1028 --#define LIMA_PP_INT_STATUS 0x102c --#define LIMA_PP_IRQ_END_OF_FRAME (1 << 0) --#define LIMA_PP_IRQ_END_OF_TILE (1 << 1) --#define LIMA_PP_IRQ_HANG (1 << 2) --#define LIMA_PP_IRQ_FORCE_HANG (1 << 3) --#define LIMA_PP_IRQ_BUS_ERROR (1 << 4) --#define LIMA_PP_IRQ_BUS_STOP (1 << 5) --#define LIMA_PP_IRQ_CNT_0_LIMIT (1 << 6) --#define LIMA_PP_IRQ_CNT_1_LIMIT (1 << 7) --#define LIMA_PP_IRQ_WRITE_BOUNDARY_ERROR (1 << 8) --#define LIMA_PP_IRQ_INVALID_PLIST_COMMAND (1 << 9) --#define LIMA_PP_IRQ_CALL_STACK_UNDERFLOW (1 << 10) --#define LIMA_PP_IRQ_CALL_STACK_OVERFLOW (1 << 11) --#define LIMA_PP_IRQ_RESET_COMPLETED (1 << 12) --#define LIMA_PP_WRITE_BOUNDARY_LOW 0x1044 --#define LIMA_PP_BUS_ERROR_STATUS 0x1050 --#define LIMA_PP_PERF_CNT_0_ENABLE 0x1080 --#define LIMA_PP_PERF_CNT_0_SRC 0x1084 --#define LIMA_PP_PERF_CNT_0_LIMIT 0x1088 --#define LIMA_PP_PERF_CNT_0_VALUE 0x108c --#define LIMA_PP_PERF_CNT_1_ENABLE 0x10a0 --#define LIMA_PP_PERF_CNT_1_SRC 0x10a4 --#define LIMA_PP_PERF_CNT_1_LIMIT 0x10a8 --#define LIMA_PP_PERF_CNT_1_VALUE 0x10ac -+#define LIMA_PP_STATUS 0x1008 -+#define LIMA_PP_STATUS_RENDERING_ACTIVE BIT(0) -+#define LIMA_PP_STATUS_BUS_STOPPED BIT(4) -+#define LIMA_PP_CTRL 0x100c -+#define LIMA_PP_CTRL_STOP_BUS BIT(0) -+#define LIMA_PP_CTRL_FLUSH_CACHES BIT(3) -+#define LIMA_PP_CTRL_FORCE_RESET BIT(5) -+#define LIMA_PP_CTRL_START_RENDERING BIT(6) -+#define LIMA_PP_CTRL_SOFT_RESET BIT(7) -+#define LIMA_PP_INT_RAWSTAT 0x1020 -+#define LIMA_PP_INT_CLEAR 0x1024 -+#define LIMA_PP_INT_MASK 0x1028 -+#define LIMA_PP_INT_STATUS 0x102c -+#define LIMA_PP_IRQ_END_OF_FRAME BIT(0) -+#define LIMA_PP_IRQ_END_OF_TILE BIT(1) -+#define LIMA_PP_IRQ_HANG BIT(2) -+#define LIMA_PP_IRQ_FORCE_HANG BIT(3) -+#define LIMA_PP_IRQ_BUS_ERROR BIT(4) -+#define LIMA_PP_IRQ_BUS_STOP BIT(5) -+#define LIMA_PP_IRQ_CNT_0_LIMIT BIT(6) -+#define LIMA_PP_IRQ_CNT_1_LIMIT BIT(7) -+#define LIMA_PP_IRQ_WRITE_BOUNDARY_ERROR BIT(8) -+#define LIMA_PP_IRQ_INVALID_PLIST_COMMAND BIT(9) -+#define LIMA_PP_IRQ_CALL_STACK_UNDERFLOW BIT(10) -+#define LIMA_PP_IRQ_CALL_STACK_OVERFLOW BIT(11) -+#define LIMA_PP_IRQ_RESET_COMPLETED BIT(12) -+#define LIMA_PP_WRITE_BOUNDARY_LOW 0x1044 -+#define LIMA_PP_BUS_ERROR_STATUS 0x1050 -+#define LIMA_PP_PERF_CNT_0_ENABLE 0x1080 -+#define LIMA_PP_PERF_CNT_0_SRC 0x1084 -+#define LIMA_PP_PERF_CNT_0_LIMIT 0x1088 -+#define LIMA_PP_PERF_CNT_0_VALUE 0x108c -+#define LIMA_PP_PERF_CNT_1_ENABLE 0x10a0 -+#define LIMA_PP_PERF_CNT_1_SRC 0x10a4 -+#define LIMA_PP_PERF_CNT_1_LIMIT 0x10a8 -+#define LIMA_PP_PERF_CNT_1_VALUE 0x10ac - #define LIMA_PP_PERFMON_CONTR 0x10b0 - #define LIMA_PP_PERFMON_BASE 0x10b4 - -@@ -226,41 +226,41 @@ - LIMA_PP_IRQ_MASK_ERROR) - - /* MMU regs */ --#define LIMA_MMU_DTE_ADDR 0x0000 --#define LIMA_MMU_STATUS 0x0004 --#define LIMA_MMU_STATUS_PAGING_ENABLED (1 << 0) --#define LIMA_MMU_STATUS_PAGE_FAULT_ACTIVE (1 << 1) --#define LIMA_MMU_STATUS_STALL_ACTIVE (1 << 2) --#define LIMA_MMU_STATUS_IDLE (1 << 3) --#define LIMA_MMU_STATUS_REPLAY_BUFFER_EMPTY (1 << 4) --#define LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE (1 << 5) -+#define LIMA_MMU_DTE_ADDR 0x0000 -+#define LIMA_MMU_STATUS 0x0004 -+#define LIMA_MMU_STATUS_PAGING_ENABLED BIT(0) -+#define LIMA_MMU_STATUS_PAGE_FAULT_ACTIVE BIT(1) -+#define LIMA_MMU_STATUS_STALL_ACTIVE BIT(2) -+#define LIMA_MMU_STATUS_IDLE BIT(3) -+#define LIMA_MMU_STATUS_REPLAY_BUFFER_EMPTY BIT(4) -+#define LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE BIT(5) - #define LIMA_MMU_STATUS_BUS_ID(x) ((x >> 6) & 0x1F) --#define LIMA_MMU_COMMAND 0x0008 --#define LIMA_MMU_COMMAND_ENABLE_PAGING 0x00 --#define LIMA_MMU_COMMAND_DISABLE_PAGING 0x01 --#define LIMA_MMU_COMMAND_ENABLE_STALL 0x02 --#define LIMA_MMU_COMMAND_DISABLE_STALL 0x03 --#define LIMA_MMU_COMMAND_ZAP_CACHE 0x04 --#define LIMA_MMU_COMMAND_PAGE_FAULT_DONE 0x05 --#define LIMA_MMU_COMMAND_HARD_RESET 0x06 --#define LIMA_MMU_PAGE_FAULT_ADDR 0x000C --#define LIMA_MMU_ZAP_ONE_LINE 0x0010 --#define LIMA_MMU_INT_RAWSTAT 0x0014 --#define LIMA_MMU_INT_CLEAR 0x0018 --#define LIMA_MMU_INT_MASK 0x001C --#define LIMA_MMU_INT_PAGE_FAULT 0x01 --#define LIMA_MMU_INT_READ_BUS_ERROR 0x02 --#define LIMA_MMU_INT_STATUS 0x0020 -+#define LIMA_MMU_COMMAND 0x0008 -+#define LIMA_MMU_COMMAND_ENABLE_PAGING 0x00 -+#define LIMA_MMU_COMMAND_DISABLE_PAGING 0x01 -+#define LIMA_MMU_COMMAND_ENABLE_STALL 0x02 -+#define LIMA_MMU_COMMAND_DISABLE_STALL 0x03 -+#define LIMA_MMU_COMMAND_ZAP_CACHE 0x04 -+#define LIMA_MMU_COMMAND_PAGE_FAULT_DONE 0x05 -+#define LIMA_MMU_COMMAND_HARD_RESET 0x06 -+#define LIMA_MMU_PAGE_FAULT_ADDR 0x000C -+#define LIMA_MMU_ZAP_ONE_LINE 0x0010 -+#define LIMA_MMU_INT_RAWSTAT 0x0014 -+#define LIMA_MMU_INT_CLEAR 0x0018 -+#define LIMA_MMU_INT_MASK 0x001C -+#define LIMA_MMU_INT_PAGE_FAULT BIT(0) -+#define LIMA_MMU_INT_READ_BUS_ERROR BIT(1) -+#define LIMA_MMU_INT_STATUS 0x0020 - --#define LIMA_VM_FLAG_PRESENT (1 << 0) --#define LIMA_VM_FLAG_READ_PERMISSION (1 << 1) --#define LIMA_VM_FLAG_WRITE_PERMISSION (1 << 2) --#define LIMA_VM_FLAG_OVERRIDE_CACHE (1 << 3) --#define LIMA_VM_FLAG_WRITE_CACHEABLE (1 << 4) --#define LIMA_VM_FLAG_WRITE_ALLOCATE (1 << 5) --#define LIMA_VM_FLAG_WRITE_BUFFERABLE (1 << 6) --#define LIMA_VM_FLAG_READ_CACHEABLE (1 << 7) --#define LIMA_VM_FLAG_READ_ALLOCATE (1 << 8) -+#define LIMA_VM_FLAG_PRESENT BIT(0) -+#define LIMA_VM_FLAG_READ_PERMISSION BIT(1) -+#define LIMA_VM_FLAG_WRITE_PERMISSION BIT(2) -+#define LIMA_VM_FLAG_OVERRIDE_CACHE BIT(3) -+#define LIMA_VM_FLAG_WRITE_CACHEABLE BIT(4) -+#define LIMA_VM_FLAG_WRITE_ALLOCATE BIT(5) -+#define LIMA_VM_FLAG_WRITE_BUFFERABLE BIT(6) -+#define LIMA_VM_FLAG_READ_CACHEABLE BIT(7) -+#define LIMA_VM_FLAG_READ_ALLOCATE BIT(8) - #define LIMA_VM_FLAG_MASK 0x1FF - - #define LIMA_VM_FLAGS_CACHE ( \ --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0063-drm-lima-add-IRQF_SHARED-for-GP-irq.patch b/patch/kernel/sunxi-legacy/0063-drm-lima-add-IRQF_SHARED-for-GP-irq.patch deleted file mode 100644 index 6ed612c6c..000000000 --- a/patch/kernel/sunxi-legacy/0063-drm-lima-add-IRQF_SHARED-for-GP-irq.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 9d7b31732a23ae2f07df1276b7d94cff59d7f0f6 Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Thu, 24 May 2018 08:36:21 +0800 -Subject: [PATCH 063/146] drm/lima: add IRQF_SHARED for GP irq - -On some platform all IRQs of GPU share the same line. - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_gp.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c -index 280a40d857f4..10d7ee16a1d5 100644 ---- a/drivers/gpu/drm/lima/lima_gp.c -+++ b/drivers/gpu/drm/lima/lima_gp.c -@@ -224,8 +224,8 @@ int lima_gp_init(struct lima_ip *ip) - if (err) - return err; - -- err = devm_request_irq(dev->dev, ip->irq, lima_gp_irq_handler, 0, -- lima_ip_name(ip), ip); -+ err = devm_request_irq(dev->dev, ip->irq, lima_gp_irq_handler, -+ IRQF_SHARED, lima_ip_name(ip), ip); - if (err) { - dev_err(dev->dev, "gp %s fail to request irq\n", - lima_ip_name(ip)); --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0064-drm-lima-Kconfig-only-depend-on-ARM-or-ARM64.patch b/patch/kernel/sunxi-legacy/0064-drm-lima-Kconfig-only-depend-on-ARM-or-ARM64.patch deleted file mode 100644 index 060c6b3a5..000000000 --- a/patch/kernel/sunxi-legacy/0064-drm-lima-Kconfig-only-depend-on-ARM-or-ARM64.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 6d3f37068bbfac21355642148a182c125eb28d19 Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Thu, 24 May 2018 14:22:03 +0800 -Subject: [PATCH 064/146] drm/lima: Kconfig only depend on ARM or ARM64 - -The depend list gets longer and longer. When adding -ARCH_ZYNQMP I decide to just depend on ARM or ARM64 -as this GPU can be seen on many ARM SoCs. - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/lima/Kconfig b/drivers/gpu/drm/lima/Kconfig -index 7256625aee04..870f66f407b8 100644 ---- a/drivers/gpu/drm/lima/Kconfig -+++ b/drivers/gpu/drm/lima/Kconfig -@@ -4,7 +4,7 @@ - config DRM_LIMA - tristate "LIMA (DRM support for ARM Mali 400/450 GPU)" - depends on DRM -- depends on ARCH_SUNXI || ARCH_ROCKCHIP || ARCH_EXYNOS || ARCH_MESON -+ depends on ARM || ARM64 || COMPILE_TEST - select DRM_SCHED - select DRM_TTM - help --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0065-drm-lima-add-comments-for-lima_reg.h.patch b/patch/kernel/sunxi-legacy/0065-drm-lima-add-comments-for-lima_reg.h.patch deleted file mode 100644 index 61e4e54ab..000000000 --- a/patch/kernel/sunxi-legacy/0065-drm-lima-add-comments-for-lima_reg.h.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 27a1223c73a19b993d0b0a45d0908fc0d76fae0d Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Thu, 24 May 2018 14:33:36 +0800 -Subject: [PATCH 065/146] drm/lima: add comments for lima_reg.h - -This file is based on official ARM Mali Utgard GPU -kernel driver. - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_regs.h | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/gpu/drm/lima/lima_regs.h b/drivers/gpu/drm/lima/lima_regs.h -index 91ae9d6c197b..d8c762c17e52 100644 ---- a/drivers/gpu/drm/lima/lima_regs.h -+++ b/drivers/gpu/drm/lima/lima_regs.h -@@ -6,6 +6,10 @@ - #ifndef __LIMA_REGS_H__ - #define __LIMA_REGS_H__ - -+/* This file's register definition is collected from the -+ * official ARM Mali Utgard GPU kernel driver source code -+ */ -+ - /* PMU regs */ - #define LIMA_PMU_POWER_UP 0x00 - #define LIMA_PMU_POWER_DOWN 0x04 --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0066-drm-lima-wait-bo-fence-before-bo-close.patch b/patch/kernel/sunxi-legacy/0066-drm-lima-wait-bo-fence-before-bo-close.patch deleted file mode 100644 index 0a7fb0c33..000000000 --- a/patch/kernel/sunxi-legacy/0066-drm-lima-wait-bo-fence-before-bo-close.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 4402e0d7858450f531f38aa7766233b4b8c8e1bb Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Mon, 28 May 2018 17:36:59 +0800 -Subject: [PATCH 066/146] drm/lima: wait bo fence before bo close - -We can't bring preclose back, so use this -method for user application termination. - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_drv.c | 9 +-------- - drivers/gpu/drm/lima/lima_sched.c | 2 +- - drivers/gpu/drm/lima/lima_vm.c | 32 +++++++++++++++++++++++++++++++ - 3 files changed, 34 insertions(+), 9 deletions(-) - -diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c -index 7f2e47da6801..d3ab9f7abb93 100644 ---- a/drivers/gpu/drm/lima/lima_drv.c -+++ b/drivers/gpu/drm/lima/lima_drv.c -@@ -270,17 +270,11 @@ static int lima_drm_driver_open(struct drm_device *dev, struct drm_file *file) - return err; - } - --static void lima_drm_driver_preclose(struct drm_device *dev, struct drm_file *file) --{ -- struct lima_drm_priv *priv = file->driver_priv; -- -- lima_ctx_mgr_fini(&priv->ctx_mgr); --} -- - static void lima_drm_driver_postclose(struct drm_device *dev, struct drm_file *file) - { - struct lima_drm_priv *priv = file->driver_priv; - -+ lima_ctx_mgr_fini(&priv->ctx_mgr); - lima_vm_put(priv->vm); - kfree(priv); - } -@@ -310,7 +304,6 @@ static const struct file_operations lima_drm_driver_fops = { - static struct drm_driver lima_drm_driver = { - .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_PRIME, - .open = lima_drm_driver_open, -- .preclose = lima_drm_driver_preclose, - .postclose = lima_drm_driver_postclose, - .ioctls = lima_drm_driver_ioctls, - .num_ioctls = ARRAY_SIZE(lima_drm_driver_ioctls), -diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c -index 3b5ea2e4674d..89e758718d62 100644 ---- a/drivers/gpu/drm/lima/lima_sched.c -+++ b/drivers/gpu/drm/lima/lima_sched.c -@@ -112,7 +112,7 @@ int lima_sched_task_init(struct lima_sched_task *task, - int err; - - err = drm_sched_job_init(&task->base, context->base.sched, -- &context->base, context); -+ &context->base, vm); - if (err) - return err; - -diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c -index 11eb3c278df2..19a683c2921b 100644 ---- a/drivers/gpu/drm/lima/lima_vm.c -+++ b/drivers/gpu/drm/lima/lima_vm.c -@@ -195,15 +195,47 @@ int lima_vm_bo_add(struct lima_vm *vm, struct lima_bo *bo) - return 0; - } - -+/* wait only fence of resv from task using vm */ -+static int lima_vm_wait_resv(struct lima_vm *vm, -+ struct reservation_object *resv) -+{ -+ unsigned nr_fences; -+ struct dma_fence **fences; -+ int i; -+ long err; -+ -+ err = reservation_object_get_fences_rcu(resv, NULL, &nr_fences, &fences); -+ if (err || !nr_fences) -+ return err; -+ -+ for (i = 0; i < nr_fences; i++) { -+ struct drm_sched_fence *sf = to_drm_sched_fence(fences[i]); -+ if (sf && sf->owner == vm) -+ err |= dma_fence_wait(fences[i], false); -+ dma_fence_put(fences[i]); -+ } -+ -+ kfree(fences); -+ return err; -+} -+ - int lima_vm_bo_del(struct lima_vm *vm, struct lima_bo *bo) - { - struct lima_bo_va *bo_va; - struct lima_bo_va_mapping *mapping, *tmp; -+ int err; - - bo_va = lima_vm_bo_find(vm, bo); - if (--bo_va->ref_count > 0) - return 0; - -+ /* wait bo idle before unmap it from vm in case user -+ * space application is terminated when bo is busy. -+ */ -+ err = lima_vm_wait_resv(vm, bo->tbo.resv); -+ if (err) -+ dev_err(vm->dev->dev, "bo del fail to wait (%d)\n", err); -+ - list_for_each_entry_safe(mapping, tmp, &bo_va->mapping, list) { - lima_vm_unmap(vm, mapping); - } --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0067-drm-lima-refine-lima_gem_sync_bo.patch b/patch/kernel/sunxi-legacy/0067-drm-lima-refine-lima_gem_sync_bo.patch deleted file mode 100644 index 79d8a4f85..000000000 --- a/patch/kernel/sunxi-legacy/0067-drm-lima-refine-lima_gem_sync_bo.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 5c2d27d3a2b35475ea707b14a41e5c557c9ebad2 Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Mon, 28 May 2018 18:55:39 +0800 -Subject: [PATCH 067/146] drm/lima: refine lima_gem_sync_bo - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_gem.c | 58 +++++++++++++++++-------------- - drivers/gpu/drm/lima/lima_sched.c | 5 ++- - 2 files changed, 36 insertions(+), 27 deletions(-) - -diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c -index d9c15acb7cf8..3bdff19eb2f9 100644 ---- a/drivers/gpu/drm/lima/lima_gem.c -+++ b/drivers/gpu/drm/lima/lima_gem.c -@@ -217,9 +217,7 @@ int lima_gem_va_unmap(struct drm_file *file, u32 handle, u32 va) - static int lima_gem_sync_bo(struct lima_sched_task *task, struct lima_bo *bo, - bool write, bool explicit) - { -- int i, err; -- struct dma_fence *f; -- u64 context = task->base.s_fence->finished.context; -+ int err = 0; - - if (!write) { - err = reservation_object_reserve_shared(bo->tbo.resv); -@@ -233,31 +231,38 @@ static int lima_gem_sync_bo(struct lima_sched_task *task, struct lima_bo *bo, - - /* implicit sync use bo fence in resv obj */ - if (write) { -- struct reservation_object_list *fobj = -- reservation_object_get_list(bo->tbo.resv); -- -- if (fobj && fobj->shared_count > 0) { -- for (i = 0; i < fobj->shared_count; i++) { -- f = rcu_dereference_protected( -- fobj->shared[i], -- reservation_object_held(bo->tbo.resv)); -- if (f->context != context) { -- err = lima_sched_task_add_dep(task, f); -- if (err) -- return err; -- } -- } -- } -- } -+ unsigned nr_fences; -+ struct dma_fence **fences; -+ int i; - -- f = reservation_object_get_excl(bo->tbo.resv); -- if (f) { -- err = lima_sched_task_add_dep(task, f); -- if (err) -+ err = reservation_object_get_fences_rcu( -+ bo->tbo.resv, NULL, &nr_fences, &fences); -+ if (err || !nr_fences) - return err; -+ -+ for (i = 0; i < nr_fences; i++) { -+ err = lima_sched_task_add_dep(task, fences[i]); -+ if (err) -+ break; -+ } -+ -+ /* for error case free remaining fences */ -+ for ( ; i < nr_fences; i++) -+ dma_fence_put(fences[i]); -+ -+ kfree(fences); -+ } -+ else { -+ struct dma_fence *fence; -+ fence = reservation_object_get_excl_rcu(bo->tbo.resv); -+ if (fence) { -+ err = lima_sched_task_add_dep(task, fence); -+ if (err) -+ dma_fence_put(fence); -+ } - } - -- return 0; -+ return err; - } - - static int lima_gem_add_deps(struct lima_ctx_mgr *mgr, struct lima_submit *submit) -@@ -291,9 +296,10 @@ static int lima_gem_add_deps(struct lima_ctx_mgr *mgr, struct lima_submit *submi - - if (fence) { - err = lima_sched_task_add_dep(submit->task, fence); -- dma_fence_put(fence); -- if (err) -+ if (err) { -+ dma_fence_put(fence); - break; -+ } - } - } - -diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c -index 89e758718d62..91ec00811071 100644 ---- a/drivers/gpu/drm/lima/lima_sched.c -+++ b/drivers/gpu/drm/lima/lima_sched.c -@@ -130,6 +130,10 @@ int lima_sched_task_add_dep(struct lima_sched_task *task, struct dma_fence *fenc - { - int i, new_dep = 4; - -+ /* same context's fence is definitly earlier then this task */ -+ if (fence->context == task->base.s_fence->finished.context) -+ return 0; -+ - if (task->dep && task->num_dep == task->max_dep) - new_dep = task->max_dep * 2; - -@@ -141,7 +145,6 @@ int lima_sched_task_add_dep(struct lima_sched_task *task, struct dma_fence *fenc - task->dep = dep; - } - -- dma_fence_get(fence); - for (i = 0; i < task->num_dep; i++) { - if (task->dep[i]->context == fence->context && - dma_fence_is_later(fence, task->dep[i])) { --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0068-drm-lima-vm-will-be-freed-when-lima_sched_free_job.patch b/patch/kernel/sunxi-legacy/0068-drm-lima-vm-will-be-freed-when-lima_sched_free_job.patch deleted file mode 100644 index 09eb6d614..000000000 --- a/patch/kernel/sunxi-legacy/0068-drm-lima-vm-will-be-freed-when-lima_sched_free_job.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 2d89860b45cc744356186504b9880c361c158476 Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Mon, 28 May 2018 19:01:48 +0800 -Subject: [PATCH 068/146] drm/lima: vm will be freed when lima_sched_free_job - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_sched.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c -index 91ec00811071..20ed966578a3 100644 ---- a/drivers/gpu/drm/lima/lima_sched.c -+++ b/drivers/gpu/drm/lima/lima_sched.c -@@ -123,7 +123,6 @@ int lima_sched_task_init(struct lima_sched_task *task, - void lima_sched_task_fini(struct lima_sched_task *task) - { - dma_fence_put(&task->base.s_fence->finished); -- lima_vm_put(task->vm); - } - - int lima_sched_task_add_dep(struct lima_sched_task *task, struct dma_fence *fence) --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0069-drm-lima-vm-alloc-buffer-with-multi-page-table.patch b/patch/kernel/sunxi-legacy/0069-drm-lima-vm-alloc-buffer-with-multi-page-table.patch deleted file mode 100644 index 7144c2ed4..000000000 --- a/patch/kernel/sunxi-legacy/0069-drm-lima-vm-alloc-buffer-with-multi-page-table.patch +++ /dev/null @@ -1,189 +0,0 @@ -From 063d7ebf17304fe8a7b85ecb4662f20c4839b6af Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Wed, 30 May 2018 19:18:03 +0800 -Subject: [PATCH 069/146] drm/lima: vm alloc buffer with multi page table - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_vm.c | 95 ++++++++++++++++++++++------------ - drivers/gpu/drm/lima/lima_vm.h | 6 ++- - 2 files changed, 66 insertions(+), 35 deletions(-) - -diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c -index 19a683c2921b..ab7438685234 100644 ---- a/drivers/gpu/drm/lima/lima_vm.c -+++ b/drivers/gpu/drm/lima/lima_vm.c -@@ -28,8 +28,18 @@ struct lima_bo_va { - struct lima_vm *vm; - }; - --#define LIMA_PDE(va) (va >> 22) --#define LIMA_PTE(va) ((va & 0x3FFFFF) >> 12) -+#define LIMA_VM_PD_SHIFT 22 -+#define LIMA_VM_PT_SHIFT 12 -+#define LIMA_VM_PB_SHIFT (LIMA_VM_PD_SHIFT + LIMA_VM_NUM_PT_PER_BT_SHIFT) -+#define LIMA_VM_BT_SHIFT LIMA_VM_PT_SHIFT -+ -+#define LIMA_VM_PT_MASK ((1 << LIMA_VM_PD_SHIFT) - 1) -+#define LIMA_VM_BT_MASK ((1 << LIMA_VM_PB_SHIFT) - 1) -+ -+#define LIMA_PDE(va) (va >> LIMA_VM_PD_SHIFT) -+#define LIMA_PTE(va) ((va & LIMA_VM_PT_MASK) >> LIMA_VM_PT_SHIFT) -+#define LIMA_PBE(va) (va >> LIMA_VM_PB_SHIFT) -+#define LIMA_BTE(va) ((va & LIMA_VM_BT_MASK) >> LIMA_VM_BT_SHIFT) - - #define START(node) ((node)->start) - #define LAST(node) ((node)->last) -@@ -45,12 +55,12 @@ static void lima_vm_unmap_page_table(struct lima_vm *vm, u32 start, u32 end) - u32 addr; - - for (addr = start; addr <= end; addr += LIMA_PAGE_SIZE) { -- u32 pde = LIMA_PDE(addr); -- u32 pte = LIMA_PTE(addr); -- u32 *pt; -+ u32 pbe = LIMA_PBE(addr); -+ u32 bte = LIMA_BTE(addr); -+ u32 *bt; - -- pt = lima_bo_kmap(vm->pt[pde]); -- pt[pte] = 0; -+ bt = lima_bo_kmap(vm->bts[pbe]); -+ bt[bte] = 0; - } - } - -@@ -61,32 +71,43 @@ static int lima_vm_map_page_table(struct lima_vm *vm, dma_addr_t *dma, - int err, i = 0; - - for (addr = start; addr <= end; addr += LIMA_PAGE_SIZE) { -- u32 pde = LIMA_PDE(addr); -- u32 pte = LIMA_PTE(addr); -- u32 *pd, *pt; -+ u32 pbe = LIMA_PBE(addr); -+ u32 bte = LIMA_BTE(addr); -+ u32 *bt; - -- if (vm->pt[pde]) -- pt = lima_bo_kmap(vm->pt[pde]); -+ if (vm->bts[pbe]) -+ bt = lima_bo_kmap(vm->bts[pbe]); - else { -- vm->pt[pde] = lima_bo_create( -- vm->dev, LIMA_PAGE_SIZE, 0, ttm_bo_type_kernel, -+ struct lima_bo *bt_bo; -+ dma_addr_t *pts; -+ u32 *pd; -+ int j; -+ -+ bt_bo = lima_bo_create( -+ vm->dev, LIMA_PAGE_SIZE << LIMA_VM_NUM_PT_PER_BT_SHIFT, -+ 0, ttm_bo_type_kernel, - NULL, vm->pd->tbo.resv); -- if (IS_ERR(vm->pt[pde])) { -- err = PTR_ERR(vm->pt[pde]); -+ if (IS_ERR(bt_bo)) { -+ err = PTR_ERR(bt_bo); - goto err_out; - } - -- pt = lima_bo_kmap(vm->pt[pde]); -- if (IS_ERR(pt)) { -- err = PTR_ERR(pt); -+ bt = lima_bo_kmap(bt_bo); -+ if (IS_ERR(bt)) { -+ lima_bo_unref(bt_bo); -+ err = PTR_ERR(bt); - goto err_out; - } - -+ vm->bts[pbe] = bt_bo; - pd = lima_bo_kmap(vm->pd); -- pd[pde] = *lima_bo_get_pages(vm->pt[pde]) | LIMA_VM_FLAG_PRESENT; -+ pd += pbe << LIMA_VM_NUM_PT_PER_BT_SHIFT; -+ pts = lima_bo_get_pages(bt_bo); -+ for (j = 0; j < LIMA_VM_NUM_PT_PER_BT; j++) -+ *pd++ = *pts++ | LIMA_VM_FLAG_PRESENT; - } - -- pt[pte] = dma[i++] | LIMA_VM_FLAGS_CACHE; -+ bt[bte] = dma[i++] | LIMA_VM_FLAGS_CACHE; - } - - return 0; -@@ -293,9 +314,9 @@ void lima_vm_release(struct kref *kref) - dev_err(dev->dev, "still active bo inside vm\n"); - } - -- for (i = 0; i < LIMA_PAGE_ENT_NUM; i++) { -- if (vm->pt[i]) -- lima_bo_unref(vm->pt[i]); -+ for (i = 0; i < LIMA_VM_NUM_BT; i++) { -+ if (vm->bts[i]) -+ lima_bo_unref(vm->bts[i]); - } - - if (vm->pd) -@@ -306,20 +327,26 @@ void lima_vm_release(struct kref *kref) - - void lima_vm_print(struct lima_vm *vm) - { -- int i, j; -- u32 *pd = lima_bo_kmap(vm->pd); -+ int i, j, k; -+ u32 *pd, *pt; - - /* to avoid the defined by not used warning */ - (void)&lima_vm_it_iter_next; - -- for (i = 0; i < LIMA_PAGE_ENT_NUM; i++) { -- if (pd[i]) { -- u32 *pt = lima_bo_kmap(vm->pt[i]); -- -- printk(KERN_INFO "lima vm pd %03x:%08x\n", i, pd[i]); -- for (j = 0; j < LIMA_PAGE_ENT_NUM; j++) { -- if (pt[j]) -- printk(KERN_INFO " pt %03x:%08x\n", j, pt[j]); -+ pd = lima_bo_kmap(vm->pd); -+ for (i = 0; i < LIMA_VM_NUM_BT; i++) { -+ if (!vm->bts[i]) -+ continue; -+ -+ pt = lima_bo_kmap(vm->bts[i]); -+ for (j = 0; j < LIMA_VM_NUM_PT_PER_BT; j++) { -+ int idx = (i << LIMA_VM_NUM_PT_PER_BT_SHIFT) + j; -+ printk(KERN_INFO "lima vm pd %03x:%08x\n", idx, pd[idx]); -+ -+ for (k = 0; k < LIMA_PAGE_ENT_NUM; k++) { -+ u32 pte = *pt++; -+ if (pte) -+ printk(KERN_INFO " pt %03x:%08x\n", k, pte); - } - } - } -diff --git a/drivers/gpu/drm/lima/lima_vm.h b/drivers/gpu/drm/lima/lima_vm.h -index c891a1ee95df..598708ac0d31 100644 ---- a/drivers/gpu/drm/lima/lima_vm.h -+++ b/drivers/gpu/drm/lima/lima_vm.h -@@ -12,6 +12,10 @@ - #define LIMA_PAGE_MASK (LIMA_PAGE_SIZE - 1) - #define LIMA_PAGE_ENT_NUM (LIMA_PAGE_SIZE / sizeof(u32)) - -+#define LIMA_VM_NUM_PT_PER_BT_SHIFT 3 -+#define LIMA_VM_NUM_PT_PER_BT (1 << LIMA_VM_NUM_PT_PER_BT_SHIFT) -+#define LIMA_VM_NUM_BT (LIMA_PAGE_ENT_NUM >> LIMA_VM_NUM_PT_PER_BT_SHIFT) -+ - #define LIMA_VA_RESERVE_START 0xFFF00000 - #define LIMA_VA_RESERVE_DLBU LIMA_VA_RESERVE_START - #define LIMA_VA_RESERVE_END 0x100000000 -@@ -28,7 +32,7 @@ struct lima_vm { - struct lima_device *dev; - - struct lima_bo *pd; -- struct lima_bo *pt[LIMA_PAGE_ENT_NUM]; -+ struct lima_bo *bts[LIMA_VM_NUM_BT]; - }; - - int lima_vm_bo_map(struct lima_vm *vm, struct lima_bo *bo, u32 start); --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0070-drm-lima-clear-vm-page-table-when-alloc.patch b/patch/kernel/sunxi-legacy/0070-drm-lima-clear-vm-page-table-when-alloc.patch deleted file mode 100644 index 4faf4aab1..000000000 --- a/patch/kernel/sunxi-legacy/0070-drm-lima-clear-vm-page-table-when-alloc.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 3930833ef2781427cccc0860a86525498d646f72 Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Thu, 31 May 2018 16:19:07 +0800 -Subject: [PATCH 070/146] drm/lima: clear vm page table when alloc - -ttm_bo_type_kernel will not be cleared when alloc. - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_vm.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c -index ab7438685234..514115df4e4c 100644 ---- a/drivers/gpu/drm/lima/lima_vm.c -+++ b/drivers/gpu/drm/lima/lima_vm.c -@@ -98,6 +98,7 @@ static int lima_vm_map_page_table(struct lima_vm *vm, dma_addr_t *dma, - err = PTR_ERR(bt); - goto err_out; - } -+ memset(bt, 0, LIMA_PAGE_SIZE << LIMA_VM_NUM_PT_PER_BT_SHIFT); - - vm->bts[pbe] = bt_bo; - pd = lima_bo_kmap(vm->pd); -@@ -286,6 +287,7 @@ struct lima_vm *lima_vm_create(struct lima_device *dev) - pd = lima_bo_kmap(vm->pd); - if (IS_ERR(pd)) - goto err_out1; -+ memset(pd, 0, LIMA_PAGE_SIZE); - - if (dev->dlbu_cpu) { - int err = lima_vm_map_page_table( --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0071-drm-lima-update-SPDX-header-to-match-kernel-rules.patch b/patch/kernel/sunxi-legacy/0071-drm-lima-update-SPDX-header-to-match-kernel-rules.patch deleted file mode 100644 index 2c9d4f696..000000000 --- a/patch/kernel/sunxi-legacy/0071-drm-lima-update-SPDX-header-to-match-kernel-rules.patch +++ /dev/null @@ -1,514 +0,0 @@ -From d1267be906c38af372a6b1ebe5145158667e6768 Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Thu, 31 May 2018 22:37:45 +0800 -Subject: [PATCH 071/146] drm/lima: update SPDX header to match kernel rules - -See -https://www.kernel.org/doc/html/latest/process/license-rules.html - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/Kconfig | 2 +- - drivers/gpu/drm/lima/Makefile | 2 +- - drivers/gpu/drm/lima/lima_bcast.c | 5 ++--- - drivers/gpu/drm/lima/lima_bcast.h | 5 ++--- - drivers/gpu/drm/lima/lima_ctx.c | 5 ++--- - drivers/gpu/drm/lima/lima_ctx.h | 5 ++--- - drivers/gpu/drm/lima/lima_device.c | 5 ++--- - drivers/gpu/drm/lima/lima_device.h | 5 ++--- - drivers/gpu/drm/lima/lima_dlbu.c | 5 ++--- - drivers/gpu/drm/lima/lima_dlbu.h | 5 ++--- - drivers/gpu/drm/lima/lima_drv.c | 5 ++--- - drivers/gpu/drm/lima/lima_drv.h | 5 ++--- - drivers/gpu/drm/lima/lima_gem.c | 5 ++--- - drivers/gpu/drm/lima/lima_gem.h | 5 ++--- - drivers/gpu/drm/lima/lima_gem_prime.c | 5 ++--- - drivers/gpu/drm/lima/lima_gem_prime.h | 5 ++--- - drivers/gpu/drm/lima/lima_gp.c | 5 ++--- - drivers/gpu/drm/lima/lima_gp.h | 5 ++--- - drivers/gpu/drm/lima/lima_l2_cache.c | 5 ++--- - drivers/gpu/drm/lima/lima_l2_cache.h | 5 ++--- - drivers/gpu/drm/lima/lima_mmu.c | 5 ++--- - drivers/gpu/drm/lima/lima_mmu.h | 5 ++--- - drivers/gpu/drm/lima/lima_object.c | 5 ++--- - drivers/gpu/drm/lima/lima_object.h | 5 ++--- - drivers/gpu/drm/lima/lima_pmu.c | 5 ++--- - drivers/gpu/drm/lima/lima_pmu.h | 5 ++--- - drivers/gpu/drm/lima/lima_pp.c | 5 ++--- - drivers/gpu/drm/lima/lima_pp.h | 5 ++--- - drivers/gpu/drm/lima/lima_regs.h | 2 +- - drivers/gpu/drm/lima/lima_sched.c | 5 ++--- - drivers/gpu/drm/lima/lima_sched.h | 5 ++--- - drivers/gpu/drm/lima/lima_ttm.c | 5 ++--- - drivers/gpu/drm/lima/lima_ttm.h | 5 ++--- - drivers/gpu/drm/lima/lima_vm.c | 5 ++--- - drivers/gpu/drm/lima/lima_vm.h | 5 ++--- - include/uapi/drm/lima_drm.h | 5 ++--- - 36 files changed, 69 insertions(+), 102 deletions(-) - -diff --git a/drivers/gpu/drm/lima/Kconfig b/drivers/gpu/drm/lima/Kconfig -index 870f66f407b8..bb75bcb97ccb 100644 ---- a/drivers/gpu/drm/lima/Kconfig -+++ b/drivers/gpu/drm/lima/Kconfig -@@ -1,5 +1,5 @@ -+# SPDX-License-Identifier: GPL-2.0 OR MIT - # Copyright 2017-2018 Qiang Yu --# SPDX-License-Identifier: MIT - - config DRM_LIMA - tristate "LIMA (DRM support for ARM Mali 400/450 GPU)" -diff --git a/drivers/gpu/drm/lima/Makefile b/drivers/gpu/drm/lima/Makefile -index 848310557e42..8bb97410d961 100644 ---- a/drivers/gpu/drm/lima/Makefile -+++ b/drivers/gpu/drm/lima/Makefile -@@ -1,5 +1,5 @@ -+# SPDX-License-Identifier: GPL-2.0 OR MIT - # Copyright 2017-2018 Qiang Yu --# SPDX-License-Identifier: MIT - - lima-y := \ - lima_drv.o \ -diff --git a/drivers/gpu/drm/lima/lima_bcast.c b/drivers/gpu/drm/lima/lima_bcast.c -index 0786336d3c77..6c2004dce648 100644 ---- a/drivers/gpu/drm/lima/lima_bcast.c -+++ b/drivers/gpu/drm/lima/lima_bcast.c -@@ -1,6 +1,5 @@ --/* Copyright 2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+// SPDX-License-Identifier: GPL-2.0 OR MIT -+/* Copyright 2018 Qiang Yu */ - - #include - #include -diff --git a/drivers/gpu/drm/lima/lima_bcast.h b/drivers/gpu/drm/lima/lima_bcast.h -index f1ba32852742..fb8e1f318c5c 100644 ---- a/drivers/gpu/drm/lima/lima_bcast.h -+++ b/drivers/gpu/drm/lima/lima_bcast.h -@@ -1,6 +1,5 @@ --/* Copyright 2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+/* SPDX-License-Identifier: GPL-2.0 OR MIT */ -+/* Copyright 2018 Qiang Yu */ - - #ifndef __LIMA_BCAST_H__ - #define __LIMA_BCAST_H__ -diff --git a/drivers/gpu/drm/lima/lima_ctx.c b/drivers/gpu/drm/lima/lima_ctx.c -index 3c8f0aba0169..3f8a944d9266 100644 ---- a/drivers/gpu/drm/lima/lima_ctx.c -+++ b/drivers/gpu/drm/lima/lima_ctx.c -@@ -1,6 +1,5 @@ --/* Copyright 2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+// SPDX-License-Identifier: GPL-2.0 OR MIT -+/* Copyright 2018 Qiang Yu */ - - #include - -diff --git a/drivers/gpu/drm/lima/lima_ctx.h b/drivers/gpu/drm/lima/lima_ctx.h -index f3bee2e1893a..80e55e16619f 100644 ---- a/drivers/gpu/drm/lima/lima_ctx.h -+++ b/drivers/gpu/drm/lima/lima_ctx.h -@@ -1,6 +1,5 @@ --/* Copyright 2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+/* SPDX-License-Identifier: GPL-2.0 OR MIT */ -+/* Copyright 2018 Qiang Yu */ - - #ifndef __LIMA_CTX_H__ - #define __LIMA_CTX_H__ -diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c -index 8611ed466a29..c85196af8830 100644 ---- a/drivers/gpu/drm/lima/lima_device.c -+++ b/drivers/gpu/drm/lima/lima_device.c -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+// SPDX-License-Identifier: GPL-2.0 OR MIT -+/* Copyright 2017-2018 Qiang Yu */ - - #include - #include -diff --git a/drivers/gpu/drm/lima/lima_device.h b/drivers/gpu/drm/lima/lima_device.h -index 29501f8361d9..d355a2c5c40b 100644 ---- a/drivers/gpu/drm/lima/lima_device.h -+++ b/drivers/gpu/drm/lima/lima_device.h -@@ -1,6 +1,5 @@ --/* Copyright 2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+/* SPDX-License-Identifier: GPL-2.0 OR MIT */ -+/* Copyright 2018 Qiang Yu */ - - #ifndef __LIMA_DEVICE_H__ - #define __LIMA_DEVICE_H__ -diff --git a/drivers/gpu/drm/lima/lima_dlbu.c b/drivers/gpu/drm/lima/lima_dlbu.c -index 0b612149accb..444a74348d5e 100644 ---- a/drivers/gpu/drm/lima/lima_dlbu.c -+++ b/drivers/gpu/drm/lima/lima_dlbu.c -@@ -1,6 +1,5 @@ --/* Copyright 2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+// SPDX-License-Identifier: GPL-2.0 OR MIT -+/* Copyright 2018 Qiang Yu */ - - #include - #include -diff --git a/drivers/gpu/drm/lima/lima_dlbu.h b/drivers/gpu/drm/lima/lima_dlbu.h -index bc441dccb1ba..6d85403fa410 100644 ---- a/drivers/gpu/drm/lima/lima_dlbu.h -+++ b/drivers/gpu/drm/lima/lima_dlbu.h -@@ -1,6 +1,5 @@ --/* Copyright 2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+/* SPDX-License-Identifier: GPL-2.0 OR MIT */ -+/* Copyright 2018 Qiang Yu */ - - #ifndef __LIMA_DLBU_H__ - #define __LIMA_DLBU_H__ -diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c -index d3ab9f7abb93..e7004e4e1853 100644 ---- a/drivers/gpu/drm/lima/lima_drv.c -+++ b/drivers/gpu/drm/lima/lima_drv.c -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+// SPDX-License-Identifier: GPL-2.0 OR MIT -+/* Copyright 2017-2018 Qiang Yu */ - - #include - #include -diff --git a/drivers/gpu/drm/lima/lima_drv.h b/drivers/gpu/drm/lima/lima_drv.h -index d7dba79950d6..455bf44ae25e 100644 ---- a/drivers/gpu/drm/lima/lima_drv.h -+++ b/drivers/gpu/drm/lima/lima_drv.h -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+/* SPDX-License-Identifier: GPL-2.0 OR MIT */ -+/* Copyright 2017-2018 Qiang Yu */ - - #ifndef __LIMA_DRV_H__ - #define __LIMA_DRV_H__ -diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c -index 3bdff19eb2f9..ee903ce17494 100644 ---- a/drivers/gpu/drm/lima/lima_gem.c -+++ b/drivers/gpu/drm/lima/lima_gem.c -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+// SPDX-License-Identifier: GPL-2.0 OR MIT -+/* Copyright 2017-2018 Qiang Yu */ - - #include - #include -diff --git a/drivers/gpu/drm/lima/lima_gem.h b/drivers/gpu/drm/lima/lima_gem.h -index 35098b692b2e..03daad9a85af 100644 ---- a/drivers/gpu/drm/lima/lima_gem.h -+++ b/drivers/gpu/drm/lima/lima_gem.h -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+/* SPDX-License-Identifier: GPL-2.0 OR MIT */ -+/* Copyright 2017-2018 Qiang Yu */ - - #ifndef __LIMA_GEM_H__ - #define __LIMA_GEM_H__ -diff --git a/drivers/gpu/drm/lima/lima_gem_prime.c b/drivers/gpu/drm/lima/lima_gem_prime.c -index 9a401a6a039b..0e0350ca7f87 100644 ---- a/drivers/gpu/drm/lima/lima_gem_prime.c -+++ b/drivers/gpu/drm/lima/lima_gem_prime.c -@@ -1,6 +1,5 @@ --/* Copyright 2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+// SPDX-License-Identifier: GPL-2.0 OR MIT -+/* Copyright 2018 Qiang Yu */ - - #include - #include -diff --git a/drivers/gpu/drm/lima/lima_gem_prime.h b/drivers/gpu/drm/lima/lima_gem_prime.h -index 407482f1a7c0..6dea7dd65b1a 100644 ---- a/drivers/gpu/drm/lima/lima_gem_prime.h -+++ b/drivers/gpu/drm/lima/lima_gem_prime.h -@@ -1,6 +1,5 @@ --/* Copyright 2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+/* SPDX-License-Identifier: GPL-2.0 OR MIT */ -+/* Copyright 2018 Qiang Yu */ - - #ifndef __LIMA_GEM_PRIME_H__ - #define __LIMA_GEM_PRIME_H__ -diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c -index 10d7ee16a1d5..706652cb1741 100644 ---- a/drivers/gpu/drm/lima/lima_gp.c -+++ b/drivers/gpu/drm/lima/lima_gp.c -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+// SPDX-License-Identifier: GPL-2.0 OR MIT -+/* Copyright 2017-2018 Qiang Yu */ - - #include - #include -diff --git a/drivers/gpu/drm/lima/lima_gp.h b/drivers/gpu/drm/lima/lima_gp.h -index 45e654737767..55bc48ec7603 100644 ---- a/drivers/gpu/drm/lima/lima_gp.h -+++ b/drivers/gpu/drm/lima/lima_gp.h -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+/* SPDX-License-Identifier: GPL-2.0 OR MIT */ -+/* Copyright 2017-2018 Qiang Yu */ - - #ifndef __LIMA_GP_H__ - #define __LIMA_GP_H__ -diff --git a/drivers/gpu/drm/lima/lima_l2_cache.c b/drivers/gpu/drm/lima/lima_l2_cache.c -index 25313ab5fe92..e7cdec720e5d 100644 ---- a/drivers/gpu/drm/lima/lima_l2_cache.c -+++ b/drivers/gpu/drm/lima/lima_l2_cache.c -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+// SPDX-License-Identifier: GPL-2.0 OR MIT -+/* Copyright 2017-2018 Qiang Yu */ - - #include - #include -diff --git a/drivers/gpu/drm/lima/lima_l2_cache.h b/drivers/gpu/drm/lima/lima_l2_cache.h -index 6ecc07e33430..2ff91eafefbe 100644 ---- a/drivers/gpu/drm/lima/lima_l2_cache.h -+++ b/drivers/gpu/drm/lima/lima_l2_cache.h -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+/* SPDX-License-Identifier: GPL-2.0 OR MIT */ -+/* Copyright 2017-2018 Qiang Yu */ - - #ifndef __LIMA_L2_CACHE_H__ - #define __LIMA_L2_CACHE_H__ -diff --git a/drivers/gpu/drm/lima/lima_mmu.c b/drivers/gpu/drm/lima/lima_mmu.c -index 7de3935b5cc6..234fb90a4285 100644 ---- a/drivers/gpu/drm/lima/lima_mmu.c -+++ b/drivers/gpu/drm/lima/lima_mmu.c -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+// SPDX-License-Identifier: GPL-2.0 OR MIT -+/* Copyright 2017-2018 Qiang Yu */ - - #include - #include -diff --git a/drivers/gpu/drm/lima/lima_mmu.h b/drivers/gpu/drm/lima/lima_mmu.h -index ac32f620e3d9..ca173b60fc73 100644 ---- a/drivers/gpu/drm/lima/lima_mmu.h -+++ b/drivers/gpu/drm/lima/lima_mmu.h -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+/* SPDX-License-Identifier: GPL-2.0 OR MIT */ -+/* Copyright 2017-2018 Qiang Yu */ - - #ifndef __LIMA_MMU_H__ - #define __LIMA_MMU_H__ -diff --git a/drivers/gpu/drm/lima/lima_object.c b/drivers/gpu/drm/lima/lima_object.c -index 6ca17ef2e701..c44e1f81abf8 100644 ---- a/drivers/gpu/drm/lima/lima_object.c -+++ b/drivers/gpu/drm/lima/lima_object.c -@@ -1,6 +1,5 @@ --/* Copyright 2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+// SPDX-License-Identifier: GPL-2.0 OR MIT -+/* Copyright 2018 Qiang Yu */ - - #include - -diff --git a/drivers/gpu/drm/lima/lima_object.h b/drivers/gpu/drm/lima/lima_object.h -index ae67de9d2565..7286514c0f07 100644 ---- a/drivers/gpu/drm/lima/lima_object.h -+++ b/drivers/gpu/drm/lima/lima_object.h -@@ -1,6 +1,5 @@ --/* Copyright 2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+/* SPDX-License-Identifier: GPL-2.0 OR MIT */ -+/* Copyright 2018 Qiang Yu */ - - #ifndef __LIMA_OBJECT_H__ - #define __LIMA_OBJECT_H__ -diff --git a/drivers/gpu/drm/lima/lima_pmu.c b/drivers/gpu/drm/lima/lima_pmu.c -index f4548c90b6b7..e852077c1e52 100644 ---- a/drivers/gpu/drm/lima/lima_pmu.c -+++ b/drivers/gpu/drm/lima/lima_pmu.c -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+// SPDX-License-Identifier: GPL-2.0 OR MIT -+/* Copyright 2017-2018 Qiang Yu */ - - #include - #include -diff --git a/drivers/gpu/drm/lima/lima_pmu.h b/drivers/gpu/drm/lima/lima_pmu.h -index b807e9f42928..1cf94a35bdf9 100644 ---- a/drivers/gpu/drm/lima/lima_pmu.h -+++ b/drivers/gpu/drm/lima/lima_pmu.h -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+/* SPDX-License-Identifier: GPL-2.0 OR MIT */ -+/* Copyright 2017-2018 Qiang Yu */ - - #ifndef __LIMA_PMU_H__ - #define __LIMA_PMU_H__ -diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c -index 8db3d134e244..29e3ddfb394b 100644 ---- a/drivers/gpu/drm/lima/lima_pp.c -+++ b/drivers/gpu/drm/lima/lima_pp.c -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+// SPDX-License-Identifier: GPL-2.0 OR MIT -+/* Copyright 2017-2018 Qiang Yu */ - - #include - #include -diff --git a/drivers/gpu/drm/lima/lima_pp.h b/drivers/gpu/drm/lima/lima_pp.h -index b928f9516d30..f83f8cb4d30a 100644 ---- a/drivers/gpu/drm/lima/lima_pp.h -+++ b/drivers/gpu/drm/lima/lima_pp.h -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+/* SPDX-License-Identifier: GPL-2.0 OR MIT */ -+/* Copyright 2017-2018 Qiang Yu */ - - #ifndef __LIMA_PP_H__ - #define __LIMA_PP_H__ -diff --git a/drivers/gpu/drm/lima/lima_regs.h b/drivers/gpu/drm/lima/lima_regs.h -index d8c762c17e52..d5ade8fc8901 100644 ---- a/drivers/gpu/drm/lima/lima_regs.h -+++ b/drivers/gpu/drm/lima/lima_regs.h -@@ -1,6 +1,6 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ - /* Copyright 2010-2017 ARM Limited. All rights reserved. - * Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: GPL-2.0 - */ - - #ifndef __LIMA_REGS_H__ -diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c -index 20ed966578a3..e725e793a668 100644 ---- a/drivers/gpu/drm/lima/lima_sched.c -+++ b/drivers/gpu/drm/lima/lima_sched.c -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+// SPDX-License-Identifier: GPL-2.0 OR MIT -+/* Copyright 2017-2018 Qiang Yu */ - - #include - #include -diff --git a/drivers/gpu/drm/lima/lima_sched.h b/drivers/gpu/drm/lima/lima_sched.h -index 581b8601fe81..e1393767128f 100644 ---- a/drivers/gpu/drm/lima/lima_sched.h -+++ b/drivers/gpu/drm/lima/lima_sched.h -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+/* SPDX-License-Identifier: GPL-2.0 OR MIT */ -+/* Copyright 2017-2018 Qiang Yu */ - - #ifndef __LIMA_SCHED_H__ - #define __LIMA_SCHED_H__ -diff --git a/drivers/gpu/drm/lima/lima_ttm.c b/drivers/gpu/drm/lima/lima_ttm.c -index 4be441b02f6c..a79ff0e86929 100644 ---- a/drivers/gpu/drm/lima/lima_ttm.c -+++ b/drivers/gpu/drm/lima/lima_ttm.c -@@ -1,6 +1,5 @@ --/* Copyright 2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+// SPDX-License-Identifier: GPL-2.0 OR MIT -+/* Copyright 2018 Qiang Yu */ - - #include - #include -diff --git a/drivers/gpu/drm/lima/lima_ttm.h b/drivers/gpu/drm/lima/lima_ttm.h -index 42af0b136ffb..df3c06aa92a9 100644 ---- a/drivers/gpu/drm/lima/lima_ttm.h -+++ b/drivers/gpu/drm/lima/lima_ttm.h -@@ -1,6 +1,5 @@ --/* Copyright 2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+/* SPDX-License-Identifier: GPL-2.0 OR MIT */ -+/* Copyright 2018 Qiang Yu */ - - #ifndef __LIMA_TTM_H__ - #define __LIMA_TTM_H__ -diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c -index 514115df4e4c..a264f3ae83fe 100644 ---- a/drivers/gpu/drm/lima/lima_vm.c -+++ b/drivers/gpu/drm/lima/lima_vm.c -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+// SPDX-License-Identifier: GPL-2.0 OR MIT -+/* Copyright 2017-2018 Qiang Yu */ - - #include - #include -diff --git a/drivers/gpu/drm/lima/lima_vm.h b/drivers/gpu/drm/lima/lima_vm.h -index 598708ac0d31..f615f8dfe71d 100644 ---- a/drivers/gpu/drm/lima/lima_vm.h -+++ b/drivers/gpu/drm/lima/lima_vm.h -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+/* SPDX-License-Identifier: GPL-2.0 OR MIT */ -+/* Copyright 2017-2018 Qiang Yu */ - - #ifndef __LIMA_VM_H__ - #define __LIMA_VM_H__ -diff --git a/include/uapi/drm/lima_drm.h b/include/uapi/drm/lima_drm.h -index a489bba517c7..e453bc4f0de4 100644 ---- a/include/uapi/drm/lima_drm.h -+++ b/include/uapi/drm/lima_drm.h -@@ -1,6 +1,5 @@ --/* Copyright 2017-2018 Qiang Yu -- * SPDX-License-Identifier: MIT -- */ -+/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR MIT */ -+/* Copyright 2017-2018 Qiang Yu */ - - #ifndef __LIMA_DRM_H__ - #define __LIMA_DRM_H__ --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0073-drm-lima-add-DRM_LIMA_GEM_MOD-ioctl.patch b/patch/kernel/sunxi-legacy/0073-drm-lima-add-DRM_LIMA_GEM_MOD-ioctl.patch deleted file mode 100644 index ba4d2ab89..000000000 --- a/patch/kernel/sunxi-legacy/0073-drm-lima-add-DRM_LIMA_GEM_MOD-ioctl.patch +++ /dev/null @@ -1,172 +0,0 @@ -From e0cc638d05b59eb60cd268106d883e1913c62de5 Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Tue, 19 Jun 2018 22:22:09 +0800 -Subject: [PATCH 073/146] drm/lima: add DRM_LIMA_GEM_MOD ioctl - -Used to share buffer format across processes. - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_drv.c | 13 ++++++++++++ - drivers/gpu/drm/lima/lima_gem.c | 32 ++++++++++++++++++++++++++++++ - drivers/gpu/drm/lima/lima_gem.h | 2 ++ - drivers/gpu/drm/lima/lima_object.c | 2 ++ - drivers/gpu/drm/lima/lima_object.h | 2 ++ - include/uapi/drm/lima_drm.h | 11 ++++++++++ - 6 files changed, 62 insertions(+) - -diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c -index e7004e4e1853..536d0d442970 100644 ---- a/drivers/gpu/drm/lima/lima_drv.c -+++ b/drivers/gpu/drm/lima/lima_drv.c -@@ -243,6 +243,18 @@ static int lima_ioctl_ctx(struct drm_device *dev, void *data, struct drm_file *f - return -EINVAL; - } - -+static int lima_ioctl_gem_mod(struct drm_device *dev, void *data, struct drm_file *file) -+{ -+ struct drm_lima_gem_mod *args = data; -+ -+ if (args->op == LIMA_GEM_MOD_OP_GET) -+ return lima_gem_get_modifier(file, args->handle, &args->modifier); -+ else if (args->op == LIMA_GEM_MOD_OP_SET) -+ return lima_gem_set_modifier(file, args->handle, args->modifier); -+ -+ return -EINVAL; -+} -+ - static int lima_drm_driver_open(struct drm_device *dev, struct drm_file *file) - { - int err; -@@ -287,6 +299,7 @@ static const struct drm_ioctl_desc lima_drm_driver_ioctls[] = { - DRM_IOCTL_DEF_DRV(LIMA_WAIT_FENCE, lima_ioctl_wait_fence, DRM_AUTH|DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(LIMA_GEM_WAIT, lima_ioctl_gem_wait, DRM_AUTH|DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(LIMA_CTX, lima_ioctl_ctx, DRM_AUTH|DRM_RENDER_ALLOW), -+ DRM_IOCTL_DEF_DRV(LIMA_GEM_MOD, lima_ioctl_gem_mod, DRM_AUTH|DRM_RENDER_ALLOW), - }; - - static const struct file_operations lima_drm_driver_fops = { -diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c -index ee903ce17494..02bf76113a66 100644 ---- a/drivers/gpu/drm/lima/lima_gem.c -+++ b/drivers/gpu/drm/lima/lima_gem.c -@@ -444,3 +444,35 @@ int lima_gem_wait(struct drm_file *file, u32 handle, u32 op, u64 timeout_ns) - drm_gem_object_put_unlocked(obj); - return ret; - } -+ -+int lima_gem_get_modifier(struct drm_file *file, u32 handle, u64 *modifier) -+{ -+ struct drm_gem_object *obj; -+ struct lima_bo *bo; -+ -+ obj = drm_gem_object_lookup(file, handle); -+ if (!obj) -+ return -ENOENT; -+ -+ bo = to_lima_bo(obj); -+ *modifier = bo->modifier; -+ -+ drm_gem_object_put_unlocked(obj); -+ return 0; -+} -+ -+int lima_gem_set_modifier(struct drm_file *file, u32 handle, u64 modifier) -+{ -+ struct drm_gem_object *obj; -+ struct lima_bo *bo; -+ -+ obj = drm_gem_object_lookup(file, handle); -+ if (!obj) -+ return -ENOENT; -+ -+ bo = to_lima_bo(obj); -+ bo->modifier = modifier; -+ -+ drm_gem_object_put_unlocked(obj); -+ return 0; -+} -diff --git a/drivers/gpu/drm/lima/lima_gem.h b/drivers/gpu/drm/lima/lima_gem.h -index 03daad9a85af..da6968fab6bb 100644 ---- a/drivers/gpu/drm/lima/lima_gem.h -+++ b/drivers/gpu/drm/lima/lima_gem.h -@@ -19,5 +19,7 @@ int lima_gem_va_map(struct drm_file *file, u32 handle, u32 flags, u32 va); - int lima_gem_va_unmap(struct drm_file *file, u32 handle, u32 va); - int lima_gem_submit(struct drm_file *file, struct lima_submit *submit); - int lima_gem_wait(struct drm_file *file, u32 handle, u32 op, u64 timeout_ns); -+int lima_gem_get_modifier(struct drm_file *file, u32 handle, u64 *modifier); -+int lima_gem_set_modifier(struct drm_file *file, u32 handle, u64 modifier); - - #endif -diff --git a/drivers/gpu/drm/lima/lima_object.c b/drivers/gpu/drm/lima/lima_object.c -index c44e1f81abf8..34d9b4dc2df6 100644 ---- a/drivers/gpu/drm/lima/lima_object.c -+++ b/drivers/gpu/drm/lima/lima_object.c -@@ -2,6 +2,7 @@ - /* Copyright 2018 Qiang Yu */ - - #include -+#include - - #include "lima_object.h" - -@@ -70,6 +71,7 @@ struct lima_bo *lima_bo_create(struct lima_device *dev, u64 size, - if (err) - goto err_out; - -+ bo->modifier = DRM_FORMAT_MOD_INVALID; - return bo; - - err_out: -diff --git a/drivers/gpu/drm/lima/lima_object.h b/drivers/gpu/drm/lima/lima_object.h -index 7286514c0f07..f854a25637f2 100644 ---- a/drivers/gpu/drm/lima/lima_object.h -+++ b/drivers/gpu/drm/lima/lima_object.h -@@ -19,6 +19,8 @@ struct lima_bo { - struct ttm_bo_kmap_obj kmap; - - struct list_head va; -+ -+ u64 modifier; - }; - - static inline struct lima_bo * -diff --git a/include/uapi/drm/lima_drm.h b/include/uapi/drm/lima_drm.h -index e453bc4f0de4..77cb39af1a45 100644 ---- a/include/uapi/drm/lima_drm.h -+++ b/include/uapi/drm/lima_drm.h -@@ -152,6 +152,15 @@ struct drm_lima_ctx { - __u32 id; /* in/out */ - }; - -+#define LIMA_GEM_MOD_OP_GET 0 -+#define LIMA_GEM_MOD_OP_SET 1 -+ -+struct drm_lima_gem_mod { -+ __u32 handle; /* in */ -+ __u32 op; /* in */ -+ __u64 modifier; /* in/out */ -+}; -+ - #define DRM_LIMA_INFO 0x00 - #define DRM_LIMA_GEM_CREATE 0x01 - #define DRM_LIMA_GEM_INFO 0x02 -@@ -160,6 +169,7 @@ struct drm_lima_ctx { - #define DRM_LIMA_WAIT_FENCE 0x05 - #define DRM_LIMA_GEM_WAIT 0x06 - #define DRM_LIMA_CTX 0x07 -+#define DRM_LIMA_GEM_MOD 0x08 - - #define DRM_IOCTL_LIMA_INFO DRM_IOR(DRM_COMMAND_BASE + DRM_LIMA_INFO, struct drm_lima_info) - #define DRM_IOCTL_LIMA_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_LIMA_GEM_CREATE, struct drm_lima_gem_create) -@@ -169,6 +179,7 @@ struct drm_lima_ctx { - #define DRM_IOCTL_LIMA_WAIT_FENCE DRM_IOW(DRM_COMMAND_BASE + DRM_LIMA_WAIT_FENCE, struct drm_lima_wait_fence) - #define DRM_IOCTL_LIMA_GEM_WAIT DRM_IOW(DRM_COMMAND_BASE + DRM_LIMA_GEM_WAIT, struct drm_lima_gem_wait) - #define DRM_IOCTL_LIMA_CTX DRM_IOWR(DRM_COMMAND_BASE + DRM_LIMA_CTX, struct drm_lima_ctx) -+#define DRM_IOCTL_LIMA_GEM_MOD DRM_IOWR(DRM_COMMAND_BASE + DRM_LIMA_GEM_MOD, struct drm_lima_gem_mod) - - #if defined(__cplusplus) - } --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0076-drm-lima-remove-depend-on-ARM-arch.patch b/patch/kernel/sunxi-legacy/0076-drm-lima-remove-depend-on-ARM-arch.patch deleted file mode 100644 index e415c79c9..000000000 --- a/patch/kernel/sunxi-legacy/0076-drm-lima-remove-depend-on-ARM-arch.patch +++ /dev/null @@ -1,63 +0,0 @@ -From fa09957c702e5aa41c09ca452bd7220c1e8a6985 Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Sun, 15 Jul 2018 11:24:41 +0800 -Subject: [PATCH 076/146] drm/lima: remove depend on ARM arch - -Mali GPU is used on x86-64 arch too: -https://en.wikipedia.org/wiki/Rockchip#Tablet_processors_with_integrated_modem - -Always use need_dma32 as it won't cause any trouble -on 32bit arch. - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/Kconfig | 1 - - drivers/gpu/drm/lima/lima_ttm.c | 9 +-------- - 2 files changed, 1 insertion(+), 9 deletions(-) - -diff --git a/drivers/gpu/drm/lima/Kconfig b/drivers/gpu/drm/lima/Kconfig -index bb75bcb97ccb..89d63cca8a75 100644 ---- a/drivers/gpu/drm/lima/Kconfig -+++ b/drivers/gpu/drm/lima/Kconfig -@@ -4,7 +4,6 @@ - config DRM_LIMA - tristate "LIMA (DRM support for ARM Mali 400/450 GPU)" - depends on DRM -- depends on ARM || ARM64 || COMPILE_TEST - select DRM_SCHED - select DRM_TTM - help -diff --git a/drivers/gpu/drm/lima/lima_ttm.c b/drivers/gpu/drm/lima/lima_ttm.c -index a79ff0e86929..af46dd1edf43 100644 ---- a/drivers/gpu/drm/lima/lima_ttm.c -+++ b/drivers/gpu/drm/lima/lima_ttm.c -@@ -333,25 +333,18 @@ static struct ttm_bo_driver lima_bo_driver = { - int lima_ttm_init(struct lima_device *dev) - { - int err; -- bool need_dma32; - u64 gtt_size; - - err = lima_ttm_global_init(dev); - if (err) - return err; - --#if defined(CONFIG_ARM) && !defined(CONFIG_ARM_LPAE) -- need_dma32 = false; --#else -- need_dma32 = true; --#endif -- - err = ttm_bo_device_init(&dev->mman.bdev, - dev->mman.bo_global_ref.ref.object, - &lima_bo_driver, - dev->ddev->anon_inode->i_mapping, - DRM_FILE_PAGE_OFFSET, -- need_dma32); -+ true); - if (err) { - dev_err(dev->dev, "failed initializing buffer object " - "driver(%d).\n", err); --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0077-drm-lima-port-to-4.18-kernel.patch b/patch/kernel/sunxi-legacy/0077-drm-lima-port-to-4.18-kernel.patch deleted file mode 100644 index 4f5303683..000000000 --- a/patch/kernel/sunxi-legacy/0077-drm-lima-port-to-4.18-kernel.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 3785d95f0a1735e427c3ddf6c5f49545ff7559e9 Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Sun, 15 Jul 2018 12:26:26 +0800 -Subject: [PATCH 077/146] drm/lima: port to 4.18 kernel - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_sched.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c -index e725e793a668..1e715e58d33b 100644 ---- a/drivers/gpu/drm/lima/lima_sched.c -+++ b/drivers/gpu/drm/lima/lima_sched.c -@@ -169,8 +169,7 @@ int lima_sched_context_init(struct lima_sched_pipe *pipe, - return -ENOMEM; - - mutex_init(&context->lock); -- err = drm_sched_entity_init(&pipe->base, &context->base, rq, -- lima_sched_max_tasks, guilty); -+ err = drm_sched_entity_init(&pipe->base, &context->base, rq, guilty); - if (err) { - kfree(context->fences); - context->fences = NULL; --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0078-drm-lima-user-can-choose-not-to-use-dlbu-on-mali450.patch b/patch/kernel/sunxi-legacy/0078-drm-lima-user-can-choose-not-to-use-dlbu-on-mali450.patch deleted file mode 100644 index 748b8598e..000000000 --- a/patch/kernel/sunxi-legacy/0078-drm-lima-user-can-choose-not-to-use-dlbu-on-mali450.patch +++ /dev/null @@ -1,309 +0,0 @@ -From ed6a8088a598439e2cd5d1ab86389b658f19e465 Mon Sep 17 00:00:00 2001 -From: Qiang Yu -Date: Wed, 15 Aug 2018 11:17:09 +0800 -Subject: [PATCH 078/146] drm/lima: user can choose not to use dlbu on mali450 - -Signed-off-by: Qiang Yu ---- - drivers/gpu/drm/lima/lima_bcast.c | 24 +++++----- - drivers/gpu/drm/lima/lima_bcast.h | 3 +- - drivers/gpu/drm/lima/lima_device.c | 5 -- - drivers/gpu/drm/lima/lima_dlbu.c | 4 +- - drivers/gpu/drm/lima/lima_dlbu.h | 2 +- - drivers/gpu/drm/lima/lima_pp.c | 75 ++++++++++++++++++------------ - include/uapi/drm/lima_drm.h | 9 +++- - 7 files changed, 67 insertions(+), 55 deletions(-) - -diff --git a/drivers/gpu/drm/lima/lima_bcast.c b/drivers/gpu/drm/lima/lima_bcast.c -index 6c2004dce648..63754f6465ea 100644 ---- a/drivers/gpu/drm/lima/lima_bcast.c -+++ b/drivers/gpu/drm/lima/lima_bcast.c -@@ -11,31 +11,31 @@ - #define bcast_write(reg, data) writel(data, ip->iomem + LIMA_BCAST_##reg) - #define bcast_read(reg) readl(ip->iomem + LIMA_BCAST_##reg) - --void lima_bcast_enable(struct lima_device *dev) -+void lima_bcast_enable(struct lima_device *dev, int num_pp) - { - struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; - struct lima_ip *ip = dev->ip + lima_ip_bcast; -- int i, mask = 0; -+ int i, mask = bcast_read(BROADCAST_MASK) & 0xffff0000; - -- for (i = 0; i < pipe->num_processor; i++) { -+ for (i = 0; i < num_pp; i++) { - struct lima_ip *pp = pipe->processor[i]; - mask |= 1 << (pp->id - lima_ip_pp0); - } - -- bcast_write(BROADCAST_MASK, (mask << 16) | mask); -- bcast_write(INTERRUPT_MASK, mask); -+ bcast_write(BROADCAST_MASK, mask); - } - --void lima_bcast_disable(struct lima_device *dev) -+int lima_bcast_init(struct lima_ip *ip) - { -- struct lima_ip *ip = dev->ip + lima_ip_bcast; -+ int i, mask = 0; - -- bcast_write(BROADCAST_MASK, 0); -- bcast_write(INTERRUPT_MASK, 0); --} -+ for (i = lima_ip_pp0; i <= lima_ip_pp7; i++) { -+ if (ip->dev->ip[i].present) -+ mask |= 1 << (i - lima_ip_pp0); -+ } - --int lima_bcast_init(struct lima_ip *ip) --{ -+ bcast_write(BROADCAST_MASK, mask << 16); -+ bcast_write(INTERRUPT_MASK, mask); - return 0; - } - -diff --git a/drivers/gpu/drm/lima/lima_bcast.h b/drivers/gpu/drm/lima/lima_bcast.h -index fb8e1f318c5c..345e3e809860 100644 ---- a/drivers/gpu/drm/lima/lima_bcast.h -+++ b/drivers/gpu/drm/lima/lima_bcast.h -@@ -9,7 +9,6 @@ struct lima_ip; - int lima_bcast_init(struct lima_ip *ip); - void lima_bcast_fini(struct lima_ip *ip); - --void lima_bcast_enable(struct lima_device *dev); --void lima_bcast_disable(struct lima_device *dev); -+void lima_bcast_enable(struct lima_device *dev, int num_pp); - - #endif -diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c -index c85196af8830..b88c84d796fc 100644 ---- a/drivers/gpu/drm/lima/lima_device.c -+++ b/drivers/gpu/drm/lima/lima_device.c -@@ -338,11 +338,6 @@ int lima_device_init(struct lima_device *ldev) - if (err) - goto err_out6; - -- if (ldev->id == lima_gpu_mali450) { -- lima_dlbu_enable(ldev); -- lima_bcast_enable(ldev); -- } -- - return 0; - - err_out6: -diff --git a/drivers/gpu/drm/lima/lima_dlbu.c b/drivers/gpu/drm/lima/lima_dlbu.c -index 444a74348d5e..6697d4ddd887 100644 ---- a/drivers/gpu/drm/lima/lima_dlbu.c -+++ b/drivers/gpu/drm/lima/lima_dlbu.c -@@ -12,13 +12,13 @@ - #define dlbu_write(reg, data) writel(data, ip->iomem + LIMA_DLBU_##reg) - #define dlbu_read(reg) readl(ip->iomem + LIMA_DLBU_##reg) - --void lima_dlbu_enable(struct lima_device *dev) -+void lima_dlbu_enable(struct lima_device *dev, int num_pp) - { - struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; - struct lima_ip *ip = dev->ip + lima_ip_dlbu; - int i, mask = 0; - -- for (i = 0; i < pipe->num_processor; i++) { -+ for (i = 0; i < num_pp; i++) { - struct lima_ip *pp = pipe->processor[i]; - mask |= 1 << (pp->id - lima_ip_pp0); - } -diff --git a/drivers/gpu/drm/lima/lima_dlbu.h b/drivers/gpu/drm/lima/lima_dlbu.h -index 6d85403fa410..60cba387cf30 100644 ---- a/drivers/gpu/drm/lima/lima_dlbu.h -+++ b/drivers/gpu/drm/lima/lima_dlbu.h -@@ -7,7 +7,7 @@ - struct lima_ip; - struct lima_device; - --void lima_dlbu_enable(struct lima_device *dev); -+void lima_dlbu_enable(struct lima_device *dev, int num_pp); - void lima_dlbu_disable(struct lima_device *dev); - - void lima_dlbu_set_reg(struct lima_ip *ip, u32 *reg); -diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c -index 29e3ddfb394b..3355895ceeba 100644 ---- a/drivers/gpu/drm/lima/lima_pp.c -+++ b/drivers/gpu/drm/lima/lima_pp.c -@@ -64,8 +64,9 @@ static irqreturn_t lima_pp_bcast_irq_handler(int irq, void *data) - struct lima_ip *pp_bcast = data; - struct lima_device *dev = pp_bcast->dev; - struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; -+ struct drm_lima_m450_pp_frame *frame = pipe->current_task->frame; - -- for (i = 0; i < pipe->num_processor; i++) { -+ for (i = 0; i < frame->num_pp; i++) { - struct lima_ip *ip = pipe->processor[i]; - u32 status, state; - -@@ -135,7 +136,9 @@ static int lima_pp_soft_reset_async_wait(struct lima_ip *ip) - if (ip->id == lima_ip_pp_bcast) { - struct lima_device *dev = ip->dev; - struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp; -- for (i = 0; i < pipe->num_processor; i++) -+ struct drm_lima_m450_pp_frame *frame = pipe->current_task->frame; -+ -+ for (i = 0; i < frame->num_pp; i++) - err |= lima_pp_soft_reset_async_wait_one(pipe->processor[i]); - } - else -@@ -145,24 +148,17 @@ static int lima_pp_soft_reset_async_wait(struct lima_ip *ip) - return err; - } - --static void lima_pp_start_task(struct lima_ip *ip, u32 *frame, u32 *wb, -- bool skip_stack_addr) -+static void lima_pp_write_frame(struct lima_ip *ip, u32 *frame, u32 *wb) - { - int i, j, n = 0; - -- for (i = 0; i < LIMA_PP_FRAME_REG_NUM; i++) { -- if (skip_stack_addr && i * 4 == LIMA_PP_STACK) -- continue; -- -+ for (i = 0; i < LIMA_PP_FRAME_REG_NUM; i++) - writel(frame[i], ip->iomem + LIMA_PP_FRAME + i * 4); -- } - - for (i = 0; i < 3; i++) { - for (j = 0; j < LIMA_PP_WB_REG_NUM; j++) - writel(wb[n++], ip->iomem + LIMA_PP_WB(i) + j * 4); - } -- -- pp_write(CTRL, LIMA_PP_CTRL_START_RENDERING); - } - - static int lima_pp_hard_reset(struct lima_ip *ip) -@@ -271,13 +267,20 @@ void lima_pp_bcast_fini(struct lima_ip *ip) - static int lima_pp_task_validate(struct lima_sched_pipe *pipe, - struct lima_sched_task *task) - { -- if (!pipe->bcast_processor) { -- struct drm_lima_m400_pp_frame *f = task->frame; -+ u32 num_pp; - -- if (f->num_pp > pipe->num_processor) -- return -EINVAL; -+ if (pipe->bcast_processor) { -+ struct drm_lima_m450_pp_frame *f = task->frame; -+ num_pp = f->num_pp; -+ } -+ else { -+ struct drm_lima_m400_pp_frame *f = task->frame; -+ num_pp = f->num_pp; - } - -+ if (num_pp == 0 || num_pp > pipe->num_processor) -+ return -EINVAL; -+ - return 0; - } - -@@ -287,23 +290,36 @@ static void lima_pp_task_run(struct lima_sched_pipe *pipe, - if (pipe->bcast_processor) { - struct drm_lima_m450_pp_frame *frame = task->frame; - struct lima_device *dev = pipe->bcast_processor->dev; -+ struct lima_ip *ip = pipe->bcast_processor; - int i; - - pipe->done = 0; -- atomic_set(&pipe->task, pipe->num_processor); -+ atomic_set(&pipe->task, frame->num_pp); - -- frame->frame[LIMA_PP_FRAME >> 2] = LIMA_VA_RESERVE_DLBU; -- lima_dlbu_set_reg(dev->ip + lima_ip_dlbu, frame->dlbu_regs); -+ if (frame->use_dlbu) { -+ lima_dlbu_enable(dev, frame->num_pp); - -- lima_pp_soft_reset_async_wait(pipe->bcast_processor); -+ frame->frame[LIMA_PP_FRAME >> 2] = LIMA_VA_RESERVE_DLBU; -+ lima_dlbu_set_reg(dev->ip + lima_ip_dlbu, frame->dlbu_regs); -+ } -+ else -+ lima_dlbu_disable(dev); -+ -+ lima_bcast_enable(dev, frame->num_pp); -+ -+ lima_pp_soft_reset_async_wait(ip); -+ -+ lima_pp_write_frame(ip, frame->frame, frame->wb); - -- for (i = 0; i < pipe->num_processor; i++) { -+ for (i = 0; i < frame->num_pp; i++) { - struct lima_ip *ip = pipe->processor[i]; -+ - pp_write(STACK, frame->fragment_stack_address[i]); -+ if (!frame->use_dlbu) -+ pp_write(FRAME, frame->plbu_array_address[i]); - } - -- lima_pp_start_task(pipe->bcast_processor, frame->frame, -- frame->wb, true); -+ pp_write(CTRL, LIMA_PP_CTRL_START_RENDERING); - } - else { - struct drm_lima_m400_pp_frame *frame = task->frame; -@@ -312,15 +328,18 @@ static void lima_pp_task_run(struct lima_sched_pipe *pipe, - atomic_set(&pipe->task, frame->num_pp); - - for (i = 0; i < frame->num_pp; i++) { -+ struct lima_ip *ip = pipe->processor[i]; -+ - frame->frame[LIMA_PP_FRAME >> 2] = - frame->plbu_array_address[i]; - frame->frame[LIMA_PP_STACK >> 2] = - frame->fragment_stack_address[i]; - -- lima_pp_soft_reset_async_wait(pipe->processor[i]); -+ lima_pp_soft_reset_async_wait(ip); -+ -+ lima_pp_write_frame(ip, frame->frame, frame->wb); - -- lima_pp_start_task(pipe->processor[i], frame->frame, -- frame->wb, false); -+ pp_write(CTRL, LIMA_PP_CTRL_START_RENDERING); - } - } - } -@@ -340,14 +359,8 @@ static void lima_pp_task_error(struct lima_sched_pipe *pipe) - { - int i; - -- if (pipe->bcast_processor) -- lima_bcast_disable(pipe->bcast_processor->dev); -- - for (i = 0; i < pipe->num_processor; i++) - lima_pp_hard_reset(pipe->processor[i]); -- -- if (pipe->bcast_processor) -- lima_bcast_enable(pipe->bcast_processor->dev); - } - - static void lima_pp_task_mmu_error(struct lima_sched_pipe *pipe) -diff --git a/include/uapi/drm/lima_drm.h b/include/uapi/drm/lima_drm.h -index 77cb39af1a45..0c17bf693184 100644 ---- a/include/uapi/drm/lima_drm.h -+++ b/include/uapi/drm/lima_drm.h -@@ -91,9 +91,14 @@ struct drm_lima_m400_pp_frame { - - struct drm_lima_m450_pp_frame { - __u32 frame[LIMA_PP_FRAME_REG_NUM]; -- __u32 _pad; -+ __u32 num_pp; - __u32 wb[3 * LIMA_PP_WB_REG_NUM]; -- __u32 dlbu_regs[4]; -+ __u32 use_dlbu; -+ __u32 _pad; -+ union { -+ __u32 plbu_array_address[8]; -+ __u32 dlbu_regs[4]; -+ }; - __u32 fragment_stack_address[8]; - }; - --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0081-arm64-arch_timer-Workaround-for-Allwinner-A64-timer-.patch.disabled b/patch/kernel/sunxi-legacy/0081-arm64-arch_timer-Workaround-for-Allwinner-A64-timer-.patch.disabled deleted file mode 100644 index c33891116..000000000 --- a/patch/kernel/sunxi-legacy/0081-arm64-arch_timer-Workaround-for-Allwinner-A64-timer-.patch.disabled +++ /dev/null @@ -1,178 +0,0 @@ -From 40fc81b67d761368566053d7498c03088adedc10 Mon Sep 17 00:00:00 2001 -From: Samuel Holland -Date: Thu, 10 May 2018 21:27:50 -0500 -Subject: [PATCH 081/146] arm64: arch_timer: Workaround for Allwinner A64 timer - instability -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The Allwinner A64 SoC is known [1] to have an unstable architectural -timer, which manifests itself most obviously in the time jumping forward -a multiple of 95 years [2][3]. This coincides with 2^56 cycles at a -timer frequency of 24 MHz, implying that the time went slightly backward -(and this was interpreted by the kernel as it jumping forward and -wrapping around past the epoch). - -Further investigation revealed instability in the low bits of CNTVCT at -the point a high bit rolls over. This leads to power-of-two cycle -forward and backward jumps. (Testing shows that forward jumps are about -twice as likely as backward jumps.) - -Without trapping reads to CNTVCT, a userspace program is able to read it -in a loop faster than it changes. A test program running on all 4 CPU -cores that reported jumps larger than 100 ms was run for 13.6 hours and -reported the following: - - Count | Event --------+--------------------------- - 9940 | jumped backward 699ms - 268 | jumped backward 1398ms - 1 | jumped backward 2097ms - 16020 | jumped forward 175ms - 6443 | jumped forward 699ms - 2976 | jumped forward 1398ms - 9 | jumped forward 356516ms - 9 | jumped forward 357215ms - 4 | jumped forward 714430ms - 1 | jumped forward 3578440ms - -This works out to a jump larger than 100 ms about every 5.5 seconds on -each CPU core. - -The largest jump (almost an hour!) was the following sequence of reads: - 0x0000007fffffffff → 0x00000093feffffff → 0x0000008000000000 - -Note that the middle bits don't necessarily all read as all zeroes or -all ones during the anomalous behavior; however the low 11 bits checked -by the function in this patch have never been observed with any other -value. - -Also note that smaller jumps are much more common, with the smallest -backward jumps of 2048 cycles observed over 400 times per second on each -core. (Of course, this is partially due to lower bits rolling over more -frequently.) Any one of these could have caused the 95 year time skip. - -Similar anomalies were observed while reading CNTPCT (after patching the -kernel to allow reads from userspace). However, the jumps are much less -frequent, and only small jumps were observed. The same program as before -(except now reading CNTPCT) observed after 72 hours: - - Count | Event --------+--------------------------- - 17 | jumped backward 699ms - 52 | jumped forward 175ms - 2831 | jumped forward 699ms - 5 | jumped forward 1398ms -Acked-by: Maxime Ripard -Tested-by: Andre Przywara - -======================================================================== - -Because the CPU can read the CNTPCT/CNTVCT registers faster than they -change, performing two reads of the register and comparing the high bits -(like other workarounds) is not a workable solution. And because the -timer can jump both forward and backward, no pair of reads can -distinguish a good value from a bad one. The only way to guarantee a -good value from consecutive reads would be to read _three_ times, and -take the middle value iff the three values are 1) individually unique -and 2) increasing. This takes at minimum 3 cycles (125 ns), or more if -an anomaly is detected. - -However, since there is a distinct pattern to the bad values, we can -optimize the common case (2046/2048 of the time) to a single read by -simply ignoring values that match the pattern. This still takes no more -than 3 cycles in the worst case, and requires much less code. - -[1]: https://github.com/armbian/build/commit/a08cd6fe7ae9 -[2]: https://forum.armbian.com/topic/3458-a64-datetime-clock-issue/ -[3]: https://irclog.whitequark.org/linux-sunxi/2018-01-26 - -Signed-off-by: Samuel Holland ---- - drivers/clocksource/Kconfig | 11 ++++++++ - drivers/clocksource/arm_arch_timer.c | 39 ++++++++++++++++++++++++++++ - 2 files changed, 50 insertions(+) - -diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig -index a11f4ba98b05..bb7fa4175954 100644 ---- a/drivers/clocksource/Kconfig -+++ b/drivers/clocksource/Kconfig -@@ -364,6 +364,17 @@ config ARM64_ERRATUM_858921 - The workaround will be dynamically enabled when an affected - core is detected. - -+config SUN50I_A64_UNSTABLE_TIMER -+ bool "Workaround for Allwinner A64 timer instability" -+ default y -+ depends on ARM_ARCH_TIMER && ARM64 && ARCH_SUNXI -+ select ARM_ARCH_TIMER_OOL_WORKAROUND -+ help -+ This option enables a workaround for instability in the timer on -+ the Allwinner A64 SoC. The workaround will only be active if the -+ allwinner,sun50i-a64-unstable-timer property is found in the -+ timer node. -+ - config ARM_GLOBAL_TIMER - bool "Support for the ARM global timer" if COMPILE_TEST - select TIMER_OF if OF -diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c -index d8c7f5750cdb..e10456525dda 100644 ---- a/drivers/clocksource/arm_arch_timer.c -+++ b/drivers/clocksource/arm_arch_timer.c -@@ -319,6 +319,36 @@ static u64 notrace arm64_858921_read_cntvct_el0(void) - } - #endif - -+#ifdef CONFIG_SUN50I_A64_UNSTABLE_TIMER -+/* -+ * The low bits of each register can transiently read as all ones or all zeroes -+ * when bit 11 or greater rolls over. Since the value can jump both backward -+ * (7ff -> 000 -> 800) and forward (7ff -> fff -> 800), it is simplest to just -+ * ignore register values with all ones or zeros in the low bits. -+ */ -+static u64 notrace sun50i_a64_read_cntpct_el0(void) -+{ -+ u64 val; -+ -+ do { -+ val = read_sysreg(cntpct_el0); -+ } while (((val + 1) & GENMASK(10, 0)) <= 1); -+ -+ return val; -+} -+ -+static u64 notrace sun50i_a64_read_cntvct_el0(void) -+{ -+ u64 val; -+ -+ do { -+ val = read_sysreg(cntvct_el0); -+ } while (((val + 1) & GENMASK(10, 0)) <= 1); -+ -+ return val; -+} -+#endif -+ - #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND - DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *, timer_unstable_counter_workaround); - EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround); -@@ -408,6 +438,15 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { - .read_cntvct_el0 = arm64_858921_read_cntvct_el0, - }, - #endif -+#ifdef CONFIG_SUN50I_A64_UNSTABLE_TIMER -+ { -+ .match_type = ate_match_dt, -+ .id = "allwinner,sun50i-a64-unstable-timer", -+ .desc = "Allwinner A64 timer instability", -+ .read_cntpct_el0 = sun50i_a64_read_cntpct_el0, -+ .read_cntvct_el0 = sun50i_a64_read_cntvct_el0, -+ }, -+#endif - }; - - typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround *, --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0082-arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch.disabled b/patch/kernel/sunxi-legacy/0082-arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch.disabled deleted file mode 100644 index f87b1419d..000000000 --- a/patch/kernel/sunxi-legacy/0082-arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch.disabled +++ /dev/null @@ -1,30 +0,0 @@ -From a740ecc40aa9df18fbfb12925c1b7600c043a3cd Mon Sep 17 00:00:00 2001 -From: Samuel Holland -Date: Thu, 10 May 2018 21:27:51 -0500 -Subject: [PATCH 082/146] arm64: dts: allwinner: a64: Enable A64 timer - workaround - -As instability in the architectural timer has been observed on multiple -devices using this SoC, inluding the Pine64 and the Orange Pi Win, -enable the workaround in the SoC's device tree. - -Signed-off-by: Samuel Holland ---- - arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -index 62b880f68d6a..73f7e69755f8 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -@@ -281,6 +281,7 @@ - - timer { - compatible = "arm,armv8-timer"; -+ allwinner,sun50i-a64-unstable-timer; - interrupts = , - -Date: Thu, 9 Aug 2018 18:52:13 +0200 -Subject: [PATCH 083/146] clk: sunxi-ng: Add maximum rate constraint to NM PLLs - -On some NM PLLs, frequency can be set above PLL working range. - -Add a constraint for maximum supported rate. This way, drivers can -specify which is maximum allowed rate for PLL. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Maxime Ripard ---- - drivers/clk/sunxi-ng/ccu_nm.c | 7 +++++++ - drivers/clk/sunxi-ng/ccu_nm.h | 30 ++++++++++++++++++++++++++++++ - 2 files changed, 37 insertions(+) - -diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c -index 4e2073307f34..6fe3c14f7b2d 100644 ---- a/drivers/clk/sunxi-ng/ccu_nm.c -+++ b/drivers/clk/sunxi-ng/ccu_nm.c -@@ -124,6 +124,13 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate, - return rate; - } - -+ if (nm->max_rate && rate > nm->max_rate) { -+ rate = nm->max_rate; -+ if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) -+ rate /= nm->fixed_post_div; -+ return rate; -+ } -+ - if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) { - if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate /= nm->fixed_post_div; -diff --git a/drivers/clk/sunxi-ng/ccu_nm.h b/drivers/clk/sunxi-ng/ccu_nm.h -index 1d8b459c50b7..de232f2199a6 100644 ---- a/drivers/clk/sunxi-ng/ccu_nm.h -+++ b/drivers/clk/sunxi-ng/ccu_nm.h -@@ -38,6 +38,7 @@ struct ccu_nm { - - unsigned int fixed_post_div; - unsigned int min_rate; -+ unsigned int max_rate; - - struct ccu_common common; - }; -@@ -115,6 +116,35 @@ struct ccu_nm { - }, \ - } - -+#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(_struct, _name, \ -+ _parent, _reg, \ -+ _min_rate, _max_rate, \ -+ _nshift, _nwidth, \ -+ _mshift, _mwidth, \ -+ _frac_en, _frac_sel, \ -+ _frac_rate_0, \ -+ _frac_rate_1, \ -+ _gate, _lock, _flags) \ -+ struct ccu_nm _struct = { \ -+ .enable = _gate, \ -+ .lock = _lock, \ -+ .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \ -+ .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ -+ .frac = _SUNXI_CCU_FRAC(_frac_en, _frac_sel, \ -+ _frac_rate_0, \ -+ _frac_rate_1), \ -+ .min_rate = _min_rate, \ -+ .max_rate = _max_rate, \ -+ .common = { \ -+ .reg = _reg, \ -+ .features = CCU_FEATURE_FRACTIONAL, \ -+ .hw.init = CLK_HW_INIT(_name, \ -+ _parent, \ -+ &ccu_nm_ops, \ -+ _flags), \ -+ }, \ -+ } -+ - #define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \ - _nshift, _nwidth, \ - _mshift, _mwidth, \ --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0084-clk-sunxi-ng-h3-h5-Add-max.-rate-constraint-to-pll-v.patch b/patch/kernel/sunxi-legacy/0084-clk-sunxi-ng-h3-h5-Add-max.-rate-constraint-to-pll-v.patch deleted file mode 100644 index e872e4727..000000000 --- a/patch/kernel/sunxi-legacy/0084-clk-sunxi-ng-h3-h5-Add-max.-rate-constraint-to-pll-v.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 461aa98f7ee6d5347625728949d51122ee92999b Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Thu, 9 Aug 2018 18:52:14 +0200 -Subject: [PATCH 084/146] clk: sunxi-ng: h3/h5: Add max. rate constraint to - pll-video - -As it turns out, pll-video can be set to higher rate that it is really -supported by HW. - -For example, one monitor requested 185.58 MHz pixel clock. Clock -framework calculated that minimum rate error would be when pll-video -is set to 2040 MHz. This is clearly out of specs. - -Both H3 and H5 user manuals specify 600 MHz as maximum supported rate. -However, BSP clock drivers allow up to 912 MHz and 1008 MHz -respectively. Here 912 MHz is chosen because user manuals were already -proven wrong once for lower limits. - -Signed-off-by: Jernej Skrabec -Signed-off-by: Maxime Ripard ---- - drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 25 +++++++++++++------------ - 1 file changed, 13 insertions(+), 12 deletions(-) - -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c -index 77ed0b0ba681..eb5c608428fa 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c -@@ -69,18 +69,19 @@ static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", - BIT(28), /* lock */ - CLK_SET_RATE_UNGATE); - --static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video_clk, "pll-video", -- "osc24M", 0x0010, -- 192000000, /* Minimum rate */ -- 8, 7, /* N */ -- 0, 4, /* M */ -- BIT(24), /* frac enable */ -- BIT(25), /* frac select */ -- 270000000, /* frac rate 0 */ -- 297000000, /* frac rate 1 */ -- BIT(31), /* gate */ -- BIT(28), /* lock */ -- CLK_SET_RATE_UNGATE); -+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video_clk, "pll-video", -+ "osc24M", 0x0010, -+ 192000000, /* Minimum rate */ -+ 912000000, /* Maximum rate */ -+ 8, 7, /* N */ -+ 0, 4, /* M */ -+ BIT(24), /* frac enable */ -+ BIT(25), /* frac select */ -+ 270000000, /* frac rate 0 */ -+ 297000000, /* frac rate 1 */ -+ BIT(31), /* gate */ -+ BIT(28), /* lock */ -+ CLK_SET_RATE_UNGATE); - - static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", - "osc24M", 0x0018, --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0085-clk-sunxi-ng-Adjust-MP-clock-parent-rate-when-allowe.patch.disabled b/patch/kernel/sunxi-legacy/0085-clk-sunxi-ng-Adjust-MP-clock-parent-rate-when-allowe.patch.disabled deleted file mode 100644 index f5ba597e5..000000000 --- a/patch/kernel/sunxi-legacy/0085-clk-sunxi-ng-Adjust-MP-clock-parent-rate-when-allowe.patch.disabled +++ /dev/null @@ -1,107 +0,0 @@ -From b0019c82e8ffbce13b5a98eb4fa16b966809c04a Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Sun, 7 Oct 2018 11:38:38 +0200 -Subject: [PATCH 085/146] clk: sunxi-ng: Adjust MP clock parent rate when - allowed - -Currently MP clocks don't consider adjusting parent rate even if they -are allowed to do so. Such behaviour considerably lowers amount of -possible rates, which is very inconvenient when such clock is used for -pixel clock, for example. - -In order to improve the situation, adjusting parent rate is considered -when allowed. - -This code is inspired by clk_divider_bestdiv() function, which does -basically the same thing for different clock type. - -Signed-off-by: Jernej Skrabec ---- - drivers/clk/sunxi-ng/ccu_mp.c | 64 +++++++++++++++++++++++++++++++++-- - 1 file changed, 62 insertions(+), 2 deletions(-) - -diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c -index 5d0af4051737..0357349eb767 100644 ---- a/drivers/clk/sunxi-ng/ccu_mp.c -+++ b/drivers/clk/sunxi-ng/ccu_mp.c -@@ -40,6 +40,61 @@ static void ccu_mp_find_best(unsigned long parent, unsigned long rate, - *p = best_p; - } - -+static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw *hw, -+ unsigned long *parent, -+ unsigned long rate, -+ unsigned int max_m, -+ unsigned int max_p) -+{ -+ unsigned long parent_rate_saved; -+ unsigned long parent_rate, now; -+ unsigned long best_rate = 0; -+ unsigned int _m, _p, div; -+ unsigned long maxdiv; -+ -+ parent_rate_saved = *parent; -+ -+ /* -+ * The maximum divider we can use without overflowing -+ * unsigned long in rate * m * p below -+ */ -+ maxdiv = max_m * max_p; -+ maxdiv = min(ULONG_MAX / rate, maxdiv); -+ -+ for (_p = 1; _p <= max_p; _p <<= 1) { -+ for (_m = 1; _m <= max_m; _m++) { -+ div = _m * _p; -+ -+ if (div > maxdiv) -+ break; -+ -+ if (rate * div == parent_rate_saved) { -+ /* -+ * It's the most ideal case if the requested -+ * rate can be divided from parent clock without -+ * needing to change parent rate, so return the -+ * divider immediately. -+ */ -+ *parent = parent_rate_saved; -+ return rate; -+ } -+ -+ parent_rate = clk_hw_round_rate(hw, rate * div); -+ now = parent_rate / div; -+ -+ if (now <= rate && now > best_rate) { -+ best_rate = now; -+ *parent = parent_rate; -+ -+ if (now == rate) -+ return rate; -+ } -+ } -+ } -+ -+ return best_rate; -+} -+ - static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, - struct clk_hw *hw, - unsigned long *parent_rate, -@@ -56,8 +111,13 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, - max_m = cmp->m.max ?: 1 << cmp->m.width; - max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1); - -- ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p); -- rate = *parent_rate / p / m; -+ if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { -+ ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p); -+ rate = *parent_rate / p / m; -+ } else { -+ rate = ccu_mp_find_best_with_parent_adj(hw, parent_rate, rate, -+ max_m, max_p); -+ } - - if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate /= cmp->fixed_post_div; --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0087-drm-sun4i-tcon-Pass-drm_encoder-into-sun4i_tcon0_mod.patch b/patch/kernel/sunxi-legacy/0087-drm-sun4i-tcon-Pass-drm_encoder-into-sun4i_tcon0_mod.patch deleted file mode 100644 index 6e9d0fbf5..000000000 --- a/patch/kernel/sunxi-legacy/0087-drm-sun4i-tcon-Pass-drm_encoder-into-sun4i_tcon0_mod.patch +++ /dev/null @@ -1,66 +0,0 @@ -From af6d185a66b416cb714fb3f1602e8e3f5ca46632 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai -Date: Fri, 7 Sep 2018 12:19:43 +0800 -Subject: [PATCH 087/146] drm/sun4i: tcon: Pass drm_encoder * into - sun4i_tcon0_mode_set_cpu - -sun4i_tcon0_mode_set_cpu() currently accepts struct mipi_dsi_device * -as its second parameter. This is derived from drm_encoder. - -The DSI encoder is tied to the CPU interface mode of the TCON as a -special case. In theory, if hardware were available, we could also -support normal CPU interface modes. It is better to pass the generic -encoder instead of the specialized mipi_dsi_device, and handle the -differences inside the function. - -Passing the encoder would also enable the function to pass it, or any -other data structures related to it, to other functions expecting it. -One such example would be dithering support that will be added in a -later patch, which looks at properties tied to the connector to -determine whether dithering should be enabled or not. - -Signed-off-by: Chen-Yu Tsai ---- - drivers/gpu/drm/sun4i/sun4i_tcon.c | 15 ++++++--------- - 1 file changed, 6 insertions(+), 9 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c -index 3fb084f802e2..52e1150612ba 100644 ---- a/drivers/gpu/drm/sun4i/sun4i_tcon.c -+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c -@@ -276,9 +276,12 @@ static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon, - } - - static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon *tcon, -- struct mipi_dsi_device *device, -+ const struct drm_encoder *encoder, - const struct drm_display_mode *mode) - { -+ /* TODO support normal CPU interface modes */ -+ struct sun6i_dsi *dsi = encoder_to_sun6i_dsi(encoder); -+ struct mipi_dsi_device *device = dsi->device; - u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format); - u8 lanes = device->lanes; - u32 block_space, start_delay; -@@ -581,16 +584,10 @@ void sun4i_tcon_mode_set(struct sun4i_tcon *tcon, - const struct drm_encoder *encoder, - const struct drm_display_mode *mode) - { -- struct sun6i_dsi *dsi; -- - switch (encoder->encoder_type) { - case DRM_MODE_ENCODER_DSI: -- /* -- * This is not really elegant, but it's the "cleaner" -- * way I could think of... -- */ -- dsi = encoder_to_sun6i_dsi(encoder); -- sun4i_tcon0_mode_set_cpu(tcon, dsi->device, mode); -+ /* DSI is tied to special case of CPU interface */ -+ sun4i_tcon0_mode_set_cpu(tcon, encoder, mode); - break; - case DRM_MODE_ENCODER_LVDS: - sun4i_tcon0_mode_set_lvds(tcon, encoder, mode); --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0088-drm-sun4i-tcon-Rename-Dithering-related-register-mac.patch b/patch/kernel/sunxi-legacy/0088-drm-sun4i-tcon-Rename-Dithering-related-register-mac.patch deleted file mode 100644 index 3332362bc..000000000 --- a/patch/kernel/sunxi-legacy/0088-drm-sun4i-tcon-Rename-Dithering-related-register-mac.patch +++ /dev/null @@ -1,59 +0,0 @@ -From cf81b437511bf56512273c773013c40b11a01520 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai -Date: Fri, 7 Sep 2018 12:19:44 +0800 -Subject: [PATCH 088/146] drm/sun4i: tcon: Rename Dithering related register - macros - -Dithering is only supported for TCON channel 0. Throughout the datasheet -all the names associated with these register are prefixed "TCON0", -instead of "TCON". The only exception is the control register -"TCON_FRM_CTL_REG". - -Rename the macros to reflect this. - -Signed-off-by: Chen-Yu Tsai ---- - drivers/gpu/drm/sun4i/sun4i_tcon.h | 27 +++++++++++++++------------ - 1 file changed, 15 insertions(+), 12 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h -index f6a071cd5a6f..3d492c8be1fc 100644 ---- a/drivers/gpu/drm/sun4i/sun4i_tcon.h -+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h -@@ -37,18 +37,21 @@ - #define SUN4I_TCON_GINT1_REG 0x8 - - #define SUN4I_TCON_FRM_CTL_REG 0x10 --#define SUN4I_TCON_FRM_CTL_EN BIT(31) -- --#define SUN4I_TCON_FRM_SEED_PR_REG 0x14 --#define SUN4I_TCON_FRM_SEED_PG_REG 0x18 --#define SUN4I_TCON_FRM_SEED_PB_REG 0x1c --#define SUN4I_TCON_FRM_SEED_LR_REG 0x20 --#define SUN4I_TCON_FRM_SEED_LG_REG 0x24 --#define SUN4I_TCON_FRM_SEED_LB_REG 0x28 --#define SUN4I_TCON_FRM_TBL0_REG 0x2c --#define SUN4I_TCON_FRM_TBL1_REG 0x30 --#define SUN4I_TCON_FRM_TBL2_REG 0x34 --#define SUN4I_TCON_FRM_TBL3_REG 0x38 -+#define SUN4I_TCON0_FRM_CTL_EN BIT(31) -+#define SUN4I_TCON0_FRM_CTL_MODE_R BIT(6) -+#define SUN4I_TCON0_FRM_CTL_MODE_G BIT(5) -+#define SUN4I_TCON0_FRM_CTL_MODE_B BIT(4) -+ -+#define SUN4I_TCON0_FRM_SEED_PR_REG 0x14 -+#define SUN4I_TCON0_FRM_SEED_PG_REG 0x18 -+#define SUN4I_TCON0_FRM_SEED_PB_REG 0x1c -+#define SUN4I_TCON0_FRM_SEED_LR_REG 0x20 -+#define SUN4I_TCON0_FRM_SEED_LG_REG 0x24 -+#define SUN4I_TCON0_FRM_SEED_LB_REG 0x28 -+#define SUN4I_TCON0_FRM_TBL0_REG 0x2c -+#define SUN4I_TCON0_FRM_TBL1_REG 0x30 -+#define SUN4I_TCON0_FRM_TBL2_REG 0x34 -+#define SUN4I_TCON0_FRM_TBL3_REG 0x38 - - #define SUN4I_TCON0_CTL_REG 0x40 - #define SUN4I_TCON0_CTL_TCON_ENABLE BIT(31) --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0089-drm-sun4i-tcon-Add-dithering-support-for-RGB565-RGB6.patch b/patch/kernel/sunxi-legacy/0089-drm-sun4i-tcon-Add-dithering-support-for-RGB565-RGB6.patch deleted file mode 100644 index bff716f43..000000000 --- a/patch/kernel/sunxi-legacy/0089-drm-sun4i-tcon-Add-dithering-support-for-RGB565-RGB6.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 559d035001097a7ce6018117866e8f573fb15211 Mon Sep 17 00:00:00 2001 -From: Jonathan Liu -Date: Fri, 7 Sep 2018 12:19:45 +0800 -Subject: [PATCH 089/146] drm/sun4i: tcon: Add dithering support for - RGB565/RGB666 LCD panels - -The hardware supports dithering on TCON channel 0 which is used for LCD -panels. - -Dithering is a method of approximating a color from a mixture of other -colors when the required color isn't available. It reduces color -banding artifacts that can be observed when displaying gradients -(e.g. grayscale gradients). This may occur when the image that needs -to be displayed is 24-bit but the LCD panel is a lower bit depth and -does not perform dithering on its own. - -Signed-off-by: Jonathan Liu -[wens@csie.org: check display_info.bpc first; handle LVDS and MIPI DSI] -Signed-off-by: Chen-Yu Tsai ---- - drivers/gpu/drm/sun4i/sun4i_tcon.c | 62 ++++++++++++++++++++++++++++++ - 1 file changed, 62 insertions(+) - -diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c -index 52e1150612ba..0d438f633b5d 100644 ---- a/drivers/gpu/drm/sun4i/sun4i_tcon.c -+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c -@@ -12,11 +12,13 @@ - - #include - #include -+#include - #include - #include - #include - #include - #include -+#include - - #include - -@@ -275,6 +277,57 @@ static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon, - SUN4I_TCON0_BASIC0_Y(mode->crtc_vdisplay)); - } - -+static void sun4i_tcon0_mode_set_dithering(struct sun4i_tcon *tcon, -+ const struct drm_connector *connector) -+{ -+ u32 bus_format = 0; -+ u32 val = 0; -+ -+ /* XXX Would this ever happen? */ -+ if (!connector) -+ return; -+ -+ /* -+ * FIXME: Undocumented bits -+ * -+ * The whole dithering process and these parameters are not -+ * explained in the vendor documents or BSP kernel code. -+ */ -+ regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_PR_REG, 0x11111111); -+ regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_PG_REG, 0x11111111); -+ regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_PB_REG, 0x11111111); -+ regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_LR_REG, 0x11111111); -+ regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_LG_REG, 0x11111111); -+ regmap_write(tcon->regs, SUN4I_TCON0_FRM_SEED_LB_REG, 0x11111111); -+ regmap_write(tcon->regs, SUN4I_TCON0_FRM_TBL0_REG, 0x01010000); -+ regmap_write(tcon->regs, SUN4I_TCON0_FRM_TBL1_REG, 0x15151111); -+ regmap_write(tcon->regs, SUN4I_TCON0_FRM_TBL2_REG, 0x57575555); -+ regmap_write(tcon->regs, SUN4I_TCON0_FRM_TBL3_REG, 0x7f7f7777); -+ -+ /* Do dithering if panel only supports 6 bits per color */ -+ if (connector->display_info.bpc == 6) -+ val |= SUN4I_TCON0_FRM_CTL_EN; -+ -+ if (connector->display_info.num_bus_formats == 1) -+ bus_format = connector->display_info.bus_formats[0]; -+ -+ /* Check the connection format */ -+ switch (bus_format) { -+ case MEDIA_BUS_FMT_RGB565_1X16: -+ /* R and B components are only 5 bits deep */ -+ val |= SUN4I_TCON0_FRM_CTL_MODE_R; -+ val |= SUN4I_TCON0_FRM_CTL_MODE_B; -+ case MEDIA_BUS_FMT_RGB666_1X18: -+ case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: -+ /* Fall through: enable dithering */ -+ val |= SUN4I_TCON0_FRM_CTL_EN; -+ break; -+ } -+ -+ /* Write dithering settings */ -+ regmap_write(tcon->regs, SUN4I_TCON_FRM_CTL_REG, val); -+} -+ - static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon *tcon, - const struct drm_encoder *encoder, - const struct drm_display_mode *mode) -@@ -292,6 +345,9 @@ static void sun4i_tcon0_mode_set_cpu(struct sun4i_tcon *tcon, - - sun4i_tcon0_mode_set_common(tcon, mode); - -+ /* Set dithering if needed */ -+ sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder)); -+ - regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG, - SUN4I_TCON0_CTL_IF_MASK, - SUN4I_TCON0_CTL_IF_8080); -@@ -357,6 +413,9 @@ static void sun4i_tcon0_mode_set_lvds(struct sun4i_tcon *tcon, - tcon->dclk_max_div = 7; - sun4i_tcon0_mode_set_common(tcon, mode); - -+ /* Set dithering if needed */ -+ sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder)); -+ - /* Adjust clock delay */ - clk_delay = sun4i_tcon_get_clk_delay(mode, 0); - regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG, -@@ -430,6 +489,9 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, - tcon->dclk_max_div = 127; - sun4i_tcon0_mode_set_common(tcon, mode); - -+ /* Set dithering if needed */ -+ sun4i_tcon0_mode_set_dithering(tcon, tcon->panel->connector); -+ - /* Adjust clock delay */ - clk_delay = sun4i_tcon_get_clk_delay(mode, 0); - regmap_update_bits(tcon->regs, SUN4I_TCON0_CTL_REG, --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0090-drm-sun4i-tcon-prevent-tcon-panel-dereference-if-nul.patch b/patch/kernel/sunxi-legacy/0090-drm-sun4i-tcon-prevent-tcon-panel-dereference-if-nul.patch deleted file mode 100644 index a35a7f57b..000000000 --- a/patch/kernel/sunxi-legacy/0090-drm-sun4i-tcon-prevent-tcon-panel-dereference-if-nul.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 99b4088bcefec2a055c1d7caa1f135168405ccf1 Mon Sep 17 00:00:00 2001 -From: Giulio Benetti -Date: Tue, 2 Oct 2018 23:59:17 +0200 -Subject: [PATCH 090/146] drm/sun4i: tcon: prevent tcon->panel dereference if - null - -If using tcon with VGA, tcon->panel will be null(0), this will cause -segmentation fault when trying to dereference tcon->panel->connector. - -Add tcon->panel null check before calling -sun4i_tcon0_mode_set_dithering(). - -Signed-off-by: Giulio Benetti ---- - drivers/gpu/drm/sun4i/sun4i_tcon.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c -index 0d438f633b5d..1b28fd9c2908 100644 ---- a/drivers/gpu/drm/sun4i/sun4i_tcon.c -+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c -@@ -490,7 +490,8 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, - sun4i_tcon0_mode_set_common(tcon, mode); - - /* Set dithering if needed */ -- sun4i_tcon0_mode_set_dithering(tcon, tcon->panel->connector); -+ if (tcon->panel) -+ sun4i_tcon0_mode_set_dithering(tcon, tcon->panel->connector); - - /* Adjust clock delay */ - clk_delay = sun4i_tcon_get_clk_delay(mode, 0); --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0091-clk-sunxi-ng-a64-Add-minimal-rate-for-video-PLLs.patch b/patch/kernel/sunxi-legacy/0091-clk-sunxi-ng-a64-Add-minimal-rate-for-video-PLLs.patch deleted file mode 100644 index b55b2b501..000000000 --- a/patch/kernel/sunxi-legacy/0091-clk-sunxi-ng-a64-Add-minimal-rate-for-video-PLLs.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 8a348934a01914c7e6ada897d7ba121209961032 Mon Sep 17 00:00:00 2001 -From: Jagan Teki -Date: Tue, 4 Sep 2018 12:40:43 +0800 -Subject: [PATCH 091/146] clk: sunxi-ng: a64: Add minimal rate for video PLLs - -According to documentation and experience with other similar SoCs, video -PLLs don't work stable if their output frequency is set below 192 MHz. - -Because of that, set minimal rate to both A64 video PLLs to 192 MHz. - -Signed-off-by: Jagan Teki -Signed-off-by: Icenowy Zheng -Reviewed-by: Jernej Skrabec ---- - drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 46 ++++++++++++++------------- - 1 file changed, 24 insertions(+), 22 deletions(-) - -diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c -index 7c645f2c017a..40a7b5fd091c 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c -+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c -@@ -64,17 +64,18 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", - BIT(28), /* lock */ - CLK_SET_RATE_UNGATE); - --static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0", -- "osc24M", 0x010, -- 8, 7, /* N */ -- 0, 4, /* M */ -- BIT(24), /* frac enable */ -- BIT(25), /* frac select */ -- 270000000, /* frac rate 0 */ -- 297000000, /* frac rate 1 */ -- BIT(31), /* gate */ -- BIT(28), /* lock */ -- CLK_SET_RATE_UNGATE); -+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video0_clk, "pll-video0", -+ "osc24M", 0x010, -+ 192000000, /* Minimum rate */ -+ 8, 7, /* N */ -+ 0, 4, /* M */ -+ BIT(24), /* frac enable */ -+ BIT(25), /* frac select */ -+ 270000000, /* frac rate 0 */ -+ 297000000, /* frac rate 1 */ -+ BIT(31), /* gate */ -+ BIT(28), /* lock */ -+ CLK_SET_RATE_UNGATE); - - static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", - "osc24M", 0x018, -@@ -125,17 +126,18 @@ static struct ccu_nk pll_periph1_clk = { - }, - }; - --static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1", -- "osc24M", 0x030, -- 8, 7, /* N */ -- 0, 4, /* M */ -- BIT(24), /* frac enable */ -- BIT(25), /* frac select */ -- 270000000, /* frac rate 0 */ -- 297000000, /* frac rate 1 */ -- BIT(31), /* gate */ -- BIT(28), /* lock */ -- CLK_SET_RATE_UNGATE); -+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video1_clk, "pll-video1", -+ "osc24M", 0x030, -+ 192000000, /* Minimum rate */ -+ 8, 7, /* N */ -+ 0, 4, /* M */ -+ BIT(24), /* frac enable */ -+ BIT(25), /* frac select */ -+ 270000000, /* frac rate 0 */ -+ 297000000, /* frac rate 1 */ -+ BIT(31), /* gate */ -+ BIT(28), /* lock */ -+ CLK_SET_RATE_UNGATE); - - static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu", - "osc24M", 0x038, --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0092-clk-sunxi-ng-a64-Add-max.-rate-constraint-to-video-P.patch b/patch/kernel/sunxi-legacy/0092-clk-sunxi-ng-a64-Add-max.-rate-constraint-to-video-P.patch deleted file mode 100644 index c15f791b6..000000000 --- a/patch/kernel/sunxi-legacy/0092-clk-sunxi-ng-a64-Add-max.-rate-constraint-to-video-P.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 99ce6e04231a5a185c1cc7d8d2bd9484c8eabc56 Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Tue, 4 Sep 2018 12:40:44 +0800 -Subject: [PATCH 092/146] clk: sunxi-ng: a64: Add max. rate constraint to video - PLLs - -Video PLLs on A64 can be set to higher rate that it is actually -supported by HW. - -Limit maximum rate to 1008 MHz. This is the maximum allowed rate by BSP -clock driver. Interestengly, user manual specifies maximum frequency to -be 600 MHz. Historically, this data was wrong in some user manuals for -other SoCs, so more faith is put in BSP clock driver. - -Signed-off-by: Icenowy Zheng ---- - drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 50 ++++++++++++++------------- - 1 file changed, 26 insertions(+), 24 deletions(-) - -diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c -index 40a7b5fd091c..90ffee824c33 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c -+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c -@@ -64,18 +64,19 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", - BIT(28), /* lock */ - CLK_SET_RATE_UNGATE); - --static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video0_clk, "pll-video0", -- "osc24M", 0x010, -- 192000000, /* Minimum rate */ -- 8, 7, /* N */ -- 0, 4, /* M */ -- BIT(24), /* frac enable */ -- BIT(25), /* frac select */ -- 270000000, /* frac rate 0 */ -- 297000000, /* frac rate 1 */ -- BIT(31), /* gate */ -- BIT(28), /* lock */ -- CLK_SET_RATE_UNGATE); -+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, "pll-video0", -+ "osc24M", 0x010, -+ 192000000, /* Minimum rate */ -+ 1008000000, /* Maximum rate */ -+ 8, 7, /* N */ -+ 0, 4, /* M */ -+ BIT(24), /* frac enable */ -+ BIT(25), /* frac select */ -+ 270000000, /* frac rate 0 */ -+ 297000000, /* frac rate 1 */ -+ BIT(31), /* gate */ -+ BIT(28), /* lock */ -+ CLK_SET_RATE_UNGATE); - - static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", - "osc24M", 0x018, -@@ -126,18 +127,19 @@ static struct ccu_nk pll_periph1_clk = { - }, - }; - --static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video1_clk, "pll-video1", -- "osc24M", 0x030, -- 192000000, /* Minimum rate */ -- 8, 7, /* N */ -- 0, 4, /* M */ -- BIT(24), /* frac enable */ -- BIT(25), /* frac select */ -- 270000000, /* frac rate 0 */ -- 297000000, /* frac rate 1 */ -- BIT(31), /* gate */ -- BIT(28), /* lock */ -- CLK_SET_RATE_UNGATE); -+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video1_clk, "pll-video1", -+ "osc24M", 0x030, -+ 192000000, /* Minimum rate */ -+ 1008000000, /* Maximum rate */ -+ 8, 7, /* N */ -+ 0, 4, /* M */ -+ BIT(24), /* frac enable */ -+ BIT(25), /* frac select */ -+ 270000000, /* frac rate 0 */ -+ 297000000, /* frac rate 1 */ -+ BIT(31), /* gate */ -+ BIT(28), /* lock */ -+ CLK_SET_RATE_UNGATE); - - static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu", - "osc24M", 0x038, --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0093-dt-bindings-display-Add-compatible-for-A64-DE2-displ.patch b/patch/kernel/sunxi-legacy/0093-dt-bindings-display-Add-compatible-for-A64-DE2-displ.patch deleted file mode 100644 index 5f607c3f5..000000000 --- a/patch/kernel/sunxi-legacy/0093-dt-bindings-display-Add-compatible-for-A64-DE2-displ.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 3c133c6aa20eacb1b7f77e6b3136d483fdd80582 Mon Sep 17 00:00:00 2001 -From: Jagan Teki -Date: Tue, 4 Sep 2018 12:40:45 +0800 -Subject: [PATCH 093/146] dt-bindings: display: Add compatible for A64 DE2 - display pipeline - -Allwinner A64 has a DE2 display pipeline. The TCONs are similar to the -ones in A83T, but the mixers are new (similar to the later R40 SoC). - -This patch adds dt-binding documentation for A64 DE2 display pipeline. - -Signed-off-by: Jagan Teki -Reviewed-by: Rob Herring -[Icenowy: Refactor and also cover TCON1] -Signed-off-by: Icenowy Zheng ---- - .../devicetree/bindings/display/sunxi/sun4i-drm.txt | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt -index f8773ecb7525..7b79c5e3dffc 100644 ---- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt -+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt -@@ -151,6 +151,8 @@ Required properties: - * allwinner,sun8i-v3s-tcon - * allwinner,sun9i-a80-tcon-lcd - * allwinner,sun9i-a80-tcon-tv -+ * "allwinner,sun50i-a64-tcon-lcd", "allwinner,sun8i-a83t-tcon-lcd" -+ * "allwinner,sun50i-a64-tcon-tv", "allwinner,sun8i-a83t-tcon-tv" - - reg: base address and size of memory-mapped region - - interrupts: interrupt associated to this IP - - clocks: phandles to the clocks feeding the TCON. -@@ -370,6 +372,8 @@ Required properties: - * allwinner,sun8i-a83t-de2-mixer-1 - * allwinner,sun8i-h3-de2-mixer-0 - * allwinner,sun8i-v3s-de2-mixer -+ * allwinner,sun50i-a64-de2-mixer-0 -+ * allwinner,sun50i-a64-de2-mixer-1 - - reg: base address and size of the memory-mapped region. - - clocks: phandles to the clocks feeding the mixer - * bus: the mixer interface clock -@@ -403,6 +407,7 @@ Required properties: - * allwinner,sun8i-r40-display-engine - * allwinner,sun8i-v3s-display-engine - * allwinner,sun9i-a80-display-engine -+ * allwinner,sun50i-a64-display-engine - - - allwinner,pipelines: list of phandle to the display engine - frontends (DE 1.0) or mixers (DE 2.0) available. --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0094-drm-sun4i-Add-support-for-A64-mixers.patch b/patch/kernel/sunxi-legacy/0094-drm-sun4i-Add-support-for-A64-mixers.patch deleted file mode 100644 index b13df124c..000000000 --- a/patch/kernel/sunxi-legacy/0094-drm-sun4i-Add-support-for-A64-mixers.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 06cbcf31db7e0f3604f248e1731a0f316837cd64 Mon Sep 17 00:00:00 2001 -From: Jagan Teki -Date: Tue, 4 Sep 2018 12:40:46 +0800 -Subject: [PATCH 094/146] drm/sun4i: Add support for A64 mixers - -Mixers in Allwinner have similar capabilities as others SoCs with DE2. - -Add support for them. - -Signed-off-by: Jagan Teki -[Icenowy: Add mixer1] -Signed-off-by: Icenowy Zheng -Reviewed-by: Jernej Skrabec ---- - drivers/gpu/drm/sun4i/sun8i_mixer.c | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c -index cb65b0ed53fd..091f6cf40353 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_mixer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c -@@ -553,6 +553,22 @@ static const struct sun8i_mixer_cfg sun8i_v3s_mixer_cfg = { - .mod_rate = 150000000, - }; - -+static const struct sun8i_mixer_cfg sun50i_a64_mixer0_cfg = { -+ .ccsc = 0, -+ .mod_rate = 297000000, -+ .scaler_mask = 0xf, -+ .ui_num = 3, -+ .vi_num = 1, -+}; -+ -+static const struct sun8i_mixer_cfg sun50i_a64_mixer1_cfg = { -+ .ccsc = 1, -+ .mod_rate = 297000000, -+ .scaler_mask = 0x3, -+ .ui_num = 1, -+ .vi_num = 1, -+}; -+ - static const struct of_device_id sun8i_mixer_of_table[] = { - { - .compatible = "allwinner,sun8i-a83t-de2-mixer-0", -@@ -570,6 +586,14 @@ static const struct of_device_id sun8i_mixer_of_table[] = { - .compatible = "allwinner,sun8i-v3s-de2-mixer", - .data = &sun8i_v3s_mixer_cfg, - }, -+ { -+ .compatible = "allwinner,sun50i-a64-de2-mixer-0", -+ .data = &sun50i_a64_mixer0_cfg, -+ }, -+ { -+ .compatible = "allwinner,sun50i-a64-de2-mixer-1", -+ .data = &sun50i_a64_mixer1_cfg, -+ }, - { } - }; - MODULE_DEVICE_TABLE(of, sun8i_mixer_of_table); --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0095-drm-sun4i-Add-support-for-A64-display-engine.patch b/patch/kernel/sunxi-legacy/0095-drm-sun4i-Add-support-for-A64-display-engine.patch deleted file mode 100644 index 99e0b6238..000000000 --- a/patch/kernel/sunxi-legacy/0095-drm-sun4i-Add-support-for-A64-display-engine.patch +++ /dev/null @@ -1,33 +0,0 @@ -From dd3d2cbe3b5312585fd0c525d0515ef0493192fa Mon Sep 17 00:00:00 2001 -From: Jagan Teki -Date: Tue, 4 Sep 2018 12:40:47 +0800 -Subject: [PATCH 095/146] drm/sun4i: Add support for A64 display engine - -Display Engine(DE2) in Allwinner A64 has two mixers and tcons. - -The routing for mixer0 is through tcon0 and connected to -LVDS/RGB/MIPI-DSI controller. - -The routing for mixer1 is through tcon1 and connected to HDMI. - -Signed-off-by: Jagan Teki -Signed-off-by: Icenowy Zheng ---- - drivers/gpu/drm/sun4i/sun4i_drv.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c -index 9f5de14fb2fe..486ae8507ae9 100644 ---- a/drivers/gpu/drm/sun4i/sun4i_drv.c -+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c -@@ -447,6 +447,7 @@ static const struct of_device_id sun4i_drv_of_table[] = { - { .compatible = "allwinner,sun8i-h3-display-engine" }, - { .compatible = "allwinner,sun8i-v3s-display-engine" }, - { .compatible = "allwinner,sun9i-a80-display-engine" }, -+ { .compatible = "allwinner,sun50i-a64-display-engine" }, - { } - }; - MODULE_DEVICE_TABLE(of, sun4i_drv_of_table); --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0096-dt-bindings-display-Add-compatible-for-A64-HDMI.patch b/patch/kernel/sunxi-legacy/0096-dt-bindings-display-Add-compatible-for-A64-HDMI.patch deleted file mode 100644 index 19ee6a52e..000000000 --- a/patch/kernel/sunxi-legacy/0096-dt-bindings-display-Add-compatible-for-A64-HDMI.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 9985b7ab016e7dd192c717de1f0431e1e66212d9 Mon Sep 17 00:00:00 2001 -From: Jagan Teki -Date: Tue, 4 Sep 2018 12:40:48 +0800 -Subject: [PATCH 096/146] dt-bindings: display: Add compatible for A64 HDMI - -The HDMI controller on Allwinner A64 is similar on the one on -H3/H5/A83T (although the PHY is different with A83T). - -Add A64 compatible and append A83T compatible as fallback. - -Signed-off-by: Jagan Teki -Reviewed-by: Rob Herring -[Icenowy: refactor commit log] -Signed-off-by: Icenowy Zheng ---- - Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt -index 7b79c5e3dffc..fdb8fb29033f 100644 ---- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt -+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt -@@ -78,6 +78,7 @@ Required properties: - - - compatible: value must be one of: - * "allwinner,sun8i-a83t-dw-hdmi" -+ * "allwinner,sun50i-a64-dw-hdmi", "allwinner,sun8i-a83t-dw-hdmi" - - reg: base address and size of memory-mapped region - - reg-io-width: See dw_hdmi.txt. Shall be 1. - - interrupts: HDMI interrupt number --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0097-dt-bindings-clock-sun50i-a64-ccu-Add-PLL_VIDEO0-macr.patch b/patch/kernel/sunxi-legacy/0097-dt-bindings-clock-sun50i-a64-ccu-Add-PLL_VIDEO0-macr.patch deleted file mode 100644 index bf1ec2ae9..000000000 --- a/patch/kernel/sunxi-legacy/0097-dt-bindings-clock-sun50i-a64-ccu-Add-PLL_VIDEO0-macr.patch +++ /dev/null @@ -1,49 +0,0 @@ -From b82507436dc7629f7a1e0ec8fffac4aa42e3c81d Mon Sep 17 00:00:00 2001 -From: Jagan Teki -Date: Tue, 4 Sep 2018 12:40:49 +0800 -Subject: [PATCH 097/146] dt-bindings: clock: sun50i-a64-ccu: Add PLL_VIDEO0 - macro - -Allwinner A64 HDMI PHY clock has PLL_VIDEO0 as a parent. - -Include the macro on dt-bindings so-that the same can be used -while defining CCU clock phandles. - -Signed-off-by: Jagan Teki -Reviewed-by: Rob Herring -Signed-off-by: Icenowy Zheng ---- - drivers/clk/sunxi-ng/ccu-sun50i-a64.h | 4 +++- - include/dt-bindings/clock/sun50i-a64-ccu.h | 1 + - 2 files changed, 4 insertions(+), 1 deletion(-) - -diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h -index 91f79512cee4..704f038a8496 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h -+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h -@@ -27,7 +27,9 @@ - #define CLK_PLL_AUDIO_2X 4 - #define CLK_PLL_AUDIO_4X 5 - #define CLK_PLL_AUDIO_8X 6 --#define CLK_PLL_VIDEO0 7 -+ -+/* PLL_VIDEO0 exported for HDMI PHY */ -+ - #define CLK_PLL_VIDEO0_2X 8 - #define CLK_PLL_VE 9 - #define CLK_PLL_DDR0 10 -diff --git a/include/dt-bindings/clock/sun50i-a64-ccu.h b/include/dt-bindings/clock/sun50i-a64-ccu.h -index d7f42dd22663..e512a1c9b0fc 100644 ---- a/include/dt-bindings/clock/sun50i-a64-ccu.h -+++ b/include/dt-bindings/clock/sun50i-a64-ccu.h -@@ -43,6 +43,7 @@ - #ifndef _DT_BINDINGS_CLK_SUN50I_A64_H_ - #define _DT_BINDINGS_CLK_SUN50I_A64_H_ - -+#define CLK_PLL_VIDEO0 7 - #define CLK_PLL_PERIPH0 11 - - #define CLK_CPUX 21 --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0098-arm64-dts-allwinner-a64-Add-display-pipeline.patch b/patch/kernel/sunxi-legacy/0098-arm64-dts-allwinner-a64-Add-display-pipeline.patch deleted file mode 100644 index a70ec6448..000000000 --- a/patch/kernel/sunxi-legacy/0098-arm64-dts-allwinner-a64-Add-display-pipeline.patch +++ /dev/null @@ -1,221 +0,0 @@ -From 38727062e2758832418fbf250f327e5e916f877e Mon Sep 17 00:00:00 2001 -From: Jagan Teki -Date: Tue, 4 Sep 2018 12:40:50 +0800 -Subject: [PATCH 098/146] arm64: dts: allwinner: a64: Add display pipeline - -Allwinner A64 have a display pipeline with 2 mixers/TCONs, the first -TCON is connected to LCD and the second is to HDMI. - -The HDMI controller/PHY pair is similar to the one on H3/H5. - -Add all required device tree nodes of the display pipeline, including -the TCON0 LCD one and the TCON1 HDMI one. - -Signed-off-by: Jagan Teki -[Icenowy: refactor commit message and add 1st pipeline] -Signed-off-by: Icenowy Zheng ---- - arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 166 ++++++++++++++++++ - 1 file changed, 166 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -index 73f7e69755f8..132da408aa52 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -@@ -166,6 +166,13 @@ - }; - }; - -+ de: display-engine { -+ compatible = "allwinner,sun50i-a64-display-engine"; -+ allwinner,pipelines = <&mixer0>, -+ <&mixer1>; -+ status = "disabled"; -+ }; -+ - osc24M: osc24M_clk { - #clock-cells = <0>; - compatible = "fixed-clock"; -@@ -317,6 +324,52 @@ - #clock-cells = <1>; - #reset-cells = <1>; - }; -+ -+ mixer0: mixer@100000 { -+ compatible = "allwinner,sun50i-a64-de2-mixer-0"; -+ reg = <0x100000 0x100000>; -+ clocks = <&display_clocks CLK_BUS_MIXER0>, -+ <&display_clocks CLK_MIXER0>; -+ clock-names = "bus", -+ "mod"; -+ resets = <&display_clocks RST_MIXER0>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ mixer0_out: port@1 { -+ reg = <1>; -+ -+ mixer0_out_tcon0: endpoint { -+ remote-endpoint = <&tcon0_in_mixer0>; -+ }; -+ }; -+ }; -+ }; -+ -+ mixer1: mixer@200000 { -+ compatible = "allwinner,sun50i-a64-de2-mixer-1"; -+ reg = <0x200000 0x100000>; -+ clocks = <&display_clocks CLK_BUS_MIXER1>, -+ <&display_clocks CLK_MIXER1>; -+ clock-names = "bus", -+ "mod"; -+ resets = <&display_clocks RST_MIXER1>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ mixer1_out: port@1 { -+ reg = <1>; -+ -+ mixer1_out_tcon1: endpoint { -+ remote-endpoint = <&tcon1_in_mixer1>; -+ }; -+ }; -+ }; -+ }; - }; - - syscon: syscon@1c00000 { -@@ -351,6 +404,75 @@ - #dma-cells = <1>; - }; - -+ tcon0: lcd-controller@1c0c000 { -+ compatible = "allwinner,sun50i-a64-tcon-lcd", -+ "allwinner,sun8i-a83t-tcon-lcd"; -+ reg = <0x01c0c000 0x1000>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_TCON0>, <&ccu CLK_TCON0>; -+ clock-names = "ahb", "tcon-ch0"; -+ clock-output-names = "tcon-pixel-clock"; -+ resets = <&ccu RST_BUS_TCON0>, <&ccu RST_BUS_LVDS>; -+ reset-names = "lcd", "lvds"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ tcon0_in: port@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ -+ tcon0_in_mixer0: endpoint@0 { -+ reg = <0>; -+ remote-endpoint = <&mixer0_out_tcon0>; -+ }; -+ }; -+ -+ tcon0_out: port@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ }; -+ }; -+ }; -+ -+ tcon1: lcd-controller@1c0d000 { -+ compatible = "allwinner,sun50i-a64-tcon-tv", -+ "allwinner,sun8i-a83t-tcon-tv"; -+ reg = <0x01c0d000 0x1000>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_TCON1>, <&ccu CLK_TCON1>; -+ clock-names = "ahb", "tcon-ch1"; -+ resets = <&ccu RST_BUS_TCON1>; -+ reset-names = "lcd"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ tcon1_in: port@0 { -+ reg = <0>; -+ -+ tcon1_in_mixer1: endpoint { -+ remote-endpoint = <&mixer1_out_tcon1>; -+ }; -+ }; -+ -+ tcon1_out: port@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ -+ tcon1_out_hdmi: endpoint@1 { -+ reg = <1>; -+ remote-endpoint = <&hdmi_in_tcon1>; -+ }; -+ }; -+ }; -+ }; -+ - mmc0: mmc@1c0f000 { - compatible = "allwinner,sun50i-a64-mmc"; - reg = <0x01c0f000 0x1000>; -@@ -860,6 +982,50 @@ - status = "disabled"; - }; - -+ hdmi: hdmi@1ee0000 { -+ compatible = "allwinner,sun50i-a64-dw-hdmi", -+ "allwinner,sun8i-a83t-dw-hdmi"; -+ reg = <0x01ee0000 0x10000>; -+ reg-io-width = <1>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_DDC>, -+ <&ccu CLK_HDMI>; -+ clock-names = "iahb", "isfr", "tmds"; -+ resets = <&ccu RST_BUS_HDMI1>; -+ reset-names = "ctrl"; -+ phys = <&hdmi_phy>; -+ phy-names = "hdmi-phy"; -+ status = "disabled"; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ hdmi_in: port@0 { -+ reg = <0>; -+ -+ hdmi_in_tcon1: endpoint { -+ remote-endpoint = <&tcon1_out_hdmi>; -+ }; -+ }; -+ -+ hdmi_out: port@1 { -+ reg = <1>; -+ }; -+ }; -+ }; -+ -+ hdmi_phy: hdmi-phy@1ef0000 { -+ compatible = "allwinner,sun8i-h3-hdmi-phy"; -+ reg = <0x01ef0000 0x10000>; -+ clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_DDC>, -+ <&ccu 7>; -+ clock-names = "bus", "mod", "pll-0"; -+ resets = <&ccu RST_BUS_HDMI0>; -+ reset-names = "phy"; -+ #phy-cells = <0>; -+ }; -+ - sound_hdmi: sound_hdmi { - compatible = "simple-audio-card"; - simple-audio-card,format = "i2s"; --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0099-dt-bindings-sun4i-drm-add-HDMI-VCC-supply-property-f.patch b/patch/kernel/sunxi-legacy/0099-dt-bindings-sun4i-drm-add-HDMI-VCC-supply-property-f.patch deleted file mode 100644 index a8e0639fd..000000000 --- a/patch/kernel/sunxi-legacy/0099-dt-bindings-sun4i-drm-add-HDMI-VCC-supply-property-f.patch +++ /dev/null @@ -1,33 +0,0 @@ -From d2deb88ff41a528b4c35f1f6e344e6a097eabedd Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Tue, 4 Sep 2018 12:40:51 +0800 -Subject: [PATCH 099/146] dt-bindings: sun4i-drm: add HDMI VCC supply property - for sun8i-dw-hdmi - -Allwiner SoCs with DesignWare HDMI controller all come with a "HVCC" -pin, which is the VCC of HDMI part. - -Add a supply property to specify HVCC's regulator in the device tree. - -Signed-off-by: Icenowy Zheng ---- - Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt -index fdb8fb29033f..0bbb5d47f228 100644 ---- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt -+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt -@@ -97,6 +97,9 @@ Required properties: - first port should be the input endpoint. The second should be the - output, usually to an HDMI connector. - -+Optional properties: -+ - hvcc-supply: the VCC power supply of the controller -+ - DWC HDMI PHY - ------------ - --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0100-drm-sun4i-Add-support-for-HDMI-voltage-regulator.patch b/patch/kernel/sunxi-legacy/0100-drm-sun4i-Add-support-for-HDMI-voltage-regulator.patch deleted file mode 100644 index d5a343bb1..000000000 --- a/patch/kernel/sunxi-legacy/0100-drm-sun4i-Add-support-for-HDMI-voltage-regulator.patch +++ /dev/null @@ -1,87 +0,0 @@ -From f50ad947fd638dc7dde8afb54db743dfc5db6177 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Tue, 4 Sep 2018 12:40:52 +0800 -Subject: [PATCH 100/146] drm/sun4i: Add support for HDMI voltage regulator - -Some boards have HDMI VCC pin connected to voltage regulator which may -not be turned on by default. - -Add support for such boards by adding voltage regulator handling code to -HDMI driver. - -Signed-off-by: Jernej Skrabec -[Icenowy: change supply name to "hvcc"] -Signed-off-by: Icenowy Zheng ---- - drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 17 ++++++++++++++++- - drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 2 ++ - 2 files changed, 18 insertions(+), 1 deletion(-) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c -index 31875b636434..ed2983770e9c 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c -+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c -@@ -125,10 +125,22 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, - return PTR_ERR(hdmi->clk_tmds); - } - -+ hdmi->regulator = devm_regulator_get(dev, "hvcc"); -+ if (IS_ERR(hdmi->regulator)) { -+ dev_err(dev, "Couldn't get regulator\n"); -+ return PTR_ERR(hdmi->regulator); -+ } -+ -+ ret = regulator_enable(hdmi->regulator); -+ if (ret) { -+ dev_err(dev, "Failed to enable regulator\n"); -+ return ret; -+ } -+ - ret = reset_control_deassert(hdmi->rst_ctrl); - if (ret) { - dev_err(dev, "Could not deassert ctrl reset control\n"); -- return ret; -+ goto err_disable_regulator; - } - - ret = clk_prepare_enable(hdmi->clk_tmds); -@@ -183,6 +195,8 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, - clk_disable_unprepare(hdmi->clk_tmds); - err_assert_ctrl_reset: - reset_control_assert(hdmi->rst_ctrl); -+err_disable_regulator: -+ regulator_disable(hdmi->regulator); - - return ret; - } -@@ -196,6 +210,7 @@ static void sun8i_dw_hdmi_unbind(struct device *dev, struct device *master, - sun8i_hdmi_phy_remove(hdmi); - clk_disable_unprepare(hdmi->clk_tmds); - reset_control_assert(hdmi->rst_ctrl); -+ regulator_disable(hdmi->regulator); - } - - static const struct component_ops sun8i_dw_hdmi_ops = { -diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h -index aadbe0a10b0c..7fdc1ecd2892 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h -+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - #include - - #define SUN8I_HDMI_PHY_DBG_CTRL_REG 0x0000 -@@ -176,6 +177,7 @@ struct sun8i_dw_hdmi { - struct drm_encoder encoder; - struct sun8i_hdmi_phy *phy; - struct dw_hdmi_plat_data plat_data; -+ struct regulator *regulator; - struct reset_control *rst_ctrl; - }; - --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0101-arm64-dts-allwinner-a64-Enable-HDMI-output-on-A64-bo.patch b/patch/kernel/sunxi-legacy/0101-arm64-dts-allwinner-a64-Enable-HDMI-output-on-A64-bo.patch index 2b1729a59..56ed5643c 100644 --- a/patch/kernel/sunxi-legacy/0101-arm64-dts-allwinner-a64-Enable-HDMI-output-on-A64-bo.patch +++ b/patch/kernel/sunxi-legacy/0101-arm64-dts-allwinner-a64-Enable-HDMI-output-on-A64-bo.patch @@ -22,241 +22,6 @@ Tested-by: Vasily Khoruzhick .../allwinner/sun50i-a64-sopine-baseboard.dts | 26 ++++++++++++++++++ 7 files changed, 185 insertions(+) -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts -index 094cfed13df9..c3cb0aa6ae83 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts -@@ -60,6 +60,17 @@ - stdout-path = "serial0:115200n8"; - }; - -+ hdmi-connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_con_in: endpoint { -+ remote-endpoint = <&hdmi_out_con>; -+ }; -+ }; -+ }; -+ - leds { - compatible = "gpio-leds"; - -@@ -86,6 +97,10 @@ - }; - }; - -+&de { -+ status = "okay"; -+}; -+ - &ehci0 { - status = "okay"; - }; -@@ -103,6 +118,17 @@ - status = "okay"; - }; - -+&hdmi { -+ hvcc-supply = <®_dldo1>; -+ status = "okay"; -+}; -+ -+&hdmi_out { -+ hdmi_out_con: endpoint { -+ remote-endpoint = <&hdmi_con_in>; -+ }; -+}; -+ - &i2c1 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c1_pins>; -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts -index 98dbff19f5cc..f9fa87834b07 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts -@@ -57,6 +57,22 @@ - chosen { - stdout-path = "serial0:115200n8"; - }; -+ -+ hdmi-connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_con_in: endpoint { -+ remote-endpoint = <&hdmi_out_con>; -+ }; -+ }; -+ }; -+ -+}; -+ -+&de { -+ status = "okay"; - }; - - &ehci0 { -@@ -67,6 +83,17 @@ - status = "okay"; - }; - -+&hdmi { -+ hvcc-supply = <®_dldo1>; -+ status = "okay"; -+}; -+ -+&hdmi_out { -+ hdmi_out_con: endpoint { -+ remote-endpoint = <&hdmi_con_in>; -+ }; -+}; -+ - /* i2c1 connected with gpio headers like pine64, bananapi */ - &i2c1 { - pinctrl-names = "default"; -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts -index 3f531393eaee..d1c713520ad5 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts -@@ -58,12 +58,38 @@ - stdout-path = "serial0:115200n8"; - }; - -+ hdmi-connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_con_in: endpoint { -+ remote-endpoint = <&hdmi_out_con>; -+ }; -+ }; -+ }; -+ - wifi_pwrseq: wifi_pwrseq { - compatible = "mmc-pwrseq-simple"; - reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */ - }; - }; - -+&de { -+ status = "okay"; -+}; -+ -+&hdmi { -+ hvcc-supply = <®_dldo1>; -+ status = "okay"; -+}; -+ -+&hdmi_out { -+ hdmi_out_con: endpoint { -+ remote-endpoint = <&hdmi_con_in>; -+ }; -+}; -+ - &mmc0 { - pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins>; -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts -index 1221764f5719..08d96ca9f4da 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts -@@ -57,12 +57,39 @@ - chosen { - stdout-path = "serial0:115200n8"; - }; -+ -+ hdmi-connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_con_in: endpoint { -+ remote-endpoint = <&hdmi_out_con>; -+ }; -+ }; -+ }; -+ -+}; -+ -+&de { -+ status = "okay"; - }; - - &ehci1 { - status = "okay"; - }; - -+&hdmi { -+ hvcc-supply = <®_dldo1>; -+ status = "okay"; -+}; -+ -+&hdmi_out { -+ hdmi_out_con: endpoint { -+ remote-endpoint = <&hdmi_con_in>; -+ }; -+}; -+ - &mmc0 { - pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins>; -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts -index cdf5169f2a1a..cd7e938db01a 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts -@@ -63,6 +63,18 @@ - stdout-path = "serial0:115200n8"; - }; - -+ -+ hdmi-connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_con_in: endpoint { -+ remote-endpoint = <&hdmi_out_con>; -+ }; -+ }; -+ }; -+ - wifi_pwrseq: wifi_pwrseq { - compatible = "mmc-pwrseq-simple"; - reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */ -@@ -73,6 +85,10 @@ - cpu-supply = <®_dcdc2>; - }; - -+&de { -+ status = "okay"; -+}; -+ - &ehci0 { - status = "okay"; - }; -@@ -91,6 +107,17 @@ - - }; - -+&hdmi { -+ hvcc-supply = <®_dldo1>; -+ status = "okay"; -+}; -+ -+&hdmi_out { -+ hdmi_out_con: endpoint { -+ remote-endpoint = <&hdmi_con_in>; -+ }; -+}; -+ - &i2c1 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c1_pins>; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts index b3698a8bb1d3..52cbb3052588 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts @@ -308,57 +73,6 @@ index b3698a8bb1d3..52cbb3052588 100644 &mmc0 { pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins>; -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts -index abad307b414a..8e9191f489a6 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts -@@ -61,6 +61,17 @@ - stdout-path = "serial0:115200n8"; - }; - -+ hdmi-connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_con_in: endpoint { -+ remote-endpoint = <&hdmi_out_con>; -+ }; -+ }; -+ }; -+ - reg_vcc1v8: vcc1v8 { - compatible = "regulator-fixed"; - regulator-name = "vcc1v8"; -@@ -73,6 +84,10 @@ - cpu-supply = <®_dcdc2>; - }; - -+&de { -+ status = "okay"; -+}; -+ - &ehci0 { - status = "okay"; - }; -@@ -90,6 +105,17 @@ - status = "okay"; - }; - -+&hdmi { -+ hvcc-supply = <®_dldo1>; -+ status = "okay"; -+}; -+ -+&hdmi_out { -+ hdmi_out_con: endpoint { -+ remote-endpoint = <&hdmi_con_in>; -+ }; -+}; -+ - &i2s2 { - status = "okay"; - }; -- 2.17.1 diff --git a/patch/kernel/sunxi-legacy/0102-dt-bindings-power-supply-axp20x-add-AXP813-AC-power-.patch b/patch/kernel/sunxi-legacy/0102-dt-bindings-power-supply-axp20x-add-AXP813-AC-power-.patch deleted file mode 100644 index a64a8fe58..000000000 --- a/patch/kernel/sunxi-legacy/0102-dt-bindings-power-supply-axp20x-add-AXP813-AC-power-.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 7e6f7bf5c8a482c2391a16d76a50aff7a47c8223 Mon Sep 17 00:00:00 2001 -From: Oskari Lemmela -Date: Tue, 23 Oct 2018 21:53:20 +0300 -Subject: [PATCH 102/146] dt-bindings: power: supply: axp20x: add AXP813 AC - power DT binding - -The AXP803/AXP813 AC power supply can limit input current and voltage. - -Signed-off-by: Oskari Lemmela -Reviewed-by: Rob Herring -Reviewed-by: Quentin Schulz -Reviewed-by: Chen-Yu Tsai -Reviewed-by: Sebastian Reichel -Tested-by: Vasily Khoruzhick ---- - .../devicetree/bindings/power/supply/axp20x_ac_power.txt | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt b/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt -index 826e8a879121..7a1fb532abe5 100644 ---- a/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt -+++ b/Documentation/devicetree/bindings/power/supply/axp20x_ac_power.txt -@@ -4,6 +4,7 @@ Required Properties: - - compatible: One of: - "x-powers,axp202-ac-power-supply" - "x-powers,axp221-ac-power-supply" -+ "x-powers,axp813-ac-power-supply" - - This node is a subnode of the axp20x PMIC. - -@@ -13,6 +14,8 @@ reading ADC channels from the AXP20X ADC. - The AXP22X is only able to tell if an AC power supply is present and - usable. - -+AXP813/AXP803 are able to limit current and supply voltage -+ - Example: - - &axp209 { --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0106-ARM-dts-axp81x-add-AC-power-supply-subnode.patch b/patch/kernel/sunxi-legacy/0106-ARM-dts-axp81x-add-AC-power-supply-subnode.patch deleted file mode 100644 index 1147b6be3..000000000 --- a/patch/kernel/sunxi-legacy/0106-ARM-dts-axp81x-add-AC-power-supply-subnode.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 89dba78ca59cf4f8973fff843abfe956a7788f27 Mon Sep 17 00:00:00 2001 -From: Oskari Lemmela -Date: Tue, 23 Oct 2018 21:53:24 +0300 -Subject: [PATCH 106/146] ARM: dts: axp81x: add AC power supply subnode - -Add AC power supply subnode for AXP81X PMIC. - -Signed-off-by: Oskari Lemmela -Reviewed-by: Quentin Schulz -Reviewed-by: Chen-Yu Tsai -Tested-by: Vasily Khoruzhick ---- - arch/arm/boot/dts/axp81x.dtsi | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/arch/arm/boot/dts/axp81x.dtsi b/arch/arm/boot/dts/axp81x.dtsi -index 043c717dcef1..bd83962d3627 100644 ---- a/arch/arm/boot/dts/axp81x.dtsi -+++ b/arch/arm/boot/dts/axp81x.dtsi -@@ -48,6 +48,11 @@ - interrupt-controller; - #interrupt-cells = <1>; - -+ ac_power_supply: ac-power-supply { -+ compatible = "x-powers,axp813-ac-power-supply"; -+ status = "disabled"; -+ }; -+ - axp_adc: adc { - compatible = "x-powers,axp813-adc"; - #io-channel-cells = <1>; --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0107-arm64-dts-allwinner-axp803-add-AC-and-battery-power-.patch b/patch/kernel/sunxi-legacy/0107-arm64-dts-allwinner-axp803-add-AC-and-battery-power-.patch deleted file mode 100644 index e7f21bbe0..000000000 --- a/patch/kernel/sunxi-legacy/0107-arm64-dts-allwinner-axp803-add-AC-and-battery-power-.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 7466a08110850f608e2843a4b8089d184f05fb32 Mon Sep 17 00:00:00 2001 -From: Oskari Lemmela -Date: Tue, 23 Oct 2018 21:53:25 +0300 -Subject: [PATCH 107/146] arm64: dts: allwinner: axp803: add AC and battery - power supplies - -Parts of the AXP803 are compatible with their counterparts on the AXP813. -Add DT nodes ADC, GPIO, AC and battery power supplies. - -Signed-off-by: Oskari Lemmela -Reviewed-by: Quentin Schulz -Tested-by: Vasily Khoruzhick ---- - arch/arm64/boot/dts/allwinner/axp803.dtsi | 33 +++++++++++++++++++++++ - 1 file changed, 33 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/axp803.dtsi b/arch/arm64/boot/dts/allwinner/axp803.dtsi -index e5eae8bafc42..c3a618e1279a 100644 ---- a/arch/arm64/boot/dts/allwinner/axp803.dtsi -+++ b/arch/arm64/boot/dts/allwinner/axp803.dtsi -@@ -49,6 +49,39 @@ - interrupt-controller; - #interrupt-cells = <1>; - -+ ac_power_supply: ac-power-supply { -+ compatible = "x-powers,axp803-ac-power-supply", -+ "x-powers,axp813-ac-power-supply"; -+ status = "disabled"; -+ }; -+ -+ axp_adc: adc { -+ compatible = "x-powers,axp803-adc", "x-powers,axp813-adc"; -+ #io-channel-cells = <1>; -+ }; -+ -+ axp_gpio: gpio { -+ compatible = "x-powers,axp803-gpio", "x-powers,axp813-gpio"; -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ gpio0_ldo: gpio0-ldo { -+ pins = "GPIO0"; -+ function = "ldo"; -+ }; -+ -+ gpio1_ldo: gpio1-ldo { -+ pins = "GPIO1"; -+ function = "ldo"; -+ }; -+ }; -+ -+ battery_power_supply: battery-power-supply { -+ compatible = "x-powers,axp803-battery-power-supply", -+ "x-powers,axp813-battery-power-supply"; -+ status = "disabled"; -+ }; -+ - regulators { - /* Default work frequency for buck regulators */ - x-powers,dcdc-freq = <3000>; --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0108-arm64-dts-allwinner-a64-sopine-baseboard-enable-powe.patch b/patch/kernel/sunxi-legacy/0108-arm64-dts-allwinner-a64-sopine-baseboard-enable-powe.patch deleted file mode 100644 index f6b2c7d0b..000000000 --- a/patch/kernel/sunxi-legacy/0108-arm64-dts-allwinner-a64-sopine-baseboard-enable-powe.patch +++ /dev/null @@ -1,39 +0,0 @@ -From f16f4cbdb0deb70c03731fbccb4f52eb4d1d096a Mon Sep 17 00:00:00 2001 -From: Oskari Lemmela -Date: Tue, 23 Oct 2018 21:53:26 +0300 -Subject: [PATCH 108/146] arm64: dts: allwinner: a64: sopine-baseboard: enable - power supplies - -AXP803 ACIN pins are routed from SOM to the DC jack on the baseboard. -AXP803 charger pins BATSENSE, LOADSENSE, N_BATDRV, LX_CHG, VIN_CHG -and IPSOUT are connected via PMOS driver to SOM VBAT pins. VBAT and -AXP803 TS pins are routed to the baseboard 3-pin battery connector. - -Signed-off-by: Oskari Lemmela -Reviewed-by: Quentin Schulz ---- - .../boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts -index 8e9191f489a6..df7aa8c5f751 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts -@@ -80,6 +80,14 @@ - }; - }; - -+&ac_power_supply { -+ status = "okay"; -+}; -+ -+&battery_power_supply { -+ status = "okay"; -+}; -+ - &cpu0 { - cpu-supply = <®_dcdc2>; - }; --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0109-arm64-dts-allwinner-a64-pinebook-enable-power-suppli.patch b/patch/kernel/sunxi-legacy/0109-arm64-dts-allwinner-a64-pinebook-enable-power-suppli.patch deleted file mode 100644 index e17823861..000000000 --- a/patch/kernel/sunxi-legacy/0109-arm64-dts-allwinner-a64-pinebook-enable-power-suppli.patch +++ /dev/null @@ -1,35 +0,0 @@ -From bedc59458dbad00e9e9b324ebf6836f724158539 Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Tue, 23 Oct 2018 21:53:27 +0300 -Subject: [PATCH 109/146] arm64: dts: allwinner: a64: pinebook: enable power - supplies - -Pinebook has ACIN connector and 10000 mAh battery. - -Signed-off-by: Vasily Khoruzhick ---- - arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -index 52cbb3052588..dce16d9d6afb 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -@@ -179,6 +179,14 @@ - - #include "axp803.dtsi" - -+&ac_power_supply { -+ status = "okay"; -+}; -+ -+&battery_power_supply { -+ status = "okay"; -+}; -+ - ®_aldo1 { - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0110-power-supply-add-AC-power-supply-driver-for-AXP813.patch b/patch/kernel/sunxi-legacy/0110-power-supply-add-AC-power-supply-driver-for-AXP813.patch deleted file mode 100644 index ca9b56f2c..000000000 --- a/patch/kernel/sunxi-legacy/0110-power-supply-add-AC-power-supply-driver-for-AXP813.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 361aaaf61fc87465c3a59a5e655ad2ce5c727f46 Mon Sep 17 00:00:00 2001 -From: Oskari Lemmela -Date: Tue, 23 Oct 2018 21:53:28 +0300 -Subject: [PATCH 110/146] power: supply: add AC power supply driver for AXP813 - -AXP813 and AXP803 PMICs can control input current and minimum voltage. - -Both of these values are configurable. - -Signed-off-by: Oskari Lemmela -Reviewed-by: Quentin Schulz -Acked-by: Lee Jones ---- - drivers/power/supply/axp20x_ac_power.c | 94 ++++++++++++++++++++++++++ - include/linux/mfd/axp20x.h | 1 + - 2 files changed, 95 insertions(+) - -diff --git a/drivers/power/supply/axp20x_ac_power.c b/drivers/power/supply/axp20x_ac_power.c -index 0771f951b11f..59b4c8d3b961 100644 ---- a/drivers/power/supply/axp20x_ac_power.c -+++ b/drivers/power/supply/axp20x_ac_power.c -@@ -27,6 +27,16 @@ - #define AXP20X_PWR_STATUS_ACIN_PRESENT BIT(7) - #define AXP20X_PWR_STATUS_ACIN_AVAIL BIT(6) - -+#define AXP813_VHOLD_MASK GENMASK(5, 3) -+#define AXP813_VHOLD_UV_TO_BIT(x) ((((x) / 100000) - 40) << 3) -+#define AXP813_VHOLD_REG_TO_UV(x) \ -+ (((((x) & AXP813_VHOLD_MASK) >> 3) + 40) * 100000) -+ -+#define AXP813_CURR_LIMIT_MASK GENMASK(2, 0) -+#define AXP813_CURR_LIMIT_UA_TO_BIT(x) (((x) / 500000) - 3) -+#define AXP813_CURR_LIMIT_REG_TO_UA(x) \ -+ ((((x) & AXP813_CURR_LIMIT_MASK) + 3) * 500000) -+ - #define DRVNAME "axp20x-ac-power-supply" - - struct axp20x_ac_power { -@@ -102,6 +112,57 @@ static int axp20x_ac_power_get_property(struct power_supply *psy, - - return 0; - -+ case POWER_SUPPLY_PROP_VOLTAGE_MIN: -+ ret = regmap_read(power->regmap, AXP813_ACIN_PATH_CTRL, ®); -+ if (ret) -+ return ret; -+ -+ val->intval = AXP813_VHOLD_REG_TO_UV(reg); -+ -+ return 0; -+ -+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: -+ ret = regmap_read(power->regmap, AXP813_ACIN_PATH_CTRL, ®); -+ if (ret) -+ return ret; -+ -+ val->intval = AXP813_CURR_LIMIT_REG_TO_UA(reg); -+ /* AXP813 datasheet defines values 11x as 4000mA */ -+ if (val->intval > 4000000) -+ val->intval = 4000000; -+ -+ return 0; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ return -EINVAL; -+} -+ -+static int axp813_ac_power_set_property(struct power_supply *psy, -+ enum power_supply_property psp, -+ const union power_supply_propval *val) -+{ -+ struct axp20x_ac_power *power = power_supply_get_drvdata(psy); -+ -+ switch (psp) { -+ case POWER_SUPPLY_PROP_VOLTAGE_MIN: -+ if (val->intval < 4000000 || val->intval > 4700000) -+ return -EINVAL; -+ -+ return regmap_update_bits(power->regmap, AXP813_ACIN_PATH_CTRL, -+ AXP813_VHOLD_MASK, -+ AXP813_VHOLD_UV_TO_BIT(val->intval)); -+ -+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: -+ if (val->intval < 1500000 || val->intval > 4000000) -+ return -EINVAL; -+ -+ return regmap_update_bits(power->regmap, AXP813_ACIN_PATH_CTRL, -+ AXP813_CURR_LIMIT_MASK, -+ AXP813_CURR_LIMIT_UA_TO_BIT(val->intval)); -+ - default: - return -EINVAL; - } -@@ -109,6 +170,13 @@ static int axp20x_ac_power_get_property(struct power_supply *psy, - return -EINVAL; - } - -+static int axp813_ac_power_prop_writeable(struct power_supply *psy, -+ enum power_supply_property psp) -+{ -+ return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN || -+ psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT; -+} -+ - static enum power_supply_property axp20x_ac_power_properties[] = { - POWER_SUPPLY_PROP_HEALTH, - POWER_SUPPLY_PROP_PRESENT, -@@ -123,6 +191,14 @@ static enum power_supply_property axp22x_ac_power_properties[] = { - POWER_SUPPLY_PROP_ONLINE, - }; - -+static enum power_supply_property axp813_ac_power_properties[] = { -+ POWER_SUPPLY_PROP_HEALTH, -+ POWER_SUPPLY_PROP_PRESENT, -+ POWER_SUPPLY_PROP_ONLINE, -+ POWER_SUPPLY_PROP_VOLTAGE_MIN, -+ POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, -+}; -+ - static const struct power_supply_desc axp20x_ac_power_desc = { - .name = "axp20x-ac", - .type = POWER_SUPPLY_TYPE_MAINS, -@@ -139,6 +215,16 @@ static const struct power_supply_desc axp22x_ac_power_desc = { - .get_property = axp20x_ac_power_get_property, - }; - -+static const struct power_supply_desc axp813_ac_power_desc = { -+ .name = "axp813-ac", -+ .type = POWER_SUPPLY_TYPE_MAINS, -+ .properties = axp813_ac_power_properties, -+ .num_properties = ARRAY_SIZE(axp813_ac_power_properties), -+ .property_is_writeable = axp813_ac_power_prop_writeable, -+ .get_property = axp20x_ac_power_get_property, -+ .set_property = axp813_ac_power_set_property, -+}; -+ - struct axp_data { - const struct power_supply_desc *power_desc; - bool acin_adc; -@@ -154,6 +240,11 @@ static const struct axp_data axp22x_data = { - .acin_adc = false, - }; - -+static const struct axp_data axp813_data = { -+ .power_desc = &axp813_ac_power_desc, -+ .acin_adc = false, -+}; -+ - static int axp20x_ac_power_probe(struct platform_device *pdev) - { - struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); -@@ -234,6 +325,9 @@ static const struct of_device_id axp20x_ac_power_match[] = { - }, { - .compatible = "x-powers,axp221-ac-power-supply", - .data = &axp22x_data, -+ }, { -+ .compatible = "x-powers,axp813-ac-power-supply", -+ .data = &axp813_data, - }, { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, axp20x_ac_power_match); -diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h -index 517e60eecbcb..2302b620d238 100644 ---- a/include/linux/mfd/axp20x.h -+++ b/include/linux/mfd/axp20x.h -@@ -266,6 +266,7 @@ enum axp20x_variants { - #define AXP288_RT_BATT_V_H 0xa0 - #define AXP288_RT_BATT_V_L 0xa1 - -+#define AXP813_ACIN_PATH_CTRL 0x3a - #define AXP813_ADC_RATE 0x85 - - /* Fuel Gauge */ --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0111-mfd-axp20x-Add-AC-power-supply-cell-for-AXP813.patch b/patch/kernel/sunxi-legacy/0111-mfd-axp20x-Add-AC-power-supply-cell-for-AXP813.patch deleted file mode 100644 index 22147f308..000000000 --- a/patch/kernel/sunxi-legacy/0111-mfd-axp20x-Add-AC-power-supply-cell-for-AXP813.patch +++ /dev/null @@ -1,41 +0,0 @@ -From ea6865e1bfc1a1ac72fe95be42abb88b47413363 Mon Sep 17 00:00:00 2001 -From: Oskari Lemmela -Date: Tue, 23 Oct 2018 21:53:29 +0300 -Subject: [PATCH 111/146] mfd: axp20x: Add AC power supply cell for AXP813 - -As axp20x-ac-power-supply now supports AXP813, add a cell for it. - -Signed-off-by: Oskari Lemmela -Reviewed-by: Quentin Schulz -Reviewed-by: Chen-Yu Tsai -Tested-by: Vasily Khoruzhick - -Changed-by: Igor@armbian ---- - drivers/mfd/axp20x.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c -index 0be511dd93d0..dfc3cff1d08b 100644 ---- a/drivers/mfd/axp20x.c -+++ b/drivers/mfd/axp20x.c -@@ -805,8 +805,13 @@ static const struct mfd_cell axp813_cells[] = { - .name = "axp813-adc", - .of_compatible = "x-powers,axp813-adc", - }, { -- .name = "axp20x-battery-power-supply", -- .of_compatible = "x-powers,axp813-battery-power-supply", -+ .name = "axp20x-battery-power-supply", -+ .of_compatible = "x-powers,axp813-battery-power-supply", -+ }, { -+ .name = "axp20x-ac-power-supply", -+ .of_compatible = "x-powers,axp813-ac-power-supply", -+ .num_resources = ARRAY_SIZE(axp20x_ac_power_supply_resources), -+ .resources = axp20x_ac_power_supply_resources, - }, { - .name = "axp20x-usb-power-supply", - .of_compatible = "x-powers,axp813-usb-power-supply", - --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0113-ASoC-sun4i-i2s-move-code-from-startup-shutdown-hooks.patch b/patch/kernel/sunxi-legacy/0113-ASoC-sun4i-i2s-move-code-from-startup-shutdown-hooks.patch deleted file mode 100644 index 2d6eaa9f3..000000000 --- a/patch/kernel/sunxi-legacy/0113-ASoC-sun4i-i2s-move-code-from-startup-shutdown-hooks.patch +++ /dev/null @@ -1,117 +0,0 @@ -From e4ff7b4f7eddc3a9adc41f3f1d97444a72561910 Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Fri, 12 Oct 2018 08:27:43 -0700 -Subject: [PATCH 113/146] ASoC: sun4i-i2s: move code from startup/shutdown - hooks into pm_runtime hooks - -startup() and shutdown() hooks are called for both substreams, -so stopping either substream when another is running breaks the -latter. - -E.g. playback breaks if capture is stopped when playback is running. - -Move code from startup() and shutdown() to resume() and suspend() -hooks respectively to fix this issue - -Signed-off-by: Vasily Khoruzhick -Acked-by: Maxime Ripard ---- - sound/soc/sunxi/sun4i-i2s.c | 61 +++++++++++++++---------------------- - 1 file changed, 25 insertions(+), 36 deletions(-) - -diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c -index a4aa931ebfae..daa6c08cffbc 100644 ---- a/sound/soc/sunxi/sun4i-i2s.c -+++ b/sound/soc/sunxi/sun4i-i2s.c -@@ -644,40 +644,6 @@ static int sun4i_i2s_trigger(struct snd_pcm_substream *substream, int cmd, - return 0; - } - --static int sun4i_i2s_startup(struct snd_pcm_substream *substream, -- struct snd_soc_dai *dai) --{ -- struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); -- -- /* Enable the whole hardware block */ -- regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, -- SUN4I_I2S_CTRL_GL_EN, SUN4I_I2S_CTRL_GL_EN); -- -- /* Enable the first output line */ -- regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, -- SUN4I_I2S_CTRL_SDO_EN_MASK, -- SUN4I_I2S_CTRL_SDO_EN(0)); -- -- -- return clk_prepare_enable(i2s->mod_clk); --} -- --static void sun4i_i2s_shutdown(struct snd_pcm_substream *substream, -- struct snd_soc_dai *dai) --{ -- struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); -- -- clk_disable_unprepare(i2s->mod_clk); -- -- /* Disable our output lines */ -- regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, -- SUN4I_I2S_CTRL_SDO_EN_MASK, 0); -- -- /* Disable the whole hardware block */ -- regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, -- SUN4I_I2S_CTRL_GL_EN, 0); --} -- - static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, - unsigned int freq, int dir) - { -@@ -695,8 +661,6 @@ static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = { - .hw_params = sun4i_i2s_hw_params, - .set_fmt = sun4i_i2s_set_fmt, - .set_sysclk = sun4i_i2s_set_sysclk, -- .shutdown = sun4i_i2s_shutdown, -- .startup = sun4i_i2s_startup, - .trigger = sun4i_i2s_trigger, - }; - -@@ -869,6 +833,21 @@ static int sun4i_i2s_runtime_resume(struct device *dev) - goto err_disable_clk; - } - -+ /* Enable the whole hardware block */ -+ regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, -+ SUN4I_I2S_CTRL_GL_EN, SUN4I_I2S_CTRL_GL_EN); -+ -+ /* Enable the first output line */ -+ regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, -+ SUN4I_I2S_CTRL_SDO_EN_MASK, -+ SUN4I_I2S_CTRL_SDO_EN(0)); -+ -+ ret = clk_prepare_enable(i2s->mod_clk); -+ if (ret) { -+ dev_err(dev, "Failed to enable module clock\n"); -+ goto err_disable_clk; -+ } -+ - return 0; - - err_disable_clk: -@@ -880,6 +859,16 @@ static int sun4i_i2s_runtime_suspend(struct device *dev) - { - struct sun4i_i2s *i2s = dev_get_drvdata(dev); - -+ clk_disable_unprepare(i2s->mod_clk); -+ -+ /* Disable our output lines */ -+ regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, -+ SUN4I_I2S_CTRL_SDO_EN_MASK, 0); -+ -+ /* Disable the whole hardware block */ -+ regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, -+ SUN4I_I2S_CTRL_GL_EN, 0); -+ - regcache_cache_only(i2s->regmap, true); - - clk_disable_unprepare(i2s->bus_clk); --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0114-ASoC-sun4i-i2s-Add-compatibility-with-A64-codec-I2S.patch b/patch/kernel/sunxi-legacy/0114-ASoC-sun4i-i2s-Add-compatibility-with-A64-codec-I2S.patch deleted file mode 100644 index 537f260f1..000000000 --- a/patch/kernel/sunxi-legacy/0114-ASoC-sun4i-i2s-Add-compatibility-with-A64-codec-I2S.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 4bfc6b2d77838f3c04e4a1b0814fcf17be2b048f Mon Sep 17 00:00:00 2001 -From: Marcus Cooper -Date: Sun, 3 Dec 2017 10:09:08 -0800 -Subject: [PATCH 114/146] ASoC: sun4i-i2s: Add compatibility with A64 codec I2S - -The I2S block used for the audio codec in the A64 differs from other 3 -I2S modules in A64 and isn't compatible with H3. But it is very similar -to what is found in A10(sun4i). However, its TX FIFO is -located at a different address. - -Signed-off-by: Marcus Cooper -Signed-off-by: Vasily Khoruzhick -Acked-by: Maxime Ripard ---- - .../devicetree/bindings/sound/sun4i-i2s.txt | 2 ++ - sound/soc/sunxi/sun4i-i2s.c | 21 +++++++++++++++++++ - 2 files changed, 23 insertions(+) - -diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt -index b9d50d6cdef3..61e71c1729e0 100644 ---- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt -+++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt -@@ -10,6 +10,7 @@ Required properties: - - "allwinner,sun6i-a31-i2s" - - "allwinner,sun8i-a83t-i2s" - - "allwinner,sun8i-h3-i2s" -+ - "allwinner,sun50i-a64-codec-i2s" - - reg: physical base address of the controller and length of memory mapped - region. - - interrupts: should contain the I2S interrupt. -@@ -26,6 +27,7 @@ Required properties for the following compatibles: - - "allwinner,sun6i-a31-i2s" - - "allwinner,sun8i-a83t-i2s" - - "allwinner,sun8i-h3-i2s" -+ - "allwinner,sun50i-a64-codec-i2s" - - resets: phandle to the reset line for this codec - - Example: -diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c -index daa6c08cffbc..d5ec1a20499d 100644 ---- a/sound/soc/sunxi/sun4i-i2s.c -+++ b/sound/soc/sunxi/sun4i-i2s.c -@@ -950,6 +950,23 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { - .field_rxchansel = REG_FIELD(SUN8I_I2S_RX_CHAN_SEL_REG, 0, 2), - }; - -+static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = { -+ .has_reset = true, -+ .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, -+ .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, -+ .has_slave_select_bit = true, -+ .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), -+ .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), -+ .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), -+ .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), -+ .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), -+ .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), -+ .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), -+ .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), -+ .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), -+ .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), -+}; -+ - static int sun4i_i2s_init_regmap_fields(struct device *dev, - struct sun4i_i2s *i2s) - { -@@ -1158,6 +1175,10 @@ static const struct of_device_id sun4i_i2s_match[] = { - .compatible = "allwinner,sun8i-h3-i2s", - .data = &sun8i_h3_i2s_quirks, - }, -+ { -+ .compatible = "allwinner,sun50i-a64-codec-i2s", -+ .data = &sun50i_a64_codec_i2s_quirks, -+ }, - {} - }; - MODULE_DEVICE_TABLE(of, sun4i_i2s_match); --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0115-ASoC-sun8i-codec-Don-t-hardcode-BCLK-LRCK-ratio.patch b/patch/kernel/sunxi-legacy/0115-ASoC-sun8i-codec-Don-t-hardcode-BCLK-LRCK-ratio.patch deleted file mode 100644 index c65852577..000000000 --- a/patch/kernel/sunxi-legacy/0115-ASoC-sun8i-codec-Don-t-hardcode-BCLK-LRCK-ratio.patch +++ /dev/null @@ -1,79 +0,0 @@ -From a773d556e204228df20f8622d24a37f400f96f96 Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Sat, 9 Dec 2017 11:15:27 -0800 -Subject: [PATCH 115/146] ASoC: sun8i-codec: Don't hardcode BCLK / LRCK ratio - -BCLK / LRCK ratio should be sample size * channels, but it was -hardcoded to 32 (0x1 is 32 as per A33 and A64 datasheets). - -Calculate it basing on sample size and number of channels. - -Signed-off-by: Vasily Khoruzhick ---- - sound/soc/sunxi/sun8i-codec.c | 22 +++++++++++++++++++--- - 1 file changed, 19 insertions(+), 3 deletions(-) - -diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c -index fb37dd927e33..522a72fde78d 100644 ---- a/sound/soc/sunxi/sun8i-codec.c -+++ b/sound/soc/sunxi/sun8i-codec.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -52,7 +53,6 @@ - #define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV 13 - #define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV 9 - #define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV 6 --#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_16 (1 << 6) - #define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ 4 - #define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_16 (1 << 4) - #define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT 2 -@@ -300,12 +300,23 @@ static u8 sun8i_codec_get_bclk_div(struct sun8i_codec *scodec, - return best_val; - } - -+static int sun8i_codec_get_lrck_div(unsigned int channels, -+ unsigned int word_size) -+{ -+ unsigned int div = word_size * channels; -+ -+ if (div < 16 || div > 256) -+ return -EINVAL; -+ -+ return ilog2(div) - 4; -+} -+ - static int sun8i_codec_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) - { - struct sun8i_codec *scodec = snd_soc_component_get_drvdata(dai->component); -- int sample_rate; -+ int sample_rate, lrck_div; - u8 bclk_div; - - /* -@@ -321,9 +332,14 @@ static int sun8i_codec_hw_params(struct snd_pcm_substream *substream, - SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV_MASK, - bclk_div << SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV); - -+ lrck_div = sun8i_codec_get_lrck_div(params_channels(params), -+ params_physical_width(params)); -+ if (lrck_div < 0) -+ return lrck_div; -+ - regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL, - SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_MASK, -- SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_16); -+ lrck_div << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV); - - sample_rate = sun8i_codec_get_hw_rate(params); - if (sample_rate < 0) --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0116-ASoC-sun8i-codec-analog-split-regmap-code-into-separ.patch b/patch/kernel/sunxi-legacy/0116-ASoC-sun8i-codec-analog-split-regmap-code-into-separ.patch deleted file mode 100644 index 1b17dab85..000000000 --- a/patch/kernel/sunxi-legacy/0116-ASoC-sun8i-codec-analog-split-regmap-code-into-separ.patch +++ /dev/null @@ -1,283 +0,0 @@ -From 0415b4bd59d85ccc3c93e1014a798a8092302648 Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Thu, 11 Oct 2018 20:59:02 -0700 -Subject: [PATCH 116/146] ASoC: sun8i-codec-analog: split regmap code into - separate driver - -It will be reused by sun50i-codec-analog later. - -Signed-off-by: Vasily Khoruzhick -Acked-by: Maxime Ripard - -Changed by Igor - ---- - sound/soc/sunxi/Kconfig | 7 +- - sound/soc/sunxi/Makefile | 1 + - sound/soc/sunxi/sun8i-adda-pr-regmap.c | 102 +++++++++++++++++++++++++ - sound/soc/sunxi/sun8i-adda-pr-regmap.h | 7 ++ - sound/soc/sunxi/sun8i-codec-analog.c | 79 +------------------ - 5 files changed, 119 insertions(+), 77 deletions(-) - create mode 100644 sound/soc/sunxi/sun8i-adda-pr-regmap.c - create mode 100644 sound/soc/sunxi/sun8i-adda-pr-regmap.h - -diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig -index 22408bc2d6ec..83b770cdfdaa 100644 ---- a/sound/soc/sunxi/Kconfig -+++ b/sound/soc/sunxi/Kconfig -@@ -23,7 +23,7 @@ config SND_SUN8I_CODEC - config SND_SUN8I_CODEC_ANALOG - tristate "Allwinner sun8i Codec Analog Controls Support" - depends on MACH_SUN8I || (ARM64 && ARCH_SUNXI) || COMPILE_TEST -- select REGMAP -+ select SND_SUN8I_ADDA_PR_REGMAP - help - Say Y or M if you want to add support for the analog controls for - the codec embedded in newer Allwinner SoCs. -@@ -45,4 +45,9 @@ config SND_SUN4I_SPDIF - help - Say Y or M to add support for the S/PDIF audio block in the Allwinner - A10 and affiliated SoCs. -+ -+config SND_SUN8I_ADDA_PR_REGMAP -+ tristate -+ select REGMAP -+ - endmenu -diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile -index 4a9ef67386ca..74b99d55cfca 100644 ---- a/sound/soc/sunxi/Makefile -+++ b/sound/soc/sunxi/Makefile -@@ -4,3 +4,4 @@ obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o - obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o - obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o - obj-$(CONFIG_SND_AC100_CODEC) += ac100-codec.o -+obj-$(CONFIG_SND_SUN8I_ADDA_PR_REGMAP) += sun8i-adda-pr-regmap.o -diff --git a/sound/soc/sunxi/sun8i-adda-pr-regmap.c b/sound/soc/sunxi/sun8i-adda-pr-regmap.c -new file mode 100644 -index 000000000000..e68ce9d2884d ---- /dev/null -+++ b/sound/soc/sunxi/sun8i-adda-pr-regmap.c -@@ -0,0 +1,102 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * This driver provides regmap to access to analog part of audio codec -+ * found on Allwinner A23, A31s, A33, H3 and A64 Socs -+ * -+ * Copyright 2016 Chen-Yu Tsai -+ * Copyright (C) 2018 Vasily Khoruzhick -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "sun8i-adda-pr-regmap.h" -+ -+/* Analog control register access bits */ -+#define ADDA_PR 0x0 /* PRCM base + 0x1c0 */ -+#define ADDA_PR_RESET BIT(28) -+#define ADDA_PR_WRITE BIT(24) -+#define ADDA_PR_ADDR_SHIFT 16 -+#define ADDA_PR_ADDR_MASK GENMASK(4, 0) -+#define ADDA_PR_DATA_IN_SHIFT 8 -+#define ADDA_PR_DATA_IN_MASK GENMASK(7, 0) -+#define ADDA_PR_DATA_OUT_SHIFT 0 -+#define ADDA_PR_DATA_OUT_MASK GENMASK(7, 0) -+ -+/* regmap access bits */ -+static int adda_reg_read(void *context, unsigned int reg, unsigned int *val) -+{ -+ void __iomem *base = (void __iomem *)context; -+ u32 tmp; -+ -+ /* De-assert reset */ -+ writel(readl(base) | ADDA_PR_RESET, base); -+ -+ /* Clear write bit */ -+ writel(readl(base) & ~ADDA_PR_WRITE, base); -+ -+ /* Set register address */ -+ tmp = readl(base); -+ tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT); -+ tmp |= (reg & ADDA_PR_ADDR_MASK) << ADDA_PR_ADDR_SHIFT; -+ writel(tmp, base); -+ -+ /* Read back value */ -+ *val = readl(base) & ADDA_PR_DATA_OUT_MASK; -+ -+ return 0; -+} -+ -+static int adda_reg_write(void *context, unsigned int reg, unsigned int val) -+{ -+ void __iomem *base = (void __iomem *)context; -+ u32 tmp; -+ -+ /* De-assert reset */ -+ writel(readl(base) | ADDA_PR_RESET, base); -+ -+ /* Set register address */ -+ tmp = readl(base); -+ tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT); -+ tmp |= (reg & ADDA_PR_ADDR_MASK) << ADDA_PR_ADDR_SHIFT; -+ writel(tmp, base); -+ -+ /* Set data to write */ -+ tmp = readl(base); -+ tmp &= ~(ADDA_PR_DATA_IN_MASK << ADDA_PR_DATA_IN_SHIFT); -+ tmp |= (val & ADDA_PR_DATA_IN_MASK) << ADDA_PR_DATA_IN_SHIFT; -+ writel(tmp, base); -+ -+ /* Set write bit to signal a write */ -+ writel(readl(base) | ADDA_PR_WRITE, base); -+ -+ /* Clear write bit */ -+ writel(readl(base) & ~ADDA_PR_WRITE, base); -+ -+ return 0; -+} -+ -+static const struct regmap_config adda_pr_regmap_cfg = { -+ .name = "adda-pr", -+ .reg_bits = 5, -+ .reg_stride = 1, -+ .val_bits = 8, -+ .reg_read = adda_reg_read, -+ .reg_write = adda_reg_write, -+ .fast_io = true, -+ .max_register = 31, -+}; -+ -+struct regmap *sun8i_adda_pr_regmap_init(struct device *dev, -+ void __iomem *base) -+{ -+ return devm_regmap_init(dev, NULL, base, &adda_pr_regmap_cfg); -+} -+EXPORT_SYMBOL_GPL(sun8i_adda_pr_regmap_init); -+ -+MODULE_DESCRIPTION("Allwinner analog audio codec regmap driver"); -+MODULE_AUTHOR("Vasily Khoruzhick "); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:sunxi-adda-pr"); -diff --git a/sound/soc/sunxi/sun8i-adda-pr-regmap.h b/sound/soc/sunxi/sun8i-adda-pr-regmap.h -new file mode 100644 -index 000000000000..a5ae95dfebc1 ---- /dev/null -+++ b/sound/soc/sunxi/sun8i-adda-pr-regmap.h -@@ -0,0 +1,7 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ -+/* -+ * Copyright (C) 2018 Vasily Khoruzhick -+ */ -+ -+struct regmap *sun8i_adda_pr_regmap_init(struct device *dev, -+ void __iomem *base); -diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c -index 485e79f292c4..916a46bbc1c8 100644 ---- a/sound/soc/sunxi/sun8i-codec-analog.c -+++ b/sound/soc/sunxi/sun8i-codec-analog.c -@@ -27,6 +27,8 @@ - #include - #include - -+#include "sun8i-adda-pr-regmap.h" -+ - /* Codec analog control register offsets and bit fields */ - #define SUN8I_ADDA_HP_VOLC 0x00 - #define SUN8I_ADDA_HP_VOLC_PA_CLK_GATE 7 -@@ -120,81 +122,6 @@ - #define SUN8I_ADDA_ADC_AP_EN_ADCLEN 6 - #define SUN8I_ADDA_ADC_AP_EN_ADCG 0 - --/* Analog control register access bits */ --#define ADDA_PR 0x0 /* PRCM base + 0x1c0 */ --#define ADDA_PR_RESET BIT(28) --#define ADDA_PR_WRITE BIT(24) --#define ADDA_PR_ADDR_SHIFT 16 --#define ADDA_PR_ADDR_MASK GENMASK(4, 0) --#define ADDA_PR_DATA_IN_SHIFT 8 --#define ADDA_PR_DATA_IN_MASK GENMASK(7, 0) --#define ADDA_PR_DATA_OUT_SHIFT 0 --#define ADDA_PR_DATA_OUT_MASK GENMASK(7, 0) -- --/* regmap access bits */ --static int adda_reg_read(void *context, unsigned int reg, unsigned int *val) --{ -- void __iomem *base = (void __iomem *)context; -- u32 tmp; -- -- /* De-assert reset */ -- writel(readl(base) | ADDA_PR_RESET, base); -- -- /* Clear write bit */ -- writel(readl(base) & ~ADDA_PR_WRITE, base); -- -- /* Set register address */ -- tmp = readl(base); -- tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT); -- tmp |= (reg & ADDA_PR_ADDR_MASK) << ADDA_PR_ADDR_SHIFT; -- writel(tmp, base); -- -- /* Read back value */ -- *val = readl(base) & ADDA_PR_DATA_OUT_MASK; -- -- return 0; --} -- --static int adda_reg_write(void *context, unsigned int reg, unsigned int val) --{ -- void __iomem *base = (void __iomem *)context; -- u32 tmp; -- -- /* De-assert reset */ -- writel(readl(base) | ADDA_PR_RESET, base); -- -- /* Set register address */ -- tmp = readl(base); -- tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT); -- tmp |= (reg & ADDA_PR_ADDR_MASK) << ADDA_PR_ADDR_SHIFT; -- writel(tmp, base); -- -- /* Set data to write */ -- tmp = readl(base); -- tmp &= ~(ADDA_PR_DATA_IN_MASK << ADDA_PR_DATA_IN_SHIFT); -- tmp |= (val & ADDA_PR_DATA_IN_MASK) << ADDA_PR_DATA_IN_SHIFT; -- writel(tmp, base); -- -- /* Set write bit to signal a write */ -- writel(readl(base) | ADDA_PR_WRITE, base); -- -- /* Clear write bit */ -- writel(readl(base) & ~ADDA_PR_WRITE, base); -- -- return 0; --} -- --static const struct regmap_config adda_pr_regmap_cfg = { -- .name = "adda-pr", -- .reg_bits = 5, -- .reg_stride = 1, -- .val_bits = 8, -- .reg_read = adda_reg_read, -- .reg_write = adda_reg_write, -- .fast_io = true, -- .max_register = 24, --}; -- - /* mixer controls */ - static const struct snd_kcontrol_new sun8i_codec_mixer_controls[] = { - SOC_DAPM_DOUBLE_R("DAC Playback Switch", -@@ -912,7 +839,7 @@ static int sun8i_codec_analog_probe(struct platform_device *pdev) - return PTR_ERR(base); - } - -- regmap = devm_regmap_init(&pdev->dev, NULL, base, &adda_pr_regmap_cfg); -+ regmap = sun8i_adda_pr_regmap_init(&pdev->dev, base); - if (IS_ERR(regmap)) { - dev_err(&pdev->dev, "Failed to create regmap\n"); - return PTR_ERR(regmap); --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0117-ASoC-dt-binding-Add-bindings-for-Allwinner-A64-codec.patch b/patch/kernel/sunxi-legacy/0117-ASoC-dt-binding-Add-bindings-for-Allwinner-A64-codec.patch deleted file mode 100644 index cd90e2840..000000000 --- a/patch/kernel/sunxi-legacy/0117-ASoC-dt-binding-Add-bindings-for-Allwinner-A64-codec.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 426a0f3c97e6ea270e82ec36f5f7ac34fd960d56 Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Thu, 11 Oct 2018 22:55:57 -0700 -Subject: [PATCH 117/146] ASoC: dt-binding: Add bindings for Allwinner A64 - codec's analog path controls - -The internal codec on Allwinner A64 is split into 2 parts. The -analog path controls are routed through an embedded custom register -bus accessed through the PRCM block just as on A23/A33/H3. - -Add a binding for this hardware. - -Signed-off-by: Vasily Khoruzhick -Acked-by: Maxime Ripard ---- - .../bindings/sound/sun50i-codec-analog.txt | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - create mode 100644 Documentation/devicetree/bindings/sound/sun50i-codec-analog.txt - -diff --git a/Documentation/devicetree/bindings/sound/sun50i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun50i-codec-analog.txt -new file mode 100644 -index 000000000000..4f8ad0e04d20 ---- /dev/null -+++ b/Documentation/devicetree/bindings/sound/sun50i-codec-analog.txt -@@ -0,0 +1,12 @@ -+* Allwinner A64 Codec Analog Controls -+ -+Required properties: -+- compatible: must be one of the following compatibles: -+ - "allwinner,sun50i-a64-codec-analog" -+- reg: must contain the registers location and length -+ -+Example: -+ codec_analog: codec-analog@1f015c0 { -+ compatible = "allwinner,sun50i-a64-codec-analog"; -+ reg = <0x01f015c0 0x4>; -+ }; --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0118-ASoC-sunxi-Add-new-driver-for-Allwinner-A64-codec-s-.patch b/patch/kernel/sunxi-legacy/0118-ASoC-sunxi-Add-new-driver-for-Allwinner-A64-codec-s-.patch deleted file mode 100644 index 25ee2e621..000000000 --- a/patch/kernel/sunxi-legacy/0118-ASoC-sunxi-Add-new-driver-for-Allwinner-A64-codec-s-.patch +++ /dev/null @@ -1,505 +0,0 @@ -From 010a2d4736116f5464898c3118637a18a214281b Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Thu, 11 Oct 2018 23:07:40 -0700 -Subject: [PATCH 118/146] ASoC: sunxi: Add new driver for Allwinner A64 codec's - analog path controls - -The internal codec on A64 is split into 2 parts. The analog path controls -are routed through an embedded custom register bus accessed through -the PRCM block. - -Add an ASoC component driver for it. This should be tied to the codec -audio card as an auxiliary device. - -Signed-off-by: Vasily Khoruzhick -Acked-by: Maxime Ripard ---- - sound/soc/sunxi/Kconfig | 8 + - sound/soc/sunxi/Makefile | 1 + - sound/soc/sunxi/sun50i-codec-analog.c | 444 ++++++++++++++++++++++++++ - 3 files changed, 453 insertions(+) - create mode 100644 sound/soc/sunxi/sun50i-codec-analog.c - -diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig -index 83b770cdfdaa..8a055ca1819a 100644 ---- a/sound/soc/sunxi/Kconfig -+++ b/sound/soc/sunxi/Kconfig -@@ -28,6 +28,14 @@ config SND_SUN8I_CODEC_ANALOG - Say Y or M if you want to add support for the analog controls for - the codec embedded in newer Allwinner SoCs. - -+config SND_SUN50I_CODEC_ANALOG -+ tristate "Allwinner sun50i Codec Analog Controls Support" -+ depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST -+ select SND_SUNXI_ADDA_PR_REGMAP -+ help -+ Say Y or M if you want to add support for the analog controls for -+ the codec embedded in Allwinner A64 SoC. -+ - config SND_SUN4I_I2S - tristate "Allwinner A10 I2S Support" - select SND_SOC_GENERIC_DMAENGINE_PCM -diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile -index 74b99d55cfca..a86be340a076 100644 ---- a/sound/soc/sunxi/Makefile -+++ b/sound/soc/sunxi/Makefile -@@ -3,5 +3,6 @@ obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o - obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o - obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o - obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o -+obj-$(CONFIG_SND_SUN50I_CODEC_ANALOG) += sun50i-codec-analog.o - obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o - obj-$(CONFIG_SND_SUN8I_ADDA_PR_REGMAP) += sun8i-adda-pr-regmap.o -diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c -new file mode 100644 -index 000000000000..8f5f999df631 ---- /dev/null -+++ b/sound/soc/sunxi/sun50i-codec-analog.c -@@ -0,0 +1,444 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * This driver supports the analog controls for the internal codec -+ * found in Allwinner's A64 SoC. -+ * -+ * Copyright (C) 2016 Chen-Yu Tsai -+ * Copyright (C) 2017 Marcus Cooper -+ * Copyright (C) 2018 Vasily Khoruzhick -+ * -+ * Based on sun8i-codec-analog.c -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "sun8i-adda-pr-regmap.h" -+ -+/* Codec analog control register offsets and bit fields */ -+#define SUN50I_ADDA_HP_CTRL 0x00 -+#define SUN50I_ADDA_HP_CTRL_PA_CLK_GATE 7 -+#define SUN50I_ADDA_HP_CTRL_HPPA_EN 6 -+#define SUN50I_ADDA_HP_CTRL_HPVOL 0 -+ -+#define SUN50I_ADDA_OL_MIX_CTRL 0x01 -+#define SUN50I_ADDA_OL_MIX_CTRL_MIC1 6 -+#define SUN50I_ADDA_OL_MIX_CTRL_MIC2 5 -+#define SUN50I_ADDA_OL_MIX_CTRL_PHONE 4 -+#define SUN50I_ADDA_OL_MIX_CTRL_PHONEN 3 -+#define SUN50I_ADDA_OL_MIX_CTRL_LINEINL 2 -+#define SUN50I_ADDA_OL_MIX_CTRL_DACL 1 -+#define SUN50I_ADDA_OL_MIX_CTRL_DACR 0 -+ -+#define SUN50I_ADDA_OR_MIX_CTRL 0x02 -+#define SUN50I_ADDA_OR_MIX_CTRL_MIC1 6 -+#define SUN50I_ADDA_OR_MIX_CTRL_MIC2 5 -+#define SUN50I_ADDA_OR_MIX_CTRL_PHONE 4 -+#define SUN50I_ADDA_OR_MIX_CTRL_PHONEP 3 -+#define SUN50I_ADDA_OR_MIX_CTRL_LINEINR 2 -+#define SUN50I_ADDA_OR_MIX_CTRL_DACR 1 -+#define SUN50I_ADDA_OR_MIX_CTRL_DACL 0 -+ -+#define SUN50I_ADDA_LINEOUT_CTRL0 0x05 -+#define SUN50I_ADDA_LINEOUT_CTRL0_LEN 7 -+#define SUN50I_ADDA_LINEOUT_CTRL0_REN 6 -+#define SUN50I_ADDA_LINEOUT_CTRL0_LSRC_SEL 5 -+#define SUN50I_ADDA_LINEOUT_CTRL0_RSRC_SEL 4 -+ -+#define SUN50I_ADDA_LINEOUT_CTRL1 0x06 -+#define SUN50I_ADDA_LINEOUT_CTRL1_VOL 0 -+ -+#define SUN50I_ADDA_MIC1_CTRL 0x07 -+#define SUN50I_ADDA_MIC1_CTRL_MIC1G 4 -+#define SUN50I_ADDA_MIC1_CTRL_MIC1AMPEN 3 -+#define SUN50I_ADDA_MIC1_CTRL_MIC1BOOST 0 -+ -+#define SUN50I_ADDA_MIC2_CTRL 0x08 -+#define SUN50I_ADDA_MIC2_CTRL_MIC2G 4 -+#define SUN50I_ADDA_MIC2_CTRL_MIC2AMPEN 3 -+#define SUN50I_ADDA_MIC2_CTRL_MIC2BOOST 0 -+ -+#define SUN50I_ADDA_LINEIN_CTRL 0x09 -+#define SUN50I_ADDA_LINEIN_CTRL_LINEING 0 -+ -+#define SUN50I_ADDA_MIX_DAC_CTRL 0x0a -+#define SUN50I_ADDA_MIX_DAC_CTRL_DACAREN 7 -+#define SUN50I_ADDA_MIX_DAC_CTRL_DACALEN 6 -+#define SUN50I_ADDA_MIX_DAC_CTRL_RMIXEN 5 -+#define SUN50I_ADDA_MIX_DAC_CTRL_LMIXEN 4 -+#define SUN50I_ADDA_MIX_DAC_CTRL_RHPPAMUTE 3 -+#define SUN50I_ADDA_MIX_DAC_CTRL_LHPPAMUTE 2 -+#define SUN50I_ADDA_MIX_DAC_CTRL_RHPIS 1 -+#define SUN50I_ADDA_MIX_DAC_CTRL_LHPIS 0 -+ -+#define SUN50I_ADDA_L_ADCMIX_SRC 0x0b -+#define SUN50I_ADDA_L_ADCMIX_SRC_MIC1 6 -+#define SUN50I_ADDA_L_ADCMIX_SRC_MIC2 5 -+#define SUN50I_ADDA_L_ADCMIX_SRC_PHONE 4 -+#define SUN50I_ADDA_L_ADCMIX_SRC_PHONEN 3 -+#define SUN50I_ADDA_L_ADCMIX_SRC_LINEINL 2 -+#define SUN50I_ADDA_L_ADCMIX_SRC_OMIXRL 1 -+#define SUN50I_ADDA_L_ADCMIX_SRC_OMIXRR 0 -+ -+#define SUN50I_ADDA_R_ADCMIX_SRC 0x0c -+#define SUN50I_ADDA_R_ADCMIX_SRC_MIC1 6 -+#define SUN50I_ADDA_R_ADCMIX_SRC_MIC2 5 -+#define SUN50I_ADDA_R_ADCMIX_SRC_PHONE 4 -+#define SUN50I_ADDA_R_ADCMIX_SRC_PHONEP 3 -+#define SUN50I_ADDA_R_ADCMIX_SRC_LINEINR 2 -+#define SUN50I_ADDA_R_ADCMIX_SRC_OMIXR 1 -+#define SUN50I_ADDA_R_ADCMIX_SRC_OMIXL 0 -+ -+#define SUN50I_ADDA_ADC_CTRL 0x0d -+#define SUN50I_ADDA_ADC_CTRL_ADCREN 7 -+#define SUN50I_ADDA_ADC_CTRL_ADCLEN 6 -+#define SUN50I_ADDA_ADC_CTRL_ADCG 0 -+ -+#define SUN50I_ADDA_HS_MBIAS_CTRL 0x0e -+#define SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN 7 -+ -+#define SUN50I_ADDA_JACK_MIC_CTRL 0x1d -+#define SUN50I_ADDA_JACK_MIC_CTRL_HMICBIASEN 5 -+ -+/* mixer controls */ -+static const struct snd_kcontrol_new sun50i_a64_codec_mixer_controls[] = { -+ SOC_DAPM_DOUBLE_R("DAC Playback Switch", -+ SUN50I_ADDA_OL_MIX_CTRL, -+ SUN50I_ADDA_OR_MIX_CTRL, -+ SUN50I_ADDA_OL_MIX_CTRL_DACL, 1, 0), -+ SOC_DAPM_DOUBLE_R("DAC Reversed Playback Switch", -+ SUN50I_ADDA_OL_MIX_CTRL, -+ SUN50I_ADDA_OR_MIX_CTRL, -+ SUN50I_ADDA_OL_MIX_CTRL_DACR, 1, 0), -+ SOC_DAPM_DOUBLE_R("Line In Playback Switch", -+ SUN50I_ADDA_OL_MIX_CTRL, -+ SUN50I_ADDA_OR_MIX_CTRL, -+ SUN50I_ADDA_OL_MIX_CTRL_LINEINL, 1, 0), -+ SOC_DAPM_DOUBLE_R("Mic1 Playback Switch", -+ SUN50I_ADDA_OL_MIX_CTRL, -+ SUN50I_ADDA_OR_MIX_CTRL, -+ SUN50I_ADDA_OL_MIX_CTRL_MIC1, 1, 0), -+ SOC_DAPM_DOUBLE_R("Mic2 Playback Switch", -+ SUN50I_ADDA_OL_MIX_CTRL, -+ SUN50I_ADDA_OR_MIX_CTRL, -+ SUN50I_ADDA_OL_MIX_CTRL_MIC2, 1, 0), -+}; -+ -+/* ADC mixer controls */ -+static const struct snd_kcontrol_new sun50i_codec_adc_mixer_controls[] = { -+ SOC_DAPM_DOUBLE_R("Mixer Capture Switch", -+ SUN50I_ADDA_L_ADCMIX_SRC, -+ SUN50I_ADDA_R_ADCMIX_SRC, -+ SUN50I_ADDA_L_ADCMIX_SRC_OMIXRL, 1, 0), -+ SOC_DAPM_DOUBLE_R("Mixer Reversed Capture Switch", -+ SUN50I_ADDA_L_ADCMIX_SRC, -+ SUN50I_ADDA_R_ADCMIX_SRC, -+ SUN50I_ADDA_L_ADCMIX_SRC_OMIXRR, 1, 0), -+ SOC_DAPM_DOUBLE_R("Line In Capture Switch", -+ SUN50I_ADDA_L_ADCMIX_SRC, -+ SUN50I_ADDA_R_ADCMIX_SRC, -+ SUN50I_ADDA_L_ADCMIX_SRC_LINEINL, 1, 0), -+ SOC_DAPM_DOUBLE_R("Mic1 Capture Switch", -+ SUN50I_ADDA_L_ADCMIX_SRC, -+ SUN50I_ADDA_R_ADCMIX_SRC, -+ SUN50I_ADDA_L_ADCMIX_SRC_MIC1, 1, 0), -+ SOC_DAPM_DOUBLE_R("Mic2 Capture Switch", -+ SUN50I_ADDA_L_ADCMIX_SRC, -+ SUN50I_ADDA_R_ADCMIX_SRC, -+ SUN50I_ADDA_L_ADCMIX_SRC_MIC2, 1, 0), -+}; -+ -+static const DECLARE_TLV_DB_SCALE(sun50i_codec_out_mixer_pregain_scale, -+ -450, 150, 0); -+static const DECLARE_TLV_DB_RANGE(sun50i_codec_mic_gain_scale, -+ 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), -+ 1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0), -+); -+ -+static const DECLARE_TLV_DB_SCALE(sun50i_codec_hp_vol_scale, -6300, 100, 1); -+ -+static const DECLARE_TLV_DB_RANGE(sun50i_codec_lineout_vol_scale, -+ 0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), -+ 2, 31, TLV_DB_SCALE_ITEM(-4350, 150, 0), -+); -+ -+ -+/* volume / mute controls */ -+static const struct snd_kcontrol_new sun50i_a64_codec_controls[] = { -+ SOC_SINGLE_TLV("Headphone Playback Volume", -+ SUN50I_ADDA_HP_CTRL, -+ SUN50I_ADDA_HP_CTRL_HPVOL, 0x3f, 0, -+ sun50i_codec_hp_vol_scale), -+ -+ SOC_DOUBLE("Headphone Playback Switch", -+ SUN50I_ADDA_MIX_DAC_CTRL, -+ SUN50I_ADDA_MIX_DAC_CTRL_LHPPAMUTE, -+ SUN50I_ADDA_MIX_DAC_CTRL_RHPPAMUTE, 1, 0), -+ -+ /* Mixer pre-gain */ -+ SOC_SINGLE_TLV("Mic1 Playback Volume", SUN50I_ADDA_MIC1_CTRL, -+ SUN50I_ADDA_MIC1_CTRL_MIC1G, -+ 0x7, 0, sun50i_codec_out_mixer_pregain_scale), -+ -+ /* Microphone Amp boost gain */ -+ SOC_SINGLE_TLV("Mic1 Boost Volume", SUN50I_ADDA_MIC1_CTRL, -+ SUN50I_ADDA_MIC1_CTRL_MIC1BOOST, 0x7, 0, -+ sun50i_codec_mic_gain_scale), -+ -+ /* Mixer pre-gain */ -+ SOC_SINGLE_TLV("Mic2 Playback Volume", -+ SUN50I_ADDA_MIC2_CTRL, SUN50I_ADDA_MIC2_CTRL_MIC2G, -+ 0x7, 0, sun50i_codec_out_mixer_pregain_scale), -+ -+ /* Microphone Amp boost gain */ -+ SOC_SINGLE_TLV("Mic2 Boost Volume", SUN50I_ADDA_MIC2_CTRL, -+ SUN50I_ADDA_MIC2_CTRL_MIC2BOOST, 0x7, 0, -+ sun50i_codec_mic_gain_scale), -+ -+ /* ADC */ -+ SOC_SINGLE_TLV("ADC Gain Capture Volume", SUN50I_ADDA_ADC_CTRL, -+ SUN50I_ADDA_ADC_CTRL_ADCG, 0x7, 0, -+ sun50i_codec_out_mixer_pregain_scale), -+ -+ /* Mixer pre-gain */ -+ SOC_SINGLE_TLV("Line In Playback Volume", SUN50I_ADDA_LINEIN_CTRL, -+ SUN50I_ADDA_LINEIN_CTRL_LINEING, -+ 0x7, 0, sun50i_codec_out_mixer_pregain_scale), -+ -+ SOC_SINGLE_TLV("Line Out Playback Volume", -+ SUN50I_ADDA_LINEOUT_CTRL1, -+ SUN50I_ADDA_LINEOUT_CTRL1_VOL, 0x1f, 0, -+ sun50i_codec_lineout_vol_scale), -+ -+ SOC_DOUBLE("Line Out Playback Switch", -+ SUN50I_ADDA_LINEOUT_CTRL0, -+ SUN50I_ADDA_LINEOUT_CTRL0_LEN, -+ SUN50I_ADDA_LINEOUT_CTRL0_REN, 1, 0), -+ -+}; -+ -+static const char * const sun50i_codec_hp_src_enum_text[] = { -+ "DAC", "Mixer", -+}; -+ -+static SOC_ENUM_DOUBLE_DECL(sun50i_codec_hp_src_enum, -+ SUN50I_ADDA_MIX_DAC_CTRL, -+ SUN50I_ADDA_MIX_DAC_CTRL_LHPIS, -+ SUN50I_ADDA_MIX_DAC_CTRL_RHPIS, -+ sun50i_codec_hp_src_enum_text); -+ -+static const struct snd_kcontrol_new sun50i_codec_hp_src[] = { -+ SOC_DAPM_ENUM("Headphone Source Playback Route", -+ sun50i_codec_hp_src_enum), -+}; -+ -+static const char * const sun50i_codec_lineout_src_enum_text[] = { -+ "Stereo", "Mono Differential", -+}; -+ -+static SOC_ENUM_DOUBLE_DECL(sun50i_codec_lineout_src_enum, -+ SUN50I_ADDA_LINEOUT_CTRL0, -+ SUN50I_ADDA_LINEOUT_CTRL0_LSRC_SEL, -+ SUN50I_ADDA_LINEOUT_CTRL0_RSRC_SEL, -+ sun50i_codec_lineout_src_enum_text); -+ -+static const struct snd_kcontrol_new sun50i_codec_lineout_src[] = { -+ SOC_DAPM_ENUM("Line Out Source Playback Route", -+ sun50i_codec_lineout_src_enum), -+}; -+ -+static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = { -+ /* DAC */ -+ SND_SOC_DAPM_DAC("Left DAC", NULL, SUN50I_ADDA_MIX_DAC_CTRL, -+ SUN50I_ADDA_MIX_DAC_CTRL_DACALEN, 0), -+ SND_SOC_DAPM_DAC("Right DAC", NULL, SUN50I_ADDA_MIX_DAC_CTRL, -+ SUN50I_ADDA_MIX_DAC_CTRL_DACAREN, 0), -+ /* ADC */ -+ SND_SOC_DAPM_ADC("Left ADC", NULL, SUN50I_ADDA_ADC_CTRL, -+ SUN50I_ADDA_ADC_CTRL_ADCLEN, 0), -+ SND_SOC_DAPM_ADC("Right ADC", NULL, SUN50I_ADDA_ADC_CTRL, -+ SUN50I_ADDA_ADC_CTRL_ADCREN, 0), -+ /* -+ * Due to this component and the codec belonging to separate DAPM -+ * contexts, we need to manually link the above widgets to their -+ * stream widgets at the card level. -+ */ -+ -+ SND_SOC_DAPM_MUX("Headphone Source Playback Route", -+ SND_SOC_NOPM, 0, 0, sun50i_codec_hp_src), -+ SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN50I_ADDA_HP_CTRL, -+ SUN50I_ADDA_HP_CTRL_HPPA_EN, 0, NULL, 0), -+ SND_SOC_DAPM_OUTPUT("HP"), -+ -+ SND_SOC_DAPM_MUX("Line Out Source Playback Route", -+ SND_SOC_NOPM, 0, 0, sun50i_codec_lineout_src), -+ SND_SOC_DAPM_OUTPUT("LINEOUT"), -+ -+ /* Microphone inputs */ -+ SND_SOC_DAPM_INPUT("MIC1"), -+ -+ /* Microphone Bias */ -+ SND_SOC_DAPM_SUPPLY("MBIAS", SUN50I_ADDA_HS_MBIAS_CTRL, -+ SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN, -+ 0, NULL, 0), -+ -+ /* Mic input path */ -+ SND_SOC_DAPM_PGA("Mic1 Amplifier", SUN50I_ADDA_MIC1_CTRL, -+ SUN50I_ADDA_MIC1_CTRL_MIC1AMPEN, 0, NULL, 0), -+ -+ /* Microphone input */ -+ SND_SOC_DAPM_INPUT("MIC2"), -+ -+ /* Microphone Bias */ -+ SND_SOC_DAPM_SUPPLY("HBIAS", SUN50I_ADDA_JACK_MIC_CTRL, -+ SUN50I_ADDA_JACK_MIC_CTRL_HMICBIASEN, -+ 0, NULL, 0), -+ -+ /* Mic input path */ -+ SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN50I_ADDA_MIC2_CTRL, -+ SUN50I_ADDA_MIC2_CTRL_MIC2AMPEN, 0, NULL, 0), -+ -+ /* Line input */ -+ SND_SOC_DAPM_INPUT("LINEIN"), -+ -+ /* Mixers */ -+ SND_SOC_DAPM_MIXER("Left Mixer", SUN50I_ADDA_MIX_DAC_CTRL, -+ SUN50I_ADDA_MIX_DAC_CTRL_LMIXEN, 0, -+ sun50i_a64_codec_mixer_controls, -+ ARRAY_SIZE(sun50i_a64_codec_mixer_controls)), -+ SND_SOC_DAPM_MIXER("Right Mixer", SUN50I_ADDA_MIX_DAC_CTRL, -+ SUN50I_ADDA_MIX_DAC_CTRL_RMIXEN, 0, -+ sun50i_a64_codec_mixer_controls, -+ ARRAY_SIZE(sun50i_a64_codec_mixer_controls)), -+ SND_SOC_DAPM_MIXER("Left ADC Mixer", SUN50I_ADDA_ADC_CTRL, -+ SUN50I_ADDA_ADC_CTRL_ADCLEN, 0, -+ sun50i_codec_adc_mixer_controls, -+ ARRAY_SIZE(sun50i_codec_adc_mixer_controls)), -+ SND_SOC_DAPM_MIXER("Right ADC Mixer", SUN50I_ADDA_ADC_CTRL, -+ SUN50I_ADDA_ADC_CTRL_ADCREN, 0, -+ sun50i_codec_adc_mixer_controls, -+ ARRAY_SIZE(sun50i_codec_adc_mixer_controls)), -+}; -+ -+static const struct snd_soc_dapm_route sun50i_a64_codec_routes[] = { -+ /* Left Mixer Routes */ -+ { "Left Mixer", "DAC Playback Switch", "Left DAC" }, -+ { "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" }, -+ { "Left Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" }, -+ -+ /* Right Mixer Routes */ -+ { "Right Mixer", "DAC Playback Switch", "Right DAC" }, -+ { "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" }, -+ { "Right Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" }, -+ -+ /* Left ADC Mixer Routes */ -+ { "Left ADC Mixer", "Mixer Capture Switch", "Left Mixer" }, -+ { "Left ADC Mixer", "Mixer Reversed Capture Switch", "Right Mixer" }, -+ { "Left ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" }, -+ -+ /* Right ADC Mixer Routes */ -+ { "Right ADC Mixer", "Mixer Capture Switch", "Right Mixer" }, -+ { "Right ADC Mixer", "Mixer Reversed Capture Switch", "Left Mixer" }, -+ { "Right ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" }, -+ -+ /* ADC Routes */ -+ { "Left ADC", NULL, "Left ADC Mixer" }, -+ { "Right ADC", NULL, "Right ADC Mixer" }, -+ -+ /* Headphone Routes */ -+ { "Headphone Source Playback Route", "DAC", "Left DAC" }, -+ { "Headphone Source Playback Route", "DAC", "Right DAC" }, -+ { "Headphone Source Playback Route", "Mixer", "Left Mixer" }, -+ { "Headphone Source Playback Route", "Mixer", "Right Mixer" }, -+ { "Headphone Amp", NULL, "Headphone Source Playback Route" }, -+ { "HP", NULL, "Headphone Amp" }, -+ -+ /* Microphone Routes */ -+ { "Mic1 Amplifier", NULL, "MIC1"}, -+ -+ /* Microphone Routes */ -+ { "Mic2 Amplifier", NULL, "MIC2"}, -+ { "Left Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" }, -+ { "Right Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" }, -+ { "Left ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" }, -+ { "Right ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" }, -+ -+ /* Line-in Routes */ -+ { "Left Mixer", "Line In Playback Switch", "LINEIN" }, -+ { "Right Mixer", "Line In Playback Switch", "LINEIN" }, -+ { "Left ADC Mixer", "Line In Capture Switch", "LINEIN" }, -+ { "Right ADC Mixer", "Line In Capture Switch", "LINEIN" }, -+ -+ /* Line-out Routes */ -+ { "Line Out Source Playback Route", "Stereo", "Left Mixer" }, -+ { "Line Out Source Playback Route", "Stereo", "Right Mixer" }, -+ { "Line Out Source Playback Route", "Mono Differential", "Left Mixer" }, -+ { "Line Out Source Playback Route", "Mono Differential", -+ "Right Mixer" }, -+ { "LINEOUT", NULL, "Line Out Source Playback Route" }, -+}; -+ -+static const struct snd_soc_component_driver sun50i_codec_analog_cmpnt_drv = { -+ .controls = sun50i_a64_codec_controls, -+ .num_controls = ARRAY_SIZE(sun50i_a64_codec_controls), -+ .dapm_widgets = sun50i_a64_codec_widgets, -+ .num_dapm_widgets = ARRAY_SIZE(sun50i_a64_codec_widgets), -+ .dapm_routes = sun50i_a64_codec_routes, -+ .num_dapm_routes = ARRAY_SIZE(sun50i_a64_codec_routes), -+}; -+ -+static const struct of_device_id sun50i_codec_analog_of_match[] = { -+ { -+ .compatible = "allwinner,sun50i-a64-codec-analog", -+ }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, sun50i_codec_analog_of_match); -+ -+static int sun50i_codec_analog_probe(struct platform_device *pdev) -+{ -+ struct resource *res; -+ struct regmap *regmap; -+ void __iomem *base; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(base)) { -+ dev_err(&pdev->dev, "Failed to map the registers\n"); -+ return PTR_ERR(base); -+ } -+ -+ regmap = sun8i_adda_pr_regmap_init(&pdev->dev, base); -+ if (IS_ERR(regmap)) { -+ dev_err(&pdev->dev, "Failed to create regmap\n"); -+ return PTR_ERR(regmap); -+ } -+ -+ return devm_snd_soc_register_component(&pdev->dev, -+ &sun50i_codec_analog_cmpnt_drv, -+ NULL, 0); -+} -+ -+static struct platform_driver sun50i_codec_analog_driver = { -+ .driver = { -+ .name = "sun50i-codec-analog", -+ .of_match_table = sun50i_codec_analog_of_match, -+ }, -+ .probe = sun50i_codec_analog_probe, -+}; -+module_platform_driver(sun50i_codec_analog_driver); -+ -+MODULE_DESCRIPTION("Allwinner internal codec analog controls driver for A64"); -+MODULE_AUTHOR("Vasily Khoruzhick "); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:sun50i-codec-analog"); --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0119-ASoC-sunxi-allow-the-sun8i-codec-driver-to-be-built-.patch b/patch/kernel/sunxi-legacy/0119-ASoC-sunxi-allow-the-sun8i-codec-driver-to-be-built-.patch deleted file mode 100644 index 73f892814..000000000 --- a/patch/kernel/sunxi-legacy/0119-ASoC-sunxi-allow-the-sun8i-codec-driver-to-be-built-.patch +++ /dev/null @@ -1,31 +0,0 @@ -From b66aa83817ae94f594e1c1505127530190ef4eba Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Fri, 12 Oct 2018 23:54:55 -0700 -Subject: [PATCH 119/146] ASoC: sunxi: allow the sun8i-codec driver to be built - on ARM64 - -Allwinner A64 uses the same digital codec part as in A33, so we need -to build this driver on ARM64 as well. - -Signed-off-by: Vasily Khoruzhick -Acked-by: Maxime Ripard ---- - sound/soc/sunxi/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig -index 8a055ca1819a..66aad0d3f9c7 100644 ---- a/sound/soc/sunxi/Kconfig -+++ b/sound/soc/sunxi/Kconfig -@@ -12,7 +12,7 @@ config SND_SUN4I_CODEC - config SND_SUN8I_CODEC - tristate "Allwinner SUN8I audio codec" - depends on OF -- depends on MACH_SUN8I || COMPILE_TEST -+ depends on MACH_SUN8I || (ARM64 && ARCH_SUNXI) || COMPILE_TEST - select REGMAP_MMIO - help - This option enables the digital part of the internal audio codec for --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0120-arm64-dts-allwinner-a64-add-nodes-necessary-for-anal.patch b/patch/kernel/sunxi-legacy/0120-arm64-dts-allwinner-a64-add-nodes-necessary-for-anal.patch-DISABLED similarity index 100% rename from patch/kernel/sunxi-legacy/0120-arm64-dts-allwinner-a64-add-nodes-necessary-for-anal.patch rename to patch/kernel/sunxi-legacy/0120-arm64-dts-allwinner-a64-add-nodes-necessary-for-anal.patch-DISABLED diff --git a/patch/kernel/sunxi-legacy/0121-arm64-dts-allwinner-a64-enable-sound-on-Pine64-and-S.patch b/patch/kernel/sunxi-legacy/0121-arm64-dts-allwinner-a64-enable-sound-on-Pine64-and-S.patch deleted file mode 100644 index 6f7fb61e0..000000000 --- a/patch/kernel/sunxi-legacy/0121-arm64-dts-allwinner-a64-enable-sound-on-Pine64-and-S.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 4c61972a0318859afc6a2dbb9cdd355625f6cefc Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Sun, 3 Dec 2017 11:39:19 -0800 -Subject: [PATCH 121/146] arm64: dts: allwinner: a64: enable sound on Pine64 - and SoPine - -This commit enables I2S, digital and analog parts of audiocodec on -Pine64 and SoPine boards. - -Signed-off-by: Vasily Khoruzhick ---- - .../boot/dts/allwinner/sun50i-a64-pine64.dts | 29 +++++++++++++++++++ - .../allwinner/sun50i-a64-sopine-baseboard.dts | 29 +++++++++++++++++++ - 2 files changed, 58 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts -index cd7e938db01a..f6fc0ed2f4ec 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts -@@ -81,10 +81,22 @@ - }; - }; - -+&codec { -+ status = "okay"; -+}; -+ -+&codec_analog { -+ status = "okay"; -+}; -+ - &cpu0 { - cpu-supply = <®_dcdc2>; - }; - -+&dai { -+ status = "okay"; -+}; -+ - &de { - status = "okay"; - }; -@@ -289,6 +301,23 @@ - status = "disabled"; - }; - -+&sound { -+ status = "okay"; -+ simple-audio-card,widgets = "Microphone", "Microphone Jack", -+ "Headphone", "Headphone Jack"; -+ simple-audio-card,routing = -+ "Left DAC", "AIF1 Slot 0 Left", -+ "Right DAC", "AIF1 Slot 0 Right", -+ "Speaker", "LINEOUT", -+ "Headphone Jack", "HP", -+ "AIF1 Slot 0 Left ADC", "Left ADC", -+ "AIF1 Slot 0 Right ADC", "Right ADC", -+ "Left ADC", "ADC", -+ "Right ADC", "ADC", -+ "Microphone Jack", "HBIAS", -+ "MIC2", "Microphone Jack"; -+}; -+ - &sound_hdmi { - status = "okay"; - }; -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts -index df7aa8c5f751..9010bd58af1b 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts -@@ -88,10 +88,22 @@ - status = "okay"; - }; - -+&codec { -+ status = "okay"; -+}; -+ -+&codec_analog { -+ status = "okay"; -+}; -+ - &cpu0 { - cpu-supply = <®_dcdc2>; - }; - -+&dai { -+ status = "okay"; -+}; -+ - &de { - status = "okay"; - }; -@@ -191,6 +203,23 @@ - vcc-hdmi-supply = <®_dldo1>; - }; - -+&sound { -+ status = "okay"; -+ simple-audio-card,widgets = "Microphone", "Microphone Jack", -+ "Headphone", "Headphone Jack"; -+ simple-audio-card,routing = -+ "Left DAC", "AIF1 Slot 0 Left", -+ "Right DAC", "AIF1 Slot 0 Right", -+ "Speaker", "LINEOUT", -+ "Headphone Jack", "HP", -+ "AIF1 Slot 0 Left ADC", "Left ADC", -+ "AIF1 Slot 0 Right ADC", "Right ADC", -+ "Left ADC", "ADC", -+ "Right ADC", "ADC", -+ "Microphone Jack", "HBIAS", -+ "MIC2", "Microphone Jack"; -+}; -+ - &sound_hdmi { - status = "okay"; - }; --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0122-arm64-dts-allwinner-a64-enable-sound-on-Pinebook.patch b/patch/kernel/sunxi-legacy/0122-arm64-dts-allwinner-a64-enable-sound-on-Pinebook.patch deleted file mode 100644 index 3b1479df5..000000000 --- a/patch/kernel/sunxi-legacy/0122-arm64-dts-allwinner-a64-enable-sound-on-Pinebook.patch +++ /dev/null @@ -1,86 +0,0 @@ -From d0970394839f5b09d564142c8a4687ef64458586 Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Sun, 3 Dec 2017 11:40:25 -0800 -Subject: [PATCH 122/146] arm64: dts: allwinner: a64: enable sound on Pinebook - -This commit enables I2S, digital and analog parts of audiocodec on -Pinebook - -Signed-off-by: Vasily Khoruzhick ---- - .../dts/allwinner/sun50i-a64-pinebook.dts | 42 +++++++++++++++++++ - 1 file changed, 42 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -index dce16d9d6afb..b55ac4e1df37 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -@@ -71,16 +71,33 @@ - regulator-max-microvolt = <3300000>; - }; - -+ speaker_amp: speaker_amp { -+ compatible = "simple-audio-amplifier"; -+ enable-gpios = <&pio 7 7 GPIO_ACTIVE_HIGH>; -+ }; -+ - wifi_pwrseq: wifi_pwrseq { - compatible = "mmc-pwrseq-simple"; - reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */ - }; - }; - -+&codec { -+ status = "okay"; -+}; -+ -+&codec_analog { -+ status = "okay"; -+}; -+ - &cpu0 { - cpu-supply = <®_dcdc2>; - }; - -+&dai { -+ status = "okay"; -+}; -+ - &de { - status = "okay"; - }; -@@ -306,6 +323,31 @@ - vcc-hdmi-supply = <®_dldo1>; - }; - -+&sound { -+ status = "okay"; -+ simple-audio-card,widgets = "Microphone", "Internal Microphone Left", -+ "Microphone", "Internal Microphone Right", -+ "Headphone", "Headphone Jack", -+ "Speaker", "Internal Speaker"; -+ simple-audio-card,aux-devs = <&codec_analog>, <&speaker_amp>; -+ simple-audio-card,routing = -+ "Left DAC", "AIF1 Slot 0 Left", -+ "Right DAC", "AIF1 Slot 0 Right", -+ "INL", "LINEOUT", -+ "INR", "LINEOUT", -+ "Internal Speaker", "OUTL", -+ "Internal Speaker", "OUTR", -+ "Headphone Jack", "HP", -+ "AIF1 Slot 0 Left ADC", "Left ADC", -+ "AIF1 Slot 0 Right ADC", "Right ADC", -+ "Left ADC", "ADC", -+ "Right ADC", "ADC", -+ "Internal Microphone Left", "MBIAS", -+ "MIC1", "Internal Microphone Left", -+ "Internal Microphone Right", "HBIAS", -+ "MIC2", "Internal Microphone Right"; -+}; -+ - &uart0 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0123-drm-sun4i-tcon-enable-dithering-on-tcon0-is-there-s-.patch b/patch/kernel/sunxi-legacy/0123-drm-sun4i-tcon-enable-dithering-on-tcon0-is-there-s-.patch.disabled similarity index 100% rename from patch/kernel/sunxi-legacy/0123-drm-sun4i-tcon-enable-dithering-on-tcon0-is-there-s-.patch rename to patch/kernel/sunxi-legacy/0123-drm-sun4i-tcon-enable-dithering-on-tcon0-is-there-s-.patch.disabled diff --git a/patch/kernel/sunxi-legacy/0124-drm-lima-Fix-Lima-to-work-with-drm-scheduler-changes.patch b/patch/kernel/sunxi-legacy/0124-drm-lima-Fix-Lima-to-work-with-drm-scheduler-changes.patch deleted file mode 100644 index 834a75467..000000000 --- a/patch/kernel/sunxi-legacy/0124-drm-lima-Fix-Lima-to-work-with-drm-scheduler-changes.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 2b07a3e1c8918d96db4939c85b5eafcffefd2285 Mon Sep 17 00:00:00 2001 -From: Andreas Baierl -Date: Thu, 4 Oct 2018 06:21:09 -0400 -Subject: [PATCH 124/146] drm/lima: Fix Lima to work with drm scheduler changes - since 4.19 - -Signed-off-by: Andreas Baierl ---- - drivers/gpu/drm/lima/lima_sched.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c -index 1e715e58d33b..d09aae446883 100644 ---- a/drivers/gpu/drm/lima/lima_sched.c -+++ b/drivers/gpu/drm/lima/lima_sched.c -@@ -110,8 +110,7 @@ int lima_sched_task_init(struct lima_sched_task *task, - { - int err; - -- err = drm_sched_job_init(&task->base, context->base.sched, -- &context->base, vm); -+ err = drm_sched_job_init(&task->base, &context->base, vm); - if (err) - return err; - -@@ -169,7 +168,7 @@ int lima_sched_context_init(struct lima_sched_pipe *pipe, - return -ENOMEM; - - mutex_init(&context->lock); -- err = drm_sched_entity_init(&pipe->base, &context->base, rq, guilty); -+ err = drm_sched_entity_init(&context->base, &rq, 1, guilty); - if (err) { - kfree(context->fences); - context->fences = NULL; -@@ -182,7 +181,7 @@ int lima_sched_context_init(struct lima_sched_pipe *pipe, - void lima_sched_context_fini(struct lima_sched_pipe *pipe, - struct lima_sched_context *context) - { -- drm_sched_entity_fini(&pipe->base, &context->base); -+ drm_sched_entity_fini(&context->base); - - mutex_destroy(&context->lock); - --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0125-drm-lima-Fix-lima-cache-creation.patch b/patch/kernel/sunxi-legacy/0125-drm-lima-Fix-lima-cache-creation.patch deleted file mode 100644 index 2712a0116..000000000 --- a/patch/kernel/sunxi-legacy/0125-drm-lima-Fix-lima-cache-creation.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 491af9a7e7ccddb1c3045c7f9cd2990f6d22154f Mon Sep 17 00:00:00 2001 -From: Andreas Baierl -Date: Tue, 16 Oct 2018 03:19:20 -0400 -Subject: [PATCH 125/146] drm/lima: Fix lima cache creation - -Due to the kernel merge of the hardened usercopy patch set -we have to whitelist the memory area which is used for -copy_from_user actions. Otherwise lima fails with an abort -and segmentation fault. - -This is necessary on systems with CONFIG_HARDENED_USERCOPY enabled. -It was tested on a Cubieboard 1, Allwinner A10. - -Signed-off-by: Andreas Baierl ---- - drivers/gpu/drm/lima/lima_gp.c | 5 +++-- - drivers/gpu/drm/lima/lima_pp.c | 5 +++-- - 2 files changed, 6 insertions(+), 4 deletions(-) - -diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c -index 706652cb1741..6c902648e5cd 100644 ---- a/drivers/gpu/drm/lima/lima_gp.c -+++ b/drivers/gpu/drm/lima/lima_gp.c -@@ -245,9 +245,10 @@ int lima_gp_pipe_init(struct lima_device *dev) - struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp; - - if (!lima_gp_task_slab) { -- lima_gp_task_slab = kmem_cache_create( -+ lima_gp_task_slab = kmem_cache_create_usercopy( - "lima_gp_task", sizeof(struct lima_sched_task) + frame_size, -- 0, SLAB_HWCACHE_ALIGN, NULL); -+ 0, SLAB_HWCACHE_ALIGN, sizeof(struct lima_sched_task), -+ frame_size, NULL); - if (!lima_gp_task_slab) - return -ENOMEM; - } -diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c -index 3355895ceeba..502190d1bf3f 100644 ---- a/drivers/gpu/drm/lima/lima_pp.c -+++ b/drivers/gpu/drm/lima/lima_pp.c -@@ -383,9 +383,10 @@ int lima_pp_pipe_init(struct lima_device *dev) - frame_size = sizeof(struct drm_lima_m450_pp_frame); - - if (!lima_pp_task_slab) { -- lima_pp_task_slab = kmem_cache_create( -+ lima_pp_task_slab = kmem_cache_create_usercopy( - "lima_pp_task", sizeof(struct lima_sched_task) + frame_size, -- 0, SLAB_HWCACHE_ALIGN, NULL); -+ 0, SLAB_HWCACHE_ALIGN, sizeof(struct lima_sched_task), -+ frame_size, NULL); - if (!lima_pp_task_slab) - return -ENOMEM; - } --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0126-drm-bridge-move-ANA78xx-driver-to-analogix-subdirect.patch b/patch/kernel/sunxi-legacy/0126-drm-bridge-move-ANA78xx-driver-to-analogix-subdirect.patch index ef311d2df..d58ce1bca 100644 --- a/patch/kernel/sunxi-legacy/0126-drm-bridge-move-ANA78xx-driver-to-analogix-subdirect.patch +++ b/patch/kernel/sunxi-legacy/0126-drm-bridge-move-ANA78xx-driver-to-analogix-subdirect.patch @@ -20,29 +20,8 @@ Reviewed-by: Laurent Pinchart rename drivers/gpu/drm/bridge/{ => analogix}/analogix-anx78xx.c (100%) rename drivers/gpu/drm/bridge/{ => analogix}/analogix-anx78xx.h (100%) -diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig -index bf6cad6c9178..43f3c8ff54a4 100644 ---- a/drivers/gpu/drm/bridge/Kconfig -+++ b/drivers/gpu/drm/bridge/Kconfig -@@ -15,16 +15,6 @@ config DRM_PANEL_BRIDGE - menu "Display Interface Bridges" - depends on DRM && DRM_BRIDGE - --config DRM_ANALOGIX_ANX78XX -- tristate "Analogix ANX78XX bridge" -- select DRM_KMS_HELPER -- select REGMAP_I2C -- ---help--- -- ANX78XX is an ultra-low Full-HD SlimPort transmitter -- designed for portable devices. The ANX78XX transforms -- the HDMI output of an application processor to MyDP -- or DisplayPort. -- - config DRM_CDNS_DSI - tristate "Cadence DPI/DSI bridge" - select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile -index 35f88d48ec20..49a5d92a0d9d 100644 +index 4934fcf..729a806 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,5 +1,4 @@ @@ -51,50 +30,3 @@ index 35f88d48ec20..49a5d92a0d9d 100644 obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o obj-$(CONFIG_DRM_LVDS_ENCODER) += lvds-encoder.o -@@ -11,7 +10,8 @@ obj-$(CONFIG_DRM_SII902X) += sii902x.o - obj-$(CONFIG_DRM_SII9234) += sii9234.o - obj-$(CONFIG_DRM_THINE_THC63LVD1024) += thc63lvd1024.o - obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o --obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/ - obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ - obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o -+ -+obj-y += analogix/ - obj-y += synopsys/ -diff --git a/drivers/gpu/drm/bridge/analogix/Kconfig b/drivers/gpu/drm/bridge/analogix/Kconfig -index 80f286fa3a69..27b37aa2ea77 100644 ---- a/drivers/gpu/drm/bridge/analogix/Kconfig -+++ b/drivers/gpu/drm/bridge/analogix/Kconfig -@@ -1,3 +1,13 @@ - config DRM_ANALOGIX_DP - tristate - depends on DRM -+ -+config DRM_ANALOGIX_ANX78XX -+ tristate "Analogix ANX78XX bridge" -+ select DRM_KMS_HELPER -+ select REGMAP_I2C -+ ---help--- -+ ANX78XX is an ultra-low Full-HD SlimPort transmitter -+ designed for portable devices. The ANX78XX transforms -+ the HDMI output of an application processor to MyDP -+ or DisplayPort. -diff --git a/drivers/gpu/drm/bridge/analogix/Makefile b/drivers/gpu/drm/bridge/analogix/Makefile -index cd4010ba6890..eb41be845055 100644 ---- a/drivers/gpu/drm/bridge/analogix/Makefile -+++ b/drivers/gpu/drm/bridge/analogix/Makefile -@@ -1,2 +1,3 @@ - analogix_dp-objs := analogix_dp_core.o analogix_dp_reg.o - obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix_dp.o -+obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o -diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c -similarity index 100% -rename from drivers/gpu/drm/bridge/analogix-anx78xx.c -rename to drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c -diff --git a/drivers/gpu/drm/bridge/analogix-anx78xx.h b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.h -similarity index 100% -rename from drivers/gpu/drm/bridge/analogix-anx78xx.h -rename to drivers/gpu/drm/bridge/analogix/analogix-anx78xx.h --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0127-drm-bridge-split-some-definitions-of-ANX78xx-to-dedi.patch b/patch/kernel/sunxi-legacy/0127-drm-bridge-split-some-definitions-of-ANX78xx-to-dedi.patch deleted file mode 100644 index 03b380246..000000000 --- a/patch/kernel/sunxi-legacy/0127-drm-bridge-split-some-definitions-of-ANX78xx-to-dedi.patch +++ /dev/null @@ -1,1005 +0,0 @@ -From d369162154e5d904c62ed6275ec71d8c2cbcb024 Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Thu, 18 Oct 2018 15:33:20 +0800 -Subject: [PATCH 127/146] drm/bridge: split some definitions of ANX78xx to - dedicated headers - -Some definitions currently in analogix-anx78xx.h are not restricted to -the ANX78xx series, but also applicable to other DisplayPort -transmitters by Analogix. - -Split out them to dedicated headers, and make analogix-anx78xx.h include -them. - -Signed-off-by: Icenowy Zheng ---- - .../drm/bridge/analogix/analogix-anx78xx.h | 464 +----------------- - .../drm/bridge/analogix/analogix-i2c-dptx.h | 248 ++++++++++ - .../bridge/analogix/analogix-i2c-txcommon.h | 237 +++++++++ - 3 files changed, 490 insertions(+), 459 deletions(-) - create mode 100644 drivers/gpu/drm/bridge/analogix/analogix-i2c-dptx.h - create mode 100644 drivers/gpu/drm/bridge/analogix/analogix-i2c-txcommon.h - -diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.h b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.h -index 38753c870137..8aa1eca306d3 100644 ---- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.h -+++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.h -@@ -15,9 +15,12 @@ - #ifndef __ANX78xx_H - #define __ANX78xx_H - --#define TX_P0 0x70 -+#include "analogix-i2c-dptx.h" -+#include "analogix-i2c-txcommon.h" -+ -+#define TX_P0 ANALOGIX_I2C_DPTX - #define TX_P1 0x7a --#define TX_P2 0x72 -+#define TX_P2 ANALOGIX_I2C_TXCOMMON - - #define RX_P0 0x7e - #define RX_P1 0x80 -@@ -225,463 +228,6 @@ - #define SP_CLEAR_AVMUTE BIT(4) - #define SP_SET_AVMUTE BIT(0) - --/***************************************************************/ --/* Register definition of device address 0x70 */ --/***************************************************************/ -- --/* HDCP Status Register */ --#define SP_TX_HDCP_STATUS_REG 0x00 --#define SP_AUTH_FAIL BIT(5) --#define SP_AUTHEN_PASS BIT(1) -- --/* HDCP Control Register 0 */ --#define SP_HDCP_CTRL0_REG 0x01 --#define SP_RX_REPEATER BIT(6) --#define SP_RE_AUTH BIT(5) --#define SP_SW_AUTH_OK BIT(4) --#define SP_HARD_AUTH_EN BIT(3) --#define SP_HDCP_ENC_EN BIT(2) --#define SP_BKSV_SRM_PASS BIT(1) --#define SP_KSVLIST_VLD BIT(0) --/* HDCP Function Enabled */ --#define SP_HDCP_FUNCTION_ENABLED (BIT(0) | BIT(1) | BIT(2) | BIT(3)) -- --/* HDCP Receiver BSTATUS Register 0 */ --#define SP_HDCP_RX_BSTATUS0_REG 0x1b --/* HDCP Receiver BSTATUS Register 1 */ --#define SP_HDCP_RX_BSTATUS1_REG 0x1c -- --/* HDCP Embedded "Blue Screen" Content Registers */ --#define SP_HDCP_VID0_BLUE_SCREEN_REG 0x2c --#define SP_HDCP_VID1_BLUE_SCREEN_REG 0x2d --#define SP_HDCP_VID2_BLUE_SCREEN_REG 0x2e -- --/* HDCP Wait R0 Timing Register */ --#define SP_HDCP_WAIT_R0_TIME_REG 0x40 -- --/* HDCP Link Integrity Check Timer Register */ --#define SP_HDCP_LINK_CHECK_TIMER_REG 0x41 -- --/* HDCP Repeater Ready Wait Timer Register */ --#define SP_HDCP_RPTR_RDY_WAIT_TIME_REG 0x42 -- --/* HDCP Auto Timer Register */ --#define SP_HDCP_AUTO_TIMER_REG 0x51 -- --/* HDCP Key Status Register */ --#define SP_HDCP_KEY_STATUS_REG 0x5e -- --/* HDCP Key Command Register */ --#define SP_HDCP_KEY_COMMAND_REG 0x5f --#define SP_DISABLE_SYNC_HDCP BIT(2) -- --/* OTP Memory Key Protection Registers */ --#define SP_OTP_KEY_PROTECT1_REG 0x60 --#define SP_OTP_KEY_PROTECT2_REG 0x61 --#define SP_OTP_KEY_PROTECT3_REG 0x62 --#define SP_OTP_PSW1 0xa2 --#define SP_OTP_PSW2 0x7e --#define SP_OTP_PSW3 0xc6 -- --/* DP System Control Registers */ --#define SP_DP_SYSTEM_CTRL_BASE (0x80 - 1) --/* Bits for DP System Control Register 2 */ --#define SP_CHA_STA BIT(2) --/* Bits for DP System Control Register 3 */ --#define SP_HPD_STATUS BIT(6) --#define SP_STRM_VALID BIT(2) --/* Bits for DP System Control Register 4 */ --#define SP_ENHANCED_MODE BIT(3) -- --/* DP Video Control Register */ --#define SP_DP_VIDEO_CTRL_REG 0x84 --#define SP_COLOR_F_MASK 0x06 --#define SP_COLOR_F_SHIFT 1 --#define SP_BPC_MASK 0xe0 --#define SP_BPC_SHIFT 5 --# define SP_BPC_6BITS 0x00 --# define SP_BPC_8BITS 0x01 --# define SP_BPC_10BITS 0x02 --# define SP_BPC_12BITS 0x03 -- --/* DP Audio Control Register */ --#define SP_DP_AUDIO_CTRL_REG 0x87 --#define SP_AUD_EN BIT(0) -- --/* 10us Pulse Generate Timer Registers */ --#define SP_I2C_GEN_10US_TIMER0_REG 0x88 --#define SP_I2C_GEN_10US_TIMER1_REG 0x89 -- --/* Packet Send Control Register */ --#define SP_PACKET_SEND_CTRL_REG 0x90 --#define SP_AUD_IF_UP BIT(7) --#define SP_AVI_IF_UD BIT(6) --#define SP_MPEG_IF_UD BIT(5) --#define SP_SPD_IF_UD BIT(4) --#define SP_AUD_IF_EN BIT(3) --#define SP_AVI_IF_EN BIT(2) --#define SP_MPEG_IF_EN BIT(1) --#define SP_SPD_IF_EN BIT(0) -- --/* DP HDCP Control Register */ --#define SP_DP_HDCP_CTRL_REG 0x92 --#define SP_AUTO_EN BIT(7) --#define SP_AUTO_START BIT(5) --#define SP_LINK_POLLING BIT(1) -- --/* DP Main Link Bandwidth Setting Register */ --#define SP_DP_MAIN_LINK_BW_SET_REG 0xa0 --#define SP_LINK_BW_SET_MASK 0x1f --#define SP_INITIAL_SLIM_M_AUD_SEL BIT(5) -- --/* DP Training Pattern Set Register */ --#define SP_DP_TRAINING_PATTERN_SET_REG 0xa2 -- --/* DP Lane 0 Link Training Control Register */ --#define SP_DP_LANE0_LT_CTRL_REG 0xa3 --#define SP_TX_SW_SET_MASK 0x1b --#define SP_MAX_PRE_REACH BIT(5) --#define SP_MAX_DRIVE_REACH BIT(4) --#define SP_PRE_EMP_LEVEL1 BIT(3) --#define SP_DRVIE_CURRENT_LEVEL1 BIT(0) -- --/* DP Link Training Control Register */ --#define SP_DP_LT_CTRL_REG 0xa8 --#define SP_LT_ERROR_TYPE_MASK 0x70 --# define SP_LT_NO_ERROR 0x00 --# define SP_LT_AUX_WRITE_ERROR 0x01 --# define SP_LT_MAX_DRIVE_REACHED 0x02 --# define SP_LT_WRONG_LANE_COUNT_SET 0x03 --# define SP_LT_LOOP_SAME_5_TIME 0x04 --# define SP_LT_CR_FAIL_IN_EQ 0x05 --# define SP_LT_EQ_LOOP_5_TIME 0x06 --#define SP_LT_EN BIT(0) -- --/* DP CEP Training Control Registers */ --#define SP_DP_CEP_TRAINING_CTRL0_REG 0xa9 --#define SP_DP_CEP_TRAINING_CTRL1_REG 0xaa -- --/* DP Debug Register 1 */ --#define SP_DP_DEBUG1_REG 0xb0 --#define SP_DEBUG_PLL_LOCK BIT(4) --#define SP_POLLING_EN BIT(1) -- --/* DP Polling Control Register */ --#define SP_DP_POLLING_CTRL_REG 0xb4 --#define SP_AUTO_POLLING_DISABLE BIT(0) -- --/* DP Link Debug Control Register */ --#define SP_DP_LINK_DEBUG_CTRL_REG 0xb8 --#define SP_M_VID_DEBUG BIT(5) --#define SP_NEW_PRBS7 BIT(4) --#define SP_INSERT_ER BIT(1) --#define SP_PRBS31_EN BIT(0) -- --/* AUX Misc control Register */ --#define SP_AUX_MISC_CTRL_REG 0xbf -- --/* DP PLL control Register */ --#define SP_DP_PLL_CTRL_REG 0xc7 --#define SP_PLL_RST BIT(6) -- --/* DP Analog Power Down Register */ --#define SP_DP_ANALOG_POWER_DOWN_REG 0xc8 --#define SP_CH0_PD BIT(0) -- --/* DP Misc Control Register */ --#define SP_DP_MISC_CTRL_REG 0xcd --#define SP_EQ_TRAINING_LOOP BIT(6) -- --/* DP Extra I2C Device Address Register */ --#define SP_DP_EXTRA_I2C_DEV_ADDR_REG 0xce --#define SP_I2C_STRETCH_DISABLE BIT(7) -- --#define SP_I2C_EXTRA_ADDR 0x50 -- --/* DP Downspread Control Register 1 */ --#define SP_DP_DOWNSPREAD_CTRL1_REG 0xd0 -- --/* DP M Value Calculation Control Register */ --#define SP_DP_M_CALCULATION_CTRL_REG 0xd9 --#define SP_M_GEN_CLK_SEL BIT(0) -- --/* AUX Channel Access Status Register */ --#define SP_AUX_CH_STATUS_REG 0xe0 --#define SP_AUX_STATUS 0x0f -- --/* AUX Channel DEFER Control Register */ --#define SP_AUX_DEFER_CTRL_REG 0xe2 --#define SP_DEFER_CTRL_EN BIT(7) -- --/* DP Buffer Data Count Register */ --#define SP_BUF_DATA_COUNT_REG 0xe4 --#define SP_BUF_DATA_COUNT_MASK 0x1f --#define SP_BUF_CLR BIT(7) -- --/* DP AUX Channel Control Register 1 */ --#define SP_DP_AUX_CH_CTRL1_REG 0xe5 --#define SP_AUX_TX_COMM_MASK 0x0f --#define SP_AUX_LENGTH_MASK 0xf0 --#define SP_AUX_LENGTH_SHIFT 4 -- --/* DP AUX CH Address Register 0 */ --#define SP_AUX_ADDR_7_0_REG 0xe6 -- --/* DP AUX CH Address Register 1 */ --#define SP_AUX_ADDR_15_8_REG 0xe7 -- --/* DP AUX CH Address Register 2 */ --#define SP_AUX_ADDR_19_16_REG 0xe8 --#define SP_AUX_ADDR_19_16_MASK 0x0f -- --/* DP AUX Channel Control Register 2 */ --#define SP_DP_AUX_CH_CTRL2_REG 0xe9 --#define SP_AUX_SEL_RXCM BIT(6) --#define SP_AUX_CHSEL BIT(3) --#define SP_AUX_PN_INV BIT(2) --#define SP_ADDR_ONLY BIT(1) --#define SP_AUX_EN BIT(0) -- --/* DP Video Stream Control InfoFrame Register */ --#define SP_DP_3D_VSC_CTRL_REG 0xea --#define SP_INFO_FRAME_VSC_EN BIT(0) -- --/* DP Video Stream Data Byte 1 Register */ --#define SP_DP_VSC_DB1_REG 0xeb -- --/* DP AUX Channel Control Register 3 */ --#define SP_DP_AUX_CH_CTRL3_REG 0xec --#define SP_WAIT_COUNTER_7_0_MASK 0xff -- --/* DP AUX Channel Control Register 4 */ --#define SP_DP_AUX_CH_CTRL4_REG 0xed -- --/* DP AUX Buffer Data Registers */ --#define SP_DP_BUF_DATA0_REG 0xf0 -- --/***************************************************************/ --/* Register definition of device address 0x72 */ --/***************************************************************/ -- --/* -- * Core Register Definitions -- */ -- --/* Device ID Low Byte Register */ --#define SP_DEVICE_IDL_REG 0x02 -- --/* Device ID High Byte Register */ --#define SP_DEVICE_IDH_REG 0x03 -- --/* Device version register */ --#define SP_DEVICE_VERSION_REG 0x04 -- --/* Power Down Control Register */ --#define SP_POWERDOWN_CTRL_REG 0x05 --#define SP_REGISTER_PD BIT(7) --#define SP_HDCP_PD BIT(5) --#define SP_AUDIO_PD BIT(4) --#define SP_VIDEO_PD BIT(3) --#define SP_LINK_PD BIT(2) --#define SP_TOTAL_PD BIT(1) -- --/* Reset Control Register 1 */ --#define SP_RESET_CTRL1_REG 0x06 --#define SP_MISC_RST BIT(7) --#define SP_VIDCAP_RST BIT(6) --#define SP_VIDFIF_RST BIT(5) --#define SP_AUDFIF_RST BIT(4) --#define SP_AUDCAP_RST BIT(3) --#define SP_HDCP_RST BIT(2) --#define SP_SW_RST BIT(1) --#define SP_HW_RST BIT(0) -- --/* Reset Control Register 2 */ --#define SP_RESET_CTRL2_REG 0x07 --#define SP_AUX_RST BIT(2) --#define SP_SERDES_FIFO_RST BIT(1) --#define SP_I2C_REG_RST BIT(0) -- --/* Video Control Register 1 */ --#define SP_VID_CTRL1_REG 0x08 --#define SP_VIDEO_EN BIT(7) --#define SP_VIDEO_MUTE BIT(2) --#define SP_DE_GEN BIT(1) --#define SP_DEMUX BIT(0) -- --/* Video Control Register 2 */ --#define SP_VID_CTRL2_REG 0x09 --#define SP_IN_COLOR_F_MASK 0x03 --#define SP_IN_YC_BIT_SEL BIT(2) --#define SP_IN_BPC_MASK 0x70 --#define SP_IN_BPC_SHIFT 4 --# define SP_IN_BPC_12BIT 0x03 --# define SP_IN_BPC_10BIT 0x02 --# define SP_IN_BPC_8BIT 0x01 --# define SP_IN_BPC_6BIT 0x00 --#define SP_IN_D_RANGE BIT(7) -- --/* Video Control Register 3 */ --#define SP_VID_CTRL3_REG 0x0a --#define SP_HPD_OUT BIT(6) -- --/* Video Control Register 5 */ --#define SP_VID_CTRL5_REG 0x0c --#define SP_CSC_STD_SEL BIT(7) --#define SP_XVYCC_RNG_LMT BIT(6) --#define SP_RANGE_Y2R BIT(5) --#define SP_CSPACE_Y2R BIT(4) --#define SP_RGB_RNG_LMT BIT(3) --#define SP_Y_RNG_LMT BIT(2) --#define SP_RANGE_R2Y BIT(1) --#define SP_CSPACE_R2Y BIT(0) -- --/* Video Control Register 6 */ --#define SP_VID_CTRL6_REG 0x0d --#define SP_TEST_PATTERN_EN BIT(7) --#define SP_VIDEO_PROCESS_EN BIT(6) --#define SP_VID_US_MODE BIT(3) --#define SP_VID_DS_MODE BIT(2) --#define SP_UP_SAMPLE BIT(1) --#define SP_DOWN_SAMPLE BIT(0) -- --/* Video Control Register 8 */ --#define SP_VID_CTRL8_REG 0x0f --#define SP_VID_VRES_TH BIT(0) -- --/* Total Line Status Low Byte Register */ --#define SP_TOTAL_LINE_STAL_REG 0x24 -- --/* Total Line Status High Byte Register */ --#define SP_TOTAL_LINE_STAH_REG 0x25 -- --/* Active Line Status Low Byte Register */ --#define SP_ACT_LINE_STAL_REG 0x26 -- --/* Active Line Status High Byte Register */ --#define SP_ACT_LINE_STAH_REG 0x27 -- --/* Vertical Front Porch Status Register */ --#define SP_V_F_PORCH_STA_REG 0x28 -- --/* Vertical SYNC Width Status Register */ --#define SP_V_SYNC_STA_REG 0x29 -- --/* Vertical Back Porch Status Register */ --#define SP_V_B_PORCH_STA_REG 0x2a -- --/* Total Pixel Status Low Byte Register */ --#define SP_TOTAL_PIXEL_STAL_REG 0x2b -- --/* Total Pixel Status High Byte Register */ --#define SP_TOTAL_PIXEL_STAH_REG 0x2c -- --/* Active Pixel Status Low Byte Register */ --#define SP_ACT_PIXEL_STAL_REG 0x2d -- --/* Active Pixel Status High Byte Register */ --#define SP_ACT_PIXEL_STAH_REG 0x2e -- --/* Horizontal Front Porch Status Low Byte Register */ --#define SP_H_F_PORCH_STAL_REG 0x2f -- --/* Horizontal Front Porch Statys High Byte Register */ --#define SP_H_F_PORCH_STAH_REG 0x30 -- --/* Horizontal SYNC Width Status Low Byte Register */ --#define SP_H_SYNC_STAL_REG 0x31 -- --/* Horizontal SYNC Width Status High Byte Register */ --#define SP_H_SYNC_STAH_REG 0x32 -- --/* Horizontal Back Porch Status Low Byte Register */ --#define SP_H_B_PORCH_STAL_REG 0x33 -- --/* Horizontal Back Porch Status High Byte Register */ --#define SP_H_B_PORCH_STAH_REG 0x34 -- --/* InfoFrame AVI Packet DB1 Register */ --#define SP_INFOFRAME_AVI_DB1_REG 0x70 -- --/* Bit Control Specific Register */ --#define SP_BIT_CTRL_SPECIFIC_REG 0x80 --#define SP_BIT_CTRL_SELECT_SHIFT 1 --#define SP_ENABLE_BIT_CTRL BIT(0) -- --/* InfoFrame Audio Packet DB1 Register */ --#define SP_INFOFRAME_AUD_DB1_REG 0x83 -- --/* InfoFrame MPEG Packet DB1 Register */ --#define SP_INFOFRAME_MPEG_DB1_REG 0xb0 -- --/* Audio Channel Status Registers */ --#define SP_AUD_CH_STATUS_BASE 0xd0 -- --/* Audio Channel Num Register 5 */ --#define SP_I2S_CHANNEL_NUM_MASK 0xe0 --# define SP_I2S_CH_NUM_1 (0x00 << 5) --# define SP_I2S_CH_NUM_2 (0x01 << 5) --# define SP_I2S_CH_NUM_3 (0x02 << 5) --# define SP_I2S_CH_NUM_4 (0x03 << 5) --# define SP_I2S_CH_NUM_5 (0x04 << 5) --# define SP_I2S_CH_NUM_6 (0x05 << 5) --# define SP_I2S_CH_NUM_7 (0x06 << 5) --# define SP_I2S_CH_NUM_8 (0x07 << 5) --#define SP_EXT_VUCP BIT(2) --#define SP_VBIT BIT(1) --#define SP_AUDIO_LAYOUT BIT(0) -- --/* Analog Debug Register 2 */ --#define SP_ANALOG_DEBUG2_REG 0xdd --#define SP_FORCE_SW_OFF_BYPASS 0x20 --#define SP_XTAL_FRQ 0x1c --# define SP_XTAL_FRQ_19M2 (0x00 << 2) --# define SP_XTAL_FRQ_24M (0x01 << 2) --# define SP_XTAL_FRQ_25M (0x02 << 2) --# define SP_XTAL_FRQ_26M (0x03 << 2) --# define SP_XTAL_FRQ_27M (0x04 << 2) --# define SP_XTAL_FRQ_38M4 (0x05 << 2) --# define SP_XTAL_FRQ_52M (0x06 << 2) --#define SP_POWERON_TIME_1P5MS 0x03 -- --/* Analog Control 0 Register */ --#define SP_ANALOG_CTRL0_REG 0xe1 -- --/* Common Interrupt Status Register 1 */ --#define SP_COMMON_INT_STATUS_BASE (0xf1 - 1) --#define SP_PLL_LOCK_CHG 0x40 -- --/* Common Interrupt Status Register 2 */ --#define SP_COMMON_INT_STATUS2 0xf2 --#define SP_HDCP_AUTH_CHG BIT(1) --#define SP_HDCP_AUTH_DONE BIT(0) -- --#define SP_HDCP_LINK_CHECK_FAIL BIT(0) -- --/* Common Interrupt Status Register 4 */ --#define SP_COMMON_INT_STATUS4_REG 0xf4 --#define SP_HPD_IRQ BIT(6) --#define SP_HPD_ESYNC_ERR BIT(4) --#define SP_HPD_CHG BIT(2) --#define SP_HPD_LOST BIT(1) --#define SP_HPD_PLUG BIT(0) -- --/* DP Interrupt Status Register */ --#define SP_DP_INT_STATUS1_REG 0xf7 --#define SP_TRAINING_FINISH BIT(5) --#define SP_POLLING_ERR BIT(4) -- --/* Common Interrupt Mask Register */ --#define SP_COMMON_INT_MASK_BASE (0xf8 - 1) -- --#define SP_COMMON_INT_MASK4_REG 0xfb -- --/* DP Interrupts Mask Register */ --#define SP_DP_INT_MASK1_REG 0xfe -- --/* Interrupt Control Register */ --#define SP_INT_CTRL_REG 0xff -- - /***************************************************************/ - /* Register definition of device address 0x7a */ - /***************************************************************/ -diff --git a/drivers/gpu/drm/bridge/analogix/analogix-i2c-dptx.h b/drivers/gpu/drm/bridge/analogix/analogix-i2c-dptx.h -new file mode 100644 -index 000000000000..bc0831b127bf ---- /dev/null -+++ b/drivers/gpu/drm/bridge/analogix/analogix-i2c-dptx.h -@@ -0,0 +1,248 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright(c) 2017 Icenowy Zheng -+ * -+ * Based on analogix-anx78xx.h, which is: -+ * Copyright(c) 2016, Analogix Semiconductor. All rights reserved. -+ */ -+ -+#ifndef _ANALOGIX_I2C_DPTX_H_ -+#define _ANALOGIX_I2C_DPTX_H_ -+ -+#define ANALOGIX_I2C_DPTX 0x70 -+ -+/***************************************************************/ -+/* Register definition of device address 0x70 */ -+/***************************************************************/ -+ -+/* HDCP Status Register */ -+#define SP_TX_HDCP_STATUS_REG 0x00 -+#define SP_AUTH_FAIL BIT(5) -+#define SP_AUTHEN_PASS BIT(1) -+ -+/* HDCP Control Register 0 */ -+#define SP_HDCP_CTRL0_REG 0x01 -+#define SP_RX_REPEATER BIT(6) -+#define SP_RE_AUTH BIT(5) -+#define SP_SW_AUTH_OK BIT(4) -+#define SP_HARD_AUTH_EN BIT(3) -+#define SP_HDCP_ENC_EN BIT(2) -+#define SP_BKSV_SRM_PASS BIT(1) -+#define SP_KSVLIST_VLD BIT(0) -+/* HDCP Function Enabled */ -+#define SP_HDCP_FUNCTION_ENABLED (BIT(0) | BIT(1) | BIT(2) | BIT(3)) -+ -+/* HDCP Receiver BSTATUS Register 0 */ -+#define SP_HDCP_RX_BSTATUS0_REG 0x1b -+/* HDCP Receiver BSTATUS Register 1 */ -+#define SP_HDCP_RX_BSTATUS1_REG 0x1c -+ -+/* HDCP Embedded "Blue Screen" Content Registers */ -+#define SP_HDCP_VID0_BLUE_SCREEN_REG 0x2c -+#define SP_HDCP_VID1_BLUE_SCREEN_REG 0x2d -+#define SP_HDCP_VID2_BLUE_SCREEN_REG 0x2e -+ -+/* HDCP Wait R0 Timing Register */ -+#define SP_HDCP_WAIT_R0_TIME_REG 0x40 -+ -+/* HDCP Link Integrity Check Timer Register */ -+#define SP_HDCP_LINK_CHECK_TIMER_REG 0x41 -+ -+/* HDCP Repeater Ready Wait Timer Register */ -+#define SP_HDCP_RPTR_RDY_WAIT_TIME_REG 0x42 -+ -+/* HDCP Auto Timer Register */ -+#define SP_HDCP_AUTO_TIMER_REG 0x51 -+ -+/* HDCP Key Status Register */ -+#define SP_HDCP_KEY_STATUS_REG 0x5e -+ -+/* HDCP Key Command Register */ -+#define SP_HDCP_KEY_COMMAND_REG 0x5f -+#define SP_DISABLE_SYNC_HDCP BIT(2) -+ -+/* OTP Memory Key Protection Registers */ -+#define SP_OTP_KEY_PROTECT1_REG 0x60 -+#define SP_OTP_KEY_PROTECT2_REG 0x61 -+#define SP_OTP_KEY_PROTECT3_REG 0x62 -+#define SP_OTP_PSW1 0xa2 -+#define SP_OTP_PSW2 0x7e -+#define SP_OTP_PSW3 0xc6 -+ -+/* DP System Control Registers */ -+#define SP_DP_SYSTEM_CTRL_BASE (0x80 - 1) -+/* Bits for DP System Control Register 2 */ -+#define SP_CHA_STA BIT(2) -+/* Bits for DP System Control Register 3 */ -+#define SP_HPD_STATUS BIT(6) -+#define SP_STRM_VALID BIT(2) -+/* Bits for DP System Control Register 4 */ -+#define SP_ENHANCED_MODE BIT(3) -+ -+/* DP Video Control Register */ -+#define SP_DP_VIDEO_CTRL_REG 0x84 -+#define SP_COLOR_F_MASK 0x06 -+#define SP_COLOR_F_SHIFT 1 -+#define SP_BPC_MASK 0xe0 -+#define SP_BPC_SHIFT 5 -+# define SP_BPC_6BITS 0x00 -+# define SP_BPC_8BITS 0x01 -+# define SP_BPC_10BITS 0x02 -+# define SP_BPC_12BITS 0x03 -+ -+/* DP Audio Control Register */ -+#define SP_DP_AUDIO_CTRL_REG 0x87 -+#define SP_AUD_EN BIT(0) -+ -+/* 10us Pulse Generate Timer Registers */ -+#define SP_I2C_GEN_10US_TIMER0_REG 0x88 -+#define SP_I2C_GEN_10US_TIMER1_REG 0x89 -+ -+/* Packet Send Control Register */ -+#define SP_PACKET_SEND_CTRL_REG 0x90 -+#define SP_AUD_IF_UP BIT(7) -+#define SP_AVI_IF_UD BIT(6) -+#define SP_MPEG_IF_UD BIT(5) -+#define SP_SPD_IF_UD BIT(4) -+#define SP_AUD_IF_EN BIT(3) -+#define SP_AVI_IF_EN BIT(2) -+#define SP_MPEG_IF_EN BIT(1) -+#define SP_SPD_IF_EN BIT(0) -+ -+/* DP HDCP Control Register */ -+#define SP_DP_HDCP_CTRL_REG 0x92 -+#define SP_AUTO_EN BIT(7) -+#define SP_AUTO_START BIT(5) -+#define SP_LINK_POLLING BIT(1) -+ -+/* DP Main Link Bandwidth Setting Register */ -+#define SP_DP_MAIN_LINK_BW_SET_REG 0xa0 -+#define SP_LINK_BW_SET_MASK 0x1f -+#define SP_INITIAL_SLIM_M_AUD_SEL BIT(5) -+ -+/* DP Training Pattern Set Register */ -+#define SP_DP_TRAINING_PATTERN_SET_REG 0xa2 -+ -+/* DP Lane 0 Link Training Control Register */ -+#define SP_DP_LANE0_LT_CTRL_REG 0xa3 -+#define SP_TX_SW_SET_MASK 0x1b -+#define SP_MAX_PRE_REACH BIT(5) -+#define SP_MAX_DRIVE_REACH BIT(4) -+#define SP_PRE_EMP_LEVEL1 BIT(3) -+#define SP_DRVIE_CURRENT_LEVEL1 BIT(0) -+ -+/* DP Link Training Control Register */ -+#define SP_DP_LT_CTRL_REG 0xa8 -+#define SP_LT_ERROR_TYPE_MASK 0x70 -+# define SP_LT_NO_ERROR 0x00 -+# define SP_LT_AUX_WRITE_ERROR 0x01 -+# define SP_LT_MAX_DRIVE_REACHED 0x02 -+# define SP_LT_WRONG_LANE_COUNT_SET 0x03 -+# define SP_LT_LOOP_SAME_5_TIME 0x04 -+# define SP_LT_CR_FAIL_IN_EQ 0x05 -+# define SP_LT_EQ_LOOP_5_TIME 0x06 -+#define SP_LT_EN BIT(0) -+ -+/* DP CEP Training Control Registers */ -+#define SP_DP_CEP_TRAINING_CTRL0_REG 0xa9 -+#define SP_DP_CEP_TRAINING_CTRL1_REG 0xaa -+ -+/* DP Debug Register 1 */ -+#define SP_DP_DEBUG1_REG 0xb0 -+#define SP_DEBUG_PLL_LOCK BIT(4) -+#define SP_POLLING_EN BIT(1) -+ -+/* DP Polling Control Register */ -+#define SP_DP_POLLING_CTRL_REG 0xb4 -+#define SP_AUTO_POLLING_DISABLE BIT(0) -+ -+/* DP Link Debug Control Register */ -+#define SP_DP_LINK_DEBUG_CTRL_REG 0xb8 -+#define SP_M_VID_DEBUG BIT(5) -+#define SP_NEW_PRBS7 BIT(4) -+#define SP_INSERT_ER BIT(1) -+#define SP_PRBS31_EN BIT(0) -+ -+/* AUX Misc control Register */ -+#define SP_AUX_MISC_CTRL_REG 0xbf -+ -+/* DP PLL control Register */ -+#define SP_DP_PLL_CTRL_REG 0xc7 -+#define SP_PLL_RST BIT(6) -+ -+/* DP Analog Power Down Register */ -+#define SP_DP_ANALOG_POWER_DOWN_REG 0xc8 -+#define SP_CH0_PD BIT(0) -+ -+/* DP Misc Control Register */ -+#define SP_DP_MISC_CTRL_REG 0xcd -+#define SP_EQ_TRAINING_LOOP BIT(6) -+ -+/* DP Extra I2C Device Address Register */ -+#define SP_DP_EXTRA_I2C_DEV_ADDR_REG 0xce -+#define SP_I2C_STRETCH_DISABLE BIT(7) -+ -+#define SP_I2C_EXTRA_ADDR 0x50 -+ -+/* DP Downspread Control Register 1 */ -+#define SP_DP_DOWNSPREAD_CTRL1_REG 0xd0 -+ -+/* DP M Value Calculation Control Register */ -+#define SP_DP_M_CALCULATION_CTRL_REG 0xd9 -+#define SP_M_GEN_CLK_SEL BIT(0) -+ -+/* AUX Channel Access Status Register */ -+#define SP_AUX_CH_STATUS_REG 0xe0 -+#define SP_AUX_STATUS 0x0f -+ -+/* AUX Channel DEFER Control Register */ -+#define SP_AUX_DEFER_CTRL_REG 0xe2 -+#define SP_DEFER_CTRL_EN BIT(7) -+ -+/* DP Buffer Data Count Register */ -+#define SP_BUF_DATA_COUNT_REG 0xe4 -+#define SP_BUF_DATA_COUNT_MASK 0x1f -+#define SP_BUF_CLR BIT(7) -+ -+/* DP AUX Channel Control Register 1 */ -+#define SP_DP_AUX_CH_CTRL1_REG 0xe5 -+#define SP_AUX_TX_COMM_MASK 0x0f -+#define SP_AUX_LENGTH_MASK 0xf0 -+#define SP_AUX_LENGTH_SHIFT 4 -+ -+/* DP AUX CH Address Register 0 */ -+#define SP_AUX_ADDR_7_0_REG 0xe6 -+ -+/* DP AUX CH Address Register 1 */ -+#define SP_AUX_ADDR_15_8_REG 0xe7 -+ -+/* DP AUX CH Address Register 2 */ -+#define SP_AUX_ADDR_19_16_REG 0xe8 -+#define SP_AUX_ADDR_19_16_MASK 0x0f -+ -+/* DP AUX Channel Control Register 2 */ -+#define SP_DP_AUX_CH_CTRL2_REG 0xe9 -+#define SP_AUX_SEL_RXCM BIT(6) -+#define SP_AUX_CHSEL BIT(3) -+#define SP_AUX_PN_INV BIT(2) -+#define SP_ADDR_ONLY BIT(1) -+#define SP_AUX_EN BIT(0) -+ -+/* DP Video Stream Control InfoFrame Register */ -+#define SP_DP_3D_VSC_CTRL_REG 0xea -+#define SP_INFO_FRAME_VSC_EN BIT(0) -+ -+/* DP Video Stream Data Byte 1 Register */ -+#define SP_DP_VSC_DB1_REG 0xeb -+ -+/* DP AUX Channel Control Register 3 */ -+#define SP_DP_AUX_CH_CTRL3_REG 0xec -+#define SP_WAIT_COUNTER_7_0_MASK 0xff -+ -+/* DP AUX Channel Control Register 4 */ -+#define SP_DP_AUX_CH_CTRL4_REG 0xed -+ -+/* DP AUX Buffer Data Registers */ -+#define SP_DP_BUF_DATA0_REG 0xf0 -+ -+#endif -diff --git a/drivers/gpu/drm/bridge/analogix/analogix-i2c-txcommon.h b/drivers/gpu/drm/bridge/analogix/analogix-i2c-txcommon.h -new file mode 100644 -index 000000000000..7d683573e970 ---- /dev/null -+++ b/drivers/gpu/drm/bridge/analogix/analogix-i2c-txcommon.h -@@ -0,0 +1,237 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright(c) 2017 Icenowy Zheng -+ * -+ * Based on analogix-anx78xx.h, which is: -+ * Copyright(c) 2016, Analogix Semiconductor. All rights reserved. -+ */ -+ -+#ifndef _ANALOGIX_I2C_TXCOMMON_H_ -+#define _ANALOGIX_I2C_TXCOMMON_H_ -+ -+#define ANALOGIX_I2C_TXCOMMON 0x72 -+ -+/***************************************************************/ -+/* Register definition of device address 0x72 */ -+/***************************************************************/ -+ -+/* -+ * Core Register Definitions -+ */ -+ -+/* Device ID Low Byte Register */ -+#define SP_DEVICE_IDL_REG 0x02 -+ -+/* Device ID High Byte Register */ -+#define SP_DEVICE_IDH_REG 0x03 -+ -+/* Device version register */ -+#define SP_DEVICE_VERSION_REG 0x04 -+ -+/* Power Down Control Register */ -+#define SP_POWERDOWN_CTRL_REG 0x05 -+#define SP_REGISTER_PD BIT(7) -+#define SP_HDCP_PD BIT(5) -+#define SP_AUDIO_PD BIT(4) -+#define SP_VIDEO_PD BIT(3) -+#define SP_LINK_PD BIT(2) -+#define SP_TOTAL_PD BIT(1) -+ -+/* Reset Control Register 1 */ -+#define SP_RESET_CTRL1_REG 0x06 -+#define SP_MISC_RST BIT(7) -+#define SP_VIDCAP_RST BIT(6) -+#define SP_VIDFIF_RST BIT(5) -+#define SP_AUDFIF_RST BIT(4) -+#define SP_AUDCAP_RST BIT(3) -+#define SP_HDCP_RST BIT(2) -+#define SP_SW_RST BIT(1) -+#define SP_HW_RST BIT(0) -+ -+/* Reset Control Register 2 */ -+#define SP_RESET_CTRL2_REG 0x07 -+#define SP_AUX_RST BIT(2) -+#define SP_SERDES_FIFO_RST BIT(1) -+#define SP_I2C_REG_RST BIT(0) -+ -+/* Video Control Register 1 */ -+#define SP_VID_CTRL1_REG 0x08 -+#define SP_VIDEO_EN BIT(7) -+#define SP_VIDEO_MUTE BIT(2) -+#define SP_DE_GEN BIT(1) -+#define SP_DEMUX BIT(0) -+ -+/* Video Control Register 2 */ -+#define SP_VID_CTRL2_REG 0x09 -+#define SP_IN_COLOR_F_MASK 0x03 -+#define SP_IN_YC_BIT_SEL BIT(2) -+#define SP_IN_BPC_MASK 0x70 -+#define SP_IN_BPC_SHIFT 4 -+# define SP_IN_BPC_12BIT 0x03 -+# define SP_IN_BPC_10BIT 0x02 -+# define SP_IN_BPC_8BIT 0x01 -+# define SP_IN_BPC_6BIT 0x00 -+#define SP_IN_D_RANGE BIT(7) -+ -+/* Video Control Register 3 */ -+#define SP_VID_CTRL3_REG 0x0a -+#define SP_HPD_OUT BIT(6) -+ -+/* Video Control Register 5 */ -+#define SP_VID_CTRL5_REG 0x0c -+#define SP_CSC_STD_SEL BIT(7) -+#define SP_XVYCC_RNG_LMT BIT(6) -+#define SP_RANGE_Y2R BIT(5) -+#define SP_CSPACE_Y2R BIT(4) -+#define SP_RGB_RNG_LMT BIT(3) -+#define SP_Y_RNG_LMT BIT(2) -+#define SP_RANGE_R2Y BIT(1) -+#define SP_CSPACE_R2Y BIT(0) -+ -+/* Video Control Register 6 */ -+#define SP_VID_CTRL6_REG 0x0d -+#define SP_TEST_PATTERN_EN BIT(7) -+#define SP_VIDEO_PROCESS_EN BIT(6) -+#define SP_VID_US_MODE BIT(3) -+#define SP_VID_DS_MODE BIT(2) -+#define SP_UP_SAMPLE BIT(1) -+#define SP_DOWN_SAMPLE BIT(0) -+ -+/* Video Control Register 8 */ -+#define SP_VID_CTRL8_REG 0x0f -+#define SP_VID_VRES_TH BIT(0) -+ -+/* Total Line Status Low Byte Register */ -+#define SP_TOTAL_LINE_STAL_REG 0x24 -+ -+/* Total Line Status High Byte Register */ -+#define SP_TOTAL_LINE_STAH_REG 0x25 -+ -+/* Active Line Status Low Byte Register */ -+#define SP_ACT_LINE_STAL_REG 0x26 -+ -+/* Active Line Status High Byte Register */ -+#define SP_ACT_LINE_STAH_REG 0x27 -+ -+/* Vertical Front Porch Status Register */ -+#define SP_V_F_PORCH_STA_REG 0x28 -+ -+/* Vertical SYNC Width Status Register */ -+#define SP_V_SYNC_STA_REG 0x29 -+ -+/* Vertical Back Porch Status Register */ -+#define SP_V_B_PORCH_STA_REG 0x2a -+ -+/* Total Pixel Status Low Byte Register */ -+#define SP_TOTAL_PIXEL_STAL_REG 0x2b -+ -+/* Total Pixel Status High Byte Register */ -+#define SP_TOTAL_PIXEL_STAH_REG 0x2c -+ -+/* Active Pixel Status Low Byte Register */ -+#define SP_ACT_PIXEL_STAL_REG 0x2d -+ -+/* Active Pixel Status High Byte Register */ -+#define SP_ACT_PIXEL_STAH_REG 0x2e -+ -+/* Horizontal Front Porch Status Low Byte Register */ -+#define SP_H_F_PORCH_STAL_REG 0x2f -+ -+/* Horizontal Front Porch Statys High Byte Register */ -+#define SP_H_F_PORCH_STAH_REG 0x30 -+ -+/* Horizontal SYNC Width Status Low Byte Register */ -+#define SP_H_SYNC_STAL_REG 0x31 -+ -+/* Horizontal SYNC Width Status High Byte Register */ -+#define SP_H_SYNC_STAH_REG 0x32 -+ -+/* Horizontal Back Porch Status Low Byte Register */ -+#define SP_H_B_PORCH_STAL_REG 0x33 -+ -+/* Horizontal Back Porch Status High Byte Register */ -+#define SP_H_B_PORCH_STAH_REG 0x34 -+ -+/* InfoFrame AVI Packet DB1 Register */ -+#define SP_INFOFRAME_AVI_DB1_REG 0x70 -+ -+/* Bit Control Specific Register */ -+#define SP_BIT_CTRL_SPECIFIC_REG 0x80 -+#define SP_BIT_CTRL_SELECT_SHIFT 1 -+#define SP_ENABLE_BIT_CTRL BIT(0) -+ -+/* InfoFrame Audio Packet DB1 Register */ -+#define SP_INFOFRAME_AUD_DB1_REG 0x83 -+ -+/* InfoFrame MPEG Packet DB1 Register */ -+#define SP_INFOFRAME_MPEG_DB1_REG 0xb0 -+ -+/* Audio Channel Status Registers */ -+#define SP_AUD_CH_STATUS_BASE 0xd0 -+ -+/* Audio Channel Num Register 5 */ -+#define SP_I2S_CHANNEL_NUM_MASK 0xe0 -+# define SP_I2S_CH_NUM_1 (0x00 << 5) -+# define SP_I2S_CH_NUM_2 (0x01 << 5) -+# define SP_I2S_CH_NUM_3 (0x02 << 5) -+# define SP_I2S_CH_NUM_4 (0x03 << 5) -+# define SP_I2S_CH_NUM_5 (0x04 << 5) -+# define SP_I2S_CH_NUM_6 (0x05 << 5) -+# define SP_I2S_CH_NUM_7 (0x06 << 5) -+# define SP_I2S_CH_NUM_8 (0x07 << 5) -+#define SP_EXT_VUCP BIT(2) -+#define SP_VBIT BIT(1) -+#define SP_AUDIO_LAYOUT BIT(0) -+ -+/* Analog Debug Register 2 */ -+#define SP_ANALOG_DEBUG2_REG 0xdd -+#define SP_FORCE_SW_OFF_BYPASS 0x20 -+#define SP_XTAL_FRQ 0x1c -+# define SP_XTAL_FRQ_19M2 (0x00 << 2) -+# define SP_XTAL_FRQ_24M (0x01 << 2) -+# define SP_XTAL_FRQ_25M (0x02 << 2) -+# define SP_XTAL_FRQ_26M (0x03 << 2) -+# define SP_XTAL_FRQ_27M (0x04 << 2) -+# define SP_XTAL_FRQ_38M4 (0x05 << 2) -+# define SP_XTAL_FRQ_52M (0x06 << 2) -+#define SP_POWERON_TIME_1P5MS 0x03 -+ -+/* Analog Control 0 Register */ -+#define SP_ANALOG_CTRL0_REG 0xe1 -+ -+/* Common Interrupt Status Register 1 */ -+#define SP_COMMON_INT_STATUS_BASE (0xf1 - 1) -+#define SP_PLL_LOCK_CHG 0x40 -+ -+/* Common Interrupt Status Register 2 */ -+#define SP_COMMON_INT_STATUS2 0xf2 -+#define SP_HDCP_AUTH_CHG BIT(1) -+#define SP_HDCP_AUTH_DONE BIT(0) -+ -+#define SP_HDCP_LINK_CHECK_FAIL BIT(0) -+ -+/* Common Interrupt Status Register 4 */ -+#define SP_COMMON_INT_STATUS4_REG 0xf4 -+#define SP_HPD_IRQ BIT(6) -+#define SP_HPD_ESYNC_ERR BIT(4) -+#define SP_HPD_CHG BIT(2) -+#define SP_HPD_LOST BIT(1) -+#define SP_HPD_PLUG BIT(0) -+ -+/* DP Interrupt Status Register */ -+#define SP_DP_INT_STATUS1_REG 0xf7 -+#define SP_TRAINING_FINISH BIT(5) -+#define SP_POLLING_ERR BIT(4) -+ -+/* Common Interrupt Mask Register */ -+#define SP_COMMON_INT_MASK_BASE (0xf8 - 1) -+ -+#define SP_COMMON_INT_MASK4_REG 0xfb -+ -+/* DP Interrupts Mask Register */ -+#define SP_DP_INT_MASK1_REG 0xfe -+ -+/* Interrupt Control Register */ -+#define SP_INT_CTRL_REG 0xff -+ -+#endif /* _ANALOGIX_I2C_TXCOMMON_H_ */ --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0129-dt-bindings-Add-ANX6345-DP-eDP-transmitter-binding.patch b/patch/kernel/sunxi-legacy/0129-dt-bindings-Add-ANX6345-DP-eDP-transmitter-binding.patch deleted file mode 100644 index 5e76ebfb8..000000000 --- a/patch/kernel/sunxi-legacy/0129-dt-bindings-Add-ANX6345-DP-eDP-transmitter-binding.patch +++ /dev/null @@ -1,64 +0,0 @@ -From db3c5b3983ab2395794ea3ebd5c73ab7b39d2caa Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Thu, 18 Oct 2018 15:33:22 +0800 -Subject: [PATCH 129/146] dt-bindings: Add ANX6345 DP/eDP transmitter binding - -The ANX6345 is an ultra-low power DisplayPort/eDP transmitter designed -for portable devices. - -Add a binding document for it. - -Signed-off-by: Icenowy Zheng ---- - .../bindings/display/bridge/anx6345.txt | 39 +++++++++++++++++++ - 1 file changed, 39 insertions(+) - create mode 100644 Documentation/devicetree/bindings/display/bridge/anx6345.txt - -diff --git a/Documentation/devicetree/bindings/display/bridge/anx6345.txt b/Documentation/devicetree/bindings/display/bridge/anx6345.txt -new file mode 100644 -index 000000000000..0689d4eb5f65 ---- /dev/null -+++ b/Documentation/devicetree/bindings/display/bridge/anx6345.txt -@@ -0,0 +1,39 @@ -+Analogix ANX6345 eDP Transmitter -+-------------------------------- -+ -+The ANX6345 is an ultra-low power Full-HD eDP transmitter designed for -+portable devices. -+ -+Required properties: -+ -+ - compatible : "analogix,anx6345" -+ - reg : I2C address of the device -+ - reset-gpios : Which GPIO to use for reset -+ -+Optional properties: -+ -+ - dvdd12-supply : Regulator for 1.2V digital core power. -+ - dvdd25-supply : Regulator for 2.5V digital core power. -+ - panel-supply : Regulator for the power of the panel. -+ - edid : verbatim EDID data block describing attached -+ panel, only used when the panel has no EDID info. -+ - Video port for RGB input, using the DT bindings defined in [1]. -+ -+[1]: Documentation/devicetree/bindings/media/video-interfaces.txt -+ -+Example: -+ -+anx6345: anx6345@38 { -+ compatible = "analogix,anx6345"; -+ reg = <0x38>; -+ reset-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */ -+ panel-supply = <®_dc1sw>; -+ dvdd25-supply = <®_dldo2>; -+ dvdd12-supply = <®_fldo1>; -+ -+ port { -+ anx6345_in: endpoint { -+ remote-endpoint = <&tcon0_out_anx6345>; -+ }; -+ }; -+}; --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0131-arm64-allwinner-a64-add-pinmux-for-RGB666-LCD.patch b/patch/kernel/sunxi-legacy/0131-arm64-allwinner-a64-add-pinmux-for-RGB666-LCD.patch deleted file mode 100644 index 4c7d893ad..000000000 --- a/patch/kernel/sunxi-legacy/0131-arm64-allwinner-a64-add-pinmux-for-RGB666-LCD.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 3d017794525d830a3251bed7ebbacbf74efe9605 Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Thu, 18 Oct 2018 15:33:24 +0800 -Subject: [PATCH 131/146] arm64: allwinner: a64: add pinmux for RGB666 LCD - -Allwinner A64's TCON0 can output RGB666 LCD signal. - -Add its pinmux. - -Signed-off-by: Icenowy Zheng ---- - arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -index cb7d4a96e789..0f5b412cfc81 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -@@ -655,6 +655,15 @@ - function = "i2c1"; - }; - -+ lcd_rgb666_pins: lcd-rgb666 { -+ pins = "PD0", "PD1", "PD2", "PD3", "PD4", -+ "PD5", "PD6", "PD7", "PD8", "PD9", -+ "PD10", "PD11", "PD12", "PD13", -+ "PD14", "PD15", "PD16", "PD17", -+ "PD18", "PD19", "PD20", "PD21"; -+ function = "lcd0"; -+ }; -+ - mmc0_pins: mmc0-pins { - pins = "PF0", "PF1", "PF2", "PF3", - "PF4", "PF5"; --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0132-arm64-allwinner-a64-enable-ANX6345-bridge-on-Pineboo.patch b/patch/kernel/sunxi-legacy/0132-arm64-allwinner-a64-enable-ANX6345-bridge-on-Pineboo.patch deleted file mode 100644 index edd0bff35..000000000 --- a/patch/kernel/sunxi-legacy/0132-arm64-allwinner-a64-enable-ANX6345-bridge-on-Pineboo.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 82fe5562e8d5cb289e97ff8d259b21889e72b03b Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Thu, 18 Oct 2018 15:33:25 +0800 -Subject: [PATCH 132/146] arm64: allwinner: a64: enable ANX6345 bridge on - Pinebook - -Pinebook has an ANX6345 bridge connected to the RGB666 LCD output, and -the I2C controlling signals are connected to R_I2C bus. - -Enable it in the device tree, and add a usable EDID from the panel's -datasheet (at least 14" Pinebook used a panel without EDID). - -Signed-off-by: Icenowy Zheng ---- - .../dts/allwinner/sun50i-a64-pinebook.dts | 39 +++++++++++++++++++ - 1 file changed, 39 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -index b55ac4e1df37..8c9bd4dfbbba 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -@@ -123,6 +123,10 @@ - }; - }; - -+&mixer0 { -+ status = "okay"; -+}; -+ - &mmc0 { - pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins>; -@@ -175,6 +179,27 @@ - status = "okay"; - }; - -+&r_i2c { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&r_i2c_pins_a>; -+ status = "okay"; -+ -+ anx6345: anx6345@38 { -+ compatible = "analogix,anx6345"; -+ reg = <0x38>; -+ reset-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */ -+ panel-supply = <®_dc1sw>; -+ dvdd25-supply = <®_dldo2>; -+ dvdd12-supply = <®_fldo1>; -+ -+ port { -+ anx6345_in: endpoint { -+ remote-endpoint = <&tcon0_out_anx6345>; -+ }; -+ }; -+ }; -+}; -+ - &r_rsb { - status = "okay"; - -@@ -348,6 +373,20 @@ - "MIC2", "Internal Microphone Right"; - }; - -+&tcon0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&lcd_rgb666_pins>; -+ -+ status = "okay"; -+}; -+ -+&tcon0_out { -+ tcon0_out_anx6345: endpoint@0 { -+ reg = <0>; -+ remote-endpoint = <&anx6345_in>; -+ }; -+}; -+ - &uart0 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0133-arm64-allwinner-a64-enable-ANX6345-bridge-on-TERES-I.patch b/patch/kernel/sunxi-legacy/0133-arm64-allwinner-a64-enable-ANX6345-bridge-on-TERES-I.patch deleted file mode 100644 index 5098b5c9a..000000000 --- a/patch/kernel/sunxi-legacy/0133-arm64-allwinner-a64-enable-ANX6345-bridge-on-TERES-I.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 955974c9ba484fc2b7e4396b5fdc6687a9a530a0 Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Thu, 18 Oct 2018 15:33:26 +0800 -Subject: [PATCH 133/146] arm64: allwinner: a64: enable ANX6345 bridge on - TERES-I - -TERES-I has an ANX6345 bridge connected to the RGB666 LCD output, and -the I2C controlling signals are connected to I2C0 bus. - -Enable it in the device tree. - -Signed-off-by: Icenowy Zheng ---- - .../boot/dts/allwinner/sun50i-a64-teres-i.dts | 40 +++++++++++++++++-- - 1 file changed, 36 insertions(+), 4 deletions(-) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts -index 81f8e0098699..6c3318b3c648 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts -@@ -72,20 +72,38 @@ - }; - }; - -+&de { -+ status = "okay"; -+}; -+ - &ehci1 { - status = "okay"; - }; - - --/* The ANX6345 eDP-bridge is on i2c0. There is no linux (mainline) -- * driver for this chip at the moment, the bootloader initializes it. -- * However it can be accessed with the i2c-dev driver from user space. -- */ - &i2c0 { - clock-frequency = <100000>; - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins>; - status = "okay"; -+ -+ anx6345: anx6345@38 { -+ compatible = "analogix,anx6345"; -+ reg = <0x38>; -+ reset-gpios = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */ -+ dvdd25-supply = <®_dldo2>; -+ dvdd12-supply = <®_dldo3>; -+ -+ port { -+ anx6345_in: endpoint { -+ remote-endpoint = <&tcon0_out_anx6345>; -+ }; -+ }; -+ }; -+}; -+ -+&mixer0 { -+ status = "okay"; - }; - - &mmc0 { -@@ -258,6 +276,20 @@ - vcc-hdmi-supply = <®_dldo1>; - }; - -+&tcon0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&lcd_rgb666_pins>; -+ -+ status = "okay"; -+}; -+ -+&tcon0_out { -+ tcon0_out_anx6345: endpoint@0 { -+ reg = <0>; -+ remote-endpoint = <&anx6345_in>; -+ }; -+}; -+ - &uart0 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0134-drm-sun4i-rgb-Add-5-tolerance-to-dot-clock-frequency.patch b/patch/kernel/sunxi-legacy/0134-drm-sun4i-rgb-Add-5-tolerance-to-dot-clock-frequency.patch deleted file mode 100644 index 3a9fb910c..000000000 --- a/patch/kernel/sunxi-legacy/0134-drm-sun4i-rgb-Add-5-tolerance-to-dot-clock-frequency.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0957f917d9a53bd9264bde6c2bd9d4f93cdd1d0c Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai -Date: Thu, 18 Oct 2018 15:33:27 +0800 -Subject: [PATCH 134/146] drm/sun4i: rgb: Add 5% tolerance to dot clock - frequency check - -The panels shipped with Allwinner devices are very "generic", i.e. -they do not have model numbers or reliable sources of information -for the timings (that we know of) other than the fex files shipped -on them. The dot clock frequency provided in the fex files have all -been rounded to the nearest MHz, as that is the unit used in them. - -We were using the simple panel "urt,umsh-8596md-t" as a substitute -for the A13 Q8 tablets in the absence of a specific model for what -may be many different but otherwise timing compatible panels. This -was usable without any visual artifacts or side effects, until the -dot clock rate check was added in commit bb43d40d7c83 ("drm/sun4i: -rgb: Validate the clock rate"). - -The reason this check fails is because the dotclock frequency for -this model is 33.26 MHz, which is not achievable with our dot clock -hardware, and the rate returned by clk_round_rate deviates slightly, -causing the driver to reject the display mode. - -The LCD panels have some tolerance on the dot clock frequency, even -if it's not specified in their datasheets. - -This patch adds a 5% tolerence to the dot clock check. - -Signed-off-by: Chen-Yu Tsai ---- - drivers/gpu/drm/sun4i/sun4i_rgb.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c -index bf068da6b12e..23bdc449eacc 100644 ---- a/drivers/gpu/drm/sun4i/sun4i_rgb.c -+++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c -@@ -92,13 +92,14 @@ static enum drm_mode_status sun4i_rgb_mode_valid(struct drm_encoder *crtc, - - DRM_DEBUG_DRIVER("Vertical parameters OK\n"); - -+ /* Check against a 5% tolerance for the dot clock */ - tcon->dclk_min_div = 6; - tcon->dclk_max_div = 127; - rounded_rate = clk_round_rate(tcon->dclk, rate); -- if (rounded_rate < rate) -+ if (rounded_rate < rate * 19 / 20 ) - return MODE_CLOCK_LOW; - -- if (rounded_rate > rate) -+ if (rounded_rate > rate * 21 / 20) - return MODE_CLOCK_HIGH; - - DRM_DEBUG_DRIVER("Clock rate OK\n"); --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0138-ASoC-sunxi-rename-SND_SUNXI_ADDA_PR_REGMAP-to-SND_SU.patch b/patch/kernel/sunxi-legacy/0138-ASoC-sunxi-rename-SND_SUNXI_ADDA_PR_REGMAP-to-SND_SU.patch deleted file mode 100644 index 73bba2700..000000000 --- a/patch/kernel/sunxi-legacy/0138-ASoC-sunxi-rename-SND_SUNXI_ADDA_PR_REGMAP-to-SND_SU.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 4408d80fe8dd0a724cebcc9b0d50af8674d56377 Mon Sep 17 00:00:00 2001 -From: Vasily Khoruzhick -Date: Fri, 2 Nov 2018 21:16:26 -0700 -Subject: [PATCH 138/146] ASoC: sunxi: rename SND_SUNXI_ADDA_PR_REGMAP to - SND_SUN8I_ADDA_PR_REGMAP - -SND_SUN50I_CODEC_ANALOG selects SND_SUNXI_ADDA_PR_REGMAP which is leftover -of renaming SND_SUNXI_ADDA_PR_REGMAP to SND_SUN8I_ADDA_PR_REGMAP. Replace -it with SND_SUN8I_ADDA_PR_REGMAP to fix possible link errors for some -configurations: - -sound/soc/sunxi/sun50i-codec-analog.o: In function `sun50i_codec_analog_probe': -sun50i-codec-analog.c:(.text+0x62): undefined reference to `sun8i_adda_pr_regmap_init' - -Fixes: 42371f327df0 ("ASoC: sunxi: Add new driver for Allwinner A64 codec's analog path controls") -Signed-off-by: Vasily Khoruzhick ---- - sound/soc/sunxi/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig -index 66aad0d3f9c7..8134c3c94229 100644 ---- a/sound/soc/sunxi/Kconfig -+++ b/sound/soc/sunxi/Kconfig -@@ -31,7 +31,7 @@ config SND_SUN8I_CODEC_ANALOG - config SND_SUN50I_CODEC_ANALOG - tristate "Allwinner sun50i Codec Analog Controls Support" - depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST -- select SND_SUNXI_ADDA_PR_REGMAP -+ select SND_SUN8I_ADDA_PR_REGMAP - help - Say Y or M if you want to add support for the analog controls for - the codec embedded in Allwinner A64 SoC. --- -2.17.1 - diff --git a/patch/kernel/sunxi-legacy/0142-Bluetooth-hci_h5-Add-support-for-binding-RTL8723BS-w.patch b/patch/kernel/sunxi-legacy/0142-Bluetooth-hci_h5-Add-support-for-binding-RTL8723BS-w.patch index be3dc20c0..5dae8ea6b 100644 --- a/patch/kernel/sunxi-legacy/0142-Bluetooth-hci_h5-Add-support-for-binding-RTL8723BS-w.patch +++ b/patch/kernel/sunxi-legacy/0142-Bluetooth-hci_h5-Add-support-for-binding-RTL8723BS-w.patch @@ -36,7 +36,7 @@ index 6e047df4f475..9cc10e299fa8 100644 } h5->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW); -@@ -944,12 +950,26 @@ static const struct acpi_device_id h5_acpi_match[] = { +@@ -944,13 +950,27 @@ static const struct acpi_device_id h5_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, h5_acpi_match); #endif @@ -59,6 +59,7 @@ index 6e047df4f475..9cc10e299fa8 100644 .driver = { .name = "hci_uart_h5", .acpi_match_table = ACPI_PTR(h5_acpi_match), + .pm = &h5_serdev_pm_ops, + .of_match_table = of_match_ptr(h5_of_match), }, }; diff --git a/patch/kernel/sunxi-current/0526-pwm-sun4i-Add-support-for-Allwinner-H6.patch b/patch/kernel/sunxi-legacy/0526-pwm-sun4i-Add-support-for-Allwinner-H6.patch similarity index 100% rename from patch/kernel/sunxi-current/0526-pwm-sun4i-Add-support-for-Allwinner-H6.patch rename to patch/kernel/sunxi-legacy/0526-pwm-sun4i-Add-support-for-Allwinner-H6.patch diff --git a/patch/kernel/sunxi-current/0533-allwinner-h6-add-AC200-EPHY-support.patch b/patch/kernel/sunxi-legacy/0533-allwinner-h6-add-AC200-EPHY-support.patch similarity index 100% rename from patch/kernel/sunxi-current/0533-allwinner-h6-add-AC200-EPHY-support.patch rename to patch/kernel/sunxi-legacy/0533-allwinner-h6-add-AC200-EPHY-support.patch diff --git a/patch/kernel/sunxi-current/0534-arm64-dts-sun50i-h6-add-AC200-nodes.patch b/patch/kernel/sunxi-legacy/0534-arm64-dts-sun50i-h6-add-AC200-nodes.patch similarity index 100% rename from patch/kernel/sunxi-current/0534-arm64-dts-sun50i-h6-add-AC200-nodes.patch rename to patch/kernel/sunxi-legacy/0534-arm64-dts-sun50i-h6-add-AC200-nodes.patch diff --git a/patch/kernel/sunxi-current/0607-media-cedrus-choose-default-pixelformat-in-try_fmt.patch b/patch/kernel/sunxi-legacy/0607-media-cedrus-choose-default-pixelformat-in-try_fmt.patch similarity index 100% rename from patch/kernel/sunxi-current/0607-media-cedrus-choose-default-pixelformat-in-try_fmt.patch rename to patch/kernel/sunxi-legacy/0607-media-cedrus-choose-default-pixelformat-in-try_fmt.patch diff --git a/patch/kernel/sunxi-current/0608-media-cedrus-fix-various-format-related-compliance-issues.patch b/patch/kernel/sunxi-legacy/0608-media-cedrus-fix-various-format-related-compliance-issues.patch similarity index 100% rename from patch/kernel/sunxi-current/0608-media-cedrus-fix-various-format-related-compliance-issues.patch rename to patch/kernel/sunxi-legacy/0608-media-cedrus-fix-various-format-related-compliance-issues.patch diff --git a/patch/kernel/sunxi-current/0609-media-cedrus-h264-Support-multiple-slices-per-frame.patch b/patch/kernel/sunxi-legacy/0609-media-cedrus-h264-Support-multiple-slices-per-frame.patch similarity index 100% rename from patch/kernel/sunxi-current/0609-media-cedrus-h264-Support-multiple-slices-per-frame.patch rename to patch/kernel/sunxi-legacy/0609-media-cedrus-h264-Support-multiple-slices-per-frame.patch diff --git a/patch/kernel/sunxi-current/0611-media-cedrus-Remove-unnecessary-parenthesis-aroundDIV_ROUND_UP.patch b/patch/kernel/sunxi-legacy/0611-media-cedrus-Remove-unnecessary-parenthesis-aroundDIV_ROUND_UP.patch similarity index 100% rename from patch/kernel/sunxi-current/0611-media-cedrus-Remove-unnecessary-parenthesis-aroundDIV_ROUND_UP.patch rename to patch/kernel/sunxi-legacy/0611-media-cedrus-Remove-unnecessary-parenthesis-aroundDIV_ROUND_UP.patch diff --git a/patch/kernel/sunxi-current/0612-media-cedrus-Add-HEVC-decoding-support.patch b/patch/kernel/sunxi-legacy/0612-media-cedrus-Add-HEVC-decoding-support.patch similarity index 100% rename from patch/kernel/sunxi-current/0612-media-cedrus-Add-HEVC-decoding-support.patch rename to patch/kernel/sunxi-legacy/0612-media-cedrus-Add-HEVC-decoding-support.patch diff --git a/patch/kernel/sunxi-current/0615-media-cedrus-Fix-decoding-for-some-H264-videos.patch b/patch/kernel/sunxi-legacy/0615-media-cedrus-Fix-decoding-for-some-H264-videos.patch similarity index 100% rename from patch/kernel/sunxi-current/0615-media-cedrus-Fix-decoding-for-some-H264-videos.patch rename to patch/kernel/sunxi-legacy/0615-media-cedrus-Fix-decoding-for-some-H264-videos.patch diff --git a/patch/kernel/sunxi-current/0617-media-cedrus-Use-correct-H264-8x8-scaling-list.patch.disabled b/patch/kernel/sunxi-legacy/0617-media-cedrus-Use-correct-H264-8x8-scaling-list.patch.disabled similarity index 100% rename from patch/kernel/sunxi-current/0617-media-cedrus-Use-correct-H264-8x8-scaling-list.patch.disabled rename to patch/kernel/sunxi-legacy/0617-media-cedrus-Use-correct-H264-8x8-scaling-list.patch.disabled diff --git a/patch/kernel/sunxi-current/0619-media-cedrus-Properly-signa-size-in-mode-register.patch b/patch/kernel/sunxi-legacy/0619-media-cedrus-Properly-signa-size-in-mode-register.patch similarity index 100% rename from patch/kernel/sunxi-current/0619-media-cedrus-Properly-signa-size-in-mode-register.patch rename to patch/kernel/sunxi-legacy/0619-media-cedrus-Properly-signa-size-in-mode-register.patch diff --git a/patch/kernel/sunxi-current/0620-media-cedrus-Fix-H264-4k-support.patch b/patch/kernel/sunxi-legacy/0620-media-cedrus-Fix-H264-4k-support.patch similarity index 100% rename from patch/kernel/sunxi-current/0620-media-cedrus-Fix-H264-4k-support.patch rename to patch/kernel/sunxi-legacy/0620-media-cedrus-Fix-H264-4k-support.patch diff --git a/patch/kernel/sunxi-current/0621-media-cedrus-Increase-maximum-supported-size.patch b/patch/kernel/sunxi-legacy/0621-media-cedrus-Increase-maximum-supported-size.patch similarity index 100% rename from patch/kernel/sunxi-current/0621-media-cedrus-Increase-maximum-supported-size.patch rename to patch/kernel/sunxi-legacy/0621-media-cedrus-Increase-maximum-supported-size.patch diff --git a/patch/kernel/sunxi-current/0622-media-cedrus-improvements.patch b/patch/kernel/sunxi-legacy/0622-media-cedrus-improvements.patch similarity index 100% rename from patch/kernel/sunxi-current/0622-media-cedrus-improvements.patch rename to patch/kernel/sunxi-legacy/0622-media-cedrus-improvements.patch diff --git a/patch/kernel/sunxi-current/0623-media-cedrus-10bit-HEVC-hack.patch b/patch/kernel/sunxi-legacy/0623-media-cedrus-10bit-HEVC-hack.patch similarity index 100% rename from patch/kernel/sunxi-current/0623-media-cedrus-10bit-HEVC-hack.patch rename to patch/kernel/sunxi-legacy/0623-media-cedrus-10bit-HEVC-hack.patch diff --git a/patch/kernel/sunxi-legacy/0700-h3-spdif-clk-fix.patch b/patch/kernel/sunxi-legacy/0700-h3-spdif-clk-fix.patch index 4bb653ccc..20c7b3148 100644 --- a/patch/kernel/sunxi-legacy/0700-h3-spdif-clk-fix.patch +++ b/patch/kernel/sunxi-legacy/0700-h3-spdif-clk-fix.patch @@ -1,63 +1,57 @@ diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c -index b4af4aabe..d9db852bb 100644 +index cbe598b0f..08f0ed3e9 100644 --- a/sound/soc/sunxi/sun4i-spdif.c +++ b/sound/soc/sunxi/sun4i-spdif.c -@@ -169,6 +169,7 @@ struct sun4i_spdif_dev { - struct snd_soc_dai_driver cpu_dai_drv; - struct regmap *regmap; - struct snd_dmaengine_dai_dma_data dma_params_tx; -+ unsigned int spdif_clk_mult; - }; - - static void sun4i_spdif_configure(struct sun4i_spdif_dev *host) -@@ -293,6 +294,8 @@ static int sun4i_spdif_hw_params(struct snd_pcm_substream *substream, - return -EINVAL; - } - -+ mclk *= host->spdif_clk_mult; -+ - ret = clk_set_rate(host->spdif_clk, mclk); - if (ret < 0) { - dev_err(&pdev->dev, -@@ -327,6 +330,8 @@ static int sun4i_spdif_hw_params(struct snd_pcm_substream *substream, - return -EINVAL; - } - -+ mclk_div *= host->spdif_clk_mult; -+ - reg_val = 0; - reg_val |= SUN4I_SPDIF_TXCFG_ASS; - reg_val |= fmt; /* set non audio and bit depth */ -@@ -408,20 +413,24 @@ static struct snd_soc_dai_driver sun4i_spdif_dai = { - struct sun4i_spdif_quirks { - unsigned int reg_dac_txdata; /* TX FIFO offset for DMA config */ +@@ -175,6 +175,7 @@ struct sun4i_spdif_quirks { + unsigned int reg_dac_txdata; bool has_reset; + unsigned int val_fctl_ftx; + unsigned int mclk_multiplier; }; + struct sun4i_spdif_dev { +@@ -311,6 +312,7 @@ static int sun4i_spdif_hw_params(struct snd_pcm_substream *substream, + default: + return -EINVAL; + } ++ mclk *= host->quirks->mclk_multiplier; + + ret = clk_set_rate(host->spdif_clk, mclk); + if (ret < 0) { +@@ -345,6 +347,7 @@ static int sun4i_spdif_hw_params(struct snd_pcm_substream *substream, + default: + return -EINVAL; + } ++ mclk_div *= host->quirks->mclk_multiplier; + + reg_val = 0; + reg_val |= SUN4I_SPDIF_TXCFG_ASS; +@@ -427,24 +430,28 @@ static struct snd_soc_dai_driver sun4i_spdif_dai = { static const struct sun4i_spdif_quirks sun4i_a10_spdif_quirks = { .reg_dac_txdata = SUN4I_SPDIF_TXFIFO, + .val_fctl_ftx = SUN4I_SPDIF_FCTL_FTX, + .mclk_multiplier = 1, }; static const struct sun4i_spdif_quirks sun6i_a31_spdif_quirks = { .reg_dac_txdata = SUN4I_SPDIF_TXFIFO, + .val_fctl_ftx = SUN4I_SPDIF_FCTL_FTX, .has_reset = true, + .mclk_multiplier = 1, }; static const struct sun4i_spdif_quirks sun8i_h3_spdif_quirks = { .reg_dac_txdata = SUN8I_SPDIF_TXFIFO, + .val_fctl_ftx = SUN4I_SPDIF_FCTL_FTX, .has_reset = true, + .mclk_multiplier = 4, }; - static const struct of_device_id sun4i_spdif_of_match[] = { -@@ -517,6 +526,7 @@ static int sun4i_spdif_probe(struct platform_device *pdev) - dev_err(&pdev->dev, "failed to get a spdif clock.\n"); - return PTR_ERR(host->spdif_clk); - } -+ host->spdif_clk_mult = quirks->mclk_multiplier; + static const struct sun4i_spdif_quirks sun50i_h6_spdif_quirks = { + .reg_dac_txdata = SUN8I_SPDIF_TXFIFO, + .val_fctl_ftx = SUN50I_H6_SPDIF_FCTL_FTX, + .has_reset = true, ++ .mclk_multiplier = 1, + }; - host->dma_params_tx.addr = res->start + quirks->reg_dac_txdata; - host->dma_params_tx.maxburst = 8; + static const struct of_device_id sun4i_spdif_of_match[] = { diff --git a/patch/kernel/sunxi-current/1000-orangepi-win_enable_audio_codec.patch b/patch/kernel/sunxi-legacy/1000-orangepi-win_enable_audio_codec.patch similarity index 100% rename from patch/kernel/sunxi-current/1000-orangepi-win_enable_audio_codec.patch rename to patch/kernel/sunxi-legacy/1000-orangepi-win_enable_audio_codec.patch diff --git a/patch/kernel/sunxi-current/2000-a64-enable-dvfs.patch b/patch/kernel/sunxi-legacy/2000-a64-enable-dvfs.patch similarity index 100% rename from patch/kernel/sunxi-current/2000-a64-enable-dvfs.patch rename to patch/kernel/sunxi-legacy/2000-a64-enable-dvfs.patch diff --git a/patch/kernel/sunxi-current/5000-patch-4.19.9-10.patch.disabled b/patch/kernel/sunxi-legacy/5000-patch-4.19.9-10.patch.disabled similarity index 100% rename from patch/kernel/sunxi-current/5000-patch-4.19.9-10.patch.disabled rename to patch/kernel/sunxi-legacy/5000-patch-4.19.9-10.patch.disabled diff --git a/patch/kernel/sunxi-current/5001-patch-4.19.10-11.patch.disabled b/patch/kernel/sunxi-legacy/5001-patch-4.19.10-11.patch.disabled similarity index 100% rename from patch/kernel/sunxi-current/5001-patch-4.19.10-11.patch.disabled rename to patch/kernel/sunxi-legacy/5001-patch-4.19.10-11.patch.disabled diff --git a/patch/kernel/sunxi-legacy/ARM-dts-sun7i-Disable-OOB-IRQ-for-brcm-wifi-on-Banana-Pi-M1-plus.patch b/patch/kernel/sunxi-legacy/ARM-dts-sun7i-Disable-OOB-IRQ-for-brcm-wifi-on-Banana-Pi-M1-plus.patch deleted file mode 100644 index 8a3a23db2..000000000 --- a/patch/kernel/sunxi-legacy/ARM-dts-sun7i-Disable-OOB-IRQ-for-brcm-wifi-on-Banana-Pi-M1-plus.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0999574c7b78b85d56ef6ca39684817636773d75 Mon Sep 17 00:00:00 2001 -From: Richard Kojedzinszky -Date: Sun, 20 Jan 2019 18:43:37 +0100 -Subject: [PATCH] Disable OOB IRQ for wifi on bananapi m1 plus - -See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=908438 ---- - arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts | 16 +++++++++++++--- - 1 file changed, 13 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts b/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts -index 763cb03033c4..661b4f90db91 100644 ---- a/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts -+++ b/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts -@@ -203,9 +203,19 @@ - brcmf: wifi@1 { - reg = <1>; - compatible = "brcm,bcm4329-fmac"; -- interrupt-parent = <&pio>; -- interrupts = <7 15 IRQ_TYPE_LEVEL_LOW>; -- interrupt-names = "host-wake"; -+ /* -+ * OOB interrupt support is broken ATM, often the first irq -+ * does not get seen resulting in the drv probe failing with: -+ * -+ * brcmfmac: brcmf_sdio_bus_rxctl: resumed on timeout -+ * brcmfmac: brcmf_bus_started: failed: -110 -+ * brcmfmac: brcmf_attach: dongle is not responding: err=-110 -+ * brcmfmac: brcmf_sdio_firmware_callback: brcmf_attach failed -+ * -+ * interrupt-parent = <&pio>; -+ * interrupts = <7 15 IRQ_TYPE_LEVEL_LOW>; -+ * interrupt-names = "host-wake"; -+ */ - }; - }; - --- -2.11.0 - diff --git a/patch/kernel/sunxi-legacy/Add_HDMI_audio_support_for_the_sun4i-hdmi.patch b/patch/kernel/sunxi-legacy/Add_HDMI_audio_support_for_the_sun4i-hdmi.patch new file mode 100644 index 000000000..6967ba0cd --- /dev/null +++ b/patch/kernel/sunxi-legacy/Add_HDMI_audio_support_for_the_sun4i-hdmi.patch @@ -0,0 +1,637 @@ +Add HDMI audio support for the sun4i-hdmi encoder, used on +the older Allwinner chips - A10, A20, A31. + +Most of the code is based on the BSP implementation. In it +dditional formats are supported (S20_3LE and S24_LE), however +there where some problems with them and only S16_LE is left. + +Signed-off-by: Stefan Mavrodiev +--- +Changes for v3: + - Instead of platfrom_driver dynammicly register/unregister card + - Add Kconfig dependencies + - Restrore drvdata after card unregistering + +Changes for v2: + - Create a new platform driver instead of using the HDMI encoder + - Expose a new kcontrol to the userspace holding the ELD data + - Wrap all macro arguments in parentheses + + drivers/gpu/drm/sun4i/Kconfig | 11 + + drivers/gpu/drm/sun4i/Makefile | 3 + + drivers/gpu/drm/sun4i/sun4i_hdmi.h | 37 ++ + drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c | 450 +++++++++++++++++++++++ + drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 14 + + 5 files changed, 515 insertions(+) + create mode 100644 drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c + +diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig +index 37e90e42943f..ca2ab5d53dd4 100644 +--- a/drivers/gpu/drm/sun4i/Kconfig ++++ b/drivers/gpu/drm/sun4i/Kconfig +@@ -23,6 +23,17 @@ config DRM_SUN4I_HDMI + Choose this option if you have an Allwinner SoC with an HDMI + controller. + ++config DRM_SUN4I_HDMI_AUDIO ++ bool "Allwinner A10 HDMI Audio Support" ++ default y ++ depends on DRM_SUN4I_HDMI ++ depends on SND_SOC=y || SND_SOC=DRM_SUN4I_HDMI ++ select SND_PCM_ELD ++ select SND_SOC_GENERIC_DMAENGINE_PCM ++ help ++ Choose this option if you have an Allwinner SoC with an HDMI ++ controller and want to use audio. ++ + config DRM_SUN4I_HDMI_CEC + bool "Allwinner A10 HDMI CEC Support" + depends on DRM_SUN4I_HDMI +diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile +index 0d04f2447b01..492bfd28ad2e 100644 +--- a/drivers/gpu/drm/sun4i/Makefile ++++ b/drivers/gpu/drm/sun4i/Makefile +@@ -5,6 +5,9 @@ sun4i-frontend-y += sun4i_frontend.o + sun4i-drm-y += sun4i_drv.o + sun4i-drm-y += sun4i_framebuffer.o + ++ifdef CONFIG_DRM_SUN4I_HDMI_AUDIO ++sun4i-drm-hdmi-y += sun4i_hdmi_audio.o ++endif + sun4i-drm-hdmi-y += sun4i_hdmi_ddc_clk.o + sun4i-drm-hdmi-y += sun4i_hdmi_enc.o + sun4i-drm-hdmi-y += sun4i_hdmi_i2c.o +diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h +index 7ad3f06c127e..28621d289655 100644 +--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h ++++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h +@@ -42,7 +42,32 @@ + #define SUN4I_HDMI_VID_TIMING_POL_VSYNC BIT(1) + #define SUN4I_HDMI_VID_TIMING_POL_HSYNC BIT(0) + ++#define SUN4I_HDMI_AUDIO_CTRL_REG 0x040 ++#define SUN4I_HDMI_AUDIO_CTRL_ENABLE BIT(31) ++#define SUN4I_HDMI_AUDIO_CTRL_RESET BIT(30) ++ ++#define SUN4I_HDMI_AUDIO_FMT_REG 0x048 ++#define SUN4I_HDMI_AUDIO_FMT_SRC BIT(31) ++#define SUN4I_HDMI_AUDIO_FMT_LAYOUT BIT(3) ++#define SUN4I_HDMI_AUDIO_FMT_CH_CFG(n) ((n) - 1) ++#define SUN4I_HDMI_AUDIO_FMT_CH_CFG_MASK GENMASK(2, 0) ++ ++#define SUN4I_HDMI_AUDIO_PCM_REG 0x4c ++#define SUN4I_HDMI_AUDIO_PCM_CH_MAP(n, m) (((m) - 1) << ((n) * 4)) ++#define SUN4I_HDMI_AUDIO_PCM_CH_MAP_MASK(n) (GENMASK(2, 0) << ((n) * 4)) ++ ++#define SUN4I_HDMI_AUDIO_CTS_REG 0x050 ++#define SUN4I_HDMI_AUDIO_CTS(n) ((n) & GENMASK(19, 0)) ++ ++#define SUN4I_HDMI_AUDIO_N_REG 0x054 ++#define SUN4I_HDMI_AUDIO_N(n) ((n) & GENMASK(19, 0)) ++ ++#define SUN4I_HDMI_AUDIO_STAT0_REG 0x58 ++#define SUN4I_HDMI_AUDIO_STAT0_FREQ(n) ((n) << 24) ++#define SUN4I_HDMI_AUDIO_STAT0_FREQ_MASK GENMASK(27, 24) ++ + #define SUN4I_HDMI_AVI_INFOFRAME_REG(n) (0x080 + (n)) ++#define SUN4I_HDMI_AUDIO_INFOFRAME_REG(n) (0x0a0 + (n)) + + #define SUN4I_HDMI_PAD_CTRL0_REG 0x200 + #define SUN4I_HDMI_PAD_CTRL0_BIASEN BIT(31) +@@ -242,6 +267,11 @@ struct sun4i_hdmi_variant { + bool ddc_fifo_has_dir; + }; + ++struct sun4i_hdmi_audio { ++ struct snd_soc_card *card; ++ u8 channels; ++}; ++ + struct sun4i_hdmi { + struct drm_connector connector; + struct drm_encoder encoder; +@@ -283,9 +313,14 @@ struct sun4i_hdmi { + struct regmap_field *field_ddc_sda_en; + struct regmap_field *field_ddc_sck_en; + ++ + struct sun4i_drv *drv; + + bool hdmi_monitor; ++ bool hdmi_audio; ++ ++ struct sun4i_hdmi_audio audio; ++ + struct cec_adapter *cec_adap; + + const struct sun4i_hdmi_variant *variant; +@@ -294,5 +329,7 @@ struct sun4i_hdmi { + int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *clk); + int sun4i_tmds_create(struct sun4i_hdmi *hdmi); + int sun4i_hdmi_i2c_create(struct device *dev, struct sun4i_hdmi *hdmi); ++int sun4i_hdmi_audio_create(struct sun4i_hdmi *hdmi); ++void sun4i_hdmi_audio_destroy(struct sun4i_hdmi *hdmi); + + #endif /* _SUN4I_HDMI_H_ */ +diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c +new file mode 100644 +index 000000000000..f42f2cea4e9e +--- /dev/null ++++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c +@@ -0,0 +1,450 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Copyright (C) 2020 Olimex Ltd. ++ * Author: Stefan Mavrodiev ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "sun4i_hdmi.h" ++ ++static int sun4i_hdmi_audio_ctl_eld_info(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; ++ uinfo->count = MAX_ELD_BYTES; ++ return 0; ++} ++ ++static int sun4i_hdmi_audio_ctl_eld_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); ++ struct snd_soc_card *card = snd_soc_component_get_drvdata(component); ++ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); ++ ++ memcpy(ucontrol->value.bytes.data, ++ hdmi->connector.eld, ++ MAX_ELD_BYTES); ++ ++ return 0; ++} ++ ++static const struct snd_kcontrol_new sun4i_hdmi_audio_controls[] = { ++ { ++ .access = SNDRV_CTL_ELEM_ACCESS_READ | ++ SNDRV_CTL_ELEM_ACCESS_VOLATILE, ++ .iface = SNDRV_CTL_ELEM_IFACE_PCM, ++ .name = "ELD", ++ .info = sun4i_hdmi_audio_ctl_eld_info, ++ .get = sun4i_hdmi_audio_ctl_eld_get, ++ }, ++}; ++ ++static const struct snd_soc_dapm_widget sun4i_hdmi_audio_widgets[] = { ++ SND_SOC_DAPM_OUTPUT("TX"), ++}; ++ ++static const struct snd_soc_dapm_route sun4i_hdmi_audio_routes[] = { ++ { "TX", NULL, "Playback" }, ++}; ++ ++static const struct snd_soc_component_driver sun4i_hdmi_audio_component = { ++ .controls = sun4i_hdmi_audio_controls, ++ .num_controls = ARRAY_SIZE(sun4i_hdmi_audio_controls), ++ .dapm_widgets = sun4i_hdmi_audio_widgets, ++ .num_dapm_widgets = ARRAY_SIZE(sun4i_hdmi_audio_widgets), ++ .dapm_routes = sun4i_hdmi_audio_routes, ++ .num_dapm_routes = ARRAY_SIZE(sun4i_hdmi_audio_routes), ++}; ++ ++static int sun4i_hdmi_audio_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); ++ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); ++ u32 reg; ++ int ret; ++ ++ regmap_write(hdmi->regmap, SUN4I_HDMI_AUDIO_CTRL_REG, 0); ++ regmap_write(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_CTRL_REG, ++ SUN4I_HDMI_AUDIO_CTRL_RESET); ++ ret = regmap_read_poll_timeout(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_CTRL_REG, ++ reg, !reg, 100, 50000); ++ if (ret < 0) { ++ DRM_ERROR("Failed to reset HDMI Audio\n"); ++ return ret; ++ } ++ ++ regmap_write(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_CTRL_REG, ++ SUN4I_HDMI_AUDIO_CTRL_ENABLE); ++ ++ return snd_pcm_hw_constraint_eld(substream->runtime, ++ hdmi->connector.eld); ++} ++ ++static void sun4i_hdmi_audio_shutdown(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); ++ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); ++ ++ regmap_write(hdmi->regmap, SUN4I_HDMI_AUDIO_CTRL_REG, 0); ++} ++ ++static int sun4i_hdmi_setup_audio_infoframes(struct sun4i_hdmi *hdmi) ++{ ++ union hdmi_infoframe frame; ++ u8 buffer[14]; ++ int i, ret; ++ ++ ret = hdmi_audio_infoframe_init(&frame.audio); ++ if (ret < 0) { ++ DRM_ERROR("Failed to init HDMI audio infoframe\n"); ++ return ret; ++ } ++ ++ frame.audio.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; ++ frame.audio.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; ++ frame.audio.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; ++ frame.audio.channels = hdmi->audio.channels; ++ ++ ret = hdmi_infoframe_pack(&frame, buffer, sizeof(buffer)); ++ if (ret < 0) { ++ DRM_ERROR("Failed to pack HDMI audio infoframe\n"); ++ return ret; ++ } ++ ++ for (i = 0; i < sizeof(buffer); i++) ++ writeb(buffer[i], ++ hdmi->base + SUN4I_HDMI_AUDIO_INFOFRAME_REG(i)); ++ ++ return 0; ++} ++ ++static void sun4i_hdmi_audio_set_cts_n(struct sun4i_hdmi *hdmi, ++ struct snd_pcm_hw_params *params) ++{ ++ struct drm_encoder *encoder = &hdmi->encoder; ++ struct drm_crtc *crtc = encoder->crtc; ++ const struct drm_display_mode *mode = &crtc->state->adjusted_mode; ++ u32 rate = params_rate(params); ++ u32 n, cts; ++ u64 tmp; ++ ++ /** ++ * Calculate Cycle Time Stamp (CTS) and Numerator (N): ++ * ++ * N = 128 * Samplerate / 1000 ++ * CTS = (Ftdms * N) / (128 * Samplerate) ++ */ ++ ++ n = 128 * rate / 1000; ++ tmp = (u64)(mode->clock * 1000) * n; ++ do_div(tmp, 128 * rate); ++ cts = tmp; ++ ++ regmap_write(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_CTS_REG, ++ SUN4I_HDMI_AUDIO_CTS(cts)); ++ ++ regmap_write(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_N_REG, ++ SUN4I_HDMI_AUDIO_N(n)); ++} ++ ++static int sun4i_hdmi_audio_set_hw_rate(struct sun4i_hdmi *hdmi, ++ struct snd_pcm_hw_params *params) ++{ ++ u32 rate = params_rate(params); ++ u32 val; ++ ++ switch (rate) { ++ case 44100: ++ val = 0x0; ++ break; ++ case 48000: ++ val = 0x2; ++ break; ++ case 32000: ++ val = 0x3; ++ break; ++ case 88200: ++ val = 0x8; ++ break; ++ case 96000: ++ val = 0x9; ++ break; ++ case 176400: ++ val = 0xc; ++ break; ++ case 192000: ++ val = 0xe; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_STAT0_REG, ++ SUN4I_HDMI_AUDIO_STAT0_FREQ_MASK, ++ SUN4I_HDMI_AUDIO_STAT0_FREQ(val)); ++ ++ return 0; ++} ++ ++static int sun4i_hdmi_audio_set_hw_channels(struct sun4i_hdmi *hdmi, ++ struct snd_pcm_hw_params *params) ++{ ++ u32 channels = params_channels(params); ++ ++ if (channels > 8) ++ return -EINVAL; ++ ++ hdmi->audio.channels = channels; ++ ++ regmap_update_bits(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_FMT_REG, ++ SUN4I_HDMI_AUDIO_FMT_LAYOUT, ++ (channels > 2) ? SUN4I_HDMI_AUDIO_FMT_LAYOUT : 0); ++ ++ regmap_update_bits(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_FMT_REG, ++ SUN4I_HDMI_AUDIO_FMT_CH_CFG_MASK, ++ SUN4I_HDMI_AUDIO_FMT_CH_CFG(channels)); ++ ++ regmap_write(hdmi->regmap, SUN4I_HDMI_AUDIO_PCM_REG, 0x76543210); ++ ++ /** ++ * If only one channel is required, send the same sample ++ * to the sink device as a left and right channel. ++ */ ++ if (channels == 1) ++ regmap_update_bits(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_PCM_REG, ++ SUN4I_HDMI_AUDIO_PCM_CH_MAP_MASK(1), ++ SUN4I_HDMI_AUDIO_PCM_CH_MAP(1, 1)); ++ ++ return 0; ++} ++ ++static int sun4i_hdmi_audio_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); ++ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); ++ int ret; ++ ++ ret = sun4i_hdmi_audio_set_hw_rate(hdmi, params); ++ if (ret < 0) ++ return ret; ++ ++ ret = sun4i_hdmi_audio_set_hw_channels(hdmi, params); ++ if (ret < 0) ++ return ret; ++ ++ sun4i_hdmi_audio_set_cts_n(hdmi, params); ++ ++ return 0; ++} ++ ++static int sun4i_hdmi_audio_trigger(struct snd_pcm_substream *substream, ++ int cmd, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); ++ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); ++ int ret = 0; ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ ret = sun4i_hdmi_setup_audio_infoframes(hdmi); ++ break; ++ default: ++ break; ++ } ++ ++ return ret; ++} ++ ++static const struct snd_soc_dai_ops sun4i_hdmi_audio_dai_ops = { ++ .startup = sun4i_hdmi_audio_startup, ++ .shutdown = sun4i_hdmi_audio_shutdown, ++ .hw_params = sun4i_hdmi_audio_hw_params, ++ .trigger = sun4i_hdmi_audio_trigger, ++}; ++ ++static int sun4i_hdmi_audio_dai_probe(struct snd_soc_dai *dai) ++{ ++ struct snd_dmaengine_dai_dma_data *dma_data; ++ ++ dma_data = devm_kzalloc(dai->dev, sizeof(*dma_data), GFP_KERNEL); ++ if (!dma_data) ++ return -ENOMEM; ++ ++ dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ dma_data->maxburst = 8; ++ ++ snd_soc_dai_init_dma_data(dai, dma_data, NULL); ++ ++ return 0; ++} ++ ++static struct snd_soc_dai_driver sun4i_hdmi_audio_dai = { ++ .name = "HDMI", ++ .ops = &sun4i_hdmi_audio_dai_ops, ++ .probe = sun4i_hdmi_audio_dai_probe, ++ .playback = { ++ .stream_name = "Playback", ++ .channels_min = 1, ++ .channels_max = 8, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ }, ++}; ++ ++static const struct snd_pcm_hardware sun4i_hdmi_audio_pcm_hardware = { ++ .info = SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_BLOCK_TRANSFER | ++ SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_MMAP_VALID | ++ SNDRV_PCM_INFO_PAUSE | ++ SNDRV_PCM_INFO_RESUME, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ .rate_min = 8000, ++ .rate_max = 192000, ++ .channels_min = 1, ++ .channels_max = 8, ++ .buffer_bytes_max = 128 * 1024, ++ .period_bytes_min = 4 * 1024, ++ .period_bytes_max = 32 * 1024, ++ .periods_min = 2, ++ .periods_max = 8, ++ .fifo_size = 128, ++}; ++ ++static const struct snd_dmaengine_pcm_config sun4i_hdmi_audio_pcm_config = { ++ .chan_names[SNDRV_PCM_STREAM_PLAYBACK] = "audio-tx", ++ .pcm_hardware = &sun4i_hdmi_audio_pcm_hardware, ++ .prealloc_buffer_size = 128 * 1024, ++ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, ++}; ++ ++struct snd_soc_card sun4i_hdmi_audio_card = { ++ .name = "sun4i-hdmi", ++}; ++ ++int sun4i_hdmi_audio_create(struct sun4i_hdmi *hdmi) ++{ ++ struct snd_soc_card *card = &sun4i_hdmi_audio_card; ++ struct snd_soc_dai_link_component *comp; ++ struct snd_soc_dai_link *link; ++ int ret; ++ ++ ret = snd_dmaengine_pcm_register(hdmi->dev, ++ &sun4i_hdmi_audio_pcm_config, 0); ++ if (ret < 0) { ++ DRM_ERROR("Could not register PCM\n"); ++ return ret; ++ } ++ ++ ret = snd_soc_register_component(hdmi->dev, ++ &sun4i_hdmi_audio_component, ++ &sun4i_hdmi_audio_dai, 1); ++ if (ret < 0) { ++ DRM_ERROR("Could not register DAI\n"); ++ goto unregister_pcm; ++ } ++ ++ link = devm_kzalloc(hdmi->dev, sizeof(*link), GFP_KERNEL); ++ if (!link) { ++ ret = -ENOMEM; ++ goto unregister_component; ++ } ++ ++ comp = devm_kzalloc(hdmi->dev, sizeof(*comp) * 3, GFP_KERNEL); ++ if (!comp) { ++ ret = -ENOMEM; ++ goto unregister_component; ++ } ++ ++ link->cpus = &comp[0]; ++ link->codecs = &comp[1]; ++ link->platforms = &comp[2]; ++ ++ link->num_cpus = 1; ++ link->num_codecs = 1; ++ link->num_platforms = 1; ++ ++ link->playback_only = 1; ++ ++ link->name = "SUN4I-HDMI"; ++ link->stream_name = "SUN4I-HDMI PCM"; ++ ++ link->codecs->name = dev_name(hdmi->dev); ++ link->codecs->dai_name = sun4i_hdmi_audio_dai.name; ++ ++ link->cpus->dai_name = dev_name(hdmi->dev); ++ ++ link->platforms->name = dev_name(hdmi->dev); ++ ++ link->dai_fmt = SND_SOC_DAIFMT_I2S; ++ ++ card->dai_link = link; ++ card->num_links = 1; ++ card->dev = hdmi->dev; ++ ++ hdmi->audio.card = card; ++ ++ /** ++ * snd_soc_register_card() will overwrite the driver_data pointer. ++ * So before registering the card, store the original pointer in ++ * card->drvdata. ++ */ ++ snd_soc_card_set_drvdata(card, hdmi); ++ ret = snd_soc_register_card(card); ++ if (ret) ++ goto unregister_component; ++ ++ return 0; ++ ++unregister_component: ++ snd_soc_unregister_component(hdmi->dev); ++unregister_pcm: ++ snd_dmaengine_pcm_unregister(hdmi->dev); ++ return ret; ++} ++ ++void sun4i_hdmi_audio_destroy(struct sun4i_hdmi *hdmi) ++{ ++ struct snd_soc_card *card = hdmi->audio.card; ++ void *data; ++ ++ /** ++ * Before removing the card, restore the previously stored driver_data. ++ * This will ensure proper removal of the sun4i-hdmi module, since it ++ * uses dev_get_drvdata() in the unbind function. ++ */ ++ data = snd_soc_card_get_drvdata(card); ++ ++ snd_soc_unregister_card(card); ++ snd_soc_unregister_component(hdmi->dev); ++ snd_dmaengine_pcm_unregister(hdmi->dev); ++ ++ dev_set_drvdata(hdmi->dev, data); ++} +diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +index 68d4644ac2dc..4cd35c97c503 100644 +--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c ++++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +@@ -23,6 +23,8 @@ + #include + #include + ++#include ++ + #include "sun4i_backend.h" + #include "sun4i_crtc.h" + #include "sun4i_drv.h" +@@ -87,6 +89,10 @@ static void sun4i_hdmi_disable(struct drm_encoder *encoder) + + DRM_DEBUG_DRIVER("Disabling the HDMI Output\n"); + ++#ifdef CONFIG_DRM_SUN4I_HDMI_AUDIO ++ sun4i_hdmi_audio_destroy(hdmi); ++#endif ++ + val = readl(hdmi->base + SUN4I_HDMI_VID_CTRL_REG); + val &= ~SUN4I_HDMI_VID_CTRL_ENABLE; + writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG); +@@ -114,6 +120,11 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder) + val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE; + + writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG); ++ ++#ifdef CONFIG_DRM_SUN4I_HDMI_AUDIO ++ if (hdmi->hdmi_audio && sun4i_hdmi_audio_create(hdmi)) ++ DRM_ERROR("Couldn't create the HDMI audio adapter\n"); ++#endif + } + + static void sun4i_hdmi_mode_set(struct drm_encoder *encoder, +@@ -218,6 +229,9 @@ static int sun4i_hdmi_get_modes(struct drm_connector *connector) + if (!edid) + return 0; + ++#ifdef CONFIG_DRM_SUN4I_HDMI_AUDIO ++ hdmi->hdmi_audio = drm_detect_monitor_audio(edid); ++#endif + hdmi->hdmi_monitor = drm_detect_hdmi_monitor(edid); + DRM_DEBUG_DRIVER("Monitor is %s monitor\n", + hdmi->hdmi_monitor ? "an HDMI" : "a DVI"); diff --git a/patch/kernel/sunxi-legacy/Add_frame_inversion_to_correct_audio_channels.patch b/patch/kernel/sunxi-legacy/Add_frame_inversion_to_correct_audio_channels.patch new file mode 100644 index 000000000..4cb1edeca --- /dev/null +++ b/patch/kernel/sunxi-legacy/Add_frame_inversion_to_correct_audio_channels.patch @@ -0,0 +1,113 @@ +From 62d75bddd6fb671adc7684bfd206f8e635c4bf4b Mon Sep 17 00:00:00 2001 +From: Marcus Cooper +Date: Wed, 1 Jan 2020 20:03:03 +0100 +Subject: [PATCH] Allwinner: Add frame inversion to correct audio channels + +For some reason the mainline i2s driver inverts the frame clock +which in turn maps the audio channels incorrectly when not using +audio passthrough on multi-channel audio. + +Adding frame-inversion to the device tree properties fixes the +issue but should be seen as a temporary fix whilst we investigate +the correct default setup of the i2s block. + +Signed-off-by: Marcus Cooper +--- + ...rsion-to-correct-multi-channel-audio.patch | 24 +++++++++++++++++++ + ...rsion-to-correct-multi-channel-audio.patch | 24 +++++++++++++++++++ + ...rsion-to-correct-multi-channel-audio.patch | 24 +++++++++++++++++++ + 3 files changed, 72 insertions(+) + create mode 100644 projects/Allwinner/devices/A64/patches/linux/04-Add-frame-inversion-to-correct-multi-channel-audio.patch + create mode 100644 projects/Allwinner/devices/H3/patches/linux/17-Add-frame-inversion-to-correct-multi-channel-audio.patch + create mode 100644 projects/Allwinner/devices/H6/patches/linux/16-Add-frame-inversion-to-correct-multi-channel-audio.patch + +diff --git a/projects/Allwinner/devices/A64/patches/linux/04-Add-frame-inversion-to-correct-multi-channel-audio.patch b/projects/Allwinner/devices/A64/patches/linux/04-Add-frame-inversion-to-correct-multi-channel-audio.patch +new file mode 100644 +index 00000000000..16bbbb5c808 +--- /dev/null ++++ b/projects/Allwinner/devices/A64/patches/linux/04-Add-frame-inversion-to-correct-multi-channel-audio.patch +@@ -0,0 +1,24 @@ ++From 08d35c5d5ce6de3453f17e6eff7375afa74173d2 Mon Sep 17 00:00:00 2001 ++From: Marcus Cooper ++Date: Thu, 2 Jan 2020 19:09:25 +0100 ++Subject: [PATCH] Add frame inversion to correct multi-channel audio ++ ++--- ++ arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 1 + ++ 1 file changed, 1 insertion(+) ++ ++diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi ++index 988e261a0ab3..4e20a0872c0c 100644 ++--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi ++@@ -1101,6 +1101,7 @@ ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,name = "allwinner-hdmi"; ++ simple-audio-card,mclk-fs = <128>; +++ simple-audio-card,frame-inversion; ++ ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++-- ++2.24.1 ++ +diff --git a/projects/Allwinner/devices/H3/patches/linux/17-Add-frame-inversion-to-correct-multi-channel-audio.patch b/projects/Allwinner/devices/H3/patches/linux/17-Add-frame-inversion-to-correct-multi-channel-audio.patch +new file mode 100644 +index 00000000000..21e13cbfd72 +--- /dev/null ++++ b/projects/Allwinner/devices/H3/patches/linux/17-Add-frame-inversion-to-correct-multi-channel-audio.patch +@@ -0,0 +1,24 @@ ++From 51dcda7a261bcadca0a8f5e6fe6241ec266438d0 Mon Sep 17 00:00:00 2001 ++From: Marcus Cooper ++Date: Thu, 2 Jan 2020 19:03:35 +0100 ++Subject: [PATCH] Add frame inversion to correct multi-channel audio ++ ++--- ++ arch/arm/boot/dts/sunxi-h3-h5.dtsi | 1 + ++ 1 file changed, 1 insertion(+) ++ ++diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi ++index 8644435e66d3..7375a9479e84 100644 ++--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi +++++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi ++@@ -82,6 +82,7 @@ ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,name = "allwinner-hdmi"; ++ simple-audio-card,mclk-fs = <128>; +++ simple-audio-card,frame-inversion; ++ ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++-- ++2.24.1 ++ +diff --git a/projects/Allwinner/devices/H6/patches/linux/16-Add-frame-inversion-to-correct-multi-channel-audio.patch b/projects/Allwinner/devices/H6/patches/linux/16-Add-frame-inversion-to-correct-multi-channel-audio.patch +new file mode 100644 +index 00000000000..18f7f636562 +--- /dev/null ++++ b/projects/Allwinner/devices/H6/patches/linux/16-Add-frame-inversion-to-correct-multi-channel-audio.patch +@@ -0,0 +1,24 @@ ++From 3e9d104275c44ab1711a3564ce67cabe850afe75 Mon Sep 17 00:00:00 2001 ++From: Marcus Cooper ++Date: Thu, 2 Jan 2020 19:07:29 +0100 ++Subject: [PATCH] Add frame inversion to correct multi-channel audio ++ ++--- ++ arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 1 + ++ 1 file changed, 1 insertion(+) ++ ++diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi ++index 132ef9c2d348..43ed134b49f7 100644 ++--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi ++@@ -103,6 +103,7 @@ ++ simple-audio-card,format = "i2s"; ++ simple-audio-card,name = "allwinner-hdmi"; ++ simple-audio-card,mclk-fs = <128>; +++ simple-audio-card,frame-inversion; ++ ++ simple-audio-card,codec { ++ sound-dai = <&hdmi>; ++-- ++2.24.1 ++ diff --git a/patch/kernel/sunxi-legacy/RFC-drivers-ata-ahci_sunxi-Increased-SATA-AHCI-DMA-TX-RX-FIFOs.patch b/patch/kernel/sunxi-legacy/RFC-drivers-ata-ahci_sunxi-Increased-SATA-AHCI-DMA-TX-RX-FIFOs.patch deleted file mode 100644 index 244f8d4b0..000000000 --- a/patch/kernel/sunxi-legacy/RFC-drivers-ata-ahci_sunxi-Increased-SATA-AHCI-DMA-TX-RX-FIFOs.patch +++ /dev/null @@ -1,36 +0,0 @@ -Increasing the SATA/AHCI DMA TX/RX FIFOs (P0DMACR.TXTS and .RXTS) from -default 0x0 each to 0x3 each gives a write performance boost of 120MB/s -from lame 36MB/s to 45MB/s previously. Read performance is about 200MB/s -[tested on SSD using dd bs=4K count=512K]. - -Tested on the Banana Pi R1 (aka Lamobo R1) and Banana Pi M1 SBCs -with Allwinner A20 32bit-SoCs (ARMv7-a / arm-linux-gnueabihf). -These devices are RaspberryPi-like small devices. - -RFC: Since more than about 25 similar SBC/SoC models do use the -ahci_sunxi driver, users are encouraged to test it on all the -affected boards and give feedback. - -List of the affected sunxi and other boards and SoCs with SATA using -the ahci_sunxi driver: - $ grep -i -e "^&ahci" arch/arm/boot/dts/sun*dts - and http://linux-sunxi.org/Category:Devices_with_SATA_port - -Signed-off-by: Uenal Mutlu ---- - drivers/ata/ahci_sunxi.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c -index 911710643305..257986431c79 100644 ---- a/drivers/ata/ahci_sunxi.c -+++ b/drivers/ata/ahci_sunxi.c -@@ -158,7 +158,7 @@ static void ahci_sunxi_start_engine(struct ata_port *ap) - struct ahci_host_priv *hpriv = ap->host->private_data; - - /* Setup DMA before DMA start */ -- sunxi_clrsetbits(hpriv->mmio + AHCI_P0DMACR, 0x0000ff00, 0x00004400); -+ sunxi_clrsetbits(hpriv->mmio + AHCI_P0DMACR, 0x0000ffff, 0x00004433); - - /* Start DMA */ - sunxi_setbits(port_mmio + PORT_CMD, PORT_CMD_START); diff --git a/patch/kernel/sunxi-legacy/add-h5-emmc-compatible.patch b/patch/kernel/sunxi-legacy/add-h5-emmc-compatible.patch new file mode 100644 index 000000000..3aeb5a5bf --- /dev/null +++ b/patch/kernel/sunxi-legacy/add-h5-emmc-compatible.patch @@ -0,0 +1,26 @@ +diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c +index bba98d8..6087fdb 100644 +--- a/drivers/mmc/host/sunxi-mmc.c ++++ b/drivers/mmc/host/sunxi-mmc.c +@@ -1180,6 +1180,13 @@ static const struct sunxi_mmc_cfg sun50i_a64_emmc_cfg = { + .needs_new_timings = true, + }; + ++static const struct sunxi_mmc_cfg sun50i_h5_emmc_cfg = { ++ .idma_des_size_bits = 13, ++ .clk_delays = NULL, ++ .can_calibrate = true, ++ .needs_new_timings = false, ++}; ++ + static const struct of_device_id sunxi_mmc_of_match[] = { + { .compatible = "allwinner,sun4i-a10-mmc", .data = &sun4i_a10_cfg }, + { .compatible = "allwinner,sun5i-a13-mmc", .data = &sun5i_a13_cfg }, +@@ -1188,6 +1195,7 @@ static const struct of_device_id sunxi_mmc_of_match[] = { + { .compatible = "allwinner,sun9i-a80-mmc", .data = &sun9i_a80_cfg }, + { .compatible = "allwinner,sun50i-a64-mmc", .data = &sun50i_a64_cfg }, + { .compatible = "allwinner,sun50i-a64-emmc", .data = &sun50i_a64_emmc_cfg }, ++ { .compatible = "allwinner,sun50i-h5-emmc", .data = &sun50i_h5_emmc_cfg }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, sunxi_mmc_of_match); diff --git a/patch/kernel/sunxi-legacy/add-nanopi-npi-stuff.patch b/patch/kernel/sunxi-legacy/add-nanopi-npi-stuff.patch new file mode 100644 index 000000000..f2ce4f8ad --- /dev/null +++ b/patch/kernel/sunxi-legacy/add-nanopi-npi-stuff.patch @@ -0,0 +1,48 @@ +diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi b/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi +index 4df29a6..cf59d3f 100644 +--- a/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi ++++ b/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi +@@ -59,6 +63,8 @@ + + leds { + compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&leds_npi>, <&leds_r_npi>; + + status { + label = "nanopi:blue:status"; +@@ -76,6 +82,8 @@ + r_gpio_keys { + compatible = "gpio-keys"; + input-name = "k1"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sw_r_npi>; + + k1 { + label = "k1"; +@@ -100,6 +136,25 @@ + status = "okay"; + }; + ++&pio { ++ leds_npi: led_pins { ++ pins = "PA10"; ++ function = "gpio_out"; ++ }; ++}; ++ ++&r_pio { ++ leds_r_npi: led_pins { ++ pins = "PL10"; ++ function = "gpio_out"; ++ }; ++ ++ sw_r_npi: key_pins { ++ pins = "PL3"; ++ function = "gpio_in"; ++ }; ++}; ++ + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pa_pins>; diff --git a/patch/kernel/sunxi-legacy/add-orangepi-zeroplus2.patch b/patch/kernel/sunxi-legacy/add-orangepi-zeroplus2.patch new file mode 100644 index 000000000..7993e083a --- /dev/null +++ b/patch/kernel/sunxi-legacy/add-orangepi-zeroplus2.patch @@ -0,0 +1,123 @@ +diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-zero-plus2.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-zero-plus2.dts +index b8f46e2..24cb8b9 100644 +--- a/arch/arm/boot/dts/sun8i-h3-orangepi-zero-plus2.dts ++++ b/arch/arm/boot/dts/sun8i-h3-orangepi-zero-plus2.dts +@@ -53,12 +53,29 @@ + + aliases { + serial0 = &uart0; ++ ethernet1 = &brcmf; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + ++ leds { ++ compatible = "gpio-leds"; ++ ++ pwr_led { ++ label = "orangepi:green:pwr"; ++ gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; ++ default-state = "on"; ++ }; ++ ++ status_led { ++ label = "orangepi:red:status"; ++ gpios = <&pio 0 17 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ }; ++ }; ++ + connector { + compatible = "hdmi-connector"; + type = "a"; +@@ -88,6 +105,11 @@ + status = "okay"; + }; + ++&ehci0 { ++ status = "okay"; ++}; ++ ++ + &hdmi { + status = "okay"; + }; +@@ -98,6 +120,22 @@ + }; + }; + ++&sound_hdmi { ++ status = "okay"; ++}; ++ ++&i2s2 { ++ status = "okay"; ++}; ++ ++&mixer0 { ++ status = "okay"; ++}; ++ ++&tcon0 { ++ status = "okay"; ++}; ++ + &mmc0 { + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; +@@ -132,8 +170,53 @@ + status = "okay"; + }; + ++&pio { ++ bt_pwr_pin: bt_pwr_pin@0 { ++ pins = "PA10"; ++ function = "gpio_out"; ++ }; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&spi0 { ++ /* Disable SPI NOR by default: it optional on Orange Pi Zero boards */ ++ status = "disabled"; ++ ++ flash@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "mxicy,mx25l1606e", "winbond,w25q128"; ++ reg = <0>; ++ spi-max-frequency = <40000000>; ++ }; ++}; ++ + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pa_pins>; + status = "okay"; + }; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; ++ status = "okay"; ++}; ++ ++&usb_otg { ++ dr_mode = "peripheral"; ++ status = "okay"; ++}; ++ ++&usbphy { ++ /* ++ * USB Type-A port VBUS is always on. However, MicroUSB VBUS can only ++ * power up the board; when it's used as OTG port, this VBUS is ++ * always off even if the board is powered via GPIO pins. ++ */ ++ status = "okay"; ++ usb0_id_det-gpios = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */ ++}; diff --git a/patch/kernel/sunxi-current/arm64-dts-allwinner-a64-pinebook-Fix-lid-wakeup.patch b/patch/kernel/sunxi-legacy/arm64-dts-allwinner-a64-pinebook-Fix-lid-wakeup.patch similarity index 100% rename from patch/kernel/sunxi-current/arm64-dts-allwinner-a64-pinebook-Fix-lid-wakeup.patch rename to patch/kernel/sunxi-legacy/arm64-dts-allwinner-a64-pinebook-Fix-lid-wakeup.patch diff --git a/patch/kernel/sunxi-current/banana-m3-remove-unstable_clocks.patch b/patch/kernel/sunxi-legacy/banana-m3-remove-unstable_clocks.patch similarity index 100% rename from patch/kernel/sunxi-current/banana-m3-remove-unstable_clocks.patch rename to patch/kernel/sunxi-legacy/banana-m3-remove-unstable_clocks.patch diff --git a/patch/kernel/sunxi-legacy/board-a64-v3-01-19-arm64-dts-allwinner-a64-Add-L2-cache-nodes.patch b/patch/kernel/sunxi-legacy/board-a64-v3-01-19-arm64-dts-allwinner-a64-Add-L2-cache-nodes.patch deleted file mode 100644 index 5608decbb..000000000 --- a/patch/kernel/sunxi-legacy/board-a64-v3-01-19-arm64-dts-allwinner-a64-Add-L2-cache-nodes.patch +++ /dev/null @@ -1,42 +0,0 @@ -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -index d3daf90a8715..934d7e87fa08 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -@@ -134,6 +134,7 @@ - clock-names = "cpu"; - operating-points-v2 = <&cpu0_opp_table>; - #cooling-cells = <2>; -+ next-level-cache = <&L2>; - }; - - cpu1: cpu@1 { -@@ -142,6 +143,7 @@ - reg = <1>; - enable-method = "psci"; - operating-points-v2 = <&cpu0_opp_table>; -+ next-level-cache = <&L2>; - }; - - cpu2: cpu@2 { -@@ -150,6 +152,7 @@ - reg = <2>; - enable-method = "psci"; - operating-points-v2 = <&cpu0_opp_table>; -+ next-level-cache = <&L2>; - }; - - cpu3: cpu@3 { -@@ -158,7 +161,13 @@ - reg = <3>; - enable-method = "psci"; - operating-points-v2 = <&cpu0_opp_table>; -+ next-level-cache = <&L2>; - }; -+ -+ L2: l2-cache { -+ compatible = "cache"; -+ cache-level = <2>; -+ }; - }; - - de: display-engine { diff --git a/patch/kernel/sunxi-legacy/board-a64-v3-02-19-arm64-dts-allwinner-a64-Add-Pine64-LTS-device-tree-file.patch b/patch/kernel/sunxi-legacy/board-a64-v3-02-19-arm64-dts-allwinner-a64-Add-Pine64-LTS-device-tree-file.patch deleted file mode 100644 index 522dda608..000000000 --- a/patch/kernel/sunxi-legacy/board-a64-v3-02-19-arm64-dts-allwinner-a64-Add-Pine64-LTS-device-tree-file.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile -index 9ffa7a038791..b7034327b28b 100644 ---- a/arch/arm64/boot/dts/allwinner/Makefile -+++ b/arch/arm64/boot/dts/allwinner/Makefile -@@ -4,6 +4,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-bananapi-m64.dtb - dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-nanopi-a64.dtb - dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-olinuxino.dtb - dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-orangepi-win.dtb -+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-lts.dtb - dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-plus.dtb sun50i-a64-pine64.dtb - dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinebook.dtb - dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts -new file mode 100644 -index 000000000000..72d6961dc312 ---- /dev/null -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts -@@ -0,0 +1,13 @@ -+/* -+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+ * -+ * Copyright (c) 2018 ARM Ltd. -+ */ -+ -+#include "sun50i-a64-sopine-baseboard.dts" -+ -+/ { -+ model = "Pine64 LTS"; -+ compatible = "pine64,pine64-lts", "allwinner,sun50i-r18", -+ "allwinner,sun50i-a64"; -+}; diff --git a/patch/kernel/sunxi-legacy/board-a64-v3-14-19-arm64-dts-allwinner-a64-Olinuxino-add-Ethernet-nodes.patch b/patch/kernel/sunxi-legacy/board-a64-v3-14-19-arm64-dts-allwinner-a64-Olinuxino-add-Ethernet-nodes.patch deleted file mode 100644 index 44923ac64..000000000 --- a/patch/kernel/sunxi-legacy/board-a64-v3-14-19-arm64-dts-allwinner-a64-Olinuxino-add-Ethernet-nodes.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts -index b3f186434f36..26075b9a76e3 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts -@@ -51,6 +51,7 @@ - compatible = "olimex,a64-olinuxino", "allwinner,sun50i-a64"; - - aliases { -+ ethernet0 = &emac; - serial0 = &uart0; - }; - -@@ -64,6 +65,22 @@ - }; - }; - -+&emac { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rgmii_pins>; -+ phy-mode = "rgmii"; -+ phy-handle = <&ext_rgmii_phy>; -+ phy-supply = <®_dcdc1>; -+ status = "okay"; -+}; -+ -+&mdio { -+ ext_rgmii_phy: ethernet-phy@1 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <1>; -+ }; -+}; -+ - &mmc0 { - pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins>; diff --git a/patch/kernel/sunxi-legacy/board-a64-v3-15-19-arm64-dts-allwinner-a64-Olinuxino-enable-USB.patch b/patch/kernel/sunxi-legacy/board-a64-v3-15-19-arm64-dts-allwinner-a64-Olinuxino-enable-USB.patch new file mode 100644 index 000000000..7aee3ebf2 --- /dev/null +++ b/patch/kernel/sunxi-legacy/board-a64-v3-15-19-arm64-dts-allwinner-a64-Olinuxino-enable-USB.patch @@ -0,0 +1,80 @@ +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts +index 26075b9a76e3..a1c2f06ed474 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts +@@ -77,6 +77,17 @@ + regulator-max-microvolt = <3300000>; + }; + ++ reg_usb1_vbus: usb1-vbus { ++ compatible = "regulator-fixed"; ++ regulator-name = "usb1-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-boot-on; ++ enable-active-high; ++ gpio = <&pio 6 9 GPIO_ACTIVE_HIGH>; /* PG9 */ ++ status = "okay"; ++ }; ++ + wifi_pwrseq: wifi_pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */ +@@ -98,6 +109,14 @@ + }; + }; + ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ehci1 { ++ status = "okay"; ++}; ++ + &emac { + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; +@@ -109,6 +128,14 @@ + }; + }; + ++&ohci0 { ++ status = "okay"; ++}; ++ ++&ohci1 { ++ status = "okay"; ++}; ++ + &r_rsb { + status = "okay"; + +@@ -201,6 +229,11 @@ + regulator-name = "vcc-wifi-io"; + }; + ++®_drivevbus { ++ regulator-name = "usb0-vbus"; ++ status = "okay"; ++}; ++ + ®_eldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; +@@ -244,3 +277,15 @@ + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; + }; ++ ++&usb_otg { ++ dr_mode = "otg"; ++ status = "okay"; ++}; ++ ++&usbphy { ++ status = "okay"; ++ usb0_id_det-gpios = <&pio 7 9 GPIO_ACTIVE_HIGH>; /* PH9 */ ++ usb0_vbus-supply = <®_drivevbus>; ++ usb1_vbus-supply = <®_usb1_vbus>; ++}; diff --git a/patch/kernel/sunxi-legacy/board-a64-v3-17-19-arm64-dts-allwinner-a64-NanoPi-A64-Add-Ethernet.patch b/patch/kernel/sunxi-legacy/board-a64-v3-17-19-arm64-dts-allwinner-a64-NanoPi-A64-Add-Ethernet.patch deleted file mode 100644 index a8513f10f..000000000 --- a/patch/kernel/sunxi-legacy/board-a64-v3-17-19-arm64-dts-allwinner-a64-NanoPi-A64-Add-Ethernet.patch +++ /dev/null @@ -1,42 +0,0 @@ -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts -index 5caba225b4f7..1eba1324e5b9 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts -@@ -51,6 +51,7 @@ - compatible = "friendlyarm,nanopi-a64", "allwinner,sun50i-a64"; - - aliases { -+ ethernet0 = &emac; - serial0 = &uart0; - }; - -@@ -67,6 +68,15 @@ - status = "okay"; - }; - -+&emac { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rgmii_pins>; -+ phy-mode = "rgmii"; -+ phy-handle = <&ext_rgmii_phy>; -+ phy-supply = <®_dcdc1>; -+ status = "okay"; -+}; -+ - /* i2c1 connected with gpio headers like pine64, bananapi */ - &i2c1 { - pinctrl-names = "default"; -@@ -78,6 +88,13 @@ - bias-pull-up; - }; - -+&mdio { -+ ext_rgmii_phy: ethernet-phy@1 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <7>; -+ }; -+}; -+ - &mmc0 { - pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins>; diff --git a/patch/kernel/sunxi-legacy/board-a83t-3-5-clk-sunxi-ng-r40-Add-max.-rate-constraint-to-video-PLLs.patch b/patch/kernel/sunxi-legacy/board-a83t-3-5-clk-sunxi-ng-r40-Add-max.-rate-constraint-to-video-PLLs.patch deleted file mode 100644 index 2612555b6..000000000 --- a/patch/kernel/sunxi-legacy/board-a83t-3-5-clk-sunxi-ng-r40-Add-max.-rate-constraint-to-video-PLLs.patch +++ /dev/null @@ -1,70 +0,0 @@ -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c -index 0f388f6944d5..582ebd41d20d 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c -@@ -65,19 +65,19 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", - BIT(28), /* lock */ - CLK_SET_RATE_UNGATE); - --/* TODO: The result of N/M is required to be in [8, 25] range. */ --static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video0_clk, "pll-video0", -- "osc24M", 0x0010, -- 192000000, /* Minimum rate */ -- 8, 7, /* N */ -- 0, 4, /* M */ -- BIT(24), /* frac enable */ -- BIT(25), /* frac select */ -- 270000000, /* frac rate 0 */ -- 297000000, /* frac rate 1 */ -- BIT(31), /* gate */ -- BIT(28), /* lock */ -- CLK_SET_RATE_UNGATE); -+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, "pll-video0", -+ "osc24M", 0x0010, -+ 192000000, /* Minimum rate */ -+ 1008000000, /* Maximum rate */ -+ 8, 7, /* N */ -+ 0, 4, /* M */ -+ BIT(24), /* frac enable */ -+ BIT(25), /* frac select */ -+ 270000000, /* frac rate 0 */ -+ 297000000, /* frac rate 1 */ -+ BIT(31), /* gate */ -+ BIT(28), /* lock */ -+ CLK_SET_RATE_UNGATE); - - /* TODO: The result of N/M is required to be in [8, 25] range. */ - static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", -@@ -152,19 +152,19 @@ static struct ccu_nk pll_periph1_clk = { - }, - }; - --/* TODO: The result of N/M is required to be in [8, 25] range. */ --static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video1_clk, "pll-video1", -- "osc24M", 0x030, -- 192000000, /* Minimum rate */ -- 8, 7, /* N */ -- 0, 4, /* M */ -- BIT(24), /* frac enable */ -- BIT(25), /* frac select */ -- 270000000, /* frac rate 0 */ -- 297000000, /* frac rate 1 */ -- BIT(31), /* gate */ -- BIT(28), /* lock */ -- CLK_SET_RATE_UNGATE); -+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video1_clk, "pll-video1", -+ "osc24M", 0x030, -+ 192000000, /* Minimum rate */ -+ 1008000000, /* Maximum rate */ -+ 8, 7, /* N */ -+ 0, 4, /* M */ -+ BIT(24), /* frac enable */ -+ BIT(25), /* frac select */ -+ 270000000, /* frac rate 0 */ -+ 297000000, /* frac rate 1 */ -+ BIT(31), /* gate */ -+ BIT(28), /* lock */ -+ CLK_SET_RATE_UNGATE); - - static struct ccu_nkm pll_sata_clk = { - .enable = BIT(31), diff --git a/patch/kernel/sunxi-legacy/board-a83t-4-5-clk-sunxi-ng-nkmp-Add-constraint-for-maximum-rate.patch b/patch/kernel/sunxi-legacy/board-a83t-4-5-clk-sunxi-ng-nkmp-Add-constraint-for-maximum-rate.patch deleted file mode 100644 index c7b429a33..000000000 --- a/patch/kernel/sunxi-legacy/board-a83t-4-5-clk-sunxi-ng-nkmp-Add-constraint-for-maximum-rate.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c -index ebd9436d2c7c..9b49adb20d07 100644 ---- a/drivers/clk/sunxi-ng/ccu_nkmp.c -+++ b/drivers/clk/sunxi-ng/ccu_nkmp.c -@@ -137,6 +137,13 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, - if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate *= nkmp->fixed_post_div; - -+ if (nkmp->max_rate && rate > nkmp->max_rate) { -+ rate = nkmp->max_rate; -+ if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) -+ rate /= nkmp->fixed_post_div; -+ return rate; -+ } -+ - _nkmp.min_n = nkmp->n.min ?: 1; - _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width; - _nkmp.min_k = nkmp->k.min ?: 1; -diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.h b/drivers/clk/sunxi-ng/ccu_nkmp.h -index 6940503e7fc4..a9f8c116a745 100644 ---- a/drivers/clk/sunxi-ng/ccu_nkmp.h -+++ b/drivers/clk/sunxi-ng/ccu_nkmp.h -@@ -35,6 +35,7 @@ struct ccu_nkmp { - struct ccu_div_internal p; - - unsigned int fixed_post_div; -+ unsigned int max_rate; - - struct ccu_common common; - }; diff --git a/patch/kernel/sunxi-legacy/board-a83t-5-5-clk-sunxi-ng-a83t-Add-max.-rate-constraint-to-video-PLLs.patch b/patch/kernel/sunxi-legacy/board-a83t-5-5-clk-sunxi-ng-a83t-Add-max.-rate-constraint-to-video-PLLs.patch deleted file mode 100644 index faf48a4ce..000000000 --- a/patch/kernel/sunxi-legacy/board-a83t-5-5-clk-sunxi-ng-a83t-Add-max.-rate-constraint-to-video-PLLs.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c -index 7d08015b980d..2d6555d73170 100644 ---- a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c -@@ -108,6 +108,7 @@ static struct ccu_nkmp pll_video0_clk = { - .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), - .m = _SUNXI_CCU_DIV(16, 1), /* input divider */ - .p = _SUNXI_CCU_DIV(0, 2), /* output divider */ -+ .max_rate = 3000000000UL, - .common = { - .reg = 0x010, - .lock_reg = CCU_SUN8I_A83T_LOCK_REG, -@@ -220,6 +221,7 @@ static struct ccu_nkmp pll_video1_clk = { - .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), - .m = _SUNXI_CCU_DIV(16, 1), /* input divider */ - .p = _SUNXI_CCU_DIV(0, 2), /* external divider p */ -+ .max_rate = 3000000000UL, - .common = { - .reg = 0x04c, - .lock_reg = CCU_SUN8I_A83T_LOCK_REG, diff --git a/patch/kernel/sunxi-legacy/board-a83t-add-one-more-freq-step-1.6ghz.patch b/patch/kernel/sunxi-legacy/board-a83t-add-one-more-freq-step-1.6ghz.patch deleted file mode 100644 index ecdfa866b..000000000 --- a/patch/kernel/sunxi-legacy/board-a83t-add-one-more-freq-step-1.6ghz.patch +++ /dev/null @@ -1,32 +0,0 @@ -diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi -index 0233008a8..c707fed8c 100644 ---- a/arch/arm/boot/dts/sun8i-a83t.dtsi -+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi -@@ -243,6 +243,13 @@ - opp-microvolt = <840000>; - clock-latency-ns = <244144>; /* 8 32k periods */ - }; -+ -+ opp-1608000000 { -+ opp-hz = /bits/ 64 <1608000000>; -+ opp-microvolt = <920000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ - }; - - cpu1_opp_table: opp_table1 { -@@ -296,6 +303,13 @@ - opp-microvolt = <840000>; - clock-latency-ns = <244144>; /* 8 32k periods */ - }; -+ -+ opp-1608000000 { -+ opp-hz = /bits/ 64 <1608000000>; -+ opp-microvolt = <920000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ - }; - - soc { diff --git a/patch/kernel/sunxi-legacy/board-a83t-v7-1-4-ARM-dts-sun8i-a83t-Add-the-cir-pin-for-the-A83T.patch b/patch/kernel/sunxi-legacy/board-a83t-v7-1-4-ARM-dts-sun8i-a83t-Add-the-cir-pin-for-the-A83T.patch deleted file mode 100644 index 3377ef7aa..000000000 --- a/patch/kernel/sunxi-legacy/board-a83t-v7-1-4-ARM-dts-sun8i-a83t-Add-the-cir-pin-for-the-A83T.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi -index 2be23d600957..afed6c0dea6f 100644 ---- a/arch/arm/boot/dts/sun8i-a83t.dtsi -+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi -@@ -1004,6 +1004,11 @@ - interrupt-controller; - #interrupt-cells = <3>; - -+ r_cir_pin: r-cir-pin { -+ pins = "PL12"; -+ function = "s_cir_rx"; -+ }; -+ - r_rsb_pins: r-rsb-pins { - pins = "PL0", "PL1"; - function = "s_rsb"; diff --git a/patch/kernel/sunxi-legacy/board-a83t-v7-2-4-ARM-dts-sun8i-a83t-Add-support-for-the-cir-interface.patch b/patch/kernel/sunxi-legacy/board-a83t-v7-2-4-ARM-dts-sun8i-a83t-Add-support-for-the-cir-interface.patch deleted file mode 100644 index b9109f192..000000000 --- a/patch/kernel/sunxi-legacy/board-a83t-v7-2-4-ARM-dts-sun8i-a83t-Add-support-for-the-cir-interface.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi -index afed6c0dea6f..798ab48c5479 100644 ---- a/arch/arm/boot/dts/sun8i-a83t.dtsi -+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi -@@ -992,6 +992,19 @@ - reg = <0x1f01c00 0x400>; - }; - -+ r_cir: ir@1f02000 { -+ compatible = "allwinner,sun8i-a83t-ir", -+ "allwinner,sun5i-a13-ir"; -+ clocks = <&r_ccu CLK_APB0_IR>, <&r_ccu CLK_IR>; -+ clock-names = "apb", "ir"; -+ resets = <&r_ccu RST_APB0_IR>; -+ interrupts = ; -+ reg = <0x01f02000 0x400>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&r_cir_pin>; -+ status = "disabled"; -+ }; -+ - r_pio: pinctrl@1f02c00 { - compatible = "allwinner,sun8i-a83t-r-pinctrl"; - reg = <0x01f02c00 0x400>; diff --git a/patch/kernel/sunxi-legacy/board-cubietruck-enable-uart2.patch b/patch/kernel/sunxi-legacy/board-cubietruck-enable-uart2.patch index 565fb6a07..5350a1e54 100644 --- a/patch/kernel/sunxi-legacy/board-cubietruck-enable-uart2.patch +++ b/patch/kernel/sunxi-legacy/board-cubietruck-enable-uart2.patch @@ -16,7 +16,7 @@ index 8da939a..42fd205 100644 +&uart2 { + pinctrl-names = "default"; -+ pinctrl-0 = <&uart2_pins_a>; ++ pinctrl-0 = <&uart2_cts_rts_pi_pins>, <&uart2_pi_pins>; + status = "okay"; +}; + diff --git a/patch/kernel/sunxi-legacy/board-cubietruckplus-enable-hdmi.patch b/patch/kernel/sunxi-legacy/board-cubietruckplus-enable-hdmi.patch deleted file mode 100644 index 058dc5940..000000000 --- a/patch/kernel/sunxi-legacy/board-cubietruckplus-enable-hdmi.patch +++ /dev/null @@ -1,50 +0,0 @@ -diff --git a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts -index 88decb07..e3292916 100644 ---- a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts -+++ b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts -@@ -60,6 +60,17 @@ - stdout-path = "serial0:115200n8"; - }; - -+ connector { -+ compatible = "hdmi-connector"; -+ type = "a"; -+ -+ port { -+ hdmi_con_in: endpoint { -+ remote-endpoint = <&hdmi_out_con>; -+ }; -+ }; -+ }; -+ - leds { - compatible = "gpio-leds"; - -@@ -145,6 +155,10 @@ - }; - }; - -+&de { -+ status = "okay"; -+}; -+ - &ehci0 { - /* GL830 USB-to-SATA bridge here */ - status = "okay"; -@@ -164,6 +178,16 @@ - status = "okay"; - }; - -+&hdmi { -+ status = "okay"; -+}; -+ -+&hdmi_out { -+ hdmi_out_con: endpoint { -+ remote-endpoint = <&hdmi_con_in>; -+ }; -+}; -+ - &mdio { - rgmii_phy: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; diff --git a/patch/kernel/sunxi-current/board-cubietruckplus-enable-hdmi.patch-disabled b/patch/kernel/sunxi-legacy/board-cubietruckplus-enable-hdmi.patch-disabled similarity index 100% rename from patch/kernel/sunxi-current/board-cubietruckplus-enable-hdmi.patch-disabled rename to patch/kernel/sunxi-legacy/board-cubietruckplus-enable-hdmi.patch-disabled diff --git a/patch/kernel/sunxi-legacy/board-h2plus-sunvell-r69-add-device.patch b/patch/kernel/sunxi-legacy/board-h2plus-sunvell-r69-add-device.patch index d0ccdc7fe..bcb87accd 100644 --- a/patch/kernel/sunxi-legacy/board-h2plus-sunvell-r69-add-device.patch +++ b/patch/kernel/sunxi-legacy/board-h2plus-sunvell-r69-add-device.patch @@ -12,7 +12,7 @@ index f47ce87..9f4bc9e 100644 sun8i-h3-beelink-x2.dtb \ diff --git a/arch/arm/boot/dts/sun8i-h2-plus-sunvell-r69.dts b/arch/arm/boot/dts/sun8i-h2-plus-sunvell-r69.dts new file mode 100644 -index 0000000..ef7cb09 +index 0000000..bb0c2f7 --- /dev/null +++ b/arch/arm/boot/dts/sun8i-h2-plus-sunvell-r69.dts @@ -0,0 +1,225 @@ @@ -140,7 +140,7 @@ index 0000000..ef7cb09 + +&ir { + pinctrl-names = "default"; -+ pinctrl-0 = <&ir_pins_a>; ++ pinctrl-0 = <&r_ir_rx_pin>; /* <&r_ir_rx_pin> */ + status = "okay"; +}; + @@ -211,7 +211,7 @@ index 0000000..ef7cb09 + +&uart0 { + pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins_a>; ++ pinctrl-0 = <&uart0_pa_pins>; + status = "okay"; +}; + @@ -234,7 +234,7 @@ index 0000000..ef7cb09 +}; + +&usb_otg { -+ dr_mode = "otg"; ++ dr_mode = "host"; + status = "okay"; +}; + diff --git a/patch/kernel/sunxi-legacy/board-h3-add-rtc-osc32k-out.patch b/patch/kernel/sunxi-legacy/board-h3-add-rtc-osc32k-out.patch deleted file mode 100644 index f9d2cc8b9..000000000 --- a/patch/kernel/sunxi-legacy/board-h3-add-rtc-osc32k-out.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -index c3bff11..48b8447 100644 ---- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi -+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -@@ -96,6 +112,13 @@ - clock-output-names = "osc32k"; - }; - -+ ext_osc32k: ext_osc32k_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+ clock-output-names = "ext_osc32k"; -+ }; -+ - iosc: internal-osc-clk { - #clock-cells = <0>; - compatible = "fixed-clock"; -@@ -795,6 +861,9 @@ - reg = <0x01f00000 0x54>; - interrupts = , - ; -+ clock-output-names = "rtc-osc32k", "rtc-osc32k-out"; -+ clocks = <&ext_osc32k>; -+ #clock-cells = <1>; - }; - - r_ccu: clock@1f01400 { diff --git a/patch/kernel/sunxi-legacy/board-h5-add-0000-nanopi-k1plus.patch b/patch/kernel/sunxi-legacy/board-h5-add-0000-nanopi-k1plus.patch index c44343c2e..775d8dbf8 100644 --- a/patch/kernel/sunxi-legacy/board-h5-add-0000-nanopi-k1plus.patch +++ b/patch/kernel/sunxi-legacy/board-h5-add-0000-nanopi-k1plus.patch @@ -229,7 +229,7 @@ index 000000000000..52337a18721f + +&ir { + pinctrl-names = "default"; -+ pinctrl-0 = <&ir_pins_a>; ++ pinctrl-0 = <&r_ir_rx_pin>; + status = "okay"; +}; + @@ -357,7 +357,7 @@ index 000000000000..52337a18721f + +&uart0 { + pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins_a>; ++ pinctrl-0 = <&uart0_pa_pins>; + status = "okay"; +}; + diff --git a/patch/kernel/sunxi-legacy/board-h5-add-0001-nanopi-neo-core2.patch b/patch/kernel/sunxi-legacy/board-h5-add-0001-nanopi-neo-core2.patch index 037f9ac60..e21bccea9 100644 --- a/patch/kernel/sunxi-legacy/board-h5-add-0001-nanopi-neo-core2.patch +++ b/patch/kernel/sunxi-legacy/board-h5-add-0001-nanopi-neo-core2.patch @@ -213,12 +213,12 @@ index 000000000..b3035ddd7 + +&uart0 { + pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins_a>; ++ pinctrl-0 = <&uart0_pa_pins>; + status = "okay"; +}; + +&usb_otg { -+ dr_mode = "host"; ++ dr_mode = "otg"; + status = "okay"; +}; + diff --git a/patch/kernel/sunxi-legacy/board-h5-add-0002-nanopi-neo2-v1.1.patch b/patch/kernel/sunxi-legacy/board-h5-add-0002-nanopi-neo2-v1.1.patch index 1637217aa..abbe93eba 100644 --- a/patch/kernel/sunxi-legacy/board-h5-add-0002-nanopi-neo2-v1.1.patch +++ b/patch/kernel/sunxi-legacy/board-h5-add-0002-nanopi-neo2-v1.1.patch @@ -181,7 +181,7 @@ index 00000000..cab3c73b + +&uart0 { + pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins_a>; ++ pinctrl-0 = <&uart0_pa_pins>; + status = "okay"; +}; + diff --git a/patch/kernel/sunxi-legacy/board-h5-add-0003-nanopi-m1-plus2.patch b/patch/kernel/sunxi-legacy/board-h5-add-0003-nanopi-m1-plus2.patch index 769e8cfc6..9da4d1192 100644 --- a/patch/kernel/sunxi-legacy/board-h5-add-0003-nanopi-m1-plus2.patch +++ b/patch/kernel/sunxi-legacy/board-h5-add-0003-nanopi-m1-plus2.patch @@ -245,7 +245,7 @@ index 0000000..a6bf32d + +&uart0 { + pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins_a>; ++ pinctrl-0 = <&uart0_pa_pins>; + status = "okay"; +}; + diff --git a/patch/kernel/sunxi-legacy/board-h5-orangepi-pc2-add-spi-flash.patch b/patch/kernel/sunxi-legacy/board-h5-orangepi-pc2-add-spi-flash.patch index 003f3825d..df266068c 100644 --- a/patch/kernel/sunxi-legacy/board-h5-orangepi-pc2-add-spi-flash.patch +++ b/patch/kernel/sunxi-legacy/board-h5-orangepi-pc2-add-spi-flash.patch @@ -33,4 +33,4 @@ index 2582b113..93af1282 100644 + &uart0 { pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; + pinctrl-0 = <&uart0_pa_pins>; diff --git a/patch/kernel/sunxi-legacy/board-h6-add-orangepi-one-plus-and-lite2.patch b/patch/kernel/sunxi-legacy/board-h6-add-orangepi-one-plus-and-lite2.patch_broken_below_5.1 similarity index 94% rename from patch/kernel/sunxi-legacy/board-h6-add-orangepi-one-plus-and-lite2.patch rename to patch/kernel/sunxi-legacy/board-h6-add-orangepi-one-plus-and-lite2.patch_broken_below_5.1 index a6f272bad..92c86afcd 100644 --- a/patch/kernel/sunxi-legacy/board-h6-add-orangepi-one-plus-and-lite2.patch +++ b/patch/kernel/sunxi-legacy/board-h6-add-orangepi-one-plus-and-lite2.patch_broken_below_5.1 @@ -14,7 +14,7 @@ new file mode 100644 index 000000000..385015396 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts -@@ -0,0 +1,254 @@ +@@ -0,0 +1,280 @@ +// SPDX-License-Identifier: (GPL-2.0+ or MIT) +/* + * Copyright (c) 2018 Armbian @@ -32,12 +32,24 @@ index 000000000..385015396 + + aliases { + serial0 = &uart0; ++ ethernet0 = &emac; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + ++ connector { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ + leds { + compatible = "gpio-leds"; + @@ -117,6 +129,20 @@ index 000000000..385015396 + status = "okay"; +}; + ++&de { ++ status = "okay"; ++}; ++ ++&hdmi { ++ status = "okay"; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ +&mdio { + ext_rgmii_phy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; @@ -286,7 +312,7 @@ new file mode 100644 index 000000000..b9aff606e --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts -@@ -0,0 +1,275 @@ +@@ -0,0 +1,300 @@ +// SPDX-License-Identifier: (GPL-2.0+ or MIT) +/* + * Copyright (c) 2017 Icenowy Zheng @@ -300,7 +326,7 @@ index 000000000..b9aff606e + +/ { + model = "Orange Pi Lite 2"; -+ compatible = "pine64,pine-h64", "allwinner,sun50i-h6"; ++ compatible = "xunlong,orangepi-lite2", "allwinner,sun50i-h6"; + + aliases { + serial0 = &uart0; @@ -310,6 +336,17 @@ index 000000000..b9aff606e + stdout-path = "serial0:115200n8"; + }; + ++ connector { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ + leds { + compatible = "gpio-leds"; + @@ -366,6 +403,20 @@ index 000000000..b9aff606e + status = "okay"; +}; + ++&de { ++ status = "okay"; ++}; ++ ++&hdmi { ++ status = "okay"; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ +&ehci0 { + status = "okay"; +}; diff --git a/patch/kernel/sunxi-legacy/board-h6-add-rtc-osc32k-out.patch b/patch/kernel/sunxi-legacy/board-h6-add-rtc-osc32k-out.patch deleted file mode 100644 index 303a609a5..000000000 --- a/patch/kernel/sunxi-legacy/board-h6-add-rtc-osc32k-out.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -index bec8c4a..73ed36d 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -@@ -124,6 +124,13 @@ - clock-output-names = "osc32k"; - }; - -+ ext_osc32k: ext_osc32k_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+ clock-output-names = "ext_osc32k"; -+ }; -+ - psci { - compatible = "arm,psci-0.2"; - method = "smc"; -@@ -511,6 +526,16 @@ - #reset-cells = <1>; - }; - -+ rtc: rtc@7000000 { -+ compatible = "allwinner,sun6i-a31-rtc"; -+ reg = <0x07000000 0x54>; -+ interrupts = , -+ ; -+ clock-output-names = "rtc-osc32k", "rtc-osc32k-out"; -+ clocks = <&ext_osc32k>; -+ #clock-cells = <1>; -+ }; -+ - r_intc: interrupt-controller@7021000 { - compatible = "allwinner,sun50i-h6-r-intc", - "allwinner,sun6i-a31-r-intc"; diff --git a/patch/kernel/sunxi-legacy/board-h6-clock-higher.patch b/patch/kernel/sunxi-legacy/board-h6-clock-higher.patch deleted file mode 100644 index ece151eea..000000000 --- a/patch/kernel/sunxi-legacy/board-h6-clock-higher.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -index bec8c4a4..f0566d2b 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -@@ -59,6 +59,12 @@ - opp-microvolt = <1060000>; - clock-latency-ns = <244144>; /* 8 32k periods */ - }; -+ -+ opp-1800000000 { -+ opp-hz = /bits/ 64 <1800000000>; -+ opp-microvolt = <1160000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; - }; - - cpus { diff --git a/patch/kernel/sunxi-legacy/board-h6-orangepi-lite2-fix-missing-all.patch b/patch/kernel/sunxi-legacy/board-h6-orangepi-lite2-fix-missing-all.patch new file mode 100644 index 000000000..18a3b1048 --- /dev/null +++ b/patch/kernel/sunxi-legacy/board-h6-orangepi-lite2-fix-missing-all.patch @@ -0,0 +1,350 @@ +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts +index e098a2475..6c481b547 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts +@@ -3,9 +3,344 @@ + * Copyright (C) 2018 Jagan Teki + */ + +-#include "sun50i-h6-orangepi.dtsi" ++/dts-v1/; ++ ++#include "sun50i-h6.dtsi" ++ ++#include + + / { + model = "OrangePi Lite2"; + compatible = "xunlong,orangepi-lite2", "allwinner,sun50i-h6"; ++ ++ aliases { ++ serial0 = &uart0; /* debug */ ++ serial1 = &uart1; /* BT-UART */ ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ connector { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ddc-supply = <®_ddc>; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ power { ++ label = "orangepi:red:power"; ++ gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */ ++ default-state = "on"; ++ }; ++ ++ status { ++ label = "orangepi:green:status"; ++ gpios = <&r_pio 0 7 GPIO_ACTIVE_HIGH>; /* PL7 */ ++ }; ++ }; ++ ++ reg_ddc: ddc-io { ++ compatible = "regulator-fixed"; ++ regulator-name = "ddc-io"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ enable-active-high; ++ gpio = <&pio 7 2 GPIO_ACTIVE_HIGH>; /* PH2 */ ++ }; ++ ++ reg_vcc5v: vcc5v { ++ /* board wide 5V supply directly from the DC jack */ ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc-5v"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-always-on; ++ }; ++ ++ reg_usb_vbus: vbus { ++ compatible = "regulator-fixed"; ++ regulator-name = "usb-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <100000>; ++ gpio = <&r_pio 0 5 GPIO_ACTIVE_HIGH>; /* PL5 USB0-DRVVBUS */ ++ enable-active-high; ++ }; ++ ++ wifi_pwrseq: wifi_pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&rtc 1>; ++ clock-names = "ext_clock"; ++ reset-gpios = <&r_pio 1 3 GPIO_ACTIVE_LOW>; /* PM3 */ ++ post-power-on-delay-ms = <200>; ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <®_dcdca>; ++}; ++ ++&de { ++ status = "okay"; ++}; ++ ++&hdmi { ++ status = "okay"; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ ++&mmc0 { ++ vmmc-supply = <®_cldo1>; ++ cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&mmc1 { ++ vmmc-supply = <®_cldo2>; ++ vqmmc-supply = <®_bldo3>; ++ mmc-pwrseq = <&wifi_pwrseq>; ++ bus-width = <4>; ++ non-removable; ++ status = "okay"; ++ ++ brcm: sdio-wifi@1 { ++ reg = <1>; ++ compatible = "brcm,bcm4329-fmac"; ++ interrupt-parent = <&r_pio>; ++ interrupts = <1 0 IRQ_TYPE_LEVEL_LOW>; /* PM0 */ ++ interrupt-names = "host-wake"; ++ }; ++}; ++ ++&pio { ++ vcc-pc-supply = <®_bldo2>; ++ vcc-pd-supply = <®_cldo1>; ++ vcc-pg-supply = <®_bldo3>; ++}; ++ ++&r_i2c { ++ status = "okay"; ++ ++ axp805: pmic@36 { ++ compatible = "x-powers,axp805", "x-powers,axp806"; ++ reg = <0x36>; ++ interrupt-parent = <&r_intc>; ++ interrupts = <0 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-controller; ++ #interrupt-cells = <1>; ++ x-powers,self-working-mode; ++ vina-supply = <®_vcc5v>; ++ vinb-supply = <®_vcc5v>; ++ vinc-supply = <®_vcc5v>; ++ vind-supply = <®_vcc5v>; ++ vine-supply = <®_vcc5v>; ++ aldoin-supply = <®_vcc5v>; ++ bldoin-supply = <®_vcc5v>; ++ cldoin-supply = <®_vcc5v>; ++ ++ regulators { ++ reg_aldo1: aldo1 { ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc-pl-led-ir"; ++ }; ++ ++ reg_aldo2: aldo2 { ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc33-audio-tv-ephy-mac"; ++ }; ++ ++ /* ALDO3 is shorted to CLDO1 */ ++ reg_aldo3: aldo3 { ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc33-io-pd-emmc-sd-usb-uart-1"; ++ }; ++ ++ reg_bldo1: bldo1 { ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc18-dram-bias-pll"; ++ }; ++ ++ reg_bldo2: bldo2 { ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc-efuse-pcie-hdmi-pc"; ++ }; ++ ++ reg_bldo3: bldo3 { ++ regulator-always-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-name = "vcc-dcxoio"; ++ }; ++ ++ bldo4 { ++ /* unused */ ++ }; ++ ++ reg_cldo1: cldo1 { ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc33-io-pd-emmc-sd-usb-uart-2"; ++ }; ++ ++ reg_cldo2: cldo2 { ++ /* ++ * This regulator is connected with CLDO3. ++ * Before the kernel can support synchronized ++ * enable of coupled regulators, keep them ++ * both always on as a ugly hack. ++ */ ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc-wifi-1"; ++ }; ++ ++ reg_cldo3: cldo3 { ++ /* ++ * This regulator is connected with CLDO2. ++ * See the comments for CLDO2. ++ */ ++ regulator-always-on; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-name = "vcc-wifi-2"; ++ }; ++ ++ reg_dcdca: dcdca { ++ regulator-always-on; ++ regulator-min-microvolt = <800000>; ++ regulator-max-microvolt = <1160000>; ++ regulator-name = "vdd-cpu"; ++ }; ++ ++ reg_dcdcc: dcdcc { ++ regulator-min-microvolt = <810000>; ++ regulator-max-microvolt = <1080000>; ++ regulator-name = "vdd-gpu"; ++ }; ++ ++ reg_dcdcd: dcdcd { ++ regulator-always-on; ++ regulator-min-microvolt = <960000>; ++ regulator-max-microvolt = <960000>; ++ regulator-name = "vdd-sys"; ++ }; ++ ++ reg_dcdce: dcdce { ++ regulator-always-on; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <1200000>; ++ regulator-name = "vcc-dram"; ++ }; ++ ++ sw { ++ /* unused */ ++ }; ++ }; ++ }; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins>; ++ status = "disabled"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_ph_pins>; ++ status = "okay"; ++}; ++ ++/* There's the BT part of the AP6255 connected to that UART */ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; ++ uart-has-rtscts; ++ status = "okay"; ++ ++ bluetooth { ++ compatible = "brcm,bcm4345c5"; ++ clocks = <&rtc 1>; ++ clock-names = "lpo"; ++ device-wakeup-gpios = <&r_pio 1 2 GPIO_ACTIVE_HIGH>; /* PM2 */ ++ host-wakeup-gpios = <&r_pio 1 1 GPIO_ACTIVE_HIGH>; /* PM1 */ ++ shutdown-gpios = <&r_pio 1 4 GPIO_ACTIVE_HIGH>; /* PM4 */ ++ max-speed = <1500000>; ++ }; ++}; ++ ++&uart3 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart3_pins>, <&uart3_rts_cts_pins>; ++ uart-has-rtscts; ++ status = "disabled"; ++}; ++ ++&usb2otg { ++ /* ++ * This board doesn't have a controllable VBUS even though it ++ * does have an ID pin. Using it as anything but a USB host is ++ * unsafe. ++ */ ++ dr_mode = "host"; ++ status = "okay"; ++}; ++ ++&usb2phy { ++ usb0_id_det-gpios = <&pio 2 6 GPIO_ACTIVE_HIGH>; /* PC6 */ ++ usb0_vbus-supply = <®_vcc5v>; ++ usb3_vbus-supply = <®_vcc5v>; ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&ehci3 { ++ status = "okay"; ++}; ++ ++&ohci3 { ++ status = "okay"; ++}; ++ ++&usb3phy { ++ phy-supply = <®_usb_vbus>; ++ status = "okay"; ++}; ++ ++&dwc3 { ++ status = "okay"; + }; diff --git a/patch/kernel/sunxi-current/board-h6-orangepioneplus-fix-missing-ethernet.patch b/patch/kernel/sunxi-legacy/board-h6-orangepioneplus-fix-missing-ethernet.patch similarity index 100% rename from patch/kernel/sunxi-current/board-h6-orangepioneplus-fix-missing-ethernet.patch rename to patch/kernel/sunxi-legacy/board-h6-orangepioneplus-fix-missing-ethernet.patch diff --git a/patch/kernel/sunxi-legacy/board-nanopi-adjust-defaults.patch b/patch/kernel/sunxi-legacy/board-nanopi-adjust-defaults.patch deleted file mode 100644 index 19797a5a3..000000000 --- a/patch/kernel/sunxi-legacy/board-nanopi-adjust-defaults.patch +++ /dev/null @@ -1,91 +0,0 @@ -diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi b/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi -index f110ee382..c25c08bae 100644 ---- a/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi -+++ b/arch/arm/boot/dts/sun8i-h3-nanopi.dtsi -@@ -51,6 +51,10 @@ - / { - aliases { - serial0 = &uart0; -+ serial1 = &uart1; -+ serial2 = &uart2; -+ serial3 = &uart3; -+ ethernet0 = &emac; - }; - - chosen { -@@ -89,10 +93,38 @@ - }; - }; - -+&ehci0 { -+ status = "okay"; -+}; -+ -+&ohci0 { -+ status = "okay"; -+}; -+ -+&ehci1 { -+ status = "okay"; -+}; -+ -+&ohci1 { -+ status = "okay"; -+}; -+ -+&ehci2 { -+ status = "okay"; -+}; -+ -+&ohci2 { -+ status = "okay"; -+}; -+ - &ehci3 { - status = "okay"; - }; - -+&ohci3 { -+ status = "okay"; -+}; -+ - &mmc0 { - bus-width = <4>; - cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; -@@ -100,10 +132,6 @@ - vmmc-supply = <®_vcc3v3>; - }; - --&ohci3 { -- status = "okay"; --}; -- - &pio { - leds_npi: led_pins { - pins = "PA10"; -@@ -129,6 +157,25 @@ - status = "okay"; - }; - -+&uart3 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart3_pins>, <&uart3_rts_cts_pins>; -+ status = "disabled"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+}; -+ -+&usb_otg { -+ // OTG is not stable. -+ // most nanopi-h3's MicroUSB support OTG, except: -+ // 1. nanopi-neo-V1.4 support OTG, nanopi-neo-V1.3/1.2... support USB device. -+ // 2. nanopi-k1 only use as power. -+ dr_mode = "otg"; -+ status = "okay"; -+}; -+ - &usbphy { - status = "okay"; - }; diff --git a/patch/kernel/sunxi-legacy/board-nanopiair-h3-camera-wifi-bluetooth-otg.patch b/patch/kernel/sunxi-legacy/board-nanopiair-h3-camera-wifi-bluetooth-otg.patch index 869e22b84..f19a6faac 100644 --- a/patch/kernel/sunxi-legacy/board-nanopiair-h3-camera-wifi-bluetooth-otg.patch +++ b/patch/kernel/sunxi-legacy/board-nanopiair-h3-camera-wifi-bluetooth-otg.patch @@ -155,7 +155,7 @@ index 6246d3ef..a2b6e0b2 100644 + &uart0 { pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; + pinctrl-0 = <&uart0_pa_pins>; status = "okay"; }; diff --git a/patch/kernel/sunxi-legacy/board-olinuxino-A64-add-eMMC.patch b/patch/kernel/sunxi-legacy/board-olinuxino-A64-add-eMMC.patch new file mode 100644 index 000000000..2f3e58a31 --- /dev/null +++ b/patch/kernel/sunxi-legacy/board-olinuxino-A64-add-eMMC.patch @@ -0,0 +1,35 @@ +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts +index 3b3081b..24cde3d 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts +@@ -81,6 +81,13 @@ + status = "okay"; + }; + ++ reg_vcc3v3: vcc3v3 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc3v3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ }; ++ + wifi_pwrseq: wifi_pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */ +@@ -92,6 +99,16 @@ + }; + }; + ++&mmc2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc2_pins>; ++ vmmc-supply = <®_vcc3v3>; ++ bus-width = <8>; ++ non-removable; ++ cap-mmc-hw-reset; ++ status = "okay"; ++}; ++ + &r_rsb { + status = "okay"; + diff --git a/patch/kernel/sunxi-current/board-orangepi3-add-missing-HDMI.patch b/patch/kernel/sunxi-legacy/board-orangepi3-add-missing-HDMI.patch similarity index 100% rename from patch/kernel/sunxi-current/board-orangepi3-add-missing-HDMI.patch rename to patch/kernel/sunxi-legacy/board-orangepi3-add-missing-HDMI.patch diff --git a/patch/kernel/sunxi-legacy/board-orangepi3-add-missing-eMMC.patch b/patch/kernel/sunxi-legacy/board-orangepi3-add-missing-eMMC.patch new file mode 100644 index 000000000..16c4ed8f7 --- /dev/null +++ b/patch/kernel/sunxi-legacy/board-orangepi3-add-missing-eMMC.patch @@ -0,0 +1,22 @@ +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +index c0150b7..ed0b76d 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +@@ -196,6 +196,17 @@ + }; + }; + ++&mmc2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc2_pins>; ++ vmmc-supply = <®_cldo1>; ++ vqmmc-supply = <®_bldo2>; ++ bus-width = <8>; ++ non-removable; ++ cap-mmc-hw-reset; ++ status = "okay"; ++}; ++ + &ohci0 { + status = "okay"; + }; diff --git a/patch/kernel/sunxi-legacy/board-orangepi3-delete-spi0.patch b/patch/kernel/sunxi-legacy/board-orangepi3-delete-spi0.patch new file mode 100644 index 000000000..52c744916 --- /dev/null +++ b/patch/kernel/sunxi-legacy/board-orangepi3-delete-spi0.patch @@ -0,0 +1,13 @@ +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +index c0150b7..06f4161 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts +@@ -275,6 +326,8 @@ + }; + }; + ++/delete-node/ &spi0; ++ + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_ph_pins>; diff --git a/patch/kernel/sunxi-legacy/board-pine-h6-add-RTL8723.patch b/patch/kernel/sunxi-legacy/board-pine-h6-add-RTL8723.patch new file mode 100644 index 000000000..cf264d74b --- /dev/null +++ b/patch/kernel/sunxi-legacy/board-pine-h6-add-RTL8723.patch @@ -0,0 +1,69 @@ +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts-old b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts +index 52a1574..326195b 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts-old ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts +@@ -75,6 +75,14 @@ + enable-active-high; + }; + ++ wifi_pwrseq: wifi_pwrseq { ++ compatible = "mmc-pwrseq-simple"; ++ clocks = <&rtc 1>; ++ clock-names = "ext_clock"; ++ reset-gpios = <&r_pio 1 3 GPIO_ACTIVE_LOW>; /* PM3 */ ++ post-power-on-delay-ms = <200>; ++ }; ++ + leds { + compatible = "gpio-leds"; + +@@ -160,6 +168,24 @@ + status = "okay"; + }; + ++&mmc1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc1_pins>; ++ vmmc-supply = <®_cldo2>; ++ vqmmc-supply = <®_bldo2>; ++ mmc-pwrseq = <&wifi_pwrseq>; ++ bus-width = <4>; ++ non-removable; ++ status = "okay"; ++ ++ rtl8723cs: sdio_wifi@1 { ++ reg = <1>; ++ interrupt-parent = <&r_pio>; ++ interrupts = <1 0 IRQ_TYPE_LEVEL_LOW>; /* PM0 */ ++ interrupt-names = "host-wake"; ++ }; ++}; ++ + &mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_pins>; +@@ -263,12 +263,24 @@ + }; + + reg_cldo2: cldo2 { ++ /* ++ * This regulator is connected with CLDO3. ++ * Before the kernel can support synchronized ++ * enable of coupled regulators, keep them ++ * both always on as a ugly hack. ++ */ ++ regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi-1"; + }; + + reg_cldo3: cldo3 { ++ /* ++ * This regulator is connected with CLDO2. ++ * See the comments for CLDO2. ++ */ ++ regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi-2"; diff --git a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0008-arm64-allwinner-h6-add-missing-mmc-pins.patch b/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0008-arm64-allwinner-h6-add-missing-mmc-pins.patch deleted file mode 100644 index be7c9ff38..000000000 --- a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0008-arm64-allwinner-h6-add-missing-mmc-pins.patch +++ /dev/null @@ -1,19 +0,0 @@ -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -index fd6681ab9..89e0837d7 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -@@ -216,6 +216,14 @@ - bias-pull-up; - }; - -+ mmc1_pins: mmc1-pins { -+ pins = "PG0", "PG1", "PG2", "PG3", -+ "PG4", "PG5"; -+ function = "mmc1"; -+ drive-strength = <30>; -+ bias-pull-up; -+ }; -+ - mmc2_pins: mmc2-pins { - pins = "PC1", "PC4", "PC5", "PC6", - "PC7", "PC8", "PC9", "PC10", diff --git a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0018-arm64-allwinner-h6-enable-AXP805-PMIC-on-Pine-H64.patch b/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0018-arm64-allwinner-h6-enable-AXP805-PMIC-on-Pine-H64.patch index d18f6493e..4001a115d 100644 --- a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0018-arm64-allwinner-h6-enable-AXP805-PMIC-on-Pine-H64.patch +++ b/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0018-arm64-allwinner-h6-enable-AXP805-PMIC-on-Pine-H64.patch @@ -103,7 +103,7 @@ index 3e31f39..9177224 100644 + reg_dcdca: dcdca { + regulator-always-on; + regulator-min-microvolt = <810000>; -+ regulator-max-microvolt = <1080000>; ++ regulator-max-microvolt = <1160000>; + regulator-name = "vdd-cpu"; + }; + diff --git a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0020-phy-allwinner-add-phy-driver-for-USB3-PHY-on-Allwinn.patch b/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0020-phy-allwinner-add-phy-driver-for-USB3-PHY-on-Allwinn.patch deleted file mode 100644 index 70513ae8b..000000000 --- a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0020-phy-allwinner-add-phy-driver-for-USB3-PHY-on-Allwinn.patch +++ /dev/null @@ -1,287 +0,0 @@ -From e6f5b5df3b4cbba6e3a23695fe0f5f007f355978 Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Mon, 25 Dec 2017 12:04:02 +0800 -Subject: [PATCH 20/35] phy: allwinner: add phy driver for USB3 PHY on - Allwinner H6 SoC - -Allwinner H6 SoC contains a USB3 PHY (with USB2 DP/DM lines also -controlled). - -Add a driver for it. - -The register operations in this driver is mainly extracted from the BSP -USB3 driver. - -Signed-off-by: Icenowy Zheng ---- - .../devicetree/bindings/phy/sun50i-usb3-phy.txt | 24 +++ - drivers/phy/allwinner/Kconfig | 13 ++ - drivers/phy/allwinner/Makefile | 1 + - drivers/phy/allwinner/phy-sun50i-usb3.c | 195 +++++++++++++++++++++ - 4 files changed, 233 insertions(+) - create mode 100644 Documentation/devicetree/bindings/phy/sun50i-usb3-phy.txt - create mode 100644 drivers/phy/allwinner/phy-sun50i-usb3.c - -diff --git a/Documentation/devicetree/bindings/phy/sun50i-usb3-phy.txt b/Documentation/devicetree/bindings/phy/sun50i-usb3-phy.txt -new file mode 100644 -index 0000000..912d55f ---- /dev/null -+++ b/Documentation/devicetree/bindings/phy/sun50i-usb3-phy.txt -@@ -0,0 +1,24 @@ -+Allwinner sun50i USB3 PHY -+----------------------- -+ -+Required properties: -+- compatible : should be one of -+ * allwinner,sun60i-h6-usb3-phy -+- reg : a list of offset + length pairs -+- #phy-cells : from the generic phy bindings, must be 0 -+- clocks : phandle + clock specifier for the phy clock -+- resets : phandle + reset specifier for the phy reset -+ -+Optional Properties: -+- phy-supply : from the generic phy bindings, a phandle to a regulator that -+ provides power to VBUS. -+ -+Example: -+ usb3phy: phy@5210000 { -+ compatible = "allwinner,sun50i-h6-usb3-phy"; -+ reg = <0x5210000 0x10000>; -+ clocks = <&ccu CLK_USB_PHY1>; -+ resets = <&ccu RST_USB_PHY1>; -+ #phy-cells = <0>; -+ status = "disabled"; -+ }; -diff --git a/drivers/phy/allwinner/Kconfig b/drivers/phy/allwinner/Kconfig -index cdc1e74..cf373bc 100644 ---- a/drivers/phy/allwinner/Kconfig -+++ b/drivers/phy/allwinner/Kconfig -@@ -29,3 +29,16 @@ config PHY_SUN9I_USB - sun9i SoCs. - - This driver controls each individual USB 2 host PHY. -+ -+config PHY_SUN50I_USB3 -+ tristate "Allwinner sun50i SoC USB3 PHY driver" -+ depends on ARCH_SUNXI && HAS_IOMEM && OF -+ depends on RESET_CONTROLLER -+ depends on USB_SUPPORT -+ select USB_COMMON -+ select GENERIC_PHY -+ help -+ Enable this to support the USB3.0-capable transceiver that is -+ part of some Allwinner sun50i SoCs. -+ -+ This driver controls each individual USB 2+3 host PHY combo. -diff --git a/drivers/phy/allwinner/Makefile b/drivers/phy/allwinner/Makefile -index 8605529c..a8d01e9 100644 ---- a/drivers/phy/allwinner/Makefile -+++ b/drivers/phy/allwinner/Makefile -@@ -1,2 +1,3 @@ - obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o - obj-$(CONFIG_PHY_SUN9I_USB) += phy-sun9i-usb.o -+obj-$(CONFIG_PHY_SUN50I_USB3) += phy-sun50i-usb3.o -diff --git a/drivers/phy/allwinner/phy-sun50i-usb3.c b/drivers/phy/allwinner/phy-sun50i-usb3.c -new file mode 100644 -index 0000000..000a3e0 ---- /dev/null -+++ b/drivers/phy/allwinner/phy-sun50i-usb3.c -@@ -0,0 +1,195 @@ -+/* -+ * Allwinner sun50i(H6) USB 3.0 phy driver -+ * -+ * Copyright (C) 2017 Icenowy Zheng -+ * -+ * Based on phy-sun9i-usb.c, which is: -+ * -+ * Copyright (C) 2014-2015 Chen-Yu Tsai -+ * -+ * Based on code from Allwinner BSP, which is: -+ * -+ * Copyright (c) 2010-2015 Allwinner Technology Co., Ltd. -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Interface Status and Control Registers */ -+#define SUNXI_ISCR 0x00 -+#define SUNXI_PIPE_CLOCK_CONTROL 0x14 -+#define SUNXI_PHY_TUNE_LOW 0x18 -+#define SUNXI_PHY_TUNE_HIGH 0x1c -+#define SUNXI_PHY_EXTERNAL_CONTROL 0x20 -+ -+/* USB2.0 Interface Status and Control Register */ -+#define SUNXI_ISCR_FORCE_VBUS (3 << 12) -+ -+/* PIPE Clock Control Register */ -+#define SUNXI_PCC_PIPE_CLK_OPEN (1 << 6) -+ -+/* PHY External Control Register */ -+#define SUNXI_PEC_EXTERN_VBUS (3 << 1) -+#define SUNXI_PEC_SSC_EN (1 << 24) -+#define SUNXI_PEC_REF_SSP_EN (1 << 26) -+ -+/* PHY Tune High Register */ -+#define SUNXI_TX_DEEMPH_3P5DB(n) ((n) << 19) -+#define SUNXI_TX_DEEMPH_3P5DB_MASK GENMASK(24, 19) -+#define SUNXI_TX_DEEMPH_6DB(n) ((n) << 13) -+#define SUNXI_TX_DEEMPH_6GB_MASK GENMASK(18, 13) -+#define SUNXI_TX_SWING_FULL(n) ((n) << 6) -+#define SUNXI_TX_SWING_FULL_MASK GENMASK(12, 6) -+#define SUNXI_LOS_BIAS(n) ((n) << 3) -+#define SUNXI_LOS_BIAS_MASK GENMASK(5, 3) -+#define SUNXI_TXVBOOSTLVL(n) ((n) << 0) -+#define SUNXI_TXVBOOSTLVL_MASK GENMASK(0, 2) -+ -+struct sun50i_usb3_phy { -+ struct phy *phy; -+ void __iomem *regs; -+ struct reset_control *reset; -+ struct clk *clk; -+}; -+ -+static void sun50i_usb3_phy_open(struct sun50i_usb3_phy *phy) -+{ -+ u32 val; -+ -+ val = readl(phy->regs + SUNXI_PHY_EXTERNAL_CONTROL); -+ val |= SUNXI_PEC_EXTERN_VBUS; -+ val |= SUNXI_PEC_SSC_EN | SUNXI_PEC_REF_SSP_EN; -+ writel(val, phy->regs + SUNXI_PHY_EXTERNAL_CONTROL); -+ -+ val = readl(phy->regs + SUNXI_PIPE_CLOCK_CONTROL); -+ val |= SUNXI_PCC_PIPE_CLK_OPEN; -+ writel(val, phy->regs + SUNXI_PIPE_CLOCK_CONTROL); -+ -+ val = readl(phy->regs + SUNXI_ISCR); -+ val |= SUNXI_ISCR_FORCE_VBUS; -+ writel(val, phy->regs + SUNXI_ISCR); -+ -+ /* -+ * All the magic numbers written to the PHY_TUNE_{LOW_HIGH} -+ * registers are directly taken from the BSP USB3 driver from -+ * Allwiner. -+ */ -+ writel(0x0047fc87, phy->regs + SUNXI_PHY_TUNE_LOW); -+ -+ val = readl(phy->regs + SUNXI_PHY_TUNE_HIGH); -+ val &= ~(SUNXI_TXVBOOSTLVL_MASK | SUNXI_LOS_BIAS_MASK | -+ SUNXI_TX_SWING_FULL_MASK | SUNXI_TX_DEEMPH_6GB_MASK | -+ SUNXI_TX_DEEMPH_3P5DB_MASK); -+ val |= SUNXI_TXVBOOSTLVL(0x7); -+ val |= SUNXI_LOS_BIAS(0x7); -+ val |= SUNXI_TX_SWING_FULL(0x55); -+ val |= SUNXI_TX_DEEMPH_6DB(0x20); -+ val |= SUNXI_TX_DEEMPH_3P5DB(0x15); -+ writel(val, phy->regs + SUNXI_PHY_TUNE_HIGH); -+} -+ -+static int sun50i_usb3_phy_init(struct phy *_phy) -+{ -+ struct sun50i_usb3_phy *phy = phy_get_drvdata(_phy); -+ int ret; -+ -+ ret = clk_prepare_enable(phy->clk); -+ if (ret) -+ goto err_clk; -+ -+ ret = reset_control_deassert(phy->reset); -+ if (ret) -+ goto err_reset; -+ -+ sun50i_usb3_phy_open(phy); -+ return 0; -+ -+err_reset: -+ clk_disable_unprepare(phy->clk); -+ -+err_clk: -+ return ret; -+} -+ -+static int sun50i_usb3_phy_exit(struct phy *_phy) -+{ -+ struct sun50i_usb3_phy *phy = phy_get_drvdata(_phy); -+ -+ reset_control_assert(phy->reset); -+ clk_disable_unprepare(phy->clk); -+ -+ return 0; -+} -+ -+static const struct phy_ops sun50i_usb3_phy_ops = { -+ .init = sun50i_usb3_phy_init, -+ .exit = sun50i_usb3_phy_exit, -+ .owner = THIS_MODULE, -+}; -+ -+static int sun50i_usb3_phy_probe(struct platform_device *pdev) -+{ -+ struct sun50i_usb3_phy *phy; -+ struct device *dev = &pdev->dev; -+ struct phy_provider *phy_provider; -+ struct resource *res; -+ -+ phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); -+ if (!phy) -+ return -ENOMEM; -+ -+ phy->clk = devm_clk_get(dev, NULL); -+ if (IS_ERR(phy->clk)) { -+ dev_err(dev, "failed to get phy clock\n"); -+ return PTR_ERR(phy->clk); -+ } -+ -+ phy->reset = devm_reset_control_get(dev, NULL); -+ if (IS_ERR(phy->reset)) { -+ dev_err(dev, "failed to get reset control\n"); -+ return PTR_ERR(phy->reset); -+ } -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ phy->regs = devm_ioremap_resource(dev, res); -+ if (IS_ERR(phy->regs)) -+ return PTR_ERR(phy->regs); -+ -+ phy->phy = devm_phy_create(dev, NULL, &sun50i_usb3_phy_ops); -+ if (IS_ERR(phy->phy)) { -+ dev_err(dev, "failed to create PHY\n"); -+ return PTR_ERR(phy->phy); -+ } -+ -+ phy_set_drvdata(phy->phy, phy); -+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); -+ -+ return PTR_ERR_OR_ZERO(phy_provider); -+} -+ -+static const struct of_device_id sun50i_usb3_phy_of_match[] = { -+ { .compatible = "allwinner,sun50i-h6-usb3-phy" }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, sun50i_usb3_phy_of_match); -+ -+static struct platform_driver sun50i_usb3_phy_driver = { -+ .probe = sun50i_usb3_phy_probe, -+ .driver = { -+ .of_match_table = sun50i_usb3_phy_of_match, -+ .name = "sun50i-usb3-phy", -+ } -+}; -+module_platform_driver(sun50i_usb3_phy_driver); -+ -+MODULE_DESCRIPTION("Allwinner sun50i USB 3.0 phy driver"); -+MODULE_AUTHOR("Icenowy Zheng "); -+MODULE_LICENSE("GPL"); --- -2.7.4 - diff --git a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0023-arm64-allwinner-h6-add-USB3-device-nodes.patch b/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0023-arm64-allwinner-h6-add-USB3-device-nodes.patch deleted file mode 100644 index ad5bdc39e..000000000 --- a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0023-arm64-allwinner-h6-add-USB3-device-nodes.patch +++ /dev/null @@ -1,67 +0,0 @@ -From a3e8bf0e49687679382fd76aaad5be49bd65793c Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Mon, 25 Dec 2017 12:10:06 +0800 -Subject: [PATCH 23/35] arm64: allwinner: h6: add USB3 device nodes - -Allwinner H6 SoC features USB3 functionality, with a DWC3 controller and -a custom PHY. - -Add device tree nodes for them. - -Signed-off-by: Icenowy Zheng ---- - arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 38 ++++++++++++++++++++++++++++ - 1 file changed, 38 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -index f3ca411..b3d8da4 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -@@ -233,6 +233,44 @@ - status = "disabled"; - }; - -+ usb3: usb@5200000 { -+ compatible = "allwinner,sun50i-h6-dwc3"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ clocks = <&ccu CLK_BUS_XHCI>; -+ clock-names = "bus"; -+ resets = <&ccu RST_BUS_XHCI>; -+ reset-names = "bus"; -+ status = "disabled"; -+ -+ dwc3: dwc3 { -+ compatible = "snps,dwc3"; -+ reg = <0x5200000 0x10000>; -+ interrupts = ; -+ /* -+ * According to Wink from Allwinner, the -+ * USB3 port on H6 is not capable of OTG; -+ * the datasheet doesn't mention OTG at all -+ * either, so the dr_mode is default to -+ * "host" here. -+ */ -+ dr_mode = "host"; -+ phys = <&usb3phy>; -+ phy-names = "usb3-phy"; -+ status = "disabled"; -+ }; -+ }; -+ -+ usb3phy: phy@5210000 { -+ compatible = "allwinner,sun50i-h6-usb3-phy"; -+ reg = <0x5210000 0x10000>; -+ clocks = <&ccu CLK_USB_PHY1>; -+ resets = <&ccu RST_USB_PHY1>; -+ #phy-cells = <0>; -+ status = "disabled"; -+ }; -+ - r_ccu: clock@7010000 { - compatible = "allwinner,sun50i-h6-r-ccu"; - reg = <0x07010000 0x400>; --- -2.7.4 - diff --git a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0024-arm64-allwinner-h6-enable-USB3-port-on-Pine-H64.patch b/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0024-arm64-allwinner-h6-enable-USB3-port-on-Pine-H64.patch index ef5521c9c..c4a6378a7 100644 --- a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0024-arm64-allwinner-h6-enable-USB3-port-on-Pine-H64.patch +++ b/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0024-arm64-allwinner-h6-enable-USB3-port-on-Pine-H64.patch @@ -39,15 +39,11 @@ index e2195b0..acfa90e 100644 }; &mmc0 { -@@ -180,3 +194,12 @@ +@@ -180,3 +194,08 @@ pinctrl-0 = <&uart0_ph_pins>; status = "okay"; }; + -+&usb3 { -+ status = "okay"; -+}; -+ +&usb3phy { + phy-supply = <®_usb_vbus>; + status = "okay"; diff --git a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0026-phy-sun4i-usb-add-support-for-H6-USB2-PHY.patch b/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0026-phy-sun4i-usb-add-support-for-H6-USB2-PHY.patch deleted file mode 100644 index 75091d92e..000000000 --- a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0026-phy-sun4i-usb-add-support-for-H6-USB2-PHY.patch +++ /dev/null @@ -1,76 +0,0 @@ -From bd356126b12ba97fd56f9d662c1f8f5ac8fd97e9 Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Fri, 5 Jan 2018 18:32:55 +0800 -Subject: [PATCH 26/35] phy: sun4i-usb: add support for H6 USB2 PHY - -The USB 2.0 PHY on Allwinner H6 SoC is similar to older Allwinner SoCs, -with some USB0 quirk like A83T and PHY index 1/2 missing. - -Add support for it. - -Signed-off-by: Icenowy Zheng ---- - drivers/phy/allwinner/phy-sun4i-usb.c | 19 +++++++++++++++++-- - 1 file changed, 17 insertions(+), 2 deletions(-) - -diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c -index d243695..5a253c1 100644 ---- a/drivers/phy/allwinner/phy-sun4i-usb.c -+++ b/drivers/phy/allwinner/phy-sun4i-usb.c -@@ -114,6 +114,7 @@ enum sun4i_usb_phy_type { - sun8i_h3_phy, - sun8i_v3s_phy, - sun50i_a64_phy, -+ sun50i_h6_phy, - }; - - struct sun4i_usb_phy_cfg { -@@ -294,7 +295,8 @@ static int sun4i_usb_phy_init(struct phy *_phy) - return ret; - } - -- if (data->cfg->type == sun8i_a83t_phy) { -+ if (data->cfg->type == sun8i_a83t_phy || -+ data->cfg->type == sun50i_h6_phy) { - if (phy->index == 0) { - val = readl(data->base + data->cfg->phyctl_offset); - val |= PHY_CTL_VBUSVLDEXT; -@@ -343,7 +345,8 @@ static int sun4i_usb_phy_exit(struct phy *_phy) - struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); - - if (phy->index == 0) { -- if (data->cfg->type == sun8i_a83t_phy) { -+ if (data->cfg->type == sun8i_a83t_phy || -+ data->cfg->type == sun50i_h6_phy) { - void __iomem *phyctl = data->base + - data->cfg->phyctl_offset; - -@@ -946,6 +949,17 @@ static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = { - .phy0_dual_route = true, - }; - -+static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = { -+ .num_phys = 4, -+ .type = sun50i_h6_phy, -+ .disc_thresh = 3, -+ .phyctl_offset = REG_PHYCTL_A33, -+ .dedicated_clocks = true, -+ .enable_pmu_unk1 = true, -+ .phy0_dual_route = true, -+ .missing_phys = BIT(1) | BIT(2), -+}; -+ - static const struct of_device_id sun4i_usb_phy_of_match[] = { - { .compatible = "allwinner,sun4i-a10-usb-phy", .data = &sun4i_a10_cfg }, - { .compatible = "allwinner,sun5i-a13-usb-phy", .data = &sun5i_a13_cfg }, -@@ -958,6 +972,7 @@ static const struct of_device_id sun4i_usb_phy_of_match[] = { - { .compatible = "allwinner,sun8i-v3s-usb-phy", .data = &sun8i_v3s_cfg }, - { .compatible = "allwinner,sun50i-a64-usb-phy", - .data = &sun50i_a64_cfg}, -+ { .compatible = "allwinner,sun50i-h6-usb-phy", .data = &sun50i_h6_cfg }, - { }, - }; - MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match); --- -2.7.4 - diff --git a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0027-arm64-allwinner-h6-add-USB2-related-device-nodes.patch b/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0027-arm64-allwinner-h6-add-USB2-related-device-nodes.patch deleted file mode 100644 index b0ee35815..000000000 --- a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0027-arm64-allwinner-h6-add-USB2-related-device-nodes.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 994865c02ec76b97dbcac43b25eaa2147b84264a Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Fri, 5 Jan 2018 18:34:15 +0800 -Subject: [PATCH 27/35] arm64: allwinner: h6: add USB2-related device nodes - -Allwinner H6 has two USB2 ports, one OTG and one host-only. - -Add device tree nodes related to them. - -Signed-off-by: Icenowy Zheng ---- - arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 81 ++++++++++++++++++++++++++++ - 1 file changed, 81 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -index b3d8da4..e4ea224 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -@@ -233,6 +233,61 @@ - status = "disabled"; - }; - -+ usb2otg: usb@5100000 { -+ compatible = "allwinner,sun8i-a33-musb"; -+ reg = <0x05100000 0x0400>; -+ clocks = <&ccu CLK_BUS_OTG>; -+ resets = <&ccu RST_BUS_OTG>; -+ interrupts = ; -+ interrupt-names = "mc"; -+ phys = <&usb2phy 0>; -+ phy-names = "usb"; -+ extcon = <&usb2phy 0>; -+ status = "disabled"; -+ }; -+ -+ usb2phy: phy@5100400 { -+ compatible = "allwinner,sun50i-h6-usb-phy"; -+ reg = <0x05100400 0x14>, -+ <0x05101800 0x4>, -+ <0x05311800 0x4>; -+ reg-names = "phy_ctrl", -+ "pmu0", -+ "pmu3"; -+ clocks = <&ccu CLK_USB_PHY0>, -+ <&ccu CLK_USB_PHY3>; -+ clock-names = "usb0_phy", -+ "usb3_phy"; -+ resets = <&ccu RST_USB_PHY0>, -+ <&ccu RST_USB_PHY3>; -+ reset-names = "usb0_reset", -+ "usb3_reset"; -+ status = "disabled"; -+ #phy-cells = <1>; -+ }; -+ -+ ehci0: usb@5101000 { -+ compatible = "allwinner,sun50i-h6-ehci", "generic-ehci"; -+ reg = <0x05101000 0x100>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_OHCI0>, -+ <&ccu CLK_BUS_EHCI0>, -+ <&ccu CLK_USB_OHCI0>; -+ resets = <&ccu RST_BUS_OHCI0>, -+ <&ccu RST_BUS_EHCI0>; -+ status = "disabled"; -+ }; -+ -+ ohci0: usb@5101400 { -+ compatible = "allwinner,sun50i-h6-ohci", "generic-ohci"; -+ reg = <0x05101400 0x100>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_OHCI0>, -+ <&ccu CLK_USB_OHCI0>; -+ resets = <&ccu RST_BUS_OHCI0>; -+ status = "disabled"; -+ }; -+ - usb3: usb@5200000 { - compatible = "allwinner,sun50i-h6-dwc3"; - #address-cells = <1>; -@@ -271,6 +326,32 @@ - status = "disabled"; - }; - -+ ehci3: usb@5311000 { -+ compatible = "allwinner,sun50i-h6-ehci", "generic-ehci"; -+ reg = <0x05311000 0x100>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_OHCI3>, -+ <&ccu CLK_BUS_EHCI3>, -+ <&ccu CLK_USB_OHCI3>; -+ resets = <&ccu RST_BUS_OHCI3>, -+ <&ccu RST_BUS_EHCI3>; -+ phys = <&usb2phy 3>; -+ phy-names = "usb"; -+ status = "disabled"; -+ }; -+ -+ ohci3: usb@5311400 { -+ compatible = "allwinner,sun50i-h6-ohci", "generic-ohci"; -+ reg = <0x05311400 0x100>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_OHCI3>, -+ <&ccu CLK_USB_OHCI3>; -+ resets = <&ccu RST_BUS_OHCI3>; -+ phys = <&usb2phy 3>; -+ phy-names = "usb"; -+ status = "disabled"; -+ }; -+ - r_ccu: clock@7010000 { - compatible = "allwinner,sun50i-h6-r-ccu"; - reg = <0x07010000 0x400>; --- -2.7.4 - diff --git a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0028-arm64-allwinner-h6-enable-USB2-on-Pine-H64.patch b/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0028-arm64-allwinner-h6-enable-USB2-on-Pine-H64.patch deleted file mode 100644 index 360c8b7f2..000000000 --- a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0028-arm64-allwinner-h6-enable-USB2-on-Pine-H64.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 46ea76edb4c37e99f1cc2b2b75c80841467f6f3b Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Fri, 5 Jan 2018 18:35:04 +0800 -Subject: [PATCH 28/35] arm64: allwinner: h6: enable USB2 on Pine H64 - -Pine H64 board has both the USB2 OTG port and the USB2 host port on H6 -SoC wired out to USB Type-A port. - -Enable them. - -Signed-off-by: Icenowy Zheng ---- - .../boot/dts/allwinner/sun50i-h6-pine-h64.dts | 27 ++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts -index acfa90e..038e213 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts -@@ -51,6 +51,14 @@ - status = "okay"; - }; - -+&ehci0 { -+ status = "okay"; -+}; -+ -+&ehci3 { -+ status = "okay"; -+}; -+ - &mmc0 { - pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins>; -@@ -69,6 +77,14 @@ - status = "okay"; - }; - -+&ohci0 { -+ status = "okay"; -+}; -+ -+&ohci3 { -+ status = "okay"; -+}; -+ - &r_i2c { - pinctrl-names = "default"; - pinctrl-0 = <&r_i2c_pins>; -@@ -195,6 +211,17 @@ - status = "okay"; - }; - -+&usb2otg { -+ dr_mode = "host"; -+ status = "okay"; -+}; -+ -+&usb2phy { -+ usb0_vbus-supply = <®_usb_vbus>; -+ usb3_vbus-supply = <®_usb_vbus>; -+ status = "okay"; -+}; -+ - &usb3 { - status = "okay"; - }; --- -2.7.4 - diff --git a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0029-arm64-allwinner-h6-add-basical-DVFS-support.patch b/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0029-arm64-allwinner-h6-add-basical-DVFS-support.patch deleted file mode 100644 index 725f805e3..000000000 --- a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0029-arm64-allwinner-h6-add-basical-DVFS-support.patch +++ /dev/null @@ -1,76 +0,0 @@ -From e725812b6ff85fb5f3fff8fbb760d095a0c1bd2f Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Fri, 5 Jan 2018 19:37:14 +0800 -Subject: [PATCH 29/35] arm64: allwinner: h6: add basical DVFS support - -Add basical DVFS support for Allwinner H6 SoC. - -Only one lowest OPP is added, as it's under the initial voltage of -AXP805's DCDCA regulator (0.9V). - -Signed-off-by: Icenowy Zheng ---- - arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -index e4ea224..4183819 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -@@ -15,6 +15,17 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ cpu0_opp_table: opp_table0 { -+ compatible = "operating-points-v2"; -+ opp-shared; -+ -+ opp-888000000 { -+ opp-hz = /bits/ 64 <888000000>; -+ opp-microvolt = <880000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -24,6 +35,11 @@ - device_type = "cpu"; - reg = <0>; - enable-method = "psci"; -+ -+ clocks = <&ccu CLK_CPUX>; -+ clock-names = "cpu"; -+ operating-points-v2 = <&cpu0_opp_table>; -+ #cooling-cells = <2>; - }; - - cpu1: cpu@1 { -@@ -31,6 +47,7 @@ - device_type = "cpu"; - reg = <1>; - enable-method = "psci"; -+ operating-points-v2 = <&cpu0_opp_table>; - }; - - cpu2: cpu@2 { -@@ -38,6 +55,7 @@ - device_type = "cpu"; - reg = <2>; - enable-method = "psci"; -+ operating-points-v2 = <&cpu0_opp_table>; - }; - - cpu3: cpu@3 { -@@ -45,6 +63,7 @@ - device_type = "cpu"; - reg = <3>; - enable-method = "psci"; -+ operating-points-v2 = <&cpu0_opp_table>; - }; - }; - --- -2.7.4 - diff --git a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0033-net-stmmac-sun8i-add-support-for-Allwinner-H6-EMAC.patch b/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0033-net-stmmac-sun8i-add-support-for-Allwinner-H6-EMAC.patch deleted file mode 100644 index 97301167a..000000000 --- a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0033-net-stmmac-sun8i-add-support-for-Allwinner-H6-EMAC.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 7794e4fa9fa31ac5cb6d7712d76730fc42f21b85 Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Wed, 10 Jan 2018 00:02:24 +0800 -Subject: [PATCH 33/35] net: stmmac: sun8i: add support for Allwinner H6 EMAC - -The EMAC on Allwinner H6 is just like the one on A64. The "internal PHY" -on H6 is on a co-packaged AC200 chip, and it's not really internal (it's -connected via RMII at PA GPIO bank). - -Add support for the Allwinner H6 EMAC in the dwmac-sun8i driver. - -Signed-off-by: Icenowy Zheng ---- - Documentation/devicetree/bindings/net/dwmac-sun8i.txt | 2 ++ - drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 14 ++++++++++++++ - 2 files changed, 16 insertions(+) - -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c -index 099daef..0b3e686 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c -@@ -105,6 +105,18 @@ static const struct emac_variant emac_variant_a64 = { - .support_rgmii = true - }; - -+static const struct emac_variant emac_variant_h6 = { -+ .default_syscon_value = 0x148000, -+ /* -+ * The "Internal PHY" of H6 is not on the die. It's on the co-packaged -+ * AC200 chip instead. -+ */ -+ .soc_has_internal_phy = false, -+ .support_mii = true, -+ .support_rmii = true, -+ .support_rgmii = true -+}; -+ - #define EMAC_BASIC_CTL0 0x00 - #define EMAC_BASIC_CTL1 0x04 - #define EMAC_INT_STA 0x08 -@@ -1085,6 +1097,8 @@ static const struct of_device_id sun8i_dwmac_match[] = { - .data = &emac_variant_a83t }, - { .compatible = "allwinner,sun50i-a64-emac", - .data = &emac_variant_a64 }, -+ { .compatible = "allwinner,sun50i-h6-emac", -+ .data = &emac_variant_h6 }, - { } - }; - MODULE_DEVICE_TABLE(of, sun8i_dwmac_match); --- -2.7.4 - diff --git a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0034-arm64-allwinner-h6-add-EMAC-device-nodes.patch b/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0034-arm64-allwinner-h6-add-EMAC-device-nodes.patch deleted file mode 100644 index 06ec12723..000000000 --- a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0034-arm64-allwinner-h6-add-EMAC-device-nodes.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 07a78eea37bdd34619ac73ed828a900166d41f02 Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Wed, 10 Jan 2018 00:09:54 +0800 -Subject: [PATCH 34/35] arm64: allwinner: h6: add EMAC device nodes - -Allwinner H6 SoC has an EMAC like the one in A64. - -Add device tree nodes for the H6 DTSI file. - -Signed-off-by: Icenowy Zheng ---- - arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 35 ++++++++++++++++++++++++++++ - 1 file changed, 35 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -index f548eb4..2c0ecf7 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -@@ -118,6 +118,12 @@ - #size-cells = <1>; - ranges; - -+ syscon: syscon@3000000 { -+ compatible = "allwinner,sun50i-h6-system-controller", -+ "syscon"; -+ reg = <0x03000000 0x1000>; -+ }; -+ - ccu: clock@3001000 { - compatible = "allwinner,sun50i-h6-ccu"; - reg = <0x03001000 0x1000>; -@@ -152,6 +158,14 @@ - interrupt-controller; - #interrupt-cells = <3>; - -+ ext_rgmii_pins: rgmii_pins { -+ pins = "PD0", "PD1", "PD2", "PD3", "PD4", -+ "PD5", "PD7", "PD8", "PD9", "PD10", -+ "PD11", "PD12", "PD13", "PD19", "PD20"; -+ function = "emac"; -+ drive-strength = <40>; -+ }; -+ - mmc0_pins: mmc0-pins { - pins = "PF0", "PF1", "PF2", "PF3", - "PF4", "PF5"; -@@ -313,6 +327,27 @@ - status = "disabled"; - }; - -+ emac: ethernet@5020000 { -+ compatible = "allwinner,sun50i-h6-emac"; -+ syscon = <&syscon>; -+ reg = <0x05020000 0x10000>; -+ interrupts = ; -+ interrupt-names = "macirq"; -+ resets = <&ccu RST_BUS_EMAC>; -+ reset-names = "stmmaceth"; -+ clocks = <&ccu CLK_BUS_EMAC>; -+ clock-names = "stmmaceth"; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ mdio: mdio { -+ compatible = "snps,dwmac-mdio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ }; -+ - usb3: usb@5200000 { - compatible = "allwinner,sun50i-h6-dwc3"; - #address-cells = <1>; --- -2.7.4 - diff --git a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0035-arm64-allwinner-h6-add-support-for-the-Ethernet-on-P.patch b/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0035-arm64-allwinner-h6-add-support-for-the-Ethernet-on-P.patch deleted file mode 100644 index 2333175e6..000000000 --- a/patch/kernel/sunxi-legacy/board-pine-h6-pine-h6-0035-arm64-allwinner-h6-add-support-for-the-Ethernet-on-P.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 66ae9ca01bd3d7f111952ff60f8eef782e6151c1 Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Wed, 10 Jan 2018 00:16:29 +0800 -Subject: [PATCH 35/35] arm64: allwinner: h6: add support for the Ethernet on - Pine H64 - -The Pine H64 board has an Ethernet port, which is connected to a -RTL8211E PHY, then the PHY is connected to the MAC on H6 SoC. - -Add support for the Ethernet port. - -Signed-off-by: Icenowy Zheng ---- - .../boot/dts/allwinner/sun50i-h6-pine-h64.dts | 29 ++++++++++++++++++++++ - 1 file changed, 29 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts -index 7f8e958..b6f353d 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts -@@ -15,6 +15,7 @@ - compatible = "pine64,pine-h64", "allwinner,sun50i-h6"; - - aliases { -+ ethernet0 = &emac; - serial0 = &uart0; - }; - -@@ -22,6 +23,16 @@ - stdout-path = "serial0:115200n8"; - }; - -+ reg_gmac_3v3: gmac-3v3 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vcc-gmac-3v3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ startup-delay-us = <100000>; -+ gpio = <&pio 2 16 GPIO_ACTIVE_HIGH>; -+ enable-active-high; -+ }; -+ - reg_vcc3v3: vcc3v3 { - compatible = "regulator-fixed"; - regulator-name = "vcc3v3"; -@@ -63,6 +74,24 @@ - status = "okay"; - }; - -+&emac { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ext_rgmii_pins>; -+ phy-mode = "rgmii"; -+ phy-handle = <&ext_rgmii_phy>; -+ phy-supply = <®_gmac_3v3>; -+ allwinner,rx-delay-ps = <200>; -+ allwinner,tx-delay-ps = <200>; -+ status = "okay"; -+}; -+ -+&mdio { -+ ext_rgmii_phy: ethernet-phy@1 { -+ compatible = "ethernet-phy-ieee802.3-c22"; -+ reg = <1>; -+ }; -+}; -+ - &mmc0 { - pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins>; --- -2.7.4 - diff --git a/patch/kernel/sunxi-legacy/board-r40-sata-support.patch b/patch/kernel/sunxi-legacy/board-r40-sata-support.patch deleted file mode 100644 index 2d6c55085..000000000 --- a/patch/kernel/sunxi-legacy/board-r40-sata-support.patch +++ /dev/null @@ -1,382 +0,0 @@ -This patch fix the indentation of target-supply's ':'. - -Signed-off-by: Corentin Labbe ---- - Documentation/devicetree/bindings/ata/ahci-platform.txt | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt -index 5d5bd456d9d9..b88820b4c01e 100644 ---- a/Documentation/devicetree/bindings/ata/ahci-platform.txt -+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt -@@ -47,7 +47,7 @@ Sub-nodes required properties: - - reg : the port number - And at least one of the following properties: - - phys : reference to the SATA PHY node --- target-supply : regulator for SATA target power -+- target-supply : regulator for SATA target power - - Examples: - sata@ffe08000 { - -The SoC R40 AHCI controller need a regulator to work. -So this patch add a way to add an optional regulator on AHCI controller. - -Signed-off-by: Corentin Labbe ---- - drivers/ata/ahci.h | 1 + - drivers/ata/libahci_platform.c | 26 ++++++++++++++++++++++++-- - 2 files changed, 25 insertions(+), 2 deletions(-) - -diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h -index 6a1515f0da40..1415f1012de5 100644 ---- a/drivers/ata/ahci.h -+++ b/drivers/ata/ahci.h -@@ -352,6 +352,7 @@ struct ahci_host_priv { - struct clk *clks[AHCI_MAX_CLKS]; /* Optional */ - struct reset_control *rsts; /* Optional */ - struct regulator **target_pwrs; /* Optional */ -+ struct regulator *ahci_regulator;/* Optional */ - /* - * If platform uses PHYs. There is a 1:1 relation between the port number and - * the PHY position in this array. -diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c -index c92c10d55374..a886b61476a3 100644 ---- a/drivers/ata/libahci_platform.c -+++ b/drivers/ata/libahci_platform.c -@@ -139,7 +139,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_disable_clks); - * ahci_platform_enable_regulators - Enable regulators - * @hpriv: host private area to store config values - * -- * This function enables all the regulators found in -+ * This function enables all the regulators found in controller and - * hpriv->target_pwrs, if any. If a regulator fails to be enabled, it - * disables all the regulators already enabled in reverse order and - * returns an error. -@@ -151,6 +151,12 @@ int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv) - { - int rc, i; - -+ if (hpriv->ahci_regulator) { -+ rc = regulator_enable(hpriv->ahci_regulator); -+ if (rc) -+ return rc; -+ } -+ - for (i = 0; i < hpriv->nports; i++) { - if (!hpriv->target_pwrs[i]) - continue; -@@ -167,6 +173,8 @@ int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv) - if (hpriv->target_pwrs[i]) - regulator_disable(hpriv->target_pwrs[i]); - -+ if (hpriv->ahci_regulator) -+ regulator_disable(hpriv->ahci_regulator); - return rc; - } - EXPORT_SYMBOL_GPL(ahci_platform_enable_regulators); -@@ -175,7 +183,8 @@ EXPORT_SYMBOL_GPL(ahci_platform_enable_regulators); - * ahci_platform_disable_regulators - Disable regulators - * @hpriv: host private area to store config values - * -- * This function disables all regulators found in hpriv->target_pwrs. -+ * This function disables all regulators found in hpriv->target_pwrs and -+ * AHCI controller. - */ - void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv) - { -@@ -186,6 +195,9 @@ void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv) - continue; - regulator_disable(hpriv->target_pwrs[i]); - } -+ -+ if (hpriv->ahci_regulator) -+ regulator_disable(hpriv->ahci_regulator); - } - EXPORT_SYMBOL_GPL(ahci_platform_disable_regulators); - /** -@@ -351,6 +363,7 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port, - * - * 1) mmio registers (IORESOURCE_MEM 0, mandatory) - * 2) regulator for controlling the targets power (optional) -+ * regulator for controlling the AHCI controller (optional) - * 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node, - * or for non devicetree enabled platforms a single clock - * 4) resets, if flags has AHCI_PLATFORM_GET_RESETS (optional) -@@ -408,6 +421,15 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev, - hpriv->clks[i] = clk; - } - -+ hpriv->ahci_regulator = devm_regulator_get_optional(dev, "ahci"); -+ if (IS_ERR(hpriv->ahci_regulator)) { -+ rc = PTR_ERR(hpriv->ahci_regulator); -+ if (rc == -EPROBE_DEFER) -+ goto err_out; -+ rc = 0; -+ hpriv->ahci_regulator = NULL; -+ } -+ - if (flags & AHCI_PLATFORM_GET_RESETS) { - hpriv->rsts = devm_reset_control_array_get_optional_shared(dev); - if (IS_ERR(hpriv->rsts)) { - -This patch document the new optional ahci-supply. - -Signed-off-by: Corentin Labbe -Reviewed-by: Rob Herring ---- - Documentation/devicetree/bindings/ata/ahci-platform.txt | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt -index b88820b4c01e..f495774c8af9 100644 ---- a/Documentation/devicetree/bindings/ata/ahci-platform.txt -+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt -@@ -33,6 +33,7 @@ Optional properties: - - target-supply : regulator for SATA target power - - phys : reference to the SATA PHY node - - phy-names : must be "sata-phy" -+- ahci-supply : regulator for AHCI controller - - ports-implemented : Mask that indicates which ports that the HBA supports - are available for software to use. Useful if PORTS_IMPL - is not programmed by the BIOS, which is true with - - -The SoC R40 AHCI controller need a PHY regulator to work. -But since the PHY is embedded in the controller, we cannot do a DT node for it, -since phy-supply works only in node with a PHY compatible. -So this patch adds a way to add an optional phy-supply regulator on AHCI controller node. - -Signed-off-by: Corentin Labbe ---- - drivers/ata/ahci.h | 1 + - drivers/ata/libahci_platform.c | 20 ++++++++++++++++++++ - 2 files changed, 21 insertions(+) - -diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h -index 1415f1012de5..ef356e70e6de 100644 ---- a/drivers/ata/ahci.h -+++ b/drivers/ata/ahci.h -@@ -353,6 +353,7 @@ struct ahci_host_priv { - struct reset_control *rsts; /* Optional */ - struct regulator **target_pwrs; /* Optional */ - struct regulator *ahci_regulator;/* Optional */ -+ struct regulator *phy_regulator;/* Optional */ - /* - * If platform uses PHYs. There is a 1:1 relation between the port number and - * the PHY position in this array. -diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c -index a886b61476a3..dc4d79b1c9ae 100644 ---- a/drivers/ata/libahci_platform.c -+++ b/drivers/ata/libahci_platform.c -@@ -157,6 +157,12 @@ int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv) - return rc; - } - -+ if (hpriv->phy_regulator) { -+ rc = regulator_enable(hpriv->phy_regulator); -+ if (rc) -+ goto disable_ahci_pwrs; -+ } -+ - for (i = 0; i < hpriv->nports; i++) { - if (!hpriv->target_pwrs[i]) - continue; -@@ -173,6 +179,9 @@ int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv) - if (hpriv->target_pwrs[i]) - regulator_disable(hpriv->target_pwrs[i]); - -+ if (hpriv->phy_regulator) -+ regulator_disable(hpriv->phy_regulator); -+disable_ahci_pwrs: - if (hpriv->ahci_regulator) - regulator_disable(hpriv->ahci_regulator); - return rc; -@@ -198,6 +207,8 @@ void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv) - - if (hpriv->ahci_regulator) - regulator_disable(hpriv->ahci_regulator); -+ if (hpriv->phy_regulator) -+ regulator_disable(hpriv->phy_regulator); - } - EXPORT_SYMBOL_GPL(ahci_platform_disable_regulators); - /** -@@ -430,6 +441,15 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev, - hpriv->ahci_regulator = NULL; - } - -+ hpriv->phy_regulator = devm_regulator_get_optional(dev, "phy"); -+ if (IS_ERR(hpriv->phy_regulator)) { -+ rc = PTR_ERR(hpriv->phy_regulator); -+ if (rc == -EPROBE_DEFER) -+ goto err_out; -+ rc = 0; -+ hpriv->phy_regulator = NULL; -+ } -+ - if (flags & AHCI_PLATFORM_GET_RESETS) { - hpriv->rsts = devm_reset_control_array_get_optional_shared(dev); - if (IS_ERR(hpriv->rsts)) { - -This patch document the new optional phy-supply. - -Signed-off-by: Corentin Labbe ---- - Documentation/devicetree/bindings/ata/ahci-platform.txt | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt -index f495774c8af9..45b451961612 100644 ---- a/Documentation/devicetree/bindings/ata/ahci-platform.txt -+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt -@@ -31,6 +31,7 @@ Optional properties: - - clocks : a list of phandle + clock specifier pairs - - resets : a list of phandle + reset specifier pairs - - target-supply : regulator for SATA target power -+- phy-supply : regulator for PHY power - - phys : reference to the SATA PHY node - - phy-names : must be "sata-phy" - - ahci-supply : regulator for AHCI controller - -This patch add the r40 compatible to the ahci_sunxi's supported list of -compatible. - -Since R40 need ahci_platform to handle the reset controller, we also add -the new AHCI_PLATFORM_GET_RESETS flag for ahci_platform_get_resources(). -This has no consequence for older platform (a10, a20) since the reset is -optional. - -Signed-off-by: Corentin Labbe ---- - drivers/ata/ahci_sunxi.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c -index 631610b72aa5..911710643305 100644 ---- a/drivers/ata/ahci_sunxi.c -+++ b/drivers/ata/ahci_sunxi.c -@@ -181,7 +181,7 @@ static int ahci_sunxi_probe(struct platform_device *pdev) - struct ahci_host_priv *hpriv; - int rc; - -- hpriv = ahci_platform_get_resources(pdev, 0); -+ hpriv = ahci_platform_get_resources(pdev, AHCI_PLATFORM_GET_RESETS); - if (IS_ERR(hpriv)) - return PTR_ERR(hpriv); - -@@ -250,6 +250,7 @@ static SIMPLE_DEV_PM_OPS(ahci_sunxi_pm_ops, ahci_platform_suspend, - - static const struct of_device_id ahci_sunxi_of_match[] = { - { .compatible = "allwinner,sun4i-a10-ahci", }, -+ { .compatible = "allwinner,sun8i-r40-ahci", }, - { }, - }; - MODULE_DEVICE_TABLE(of, ahci_sunxi_of_match); - -This patch update binding with the new R40 compatible. - -Signed-off-by: Corentin Labbe -Reviewed-by: Rob Herring ---- - Documentation/devicetree/bindings/ata/ahci-platform.txt | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt -index 45b451961612..e30fd106df4f 100644 ---- a/Documentation/devicetree/bindings/ata/ahci-platform.txt -+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt -@@ -10,6 +10,7 @@ PHYs. - Required properties: - - compatible : compatible string, one of: - - "allwinner,sun4i-a10-ahci" -+ - "allwinner,sun8i-r40-ahci" - - "brcm,iproc-ahci" - - "hisilicon,hisi-ahci" - - "cavium,octeon-7130-ahci" -@@ -44,6 +45,7 @@ Required properties when using sub-nodes: - - #address-cells : number of cells to encode an address - - #size-cells : number of cells representing the size of an address - -+For allwinner,sun8i-r40-ahci, the reset propertie must be present. - - Sub-nodes required properties: - - reg : the port number - -R40 have a sata controller which is the same as A20. -This patch adds a DT node for it. - -Signed-off-by: Icenowy Zheng -Signed-off-by: Corentin Labbe ---- - arch/arm/boot/dts/sun8i-r40.dtsi | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi -index 852c2ccc3268..d27c522e1918 100644 ---- a/arch/arm/boot/dts/sun8i-r40.dtsi -+++ b/arch/arm/boot/dts/sun8i-r40.dtsi -@@ -550,6 +550,19 @@ - #size-cells = <0>; - }; - -+ ahci: sata@1c18000 { -+ compatible = "allwinner,sun8i-r40-ahci"; -+ reg = <0x01c18000 0x1000>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_SATA>, <&ccu CLK_SATA>; -+ resets = <&ccu RST_BUS_SATA>; -+ resets-name = "ahci"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ -+ }; -+ - gmac: ethernet@1c50000 { - compatible = "allwinner,sun8i-r40-gmac"; - syscon = <&ccu>; - -This patch enable the AHCI controller. -Since this controller need two regulator, this patch add them. - -Signed-off-by: Corentin Labbe ---- - arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts -index a891a387e8f1..438b7b44dab3 100644 ---- a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts -+++ b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts -@@ -105,6 +105,12 @@ - }; - }; - -+&ahci { -+ ahci-supply = <®_dldo4>; -+ phy-supply = <®_eldo3>; -+ status = "okay"; -+}; -+ - &de { - status = "okay"; - }; -@@ -257,6 +257,18 @@ - regulator-name = "vcc-wifi"; - }; - -+®_dldo4 { -+ regulator-min-microvolt = <2500000>; -+ regulator-max-microvolt = <2500000>; -+ regulator-name = "vdd2v5-sata"; -+}; -+ -+®_eldo3 { -+ regulator-min-microvolt = <1200000>; -+ regulator-max-microvolt = <1200000>; -+ regulator-name = "vdd1v2-sata"; -+}; -+ - &tcon_tv0 { - status = "okay"; - }; diff --git a/patch/kernel/sunxi-legacy/camera-add-the-H3-H5-CSI-controller.patch b/patch/kernel/sunxi-legacy/camera-add-the-H3-H5-CSI-controller.patch deleted file mode 100644 index 505b13309..000000000 --- a/patch/kernel/sunxi-legacy/camera-add-the-H3-H5-CSI-controller.patch +++ /dev/null @@ -1,63 +0,0 @@ -From d9ad129ac7a3114568a323f44316d9d5bfd9a3f9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= -Date: Mon, 5 Mar 2018 11:04:31 +0100 -Subject: [PATCH 39/60] ARM: dts: sun8i: Add the H3/H5 CSI controller -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The H3 and H5 features the same CSI controller that was initially found on -the A31. - -Add a DT node for it. - -Signed-off-by: Mylène Josserand -Signed-off-by: Maxime Ripard ---- - arch/arm/boot/dts/sunxi-h3-h5.dtsi | 22 +++++++++++++++++++ - .../platform/sunxi/sun6i-csi/sun6i_csi.c | 1 + - 2 files changed, 23 insertions(+) - -diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -index ff05c532792d..be75e7cfdc3a 100644 ---- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi -+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -@@ -550,6 +550,13 @@ - interrupt-controller; - #interrupt-cells = <3>; - -+ csi_pins: csi { -+ pins = "PE0", "PE1", "PE2", "PE3", "PE4", -+ "PE5", "PE6", "PE7", "PE8", "PE9", -+ "PE10", "PE11"; -+ function = "csi"; -+ }; -+ - emac_rgmii_pins: emac0 { - pins = "PD0", "PD1", "PD2", "PD3", "PD4", - "PD5", "PD7", "PD8", "PD9", "PD10", -@@ -936,6 +943,21 @@ - interrupts = ; - }; - -+ csi: camera@1cb0000 { -+ compatible = "allwinner,sun8i-h3-csi", -+ "allwinner,sun6i-a31-csi"; -+ reg = <0x01cb0000 0x1000>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_CSI>, -+ <&ccu CLK_CSI_SCLK>, -+ <&ccu CLK_DRAM_CSI>; -+ clock-names = "bus", "mod", "ram"; -+ resets = <&ccu RST_BUS_CSI>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&csi_pins>; -+ status = "disabled"; -+ }; -+ - rtc: rtc@1f00000 { - compatible = "allwinner,sun6i-a31-rtc"; - reg = <0x01f00000 0x54>; - --- -2.20.1 diff --git a/patch/kernel/sunxi-legacy/fix-A64-mmc2-remove-PC1-pin.patch b/patch/kernel/sunxi-legacy/fix-A64-mmc2-remove-PC1-pin.patch deleted file mode 100644 index 5e28d360f..000000000 --- a/patch/kernel/sunxi-legacy/fix-A64-mmc2-remove-PC1-pin.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -index 1b2ef28..405e996 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -@@ -356,7 +366,7 @@ - }; - - mmc2_pins: mmc2-pins { -- pins = "PC1", "PC5", "PC6", "PC8", "PC9", -+ pins = "PC5", "PC6", "PC8", "PC9", - "PC10","PC11", "PC12", "PC13", - "PC14", "PC15", "PC16"; - function = "mmc2"; diff --git a/patch/kernel/sunxi-legacy/fix-a64-timejump.patch b/patch/kernel/sunxi-legacy/fix-a64-timejump.patch new file mode 100644 index 000000000..5920fe4a5 --- /dev/null +++ b/patch/kernel/sunxi-legacy/fix-a64-timejump.patch @@ -0,0 +1,34 @@ +diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c +index 9a5464c62..91142959c 100644 +--- a/drivers/clocksource/arm_arch_timer.c ++++ b/drivers/clocksource/arm_arch_timer.c +@@ -341,17 +341,18 @@ static u64 notrace arm64_858921_read_cntvct_el0(void) + * with all ones or all zeros in the low bits. Bound the loop by the maximum + * number of CPU cycles in 3 consecutive 24 MHz counter periods. + */ +-#define __sun50i_a64_read_reg(reg) ({ \ +- u64 _val; \ +- int _retries = 150; \ +- \ +- do { \ +- _val = read_sysreg(reg); \ +- _retries--; \ +- } while (((_val + 1) & GENMASK(9, 0)) <= 1 && _retries); \ +- \ +- WARN_ON_ONCE(!_retries); \ +- _val; \ ++#define __sun50i_a64_read_reg(reg) ({ \ ++ u64 _old, _new; \ ++ int _retries = 200; \ ++ \ ++ do { \ ++ _old = read_sysreg(reg); \ ++ _new = read_sysreg(reg); \ ++ _retries--; \ ++ } while (unlikely(_old != _new) && _retries); \ ++ \ ++ WARN_ON_ONCE(!_retries); \ ++ _new; \ + }) + + static u64 notrace sun50i_a64_read_cntpct_el0(void) diff --git a/patch/kernel/sunxi-legacy/fix-bananam2ultra-missing-clk-out-a.patch b/patch/kernel/sunxi-legacy/fix-bananam2ultra-missing-clk-out-a.patch index 5a52962e8..c8e1963fd 100644 --- a/patch/kernel/sunxi-legacy/fix-bananam2ultra-missing-clk-out-a.patch +++ b/patch/kernel/sunxi-legacy/fix-bananam2ultra-missing-clk-out-a.patch @@ -26,17 +26,3 @@ index bd97ca3..a8a522f 100644 }; cpus { -@@ -265,6 +340,13 @@ - #interrupt-cells = <3>; - #gpio-cells = <3>; - -+ clk_out_a_pin: clk-out-a-pin { -+ pins = "PI12"; -+ function = "clk_out_a"; -+ drive = <0>; -+ pull = <0>; -+ }; -+ - gmac_rgmii_pins: gmac-rgmii-pins { - pins = "PA0", "PA1", "PA2", "PA3", - "PA4", "PA5", "PA6", "PA7", diff --git a/patch/kernel/sunxi-legacy/fix-bananapi-m2-ultra-wifi.patch b/patch/kernel/sunxi-legacy/fix-bananapi-m2-ultra-wifi.patch deleted file mode 100644 index b3711d351..000000000 --- a/patch/kernel/sunxi-legacy/fix-bananapi-m2-ultra-wifi.patch +++ /dev/null @@ -1,108 +0,0 @@ -diff --git a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts -index 438b7b4..829c67a 100644 ---- a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts -+++ b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts -@@ -102,6 +102,8 @@ - wifi_pwrseq: wifi_pwrseq { - compatible = "mmc-pwrseq-simple"; - reset-gpios = <&pio 6 10 GPIO_ACTIVE_LOW>; /* PG10 WIFI_EN */ -+ clocks = <&ccu CLK_OUTA>; -+ clock-names = "ext_clock"; - }; - }; - -@@ -178,6 +180,15 @@ - bus-width = <4>; - non-removable; - status = "okay"; -+ -+ brcmf: bcrmf@1 { -+ reg = <1>; -+ compatible = "brcm,bcm4329-fmac"; -+ interrupt-names = "host-wake"; -+ clocks = <&clk_out_a>; -+ pinctrl-0 = <&clk_out_a_pin>; -+ pinctrl-names = "default"; -+ }; - }; - - &mmc2 { -@@ -196,6 +207,11 @@ - status = "okay"; - }; - -+&pio { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&clk_out_a_pin>; -+}; -+ - ®_aldo2 { - regulator-always-on; - regulator-min-microvolt = <2500000>; -@@ -251,11 +267,19 @@ - }; - - ®_dldo2 { -+ regulator-always-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-name = "vcc-wifi"; - }; - -+®_dldo3 { -+ regulator-always-on; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-name = "vcc-wifi-2"; -+}; -+ - ®_dldo4 { - regulator-min-microvolt = <2500000>; - regulator-max-microvolt = <2500000>; -@@ -278,6 +302,25 @@ - status = "okay"; - }; - -+&uart3 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart3_pg_pins>, <&uart3_rts_cts_pg_pins>; -+ uart-has-rtscts; -+ status = "okay"; -+ -+ bluetooth { -+ compatible = "brcm,bcm43438-bt"; -+ clocks = <&ccu CLK_OUTA>; -+ clock-names = "lpo"; -+ vbat-supply = <®_dldo2>; -+ vddio-supply = <®_dldo1>; -+ device-wakeup-gpios = <&pio 6 11 GPIO_ACTIVE_HIGH>; /* PG11 */ -+ /* TODO host wake line connected to PMIC GPIO pins */ -+ shutdown-gpios = <&pio 7 12 GPIO_ACTIVE_HIGH>; /* PH12 */ -+ max-speed = <1500000>; -+ }; -+}; -+ - &usbphy { - usb1_vbus-supply = <®_vcc5v0>; - usb2_vbus-supply = <®_vcc5v0>; -diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi -index 6f4c9ca..0781b85 100644 ---- a/arch/arm/boot/dts/sun8i-r40.dtsi -+++ b/arch/arm/boot/dts/sun8i-r40.dtsi -@@ -377,6 +401,16 @@ - pins = "PB22", "PB23"; - function = "uart0"; - }; -+ -+ uart3_pg_pins: uart3-pg-pins { -+ pins = "PG6", "PG7"; -+ function = "uart3"; -+ }; -+ -+ uart3_rts_cts_pg_pins: uart3-rts-cts-pg-pins { -+ pins = "PG8", "PG9"; -+ function = "uart3"; -+ }; - }; - - wdt: watchdog@1c20c90 { diff --git a/patch/kernel/sunxi-legacy/fix-orangepiwin-wlan0-alias.patch b/patch/kernel/sunxi-legacy/fix-orangepiwin-wlan0-alias.patch new file mode 100644 index 000000000..691fd4b62 --- /dev/null +++ b/patch/kernel/sunxi-legacy/fix-orangepiwin-wlan0-alias.patch @@ -0,0 +1,12 @@ +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts +index 04446e4..5013c8e 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts +@@ -53,6 +53,7 @@ + + aliases { + ethernet0 = &emac; ++ ethernet1 = &brcmf; + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; diff --git a/patch/kernel/sunxi-current/fix-pinebook-backlight.patch b/patch/kernel/sunxi-legacy/fix-pinebook-backlight.patch similarity index 100% rename from patch/kernel/sunxi-current/fix-pinebook-backlight.patch rename to patch/kernel/sunxi-legacy/fix-pinebook-backlight.patch diff --git a/patch/kernel/sunxi-legacy/force-mmc0-bus-width-A64.patch b/patch/kernel/sunxi-legacy/force-mmc0-bus-width-A64.patch new file mode 100644 index 000000000..effdbec27 --- /dev/null +++ b/patch/kernel/sunxi-legacy/force-mmc0-bus-width-A64.patch @@ -0,0 +1,12 @@ +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +index e628d06..8ea7fda 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +@@ -420,6 +528,7 @@ + interrupts = ; + max-frequency = <150000000>; + status = "disabled"; ++ bus-width = <0x4>; + #address-cells = <1>; + #size-cells = <0>; + }; diff --git a/patch/kernel/sunxi-legacy/force-mmc0-bus-width-H3-H5.patch b/patch/kernel/sunxi-legacy/force-mmc0-bus-width-H3-H5.patch new file mode 100644 index 000000000..ca0dc84dc --- /dev/null +++ b/patch/kernel/sunxi-legacy/force-mmc0-bus-width-H3-H5.patch @@ -0,0 +1,12 @@ +diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi +index a663c7c..71c1afa 100644 +--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi ++++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi +@@ -300,6 +307,7 @@ + resets = <&ccu RST_BUS_MMC0>; + reset-names = "ahb"; + interrupts = ; ++ bus-width = <0x4>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; diff --git a/patch/kernel/sunxi-legacy/general-add-H6-GPIO-disable_strict_mode.patch b/patch/kernel/sunxi-legacy/general-add-H6-GPIO-disable_strict_mode.patch index 8c4218b93..1ee464df4 100644 --- a/patch/kernel/sunxi-legacy/general-add-H6-GPIO-disable_strict_mode.patch +++ b/patch/kernel/sunxi-legacy/general-add-H6-GPIO-disable_strict_mode.patch @@ -1,12 +1,12 @@ diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-h6.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-h6.c -index aa8b581..b094fe6 100644 +index 3cc1121..1182cc8 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun50i-h6.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-h6.c -@@ -591,6 +591,7 @@ static const struct sunxi_pinctrl_desc h6_pinctrl_data = { - .irq_banks = 3, +@@ -588,6 +588,7 @@ static const unsigned int h6_irq_bank_map[] = { 1, 5, 6, 7 }; + static const struct sunxi_pinctrl_desc h6_pinctrl_data = { + .pins = h6_pins, + .npins = ARRAY_SIZE(h6_pins), ++ .disable_strict_mode = true, + .irq_banks = 4, .irq_bank_map = h6_irq_bank_map, .irq_read_needs_mux = true, -+ .disable_strict_mode = true, - }; - - static int h6_pinctrl_probe(struct platform_device *pdev) diff --git a/patch/kernel/sunxi-legacy/general-add-H6-I2Cs.patch b/patch/kernel/sunxi-legacy/general-add-H6-I2Cs.patch deleted file mode 100644 index dba504df5..000000000 --- a/patch/kernel/sunxi-legacy/general-add-H6-I2Cs.patch +++ /dev/null @@ -1,75 +0,0 @@ -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -index bec8c4a..25d3be2 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -@@ -245,6 +258,24 @@ - drive-strength = <40>; - }; - -+ i2c0_pins: i2c0 { -+ pins = "PD25", "PD26"; -+ function = "i2c0"; -+ pull = <1>; -+ }; -+ -+ i2c1_pins: i2c1 { -+ pins = "PH5", "PH6"; -+ function = "i2c1"; -+ pull = <1>; -+ }; -+ -+ i2c2_pins: i2c2 { -+ pins = "PD23", "PD24"; -+ function = "i2c2"; -+ pull = <1>; -+ }; -+ - mmc0_pins: mmc0-pins { - pins = "PF0", "PF1", "PF2", "PF3", - "PF4", "PF5"; -@@ -268,6 +294,45 @@ - }; - }; - -+ i2c0: i2c@5002000 { -+ compatible = "allwinner,sun6i-a31-i2c"; -+ reg = <0x05002000 0x400>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_I2C0>; -+ resets = <&ccu RST_BUS_I2C0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ i2c1: i2c@5002400 { -+ compatible = "allwinner,sun6i-a31-i2c"; -+ reg = <0x05002400 0x400>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_I2C1>; -+ resets = <&ccu RST_BUS_I2C1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ i2c2: i2c@5002800 { -+ compatible = "allwinner,sun6i-a31-i2c"; -+ reg = <0x05002800 0x400>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_I2C2>; -+ resets = <&ccu RST_BUS_I2C2>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c2_pins>; -+ status = "disabled"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ - mmc0: mmc@4020000 { - compatible = "allwinner,sun50i-h6-mmc", - "allwinner,sun50i-a64-mmc"; diff --git a/patch/kernel/sunxi-legacy/general-add-H6-UARTs.patch b/patch/kernel/sunxi-legacy/general-add-H6-UARTs.patch deleted file mode 100644 index 56bbc5461..000000000 --- a/patch/kernel/sunxi-legacy/general-add-H6-UARTs.patch +++ /dev/null @@ -1,60 +0,0 @@ -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -index c72da8c..41a057e 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -@@ -128,6 +128,21 @@ - pins = "PH0", "PH1"; - function = "uart0"; - }; -+ -+ uart1_pins: uart1 { -+ pins = "PG6", "PG7", "PG8", "PG9"; -+ function = "uart1"; -+ }; -+ -+ uart2_pins: uart2 { -+ pins = "PD19", "PD20"; -+ function = "uart2"; -+ }; -+ -+ uart3_pins: uart3 { -+ pins = "PD23", "PD24", "PD25", "PD26"; -+ function = "uart3"; -+ }; - }; - - uart0: serial@5000000 { -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts -index 4d8ca45..f05c995 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts -@@ -242,6 +242,12 @@ - status = "okay"; - }; - -+&uart3 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart3_pins>; -+ status = "disabled"; -+}; -+ - &usb2otg { - dr_mode = "host"; - status = "okay"; -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts -index 4d8ca45..f05c995 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts -@@ -242,6 +242,12 @@ - status = "okay"; - }; - -+&uart3 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart3_pins>; -+ status = "disabled"; -+}; -+ - &usb2otg { - dr_mode = "host"; - status = "okay"; diff --git a/patch/kernel/sunxi-legacy/general-add-i2s-DT-pins.patch b/patch/kernel/sunxi-legacy/general-add-i2s-DT-pins.patch index da3ba0516..c649966a9 100644 --- a/patch/kernel/sunxi-legacy/general-add-i2s-DT-pins.patch +++ b/patch/kernel/sunxi-legacy/general-add-i2s-DT-pins.patch @@ -6,16 +6,16 @@ index 1be1a02..dc9775d 100644 function = "i2c2"; }; -+ i2s0_pins: i2s0 { ++ i2s0_pins: i2s0-pins { + pins = "PA18", "PA19", "PA20", "PA21"; + function = "i2s0"; + }; + -+ i2s1_pins: i2s1 { ++ i2s1_pins: i2s1-pins { + pins = "PG10", "PG11", "PG12", "PG13"; + function = "i2s1"; + }; + - mmc0_pins: mmc0 { + mmc0_pins: mmc0-pins { pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5"; diff --git a/patch/kernel/sunxi-current/general-add-missing-uart2_rts_cts_pins-H3-H5.patch b/patch/kernel/sunxi-legacy/general-add-missing-uart2_rts_cts_pins-H3-H5.patch similarity index 100% rename from patch/kernel/sunxi-current/general-add-missing-uart2_rts_cts_pins-H3-H5.patch rename to patch/kernel/sunxi-legacy/general-add-missing-uart2_rts_cts_pins-H3-H5.patch diff --git a/patch/kernel/sunxi-legacy/general-add-overlay-compilation-support.patch b/patch/kernel/sunxi-legacy/general-add-overlay-compilation-support.patch index c8ff70eb6..bd6256c98 100644 --- a/patch/kernel/sunxi-legacy/general-add-overlay-compilation-support.patch +++ b/patch/kernel/sunxi-legacy/general-add-overlay-compilation-support.patch @@ -1,20 +1,3 @@ -diff --git a/arch/arm/Makefile b/arch/arm/Makefile -index 65f4e2a4..9eb2043c 100644 ---- a/arch/arm/Makefile -+++ b/arch/arm/Makefile -@@ -339,6 +339,12 @@ $(INSTALL_TARGETS): - %.dtb: | scripts - $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ - -+%.dtbo: | scripts -+ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ -+ -+%.scr: | scripts -+ $(Q)$(MAKE) $(build)=$(boot)/dts ARCH=$(ARCH) $(boot)/dts/$@ -+ - PHONY += dtbs dtbs_install - - dtbs: prepare scripts diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore index 3c79f859..4e5c1d59 100644 --- a/arch/arm/boot/.gitignore @@ -25,24 +8,6 @@ index 3c79f859..4e5c1d59 100644 uImage +*.dtb* +*.scr -\ No newline at end of file -diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile -index f839ecd9..9788f16d 100644 ---- a/arch/arm64/Makefile -+++ b/arch/arm64/Makefile -@@ -121,6 +121,12 @@ zinstall install: - %.dtb: scripts - $(Q)$(MAKE) $(build)=$(boot)/dts $(boot)/dts/$@ - -+%.dtbo: | scripts -+ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ -+ -+%.scr: | scripts -+ $(Q)$(MAKE) $(build)=$(boot)/dts ARCH=$(ARCH) $(boot)/dts/$@ -+ - PHONY += dtbs dtbs_install - - dtbs: prepare scripts diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst index 34614a48..8a8313d6 100644 --- a/scripts/Makefile.dtbinst diff --git a/patch/kernel/sunxi-legacy/general-aufs4.19-20181029.patch b/patch/kernel/sunxi-legacy/general-aufs4.19-20181029.patch deleted file mode 100644 index f11b030b2..000000000 --- a/patch/kernel/sunxi-legacy/general-aufs4.19-20181029.patch +++ /dev/null @@ -1,39290 +0,0 @@ -diff --git a/Documentation/ABI/testing/debugfs-aufs b/Documentation/ABI/testing/debugfs-aufs -new file mode 100644 -index 000000000..4a6694194 ---- /dev/null -+++ b/Documentation/ABI/testing/debugfs-aufs -@@ -0,0 +1,55 @@ -+What: /debug/aufs/si_/ -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ Under /debug/aufs, a directory named si_ is created -+ per aufs mount, where is a unique id generated -+ internally. -+ -+What: /debug/aufs/si_/plink -+Date: Apr 2013 -+Contact: J. R. Okajima -+Description: -+ It has three lines and shows the information about the -+ pseudo-link. The first line is a single number -+ representing a number of buckets. The second line is a -+ number of pseudo-links per buckets (separated by a -+ blank). The last line is a single number representing a -+ total number of psedo-links. -+ When the aufs mount option 'noplink' is specified, it -+ will show "1\n0\n0\n". -+ -+What: /debug/aufs/si_/xib -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ It shows the consumed blocks by xib (External Inode Number -+ Bitmap), its block size and file size. -+ When the aufs mount option 'noxino' is specified, it -+ will be empty. About XINO files, see the aufs manual. -+ -+What: /debug/aufs/si_/xi0, xi1 ... xiN and xiN-N -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ It shows the consumed blocks by xino (External Inode Number -+ Translation Table), its link count, block size and file -+ size. -+ Due to the file size limit, there may exist multiple -+ xino files per branch. In this case, "-N" is added to -+ the filename and it corresponds to the index of the -+ internal xino array. "-0" is omitted. -+ When the aufs mount option 'noxino' is specified, Those -+ entries won't exist. About XINO files, see the aufs -+ manual. -+ -+What: /debug/aufs/si_/xigen -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ It shows the consumed blocks by xigen (External Inode -+ Generation Table), its block size and file size. -+ If CONFIG_AUFS_EXPORT is disabled, this entry will not -+ be created. -+ When the aufs mount option 'noxino' is specified, it -+ will be empty. About XINO files, see the aufs manual. -diff --git a/Documentation/ABI/testing/sysfs-aufs b/Documentation/ABI/testing/sysfs-aufs -new file mode 100644 -index 000000000..82f951849 ---- /dev/null -+++ b/Documentation/ABI/testing/sysfs-aufs -@@ -0,0 +1,31 @@ -+What: /sys/fs/aufs/si_/ -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ Under /sys/fs/aufs, a directory named si_ is created -+ per aufs mount, where is a unique id generated -+ internally. -+ -+What: /sys/fs/aufs/si_/br0, br1 ... brN -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ It shows the abolute path of a member directory (which -+ is called branch) in aufs, and its permission. -+ -+What: /sys/fs/aufs/si_/brid0, brid1 ... bridN -+Date: July 2013 -+Contact: J. R. Okajima -+Description: -+ It shows the id of a member directory (which is called -+ branch) in aufs. -+ -+What: /sys/fs/aufs/si_/xi_path -+Date: March 2009 -+Contact: J. R. Okajima -+Description: -+ It shows the abolute path of XINO (External Inode Number -+ Bitmap, Translation Table and Generation Table) file -+ even if it is the default path. -+ When the aufs mount option 'noxino' is specified, it -+ will be empty. About XINO files, see the aufs manual. -diff --git a/Documentation/filesystems/aufs/README b/Documentation/filesystems/aufs/README -new file mode 100644 -index 000000000..79eb50ae0 ---- /dev/null -+++ b/Documentation/filesystems/aufs/README -@@ -0,0 +1,394 @@ -+ -+Aufs4 -- advanced multi layered unification filesystem version 4.x -+http://aufs.sf.net -+Junjiro R. Okajima -+ -+ -+0. Introduction -+---------------------------------------- -+In the early days, aufs was entirely re-designed and re-implemented -+Unionfs Version 1.x series. Adding many original ideas, approaches, -+improvements and implementations, it becomes totally different from -+Unionfs while keeping the basic features. -+Recently, Unionfs Version 2.x series begin taking some of the same -+approaches to aufs1's. -+Unionfs is being developed by Professor Erez Zadok at Stony Brook -+University and his team. -+ -+Aufs4 supports linux-4.0 and later, and for linux-3.x series try aufs3. -+If you want older kernel version support, try aufs2-2.6.git or -+aufs2-standalone.git repository, aufs1 from CVS on SourceForge. -+ -+Note: it becomes clear that "Aufs was rejected. Let's give it up." -+ According to Christoph Hellwig, linux rejects all union-type -+ filesystems but UnionMount. -+ -+ -+PS. Al Viro seems have a plan to merge aufs as well as overlayfs and -+ UnionMount, and he pointed out an issue around a directory mutex -+ lock and aufs addressed it. But it is still unsure whether aufs will -+ be merged (or any other union solution). -+ -+ -+ -+1. Features -+---------------------------------------- -+- unite several directories into a single virtual filesystem. The member -+ directory is called as a branch. -+- you can specify the permission flags to the branch, which are 'readonly', -+ 'readwrite' and 'whiteout-able.' -+- by upper writable branch, internal copyup and whiteout, files/dirs on -+ readonly branch are modifiable logically. -+- dynamic branch manipulation, add, del. -+- etc... -+ -+Also there are many enhancements in aufs, such as: -+- test only the highest one for the directory permission (dirperm1) -+- copyup on open (coo=) -+- 'move' policy for copy-up between two writable branches, after -+ checking free space. -+- xattr, acl -+- readdir(3) in userspace. -+- keep inode number by external inode number table -+- keep the timestamps of file/dir in internal copyup operation -+- seekable directory, supporting NFS readdir. -+- whiteout is hardlinked in order to reduce the consumption of inodes -+ on branch -+- do not copyup, nor create a whiteout when it is unnecessary -+- revert a single systemcall when an error occurs in aufs -+- remount interface instead of ioctl -+- maintain /etc/mtab by an external command, /sbin/mount.aufs. -+- loopback mounted filesystem as a branch -+- kernel thread for removing the dir who has a plenty of whiteouts -+- support copyup sparse file (a file which has a 'hole' in it) -+- default permission flags for branches -+- selectable permission flags for ro branch, whether whiteout can -+ exist or not -+- export via NFS. -+- support /fs/aufs and /aufs. -+- support multiple writable branches, some policies to select one -+ among multiple writable branches. -+- a new semantics for link(2) and rename(2) to support multiple -+ writable branches. -+- no glibc changes are required. -+- pseudo hardlink (hardlink over branches) -+- allow a direct access manually to a file on branch, e.g. bypassing aufs. -+ including NFS or remote filesystem branch. -+- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX. -+- and more... -+ -+Currently these features are dropped temporary from aufs4. -+See design/08plan.txt in detail. -+- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs -+ (robr) -+- statistics of aufs thread (/sys/fs/aufs/stat) -+ -+Features or just an idea in the future (see also design/*.txt), -+- reorder the branch index without del/re-add. -+- permanent xino files for NFSD -+- an option for refreshing the opened files after add/del branches -+- light version, without branch manipulation. (unnecessary?) -+- copyup in userspace -+- inotify in userspace -+- readv/writev -+ -+ -+2. Download -+---------------------------------------- -+There are three GIT trees for aufs4, aufs4-linux.git, -+aufs4-standalone.git, and aufs-util.git. Note that there is no "4" in -+"aufs-util.git." -+While the aufs-util is always necessary, you need either of aufs4-linux -+or aufs4-standalone. -+ -+The aufs4-linux tree includes the whole linux mainline GIT tree, -+git://git.kernel.org/.../torvalds/linux.git. -+And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot -+build aufs4 as an external kernel module. -+Several extra patches are not included in this tree. Only -+aufs4-standalone tree contains them. They are described in the later -+section "Configuration and Compilation." -+ -+On the other hand, the aufs4-standalone tree has only aufs source files -+and necessary patches, and you can select CONFIG_AUFS_FS=m. -+But you need to apply all aufs patches manually. -+ -+You will find GIT branches whose name is in form of "aufs4.x" where "x" -+represents the linux kernel version, "linux-4.x". For instance, -+"aufs4.0" is for linux-4.0. For latest "linux-4.x-rcN", use -+"aufs4.x-rcN" branch. -+ -+o aufs4-linux tree -+$ git clone --reference /your/linux/git/tree \ -+ git://github.com/sfjro/aufs4-linux.git aufs4-linux.git -+- if you don't have linux GIT tree, then remove "--reference ..." -+$ cd aufs4-linux.git -+$ git checkout origin/aufs4.0 -+ -+Or You may want to directly git-pull aufs into your linux GIT tree, and -+leave the patch-work to GIT. -+$ cd /your/linux/git/tree -+$ git remote add aufs4 git://github.com/sfjro/aufs4-linux.git -+$ git fetch aufs4 -+$ git checkout -b my4.0 v4.0 -+$ (add your local change...) -+$ git pull aufs4 aufs4.0 -+- now you have v4.0 + your_changes + aufs4.0 in you my4.0 branch. -+- you may need to solve some conflicts between your_changes and -+ aufs4.0. in this case, git-rerere is recommended so that you can -+ solve the similar conflicts automatically when you upgrade to 4.1 or -+ later in the future. -+ -+o aufs4-standalone tree -+$ git clone git://github.com/sfjro/aufs4-standalone.git aufs4-standalone.git -+$ cd aufs4-standalone.git -+$ git checkout origin/aufs4.0 -+ -+o aufs-util tree -+$ git clone git://git.code.sf.net/p/aufs/aufs-util aufs-util.git -+- note that the public aufs-util.git is on SourceForge instead of -+ GitHUB. -+$ cd aufs-util.git -+$ git checkout origin/aufs4.0 -+ -+Note: The 4.x-rcN branch is to be used with `rc' kernel versions ONLY. -+The minor version number, 'x' in '4.x', of aufs may not always -+follow the minor version number of the kernel. -+Because changes in the kernel that cause the use of a new -+minor version number do not always require changes to aufs-util. -+ -+Since aufs-util has its own minor version number, you may not be -+able to find a GIT branch in aufs-util for your kernel's -+exact minor version number. -+In this case, you should git-checkout the branch for the -+nearest lower number. -+ -+For (an unreleased) example: -+If you are using "linux-4.10" and the "aufs4.10" branch -+does not exist in aufs-util repository, then "aufs4.9", "aufs4.8" -+or something numerically smaller is the branch for your kernel. -+ -+Also you can view all branches by -+ $ git branch -a -+ -+ -+3. Configuration and Compilation -+---------------------------------------- -+Make sure you have git-checkout'ed the correct branch. -+ -+For aufs4-linux tree, -+- enable CONFIG_AUFS_FS. -+- set other aufs configurations if necessary. -+ -+For aufs4-standalone tree, -+There are several ways to build. -+ -+1. -+- apply ./aufs4-kbuild.patch to your kernel source files. -+- apply ./aufs4-base.patch too. -+- apply ./aufs4-mmap.patch too. -+- apply ./aufs4-standalone.patch too, if you have a plan to set -+ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs4-standalone.patch. -+- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your -+ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild. -+- enable CONFIG_AUFS_FS, you can select either -+ =m or =y. -+- and build your kernel as usual. -+- install the built kernel. -+ Note: Since linux-3.9, every filesystem module requires an alias -+ "fs-". You should make sure that "fs-aufs" is listed in your -+ modules.aliases file if you set CONFIG_AUFS_FS=m. -+- install the header files too by "make headers_install" to the -+ directory where you specify. By default, it is $PWD/usr. -+ "make help" shows a brief note for headers_install. -+- and reboot your system. -+ -+2. -+- module only (CONFIG_AUFS_FS=m). -+- apply ./aufs4-base.patch to your kernel source files. -+- apply ./aufs4-mmap.patch too. -+- apply ./aufs4-standalone.patch too. -+- build your kernel, don't forget "make headers_install", and reboot. -+- edit ./config.mk and set other aufs configurations if necessary. -+ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes -+ every aufs configurations. -+- build the module by simple "make". -+ Note: Since linux-3.9, every filesystem module requires an alias -+ "fs-". You should make sure that "fs-aufs" is listed in your -+ modules.aliases file. -+- you can specify ${KDIR} make variable which points to your kernel -+ source tree. -+- install the files -+ + run "make install" to install the aufs module, or copy the built -+ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply). -+ + run "make install_headers" (instead of headers_install) to install -+ the modified aufs header file (you can specify DESTDIR which is -+ available in aufs standalone version's Makefile only), or copy -+ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever -+ you like manually. By default, the target directory is $PWD/usr. -+- no need to apply aufs4-kbuild.patch, nor copying source files to your -+ kernel source tree. -+ -+Note: The header file aufs_type.h is necessary to build aufs-util -+ as well as "make headers_install" in the kernel source tree. -+ headers_install is subject to be forgotten, but it is essentially -+ necessary, not only for building aufs-util. -+ You may not meet problems without headers_install in some older -+ version though. -+ -+And then, -+- read README in aufs-util, build and install it -+- note that your distribution may contain an obsoleted version of -+ aufs_type.h in /usr/include/linux or something. When you build aufs -+ utilities, make sure that your compiler refers the correct aufs header -+ file which is built by "make headers_install." -+- if you want to use readdir(3) in userspace or pathconf(3) wrapper, -+ then run "make install_ulib" too. And refer to the aufs manual in -+ detail. -+ -+There several other patches in aufs4-standalone.git. They are all -+optional. When you meet some problems, they will help you. -+- aufs4-loopback.patch -+ Supports a nested loopback mount in a branch-fs. This patch is -+ unnecessary until aufs produces a message like "you may want to try -+ another patch for loopback file". -+- vfs-ino.patch -+ Modifies a system global kernel internal function get_next_ino() in -+ order to stop assigning 0 for an inode-number. Not directly related to -+ aufs, but recommended generally. -+- tmpfs-idr.patch -+ Keeps the tmpfs inode number as the lowest value. Effective to reduce -+ the size of aufs XINO files for tmpfs branch. Also it prevents the -+ duplication of inode number, which is important for backup tools and -+ other utilities. When you find aufs XINO files for tmpfs branch -+ growing too much, try this patch. -+- lockdep-debug.patch -+ Because aufs is not only an ordinary filesystem (callee of VFS), but -+ also a caller of VFS functions for branch filesystems, subclassing of -+ the internal locks for LOCKDEP is necessary. LOCKDEP is a debugging -+ feature of linux kernel. If you enable CONFIG_LOCKDEP, then you will -+ need to apply this debug patch to expand several constant values. -+ If don't know what LOCKDEP, then you don't have apply this patch. -+ -+ -+4. Usage -+---------------------------------------- -+At first, make sure aufs-util are installed, and please read the aufs -+manual, aufs.5 in aufs-util.git tree. -+$ man -l aufs.5 -+ -+And then, -+$ mkdir /tmp/rw /tmp/aufs -+# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs -+ -+Here is another example. The result is equivalent. -+# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs -+ Or -+# mount -t aufs -o br:/tmp/rw none /tmp/aufs -+# mount -o remount,append:${HOME} /tmp/aufs -+ -+Then, you can see whole tree of your home dir through /tmp/aufs. If -+you modify a file under /tmp/aufs, the one on your home directory is -+not affected, instead the same named file will be newly created under -+/tmp/rw. And all of your modification to a file will be applied to -+the one under /tmp/rw. This is called the file based Copy on Write -+(COW) method. -+Aufs mount options are described in aufs.5. -+If you run chroot or something and make your aufs as a root directory, -+then you need to customize the shutdown script. See the aufs manual in -+detail. -+ -+Additionally, there are some sample usages of aufs which are a -+diskless system with network booting, and LiveCD over NFS. -+See sample dir in CVS tree on SourceForge. -+ -+ -+5. Contact -+---------------------------------------- -+When you have any problems or strange behaviour in aufs, please let me -+know with: -+- /proc/mounts (instead of the output of mount(8)) -+- /sys/module/aufs/* -+- /sys/fs/aufs/* (if you have them) -+- /debug/aufs/* (if you have them) -+- linux kernel version -+ if your kernel is not plain, for example modified by distributor, -+ the url where i can download its source is necessary too. -+- aufs version which was printed at loading the module or booting the -+ system, instead of the date you downloaded. -+- configuration (define/undefine CONFIG_AUFS_xxx) -+- kernel configuration or /proc/config.gz (if you have it) -+- behaviour which you think to be incorrect -+- actual operation, reproducible one is better -+- mailto: aufs-users at lists.sourceforge.net -+ -+Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches, -+and Feature Requests) on SourceForge. Please join and write to -+aufs-users ML. -+ -+ -+6. Acknowledgements -+---------------------------------------- -+Thanks to everyone who have tried and are using aufs, whoever -+have reported a bug or any feedback. -+ -+Especially donators: -+Tomas Matejicek(slax.org) made a donation (much more than once). -+ Since Apr 2010, Tomas M (the author of Slax and Linux Live -+ scripts) is making "doubling" donations. -+ Unfortunately I cannot list all of the donators, but I really -+ appreciate. -+ It ends Aug 2010, but the ordinary donation URL is still available. -+ -+Dai Itasaka made a donation (2007/8). -+Chuck Smith made a donation (2008/4, 10 and 12). -+Henk Schoneveld made a donation (2008/9). -+Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10). -+Francois Dupoux made a donation (2008/11). -+Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public -+ aufs2 GIT tree (2009/2). -+William Grant made a donation (2009/3). -+Patrick Lane made a donation (2009/4). -+The Mail Archive (mail-archive.com) made donations (2009/5). -+Nippy Networks (Ed Wildgoose) made a donation (2009/7). -+New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11). -+Pavel Pronskiy made a donation (2011/2). -+Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy -+ Networks (Ed Wildgoose) made a donation for hardware (2011/3). -+Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and -+11). -+Sam Liddicott made a donation (2011/9). -+Era Scarecrow made a donation (2013/4). -+Bor Ratajc made a donation (2013/4). -+Alessandro Gorreta made a donation (2013/4). -+POIRETTE Marc made a donation (2013/4). -+Alessandro Gorreta made a donation (2013/4). -+lauri kasvandik made a donation (2013/5). -+"pemasu from Finland" made a donation (2013/7). -+The Parted Magic Project made a donation (2013/9 and 11). -+Pavel Barta made a donation (2013/10). -+Nikolay Pertsev made a donation (2014/5). -+James B made a donation (2014/7 and 2015/7). -+Stefano Di Biase made a donation (2014/8). -+Daniel Epellei made a donation (2015/1). -+OmegaPhil made a donation (2016/1, 2018/4). -+Tomasz Szewczyk made a donation (2016/4). -+James Burry made a donation (2016/12). -+Carsten Rose made a donation (2018/9). -+ -+Thank you very much. -+Donations are always, including future donations, very important and -+helpful for me to keep on developing aufs. -+ -+ -+7. -+---------------------------------------- -+If you are an experienced user, no explanation is needed. Aufs is -+just a linux filesystem. -+ -+ -+Enjoy! -+ -+# Local variables: ; -+# mode: text; -+# End: ; -diff --git a/Documentation/filesystems/aufs/design/01intro.txt b/Documentation/filesystems/aufs/design/01intro.txt -new file mode 100644 -index 000000000..aa1052982 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/01intro.txt -@@ -0,0 +1,171 @@ -+ -+# Copyright (C) 2005-2018 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Introduction -+---------------------------------------- -+ -+aufs [ei ju: ef es] | /ey-yoo-ef-es/ | [a u f s] -+1. abbrev. for "advanced multi-layered unification filesystem". -+2. abbrev. for "another unionfs". -+3. abbrev. for "auf das" in German which means "on the" in English. -+ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E). -+ But "Filesystem aufs Filesystem" is hard to understand. -+4. abbrev. for "African Urban Fashion Show". -+ -+AUFS is a filesystem with features: -+- multi layered stackable unification filesystem, the member directory -+ is called as a branch. -+- branch permission and attribute, 'readonly', 'real-readonly', -+ 'readwrite', 'whiteout-able', 'link-able whiteout', etc. and their -+ combination. -+- internal "file copy-on-write". -+- logical deletion, whiteout. -+- dynamic branch manipulation, adding, deleting and changing permission. -+- allow bypassing aufs, user's direct branch access. -+- external inode number translation table and bitmap which maintains the -+ persistent aufs inode number. -+- seekable directory, including NFS readdir. -+- file mapping, mmap and sharing pages. -+- pseudo-link, hardlink over branches. -+- loopback mounted filesystem as a branch. -+- several policies to select one among multiple writable branches. -+- revert a single systemcall when an error occurs in aufs. -+- and more... -+ -+ -+Multi Layered Stackable Unification Filesystem -+---------------------------------------------------------------------- -+Most people already knows what it is. -+It is a filesystem which unifies several directories and provides a -+merged single directory. When users access a file, the access will be -+passed/re-directed/converted (sorry, I am not sure which English word is -+correct) to the real file on the member filesystem. The member -+filesystem is called 'lower filesystem' or 'branch' and has a mode -+'readonly' and 'readwrite.' And the deletion for a file on the lower -+readonly branch is handled by creating 'whiteout' on the upper writable -+branch. -+ -+On LKML, there have been discussions about UnionMount (Jan Blunck, -+Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took -+different approaches to implement the merged-view. -+The former tries putting it into VFS, and the latter implements as a -+separate filesystem. -+(If I misunderstand about these implementations, please let me know and -+I shall correct it. Because it is a long time ago when I read their -+source files last time). -+ -+UnionMount's approach will be able to small, but may be hard to share -+branches between several UnionMount since the whiteout in it is -+implemented in the inode on branch filesystem and always -+shared. According to Bharata's post, readdir does not seems to be -+finished yet. -+There are several missing features known in this implementations such as -+- for users, the inode number may change silently. eg. copy-up. -+- link(2) may break by copy-up. -+- read(2) may get an obsoleted filedata (fstat(2) too). -+- fcntl(F_SETLK) may be broken by copy-up. -+- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after -+ open(O_RDWR). -+ -+In linux-3.18, "overlay" filesystem (formerly known as "overlayfs") was -+merged into mainline. This is another implementation of UnionMount as a -+separated filesystem. All the limitations and known problems which -+UnionMount are equally inherited to "overlay" filesystem. -+ -+Unionfs has a longer history. When I started implementing a stackable -+filesystem (Aug 2005), it already existed. It has virtual super_block, -+inode, dentry and file objects and they have an array pointing lower -+same kind objects. After contributing many patches for Unionfs, I -+re-started my project AUFS (Jun 2006). -+ -+In AUFS, the structure of filesystem resembles to Unionfs, but I -+implemented my own ideas, approaches and enhancements and it became -+totally different one. -+ -+Comparing DM snapshot and fs based implementation -+- the number of bytes to be copied between devices is much smaller. -+- the type of filesystem must be one and only. -+- the fs must be writable, no readonly fs, even for the lower original -+ device. so the compression fs will not be usable. but if we use -+ loopback mount, we may address this issue. -+ for instance, -+ mount /cdrom/squashfs.img /sq -+ losetup /sq/ext2.img -+ losetup /somewhere/cow -+ dmsetup "snapshot /dev/loop0 /dev/loop1 ..." -+- it will be difficult (or needs more operations) to extract the -+ difference between the original device and COW. -+- DM snapshot-merge may help a lot when users try merging. in the -+ fs-layer union, users will use rsync(1). -+ -+You may want to read my old paper "Filesystems in LiveCD" -+(http://aufs.sourceforge.net/aufs2/report/sq/sq.pdf). -+ -+ -+Several characters/aspects/persona of aufs -+---------------------------------------------------------------------- -+ -+Aufs has several characters, aspects or persona. -+1. a filesystem, callee of VFS helper -+2. sub-VFS, caller of VFS helper for branches -+3. a virtual filesystem which maintains persistent inode number -+4. reader/writer of files on branches such like an application -+ -+1. Callee of VFS Helper -+As an ordinary linux filesystem, aufs is a callee of VFS. For instance, -+unlink(2) from an application reaches sys_unlink() kernel function and -+then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it -+calls filesystem specific unlink operation. Actually aufs implements the -+unlink operation but it behaves like a redirector. -+ -+2. Caller of VFS Helper for Branches -+aufs_unlink() passes the unlink request to the branch filesystem as if -+it were called from VFS. So the called unlink operation of the branch -+filesystem acts as usual. As a caller of VFS helper, aufs should handle -+every necessary pre/post operation for the branch filesystem. -+- acquire the lock for the parent dir on a branch -+- lookup in a branch -+- revalidate dentry on a branch -+- mnt_want_write() for a branch -+- vfs_unlink() for a branch -+- mnt_drop_write() for a branch -+- release the lock on a branch -+ -+3. Persistent Inode Number -+One of the most important issue for a filesystem is to maintain inode -+numbers. This is particularly important to support exporting a -+filesystem via NFS. Aufs is a virtual filesystem which doesn't have a -+backend block device for its own. But some storage is necessary to -+keep and maintain the inode numbers. It may be a large space and may not -+suit to keep in memory. Aufs rents some space from its first writable -+branch filesystem (by default) and creates file(s) on it. These files -+are created by aufs internally and removed soon (currently) keeping -+opened. -+Note: Because these files are removed, they are totally gone after -+ unmounting aufs. It means the inode numbers are not persistent -+ across unmount or reboot. I have a plan to make them really -+ persistent which will be important for aufs on NFS server. -+ -+4. Read/Write Files Internally (copy-on-write) -+Because a branch can be readonly, when you write a file on it, aufs will -+"copy-up" it to the upper writable branch internally. And then write the -+originally requested thing to the file. Generally kernel doesn't -+open/read/write file actively. In aufs, even a single write may cause a -+internal "file copy". This behaviour is very similar to cp(1) command. -+ -+Some people may think it is better to pass such work to user space -+helper, instead of doing in kernel space. Actually I am still thinking -+about it. But currently I have implemented it in kernel space. -diff --git a/Documentation/filesystems/aufs/design/02struct.txt b/Documentation/filesystems/aufs/design/02struct.txt -new file mode 100644 -index 000000000..f5fb6a8ad ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/02struct.txt -@@ -0,0 +1,258 @@ -+ -+# Copyright (C) 2005-2018 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Basic Aufs Internal Structure -+ -+Superblock/Inode/Dentry/File Objects -+---------------------------------------------------------------------- -+As like an ordinary filesystem, aufs has its own -+superblock/inode/dentry/file objects. All these objects have a -+dynamically allocated array and store the same kind of pointers to the -+lower filesystem, branch. -+For example, when you build a union with one readwrite branch and one -+readonly, mounted /au, /rw and /ro respectively. -+- /au = /rw + /ro -+- /ro/fileA exists but /rw/fileA -+ -+Aufs lookup operation finds /ro/fileA and gets dentry for that. These -+pointers are stored in a aufs dentry. The array in aufs dentry will be, -+- [0] = NULL (because /rw/fileA doesn't exist) -+- [1] = /ro/fileA -+ -+This style of an array is essentially same to the aufs -+superblock/inode/dentry/file objects. -+ -+Because aufs supports manipulating branches, ie. add/delete/change -+branches dynamically, these objects has its own generation. When -+branches are changed, the generation in aufs superblock is -+incremented. And a generation in other object are compared when it is -+accessed. When a generation in other objects are obsoleted, aufs -+refreshes the internal array. -+ -+ -+Superblock -+---------------------------------------------------------------------- -+Additionally aufs superblock has some data for policies to select one -+among multiple writable branches, XIB files, pseudo-links and kobject. -+See below in detail. -+About the policies which supports copy-down a directory, see -+wbr_policy.txt too. -+ -+ -+Branch and XINO(External Inode Number Translation Table) -+---------------------------------------------------------------------- -+Every branch has its own xino (external inode number translation table) -+file. The xino file is created and unlinked by aufs internally. When two -+members of a union exist on the same filesystem, they share the single -+xino file. -+The struct of a xino file is simple, just a sequence of aufs inode -+numbers which is indexed by the lower inode number. -+In the above sample, assume the inode number of /ro/fileA is i111 and -+aufs assigns the inode number i999 for fileA. Then aufs writes 999 as -+4(8) bytes at 111 * 4(8) bytes offset in the xino file. -+ -+When the inode numbers are not contiguous, the xino file will be sparse -+which has a hole in it and doesn't consume as much disk space as it -+might appear. If your branch filesystem consumes disk space for such -+holes, then you should specify 'xino=' option at mounting aufs. -+ -+Aufs has a mount option to free the disk blocks for such holes in XINO -+files on tmpfs or ramdisk. But it is not so effective actually. If you -+meet a problem of disk shortage due to XINO files, then you should try -+"tmpfs-ino.patch" (and "vfs-ino.patch" too) in aufs4-standalone.git. -+The patch localizes the assignment inumbers per tmpfs-mount and avoid -+the holes in XINO files. -+ -+Also a writable branch has three kinds of "whiteout bases". All these -+are existed when the branch is joined to aufs, and their names are -+whiteout-ed doubly, so that users will never see their names in aufs -+hierarchy. -+1. a regular file which will be hardlinked to all whiteouts. -+2. a directory to store a pseudo-link. -+3. a directory to store an "orphan"-ed file temporary. -+ -+1. Whiteout Base -+ When you remove a file on a readonly branch, aufs handles it as a -+ logical deletion and creates a whiteout on the upper writable branch -+ as a hardlink of this file in order not to consume inode on the -+ writable branch. -+2. Pseudo-link Dir -+ See below, Pseudo-link. -+3. Step-Parent Dir -+ When "fileC" exists on the lower readonly branch only and it is -+ opened and removed with its parent dir, and then user writes -+ something into it, then aufs copies-up fileC to this -+ directory. Because there is no other dir to store fileC. After -+ creating a file under this dir, the file is unlinked. -+ -+Because aufs supports manipulating branches, ie. add/delete/change -+dynamically, a branch has its own id. When the branch order changes, -+aufs finds the new index by searching the branch id. -+ -+ -+Pseudo-link -+---------------------------------------------------------------------- -+Assume "fileA" exists on the lower readonly branch only and it is -+hardlinked to "fileB" on the branch. When you write something to fileA, -+aufs copies-up it to the upper writable branch. Additionally aufs -+creates a hardlink under the Pseudo-link Directory of the writable -+branch. The inode of a pseudo-link is kept in aufs super_block as a -+simple list. If fileB is read after unlinking fileA, aufs returns -+filedata from the pseudo-link instead of the lower readonly -+branch. Because the pseudo-link is based upon the inode, to keep the -+inode number by xino (see above) is essentially necessary. -+ -+All the hardlinks under the Pseudo-link Directory of the writable branch -+should be restored in a proper location later. Aufs provides a utility -+to do this. The userspace helpers executed at remounting and unmounting -+aufs by default. -+During this utility is running, it puts aufs into the pseudo-link -+maintenance mode. In this mode, only the process which began the -+maintenance mode (and its child processes) is allowed to operate in -+aufs. Some other processes which are not related to the pseudo-link will -+be allowed to run too, but the rest have to return an error or wait -+until the maintenance mode ends. If a process already acquires an inode -+mutex (in VFS), it has to return an error. -+ -+ -+XIB(external inode number bitmap) -+---------------------------------------------------------------------- -+Addition to the xino file per a branch, aufs has an external inode number -+bitmap in a superblock object. It is also an internal file such like a -+xino file. -+It is a simple bitmap to mark whether the aufs inode number is in-use or -+not. -+To reduce the file I/O, aufs prepares a single memory page to cache xib. -+ -+As well as XINO files, aufs has a feature to truncate/refresh XIB to -+reduce the number of consumed disk blocks for these files. -+ -+ -+Virtual or Vertical Dir, and Readdir in Userspace -+---------------------------------------------------------------------- -+In order to support multiple layers (branches), aufs readdir operation -+constructs a virtual dir block on memory. For readdir, aufs calls -+vfs_readdir() internally for each dir on branches, merges their entries -+with eliminating the whiteout-ed ones, and sets it to file (dir) -+object. So the file object has its entry list until it is closed. The -+entry list will be updated when the file position is zero and becomes -+obsoleted. This decision is made in aufs automatically. -+ -+The dynamically allocated memory block for the name of entries has a -+unit of 512 bytes (by default) and stores the names contiguously (no -+padding). Another block for each entry is handled by kmem_cache too. -+During building dir blocks, aufs creates hash list and judging whether -+the entry is whiteouted by its upper branch or already listed. -+The merged result is cached in the corresponding inode object and -+maintained by a customizable life-time option. -+ -+Some people may call it can be a security hole or invite DoS attack -+since the opened and once readdir-ed dir (file object) holds its entry -+list and becomes a pressure for system memory. But I'd say it is similar -+to files under /proc or /sys. The virtual files in them also holds a -+memory page (generally) while they are opened. When an idea to reduce -+memory for them is introduced, it will be applied to aufs too. -+For those who really hate this situation, I've developed readdir(3) -+library which operates this merging in userspace. You just need to set -+LD_PRELOAD environment variable, and aufs will not consume no memory in -+kernel space for readdir(3). -+ -+ -+Workqueue -+---------------------------------------------------------------------- -+Aufs sometimes requires privilege access to a branch. For instance, -+in copy-up/down operation. When a user process is going to make changes -+to a file which exists in the lower readonly branch only, and the mode -+of one of ancestor directories may not be writable by a user -+process. Here aufs copy-up the file with its ancestors and they may -+require privilege to set its owner/group/mode/etc. -+This is a typical case of a application character of aufs (see -+Introduction). -+ -+Aufs uses workqueue synchronously for this case. It creates its own -+workqueue. The workqueue is a kernel thread and has privilege. Aufs -+passes the request to call mkdir or write (for example), and wait for -+its completion. This approach solves a problem of a signal handler -+simply. -+If aufs didn't adopt the workqueue and changed the privilege of the -+process, then the process may receive the unexpected SIGXFSZ or other -+signals. -+ -+Also aufs uses the system global workqueue ("events" kernel thread) too -+for asynchronous tasks, such like handling inotify/fsnotify, re-creating a -+whiteout base and etc. This is unrelated to a privilege. -+Most of aufs operation tries acquiring a rw_semaphore for aufs -+superblock at the beginning, at the same time waits for the completion -+of all queued asynchronous tasks. -+ -+ -+Whiteout -+---------------------------------------------------------------------- -+The whiteout in aufs is very similar to Unionfs's. That is represented -+by its filename. UnionMount takes an approach of a file mode, but I am -+afraid several utilities (find(1) or something) will have to support it. -+ -+Basically the whiteout represents "logical deletion" which stops aufs to -+lookup further, but also it represents "dir is opaque" which also stop -+further lookup. -+ -+In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively. -+In order to make several functions in a single systemcall to be -+revertible, aufs adopts an approach to rename a directory to a temporary -+unique whiteouted name. -+For example, in rename(2) dir where the target dir already existed, aufs -+renames the target dir to a temporary unique whiteouted name before the -+actual rename on a branch, and then handles other actions (make it opaque, -+update the attributes, etc). If an error happens in these actions, aufs -+simply renames the whiteouted name back and returns an error. If all are -+succeeded, aufs registers a function to remove the whiteouted unique -+temporary name completely and asynchronously to the system global -+workqueue. -+ -+ -+Copy-up -+---------------------------------------------------------------------- -+It is a well-known feature or concept. -+When user modifies a file on a readonly branch, aufs operate "copy-up" -+internally and makes change to the new file on the upper writable branch. -+When the trigger systemcall does not update the timestamps of the parent -+dir, aufs reverts it after copy-up. -+ -+ -+Move-down (aufs3.9 and later) -+---------------------------------------------------------------------- -+"Copy-up" is one of the essential feature in aufs. It copies a file from -+the lower readonly branch to the upper writable branch when a user -+changes something about the file. -+"Move-down" is an opposite action of copy-up. Basically this action is -+ran manually instead of automatically and internally. -+For desgin and implementation, aufs has to consider these issues. -+- whiteout for the file may exist on the lower branch. -+- ancestor directories may not exist on the lower branch. -+- diropq for the ancestor directories may exist on the upper branch. -+- free space on the lower branch will reduce. -+- another access to the file may happen during moving-down, including -+ UDBA (see "Revalidate Dentry and UDBA"). -+- the file should not be hard-linked nor pseudo-linked. they should be -+ handled by auplink utility later. -+ -+Sometimes users want to move-down a file from the upper writable branch -+to the lower readonly or writable branch. For instance, -+- the free space of the upper writable branch is going to run out. -+- create a new intermediate branch between the upper and lower branch. -+- etc. -+ -+For this purpose, use "aumvdown" command in aufs-util.git. -diff --git a/Documentation/filesystems/aufs/design/03atomic_open.txt b/Documentation/filesystems/aufs/design/03atomic_open.txt -new file mode 100644 -index 000000000..1b0699f8b ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/03atomic_open.txt -@@ -0,0 +1,85 @@ -+ -+# Copyright (C) 2015-2018 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Support for a branch who has its ->atomic_open() -+---------------------------------------------------------------------- -+The filesystems who implement its ->atomic_open() are not majority. For -+example NFSv4 does, and aufs should call NFSv4 ->atomic_open, -+particularly for open(O_CREAT|O_EXCL, 0400) case. Other than -+->atomic_open(), NFSv4 returns an error for this open(2). While I am not -+sure whether all filesystems who have ->atomic_open() behave like this, -+but NFSv4 surely returns the error. -+ -+In order to support ->atomic_open() for aufs, there are a few -+approaches. -+ -+A. Introduce aufs_atomic_open() -+ - calls one of VFS:do_last(), lookup_open() or atomic_open() for -+ branch fs. -+B. Introduce aufs_atomic_open() calling create, open and chmod. this is -+ an aufs user Pip Cet's approach -+ - calls aufs_create(), VFS finish_open() and notify_change(). -+ - pass fake-mode to finish_open(), and then correct the mode by -+ notify_change(). -+C. Extend aufs_open() to call branch fs's ->atomic_open() -+ - no aufs_atomic_open(). -+ - aufs_lookup() registers the TID to an aufs internal object. -+ - aufs_create() does nothing when the matching TID is registered, but -+ registers the mode. -+ - aufs_open() calls branch fs's ->atomic_open() when the matching -+ TID is registered. -+D. Extend aufs_open() to re-try branch fs's ->open() with superuser's -+ credential -+ - no aufs_atomic_open(). -+ - aufs_create() registers the TID to an internal object. this info -+ represents "this process created this file just now." -+ - when aufs gets EACCES from branch fs's ->open(), then confirm the -+ registered TID and re-try open() with superuser's credential. -+ -+Pros and cons for each approach. -+ -+A. -+ - straightforward but highly depends upon VFS internal. -+ - the atomic behavaiour is kept. -+ - some of parameters such as nameidata are hard to reproduce for -+ branch fs. -+ - large overhead. -+B. -+ - easy to implement. -+ - the atomic behavaiour is lost. -+C. -+ - the atomic behavaiour is kept. -+ - dirty and tricky. -+ - VFS checks whether the file is created correctly after calling -+ ->create(), which means this approach doesn't work. -+D. -+ - easy to implement. -+ - the atomic behavaiour is lost. -+ - to open a file with superuser's credential and give it to a user -+ process is a bad idea, since the file object keeps the credential -+ in it. It may affect LSM or something. This approach doesn't work -+ either. -+ -+The approach A is ideal, but it hard to implement. So here is a -+variation of A, which is to be implemented. -+ -+A-1. Introduce aufs_atomic_open() -+ - calls branch fs ->atomic_open() if exists. otherwise calls -+ vfs_create() and finish_open(). -+ - the demerit is that the several checks after branch fs -+ ->atomic_open() are lost. in the ordinary case, the checks are -+ done by VFS:do_last(), lookup_open() and atomic_open(). some can -+ be implemented in aufs, but not all I am afraid. -diff --git a/Documentation/filesystems/aufs/design/03lookup.txt b/Documentation/filesystems/aufs/design/03lookup.txt -new file mode 100644 -index 000000000..80ae63bce ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/03lookup.txt -@@ -0,0 +1,113 @@ -+ -+# Copyright (C) 2005-2018 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Lookup in a Branch -+---------------------------------------------------------------------- -+Since aufs has a character of sub-VFS (see Introduction), it operates -+lookup for branches as VFS does. It may be a heavy work. But almost all -+lookup operation in aufs is the simplest case, ie. lookup only an entry -+directly connected to its parent. Digging down the directory hierarchy -+is unnecessary. VFS has a function lookup_one_len() for that use, and -+aufs calls it. -+ -+When a branch is a remote filesystem, aufs basically relies upon its -+->d_revalidate(), also aufs forces the hardest revalidate tests for -+them. -+For d_revalidate, aufs implements three levels of revalidate tests. See -+"Revalidate Dentry and UDBA" in detail. -+ -+ -+Test Only the Highest One for the Directory Permission (dirperm1 option) -+---------------------------------------------------------------------- -+Let's try case study. -+- aufs has two branches, upper readwrite and lower readonly. -+ /au = /rw + /ro -+- "dirA" exists under /ro, but /rw. and its mode is 0700. -+- user invoked "chmod a+rx /au/dirA" -+- the internal copy-up is activated and "/rw/dirA" is created and its -+ permission bits are set to world readable. -+- then "/au/dirA" becomes world readable? -+ -+In this case, /ro/dirA is still 0700 since it exists in readonly branch, -+or it may be a natively readonly filesystem. If aufs respects the lower -+branch, it should not respond readdir request from other users. But user -+allowed it by chmod. Should really aufs rejects showing the entries -+under /ro/dirA? -+ -+To be honest, I don't have a good solution for this case. So aufs -+implements 'dirperm1' and 'nodirperm1' mount options, and leave it to -+users. -+When dirperm1 is specified, aufs checks only the highest one for the -+directory permission, and shows the entries. Otherwise, as usual, checks -+every dir existing on all branches and rejects the request. -+ -+As a side effect, dirperm1 option improves the performance of aufs -+because the number of permission check is reduced when the number of -+branch is many. -+ -+ -+Revalidate Dentry and UDBA (User's Direct Branch Access) -+---------------------------------------------------------------------- -+Generally VFS helpers re-validate a dentry as a part of lookup. -+0. digging down the directory hierarchy. -+1. lock the parent dir by its i_mutex. -+2. lookup the final (child) entry. -+3. revalidate it. -+4. call the actual operation (create, unlink, etc.) -+5. unlock the parent dir -+ -+If the filesystem implements its ->d_revalidate() (step 3), then it is -+called. Actually aufs implements it and checks the dentry on a branch is -+still valid. -+But it is not enough. Because aufs has to release the lock for the -+parent dir on a branch at the end of ->lookup() (step 2) and -+->d_revalidate() (step 3) while the i_mutex of the aufs dir is still -+held by VFS. -+If the file on a branch is changed directly, eg. bypassing aufs, after -+aufs released the lock, then the subsequent operation may cause -+something unpleasant result. -+ -+This situation is a result of VFS architecture, ->lookup() and -+->d_revalidate() is separated. But I never say it is wrong. It is a good -+design from VFS's point of view. It is just not suitable for sub-VFS -+character in aufs. -+ -+Aufs supports such case by three level of revalidation which is -+selectable by user. -+1. Simple Revalidate -+ Addition to the native flow in VFS's, confirm the child-parent -+ relationship on the branch just after locking the parent dir on the -+ branch in the "actual operation" (step 4). When this validation -+ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still -+ checks the validation of the dentry on branches. -+2. Monitor Changes Internally by Inotify/Fsnotify -+ Addition to above, in the "actual operation" (step 4) aufs re-lookup -+ the dentry on the branch, and returns EBUSY if it finds different -+ dentry. -+ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches -+ during it is in cache. When the event is notified, aufs registers a -+ function to kernel 'events' thread by schedule_work(). And the -+ function sets some special status to the cached aufs dentry and inode -+ private data. If they are not cached, then aufs has nothing to -+ do. When the same file is accessed through aufs (step 0-3) later, -+ aufs will detect the status and refresh all necessary data. -+ In this mode, aufs has to ignore the event which is fired by aufs -+ itself. -+3. No Extra Validation -+ This is the simplest test and doesn't add any additional revalidation -+ test, and skip the revalidation in step 4. It is useful and improves -+ aufs performance when system surely hide the aufs branches from user, -+ by over-mounting something (or another method). -diff --git a/Documentation/filesystems/aufs/design/04branch.txt b/Documentation/filesystems/aufs/design/04branch.txt -new file mode 100644 -index 000000000..0c1289737 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/04branch.txt -@@ -0,0 +1,74 @@ -+ -+# Copyright (C) 2005-2018 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Branch Manipulation -+ -+Since aufs supports dynamic branch manipulation, ie. add/remove a branch -+and changing its permission/attribute, there are a lot of works to do. -+ -+ -+Add a Branch -+---------------------------------------------------------------------- -+o Confirm the adding dir exists outside of aufs, including loopback -+ mount, and its various attributes. -+o Initialize the xino file and whiteout bases if necessary. -+ See struct.txt. -+ -+o Check the owner/group/mode of the directory -+ When the owner/group/mode of the adding directory differs from the -+ existing branch, aufs issues a warning because it may impose a -+ security risk. -+ For example, when a upper writable branch has a world writable empty -+ top directory, a malicious user can create any files on the writable -+ branch directly, like copy-up and modify manually. If something like -+ /etc/{passwd,shadow} exists on the lower readonly branch but the upper -+ writable branch, and the writable branch is world-writable, then a -+ malicious guy may create /etc/passwd on the writable branch directly -+ and the infected file will be valid in aufs. -+ I am afraid it can be a security issue, but aufs can do nothing except -+ producing a warning. -+ -+ -+Delete a Branch -+---------------------------------------------------------------------- -+o Confirm the deleting branch is not busy -+ To be general, there is one merit to adopt "remount" interface to -+ manipulate branches. It is to discard caches. At deleting a branch, -+ aufs checks the still cached (and connected) dentries and inodes. If -+ there are any, then they are all in-use. An inode without its -+ corresponding dentry can be alive alone (for example, inotify/fsnotify case). -+ -+ For the cached one, aufs checks whether the same named entry exists on -+ other branches. -+ If the cached one is a directory, because aufs provides a merged view -+ to users, as long as one dir is left on any branch aufs can show the -+ dir to users. In this case, the branch can be removed from aufs. -+ Otherwise aufs rejects deleting the branch. -+ -+ If any file on the deleting branch is opened by aufs, then aufs -+ rejects deleting. -+ -+ -+Modify the Permission of a Branch -+---------------------------------------------------------------------- -+o Re-initialize or remove the xino file and whiteout bases if necessary. -+ See struct.txt. -+ -+o rw --> ro: Confirm the modifying branch is not busy -+ Aufs rejects the request if any of these conditions are true. -+ - a file on the branch is mmap-ed. -+ - a regular file on the branch is opened for write and there is no -+ same named entry on the upper branch. -diff --git a/Documentation/filesystems/aufs/design/05wbr_policy.txt b/Documentation/filesystems/aufs/design/05wbr_policy.txt -new file mode 100644 -index 000000000..cc5b7979c ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/05wbr_policy.txt -@@ -0,0 +1,64 @@ -+ -+# Copyright (C) 2005-2018 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Policies to Select One among Multiple Writable Branches -+---------------------------------------------------------------------- -+When the number of writable branch is more than one, aufs has to decide -+the target branch for file creation or copy-up. By default, the highest -+writable branch which has the parent (or ancestor) dir of the target -+file is chosen (top-down-parent policy). -+By user's request, aufs implements some other policies to select the -+writable branch, for file creation several policies, round-robin, -+most-free-space, and other policies. For copy-up, top-down-parent, -+bottom-up-parent, bottom-up and others. -+ -+As expected, the round-robin policy selects the branch in circular. When -+you have two writable branches and creates 10 new files, 5 files will be -+created for each branch. mkdir(2) systemcall is an exception. When you -+create 10 new directories, all will be created on the same branch. -+And the most-free-space policy selects the one which has most free -+space among the writable branches. The amount of free space will be -+checked by aufs internally, and users can specify its time interval. -+ -+The policies for copy-up is more simple, -+top-down-parent is equivalent to the same named on in create policy, -+bottom-up-parent selects the writable branch where the parent dir -+exists and the nearest upper one from the copyup-source, -+bottom-up selects the nearest upper writable branch from the -+copyup-source, regardless the existence of the parent dir. -+ -+There are some rules or exceptions to apply these policies. -+- If there is a readonly branch above the policy-selected branch and -+ the parent dir is marked as opaque (a variation of whiteout), or the -+ target (creating) file is whiteout-ed on the upper readonly branch, -+ then the result of the policy is ignored and the target file will be -+ created on the nearest upper writable branch than the readonly branch. -+- If there is a writable branch above the policy-selected branch and -+ the parent dir is marked as opaque or the target file is whiteouted -+ on the branch, then the result of the policy is ignored and the target -+ file will be created on the highest one among the upper writable -+ branches who has diropq or whiteout. In case of whiteout, aufs removes -+ it as usual. -+- link(2) and rename(2) systemcalls are exceptions in every policy. -+ They try selecting the branch where the source exists as possible -+ since copyup a large file will take long time. If it can't be, -+ ie. the branch where the source exists is readonly, then they will -+ follow the copyup policy. -+- There is an exception for rename(2) when the target exists. -+ If the rename target exists, aufs compares the index of the branches -+ where the source and the target exists and selects the higher -+ one. If the selected branch is readonly, then aufs follows the -+ copyup policy. -diff --git a/Documentation/filesystems/aufs/design/06dirren.dot b/Documentation/filesystems/aufs/design/06dirren.dot -new file mode 100644 -index 000000000..2d62bb6dd ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/06dirren.dot -@@ -0,0 +1,31 @@ -+ -+// to view this graph, run dot(1) command in GRAPHVIZ. -+ -+digraph G { -+node [shape=box]; -+whinfo [label="detailed info file\n(lower_brid_root-hinum, h_inum, namelen, old name)"]; -+ -+node [shape=oval]; -+ -+aufs_rename -> whinfo [label="store/remove"]; -+ -+node [shape=oval]; -+inode_list [label="h_inum list in branch\ncache"]; -+ -+node [shape=box]; -+whinode [label="h_inum list file"]; -+ -+node [shape=oval]; -+brmgmt [label="br_add/del/mod/umount"]; -+ -+brmgmt -> inode_list [label="create/remove"]; -+brmgmt -> whinode [label="load/store"]; -+ -+inode_list -> whinode [style=dashed,dir=both]; -+ -+aufs_rename -> inode_list [label="add/del"]; -+ -+aufs_lookup -> inode_list [label="search"]; -+ -+aufs_lookup -> whinfo [label="load/remove"]; -+} -diff --git a/Documentation/filesystems/aufs/design/06dirren.txt b/Documentation/filesystems/aufs/design/06dirren.txt -new file mode 100644 -index 000000000..1f3cb86d9 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/06dirren.txt -@@ -0,0 +1,102 @@ -+ -+# Copyright (C) 2017-2018 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Special handling for renaming a directory (DIRREN) -+---------------------------------------------------------------------- -+First, let's assume we have a simple usecase. -+ -+- /u = /rw + /ro -+- /rw/dirA exists -+- /ro/dirA and /ro/dirA/file exist too -+- there is no dirB on both branches -+- a user issues rename("dirA", "dirB") -+ -+Now, what should aufs behave against this rename(2)? -+There are a few possible cases. -+ -+A. returns EROFS. -+ since dirA exists on a readonly branch which cannot be renamed. -+B. returns EXDEV. -+ it is possible to copy-up dirA (only the dir itself), but the child -+ entries ("file" in this case) should not be. it must be a bad -+ approach to copy-up recursively. -+C. returns a success. -+ even the branch /ro is readonly, aufs tries renaming it. Obviously it -+ is a violation of aufs' policy. -+D. construct an extra information which indicates that /ro/dirA should -+ be handled as the name of dirB. -+ overlayfs has a similar feature called REDIRECT. -+ -+Until now, aufs implements the case B only which returns EXDEV, and -+expects the userspace application behaves like mv(1) which tries -+issueing rename(2) recursively. -+ -+A new aufs feature called DIRREN is introduced which implements the case -+D. There are several "extra information" added. -+ -+1. detailed info per renamed directory -+ path: /rw/dirB/$AUFS_WH_DR_INFO_PFX. -+2. the inode-number list of directories on a branch -+ path: /rw/dirB/$AUFS_WH_DR_BRHINO -+ -+The filename of "detailed info per directory" represents the lower -+branch, and its format is -+- a type of the branch id -+ one of these. -+ + uuid (not implemented yet) -+ + fsid -+ + dev -+- the inode-number of the branch root dir -+ -+And it contains these info in a single regular file. -+- magic number -+- branch's inode-number of the logically renamed dir -+- the name of the before-renamed dir -+ -+The "detailed info per directory" file is created in aufs rename(2), and -+loaded in any lookup. -+The info is considered in lookup for the matching case only. Here -+"matching" means that the root of branch (in the info filename) is same -+to the current looking-up branch. After looking-up the before-renamed -+name, the inode-number is compared. And the matched dentry is used. -+ -+The "inode-number list of directories" is a regular file which contains -+simply the inode-numbers on the branch. The file is created or updated -+in removing the branch, and loaded in adding the branch. Its lifetime is -+equal to the branch. -+The list is refered in lookup, and when the current target inode is -+found in the list, the aufs tries loading the "detailed info per -+directory" and get the changed and valid name of the dir. -+ -+Theoretically these "extra informaiton" may be able to be put into XATTR -+in the dir inode. But aufs doesn't choose this way because -+1. XATTR may not be supported by the branch (or its configuration) -+2. XATTR may have its size limit. -+3. XATTR may be less easy to convert than a regular file, when the -+ format of the info is changed in the future. -+At the same time, I agree that the regular file approach is much slower -+than XATTR approach. So, in the future, aufs may take the XATTR or other -+better approach. -+ -+This DIRREN feature is enabled by aufs configuration, and is activated -+by a new mount option. -+ -+For the more complicated case, there is a work with UDBA option, which -+is to dected the direct access to the branches (by-passing aufs) and to -+maintain the cashes in aufs. Since a single cached aufs dentry may -+contains two names, before- and after-rename, the name comparision in -+UDBA handler may not work correctly. In this case, the behaviour will be -+equivalen to udba=reval case. -diff --git a/Documentation/filesystems/aufs/design/06fhsm.txt b/Documentation/filesystems/aufs/design/06fhsm.txt -new file mode 100644 -index 000000000..ddfebecdf ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/06fhsm.txt -@@ -0,0 +1,120 @@ -+ -+# Copyright (C) 2011-2018 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ -+ -+File-based Hierarchical Storage Management (FHSM) -+---------------------------------------------------------------------- -+Hierarchical Storage Management (or HSM) is a well-known feature in the -+storage world. Aufs provides this feature as file-based with multiple -+writable branches, based upon the principle of "Colder, the Lower". -+Here the word "colder" means that the less used files, and "lower" means -+that the position in the order of the stacked branches vertically. -+These multiple writable branches are prioritized, ie. the topmost one -+should be the fastest drive and be used heavily. -+ -+o Characters in aufs FHSM story -+- aufs itself and a new branch attribute. -+- a new ioctl interface to move-down and to establish a connection with -+ the daemon ("move-down" is a converse of "copy-up"). -+- userspace tool and daemon. -+ -+The userspace daemon establishes a connection with aufs and waits for -+the notification. The notified information is very similar to struct -+statfs containing the number of consumed blocks and inodes. -+When the consumed blocks/inodes of a branch exceeds the user-specified -+upper watermark, the daemon activates its move-down process until the -+consumed blocks/inodes reaches the user-specified lower watermark. -+ -+The actual move-down is done by aufs based upon the request from -+user-space since we need to maintain the inode number and the internal -+pointer arrays in aufs. -+ -+Currently aufs FHSM handles the regular files only. Additionally they -+must not be hard-linked nor pseudo-linked. -+ -+ -+o Cowork of aufs and the user-space daemon -+ During the userspace daemon established the connection, aufs sends a -+ small notification to it whenever aufs writes something into the -+ writable branch. But it may cost high since aufs issues statfs(2) -+ internally. So user can specify a new option to cache the -+ info. Actually the notification is controlled by these factors. -+ + the specified cache time. -+ + classified as "force" by aufs internally. -+ Until the specified time expires, aufs doesn't send the info -+ except the forced cases. When aufs decide forcing, the info is always -+ notified to userspace. -+ For example, the number of free inodes is generally large enough and -+ the shortage of it happens rarely. So aufs doesn't force the -+ notification when creating a new file, directory and others. This is -+ the typical case which aufs doesn't force. -+ When aufs writes the actual filedata and the files consumes any of new -+ blocks, the aufs forces notifying. -+ -+ -+o Interfaces in aufs -+- New branch attribute. -+ + fhsm -+ Specifies that the branch is managed by FHSM feature. In other word, -+ participant in the FHSM. -+ When nofhsm is set to the branch, it will not be the source/target -+ branch of the move-down operation. This attribute is set -+ independently from coo and moo attributes, and if you want full -+ FHSM, you should specify them as well. -+- New mount option. -+ + fhsm_sec -+ Specifies a second to suppress many less important info to be -+ notified. -+- New ioctl. -+ + AUFS_CTL_FHSM_FD -+ create a new file descriptor which userspace can read the notification -+ (a subset of struct statfs) from aufs. -+- Module parameter 'brs' -+ It has to be set to 1. Otherwise the new mount option 'fhsm' will not -+ be set. -+- mount helpers /sbin/mount.aufs and /sbin/umount.aufs -+ When there are two or more branches with fhsm attributes, -+ /sbin/mount.aufs invokes the user-space daemon and /sbin/umount.aufs -+ terminates it. As a result of remounting and branch-manipulation, the -+ number of branches with fhsm attribute can be one. In this case, -+ /sbin/mount.aufs will terminate the user-space daemon. -+ -+ -+Finally the operation is done as these steps in kernel-space. -+- make sure that, -+ + no one else is using the file. -+ + the file is not hard-linked. -+ + the file is not pseudo-linked. -+ + the file is a regular file. -+ + the parent dir is not opaqued. -+- find the target writable branch. -+- make sure the file is not whiteout-ed by the upper (than the target) -+ branch. -+- make the parent dir on the target branch. -+- mutex lock the inode on the branch. -+- unlink the whiteout on the target branch (if exists). -+- lookup and create the whiteout-ed temporary name on the target branch. -+- copy the file as the whiteout-ed temporary name on the target branch. -+- rename the whiteout-ed temporary name to the original name. -+- unlink the file on the source branch. -+- maintain the internal pointer array and the external inode number -+ table (XINO). -+- maintain the timestamps and other attributes of the parent dir and the -+ file. -+ -+And of course, in every step, an error may happen. So the operation -+should restore the original file state after an error happens. -diff --git a/Documentation/filesystems/aufs/design/06mmap.txt b/Documentation/filesystems/aufs/design/06mmap.txt -new file mode 100644 -index 000000000..9a0a096b1 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/06mmap.txt -@@ -0,0 +1,72 @@ -+ -+# Copyright (C) 2005-2018 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+mmap(2) -- File Memory Mapping -+---------------------------------------------------------------------- -+In aufs, the file-mapped pages are handled by a branch fs directly, no -+interaction with aufs. It means aufs_mmap() calls the branch fs's -+->mmap(). -+This approach is simple and good, but there is one problem. -+Under /proc, several entries show the mmapped files by its path (with -+device and inode number), and the printed path will be the path on the -+branch fs's instead of virtual aufs's. -+This is not a problem in most cases, but some utilities lsof(1) (and its -+user) may expect the path on aufs. -+ -+To address this issue, aufs adds a new member called vm_prfile in struct -+vm_area_struct (and struct vm_region). The original vm_file points to -+the file on the branch fs in order to handle everything correctly as -+usual. The new vm_prfile points to a virtual file in aufs, and the -+show-functions in procfs refers to vm_prfile if it is set. -+Also we need to maintain several other places where touching vm_file -+such like -+- fork()/clone() copies vma and the reference count of vm_file is -+ incremented. -+- merging vma maintains the ref count too. -+ -+This is not a good approach. It just fakes the printed path. But it -+leaves all behaviour around f_mapping unchanged. This is surely an -+advantage. -+Actually aufs had adopted another complicated approach which calls -+generic_file_mmap() and handles struct vm_operations_struct. In this -+approach, aufs met a hard problem and I could not solve it without -+switching the approach. -+ -+There may be one more another approach which is -+- bind-mount the branch-root onto the aufs-root internally -+- grab the new vfsmount (ie. struct mount) -+- lazy-umount the branch-root internally -+- in open(2) the aufs-file, open the branch-file with the hidden -+ vfsmount (instead of the original branch's vfsmount) -+- ideally this "bind-mount and lazy-umount" should be done atomically, -+ but it may be possible from userspace by the mount helper. -+ -+Adding the internal hidden vfsmount and using it in opening a file, the -+file path under /proc will be printed correctly. This approach looks -+smarter, but is not possible I am afraid. -+- aufs-root may be bind-mount later. when it happens, another hidden -+ vfsmount will be required. -+- it is hard to get the chance to bind-mount and lazy-umount -+ + in kernel-space, FS can have vfsmount in open(2) via -+ file->f_path, and aufs can know its vfsmount. But several locks are -+ already acquired, and if aufs tries to bind-mount and lazy-umount -+ here, then it may cause a deadlock. -+ + in user-space, bind-mount doesn't invoke the mount helper. -+- since /proc shows dev and ino, aufs has to give vma these info. it -+ means a new member vm_prinode will be necessary. this is essentially -+ equivalent to vm_prfile described above. -+ -+I have to give up this "looks-smater" approach. -diff --git a/Documentation/filesystems/aufs/design/06xattr.txt b/Documentation/filesystems/aufs/design/06xattr.txt -new file mode 100644 -index 000000000..be441e8d3 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/06xattr.txt -@@ -0,0 +1,96 @@ -+ -+# Copyright (C) 2014-2018 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ -+ -+Listing XATTR/EA and getting the value -+---------------------------------------------------------------------- -+For the inode standard attributes (owner, group, timestamps, etc.), aufs -+shows the values from the topmost existing file. This behaviour is good -+for the non-dir entries since the bahaviour exactly matches the shown -+information. But for the directories, aufs considers all the same named -+entries on the lower branches. Which means, if one of the lower entry -+rejects readdir call, then aufs returns an error even if the topmost -+entry allows it. This behaviour is necessary to respect the branch fs's -+security, but can make users confused since the user-visible standard -+attributes don't match the behaviour. -+To address this issue, aufs has a mount option called dirperm1 which -+checks the permission for the topmost entry only, and ignores the lower -+entry's permission. -+ -+A similar issue can happen around XATTR. -+getxattr(2) and listxattr(2) families behave as if dirperm1 option is -+always set. Otherwise these very unpleasant situation would happen. -+- listxattr(2) may return the duplicated entries. -+- users may not be able to remove or reset the XATTR forever, -+ -+ -+XATTR/EA support in the internal (copy,move)-(up,down) -+---------------------------------------------------------------------- -+Generally the extended attributes of inode are categorized as these. -+- "security" for LSM and capability. -+- "system" for posix ACL, 'acl' mount option is required for the branch -+ fs generally. -+- "trusted" for userspace, CAP_SYS_ADMIN is required. -+- "user" for userspace, 'user_xattr' mount option is required for the -+ branch fs generally. -+ -+Moreover there are some other categories. Aufs handles these rather -+unpopular categories as the ordinary ones, ie. there is no special -+condition nor exception. -+ -+In copy-up, the support for XATTR on the dst branch may differ from the -+src branch. In this case, the copy-up operation will get an error and -+the original user operation which triggered the copy-up will fail. It -+can happen that even all copy-up will fail. -+When both of src and dst branches support XATTR and if an error occurs -+during copying XATTR, then the copy-up should fail obviously. That is a -+good reason and aufs should return an error to userspace. But when only -+the src branch support that XATTR, aufs should not return an error. -+For example, the src branch supports ACL but the dst branch doesn't -+because the dst branch may natively un-support it or temporary -+un-support it due to "noacl" mount option. Of course, the dst branch fs -+may NOT return an error even if the XATTR is not supported. It is -+totally up to the branch fs. -+ -+Anyway when the aufs internal copy-up gets an error from the dst branch -+fs, then aufs tries removing the just copied entry and returns the error -+to the userspace. The worst case of this situation will be all copy-up -+will fail. -+ -+For the copy-up operation, there two basic approaches. -+- copy the specified XATTR only (by category above), and return the -+ error unconditionally if it happens. -+- copy all XATTR, and ignore the error on the specified category only. -+ -+In order to support XATTR and to implement the correct behaviour, aufs -+chooses the latter approach and introduces some new branch attributes, -+"icexsec", "icexsys", "icextr", "icexusr", and "icexoth". -+They correspond to the XATTR namespaces (see above). Additionally, to be -+convenient, "icex" is also provided which means all "icex*" attributes -+are set (here the word "icex" stands for "ignore copy-error on XATTR"). -+ -+The meaning of these attributes is to ignore the error from setting -+XATTR on that branch. -+Note that aufs tries copying all XATTR unconditionally, and ignores the -+error from the dst branch according to the specified attributes. -+ -+Some XATTR may have its default value. The default value may come from -+the parent dir or the environment. If the default value is set at the -+file creating-time, it will be overwritten by copy-up. -+Some contradiction may happen I am afraid. -+Do we need another attribute to stop copying XATTR? I am unsure. For -+now, aufs implements the branch attributes to ignore the error. -diff --git a/Documentation/filesystems/aufs/design/07export.txt b/Documentation/filesystems/aufs/design/07export.txt -new file mode 100644 -index 000000000..bb700cb18 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/07export.txt -@@ -0,0 +1,58 @@ -+ -+# Copyright (C) 2005-2018 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Export Aufs via NFS -+---------------------------------------------------------------------- -+Here is an approach. -+- like xino/xib, add a new file 'xigen' which stores aufs inode -+ generation. -+- iget_locked(): initialize aufs inode generation for a new inode, and -+ store it in xigen file. -+- destroy_inode(): increment aufs inode generation and store it in xigen -+ file. it is necessary even if it is not unlinked, because any data of -+ inode may be changed by UDBA. -+- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise -+ build file handle by -+ + branch id (4 bytes) -+ + superblock generation (4 bytes) -+ + inode number (4 or 8 bytes) -+ + parent dir inode number (4 or 8 bytes) -+ + inode generation (4 bytes)) -+ + return value of exportfs_encode_fh() for the parent on a branch (4 -+ bytes) -+ + file handle for a branch (by exportfs_encode_fh()) -+- fh_to_dentry(): -+ + find the index of a branch from its id in handle, and check it is -+ still exist in aufs. -+ + 1st level: get the inode number from handle and search it in cache. -+ + 2nd level: if not found in cache, get the parent inode number from -+ the handle and search it in cache. and then open the found parent -+ dir, find the matching inode number by vfs_readdir() and get its -+ name, and call lookup_one_len() for the target dentry. -+ + 3rd level: if the parent dir is not cached, call -+ exportfs_decode_fh() for a branch and get the parent on a branch, -+ build a pathname of it, convert it a pathname in aufs, call -+ path_lookup(). now aufs gets a parent dir dentry, then handle it as -+ the 2nd level. -+ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount -+ for every branch, but not itself. to get this, (currently) aufs -+ searches in current->nsproxy->mnt_ns list. it may not be a good -+ idea, but I didn't get other approach. -+ + test the generation of the gotten inode. -+- every inode operation: they may get EBUSY due to UDBA. in this case, -+ convert it into ESTALE for NFSD. -+- readdir(): call lockdep_on/off() because filldir in NFSD calls -+ lookup_one_len(), vfs_getattr(), encode_fh() and others. -diff --git a/Documentation/filesystems/aufs/design/08shwh.txt b/Documentation/filesystems/aufs/design/08shwh.txt -new file mode 100644 -index 000000000..1dad573f6 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/08shwh.txt -@@ -0,0 +1,52 @@ -+ -+# Copyright (C) 2005-2018 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Show Whiteout Mode (shwh) -+---------------------------------------------------------------------- -+Generally aufs hides the name of whiteouts. But in some cases, to show -+them is very useful for users. For instance, creating a new middle layer -+(branch) by merging existing layers. -+ -+(borrowing aufs1 HOW-TO from a user, Michael Towers) -+When you have three branches, -+- Bottom: 'system', squashfs (underlying base system), read-only -+- Middle: 'mods', squashfs, read-only -+- Top: 'overlay', ram (tmpfs), read-write -+ -+The top layer is loaded at boot time and saved at shutdown, to preserve -+the changes made to the system during the session. -+When larger changes have been made, or smaller changes have accumulated, -+the size of the saved top layer data grows. At this point, it would be -+nice to be able to merge the two overlay branches ('mods' and 'overlay') -+and rewrite the 'mods' squashfs, clearing the top layer and thus -+restoring save and load speed. -+ -+This merging is simplified by the use of another aufs mount, of just the -+two overlay branches using the 'shwh' option. -+# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \ -+ aufs /livesys/merge_union -+ -+A merged view of these two branches is then available at -+/livesys/merge_union, and the new feature is that the whiteouts are -+visible! -+Note that in 'shwh' mode the aufs mount must be 'ro', which will disable -+writing to all branches. Also the default mode for all branches is 'ro'. -+It is now possible to save the combined contents of the two overlay -+branches to a new squashfs, e.g.: -+# mksquashfs /livesys/merge_union /path/to/newmods.squash -+ -+This new squashfs archive can be stored on the boot device and the -+initramfs will use it to replace the old one at the next boot. -diff --git a/Documentation/filesystems/aufs/design/10dynop.txt b/Documentation/filesystems/aufs/design/10dynop.txt -new file mode 100644 -index 000000000..710313c08 ---- /dev/null -+++ b/Documentation/filesystems/aufs/design/10dynop.txt -@@ -0,0 +1,47 @@ -+ -+# Copyright (C) 2010-2018 Junjiro R. Okajima -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program. If not, see . -+ -+Dynamically customizable FS operations -+---------------------------------------------------------------------- -+Generally FS operations (struct inode_operations, struct -+address_space_operations, struct file_operations, etc.) are defined as -+"static const", but it never means that FS have only one set of -+operation. Some FS have multiple sets of them. For instance, ext2 has -+three sets, one for XIP, for NOBH, and for normal. -+Since aufs overrides and redirects these operations, sometimes aufs has -+to change its behaviour according to the branch FS type. More importantly -+VFS acts differently if a function (member in the struct) is set or -+not. It means aufs should have several sets of operations and select one -+among them according to the branch FS definition. -+ -+In order to solve this problem and not to affect the behaviour of VFS, -+aufs defines these operations dynamically. For instance, aufs defines -+dummy direct_IO function for struct address_space_operations, but it may -+not be set to the address_space_operations actually. When the branch FS -+doesn't have it, aufs doesn't set it to its address_space_operations -+while the function definition itself is still alive. So the behaviour -+itself will not change, and it will return an error when direct_IO is -+not set. -+ -+The lifetime of these dynamically generated operation object is -+maintained by aufs branch object. When the branch is removed from aufs, -+the reference counter of the object is decremented. When it reaches -+zero, the dynamically generated operation object will be freed. -+ -+This approach is designed to support AIO (io_submit), Direct I/O and -+XIP (DAX) mainly. -+Currently this approach is applied to address_space_operations for -+regular files only. -diff --git a/MAINTAINERS b/MAINTAINERS -index b2f710eee..d21161917 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -2605,6 +2605,19 @@ F: include/linux/audit.h - F: include/uapi/linux/audit.h - F: kernel/audit* - -+AUFS (advanced multi layered unification filesystem) FILESYSTEM -+M: "J. R. Okajima" -+L: linux-unionfs@vger.kernel.org -+L: aufs-users@lists.sourceforge.net (members only) -+W: http://aufs.sourceforge.net -+T: git://github.com/sfjro/aufs4-linux.git -+S: Supported -+F: Documentation/filesystems/aufs/ -+F: Documentation/ABI/testing/debugfs-aufs -+F: Documentation/ABI/testing/sysfs-aufs -+F: fs/aufs/ -+F: include/uapi/linux/aufs_type.h -+ - AUXILIARY DISPLAY DRIVERS - M: Miguel Ojeda Sandonis - S: Maintained -diff --git a/drivers/block/loop.c b/drivers/block/loop.c -index ea9debf59..9e534a36c 100644 ---- a/drivers/block/loop.c -+++ b/drivers/block/loop.c -@@ -739,6 +739,24 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, - return error; - } - -+/* -+ * for AUFS -+ * no get/put for file. -+ */ -+struct file *loop_backing_file(struct super_block *sb) -+{ -+ struct file *ret; -+ struct loop_device *l; -+ -+ ret = NULL; -+ if (MAJOR(sb->s_dev) == LOOP_MAJOR) { -+ l = sb->s_bdev->bd_disk->private_data; -+ ret = l->lo_backing_file; -+ } -+ return ret; -+} -+EXPORT_SYMBOL_GPL(loop_backing_file); -+ - /* loop sysfs attributes */ - - static ssize_t loop_attr_show(struct device *dev, char *page, -diff --git a/fs/Kconfig b/fs/Kconfig -index ac474a61b..284cee954 100644 ---- a/fs/Kconfig -+++ b/fs/Kconfig -@@ -255,6 +255,7 @@ source "fs/pstore/Kconfig" - source "fs/sysv/Kconfig" - source "fs/ufs/Kconfig" - source "fs/exofs/Kconfig" -+source "fs/aufs/Kconfig" - - endif # MISC_FILESYSTEMS - -diff --git a/fs/Makefile b/fs/Makefile -index 293733f61..12d19d0de 100644 ---- a/fs/Makefile -+++ b/fs/Makefile -@@ -128,3 +128,4 @@ obj-y += exofs/ # Multiple modules - obj-$(CONFIG_CEPH_FS) += ceph/ - obj-$(CONFIG_PSTORE) += pstore/ - obj-$(CONFIG_EFIVAR_FS) += efivarfs/ -+obj-$(CONFIG_AUFS_FS) += aufs/ -diff --git a/fs/aufs/Kconfig b/fs/aufs/Kconfig -new file mode 100644 -index 000000000..9f4364257 ---- /dev/null -+++ b/fs/aufs/Kconfig -@@ -0,0 +1,199 @@ -+# SPDX-License-Identifier: GPL-2.0 -+config AUFS_FS -+ tristate "Aufs (Advanced multi layered unification filesystem) support" -+ help -+ Aufs is a stackable unification filesystem such as Unionfs, -+ which unifies several directories and provides a merged single -+ directory. -+ In the early days, aufs was entirely re-designed and -+ re-implemented Unionfs Version 1.x series. Introducing many -+ original ideas, approaches and improvements, it becomes totally -+ different from Unionfs while keeping the basic features. -+ -+if AUFS_FS -+choice -+ prompt "Maximum number of branches" -+ default AUFS_BRANCH_MAX_127 -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+config AUFS_BRANCH_MAX_127 -+ bool "127" -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+config AUFS_BRANCH_MAX_511 -+ bool "511" -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+config AUFS_BRANCH_MAX_1023 -+ bool "1023" -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+config AUFS_BRANCH_MAX_32767 -+ bool "32767" -+ help -+ Specifies the maximum number of branches (or member directories) -+ in a single aufs. The larger value consumes more system -+ resources and has a minor impact to performance. -+endchoice -+ -+config AUFS_SBILIST -+ bool -+ depends on AUFS_MAGIC_SYSRQ || PROC_FS -+ default y -+ help -+ Automatic configuration for internal use. -+ When aufs supports Magic SysRq or /proc, enabled automatically. -+ -+config AUFS_HNOTIFY -+ bool "Detect direct branch access (bypassing aufs)" -+ help -+ If you want to modify files on branches directly, eg. bypassing aufs, -+ and want aufs to detect the changes of them fully, then enable this -+ option and use 'udba=notify' mount option. -+ Currently there is only one available configuration, "fsnotify". -+ It will have a negative impact to the performance. -+ See detail in aufs.5. -+ -+choice -+ prompt "method" if AUFS_HNOTIFY -+ default AUFS_HFSNOTIFY -+config AUFS_HFSNOTIFY -+ bool "fsnotify" -+ select FSNOTIFY -+endchoice -+ -+config AUFS_EXPORT -+ bool "NFS-exportable aufs" -+ depends on EXPORTFS -+ help -+ If you want to export your mounted aufs via NFS, then enable this -+ option. There are several requirements for this configuration. -+ See detail in aufs.5. -+ -+config AUFS_INO_T_64 -+ bool -+ depends on AUFS_EXPORT -+ depends on 64BIT && !(ALPHA || S390) -+ default y -+ help -+ Automatic configuration for internal use. -+ /* typedef unsigned long/int __kernel_ino_t */ -+ /* alpha and s390x are int */ -+ -+config AUFS_XATTR -+ bool "support for XATTR/EA (including Security Labels)" -+ help -+ If your branch fs supports XATTR/EA and you want to make them -+ available in aufs too, then enable this opsion and specify the -+ branch attributes for EA. -+ See detail in aufs.5. -+ -+config AUFS_FHSM -+ bool "File-based Hierarchical Storage Management" -+ help -+ Hierarchical Storage Management (or HSM) is a well-known feature -+ in the storage world. Aufs provides this feature as file-based. -+ with multiple branches. -+ These multiple branches are prioritized, ie. the topmost one -+ should be the fastest drive and be used heavily. -+ -+config AUFS_RDU -+ bool "Readdir in userspace" -+ help -+ Aufs has two methods to provide a merged view for a directory, -+ by a user-space library and by kernel-space natively. The latter -+ is always enabled but sometimes large and slow. -+ If you enable this option, install the library in aufs2-util -+ package, and set some environment variables for your readdir(3), -+ then the work will be handled in user-space which generally -+ shows better performance in most cases. -+ See detail in aufs.5. -+ -+config AUFS_DIRREN -+ bool "Workaround for rename(2)-ing a directory" -+ help -+ By default, aufs returns EXDEV error in renameing a dir who has -+ his child on the lower branch, since it is a bad idea to issue -+ rename(2) internally for every lower branch. But user may not -+ accept this behaviour. So here is a workaround to allow such -+ rename(2) and store some extra infromation on the writable -+ branch. Obviously this costs high (and I don't like it). -+ To use this feature, you need to enable this configuration AND -+ to specify the mount option `dirren.' -+ See details in aufs.5 and the design documents. -+ -+config AUFS_SHWH -+ bool "Show whiteouts" -+ help -+ If you want to make the whiteouts in aufs visible, then enable -+ this option and specify 'shwh' mount option. Although it may -+ sounds like philosophy or something, but in technically it -+ simply shows the name of whiteout with keeping its behaviour. -+ -+config AUFS_BR_RAMFS -+ bool "Ramfs (initramfs/rootfs) as an aufs branch" -+ help -+ If you want to use ramfs as an aufs branch fs, then enable this -+ option. Generally tmpfs is recommended. -+ Aufs prohibited them to be a branch fs by default, because -+ initramfs becomes unusable after switch_root or something -+ generally. If you sets initramfs as an aufs branch and boot your -+ system by switch_root, you will meet a problem easily since the -+ files in initramfs may be inaccessible. -+ Unless you are going to use ramfs as an aufs branch fs without -+ switch_root or something, leave it N. -+ -+config AUFS_BR_FUSE -+ bool "Fuse fs as an aufs branch" -+ depends on FUSE_FS -+ select AUFS_POLL -+ help -+ If you want to use fuse-based userspace filesystem as an aufs -+ branch fs, then enable this option. -+ It implements the internal poll(2) operation which is -+ implemented by fuse only (curretnly). -+ -+config AUFS_POLL -+ bool -+ help -+ Automatic configuration for internal use. -+ -+config AUFS_BR_HFSPLUS -+ bool "Hfsplus as an aufs branch" -+ depends on HFSPLUS_FS -+ default y -+ help -+ If you want to use hfsplus fs as an aufs branch fs, then enable -+ this option. This option introduces a small overhead at -+ copying-up a file on hfsplus. -+ -+config AUFS_BDEV_LOOP -+ bool -+ depends on BLK_DEV_LOOP -+ default y -+ help -+ Automatic configuration for internal use. -+ Convert =[ym] into =y. -+ -+config AUFS_DEBUG -+ bool "Debug aufs" -+ help -+ Enable this to compile aufs internal debug code. -+ It will have a negative impact to the performance. -+ -+config AUFS_MAGIC_SYSRQ -+ bool -+ depends on AUFS_DEBUG && MAGIC_SYSRQ -+ default y -+ help -+ Automatic configuration for internal use. -+ When aufs supports Magic SysRq, enabled automatically. -+endif -diff --git a/fs/aufs/Makefile b/fs/aufs/Makefile -new file mode 100644 -index 000000000..2c819a649 ---- /dev/null -+++ b/fs/aufs/Makefile -@@ -0,0 +1,46 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+include ${src}/magic.mk -+ifeq (${CONFIG_AUFS_FS},m) -+include ${src}/conf.mk -+endif -+-include ${src}/priv_def.mk -+ -+# cf. include/linux/kernel.h -+# enable pr_debug -+ccflags-y += -DDEBUG -+# sparse requires the full pathname -+ifdef M -+ccflags-y += -include ${M}/../../include/uapi/linux/aufs_type.h -+else -+ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h -+endif -+ -+obj-$(CONFIG_AUFS_FS) += aufs.o -+aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \ -+ wkq.o vfsub.o dcsub.o \ -+ cpup.o whout.o wbr_policy.o \ -+ dinfo.o dentry.o \ -+ dynop.o \ -+ finfo.o file.o f_op.o \ -+ dir.o vdir.o \ -+ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \ -+ mvdown.o ioctl.o -+ -+# all are boolean -+aufs-$(CONFIG_PROC_FS) += procfs.o plink.o -+aufs-$(CONFIG_SYSFS) += sysfs.o -+aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o -+aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o -+aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o -+aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o -+aufs-$(CONFIG_AUFS_EXPORT) += export.o -+aufs-$(CONFIG_AUFS_XATTR) += xattr.o -+aufs-$(CONFIG_FS_POSIX_ACL) += posix_acl.o -+aufs-$(CONFIG_AUFS_DIRREN) += dirren.o -+aufs-$(CONFIG_AUFS_FHSM) += fhsm.o -+aufs-$(CONFIG_AUFS_POLL) += poll.o -+aufs-$(CONFIG_AUFS_RDU) += rdu.o -+aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o -+aufs-$(CONFIG_AUFS_DEBUG) += debug.o -+aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o -diff --git a/fs/aufs/aufs.h b/fs/aufs/aufs.h -new file mode 100644 -index 000000000..245691743 ---- /dev/null -+++ b/fs/aufs/aufs.h -@@ -0,0 +1,62 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * all header files -+ */ -+ -+#ifndef __AUFS_H__ -+#define __AUFS_H__ -+ -+#ifdef __KERNEL__ -+ -+#define AuStub(type, name, body, ...) \ -+ static inline type name(__VA_ARGS__) { body; } -+ -+#define AuStubVoid(name, ...) \ -+ AuStub(void, name, , __VA_ARGS__) -+#define AuStubInt0(name, ...) \ -+ AuStub(int, name, return 0, __VA_ARGS__) -+ -+#include "debug.h" -+ -+#include "branch.h" -+#include "cpup.h" -+#include "dcsub.h" -+#include "dbgaufs.h" -+#include "dentry.h" -+#include "dir.h" -+#include "dirren.h" -+#include "dynop.h" -+#include "file.h" -+#include "fstype.h" -+#include "hbl.h" -+#include "inode.h" -+#include "lcnt.h" -+#include "loop.h" -+#include "module.h" -+#include "opts.h" -+#include "rwsem.h" -+#include "super.h" -+#include "sysaufs.h" -+#include "vfsub.h" -+#include "whout.h" -+#include "wkq.h" -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_H__ */ -diff --git a/fs/aufs/branch.c b/fs/aufs/branch.c -new file mode 100644 -index 000000000..2fc6dc1e3 ---- /dev/null -+++ b/fs/aufs/branch.c -@@ -0,0 +1,1422 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * branch management -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+/* -+ * free a single branch -+ */ -+static void au_br_do_free(struct au_branch *br) -+{ -+ int i; -+ struct au_wbr *wbr; -+ struct au_dykey **key; -+ -+ au_hnotify_fin_br(br); -+ /* always, regardless the mount option */ -+ au_dr_hino_free(&br->br_dirren); -+ au_xino_put(br); -+ -+ AuLCntZero(au_lcnt_read(&br->br_nfiles, /*do_rev*/0)); -+ au_lcnt_fin(&br->br_nfiles, /*do_sync*/0); -+ AuLCntZero(au_lcnt_read(&br->br_count, /*do_rev*/0)); -+ au_lcnt_fin(&br->br_count, /*do_sync*/0); -+ -+ wbr = br->br_wbr; -+ if (wbr) { -+ for (i = 0; i < AuBrWh_Last; i++) -+ dput(wbr->wbr_wh[i]); -+ AuDebugOn(atomic_read(&wbr->wbr_wh_running)); -+ AuRwDestroy(&wbr->wbr_wh_rwsem); -+ } -+ -+ if (br->br_fhsm) { -+ au_br_fhsm_fin(br->br_fhsm); -+ kfree(br->br_fhsm); -+ } -+ -+ key = br->br_dykey; -+ for (i = 0; i < AuBrDynOp; i++, key++) -+ if (*key) -+ au_dy_put(*key); -+ else -+ break; -+ -+ /* recursive lock, s_umount of branch's */ -+ /* synchronize_rcu(); */ /* why? */ -+ lockdep_off(); -+ path_put(&br->br_path); -+ lockdep_on(); -+ kfree(wbr); -+ au_lcnt_wait_for_fin(&br->br_nfiles); -+ au_lcnt_wait_for_fin(&br->br_count); -+ /* I don't know why, but percpu_refcount requires this */ -+ /* synchronize_rcu(); */ -+ kfree(br); -+} -+ -+/* -+ * frees all branches -+ */ -+void au_br_free(struct au_sbinfo *sbinfo) -+{ -+ aufs_bindex_t bmax; -+ struct au_branch **br; -+ -+ AuRwMustWriteLock(&sbinfo->si_rwsem); -+ -+ bmax = sbinfo->si_bbot + 1; -+ br = sbinfo->si_branch; -+ while (bmax--) -+ au_br_do_free(*br++); -+} -+ -+/* -+ * find the index of a branch which is specified by @br_id. -+ */ -+int au_br_index(struct super_block *sb, aufs_bindex_t br_id) -+{ -+ aufs_bindex_t bindex, bbot; -+ -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) -+ if (au_sbr_id(sb, bindex) == br_id) -+ return bindex; -+ return -1; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * add a branch -+ */ -+ -+static int test_overlap(struct super_block *sb, struct dentry *h_adding, -+ struct dentry *h_root) -+{ -+ if (unlikely(h_adding == h_root -+ || au_test_loopback_overlap(sb, h_adding))) -+ return 1; -+ if (h_adding->d_sb != h_root->d_sb) -+ return 0; -+ return au_test_subdir(h_adding, h_root) -+ || au_test_subdir(h_root, h_adding); -+} -+ -+/* -+ * returns a newly allocated branch. @new_nbranch is a number of branches -+ * after adding a branch. -+ */ -+static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch, -+ int perm) -+{ -+ struct au_branch *add_branch; -+ struct dentry *root; -+ struct inode *inode; -+ int err; -+ -+ err = -ENOMEM; -+ add_branch = kzalloc(sizeof(*add_branch), GFP_NOFS); -+ if (unlikely(!add_branch)) -+ goto out; -+ add_branch->br_xino = au_xino_alloc(/*nfile*/1); -+ if (unlikely(!add_branch->br_xino)) -+ goto out_br; -+ err = au_hnotify_init_br(add_branch, perm); -+ if (unlikely(err)) -+ goto out_xino; -+ -+ if (au_br_writable(perm)) { -+ /* may be freed separately at changing the branch permission */ -+ add_branch->br_wbr = kzalloc(sizeof(*add_branch->br_wbr), -+ GFP_NOFS); -+ if (unlikely(!add_branch->br_wbr)) -+ goto out_hnotify; -+ } -+ -+ if (au_br_fhsm(perm)) { -+ err = au_fhsm_br_alloc(add_branch); -+ if (unlikely(err)) -+ goto out_wbr; -+ } -+ -+ root = sb->s_root; -+ err = au_sbr_realloc(au_sbi(sb), new_nbranch, /*may_shrink*/0); -+ if (!err) -+ err = au_di_realloc(au_di(root), new_nbranch, /*may_shrink*/0); -+ if (!err) { -+ inode = d_inode(root); -+ err = au_hinode_realloc(au_ii(inode), new_nbranch, -+ /*may_shrink*/0); -+ } -+ if (!err) -+ return add_branch; /* success */ -+ -+out_wbr: -+ kfree(add_branch->br_wbr); -+out_hnotify: -+ au_hnotify_fin_br(add_branch); -+out_xino: -+ au_xino_put(add_branch); -+out_br: -+ kfree(add_branch); -+out: -+ return ERR_PTR(err); -+} -+ -+/* -+ * test if the branch permission is legal or not. -+ */ -+static int test_br(struct inode *inode, int brperm, char *path) -+{ -+ int err; -+ -+ err = (au_br_writable(brperm) && IS_RDONLY(inode)); -+ if (!err) -+ goto out; -+ -+ err = -EINVAL; -+ pr_err("write permission for readonly mount or inode, %s\n", path); -+ -+out: -+ return err; -+} -+ -+/* -+ * returns: -+ * 0: success, the caller will add it -+ * plus: success, it is already unified, the caller should ignore it -+ * minus: error -+ */ -+static int test_add(struct super_block *sb, struct au_opt_add *add, int remount) -+{ -+ int err; -+ aufs_bindex_t bbot, bindex; -+ struct dentry *root, *h_dentry; -+ struct inode *inode, *h_inode; -+ -+ root = sb->s_root; -+ bbot = au_sbbot(sb); -+ if (unlikely(bbot >= 0 -+ && au_find_dbindex(root, add->path.dentry) >= 0)) { -+ err = 1; -+ if (!remount) { -+ err = -EINVAL; -+ pr_err("%s duplicated\n", add->pathname); -+ } -+ goto out; -+ } -+ -+ err = -ENOSPC; /* -E2BIG; */ -+ if (unlikely(AUFS_BRANCH_MAX <= add->bindex -+ || AUFS_BRANCH_MAX - 1 <= bbot)) { -+ pr_err("number of branches exceeded %s\n", add->pathname); -+ goto out; -+ } -+ -+ err = -EDOM; -+ if (unlikely(add->bindex < 0 || bbot + 1 < add->bindex)) { -+ pr_err("bad index %d\n", add->bindex); -+ goto out; -+ } -+ -+ inode = d_inode(add->path.dentry); -+ err = -ENOENT; -+ if (unlikely(!inode->i_nlink)) { -+ pr_err("no existence %s\n", add->pathname); -+ goto out; -+ } -+ -+ err = -EINVAL; -+ if (unlikely(inode->i_sb == sb)) { -+ pr_err("%s must be outside\n", add->pathname); -+ goto out; -+ } -+ -+ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) { -+ pr_err("unsupported filesystem, %s (%s)\n", -+ add->pathname, au_sbtype(inode->i_sb)); -+ goto out; -+ } -+ -+ if (unlikely(inode->i_sb->s_stack_depth)) { -+ pr_err("already stacked, %s (%s)\n", -+ add->pathname, au_sbtype(inode->i_sb)); -+ goto out; -+ } -+ -+ err = test_br(d_inode(add->path.dentry), add->perm, add->pathname); -+ if (unlikely(err)) -+ goto out; -+ -+ if (bbot < 0) -+ return 0; /* success */ -+ -+ err = -EINVAL; -+ for (bindex = 0; bindex <= bbot; bindex++) -+ if (unlikely(test_overlap(sb, add->path.dentry, -+ au_h_dptr(root, bindex)))) { -+ pr_err("%s is overlapped\n", add->pathname); -+ goto out; -+ } -+ -+ err = 0; -+ if (au_opt_test(au_mntflags(sb), WARN_PERM)) { -+ h_dentry = au_h_dptr(root, 0); -+ h_inode = d_inode(h_dentry); -+ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO) -+ || !uid_eq(h_inode->i_uid, inode->i_uid) -+ || !gid_eq(h_inode->i_gid, inode->i_gid)) -+ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n", -+ add->pathname, -+ i_uid_read(inode), i_gid_read(inode), -+ (inode->i_mode & S_IALLUGO), -+ i_uid_read(h_inode), i_gid_read(h_inode), -+ (h_inode->i_mode & S_IALLUGO)); -+ } -+ -+out: -+ return err; -+} -+ -+/* -+ * initialize or clean the whiteouts for an adding branch -+ */ -+static int au_br_init_wh(struct super_block *sb, struct au_branch *br, -+ int new_perm) -+{ -+ int err, old_perm; -+ aufs_bindex_t bindex; -+ struct inode *h_inode; -+ struct au_wbr *wbr; -+ struct au_hinode *hdir; -+ struct dentry *h_dentry; -+ -+ err = vfsub_mnt_want_write(au_br_mnt(br)); -+ if (unlikely(err)) -+ goto out; -+ -+ wbr = br->br_wbr; -+ old_perm = br->br_perm; -+ br->br_perm = new_perm; -+ hdir = NULL; -+ h_inode = NULL; -+ bindex = au_br_index(sb, br->br_id); -+ if (0 <= bindex) { -+ hdir = au_hi(d_inode(sb->s_root), bindex); -+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT); -+ } else { -+ h_dentry = au_br_dentry(br); -+ h_inode = d_inode(h_dentry); -+ inode_lock_nested(h_inode, AuLsc_I_PARENT); -+ } -+ if (!wbr) -+ err = au_wh_init(br, sb); -+ else { -+ wbr_wh_write_lock(wbr); -+ err = au_wh_init(br, sb); -+ wbr_wh_write_unlock(wbr); -+ } -+ if (hdir) -+ au_hn_inode_unlock(hdir); -+ else -+ inode_unlock(h_inode); -+ vfsub_mnt_drop_write(au_br_mnt(br)); -+ br->br_perm = old_perm; -+ -+ if (!err && wbr && !au_br_writable(new_perm)) { -+ kfree(wbr); -+ br->br_wbr = NULL; -+ } -+ -+out: -+ return err; -+} -+ -+static int au_wbr_init(struct au_branch *br, struct super_block *sb, -+ int perm) -+{ -+ int err; -+ struct kstatfs kst; -+ struct au_wbr *wbr; -+ -+ wbr = br->br_wbr; -+ au_rw_init(&wbr->wbr_wh_rwsem); -+ atomic_set(&wbr->wbr_wh_running, 0); -+ -+ /* -+ * a limit for rmdir/rename a dir -+ * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h -+ */ -+ err = vfs_statfs(&br->br_path, &kst); -+ if (unlikely(err)) -+ goto out; -+ err = -EINVAL; -+ if (kst.f_namelen >= NAME_MAX) -+ err = au_br_init_wh(sb, br, perm); -+ else -+ pr_err("%pd(%s), unsupported namelen %ld\n", -+ au_br_dentry(br), -+ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen); -+ -+out: -+ return err; -+} -+ -+/* initialize a new branch */ -+static int au_br_init(struct au_branch *br, struct super_block *sb, -+ struct au_opt_add *add) -+{ -+ int err; -+ struct au_branch *brbase; -+ struct file *xf; -+ struct inode *h_inode; -+ -+ err = 0; -+ br->br_perm = add->perm; -+ br->br_path = add->path; /* set first, path_get() later */ -+ spin_lock_init(&br->br_dykey_lock); -+ au_lcnt_init(&br->br_nfiles, /*release*/NULL); -+ au_lcnt_init(&br->br_count, /*release*/NULL); -+ br->br_id = au_new_br_id(sb); -+ AuDebugOn(br->br_id < 0); -+ -+ /* always, regardless the given option */ -+ err = au_dr_br_init(sb, br, &add->path); -+ if (unlikely(err)) -+ goto out_err; -+ -+ if (au_br_writable(add->perm)) { -+ err = au_wbr_init(br, sb, add->perm); -+ if (unlikely(err)) -+ goto out_err; -+ } -+ -+ if (au_opt_test(au_mntflags(sb), XINO)) { -+ brbase = au_sbr(sb, 0); -+ xf = au_xino_file(brbase->br_xino, /*idx*/-1); -+ AuDebugOn(!xf); -+ h_inode = d_inode(add->path.dentry); -+ err = au_xino_init_br(sb, br, h_inode->i_ino, &xf->f_path); -+ if (unlikely(err)) { -+ AuDebugOn(au_xino_file(br->br_xino, /*idx*/-1)); -+ goto out_err; -+ } -+ } -+ -+ sysaufs_br_init(br); -+ path_get(&br->br_path); -+ goto out; /* success */ -+ -+out_err: -+ memset(&br->br_path, 0, sizeof(br->br_path)); -+out: -+ return err; -+} -+ -+static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex, -+ struct au_branch *br, aufs_bindex_t bbot, -+ aufs_bindex_t amount) -+{ -+ struct au_branch **brp; -+ -+ AuRwMustWriteLock(&sbinfo->si_rwsem); -+ -+ brp = sbinfo->si_branch + bindex; -+ memmove(brp + 1, brp, sizeof(*brp) * amount); -+ *brp = br; -+ sbinfo->si_bbot++; -+ if (unlikely(bbot < 0)) -+ sbinfo->si_bbot = 0; -+} -+ -+static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex, -+ aufs_bindex_t bbot, aufs_bindex_t amount) -+{ -+ struct au_hdentry *hdp; -+ -+ AuRwMustWriteLock(&dinfo->di_rwsem); -+ -+ hdp = au_hdentry(dinfo, bindex); -+ memmove(hdp + 1, hdp, sizeof(*hdp) * amount); -+ au_h_dentry_init(hdp); -+ dinfo->di_bbot++; -+ if (unlikely(bbot < 0)) -+ dinfo->di_btop = 0; -+} -+ -+static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex, -+ aufs_bindex_t bbot, aufs_bindex_t amount) -+{ -+ struct au_hinode *hip; -+ -+ AuRwMustWriteLock(&iinfo->ii_rwsem); -+ -+ hip = au_hinode(iinfo, bindex); -+ memmove(hip + 1, hip, sizeof(*hip) * amount); -+ au_hinode_init(hip); -+ iinfo->ii_bbot++; -+ if (unlikely(bbot < 0)) -+ iinfo->ii_btop = 0; -+} -+ -+static void au_br_do_add(struct super_block *sb, struct au_branch *br, -+ aufs_bindex_t bindex) -+{ -+ struct dentry *root, *h_dentry; -+ struct inode *root_inode, *h_inode; -+ aufs_bindex_t bbot, amount; -+ -+ root = sb->s_root; -+ root_inode = d_inode(root); -+ bbot = au_sbbot(sb); -+ amount = bbot + 1 - bindex; -+ h_dentry = au_br_dentry(br); -+ au_sbilist_lock(); -+ au_br_do_add_brp(au_sbi(sb), bindex, br, bbot, amount); -+ au_br_do_add_hdp(au_di(root), bindex, bbot, amount); -+ au_br_do_add_hip(au_ii(root_inode), bindex, bbot, amount); -+ au_set_h_dptr(root, bindex, dget(h_dentry)); -+ h_inode = d_inode(h_dentry); -+ au_set_h_iptr(root_inode, bindex, au_igrab(h_inode), /*flags*/0); -+ au_sbilist_unlock(); -+} -+ -+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount) -+{ -+ int err; -+ aufs_bindex_t bbot, add_bindex; -+ struct dentry *root, *h_dentry; -+ struct inode *root_inode; -+ struct au_branch *add_branch; -+ -+ root = sb->s_root; -+ root_inode = d_inode(root); -+ IMustLock(root_inode); -+ IiMustWriteLock(root_inode); -+ err = test_add(sb, add, remount); -+ if (unlikely(err < 0)) -+ goto out; -+ if (err) { -+ err = 0; -+ goto out; /* success */ -+ } -+ -+ bbot = au_sbbot(sb); -+ add_branch = au_br_alloc(sb, bbot + 2, add->perm); -+ err = PTR_ERR(add_branch); -+ if (IS_ERR(add_branch)) -+ goto out; -+ -+ err = au_br_init(add_branch, sb, add); -+ if (unlikely(err)) { -+ au_br_do_free(add_branch); -+ goto out; -+ } -+ -+ add_bindex = add->bindex; -+ sysaufs_brs_del(sb, add_bindex); /* remove successors */ -+ au_br_do_add(sb, add_branch, add_bindex); -+ sysaufs_brs_add(sb, add_bindex); /* append successors */ -+ dbgaufs_brs_add(sb, add_bindex, /*topdown*/0); /* rename successors */ -+ -+ h_dentry = add->path.dentry; -+ if (!add_bindex) { -+ au_cpup_attr_all(root_inode, /*force*/1); -+ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes; -+ } else -+ au_add_nlink(root_inode, d_inode(h_dentry)); -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static unsigned long long au_farray_cb(struct super_block *sb, void *a, -+ unsigned long long max __maybe_unused, -+ void *arg) -+{ -+ unsigned long long n; -+ struct file **p, *f; -+ struct hlist_bl_head *files; -+ struct hlist_bl_node *pos; -+ struct au_finfo *finfo; -+ -+ n = 0; -+ p = a; -+ files = &au_sbi(sb)->si_files; -+ hlist_bl_lock(files); -+ hlist_bl_for_each_entry(finfo, pos, files, fi_hlist) { -+ f = finfo->fi_file; -+ if (file_count(f) -+ && !special_file(file_inode(f)->i_mode)) { -+ get_file(f); -+ *p++ = f; -+ n++; -+ AuDebugOn(n > max); -+ } -+ } -+ hlist_bl_unlock(files); -+ -+ return n; -+} -+ -+static struct file **au_farray_alloc(struct super_block *sb, -+ unsigned long long *max) -+{ -+ struct au_sbinfo *sbi; -+ -+ sbi = au_sbi(sb); -+ *max = au_lcnt_read(&sbi->si_nfiles, /*do_rev*/1); -+ return au_array_alloc(max, au_farray_cb, sb, /*arg*/NULL); -+} -+ -+static void au_farray_free(struct file **a, unsigned long long max) -+{ -+ unsigned long long ull; -+ -+ for (ull = 0; ull < max; ull++) -+ if (a[ull]) -+ fput(a[ull]); -+ kvfree(a); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * delete a branch -+ */ -+ -+/* to show the line number, do not make it inlined function */ -+#define AuVerbose(do_info, fmt, ...) do { \ -+ if (do_info) \ -+ pr_info(fmt, ##__VA_ARGS__); \ -+} while (0) -+ -+static int au_test_ibusy(struct inode *inode, aufs_bindex_t btop, -+ aufs_bindex_t bbot) -+{ -+ return (inode && !S_ISDIR(inode->i_mode)) || btop == bbot; -+} -+ -+static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t btop, -+ aufs_bindex_t bbot) -+{ -+ return au_test_ibusy(d_inode(dentry), btop, bbot); -+} -+ -+/* -+ * test if the branch is deletable or not. -+ */ -+static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex, -+ unsigned int sigen, const unsigned int verbose) -+{ -+ int err, i, j, ndentry; -+ aufs_bindex_t btop, bbot; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry *d; -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_dcsub_pages(&dpages, root, NULL, NULL); -+ if (unlikely(err)) -+ goto out_dpages; -+ -+ for (i = 0; !err && i < dpages.ndpage; i++) { -+ dpage = dpages.dpages + i; -+ ndentry = dpage->ndentry; -+ for (j = 0; !err && j < ndentry; j++) { -+ d = dpage->dentries[j]; -+ AuDebugOn(au_dcount(d) <= 0); -+ if (!au_digen_test(d, sigen)) { -+ di_read_lock_child(d, AuLock_IR); -+ if (unlikely(au_dbrange_test(d))) { -+ di_read_unlock(d, AuLock_IR); -+ continue; -+ } -+ } else { -+ di_write_lock_child(d); -+ if (unlikely(au_dbrange_test(d))) { -+ di_write_unlock(d); -+ continue; -+ } -+ err = au_reval_dpath(d, sigen); -+ if (!err) -+ di_downgrade_lock(d, AuLock_IR); -+ else { -+ di_write_unlock(d); -+ break; -+ } -+ } -+ -+ /* AuDbgDentry(d); */ -+ btop = au_dbtop(d); -+ bbot = au_dbbot(d); -+ if (btop <= bindex -+ && bindex <= bbot -+ && au_h_dptr(d, bindex) -+ && au_test_dbusy(d, btop, bbot)) { -+ err = -EBUSY; -+ AuVerbose(verbose, "busy %pd\n", d); -+ AuDbgDentry(d); -+ } -+ di_read_unlock(d, AuLock_IR); -+ } -+ } -+ -+out_dpages: -+ au_dpages_free(&dpages); -+out: -+ return err; -+} -+ -+static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex, -+ unsigned int sigen, const unsigned int verbose) -+{ -+ int err; -+ unsigned long long max, ull; -+ struct inode *i, **array; -+ aufs_bindex_t btop, bbot; -+ -+ array = au_iarray_alloc(sb, &max); -+ err = PTR_ERR(array); -+ if (IS_ERR(array)) -+ goto out; -+ -+ err = 0; -+ AuDbg("b%d\n", bindex); -+ for (ull = 0; !err && ull < max; ull++) { -+ i = array[ull]; -+ if (unlikely(!i)) -+ break; -+ if (i->i_ino == AUFS_ROOT_INO) -+ continue; -+ -+ /* AuDbgInode(i); */ -+ if (au_iigen(i, NULL) == sigen) -+ ii_read_lock_child(i); -+ else { -+ ii_write_lock_child(i); -+ err = au_refresh_hinode_self(i); -+ au_iigen_dec(i); -+ if (!err) -+ ii_downgrade_lock(i); -+ else { -+ ii_write_unlock(i); -+ break; -+ } -+ } -+ -+ btop = au_ibtop(i); -+ bbot = au_ibbot(i); -+ if (btop <= bindex -+ && bindex <= bbot -+ && au_h_iptr(i, bindex) -+ && au_test_ibusy(i, btop, bbot)) { -+ err = -EBUSY; -+ AuVerbose(verbose, "busy i%lu\n", i->i_ino); -+ AuDbgInode(i); -+ } -+ ii_read_unlock(i); -+ } -+ au_iarray_free(array, max); -+ -+out: -+ return err; -+} -+ -+static int test_children_busy(struct dentry *root, aufs_bindex_t bindex, -+ const unsigned int verbose) -+{ -+ int err; -+ unsigned int sigen; -+ -+ sigen = au_sigen(root->d_sb); -+ DiMustNoWaiters(root); -+ IiMustNoWaiters(d_inode(root)); -+ di_write_unlock(root); -+ err = test_dentry_busy(root, bindex, sigen, verbose); -+ if (!err) -+ err = test_inode_busy(root->d_sb, bindex, sigen, verbose); -+ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */ -+ -+ return err; -+} -+ -+static int test_dir_busy(struct file *file, aufs_bindex_t br_id, -+ struct file **to_free, int *idx) -+{ -+ int err; -+ unsigned char matched, root; -+ aufs_bindex_t bindex, bbot; -+ struct au_fidir *fidir; -+ struct au_hfile *hfile; -+ -+ err = 0; -+ root = IS_ROOT(file->f_path.dentry); -+ if (root) { -+ get_file(file); -+ to_free[*idx] = file; -+ (*idx)++; -+ goto out; -+ } -+ -+ matched = 0; -+ fidir = au_fi(file)->fi_hdir; -+ AuDebugOn(!fidir); -+ bbot = au_fbbot_dir(file); -+ for (bindex = au_fbtop(file); bindex <= bbot; bindex++) { -+ hfile = fidir->fd_hfile + bindex; -+ if (!hfile->hf_file) -+ continue; -+ -+ if (hfile->hf_br->br_id == br_id) { -+ matched = 1; -+ break; -+ } -+ } -+ if (matched) -+ err = -EBUSY; -+ -+out: -+ return err; -+} -+ -+static int test_file_busy(struct super_block *sb, aufs_bindex_t br_id, -+ struct file **to_free, int opened) -+{ -+ int err, idx; -+ unsigned long long ull, max; -+ aufs_bindex_t btop; -+ struct file *file, **array; -+ struct dentry *root; -+ struct au_hfile *hfile; -+ -+ array = au_farray_alloc(sb, &max); -+ err = PTR_ERR(array); -+ if (IS_ERR(array)) -+ goto out; -+ -+ err = 0; -+ idx = 0; -+ root = sb->s_root; -+ di_write_unlock(root); -+ for (ull = 0; ull < max; ull++) { -+ file = array[ull]; -+ if (unlikely(!file)) -+ break; -+ -+ /* AuDbg("%pD\n", file); */ -+ fi_read_lock(file); -+ btop = au_fbtop(file); -+ if (!d_is_dir(file->f_path.dentry)) { -+ hfile = &au_fi(file)->fi_htop; -+ if (hfile->hf_br->br_id == br_id) -+ err = -EBUSY; -+ } else -+ err = test_dir_busy(file, br_id, to_free, &idx); -+ fi_read_unlock(file); -+ if (unlikely(err)) -+ break; -+ } -+ di_write_lock_child(root); -+ au_farray_free(array, max); -+ AuDebugOn(idx > opened); -+ -+out: -+ return err; -+} -+ -+static void br_del_file(struct file **to_free, unsigned long long opened, -+ aufs_bindex_t br_id) -+{ -+ unsigned long long ull; -+ aufs_bindex_t bindex, btop, bbot, bfound; -+ struct file *file; -+ struct au_fidir *fidir; -+ struct au_hfile *hfile; -+ -+ for (ull = 0; ull < opened; ull++) { -+ file = to_free[ull]; -+ if (unlikely(!file)) -+ break; -+ -+ /* AuDbg("%pD\n", file); */ -+ AuDebugOn(!d_is_dir(file->f_path.dentry)); -+ bfound = -1; -+ fidir = au_fi(file)->fi_hdir; -+ AuDebugOn(!fidir); -+ fi_write_lock(file); -+ btop = au_fbtop(file); -+ bbot = au_fbbot_dir(file); -+ for (bindex = btop; bindex <= bbot; bindex++) { -+ hfile = fidir->fd_hfile + bindex; -+ if (!hfile->hf_file) -+ continue; -+ -+ if (hfile->hf_br->br_id == br_id) { -+ bfound = bindex; -+ break; -+ } -+ } -+ AuDebugOn(bfound < 0); -+ au_set_h_fptr(file, bfound, NULL); -+ if (bfound == btop) { -+ for (btop++; btop <= bbot; btop++) -+ if (au_hf_dir(file, btop)) { -+ au_set_fbtop(file, btop); -+ break; -+ } -+ } -+ fi_write_unlock(file); -+ } -+} -+ -+static void au_br_do_del_brp(struct au_sbinfo *sbinfo, -+ const aufs_bindex_t bindex, -+ const aufs_bindex_t bbot) -+{ -+ struct au_branch **brp, **p; -+ -+ AuRwMustWriteLock(&sbinfo->si_rwsem); -+ -+ brp = sbinfo->si_branch + bindex; -+ if (bindex < bbot) -+ memmove(brp, brp + 1, sizeof(*brp) * (bbot - bindex)); -+ sbinfo->si_branch[0 + bbot] = NULL; -+ sbinfo->si_bbot--; -+ -+ p = au_krealloc(sbinfo->si_branch, sizeof(*p) * bbot, AuGFP_SBILIST, -+ /*may_shrink*/1); -+ if (p) -+ sbinfo->si_branch = p; -+ /* harmless error */ -+} -+ -+static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex, -+ const aufs_bindex_t bbot) -+{ -+ struct au_hdentry *hdp, *p; -+ -+ AuRwMustWriteLock(&dinfo->di_rwsem); -+ -+ hdp = au_hdentry(dinfo, bindex); -+ if (bindex < bbot) -+ memmove(hdp, hdp + 1, sizeof(*hdp) * (bbot - bindex)); -+ /* au_h_dentry_init(au_hdentry(dinfo, bbot); */ -+ dinfo->di_bbot--; -+ -+ p = au_krealloc(dinfo->di_hdentry, sizeof(*p) * bbot, AuGFP_SBILIST, -+ /*may_shrink*/1); -+ if (p) -+ dinfo->di_hdentry = p; -+ /* harmless error */ -+} -+ -+static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex, -+ const aufs_bindex_t bbot) -+{ -+ struct au_hinode *hip, *p; -+ -+ AuRwMustWriteLock(&iinfo->ii_rwsem); -+ -+ hip = au_hinode(iinfo, bindex); -+ if (bindex < bbot) -+ memmove(hip, hip + 1, sizeof(*hip) * (bbot - bindex)); -+ /* au_hinode_init(au_hinode(iinfo, bbot)); */ -+ iinfo->ii_bbot--; -+ -+ p = au_krealloc(iinfo->ii_hinode, sizeof(*p) * bbot, AuGFP_SBILIST, -+ /*may_shrink*/1); -+ if (p) -+ iinfo->ii_hinode = p; -+ /* harmless error */ -+} -+ -+static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex, -+ struct au_branch *br) -+{ -+ aufs_bindex_t bbot; -+ struct au_sbinfo *sbinfo; -+ struct dentry *root, *h_root; -+ struct inode *inode, *h_inode; -+ struct au_hinode *hinode; -+ -+ SiMustWriteLock(sb); -+ -+ root = sb->s_root; -+ inode = d_inode(root); -+ sbinfo = au_sbi(sb); -+ bbot = sbinfo->si_bbot; -+ -+ h_root = au_h_dptr(root, bindex); -+ hinode = au_hi(inode, bindex); -+ h_inode = au_igrab(hinode->hi_inode); -+ au_hiput(hinode); -+ -+ au_sbilist_lock(); -+ au_br_do_del_brp(sbinfo, bindex, bbot); -+ au_br_do_del_hdp(au_di(root), bindex, bbot); -+ au_br_do_del_hip(au_ii(inode), bindex, bbot); -+ au_sbilist_unlock(); -+ -+ /* ignore an error */ -+ au_dr_br_fin(sb, br); /* always, regardless the mount option */ -+ -+ dput(h_root); -+ iput(h_inode); -+ au_br_do_free(br); -+} -+ -+static unsigned long long empty_cb(struct super_block *sb, void *array, -+ unsigned long long max, void *arg) -+{ -+ return max; -+} -+ -+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount) -+{ -+ int err, rerr, i; -+ unsigned long long opened; -+ unsigned int mnt_flags; -+ aufs_bindex_t bindex, bbot, br_id; -+ unsigned char do_wh, verbose; -+ struct au_branch *br; -+ struct au_wbr *wbr; -+ struct dentry *root; -+ struct file **to_free; -+ -+ err = 0; -+ opened = 0; -+ to_free = NULL; -+ root = sb->s_root; -+ bindex = au_find_dbindex(root, del->h_path.dentry); -+ if (bindex < 0) { -+ if (remount) -+ goto out; /* success */ -+ err = -ENOENT; -+ pr_err("%s no such branch\n", del->pathname); -+ goto out; -+ } -+ AuDbg("bindex b%d\n", bindex); -+ -+ err = -EBUSY; -+ mnt_flags = au_mntflags(sb); -+ verbose = !!au_opt_test(mnt_flags, VERBOSE); -+ bbot = au_sbbot(sb); -+ if (unlikely(!bbot)) { -+ AuVerbose(verbose, "no more branches left\n"); -+ goto out; -+ } -+ -+ br = au_sbr(sb, bindex); -+ AuDebugOn(!path_equal(&br->br_path, &del->h_path)); -+ if (unlikely(au_lcnt_read(&br->br_count, /*do_rev*/1))) { -+ AuVerbose(verbose, "br %pd2 is busy now\n", del->h_path.dentry); -+ goto out; -+ } -+ -+ br_id = br->br_id; -+ opened = au_lcnt_read(&br->br_nfiles, /*do_rev*/1); -+ if (unlikely(opened)) { -+ to_free = au_array_alloc(&opened, empty_cb, sb, NULL); -+ err = PTR_ERR(to_free); -+ if (IS_ERR(to_free)) -+ goto out; -+ -+ err = test_file_busy(sb, br_id, to_free, opened); -+ if (unlikely(err)) { -+ AuVerbose(verbose, "%llu file(s) opened\n", opened); -+ goto out; -+ } -+ } -+ -+ wbr = br->br_wbr; -+ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph); -+ if (do_wh) { -+ /* instead of WbrWhMustWriteLock(wbr) */ -+ SiMustWriteLock(sb); -+ for (i = 0; i < AuBrWh_Last; i++) { -+ dput(wbr->wbr_wh[i]); -+ wbr->wbr_wh[i] = NULL; -+ } -+ } -+ -+ err = test_children_busy(root, bindex, verbose); -+ if (unlikely(err)) { -+ if (do_wh) -+ goto out_wh; -+ goto out; -+ } -+ -+ err = 0; -+ if (to_free) { -+ /* -+ * now we confirmed the branch is deletable. -+ * let's free the remaining opened dirs on the branch. -+ */ -+ di_write_unlock(root); -+ br_del_file(to_free, opened, br_id); -+ di_write_lock_child(root); -+ } -+ -+ sysaufs_brs_del(sb, bindex); /* remove successors */ -+ dbgaufs_xino_del(br); /* remove one */ -+ au_br_do_del(sb, bindex, br); -+ sysaufs_brs_add(sb, bindex); /* append successors */ -+ dbgaufs_brs_add(sb, bindex, /*topdown*/1); /* rename successors */ -+ -+ if (!bindex) { -+ au_cpup_attr_all(d_inode(root), /*force*/1); -+ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes; -+ } else -+ au_sub_nlink(d_inode(root), d_inode(del->h_path.dentry)); -+ if (au_opt_test(mnt_flags, PLINK)) -+ au_plink_half_refresh(sb, br_id); -+ -+ goto out; /* success */ -+ -+out_wh: -+ /* revert */ -+ rerr = au_br_init_wh(sb, br, br->br_perm); -+ if (rerr) -+ pr_warn("failed re-creating base whiteout, %s. (%d)\n", -+ del->pathname, rerr); -+out: -+ if (to_free) -+ au_farray_free(to_free, opened); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg) -+{ -+ int err; -+ aufs_bindex_t btop, bbot; -+ struct aufs_ibusy ibusy; -+ struct inode *inode, *h_inode; -+ -+ err = -EPERM; -+ if (unlikely(!capable(CAP_SYS_ADMIN))) -+ goto out; -+ -+ err = copy_from_user(&ibusy, arg, sizeof(ibusy)); -+ if (!err) -+ err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ goto out; -+ } -+ -+ err = -EINVAL; -+ si_read_lock(sb, AuLock_FLUSH); -+ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbbot(sb))) -+ goto out_unlock; -+ -+ err = 0; -+ ibusy.h_ino = 0; /* invalid */ -+ inode = ilookup(sb, ibusy.ino); -+ if (!inode -+ || inode->i_ino == AUFS_ROOT_INO -+ || au_is_bad_inode(inode)) -+ goto out_unlock; -+ -+ ii_read_lock_child(inode); -+ btop = au_ibtop(inode); -+ bbot = au_ibbot(inode); -+ if (btop <= ibusy.bindex && ibusy.bindex <= bbot) { -+ h_inode = au_h_iptr(inode, ibusy.bindex); -+ if (h_inode && au_test_ibusy(inode, btop, bbot)) -+ ibusy.h_ino = h_inode->i_ino; -+ } -+ ii_read_unlock(inode); -+ iput(inode); -+ -+out_unlock: -+ si_read_unlock(sb); -+ if (!err) { -+ err = __put_user(ibusy.h_ino, &arg->h_ino); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ } -+ } -+out: -+ return err; -+} -+ -+long au_ibusy_ioctl(struct file *file, unsigned long arg) -+{ -+ return au_ibusy(file->f_path.dentry->d_sb, (void __user *)arg); -+} -+ -+#ifdef CONFIG_COMPAT -+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg) -+{ -+ return au_ibusy(file->f_path.dentry->d_sb, compat_ptr(arg)); -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * change a branch permission -+ */ -+ -+static void au_warn_ima(void) -+{ -+#ifdef CONFIG_IMA -+ /* since it doesn't support mark_files_ro() */ -+ AuWarn1("RW -> RO makes IMA to produce wrong message\n"); -+#endif -+} -+ -+static int do_need_sigen_inc(int a, int b) -+{ -+ return au_br_whable(a) && !au_br_whable(b); -+} -+ -+static int need_sigen_inc(int old, int new) -+{ -+ return do_need_sigen_inc(old, new) -+ || do_need_sigen_inc(new, old); -+} -+ -+static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ int err, do_warn; -+ unsigned int mnt_flags; -+ unsigned long long ull, max; -+ aufs_bindex_t br_id; -+ unsigned char verbose, writer; -+ struct file *file, *hf, **array; -+ struct au_hfile *hfile; -+ -+ mnt_flags = au_mntflags(sb); -+ verbose = !!au_opt_test(mnt_flags, VERBOSE); -+ -+ array = au_farray_alloc(sb, &max); -+ err = PTR_ERR(array); -+ if (IS_ERR(array)) -+ goto out; -+ -+ do_warn = 0; -+ br_id = au_sbr_id(sb, bindex); -+ for (ull = 0; ull < max; ull++) { -+ file = array[ull]; -+ if (unlikely(!file)) -+ break; -+ -+ /* AuDbg("%pD\n", file); */ -+ fi_read_lock(file); -+ if (unlikely(au_test_mmapped(file))) { -+ err = -EBUSY; -+ AuVerbose(verbose, "mmapped %pD\n", file); -+ AuDbgFile(file); -+ FiMustNoWaiters(file); -+ fi_read_unlock(file); -+ goto out_array; -+ } -+ -+ hfile = &au_fi(file)->fi_htop; -+ hf = hfile->hf_file; -+ if (!d_is_reg(file->f_path.dentry) -+ || !(file->f_mode & FMODE_WRITE) -+ || hfile->hf_br->br_id != br_id -+ || !(hf->f_mode & FMODE_WRITE)) -+ array[ull] = NULL; -+ else { -+ do_warn = 1; -+ get_file(file); -+ } -+ -+ FiMustNoWaiters(file); -+ fi_read_unlock(file); -+ fput(file); -+ } -+ -+ err = 0; -+ if (do_warn) -+ au_warn_ima(); -+ -+ for (ull = 0; ull < max; ull++) { -+ file = array[ull]; -+ if (!file) -+ continue; -+ -+ /* todo: already flushed? */ -+ /* -+ * fs/super.c:mark_files_ro() is gone, but aufs keeps its -+ * approach which resets f_mode and calls mnt_drop_write() and -+ * file_release_write() for each file, because the branch -+ * attribute in aufs world is totally different from the native -+ * fs rw/ro mode. -+ */ -+ /* fi_read_lock(file); */ -+ hfile = &au_fi(file)->fi_htop; -+ hf = hfile->hf_file; -+ /* fi_read_unlock(file); */ -+ spin_lock(&hf->f_lock); -+ writer = !!(hf->f_mode & FMODE_WRITER); -+ hf->f_mode &= ~(FMODE_WRITE | FMODE_WRITER); -+ spin_unlock(&hf->f_lock); -+ if (writer) { -+ put_write_access(file_inode(hf)); -+ __mnt_drop_write(hf->f_path.mnt); -+ } -+ } -+ -+out_array: -+ au_farray_free(array, max); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, -+ int *do_refresh) -+{ -+ int err, rerr; -+ aufs_bindex_t bindex; -+ struct dentry *root; -+ struct au_branch *br; -+ struct au_br_fhsm *bf; -+ -+ root = sb->s_root; -+ bindex = au_find_dbindex(root, mod->h_root); -+ if (bindex < 0) { -+ if (remount) -+ return 0; /* success */ -+ err = -ENOENT; -+ pr_err("%s no such branch\n", mod->path); -+ goto out; -+ } -+ AuDbg("bindex b%d\n", bindex); -+ -+ err = test_br(d_inode(mod->h_root), mod->perm, mod->path); -+ if (unlikely(err)) -+ goto out; -+ -+ br = au_sbr(sb, bindex); -+ AuDebugOn(mod->h_root != au_br_dentry(br)); -+ if (br->br_perm == mod->perm) -+ return 0; /* success */ -+ -+ /* pre-allocate for non-fhsm --> fhsm */ -+ bf = NULL; -+ if (!au_br_fhsm(br->br_perm) && au_br_fhsm(mod->perm)) { -+ err = au_fhsm_br_alloc(br); -+ if (unlikely(err)) -+ goto out; -+ bf = br->br_fhsm; -+ br->br_fhsm = NULL; -+ } -+ -+ if (au_br_writable(br->br_perm)) { -+ /* remove whiteout base */ -+ err = au_br_init_wh(sb, br, mod->perm); -+ if (unlikely(err)) -+ goto out_bf; -+ -+ if (!au_br_writable(mod->perm)) { -+ /* rw --> ro, file might be mmapped */ -+ DiMustNoWaiters(root); -+ IiMustNoWaiters(d_inode(root)); -+ di_write_unlock(root); -+ err = au_br_mod_files_ro(sb, bindex); -+ /* aufs_write_lock() calls ..._child() */ -+ di_write_lock_child(root); -+ -+ if (unlikely(err)) { -+ rerr = -ENOMEM; -+ br->br_wbr = kzalloc(sizeof(*br->br_wbr), -+ GFP_NOFS); -+ if (br->br_wbr) -+ rerr = au_wbr_init(br, sb, br->br_perm); -+ if (unlikely(rerr)) { -+ AuIOErr("nested error %d (%d)\n", -+ rerr, err); -+ br->br_perm = mod->perm; -+ } -+ } -+ } -+ } else if (au_br_writable(mod->perm)) { -+ /* ro --> rw */ -+ err = -ENOMEM; -+ br->br_wbr = kzalloc(sizeof(*br->br_wbr), GFP_NOFS); -+ if (br->br_wbr) { -+ err = au_wbr_init(br, sb, mod->perm); -+ if (unlikely(err)) { -+ kfree(br->br_wbr); -+ br->br_wbr = NULL; -+ } -+ } -+ } -+ if (unlikely(err)) -+ goto out_bf; -+ -+ if (au_br_fhsm(br->br_perm)) { -+ if (!au_br_fhsm(mod->perm)) { -+ /* fhsm --> non-fhsm */ -+ au_br_fhsm_fin(br->br_fhsm); -+ kfree(br->br_fhsm); -+ br->br_fhsm = NULL; -+ } -+ } else if (au_br_fhsm(mod->perm)) -+ /* non-fhsm --> fhsm */ -+ br->br_fhsm = bf; -+ -+ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm); -+ br->br_perm = mod->perm; -+ goto out; /* success */ -+ -+out_bf: -+ kfree(bf); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs) -+{ -+ int err; -+ struct kstatfs kstfs; -+ -+ err = vfs_statfs(&br->br_path, &kstfs); -+ if (!err) { -+ stfs->f_blocks = kstfs.f_blocks; -+ stfs->f_bavail = kstfs.f_bavail; -+ stfs->f_files = kstfs.f_files; -+ stfs->f_ffree = kstfs.f_ffree; -+ } -+ -+ return err; -+} -diff --git a/fs/aufs/branch.h b/fs/aufs/branch.h -new file mode 100644 -index 000000000..2b0f58bb9 ---- /dev/null -+++ b/fs/aufs/branch.h -@@ -0,0 +1,367 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * branch filesystems and xino for them -+ */ -+ -+#ifndef __AUFS_BRANCH_H__ -+#define __AUFS_BRANCH_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include "dirren.h" -+#include "dynop.h" -+#include "lcnt.h" -+#include "rwsem.h" -+#include "super.h" -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* a xino file */ -+struct au_xino { -+ struct file **xi_file; -+ unsigned int xi_nfile; -+ -+ struct { -+ spinlock_t spin; -+ ino_t *array; -+ int total; -+ /* reserved for future use */ -+ /* unsigned long *bitmap; */ -+ wait_queue_head_t wqh; -+ } xi_nondir; -+ -+ struct mutex xi_mtx; /* protects xi_file array */ -+ /* reserved for future use */ -+ /* wait_queue_head_t xi_wq; */ -+ /* atomic_t xi_pending; */ -+ -+ atomic_t xi_truncating; -+ -+ struct kref xi_kref; -+}; -+ -+/* File-based Hierarchical Storage Management */ -+struct au_br_fhsm { -+#ifdef CONFIG_AUFS_FHSM -+ struct mutex bf_lock; -+ unsigned long bf_jiffy; -+ struct aufs_stfs bf_stfs; -+ int bf_readable; -+#endif -+}; -+ -+/* members for writable branch only */ -+enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last}; -+struct au_wbr { -+ struct au_rwsem wbr_wh_rwsem; -+ struct dentry *wbr_wh[AuBrWh_Last]; -+ atomic_t wbr_wh_running; -+#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */ -+#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */ -+#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */ -+ -+ /* mfs mode */ -+ unsigned long long wbr_bytes; -+}; -+ -+/* ext2 has 3 types of operations at least, ext3 has 4 */ -+#define AuBrDynOp (AuDyLast * 4) -+ -+#ifdef CONFIG_AUFS_HFSNOTIFY -+/* support for asynchronous destruction */ -+struct au_br_hfsnotify { -+ struct fsnotify_group *hfsn_group; -+}; -+#endif -+ -+/* sysfs entries */ -+struct au_brsysfs { -+ char name[16]; -+ struct attribute attr; -+}; -+ -+enum { -+ AuBrSysfs_BR, -+ AuBrSysfs_BRID, -+ AuBrSysfs_Last -+}; -+ -+/* protected by superblock rwsem */ -+struct au_branch { -+ struct au_xino *br_xino; -+ -+ aufs_bindex_t br_id; -+ -+ int br_perm; -+ struct path br_path; -+ spinlock_t br_dykey_lock; -+ struct au_dykey *br_dykey[AuBrDynOp]; -+ au_lcnt_t br_nfiles; /* opened files */ -+ au_lcnt_t br_count; /* in-use for other */ -+ -+ struct au_wbr *br_wbr; -+ struct au_br_fhsm *br_fhsm; -+ -+#ifdef CONFIG_AUFS_HFSNOTIFY -+ struct au_br_hfsnotify *br_hfsn; -+#endif -+ -+#ifdef CONFIG_SYSFS -+ /* entries under sysfs per mount-point */ -+ struct au_brsysfs br_sysfs[AuBrSysfs_Last]; -+#endif -+ -+#ifdef CONFIG_DEBUG_FS -+ struct dentry *br_dbgaufs; /* xino */ -+#endif -+ -+ struct au_dr_br br_dirren; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct vfsmount *au_br_mnt(struct au_branch *br) -+{ -+ return br->br_path.mnt; -+} -+ -+static inline struct dentry *au_br_dentry(struct au_branch *br) -+{ -+ return br->br_path.dentry; -+} -+ -+static inline struct super_block *au_br_sb(struct au_branch *br) -+{ -+ return au_br_mnt(br)->mnt_sb; -+} -+ -+static inline int au_br_rdonly(struct au_branch *br) -+{ -+ return (sb_rdonly(au_br_sb(br)) -+ || !au_br_writable(br->br_perm)) -+ ? -EROFS : 0; -+} -+ -+static inline int au_br_hnotifyable(int brperm __maybe_unused) -+{ -+#ifdef CONFIG_AUFS_HNOTIFY -+ return !(brperm & AuBrPerm_RR); -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_br_test_oflag(int oflag, struct au_branch *br) -+{ -+ int err, exec_flag; -+ -+ err = 0; -+ exec_flag = oflag & __FMODE_EXEC; -+ if (unlikely(exec_flag && path_noexec(&br->br_path))) -+ err = -EACCES; -+ -+ return err; -+} -+ -+static inline void au_xino_get(struct au_branch *br) -+{ -+ struct au_xino *xi; -+ -+ xi = br->br_xino; -+ if (xi) -+ kref_get(&xi->xi_kref); -+} -+ -+static inline int au_xino_count(struct au_branch *br) -+{ -+ int v; -+ struct au_xino *xi; -+ -+ v = 0; -+ xi = br->br_xino; -+ if (xi) -+ v = kref_read(&xi->xi_kref); -+ -+ return v; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* branch.c */ -+struct au_sbinfo; -+void au_br_free(struct au_sbinfo *sinfo); -+int au_br_index(struct super_block *sb, aufs_bindex_t br_id); -+struct au_opt_add; -+int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount); -+struct au_opt_del; -+int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount); -+long au_ibusy_ioctl(struct file *file, unsigned long arg); -+#ifdef CONFIG_COMPAT -+long au_ibusy_compat_ioctl(struct file *file, unsigned long arg); -+#endif -+struct au_opt_mod; -+int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, -+ int *do_refresh); -+struct aufs_stfs; -+int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs); -+ -+/* xino.c */ -+static const loff_t au_loff_max = LLONG_MAX; -+ -+aufs_bindex_t au_xi_root(struct super_block *sb, struct dentry *dentry); -+struct file *au_xino_create(struct super_block *sb, char *fpath, int silent); -+struct file *au_xino_create2(struct super_block *sb, struct path *base, -+ struct file *copy_src); -+struct au_xi_new { -+ struct au_xino *xi; /* switch between xino and xigen */ -+ int idx; -+ struct path *base; -+ struct file *copy_src; -+}; -+struct file *au_xi_new(struct super_block *sb, struct au_xi_new *xinew); -+ -+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ ino_t *ino); -+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ ino_t ino); -+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *buf, size_t size, -+ loff_t *pos); -+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos); -+ -+int au_xib_trunc(struct super_block *sb); -+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex, int idx_begin); -+ -+struct au_xino *au_xino_alloc(unsigned int nfile); -+int au_xino_put(struct au_branch *br); -+struct file *au_xino_file1(struct au_xino *xi); -+ -+struct au_opt_xino; -+void au_xino_clr(struct super_block *sb); -+int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt, int remount); -+struct file *au_xino_def(struct super_block *sb); -+int au_xino_init_br(struct super_block *sb, struct au_branch *br, ino_t hino, -+ struct path *base); -+ -+ino_t au_xino_new_ino(struct super_block *sb); -+void au_xino_delete_inode(struct inode *inode, const int unlinked); -+ -+void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex, -+ ino_t h_ino, int idx); -+int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ int *idx); -+ -+int au_xino_path(struct seq_file *seq, struct file *file); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* @idx is signed to accept -1 meaning the first file */ -+static inline struct file *au_xino_file(struct au_xino *xi, int idx) -+{ -+ struct file *file; -+ -+ file = NULL; -+ if (!xi) -+ goto out; -+ -+ if (idx >= 0) { -+ if (idx < xi->xi_nfile) -+ file = xi->xi_file[idx]; -+ } else -+ file = au_xino_file1(xi); -+ -+out: -+ return file; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* Superblock to branch */ -+static inline -+aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ return au_sbr(sb, bindex)->br_id; -+} -+ -+static inline -+struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ return au_br_mnt(au_sbr(sb, bindex)); -+} -+ -+static inline -+struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ return au_br_sb(au_sbr(sb, bindex)); -+} -+ -+static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ return au_sbr(sb, bindex)->br_perm; -+} -+ -+static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ return au_br_whable(au_sbr_perm(sb, bindex)); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define wbr_wh_read_lock(wbr) au_rw_read_lock(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_write_lock(wbr) au_rw_write_lock(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_read_trylock(wbr) au_rw_read_trylock(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_write_trylock(wbr) au_rw_write_trylock(&(wbr)->wbr_wh_rwsem) -+/* -+#define wbr_wh_read_trylock_nested(wbr) \ -+ au_rw_read_trylock_nested(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_write_trylock_nested(wbr) \ -+ au_rw_write_trylock_nested(&(wbr)->wbr_wh_rwsem) -+*/ -+ -+#define wbr_wh_read_unlock(wbr) au_rw_read_unlock(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_write_unlock(wbr) au_rw_write_unlock(&(wbr)->wbr_wh_rwsem) -+#define wbr_wh_downgrade_lock(wbr) au_rw_dgrade_lock(&(wbr)->wbr_wh_rwsem) -+ -+#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&(wbr)->wbr_wh_rwsem) -+#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&(wbr)->wbr_wh_rwsem) -+#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&(wbr)->wbr_wh_rwsem) -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_FHSM -+static inline void au_br_fhsm_init(struct au_br_fhsm *brfhsm) -+{ -+ mutex_init(&brfhsm->bf_lock); -+ brfhsm->bf_jiffy = 0; -+ brfhsm->bf_readable = 0; -+} -+ -+static inline void au_br_fhsm_fin(struct au_br_fhsm *brfhsm) -+{ -+ mutex_destroy(&brfhsm->bf_lock); -+} -+#else -+AuStubVoid(au_br_fhsm_init, struct au_br_fhsm *brfhsm) -+AuStubVoid(au_br_fhsm_fin, struct au_br_fhsm *brfhsm) -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_BRANCH_H__ */ -diff --git a/fs/aufs/conf.mk b/fs/aufs/conf.mk -new file mode 100644 -index 000000000..12782f8e0 ---- /dev/null -+++ b/fs/aufs/conf.mk -@@ -0,0 +1,40 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS} -+ -+define AuConf -+ifdef ${1} -+AuConfStr += ${1}=${${1}} -+endif -+endef -+ -+AuConfAll = BRANCH_MAX_127 BRANCH_MAX_511 BRANCH_MAX_1023 BRANCH_MAX_32767 \ -+ SBILIST \ -+ HNOTIFY HFSNOTIFY \ -+ EXPORT INO_T_64 \ -+ XATTR \ -+ FHSM \ -+ RDU \ -+ DIRREN \ -+ SHWH \ -+ BR_RAMFS \ -+ BR_FUSE POLL \ -+ BR_HFSPLUS \ -+ BDEV_LOOP \ -+ DEBUG MAGIC_SYSRQ -+$(foreach i, ${AuConfAll}, \ -+ $(eval $(call AuConf,CONFIG_AUFS_${i}))) -+ -+AuConfName = ${obj}/conf.str -+${AuConfName}.tmp: FORCE -+ @echo ${AuConfStr} | tr ' ' '\n' | sed -e 's/^/"/' -e 's/$$/\\n"/' > $@ -+${AuConfName}: ${AuConfName}.tmp -+ @diff -q $< $@ > /dev/null 2>&1 || { \ -+ echo ' GEN ' $@; \ -+ cp -p $< $@; \ -+ } -+FORCE: -+clean-files += ${AuConfName} ${AuConfName}.tmp -+${obj}/sysfs.o: ${AuConfName} -+ -+-include ${srctree}/${src}/conf_priv.mk -diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c -new file mode 100644 -index 000000000..a1ef90f08 ---- /dev/null -+++ b/fs/aufs/cpup.c -@@ -0,0 +1,1444 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * copy-up functions, see wbr_policy.c for copy-down -+ */ -+ -+#include -+#include -+#include -+#include "aufs.h" -+ -+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags) -+{ -+ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE -+ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT; -+ -+ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags)); -+ -+ dst->i_flags |= iflags & ~mask; -+ if (au_test_fs_notime(dst->i_sb)) -+ dst->i_flags |= S_NOATIME | S_NOCMTIME; -+} -+ -+void au_cpup_attr_timesizes(struct inode *inode) -+{ -+ struct inode *h_inode; -+ -+ h_inode = au_h_iptr(inode, au_ibtop(inode)); -+ fsstack_copy_attr_times(inode, h_inode); -+ fsstack_copy_inode_size(inode, h_inode); -+} -+ -+void au_cpup_attr_nlink(struct inode *inode, int force) -+{ -+ struct inode *h_inode; -+ struct super_block *sb; -+ aufs_bindex_t bindex, bbot; -+ -+ sb = inode->i_sb; -+ bindex = au_ibtop(inode); -+ h_inode = au_h_iptr(inode, bindex); -+ if (!force -+ && !S_ISDIR(h_inode->i_mode) -+ && au_opt_test(au_mntflags(sb), PLINK) -+ && au_plink_test(inode)) -+ return; -+ -+ /* -+ * 0 can happen in revalidating. -+ * h_inode->i_mutex may not be held here, but it is harmless since once -+ * i_nlink reaches 0, it will never become positive except O_TMPFILE -+ * case. -+ * todo: O_TMPFILE+linkat(AT_SYMLINK_FOLLOW) bypassing aufs may cause -+ * the incorrect link count. -+ */ -+ set_nlink(inode, h_inode->i_nlink); -+ -+ /* -+ * fewer nlink makes find(1) noisy, but larger nlink doesn't. -+ * it may includes whplink directory. -+ */ -+ if (S_ISDIR(h_inode->i_mode)) { -+ bbot = au_ibbot(inode); -+ for (bindex++; bindex <= bbot; bindex++) { -+ h_inode = au_h_iptr(inode, bindex); -+ if (h_inode) -+ au_add_nlink(inode, h_inode); -+ } -+ } -+} -+ -+void au_cpup_attr_changeable(struct inode *inode) -+{ -+ struct inode *h_inode; -+ -+ h_inode = au_h_iptr(inode, au_ibtop(inode)); -+ inode->i_mode = h_inode->i_mode; -+ inode->i_uid = h_inode->i_uid; -+ inode->i_gid = h_inode->i_gid; -+ au_cpup_attr_timesizes(inode); -+ au_cpup_attr_flags(inode, h_inode->i_flags); -+} -+ -+void au_cpup_igen(struct inode *inode, struct inode *h_inode) -+{ -+ struct au_iinfo *iinfo = au_ii(inode); -+ -+ IiMustWriteLock(inode); -+ -+ iinfo->ii_higen = h_inode->i_generation; -+ iinfo->ii_hsb1 = h_inode->i_sb; -+} -+ -+void au_cpup_attr_all(struct inode *inode, int force) -+{ -+ struct inode *h_inode; -+ -+ h_inode = au_h_iptr(inode, au_ibtop(inode)); -+ au_cpup_attr_changeable(inode); -+ if (inode->i_nlink > 0) -+ au_cpup_attr_nlink(inode, force); -+ inode->i_rdev = h_inode->i_rdev; -+ inode->i_blkbits = h_inode->i_blkbits; -+ au_cpup_igen(inode, h_inode); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */ -+ -+/* keep the timestamps of the parent dir when cpup */ -+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, -+ struct path *h_path) -+{ -+ struct inode *h_inode; -+ -+ dt->dt_dentry = dentry; -+ dt->dt_h_path = *h_path; -+ h_inode = d_inode(h_path->dentry); -+ dt->dt_atime = h_inode->i_atime; -+ dt->dt_mtime = h_inode->i_mtime; -+ /* smp_mb(); */ -+} -+ -+void au_dtime_revert(struct au_dtime *dt) -+{ -+ struct iattr attr; -+ int err; -+ -+ attr.ia_atime = dt->dt_atime; -+ attr.ia_mtime = dt->dt_mtime; -+ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET -+ | ATTR_ATIME | ATTR_ATIME_SET; -+ -+ /* no delegation since this is a directory */ -+ err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL); -+ if (unlikely(err)) -+ pr_warn("restoring timestamps failed(%d). ignored\n", err); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* internal use only */ -+struct au_cpup_reg_attr { -+ int valid; -+ struct kstat st; -+ unsigned int iflags; /* inode->i_flags */ -+}; -+ -+static noinline_for_stack -+int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src, -+ struct au_cpup_reg_attr *h_src_attr) -+{ -+ int err, sbits, icex; -+ unsigned int mnt_flags; -+ unsigned char verbose; -+ struct iattr ia; -+ struct path h_path; -+ struct inode *h_isrc, *h_idst; -+ struct kstat *h_st; -+ struct au_branch *br; -+ -+ h_path.dentry = au_h_dptr(dst, bindex); -+ h_idst = d_inode(h_path.dentry); -+ br = au_sbr(dst->d_sb, bindex); -+ h_path.mnt = au_br_mnt(br); -+ h_isrc = d_inode(h_src); -+ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID -+ | ATTR_ATIME | ATTR_MTIME -+ | ATTR_ATIME_SET | ATTR_MTIME_SET; -+ if (h_src_attr && h_src_attr->valid) { -+ h_st = &h_src_attr->st; -+ ia.ia_uid = h_st->uid; -+ ia.ia_gid = h_st->gid; -+ ia.ia_atime = h_st->atime; -+ ia.ia_mtime = h_st->mtime; -+ if (h_idst->i_mode != h_st->mode -+ && !S_ISLNK(h_idst->i_mode)) { -+ ia.ia_valid |= ATTR_MODE; -+ ia.ia_mode = h_st->mode; -+ } -+ sbits = !!(h_st->mode & (S_ISUID | S_ISGID)); -+ au_cpup_attr_flags(h_idst, h_src_attr->iflags); -+ } else { -+ ia.ia_uid = h_isrc->i_uid; -+ ia.ia_gid = h_isrc->i_gid; -+ ia.ia_atime = h_isrc->i_atime; -+ ia.ia_mtime = h_isrc->i_mtime; -+ if (h_idst->i_mode != h_isrc->i_mode -+ && !S_ISLNK(h_idst->i_mode)) { -+ ia.ia_valid |= ATTR_MODE; -+ ia.ia_mode = h_isrc->i_mode; -+ } -+ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID)); -+ au_cpup_attr_flags(h_idst, h_isrc->i_flags); -+ } -+ /* no delegation since it is just created */ -+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL); -+ -+ /* is this nfs only? */ -+ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) { -+ ia.ia_valid = ATTR_FORCE | ATTR_MODE; -+ ia.ia_mode = h_isrc->i_mode; -+ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL); -+ } -+ -+ icex = br->br_perm & AuBrAttr_ICEX; -+ if (!err) { -+ mnt_flags = au_mntflags(dst->d_sb); -+ verbose = !!au_opt_test(mnt_flags, VERBOSE); -+ err = au_cpup_xattr(h_path.dentry, h_src, icex, verbose); -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_do_copy_file(struct file *dst, struct file *src, loff_t len, -+ char *buf, unsigned long blksize) -+{ -+ int err; -+ size_t sz, rbytes, wbytes; -+ unsigned char all_zero; -+ char *p, *zp; -+ struct inode *h_inode; -+ /* reduce stack usage */ -+ struct iattr *ia; -+ -+ zp = page_address(ZERO_PAGE(0)); -+ if (unlikely(!zp)) -+ return -ENOMEM; /* possible? */ -+ -+ err = 0; -+ all_zero = 0; -+ while (len) { -+ AuDbg("len %lld\n", len); -+ sz = blksize; -+ if (len < blksize) -+ sz = len; -+ -+ rbytes = 0; -+ /* todo: signal_pending? */ -+ while (!rbytes || err == -EAGAIN || err == -EINTR) { -+ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos); -+ err = rbytes; -+ } -+ if (unlikely(err < 0)) -+ break; -+ -+ all_zero = 0; -+ if (len >= rbytes && rbytes == blksize) -+ all_zero = !memcmp(buf, zp, rbytes); -+ if (!all_zero) { -+ wbytes = rbytes; -+ p = buf; -+ while (wbytes) { -+ size_t b; -+ -+ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos); -+ err = b; -+ /* todo: signal_pending? */ -+ if (unlikely(err == -EAGAIN || err == -EINTR)) -+ continue; -+ if (unlikely(err < 0)) -+ break; -+ wbytes -= b; -+ p += b; -+ } -+ if (unlikely(err < 0)) -+ break; -+ } else { -+ loff_t res; -+ -+ AuLabel(hole); -+ res = vfsub_llseek(dst, rbytes, SEEK_CUR); -+ err = res; -+ if (unlikely(res < 0)) -+ break; -+ } -+ len -= rbytes; -+ err = 0; -+ } -+ -+ /* the last block may be a hole */ -+ if (!err && all_zero) { -+ AuLabel(last hole); -+ -+ err = 1; -+ if (au_test_nfs(dst->f_path.dentry->d_sb)) { -+ /* nfs requires this step to make last hole */ -+ /* is this only nfs? */ -+ do { -+ /* todo: signal_pending? */ -+ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos); -+ } while (err == -EAGAIN || err == -EINTR); -+ if (err == 1) -+ dst->f_pos--; -+ } -+ -+ if (err == 1) { -+ ia = (void *)buf; -+ ia->ia_size = dst->f_pos; -+ ia->ia_valid = ATTR_SIZE | ATTR_FILE; -+ ia->ia_file = dst; -+ h_inode = file_inode(dst); -+ inode_lock_nested(h_inode, AuLsc_I_CHILD2); -+ /* no delegation since it is just created */ -+ err = vfsub_notify_change(&dst->f_path, ia, -+ /*delegated*/NULL); -+ inode_unlock(h_inode); -+ } -+ } -+ -+ return err; -+} -+ -+int au_copy_file(struct file *dst, struct file *src, loff_t len) -+{ -+ int err; -+ unsigned long blksize; -+ unsigned char do_kfree; -+ char *buf; -+ -+ err = -ENOMEM; -+ blksize = dst->f_path.dentry->d_sb->s_blocksize; -+ if (!blksize || PAGE_SIZE < blksize) -+ blksize = PAGE_SIZE; -+ AuDbg("blksize %lu\n", blksize); -+ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *)); -+ if (do_kfree) -+ buf = kmalloc(blksize, GFP_NOFS); -+ else -+ buf = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!buf)) -+ goto out; -+ -+ if (len > (1 << 22)) -+ AuDbg("copying a large file %lld\n", (long long)len); -+ -+ src->f_pos = 0; -+ dst->f_pos = 0; -+ err = au_do_copy_file(dst, src, len, buf, blksize); -+ if (do_kfree) -+ kfree(buf); -+ else -+ free_page((unsigned long)buf); -+ -+out: -+ return err; -+} -+ -+static int au_do_copy(struct file *dst, struct file *src, loff_t len) -+{ -+ int err; -+ struct super_block *h_src_sb; -+ struct inode *h_src_inode; -+ -+ h_src_inode = file_inode(src); -+ h_src_sb = h_src_inode->i_sb; -+ -+ /* XFS acquires inode_lock */ -+ if (!au_test_xfs(h_src_sb)) -+ err = au_copy_file(dst, src, len); -+ else { -+ inode_unlock_shared(h_src_inode); -+ err = au_copy_file(dst, src, len); -+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD); -+ } -+ -+ return err; -+} -+ -+static int au_clone_or_copy(struct file *dst, struct file *src, loff_t len) -+{ -+ int err; -+ struct super_block *h_src_sb; -+ struct inode *h_src_inode; -+ -+ h_src_inode = file_inode(src); -+ h_src_sb = h_src_inode->i_sb; -+ if (h_src_sb != file_inode(dst)->i_sb -+ || !dst->f_op->clone_file_range) { -+ err = au_do_copy(dst, src, len); -+ goto out; -+ } -+ -+ if (!au_test_nfs(h_src_sb)) { -+ inode_unlock_shared(h_src_inode); -+ err = vfsub_clone_file_range(src, dst, len); -+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD); -+ } else -+ err = vfsub_clone_file_range(src, dst, len); -+ /* older XFS has a condition in cloning */ -+ if (unlikely(err != -EOPNOTSUPP)) -+ goto out; -+ -+ /* the backend fs on NFS may not support cloning */ -+ err = au_do_copy(dst, src, len); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * to support a sparse file which is opened with O_APPEND, -+ * we need to close the file. -+ */ -+static int au_cp_regular(struct au_cp_generic *cpg) -+{ -+ int err, i; -+ enum { SRC, DST }; -+ struct { -+ aufs_bindex_t bindex; -+ unsigned int flags; -+ struct dentry *dentry; -+ int force_wr; -+ struct file *file; -+ void *label; -+ } *f, file[] = { -+ { -+ .bindex = cpg->bsrc, -+ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE, -+ .label = &&out -+ }, -+ { -+ .bindex = cpg->bdst, -+ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE, -+ .force_wr = !!au_ftest_cpup(cpg->flags, RWDST), -+ .label = &&out_src -+ } -+ }; -+ struct au_branch *br; -+ struct super_block *sb, *h_src_sb; -+ struct inode *h_src_inode; -+ struct task_struct *tsk = current; -+ -+ /* bsrc branch can be ro/rw. */ -+ sb = cpg->dentry->d_sb; -+ f = file; -+ for (i = 0; i < 2; i++, f++) { -+ f->dentry = au_h_dptr(cpg->dentry, f->bindex); -+ f->file = au_h_open(cpg->dentry, f->bindex, f->flags, -+ /*file*/NULL, f->force_wr); -+ err = PTR_ERR(f->file); -+ if (IS_ERR(f->file)) -+ goto *f->label; -+ } -+ -+ /* try stopping to update while we copyup */ -+ h_src_inode = d_inode(file[SRC].dentry); -+ h_src_sb = h_src_inode->i_sb; -+ if (!au_test_nfs(h_src_sb)) -+ IMustLock(h_src_inode); -+ err = au_clone_or_copy(file[DST].file, file[SRC].file, cpg->len); -+ -+ /* i wonder if we had O_NO_DELAY_FPUT flag */ -+ if (tsk->flags & PF_KTHREAD) -+ __fput_sync(file[DST].file); -+ else { -+ /* it happened actually */ -+ fput(file[DST].file); -+ /* -+ * too bad. -+ * we have to call both since we don't know which place the file -+ * was added to. -+ */ -+ task_work_run(); -+ flush_delayed_fput(); -+ } -+ br = au_sbr(sb, file[DST].bindex); -+ au_lcnt_dec(&br->br_nfiles); -+ -+out_src: -+ fput(file[SRC].file); -+ br = au_sbr(sb, file[SRC].bindex); -+ au_lcnt_dec(&br->br_nfiles); -+out: -+ return err; -+} -+ -+static int au_do_cpup_regular(struct au_cp_generic *cpg, -+ struct au_cpup_reg_attr *h_src_attr) -+{ -+ int err, rerr; -+ loff_t l; -+ struct path h_path; -+ struct inode *h_src_inode, *h_dst_inode; -+ -+ err = 0; -+ h_src_inode = au_h_iptr(d_inode(cpg->dentry), cpg->bsrc); -+ l = i_size_read(h_src_inode); -+ if (cpg->len == -1 || l < cpg->len) -+ cpg->len = l; -+ if (cpg->len) { -+ /* try stopping to update while we are referencing */ -+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD); -+ au_pin_hdir_unlock(cpg->pin); -+ -+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc); -+ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc); -+ h_src_attr->iflags = h_src_inode->i_flags; -+ if (!au_test_nfs(h_src_inode->i_sb)) -+ err = vfsub_getattr(&h_path, &h_src_attr->st); -+ else { -+ inode_unlock_shared(h_src_inode); -+ err = vfsub_getattr(&h_path, &h_src_attr->st); -+ inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD); -+ } -+ if (unlikely(err)) { -+ inode_unlock_shared(h_src_inode); -+ goto out; -+ } -+ h_src_attr->valid = 1; -+ if (!au_test_nfs(h_src_inode->i_sb)) { -+ err = au_cp_regular(cpg); -+ inode_unlock_shared(h_src_inode); -+ } else { -+ inode_unlock_shared(h_src_inode); -+ err = au_cp_regular(cpg); -+ } -+ rerr = au_pin_hdir_relock(cpg->pin); -+ if (!err && rerr) -+ err = rerr; -+ } -+ if (!err && (h_src_inode->i_state & I_LINKABLE)) { -+ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst); -+ h_dst_inode = d_inode(h_path.dentry); -+ spin_lock(&h_dst_inode->i_lock); -+ h_dst_inode->i_state |= I_LINKABLE; -+ spin_unlock(&h_dst_inode->i_lock); -+ } -+ -+out: -+ return err; -+} -+ -+static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src, -+ struct inode *h_dir) -+{ -+ int err, symlen; -+ mm_segment_t old_fs; -+ union { -+ char *k; -+ char __user *u; -+ } sym; -+ -+ err = -ENOMEM; -+ sym.k = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!sym.k)) -+ goto out; -+ -+ /* unnecessary to support mmap_sem since symlink is not mmap-able */ -+ old_fs = get_fs(); -+ set_fs(KERNEL_DS); -+ symlen = vfs_readlink(h_src, sym.u, PATH_MAX); -+ err = symlen; -+ set_fs(old_fs); -+ -+ if (symlen > 0) { -+ sym.k[symlen] = 0; -+ err = vfsub_symlink(h_dir, h_path, sym.k); -+ } -+ free_page((unsigned long)sym.k); -+ -+out: -+ return err; -+} -+ -+/* -+ * regardless 'acl' option, reset all ACL. -+ * All ACL will be copied up later from the original entry on the lower branch. -+ */ -+static int au_reset_acl(struct inode *h_dir, struct path *h_path, umode_t mode) -+{ -+ int err; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ -+ h_dentry = h_path->dentry; -+ h_inode = d_inode(h_dentry); -+ /* forget_all_cached_acls(h_inode)); */ -+ err = vfsub_removexattr(h_dentry, XATTR_NAME_POSIX_ACL_ACCESS); -+ AuTraceErr(err); -+ if (err == -EOPNOTSUPP) -+ err = 0; -+ if (!err) -+ err = vfsub_acl_chmod(h_inode, mode); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_do_cpup_dir(struct au_cp_generic *cpg, struct dentry *dst_parent, -+ struct inode *h_dir, struct path *h_path) -+{ -+ int err; -+ struct inode *dir, *inode; -+ -+ err = vfsub_removexattr(h_path->dentry, XATTR_NAME_POSIX_ACL_DEFAULT); -+ AuTraceErr(err); -+ if (err == -EOPNOTSUPP) -+ err = 0; -+ if (unlikely(err)) -+ goto out; -+ -+ /* -+ * strange behaviour from the users view, -+ * particularly setattr case -+ */ -+ dir = d_inode(dst_parent); -+ if (au_ibtop(dir) == cpg->bdst) -+ au_cpup_attr_nlink(dir, /*force*/1); -+ inode = d_inode(cpg->dentry); -+ au_cpup_attr_nlink(inode, /*force*/1); -+ -+out: -+ return err; -+} -+ -+static noinline_for_stack -+int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent, -+ struct au_cpup_reg_attr *h_src_attr) -+{ -+ int err; -+ umode_t mode; -+ unsigned int mnt_flags; -+ unsigned char isdir, isreg, force; -+ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME); -+ struct au_dtime dt; -+ struct path h_path; -+ struct dentry *h_src, *h_dst, *h_parent; -+ struct inode *h_inode, *h_dir; -+ struct super_block *sb; -+ -+ /* bsrc branch can be ro/rw. */ -+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc); -+ h_inode = d_inode(h_src); -+ AuDebugOn(h_inode != au_h_iptr(d_inode(cpg->dentry), cpg->bsrc)); -+ -+ /* try stopping to be referenced while we are creating */ -+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst); -+ if (au_ftest_cpup(cpg->flags, RENAME)) -+ AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX, -+ AUFS_WH_PFX_LEN)); -+ h_parent = h_dst->d_parent; /* dir inode is locked */ -+ h_dir = d_inode(h_parent); -+ IMustLock(h_dir); -+ AuDebugOn(h_parent != h_dst->d_parent); -+ -+ sb = cpg->dentry->d_sb; -+ h_path.mnt = au_sbr_mnt(sb, cpg->bdst); -+ if (do_dt) { -+ h_path.dentry = h_parent; -+ au_dtime_store(&dt, dst_parent, &h_path); -+ } -+ h_path.dentry = h_dst; -+ -+ isreg = 0; -+ isdir = 0; -+ mode = h_inode->i_mode; -+ switch (mode & S_IFMT) { -+ case S_IFREG: -+ isreg = 1; -+ err = vfsub_create(h_dir, &h_path, 0600, /*want_excl*/true); -+ if (!err) -+ err = au_do_cpup_regular(cpg, h_src_attr); -+ break; -+ case S_IFDIR: -+ isdir = 1; -+ err = vfsub_mkdir(h_dir, &h_path, mode); -+ if (!err) -+ err = au_do_cpup_dir(cpg, dst_parent, h_dir, &h_path); -+ break; -+ case S_IFLNK: -+ err = au_do_cpup_symlink(&h_path, h_src, h_dir); -+ break; -+ case S_IFCHR: -+ case S_IFBLK: -+ AuDebugOn(!capable(CAP_MKNOD)); -+ /*FALLTHROUGH*/ -+ case S_IFIFO: -+ case S_IFSOCK: -+ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev); -+ break; -+ default: -+ AuIOErr("Unknown inode type 0%o\n", mode); -+ err = -EIO; -+ } -+ if (!err) -+ err = au_reset_acl(h_dir, &h_path, mode); -+ -+ mnt_flags = au_mntflags(sb); -+ if (!au_opt_test(mnt_flags, UDBA_NONE) -+ && !isdir -+ && au_opt_test(mnt_flags, XINO) -+ && (h_inode->i_nlink == 1 -+ || (h_inode->i_state & I_LINKABLE)) -+ /* todo: unnecessary? */ -+ /* && d_inode(cpg->dentry)->i_nlink == 1 */ -+ && cpg->bdst < cpg->bsrc -+ && !au_ftest_cpup(cpg->flags, KEEPLINO)) -+ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0); -+ /* ignore this error */ -+ -+ if (!err) { -+ force = 0; -+ if (isreg) { -+ force = !!cpg->len; -+ if (cpg->len == -1) -+ force = !!i_size_read(h_inode); -+ } -+ au_fhsm_wrote(sb, cpg->bdst, force); -+ } -+ -+ if (do_dt) -+ au_dtime_revert(&dt); -+ return err; -+} -+ -+static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path) -+{ -+ int err; -+ struct dentry *dentry, *h_dentry, *h_parent, *parent; -+ struct inode *h_dir; -+ aufs_bindex_t bdst; -+ -+ dentry = cpg->dentry; -+ bdst = cpg->bdst; -+ h_dentry = au_h_dptr(dentry, bdst); -+ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) { -+ dget(h_dentry); -+ au_set_h_dptr(dentry, bdst, NULL); -+ err = au_lkup_neg(dentry, bdst, /*wh*/0); -+ if (!err) -+ h_path->dentry = dget(au_h_dptr(dentry, bdst)); -+ au_set_h_dptr(dentry, bdst, h_dentry); -+ } else { -+ err = 0; -+ parent = dget_parent(dentry); -+ h_parent = au_h_dptr(parent, bdst); -+ dput(parent); -+ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent); -+ if (IS_ERR(h_path->dentry)) -+ err = PTR_ERR(h_path->dentry); -+ } -+ if (unlikely(err)) -+ goto out; -+ -+ h_parent = h_dentry->d_parent; /* dir inode is locked */ -+ h_dir = d_inode(h_parent); -+ IMustLock(h_dir); -+ AuDbg("%pd %pd\n", h_dentry, h_path->dentry); -+ /* no delegation since it is just created */ -+ err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL, -+ /*flags*/0); -+ dput(h_path->dentry); -+ -+out: -+ return err; -+} -+ -+/* -+ * copyup the @dentry from @bsrc to @bdst. -+ * the caller must set the both of lower dentries. -+ * @len is for truncating when it is -1 copyup the entire file. -+ * in link/rename cases, @dst_parent may be different from the real one. -+ * basic->bsrc can be larger than basic->bdst. -+ * aufs doesn't touch the credential so -+ * security_inode_copy_up{,_xattr}() are unnecessary. -+ */ -+static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent) -+{ -+ int err, rerr; -+ aufs_bindex_t old_ibtop; -+ unsigned char isdir, plink; -+ struct dentry *h_src, *h_dst, *h_parent; -+ struct inode *dst_inode, *h_dir, *inode, *delegated, *src_inode; -+ struct super_block *sb; -+ struct au_branch *br; -+ /* to reduce stack size */ -+ struct { -+ struct au_dtime dt; -+ struct path h_path; -+ struct au_cpup_reg_attr h_src_attr; -+ } *a; -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ a->h_src_attr.valid = 0; -+ -+ sb = cpg->dentry->d_sb; -+ br = au_sbr(sb, cpg->bdst); -+ a->h_path.mnt = au_br_mnt(br); -+ h_dst = au_h_dptr(cpg->dentry, cpg->bdst); -+ h_parent = h_dst->d_parent; /* dir inode is locked */ -+ h_dir = d_inode(h_parent); -+ IMustLock(h_dir); -+ -+ h_src = au_h_dptr(cpg->dentry, cpg->bsrc); -+ inode = d_inode(cpg->dentry); -+ -+ if (!dst_parent) -+ dst_parent = dget_parent(cpg->dentry); -+ else -+ dget(dst_parent); -+ -+ plink = !!au_opt_test(au_mntflags(sb), PLINK); -+ dst_inode = au_h_iptr(inode, cpg->bdst); -+ if (dst_inode) { -+ if (unlikely(!plink)) { -+ err = -EIO; -+ AuIOErr("hi%lu(i%lu) exists on b%d " -+ "but plink is disabled\n", -+ dst_inode->i_ino, inode->i_ino, cpg->bdst); -+ goto out_parent; -+ } -+ -+ if (dst_inode->i_nlink) { -+ const int do_dt = au_ftest_cpup(cpg->flags, DTIME); -+ -+ h_src = au_plink_lkup(inode, cpg->bdst); -+ err = PTR_ERR(h_src); -+ if (IS_ERR(h_src)) -+ goto out_parent; -+ if (unlikely(d_is_negative(h_src))) { -+ err = -EIO; -+ AuIOErr("i%lu exists on b%d " -+ "but not pseudo-linked\n", -+ inode->i_ino, cpg->bdst); -+ dput(h_src); -+ goto out_parent; -+ } -+ -+ if (do_dt) { -+ a->h_path.dentry = h_parent; -+ au_dtime_store(&a->dt, dst_parent, &a->h_path); -+ } -+ -+ a->h_path.dentry = h_dst; -+ delegated = NULL; -+ err = vfsub_link(h_src, h_dir, &a->h_path, &delegated); -+ if (!err && au_ftest_cpup(cpg->flags, RENAME)) -+ err = au_do_ren_after_cpup(cpg, &a->h_path); -+ if (do_dt) -+ au_dtime_revert(&a->dt); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ dput(h_src); -+ goto out_parent; -+ } else -+ /* todo: cpup_wh_file? */ -+ /* udba work */ -+ au_update_ibrange(inode, /*do_put_zero*/1); -+ } -+ -+ isdir = S_ISDIR(inode->i_mode); -+ old_ibtop = au_ibtop(inode); -+ err = cpup_entry(cpg, dst_parent, &a->h_src_attr); -+ if (unlikely(err)) -+ goto out_rev; -+ dst_inode = d_inode(h_dst); -+ inode_lock_nested(dst_inode, AuLsc_I_CHILD2); -+ /* todo: necessary? */ -+ /* au_pin_hdir_unlock(cpg->pin); */ -+ -+ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr); -+ if (unlikely(err)) { -+ /* todo: necessary? */ -+ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */ -+ inode_unlock(dst_inode); -+ goto out_rev; -+ } -+ -+ if (cpg->bdst < old_ibtop) { -+ if (S_ISREG(inode->i_mode)) { -+ err = au_dy_iaop(inode, cpg->bdst, dst_inode); -+ if (unlikely(err)) { -+ /* ignore an error */ -+ /* au_pin_hdir_relock(cpg->pin); */ -+ inode_unlock(dst_inode); -+ goto out_rev; -+ } -+ } -+ au_set_ibtop(inode, cpg->bdst); -+ } else -+ au_set_ibbot(inode, cpg->bdst); -+ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode), -+ au_hi_flags(inode, isdir)); -+ -+ /* todo: necessary? */ -+ /* err = au_pin_hdir_relock(cpg->pin); */ -+ inode_unlock(dst_inode); -+ if (unlikely(err)) -+ goto out_rev; -+ -+ src_inode = d_inode(h_src); -+ if (!isdir -+ && (src_inode->i_nlink > 1 -+ || src_inode->i_state & I_LINKABLE) -+ && plink) -+ au_plink_append(inode, cpg->bdst, h_dst); -+ -+ if (au_ftest_cpup(cpg->flags, RENAME)) { -+ a->h_path.dentry = h_dst; -+ err = au_do_ren_after_cpup(cpg, &a->h_path); -+ } -+ if (!err) -+ goto out_parent; /* success */ -+ -+ /* revert */ -+out_rev: -+ a->h_path.dentry = h_parent; -+ au_dtime_store(&a->dt, dst_parent, &a->h_path); -+ a->h_path.dentry = h_dst; -+ rerr = 0; -+ if (d_is_positive(h_dst)) { -+ if (!isdir) { -+ /* no delegation since it is just created */ -+ rerr = vfsub_unlink(h_dir, &a->h_path, -+ /*delegated*/NULL, /*force*/0); -+ } else -+ rerr = vfsub_rmdir(h_dir, &a->h_path); -+ } -+ au_dtime_revert(&a->dt); -+ if (rerr) { -+ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr); -+ err = -EIO; -+ } -+out_parent: -+ dput(dst_parent); -+ kfree(a); -+out: -+ return err; -+} -+ -+#if 0 /* reserved */ -+struct au_cpup_single_args { -+ int *errp; -+ struct au_cp_generic *cpg; -+ struct dentry *dst_parent; -+}; -+ -+static void au_call_cpup_single(void *args) -+{ -+ struct au_cpup_single_args *a = args; -+ -+ au_pin_hdir_acquire_nest(a->cpg->pin); -+ *a->errp = au_cpup_single(a->cpg, a->dst_parent); -+ au_pin_hdir_release(a->cpg->pin); -+} -+#endif -+ -+/* -+ * prevent SIGXFSZ in copy-up. -+ * testing CAP_MKNOD is for generic fs, -+ * but CAP_FSETID is for xfs only, currently. -+ */ -+static int au_cpup_sio_test(struct au_pin *pin, umode_t mode) -+{ -+ int do_sio; -+ struct super_block *sb; -+ struct inode *h_dir; -+ -+ do_sio = 0; -+ sb = au_pinned_parent(pin)->d_sb; -+ if (!au_wkq_test() -+ && (!au_sbi(sb)->si_plink_maint_pid -+ || au_plink_maint(sb, AuLock_NOPLM))) { -+ switch (mode & S_IFMT) { -+ case S_IFREG: -+ /* no condition about RLIMIT_FSIZE and the file size */ -+ do_sio = 1; -+ break; -+ case S_IFCHR: -+ case S_IFBLK: -+ do_sio = !capable(CAP_MKNOD); -+ break; -+ } -+ if (!do_sio) -+ do_sio = ((mode & (S_ISUID | S_ISGID)) -+ && !capable(CAP_FSETID)); -+ /* this workaround may be removed in the future */ -+ if (!do_sio) { -+ h_dir = au_pinned_h_dir(pin); -+ do_sio = h_dir->i_mode & S_ISVTX; -+ } -+ } -+ -+ return do_sio; -+} -+ -+#if 0 /* reserved */ -+int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent) -+{ -+ int err, wkq_err; -+ struct dentry *h_dentry; -+ -+ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc); -+ if (!au_cpup_sio_test(pin, d_inode(h_dentry)->i_mode)) -+ err = au_cpup_single(cpg, dst_parent); -+ else { -+ struct au_cpup_single_args args = { -+ .errp = &err, -+ .cpg = cpg, -+ .dst_parent = dst_parent -+ }; -+ wkq_err = au_wkq_wait(au_call_cpup_single, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ return err; -+} -+#endif -+ -+/* -+ * copyup the @dentry from the first active lower branch to @bdst, -+ * using au_cpup_single(). -+ */ -+static int au_cpup_simple(struct au_cp_generic *cpg) -+{ -+ int err; -+ unsigned int flags_orig; -+ struct dentry *dentry; -+ -+ AuDebugOn(cpg->bsrc < 0); -+ -+ dentry = cpg->dentry; -+ DiMustWriteLock(dentry); -+ -+ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1); -+ if (!err) { -+ flags_orig = cpg->flags; -+ au_fset_cpup(cpg->flags, RENAME); -+ err = au_cpup_single(cpg, NULL); -+ cpg->flags = flags_orig; -+ if (!err) -+ return 0; /* success */ -+ -+ /* revert */ -+ au_set_h_dptr(dentry, cpg->bdst, NULL); -+ au_set_dbtop(dentry, cpg->bsrc); -+ } -+ -+ return err; -+} -+ -+struct au_cpup_simple_args { -+ int *errp; -+ struct au_cp_generic *cpg; -+}; -+ -+static void au_call_cpup_simple(void *args) -+{ -+ struct au_cpup_simple_args *a = args; -+ -+ au_pin_hdir_acquire_nest(a->cpg->pin); -+ *a->errp = au_cpup_simple(a->cpg); -+ au_pin_hdir_release(a->cpg->pin); -+} -+ -+static int au_do_sio_cpup_simple(struct au_cp_generic *cpg) -+{ -+ int err, wkq_err; -+ struct dentry *dentry, *parent; -+ struct file *h_file; -+ struct inode *h_dir; -+ -+ dentry = cpg->dentry; -+ h_file = NULL; -+ if (au_ftest_cpup(cpg->flags, HOPEN)) { -+ AuDebugOn(cpg->bsrc < 0); -+ h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ } -+ -+ parent = dget_parent(dentry); -+ h_dir = au_h_iptr(d_inode(parent), cpg->bdst); -+ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE) -+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode)) -+ err = au_cpup_simple(cpg); -+ else { -+ struct au_cpup_simple_args args = { -+ .errp = &err, -+ .cpg = cpg -+ }; -+ wkq_err = au_wkq_wait(au_call_cpup_simple, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ dput(parent); -+ if (h_file) -+ au_h_open_post(dentry, cpg->bsrc, h_file); -+ -+out: -+ return err; -+} -+ -+int au_sio_cpup_simple(struct au_cp_generic *cpg) -+{ -+ aufs_bindex_t bsrc, bbot; -+ struct dentry *dentry, *h_dentry; -+ -+ if (cpg->bsrc < 0) { -+ dentry = cpg->dentry; -+ bbot = au_dbbot(dentry); -+ for (bsrc = cpg->bdst + 1; bsrc <= bbot; bsrc++) { -+ h_dentry = au_h_dptr(dentry, bsrc); -+ if (h_dentry) { -+ AuDebugOn(d_is_negative(h_dentry)); -+ break; -+ } -+ } -+ AuDebugOn(bsrc > bbot); -+ cpg->bsrc = bsrc; -+ } -+ AuDebugOn(cpg->bsrc <= cpg->bdst); -+ return au_do_sio_cpup_simple(cpg); -+} -+ -+int au_sio_cpdown_simple(struct au_cp_generic *cpg) -+{ -+ AuDebugOn(cpg->bdst <= cpg->bsrc); -+ return au_do_sio_cpup_simple(cpg); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * copyup the deleted file for writing. -+ */ -+static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry, -+ struct file *file) -+{ -+ int err; -+ unsigned int flags_orig; -+ aufs_bindex_t bsrc_orig; -+ struct au_dinfo *dinfo; -+ struct { -+ struct au_hdentry *hd; -+ struct dentry *h_dentry; -+ } hdst, hsrc; -+ -+ dinfo = au_di(cpg->dentry); -+ AuRwMustWriteLock(&dinfo->di_rwsem); -+ -+ bsrc_orig = cpg->bsrc; -+ cpg->bsrc = dinfo->di_btop; -+ hdst.hd = au_hdentry(dinfo, cpg->bdst); -+ hdst.h_dentry = hdst.hd->hd_dentry; -+ hdst.hd->hd_dentry = wh_dentry; -+ dinfo->di_btop = cpg->bdst; -+ -+ hsrc.h_dentry = NULL; -+ if (file) { -+ hsrc.hd = au_hdentry(dinfo, cpg->bsrc); -+ hsrc.h_dentry = hsrc.hd->hd_dentry; -+ hsrc.hd->hd_dentry = au_hf_top(file)->f_path.dentry; -+ } -+ flags_orig = cpg->flags; -+ cpg->flags = !AuCpup_DTIME; -+ err = au_cpup_single(cpg, /*h_parent*/NULL); -+ cpg->flags = flags_orig; -+ if (file) { -+ if (!err) -+ err = au_reopen_nondir(file); -+ hsrc.hd->hd_dentry = hsrc.h_dentry; -+ } -+ hdst.hd->hd_dentry = hdst.h_dentry; -+ dinfo->di_btop = cpg->bsrc; -+ cpg->bsrc = bsrc_orig; -+ -+ return err; -+} -+ -+static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file) -+{ -+ int err; -+ aufs_bindex_t bdst; -+ struct au_dtime dt; -+ struct dentry *dentry, *parent, *h_parent, *wh_dentry; -+ struct au_branch *br; -+ struct path h_path; -+ -+ dentry = cpg->dentry; -+ bdst = cpg->bdst; -+ br = au_sbr(dentry->d_sb, bdst); -+ parent = dget_parent(dentry); -+ h_parent = au_h_dptr(parent, bdst); -+ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out; -+ -+ h_path.dentry = h_parent; -+ h_path.mnt = au_br_mnt(br); -+ au_dtime_store(&dt, parent, &h_path); -+ err = au_do_cpup_wh(cpg, wh_dentry, file); -+ if (unlikely(err)) -+ goto out_wh; -+ -+ dget(wh_dentry); -+ h_path.dentry = wh_dentry; -+ if (!d_is_dir(wh_dentry)) { -+ /* no delegation since it is just created */ -+ err = vfsub_unlink(d_inode(h_parent), &h_path, -+ /*delegated*/NULL, /*force*/0); -+ } else -+ err = vfsub_rmdir(d_inode(h_parent), &h_path); -+ if (unlikely(err)) { -+ AuIOErr("failed remove copied-up tmp file %pd(%d)\n", -+ wh_dentry, err); -+ err = -EIO; -+ } -+ au_dtime_revert(&dt); -+ au_set_hi_wh(d_inode(dentry), bdst, wh_dentry); -+ -+out_wh: -+ dput(wh_dentry); -+out: -+ dput(parent); -+ return err; -+} -+ -+struct au_cpup_wh_args { -+ int *errp; -+ struct au_cp_generic *cpg; -+ struct file *file; -+}; -+ -+static void au_call_cpup_wh(void *args) -+{ -+ struct au_cpup_wh_args *a = args; -+ -+ au_pin_hdir_acquire_nest(a->cpg->pin); -+ *a->errp = au_cpup_wh(a->cpg, a->file); -+ au_pin_hdir_release(a->cpg->pin); -+} -+ -+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file) -+{ -+ int err, wkq_err; -+ aufs_bindex_t bdst; -+ struct dentry *dentry, *parent, *h_orph, *h_parent; -+ struct inode *dir, *h_dir, *h_tmpdir; -+ struct au_wbr *wbr; -+ struct au_pin wh_pin, *pin_orig; -+ -+ dentry = cpg->dentry; -+ bdst = cpg->bdst; -+ parent = dget_parent(dentry); -+ dir = d_inode(parent); -+ h_orph = NULL; -+ h_parent = NULL; -+ h_dir = au_igrab(au_h_iptr(dir, bdst)); -+ h_tmpdir = h_dir; -+ pin_orig = NULL; -+ if (!h_dir->i_nlink) { -+ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr; -+ h_orph = wbr->wbr_orph; -+ -+ h_parent = dget(au_h_dptr(parent, bdst)); -+ au_set_h_dptr(parent, bdst, dget(h_orph)); -+ h_tmpdir = d_inode(h_orph); -+ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0); -+ -+ inode_lock_nested(h_tmpdir, AuLsc_I_PARENT3); -+ /* todo: au_h_open_pre()? */ -+ -+ pin_orig = cpg->pin; -+ au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT, -+ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED); -+ cpg->pin = &wh_pin; -+ } -+ -+ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE) -+ && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode)) -+ err = au_cpup_wh(cpg, file); -+ else { -+ struct au_cpup_wh_args args = { -+ .errp = &err, -+ .cpg = cpg, -+ .file = file -+ }; -+ wkq_err = au_wkq_wait(au_call_cpup_wh, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ if (h_orph) { -+ inode_unlock(h_tmpdir); -+ /* todo: au_h_open_post()? */ -+ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0); -+ au_set_h_dptr(parent, bdst, h_parent); -+ AuDebugOn(!pin_orig); -+ cpg->pin = pin_orig; -+ } -+ iput(h_dir); -+ dput(parent); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * generic routine for both of copy-up and copy-down. -+ */ -+/* cf. revalidate function in file.c */ -+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, -+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, -+ struct au_pin *pin, -+ struct dentry *h_parent, void *arg), -+ void *arg) -+{ -+ int err; -+ struct au_pin pin; -+ struct dentry *d, *parent, *h_parent, *real_parent, *h_dentry; -+ -+ err = 0; -+ parent = dget_parent(dentry); -+ if (IS_ROOT(parent)) -+ goto out; -+ -+ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2, -+ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE); -+ -+ /* do not use au_dpage */ -+ real_parent = parent; -+ while (1) { -+ dput(parent); -+ parent = dget_parent(dentry); -+ h_parent = au_h_dptr(parent, bdst); -+ if (h_parent) -+ goto out; /* success */ -+ -+ /* find top dir which is necessary to cpup */ -+ do { -+ d = parent; -+ dput(parent); -+ parent = dget_parent(d); -+ di_read_lock_parent3(parent, !AuLock_IR); -+ h_parent = au_h_dptr(parent, bdst); -+ di_read_unlock(parent, !AuLock_IR); -+ } while (!h_parent); -+ -+ if (d != real_parent) -+ di_write_lock_child3(d); -+ -+ /* somebody else might create while we were sleeping */ -+ h_dentry = au_h_dptr(d, bdst); -+ if (!h_dentry || d_is_negative(h_dentry)) { -+ if (h_dentry) -+ au_update_dbtop(d); -+ -+ au_pin_set_dentry(&pin, d); -+ err = au_do_pin(&pin); -+ if (!err) { -+ err = cp(d, bdst, &pin, h_parent, arg); -+ au_unpin(&pin); -+ } -+ } -+ -+ if (d != real_parent) -+ di_write_unlock(d); -+ if (unlikely(err)) -+ break; -+ } -+ -+out: -+ dput(parent); -+ return err; -+} -+ -+static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst, -+ struct au_pin *pin, -+ struct dentry *h_parent __maybe_unused, -+ void *arg __maybe_unused) -+{ -+ struct au_cp_generic cpg = { -+ .dentry = dentry, -+ .bdst = bdst, -+ .bsrc = -1, -+ .len = 0, -+ .pin = pin, -+ .flags = AuCpup_DTIME -+ }; -+ return au_sio_cpup_simple(&cpg); -+} -+ -+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) -+{ -+ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL); -+} -+ -+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) -+{ -+ int err; -+ struct dentry *parent; -+ struct inode *dir; -+ -+ parent = dget_parent(dentry); -+ dir = d_inode(parent); -+ err = 0; -+ if (au_h_iptr(dir, bdst)) -+ goto out; -+ -+ di_read_unlock(parent, AuLock_IR); -+ di_write_lock_parent(parent); -+ /* someone else might change our inode while we were sleeping */ -+ if (!au_h_iptr(dir, bdst)) -+ err = au_cpup_dirs(dentry, bdst); -+ di_downgrade_lock(parent, AuLock_IR); -+ -+out: -+ dput(parent); -+ return err; -+} -diff --git a/fs/aufs/cpup.h b/fs/aufs/cpup.h -new file mode 100644 -index 000000000..0faad688b ---- /dev/null -+++ b/fs/aufs/cpup.h -@@ -0,0 +1,100 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * copy-up/down functions -+ */ -+ -+#ifndef __AUFS_CPUP_H__ -+#define __AUFS_CPUP_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+struct inode; -+struct file; -+struct au_pin; -+ -+void au_cpup_attr_flags(struct inode *dst, unsigned int iflags); -+void au_cpup_attr_timesizes(struct inode *inode); -+void au_cpup_attr_nlink(struct inode *inode, int force); -+void au_cpup_attr_changeable(struct inode *inode); -+void au_cpup_igen(struct inode *inode, struct inode *h_inode); -+void au_cpup_attr_all(struct inode *inode, int force); -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_cp_generic { -+ struct dentry *dentry; -+ aufs_bindex_t bdst, bsrc; -+ loff_t len; -+ struct au_pin *pin; -+ unsigned int flags; -+}; -+ -+/* cpup flags */ -+#define AuCpup_DTIME 1 /* do dtime_store/revert */ -+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino, -+ for link(2) */ -+#define AuCpup_RENAME (1 << 2) /* rename after cpup */ -+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in -+ cpup */ -+#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the -+ existing entry */ -+#define AuCpup_RWDST (1 << 5) /* force write target even if -+ the branch is marked as RO */ -+ -+#ifndef CONFIG_AUFS_BR_HFSPLUS -+#undef AuCpup_HOPEN -+#define AuCpup_HOPEN 0 -+#endif -+ -+#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name) -+#define au_fset_cpup(flags, name) \ -+ do { (flags) |= AuCpup_##name; } while (0) -+#define au_fclr_cpup(flags, name) \ -+ do { (flags) &= ~AuCpup_##name; } while (0) -+ -+int au_copy_file(struct file *dst, struct file *src, loff_t len); -+int au_sio_cpup_simple(struct au_cp_generic *cpg); -+int au_sio_cpdown_simple(struct au_cp_generic *cpg); -+int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file); -+ -+int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, -+ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, -+ struct au_pin *pin, -+ struct dentry *h_parent, void *arg), -+ void *arg); -+int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); -+int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* keep timestamps when copyup */ -+struct au_dtime { -+ struct dentry *dt_dentry; -+ struct path dt_h_path; -+ struct timespec64 dt_atime, dt_mtime; -+}; -+void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, -+ struct path *h_path); -+void au_dtime_revert(struct au_dtime *dt); -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_CPUP_H__ */ -diff --git a/fs/aufs/dbgaufs.c b/fs/aufs/dbgaufs.c -new file mode 100644 -index 000000000..13872925a ---- /dev/null -+++ b/fs/aufs/dbgaufs.c -@@ -0,0 +1,519 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * debugfs interface -+ */ -+ -+#include -+#include "aufs.h" -+ -+#ifndef CONFIG_SYSFS -+#error DEBUG_FS depends upon SYSFS -+#endif -+ -+static struct dentry *dbgaufs; -+static const mode_t dbgaufs_mode = 0444; -+ -+/* 20 is max digits length of ulong 64 */ -+struct dbgaufs_arg { -+ int n; -+ char a[20 * 4]; -+}; -+ -+/* -+ * common function for all XINO files -+ */ -+static int dbgaufs_xi_release(struct inode *inode __maybe_unused, -+ struct file *file) -+{ -+ kfree(file->private_data); -+ return 0; -+} -+ -+static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt, -+ int cnt) -+{ -+ int err; -+ struct kstat st; -+ struct dbgaufs_arg *p; -+ -+ err = -ENOMEM; -+ p = kmalloc(sizeof(*p), GFP_NOFS); -+ if (unlikely(!p)) -+ goto out; -+ -+ err = 0; -+ p->n = 0; -+ file->private_data = p; -+ if (!xf) -+ goto out; -+ -+ err = vfsub_getattr(&xf->f_path, &st); -+ if (!err) { -+ if (do_fcnt) -+ p->n = snprintf -+ (p->a, sizeof(p->a), "%d, %llux%u %lld\n", -+ cnt, st.blocks, st.blksize, -+ (long long)st.size); -+ else -+ p->n = snprintf(p->a, sizeof(p->a), "%llux%u %lld\n", -+ st.blocks, st.blksize, -+ (long long)st.size); -+ AuDebugOn(p->n >= sizeof(p->a)); -+ } else { -+ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err); -+ err = 0; -+ } -+ -+out: -+ return err; -+} -+ -+static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ struct dbgaufs_arg *p; -+ -+ p = file->private_data; -+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct dbgaufs_plink_arg { -+ int n; -+ char a[]; -+}; -+ -+static int dbgaufs_plink_release(struct inode *inode __maybe_unused, -+ struct file *file) -+{ -+ free_page((unsigned long)file->private_data); -+ return 0; -+} -+ -+static int dbgaufs_plink_open(struct inode *inode, struct file *file) -+{ -+ int err, i, limit; -+ unsigned long n, sum; -+ struct dbgaufs_plink_arg *p; -+ struct au_sbinfo *sbinfo; -+ struct super_block *sb; -+ struct hlist_bl_head *hbl; -+ -+ err = -ENOMEM; -+ p = (void *)get_zeroed_page(GFP_NOFS); -+ if (unlikely(!p)) -+ goto out; -+ -+ err = -EFBIG; -+ sbinfo = inode->i_private; -+ sb = sbinfo->si_sb; -+ si_noflush_read_lock(sb); -+ if (au_opt_test(au_mntflags(sb), PLINK)) { -+ limit = PAGE_SIZE - sizeof(p->n); -+ -+ /* the number of buckets */ -+ n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH); -+ p->n += n; -+ limit -= n; -+ -+ sum = 0; -+ for (i = 0, hbl = sbinfo->si_plink; i < AuPlink_NHASH; -+ i++, hbl++) { -+ n = au_hbl_count(hbl); -+ sum += n; -+ -+ n = snprintf(p->a + p->n, limit, "%lu ", n); -+ p->n += n; -+ limit -= n; -+ if (unlikely(limit <= 0)) -+ goto out_free; -+ } -+ p->a[p->n - 1] = '\n'; -+ -+ /* the sum of plinks */ -+ n = snprintf(p->a + p->n, limit, "%lu\n", sum); -+ p->n += n; -+ limit -= n; -+ if (unlikely(limit <= 0)) -+ goto out_free; -+ } else { -+#define str "1\n0\n0\n" -+ p->n = sizeof(str) - 1; -+ strcpy(p->a, str); -+#undef str -+ } -+ si_read_unlock(sb); -+ -+ err = 0; -+ file->private_data = p; -+ goto out; /* success */ -+ -+out_free: -+ free_page((unsigned long)p); -+out: -+ return err; -+} -+ -+static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ struct dbgaufs_plink_arg *p; -+ -+ p = file->private_data; -+ return simple_read_from_buffer(buf, count, ppos, p->a, p->n); -+} -+ -+static const struct file_operations dbgaufs_plink_fop = { -+ .owner = THIS_MODULE, -+ .open = dbgaufs_plink_open, -+ .release = dbgaufs_plink_release, -+ .read = dbgaufs_plink_read -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int dbgaufs_xib_open(struct inode *inode, struct file *file) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ struct super_block *sb; -+ -+ sbinfo = inode->i_private; -+ sb = sbinfo->si_sb; -+ si_noflush_read_lock(sb); -+ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0, /*cnt*/0); -+ si_read_unlock(sb); -+ return err; -+} -+ -+static const struct file_operations dbgaufs_xib_fop = { -+ .owner = THIS_MODULE, -+ .open = dbgaufs_xib_open, -+ .release = dbgaufs_xi_release, -+ .read = dbgaufs_xi_read -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define DbgaufsXi_PREFIX "xi" -+ -+static int dbgaufs_xino_open(struct inode *inode, struct file *file) -+{ -+ int err, idx; -+ long l; -+ aufs_bindex_t bindex; -+ char *p, a[sizeof(DbgaufsXi_PREFIX) + 8]; -+ struct au_sbinfo *sbinfo; -+ struct super_block *sb; -+ struct au_xino *xi; -+ struct file *xf; -+ struct qstr *name; -+ struct au_branch *br; -+ -+ err = -ENOENT; -+ name = &file->f_path.dentry->d_name; -+ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX) -+ || memcmp(name->name, DbgaufsXi_PREFIX, -+ sizeof(DbgaufsXi_PREFIX) - 1))) -+ goto out; -+ -+ AuDebugOn(name->len >= sizeof(a)); -+ memcpy(a, name->name, name->len); -+ a[name->len] = '\0'; -+ p = strchr(a, '-'); -+ if (p) -+ *p = '\0'; -+ err = kstrtol(a + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l); -+ if (unlikely(err)) -+ goto out; -+ bindex = l; -+ idx = 0; -+ if (p) { -+ err = kstrtol(p + 1, 10, &l); -+ if (unlikely(err)) -+ goto out; -+ idx = l; -+ } -+ -+ err = -ENOENT; -+ sbinfo = inode->i_private; -+ sb = sbinfo->si_sb; -+ si_noflush_read_lock(sb); -+ if (unlikely(bindex < 0 || bindex > au_sbbot(sb))) -+ goto out_si; -+ br = au_sbr(sb, bindex); -+ xi = br->br_xino; -+ if (unlikely(idx >= xi->xi_nfile)) -+ goto out_si; -+ xf = au_xino_file(xi, idx); -+ if (xf) -+ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1, -+ au_xino_count(br)); -+ -+out_si: -+ si_read_unlock(sb); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static const struct file_operations dbgaufs_xino_fop = { -+ .owner = THIS_MODULE, -+ .open = dbgaufs_xino_open, -+ .release = dbgaufs_xi_release, -+ .read = dbgaufs_xi_read -+}; -+ -+void dbgaufs_xino_del(struct au_branch *br) -+{ -+ struct dentry *dbgaufs; -+ -+ dbgaufs = br->br_dbgaufs; -+ if (!dbgaufs) -+ return; -+ -+ br->br_dbgaufs = NULL; -+ /* debugfs acquires the parent i_mutex */ -+ lockdep_off(); -+ debugfs_remove(dbgaufs); -+ lockdep_on(); -+} -+ -+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ aufs_bindex_t bbot; -+ struct au_branch *br; -+ -+ if (!au_sbi(sb)->si_dbgaufs) -+ return; -+ -+ bbot = au_sbbot(sb); -+ for (; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ dbgaufs_xino_del(br); -+ } -+} -+ -+static void dbgaufs_br_do_add(struct super_block *sb, aufs_bindex_t bindex, -+ unsigned int idx, struct dentry *parent, -+ struct au_sbinfo *sbinfo) -+{ -+ struct au_branch *br; -+ struct dentry *d; -+ /* "xi" bindex(5) "-" idx(2) NULL */ -+ char name[sizeof(DbgaufsXi_PREFIX) + 8]; -+ -+ if (!idx) -+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex); -+ else -+ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d-%u", -+ bindex, idx); -+ br = au_sbr(sb, bindex); -+ if (br->br_dbgaufs) { -+ struct qstr qstr = QSTR_INIT(name, strlen(name)); -+ -+ if (!au_qstreq(&br->br_dbgaufs->d_name, &qstr)) { -+ /* debugfs acquires the parent i_mutex */ -+ lockdep_off(); -+ d = debugfs_rename(parent, br->br_dbgaufs, parent, -+ name); -+ lockdep_on(); -+ if (unlikely(!d)) -+ pr_warn("failed renaming %pd/%s, ignored.\n", -+ parent, name); -+ } -+ } else { -+ lockdep_off(); -+ br->br_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent, -+ sbinfo, &dbgaufs_xino_fop); -+ lockdep_on(); -+ if (unlikely(!br->br_dbgaufs)) -+ pr_warn("failed creating %pd/%s, ignored.\n", -+ parent, name); -+ } -+} -+ -+static void dbgaufs_br_add(struct super_block *sb, aufs_bindex_t bindex, -+ struct dentry *parent, struct au_sbinfo *sbinfo) -+{ -+ struct au_branch *br; -+ struct au_xino *xi; -+ unsigned int u; -+ -+ br = au_sbr(sb, bindex); -+ xi = br->br_xino; -+ for (u = 0; u < xi->xi_nfile; u++) -+ dbgaufs_br_do_add(sb, bindex, u, parent, sbinfo); -+} -+ -+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex, int topdown) -+{ -+ struct au_sbinfo *sbinfo; -+ struct dentry *parent; -+ aufs_bindex_t bbot; -+ -+ if (!au_opt_test(au_mntflags(sb), XINO)) -+ return; -+ -+ sbinfo = au_sbi(sb); -+ parent = sbinfo->si_dbgaufs; -+ if (!parent) -+ return; -+ -+ bbot = au_sbbot(sb); -+ if (topdown) -+ for (; bindex <= bbot; bindex++) -+ dbgaufs_br_add(sb, bindex, parent, sbinfo); -+ else -+ for (; bbot >= bindex; bbot--) -+ dbgaufs_br_add(sb, bbot, parent, sbinfo); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_EXPORT -+static int dbgaufs_xigen_open(struct inode *inode, struct file *file) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ struct super_block *sb; -+ -+ sbinfo = inode->i_private; -+ sb = sbinfo->si_sb; -+ si_noflush_read_lock(sb); -+ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0, /*cnt*/0); -+ si_read_unlock(sb); -+ return err; -+} -+ -+static const struct file_operations dbgaufs_xigen_fop = { -+ .owner = THIS_MODULE, -+ .open = dbgaufs_xigen_open, -+ .release = dbgaufs_xi_release, -+ .read = dbgaufs_xi_read -+}; -+ -+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo) -+{ -+ int err; -+ -+ /* -+ * This function is a dynamic '__init' function actually, -+ * so the tiny check for si_rwsem is unnecessary. -+ */ -+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ -+ -+ err = -EIO; -+ sbinfo->si_dbgaufs_xigen = debugfs_create_file -+ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, -+ &dbgaufs_xigen_fop); -+ if (sbinfo->si_dbgaufs_xigen) -+ err = 0; -+ -+ return err; -+} -+#else -+static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo) -+{ -+ return 0; -+} -+#endif /* CONFIG_AUFS_EXPORT */ -+ -+/* ---------------------------------------------------------------------- */ -+ -+void dbgaufs_si_fin(struct au_sbinfo *sbinfo) -+{ -+ /* -+ * This function is a dynamic '__fin' function actually, -+ * so the tiny check for si_rwsem is unnecessary. -+ */ -+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ -+ -+ debugfs_remove_recursive(sbinfo->si_dbgaufs); -+ sbinfo->si_dbgaufs = NULL; -+} -+ -+int dbgaufs_si_init(struct au_sbinfo *sbinfo) -+{ -+ int err; -+ char name[SysaufsSiNameLen]; -+ -+ /* -+ * This function is a dynamic '__init' function actually, -+ * so the tiny check for si_rwsem is unnecessary. -+ */ -+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ -+ -+ err = -ENOENT; -+ if (!dbgaufs) { -+ AuErr1("/debug/aufs is uninitialized\n"); -+ goto out; -+ } -+ -+ err = -EIO; -+ sysaufs_name(sbinfo, name); -+ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs); -+ if (unlikely(!sbinfo->si_dbgaufs)) -+ goto out; -+ -+ /* regardless plink/noplink option */ -+ sbinfo->si_dbgaufs_plink = debugfs_create_file -+ ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, -+ &dbgaufs_plink_fop); -+ if (unlikely(!sbinfo->si_dbgaufs_plink)) -+ goto out_dir; -+ -+ /* regardless xino/noxino option */ -+ sbinfo->si_dbgaufs_xib = debugfs_create_file -+ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, -+ &dbgaufs_xib_fop); -+ if (unlikely(!sbinfo->si_dbgaufs_xib)) -+ goto out_dir; -+ -+ err = dbgaufs_xigen_init(sbinfo); -+ if (!err) -+ goto out; /* success */ -+ -+out_dir: -+ dbgaufs_si_fin(sbinfo); -+out: -+ if (unlikely(err)) -+ pr_err("debugfs/aufs failed\n"); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void dbgaufs_fin(void) -+{ -+ debugfs_remove(dbgaufs); -+} -+ -+int __init dbgaufs_init(void) -+{ -+ int err; -+ -+ err = -EIO; -+ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL); -+ if (dbgaufs) -+ err = 0; -+ return err; -+} -diff --git a/fs/aufs/dbgaufs.h b/fs/aufs/dbgaufs.h -new file mode 100644 -index 000000000..59d7b9d08 ---- /dev/null -+++ b/fs/aufs/dbgaufs.h -@@ -0,0 +1,53 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * debugfs interface -+ */ -+ -+#ifndef __DBGAUFS_H__ -+#define __DBGAUFS_H__ -+ -+#ifdef __KERNEL__ -+ -+struct super_block; -+struct au_sbinfo; -+struct au_branch; -+ -+#ifdef CONFIG_DEBUG_FS -+/* dbgaufs.c */ -+void dbgaufs_xino_del(struct au_branch *br); -+void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex); -+void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex, int topdown); -+void dbgaufs_si_fin(struct au_sbinfo *sbinfo); -+int dbgaufs_si_init(struct au_sbinfo *sbinfo); -+void dbgaufs_fin(void); -+int __init dbgaufs_init(void); -+#else -+AuStubVoid(dbgaufs_xino_del, struct au_branch *br) -+AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex) -+AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex, -+ int topdown) -+AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo) -+AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo) -+AuStubVoid(dbgaufs_fin, void) -+AuStubInt0(__init dbgaufs_init, void) -+#endif /* CONFIG_DEBUG_FS */ -+ -+#endif /* __KERNEL__ */ -+#endif /* __DBGAUFS_H__ */ -diff --git a/fs/aufs/dcsub.c b/fs/aufs/dcsub.c -new file mode 100644 -index 000000000..b30828810 ---- /dev/null -+++ b/fs/aufs/dcsub.c -@@ -0,0 +1,225 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * sub-routines for dentry cache -+ */ -+ -+#include "aufs.h" -+ -+static void au_dpage_free(struct au_dpage *dpage) -+{ -+ int i; -+ struct dentry **p; -+ -+ p = dpage->dentries; -+ for (i = 0; i < dpage->ndentry; i++) -+ dput(*p++); -+ free_page((unsigned long)dpage->dentries); -+} -+ -+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp) -+{ -+ int err; -+ void *p; -+ -+ err = -ENOMEM; -+ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp); -+ if (unlikely(!dpages->dpages)) -+ goto out; -+ -+ p = (void *)__get_free_page(gfp); -+ if (unlikely(!p)) -+ goto out_dpages; -+ -+ dpages->dpages[0].ndentry = 0; -+ dpages->dpages[0].dentries = p; -+ dpages->ndpage = 1; -+ return 0; /* success */ -+ -+out_dpages: -+ kfree(dpages->dpages); -+out: -+ return err; -+} -+ -+void au_dpages_free(struct au_dcsub_pages *dpages) -+{ -+ int i; -+ struct au_dpage *p; -+ -+ p = dpages->dpages; -+ for (i = 0; i < dpages->ndpage; i++) -+ au_dpage_free(p++); -+ kfree(dpages->dpages); -+} -+ -+static int au_dpages_append(struct au_dcsub_pages *dpages, -+ struct dentry *dentry, gfp_t gfp) -+{ -+ int err, sz; -+ struct au_dpage *dpage; -+ void *p; -+ -+ dpage = dpages->dpages + dpages->ndpage - 1; -+ sz = PAGE_SIZE / sizeof(dentry); -+ if (unlikely(dpage->ndentry >= sz)) { -+ AuLabel(new dpage); -+ err = -ENOMEM; -+ sz = dpages->ndpage * sizeof(*dpages->dpages); -+ p = au_kzrealloc(dpages->dpages, sz, -+ sz + sizeof(*dpages->dpages), gfp, -+ /*may_shrink*/0); -+ if (unlikely(!p)) -+ goto out; -+ -+ dpages->dpages = p; -+ dpage = dpages->dpages + dpages->ndpage; -+ p = (void *)__get_free_page(gfp); -+ if (unlikely(!p)) -+ goto out; -+ -+ dpage->ndentry = 0; -+ dpage->dentries = p; -+ dpages->ndpage++; -+ } -+ -+ AuDebugOn(au_dcount(dentry) <= 0); -+ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry); -+ return 0; /* success */ -+ -+out: -+ return err; -+} -+ -+/* todo: BAD approach */ -+/* copied from linux/fs/dcache.c */ -+enum d_walk_ret { -+ D_WALK_CONTINUE, -+ D_WALK_QUIT, -+ D_WALK_NORETRY, -+ D_WALK_SKIP, -+}; -+ -+extern void d_walk(struct dentry *parent, void *data, -+ enum d_walk_ret (*enter)(void *, struct dentry *)); -+ -+struct ac_dpages_arg { -+ int err; -+ struct au_dcsub_pages *dpages; -+ struct super_block *sb; -+ au_dpages_test test; -+ void *arg; -+}; -+ -+static enum d_walk_ret au_call_dpages_append(void *_arg, struct dentry *dentry) -+{ -+ enum d_walk_ret ret; -+ struct ac_dpages_arg *arg = _arg; -+ -+ ret = D_WALK_CONTINUE; -+ if (dentry->d_sb == arg->sb -+ && !IS_ROOT(dentry) -+ && au_dcount(dentry) > 0 -+ && au_di(dentry) -+ && (!arg->test || arg->test(dentry, arg->arg))) { -+ arg->err = au_dpages_append(arg->dpages, dentry, GFP_ATOMIC); -+ if (unlikely(arg->err)) -+ ret = D_WALK_QUIT; -+ } -+ -+ return ret; -+} -+ -+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, -+ au_dpages_test test, void *arg) -+{ -+ struct ac_dpages_arg args = { -+ .err = 0, -+ .dpages = dpages, -+ .sb = root->d_sb, -+ .test = test, -+ .arg = arg -+ }; -+ -+ d_walk(root, &args, au_call_dpages_append); -+ -+ return args.err; -+} -+ -+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, -+ int do_include, au_dpages_test test, void *arg) -+{ -+ int err; -+ -+ err = 0; -+ write_seqlock(&rename_lock); -+ spin_lock(&dentry->d_lock); -+ if (do_include -+ && au_dcount(dentry) > 0 -+ && (!test || test(dentry, arg))) -+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); -+ spin_unlock(&dentry->d_lock); -+ if (unlikely(err)) -+ goto out; -+ -+ /* -+ * RCU for vfsmount is unnecessary since this is a traverse in a single -+ * mount -+ */ -+ while (!IS_ROOT(dentry)) { -+ dentry = dentry->d_parent; /* rename_lock is locked */ -+ spin_lock(&dentry->d_lock); -+ if (au_dcount(dentry) > 0 -+ && (!test || test(dentry, arg))) -+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); -+ spin_unlock(&dentry->d_lock); -+ if (unlikely(err)) -+ break; -+ } -+ -+out: -+ write_sequnlock(&rename_lock); -+ return err; -+} -+ -+static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg) -+{ -+ return au_di(dentry) && dentry->d_sb == arg; -+} -+ -+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages, -+ struct dentry *dentry, int do_include) -+{ -+ return au_dcsub_pages_rev(dpages, dentry, do_include, -+ au_dcsub_dpages_aufs, dentry->d_sb); -+} -+ -+int au_test_subdir(struct dentry *d1, struct dentry *d2) -+{ -+ struct path path[2] = { -+ { -+ .dentry = d1 -+ }, -+ { -+ .dentry = d2 -+ } -+ }; -+ -+ return path_is_under(path + 0, path + 1); -+} -diff --git a/fs/aufs/dcsub.h b/fs/aufs/dcsub.h -new file mode 100644 -index 000000000..c610133de ---- /dev/null -+++ b/fs/aufs/dcsub.h -@@ -0,0 +1,137 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * sub-routines for dentry cache -+ */ -+ -+#ifndef __AUFS_DCSUB_H__ -+#define __AUFS_DCSUB_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+ -+struct au_dpage { -+ int ndentry; -+ struct dentry **dentries; -+}; -+ -+struct au_dcsub_pages { -+ int ndpage; -+ struct au_dpage *dpages; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* dcsub.c */ -+int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp); -+void au_dpages_free(struct au_dcsub_pages *dpages); -+typedef int (*au_dpages_test)(struct dentry *dentry, void *arg); -+int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, -+ au_dpages_test test, void *arg); -+int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, -+ int do_include, au_dpages_test test, void *arg); -+int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages, -+ struct dentry *dentry, int do_include); -+int au_test_subdir(struct dentry *d1, struct dentry *d2); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * todo: in linux-3.13, several similar (but faster) helpers are added to -+ * include/linux/dcache.h. Try them (in the future). -+ */ -+ -+static inline int au_d_hashed_positive(struct dentry *d) -+{ -+ int err; -+ struct inode *inode = d_inode(d); -+ -+ err = 0; -+ if (unlikely(d_unhashed(d) -+ || d_is_negative(d) -+ || !inode->i_nlink)) -+ err = -ENOENT; -+ return err; -+} -+ -+static inline int au_d_linkable(struct dentry *d) -+{ -+ int err; -+ struct inode *inode = d_inode(d); -+ -+ err = au_d_hashed_positive(d); -+ if (err -+ && d_is_positive(d) -+ && (inode->i_state & I_LINKABLE)) -+ err = 0; -+ return err; -+} -+ -+static inline int au_d_alive(struct dentry *d) -+{ -+ int err; -+ struct inode *inode; -+ -+ err = 0; -+ if (!IS_ROOT(d)) -+ err = au_d_hashed_positive(d); -+ else { -+ inode = d_inode(d); -+ if (unlikely(d_unlinked(d) -+ || d_is_negative(d) -+ || !inode->i_nlink)) -+ err = -ENOENT; -+ } -+ return err; -+} -+ -+static inline int au_alive_dir(struct dentry *d) -+{ -+ int err; -+ -+ err = au_d_alive(d); -+ if (unlikely(err || IS_DEADDIR(d_inode(d)))) -+ err = -ENOENT; -+ return err; -+} -+ -+static inline int au_qstreq(struct qstr *a, struct qstr *b) -+{ -+ return a->len == b->len -+ && !memcmp(a->name, b->name, a->len); -+} -+ -+/* -+ * by the commit -+ * 360f547 2015-01-25 dcache: let the dentry count go down to zero without -+ * taking d_lock -+ * the type of d_lockref.count became int, but the inlined function d_count() -+ * still returns unsigned int. -+ * I don't know why. Maybe it is for every d_count() users? -+ * Anyway au_dcount() lives on. -+ */ -+static inline int au_dcount(struct dentry *d) -+{ -+ return (int)d_count(d); -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DCSUB_H__ */ -diff --git a/fs/aufs/debug.c b/fs/aufs/debug.c -new file mode 100644 -index 000000000..51b978b0e ---- /dev/null -+++ b/fs/aufs/debug.c -@@ -0,0 +1,440 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * debug print functions -+ */ -+ -+#include "aufs.h" -+ -+/* Returns 0, or -errno. arg is in kp->arg. */ -+static int param_atomic_t_set(const char *val, const struct kernel_param *kp) -+{ -+ int err, n; -+ -+ err = kstrtoint(val, 0, &n); -+ if (!err) { -+ if (n > 0) -+ au_debug_on(); -+ else -+ au_debug_off(); -+ } -+ return err; -+} -+ -+/* Returns length written or -errno. Buffer is 4k (ie. be short!) */ -+static int param_atomic_t_get(char *buffer, const struct kernel_param *kp) -+{ -+ atomic_t *a; -+ -+ a = kp->arg; -+ return sprintf(buffer, "%d", atomic_read(a)); -+} -+ -+static struct kernel_param_ops param_ops_atomic_t = { -+ .set = param_atomic_t_set, -+ .get = param_atomic_t_get -+ /* void (*free)(void *arg) */ -+}; -+ -+atomic_t aufs_debug = ATOMIC_INIT(0); -+MODULE_PARM_DESC(debug, "debug print"); -+module_param_named(debug, aufs_debug, atomic_t, 0664); -+ -+DEFINE_MUTEX(au_dbg_mtx); /* just to serialize the dbg msgs */ -+char *au_plevel = KERN_DEBUG; -+#define dpri(fmt, ...) do { \ -+ if ((au_plevel \ -+ && strcmp(au_plevel, KERN_DEBUG)) \ -+ || au_debug_test()) \ -+ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \ -+} while (0) -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_dpri_whlist(struct au_nhash *whlist) -+{ -+ unsigned long ul, n; -+ struct hlist_head *head; -+ struct au_vdir_wh *pos; -+ -+ n = whlist->nh_num; -+ head = whlist->nh_head; -+ for (ul = 0; ul < n; ul++) { -+ hlist_for_each_entry(pos, head, wh_hash) -+ dpri("b%d, %.*s, %d\n", -+ pos->wh_bindex, -+ pos->wh_str.len, pos->wh_str.name, -+ pos->wh_str.len); -+ head++; -+ } -+} -+ -+void au_dpri_vdir(struct au_vdir *vdir) -+{ -+ unsigned long ul; -+ union au_vdir_deblk_p p; -+ unsigned char *o; -+ -+ if (!vdir || IS_ERR(vdir)) { -+ dpri("err %ld\n", PTR_ERR(vdir)); -+ return; -+ } -+ -+ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %llu\n", -+ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk, -+ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version); -+ for (ul = 0; ul < vdir->vd_nblk; ul++) { -+ p.deblk = vdir->vd_deblk[ul]; -+ o = p.deblk; -+ dpri("[%lu]: %p\n", ul, o); -+ } -+} -+ -+static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn, -+ struct dentry *wh) -+{ -+ char *n = NULL; -+ int l = 0; -+ -+ if (!inode || IS_ERR(inode)) { -+ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode)); -+ return -1; -+ } -+ -+ /* the type of i_blocks depends upon CONFIG_LBDAF */ -+ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long) -+ && sizeof(inode->i_blocks) != sizeof(u64)); -+ if (wh) { -+ n = (void *)wh->d_name.name; -+ l = wh->d_name.len; -+ } -+ -+ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu," -+ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n", -+ bindex, inode, -+ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??", -+ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode, -+ i_size_read(inode), (unsigned long long)inode->i_blocks, -+ hn, (long long)timespec64_to_ns(&inode->i_ctime) & 0x0ffff, -+ inode->i_mapping ? inode->i_mapping->nrpages : 0, -+ inode->i_state, inode->i_flags, inode_peek_iversion(inode), -+ inode->i_generation, -+ l ? ", wh " : "", l, n); -+ return 0; -+} -+ -+void au_dpri_inode(struct inode *inode) -+{ -+ struct au_iinfo *iinfo; -+ struct au_hinode *hi; -+ aufs_bindex_t bindex; -+ int err, hn; -+ -+ err = do_pri_inode(-1, inode, -1, NULL); -+ if (err || !au_test_aufs(inode->i_sb) || au_is_bad_inode(inode)) -+ return; -+ -+ iinfo = au_ii(inode); -+ dpri("i-1: btop %d, bbot %d, gen %d\n", -+ iinfo->ii_btop, iinfo->ii_bbot, au_iigen(inode, NULL)); -+ if (iinfo->ii_btop < 0) -+ return; -+ hn = 0; -+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot; bindex++) { -+ hi = au_hinode(iinfo, bindex); -+ hn = !!au_hn(hi); -+ do_pri_inode(bindex, hi->hi_inode, hn, hi->hi_whdentry); -+ } -+} -+ -+void au_dpri_dalias(struct inode *inode) -+{ -+ struct dentry *d; -+ -+ spin_lock(&inode->i_lock); -+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) -+ au_dpri_dentry(d); -+ spin_unlock(&inode->i_lock); -+} -+ -+static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry) -+{ -+ struct dentry *wh = NULL; -+ int hn; -+ struct inode *inode; -+ struct au_iinfo *iinfo; -+ struct au_hinode *hi; -+ -+ if (!dentry || IS_ERR(dentry)) { -+ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry)); -+ return -1; -+ } -+ /* do not call dget_parent() here */ -+ /* note: access d_xxx without d_lock */ -+ dpri("d%d: %p, %pd2?, %s, cnt %d, flags 0x%x, %shashed\n", -+ bindex, dentry, dentry, -+ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??", -+ au_dcount(dentry), dentry->d_flags, -+ d_unhashed(dentry) ? "un" : ""); -+ hn = -1; -+ inode = NULL; -+ if (d_is_positive(dentry)) -+ inode = d_inode(dentry); -+ if (inode -+ && au_test_aufs(dentry->d_sb) -+ && bindex >= 0 -+ && !au_is_bad_inode(inode)) { -+ iinfo = au_ii(inode); -+ hi = au_hinode(iinfo, bindex); -+ hn = !!au_hn(hi); -+ wh = hi->hi_whdentry; -+ } -+ do_pri_inode(bindex, inode, hn, wh); -+ return 0; -+} -+ -+void au_dpri_dentry(struct dentry *dentry) -+{ -+ struct au_dinfo *dinfo; -+ aufs_bindex_t bindex; -+ int err; -+ -+ err = do_pri_dentry(-1, dentry); -+ if (err || !au_test_aufs(dentry->d_sb)) -+ return; -+ -+ dinfo = au_di(dentry); -+ if (!dinfo) -+ return; -+ dpri("d-1: btop %d, bbot %d, bwh %d, bdiropq %d, gen %d, tmp %d\n", -+ dinfo->di_btop, dinfo->di_bbot, -+ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry), -+ dinfo->di_tmpfile); -+ if (dinfo->di_btop < 0) -+ return; -+ for (bindex = dinfo->di_btop; bindex <= dinfo->di_bbot; bindex++) -+ do_pri_dentry(bindex, au_hdentry(dinfo, bindex)->hd_dentry); -+} -+ -+static int do_pri_file(aufs_bindex_t bindex, struct file *file) -+{ -+ char a[32]; -+ -+ if (!file || IS_ERR(file)) { -+ dpri("f%d: err %ld\n", bindex, PTR_ERR(file)); -+ return -1; -+ } -+ a[0] = 0; -+ if (bindex < 0 -+ && !IS_ERR_OR_NULL(file->f_path.dentry) -+ && au_test_aufs(file->f_path.dentry->d_sb) -+ && au_fi(file)) -+ snprintf(a, sizeof(a), ", gen %d, mmapped %d", -+ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped)); -+ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n", -+ bindex, file->f_mode, file->f_flags, (long)file_count(file), -+ file->f_version, file->f_pos, a); -+ if (!IS_ERR_OR_NULL(file->f_path.dentry)) -+ do_pri_dentry(bindex, file->f_path.dentry); -+ return 0; -+} -+ -+void au_dpri_file(struct file *file) -+{ -+ struct au_finfo *finfo; -+ struct au_fidir *fidir; -+ struct au_hfile *hfile; -+ aufs_bindex_t bindex; -+ int err; -+ -+ err = do_pri_file(-1, file); -+ if (err -+ || IS_ERR_OR_NULL(file->f_path.dentry) -+ || !au_test_aufs(file->f_path.dentry->d_sb)) -+ return; -+ -+ finfo = au_fi(file); -+ if (!finfo) -+ return; -+ if (finfo->fi_btop < 0) -+ return; -+ fidir = finfo->fi_hdir; -+ if (!fidir) -+ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file); -+ else -+ for (bindex = finfo->fi_btop; -+ bindex >= 0 && bindex <= fidir->fd_bbot; -+ bindex++) { -+ hfile = fidir->fd_hfile + bindex; -+ do_pri_file(bindex, hfile ? hfile->hf_file : NULL); -+ } -+} -+ -+static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br) -+{ -+ struct vfsmount *mnt; -+ struct super_block *sb; -+ -+ if (!br || IS_ERR(br)) -+ goto out; -+ mnt = au_br_mnt(br); -+ if (!mnt || IS_ERR(mnt)) -+ goto out; -+ sb = mnt->mnt_sb; -+ if (!sb || IS_ERR(sb)) -+ goto out; -+ -+ dpri("s%d: {perm 0x%x, id %d, wbr %p}, " -+ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, " -+ "xino %d\n", -+ bindex, br->br_perm, br->br_id, br->br_wbr, -+ au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev), -+ sb->s_flags, sb->s_count, -+ atomic_read(&sb->s_active), -+ !!au_xino_file(br->br_xino, /*idx*/-1)); -+ return 0; -+ -+out: -+ dpri("s%d: err %ld\n", bindex, PTR_ERR(br)); -+ return -1; -+} -+ -+void au_dpri_sb(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ aufs_bindex_t bindex; -+ int err; -+ /* to reduce stack size */ -+ struct { -+ struct vfsmount mnt; -+ struct au_branch fake; -+ } *a; -+ -+ /* this function can be called from magic sysrq */ -+ a = kzalloc(sizeof(*a), GFP_ATOMIC); -+ if (unlikely(!a)) { -+ dpri("no memory\n"); -+ return; -+ } -+ -+ a->mnt.mnt_sb = sb; -+ a->fake.br_path.mnt = &a->mnt; -+ err = do_pri_br(-1, &a->fake); -+ kfree(a); -+ dpri("dev 0x%x\n", sb->s_dev); -+ if (err || !au_test_aufs(sb)) -+ return; -+ -+ sbinfo = au_sbi(sb); -+ if (!sbinfo) -+ return; -+ dpri("nw %d, gen %u, kobj %d\n", -+ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation, -+ kref_read(&sbinfo->si_kobj.kref)); -+ for (bindex = 0; bindex <= sbinfo->si_bbot; bindex++) -+ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line) -+{ -+ struct inode *h_inode, *inode = d_inode(dentry); -+ struct dentry *h_dentry; -+ aufs_bindex_t bindex, bbot, bi; -+ -+ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */) -+ return; -+ -+ bbot = au_dbbot(dentry); -+ bi = au_ibbot(inode); -+ if (bi < bbot) -+ bbot = bi; -+ bindex = au_dbtop(dentry); -+ bi = au_ibtop(inode); -+ if (bi > bindex) -+ bindex = bi; -+ -+ for (; bindex <= bbot; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry) -+ continue; -+ h_inode = au_h_iptr(inode, bindex); -+ if (unlikely(h_inode != d_inode(h_dentry))) { -+ au_debug_on(); -+ AuDbg("b%d, %s:%d\n", bindex, func, line); -+ AuDbgDentry(dentry); -+ AuDbgInode(inode); -+ au_debug_off(); -+ BUG(); -+ } -+ } -+} -+ -+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen) -+{ -+ int err, i, j; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry **dentries; -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ AuDebugOn(err); -+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1); -+ AuDebugOn(err); -+ for (i = dpages.ndpage - 1; !err && i >= 0; i--) { -+ dpage = dpages.dpages + i; -+ dentries = dpage->dentries; -+ for (j = dpage->ndentry - 1; !err && j >= 0; j--) -+ AuDebugOn(au_digen_test(dentries[j], sigen)); -+ } -+ au_dpages_free(&dpages); -+} -+ -+void au_dbg_verify_kthread(void) -+{ -+ if (au_wkq_test()) { -+ au_dbg_blocked(); -+ /* -+ * It may be recursive, but udba=notify between two aufs mounts, -+ * where a single ro branch is shared, is not a problem. -+ */ -+ /* WARN_ON(1); */ -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int __init au_debug_init(void) -+{ -+ aufs_bindex_t bindex; -+ struct au_vdir_destr destr; -+ -+ bindex = -1; -+ AuDebugOn(bindex >= 0); -+ -+ destr.len = -1; -+ AuDebugOn(destr.len < NAME_MAX); -+ -+#ifdef CONFIG_4KSTACKS -+ pr_warn("CONFIG_4KSTACKS is defined.\n"); -+#endif -+ -+ return 0; -+} -diff --git a/fs/aufs/debug.h b/fs/aufs/debug.h -new file mode 100644 -index 000000000..b80bb5a9a ---- /dev/null -+++ b/fs/aufs/debug.h -@@ -0,0 +1,226 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * debug print functions -+ */ -+ -+#ifndef __AUFS_DEBUG_H__ -+#define __AUFS_DEBUG_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_AUFS_DEBUG -+#define AuDebugOn(a) BUG_ON(a) -+ -+/* module parameter */ -+extern atomic_t aufs_debug; -+static inline void au_debug_on(void) -+{ -+ atomic_inc(&aufs_debug); -+} -+static inline void au_debug_off(void) -+{ -+ atomic_dec_if_positive(&aufs_debug); -+} -+ -+static inline int au_debug_test(void) -+{ -+ return atomic_read(&aufs_debug) > 0; -+} -+#else -+#define AuDebugOn(a) do {} while (0) -+AuStubVoid(au_debug_on, void) -+AuStubVoid(au_debug_off, void) -+AuStubInt0(au_debug_test, void) -+#endif /* CONFIG_AUFS_DEBUG */ -+ -+#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t) -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* debug print */ -+ -+#define AuDbg(fmt, ...) do { \ -+ if (au_debug_test()) \ -+ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \ -+} while (0) -+#define AuLabel(l) AuDbg(#l "\n") -+#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__) -+#define AuWarn1(fmt, ...) do { \ -+ static unsigned char _c; \ -+ if (!_c++) \ -+ pr_warn(fmt, ##__VA_ARGS__); \ -+} while (0) -+ -+#define AuErr1(fmt, ...) do { \ -+ static unsigned char _c; \ -+ if (!_c++) \ -+ pr_err(fmt, ##__VA_ARGS__); \ -+} while (0) -+ -+#define AuIOErr1(fmt, ...) do { \ -+ static unsigned char _c; \ -+ if (!_c++) \ -+ AuIOErr(fmt, ##__VA_ARGS__); \ -+} while (0) -+ -+#define AuUnsupportMsg "This operation is not supported." \ -+ " Please report this application to aufs-users ML." -+#define AuUnsupport(fmt, ...) do { \ -+ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \ -+ dump_stack(); \ -+} while (0) -+ -+#define AuTraceErr(e) do { \ -+ if (unlikely((e) < 0)) \ -+ AuDbg("err %d\n", (int)(e)); \ -+} while (0) -+ -+#define AuTraceErrPtr(p) do { \ -+ if (IS_ERR(p)) \ -+ AuDbg("err %ld\n", PTR_ERR(p)); \ -+} while (0) -+ -+/* dirty macros for debug print, use with "%.*s" and caution */ -+#define AuLNPair(qstr) (qstr)->len, (qstr)->name -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct dentry; -+#ifdef CONFIG_AUFS_DEBUG -+extern struct mutex au_dbg_mtx; -+extern char *au_plevel; -+struct au_nhash; -+void au_dpri_whlist(struct au_nhash *whlist); -+struct au_vdir; -+void au_dpri_vdir(struct au_vdir *vdir); -+struct inode; -+void au_dpri_inode(struct inode *inode); -+void au_dpri_dalias(struct inode *inode); -+void au_dpri_dentry(struct dentry *dentry); -+struct file; -+void au_dpri_file(struct file *filp); -+struct super_block; -+void au_dpri_sb(struct super_block *sb); -+ -+#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__) -+void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line); -+void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen); -+void au_dbg_verify_kthread(void); -+ -+int __init au_debug_init(void); -+ -+#define AuDbgWhlist(w) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#w "\n"); \ -+ au_dpri_whlist(w); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgVdir(v) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#v "\n"); \ -+ au_dpri_vdir(v); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgInode(i) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#i "\n"); \ -+ au_dpri_inode(i); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgDAlias(i) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#i "\n"); \ -+ au_dpri_dalias(i); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgDentry(d) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#d "\n"); \ -+ au_dpri_dentry(d); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgFile(f) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#f "\n"); \ -+ au_dpri_file(f); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgSb(sb) do { \ -+ mutex_lock(&au_dbg_mtx); \ -+ AuDbg(#sb "\n"); \ -+ au_dpri_sb(sb); \ -+ mutex_unlock(&au_dbg_mtx); \ -+} while (0) -+ -+#define AuDbgSym(addr) do { \ -+ char sym[KSYM_SYMBOL_LEN]; \ -+ sprint_symbol(sym, (unsigned long)addr); \ -+ AuDbg("%s\n", sym); \ -+} while (0) -+#else -+AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry) -+AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen) -+AuStubVoid(au_dbg_verify_kthread, void) -+AuStubInt0(__init au_debug_init, void) -+ -+#define AuDbgWhlist(w) do {} while (0) -+#define AuDbgVdir(v) do {} while (0) -+#define AuDbgInode(i) do {} while (0) -+#define AuDbgDAlias(i) do {} while (0) -+#define AuDbgDentry(d) do {} while (0) -+#define AuDbgFile(f) do {} while (0) -+#define AuDbgSb(sb) do {} while (0) -+#define AuDbgSym(addr) do {} while (0) -+#endif /* CONFIG_AUFS_DEBUG */ -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_MAGIC_SYSRQ -+int __init au_sysrq_init(void); -+void au_sysrq_fin(void); -+ -+#ifdef CONFIG_HW_CONSOLE -+#define au_dbg_blocked() do { \ -+ WARN_ON(1); \ -+ handle_sysrq('w'); \ -+} while (0) -+#else -+AuStubVoid(au_dbg_blocked, void) -+#endif -+ -+#else -+AuStubInt0(__init au_sysrq_init, void) -+AuStubVoid(au_sysrq_fin, void) -+AuStubVoid(au_dbg_blocked, void) -+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */ -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DEBUG_H__ */ -diff --git a/fs/aufs/dentry.c b/fs/aufs/dentry.c -new file mode 100644 -index 000000000..79761eae9 ---- /dev/null -+++ b/fs/aufs/dentry.c -@@ -0,0 +1,1153 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * lookup and dentry operations -+ */ -+ -+#include -+#include "aufs.h" -+ -+/* -+ * returns positive/negative dentry, NULL or an error. -+ * NULL means whiteout-ed or not-found. -+ */ -+static struct dentry* -+au_do_lookup(struct dentry *h_parent, struct dentry *dentry, -+ aufs_bindex_t bindex, struct au_do_lookup_args *args) -+{ -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ struct au_branch *br; -+ int wh_found, opq; -+ unsigned char wh_able; -+ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG); -+ const unsigned char ignore_perm = !!au_ftest_lkup(args->flags, -+ IGNORE_PERM); -+ -+ wh_found = 0; -+ br = au_sbr(dentry->d_sb, bindex); -+ wh_able = !!au_br_whable(br->br_perm); -+ if (wh_able) -+ wh_found = au_wh_test(h_parent, &args->whname, ignore_perm); -+ h_dentry = ERR_PTR(wh_found); -+ if (!wh_found) -+ goto real_lookup; -+ if (unlikely(wh_found < 0)) -+ goto out; -+ -+ /* We found a whiteout */ -+ /* au_set_dbbot(dentry, bindex); */ -+ au_set_dbwh(dentry, bindex); -+ if (!allow_neg) -+ return NULL; /* success */ -+ -+real_lookup: -+ if (!ignore_perm) -+ h_dentry = vfsub_lkup_one(args->name, h_parent); -+ else -+ h_dentry = au_sio_lkup_one(args->name, h_parent); -+ if (IS_ERR(h_dentry)) { -+ if (PTR_ERR(h_dentry) == -ENAMETOOLONG -+ && !allow_neg) -+ h_dentry = NULL; -+ goto out; -+ } -+ -+ h_inode = d_inode(h_dentry); -+ if (d_is_negative(h_dentry)) { -+ if (!allow_neg) -+ goto out_neg; -+ } else if (wh_found -+ || (args->type && args->type != (h_inode->i_mode & S_IFMT))) -+ goto out_neg; -+ else if (au_ftest_lkup(args->flags, DIRREN) -+ /* && h_inode */ -+ && !au_dr_lkup_h_ino(args, bindex, h_inode->i_ino)) { -+ AuDbg("b%d %pd ignored hi%llu\n", bindex, h_dentry, -+ (unsigned long long)h_inode->i_ino); -+ goto out_neg; -+ } -+ -+ if (au_dbbot(dentry) <= bindex) -+ au_set_dbbot(dentry, bindex); -+ if (au_dbtop(dentry) < 0 || bindex < au_dbtop(dentry)) -+ au_set_dbtop(dentry, bindex); -+ au_set_h_dptr(dentry, bindex, h_dentry); -+ -+ if (!d_is_dir(h_dentry) -+ || !wh_able -+ || (d_really_is_positive(dentry) && !d_is_dir(dentry))) -+ goto out; /* success */ -+ -+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD); -+ opq = au_diropq_test(h_dentry); -+ inode_unlock_shared(h_inode); -+ if (opq > 0) -+ au_set_dbdiropq(dentry, bindex); -+ else if (unlikely(opq < 0)) { -+ au_set_h_dptr(dentry, bindex, NULL); -+ h_dentry = ERR_PTR(opq); -+ } -+ goto out; -+ -+out_neg: -+ dput(h_dentry); -+ h_dentry = NULL; -+out: -+ return h_dentry; -+} -+ -+static int au_test_shwh(struct super_block *sb, const struct qstr *name) -+{ -+ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH) -+ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))) -+ return -EPERM; -+ return 0; -+} -+ -+/* -+ * returns the number of lower positive dentries, -+ * otherwise an error. -+ * can be called at unlinking with @type is zero. -+ */ -+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop, -+ unsigned int flags) -+{ -+ int npositive, err; -+ aufs_bindex_t bindex, btail, bdiropq; -+ unsigned char isdir, dirperm1, dirren; -+ struct au_do_lookup_args args = { -+ .flags = flags, -+ .name = &dentry->d_name -+ }; -+ struct dentry *parent; -+ struct super_block *sb; -+ -+ sb = dentry->d_sb; -+ err = au_test_shwh(sb, args.name); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_wh_name_alloc(&args.whname, args.name); -+ if (unlikely(err)) -+ goto out; -+ -+ isdir = !!d_is_dir(dentry); -+ dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1); -+ dirren = !!au_opt_test(au_mntflags(sb), DIRREN); -+ if (dirren) -+ au_fset_lkup(args.flags, DIRREN); -+ -+ npositive = 0; -+ parent = dget_parent(dentry); -+ btail = au_dbtaildir(parent); -+ for (bindex = btop; bindex <= btail; bindex++) { -+ struct dentry *h_parent, *h_dentry; -+ struct inode *h_inode, *h_dir; -+ struct au_branch *br; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry) { -+ if (d_is_positive(h_dentry)) -+ npositive++; -+ break; -+ } -+ h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || !d_is_dir(h_parent)) -+ continue; -+ -+ if (dirren) { -+ /* if the inum matches, then use the prepared name */ -+ err = au_dr_lkup_name(&args, bindex); -+ if (unlikely(err)) -+ goto out_parent; -+ } -+ -+ h_dir = d_inode(h_parent); -+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT); -+ h_dentry = au_do_lookup(h_parent, dentry, bindex, &args); -+ inode_unlock_shared(h_dir); -+ err = PTR_ERR(h_dentry); -+ if (IS_ERR(h_dentry)) -+ goto out_parent; -+ if (h_dentry) -+ au_fclr_lkup(args.flags, ALLOW_NEG); -+ if (dirperm1) -+ au_fset_lkup(args.flags, IGNORE_PERM); -+ -+ if (au_dbwh(dentry) == bindex) -+ break; -+ if (!h_dentry) -+ continue; -+ if (d_is_negative(h_dentry)) -+ continue; -+ h_inode = d_inode(h_dentry); -+ npositive++; -+ if (!args.type) -+ args.type = h_inode->i_mode & S_IFMT; -+ if (args.type != S_IFDIR) -+ break; -+ else if (isdir) { -+ /* the type of lower may be different */ -+ bdiropq = au_dbdiropq(dentry); -+ if (bdiropq >= 0 && bdiropq <= bindex) -+ break; -+ } -+ br = au_sbr(sb, bindex); -+ if (dirren -+ && au_dr_hino_test_add(&br->br_dirren, h_inode->i_ino, -+ /*add_ent*/NULL)) { -+ /* prepare next name to lookup */ -+ err = au_dr_lkup(&args, dentry, bindex); -+ if (unlikely(err)) -+ goto out_parent; -+ } -+ } -+ -+ if (npositive) { -+ AuLabel(positive); -+ au_update_dbtop(dentry); -+ } -+ err = npositive; -+ if (unlikely(!au_opt_test(au_mntflags(sb), UDBA_NONE) -+ && au_dbtop(dentry) < 0)) { -+ err = -EIO; -+ AuIOErr("both of real entry and whiteout found, %pd, err %d\n", -+ dentry, err); -+ } -+ -+out_parent: -+ dput(parent); -+ kfree(args.whname.name); -+ if (dirren) -+ au_dr_lkup_fin(&args); -+out: -+ return err; -+} -+ -+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent) -+{ -+ struct dentry *dentry; -+ int wkq_err; -+ -+ if (!au_test_h_perm_sio(d_inode(parent), MAY_EXEC)) -+ dentry = vfsub_lkup_one(name, parent); -+ else { -+ struct vfsub_lkup_one_args args = { -+ .errp = &dentry, -+ .name = name, -+ .parent = parent -+ }; -+ -+ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args); -+ if (unlikely(wkq_err)) -+ dentry = ERR_PTR(wkq_err); -+ } -+ -+ return dentry; -+} -+ -+/* -+ * lookup @dentry on @bindex which should be negative. -+ */ -+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh) -+{ -+ int err; -+ struct dentry *parent, *h_parent, *h_dentry; -+ struct au_branch *br; -+ -+ parent = dget_parent(dentry); -+ h_parent = au_h_dptr(parent, bindex); -+ br = au_sbr(dentry->d_sb, bindex); -+ if (wh) -+ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name); -+ else -+ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent); -+ err = PTR_ERR(h_dentry); -+ if (IS_ERR(h_dentry)) -+ goto out; -+ if (unlikely(d_is_positive(h_dentry))) { -+ err = -EIO; -+ AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex); -+ dput(h_dentry); -+ goto out; -+ } -+ -+ err = 0; -+ if (bindex < au_dbtop(dentry)) -+ au_set_dbtop(dentry, bindex); -+ if (au_dbbot(dentry) < bindex) -+ au_set_dbbot(dentry, bindex); -+ au_set_h_dptr(dentry, bindex, h_dentry); -+ -+out: -+ dput(parent); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* subset of struct inode */ -+struct au_iattr { -+ unsigned long i_ino; -+ /* unsigned int i_nlink; */ -+ kuid_t i_uid; -+ kgid_t i_gid; -+ u64 i_version; -+/* -+ loff_t i_size; -+ blkcnt_t i_blocks; -+*/ -+ umode_t i_mode; -+}; -+ -+static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode) -+{ -+ ia->i_ino = h_inode->i_ino; -+ /* ia->i_nlink = h_inode->i_nlink; */ -+ ia->i_uid = h_inode->i_uid; -+ ia->i_gid = h_inode->i_gid; -+ ia->i_version = inode_query_iversion(h_inode); -+/* -+ ia->i_size = h_inode->i_size; -+ ia->i_blocks = h_inode->i_blocks; -+*/ -+ ia->i_mode = (h_inode->i_mode & S_IFMT); -+} -+ -+static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode) -+{ -+ return ia->i_ino != h_inode->i_ino -+ /* || ia->i_nlink != h_inode->i_nlink */ -+ || !uid_eq(ia->i_uid, h_inode->i_uid) -+ || !gid_eq(ia->i_gid, h_inode->i_gid) -+ || !inode_eq_iversion(h_inode, ia->i_version) -+/* -+ || ia->i_size != h_inode->i_size -+ || ia->i_blocks != h_inode->i_blocks -+*/ -+ || ia->i_mode != (h_inode->i_mode & S_IFMT); -+} -+ -+static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent, -+ struct au_branch *br) -+{ -+ int err; -+ struct au_iattr ia; -+ struct inode *h_inode; -+ struct dentry *h_d; -+ struct super_block *h_sb; -+ -+ err = 0; -+ memset(&ia, -1, sizeof(ia)); -+ h_sb = h_dentry->d_sb; -+ h_inode = NULL; -+ if (d_is_positive(h_dentry)) { -+ h_inode = d_inode(h_dentry); -+ au_iattr_save(&ia, h_inode); -+ } else if (au_test_nfs(h_sb) || au_test_fuse(h_sb)) -+ /* nfs d_revalidate may return 0 for negative dentry */ -+ /* fuse d_revalidate always return 0 for negative dentry */ -+ goto out; -+ -+ /* main purpose is namei.c:cached_lookup() and d_revalidate */ -+ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent); -+ err = PTR_ERR(h_d); -+ if (IS_ERR(h_d)) -+ goto out; -+ -+ err = 0; -+ if (unlikely(h_d != h_dentry -+ || d_inode(h_d) != h_inode -+ || (h_inode && au_iattr_test(&ia, h_inode)))) -+ err = au_busy_or_stale(); -+ dput(h_d); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir, -+ struct dentry *h_parent, struct au_branch *br) -+{ -+ int err; -+ -+ err = 0; -+ if (udba == AuOpt_UDBA_REVAL -+ && !au_test_fs_remote(h_dentry->d_sb)) { -+ IMustLock(h_dir); -+ err = (d_inode(h_dentry->d_parent) != h_dir); -+ } else if (udba != AuOpt_UDBA_NONE) -+ err = au_h_verify_dentry(h_dentry, h_parent, br); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent) -+{ -+ int err; -+ aufs_bindex_t new_bindex, bindex, bbot, bwh, bdiropq; -+ struct au_hdentry tmp, *p, *q; -+ struct au_dinfo *dinfo; -+ struct super_block *sb; -+ -+ DiMustWriteLock(dentry); -+ -+ sb = dentry->d_sb; -+ dinfo = au_di(dentry); -+ bbot = dinfo->di_bbot; -+ bwh = dinfo->di_bwh; -+ bdiropq = dinfo->di_bdiropq; -+ bindex = dinfo->di_btop; -+ p = au_hdentry(dinfo, bindex); -+ for (; bindex <= bbot; bindex++, p++) { -+ if (!p->hd_dentry) -+ continue; -+ -+ new_bindex = au_br_index(sb, p->hd_id); -+ if (new_bindex == bindex) -+ continue; -+ -+ if (dinfo->di_bwh == bindex) -+ bwh = new_bindex; -+ if (dinfo->di_bdiropq == bindex) -+ bdiropq = new_bindex; -+ if (new_bindex < 0) { -+ au_hdput(p); -+ p->hd_dentry = NULL; -+ continue; -+ } -+ -+ /* swap two lower dentries, and loop again */ -+ q = au_hdentry(dinfo, new_bindex); -+ tmp = *q; -+ *q = *p; -+ *p = tmp; -+ if (tmp.hd_dentry) { -+ bindex--; -+ p--; -+ } -+ } -+ -+ dinfo->di_bwh = -1; -+ if (bwh >= 0 && bwh <= au_sbbot(sb) && au_sbr_whable(sb, bwh)) -+ dinfo->di_bwh = bwh; -+ -+ dinfo->di_bdiropq = -1; -+ if (bdiropq >= 0 -+ && bdiropq <= au_sbbot(sb) -+ && au_sbr_whable(sb, bdiropq)) -+ dinfo->di_bdiropq = bdiropq; -+ -+ err = -EIO; -+ dinfo->di_btop = -1; -+ dinfo->di_bbot = -1; -+ bbot = au_dbbot(parent); -+ bindex = 0; -+ p = au_hdentry(dinfo, bindex); -+ for (; bindex <= bbot; bindex++, p++) -+ if (p->hd_dentry) { -+ dinfo->di_btop = bindex; -+ break; -+ } -+ -+ if (dinfo->di_btop >= 0) { -+ bindex = bbot; -+ p = au_hdentry(dinfo, bindex); -+ for (; bindex >= 0; bindex--, p--) -+ if (p->hd_dentry) { -+ dinfo->di_bbot = bindex; -+ err = 0; -+ break; -+ } -+ } -+ -+ return err; -+} -+ -+static void au_do_hide(struct dentry *dentry) -+{ -+ struct inode *inode; -+ -+ if (d_really_is_positive(dentry)) { -+ inode = d_inode(dentry); -+ if (!d_is_dir(dentry)) { -+ if (inode->i_nlink && !d_unhashed(dentry)) -+ drop_nlink(inode); -+ } else { -+ clear_nlink(inode); -+ /* stop next lookup */ -+ inode->i_flags |= S_DEAD; -+ } -+ smp_mb(); /* necessary? */ -+ } -+ d_drop(dentry); -+} -+ -+static int au_hide_children(struct dentry *parent) -+{ -+ int err, i, j, ndentry; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry *dentry; -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_dcsub_pages(&dpages, parent, NULL, NULL); -+ if (unlikely(err)) -+ goto out_dpages; -+ -+ /* in reverse order */ -+ for (i = dpages.ndpage - 1; i >= 0; i--) { -+ dpage = dpages.dpages + i; -+ ndentry = dpage->ndentry; -+ for (j = ndentry - 1; j >= 0; j--) { -+ dentry = dpage->dentries[j]; -+ if (dentry != parent) -+ au_do_hide(dentry); -+ } -+ } -+ -+out_dpages: -+ au_dpages_free(&dpages); -+out: -+ return err; -+} -+ -+static void au_hide(struct dentry *dentry) -+{ -+ int err; -+ -+ AuDbgDentry(dentry); -+ if (d_is_dir(dentry)) { -+ /* shrink_dcache_parent(dentry); */ -+ err = au_hide_children(dentry); -+ if (unlikely(err)) -+ AuIOErr("%pd, failed hiding children, ignored %d\n", -+ dentry, err); -+ } -+ au_do_hide(dentry); -+} -+ -+/* -+ * By adding a dirty branch, a cached dentry may be affected in various ways. -+ * -+ * a dirty branch is added -+ * - on the top of layers -+ * - in the middle of layers -+ * - to the bottom of layers -+ * -+ * on the added branch there exists -+ * - a whiteout -+ * - a diropq -+ * - a same named entry -+ * + exist -+ * * negative --> positive -+ * * positive --> positive -+ * - type is unchanged -+ * - type is changed -+ * + doesn't exist -+ * * negative --> negative -+ * * positive --> negative (rejected by au_br_del() for non-dir case) -+ * - none -+ */ -+static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo, -+ struct au_dinfo *tmp) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct { -+ struct dentry *dentry; -+ struct inode *inode; -+ mode_t mode; -+ } orig_h, tmp_h = { -+ .dentry = NULL -+ }; -+ struct au_hdentry *hd; -+ struct inode *inode, *h_inode; -+ struct dentry *h_dentry; -+ -+ err = 0; -+ AuDebugOn(dinfo->di_btop < 0); -+ orig_h.mode = 0; -+ orig_h.dentry = au_hdentry(dinfo, dinfo->di_btop)->hd_dentry; -+ orig_h.inode = NULL; -+ if (d_is_positive(orig_h.dentry)) { -+ orig_h.inode = d_inode(orig_h.dentry); -+ orig_h.mode = orig_h.inode->i_mode & S_IFMT; -+ } -+ if (tmp->di_btop >= 0) { -+ tmp_h.dentry = au_hdentry(tmp, tmp->di_btop)->hd_dentry; -+ if (d_is_positive(tmp_h.dentry)) { -+ tmp_h.inode = d_inode(tmp_h.dentry); -+ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT; -+ } -+ } -+ -+ inode = NULL; -+ if (d_really_is_positive(dentry)) -+ inode = d_inode(dentry); -+ if (!orig_h.inode) { -+ AuDbg("negative originally\n"); -+ if (inode) { -+ au_hide(dentry); -+ goto out; -+ } -+ AuDebugOn(inode); -+ AuDebugOn(dinfo->di_btop != dinfo->di_bbot); -+ AuDebugOn(dinfo->di_bdiropq != -1); -+ -+ if (!tmp_h.inode) { -+ AuDbg("negative --> negative\n"); -+ /* should have only one negative lower */ -+ if (tmp->di_btop >= 0 -+ && tmp->di_btop < dinfo->di_btop) { -+ AuDebugOn(tmp->di_btop != tmp->di_bbot); -+ AuDebugOn(dinfo->di_btop != dinfo->di_bbot); -+ au_set_h_dptr(dentry, dinfo->di_btop, NULL); -+ au_di_cp(dinfo, tmp); -+ hd = au_hdentry(tmp, tmp->di_btop); -+ au_set_h_dptr(dentry, tmp->di_btop, -+ dget(hd->hd_dentry)); -+ } -+ au_dbg_verify_dinode(dentry); -+ } else { -+ AuDbg("negative --> positive\n"); -+ /* -+ * similar to the behaviour of creating with bypassing -+ * aufs. -+ * unhash it in order to force an error in the -+ * succeeding create operation. -+ * we should not set S_DEAD here. -+ */ -+ d_drop(dentry); -+ /* au_di_swap(tmp, dinfo); */ -+ au_dbg_verify_dinode(dentry); -+ } -+ } else { -+ AuDbg("positive originally\n"); -+ /* inode may be NULL */ -+ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode); -+ if (!tmp_h.inode) { -+ AuDbg("positive --> negative\n"); -+ /* or bypassing aufs */ -+ au_hide(dentry); -+ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_btop) -+ dinfo->di_bwh = tmp->di_bwh; -+ if (inode) -+ err = au_refresh_hinode_self(inode); -+ au_dbg_verify_dinode(dentry); -+ } else if (orig_h.mode == tmp_h.mode) { -+ AuDbg("positive --> positive, same type\n"); -+ if (!S_ISDIR(orig_h.mode) -+ && dinfo->di_btop > tmp->di_btop) { -+ /* -+ * similar to the behaviour of removing and -+ * creating. -+ */ -+ au_hide(dentry); -+ if (inode) -+ err = au_refresh_hinode_self(inode); -+ au_dbg_verify_dinode(dentry); -+ } else { -+ /* fill empty slots */ -+ if (dinfo->di_btop > tmp->di_btop) -+ dinfo->di_btop = tmp->di_btop; -+ if (dinfo->di_bbot < tmp->di_bbot) -+ dinfo->di_bbot = tmp->di_bbot; -+ dinfo->di_bwh = tmp->di_bwh; -+ dinfo->di_bdiropq = tmp->di_bdiropq; -+ bbot = dinfo->di_bbot; -+ bindex = tmp->di_btop; -+ hd = au_hdentry(tmp, bindex); -+ for (; bindex <= bbot; bindex++, hd++) { -+ if (au_h_dptr(dentry, bindex)) -+ continue; -+ h_dentry = hd->hd_dentry; -+ if (!h_dentry) -+ continue; -+ AuDebugOn(d_is_negative(h_dentry)); -+ h_inode = d_inode(h_dentry); -+ AuDebugOn(orig_h.mode -+ != (h_inode->i_mode -+ & S_IFMT)); -+ au_set_h_dptr(dentry, bindex, -+ dget(h_dentry)); -+ } -+ if (inode) -+ err = au_refresh_hinode(inode, dentry); -+ au_dbg_verify_dinode(dentry); -+ } -+ } else { -+ AuDbg("positive --> positive, different type\n"); -+ /* similar to the behaviour of removing and creating */ -+ au_hide(dentry); -+ if (inode) -+ err = au_refresh_hinode_self(inode); -+ au_dbg_verify_dinode(dentry); -+ } -+ } -+ -+out: -+ return err; -+} -+ -+void au_refresh_dop(struct dentry *dentry, int force_reval) -+{ -+ const struct dentry_operations *dop -+ = force_reval ? &aufs_dop : dentry->d_sb->s_d_op; -+ static const unsigned int mask -+ = DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE; -+ -+ BUILD_BUG_ON(sizeof(mask) != sizeof(dentry->d_flags)); -+ -+ if (dentry->d_op == dop) -+ return; -+ -+ AuDbg("%pd\n", dentry); -+ spin_lock(&dentry->d_lock); -+ if (dop == &aufs_dop) -+ dentry->d_flags |= mask; -+ else -+ dentry->d_flags &= ~mask; -+ dentry->d_op = dop; -+ spin_unlock(&dentry->d_lock); -+} -+ -+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent) -+{ -+ int err, ebrange, nbr; -+ unsigned int sigen; -+ struct au_dinfo *dinfo, *tmp; -+ struct super_block *sb; -+ struct inode *inode; -+ -+ DiMustWriteLock(dentry); -+ AuDebugOn(IS_ROOT(dentry)); -+ AuDebugOn(d_really_is_negative(parent)); -+ -+ sb = dentry->d_sb; -+ sigen = au_sigen(sb); -+ err = au_digen_test(parent, sigen); -+ if (unlikely(err)) -+ goto out; -+ -+ nbr = au_sbbot(sb) + 1; -+ dinfo = au_di(dentry); -+ err = au_di_realloc(dinfo, nbr, /*may_shrink*/0); -+ if (unlikely(err)) -+ goto out; -+ ebrange = au_dbrange_test(dentry); -+ if (!ebrange) -+ ebrange = au_do_refresh_hdentry(dentry, parent); -+ -+ if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) { -+ AuDebugOn(au_dbtop(dentry) < 0 && au_dbbot(dentry) >= 0); -+ if (d_really_is_positive(dentry)) { -+ inode = d_inode(dentry); -+ err = au_refresh_hinode_self(inode); -+ } -+ au_dbg_verify_dinode(dentry); -+ if (!err) -+ goto out_dgen; /* success */ -+ goto out; -+ } -+ -+ /* temporary dinfo */ -+ AuDbgDentry(dentry); -+ err = -ENOMEM; -+ tmp = au_di_alloc(sb, AuLsc_DI_TMP); -+ if (unlikely(!tmp)) -+ goto out; -+ au_di_swap(tmp, dinfo); -+ /* returns the number of positive dentries */ -+ /* -+ * if current working dir is removed, it returns an error. -+ * but the dentry is legal. -+ */ -+ err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG); -+ AuDbgDentry(dentry); -+ au_di_swap(tmp, dinfo); -+ if (err == -ENOENT) -+ err = 0; -+ if (err >= 0) { -+ /* compare/refresh by dinfo */ -+ AuDbgDentry(dentry); -+ err = au_refresh_by_dinfo(dentry, dinfo, tmp); -+ au_dbg_verify_dinode(dentry); -+ AuTraceErr(err); -+ } -+ au_di_realloc(dinfo, nbr, /*may_shrink*/1); /* harmless if err */ -+ au_rw_write_unlock(&tmp->di_rwsem); -+ au_di_free(tmp); -+ if (unlikely(err)) -+ goto out; -+ -+out_dgen: -+ au_update_digen(dentry); -+out: -+ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) { -+ AuIOErr("failed refreshing %pd, %d\n", dentry, err); -+ AuDbgDentry(dentry); -+ } -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags, -+ struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ int err, valid; -+ -+ err = 0; -+ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE)) -+ goto out; -+ -+ AuDbg("b%d\n", bindex); -+ /* -+ * gave up supporting LOOKUP_CREATE/OPEN for lower fs, -+ * due to whiteout and branch permission. -+ */ -+ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE -+ | LOOKUP_FOLLOW | LOOKUP_EXCL); -+ /* it may return tri-state */ -+ valid = h_dentry->d_op->d_revalidate(h_dentry, flags); -+ -+ if (unlikely(valid < 0)) -+ err = valid; -+ else if (!valid) -+ err = -EINVAL; -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* todo: remove this */ -+static int h_d_revalidate(struct dentry *dentry, struct inode *inode, -+ unsigned int flags, int do_udba, int dirren) -+{ -+ int err; -+ umode_t mode, h_mode; -+ aufs_bindex_t bindex, btail, btop, ibs, ibe; -+ unsigned char plus, unhashed, is_root, h_plus, h_nfs, tmpfile; -+ struct inode *h_inode, *h_cached_inode; -+ struct dentry *h_dentry; -+ struct qstr *name, *h_name; -+ -+ err = 0; -+ plus = 0; -+ mode = 0; -+ ibs = -1; -+ ibe = -1; -+ unhashed = !!d_unhashed(dentry); -+ is_root = !!IS_ROOT(dentry); -+ name = &dentry->d_name; -+ tmpfile = au_di(dentry)->di_tmpfile; -+ -+ /* -+ * Theoretically, REVAL test should be unnecessary in case of -+ * {FS,I}NOTIFY. -+ * But {fs,i}notify doesn't fire some necessary events, -+ * IN_ATTRIB for atime/nlink/pageio -+ * Let's do REVAL test too. -+ */ -+ if (do_udba && inode) { -+ mode = (inode->i_mode & S_IFMT); -+ plus = (inode->i_nlink > 0); -+ ibs = au_ibtop(inode); -+ ibe = au_ibbot(inode); -+ } -+ -+ btop = au_dbtop(dentry); -+ btail = btop; -+ if (inode && S_ISDIR(inode->i_mode)) -+ btail = au_dbtaildir(dentry); -+ for (bindex = btop; bindex <= btail; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry) -+ continue; -+ -+ AuDbg("b%d, %pd\n", bindex, h_dentry); -+ h_nfs = !!au_test_nfs(h_dentry->d_sb); -+ spin_lock(&h_dentry->d_lock); -+ h_name = &h_dentry->d_name; -+ if (unlikely(do_udba -+ && !is_root -+ && ((!h_nfs -+ && (unhashed != !!d_unhashed(h_dentry) -+ || (!tmpfile && !dirren -+ && !au_qstreq(name, h_name)) -+ )) -+ || (h_nfs -+ && !(flags & LOOKUP_OPEN) -+ && (h_dentry->d_flags -+ & DCACHE_NFSFS_RENAMED))) -+ )) { -+ int h_unhashed; -+ -+ h_unhashed = d_unhashed(h_dentry); -+ spin_unlock(&h_dentry->d_lock); -+ AuDbg("unhash 0x%x 0x%x, %pd %pd\n", -+ unhashed, h_unhashed, dentry, h_dentry); -+ goto err; -+ } -+ spin_unlock(&h_dentry->d_lock); -+ -+ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex); -+ if (unlikely(err)) -+ /* do not goto err, to keep the errno */ -+ break; -+ -+ /* todo: plink too? */ -+ if (!do_udba) -+ continue; -+ -+ /* UDBA tests */ -+ if (unlikely(!!inode != d_is_positive(h_dentry))) -+ goto err; -+ -+ h_inode = NULL; -+ if (d_is_positive(h_dentry)) -+ h_inode = d_inode(h_dentry); -+ h_plus = plus; -+ h_mode = mode; -+ h_cached_inode = h_inode; -+ if (h_inode) { -+ h_mode = (h_inode->i_mode & S_IFMT); -+ h_plus = (h_inode->i_nlink > 0); -+ } -+ if (inode && ibs <= bindex && bindex <= ibe) -+ h_cached_inode = au_h_iptr(inode, bindex); -+ -+ if (!h_nfs) { -+ if (unlikely(plus != h_plus && !tmpfile)) -+ goto err; -+ } else { -+ if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED) -+ && !is_root -+ && !IS_ROOT(h_dentry) -+ && unhashed != d_unhashed(h_dentry))) -+ goto err; -+ } -+ if (unlikely(mode != h_mode -+ || h_cached_inode != h_inode)) -+ goto err; -+ continue; -+ -+err: -+ err = -EINVAL; -+ break; -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+/* todo: consolidate with do_refresh() and au_reval_for_attr() */ -+static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen) -+{ -+ int err; -+ struct dentry *parent; -+ -+ if (!au_digen_test(dentry, sigen)) -+ return 0; -+ -+ parent = dget_parent(dentry); -+ di_read_lock_parent(parent, AuLock_IR); -+ AuDebugOn(au_digen_test(parent, sigen)); -+ au_dbg_verify_gen(parent, sigen); -+ err = au_refresh_dentry(dentry, parent); -+ di_read_unlock(parent, AuLock_IR); -+ dput(parent); -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_reval_dpath(struct dentry *dentry, unsigned int sigen) -+{ -+ int err; -+ struct dentry *d, *parent; -+ -+ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR)) -+ return simple_reval_dpath(dentry, sigen); -+ -+ /* slow loop, keep it simple and stupid */ -+ /* cf: au_cpup_dirs() */ -+ err = 0; -+ parent = NULL; -+ while (au_digen_test(dentry, sigen)) { -+ d = dentry; -+ while (1) { -+ dput(parent); -+ parent = dget_parent(d); -+ if (!au_digen_test(parent, sigen)) -+ break; -+ d = parent; -+ } -+ -+ if (d != dentry) -+ di_write_lock_child2(d); -+ -+ /* someone might update our dentry while we were sleeping */ -+ if (au_digen_test(d, sigen)) { -+ /* -+ * todo: consolidate with simple_reval_dpath(), -+ * do_refresh() and au_reval_for_attr(). -+ */ -+ di_read_lock_parent(parent, AuLock_IR); -+ err = au_refresh_dentry(d, parent); -+ di_read_unlock(parent, AuLock_IR); -+ } -+ -+ if (d != dentry) -+ di_write_unlock(d); -+ dput(parent); -+ if (unlikely(err)) -+ break; -+ } -+ -+ return err; -+} -+ -+/* -+ * if valid returns 1, otherwise 0. -+ */ -+static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags) -+{ -+ int valid, err; -+ unsigned int sigen; -+ unsigned char do_udba, dirren; -+ struct super_block *sb; -+ struct inode *inode; -+ -+ /* todo: support rcu-walk? */ -+ if (flags & LOOKUP_RCU) -+ return -ECHILD; -+ -+ valid = 0; -+ if (unlikely(!au_di(dentry))) -+ goto out; -+ -+ valid = 1; -+ sb = dentry->d_sb; -+ /* -+ * todo: very ugly -+ * i_mutex of parent dir may be held, -+ * but we should not return 'invalid' due to busy. -+ */ -+ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM); -+ if (unlikely(err)) { -+ valid = err; -+ AuTraceErr(err); -+ goto out; -+ } -+ inode = NULL; -+ if (d_really_is_positive(dentry)) -+ inode = d_inode(dentry); -+ if (unlikely(inode && au_is_bad_inode(inode))) { -+ err = -EINVAL; -+ AuTraceErr(err); -+ goto out_dgrade; -+ } -+ if (unlikely(au_dbrange_test(dentry))) { -+ err = -EINVAL; -+ AuTraceErr(err); -+ goto out_dgrade; -+ } -+ -+ sigen = au_sigen(sb); -+ if (au_digen_test(dentry, sigen)) { -+ AuDebugOn(IS_ROOT(dentry)); -+ err = au_reval_dpath(dentry, sigen); -+ if (unlikely(err)) { -+ AuTraceErr(err); -+ goto out_dgrade; -+ } -+ } -+ di_downgrade_lock(dentry, AuLock_IR); -+ -+ err = -EINVAL; -+ if (!(flags & (LOOKUP_OPEN | LOOKUP_EMPTY)) -+ && inode -+ && !(inode->i_state && I_LINKABLE) -+ && (IS_DEADDIR(inode) || !inode->i_nlink)) { -+ AuTraceErr(err); -+ goto out_inval; -+ } -+ -+ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE); -+ if (do_udba && inode) { -+ aufs_bindex_t btop = au_ibtop(inode); -+ struct inode *h_inode; -+ -+ if (btop >= 0) { -+ h_inode = au_h_iptr(inode, btop); -+ if (h_inode && au_test_higen(inode, h_inode)) { -+ AuTraceErr(err); -+ goto out_inval; -+ } -+ } -+ } -+ -+ dirren = !!au_opt_test(au_mntflags(sb), DIRREN); -+ err = h_d_revalidate(dentry, inode, flags, do_udba, dirren); -+ if (unlikely(!err && do_udba && au_dbtop(dentry) < 0)) { -+ err = -EIO; -+ AuDbg("both of real entry and whiteout found, %p, err %d\n", -+ dentry, err); -+ } -+ goto out_inval; -+ -+out_dgrade: -+ di_downgrade_lock(dentry, AuLock_IR); -+out_inval: -+ aufs_read_unlock(dentry, AuLock_IR); -+ AuTraceErr(err); -+ valid = !err; -+out: -+ if (!valid) { -+ AuDbg("%pd invalid, %d\n", dentry, valid); -+ d_drop(dentry); -+ } -+ return valid; -+} -+ -+static void aufs_d_release(struct dentry *dentry) -+{ -+ if (au_di(dentry)) { -+ au_di_fin(dentry); -+ au_hn_di_reinit(dentry); -+ } -+} -+ -+const struct dentry_operations aufs_dop = { -+ .d_revalidate = aufs_d_revalidate, -+ .d_weak_revalidate = aufs_d_revalidate, -+ .d_release = aufs_d_release -+}; -+ -+/* aufs_dop without d_revalidate */ -+const struct dentry_operations aufs_dop_noreval = { -+ .d_release = aufs_d_release -+}; -diff --git a/fs/aufs/dentry.h b/fs/aufs/dentry.h -new file mode 100644 -index 000000000..adc2ac997 ---- /dev/null -+++ b/fs/aufs/dentry.h -@@ -0,0 +1,267 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * lookup and dentry operations -+ */ -+ -+#ifndef __AUFS_DENTRY_H__ -+#define __AUFS_DENTRY_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include "dirren.h" -+#include "rwsem.h" -+ -+struct au_hdentry { -+ struct dentry *hd_dentry; -+ aufs_bindex_t hd_id; -+}; -+ -+struct au_dinfo { -+ atomic_t di_generation; -+ -+ struct au_rwsem di_rwsem; -+ aufs_bindex_t di_btop, di_bbot, di_bwh, di_bdiropq; -+ unsigned char di_tmpfile; /* to allow the different name */ -+ struct au_hdentry *di_hdentry; -+} ____cacheline_aligned_in_smp; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* flags for au_lkup_dentry() */ -+#define AuLkup_ALLOW_NEG 1 -+#define AuLkup_IGNORE_PERM (1 << 1) -+#define AuLkup_DIRREN (1 << 2) -+#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name) -+#define au_fset_lkup(flags, name) \ -+ do { (flags) |= AuLkup_##name; } while (0) -+#define au_fclr_lkup(flags, name) \ -+ do { (flags) &= ~AuLkup_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_DIRREN -+#undef AuLkup_DIRREN -+#define AuLkup_DIRREN 0 -+#endif -+ -+struct au_do_lookup_args { -+ unsigned int flags; -+ mode_t type; -+ struct qstr whname, *name; -+ struct au_dr_lookup dirren; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* dentry.c */ -+extern const struct dentry_operations aufs_dop, aufs_dop_noreval; -+struct au_branch; -+struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent); -+int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir, -+ struct dentry *h_parent, struct au_branch *br); -+ -+int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop, -+ unsigned int flags); -+int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh); -+int au_refresh_dentry(struct dentry *dentry, struct dentry *parent); -+int au_reval_dpath(struct dentry *dentry, unsigned int sigen); -+void au_refresh_dop(struct dentry *dentry, int force_reval); -+ -+/* dinfo.c */ -+void au_di_init_once(void *_di); -+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc); -+void au_di_free(struct au_dinfo *dinfo); -+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b); -+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src); -+int au_di_init(struct dentry *dentry); -+void au_di_fin(struct dentry *dentry); -+int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink); -+ -+void di_read_lock(struct dentry *d, int flags, unsigned int lsc); -+void di_read_unlock(struct dentry *d, int flags); -+void di_downgrade_lock(struct dentry *d, int flags); -+void di_write_lock(struct dentry *d, unsigned int lsc); -+void di_write_unlock(struct dentry *d); -+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir); -+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir); -+void di_write_unlock2(struct dentry *d1, struct dentry *d2); -+ -+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex); -+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex); -+aufs_bindex_t au_dbtail(struct dentry *dentry); -+aufs_bindex_t au_dbtaildir(struct dentry *dentry); -+ -+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_dentry); -+int au_digen_test(struct dentry *dentry, unsigned int sigen); -+int au_dbrange_test(struct dentry *dentry); -+void au_update_digen(struct dentry *dentry); -+void au_update_dbrange(struct dentry *dentry, int do_put_zero); -+void au_update_dbtop(struct dentry *dentry); -+void au_update_dbbot(struct dentry *dentry); -+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct au_dinfo *au_di(struct dentry *dentry) -+{ -+ return dentry->d_fsdata; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* lock subclass for dinfo */ -+enum { -+ AuLsc_DI_CHILD, /* child first */ -+ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */ -+ AuLsc_DI_CHILD3, /* copyup dirs */ -+ AuLsc_DI_PARENT, -+ AuLsc_DI_PARENT2, -+ AuLsc_DI_PARENT3, -+ AuLsc_DI_TMP /* temp for replacing dinfo */ -+}; -+ -+/* -+ * di_read_lock_child, di_write_lock_child, -+ * di_read_lock_child2, di_write_lock_child2, -+ * di_read_lock_child3, di_write_lock_child3, -+ * di_read_lock_parent, di_write_lock_parent, -+ * di_read_lock_parent2, di_write_lock_parent2, -+ * di_read_lock_parent3, di_write_lock_parent3, -+ */ -+#define AuReadLockFunc(name, lsc) \ -+static inline void di_read_lock_##name(struct dentry *d, int flags) \ -+{ di_read_lock(d, flags, AuLsc_DI_##lsc); } -+ -+#define AuWriteLockFunc(name, lsc) \ -+static inline void di_write_lock_##name(struct dentry *d) \ -+{ di_write_lock(d, AuLsc_DI_##lsc); } -+ -+#define AuRWLockFuncs(name, lsc) \ -+ AuReadLockFunc(name, lsc) \ -+ AuWriteLockFunc(name, lsc) -+ -+AuRWLockFuncs(child, CHILD); -+AuRWLockFuncs(child2, CHILD2); -+AuRWLockFuncs(child3, CHILD3); -+AuRWLockFuncs(parent, PARENT); -+AuRWLockFuncs(parent2, PARENT2); -+AuRWLockFuncs(parent3, PARENT3); -+ -+#undef AuReadLockFunc -+#undef AuWriteLockFunc -+#undef AuRWLockFuncs -+ -+#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem) -+#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem) -+#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem) -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* todo: memory barrier? */ -+static inline unsigned int au_digen(struct dentry *d) -+{ -+ return atomic_read(&au_di(d)->di_generation); -+} -+ -+static inline void au_h_dentry_init(struct au_hdentry *hdentry) -+{ -+ hdentry->hd_dentry = NULL; -+} -+ -+static inline struct au_hdentry *au_hdentry(struct au_dinfo *di, -+ aufs_bindex_t bindex) -+{ -+ return di->di_hdentry + bindex; -+} -+ -+static inline void au_hdput(struct au_hdentry *hd) -+{ -+ if (hd) -+ dput(hd->hd_dentry); -+} -+ -+static inline aufs_bindex_t au_dbtop(struct dentry *dentry) -+{ -+ DiMustAnyLock(dentry); -+ return au_di(dentry)->di_btop; -+} -+ -+static inline aufs_bindex_t au_dbbot(struct dentry *dentry) -+{ -+ DiMustAnyLock(dentry); -+ return au_di(dentry)->di_bbot; -+} -+ -+static inline aufs_bindex_t au_dbwh(struct dentry *dentry) -+{ -+ DiMustAnyLock(dentry); -+ return au_di(dentry)->di_bwh; -+} -+ -+static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry) -+{ -+ DiMustAnyLock(dentry); -+ return au_di(dentry)->di_bdiropq; -+} -+ -+/* todo: hard/soft set? */ -+static inline void au_set_dbtop(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ DiMustWriteLock(dentry); -+ au_di(dentry)->di_btop = bindex; -+} -+ -+static inline void au_set_dbbot(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ DiMustWriteLock(dentry); -+ au_di(dentry)->di_bbot = bindex; -+} -+ -+static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ DiMustWriteLock(dentry); -+ /* dbwh can be outside of btop - bbot range */ -+ au_di(dentry)->di_bwh = bindex; -+} -+ -+static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ DiMustWriteLock(dentry); -+ au_di(dentry)->di_bdiropq = bindex; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_HNOTIFY -+static inline void au_digen_dec(struct dentry *d) -+{ -+ atomic_dec(&au_di(d)->di_generation); -+} -+ -+static inline void au_hn_di_reinit(struct dentry *dentry) -+{ -+ dentry->d_fsdata = NULL; -+} -+#else -+AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused) -+#endif /* CONFIG_AUFS_HNOTIFY */ -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DENTRY_H__ */ -diff --git a/fs/aufs/dinfo.c b/fs/aufs/dinfo.c -new file mode 100644 -index 000000000..7e56fe742 ---- /dev/null -+++ b/fs/aufs/dinfo.c -@@ -0,0 +1,554 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * dentry private data -+ */ -+ -+#include "aufs.h" -+ -+void au_di_init_once(void *_dinfo) -+{ -+ struct au_dinfo *dinfo = _dinfo; -+ -+ au_rw_init(&dinfo->di_rwsem); -+} -+ -+struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc) -+{ -+ struct au_dinfo *dinfo; -+ int nbr, i; -+ -+ dinfo = au_cache_alloc_dinfo(); -+ if (unlikely(!dinfo)) -+ goto out; -+ -+ nbr = au_sbbot(sb) + 1; -+ if (nbr <= 0) -+ nbr = 1; -+ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS); -+ if (dinfo->di_hdentry) { -+ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc); -+ dinfo->di_btop = -1; -+ dinfo->di_bbot = -1; -+ dinfo->di_bwh = -1; -+ dinfo->di_bdiropq = -1; -+ dinfo->di_tmpfile = 0; -+ for (i = 0; i < nbr; i++) -+ dinfo->di_hdentry[i].hd_id = -1; -+ goto out; -+ } -+ -+ au_cache_free_dinfo(dinfo); -+ dinfo = NULL; -+ -+out: -+ return dinfo; -+} -+ -+void au_di_free(struct au_dinfo *dinfo) -+{ -+ struct au_hdentry *p; -+ aufs_bindex_t bbot, bindex; -+ -+ /* dentry may not be revalidated */ -+ bindex = dinfo->di_btop; -+ if (bindex >= 0) { -+ bbot = dinfo->di_bbot; -+ p = au_hdentry(dinfo, bindex); -+ while (bindex++ <= bbot) -+ au_hdput(p++); -+ } -+ kfree(dinfo->di_hdentry); -+ au_cache_free_dinfo(dinfo); -+} -+ -+void au_di_swap(struct au_dinfo *a, struct au_dinfo *b) -+{ -+ struct au_hdentry *p; -+ aufs_bindex_t bi; -+ -+ AuRwMustWriteLock(&a->di_rwsem); -+ AuRwMustWriteLock(&b->di_rwsem); -+ -+#define DiSwap(v, name) \ -+ do { \ -+ v = a->di_##name; \ -+ a->di_##name = b->di_##name; \ -+ b->di_##name = v; \ -+ } while (0) -+ -+ DiSwap(p, hdentry); -+ DiSwap(bi, btop); -+ DiSwap(bi, bbot); -+ DiSwap(bi, bwh); -+ DiSwap(bi, bdiropq); -+ /* smp_mb(); */ -+ -+#undef DiSwap -+} -+ -+void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src) -+{ -+ AuRwMustWriteLock(&dst->di_rwsem); -+ AuRwMustWriteLock(&src->di_rwsem); -+ -+ dst->di_btop = src->di_btop; -+ dst->di_bbot = src->di_bbot; -+ dst->di_bwh = src->di_bwh; -+ dst->di_bdiropq = src->di_bdiropq; -+ /* smp_mb(); */ -+} -+ -+int au_di_init(struct dentry *dentry) -+{ -+ int err; -+ struct super_block *sb; -+ struct au_dinfo *dinfo; -+ -+ err = 0; -+ sb = dentry->d_sb; -+ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD); -+ if (dinfo) { -+ atomic_set(&dinfo->di_generation, au_sigen(sb)); -+ /* smp_mb(); */ /* atomic_set */ -+ dentry->d_fsdata = dinfo; -+ } else -+ err = -ENOMEM; -+ -+ return err; -+} -+ -+void au_di_fin(struct dentry *dentry) -+{ -+ struct au_dinfo *dinfo; -+ -+ dinfo = au_di(dentry); -+ AuRwDestroy(&dinfo->di_rwsem); -+ au_di_free(dinfo); -+} -+ -+int au_di_realloc(struct au_dinfo *dinfo, int nbr, int may_shrink) -+{ -+ int err, sz; -+ struct au_hdentry *hdp; -+ -+ AuRwMustWriteLock(&dinfo->di_rwsem); -+ -+ err = -ENOMEM; -+ sz = sizeof(*hdp) * (dinfo->di_bbot + 1); -+ if (!sz) -+ sz = sizeof(*hdp); -+ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS, -+ may_shrink); -+ if (hdp) { -+ dinfo->di_hdentry = hdp; -+ err = 0; -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void do_ii_write_lock(struct inode *inode, unsigned int lsc) -+{ -+ switch (lsc) { -+ case AuLsc_DI_CHILD: -+ ii_write_lock_child(inode); -+ break; -+ case AuLsc_DI_CHILD2: -+ ii_write_lock_child2(inode); -+ break; -+ case AuLsc_DI_CHILD3: -+ ii_write_lock_child3(inode); -+ break; -+ case AuLsc_DI_PARENT: -+ ii_write_lock_parent(inode); -+ break; -+ case AuLsc_DI_PARENT2: -+ ii_write_lock_parent2(inode); -+ break; -+ case AuLsc_DI_PARENT3: -+ ii_write_lock_parent3(inode); -+ break; -+ default: -+ BUG(); -+ } -+} -+ -+static void do_ii_read_lock(struct inode *inode, unsigned int lsc) -+{ -+ switch (lsc) { -+ case AuLsc_DI_CHILD: -+ ii_read_lock_child(inode); -+ break; -+ case AuLsc_DI_CHILD2: -+ ii_read_lock_child2(inode); -+ break; -+ case AuLsc_DI_CHILD3: -+ ii_read_lock_child3(inode); -+ break; -+ case AuLsc_DI_PARENT: -+ ii_read_lock_parent(inode); -+ break; -+ case AuLsc_DI_PARENT2: -+ ii_read_lock_parent2(inode); -+ break; -+ case AuLsc_DI_PARENT3: -+ ii_read_lock_parent3(inode); -+ break; -+ default: -+ BUG(); -+ } -+} -+ -+void di_read_lock(struct dentry *d, int flags, unsigned int lsc) -+{ -+ struct inode *inode; -+ -+ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc); -+ if (d_really_is_positive(d)) { -+ inode = d_inode(d); -+ if (au_ftest_lock(flags, IW)) -+ do_ii_write_lock(inode, lsc); -+ else if (au_ftest_lock(flags, IR)) -+ do_ii_read_lock(inode, lsc); -+ } -+} -+ -+void di_read_unlock(struct dentry *d, int flags) -+{ -+ struct inode *inode; -+ -+ if (d_really_is_positive(d)) { -+ inode = d_inode(d); -+ if (au_ftest_lock(flags, IW)) { -+ au_dbg_verify_dinode(d); -+ ii_write_unlock(inode); -+ } else if (au_ftest_lock(flags, IR)) { -+ au_dbg_verify_dinode(d); -+ ii_read_unlock(inode); -+ } -+ } -+ au_rw_read_unlock(&au_di(d)->di_rwsem); -+} -+ -+void di_downgrade_lock(struct dentry *d, int flags) -+{ -+ if (d_really_is_positive(d) && au_ftest_lock(flags, IR)) -+ ii_downgrade_lock(d_inode(d)); -+ au_rw_dgrade_lock(&au_di(d)->di_rwsem); -+} -+ -+void di_write_lock(struct dentry *d, unsigned int lsc) -+{ -+ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc); -+ if (d_really_is_positive(d)) -+ do_ii_write_lock(d_inode(d), lsc); -+} -+ -+void di_write_unlock(struct dentry *d) -+{ -+ au_dbg_verify_dinode(d); -+ if (d_really_is_positive(d)) -+ ii_write_unlock(d_inode(d)); -+ au_rw_write_unlock(&au_di(d)->di_rwsem); -+} -+ -+void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir) -+{ -+ AuDebugOn(d1 == d2 -+ || d_inode(d1) == d_inode(d2) -+ || d1->d_sb != d2->d_sb); -+ -+ if ((isdir && au_test_subdir(d1, d2)) -+ || d1 < d2) { -+ di_write_lock_child(d1); -+ di_write_lock_child2(d2); -+ } else { -+ di_write_lock_child(d2); -+ di_write_lock_child2(d1); -+ } -+} -+ -+void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir) -+{ -+ AuDebugOn(d1 == d2 -+ || d_inode(d1) == d_inode(d2) -+ || d1->d_sb != d2->d_sb); -+ -+ if ((isdir && au_test_subdir(d1, d2)) -+ || d1 < d2) { -+ di_write_lock_parent(d1); -+ di_write_lock_parent2(d2); -+ } else { -+ di_write_lock_parent(d2); -+ di_write_lock_parent2(d1); -+ } -+} -+ -+void di_write_unlock2(struct dentry *d1, struct dentry *d2) -+{ -+ di_write_unlock(d1); -+ if (d_inode(d1) == d_inode(d2)) -+ au_rw_write_unlock(&au_di(d2)->di_rwsem); -+ else -+ di_write_unlock(d2); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ struct dentry *d; -+ -+ DiMustAnyLock(dentry); -+ -+ if (au_dbtop(dentry) < 0 || bindex < au_dbtop(dentry)) -+ return NULL; -+ AuDebugOn(bindex < 0); -+ d = au_hdentry(au_di(dentry), bindex)->hd_dentry; -+ AuDebugOn(d && au_dcount(d) <= 0); -+ return d; -+} -+ -+/* -+ * extended version of au_h_dptr(). -+ * returns a hashed and positive (or linkable) h_dentry in bindex, NULL, or -+ * error. -+ */ -+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ struct dentry *h_dentry; -+ struct inode *inode, *h_inode; -+ -+ AuDebugOn(d_really_is_negative(dentry)); -+ -+ h_dentry = NULL; -+ if (au_dbtop(dentry) <= bindex -+ && bindex <= au_dbbot(dentry)) -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry && !au_d_linkable(h_dentry)) { -+ dget(h_dentry); -+ goto out; /* success */ -+ } -+ -+ inode = d_inode(dentry); -+ AuDebugOn(bindex < au_ibtop(inode)); -+ AuDebugOn(au_ibbot(inode) < bindex); -+ h_inode = au_h_iptr(inode, bindex); -+ h_dentry = d_find_alias(h_inode); -+ if (h_dentry) { -+ if (!IS_ERR(h_dentry)) { -+ if (!au_d_linkable(h_dentry)) -+ goto out; /* success */ -+ dput(h_dentry); -+ } else -+ goto out; -+ } -+ -+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) { -+ h_dentry = au_plink_lkup(inode, bindex); -+ AuDebugOn(!h_dentry); -+ if (!IS_ERR(h_dentry)) { -+ if (!au_d_hashed_positive(h_dentry)) -+ goto out; /* success */ -+ dput(h_dentry); -+ h_dentry = NULL; -+ } -+ } -+ -+out: -+ AuDbgDentry(h_dentry); -+ return h_dentry; -+} -+ -+aufs_bindex_t au_dbtail(struct dentry *dentry) -+{ -+ aufs_bindex_t bbot, bwh; -+ -+ bbot = au_dbbot(dentry); -+ if (0 <= bbot) { -+ bwh = au_dbwh(dentry); -+ if (!bwh) -+ return bwh; -+ if (0 < bwh && bwh < bbot) -+ return bwh - 1; -+ } -+ return bbot; -+} -+ -+aufs_bindex_t au_dbtaildir(struct dentry *dentry) -+{ -+ aufs_bindex_t bbot, bopq; -+ -+ bbot = au_dbtail(dentry); -+ if (0 <= bbot) { -+ bopq = au_dbdiropq(dentry); -+ if (0 <= bopq && bopq < bbot) -+ bbot = bopq; -+ } -+ return bbot; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_dentry) -+{ -+ struct au_dinfo *dinfo; -+ struct au_hdentry *hd; -+ struct au_branch *br; -+ -+ DiMustWriteLock(dentry); -+ -+ dinfo = au_di(dentry); -+ hd = au_hdentry(dinfo, bindex); -+ au_hdput(hd); -+ hd->hd_dentry = h_dentry; -+ if (h_dentry) { -+ br = au_sbr(dentry->d_sb, bindex); -+ hd->hd_id = br->br_id; -+ } -+} -+ -+int au_dbrange_test(struct dentry *dentry) -+{ -+ int err; -+ aufs_bindex_t btop, bbot; -+ -+ err = 0; -+ btop = au_dbtop(dentry); -+ bbot = au_dbbot(dentry); -+ if (btop >= 0) -+ AuDebugOn(bbot < 0 && btop > bbot); -+ else { -+ err = -EIO; -+ AuDebugOn(bbot >= 0); -+ } -+ -+ return err; -+} -+ -+int au_digen_test(struct dentry *dentry, unsigned int sigen) -+{ -+ int err; -+ -+ err = 0; -+ if (unlikely(au_digen(dentry) != sigen -+ || au_iigen_test(d_inode(dentry), sigen))) -+ err = -EIO; -+ -+ return err; -+} -+ -+void au_update_digen(struct dentry *dentry) -+{ -+ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb)); -+ /* smp_mb(); */ /* atomic_set */ -+} -+ -+void au_update_dbrange(struct dentry *dentry, int do_put_zero) -+{ -+ struct au_dinfo *dinfo; -+ struct dentry *h_d; -+ struct au_hdentry *hdp; -+ aufs_bindex_t bindex, bbot; -+ -+ DiMustWriteLock(dentry); -+ -+ dinfo = au_di(dentry); -+ if (!dinfo || dinfo->di_btop < 0) -+ return; -+ -+ if (do_put_zero) { -+ bbot = dinfo->di_bbot; -+ bindex = dinfo->di_btop; -+ hdp = au_hdentry(dinfo, bindex); -+ for (; bindex <= bbot; bindex++, hdp++) { -+ h_d = hdp->hd_dentry; -+ if (h_d && d_is_negative(h_d)) -+ au_set_h_dptr(dentry, bindex, NULL); -+ } -+ } -+ -+ dinfo->di_btop = 0; -+ hdp = au_hdentry(dinfo, dinfo->di_btop); -+ for (; dinfo->di_btop <= dinfo->di_bbot; dinfo->di_btop++, hdp++) -+ if (hdp->hd_dentry) -+ break; -+ if (dinfo->di_btop > dinfo->di_bbot) { -+ dinfo->di_btop = -1; -+ dinfo->di_bbot = -1; -+ return; -+ } -+ -+ hdp = au_hdentry(dinfo, dinfo->di_bbot); -+ for (; dinfo->di_bbot >= 0; dinfo->di_bbot--, hdp--) -+ if (hdp->hd_dentry) -+ break; -+ AuDebugOn(dinfo->di_btop > dinfo->di_bbot || dinfo->di_bbot < 0); -+} -+ -+void au_update_dbtop(struct dentry *dentry) -+{ -+ aufs_bindex_t bindex, bbot; -+ struct dentry *h_dentry; -+ -+ bbot = au_dbbot(dentry); -+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry) -+ continue; -+ if (d_is_positive(h_dentry)) { -+ au_set_dbtop(dentry, bindex); -+ return; -+ } -+ au_set_h_dptr(dentry, bindex, NULL); -+ } -+} -+ -+void au_update_dbbot(struct dentry *dentry) -+{ -+ aufs_bindex_t bindex, btop; -+ struct dentry *h_dentry; -+ -+ btop = au_dbtop(dentry); -+ for (bindex = au_dbbot(dentry); bindex >= btop; bindex--) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry) -+ continue; -+ if (d_is_positive(h_dentry)) { -+ au_set_dbbot(dentry, bindex); -+ return; -+ } -+ au_set_h_dptr(dentry, bindex, NULL); -+ } -+} -+ -+int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry) -+{ -+ aufs_bindex_t bindex, bbot; -+ -+ bbot = au_dbbot(dentry); -+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) -+ if (au_h_dptr(dentry, bindex) == h_dentry) -+ return bindex; -+ return -1; -+} -diff --git a/fs/aufs/dir.c b/fs/aufs/dir.c -new file mode 100644 -index 000000000..48e067fe6 ---- /dev/null -+++ b/fs/aufs/dir.c -@@ -0,0 +1,762 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * directory operations -+ */ -+ -+#include -+#include "aufs.h" -+ -+void au_add_nlink(struct inode *dir, struct inode *h_dir) -+{ -+ unsigned int nlink; -+ -+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); -+ -+ nlink = dir->i_nlink; -+ nlink += h_dir->i_nlink - 2; -+ if (h_dir->i_nlink < 2) -+ nlink += 2; -+ smp_mb(); /* for i_nlink */ -+ /* 0 can happen in revaliding */ -+ set_nlink(dir, nlink); -+} -+ -+void au_sub_nlink(struct inode *dir, struct inode *h_dir) -+{ -+ unsigned int nlink; -+ -+ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); -+ -+ nlink = dir->i_nlink; -+ nlink -= h_dir->i_nlink - 2; -+ if (h_dir->i_nlink < 2) -+ nlink -= 2; -+ smp_mb(); /* for i_nlink */ -+ /* nlink == 0 means the branch-fs is broken */ -+ set_nlink(dir, nlink); -+} -+ -+loff_t au_dir_size(struct file *file, struct dentry *dentry) -+{ -+ loff_t sz; -+ aufs_bindex_t bindex, bbot; -+ struct file *h_file; -+ struct dentry *h_dentry; -+ -+ sz = 0; -+ if (file) { -+ AuDebugOn(!d_is_dir(file->f_path.dentry)); -+ -+ bbot = au_fbbot_dir(file); -+ for (bindex = au_fbtop(file); -+ bindex <= bbot && sz < KMALLOC_MAX_SIZE; -+ bindex++) { -+ h_file = au_hf_dir(file, bindex); -+ if (h_file && file_inode(h_file)) -+ sz += vfsub_f_size_read(h_file); -+ } -+ } else { -+ AuDebugOn(!dentry); -+ AuDebugOn(!d_is_dir(dentry)); -+ -+ bbot = au_dbtaildir(dentry); -+ for (bindex = au_dbtop(dentry); -+ bindex <= bbot && sz < KMALLOC_MAX_SIZE; -+ bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry && d_is_positive(h_dentry)) -+ sz += i_size_read(d_inode(h_dentry)); -+ } -+ } -+ if (sz < KMALLOC_MAX_SIZE) -+ sz = roundup_pow_of_two(sz); -+ if (sz > KMALLOC_MAX_SIZE) -+ sz = KMALLOC_MAX_SIZE; -+ else if (sz < NAME_MAX) { -+ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX); -+ sz = AUFS_RDBLK_DEF; -+ } -+ return sz; -+} -+ -+struct au_dir_ts_arg { -+ struct dentry *dentry; -+ aufs_bindex_t brid; -+}; -+ -+static void au_do_dir_ts(void *arg) -+{ -+ struct au_dir_ts_arg *a = arg; -+ struct au_dtime dt; -+ struct path h_path; -+ struct inode *dir, *h_dir; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_hinode *hdir; -+ int err; -+ aufs_bindex_t btop, bindex; -+ -+ sb = a->dentry->d_sb; -+ if (d_really_is_negative(a->dentry)) -+ goto out; -+ /* no dir->i_mutex lock */ -+ aufs_read_lock(a->dentry, AuLock_DW); /* noflush */ -+ -+ dir = d_inode(a->dentry); -+ btop = au_ibtop(dir); -+ bindex = au_br_index(sb, a->brid); -+ if (bindex < btop) -+ goto out_unlock; -+ -+ br = au_sbr(sb, bindex); -+ h_path.dentry = au_h_dptr(a->dentry, bindex); -+ if (!h_path.dentry) -+ goto out_unlock; -+ h_path.mnt = au_br_mnt(br); -+ au_dtime_store(&dt, a->dentry, &h_path); -+ -+ br = au_sbr(sb, btop); -+ if (!au_br_writable(br->br_perm)) -+ goto out_unlock; -+ h_path.dentry = au_h_dptr(a->dentry, btop); -+ h_path.mnt = au_br_mnt(br); -+ err = vfsub_mnt_want_write(h_path.mnt); -+ if (err) -+ goto out_unlock; -+ hdir = au_hi(dir, btop); -+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT); -+ h_dir = au_h_iptr(dir, btop); -+ if (h_dir->i_nlink -+ && timespec64_compare(&h_dir->i_mtime, &dt.dt_mtime) < 0) { -+ dt.dt_h_path = h_path; -+ au_dtime_revert(&dt); -+ } -+ au_hn_inode_unlock(hdir); -+ vfsub_mnt_drop_write(h_path.mnt); -+ au_cpup_attr_timesizes(dir); -+ -+out_unlock: -+ aufs_read_unlock(a->dentry, AuLock_DW); -+out: -+ dput(a->dentry); -+ au_nwt_done(&au_sbi(sb)->si_nowait); -+ kfree(arg); -+} -+ -+void au_dir_ts(struct inode *dir, aufs_bindex_t bindex) -+{ -+ int perm, wkq_err; -+ aufs_bindex_t btop; -+ struct au_dir_ts_arg *arg; -+ struct dentry *dentry; -+ struct super_block *sb; -+ -+ IMustLock(dir); -+ -+ dentry = d_find_any_alias(dir); -+ AuDebugOn(!dentry); -+ sb = dentry->d_sb; -+ btop = au_ibtop(dir); -+ if (btop == bindex) { -+ au_cpup_attr_timesizes(dir); -+ goto out; -+ } -+ -+ perm = au_sbr_perm(sb, btop); -+ if (!au_br_writable(perm)) -+ goto out; -+ -+ arg = kmalloc(sizeof(*arg), GFP_NOFS); -+ if (!arg) -+ goto out; -+ -+ arg->dentry = dget(dentry); /* will be dput-ted by au_do_dir_ts() */ -+ arg->brid = au_sbr_id(sb, bindex); -+ wkq_err = au_wkq_nowait(au_do_dir_ts, arg, sb, /*flags*/0); -+ if (unlikely(wkq_err)) { -+ pr_err("wkq %d\n", wkq_err); -+ dput(dentry); -+ kfree(arg); -+ } -+ -+out: -+ dput(dentry); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int reopen_dir(struct file *file) -+{ -+ int err; -+ unsigned int flags; -+ aufs_bindex_t bindex, btail, btop; -+ struct dentry *dentry, *h_dentry; -+ struct file *h_file; -+ -+ /* open all lower dirs */ -+ dentry = file->f_path.dentry; -+ btop = au_dbtop(dentry); -+ for (bindex = au_fbtop(file); bindex < btop; bindex++) -+ au_set_h_fptr(file, bindex, NULL); -+ au_set_fbtop(file, btop); -+ -+ btail = au_dbtaildir(dentry); -+ for (bindex = au_fbbot_dir(file); btail < bindex; bindex--) -+ au_set_h_fptr(file, bindex, NULL); -+ au_set_fbbot_dir(file, btail); -+ -+ flags = vfsub_file_flags(file); -+ for (bindex = btop; bindex <= btail; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry) -+ continue; -+ h_file = au_hf_dir(file, bindex); -+ if (h_file) -+ continue; -+ -+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; /* close all? */ -+ au_set_h_fptr(file, bindex, h_file); -+ } -+ au_update_figen(file); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ err = 0; -+ -+out: -+ return err; -+} -+ -+static int do_open_dir(struct file *file, int flags, struct file *h_file) -+{ -+ int err; -+ aufs_bindex_t bindex, btail; -+ struct dentry *dentry, *h_dentry; -+ struct vfsmount *mnt; -+ -+ FiMustWriteLock(file); -+ AuDebugOn(h_file); -+ -+ err = 0; -+ mnt = file->f_path.mnt; -+ dentry = file->f_path.dentry; -+ file->f_version = inode_query_iversion(d_inode(dentry)); -+ bindex = au_dbtop(dentry); -+ au_set_fbtop(file, bindex); -+ btail = au_dbtaildir(dentry); -+ au_set_fbbot_dir(file, btail); -+ for (; !err && bindex <= btail; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!h_dentry) -+ continue; -+ -+ err = vfsub_test_mntns(mnt, h_dentry->d_sb); -+ if (unlikely(err)) -+ break; -+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0); -+ if (IS_ERR(h_file)) { -+ err = PTR_ERR(h_file); -+ break; -+ } -+ au_set_h_fptr(file, bindex, h_file); -+ } -+ au_update_figen(file); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ if (!err) -+ return 0; /* success */ -+ -+ /* close all */ -+ for (bindex = au_fbtop(file); bindex <= btail; bindex++) -+ au_set_h_fptr(file, bindex, NULL); -+ au_set_fbtop(file, -1); -+ au_set_fbbot_dir(file, -1); -+ -+ return err; -+} -+ -+static int aufs_open_dir(struct inode *inode __maybe_unused, -+ struct file *file) -+{ -+ int err; -+ struct super_block *sb; -+ struct au_fidir *fidir; -+ -+ err = -ENOMEM; -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ fidir = au_fidir_alloc(sb); -+ if (fidir) { -+ struct au_do_open_args args = { -+ .open = do_open_dir, -+ .fidir = fidir -+ }; -+ err = au_do_open(file, &args); -+ if (unlikely(err)) -+ kfree(fidir); -+ } -+ si_read_unlock(sb); -+ return err; -+} -+ -+static int aufs_release_dir(struct inode *inode __maybe_unused, -+ struct file *file) -+{ -+ struct au_vdir *vdir_cache; -+ struct au_finfo *finfo; -+ struct au_fidir *fidir; -+ struct au_hfile *hf; -+ aufs_bindex_t bindex, bbot; -+ -+ finfo = au_fi(file); -+ fidir = finfo->fi_hdir; -+ if (fidir) { -+ au_hbl_del(&finfo->fi_hlist, -+ &au_sbi(file->f_path.dentry->d_sb)->si_files); -+ vdir_cache = fidir->fd_vdir_cache; /* lock-free */ -+ if (vdir_cache) -+ au_vdir_free(vdir_cache); -+ -+ bindex = finfo->fi_btop; -+ if (bindex >= 0) { -+ hf = fidir->fd_hfile + bindex; -+ /* -+ * calls fput() instead of filp_close(), -+ * since no dnotify or lock for the lower file. -+ */ -+ bbot = fidir->fd_bbot; -+ for (; bindex <= bbot; bindex++, hf++) -+ if (hf->hf_file) -+ au_hfput(hf, /*execed*/0); -+ } -+ kfree(fidir); -+ finfo->fi_hdir = NULL; -+ } -+ au_finfo_fin(file); -+ return 0; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_do_flush_dir(struct file *file, fl_owner_t id) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct file *h_file; -+ -+ err = 0; -+ bbot = au_fbbot_dir(file); -+ for (bindex = au_fbtop(file); !err && bindex <= bbot; bindex++) { -+ h_file = au_hf_dir(file, bindex); -+ if (h_file) -+ err = vfsub_flush(h_file, id); -+ } -+ return err; -+} -+ -+static int aufs_flush_dir(struct file *file, fl_owner_t id) -+{ -+ return au_do_flush(file, id, au_do_flush_dir); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync) -+{ -+ int err; -+ aufs_bindex_t bbot, bindex; -+ struct inode *inode; -+ struct super_block *sb; -+ -+ err = 0; -+ sb = dentry->d_sb; -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ bbot = au_dbbot(dentry); -+ for (bindex = au_dbtop(dentry); !err && bindex <= bbot; bindex++) { -+ struct path h_path; -+ -+ if (au_test_ro(sb, bindex, inode)) -+ continue; -+ h_path.dentry = au_h_dptr(dentry, bindex); -+ if (!h_path.dentry) -+ continue; -+ -+ h_path.mnt = au_sbr_mnt(sb, bindex); -+ err = vfsub_fsync(NULL, &h_path, datasync); -+ } -+ -+ return err; -+} -+ -+static int au_do_fsync_dir(struct file *file, int datasync) -+{ -+ int err; -+ aufs_bindex_t bbot, bindex; -+ struct file *h_file; -+ struct super_block *sb; -+ struct inode *inode; -+ -+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*fi_lsc*/0); -+ if (unlikely(err)) -+ goto out; -+ -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ bbot = au_fbbot_dir(file); -+ for (bindex = au_fbtop(file); !err && bindex <= bbot; bindex++) { -+ h_file = au_hf_dir(file, bindex); -+ if (!h_file || au_test_ro(sb, bindex, inode)) -+ continue; -+ -+ err = vfsub_fsync(h_file, &h_file->f_path, datasync); -+ } -+ -+out: -+ return err; -+} -+ -+/* -+ * @file may be NULL -+ */ -+static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end, -+ int datasync) -+{ -+ int err; -+ struct dentry *dentry; -+ struct inode *inode; -+ struct super_block *sb; -+ -+ err = 0; -+ dentry = file->f_path.dentry; -+ inode = d_inode(dentry); -+ inode_lock(inode); -+ sb = dentry->d_sb; -+ si_noflush_read_lock(sb); -+ if (file) -+ err = au_do_fsync_dir(file, datasync); -+ else { -+ di_write_lock_child(dentry); -+ err = au_do_fsync_dir_no_file(dentry, datasync); -+ } -+ au_cpup_attr_timesizes(inode); -+ di_write_unlock(dentry); -+ if (file) -+ fi_write_unlock(file); -+ -+ si_read_unlock(sb); -+ inode_unlock(inode); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int aufs_iterate_shared(struct file *file, struct dir_context *ctx) -+{ -+ int err; -+ struct dentry *dentry; -+ struct inode *inode, *h_inode; -+ struct super_block *sb; -+ -+ AuDbg("%pD, ctx{%ps, %llu}\n", file, ctx->actor, ctx->pos); -+ -+ dentry = file->f_path.dentry; -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ -+ sb = dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*fi_lsc*/0); -+ if (unlikely(err)) -+ goto out; -+ err = au_alive_dir(dentry); -+ if (!err) -+ err = au_vdir_init(file); -+ di_downgrade_lock(dentry, AuLock_IR); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ h_inode = au_h_iptr(inode, au_ibtop(inode)); -+ if (!au_test_nfsd()) { -+ err = au_vdir_fill_de(file, ctx); -+ fsstack_copy_attr_atime(inode, h_inode); -+ } else { -+ /* -+ * nfsd filldir may call lookup_one_len(), vfs_getattr(), -+ * encode_fh() and others. -+ */ -+ atomic_inc(&h_inode->i_count); -+ di_read_unlock(dentry, AuLock_IR); -+ si_read_unlock(sb); -+ err = au_vdir_fill_de(file, ctx); -+ fsstack_copy_attr_atime(inode, h_inode); -+ fi_write_unlock(file); -+ iput(h_inode); -+ -+ AuTraceErr(err); -+ return err; -+ } -+ -+out_unlock: -+ di_read_unlock(dentry, AuLock_IR); -+ fi_write_unlock(file); -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define AuTestEmpty_WHONLY 1 -+#define AuTestEmpty_CALLED (1 << 1) -+#define AuTestEmpty_SHWH (1 << 2) -+#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name) -+#define au_fset_testempty(flags, name) \ -+ do { (flags) |= AuTestEmpty_##name; } while (0) -+#define au_fclr_testempty(flags, name) \ -+ do { (flags) &= ~AuTestEmpty_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_SHWH -+#undef AuTestEmpty_SHWH -+#define AuTestEmpty_SHWH 0 -+#endif -+ -+struct test_empty_arg { -+ struct dir_context ctx; -+ struct au_nhash *whlist; -+ unsigned int flags; -+ int err; -+ aufs_bindex_t bindex; -+}; -+ -+static int test_empty_cb(struct dir_context *ctx, const char *__name, -+ int namelen, loff_t offset __maybe_unused, u64 ino, -+ unsigned int d_type) -+{ -+ struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg, -+ ctx); -+ char *name = (void *)__name; -+ -+ arg->err = 0; -+ au_fset_testempty(arg->flags, CALLED); -+ /* smp_mb(); */ -+ if (name[0] == '.' -+ && (namelen == 1 || (name[1] == '.' && namelen == 2))) -+ goto out; /* success */ -+ -+ if (namelen <= AUFS_WH_PFX_LEN -+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { -+ if (au_ftest_testempty(arg->flags, WHONLY) -+ && !au_nhash_test_known_wh(arg->whlist, name, namelen)) -+ arg->err = -ENOTEMPTY; -+ goto out; -+ } -+ -+ name += AUFS_WH_PFX_LEN; -+ namelen -= AUFS_WH_PFX_LEN; -+ if (!au_nhash_test_known_wh(arg->whlist, name, namelen)) -+ arg->err = au_nhash_append_wh -+ (arg->whlist, name, namelen, ino, d_type, arg->bindex, -+ au_ftest_testempty(arg->flags, SHWH)); -+ -+out: -+ /* smp_mb(); */ -+ AuTraceErr(arg->err); -+ return arg->err; -+} -+ -+static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg) -+{ -+ int err; -+ struct file *h_file; -+ struct au_branch *br; -+ -+ h_file = au_h_open(dentry, arg->bindex, -+ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE, -+ /*file*/NULL, /*force_wr*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = 0; -+ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE) -+ && !file_inode(h_file)->i_nlink) -+ goto out_put; -+ -+ do { -+ arg->err = 0; -+ au_fclr_testempty(arg->flags, CALLED); -+ /* smp_mb(); */ -+ err = vfsub_iterate_dir(h_file, &arg->ctx); -+ if (err >= 0) -+ err = arg->err; -+ } while (!err && au_ftest_testempty(arg->flags, CALLED)); -+ -+out_put: -+ fput(h_file); -+ br = au_sbr(dentry->d_sb, arg->bindex); -+ au_lcnt_dec(&br->br_nfiles); -+out: -+ return err; -+} -+ -+struct do_test_empty_args { -+ int *errp; -+ struct dentry *dentry; -+ struct test_empty_arg *arg; -+}; -+ -+static void call_do_test_empty(void *args) -+{ -+ struct do_test_empty_args *a = args; -+ *a->errp = do_test_empty(a->dentry, a->arg); -+} -+ -+static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg) -+{ -+ int err, wkq_err; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ -+ h_dentry = au_h_dptr(dentry, arg->bindex); -+ h_inode = d_inode(h_dentry); -+ /* todo: i_mode changes anytime? */ -+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD); -+ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ); -+ inode_unlock_shared(h_inode); -+ if (!err) -+ err = do_test_empty(dentry, arg); -+ else { -+ struct do_test_empty_args args = { -+ .errp = &err, -+ .dentry = dentry, -+ .arg = arg -+ }; -+ unsigned int flags = arg->flags; -+ -+ wkq_err = au_wkq_wait(call_do_test_empty, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ arg->flags = flags; -+ } -+ -+ return err; -+} -+ -+int au_test_empty_lower(struct dentry *dentry) -+{ -+ int err; -+ unsigned int rdhash; -+ aufs_bindex_t bindex, btop, btail; -+ struct au_nhash whlist; -+ struct test_empty_arg arg = { -+ .ctx = { -+ .actor = test_empty_cb -+ } -+ }; -+ int (*test_empty)(struct dentry *dentry, struct test_empty_arg *arg); -+ -+ SiMustAnyLock(dentry->d_sb); -+ -+ rdhash = au_sbi(dentry->d_sb)->si_rdhash; -+ if (!rdhash) -+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry)); -+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ -+ arg.flags = 0; -+ arg.whlist = &whlist; -+ btop = au_dbtop(dentry); -+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)) -+ au_fset_testempty(arg.flags, SHWH); -+ test_empty = do_test_empty; -+ if (au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1)) -+ test_empty = sio_test_empty; -+ arg.bindex = btop; -+ err = test_empty(dentry, &arg); -+ if (unlikely(err)) -+ goto out_whlist; -+ -+ au_fset_testempty(arg.flags, WHONLY); -+ btail = au_dbtaildir(dentry); -+ for (bindex = btop + 1; !err && bindex <= btail; bindex++) { -+ struct dentry *h_dentry; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry && d_is_positive(h_dentry)) { -+ arg.bindex = bindex; -+ err = test_empty(dentry, &arg); -+ } -+ } -+ -+out_whlist: -+ au_nhash_wh_free(&whlist); -+out: -+ return err; -+} -+ -+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist) -+{ -+ int err; -+ struct test_empty_arg arg = { -+ .ctx = { -+ .actor = test_empty_cb -+ } -+ }; -+ aufs_bindex_t bindex, btail; -+ -+ err = 0; -+ arg.whlist = whlist; -+ arg.flags = AuTestEmpty_WHONLY; -+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)) -+ au_fset_testempty(arg.flags, SHWH); -+ btail = au_dbtaildir(dentry); -+ for (bindex = au_dbtop(dentry); !err && bindex <= btail; bindex++) { -+ struct dentry *h_dentry; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry && d_is_positive(h_dentry)) { -+ arg.bindex = bindex; -+ err = sio_test_empty(dentry, &arg); -+ } -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+const struct file_operations aufs_dir_fop = { -+ .owner = THIS_MODULE, -+ .llseek = default_llseek, -+ .read = generic_read_dir, -+ .iterate_shared = aufs_iterate_shared, -+ .unlocked_ioctl = aufs_ioctl_dir, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = aufs_compat_ioctl_dir, -+#endif -+ .open = aufs_open_dir, -+ .release = aufs_release_dir, -+ .flush = aufs_flush_dir, -+ .fsync = aufs_fsync_dir -+}; -diff --git a/fs/aufs/dir.h b/fs/aufs/dir.h -new file mode 100644 -index 000000000..e7acabe09 ---- /dev/null -+++ b/fs/aufs/dir.h -@@ -0,0 +1,132 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * directory operations -+ */ -+ -+#ifndef __AUFS_DIR_H__ -+#define __AUFS_DIR_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* need to be faster and smaller */ -+ -+struct au_nhash { -+ unsigned int nh_num; -+ struct hlist_head *nh_head; -+}; -+ -+struct au_vdir_destr { -+ unsigned char len; -+ unsigned char name[0]; -+} __packed; -+ -+struct au_vdir_dehstr { -+ struct hlist_node hash; -+ struct au_vdir_destr *str; -+} ____cacheline_aligned_in_smp; -+ -+struct au_vdir_de { -+ ino_t de_ino; -+ unsigned char de_type; -+ /* caution: packed */ -+ struct au_vdir_destr de_str; -+} __packed; -+ -+struct au_vdir_wh { -+ struct hlist_node wh_hash; -+#ifdef CONFIG_AUFS_SHWH -+ ino_t wh_ino; -+ aufs_bindex_t wh_bindex; -+ unsigned char wh_type; -+#else -+ aufs_bindex_t wh_bindex; -+#endif -+ /* caution: packed */ -+ struct au_vdir_destr wh_str; -+} __packed; -+ -+union au_vdir_deblk_p { -+ unsigned char *deblk; -+ struct au_vdir_de *de; -+}; -+ -+struct au_vdir { -+ unsigned char **vd_deblk; -+ unsigned long vd_nblk; -+ struct { -+ unsigned long ul; -+ union au_vdir_deblk_p p; -+ } vd_last; -+ -+ u64 vd_version; -+ unsigned int vd_deblk_sz; -+ unsigned long vd_jiffy; -+} ____cacheline_aligned_in_smp; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* dir.c */ -+extern const struct file_operations aufs_dir_fop; -+void au_add_nlink(struct inode *dir, struct inode *h_dir); -+void au_sub_nlink(struct inode *dir, struct inode *h_dir); -+loff_t au_dir_size(struct file *file, struct dentry *dentry); -+void au_dir_ts(struct inode *dir, aufs_bindex_t bsrc); -+int au_test_empty_lower(struct dentry *dentry); -+int au_test_empty(struct dentry *dentry, struct au_nhash *whlist); -+ -+/* vdir.c */ -+unsigned int au_rdhash_est(loff_t sz); -+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp); -+void au_nhash_wh_free(struct au_nhash *whlist); -+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, -+ int limit); -+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen); -+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino, -+ unsigned int d_type, aufs_bindex_t bindex, -+ unsigned char shwh); -+void au_vdir_free(struct au_vdir *vdir); -+int au_vdir_init(struct file *file); -+int au_vdir_fill_de(struct file *file, struct dir_context *ctx); -+ -+/* ioctl.c */ -+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg); -+ -+#ifdef CONFIG_AUFS_RDU -+/* rdu.c */ -+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg); -+#ifdef CONFIG_COMPAT -+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, -+ unsigned long arg); -+#endif -+#else -+AuStub(long, au_rdu_ioctl, return -EINVAL, struct file *file, -+ unsigned int cmd, unsigned long arg) -+#ifdef CONFIG_COMPAT -+AuStub(long, au_rdu_compat_ioctl, return -EINVAL, struct file *file, -+ unsigned int cmd, unsigned long arg) -+#endif -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DIR_H__ */ -diff --git a/fs/aufs/dirren.c b/fs/aufs/dirren.c -new file mode 100644 -index 000000000..85c77ad80 ---- /dev/null -+++ b/fs/aufs/dirren.c -@@ -0,0 +1,1316 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2017-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * special handling in renaming a directory -+ * in order to support looking-up the before-renamed name on the lower readonly -+ * branches -+ */ -+ -+#include -+#include "aufs.h" -+ -+static void au_dr_hino_del(struct au_dr_br *dr, struct au_dr_hino *ent) -+{ -+ int idx; -+ -+ idx = au_dr_ihash(ent->dr_h_ino); -+ au_hbl_del(&ent->dr_hnode, dr->dr_h_ino + idx); -+} -+ -+static int au_dr_hino_test_empty(struct au_dr_br *dr) -+{ -+ int ret, i; -+ struct hlist_bl_head *hbl; -+ -+ ret = 1; -+ for (i = 0; ret && i < AuDirren_NHASH; i++) { -+ hbl = dr->dr_h_ino + i; -+ hlist_bl_lock(hbl); -+ ret &= hlist_bl_empty(hbl); -+ hlist_bl_unlock(hbl); -+ } -+ -+ return ret; -+} -+ -+static struct au_dr_hino *au_dr_hino_find(struct au_dr_br *dr, ino_t ino) -+{ -+ struct au_dr_hino *found, *ent; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ int idx; -+ -+ found = NULL; -+ idx = au_dr_ihash(ino); -+ hbl = dr->dr_h_ino + idx; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(ent, pos, hbl, dr_hnode) -+ if (ent->dr_h_ino == ino) { -+ found = ent; -+ break; -+ } -+ hlist_bl_unlock(hbl); -+ -+ return found; -+} -+ -+int au_dr_hino_test_add(struct au_dr_br *dr, ino_t ino, -+ struct au_dr_hino *add_ent) -+{ -+ int found, idx; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ struct au_dr_hino *ent; -+ -+ found = 0; -+ idx = au_dr_ihash(ino); -+ hbl = dr->dr_h_ino + idx; -+#if 0 -+ { -+ struct hlist_bl_node *tmp; -+ -+ hlist_bl_for_each_entry_safe(ent, pos, tmp, hbl, dr_hnode) -+ AuDbg("hi%llu\n", (unsigned long long)ent->dr_h_ino); -+ } -+#endif -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(ent, pos, hbl, dr_hnode) -+ if (ent->dr_h_ino == ino) { -+ found = 1; -+ break; -+ } -+ if (!found && add_ent) -+ hlist_bl_add_head(&add_ent->dr_hnode, hbl); -+ hlist_bl_unlock(hbl); -+ -+ if (!found && add_ent) -+ AuDbg("i%llu added\n", (unsigned long long)add_ent->dr_h_ino); -+ -+ return found; -+} -+ -+void au_dr_hino_free(struct au_dr_br *dr) -+{ -+ int i; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos, *tmp; -+ struct au_dr_hino *ent; -+ -+ /* SiMustWriteLock(sb); */ -+ -+ for (i = 0; i < AuDirren_NHASH; i++) { -+ hbl = dr->dr_h_ino + i; -+ /* no spinlock since sbinfo must be write-locked */ -+ hlist_bl_for_each_entry_safe(ent, pos, tmp, hbl, dr_hnode) -+ kfree(ent); -+ INIT_HLIST_BL_HEAD(hbl); -+ } -+} -+ -+/* returns the number of inodes or an error */ -+static int au_dr_hino_store(struct super_block *sb, struct au_branch *br, -+ struct file *hinofile) -+{ -+ int err, i; -+ ssize_t ssz; -+ loff_t pos, oldsize; -+ __be64 u64; -+ struct inode *hinoinode; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *n1, *n2; -+ struct au_dr_hino *ent; -+ -+ SiMustWriteLock(sb); -+ AuDebugOn(!au_br_writable(br->br_perm)); -+ -+ hinoinode = file_inode(hinofile); -+ oldsize = i_size_read(hinoinode); -+ -+ err = 0; -+ pos = 0; -+ hbl = br->br_dirren.dr_h_ino; -+ for (i = 0; !err && i < AuDirren_NHASH; i++, hbl++) { -+ /* no bit-lock since sbinfo must be write-locked */ -+ hlist_bl_for_each_entry_safe(ent, n1, n2, hbl, dr_hnode) { -+ AuDbg("hi%llu, %pD2\n", -+ (unsigned long long)ent->dr_h_ino, hinofile); -+ u64 = cpu_to_be64(ent->dr_h_ino); -+ ssz = vfsub_write_k(hinofile, &u64, sizeof(u64), &pos); -+ if (ssz == sizeof(u64)) -+ continue; -+ -+ /* write error */ -+ pr_err("ssz %zd, %pD2\n", ssz, hinofile); -+ err = -ENOSPC; -+ if (ssz < 0) -+ err = ssz; -+ break; -+ } -+ } -+ /* regardless the error */ -+ if (pos < oldsize) { -+ err = vfsub_trunc(&hinofile->f_path, pos, /*attr*/0, hinofile); -+ AuTraceErr(err); -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_dr_hino_load(struct au_dr_br *dr, struct file *hinofile) -+{ -+ int err, hidx; -+ ssize_t ssz; -+ size_t sz, n; -+ loff_t pos; -+ uint64_t u64; -+ struct au_dr_hino *ent; -+ struct inode *hinoinode; -+ struct hlist_bl_head *hbl; -+ -+ err = 0; -+ pos = 0; -+ hbl = dr->dr_h_ino; -+ hinoinode = file_inode(hinofile); -+ sz = i_size_read(hinoinode); -+ AuDebugOn(sz % sizeof(u64)); -+ n = sz / sizeof(u64); -+ while (n--) { -+ ssz = vfsub_read_k(hinofile, &u64, sizeof(u64), &pos); -+ if (unlikely(ssz != sizeof(u64))) { -+ pr_err("ssz %zd, %pD2\n", ssz, hinofile); -+ err = -EINVAL; -+ if (ssz < 0) -+ err = ssz; -+ goto out_free; -+ } -+ -+ ent = kmalloc(sizeof(*ent), GFP_NOFS); -+ if (!ent) { -+ err = -ENOMEM; -+ AuTraceErr(err); -+ goto out_free; -+ } -+ ent->dr_h_ino = be64_to_cpu((__force __be64)u64); -+ AuDbg("hi%llu, %pD2\n", -+ (unsigned long long)ent->dr_h_ino, hinofile); -+ hidx = au_dr_ihash(ent->dr_h_ino); -+ au_hbl_add(&ent->dr_hnode, hbl + hidx); -+ } -+ goto out; /* success */ -+ -+out_free: -+ au_dr_hino_free(dr); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * @bindex/@br is a switch to distinguish whether suspending hnotify or not. -+ * @path is a switch to distinguish load and store. -+ */ -+static int au_dr_hino(struct super_block *sb, aufs_bindex_t bindex, -+ struct au_branch *br, const struct path *path) -+{ -+ int err, flags; -+ unsigned char load, suspend; -+ struct file *hinofile; -+ struct au_hinode *hdir; -+ struct inode *dir, *delegated; -+ struct path hinopath; -+ struct qstr hinoname = QSTR_INIT(AUFS_WH_DR_BRHINO, -+ sizeof(AUFS_WH_DR_BRHINO) - 1); -+ -+ AuDebugOn(bindex < 0 && !br); -+ AuDebugOn(bindex >= 0 && br); -+ -+ err = -EINVAL; -+ suspend = !br; -+ if (suspend) -+ br = au_sbr(sb, bindex); -+ load = !!path; -+ if (!load) { -+ path = &br->br_path; -+ AuDebugOn(!au_br_writable(br->br_perm)); -+ if (unlikely(!au_br_writable(br->br_perm))) -+ goto out; -+ } -+ -+ hdir = NULL; -+ if (suspend) { -+ dir = d_inode(sb->s_root); -+ hdir = au_hinode(au_ii(dir), bindex); -+ dir = hdir->hi_inode; -+ au_hn_inode_lock_nested(hdir, AuLsc_I_CHILD); -+ } else { -+ dir = d_inode(path->dentry); -+ inode_lock_nested(dir, AuLsc_I_CHILD); -+ } -+ hinopath.dentry = vfsub_lkup_one(&hinoname, path->dentry); -+ err = PTR_ERR(hinopath.dentry); -+ if (IS_ERR(hinopath.dentry)) -+ goto out_unlock; -+ -+ err = 0; -+ flags = O_RDONLY; -+ if (load) { -+ if (d_is_negative(hinopath.dentry)) -+ goto out_dput; /* success */ -+ } else { -+ if (au_dr_hino_test_empty(&br->br_dirren)) { -+ if (d_is_positive(hinopath.dentry)) { -+ delegated = NULL; -+ err = vfsub_unlink(dir, &hinopath, &delegated, -+ /*force*/0); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ pr_err("ignored err %d, %pd2\n", -+ err, hinopath.dentry); -+ if (unlikely(err == -EWOULDBLOCK)) -+ iput(delegated); -+ err = 0; -+ } -+ goto out_dput; -+ } else if (!d_is_positive(hinopath.dentry)) { -+ err = vfsub_create(dir, &hinopath, 0600, -+ /*want_excl*/false); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out_dput; -+ } -+ flags = O_WRONLY; -+ } -+ hinopath.mnt = path->mnt; -+ hinofile = vfsub_dentry_open(&hinopath, flags); -+ if (suspend) -+ au_hn_inode_unlock(hdir); -+ else -+ inode_unlock(dir); -+ dput(hinopath.dentry); -+ AuTraceErrPtr(hinofile); -+ if (IS_ERR(hinofile)) { -+ err = PTR_ERR(hinofile); -+ goto out; -+ } -+ -+ if (load) -+ err = au_dr_hino_load(&br->br_dirren, hinofile); -+ else -+ err = au_dr_hino_store(sb, br, hinofile); -+ fput(hinofile); -+ goto out; -+ -+out_dput: -+ dput(hinopath.dentry); -+out_unlock: -+ if (suspend) -+ au_hn_inode_unlock(hdir); -+ else -+ inode_unlock(dir); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_dr_brid_init(struct au_dr_brid *brid, const struct path *path) -+{ -+ int err; -+ struct kstatfs kstfs; -+ dev_t dev; -+ struct dentry *dentry; -+ struct super_block *sb; -+ -+ err = vfs_statfs((void *)path, &kstfs); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out; -+ -+ /* todo: support for UUID */ -+ -+ if (kstfs.f_fsid.val[0] || kstfs.f_fsid.val[1]) { -+ brid->type = AuBrid_FSID; -+ brid->fsid = kstfs.f_fsid; -+ } else { -+ dentry = path->dentry; -+ sb = dentry->d_sb; -+ dev = sb->s_dev; -+ if (dev) { -+ brid->type = AuBrid_DEV; -+ brid->dev = dev; -+ } -+ } -+ -+out: -+ return err; -+} -+ -+int au_dr_br_init(struct super_block *sb, struct au_branch *br, -+ const struct path *path) -+{ -+ int err, i; -+ struct au_dr_br *dr; -+ struct hlist_bl_head *hbl; -+ -+ dr = &br->br_dirren; -+ hbl = dr->dr_h_ino; -+ for (i = 0; i < AuDirren_NHASH; i++, hbl++) -+ INIT_HLIST_BL_HEAD(hbl); -+ -+ err = au_dr_brid_init(&dr->dr_brid, path); -+ if (unlikely(err)) -+ goto out; -+ -+ if (au_opt_test(au_mntflags(sb), DIRREN)) -+ err = au_dr_hino(sb, /*bindex*/-1, br, path); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_dr_br_fin(struct super_block *sb, struct au_branch *br) -+{ -+ int err; -+ -+ err = 0; -+ if (au_br_writable(br->br_perm)) -+ err = au_dr_hino(sb, /*bindex*/-1, br, /*path*/NULL); -+ if (!err) -+ au_dr_hino_free(&br->br_dirren); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_brid_str(struct au_dr_brid *brid, struct inode *h_inode, -+ char *buf, size_t sz) -+{ -+ int err; -+ unsigned int major, minor; -+ char *p; -+ -+ p = buf; -+ err = snprintf(p, sz, "%d_", brid->type); -+ AuDebugOn(err > sz); -+ p += err; -+ sz -= err; -+ switch (brid->type) { -+ case AuBrid_Unset: -+ return -EINVAL; -+ case AuBrid_UUID: -+ err = snprintf(p, sz, "%pU", brid->uuid.b); -+ break; -+ case AuBrid_FSID: -+ err = snprintf(p, sz, "%08x-%08x", -+ brid->fsid.val[0], brid->fsid.val[1]); -+ break; -+ case AuBrid_DEV: -+ major = MAJOR(brid->dev); -+ minor = MINOR(brid->dev); -+ if (major <= 0xff && minor <= 0xff) -+ err = snprintf(p, sz, "%02x%02x", major, minor); -+ else -+ err = snprintf(p, sz, "%03x:%05x", major, minor); -+ break; -+ } -+ AuDebugOn(err > sz); -+ p += err; -+ sz -= err; -+ err = snprintf(p, sz, "_%llu", (unsigned long long)h_inode->i_ino); -+ AuDebugOn(err > sz); -+ p += err; -+ sz -= err; -+ -+ return p - buf; -+} -+ -+static int au_drinfo_name(struct au_branch *br, char *name, int len) -+{ -+ int rlen; -+ struct dentry *br_dentry; -+ struct inode *br_inode; -+ -+ br_dentry = au_br_dentry(br); -+ br_inode = d_inode(br_dentry); -+ rlen = au_brid_str(&br->br_dirren.dr_brid, br_inode, name, len); -+ AuDebugOn(rlen >= AUFS_DIRREN_ENV_VAL_SZ); -+ AuDebugOn(rlen > len); -+ -+ return rlen; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * from the given @h_dentry, construct drinfo at @*fdata. -+ * when the size of @*fdata is not enough, reallocate and return new @fdata and -+ * @allocated. -+ */ -+static int au_drinfo_construct(struct au_drinfo_fdata **fdata, -+ struct dentry *h_dentry, -+ unsigned char *allocated) -+{ -+ int err, v; -+ struct au_drinfo_fdata *f, *p; -+ struct au_drinfo *drinfo; -+ struct inode *h_inode; -+ struct qstr *qname; -+ -+ err = 0; -+ f = *fdata; -+ h_inode = d_inode(h_dentry); -+ qname = &h_dentry->d_name; -+ drinfo = &f->drinfo; -+ drinfo->ino = (__force uint64_t)cpu_to_be64(h_inode->i_ino); -+ drinfo->oldnamelen = qname->len; -+ if (*allocated < sizeof(*f) + qname->len) { -+ v = roundup_pow_of_two(*allocated + qname->len); -+ p = au_krealloc(f, v, GFP_NOFS, /*may_shrink*/0); -+ if (unlikely(!p)) { -+ err = -ENOMEM; -+ AuTraceErr(err); -+ goto out; -+ } -+ f = p; -+ *fdata = f; -+ *allocated = v; -+ drinfo = &f->drinfo; -+ } -+ memcpy(drinfo->oldname, qname->name, qname->len); -+ AuDbg("i%llu, %.*s\n", -+ be64_to_cpu((__force __be64)drinfo->ino), drinfo->oldnamelen, -+ drinfo->oldname); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* callers have to free the return value */ -+static struct au_drinfo *au_drinfo_read_k(struct file *file, ino_t h_ino) -+{ -+ struct au_drinfo *ret, *drinfo; -+ struct au_drinfo_fdata fdata; -+ int len; -+ loff_t pos; -+ ssize_t ssz; -+ -+ ret = ERR_PTR(-EIO); -+ pos = 0; -+ ssz = vfsub_read_k(file, &fdata, sizeof(fdata), &pos); -+ if (unlikely(ssz != sizeof(fdata))) { -+ AuIOErr("ssz %zd, %u, %pD2\n", -+ ssz, (unsigned int)sizeof(fdata), file); -+ goto out; -+ } -+ -+ fdata.magic = ntohl((__force __be32)fdata.magic); -+ switch (fdata.magic) { -+ case AUFS_DRINFO_MAGIC_V1: -+ break; -+ default: -+ AuIOErr("magic-num 0x%x, 0x%x, %pD2\n", -+ fdata.magic, AUFS_DRINFO_MAGIC_V1, file); -+ goto out; -+ } -+ -+ drinfo = &fdata.drinfo; -+ len = drinfo->oldnamelen; -+ if (!len) { -+ AuIOErr("broken drinfo %pD2\n", file); -+ goto out; -+ } -+ -+ ret = NULL; -+ drinfo->ino = be64_to_cpu((__force __be64)drinfo->ino); -+ if (unlikely(h_ino && drinfo->ino != h_ino)) { -+ AuDbg("ignored i%llu, i%llu, %pD2\n", -+ (unsigned long long)drinfo->ino, -+ (unsigned long long)h_ino, file); -+ goto out; /* success */ -+ } -+ -+ ret = kmalloc(sizeof(*ret) + len, GFP_NOFS); -+ if (unlikely(!ret)) { -+ ret = ERR_PTR(-ENOMEM); -+ AuTraceErrPtr(ret); -+ goto out; -+ } -+ -+ *ret = *drinfo; -+ ssz = vfsub_read_k(file, (void *)ret->oldname, len, &pos); -+ if (unlikely(ssz != len)) { -+ kfree(ret); -+ ret = ERR_PTR(-EIO); -+ AuIOErr("ssz %zd, %u, %pD2\n", ssz, len, file); -+ goto out; -+ } -+ -+ AuDbg("oldname %.*s\n", ret->oldnamelen, ret->oldname); -+ -+out: -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* in order to be revertible */ -+struct au_drinfo_rev_elm { -+ int created; -+ struct dentry *info_dentry; -+ struct au_drinfo *info_last; -+}; -+ -+struct au_drinfo_rev { -+ unsigned char already; -+ aufs_bindex_t nelm; -+ struct au_drinfo_rev_elm elm[0]; -+}; -+ -+/* todo: isn't it too large? */ -+struct au_drinfo_store { -+ struct path h_ppath; -+ struct dentry *h_dentry; -+ struct au_drinfo_fdata *fdata; -+ char *infoname; /* inside of whname, just after PFX */ -+ char whname[sizeof(AUFS_WH_DR_INFO_PFX) + AUFS_DIRREN_ENV_VAL_SZ]; -+ aufs_bindex_t btgt, btail; -+ unsigned char no_sio, -+ allocated, /* current size of *fdata */ -+ infonamelen, /* room size for p */ -+ whnamelen, /* length of the generated name */ -+ renameback; /* renamed back */ -+}; -+ -+/* on rename(2) error, the caller should revert it using @elm */ -+static int au_drinfo_do_store(struct au_drinfo_store *w, -+ struct au_drinfo_rev_elm *elm) -+{ -+ int err, len; -+ ssize_t ssz; -+ loff_t pos; -+ struct path infopath = { -+ .mnt = w->h_ppath.mnt -+ }; -+ struct inode *h_dir, *h_inode, *delegated; -+ struct file *infofile; -+ struct qstr *qname; -+ -+ AuDebugOn(elm -+ && memcmp(elm, page_address(ZERO_PAGE(0)), sizeof(*elm))); -+ -+ infopath.dentry = vfsub_lookup_one_len(w->whname, w->h_ppath.dentry, -+ w->whnamelen); -+ AuTraceErrPtr(infopath.dentry); -+ if (IS_ERR(infopath.dentry)) { -+ err = PTR_ERR(infopath.dentry); -+ goto out; -+ } -+ -+ err = 0; -+ h_dir = d_inode(w->h_ppath.dentry); -+ if (elm && d_is_negative(infopath.dentry)) { -+ err = vfsub_create(h_dir, &infopath, 0600, /*want_excl*/true); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out_dput; -+ elm->created = 1; -+ elm->info_dentry = dget(infopath.dentry); -+ } -+ -+ infofile = vfsub_dentry_open(&infopath, O_RDWR); -+ AuTraceErrPtr(infofile); -+ if (IS_ERR(infofile)) { -+ err = PTR_ERR(infofile); -+ goto out_dput; -+ } -+ -+ h_inode = d_inode(infopath.dentry); -+ if (elm && i_size_read(h_inode)) { -+ h_inode = d_inode(w->h_dentry); -+ elm->info_last = au_drinfo_read_k(infofile, h_inode->i_ino); -+ AuTraceErrPtr(elm->info_last); -+ if (IS_ERR(elm->info_last)) { -+ err = PTR_ERR(elm->info_last); -+ elm->info_last = NULL; -+ AuDebugOn(elm->info_dentry); -+ goto out_fput; -+ } -+ } -+ -+ if (elm && w->renameback) { -+ delegated = NULL; -+ err = vfsub_unlink(h_dir, &infopath, &delegated, /*force*/0); -+ AuTraceErr(err); -+ if (unlikely(err == -EWOULDBLOCK)) -+ iput(delegated); -+ goto out_fput; -+ } -+ -+ pos = 0; -+ qname = &w->h_dentry->d_name; -+ len = sizeof(*w->fdata) + qname->len; -+ if (!elm) -+ len = sizeof(*w->fdata) + w->fdata->drinfo.oldnamelen; -+ ssz = vfsub_write_k(infofile, w->fdata, len, &pos); -+ if (ssz == len) { -+ AuDbg("hi%llu, %.*s\n", w->fdata->drinfo.ino, -+ w->fdata->drinfo.oldnamelen, w->fdata->drinfo.oldname); -+ goto out_fput; /* success */ -+ } else { -+ err = -EIO; -+ if (ssz < 0) -+ err = ssz; -+ /* the caller should revert it using @elm */ -+ } -+ -+out_fput: -+ fput(infofile); -+out_dput: -+ dput(infopath.dentry); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+struct au_call_drinfo_do_store_args { -+ int *errp; -+ struct au_drinfo_store *w; -+ struct au_drinfo_rev_elm *elm; -+}; -+ -+static void au_call_drinfo_do_store(void *args) -+{ -+ struct au_call_drinfo_do_store_args *a = args; -+ -+ *a->errp = au_drinfo_do_store(a->w, a->elm); -+} -+ -+static int au_drinfo_store_sio(struct au_drinfo_store *w, -+ struct au_drinfo_rev_elm *elm) -+{ -+ int err, wkq_err; -+ -+ if (w->no_sio) -+ err = au_drinfo_do_store(w, elm); -+ else { -+ struct au_call_drinfo_do_store_args a = { -+ .errp = &err, -+ .w = w, -+ .elm = elm -+ }; -+ wkq_err = au_wkq_wait(au_call_drinfo_do_store, &a); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ AuTraceErr(err); -+ -+ return err; -+} -+ -+static int au_drinfo_store_work_init(struct au_drinfo_store *w, -+ aufs_bindex_t btgt) -+{ -+ int err; -+ -+ memset(w, 0, sizeof(*w)); -+ w->allocated = roundup_pow_of_two(sizeof(*w->fdata) + 40); -+ strcpy(w->whname, AUFS_WH_DR_INFO_PFX); -+ w->infoname = w->whname + sizeof(AUFS_WH_DR_INFO_PFX) - 1; -+ w->infonamelen = sizeof(w->whname) - sizeof(AUFS_WH_DR_INFO_PFX); -+ w->btgt = btgt; -+ w->no_sio = !!uid_eq(current_fsuid(), GLOBAL_ROOT_UID); -+ -+ err = -ENOMEM; -+ w->fdata = kcalloc(1, w->allocated, GFP_NOFS); -+ if (unlikely(!w->fdata)) { -+ AuTraceErr(err); -+ goto out; -+ } -+ w->fdata->magic = (__force uint32_t)htonl(AUFS_DRINFO_MAGIC_V1); -+ err = 0; -+ -+out: -+ return err; -+} -+ -+static void au_drinfo_store_work_fin(struct au_drinfo_store *w) -+{ -+ kfree(w->fdata); -+} -+ -+static void au_drinfo_store_rev(struct au_drinfo_rev *rev, -+ struct au_drinfo_store *w) -+{ -+ struct au_drinfo_rev_elm *elm; -+ struct inode *h_dir, *delegated; -+ int err, nelm; -+ struct path infopath = { -+ .mnt = w->h_ppath.mnt -+ }; -+ -+ h_dir = d_inode(w->h_ppath.dentry); -+ IMustLock(h_dir); -+ -+ err = 0; -+ elm = rev->elm; -+ for (nelm = rev->nelm; nelm > 0; nelm--, elm++) { -+ AuDebugOn(elm->created && elm->info_last); -+ if (elm->created) { -+ AuDbg("here\n"); -+ delegated = NULL; -+ infopath.dentry = elm->info_dentry; -+ err = vfsub_unlink(h_dir, &infopath, &delegated, -+ !w->no_sio); -+ AuTraceErr(err); -+ if (unlikely(err == -EWOULDBLOCK)) -+ iput(delegated); -+ dput(elm->info_dentry); -+ } else if (elm->info_last) { -+ AuDbg("here\n"); -+ w->fdata->drinfo = *elm->info_last; -+ memcpy(w->fdata->drinfo.oldname, -+ elm->info_last->oldname, -+ elm->info_last->oldnamelen); -+ err = au_drinfo_store_sio(w, /*elm*/NULL); -+ kfree(elm->info_last); -+ } -+ if (unlikely(err)) -+ AuIOErr("%d, %s\n", err, w->whname); -+ /* go on even if err */ -+ } -+} -+ -+/* caller has to call au_dr_rename_fin() later */ -+static int au_drinfo_store(struct dentry *dentry, aufs_bindex_t btgt, -+ struct qstr *dst_name, void *_rev) -+{ -+ int err, sz, nelm; -+ aufs_bindex_t bindex, btail; -+ struct au_drinfo_store work; -+ struct au_drinfo_rev *rev, **p; -+ struct au_drinfo_rev_elm *elm; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_hinode *hdir; -+ -+ err = au_drinfo_store_work_init(&work, btgt); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out; -+ -+ err = -ENOMEM; -+ btail = au_dbtaildir(dentry); -+ nelm = btail - btgt; -+ sz = sizeof(*rev) + sizeof(*elm) * nelm; -+ rev = kcalloc(1, sz, GFP_NOFS); -+ if (unlikely(!rev)) { -+ AuTraceErr(err); -+ goto out_args; -+ } -+ rev->nelm = nelm; -+ elm = rev->elm; -+ p = _rev; -+ *p = rev; -+ -+ err = 0; -+ sb = dentry->d_sb; -+ work.h_ppath.dentry = au_h_dptr(dentry, btgt); -+ work.h_ppath.mnt = au_sbr_mnt(sb, btgt); -+ hdir = au_hi(d_inode(dentry), btgt); -+ au_hn_inode_lock_nested(hdir, AuLsc_I_CHILD); -+ for (bindex = btgt + 1; bindex <= btail; bindex++, elm++) { -+ work.h_dentry = au_h_dptr(dentry, bindex); -+ if (!work.h_dentry) -+ continue; -+ -+ err = au_drinfo_construct(&work.fdata, work.h_dentry, -+ &work.allocated); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ break; -+ -+ work.renameback = au_qstreq(&work.h_dentry->d_name, dst_name); -+ br = au_sbr(sb, bindex); -+ work.whnamelen = sizeof(AUFS_WH_DR_INFO_PFX) - 1; -+ work.whnamelen += au_drinfo_name(br, work.infoname, -+ work.infonamelen); -+ AuDbg("whname %.*s, i%llu, %.*s\n", -+ work.whnamelen, work.whname, -+ be64_to_cpu((__force __be64)work.fdata->drinfo.ino), -+ work.fdata->drinfo.oldnamelen, -+ work.fdata->drinfo.oldname); -+ -+ err = au_drinfo_store_sio(&work, elm); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ break; -+ } -+ if (unlikely(err)) { -+ /* revert all drinfo */ -+ au_drinfo_store_rev(rev, &work); -+ kfree(rev); -+ *p = NULL; -+ } -+ au_hn_inode_unlock(hdir); -+ -+out_args: -+ au_drinfo_store_work_fin(&work); -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_dr_rename(struct dentry *src, aufs_bindex_t bindex, -+ struct qstr *dst_name, void *_rev) -+{ -+ int err, already; -+ ino_t ino; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_dr_br *dr; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ struct au_dr_hino *ent; -+ struct au_drinfo_rev *rev, **p; -+ -+ AuDbg("bindex %d\n", bindex); -+ -+ err = -ENOMEM; -+ ent = kmalloc(sizeof(*ent), GFP_NOFS); -+ if (unlikely(!ent)) -+ goto out; -+ -+ sb = src->d_sb; -+ br = au_sbr(sb, bindex); -+ dr = &br->br_dirren; -+ h_dentry = au_h_dptr(src, bindex); -+ h_inode = d_inode(h_dentry); -+ ino = h_inode->i_ino; -+ ent->dr_h_ino = ino; -+ already = au_dr_hino_test_add(dr, ino, ent); -+ AuDbg("b%d, hi%llu, already %d\n", -+ bindex, (unsigned long long)ino, already); -+ -+ err = au_drinfo_store(src, bindex, dst_name, _rev); -+ AuTraceErr(err); -+ if (!err) { -+ p = _rev; -+ rev = *p; -+ rev->already = already; -+ goto out; /* success */ -+ } -+ -+ /* revert */ -+ if (!already) -+ au_dr_hino_del(dr, ent); -+ kfree(ent); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_dr_rename_fin(struct dentry *src, aufs_bindex_t btgt, void *_rev) -+{ -+ struct au_drinfo_rev *rev; -+ struct au_drinfo_rev_elm *elm; -+ int nelm; -+ -+ rev = _rev; -+ elm = rev->elm; -+ for (nelm = rev->nelm; nelm > 0; nelm--, elm++) { -+ dput(elm->info_dentry); -+ kfree(elm->info_last); -+ } -+ kfree(rev); -+} -+ -+void au_dr_rename_rev(struct dentry *src, aufs_bindex_t btgt, void *_rev) -+{ -+ int err; -+ struct au_drinfo_store work; -+ struct au_drinfo_rev *rev = _rev; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct inode *h_inode; -+ struct au_dr_br *dr; -+ struct au_dr_hino *ent; -+ -+ err = au_drinfo_store_work_init(&work, btgt); -+ if (unlikely(err)) -+ goto out; -+ -+ sb = src->d_sb; -+ br = au_sbr(sb, btgt); -+ work.h_ppath.dentry = au_h_dptr(src, btgt); -+ work.h_ppath.mnt = au_br_mnt(br); -+ au_drinfo_store_rev(rev, &work); -+ au_drinfo_store_work_fin(&work); -+ if (rev->already) -+ goto out; -+ -+ dr = &br->br_dirren; -+ h_inode = d_inode(work.h_ppath.dentry); -+ ent = au_dr_hino_find(dr, h_inode->i_ino); -+ BUG_ON(!ent); -+ au_dr_hino_del(dr, ent); -+ kfree(ent); -+ -+out: -+ kfree(rev); -+ if (unlikely(err)) -+ pr_err("failed to remove dirren info\n"); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct au_drinfo *au_drinfo_do_load(struct path *h_ppath, -+ char *whname, int whnamelen, -+ struct dentry **info_dentry) -+{ -+ struct au_drinfo *drinfo; -+ struct file *f; -+ struct inode *h_dir; -+ struct path infopath; -+ int unlocked; -+ -+ AuDbg("%pd/%.*s\n", h_ppath->dentry, whnamelen, whname); -+ -+ *info_dentry = NULL; -+ drinfo = NULL; -+ unlocked = 0; -+ h_dir = d_inode(h_ppath->dentry); -+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT); -+ infopath.dentry = vfsub_lookup_one_len(whname, h_ppath->dentry, -+ whnamelen); -+ if (IS_ERR(infopath.dentry)) { -+ drinfo = (void *)infopath.dentry; -+ goto out; -+ } -+ -+ if (d_is_negative(infopath.dentry)) -+ goto out_dput; /* success */ -+ -+ infopath.mnt = h_ppath->mnt; -+ f = vfsub_dentry_open(&infopath, O_RDONLY); -+ inode_unlock_shared(h_dir); -+ unlocked = 1; -+ if (IS_ERR(f)) { -+ drinfo = (void *)f; -+ goto out_dput; -+ } -+ -+ drinfo = au_drinfo_read_k(f, /*h_ino*/0); -+ if (IS_ERR_OR_NULL(drinfo)) -+ goto out_fput; -+ -+ AuDbg("oldname %.*s\n", drinfo->oldnamelen, drinfo->oldname); -+ *info_dentry = dget(infopath.dentry); /* keep it alive */ -+ -+out_fput: -+ fput(f); -+out_dput: -+ dput(infopath.dentry); -+out: -+ if (!unlocked) -+ inode_unlock_shared(h_dir); -+ AuTraceErrPtr(drinfo); -+ return drinfo; -+} -+ -+struct au_drinfo_do_load_args { -+ struct au_drinfo **drinfop; -+ struct path *h_ppath; -+ char *whname; -+ int whnamelen; -+ struct dentry **info_dentry; -+}; -+ -+static void au_call_drinfo_do_load(void *args) -+{ -+ struct au_drinfo_do_load_args *a = args; -+ -+ *a->drinfop = au_drinfo_do_load(a->h_ppath, a->whname, a->whnamelen, -+ a->info_dentry); -+} -+ -+struct au_drinfo_load { -+ struct path h_ppath; -+ struct qstr *qname; -+ unsigned char no_sio; -+ -+ aufs_bindex_t ninfo; -+ struct au_drinfo **drinfo; -+}; -+ -+static int au_drinfo_load(struct au_drinfo_load *w, aufs_bindex_t bindex, -+ struct au_branch *br) -+{ -+ int err, wkq_err, whnamelen, e; -+ char whname[sizeof(AUFS_WH_DR_INFO_PFX) + AUFS_DIRREN_ENV_VAL_SZ] -+ = AUFS_WH_DR_INFO_PFX; -+ struct au_drinfo *drinfo; -+ struct qstr oldname; -+ struct inode *h_dir, *delegated; -+ struct dentry *info_dentry; -+ struct path infopath; -+ -+ whnamelen = sizeof(AUFS_WH_DR_INFO_PFX) - 1; -+ whnamelen += au_drinfo_name(br, whname + whnamelen, -+ sizeof(whname) - whnamelen); -+ if (w->no_sio) -+ drinfo = au_drinfo_do_load(&w->h_ppath, whname, whnamelen, -+ &info_dentry); -+ else { -+ struct au_drinfo_do_load_args args = { -+ .drinfop = &drinfo, -+ .h_ppath = &w->h_ppath, -+ .whname = whname, -+ .whnamelen = whnamelen, -+ .info_dentry = &info_dentry -+ }; -+ wkq_err = au_wkq_wait(au_call_drinfo_do_load, &args); -+ if (unlikely(wkq_err)) -+ drinfo = ERR_PTR(wkq_err); -+ } -+ err = PTR_ERR(drinfo); -+ if (IS_ERR_OR_NULL(drinfo)) -+ goto out; -+ -+ err = 0; -+ oldname.len = drinfo->oldnamelen; -+ oldname.name = drinfo->oldname; -+ if (au_qstreq(w->qname, &oldname)) { -+ /* the name is renamed back */ -+ kfree(drinfo); -+ drinfo = NULL; -+ -+ infopath.dentry = info_dentry; -+ infopath.mnt = w->h_ppath.mnt; -+ h_dir = d_inode(w->h_ppath.dentry); -+ delegated = NULL; -+ inode_lock_nested(h_dir, AuLsc_I_PARENT); -+ e = vfsub_unlink(h_dir, &infopath, &delegated, !w->no_sio); -+ inode_unlock(h_dir); -+ if (unlikely(e)) -+ AuIOErr("ignored %d, %pd2\n", e, &infopath.dentry); -+ if (unlikely(e == -EWOULDBLOCK)) -+ iput(delegated); -+ } -+ kfree(w->drinfo[bindex]); -+ w->drinfo[bindex] = drinfo; -+ dput(info_dentry); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_dr_lkup_free(struct au_drinfo **drinfo, int n) -+{ -+ struct au_drinfo **p = drinfo; -+ -+ while (n-- > 0) -+ kfree(*drinfo++); -+ kfree(p); -+} -+ -+int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry, -+ aufs_bindex_t btgt) -+{ -+ int err, ninfo; -+ struct au_drinfo_load w; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ struct inode *h_dir; -+ struct au_dr_hino *ent; -+ struct super_block *sb; -+ -+ AuDbg("%.*s, name %.*s, whname %.*s, b%d\n", -+ AuLNPair(&dentry->d_name), AuLNPair(&lkup->dirren.dr_name), -+ AuLNPair(&lkup->whname), btgt); -+ -+ sb = dentry->d_sb; -+ bbot = au_sbbot(sb); -+ w.ninfo = bbot + 1; -+ if (!lkup->dirren.drinfo) { -+ lkup->dirren.drinfo = kcalloc(w.ninfo, -+ sizeof(*lkup->dirren.drinfo), -+ GFP_NOFS); -+ if (unlikely(!lkup->dirren.drinfo)) { -+ err = -ENOMEM; -+ goto out; -+ } -+ lkup->dirren.ninfo = w.ninfo; -+ } -+ w.drinfo = lkup->dirren.drinfo; -+ w.no_sio = !!uid_eq(current_fsuid(), GLOBAL_ROOT_UID); -+ w.h_ppath.dentry = au_h_dptr(dentry, btgt); -+ AuDebugOn(!w.h_ppath.dentry); -+ w.h_ppath.mnt = au_sbr_mnt(sb, btgt); -+ w.qname = &dentry->d_name; -+ -+ ninfo = 0; -+ for (bindex = btgt + 1; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ err = au_drinfo_load(&w, bindex, br); -+ if (unlikely(err)) -+ goto out_free; -+ if (w.drinfo[bindex]) -+ ninfo++; -+ } -+ if (!ninfo) { -+ br = au_sbr(sb, btgt); -+ h_dir = d_inode(w.h_ppath.dentry); -+ ent = au_dr_hino_find(&br->br_dirren, h_dir->i_ino); -+ AuDebugOn(!ent); -+ au_dr_hino_del(&br->br_dirren, ent); -+ kfree(ent); -+ } -+ goto out; /* success */ -+ -+out_free: -+ au_dr_lkup_free(lkup->dirren.drinfo, lkup->dirren.ninfo); -+ lkup->dirren.ninfo = 0; -+ lkup->dirren.drinfo = NULL; -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_dr_lkup_fin(struct au_do_lookup_args *lkup) -+{ -+ au_dr_lkup_free(lkup->dirren.drinfo, lkup->dirren.ninfo); -+} -+ -+int au_dr_lkup_name(struct au_do_lookup_args *lkup, aufs_bindex_t btgt) -+{ -+ int err; -+ struct au_drinfo *drinfo; -+ -+ err = 0; -+ if (!lkup->dirren.drinfo) -+ goto out; -+ AuDebugOn(lkup->dirren.ninfo < btgt + 1); -+ drinfo = lkup->dirren.drinfo[btgt + 1]; -+ if (!drinfo) -+ goto out; -+ -+ kfree(lkup->whname.name); -+ lkup->whname.name = NULL; -+ lkup->dirren.dr_name.len = drinfo->oldnamelen; -+ lkup->dirren.dr_name.name = drinfo->oldname; -+ lkup->name = &lkup->dirren.dr_name; -+ err = au_wh_name_alloc(&lkup->whname, lkup->name); -+ if (!err) -+ AuDbg("name %.*s, whname %.*s, b%d\n", -+ AuLNPair(lkup->name), AuLNPair(&lkup->whname), -+ btgt); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex, -+ ino_t h_ino) -+{ -+ int match; -+ struct au_drinfo *drinfo; -+ -+ match = 1; -+ if (!lkup->dirren.drinfo) -+ goto out; -+ AuDebugOn(lkup->dirren.ninfo < bindex + 1); -+ drinfo = lkup->dirren.drinfo[bindex + 1]; -+ if (!drinfo) -+ goto out; -+ -+ match = (drinfo->ino == h_ino); -+ AuDbg("match %d\n", match); -+ -+out: -+ return match; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_dr_opt_set(struct super_block *sb) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ err = 0; -+ bbot = au_sbbot(sb); -+ for (bindex = 0; !err && bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ err = au_dr_hino(sb, bindex, /*br*/NULL, &br->br_path); -+ } -+ -+ return err; -+} -+ -+int au_dr_opt_flush(struct super_block *sb) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ err = 0; -+ bbot = au_sbbot(sb); -+ for (bindex = 0; !err && bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_writable(br->br_perm)) -+ err = au_dr_hino(sb, bindex, /*br*/NULL, /*path*/NULL); -+ } -+ -+ return err; -+} -+ -+int au_dr_opt_clr(struct super_block *sb, int no_flush) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ err = 0; -+ if (!no_flush) { -+ err = au_dr_opt_flush(sb); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ au_dr_hino_free(&br->br_dirren); -+ } -+ -+out: -+ return err; -+} -diff --git a/fs/aufs/dirren.h b/fs/aufs/dirren.h -new file mode 100644 -index 000000000..f5139a30c ---- /dev/null -+++ b/fs/aufs/dirren.h -@@ -0,0 +1,140 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2017-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * renamed dir info -+ */ -+ -+#ifndef __AUFS_DIRREN_H__ -+#define __AUFS_DIRREN_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include "hbl.h" -+ -+#define AuDirren_NHASH 100 -+ -+#ifdef CONFIG_AUFS_DIRREN -+enum au_brid_type { -+ AuBrid_Unset, -+ AuBrid_UUID, -+ AuBrid_FSID, -+ AuBrid_DEV -+}; -+ -+struct au_dr_brid { -+ enum au_brid_type type; -+ union { -+ uuid_t uuid; /* unimplemented yet */ -+ fsid_t fsid; -+ dev_t dev; -+ }; -+}; -+ -+/* 20 is the max digits length of ulong 64 */ -+/* brid-type "_" uuid "_" inum */ -+#define AUFS_DIRREN_FNAME_SZ (1 + 1 + UUID_STRING_LEN + 20) -+#define AUFS_DIRREN_ENV_VAL_SZ (AUFS_DIRREN_FNAME_SZ + 1 + 20) -+ -+struct au_dr_hino { -+ struct hlist_bl_node dr_hnode; -+ ino_t dr_h_ino; -+}; -+ -+struct au_dr_br { -+ struct hlist_bl_head dr_h_ino[AuDirren_NHASH]; -+ struct au_dr_brid dr_brid; -+}; -+ -+struct au_dr_lookup { -+ /* dr_name is pointed by struct au_do_lookup_args.name */ -+ struct qstr dr_name; /* subset of dr_info */ -+ aufs_bindex_t ninfo; -+ struct au_drinfo **drinfo; -+}; -+#else -+struct au_dr_hino; -+/* empty */ -+struct au_dr_br { }; -+struct au_dr_lookup { }; -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_branch; -+struct au_do_lookup_args; -+struct au_hinode; -+#ifdef CONFIG_AUFS_DIRREN -+int au_dr_hino_test_add(struct au_dr_br *dr, ino_t h_ino, -+ struct au_dr_hino *add_ent); -+void au_dr_hino_free(struct au_dr_br *dr); -+int au_dr_br_init(struct super_block *sb, struct au_branch *br, -+ const struct path *path); -+int au_dr_br_fin(struct super_block *sb, struct au_branch *br); -+int au_dr_rename(struct dentry *src, aufs_bindex_t bindex, -+ struct qstr *dst_name, void *_rev); -+void au_dr_rename_fin(struct dentry *src, aufs_bindex_t btgt, void *rev); -+void au_dr_rename_rev(struct dentry *src, aufs_bindex_t bindex, void *rev); -+int au_dr_lkup(struct au_do_lookup_args *lkup, struct dentry *dentry, -+ aufs_bindex_t bindex); -+int au_dr_lkup_name(struct au_do_lookup_args *lkup, aufs_bindex_t btgt); -+int au_dr_lkup_h_ino(struct au_do_lookup_args *lkup, aufs_bindex_t bindex, -+ ino_t h_ino); -+void au_dr_lkup_fin(struct au_do_lookup_args *lkup); -+int au_dr_opt_set(struct super_block *sb); -+int au_dr_opt_flush(struct super_block *sb); -+int au_dr_opt_clr(struct super_block *sb, int no_flush); -+#else -+AuStubInt0(au_dr_hino_test_add, struct au_dr_br *dr, ino_t h_ino, -+ struct au_dr_hino *add_ent); -+AuStubVoid(au_dr_hino_free, struct au_dr_br *dr); -+AuStubInt0(au_dr_br_init, struct super_block *sb, struct au_branch *br, -+ const struct path *path); -+AuStubInt0(au_dr_br_fin, struct super_block *sb, struct au_branch *br); -+AuStubInt0(au_dr_rename, struct dentry *src, aufs_bindex_t bindex, -+ struct qstr *dst_name, void *_rev); -+AuStubVoid(au_dr_rename_fin, struct dentry *src, aufs_bindex_t btgt, void *rev); -+AuStubVoid(au_dr_rename_rev, struct dentry *src, aufs_bindex_t bindex, -+ void *rev); -+AuStubInt0(au_dr_lkup, struct au_do_lookup_args *lkup, struct dentry *dentry, -+ aufs_bindex_t bindex); -+AuStubInt0(au_dr_lkup_name, struct au_do_lookup_args *lkup, aufs_bindex_t btgt); -+AuStubInt0(au_dr_lkup_h_ino, struct au_do_lookup_args *lkup, -+ aufs_bindex_t bindex, ino_t h_ino); -+AuStubVoid(au_dr_lkup_fin, struct au_do_lookup_args *lkup); -+AuStubInt0(au_dr_opt_set, struct super_block *sb); -+AuStubInt0(au_dr_opt_flush, struct super_block *sb); -+AuStubInt0(au_dr_opt_clr, struct super_block *sb, int no_flush); -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_DIRREN -+static inline int au_dr_ihash(ino_t h_ino) -+{ -+ return h_ino % AuDirren_NHASH; -+} -+#else -+AuStubInt0(au_dr_ihash, ino_t h_ino); -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DIRREN_H__ */ -diff --git a/fs/aufs/dynop.c b/fs/aufs/dynop.c -new file mode 100644 -index 000000000..f2ff9f3ab ---- /dev/null -+++ b/fs/aufs/dynop.c -@@ -0,0 +1,370 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2010-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * dynamically customizable operations for regular files -+ */ -+ -+#include "aufs.h" -+ -+#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop) -+ -+/* -+ * How large will these lists be? -+ * Usually just a few elements, 20-30 at most for each, I guess. -+ */ -+static struct hlist_bl_head dynop[AuDyLast]; -+ -+static struct au_dykey *dy_gfind_get(struct hlist_bl_head *hbl, -+ const void *h_op) -+{ -+ struct au_dykey *key, *tmp; -+ struct hlist_bl_node *pos; -+ -+ key = NULL; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(tmp, pos, hbl, dk_hnode) -+ if (tmp->dk_op.dy_hop == h_op) { -+ key = tmp; -+ kref_get(&key->dk_kref); -+ break; -+ } -+ hlist_bl_unlock(hbl); -+ -+ return key; -+} -+ -+static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key) -+{ -+ struct au_dykey **k, *found; -+ const void *h_op = key->dk_op.dy_hop; -+ int i; -+ -+ found = NULL; -+ k = br->br_dykey; -+ for (i = 0; i < AuBrDynOp; i++) -+ if (k[i]) { -+ if (k[i]->dk_op.dy_hop == h_op) { -+ found = k[i]; -+ break; -+ } -+ } else -+ break; -+ if (!found) { -+ spin_lock(&br->br_dykey_lock); -+ for (; i < AuBrDynOp; i++) -+ if (k[i]) { -+ if (k[i]->dk_op.dy_hop == h_op) { -+ found = k[i]; -+ break; -+ } -+ } else { -+ k[i] = key; -+ break; -+ } -+ spin_unlock(&br->br_dykey_lock); -+ BUG_ON(i == AuBrDynOp); /* expand the array */ -+ } -+ -+ return found; -+} -+ -+/* kref_get() if @key is already added */ -+static struct au_dykey *dy_gadd(struct hlist_bl_head *hbl, struct au_dykey *key) -+{ -+ struct au_dykey *tmp, *found; -+ struct hlist_bl_node *pos; -+ const void *h_op = key->dk_op.dy_hop; -+ -+ found = NULL; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(tmp, pos, hbl, dk_hnode) -+ if (tmp->dk_op.dy_hop == h_op) { -+ kref_get(&tmp->dk_kref); -+ found = tmp; -+ break; -+ } -+ if (!found) -+ hlist_bl_add_head(&key->dk_hnode, hbl); -+ hlist_bl_unlock(hbl); -+ -+ if (!found) -+ DyPrSym(key); -+ return found; -+} -+ -+static void dy_free_rcu(struct rcu_head *rcu) -+{ -+ struct au_dykey *key; -+ -+ key = container_of(rcu, struct au_dykey, dk_rcu); -+ DyPrSym(key); -+ kfree(key); -+} -+ -+static void dy_free(struct kref *kref) -+{ -+ struct au_dykey *key; -+ struct hlist_bl_head *hbl; -+ -+ key = container_of(kref, struct au_dykey, dk_kref); -+ hbl = dynop + key->dk_op.dy_type; -+ au_hbl_del(&key->dk_hnode, hbl); -+ call_rcu(&key->dk_rcu, dy_free_rcu); -+} -+ -+void au_dy_put(struct au_dykey *key) -+{ -+ kref_put(&key->dk_kref, dy_free); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *)) -+ -+#ifdef CONFIG_AUFS_DEBUG -+#define DyDbgDeclare(cnt) unsigned int cnt = 0 -+#define DyDbgInc(cnt) do { cnt++; } while (0) -+#else -+#define DyDbgDeclare(cnt) do {} while (0) -+#define DyDbgInc(cnt) do {} while (0) -+#endif -+ -+#define DySet(func, dst, src, h_op, h_sb) do { \ -+ DyDbgInc(cnt); \ -+ if (h_op->func) { \ -+ if (src.func) \ -+ dst.func = src.func; \ -+ else \ -+ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \ -+ } \ -+} while (0) -+ -+#define DySetForce(func, dst, src) do { \ -+ AuDebugOn(!src.func); \ -+ DyDbgInc(cnt); \ -+ dst.func = src.func; \ -+} while (0) -+ -+#define DySetAop(func) \ -+ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb) -+#define DySetAopForce(func) \ -+ DySetForce(func, dyaop->da_op, aufs_aop) -+ -+static void dy_aop(struct au_dykey *key, const void *h_op, -+ struct super_block *h_sb __maybe_unused) -+{ -+ struct au_dyaop *dyaop = (void *)key; -+ const struct address_space_operations *h_aop = h_op; -+ DyDbgDeclare(cnt); -+ -+ AuDbg("%s\n", au_sbtype(h_sb)); -+ -+ DySetAop(writepage); -+ DySetAopForce(readpage); /* force */ -+ DySetAop(writepages); -+ DySetAop(set_page_dirty); -+ DySetAop(readpages); -+ DySetAop(write_begin); -+ DySetAop(write_end); -+ DySetAop(bmap); -+ DySetAop(invalidatepage); -+ DySetAop(releasepage); -+ DySetAop(freepage); -+ /* this one will be changed according to an aufs mount option */ -+ DySetAop(direct_IO); -+ DySetAop(migratepage); -+ DySetAop(isolate_page); -+ DySetAop(putback_page); -+ DySetAop(launder_page); -+ DySetAop(is_partially_uptodate); -+ DySetAop(is_dirty_writeback); -+ DySetAop(error_remove_page); -+ DySetAop(swap_activate); -+ DySetAop(swap_deactivate); -+ -+ DyDbgSize(cnt, *h_aop); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void dy_bug(struct kref *kref) -+{ -+ BUG(); -+} -+ -+static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br) -+{ -+ struct au_dykey *key, *old; -+ struct hlist_bl_head *hbl; -+ struct op { -+ unsigned int sz; -+ void (*set)(struct au_dykey *key, const void *h_op, -+ struct super_block *h_sb __maybe_unused); -+ }; -+ static const struct op a[] = { -+ [AuDy_AOP] = { -+ .sz = sizeof(struct au_dyaop), -+ .set = dy_aop -+ } -+ }; -+ const struct op *p; -+ -+ hbl = dynop + op->dy_type; -+ key = dy_gfind_get(hbl, op->dy_hop); -+ if (key) -+ goto out_add; /* success */ -+ -+ p = a + op->dy_type; -+ key = kzalloc(p->sz, GFP_NOFS); -+ if (unlikely(!key)) { -+ key = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ -+ key->dk_op.dy_hop = op->dy_hop; -+ kref_init(&key->dk_kref); -+ p->set(key, op->dy_hop, au_br_sb(br)); -+ old = dy_gadd(hbl, key); -+ if (old) { -+ kfree(key); -+ key = old; -+ } -+ -+out_add: -+ old = dy_bradd(br, key); -+ if (old) -+ /* its ref-count should never be zero here */ -+ kref_put(&key->dk_kref, dy_bug); -+out: -+ return key; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * Aufs prohibits O_DIRECT by default even if the branch supports it. -+ * This behaviour is necessary to return an error from open(O_DIRECT) instead -+ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes -+ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error. -+ * See the aufs manual in detail. -+ */ -+static void dy_adx(struct au_dyaop *dyaop, int do_dx) -+{ -+ if (!do_dx) -+ dyaop->da_op.direct_IO = NULL; -+ else -+ dyaop->da_op.direct_IO = aufs_aop.direct_IO; -+} -+ -+static struct au_dyaop *dy_aget(struct au_branch *br, -+ const struct address_space_operations *h_aop, -+ int do_dx) -+{ -+ struct au_dyaop *dyaop; -+ struct au_dynop op; -+ -+ op.dy_type = AuDy_AOP; -+ op.dy_haop = h_aop; -+ dyaop = (void *)dy_get(&op, br); -+ if (IS_ERR(dyaop)) -+ goto out; -+ dy_adx(dyaop, do_dx); -+ -+out: -+ return dyaop; -+} -+ -+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex, -+ struct inode *h_inode) -+{ -+ int err, do_dx; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_dyaop *dyaop; -+ -+ AuDebugOn(!S_ISREG(h_inode->i_mode)); -+ IiMustWriteLock(inode); -+ -+ sb = inode->i_sb; -+ br = au_sbr(sb, bindex); -+ do_dx = !!au_opt_test(au_mntflags(sb), DIO); -+ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx); -+ err = PTR_ERR(dyaop); -+ if (IS_ERR(dyaop)) -+ /* unnecessary to call dy_fput() */ -+ goto out; -+ -+ err = 0; -+ inode->i_mapping->a_ops = &dyaop->da_op; -+ -+out: -+ return err; -+} -+ -+/* -+ * Is it safe to replace a_ops during the inode/file is in operation? -+ * Yes, I hope so. -+ */ -+int au_dy_irefresh(struct inode *inode) -+{ -+ int err; -+ aufs_bindex_t btop; -+ struct inode *h_inode; -+ -+ err = 0; -+ if (S_ISREG(inode->i_mode)) { -+ btop = au_ibtop(inode); -+ h_inode = au_h_iptr(inode, btop); -+ err = au_dy_iaop(inode, btop, h_inode); -+ } -+ return err; -+} -+ -+void au_dy_arefresh(int do_dx) -+{ -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ struct au_dykey *key; -+ -+ hbl = dynop + AuDy_AOP; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(key, pos, hbl, dk_hnode) -+ dy_adx((void *)key, do_dx); -+ hlist_bl_unlock(hbl); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void __init au_dy_init(void) -+{ -+ int i; -+ -+ /* make sure that 'struct au_dykey *' can be any type */ -+ BUILD_BUG_ON(offsetof(struct au_dyaop, da_key)); -+ -+ for (i = 0; i < AuDyLast; i++) -+ INIT_HLIST_BL_HEAD(dynop + i); -+} -+ -+void au_dy_fin(void) -+{ -+ int i; -+ -+ for (i = 0; i < AuDyLast; i++) -+ WARN_ON(!hlist_bl_empty(dynop + i)); -+} -diff --git a/fs/aufs/dynop.h b/fs/aufs/dynop.h -new file mode 100644 -index 000000000..d4015351e ---- /dev/null -+++ b/fs/aufs/dynop.h -@@ -0,0 +1,75 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2010-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * dynamically customizable operations (for regular files only) -+ */ -+ -+#ifndef __AUFS_DYNOP_H__ -+#define __AUFS_DYNOP_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+ -+enum {AuDy_AOP, AuDyLast}; -+ -+struct au_dynop { -+ int dy_type; -+ union { -+ const void *dy_hop; -+ const struct address_space_operations *dy_haop; -+ }; -+}; -+ -+struct au_dykey { -+ union { -+ struct hlist_bl_node dk_hnode; -+ struct rcu_head dk_rcu; -+ }; -+ struct au_dynop dk_op; -+ -+ /* -+ * during I am in the branch local array, kref is gotten. when the -+ * branch is removed, kref is put. -+ */ -+ struct kref dk_kref; -+}; -+ -+/* stop unioning since their sizes are very different from each other */ -+struct au_dyaop { -+ struct au_dykey da_key; -+ struct address_space_operations da_op; /* not const */ -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* dynop.c */ -+struct au_branch; -+void au_dy_put(struct au_dykey *key); -+int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex, -+ struct inode *h_inode); -+int au_dy_irefresh(struct inode *inode); -+void au_dy_arefresh(int do_dio); -+ -+void __init au_dy_init(void); -+void au_dy_fin(void); -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_DYNOP_H__ */ -diff --git a/fs/aufs/export.c b/fs/aufs/export.c -new file mode 100644 -index 000000000..0358fbec3 ---- /dev/null -+++ b/fs/aufs/export.c -@@ -0,0 +1,838 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * export via nfs -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+union conv { -+#ifdef CONFIG_AUFS_INO_T_64 -+ __u32 a[2]; -+#else -+ __u32 a[1]; -+#endif -+ ino_t ino; -+}; -+ -+static ino_t decode_ino(__u32 *a) -+{ -+ union conv u; -+ -+ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a)); -+ u.a[0] = a[0]; -+#ifdef CONFIG_AUFS_INO_T_64 -+ u.a[1] = a[1]; -+#endif -+ return u.ino; -+} -+ -+static void encode_ino(__u32 *a, ino_t ino) -+{ -+ union conv u; -+ -+ u.ino = ino; -+ a[0] = u.a[0]; -+#ifdef CONFIG_AUFS_INO_T_64 -+ a[1] = u.a[1]; -+#endif -+} -+ -+/* NFS file handle */ -+enum { -+ Fh_br_id, -+ Fh_sigen, -+#ifdef CONFIG_AUFS_INO_T_64 -+ /* support 64bit inode number */ -+ Fh_ino1, -+ Fh_ino2, -+ Fh_dir_ino1, -+ Fh_dir_ino2, -+#else -+ Fh_ino1, -+ Fh_dir_ino1, -+#endif -+ Fh_igen, -+ Fh_h_type, -+ Fh_tail, -+ -+ Fh_ino = Fh_ino1, -+ Fh_dir_ino = Fh_dir_ino1 -+}; -+ -+static int au_test_anon(struct dentry *dentry) -+{ -+ /* note: read d_flags without d_lock */ -+ return !!(dentry->d_flags & DCACHE_DISCONNECTED); -+} -+ -+int au_test_nfsd(void) -+{ -+ int ret; -+ struct task_struct *tsk = current; -+ char comm[sizeof(tsk->comm)]; -+ -+ ret = 0; -+ if (tsk->flags & PF_KTHREAD) { -+ get_task_comm(comm, tsk); -+ ret = !strcmp(comm, "nfsd"); -+ } -+ -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* inode generation external table */ -+ -+void au_xigen_inc(struct inode *inode) -+{ -+ loff_t pos; -+ ssize_t sz; -+ __u32 igen; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ -+ sb = inode->i_sb; -+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO)); -+ -+ sbinfo = au_sbi(sb); -+ pos = inode->i_ino; -+ pos *= sizeof(igen); -+ igen = inode->i_generation + 1; -+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen, -+ sizeof(igen), &pos); -+ if (sz == sizeof(igen)) -+ return; /* success */ -+ -+ if (unlikely(sz >= 0)) -+ AuIOErr("xigen error (%zd)\n", sz); -+} -+ -+int au_xigen_new(struct inode *inode) -+{ -+ int err; -+ loff_t pos; -+ ssize_t sz; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ -+ err = 0; -+ /* todo: dirty, at mount time */ -+ if (inode->i_ino == AUFS_ROOT_INO) -+ goto out; -+ sb = inode->i_sb; -+ SiMustAnyLock(sb); -+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO))) -+ goto out; -+ -+ err = -EFBIG; -+ pos = inode->i_ino; -+ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) { -+ AuIOErr1("too large i%lld\n", pos); -+ goto out; -+ } -+ pos *= sizeof(inode->i_generation); -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ file = sbinfo->si_xigen; -+ BUG_ON(!file); -+ -+ if (vfsub_f_size_read(file) -+ < pos + sizeof(inode->i_generation)) { -+ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next); -+ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation, -+ sizeof(inode->i_generation), &pos); -+ } else -+ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation, -+ sizeof(inode->i_generation), &pos); -+ if (sz == sizeof(inode->i_generation)) -+ goto out; /* success */ -+ -+ err = sz; -+ if (unlikely(sz >= 0)) { -+ err = -EIO; -+ AuIOErr("xigen error (%zd)\n", sz); -+ } -+ -+out: -+ return err; -+} -+ -+int au_xigen_set(struct super_block *sb, struct path *path) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ file = au_xino_create2(sb, path, sbinfo->si_xigen); -+ err = PTR_ERR(file); -+ if (IS_ERR(file)) -+ goto out; -+ err = 0; -+ if (sbinfo->si_xigen) -+ fput(sbinfo->si_xigen); -+ sbinfo->si_xigen = file; -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_xigen_clr(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ if (sbinfo->si_xigen) { -+ fput(sbinfo->si_xigen); -+ sbinfo->si_xigen = NULL; -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino, -+ ino_t dir_ino) -+{ -+ struct dentry *dentry, *d; -+ struct inode *inode; -+ unsigned int sigen; -+ -+ dentry = NULL; -+ inode = ilookup(sb, ino); -+ if (!inode) -+ goto out; -+ -+ dentry = ERR_PTR(-ESTALE); -+ sigen = au_sigen(sb); -+ if (unlikely(au_is_bad_inode(inode) -+ || IS_DEADDIR(inode) -+ || sigen != au_iigen(inode, NULL))) -+ goto out_iput; -+ -+ dentry = NULL; -+ if (!dir_ino || S_ISDIR(inode->i_mode)) -+ dentry = d_find_alias(inode); -+ else { -+ spin_lock(&inode->i_lock); -+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) { -+ spin_lock(&d->d_lock); -+ if (!au_test_anon(d) -+ && d_inode(d->d_parent)->i_ino == dir_ino) { -+ dentry = dget_dlock(d); -+ spin_unlock(&d->d_lock); -+ break; -+ } -+ spin_unlock(&d->d_lock); -+ } -+ spin_unlock(&inode->i_lock); -+ } -+ if (unlikely(dentry && au_digen_test(dentry, sigen))) { -+ /* need to refresh */ -+ dput(dentry); -+ dentry = NULL; -+ } -+ -+out_iput: -+ iput(inode); -+out: -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* todo: dirty? */ -+/* if exportfs_decode_fh() passed vfsmount*, we could be happy */ -+ -+struct au_compare_mnt_args { -+ /* input */ -+ struct super_block *sb; -+ -+ /* output */ -+ struct vfsmount *mnt; -+}; -+ -+static int au_compare_mnt(struct vfsmount *mnt, void *arg) -+{ -+ struct au_compare_mnt_args *a = arg; -+ -+ if (mnt->mnt_sb != a->sb) -+ return 0; -+ a->mnt = mntget(mnt); -+ return 1; -+} -+ -+static struct vfsmount *au_mnt_get(struct super_block *sb) -+{ -+ int err; -+ struct path root; -+ struct au_compare_mnt_args args = { -+ .sb = sb -+ }; -+ -+ get_fs_root(current->fs, &root); -+ rcu_read_lock(); -+ err = iterate_mounts(au_compare_mnt, &args, root.mnt); -+ rcu_read_unlock(); -+ path_put(&root); -+ AuDebugOn(!err); -+ AuDebugOn(!args.mnt); -+ return args.mnt; -+} -+ -+struct au_nfsd_si_lock { -+ unsigned int sigen; -+ aufs_bindex_t bindex, br_id; -+ unsigned char force_lock; -+}; -+ -+static int si_nfsd_read_lock(struct super_block *sb, -+ struct au_nfsd_si_lock *nsi_lock) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ -+ si_read_lock(sb, AuLock_FLUSH); -+ -+ /* branch id may be wrapped around */ -+ err = 0; -+ bindex = au_br_index(sb, nsi_lock->br_id); -+ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb)) -+ goto out; /* success */ -+ -+ err = -ESTALE; -+ bindex = -1; -+ if (!nsi_lock->force_lock) -+ si_read_unlock(sb); -+ -+out: -+ nsi_lock->bindex = bindex; -+ return err; -+} -+ -+struct find_name_by_ino { -+ struct dir_context ctx; -+ int called, found; -+ ino_t ino; -+ char *name; -+ int namelen; -+}; -+ -+static int -+find_name_by_ino(struct dir_context *ctx, const char *name, int namelen, -+ loff_t offset, u64 ino, unsigned int d_type) -+{ -+ struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino, -+ ctx); -+ -+ a->called++; -+ if (a->ino != ino) -+ return 0; -+ -+ memcpy(a->name, name, namelen); -+ a->namelen = namelen; -+ a->found = 1; -+ return 1; -+} -+ -+static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino, -+ struct au_nfsd_si_lock *nsi_lock) -+{ -+ struct dentry *dentry, *parent; -+ struct file *file; -+ struct inode *dir; -+ struct find_name_by_ino arg = { -+ .ctx = { -+ .actor = find_name_by_ino -+ } -+ }; -+ int err; -+ -+ parent = path->dentry; -+ if (nsi_lock) -+ si_read_unlock(parent->d_sb); -+ file = vfsub_dentry_open(path, au_dir_roflags); -+ dentry = (void *)file; -+ if (IS_ERR(file)) -+ goto out; -+ -+ dentry = ERR_PTR(-ENOMEM); -+ arg.name = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!arg.name)) -+ goto out_file; -+ arg.ino = ino; -+ arg.found = 0; -+ do { -+ arg.called = 0; -+ /* smp_mb(); */ -+ err = vfsub_iterate_dir(file, &arg.ctx); -+ } while (!err && !arg.found && arg.called); -+ dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_name; -+ /* instead of ENOENT */ -+ dentry = ERR_PTR(-ESTALE); -+ if (!arg.found) -+ goto out_name; -+ -+ /* do not call vfsub_lkup_one() */ -+ dir = d_inode(parent); -+ dentry = vfsub_lookup_one_len_unlocked(arg.name, parent, arg.namelen); -+ AuTraceErrPtr(dentry); -+ if (IS_ERR(dentry)) -+ goto out_name; -+ AuDebugOn(au_test_anon(dentry)); -+ if (unlikely(d_really_is_negative(dentry))) { -+ dput(dentry); -+ dentry = ERR_PTR(-ENOENT); -+ } -+ -+out_name: -+ free_page((unsigned long)arg.name); -+out_file: -+ fput(file); -+out: -+ if (unlikely(nsi_lock -+ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0)) -+ if (!IS_ERR(dentry)) { -+ dput(dentry); -+ dentry = ERR_PTR(-ESTALE); -+ } -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino, -+ ino_t dir_ino, -+ struct au_nfsd_si_lock *nsi_lock) -+{ -+ struct dentry *dentry; -+ struct path path; -+ -+ if (dir_ino != AUFS_ROOT_INO) { -+ path.dentry = decode_by_ino(sb, dir_ino, 0); -+ dentry = path.dentry; -+ if (!path.dentry || IS_ERR(path.dentry)) -+ goto out; -+ AuDebugOn(au_test_anon(path.dentry)); -+ } else -+ path.dentry = dget(sb->s_root); -+ -+ path.mnt = au_mnt_get(sb); -+ dentry = au_lkup_by_ino(&path, ino, nsi_lock); -+ path_put(&path); -+ -+out: -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int h_acceptable(void *expv, struct dentry *dentry) -+{ -+ return 1; -+} -+ -+static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath, -+ char *buf, int len, struct super_block *sb) -+{ -+ char *p; -+ int n; -+ struct path path; -+ -+ p = d_path(h_rootpath, buf, len); -+ if (IS_ERR(p)) -+ goto out; -+ n = strlen(p); -+ -+ path.mnt = h_rootpath->mnt; -+ path.dentry = h_parent; -+ p = d_path(&path, buf, len); -+ if (IS_ERR(p)) -+ goto out; -+ if (n != 1) -+ p += n; -+ -+ path.mnt = au_mnt_get(sb); -+ path.dentry = sb->s_root; -+ p = d_path(&path, buf, len - strlen(p)); -+ mntput(path.mnt); -+ if (IS_ERR(p)) -+ goto out; -+ if (n != 1) -+ p[strlen(p)] = '/'; -+ -+out: -+ AuTraceErrPtr(p); -+ return p; -+} -+ -+static -+struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh, -+ int fh_len, struct au_nfsd_si_lock *nsi_lock) -+{ -+ struct dentry *dentry, *h_parent, *root; -+ struct super_block *h_sb; -+ char *pathname, *p; -+ struct vfsmount *h_mnt; -+ struct au_branch *br; -+ int err; -+ struct path path; -+ -+ br = au_sbr(sb, nsi_lock->bindex); -+ h_mnt = au_br_mnt(br); -+ h_sb = h_mnt->mnt_sb; -+ /* todo: call lower fh_to_dentry()? fh_to_parent()? */ -+ lockdep_off(); -+ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail), -+ fh_len - Fh_tail, fh[Fh_h_type], -+ h_acceptable, /*context*/NULL); -+ lockdep_on(); -+ dentry = h_parent; -+ if (unlikely(!h_parent || IS_ERR(h_parent))) { -+ AuWarn1("%s decode_fh failed, %ld\n", -+ au_sbtype(h_sb), PTR_ERR(h_parent)); -+ goto out; -+ } -+ dentry = NULL; -+ if (unlikely(au_test_anon(h_parent))) { -+ AuWarn1("%s decode_fh returned a disconnected dentry\n", -+ au_sbtype(h_sb)); -+ goto out_h_parent; -+ } -+ -+ dentry = ERR_PTR(-ENOMEM); -+ pathname = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!pathname)) -+ goto out_h_parent; -+ -+ root = sb->s_root; -+ path.mnt = h_mnt; -+ di_read_lock_parent(root, !AuLock_IR); -+ path.dentry = au_h_dptr(root, nsi_lock->bindex); -+ di_read_unlock(root, !AuLock_IR); -+ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb); -+ dentry = (void *)p; -+ if (IS_ERR(p)) -+ goto out_pathname; -+ -+ si_read_unlock(sb); -+ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path); -+ dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_relock; -+ -+ dentry = ERR_PTR(-ENOENT); -+ AuDebugOn(au_test_anon(path.dentry)); -+ if (unlikely(d_really_is_negative(path.dentry))) -+ goto out_path; -+ -+ if (ino != d_inode(path.dentry)->i_ino) -+ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL); -+ else -+ dentry = dget(path.dentry); -+ -+out_path: -+ path_put(&path); -+out_relock: -+ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0)) -+ if (!IS_ERR(dentry)) { -+ dput(dentry); -+ dentry = ERR_PTR(-ESTALE); -+ } -+out_pathname: -+ free_page((unsigned long)pathname); -+out_h_parent: -+ dput(h_parent); -+out: -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct dentry * -+aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, -+ int fh_type) -+{ -+ struct dentry *dentry; -+ __u32 *fh = fid->raw; -+ struct au_branch *br; -+ ino_t ino, dir_ino; -+ struct au_nfsd_si_lock nsi_lock = { -+ .force_lock = 0 -+ }; -+ -+ dentry = ERR_PTR(-ESTALE); -+ /* it should never happen, but the file handle is unreliable */ -+ if (unlikely(fh_len < Fh_tail)) -+ goto out; -+ nsi_lock.sigen = fh[Fh_sigen]; -+ nsi_lock.br_id = fh[Fh_br_id]; -+ -+ /* branch id may be wrapped around */ -+ br = NULL; -+ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock))) -+ goto out; -+ nsi_lock.force_lock = 1; -+ -+ /* is this inode still cached? */ -+ ino = decode_ino(fh + Fh_ino); -+ /* it should never happen */ -+ if (unlikely(ino == AUFS_ROOT_INO)) -+ goto out_unlock; -+ -+ dir_ino = decode_ino(fh + Fh_dir_ino); -+ dentry = decode_by_ino(sb, ino, dir_ino); -+ if (IS_ERR(dentry)) -+ goto out_unlock; -+ if (dentry) -+ goto accept; -+ -+ /* is the parent dir cached? */ -+ br = au_sbr(sb, nsi_lock.bindex); -+ au_lcnt_inc(&br->br_nfiles); -+ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock); -+ if (IS_ERR(dentry)) -+ goto out_unlock; -+ if (dentry) -+ goto accept; -+ -+ /* lookup path */ -+ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock); -+ if (IS_ERR(dentry)) -+ goto out_unlock; -+ if (unlikely(!dentry)) -+ /* todo?: make it ESTALE */ -+ goto out_unlock; -+ -+accept: -+ if (!au_digen_test(dentry, au_sigen(sb)) -+ && d_inode(dentry)->i_generation == fh[Fh_igen]) -+ goto out_unlock; /* success */ -+ -+ dput(dentry); -+ dentry = ERR_PTR(-ESTALE); -+out_unlock: -+ if (br) -+ au_lcnt_dec(&br->br_nfiles); -+ si_read_unlock(sb); -+out: -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+#if 0 /* reserved for future use */ -+/* support subtreecheck option */ -+static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid, -+ int fh_len, int fh_type) -+{ -+ struct dentry *parent; -+ __u32 *fh = fid->raw; -+ ino_t dir_ino; -+ -+ dir_ino = decode_ino(fh + Fh_dir_ino); -+ parent = decode_by_ino(sb, dir_ino, 0); -+ if (IS_ERR(parent)) -+ goto out; -+ if (!parent) -+ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]), -+ dir_ino, fh, fh_len); -+ -+out: -+ AuTraceErrPtr(parent); -+ return parent; -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len, -+ struct inode *dir) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct super_block *sb, *h_sb; -+ struct dentry *dentry, *parent, *h_parent; -+ struct inode *h_dir; -+ struct au_branch *br; -+ -+ err = -ENOSPC; -+ if (unlikely(*max_len <= Fh_tail)) { -+ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len); -+ goto out; -+ } -+ -+ err = FILEID_ROOT; -+ if (inode->i_ino == AUFS_ROOT_INO) { -+ AuDebugOn(inode->i_ino != AUFS_ROOT_INO); -+ goto out; -+ } -+ -+ h_parent = NULL; -+ sb = inode->i_sb; -+ err = si_read_lock(sb, AuLock_FLUSH); -+ if (unlikely(err)) -+ goto out; -+ -+#ifdef CONFIG_AUFS_DEBUG -+ if (unlikely(!au_opt_test(au_mntflags(sb), XINO))) -+ AuWarn1("NFS-exporting requires xino\n"); -+#endif -+ err = -EIO; -+ parent = NULL; -+ ii_read_lock_child(inode); -+ bindex = au_ibtop(inode); -+ if (!dir) { -+ dentry = d_find_any_alias(inode); -+ if (unlikely(!dentry)) -+ goto out_unlock; -+ AuDebugOn(au_test_anon(dentry)); -+ parent = dget_parent(dentry); -+ dput(dentry); -+ if (unlikely(!parent)) -+ goto out_unlock; -+ if (d_really_is_positive(parent)) -+ dir = d_inode(parent); -+ } -+ -+ ii_read_lock_parent(dir); -+ h_dir = au_h_iptr(dir, bindex); -+ ii_read_unlock(dir); -+ if (unlikely(!h_dir)) -+ goto out_parent; -+ h_parent = d_find_any_alias(h_dir); -+ if (unlikely(!h_parent)) -+ goto out_hparent; -+ -+ err = -EPERM; -+ br = au_sbr(sb, bindex); -+ h_sb = au_br_sb(br); -+ if (unlikely(!h_sb->s_export_op)) { -+ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb)); -+ goto out_hparent; -+ } -+ -+ fh[Fh_br_id] = br->br_id; -+ fh[Fh_sigen] = au_sigen(sb); -+ encode_ino(fh + Fh_ino, inode->i_ino); -+ encode_ino(fh + Fh_dir_ino, dir->i_ino); -+ fh[Fh_igen] = inode->i_generation; -+ -+ *max_len -= Fh_tail; -+ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail), -+ max_len, -+ /*connectable or subtreecheck*/0); -+ err = fh[Fh_h_type]; -+ *max_len += Fh_tail; -+ /* todo: macros? */ -+ if (err != FILEID_INVALID) -+ err = 99; -+ else -+ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb)); -+ -+out_hparent: -+ dput(h_parent); -+out_parent: -+ dput(parent); -+out_unlock: -+ ii_read_unlock(inode); -+ si_read_unlock(sb); -+out: -+ if (unlikely(err < 0)) -+ err = FILEID_INVALID; -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int aufs_commit_metadata(struct inode *inode) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct super_block *sb; -+ struct inode *h_inode; -+ int (*f)(struct inode *inode); -+ -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ ii_write_lock_child(inode); -+ bindex = au_ibtop(inode); -+ AuDebugOn(bindex < 0); -+ h_inode = au_h_iptr(inode, bindex); -+ -+ f = h_inode->i_sb->s_export_op->commit_metadata; -+ if (f) -+ err = f(h_inode); -+ else { -+ struct writeback_control wbc = { -+ .sync_mode = WB_SYNC_ALL, -+ .nr_to_write = 0 /* metadata only */ -+ }; -+ -+ err = sync_inode(h_inode, &wbc); -+ } -+ -+ au_cpup_attr_timesizes(inode); -+ ii_write_unlock(inode); -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct export_operations aufs_export_op = { -+ .fh_to_dentry = aufs_fh_to_dentry, -+ /* .fh_to_parent = aufs_fh_to_parent, */ -+ .encode_fh = aufs_encode_fh, -+ .commit_metadata = aufs_commit_metadata -+}; -+ -+void au_export_init(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ __u32 u; -+ -+ BUILD_BUG_ON_MSG(IS_BUILTIN(CONFIG_AUFS_FS) -+ && IS_MODULE(CONFIG_EXPORTFS), -+ AUFS_NAME ": unsupported configuration " -+ "CONFIG_EXPORTFS=m and CONFIG_AUFS_FS=y"); -+ -+ sb->s_export_op = &aufs_export_op; -+ sbinfo = au_sbi(sb); -+ sbinfo->si_xigen = NULL; -+ get_random_bytes(&u, sizeof(u)); -+ BUILD_BUG_ON(sizeof(u) != sizeof(int)); -+ atomic_set(&sbinfo->si_xigen_next, u); -+} -diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c -new file mode 100644 -index 000000000..0733ae8ac ---- /dev/null -+++ b/fs/aufs/f_op.c -@@ -0,0 +1,819 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * file and vm operations -+ */ -+ -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+int au_do_open_nondir(struct file *file, int flags, struct file *h_file) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct dentry *dentry, *h_dentry; -+ struct au_finfo *finfo; -+ struct inode *h_inode; -+ -+ FiMustWriteLock(file); -+ -+ err = 0; -+ dentry = file->f_path.dentry; -+ AuDebugOn(IS_ERR_OR_NULL(dentry)); -+ finfo = au_fi(file); -+ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop)); -+ atomic_set(&finfo->fi_mmapped, 0); -+ bindex = au_dbtop(dentry); -+ if (!h_file) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb); -+ if (unlikely(err)) -+ goto out; -+ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0); -+ if (IS_ERR(h_file)) { -+ err = PTR_ERR(h_file); -+ goto out; -+ } -+ } else { -+ h_dentry = h_file->f_path.dentry; -+ err = vfsub_test_mntns(file->f_path.mnt, h_dentry->d_sb); -+ if (unlikely(err)) -+ goto out; -+ /* br ref is already inc-ed */ -+ } -+ -+ if ((flags & __O_TMPFILE) -+ && !(flags & O_EXCL)) { -+ h_inode = file_inode(h_file); -+ spin_lock(&h_inode->i_lock); -+ h_inode->i_state |= I_LINKABLE; -+ spin_unlock(&h_inode->i_lock); -+ } -+ au_set_fbtop(file, bindex); -+ au_set_h_fptr(file, bindex, h_file); -+ au_update_figen(file); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ -+out: -+ return err; -+} -+ -+static int aufs_open_nondir(struct inode *inode __maybe_unused, -+ struct file *file) -+{ -+ int err; -+ struct super_block *sb; -+ struct au_do_open_args args = { -+ .open = au_do_open_nondir -+ }; -+ -+ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n", -+ file, vfsub_file_flags(file), file->f_mode); -+ -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ err = au_do_open(file, &args); -+ si_read_unlock(sb); -+ return err; -+} -+ -+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file) -+{ -+ struct au_finfo *finfo; -+ aufs_bindex_t bindex; -+ -+ finfo = au_fi(file); -+ au_hbl_del(&finfo->fi_hlist, -+ &au_sbi(file->f_path.dentry->d_sb)->si_files); -+ bindex = finfo->fi_btop; -+ if (bindex >= 0) -+ au_set_h_fptr(file, bindex, NULL); -+ -+ au_finfo_fin(file); -+ return 0; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_do_flush_nondir(struct file *file, fl_owner_t id) -+{ -+ int err; -+ struct file *h_file; -+ -+ err = 0; -+ h_file = au_hf_top(file); -+ if (h_file) -+ err = vfsub_flush(h_file, id); -+ return err; -+} -+ -+static int aufs_flush_nondir(struct file *file, fl_owner_t id) -+{ -+ return au_do_flush(file, id, au_do_flush_nondir); -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * read and write functions acquire [fdi]_rwsem once, but release before -+ * mmap_sem. This is because to stop a race condition between mmap(2). -+ * Releasing these aufs-rwsem should be safe, no branch-management (by keeping -+ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in -+ * read functions after [fdi]_rwsem are released, but it should be harmless. -+ */ -+ -+/* Callers should call au_read_post() or fput() in the end */ -+struct file *au_read_pre(struct file *file, int keep_fi, unsigned int lsc) -+{ -+ struct file *h_file; -+ int err; -+ -+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0, lsc); -+ if (!err) { -+ di_read_unlock(file->f_path.dentry, AuLock_IR); -+ h_file = au_hf_top(file); -+ get_file(h_file); -+ if (!keep_fi) -+ fi_read_unlock(file); -+ } else -+ h_file = ERR_PTR(err); -+ -+ return h_file; -+} -+ -+static void au_read_post(struct inode *inode, struct file *h_file) -+{ -+ /* update without lock, I don't think it a problem */ -+ fsstack_copy_attr_atime(inode, file_inode(h_file)); -+ fput(h_file); -+} -+ -+struct au_write_pre { -+ /* input */ -+ unsigned int lsc; -+ -+ /* output */ -+ blkcnt_t blks; -+ aufs_bindex_t btop; -+}; -+ -+/* -+ * return with iinfo is write-locked -+ * callers should call au_write_post() or iinfo_write_unlock() + fput() in the -+ * end -+ */ -+static struct file *au_write_pre(struct file *file, int do_ready, -+ struct au_write_pre *wpre) -+{ -+ struct file *h_file; -+ struct dentry *dentry; -+ int err; -+ unsigned int lsc; -+ struct au_pin pin; -+ -+ lsc = 0; -+ if (wpre) -+ lsc = wpre->lsc; -+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1, lsc); -+ h_file = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ -+ dentry = file->f_path.dentry; -+ if (do_ready) { -+ err = au_ready_to_write(file, -1, &pin); -+ if (unlikely(err)) { -+ h_file = ERR_PTR(err); -+ di_write_unlock(dentry); -+ goto out_fi; -+ } -+ } -+ -+ di_downgrade_lock(dentry, /*flags*/0); -+ if (wpre) -+ wpre->btop = au_fbtop(file); -+ h_file = au_hf_top(file); -+ get_file(h_file); -+ if (wpre) -+ wpre->blks = file_inode(h_file)->i_blocks; -+ if (do_ready) -+ au_unpin(&pin); -+ di_read_unlock(dentry, /*flags*/0); -+ -+out_fi: -+ fi_write_unlock(file); -+out: -+ return h_file; -+} -+ -+static void au_write_post(struct inode *inode, struct file *h_file, -+ struct au_write_pre *wpre, ssize_t written) -+{ -+ struct inode *h_inode; -+ -+ au_cpup_attr_timesizes(inode); -+ AuDebugOn(au_ibtop(inode) != wpre->btop); -+ h_inode = file_inode(h_file); -+ inode->i_mode = h_inode->i_mode; -+ ii_write_unlock(inode); -+ /* AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks); */ -+ if (written > 0) -+ au_fhsm_wrote(inode->i_sb, wpre->btop, -+ /*force*/h_inode->i_blocks > wpre->blks); -+ fput(h_file); -+} -+ -+static ssize_t aufs_read(struct file *file, char __user *buf, size_t count, -+ loff_t *ppos) -+{ -+ ssize_t err; -+ struct inode *inode; -+ struct file *h_file; -+ struct super_block *sb; -+ -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ /* filedata may be obsoleted by concurrent copyup, but no problem */ -+ err = vfsub_read_u(h_file, buf, count, ppos); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ au_read_post(inode, h_file); -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* -+ * todo: very ugly -+ * it locks both of i_mutex and si_rwsem for read in safe. -+ * if the plink maintenance mode continues forever (that is the problem), -+ * may loop forever. -+ */ -+static void au_mtx_and_read_lock(struct inode *inode) -+{ -+ int err; -+ struct super_block *sb = inode->i_sb; -+ -+ while (1) { -+ inode_lock(inode); -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (!err) -+ break; -+ inode_unlock(inode); -+ si_read_lock(sb, AuLock_NOPLMW); -+ si_read_unlock(sb); -+ } -+} -+ -+static ssize_t aufs_write(struct file *file, const char __user *ubuf, -+ size_t count, loff_t *ppos) -+{ -+ ssize_t err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ char __user *buf = (char __user *)ubuf; -+ -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ wpre.lsc = 0; -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = vfsub_write_u(h_file, buf, count, ppos); -+ au_write_post(inode, h_file, &wpre, err); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ inode_unlock(inode); -+ return err; -+} -+ -+static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio, -+ struct iov_iter *iov_iter) -+{ -+ ssize_t err; -+ struct file *file; -+ ssize_t (*iter)(struct kiocb *, struct iov_iter *); -+ -+ err = security_file_permission(h_file, rw); -+ if (unlikely(err)) -+ goto out; -+ -+ err = -ENOSYS; -+ iter = NULL; -+ if (rw == MAY_READ) -+ iter = h_file->f_op->read_iter; -+ else if (rw == MAY_WRITE) -+ iter = h_file->f_op->write_iter; -+ -+ file = kio->ki_filp; -+ kio->ki_filp = h_file; -+ if (iter) { -+ lockdep_off(); -+ err = iter(kio, iov_iter); -+ lockdep_on(); -+ } else -+ /* currently there is no such fs */ -+ WARN_ON_ONCE(1); -+ kio->ki_filp = file; -+ -+out: -+ return err; -+} -+ -+static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter) -+{ -+ ssize_t err; -+ struct file *file, *h_file; -+ struct inode *inode; -+ struct super_block *sb; -+ -+ file = kio->ki_filp; -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/1, /*lsc*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ if (au_test_loopback_kthread()) { -+ au_warn_loopback(h_file->f_path.dentry->d_sb); -+ if (file->f_mapping != h_file->f_mapping) { -+ file->f_mapping = h_file->f_mapping; -+ smp_mb(); /* unnecessary? */ -+ } -+ } -+ fi_read_unlock(file); -+ -+ err = au_do_iter(h_file, MAY_READ, kio, iov_iter); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ au_read_post(inode, h_file); -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter) -+{ -+ ssize_t err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *file, *h_file; -+ -+ file = kio->ki_filp; -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ wpre.lsc = 0; -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter); -+ au_write_post(inode, h_file, &wpre, err); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ inode_unlock(inode); -+ return err; -+} -+ -+static ssize_t aufs_splice_read(struct file *file, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags) -+{ -+ ssize_t err; -+ struct file *h_file; -+ struct inode *inode; -+ struct super_block *sb; -+ -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = vfsub_splice_to(h_file, ppos, pipe, len, flags); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ au_read_post(inode, h_file); -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+static ssize_t -+aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos, -+ size_t len, unsigned int flags) -+{ -+ ssize_t err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ wpre.lsc = 0; -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = vfsub_splice_from(pipe, h_file, ppos, len, flags); -+ au_write_post(inode, h_file, &wpre, err); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ inode_unlock(inode); -+ return err; -+} -+ -+static long aufs_fallocate(struct file *file, int mode, loff_t offset, -+ loff_t len) -+{ -+ long err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ wpre.lsc = 0; -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_fallocate(h_file, mode, offset, len); -+ lockdep_on(); -+ au_write_post(inode, h_file, &wpre, /*written*/1); -+ -+out: -+ si_read_unlock(inode->i_sb); -+ inode_unlock(inode); -+ return err; -+} -+ -+static ssize_t aufs_copy_file_range(struct file *src, loff_t src_pos, -+ struct file *dst, loff_t dst_pos, -+ size_t len, unsigned int flags) -+{ -+ ssize_t err; -+ struct au_write_pre wpre; -+ enum { SRC, DST }; -+ struct { -+ struct inode *inode; -+ struct file *h_file; -+ struct super_block *h_sb; -+ } a[2]; -+#define a_src a[SRC] -+#define a_dst a[DST] -+ -+ err = -EINVAL; -+ a_src.inode = file_inode(src); -+ if (unlikely(!S_ISREG(a_src.inode->i_mode))) -+ goto out; -+ a_dst.inode = file_inode(dst); -+ if (unlikely(!S_ISREG(a_dst.inode->i_mode))) -+ goto out; -+ -+ au_mtx_and_read_lock(a_dst.inode); -+ /* -+ * in order to match the order in di_write_lock2_{child,parent}(), -+ * use f_path.dentry for this comparison. -+ */ -+ if (src->f_path.dentry < dst->f_path.dentry) { -+ a_src.h_file = au_read_pre(src, /*keep_fi*/1, AuLsc_FI_1); -+ err = PTR_ERR(a_src.h_file); -+ if (IS_ERR(a_src.h_file)) -+ goto out_si; -+ -+ wpre.lsc = AuLsc_FI_2; -+ a_dst.h_file = au_write_pre(dst, /*do_ready*/1, &wpre); -+ err = PTR_ERR(a_dst.h_file); -+ if (IS_ERR(a_dst.h_file)) { -+ au_read_post(a_src.inode, a_src.h_file); -+ goto out_si; -+ } -+ } else { -+ wpre.lsc = AuLsc_FI_1; -+ a_dst.h_file = au_write_pre(dst, /*do_ready*/1, &wpre); -+ err = PTR_ERR(a_dst.h_file); -+ if (IS_ERR(a_dst.h_file)) -+ goto out_si; -+ -+ a_src.h_file = au_read_pre(src, /*keep_fi*/1, AuLsc_FI_2); -+ err = PTR_ERR(a_src.h_file); -+ if (IS_ERR(a_src.h_file)) { -+ au_write_post(a_dst.inode, a_dst.h_file, &wpre, -+ /*written*/0); -+ goto out_si; -+ } -+ } -+ -+ err = -EXDEV; -+ a_src.h_sb = file_inode(a_src.h_file)->i_sb; -+ a_dst.h_sb = file_inode(a_dst.h_file)->i_sb; -+ if (unlikely(a_src.h_sb != a_dst.h_sb)) { -+ AuDbgFile(src); -+ AuDbgFile(dst); -+ goto out_file; -+ } -+ -+ err = vfsub_copy_file_range(a_src.h_file, src_pos, a_dst.h_file, -+ dst_pos, len, flags); -+ -+out_file: -+ au_write_post(a_dst.inode, a_dst.h_file, &wpre, err); -+ fi_read_unlock(src); -+ au_read_post(a_src.inode, a_src.h_file); -+out_si: -+ si_read_unlock(a_dst.inode->i_sb); -+ inode_unlock(a_dst.inode); -+out: -+ return err; -+#undef a_src -+#undef a_dst -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * The locking order around current->mmap_sem. -+ * - in most and regular cases -+ * file I/O syscall -- aufs_read() or something -+ * -- si_rwsem for read -- mmap_sem -+ * (Note that [fdi]i_rwsem are released before mmap_sem). -+ * - in mmap case -+ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem -+ * This AB-BA order is definitely bad, but is not a problem since "si_rwsem for -+ * read" allows multiple processes to acquire it and [fdi]i_rwsem are not held -+ * in file I/O. Aufs needs to stop lockdep in aufs_mmap() though. -+ * It means that when aufs acquires si_rwsem for write, the process should never -+ * acquire mmap_sem. -+ * -+ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a -+ * problem either since any directory is not able to be mmap-ed. -+ * The similar scenario is applied to aufs_readlink() too. -+ */ -+ -+#if 0 /* stop calling security_file_mmap() */ -+/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */ -+#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b) -+ -+static unsigned long au_arch_prot_conv(unsigned long flags) -+{ -+ /* currently ppc64 only */ -+#ifdef CONFIG_PPC64 -+ /* cf. linux/arch/powerpc/include/asm/mman.h */ -+ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO); -+ return AuConv_VM_PROT(flags, SAO); -+#else -+ AuDebugOn(arch_calc_vm_prot_bits(-1)); -+ return 0; -+#endif -+} -+ -+static unsigned long au_prot_conv(unsigned long flags) -+{ -+ return AuConv_VM_PROT(flags, READ) -+ | AuConv_VM_PROT(flags, WRITE) -+ | AuConv_VM_PROT(flags, EXEC) -+ | au_arch_prot_conv(flags); -+} -+ -+/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */ -+#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b) -+ -+static unsigned long au_flag_conv(unsigned long flags) -+{ -+ return AuConv_VM_MAP(flags, GROWSDOWN) -+ | AuConv_VM_MAP(flags, DENYWRITE) -+ | AuConv_VM_MAP(flags, LOCKED); -+} -+#endif -+ -+static int aufs_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ int err; -+ const unsigned char wlock -+ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED); -+ struct super_block *sb; -+ struct file *h_file; -+ struct inode *inode; -+ -+ AuDbgVmRegion(file, vma); -+ -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ lockdep_off(); -+ si_read_lock(sb, AuLock_NOPLMW); -+ -+ h_file = au_write_pre(file, wlock, /*wpre*/NULL); -+ lockdep_on(); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ err = 0; -+ au_set_mmapped(file); -+ au_vm_file_reset(vma, h_file); -+ /* -+ * we cannot call security_mmap_file() here since it may acquire -+ * mmap_sem or i_mutex. -+ * -+ * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags), -+ * au_flag_conv(vma->vm_flags)); -+ */ -+ if (!err) -+ err = call_mmap(h_file, vma); -+ if (!err) { -+ au_vm_prfile_set(vma, file); -+ fsstack_copy_attr_atime(inode, file_inode(h_file)); -+ goto out_fput; /* success */ -+ } -+ au_unset_mmapped(file); -+ au_vm_file_reset(vma, file); -+ -+out_fput: -+ lockdep_off(); -+ ii_write_unlock(inode); -+ lockdep_on(); -+ fput(h_file); -+out: -+ lockdep_off(); -+ si_read_unlock(sb); -+ lockdep_on(); -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end, -+ int datasync) -+{ -+ int err; -+ struct au_write_pre wpre; -+ struct inode *inode; -+ struct file *h_file; -+ -+ err = 0; /* -EBADF; */ /* posix? */ -+ if (unlikely(!(file->f_mode & FMODE_WRITE))) -+ goto out; -+ -+ inode = file_inode(file); -+ au_mtx_and_read_lock(inode); -+ -+ wpre.lsc = 0; -+ h_file = au_write_pre(file, /*do_ready*/1, &wpre); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out_unlock; -+ -+ err = vfsub_fsync(h_file, &h_file->f_path, datasync); -+ au_write_post(inode, h_file, &wpre, /*written*/0); -+ -+out_unlock: -+ si_read_unlock(inode->i_sb); -+ inode_unlock(inode); -+out: -+ return err; -+} -+ -+static int aufs_fasync(int fd, struct file *file, int flag) -+{ -+ int err; -+ struct file *h_file; -+ struct super_block *sb; -+ -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ if (h_file->f_op->fasync) -+ err = h_file->f_op->fasync(fd, h_file, flag); -+ fput(h_file); /* instead of au_read_post() */ -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+static int aufs_setfl(struct file *file, unsigned long arg) -+{ -+ int err; -+ struct file *h_file; -+ struct super_block *sb; -+ -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out; -+ -+ /* stop calling h_file->fasync */ -+ arg |= vfsub_file_flags(file) & FASYNC; -+ err = setfl(/*unused fd*/-1, h_file, arg); -+ fput(h_file); /* instead of au_read_post() */ -+ -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* no one supports this operation, currently */ -+#if 0 -+static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset, -+ size_t len, loff_t *pos, int more) -+{ -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+const struct file_operations aufs_file_fop = { -+ .owner = THIS_MODULE, -+ -+ .llseek = default_llseek, -+ -+ .read = aufs_read, -+ .write = aufs_write, -+ .read_iter = aufs_read_iter, -+ .write_iter = aufs_write_iter, -+ -+#ifdef CONFIG_AUFS_POLL -+ .poll = aufs_poll, -+#endif -+ .unlocked_ioctl = aufs_ioctl_nondir, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = aufs_compat_ioctl_nondir, -+#endif -+ .mmap = aufs_mmap, -+ .open = aufs_open_nondir, -+ .flush = aufs_flush_nondir, -+ .release = aufs_release_nondir, -+ .fsync = aufs_fsync_nondir, -+ .fasync = aufs_fasync, -+ /* .sendpage = aufs_sendpage, */ -+ .setfl = aufs_setfl, -+ .splice_write = aufs_splice_write, -+ .splice_read = aufs_splice_read, -+#if 0 -+ .aio_splice_write = aufs_aio_splice_write, -+ .aio_splice_read = aufs_aio_splice_read, -+#endif -+ .fallocate = aufs_fallocate, -+ .copy_file_range = aufs_copy_file_range -+}; -diff --git a/fs/aufs/fhsm.c b/fs/aufs/fhsm.c -new file mode 100644 -index 000000000..fdb91f6eb ---- /dev/null -+++ b/fs/aufs/fhsm.c -@@ -0,0 +1,427 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2011-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+/* -+ * File-based Hierarchy Storage Management -+ */ -+ -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+static aufs_bindex_t au_fhsm_bottom(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ SiMustAnyLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ AuDebugOn(!fhsm); -+ return fhsm->fhsm_bottom; -+} -+ -+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ AuDebugOn(!fhsm); -+ fhsm->fhsm_bottom = bindex; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_fhsm_test_jiffy(struct au_sbinfo *sbinfo, struct au_branch *br) -+{ -+ struct au_br_fhsm *bf; -+ -+ bf = br->br_fhsm; -+ MtxMustLock(&bf->bf_lock); -+ -+ return !bf->bf_readable -+ || time_after(jiffies, -+ bf->bf_jiffy + sbinfo->si_fhsm.fhsm_expire); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_fhsm_notify(struct super_block *sb, int val) -+{ -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ SiMustAnyLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ if (au_fhsm_pid(fhsm) -+ && atomic_read(&fhsm->fhsm_readable) != -1) { -+ atomic_set(&fhsm->fhsm_readable, val); -+ if (val) -+ wake_up(&fhsm->fhsm_wqh); -+ } -+} -+ -+static int au_fhsm_stfs(struct super_block *sb, aufs_bindex_t bindex, -+ struct aufs_stfs *rstfs, int do_lock, int do_notify) -+{ -+ int err; -+ struct au_branch *br; -+ struct au_br_fhsm *bf; -+ -+ br = au_sbr(sb, bindex); -+ AuDebugOn(au_br_rdonly(br)); -+ bf = br->br_fhsm; -+ AuDebugOn(!bf); -+ -+ if (do_lock) -+ mutex_lock(&bf->bf_lock); -+ else -+ MtxMustLock(&bf->bf_lock); -+ -+ /* sb->s_root for NFS is unreliable */ -+ err = au_br_stfs(br, &bf->bf_stfs); -+ if (unlikely(err)) { -+ AuErr1("FHSM failed (%d), b%d, ignored.\n", bindex, err); -+ goto out; -+ } -+ -+ bf->bf_jiffy = jiffies; -+ bf->bf_readable = 1; -+ if (do_notify) -+ au_fhsm_notify(sb, /*val*/1); -+ if (rstfs) -+ *rstfs = bf->bf_stfs; -+ -+out: -+ if (do_lock) -+ mutex_unlock(&bf->bf_lock); -+ au_fhsm_notify(sb, /*val*/1); -+ -+ return err; -+} -+ -+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ struct au_branch *br; -+ struct au_br_fhsm *bf; -+ -+ AuDbg("b%d, force %d\n", bindex, force); -+ SiMustAnyLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ if (!au_ftest_si(sbinfo, FHSM) -+ || fhsm->fhsm_bottom == bindex) -+ return; -+ -+ br = au_sbr(sb, bindex); -+ bf = br->br_fhsm; -+ AuDebugOn(!bf); -+ mutex_lock(&bf->bf_lock); -+ if (force -+ || au_fhsm_pid(fhsm) -+ || au_fhsm_test_jiffy(sbinfo, br)) -+ err = au_fhsm_stfs(sb, bindex, /*rstfs*/NULL, /*do_lock*/0, -+ /*do_notify*/1); -+ mutex_unlock(&bf->bf_lock); -+} -+ -+void au_fhsm_wrote_all(struct super_block *sb, int force) -+{ -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ /* exclude the bottom */ -+ bbot = au_fhsm_bottom(sb); -+ for (bindex = 0; bindex < bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_fhsm(br->br_perm)) -+ au_fhsm_wrote(sb, bindex, force); -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static __poll_t au_fhsm_poll(struct file *file, struct poll_table_struct *wait) -+{ -+ __poll_t mask; -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ mask = 0; -+ sbinfo = file->private_data; -+ fhsm = &sbinfo->si_fhsm; -+ poll_wait(file, &fhsm->fhsm_wqh, wait); -+ if (atomic_read(&fhsm->fhsm_readable)) -+ mask = EPOLLIN /* | EPOLLRDNORM */; -+ -+ if (!mask) -+ AuDbg("mask 0x%x\n", mask); -+ return mask; -+} -+ -+static int au_fhsm_do_read_one(struct aufs_stbr __user *stbr, -+ struct aufs_stfs *stfs, __s16 brid) -+{ -+ int err; -+ -+ err = copy_to_user(&stbr->stfs, stfs, sizeof(*stfs)); -+ if (!err) -+ err = __put_user(brid, &stbr->brid); -+ if (unlikely(err)) -+ err = -EFAULT; -+ -+ return err; -+} -+ -+static ssize_t au_fhsm_do_read(struct super_block *sb, -+ struct aufs_stbr __user *stbr, size_t count) -+{ -+ ssize_t err; -+ int nstbr; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ struct au_br_fhsm *bf; -+ -+ /* except the bottom branch */ -+ err = 0; -+ nstbr = 0; -+ bbot = au_fhsm_bottom(sb); -+ for (bindex = 0; !err && bindex < bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (!au_br_fhsm(br->br_perm)) -+ continue; -+ -+ bf = br->br_fhsm; -+ mutex_lock(&bf->bf_lock); -+ if (bf->bf_readable) { -+ err = -EFAULT; -+ if (count >= sizeof(*stbr)) -+ err = au_fhsm_do_read_one(stbr++, &bf->bf_stfs, -+ br->br_id); -+ if (!err) { -+ bf->bf_readable = 0; -+ count -= sizeof(*stbr); -+ nstbr++; -+ } -+ } -+ mutex_unlock(&bf->bf_lock); -+ } -+ if (!err) -+ err = sizeof(*stbr) * nstbr; -+ -+ return err; -+} -+ -+static ssize_t au_fhsm_read(struct file *file, char __user *buf, size_t count, -+ loff_t *pos) -+{ -+ ssize_t err; -+ int readable; -+ aufs_bindex_t nfhsm, bindex, bbot; -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ struct au_branch *br; -+ struct super_block *sb; -+ -+ err = 0; -+ sbinfo = file->private_data; -+ fhsm = &sbinfo->si_fhsm; -+need_data: -+ spin_lock_irq(&fhsm->fhsm_wqh.lock); -+ if (!atomic_read(&fhsm->fhsm_readable)) { -+ if (vfsub_file_flags(file) & O_NONBLOCK) -+ err = -EAGAIN; -+ else -+ err = wait_event_interruptible_locked_irq -+ (fhsm->fhsm_wqh, -+ atomic_read(&fhsm->fhsm_readable)); -+ } -+ spin_unlock_irq(&fhsm->fhsm_wqh.lock); -+ if (unlikely(err)) -+ goto out; -+ -+ /* sb may already be dead */ -+ au_rw_read_lock(&sbinfo->si_rwsem); -+ readable = atomic_read(&fhsm->fhsm_readable); -+ if (readable > 0) { -+ sb = sbinfo->si_sb; -+ AuDebugOn(!sb); -+ /* exclude the bottom branch */ -+ nfhsm = 0; -+ bbot = au_fhsm_bottom(sb); -+ for (bindex = 0; bindex < bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_fhsm(br->br_perm)) -+ nfhsm++; -+ } -+ err = -EMSGSIZE; -+ if (nfhsm * sizeof(struct aufs_stbr) <= count) { -+ atomic_set(&fhsm->fhsm_readable, 0); -+ err = au_fhsm_do_read(sbinfo->si_sb, (void __user *)buf, -+ count); -+ } -+ } -+ au_rw_read_unlock(&sbinfo->si_rwsem); -+ if (!readable) -+ goto need_data; -+ -+out: -+ return err; -+} -+ -+static int au_fhsm_release(struct inode *inode, struct file *file) -+{ -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ /* sb may already be dead */ -+ sbinfo = file->private_data; -+ fhsm = &sbinfo->si_fhsm; -+ spin_lock(&fhsm->fhsm_spin); -+ fhsm->fhsm_pid = 0; -+ spin_unlock(&fhsm->fhsm_spin); -+ kobject_put(&sbinfo->si_kobj); -+ -+ return 0; -+} -+ -+static const struct file_operations au_fhsm_fops = { -+ .owner = THIS_MODULE, -+ .llseek = noop_llseek, -+ .read = au_fhsm_read, -+ .poll = au_fhsm_poll, -+ .release = au_fhsm_release -+}; -+ -+int au_fhsm_fd(struct super_block *sb, int oflags) -+{ -+ int err, fd; -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ -+ err = -EPERM; -+ if (unlikely(!capable(CAP_SYS_ADMIN))) -+ goto out; -+ -+ err = -EINVAL; -+ if (unlikely(oflags & ~(O_CLOEXEC | O_NONBLOCK))) -+ goto out; -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ spin_lock(&fhsm->fhsm_spin); -+ if (!fhsm->fhsm_pid) -+ fhsm->fhsm_pid = current->pid; -+ else -+ err = -EBUSY; -+ spin_unlock(&fhsm->fhsm_spin); -+ if (unlikely(err)) -+ goto out; -+ -+ oflags |= O_RDONLY; -+ /* oflags |= FMODE_NONOTIFY; */ -+ fd = anon_inode_getfd("[aufs_fhsm]", &au_fhsm_fops, sbinfo, oflags); -+ err = fd; -+ if (unlikely(fd < 0)) -+ goto out_pid; -+ -+ /* succeed regardless 'fhsm' status */ -+ kobject_get(&sbinfo->si_kobj); -+ si_noflush_read_lock(sb); -+ if (au_ftest_si(sbinfo, FHSM)) -+ au_fhsm_wrote_all(sb, /*force*/0); -+ si_read_unlock(sb); -+ goto out; /* success */ -+ -+out_pid: -+ spin_lock(&fhsm->fhsm_spin); -+ fhsm->fhsm_pid = 0; -+ spin_unlock(&fhsm->fhsm_spin); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_fhsm_br_alloc(struct au_branch *br) -+{ -+ int err; -+ -+ err = 0; -+ br->br_fhsm = kmalloc(sizeof(*br->br_fhsm), GFP_NOFS); -+ if (br->br_fhsm) -+ au_br_fhsm_init(br->br_fhsm); -+ else -+ err = -ENOMEM; -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_fhsm_fin(struct super_block *sb) -+{ -+ au_fhsm_notify(sb, /*val*/-1); -+} -+ -+void au_fhsm_init(struct au_sbinfo *sbinfo) -+{ -+ struct au_fhsm *fhsm; -+ -+ fhsm = &sbinfo->si_fhsm; -+ spin_lock_init(&fhsm->fhsm_spin); -+ init_waitqueue_head(&fhsm->fhsm_wqh); -+ atomic_set(&fhsm->fhsm_readable, 0); -+ fhsm->fhsm_expire -+ = msecs_to_jiffies(AUFS_FHSM_CACHE_DEF_SEC * MSEC_PER_SEC); -+ fhsm->fhsm_bottom = -1; -+} -+ -+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec) -+{ -+ sbinfo->si_fhsm.fhsm_expire -+ = msecs_to_jiffies(sec * MSEC_PER_SEC); -+} -+ -+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo) -+{ -+ unsigned int u; -+ -+ if (!au_ftest_si(sbinfo, FHSM)) -+ return; -+ -+ u = jiffies_to_msecs(sbinfo->si_fhsm.fhsm_expire) / MSEC_PER_SEC; -+ if (u != AUFS_FHSM_CACHE_DEF_SEC) -+ seq_printf(seq, ",fhsm_sec=%u", u); -+} -diff --git a/fs/aufs/file.c b/fs/aufs/file.c -new file mode 100644 -index 000000000..c01b98791 ---- /dev/null -+++ b/fs/aufs/file.c -@@ -0,0 +1,863 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * handling file/dir, and address_space operation -+ */ -+ -+#ifdef CONFIG_AUFS_DEBUG -+#include -+#endif -+#include -+#include "aufs.h" -+ -+/* drop flags for writing */ -+unsigned int au_file_roflags(unsigned int flags) -+{ -+ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC); -+ flags |= O_RDONLY | O_NOATIME; -+ return flags; -+} -+ -+/* common functions to regular file and dir */ -+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, -+ struct file *file, int force_wr) -+{ -+ struct file *h_file; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct path h_path; -+ int err; -+ -+ /* a race condition can happen between open and unlink/rmdir */ -+ h_file = ERR_PTR(-ENOENT); -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (au_test_nfsd() && (!h_dentry || d_is_negative(h_dentry))) -+ goto out; -+ h_inode = d_inode(h_dentry); -+ spin_lock(&h_dentry->d_lock); -+ err = (!d_unhashed(dentry) && d_unlinked(h_dentry)) -+ /* || !d_inode(dentry)->i_nlink */ -+ ; -+ spin_unlock(&h_dentry->d_lock); -+ if (unlikely(err)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ br = au_sbr(sb, bindex); -+ err = au_br_test_oflag(flags, br); -+ h_file = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ -+ /* drop flags for writing */ -+ if (au_test_ro(sb, bindex, d_inode(dentry))) { -+ if (force_wr && !(flags & O_WRONLY)) -+ force_wr = 0; -+ flags = au_file_roflags(flags); -+ if (force_wr) { -+ h_file = ERR_PTR(-EROFS); -+ flags = au_file_roflags(flags); -+ if (unlikely(vfsub_native_ro(h_inode) -+ || IS_APPEND(h_inode))) -+ goto out; -+ flags &= ~O_ACCMODE; -+ flags |= O_WRONLY; -+ } -+ } -+ flags &= ~O_CREAT; -+ au_lcnt_inc(&br->br_nfiles); -+ h_path.dentry = h_dentry; -+ h_path.mnt = au_br_mnt(br); -+ h_file = vfsub_dentry_open(&h_path, flags); -+ if (IS_ERR(h_file)) -+ goto out_br; -+ -+ if (flags & __FMODE_EXEC) { -+ err = deny_write_access(h_file); -+ if (unlikely(err)) { -+ fput(h_file); -+ h_file = ERR_PTR(err); -+ goto out_br; -+ } -+ } -+ fsnotify_open(h_file); -+ goto out; /* success */ -+ -+out_br: -+ au_lcnt_dec(&br->br_nfiles); -+out: -+ return h_file; -+} -+ -+static int au_cmoo(struct dentry *dentry) -+{ -+ int err, cmoo, matched; -+ unsigned int udba; -+ struct path h_path; -+ struct au_pin pin; -+ struct au_cp_generic cpg = { -+ .dentry = dentry, -+ .bdst = -1, -+ .bsrc = -1, -+ .len = -1, -+ .pin = &pin, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN -+ }; -+ struct inode *delegated; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ struct au_fhsm *fhsm; -+ pid_t pid; -+ struct au_branch *br; -+ struct dentry *parent; -+ struct au_hinode *hdir; -+ -+ DiMustWriteLock(dentry); -+ IiMustWriteLock(d_inode(dentry)); -+ -+ err = 0; -+ if (IS_ROOT(dentry)) -+ goto out; -+ cpg.bsrc = au_dbtop(dentry); -+ if (!cpg.bsrc) -+ goto out; -+ -+ sb = dentry->d_sb; -+ sbinfo = au_sbi(sb); -+ fhsm = &sbinfo->si_fhsm; -+ pid = au_fhsm_pid(fhsm); -+ rcu_read_lock(); -+ matched = (pid -+ && (current->pid == pid -+ || rcu_dereference(current->real_parent)->pid == pid)); -+ rcu_read_unlock(); -+ if (matched) -+ goto out; -+ -+ br = au_sbr(sb, cpg.bsrc); -+ cmoo = au_br_cmoo(br->br_perm); -+ if (!cmoo) -+ goto out; -+ if (!d_is_reg(dentry)) -+ cmoo &= AuBrAttr_COO_ALL; -+ if (!cmoo) -+ goto out; -+ -+ parent = dget_parent(dentry); -+ di_write_lock_parent(parent); -+ err = au_wbr_do_copyup_bu(dentry, cpg.bsrc - 1); -+ cpg.bdst = err; -+ if (unlikely(err < 0)) { -+ err = 0; /* there is no upper writable branch */ -+ goto out_dgrade; -+ } -+ AuDbg("bsrc %d, bdst %d\n", cpg.bsrc, cpg.bdst); -+ -+ /* do not respect the coo attrib for the target branch */ -+ err = au_cpup_dirs(dentry, cpg.bdst); -+ if (unlikely(err)) -+ goto out_dgrade; -+ -+ di_downgrade_lock(parent, AuLock_IR); -+ udba = au_opt_udba(sb); -+ err = au_pin(&pin, dentry, cpg.bdst, udba, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ err = au_sio_cpup_simple(&cpg); -+ au_unpin(&pin); -+ if (unlikely(err)) -+ goto out_parent; -+ if (!(cmoo & AuBrWAttr_MOO)) -+ goto out_parent; /* success */ -+ -+ err = au_pin(&pin, dentry, cpg.bsrc, udba, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ h_path.mnt = au_br_mnt(br); -+ h_path.dentry = au_h_dptr(dentry, cpg.bsrc); -+ hdir = au_hi(d_inode(parent), cpg.bsrc); -+ delegated = NULL; -+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, /*force*/1); -+ au_unpin(&pin); -+ /* todo: keep h_dentry or not? */ -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ if (unlikely(err)) { -+ pr_err("unlink %pd after coo failed (%d), ignored\n", -+ dentry, err); -+ err = 0; -+ } -+ goto out_parent; /* success */ -+ -+out_dgrade: -+ di_downgrade_lock(parent, AuLock_IR); -+out_parent: -+ di_read_unlock(parent, AuLock_IR); -+ dput(parent); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_do_open(struct file *file, struct au_do_open_args *args) -+{ -+ int err, aopen = args->aopen; -+ struct dentry *dentry; -+ struct au_finfo *finfo; -+ -+ if (!aopen) -+ err = au_finfo_init(file, args->fidir); -+ else { -+ lockdep_off(); -+ err = au_finfo_init(file, args->fidir); -+ lockdep_on(); -+ } -+ if (unlikely(err)) -+ goto out; -+ -+ dentry = file->f_path.dentry; -+ AuDebugOn(IS_ERR_OR_NULL(dentry)); -+ di_write_lock_child(dentry); -+ err = au_cmoo(dentry); -+ di_downgrade_lock(dentry, AuLock_IR); -+ if (!err) { -+ if (!aopen) -+ err = args->open(file, vfsub_file_flags(file), NULL); -+ else { -+ lockdep_off(); -+ err = args->open(file, vfsub_file_flags(file), -+ args->h_file); -+ lockdep_on(); -+ } -+ } -+ di_read_unlock(dentry, AuLock_IR); -+ -+ finfo = au_fi(file); -+ if (!err) { -+ finfo->fi_file = file; -+ au_hbl_add(&finfo->fi_hlist, -+ &au_sbi(file->f_path.dentry->d_sb)->si_files); -+ } -+ if (!aopen) -+ fi_write_unlock(file); -+ else { -+ lockdep_off(); -+ fi_write_unlock(file); -+ lockdep_on(); -+ } -+ if (unlikely(err)) { -+ finfo->fi_hdir = NULL; -+ au_finfo_fin(file); -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_reopen_nondir(struct file *file) -+{ -+ int err; -+ aufs_bindex_t btop; -+ struct dentry *dentry; -+ struct au_branch *br; -+ struct file *h_file, *h_file_tmp; -+ -+ dentry = file->f_path.dentry; -+ btop = au_dbtop(dentry); -+ br = au_sbr(dentry->d_sb, btop); -+ h_file_tmp = NULL; -+ if (au_fbtop(file) == btop) { -+ h_file = au_hf_top(file); -+ if (file->f_mode == h_file->f_mode) -+ return 0; /* success */ -+ h_file_tmp = h_file; -+ get_file(h_file_tmp); -+ au_lcnt_inc(&br->br_nfiles); -+ au_set_h_fptr(file, btop, NULL); -+ } -+ AuDebugOn(au_fi(file)->fi_hdir); -+ /* -+ * it can happen -+ * file exists on both of rw and ro -+ * open --> dbtop and fbtop are both 0 -+ * prepend a branch as rw, "rw" become ro -+ * remove rw/file -+ * delete the top branch, "rw" becomes rw again -+ * --> dbtop is 1, fbtop is still 0 -+ * write --> fbtop is 0 but dbtop is 1 -+ */ -+ /* AuDebugOn(au_fbtop(file) < btop); */ -+ -+ h_file = au_h_open(dentry, btop, vfsub_file_flags(file) & ~O_TRUNC, -+ file, /*force_wr*/0); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) { -+ if (h_file_tmp) { -+ /* revert */ -+ au_set_h_fptr(file, btop, h_file_tmp); -+ h_file_tmp = NULL; -+ } -+ goto out; /* todo: close all? */ -+ } -+ -+ err = 0; -+ au_set_fbtop(file, btop); -+ au_set_h_fptr(file, btop, h_file); -+ au_update_figen(file); -+ /* todo: necessary? */ -+ /* file->f_ra = h_file->f_ra; */ -+ -+out: -+ if (h_file_tmp) { -+ fput(h_file_tmp); -+ au_lcnt_dec(&br->br_nfiles); -+ } -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_reopen_wh(struct file *file, aufs_bindex_t btgt, -+ struct dentry *hi_wh) -+{ -+ int err; -+ aufs_bindex_t btop; -+ struct au_dinfo *dinfo; -+ struct dentry *h_dentry; -+ struct au_hdentry *hdp; -+ -+ dinfo = au_di(file->f_path.dentry); -+ AuRwMustWriteLock(&dinfo->di_rwsem); -+ -+ btop = dinfo->di_btop; -+ dinfo->di_btop = btgt; -+ hdp = au_hdentry(dinfo, btgt); -+ h_dentry = hdp->hd_dentry; -+ hdp->hd_dentry = hi_wh; -+ err = au_reopen_nondir(file); -+ hdp->hd_dentry = h_dentry; -+ dinfo->di_btop = btop; -+ -+ return err; -+} -+ -+static int au_ready_to_write_wh(struct file *file, loff_t len, -+ aufs_bindex_t bcpup, struct au_pin *pin) -+{ -+ int err; -+ struct inode *inode, *h_inode; -+ struct dentry *h_dentry, *hi_wh; -+ struct au_cp_generic cpg = { -+ .dentry = file->f_path.dentry, -+ .bdst = bcpup, -+ .bsrc = -1, -+ .len = len, -+ .pin = pin -+ }; -+ -+ au_update_dbtop(cpg.dentry); -+ inode = d_inode(cpg.dentry); -+ h_inode = NULL; -+ if (au_dbtop(cpg.dentry) <= bcpup -+ && au_dbbot(cpg.dentry) >= bcpup) { -+ h_dentry = au_h_dptr(cpg.dentry, bcpup); -+ if (h_dentry && d_is_positive(h_dentry)) -+ h_inode = d_inode(h_dentry); -+ } -+ hi_wh = au_hi_wh(inode, bcpup); -+ if (!hi_wh && !h_inode) -+ err = au_sio_cpup_wh(&cpg, file); -+ else -+ /* already copied-up after unlink */ -+ err = au_reopen_wh(file, bcpup, hi_wh); -+ -+ if (!err -+ && (inode->i_nlink > 1 -+ || (inode->i_state & I_LINKABLE)) -+ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK)) -+ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup)); -+ -+ return err; -+} -+ -+/* -+ * prepare the @file for writing. -+ */ -+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin) -+{ -+ int err; -+ aufs_bindex_t dbtop; -+ struct dentry *parent; -+ struct inode *inode; -+ struct super_block *sb; -+ struct file *h_file; -+ struct au_cp_generic cpg = { -+ .dentry = file->f_path.dentry, -+ .bdst = -1, -+ .bsrc = -1, -+ .len = len, -+ .pin = pin, -+ .flags = AuCpup_DTIME -+ }; -+ -+ sb = cpg.dentry->d_sb; -+ inode = d_inode(cpg.dentry); -+ cpg.bsrc = au_fbtop(file); -+ err = au_test_ro(sb, cpg.bsrc, inode); -+ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) { -+ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE, -+ /*flags*/0); -+ goto out; -+ } -+ -+ /* need to cpup or reopen */ -+ parent = dget_parent(cpg.dentry); -+ di_write_lock_parent(parent); -+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry); -+ cpg.bdst = err; -+ if (unlikely(err < 0)) -+ goto out_dgrade; -+ err = 0; -+ -+ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) { -+ err = au_cpup_dirs(cpg.dentry, cpg.bdst); -+ if (unlikely(err)) -+ goto out_dgrade; -+ } -+ -+ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (unlikely(err)) -+ goto out_dgrade; -+ -+ dbtop = au_dbtop(cpg.dentry); -+ if (dbtop <= cpg.bdst) -+ cpg.bsrc = cpg.bdst; -+ -+ if (dbtop <= cpg.bdst /* just reopen */ -+ || !d_unhashed(cpg.dentry) /* copyup and reopen */ -+ ) { -+ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0); -+ if (IS_ERR(h_file)) -+ err = PTR_ERR(h_file); -+ else { -+ di_downgrade_lock(parent, AuLock_IR); -+ if (dbtop > cpg.bdst) -+ err = au_sio_cpup_simple(&cpg); -+ if (!err) -+ err = au_reopen_nondir(file); -+ au_h_open_post(cpg.dentry, cpg.bsrc, h_file); -+ } -+ } else { /* copyup as wh and reopen */ -+ /* -+ * since writable hfsplus branch is not supported, -+ * h_open_pre/post() are unnecessary. -+ */ -+ err = au_ready_to_write_wh(file, len, cpg.bdst, pin); -+ di_downgrade_lock(parent, AuLock_IR); -+ } -+ -+ if (!err) { -+ au_pin_set_parent_lflag(pin, /*lflag*/0); -+ goto out_dput; /* success */ -+ } -+ au_unpin(pin); -+ goto out_unlock; -+ -+out_dgrade: -+ di_downgrade_lock(parent, AuLock_IR); -+out_unlock: -+ di_read_unlock(parent, AuLock_IR); -+out_dput: -+ dput(parent); -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_do_flush(struct file *file, fl_owner_t id, -+ int (*flush)(struct file *file, fl_owner_t id)) -+{ -+ int err; -+ struct super_block *sb; -+ struct inode *inode; -+ -+ inode = file_inode(file); -+ sb = inode->i_sb; -+ si_noflush_read_lock(sb); -+ fi_read_lock(file); -+ ii_read_lock_child(inode); -+ -+ err = flush(file, id); -+ au_cpup_attr_timesizes(inode); -+ -+ ii_read_unlock(inode); -+ fi_read_unlock(file); -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_file_refresh_by_inode(struct file *file, int *need_reopen) -+{ -+ int err; -+ struct au_pin pin; -+ struct au_finfo *finfo; -+ struct dentry *parent, *hi_wh; -+ struct inode *inode; -+ struct super_block *sb; -+ struct au_cp_generic cpg = { -+ .dentry = file->f_path.dentry, -+ .bdst = -1, -+ .bsrc = -1, -+ .len = -1, -+ .pin = &pin, -+ .flags = AuCpup_DTIME -+ }; -+ -+ FiMustWriteLock(file); -+ -+ err = 0; -+ finfo = au_fi(file); -+ sb = cpg.dentry->d_sb; -+ inode = d_inode(cpg.dentry); -+ cpg.bdst = au_ibtop(inode); -+ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry)) -+ goto out; -+ -+ parent = dget_parent(cpg.dentry); -+ if (au_test_ro(sb, cpg.bdst, inode)) { -+ di_read_lock_parent(parent, !AuLock_IR); -+ err = AuWbrCopyup(au_sbi(sb), cpg.dentry); -+ cpg.bdst = err; -+ di_read_unlock(parent, !AuLock_IR); -+ if (unlikely(err < 0)) -+ goto out_parent; -+ err = 0; -+ } -+ -+ di_read_lock_parent(parent, AuLock_IR); -+ hi_wh = au_hi_wh(inode, cpg.bdst); -+ if (!S_ISDIR(inode->i_mode) -+ && au_opt_test(au_mntflags(sb), PLINK) -+ && au_plink_test(inode) -+ && !d_unhashed(cpg.dentry) -+ && cpg.bdst < au_dbtop(cpg.dentry)) { -+ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ /* always superio. */ -+ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (!err) { -+ err = au_sio_cpup_simple(&cpg); -+ au_unpin(&pin); -+ } -+ } else if (hi_wh) { -+ /* already copied-up after unlink */ -+ err = au_reopen_wh(file, cpg.bdst, hi_wh); -+ *need_reopen = 0; -+ } -+ -+out_unlock: -+ di_read_unlock(parent, AuLock_IR); -+out_parent: -+ dput(parent); -+out: -+ return err; -+} -+ -+static void au_do_refresh_dir(struct file *file) -+{ -+ aufs_bindex_t bindex, bbot, new_bindex, brid; -+ struct au_hfile *p, tmp, *q; -+ struct au_finfo *finfo; -+ struct super_block *sb; -+ struct au_fidir *fidir; -+ -+ FiMustWriteLock(file); -+ -+ sb = file->f_path.dentry->d_sb; -+ finfo = au_fi(file); -+ fidir = finfo->fi_hdir; -+ AuDebugOn(!fidir); -+ p = fidir->fd_hfile + finfo->fi_btop; -+ brid = p->hf_br->br_id; -+ bbot = fidir->fd_bbot; -+ for (bindex = finfo->fi_btop; bindex <= bbot; bindex++, p++) { -+ if (!p->hf_file) -+ continue; -+ -+ new_bindex = au_br_index(sb, p->hf_br->br_id); -+ if (new_bindex == bindex) -+ continue; -+ if (new_bindex < 0) { -+ au_set_h_fptr(file, bindex, NULL); -+ continue; -+ } -+ -+ /* swap two lower inode, and loop again */ -+ q = fidir->fd_hfile + new_bindex; -+ tmp = *q; -+ *q = *p; -+ *p = tmp; -+ if (tmp.hf_file) { -+ bindex--; -+ p--; -+ } -+ } -+ -+ p = fidir->fd_hfile; -+ if (!au_test_mmapped(file) && !d_unlinked(file->f_path.dentry)) { -+ bbot = au_sbbot(sb); -+ for (finfo->fi_btop = 0; finfo->fi_btop <= bbot; -+ finfo->fi_btop++, p++) -+ if (p->hf_file) { -+ if (file_inode(p->hf_file)) -+ break; -+ au_hfput(p, /*execed*/0); -+ } -+ } else { -+ bbot = au_br_index(sb, brid); -+ for (finfo->fi_btop = 0; finfo->fi_btop < bbot; -+ finfo->fi_btop++, p++) -+ if (p->hf_file) -+ au_hfput(p, /*execed*/0); -+ bbot = au_sbbot(sb); -+ } -+ -+ p = fidir->fd_hfile + bbot; -+ for (fidir->fd_bbot = bbot; fidir->fd_bbot >= finfo->fi_btop; -+ fidir->fd_bbot--, p--) -+ if (p->hf_file) { -+ if (file_inode(p->hf_file)) -+ break; -+ au_hfput(p, /*execed*/0); -+ } -+ AuDebugOn(fidir->fd_bbot < finfo->fi_btop); -+} -+ -+/* -+ * after branch manipulating, refresh the file. -+ */ -+static int refresh_file(struct file *file, int (*reopen)(struct file *file)) -+{ -+ int err, need_reopen, nbr; -+ aufs_bindex_t bbot, bindex; -+ struct dentry *dentry; -+ struct super_block *sb; -+ struct au_finfo *finfo; -+ struct au_hfile *hfile; -+ -+ dentry = file->f_path.dentry; -+ sb = dentry->d_sb; -+ nbr = au_sbbot(sb) + 1; -+ finfo = au_fi(file); -+ if (!finfo->fi_hdir) { -+ hfile = &finfo->fi_htop; -+ AuDebugOn(!hfile->hf_file); -+ bindex = au_br_index(sb, hfile->hf_br->br_id); -+ AuDebugOn(bindex < 0); -+ if (bindex != finfo->fi_btop) -+ au_set_fbtop(file, bindex); -+ } else { -+ err = au_fidir_realloc(finfo, nbr, /*may_shrink*/0); -+ if (unlikely(err)) -+ goto out; -+ au_do_refresh_dir(file); -+ } -+ -+ err = 0; -+ need_reopen = 1; -+ if (!au_test_mmapped(file)) -+ err = au_file_refresh_by_inode(file, &need_reopen); -+ if (finfo->fi_hdir) -+ /* harmless if err */ -+ au_fidir_realloc(finfo, nbr, /*may_shrink*/1); -+ if (!err && need_reopen && !d_unlinked(dentry)) -+ err = reopen(file); -+ if (!err) { -+ au_update_figen(file); -+ goto out; /* success */ -+ } -+ -+ /* error, close all lower files */ -+ if (finfo->fi_hdir) { -+ bbot = au_fbbot_dir(file); -+ for (bindex = au_fbtop(file); bindex <= bbot; bindex++) -+ au_set_h_fptr(file, bindex, NULL); -+ } -+ -+out: -+ return err; -+} -+ -+/* common function to regular file and dir */ -+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), -+ int wlock, unsigned int fi_lsc) -+{ -+ int err; -+ unsigned int sigen, figen; -+ aufs_bindex_t btop; -+ unsigned char pseudo_link; -+ struct dentry *dentry; -+ struct inode *inode; -+ -+ err = 0; -+ dentry = file->f_path.dentry; -+ inode = d_inode(dentry); -+ sigen = au_sigen(dentry->d_sb); -+ fi_write_lock_nested(file, fi_lsc); -+ figen = au_figen(file); -+ if (!fi_lsc) -+ di_write_lock_child(dentry); -+ else -+ di_write_lock_child2(dentry); -+ btop = au_dbtop(dentry); -+ pseudo_link = (btop != au_ibtop(inode)); -+ if (sigen == figen && !pseudo_link && au_fbtop(file) == btop) { -+ if (!wlock) { -+ di_downgrade_lock(dentry, AuLock_IR); -+ fi_downgrade_lock(file); -+ } -+ goto out; /* success */ -+ } -+ -+ AuDbg("sigen %d, figen %d\n", sigen, figen); -+ if (au_digen_test(dentry, sigen)) { -+ err = au_reval_dpath(dentry, sigen); -+ AuDebugOn(!err && au_digen_test(dentry, sigen)); -+ } -+ -+ if (!err) -+ err = refresh_file(file, reopen); -+ if (!err) { -+ if (!wlock) { -+ di_downgrade_lock(dentry, AuLock_IR); -+ fi_downgrade_lock(file); -+ } -+ } else { -+ di_write_unlock(dentry); -+ fi_write_unlock(file); -+ } -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* cf. aufs_nopage() */ -+/* for madvise(2) */ -+static int aufs_readpage(struct file *file __maybe_unused, struct page *page) -+{ -+ unlock_page(page); -+ return 0; -+} -+ -+/* it will never be called, but necessary to support O_DIRECT */ -+static ssize_t aufs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) -+{ BUG(); return 0; } -+ -+/* they will never be called. */ -+#ifdef CONFIG_AUFS_DEBUG -+static int aufs_write_begin(struct file *file, struct address_space *mapping, -+ loff_t pos, unsigned len, unsigned flags, -+ struct page **pagep, void **fsdata) -+{ AuUnsupport(); return 0; } -+static int aufs_write_end(struct file *file, struct address_space *mapping, -+ loff_t pos, unsigned len, unsigned copied, -+ struct page *page, void *fsdata) -+{ AuUnsupport(); return 0; } -+static int aufs_writepage(struct page *page, struct writeback_control *wbc) -+{ AuUnsupport(); return 0; } -+ -+static int aufs_set_page_dirty(struct page *page) -+{ AuUnsupport(); return 0; } -+static void aufs_invalidatepage(struct page *page, unsigned int offset, -+ unsigned int length) -+{ AuUnsupport(); } -+static int aufs_releasepage(struct page *page, gfp_t gfp) -+{ AuUnsupport(); return 0; } -+#if 0 /* called by memory compaction regardless file */ -+static int aufs_migratepage(struct address_space *mapping, struct page *newpage, -+ struct page *page, enum migrate_mode mode) -+{ AuUnsupport(); return 0; } -+#endif -+static bool aufs_isolate_page(struct page *page, isolate_mode_t mode) -+{ AuUnsupport(); return true; } -+static void aufs_putback_page(struct page *page) -+{ AuUnsupport(); } -+static int aufs_launder_page(struct page *page) -+{ AuUnsupport(); return 0; } -+static int aufs_is_partially_uptodate(struct page *page, -+ unsigned long from, -+ unsigned long count) -+{ AuUnsupport(); return 0; } -+static void aufs_is_dirty_writeback(struct page *page, bool *dirty, -+ bool *writeback) -+{ AuUnsupport(); } -+static int aufs_error_remove_page(struct address_space *mapping, -+ struct page *page) -+{ AuUnsupport(); return 0; } -+static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file, -+ sector_t *span) -+{ AuUnsupport(); return 0; } -+static void aufs_swap_deactivate(struct file *file) -+{ AuUnsupport(); } -+#endif /* CONFIG_AUFS_DEBUG */ -+ -+const struct address_space_operations aufs_aop = { -+ .readpage = aufs_readpage, -+ .direct_IO = aufs_direct_IO, -+#ifdef CONFIG_AUFS_DEBUG -+ .writepage = aufs_writepage, -+ /* no writepages, because of writepage */ -+ .set_page_dirty = aufs_set_page_dirty, -+ /* no readpages, because of readpage */ -+ .write_begin = aufs_write_begin, -+ .write_end = aufs_write_end, -+ /* no bmap, no block device */ -+ .invalidatepage = aufs_invalidatepage, -+ .releasepage = aufs_releasepage, -+ /* is fallback_migrate_page ok? */ -+ /* .migratepage = aufs_migratepage, */ -+ .isolate_page = aufs_isolate_page, -+ .putback_page = aufs_putback_page, -+ .launder_page = aufs_launder_page, -+ .is_partially_uptodate = aufs_is_partially_uptodate, -+ .is_dirty_writeback = aufs_is_dirty_writeback, -+ .error_remove_page = aufs_error_remove_page, -+ .swap_activate = aufs_swap_activate, -+ .swap_deactivate = aufs_swap_deactivate -+#endif /* CONFIG_AUFS_DEBUG */ -+}; -diff --git a/fs/aufs/file.h b/fs/aufs/file.h -new file mode 100644 -index 000000000..11bc65480 ---- /dev/null -+++ b/fs/aufs/file.h -@@ -0,0 +1,341 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * file operations -+ */ -+ -+#ifndef __AUFS_FILE_H__ -+#define __AUFS_FILE_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+#include "rwsem.h" -+ -+struct au_branch; -+struct au_hfile { -+ struct file *hf_file; -+ struct au_branch *hf_br; -+}; -+ -+struct au_vdir; -+struct au_fidir { -+ aufs_bindex_t fd_bbot; -+ aufs_bindex_t fd_nent; -+ struct au_vdir *fd_vdir_cache; -+ struct au_hfile fd_hfile[]; -+}; -+ -+static inline int au_fidir_sz(int nent) -+{ -+ AuDebugOn(nent < 0); -+ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent; -+} -+ -+struct au_finfo { -+ atomic_t fi_generation; -+ -+ struct au_rwsem fi_rwsem; -+ aufs_bindex_t fi_btop; -+ -+ /* do not union them */ -+ struct { /* for non-dir */ -+ struct au_hfile fi_htop; -+ atomic_t fi_mmapped; -+ }; -+ struct au_fidir *fi_hdir; /* for dir only */ -+ -+ struct hlist_bl_node fi_hlist; -+ struct file *fi_file; /* very ugly */ -+} ____cacheline_aligned_in_smp; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* file.c */ -+extern const struct address_space_operations aufs_aop; -+unsigned int au_file_roflags(unsigned int flags); -+struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, -+ struct file *file, int force_wr); -+struct au_do_open_args { -+ int aopen; -+ int (*open)(struct file *file, int flags, -+ struct file *h_file); -+ struct au_fidir *fidir; -+ struct file *h_file; -+}; -+int au_do_open(struct file *file, struct au_do_open_args *args); -+int au_reopen_nondir(struct file *file); -+struct au_pin; -+int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin); -+int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), -+ int wlock, unsigned int fi_lsc); -+int au_do_flush(struct file *file, fl_owner_t id, -+ int (*flush)(struct file *file, fl_owner_t id)); -+ -+/* poll.c */ -+#ifdef CONFIG_AUFS_POLL -+__poll_t aufs_poll(struct file *file, struct poll_table_struct *pt); -+#endif -+ -+#ifdef CONFIG_AUFS_BR_HFSPLUS -+/* hfsplus.c */ -+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex, -+ int force_wr); -+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex, -+ struct file *h_file); -+#else -+AuStub(struct file *, au_h_open_pre, return NULL, struct dentry *dentry, -+ aufs_bindex_t bindex, int force_wr) -+AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex, -+ struct file *h_file); -+#endif -+ -+/* f_op.c */ -+extern const struct file_operations aufs_file_fop; -+int au_do_open_nondir(struct file *file, int flags, struct file *h_file); -+int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file); -+struct file *au_read_pre(struct file *file, int keep_fi, unsigned int lsc); -+ -+/* finfo.c */ -+void au_hfput(struct au_hfile *hf, int execed); -+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, -+ struct file *h_file); -+ -+void au_update_figen(struct file *file); -+struct au_fidir *au_fidir_alloc(struct super_block *sb); -+int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink); -+ -+void au_fi_init_once(void *_fi); -+void au_finfo_fin(struct file *file); -+int au_finfo_init(struct file *file, struct au_fidir *fidir); -+ -+/* ioctl.c */ -+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg); -+#ifdef CONFIG_COMPAT -+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd, -+ unsigned long arg); -+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd, -+ unsigned long arg); -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct au_finfo *au_fi(struct file *file) -+{ -+ return file->private_data; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define fi_read_lock(f) au_rw_read_lock(&au_fi(f)->fi_rwsem) -+#define fi_write_lock(f) au_rw_write_lock(&au_fi(f)->fi_rwsem) -+#define fi_read_trylock(f) au_rw_read_trylock(&au_fi(f)->fi_rwsem) -+#define fi_write_trylock(f) au_rw_write_trylock(&au_fi(f)->fi_rwsem) -+/* -+#define fi_read_trylock_nested(f) \ -+ au_rw_read_trylock_nested(&au_fi(f)->fi_rwsem) -+#define fi_write_trylock_nested(f) \ -+ au_rw_write_trylock_nested(&au_fi(f)->fi_rwsem) -+*/ -+ -+#define fi_read_unlock(f) au_rw_read_unlock(&au_fi(f)->fi_rwsem) -+#define fi_write_unlock(f) au_rw_write_unlock(&au_fi(f)->fi_rwsem) -+#define fi_downgrade_lock(f) au_rw_dgrade_lock(&au_fi(f)->fi_rwsem) -+ -+/* lock subclass for finfo */ -+enum { -+ AuLsc_FI_1, -+ AuLsc_FI_2 -+}; -+ -+static inline void fi_read_lock_nested(struct file *f, unsigned int lsc) -+{ -+ au_rw_read_lock_nested(&au_fi(f)->fi_rwsem, lsc); -+} -+ -+static inline void fi_write_lock_nested(struct file *f, unsigned int lsc) -+{ -+ au_rw_write_lock_nested(&au_fi(f)->fi_rwsem, lsc); -+} -+ -+/* -+ * fi_read_lock_1, fi_write_lock_1, -+ * fi_read_lock_2, fi_write_lock_2 -+ */ -+#define AuReadLockFunc(name) \ -+static inline void fi_read_lock_##name(struct file *f) \ -+{ fi_read_lock_nested(f, AuLsc_FI_##name); } -+ -+#define AuWriteLockFunc(name) \ -+static inline void fi_write_lock_##name(struct file *f) \ -+{ fi_write_lock_nested(f, AuLsc_FI_##name); } -+ -+#define AuRWLockFuncs(name) \ -+ AuReadLockFunc(name) \ -+ AuWriteLockFunc(name) -+ -+AuRWLockFuncs(1); -+AuRWLockFuncs(2); -+ -+#undef AuReadLockFunc -+#undef AuWriteLockFunc -+#undef AuRWLockFuncs -+ -+#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem) -+#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem) -+#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem) -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* todo: hard/soft set? */ -+static inline aufs_bindex_t au_fbtop(struct file *file) -+{ -+ FiMustAnyLock(file); -+ return au_fi(file)->fi_btop; -+} -+ -+static inline aufs_bindex_t au_fbbot_dir(struct file *file) -+{ -+ FiMustAnyLock(file); -+ AuDebugOn(!au_fi(file)->fi_hdir); -+ return au_fi(file)->fi_hdir->fd_bbot; -+} -+ -+static inline struct au_vdir *au_fvdir_cache(struct file *file) -+{ -+ FiMustAnyLock(file); -+ AuDebugOn(!au_fi(file)->fi_hdir); -+ return au_fi(file)->fi_hdir->fd_vdir_cache; -+} -+ -+static inline void au_set_fbtop(struct file *file, aufs_bindex_t bindex) -+{ -+ FiMustWriteLock(file); -+ au_fi(file)->fi_btop = bindex; -+} -+ -+static inline void au_set_fbbot_dir(struct file *file, aufs_bindex_t bindex) -+{ -+ FiMustWriteLock(file); -+ AuDebugOn(!au_fi(file)->fi_hdir); -+ au_fi(file)->fi_hdir->fd_bbot = bindex; -+} -+ -+static inline void au_set_fvdir_cache(struct file *file, -+ struct au_vdir *vdir_cache) -+{ -+ FiMustWriteLock(file); -+ AuDebugOn(!au_fi(file)->fi_hdir); -+ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache; -+} -+ -+static inline struct file *au_hf_top(struct file *file) -+{ -+ FiMustAnyLock(file); -+ AuDebugOn(au_fi(file)->fi_hdir); -+ return au_fi(file)->fi_htop.hf_file; -+} -+ -+static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex) -+{ -+ FiMustAnyLock(file); -+ AuDebugOn(!au_fi(file)->fi_hdir); -+ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file; -+} -+ -+/* todo: memory barrier? */ -+static inline unsigned int au_figen(struct file *f) -+{ -+ return atomic_read(&au_fi(f)->fi_generation); -+} -+ -+static inline void au_set_mmapped(struct file *f) -+{ -+ if (atomic_inc_return(&au_fi(f)->fi_mmapped)) -+ return; -+ pr_warn("fi_mmapped wrapped around\n"); -+ while (!atomic_inc_return(&au_fi(f)->fi_mmapped)) -+ ; -+} -+ -+static inline void au_unset_mmapped(struct file *f) -+{ -+ atomic_dec(&au_fi(f)->fi_mmapped); -+} -+ -+static inline int au_test_mmapped(struct file *f) -+{ -+ return atomic_read(&au_fi(f)->fi_mmapped); -+} -+ -+/* customize vma->vm_file */ -+ -+static inline void au_do_vm_file_reset(struct vm_area_struct *vma, -+ struct file *file) -+{ -+ struct file *f; -+ -+ f = vma->vm_file; -+ get_file(file); -+ vma->vm_file = file; -+ fput(f); -+} -+ -+#ifdef CONFIG_MMU -+#define AuDbgVmRegion(file, vma) do {} while (0) -+ -+static inline void au_vm_file_reset(struct vm_area_struct *vma, -+ struct file *file) -+{ -+ au_do_vm_file_reset(vma, file); -+} -+#else -+#define AuDbgVmRegion(file, vma) \ -+ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file)) -+ -+static inline void au_vm_file_reset(struct vm_area_struct *vma, -+ struct file *file) -+{ -+ struct file *f; -+ -+ au_do_vm_file_reset(vma, file); -+ f = vma->vm_region->vm_file; -+ get_file(file); -+ vma->vm_region->vm_file = file; -+ fput(f); -+} -+#endif /* CONFIG_MMU */ -+ -+/* handle vma->vm_prfile */ -+static inline void au_vm_prfile_set(struct vm_area_struct *vma, -+ struct file *file) -+{ -+ get_file(file); -+ vma->vm_prfile = file; -+#ifndef CONFIG_MMU -+ get_file(file); -+ vma->vm_region->vm_prfile = file; -+#endif -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_FILE_H__ */ -diff --git a/fs/aufs/finfo.c b/fs/aufs/finfo.c -new file mode 100644 -index 000000000..44636ce6c ---- /dev/null -+++ b/fs/aufs/finfo.c -@@ -0,0 +1,149 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * file private data -+ */ -+ -+#include "aufs.h" -+ -+void au_hfput(struct au_hfile *hf, int execed) -+{ -+ if (execed) -+ allow_write_access(hf->hf_file); -+ fput(hf->hf_file); -+ hf->hf_file = NULL; -+ au_lcnt_dec(&hf->hf_br->br_nfiles); -+ hf->hf_br = NULL; -+} -+ -+void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val) -+{ -+ struct au_finfo *finfo = au_fi(file); -+ struct au_hfile *hf; -+ struct au_fidir *fidir; -+ -+ fidir = finfo->fi_hdir; -+ if (!fidir) { -+ AuDebugOn(finfo->fi_btop != bindex); -+ hf = &finfo->fi_htop; -+ } else -+ hf = fidir->fd_hfile + bindex; -+ -+ if (hf && hf->hf_file) -+ au_hfput(hf, vfsub_file_execed(file)); -+ if (val) { -+ FiMustWriteLock(file); -+ AuDebugOn(IS_ERR_OR_NULL(file->f_path.dentry)); -+ hf->hf_file = val; -+ hf->hf_br = au_sbr(file->f_path.dentry->d_sb, bindex); -+ } -+} -+ -+void au_update_figen(struct file *file) -+{ -+ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_path.dentry)); -+ /* smp_mb(); */ /* atomic_set */ -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_fidir *au_fidir_alloc(struct super_block *sb) -+{ -+ struct au_fidir *fidir; -+ int nbr; -+ -+ nbr = au_sbbot(sb) + 1; -+ if (nbr < 2) -+ nbr = 2; /* initial allocate for 2 branches */ -+ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS); -+ if (fidir) { -+ fidir->fd_bbot = -1; -+ fidir->fd_nent = nbr; -+ } -+ -+ return fidir; -+} -+ -+int au_fidir_realloc(struct au_finfo *finfo, int nbr, int may_shrink) -+{ -+ int err; -+ struct au_fidir *fidir, *p; -+ -+ AuRwMustWriteLock(&finfo->fi_rwsem); -+ fidir = finfo->fi_hdir; -+ AuDebugOn(!fidir); -+ -+ err = -ENOMEM; -+ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr), -+ GFP_NOFS, may_shrink); -+ if (p) { -+ p->fd_nent = nbr; -+ finfo->fi_hdir = p; -+ err = 0; -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_finfo_fin(struct file *file) -+{ -+ struct au_finfo *finfo; -+ -+ au_lcnt_dec(&au_sbi(file->f_path.dentry->d_sb)->si_nfiles); -+ -+ finfo = au_fi(file); -+ AuDebugOn(finfo->fi_hdir); -+ AuRwDestroy(&finfo->fi_rwsem); -+ au_cache_free_finfo(finfo); -+} -+ -+void au_fi_init_once(void *_finfo) -+{ -+ struct au_finfo *finfo = _finfo; -+ -+ au_rw_init(&finfo->fi_rwsem); -+} -+ -+int au_finfo_init(struct file *file, struct au_fidir *fidir) -+{ -+ int err; -+ struct au_finfo *finfo; -+ struct dentry *dentry; -+ -+ err = -ENOMEM; -+ dentry = file->f_path.dentry; -+ finfo = au_cache_alloc_finfo(); -+ if (unlikely(!finfo)) -+ goto out; -+ -+ err = 0; -+ au_lcnt_inc(&au_sbi(dentry->d_sb)->si_nfiles); -+ au_rw_write_lock(&finfo->fi_rwsem); -+ finfo->fi_btop = -1; -+ finfo->fi_hdir = fidir; -+ atomic_set(&finfo->fi_generation, au_digen(dentry)); -+ /* smp_mb(); */ /* atomic_set */ -+ -+ file->private_data = finfo; -+ -+out: -+ return err; -+} -diff --git a/fs/aufs/fstype.h b/fs/aufs/fstype.h -new file mode 100644 -index 000000000..4e295869b ---- /dev/null -+++ b/fs/aufs/fstype.h -@@ -0,0 +1,401 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * judging filesystem type -+ */ -+ -+#ifndef __AUFS_FSTYPE_H__ -+#define __AUFS_FSTYPE_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+ -+static inline int au_test_aufs(struct super_block *sb) -+{ -+ return sb->s_magic == AUFS_SUPER_MAGIC; -+} -+ -+static inline const char *au_sbtype(struct super_block *sb) -+{ -+ return sb->s_type->name; -+} -+ -+static inline int au_test_iso9660(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_ISO9660_FS) -+ return sb->s_magic == ISOFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_romfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_ROMFS_FS) -+ return sb->s_magic == ROMFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_cramfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_CRAMFS) -+ return sb->s_magic == CRAMFS_MAGIC; -+#endif -+ return 0; -+} -+ -+static inline int au_test_nfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_NFS_FS) -+ return sb->s_magic == NFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_fuse(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_FUSE_FS) -+ return sb->s_magic == FUSE_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_xfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_XFS_FS) -+ return sb->s_magic == XFS_SB_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_tmpfs(struct super_block *sb __maybe_unused) -+{ -+#ifdef CONFIG_TMPFS -+ return sb->s_magic == TMPFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_ECRYPT_FS) -+ return !strcmp(au_sbtype(sb), "ecryptfs"); -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_ramfs(struct super_block *sb) -+{ -+ return sb->s_magic == RAMFS_MAGIC; -+} -+ -+static inline int au_test_ubifs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_UBIFS_FS) -+ return sb->s_magic == UBIFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_procfs(struct super_block *sb __maybe_unused) -+{ -+#ifdef CONFIG_PROC_FS -+ return sb->s_magic == PROC_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_sysfs(struct super_block *sb __maybe_unused) -+{ -+#ifdef CONFIG_SYSFS -+ return sb->s_magic == SYSFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_configfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_CONFIGFS_FS) -+ return sb->s_magic == CONFIGFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_minix(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_MINIX_FS) -+ return sb->s_magic == MINIX3_SUPER_MAGIC -+ || sb->s_magic == MINIX2_SUPER_MAGIC -+ || sb->s_magic == MINIX2_SUPER_MAGIC2 -+ || sb->s_magic == MINIX_SUPER_MAGIC -+ || sb->s_magic == MINIX_SUPER_MAGIC2; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_fat(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_FAT_FS) -+ return sb->s_magic == MSDOS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_msdos(struct super_block *sb) -+{ -+ return au_test_fat(sb); -+} -+ -+static inline int au_test_vfat(struct super_block *sb) -+{ -+ return au_test_fat(sb); -+} -+ -+static inline int au_test_securityfs(struct super_block *sb __maybe_unused) -+{ -+#ifdef CONFIG_SECURITYFS -+ return sb->s_magic == SECURITYFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_squashfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_SQUASHFS) -+ return sb->s_magic == SQUASHFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_btrfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_BTRFS_FS) -+ return sb->s_magic == BTRFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_xenfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_XENFS) -+ return sb->s_magic == XENFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_debugfs(struct super_block *sb __maybe_unused) -+{ -+#ifdef CONFIG_DEBUG_FS -+ return sb->s_magic == DEBUGFS_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_nilfs(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_NILFS) -+ return sb->s_magic == NILFS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+static inline int au_test_hfsplus(struct super_block *sb __maybe_unused) -+{ -+#if IS_ENABLED(CONFIG_HFSPLUS_FS) -+ return sb->s_magic == HFSPLUS_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * they can't be an aufs branch. -+ */ -+static inline int au_test_fs_unsuppoted(struct super_block *sb) -+{ -+ return -+#ifndef CONFIG_AUFS_BR_RAMFS -+ au_test_ramfs(sb) || -+#endif -+ au_test_procfs(sb) -+ || au_test_sysfs(sb) -+ || au_test_configfs(sb) -+ || au_test_debugfs(sb) -+ || au_test_securityfs(sb) -+ || au_test_xenfs(sb) -+ || au_test_ecryptfs(sb) -+ /* || !strcmp(au_sbtype(sb), "unionfs") */ -+ || au_test_aufs(sb); /* will be supported in next version */ -+} -+ -+static inline int au_test_fs_remote(struct super_block *sb) -+{ -+ return !au_test_tmpfs(sb) -+#ifdef CONFIG_AUFS_BR_RAMFS -+ && !au_test_ramfs(sb) -+#endif -+ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * Note: these functions (below) are created after reading ->getattr() in all -+ * filesystems under linux/fs. it means we have to do so in every update... -+ */ -+ -+/* -+ * some filesystems require getattr to refresh the inode attributes before -+ * referencing. -+ * in most cases, we can rely on the inode attribute in NFS (or every remote fs) -+ * and leave the work for d_revalidate() -+ */ -+static inline int au_test_fs_refresh_iattr(struct super_block *sb) -+{ -+ return au_test_nfs(sb) -+ || au_test_fuse(sb) -+ /* || au_test_btrfs(sb) */ /* untested */ -+ ; -+} -+ -+/* -+ * filesystems which don't maintain i_size or i_blocks. -+ */ -+static inline int au_test_fs_bad_iattr_size(struct super_block *sb) -+{ -+ return au_test_xfs(sb) -+ || au_test_btrfs(sb) -+ || au_test_ubifs(sb) -+ || au_test_hfsplus(sb) /* maintained, but incorrect */ -+ /* || au_test_minix(sb) */ /* untested */ -+ ; -+} -+ -+/* -+ * filesystems which don't store the correct value in some of their inode -+ * attributes. -+ */ -+static inline int au_test_fs_bad_iattr(struct super_block *sb) -+{ -+ return au_test_fs_bad_iattr_size(sb) -+ || au_test_fat(sb) -+ || au_test_msdos(sb) -+ || au_test_vfat(sb); -+} -+ -+/* they don't check i_nlink in link(2) */ -+static inline int au_test_fs_no_limit_nlink(struct super_block *sb) -+{ -+ return au_test_tmpfs(sb) -+#ifdef CONFIG_AUFS_BR_RAMFS -+ || au_test_ramfs(sb) -+#endif -+ || au_test_ubifs(sb) -+ || au_test_hfsplus(sb); -+} -+ -+/* -+ * filesystems which sets S_NOATIME and S_NOCMTIME. -+ */ -+static inline int au_test_fs_notime(struct super_block *sb) -+{ -+ return au_test_nfs(sb) -+ || au_test_fuse(sb) -+ || au_test_ubifs(sb) -+ ; -+} -+ -+/* temporary support for i#1 in cramfs */ -+static inline int au_test_fs_unique_ino(struct inode *inode) -+{ -+ if (au_test_cramfs(inode->i_sb)) -+ return inode->i_ino != 1; -+ return 1; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * the filesystem where the xino files placed must support i/o after unlink and -+ * maintain i_size and i_blocks. -+ */ -+static inline int au_test_fs_bad_xino(struct super_block *sb) -+{ -+ return au_test_fs_remote(sb) -+ || au_test_fs_bad_iattr_size(sb) -+ /* don't want unnecessary work for xino */ -+ || au_test_aufs(sb) -+ || au_test_ecryptfs(sb) -+ || au_test_nilfs(sb); -+} -+ -+static inline int au_test_fs_trunc_xino(struct super_block *sb) -+{ -+ return au_test_tmpfs(sb) -+ || au_test_ramfs(sb); -+} -+ -+/* -+ * test if the @sb is real-readonly. -+ */ -+static inline int au_test_fs_rr(struct super_block *sb) -+{ -+ return au_test_squashfs(sb) -+ || au_test_iso9660(sb) -+ || au_test_cramfs(sb) -+ || au_test_romfs(sb); -+} -+ -+/* -+ * test if the @inode is nfs with 'noacl' option -+ * NFS always sets SB_POSIXACL regardless its mount option 'noacl.' -+ */ -+static inline int au_test_nfs_noacl(struct inode *inode) -+{ -+ return au_test_nfs(inode->i_sb) -+ /* && IS_POSIXACL(inode) */ -+ && !nfs_server_capable(inode, NFS_CAP_ACLS); -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_FSTYPE_H__ */ -diff --git a/fs/aufs/hbl.h b/fs/aufs/hbl.h -new file mode 100644 -index 000000000..265d7ab61 ---- /dev/null -+++ b/fs/aufs/hbl.h -@@ -0,0 +1,65 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2017-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * helpers for hlist_bl.h -+ */ -+ -+#ifndef __AUFS_HBL_H__ -+#define __AUFS_HBL_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+static inline void au_hbl_add(struct hlist_bl_node *node, -+ struct hlist_bl_head *hbl) -+{ -+ hlist_bl_lock(hbl); -+ hlist_bl_add_head(node, hbl); -+ hlist_bl_unlock(hbl); -+} -+ -+static inline void au_hbl_del(struct hlist_bl_node *node, -+ struct hlist_bl_head *hbl) -+{ -+ hlist_bl_lock(hbl); -+ hlist_bl_del(node); -+ hlist_bl_unlock(hbl); -+} -+ -+#define au_hbl_for_each(pos, head) \ -+ for (pos = hlist_bl_first(head); \ -+ pos; \ -+ pos = pos->next) -+ -+static inline unsigned long au_hbl_count(struct hlist_bl_head *hbl) -+{ -+ unsigned long cnt; -+ struct hlist_bl_node *pos; -+ -+ cnt = 0; -+ hlist_bl_lock(hbl); -+ au_hbl_for_each(pos, hbl) -+ cnt++; -+ hlist_bl_unlock(hbl); -+ return cnt; -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_HBL_H__ */ -diff --git a/fs/aufs/hfsnotify.c b/fs/aufs/hfsnotify.c -new file mode 100644 -index 000000000..7ec50daf7 ---- /dev/null -+++ b/fs/aufs/hfsnotify.c -@@ -0,0 +1,289 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * fsnotify for the lower directories -+ */ -+ -+#include "aufs.h" -+ -+/* FS_IN_IGNORED is unnecessary */ -+static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE -+ | FS_CREATE | FS_EVENT_ON_CHILD); -+static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq); -+static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0); -+ -+static void au_hfsn_free_mark(struct fsnotify_mark *mark) -+{ -+ struct au_hnotify *hn = container_of(mark, struct au_hnotify, -+ hn_mark); -+ /* AuDbg("here\n"); */ -+ au_cache_free_hnotify(hn); -+ smp_mb__before_atomic(); /* for atomic64_dec */ -+ if (atomic64_dec_and_test(&au_hfsn_ifree)) -+ wake_up(&au_hfsn_wq); -+} -+ -+static int au_hfsn_alloc(struct au_hinode *hinode) -+{ -+ int err; -+ struct au_hnotify *hn; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct fsnotify_mark *mark; -+ aufs_bindex_t bindex; -+ -+ hn = hinode->hi_notify; -+ sb = hn->hn_aufs_inode->i_sb; -+ bindex = au_br_index(sb, hinode->hi_id); -+ br = au_sbr(sb, bindex); -+ AuDebugOn(!br->br_hfsn); -+ -+ mark = &hn->hn_mark; -+ fsnotify_init_mark(mark, br->br_hfsn->hfsn_group); -+ mark->mask = AuHfsnMask; -+ /* -+ * by udba rename or rmdir, aufs assign a new inode to the known -+ * h_inode, so specify 1 to allow dups. -+ */ -+ lockdep_off(); -+ err = fsnotify_add_inode_mark(mark, hinode->hi_inode, /*allow_dups*/1); -+ lockdep_on(); -+ -+ return err; -+} -+ -+static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn) -+{ -+ struct fsnotify_mark *mark; -+ unsigned long long ull; -+ struct fsnotify_group *group; -+ -+ ull = atomic64_inc_return(&au_hfsn_ifree); -+ BUG_ON(!ull); -+ -+ mark = &hn->hn_mark; -+ spin_lock(&mark->lock); -+ group = mark->group; -+ fsnotify_get_group(group); -+ spin_unlock(&mark->lock); -+ lockdep_off(); -+ fsnotify_destroy_mark(mark, group); -+ fsnotify_put_mark(mark); -+ fsnotify_put_group(group); -+ lockdep_on(); -+ -+ /* free hn by myself */ -+ return 0; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_hfsn_ctl(struct au_hinode *hinode, int do_set) -+{ -+ struct fsnotify_mark *mark; -+ -+ mark = &hinode->hi_notify->hn_mark; -+ spin_lock(&mark->lock); -+ if (do_set) { -+ AuDebugOn(mark->mask & AuHfsnMask); -+ mark->mask |= AuHfsnMask; -+ } else { -+ AuDebugOn(!(mark->mask & AuHfsnMask)); -+ mark->mask &= ~AuHfsnMask; -+ } -+ spin_unlock(&mark->lock); -+ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */ -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* #define AuDbgHnotify */ -+#ifdef AuDbgHnotify -+static char *au_hfsn_name(u32 mask) -+{ -+#ifdef CONFIG_AUFS_DEBUG -+#define test_ret(flag) \ -+ do { \ -+ if (mask & flag) \ -+ return #flag; \ -+ } while (0) -+ test_ret(FS_ACCESS); -+ test_ret(FS_MODIFY); -+ test_ret(FS_ATTRIB); -+ test_ret(FS_CLOSE_WRITE); -+ test_ret(FS_CLOSE_NOWRITE); -+ test_ret(FS_OPEN); -+ test_ret(FS_MOVED_FROM); -+ test_ret(FS_MOVED_TO); -+ test_ret(FS_CREATE); -+ test_ret(FS_DELETE); -+ test_ret(FS_DELETE_SELF); -+ test_ret(FS_MOVE_SELF); -+ test_ret(FS_UNMOUNT); -+ test_ret(FS_Q_OVERFLOW); -+ test_ret(FS_IN_IGNORED); -+ test_ret(FS_ISDIR); -+ test_ret(FS_IN_ONESHOT); -+ test_ret(FS_EVENT_ON_CHILD); -+ return ""; -+#undef test_ret -+#else -+ return "??"; -+#endif -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_hfsn_free_group(struct fsnotify_group *group) -+{ -+ struct au_br_hfsnotify *hfsn = group->private; -+ -+ /* AuDbg("here\n"); */ -+ kfree(hfsn); -+} -+ -+static int au_hfsn_handle_event(struct fsnotify_group *group, -+ struct inode *inode, -+ u32 mask, const void *data, int data_type, -+ const unsigned char *file_name, u32 cookie, -+ struct fsnotify_iter_info *iter_info) -+{ -+ int err; -+ struct au_hnotify *hnotify; -+ struct inode *h_dir, *h_inode; -+ struct qstr h_child_qstr = QSTR_INIT(file_name, strlen(file_name)); -+ struct fsnotify_mark *inode_mark; -+ -+ AuDebugOn(data_type != FSNOTIFY_EVENT_INODE); -+ -+ err = 0; -+ /* if FS_UNMOUNT happens, there must be another bug */ -+ AuDebugOn(mask & FS_UNMOUNT); -+ if (mask & (FS_IN_IGNORED | FS_UNMOUNT)) -+ goto out; -+ -+ h_dir = inode; -+ h_inode = NULL; -+#ifdef AuDbgHnotify -+ au_debug_on(); -+ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1 -+ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) { -+ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n", -+ h_dir->i_ino, mask, au_hfsn_name(mask), -+ AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0); -+ /* WARN_ON(1); */ -+ } -+ au_debug_off(); -+#endif -+ -+ inode_mark = fsnotify_iter_inode_mark(iter_info); -+ AuDebugOn(!inode_mark); -+ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark); -+ err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode); -+ -+out: -+ return err; -+} -+ -+static struct fsnotify_ops au_hfsn_ops = { -+ .handle_event = au_hfsn_handle_event, -+ .free_group_priv = au_hfsn_free_group, -+ .free_mark = au_hfsn_free_mark -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_hfsn_fin_br(struct au_branch *br) -+{ -+ struct au_br_hfsnotify *hfsn; -+ -+ hfsn = br->br_hfsn; -+ if (hfsn) { -+ lockdep_off(); -+ fsnotify_put_group(hfsn->hfsn_group); -+ lockdep_on(); -+ } -+} -+ -+static int au_hfsn_init_br(struct au_branch *br, int perm) -+{ -+ int err; -+ struct fsnotify_group *group; -+ struct au_br_hfsnotify *hfsn; -+ -+ err = 0; -+ br->br_hfsn = NULL; -+ if (!au_br_hnotifyable(perm)) -+ goto out; -+ -+ err = -ENOMEM; -+ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS); -+ if (unlikely(!hfsn)) -+ goto out; -+ -+ err = 0; -+ group = fsnotify_alloc_group(&au_hfsn_ops); -+ if (IS_ERR(group)) { -+ err = PTR_ERR(group); -+ pr_err("fsnotify_alloc_group() failed, %d\n", err); -+ goto out_hfsn; -+ } -+ -+ group->private = hfsn; -+ hfsn->hfsn_group = group; -+ br->br_hfsn = hfsn; -+ goto out; /* success */ -+ -+out_hfsn: -+ kfree(hfsn); -+out: -+ return err; -+} -+ -+static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm) -+{ -+ int err; -+ -+ err = 0; -+ if (!br->br_hfsn) -+ err = au_hfsn_init_br(br, perm); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_hfsn_fin(void) -+{ -+ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree)); -+ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree)); -+} -+ -+const struct au_hnotify_op au_hnotify_op = { -+ .ctl = au_hfsn_ctl, -+ .alloc = au_hfsn_alloc, -+ .free = au_hfsn_free, -+ -+ .fin = au_hfsn_fin, -+ -+ .reset_br = au_hfsn_reset_br, -+ .fin_br = au_hfsn_fin_br, -+ .init_br = au_hfsn_init_br -+}; -diff --git a/fs/aufs/hfsplus.c b/fs/aufs/hfsplus.c -new file mode 100644 -index 000000000..b1f59970d ---- /dev/null -+++ b/fs/aufs/hfsplus.c -@@ -0,0 +1,60 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2010-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * special support for filesystems which acquires an inode mutex -+ * at final closing a file, eg, hfsplus. -+ * -+ * This trick is very simple and stupid, just to open the file before really -+ * necessary open to tell hfsplus that this is not the final closing. -+ * The caller should call au_h_open_pre() after acquiring the inode mutex, -+ * and au_h_open_post() after releasing it. -+ */ -+ -+#include "aufs.h" -+ -+struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex, -+ int force_wr) -+{ -+ struct file *h_file; -+ struct dentry *h_dentry; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ AuDebugOn(!h_dentry); -+ AuDebugOn(d_is_negative(h_dentry)); -+ -+ h_file = NULL; -+ if (au_test_hfsplus(h_dentry->d_sb) -+ && d_is_reg(h_dentry)) -+ h_file = au_h_open(dentry, bindex, -+ O_RDONLY | O_NOATIME | O_LARGEFILE, -+ /*file*/NULL, force_wr); -+ return h_file; -+} -+ -+void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex, -+ struct file *h_file) -+{ -+ struct au_branch *br; -+ -+ if (h_file) { -+ fput(h_file); -+ br = au_sbr(dentry->d_sb, bindex); -+ au_lcnt_dec(&br->br_nfiles); -+ } -+} -diff --git a/fs/aufs/hnotify.c b/fs/aufs/hnotify.c -new file mode 100644 -index 000000000..452f5609c ---- /dev/null -+++ b/fs/aufs/hnotify.c -@@ -0,0 +1,720 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * abstraction to notify the direct changes on lower directories -+ */ -+ -+#include "aufs.h" -+ -+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode) -+{ -+ int err; -+ struct au_hnotify *hn; -+ -+ err = -ENOMEM; -+ hn = au_cache_alloc_hnotify(); -+ if (hn) { -+ hn->hn_aufs_inode = inode; -+ hinode->hi_notify = hn; -+ err = au_hnotify_op.alloc(hinode); -+ AuTraceErr(err); -+ if (unlikely(err)) { -+ hinode->hi_notify = NULL; -+ au_cache_free_hnotify(hn); -+ /* -+ * The upper dir was removed by udba, but the same named -+ * dir left. In this case, aufs assigns a new inode -+ * number and set the monitor again. -+ * For the lower dir, the old monitor is still left. -+ */ -+ if (err == -EEXIST) -+ err = 0; -+ } -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_hn_free(struct au_hinode *hinode) -+{ -+ struct au_hnotify *hn; -+ -+ hn = hinode->hi_notify; -+ if (hn) { -+ hinode->hi_notify = NULL; -+ if (au_hnotify_op.free(hinode, hn)) -+ au_cache_free_hnotify(hn); -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_hn_ctl(struct au_hinode *hinode, int do_set) -+{ -+ if (hinode->hi_notify) -+ au_hnotify_op.ctl(hinode, do_set); -+} -+ -+void au_hn_reset(struct inode *inode, unsigned int flags) -+{ -+ aufs_bindex_t bindex, bbot; -+ struct inode *hi; -+ struct dentry *iwhdentry; -+ -+ bbot = au_ibbot(inode); -+ for (bindex = au_ibtop(inode); bindex <= bbot; bindex++) { -+ hi = au_h_iptr(inode, bindex); -+ if (!hi) -+ continue; -+ -+ /* inode_lock_nested(hi, AuLsc_I_CHILD); */ -+ iwhdentry = au_hi_wh(inode, bindex); -+ if (iwhdentry) -+ dget(iwhdentry); -+ au_igrab(hi); -+ au_set_h_iptr(inode, bindex, NULL, 0); -+ au_set_h_iptr(inode, bindex, au_igrab(hi), -+ flags & ~AuHi_XINO); -+ iput(hi); -+ dput(iwhdentry); -+ /* inode_unlock(hi); */ -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int hn_xino(struct inode *inode, struct inode *h_inode) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot, bfound, btop; -+ struct inode *h_i; -+ -+ err = 0; -+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { -+ pr_warn("branch root dir was changed\n"); -+ goto out; -+ } -+ -+ bfound = -1; -+ bbot = au_ibbot(inode); -+ btop = au_ibtop(inode); -+#if 0 /* reserved for future use */ -+ if (bindex == bbot) { -+ /* keep this ino in rename case */ -+ goto out; -+ } -+#endif -+ for (bindex = btop; bindex <= bbot; bindex++) -+ if (au_h_iptr(inode, bindex) == h_inode) { -+ bfound = bindex; -+ break; -+ } -+ if (bfound < 0) -+ goto out; -+ -+ for (bindex = btop; bindex <= bbot; bindex++) { -+ h_i = au_h_iptr(inode, bindex); -+ if (!h_i) -+ continue; -+ -+ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0); -+ /* ignore this error */ -+ /* bad action? */ -+ } -+ -+ /* children inode number will be broken */ -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int hn_gen_tree(struct dentry *dentry) -+{ -+ int err, i, j, ndentry; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry **dentries; -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_dcsub_pages(&dpages, dentry, NULL, NULL); -+ if (unlikely(err)) -+ goto out_dpages; -+ -+ for (i = 0; i < dpages.ndpage; i++) { -+ dpage = dpages.dpages + i; -+ dentries = dpage->dentries; -+ ndentry = dpage->ndentry; -+ for (j = 0; j < ndentry; j++) { -+ struct dentry *d; -+ -+ d = dentries[j]; -+ if (IS_ROOT(d)) -+ continue; -+ -+ au_digen_dec(d); -+ if (d_really_is_positive(d)) -+ /* todo: reset children xino? -+ cached children only? */ -+ au_iigen_dec(d_inode(d)); -+ } -+ } -+ -+out_dpages: -+ au_dpages_free(&dpages); -+ -+#if 0 -+ /* discard children */ -+ dentry_unhash(dentry); -+ dput(dentry); -+#endif -+out: -+ return err; -+} -+ -+/* -+ * return 0 if processed. -+ */ -+static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode, -+ const unsigned int isdir) -+{ -+ int err; -+ struct dentry *d; -+ struct qstr *dname; -+ -+ err = 1; -+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { -+ pr_warn("branch root dir was changed\n"); -+ err = 0; -+ goto out; -+ } -+ -+ if (!isdir) { -+ AuDebugOn(!name); -+ au_iigen_dec(inode); -+ spin_lock(&inode->i_lock); -+ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) { -+ spin_lock(&d->d_lock); -+ dname = &d->d_name; -+ if (dname->len != nlen -+ && memcmp(dname->name, name, nlen)) { -+ spin_unlock(&d->d_lock); -+ continue; -+ } -+ err = 0; -+ au_digen_dec(d); -+ spin_unlock(&d->d_lock); -+ break; -+ } -+ spin_unlock(&inode->i_lock); -+ } else { -+ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR); -+ d = d_find_any_alias(inode); -+ if (!d) { -+ au_iigen_dec(inode); -+ goto out; -+ } -+ -+ spin_lock(&d->d_lock); -+ dname = &d->d_name; -+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) { -+ spin_unlock(&d->d_lock); -+ err = hn_gen_tree(d); -+ spin_lock(&d->d_lock); -+ } -+ spin_unlock(&d->d_lock); -+ dput(d); -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir) -+{ -+ int err; -+ -+ if (IS_ROOT(dentry)) { -+ pr_warn("branch root dir was changed\n"); -+ return 0; -+ } -+ -+ err = 0; -+ if (!isdir) { -+ au_digen_dec(dentry); -+ if (d_really_is_positive(dentry)) -+ au_iigen_dec(d_inode(dentry)); -+ } else { -+ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR); -+ if (d_really_is_positive(dentry)) -+ err = hn_gen_tree(dentry); -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* hnotify job flags */ -+#define AuHnJob_XINO0 1 -+#define AuHnJob_GEN (1 << 1) -+#define AuHnJob_DIRENT (1 << 2) -+#define AuHnJob_ISDIR (1 << 3) -+#define AuHnJob_TRYXINO0 (1 << 4) -+#define AuHnJob_MNTPNT (1 << 5) -+#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name) -+#define au_fset_hnjob(flags, name) \ -+ do { (flags) |= AuHnJob_##name; } while (0) -+#define au_fclr_hnjob(flags, name) \ -+ do { (flags) &= ~AuHnJob_##name; } while (0) -+ -+enum { -+ AuHn_CHILD, -+ AuHn_PARENT, -+ AuHnLast -+}; -+ -+struct au_hnotify_args { -+ struct inode *h_dir, *dir, *h_child_inode; -+ u32 mask; -+ unsigned int flags[AuHnLast]; -+ unsigned int h_child_nlen; -+ char h_child_name[]; -+}; -+ -+struct hn_job_args { -+ unsigned int flags; -+ struct inode *inode, *h_inode, *dir, *h_dir; -+ struct dentry *dentry; -+ char *h_name; -+ int h_nlen; -+}; -+ -+static int hn_job(struct hn_job_args *a) -+{ -+ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR); -+ int e; -+ -+ /* reset xino */ -+ if (au_ftest_hnjob(a->flags, XINO0) && a->inode) -+ hn_xino(a->inode, a->h_inode); /* ignore this error */ -+ -+ if (au_ftest_hnjob(a->flags, TRYXINO0) -+ && a->inode -+ && a->h_inode) { -+ inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD); -+ if (!a->h_inode->i_nlink -+ && !(a->h_inode->i_state & I_LINKABLE)) -+ hn_xino(a->inode, a->h_inode); /* ignore this error */ -+ inode_unlock_shared(a->h_inode); -+ } -+ -+ /* make the generation obsolete */ -+ if (au_ftest_hnjob(a->flags, GEN)) { -+ e = -1; -+ if (a->inode) -+ e = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode, -+ isdir); -+ if (e && a->dentry) -+ hn_gen_by_name(a->dentry, isdir); -+ /* ignore this error */ -+ } -+ -+ /* make dir entries obsolete */ -+ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) { -+ struct au_vdir *vdir; -+ -+ vdir = au_ivdir(a->inode); -+ if (vdir) -+ vdir->vd_jiffy = 0; -+ /* IMustLock(a->inode); */ -+ /* inode_inc_iversion(a->inode); */ -+ } -+ -+ /* can do nothing but warn */ -+ if (au_ftest_hnjob(a->flags, MNTPNT) -+ && a->dentry -+ && d_mountpoint(a->dentry)) -+ pr_warn("mount-point %pd is removed or renamed\n", a->dentry); -+ -+ return 0; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen, -+ struct inode *dir) -+{ -+ struct dentry *dentry, *d, *parent; -+ struct qstr *dname; -+ -+ parent = d_find_any_alias(dir); -+ if (!parent) -+ return NULL; -+ -+ dentry = NULL; -+ spin_lock(&parent->d_lock); -+ list_for_each_entry(d, &parent->d_subdirs, d_child) { -+ /* AuDbg("%pd\n", d); */ -+ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED); -+ dname = &d->d_name; -+ if (dname->len != nlen || memcmp(dname->name, name, nlen)) -+ goto cont_unlock; -+ if (au_di(d)) -+ au_digen_dec(d); -+ else -+ goto cont_unlock; -+ if (au_dcount(d) > 0) { -+ dentry = dget_dlock(d); -+ spin_unlock(&d->d_lock); -+ break; -+ } -+ -+cont_unlock: -+ spin_unlock(&d->d_lock); -+ } -+ spin_unlock(&parent->d_lock); -+ dput(parent); -+ -+ if (dentry) -+ di_write_lock_child(dentry); -+ -+ return dentry; -+} -+ -+static struct inode *lookup_wlock_by_ino(struct super_block *sb, -+ aufs_bindex_t bindex, ino_t h_ino) -+{ -+ struct inode *inode; -+ ino_t ino; -+ int err; -+ -+ inode = NULL; -+ err = au_xino_read(sb, bindex, h_ino, &ino); -+ if (!err && ino) -+ inode = ilookup(sb, ino); -+ if (!inode) -+ goto out; -+ -+ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { -+ pr_warn("wrong root branch\n"); -+ iput(inode); -+ inode = NULL; -+ goto out; -+ } -+ -+ ii_write_lock_child(inode); -+ -+out: -+ return inode; -+} -+ -+static void au_hn_bh(void *_args) -+{ -+ struct au_hnotify_args *a = _args; -+ struct super_block *sb; -+ aufs_bindex_t bindex, bbot, bfound; -+ unsigned char xino, try_iput; -+ int err; -+ struct inode *inode; -+ ino_t h_ino; -+ struct hn_job_args args; -+ struct dentry *dentry; -+ struct au_sbinfo *sbinfo; -+ -+ AuDebugOn(!_args); -+ AuDebugOn(!a->h_dir); -+ AuDebugOn(!a->dir); -+ AuDebugOn(!a->mask); -+ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n", -+ a->mask, a->dir->i_ino, a->h_dir->i_ino, -+ a->h_child_inode ? a->h_child_inode->i_ino : 0); -+ -+ inode = NULL; -+ dentry = NULL; -+ /* -+ * do not lock a->dir->i_mutex here -+ * because of d_revalidate() may cause a deadlock. -+ */ -+ sb = a->dir->i_sb; -+ AuDebugOn(!sb); -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!sbinfo); -+ si_write_lock(sb, AuLock_NOPLMW); -+ -+ if (au_opt_test(sbinfo->si_mntflags, DIRREN)) -+ switch (a->mask & FS_EVENTS_POSS_ON_CHILD) { -+ case FS_MOVED_FROM: -+ case FS_MOVED_TO: -+ AuWarn1("DIRREN with UDBA may not work correctly " -+ "for the direct rename(2)\n"); -+ } -+ -+ ii_read_lock_parent(a->dir); -+ bfound = -1; -+ bbot = au_ibbot(a->dir); -+ for (bindex = au_ibtop(a->dir); bindex <= bbot; bindex++) -+ if (au_h_iptr(a->dir, bindex) == a->h_dir) { -+ bfound = bindex; -+ break; -+ } -+ ii_read_unlock(a->dir); -+ if (unlikely(bfound < 0)) -+ goto out; -+ -+ xino = !!au_opt_test(au_mntflags(sb), XINO); -+ h_ino = 0; -+ if (a->h_child_inode) -+ h_ino = a->h_child_inode->i_ino; -+ -+ if (a->h_child_nlen -+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN) -+ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT))) -+ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen, -+ a->dir); -+ try_iput = 0; -+ if (dentry && d_really_is_positive(dentry)) -+ inode = d_inode(dentry); -+ if (xino && !inode && h_ino -+ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0) -+ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0) -+ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) { -+ inode = lookup_wlock_by_ino(sb, bfound, h_ino); -+ try_iput = 1; -+ } -+ -+ args.flags = a->flags[AuHn_CHILD]; -+ args.dentry = dentry; -+ args.inode = inode; -+ args.h_inode = a->h_child_inode; -+ args.dir = a->dir; -+ args.h_dir = a->h_dir; -+ args.h_name = a->h_child_name; -+ args.h_nlen = a->h_child_nlen; -+ err = hn_job(&args); -+ if (dentry) { -+ if (au_di(dentry)) -+ di_write_unlock(dentry); -+ dput(dentry); -+ } -+ if (inode && try_iput) { -+ ii_write_unlock(inode); -+ iput(inode); -+ } -+ -+ ii_write_lock_parent(a->dir); -+ args.flags = a->flags[AuHn_PARENT]; -+ args.dentry = NULL; -+ args.inode = a->dir; -+ args.h_inode = a->h_dir; -+ args.dir = NULL; -+ args.h_dir = NULL; -+ args.h_name = NULL; -+ args.h_nlen = 0; -+ err = hn_job(&args); -+ ii_write_unlock(a->dir); -+ -+out: -+ iput(a->h_child_inode); -+ iput(a->h_dir); -+ iput(a->dir); -+ si_write_unlock(sb); -+ au_nwt_done(&sbinfo->si_nowait); -+ kfree(a); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask, -+ struct qstr *h_child_qstr, struct inode *h_child_inode) -+{ -+ int err, len; -+ unsigned int flags[AuHnLast], f; -+ unsigned char isdir, isroot, wh; -+ struct inode *dir; -+ struct au_hnotify_args *args; -+ char *p, *h_child_name; -+ -+ err = 0; -+ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode); -+ dir = igrab(hnotify->hn_aufs_inode); -+ if (!dir) -+ goto out; -+ -+ isroot = (dir->i_ino == AUFS_ROOT_INO); -+ wh = 0; -+ h_child_name = (void *)h_child_qstr->name; -+ len = h_child_qstr->len; -+ if (h_child_name) { -+ if (len > AUFS_WH_PFX_LEN -+ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { -+ h_child_name += AUFS_WH_PFX_LEN; -+ len -= AUFS_WH_PFX_LEN; -+ wh = 1; -+ } -+ } -+ -+ isdir = 0; -+ if (h_child_inode) -+ isdir = !!S_ISDIR(h_child_inode->i_mode); -+ flags[AuHn_PARENT] = AuHnJob_ISDIR; -+ flags[AuHn_CHILD] = 0; -+ if (isdir) -+ flags[AuHn_CHILD] = AuHnJob_ISDIR; -+ au_fset_hnjob(flags[AuHn_PARENT], DIRENT); -+ au_fset_hnjob(flags[AuHn_CHILD], GEN); -+ switch (mask & FS_EVENTS_POSS_ON_CHILD) { -+ case FS_MOVED_FROM: -+ case FS_MOVED_TO: -+ au_fset_hnjob(flags[AuHn_CHILD], XINO0); -+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT); -+ /*FALLTHROUGH*/ -+ case FS_CREATE: -+ AuDebugOn(!h_child_name); -+ break; -+ -+ case FS_DELETE: -+ /* -+ * aufs never be able to get this child inode. -+ * revalidation should be in d_revalidate() -+ * by checking i_nlink, i_generation or d_unhashed(). -+ */ -+ AuDebugOn(!h_child_name); -+ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0); -+ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT); -+ break; -+ -+ default: -+ AuDebugOn(1); -+ } -+ -+ if (wh) -+ h_child_inode = NULL; -+ -+ err = -ENOMEM; -+ /* iput() and kfree() will be called in au_hnotify() */ -+ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS); -+ if (unlikely(!args)) { -+ AuErr1("no memory\n"); -+ iput(dir); -+ goto out; -+ } -+ args->flags[AuHn_PARENT] = flags[AuHn_PARENT]; -+ args->flags[AuHn_CHILD] = flags[AuHn_CHILD]; -+ args->mask = mask; -+ args->dir = dir; -+ args->h_dir = igrab(h_dir); -+ if (h_child_inode) -+ h_child_inode = igrab(h_child_inode); /* can be NULL */ -+ args->h_child_inode = h_child_inode; -+ args->h_child_nlen = len; -+ if (len) { -+ p = (void *)args; -+ p += sizeof(*args); -+ memcpy(p, h_child_name, len); -+ p[len] = 0; -+ } -+ -+ /* NFS fires the event for silly-renamed one from kworker */ -+ f = 0; -+ if (!dir->i_nlink -+ || (au_test_nfs(h_dir->i_sb) && (mask & FS_DELETE))) -+ f = AuWkq_NEST; -+ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f); -+ if (unlikely(err)) { -+ pr_err("wkq %d\n", err); -+ iput(args->h_child_inode); -+ iput(args->h_dir); -+ iput(args->dir); -+ kfree(args); -+ } -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm) -+{ -+ int err; -+ -+ AuDebugOn(!(udba & AuOptMask_UDBA)); -+ -+ err = 0; -+ if (au_hnotify_op.reset_br) -+ err = au_hnotify_op.reset_br(udba, br, perm); -+ -+ return err; -+} -+ -+int au_hnotify_init_br(struct au_branch *br, int perm) -+{ -+ int err; -+ -+ err = 0; -+ if (au_hnotify_op.init_br) -+ err = au_hnotify_op.init_br(br, perm); -+ -+ return err; -+} -+ -+void au_hnotify_fin_br(struct au_branch *br) -+{ -+ if (au_hnotify_op.fin_br) -+ au_hnotify_op.fin_br(br); -+} -+ -+static void au_hn_destroy_cache(void) -+{ -+ kmem_cache_destroy(au_cache[AuCache_HNOTIFY]); -+ au_cache[AuCache_HNOTIFY] = NULL; -+} -+ -+int __init au_hnotify_init(void) -+{ -+ int err; -+ -+ err = -ENOMEM; -+ au_cache[AuCache_HNOTIFY] = AuCache(au_hnotify); -+ if (au_cache[AuCache_HNOTIFY]) { -+ err = 0; -+ if (au_hnotify_op.init) -+ err = au_hnotify_op.init(); -+ if (unlikely(err)) -+ au_hn_destroy_cache(); -+ } -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_hnotify_fin(void) -+{ -+ if (au_hnotify_op.fin) -+ au_hnotify_op.fin(); -+ -+ /* cf. au_cache_fin() */ -+ if (au_cache[AuCache_HNOTIFY]) -+ au_hn_destroy_cache(); -+} -diff --git a/fs/aufs/i_op.c b/fs/aufs/i_op.c -new file mode 100644 -index 000000000..e1210975e ---- /dev/null -+++ b/fs/aufs/i_op.c -@@ -0,0 +1,1506 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * inode operations (except add/del/rename) -+ */ -+ -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+static int h_permission(struct inode *h_inode, int mask, -+ struct path *h_path, int brperm) -+{ -+ int err; -+ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND)); -+ -+ err = -EPERM; -+ if (write_mask && IS_IMMUTABLE(h_inode)) -+ goto out; -+ -+ err = -EACCES; -+ if (((mask & MAY_EXEC) -+ && S_ISREG(h_inode->i_mode) -+ && (path_noexec(h_path) -+ || !(h_inode->i_mode & 0111)))) -+ goto out; -+ -+ /* -+ * - skip the lower fs test in the case of write to ro branch. -+ * - nfs dir permission write check is optimized, but a policy for -+ * link/rename requires a real check. -+ * - nfs always sets SB_POSIXACL regardless its mount option 'noacl.' -+ * in this case, generic_permission() returns -EOPNOTSUPP. -+ */ -+ if ((write_mask && !au_br_writable(brperm)) -+ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode) -+ && write_mask && !(mask & MAY_READ)) -+ || !h_inode->i_op->permission) { -+ /* AuLabel(generic_permission); */ -+ /* AuDbg("get_acl %ps\n", h_inode->i_op->get_acl); */ -+ err = generic_permission(h_inode, mask); -+ if (err == -EOPNOTSUPP && au_test_nfs_noacl(h_inode)) -+ err = h_inode->i_op->permission(h_inode, mask); -+ AuTraceErr(err); -+ } else { -+ /* AuLabel(h_inode->permission); */ -+ err = h_inode->i_op->permission(h_inode, mask); -+ AuTraceErr(err); -+ } -+ -+ if (!err) -+ err = devcgroup_inode_permission(h_inode, mask); -+ if (!err) -+ err = security_inode_permission(h_inode, mask); -+ -+#if 0 -+ if (!err) { -+ /* todo: do we need to call ima_path_check()? */ -+ struct path h_path = { -+ .dentry = -+ .mnt = h_mnt -+ }; -+ err = ima_path_check(&h_path, -+ mask & (MAY_READ | MAY_WRITE | MAY_EXEC), -+ IMA_COUNT_LEAVE); -+ } -+#endif -+ -+out: -+ return err; -+} -+ -+static int aufs_permission(struct inode *inode, int mask) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ const unsigned char isdir = !!S_ISDIR(inode->i_mode), -+ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND)); -+ struct inode *h_inode; -+ struct super_block *sb; -+ struct au_branch *br; -+ -+ /* todo: support rcu-walk? */ -+ if (mask & MAY_NOT_BLOCK) -+ return -ECHILD; -+ -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ ii_read_lock_child(inode); -+#if 0 -+ err = au_iigen_test(inode, au_sigen(sb)); -+ if (unlikely(err)) -+ goto out; -+#endif -+ -+ if (!isdir -+ || write_mask -+ || au_opt_test(au_mntflags(sb), DIRPERM1)) { -+ err = au_busy_or_stale(); -+ h_inode = au_h_iptr(inode, au_ibtop(inode)); -+ if (unlikely(!h_inode -+ || (h_inode->i_mode & S_IFMT) -+ != (inode->i_mode & S_IFMT))) -+ goto out; -+ -+ err = 0; -+ bindex = au_ibtop(inode); -+ br = au_sbr(sb, bindex); -+ err = h_permission(h_inode, mask, &br->br_path, br->br_perm); -+ if (write_mask -+ && !err -+ && !special_file(h_inode->i_mode)) { -+ /* test whether the upper writable branch exists */ -+ err = -EROFS; -+ for (; bindex >= 0; bindex--) -+ if (!au_br_rdonly(au_sbr(sb, bindex))) { -+ err = 0; -+ break; -+ } -+ } -+ goto out; -+ } -+ -+ /* non-write to dir */ -+ err = 0; -+ bbot = au_ibbot(inode); -+ for (bindex = au_ibtop(inode); !err && bindex <= bbot; bindex++) { -+ h_inode = au_h_iptr(inode, bindex); -+ if (h_inode) { -+ err = au_busy_or_stale(); -+ if (unlikely(!S_ISDIR(h_inode->i_mode))) -+ break; -+ -+ br = au_sbr(sb, bindex); -+ err = h_permission(h_inode, mask, &br->br_path, -+ br->br_perm); -+ } -+ } -+ -+out: -+ ii_read_unlock(inode); -+ si_read_unlock(sb); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry, -+ unsigned int flags) -+{ -+ struct dentry *ret, *parent; -+ struct inode *inode; -+ struct super_block *sb; -+ int err, npositive; -+ -+ IMustLock(dir); -+ -+ /* todo: support rcu-walk? */ -+ ret = ERR_PTR(-ECHILD); -+ if (flags & LOOKUP_RCU) -+ goto out; -+ -+ ret = ERR_PTR(-ENAMETOOLONG); -+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN)) -+ goto out; -+ -+ sb = dir->i_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ ret = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_di_init(dentry); -+ ret = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_si; -+ -+ inode = NULL; -+ npositive = 0; /* suppress a warning */ -+ parent = dentry->d_parent; /* dir inode is locked */ -+ di_read_lock_parent(parent, AuLock_IR); -+ err = au_alive_dir(parent); -+ if (!err) -+ err = au_digen_test(parent, au_sigen(sb)); -+ if (!err) { -+ /* regardless LOOKUP_CREATE, always ALLOW_NEG */ -+ npositive = au_lkup_dentry(dentry, au_dbtop(parent), -+ AuLkup_ALLOW_NEG); -+ err = npositive; -+ } -+ di_read_unlock(parent, AuLock_IR); -+ ret = ERR_PTR(err); -+ if (unlikely(err < 0)) -+ goto out_unlock; -+ -+ if (npositive) { -+ inode = au_new_inode(dentry, /*must_new*/0); -+ if (IS_ERR(inode)) { -+ ret = (void *)inode; -+ inode = NULL; -+ goto out_unlock; -+ } -+ } -+ -+ if (inode) -+ atomic_inc(&inode->i_count); -+ ret = d_splice_alias(inode, dentry); -+#if 0 -+ if (unlikely(d_need_lookup(dentry))) { -+ spin_lock(&dentry->d_lock); -+ dentry->d_flags &= ~DCACHE_NEED_LOOKUP; -+ spin_unlock(&dentry->d_lock); -+ } else -+#endif -+ if (inode) { -+ if (!IS_ERR(ret)) { -+ iput(inode); -+ if (ret && ret != dentry) -+ ii_write_unlock(inode); -+ } else { -+ ii_write_unlock(inode); -+ iput(inode); -+ inode = NULL; -+ } -+ } -+ -+out_unlock: -+ di_write_unlock(dentry); -+out_si: -+ si_read_unlock(sb); -+out: -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * very dirty and complicated aufs ->atomic_open(). -+ * aufs_atomic_open() -+ * + au_aopen_or_create() -+ * + add_simple() -+ * + vfsub_atomic_open() -+ * + branch fs ->atomic_open() -+ * may call the actual 'open' for h_file -+ * + inc br_nfiles only if opened -+ * + au_aopen_no_open() or au_aopen_do_open() -+ * -+ * au_aopen_do_open() -+ * + finish_open() -+ * + au_do_aopen() -+ * + au_do_open() the body of all 'open' -+ * + au_do_open_nondir() -+ * set the passed h_file -+ * -+ * au_aopen_no_open() -+ * + finish_no_open() -+ */ -+ -+struct aopen_node { -+ struct hlist_bl_node hblist; -+ struct file *file, *h_file; -+}; -+ -+static int au_do_aopen(struct inode *inode, struct file *file) -+{ -+ struct hlist_bl_head *aopen; -+ struct hlist_bl_node *pos; -+ struct aopen_node *node; -+ struct au_do_open_args args = { -+ .aopen = 1, -+ .open = au_do_open_nondir -+ }; -+ -+ aopen = &au_sbi(inode->i_sb)->si_aopen; -+ hlist_bl_lock(aopen); -+ hlist_bl_for_each_entry(node, pos, aopen, hblist) -+ if (node->file == file) { -+ args.h_file = node->h_file; -+ break; -+ } -+ hlist_bl_unlock(aopen); -+ /* AuDebugOn(!args.h_file); */ -+ -+ return au_do_open(file, &args); -+} -+ -+static int au_aopen_do_open(struct file *file, struct dentry *dentry, -+ struct aopen_node *aopen_node) -+{ -+ int err; -+ struct hlist_bl_head *aopen; -+ -+ AuLabel(here); -+ aopen = &au_sbi(dentry->d_sb)->si_aopen; -+ au_hbl_add(&aopen_node->hblist, aopen); -+ err = finish_open(file, dentry, au_do_aopen); -+ au_hbl_del(&aopen_node->hblist, aopen); -+ /* AuDbgFile(file); */ -+ AuDbg("%pd%s%s\n", dentry, -+ (file->f_mode & FMODE_CREATED) ? " created" : "", -+ (file->f_mode & FMODE_OPENED) ? " opened" : ""); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_aopen_no_open(struct file *file, struct dentry *dentry) -+{ -+ int err; -+ -+ AuLabel(here); -+ dget(dentry); -+ err = finish_no_open(file, dentry); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+static int aufs_atomic_open(struct inode *dir, struct dentry *dentry, -+ struct file *file, unsigned int open_flag, -+ umode_t create_mode) -+{ -+ int err, did_open; -+ unsigned int lkup_flags; -+ aufs_bindex_t bindex; -+ struct super_block *sb; -+ struct dentry *parent, *d; -+ struct vfsub_aopen_args args = { -+ .open_flag = open_flag, -+ .create_mode = create_mode -+ }; -+ struct aopen_node aopen_node = { -+ .file = file -+ }; -+ -+ IMustLock(dir); -+ AuDbg("open_flag 0%o\n", open_flag); -+ AuDbgDentry(dentry); -+ -+ err = 0; -+ if (!au_di(dentry)) { -+ lkup_flags = LOOKUP_OPEN; -+ if (open_flag & O_CREAT) -+ lkup_flags |= LOOKUP_CREATE; -+ d = aufs_lookup(dir, dentry, lkup_flags); -+ if (IS_ERR(d)) { -+ err = PTR_ERR(d); -+ AuTraceErr(err); -+ goto out; -+ } else if (d) { -+ /* -+ * obsoleted dentry found. -+ * another error will be returned later. -+ */ -+ d_drop(d); -+ AuDbgDentry(d); -+ dput(d); -+ } -+ AuDbgDentry(dentry); -+ } -+ -+ if (d_is_positive(dentry) -+ || d_unhashed(dentry) -+ || d_unlinked(dentry) -+ || !(open_flag & O_CREAT)) { -+ err = au_aopen_no_open(file, dentry); -+ goto out; /* success */ -+ } -+ -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN); -+ if (unlikely(err)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ parent = dentry->d_parent; /* dir is locked */ -+ di_write_lock_parent(parent); -+ err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG); -+ if (unlikely(err < 0)) -+ goto out_parent; -+ -+ AuDbgDentry(dentry); -+ if (d_is_positive(dentry)) { -+ err = au_aopen_no_open(file, dentry); -+ goto out_parent; /* success */ -+ } -+ -+ args.file = alloc_empty_file(file->f_flags, current_cred()); -+ err = PTR_ERR(args.file); -+ if (IS_ERR(args.file)) -+ goto out_parent; -+ -+ bindex = au_dbtop(dentry); -+ err = au_aopen_or_create(dir, dentry, &args); -+ AuTraceErr(err); -+ AuDbgFile(args.file); -+ file->f_mode = args.file->f_mode & ~FMODE_OPENED; -+ did_open = !!(args.file->f_mode & FMODE_OPENED); -+ if (!did_open) { -+ fput(args.file); -+ args.file = NULL; -+ } -+ di_write_unlock(parent); -+ di_write_unlock(dentry); -+ if (unlikely(err < 0)) { -+ if (args.file) -+ fput(args.file); -+ goto out_sb; -+ } -+ -+ if (!did_open) -+ err = au_aopen_no_open(file, dentry); -+ else { -+ aopen_node.h_file = args.file; -+ err = au_aopen_do_open(file, dentry, &aopen_node); -+ } -+ if (unlikely(err < 0)) { -+ if (args.file) -+ fput(args.file); -+ if (did_open) -+ au_lcnt_dec(&args.br->br_nfiles); -+ } -+ goto out_sb; /* success */ -+ -+out_parent: -+ di_write_unlock(parent); -+ di_write_unlock(dentry); -+out_sb: -+ si_read_unlock(sb); -+out: -+ AuTraceErr(err); -+ AuDbgFile(file); -+ return err; -+} -+ -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent, -+ const unsigned char add_entry, aufs_bindex_t bcpup, -+ aufs_bindex_t btop) -+{ -+ int err; -+ struct dentry *h_parent; -+ struct inode *h_dir; -+ -+ if (add_entry) -+ IMustLock(d_inode(parent)); -+ else -+ di_write_lock_parent(parent); -+ -+ err = 0; -+ if (!au_h_dptr(parent, bcpup)) { -+ if (btop > bcpup) -+ err = au_cpup_dirs(dentry, bcpup); -+ else if (btop < bcpup) -+ err = au_cpdown_dirs(dentry, bcpup); -+ else -+ BUG(); -+ } -+ if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) { -+ h_parent = au_h_dptr(parent, bcpup); -+ h_dir = d_inode(h_parent); -+ inode_lock_shared_nested(h_dir, AuLsc_I_PARENT); -+ err = au_lkup_neg(dentry, bcpup, /*wh*/0); -+ /* todo: no unlock here */ -+ inode_unlock_shared(h_dir); -+ -+ AuDbg("bcpup %d\n", bcpup); -+ if (!err) { -+ if (d_really_is_negative(dentry)) -+ au_set_h_dptr(dentry, btop, NULL); -+ au_update_dbrange(dentry, /*do_put_zero*/0); -+ } -+ } -+ -+ if (!add_entry) -+ di_write_unlock(parent); -+ if (!err) -+ err = bcpup; /* success */ -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * decide the branch and the parent dir where we will create a new entry. -+ * returns new bindex or an error. -+ * copyup the parent dir if needed. -+ */ -+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, -+ struct au_wr_dir_args *args) -+{ -+ int err; -+ unsigned int flags; -+ aufs_bindex_t bcpup, btop, src_btop; -+ const unsigned char add_entry -+ = au_ftest_wrdir(args->flags, ADD_ENTRY) -+ | au_ftest_wrdir(args->flags, TMPFILE); -+ struct super_block *sb; -+ struct dentry *parent; -+ struct au_sbinfo *sbinfo; -+ -+ sb = dentry->d_sb; -+ sbinfo = au_sbi(sb); -+ parent = dget_parent(dentry); -+ btop = au_dbtop(dentry); -+ bcpup = btop; -+ if (args->force_btgt < 0) { -+ if (src_dentry) { -+ src_btop = au_dbtop(src_dentry); -+ if (src_btop < btop) -+ bcpup = src_btop; -+ } else if (add_entry) { -+ flags = 0; -+ if (au_ftest_wrdir(args->flags, ISDIR)) -+ au_fset_wbr(flags, DIR); -+ err = AuWbrCreate(sbinfo, dentry, flags); -+ bcpup = err; -+ } -+ -+ if (bcpup < 0 || au_test_ro(sb, bcpup, d_inode(dentry))) { -+ if (add_entry) -+ err = AuWbrCopyup(sbinfo, dentry); -+ else { -+ if (!IS_ROOT(dentry)) { -+ di_read_lock_parent(parent, !AuLock_IR); -+ err = AuWbrCopyup(sbinfo, dentry); -+ di_read_unlock(parent, !AuLock_IR); -+ } else -+ err = AuWbrCopyup(sbinfo, dentry); -+ } -+ bcpup = err; -+ if (unlikely(err < 0)) -+ goto out; -+ } -+ } else { -+ bcpup = args->force_btgt; -+ AuDebugOn(au_test_ro(sb, bcpup, d_inode(dentry))); -+ } -+ -+ AuDbg("btop %d, bcpup %d\n", btop, bcpup); -+ err = bcpup; -+ if (bcpup == btop) -+ goto out; /* success */ -+ -+ /* copyup the new parent into the branch we process */ -+ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, btop); -+ if (err >= 0) { -+ if (d_really_is_negative(dentry)) { -+ au_set_h_dptr(dentry, btop, NULL); -+ au_set_dbtop(dentry, bcpup); -+ au_set_dbbot(dentry, bcpup); -+ } -+ AuDebugOn(add_entry -+ && !au_ftest_wrdir(args->flags, TMPFILE) -+ && !au_h_dptr(dentry, bcpup)); -+ } -+ -+out: -+ dput(parent); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_pin_hdir_unlock(struct au_pin *p) -+{ -+ if (p->hdir) -+ au_hn_inode_unlock(p->hdir); -+} -+ -+int au_pin_hdir_lock(struct au_pin *p) -+{ -+ int err; -+ -+ err = 0; -+ if (!p->hdir) -+ goto out; -+ -+ /* even if an error happens later, keep this lock */ -+ au_hn_inode_lock_nested(p->hdir, p->lsc_hi); -+ -+ err = -EBUSY; -+ if (unlikely(p->hdir->hi_inode != d_inode(p->h_parent))) -+ goto out; -+ -+ err = 0; -+ if (p->h_dentry) -+ err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode, -+ p->h_parent, p->br); -+ -+out: -+ return err; -+} -+ -+int au_pin_hdir_relock(struct au_pin *p) -+{ -+ int err, i; -+ struct inode *h_i; -+ struct dentry *h_d[] = { -+ p->h_dentry, -+ p->h_parent -+ }; -+ -+ err = au_pin_hdir_lock(p); -+ if (unlikely(err)) -+ goto out; -+ -+ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) { -+ if (!h_d[i]) -+ continue; -+ if (d_is_positive(h_d[i])) { -+ h_i = d_inode(h_d[i]); -+ err = !h_i->i_nlink; -+ } -+ } -+ -+out: -+ return err; -+} -+ -+static void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task) -+{ -+#if !defined(CONFIG_RWSEM_GENERIC_SPINLOCK) && defined(CONFIG_RWSEM_SPIN_ON_OWNER) -+ p->hdir->hi_inode->i_rwsem.owner = task; -+#endif -+} -+ -+void au_pin_hdir_acquire_nest(struct au_pin *p) -+{ -+ if (p->hdir) { -+ rwsem_acquire_nest(&p->hdir->hi_inode->i_rwsem.dep_map, -+ p->lsc_hi, 0, NULL, _RET_IP_); -+ au_pin_hdir_set_owner(p, current); -+ } -+} -+ -+void au_pin_hdir_release(struct au_pin *p) -+{ -+ if (p->hdir) { -+ au_pin_hdir_set_owner(p, p->task); -+ rwsem_release(&p->hdir->hi_inode->i_rwsem.dep_map, 1, _RET_IP_); -+ } -+} -+ -+struct dentry *au_pinned_h_parent(struct au_pin *pin) -+{ -+ if (pin && pin->parent) -+ return au_h_dptr(pin->parent, pin->bindex); -+ return NULL; -+} -+ -+void au_unpin(struct au_pin *p) -+{ -+ if (p->hdir) -+ au_pin_hdir_unlock(p); -+ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE)) -+ vfsub_mnt_drop_write(p->h_mnt); -+ if (!p->hdir) -+ return; -+ -+ if (!au_ftest_pin(p->flags, DI_LOCKED)) -+ di_read_unlock(p->parent, AuLock_IR); -+ iput(p->hdir->hi_inode); -+ dput(p->parent); -+ p->parent = NULL; -+ p->hdir = NULL; -+ p->h_mnt = NULL; -+ /* do not clear p->task */ -+} -+ -+int au_do_pin(struct au_pin *p) -+{ -+ int err; -+ struct super_block *sb; -+ struct inode *h_dir; -+ -+ err = 0; -+ sb = p->dentry->d_sb; -+ p->br = au_sbr(sb, p->bindex); -+ if (IS_ROOT(p->dentry)) { -+ if (au_ftest_pin(p->flags, MNT_WRITE)) { -+ p->h_mnt = au_br_mnt(p->br); -+ err = vfsub_mnt_want_write(p->h_mnt); -+ if (unlikely(err)) { -+ au_fclr_pin(p->flags, MNT_WRITE); -+ goto out_err; -+ } -+ } -+ goto out; -+ } -+ -+ p->h_dentry = NULL; -+ if (p->bindex <= au_dbbot(p->dentry)) -+ p->h_dentry = au_h_dptr(p->dentry, p->bindex); -+ -+ p->parent = dget_parent(p->dentry); -+ if (!au_ftest_pin(p->flags, DI_LOCKED)) -+ di_read_lock(p->parent, AuLock_IR, p->lsc_di); -+ -+ h_dir = NULL; -+ p->h_parent = au_h_dptr(p->parent, p->bindex); -+ p->hdir = au_hi(d_inode(p->parent), p->bindex); -+ if (p->hdir) -+ h_dir = p->hdir->hi_inode; -+ -+ /* -+ * udba case, or -+ * if DI_LOCKED is not set, then p->parent may be different -+ * and h_parent can be NULL. -+ */ -+ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) { -+ err = -EBUSY; -+ if (!au_ftest_pin(p->flags, DI_LOCKED)) -+ di_read_unlock(p->parent, AuLock_IR); -+ dput(p->parent); -+ p->parent = NULL; -+ goto out_err; -+ } -+ -+ if (au_ftest_pin(p->flags, MNT_WRITE)) { -+ p->h_mnt = au_br_mnt(p->br); -+ err = vfsub_mnt_want_write(p->h_mnt); -+ if (unlikely(err)) { -+ au_fclr_pin(p->flags, MNT_WRITE); -+ if (!au_ftest_pin(p->flags, DI_LOCKED)) -+ di_read_unlock(p->parent, AuLock_IR); -+ dput(p->parent); -+ p->parent = NULL; -+ goto out_err; -+ } -+ } -+ -+ au_igrab(h_dir); -+ err = au_pin_hdir_lock(p); -+ if (!err) -+ goto out; /* success */ -+ -+ au_unpin(p); -+ -+out_err: -+ pr_err("err %d\n", err); -+ err = au_busy_or_stale(); -+out: -+ return err; -+} -+ -+void au_pin_init(struct au_pin *p, struct dentry *dentry, -+ aufs_bindex_t bindex, int lsc_di, int lsc_hi, -+ unsigned int udba, unsigned char flags) -+{ -+ p->dentry = dentry; -+ p->udba = udba; -+ p->lsc_di = lsc_di; -+ p->lsc_hi = lsc_hi; -+ p->flags = flags; -+ p->bindex = bindex; -+ -+ p->parent = NULL; -+ p->hdir = NULL; -+ p->h_mnt = NULL; -+ -+ p->h_dentry = NULL; -+ p->h_parent = NULL; -+ p->br = NULL; -+ p->task = current; -+} -+ -+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex, -+ unsigned int udba, unsigned char flags) -+{ -+ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2, -+ udba, flags); -+ return au_do_pin(pin); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * ->setattr() and ->getattr() are called in various cases. -+ * chmod, stat: dentry is revalidated. -+ * fchmod, fstat: file and dentry are not revalidated, additionally they may be -+ * unhashed. -+ * for ->setattr(), ia->ia_file is passed from ftruncate only. -+ */ -+/* todo: consolidate with do_refresh() and simple_reval_dpath() */ -+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen) -+{ -+ int err; -+ struct dentry *parent; -+ -+ err = 0; -+ if (au_digen_test(dentry, sigen)) { -+ parent = dget_parent(dentry); -+ di_read_lock_parent(parent, AuLock_IR); -+ err = au_refresh_dentry(dentry, parent); -+ di_read_unlock(parent, AuLock_IR); -+ dput(parent); -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia, -+ struct au_icpup_args *a) -+{ -+ int err; -+ loff_t sz; -+ aufs_bindex_t btop, ibtop; -+ struct dentry *hi_wh, *parent; -+ struct inode *inode; -+ struct au_wr_dir_args wr_dir_args = { -+ .force_btgt = -1, -+ .flags = 0 -+ }; -+ -+ if (d_is_dir(dentry)) -+ au_fset_wrdir(wr_dir_args.flags, ISDIR); -+ /* plink or hi_wh() case */ -+ btop = au_dbtop(dentry); -+ inode = d_inode(dentry); -+ ibtop = au_ibtop(inode); -+ if (btop != ibtop && !au_test_ro(inode->i_sb, ibtop, inode)) -+ wr_dir_args.force_btgt = ibtop; -+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args); -+ if (unlikely(err < 0)) -+ goto out; -+ a->btgt = err; -+ if (err != btop) -+ au_fset_icpup(a->flags, DID_CPUP); -+ -+ err = 0; -+ a->pin_flags = AuPin_MNT_WRITE; -+ parent = NULL; -+ if (!IS_ROOT(dentry)) { -+ au_fset_pin(a->pin_flags, DI_LOCKED); -+ parent = dget_parent(dentry); -+ di_write_lock_parent(parent); -+ } -+ -+ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ sz = -1; -+ a->h_path.dentry = au_h_dptr(dentry, btop); -+ a->h_inode = d_inode(a->h_path.dentry); -+ if (ia && (ia->ia_valid & ATTR_SIZE)) { -+ inode_lock_shared_nested(a->h_inode, AuLsc_I_CHILD); -+ if (ia->ia_size < i_size_read(a->h_inode)) -+ sz = ia->ia_size; -+ inode_unlock_shared(a->h_inode); -+ } -+ -+ hi_wh = NULL; -+ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) { -+ hi_wh = au_hi_wh(inode, a->btgt); -+ if (!hi_wh) { -+ struct au_cp_generic cpg = { -+ .dentry = dentry, -+ .bdst = a->btgt, -+ .bsrc = -1, -+ .len = sz, -+ .pin = &a->pin -+ }; -+ err = au_sio_cpup_wh(&cpg, /*file*/NULL); -+ if (unlikely(err)) -+ goto out_unlock; -+ hi_wh = au_hi_wh(inode, a->btgt); -+ /* todo: revalidate hi_wh? */ -+ } -+ } -+ -+ if (parent) { -+ au_pin_set_parent_lflag(&a->pin, /*lflag*/0); -+ di_downgrade_lock(parent, AuLock_IR); -+ dput(parent); -+ parent = NULL; -+ } -+ if (!au_ftest_icpup(a->flags, DID_CPUP)) -+ goto out; /* success */ -+ -+ if (!d_unhashed(dentry)) { -+ struct au_cp_generic cpg = { -+ .dentry = dentry, -+ .bdst = a->btgt, -+ .bsrc = btop, -+ .len = sz, -+ .pin = &a->pin, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN -+ }; -+ err = au_sio_cpup_simple(&cpg); -+ if (!err) -+ a->h_path.dentry = au_h_dptr(dentry, a->btgt); -+ } else if (!hi_wh) -+ a->h_path.dentry = au_h_dptr(dentry, a->btgt); -+ else -+ a->h_path.dentry = hi_wh; /* do not dget here */ -+ -+out_unlock: -+ a->h_inode = d_inode(a->h_path.dentry); -+ if (!err) -+ goto out; /* success */ -+ au_unpin(&a->pin); -+out_parent: -+ if (parent) { -+ di_write_unlock(parent); -+ dput(parent); -+ } -+out: -+ if (!err) -+ inode_lock_nested(a->h_inode, AuLsc_I_CHILD); -+ return err; -+} -+ -+static int aufs_setattr(struct dentry *dentry, struct iattr *ia) -+{ -+ int err; -+ struct inode *inode, *delegated; -+ struct super_block *sb; -+ struct file *file; -+ struct au_icpup_args *a; -+ -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ -+ err = setattr_prepare(dentry, ia); -+ if (unlikely(err)) -+ goto out; -+ -+ err = -ENOMEM; -+ a = kzalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) -+ ia->ia_valid &= ~ATTR_MODE; -+ -+ file = NULL; -+ sb = dentry->d_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out_kfree; -+ -+ if (ia->ia_valid & ATTR_FILE) { -+ /* currently ftruncate(2) only */ -+ AuDebugOn(!d_is_reg(dentry)); -+ file = ia->ia_file; -+ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1, -+ /*fi_lsc*/0); -+ if (unlikely(err)) -+ goto out_si; -+ ia->ia_file = au_hf_top(file); -+ a->udba = AuOpt_UDBA_NONE; -+ } else { -+ /* fchmod() doesn't pass ia_file */ -+ a->udba = au_opt_udba(sb); -+ di_write_lock_child(dentry); -+ /* no d_unlinked(), to set UDBA_NONE for root */ -+ if (d_unhashed(dentry)) -+ a->udba = AuOpt_UDBA_NONE; -+ if (a->udba != AuOpt_UDBA_NONE) { -+ AuDebugOn(IS_ROOT(dentry)); -+ err = au_reval_for_attr(dentry, au_sigen(sb)); -+ if (unlikely(err)) -+ goto out_dentry; -+ } -+ } -+ -+ err = au_pin_and_icpup(dentry, ia, a); -+ if (unlikely(err < 0)) -+ goto out_dentry; -+ if (au_ftest_icpup(a->flags, DID_CPUP)) { -+ ia->ia_file = NULL; -+ ia->ia_valid &= ~ATTR_FILE; -+ } -+ -+ a->h_path.mnt = au_sbr_mnt(sb, a->btgt); -+ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME)) -+ == (ATTR_MODE | ATTR_CTIME)) { -+ err = security_path_chmod(&a->h_path, ia->ia_mode); -+ if (unlikely(err)) -+ goto out_unlock; -+ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID)) -+ && (ia->ia_valid & ATTR_CTIME)) { -+ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid); -+ if (unlikely(err)) -+ goto out_unlock; -+ } -+ -+ if (ia->ia_valid & ATTR_SIZE) { -+ struct file *f; -+ -+ if (ia->ia_size < i_size_read(inode)) -+ /* unmap only */ -+ truncate_setsize(inode, ia->ia_size); -+ -+ f = NULL; -+ if (ia->ia_valid & ATTR_FILE) -+ f = ia->ia_file; -+ inode_unlock(a->h_inode); -+ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f); -+ inode_lock_nested(a->h_inode, AuLsc_I_CHILD); -+ } else { -+ delegated = NULL; -+ while (1) { -+ err = vfsub_notify_change(&a->h_path, ia, &delegated); -+ if (delegated) { -+ err = break_deleg_wait(&delegated); -+ if (!err) -+ continue; -+ } -+ break; -+ } -+ } -+ /* -+ * regardless aufs 'acl' option setting. -+ * why don't all acl-aware fs call this func from their ->setattr()? -+ */ -+ if (!err && (ia->ia_valid & ATTR_MODE)) -+ err = vfsub_acl_chmod(a->h_inode, ia->ia_mode); -+ if (!err) -+ au_cpup_attr_changeable(inode); -+ -+out_unlock: -+ inode_unlock(a->h_inode); -+ au_unpin(&a->pin); -+ if (unlikely(err)) -+ au_update_dbtop(dentry); -+out_dentry: -+ di_write_unlock(dentry); -+ if (file) { -+ fi_write_unlock(file); -+ ia->ia_file = file; -+ ia->ia_valid |= ATTR_FILE; -+ } -+out_si: -+ si_read_unlock(sb); -+out_kfree: -+ kfree(a); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL) -+static int au_h_path_to_set_attr(struct dentry *dentry, -+ struct au_icpup_args *a, struct path *h_path) -+{ -+ int err; -+ struct super_block *sb; -+ -+ sb = dentry->d_sb; -+ a->udba = au_opt_udba(sb); -+ /* no d_unlinked(), to set UDBA_NONE for root */ -+ if (d_unhashed(dentry)) -+ a->udba = AuOpt_UDBA_NONE; -+ if (a->udba != AuOpt_UDBA_NONE) { -+ AuDebugOn(IS_ROOT(dentry)); -+ err = au_reval_for_attr(dentry, au_sigen(sb)); -+ if (unlikely(err)) -+ goto out; -+ } -+ err = au_pin_and_icpup(dentry, /*ia*/NULL, a); -+ if (unlikely(err < 0)) -+ goto out; -+ -+ h_path->dentry = a->h_path.dentry; -+ h_path->mnt = au_sbr_mnt(sb, a->btgt); -+ -+out: -+ return err; -+} -+ -+ssize_t au_sxattr(struct dentry *dentry, struct inode *inode, -+ struct au_sxattr *arg) -+{ -+ int err; -+ struct path h_path; -+ struct super_block *sb; -+ struct au_icpup_args *a; -+ struct inode *h_inode; -+ -+ IMustLock(inode); -+ -+ err = -ENOMEM; -+ a = kzalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out_kfree; -+ -+ h_path.dentry = NULL; /* silence gcc */ -+ di_write_lock_child(dentry); -+ err = au_h_path_to_set_attr(dentry, a, &h_path); -+ if (unlikely(err)) -+ goto out_di; -+ -+ inode_unlock(a->h_inode); -+ switch (arg->type) { -+ case AU_XATTR_SET: -+ AuDebugOn(d_is_negative(h_path.dentry)); -+ err = vfsub_setxattr(h_path.dentry, -+ arg->u.set.name, arg->u.set.value, -+ arg->u.set.size, arg->u.set.flags); -+ break; -+ case AU_ACL_SET: -+ err = -EOPNOTSUPP; -+ h_inode = d_inode(h_path.dentry); -+ if (h_inode->i_op->set_acl) -+ /* this will call posix_acl_update_mode */ -+ err = h_inode->i_op->set_acl(h_inode, -+ arg->u.acl_set.acl, -+ arg->u.acl_set.type); -+ break; -+ } -+ if (!err) -+ au_cpup_attr_timesizes(inode); -+ -+ au_unpin(&a->pin); -+ if (unlikely(err)) -+ au_update_dbtop(dentry); -+ -+out_di: -+ di_write_unlock(dentry); -+ si_read_unlock(sb); -+out_kfree: -+ kfree(a); -+out: -+ AuTraceErr(err); -+ return err; -+} -+#endif -+ -+static void au_refresh_iattr(struct inode *inode, struct kstat *st, -+ unsigned int nlink) -+{ -+ unsigned int n; -+ -+ inode->i_mode = st->mode; -+ /* don't i_[ug]id_write() here */ -+ inode->i_uid = st->uid; -+ inode->i_gid = st->gid; -+ inode->i_atime = st->atime; -+ inode->i_mtime = st->mtime; -+ inode->i_ctime = st->ctime; -+ -+ au_cpup_attr_nlink(inode, /*force*/0); -+ if (S_ISDIR(inode->i_mode)) { -+ n = inode->i_nlink; -+ n -= nlink; -+ n += st->nlink; -+ smp_mb(); /* for i_nlink */ -+ /* 0 can happen */ -+ set_nlink(inode, n); -+ } -+ -+ spin_lock(&inode->i_lock); -+ inode->i_blocks = st->blocks; -+ i_size_write(inode, st->size); -+ spin_unlock(&inode->i_lock); -+} -+ -+/* -+ * common routine for aufs_getattr() and au_getxattr(). -+ * returns zero or negative (an error). -+ * @dentry will be read-locked in success. -+ */ -+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path, -+ int locked) -+{ -+ int err; -+ unsigned int mnt_flags, sigen; -+ unsigned char udba_none; -+ aufs_bindex_t bindex; -+ struct super_block *sb, *h_sb; -+ struct inode *inode; -+ -+ h_path->mnt = NULL; -+ h_path->dentry = NULL; -+ -+ err = 0; -+ sb = dentry->d_sb; -+ mnt_flags = au_mntflags(sb); -+ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE); -+ -+ if (unlikely(locked)) -+ goto body; /* skip locking dinfo */ -+ -+ /* support fstat(2) */ -+ if (!d_unlinked(dentry) && !udba_none) { -+ sigen = au_sigen(sb); -+ err = au_digen_test(dentry, sigen); -+ if (!err) { -+ di_read_lock_child(dentry, AuLock_IR); -+ err = au_dbrange_test(dentry); -+ if (unlikely(err)) { -+ di_read_unlock(dentry, AuLock_IR); -+ goto out; -+ } -+ } else { -+ AuDebugOn(IS_ROOT(dentry)); -+ di_write_lock_child(dentry); -+ err = au_dbrange_test(dentry); -+ if (!err) -+ err = au_reval_for_attr(dentry, sigen); -+ if (!err) -+ di_downgrade_lock(dentry, AuLock_IR); -+ else { -+ di_write_unlock(dentry); -+ goto out; -+ } -+ } -+ } else -+ di_read_lock_child(dentry, AuLock_IR); -+ -+body: -+ inode = d_inode(dentry); -+ bindex = au_ibtop(inode); -+ h_path->mnt = au_sbr_mnt(sb, bindex); -+ h_sb = h_path->mnt->mnt_sb; -+ if (!force -+ && !au_test_fs_bad_iattr(h_sb) -+ && udba_none) -+ goto out; /* success */ -+ -+ if (au_dbtop(dentry) == bindex) -+ h_path->dentry = au_h_dptr(dentry, bindex); -+ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) { -+ h_path->dentry = au_plink_lkup(inode, bindex); -+ if (IS_ERR(h_path->dentry)) -+ /* pretending success */ -+ h_path->dentry = NULL; -+ else -+ dput(h_path->dentry); -+ } -+ -+out: -+ return err; -+} -+ -+static int aufs_getattr(const struct path *path, struct kstat *st, -+ u32 request, unsigned int query) -+{ -+ int err; -+ unsigned char positive; -+ struct path h_path; -+ struct dentry *dentry; -+ struct inode *inode; -+ struct super_block *sb; -+ -+ dentry = path->dentry; -+ inode = d_inode(dentry); -+ sb = dentry->d_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out; -+ err = au_h_path_getattr(dentry, /*force*/0, &h_path, /*locked*/0); -+ if (unlikely(err)) -+ goto out_si; -+ if (unlikely(!h_path.dentry)) -+ /* illegally overlapped or something */ -+ goto out_fill; /* pretending success */ -+ -+ positive = d_is_positive(h_path.dentry); -+ if (positive) -+ /* no vfsub version */ -+ err = vfs_getattr(&h_path, st, request, query); -+ if (!err) { -+ if (positive) -+ au_refresh_iattr(inode, st, -+ d_inode(h_path.dentry)->i_nlink); -+ goto out_fill; /* success */ -+ } -+ AuTraceErr(err); -+ goto out_di; -+ -+out_fill: -+ generic_fillattr(inode, st); -+out_di: -+ di_read_unlock(dentry, AuLock_IR); -+out_si: -+ si_read_unlock(sb); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static const char *aufs_get_link(struct dentry *dentry, struct inode *inode, -+ struct delayed_call *done) -+{ -+ const char *ret; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ int err; -+ aufs_bindex_t bindex; -+ -+ ret = NULL; /* suppress a warning */ -+ err = -ECHILD; -+ if (!dentry) -+ goto out; -+ -+ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_d_hashed_positive(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ err = -EINVAL; -+ inode = d_inode(dentry); -+ bindex = au_ibtop(inode); -+ h_inode = au_h_iptr(inode, bindex); -+ if (unlikely(!h_inode->i_op->get_link)) -+ goto out_unlock; -+ -+ err = -EBUSY; -+ h_dentry = NULL; -+ if (au_dbtop(dentry) <= bindex) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry) -+ dget(h_dentry); -+ } -+ if (!h_dentry) { -+ h_dentry = d_find_any_alias(h_inode); -+ if (IS_ERR(h_dentry)) { -+ err = PTR_ERR(h_dentry); -+ goto out_unlock; -+ } -+ } -+ if (unlikely(!h_dentry)) -+ goto out_unlock; -+ -+ err = 0; -+ AuDbg("%ps\n", h_inode->i_op->get_link); -+ AuDbgDentry(h_dentry); -+ ret = vfs_get_link(h_dentry, done); -+ dput(h_dentry); -+ if (IS_ERR(ret)) -+ err = PTR_ERR(ret); -+ -+out_unlock: -+ aufs_read_unlock(dentry, AuLock_IR); -+out: -+ if (unlikely(err)) -+ ret = ERR_PTR(err); -+ AuTraceErrPtr(ret); -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_is_special(struct inode *inode) -+{ -+ return (inode->i_mode & (S_IFBLK | S_IFCHR | S_IFIFO | S_IFSOCK)); -+} -+ -+static int aufs_update_time(struct inode *inode, struct timespec64 *ts, -+ int flags) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct super_block *sb; -+ struct inode *h_inode; -+ struct vfsmount *h_mnt; -+ -+ sb = inode->i_sb; -+ WARN_ONCE((flags & S_ATIME) && !IS_NOATIME(inode), -+ "unexpected s_flags 0x%lx", sb->s_flags); -+ -+ /* mmap_sem might be acquired already, cf. aufs_mmap() */ -+ lockdep_off(); -+ si_read_lock(sb, AuLock_FLUSH); -+ ii_write_lock_child(inode); -+ -+ err = 0; -+ bindex = au_ibtop(inode); -+ h_inode = au_h_iptr(inode, bindex); -+ if (!au_test_ro(sb, bindex, inode)) { -+ h_mnt = au_sbr_mnt(sb, bindex); -+ err = vfsub_mnt_want_write(h_mnt); -+ if (!err) { -+ err = vfsub_update_time(h_inode, ts, flags); -+ vfsub_mnt_drop_write(h_mnt); -+ } -+ } else if (au_is_special(h_inode)) { -+ /* -+ * Never copy-up here. -+ * These special files may already be opened and used for -+ * communicating. If we copied it up, then the communication -+ * would be corrupted. -+ */ -+ AuWarn1("timestamps for i%lu are ignored " -+ "since it is on readonly branch (hi%lu).\n", -+ inode->i_ino, h_inode->i_ino); -+ } else if (flags & ~S_ATIME) { -+ err = -EIO; -+ AuIOErr1("unexpected flags 0x%x\n", flags); -+ AuDebugOn(1); -+ } -+ -+ if (!err) -+ au_cpup_attr_timesizes(inode); -+ ii_write_unlock(inode); -+ si_read_unlock(sb); -+ lockdep_on(); -+ -+ if (!err && (flags & S_VERSION)) -+ inode_inc_iversion(inode); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* no getattr version will be set by module.c:aufs_init() */ -+struct inode_operations aufs_iop_nogetattr[AuIop_Last], -+ aufs_iop[] = { -+ [AuIop_SYMLINK] = { -+ .permission = aufs_permission, -+#ifdef CONFIG_FS_POSIX_ACL -+ .get_acl = aufs_get_acl, -+ .set_acl = aufs_set_acl, /* unsupport for symlink? */ -+#endif -+ -+ .setattr = aufs_setattr, -+ .getattr = aufs_getattr, -+ -+#ifdef CONFIG_AUFS_XATTR -+ .listxattr = aufs_listxattr, -+#endif -+ -+ .get_link = aufs_get_link, -+ -+ /* .update_time = aufs_update_time */ -+ }, -+ [AuIop_DIR] = { -+ .create = aufs_create, -+ .lookup = aufs_lookup, -+ .link = aufs_link, -+ .unlink = aufs_unlink, -+ .symlink = aufs_symlink, -+ .mkdir = aufs_mkdir, -+ .rmdir = aufs_rmdir, -+ .mknod = aufs_mknod, -+ .rename = aufs_rename, -+ -+ .permission = aufs_permission, -+#ifdef CONFIG_FS_POSIX_ACL -+ .get_acl = aufs_get_acl, -+ .set_acl = aufs_set_acl, -+#endif -+ -+ .setattr = aufs_setattr, -+ .getattr = aufs_getattr, -+ -+#ifdef CONFIG_AUFS_XATTR -+ .listxattr = aufs_listxattr, -+#endif -+ -+ .update_time = aufs_update_time, -+ .atomic_open = aufs_atomic_open, -+ .tmpfile = aufs_tmpfile -+ }, -+ [AuIop_OTHER] = { -+ .permission = aufs_permission, -+#ifdef CONFIG_FS_POSIX_ACL -+ .get_acl = aufs_get_acl, -+ .set_acl = aufs_set_acl, -+#endif -+ -+ .setattr = aufs_setattr, -+ .getattr = aufs_getattr, -+ -+#ifdef CONFIG_AUFS_XATTR -+ .listxattr = aufs_listxattr, -+#endif -+ -+ .update_time = aufs_update_time -+ } -+}; -diff --git a/fs/aufs/i_op_add.c b/fs/aufs/i_op_add.c -new file mode 100644 -index 000000000..97af9e5e1 ---- /dev/null -+++ b/fs/aufs/i_op_add.c -@@ -0,0 +1,935 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * inode operations (add entry) -+ */ -+ -+#include "aufs.h" -+ -+/* -+ * final procedure of adding a new entry, except link(2). -+ * remove whiteout, instantiate, copyup the parent dir's times and size -+ * and update version. -+ * if it failed, re-create the removed whiteout. -+ */ -+static int epilog(struct inode *dir, aufs_bindex_t bindex, -+ struct dentry *wh_dentry, struct dentry *dentry) -+{ -+ int err, rerr; -+ aufs_bindex_t bwh; -+ struct path h_path; -+ struct super_block *sb; -+ struct inode *inode, *h_dir; -+ struct dentry *wh; -+ -+ bwh = -1; -+ sb = dir->i_sb; -+ if (wh_dentry) { -+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */ -+ IMustLock(h_dir); -+ AuDebugOn(au_h_iptr(dir, bindex) != h_dir); -+ bwh = au_dbwh(dentry); -+ h_path.dentry = wh_dentry; -+ h_path.mnt = au_sbr_mnt(sb, bindex); -+ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, -+ dentry); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ inode = au_new_inode(dentry, /*must_new*/1); -+ if (!IS_ERR(inode)) { -+ d_instantiate(dentry, inode); -+ dir = d_inode(dentry->d_parent); /* dir inode is locked */ -+ IMustLock(dir); -+ au_dir_ts(dir, bindex); -+ inode_inc_iversion(dir); -+ au_fhsm_wrote(sb, bindex, /*force*/0); -+ return 0; /* success */ -+ } -+ -+ err = PTR_ERR(inode); -+ if (!wh_dentry) -+ goto out; -+ -+ /* revert */ -+ /* dir inode is locked */ -+ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent); -+ rerr = PTR_ERR(wh); -+ if (IS_ERR(wh)) { -+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", -+ dentry, err, rerr); -+ err = -EIO; -+ } else -+ dput(wh); -+ -+out: -+ return err; -+} -+ -+static int au_d_may_add(struct dentry *dentry) -+{ -+ int err; -+ -+ err = 0; -+ if (unlikely(d_unhashed(dentry))) -+ err = -ENOENT; -+ if (unlikely(d_really_is_positive(dentry))) -+ err = -EEXIST; -+ return err; -+} -+ -+/* -+ * simple tests for the adding inode operations. -+ * following the checks in vfs, plus the parent-child relationship. -+ */ -+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent, int isdir) -+{ -+ int err; -+ umode_t h_mode; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ -+ err = -ENAMETOOLONG; -+ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN)) -+ goto out; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (d_really_is_negative(dentry)) { -+ err = -EEXIST; -+ if (unlikely(d_is_positive(h_dentry))) -+ goto out; -+ } else { -+ /* rename(2) case */ -+ err = -EIO; -+ if (unlikely(d_is_negative(h_dentry))) -+ goto out; -+ h_inode = d_inode(h_dentry); -+ if (unlikely(!h_inode->i_nlink)) -+ goto out; -+ -+ h_mode = h_inode->i_mode; -+ if (!isdir) { -+ err = -EISDIR; -+ if (unlikely(S_ISDIR(h_mode))) -+ goto out; -+ } else if (unlikely(!S_ISDIR(h_mode))) { -+ err = -ENOTDIR; -+ goto out; -+ } -+ } -+ -+ err = 0; -+ /* expected parent dir is locked */ -+ if (unlikely(h_parent != h_dentry->d_parent)) -+ err = -EIO; -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * initial procedure of adding a new entry. -+ * prepare writable branch and the parent dir, lock it, -+ * and lookup whiteout for the new entry. -+ */ -+static struct dentry* -+lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt, -+ struct dentry *src_dentry, struct au_pin *pin, -+ struct au_wr_dir_args *wr_dir_args) -+{ -+ struct dentry *wh_dentry, *h_parent; -+ struct super_block *sb; -+ struct au_branch *br; -+ int err; -+ unsigned int udba; -+ aufs_bindex_t bcpup; -+ -+ AuDbg("%pd\n", dentry); -+ -+ err = au_wr_dir(dentry, src_dentry, wr_dir_args); -+ bcpup = err; -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err < 0)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ udba = au_opt_udba(sb); -+ err = au_pin(pin, dentry, bcpup, udba, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ -+ h_parent = au_pinned_h_parent(pin); -+ if (udba != AuOpt_UDBA_NONE -+ && au_dbtop(dentry) == bcpup) -+ err = au_may_add(dentry, bcpup, h_parent, -+ au_ftest_wrdir(wr_dir_args->flags, ISDIR)); -+ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN)) -+ err = -ENAMETOOLONG; -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_unpin; -+ -+ br = au_sbr(sb, bcpup); -+ if (dt) { -+ struct path tmp = { -+ .dentry = h_parent, -+ .mnt = au_br_mnt(br) -+ }; -+ au_dtime_store(dt, au_pinned_parent(pin), &tmp); -+ } -+ -+ wh_dentry = NULL; -+ if (bcpup != au_dbwh(dentry)) -+ goto out; /* success */ -+ -+ /* -+ * ENAMETOOLONG here means that if we allowed create such name, then it -+ * would not be able to removed in the future. So we don't allow such -+ * name here and we don't handle ENAMETOOLONG differently here. -+ */ -+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br); -+ -+out_unpin: -+ if (IS_ERR(wh_dentry)) -+ au_unpin(pin); -+out: -+ return wh_dentry; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+enum { Mknod, Symlink, Creat }; -+struct simple_arg { -+ int type; -+ union { -+ struct { -+ umode_t mode; -+ bool want_excl; -+ bool try_aopen; -+ struct vfsub_aopen_args *aopen; -+ } c; -+ struct { -+ const char *symname; -+ } s; -+ struct { -+ umode_t mode; -+ dev_t dev; -+ } m; -+ } u; -+}; -+ -+static int add_simple(struct inode *dir, struct dentry *dentry, -+ struct simple_arg *arg) -+{ -+ int err, rerr; -+ aufs_bindex_t btop; -+ unsigned char created; -+ const unsigned char try_aopen -+ = (arg->type == Creat && arg->u.c.try_aopen); -+ struct vfsub_aopen_args *aopen = arg->u.c.aopen; -+ struct dentry *wh_dentry, *parent; -+ struct inode *h_dir; -+ struct super_block *sb; -+ struct au_branch *br; -+ /* to reduce stack size */ -+ struct { -+ struct au_dtime dt; -+ struct au_pin pin; -+ struct path h_path; -+ struct au_wr_dir_args wr_dir_args; -+ } *a; -+ -+ AuDbg("%pd\n", dentry); -+ IMustLock(dir); -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ a->wr_dir_args.force_btgt = -1; -+ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY; -+ -+ parent = dentry->d_parent; /* dir inode is locked */ -+ if (!try_aopen) { -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN); -+ if (unlikely(err)) -+ goto out_free; -+ } -+ err = au_d_may_add(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ if (!try_aopen) -+ di_write_lock_parent(parent); -+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL, -+ &a->pin, &a->wr_dir_args); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ btop = au_dbtop(dentry); -+ sb = dentry->d_sb; -+ br = au_sbr(sb, btop); -+ a->h_path.dentry = au_h_dptr(dentry, btop); -+ a->h_path.mnt = au_br_mnt(br); -+ h_dir = au_pinned_h_dir(&a->pin); -+ switch (arg->type) { -+ case Creat: -+ if (!try_aopen || !h_dir->i_op->atomic_open) { -+ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode, -+ arg->u.c.want_excl); -+ created = !err; -+ if (!err && try_aopen) -+ aopen->file->f_mode |= FMODE_CREATED; -+ } else { -+ aopen->br = br; -+ err = vfsub_atomic_open(h_dir, a->h_path.dentry, aopen); -+ AuDbg("err %d\n", err); -+ AuDbgFile(aopen->file); -+ created = err >= 0 -+ && !!(aopen->file->f_mode & FMODE_CREATED); -+ } -+ break; -+ case Symlink: -+ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname); -+ created = !err; -+ break; -+ case Mknod: -+ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode, -+ arg->u.m.dev); -+ created = !err; -+ break; -+ default: -+ BUG(); -+ } -+ if (unlikely(err < 0)) -+ goto out_unpin; -+ -+ err = epilog(dir, btop, wh_dentry, dentry); -+ if (!err) -+ goto out_unpin; /* success */ -+ -+ /* revert */ -+ if (created /* && d_is_positive(a->h_path.dentry) */) { -+ /* no delegation since it is just created */ -+ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL, -+ /*force*/0); -+ if (rerr) { -+ AuIOErr("%pd revert failure(%d, %d)\n", -+ dentry, err, rerr); -+ err = -EIO; -+ } -+ au_dtime_revert(&a->dt); -+ } -+ if (try_aopen && h_dir->i_op->atomic_open -+ && (aopen->file->f_mode & FMODE_OPENED)) -+ /* aopen->file is still opened */ -+ au_lcnt_dec(&aopen->br->br_nfiles); -+ -+out_unpin: -+ au_unpin(&a->pin); -+ dput(wh_dentry); -+out_parent: -+ if (!try_aopen) -+ di_write_unlock(parent); -+out_unlock: -+ if (unlikely(err)) { -+ au_update_dbtop(dentry); -+ d_drop(dentry); -+ } -+ if (!try_aopen) -+ aufs_read_unlock(dentry, AuLock_DW); -+out_free: -+ kfree(a); -+out: -+ return err; -+} -+ -+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, -+ dev_t dev) -+{ -+ struct simple_arg arg = { -+ .type = Mknod, -+ .u.m = { -+ .mode = mode, -+ .dev = dev -+ } -+ }; -+ return add_simple(dir, dentry, &arg); -+} -+ -+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) -+{ -+ struct simple_arg arg = { -+ .type = Symlink, -+ .u.s.symname = symname -+ }; -+ return add_simple(dir, dentry, &arg); -+} -+ -+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode, -+ bool want_excl) -+{ -+ struct simple_arg arg = { -+ .type = Creat, -+ .u.c = { -+ .mode = mode, -+ .want_excl = want_excl -+ } -+ }; -+ return add_simple(dir, dentry, &arg); -+} -+ -+int au_aopen_or_create(struct inode *dir, struct dentry *dentry, -+ struct vfsub_aopen_args *aopen_args) -+{ -+ struct simple_arg arg = { -+ .type = Creat, -+ .u.c = { -+ .mode = aopen_args->create_mode, -+ .want_excl = aopen_args->open_flag & O_EXCL, -+ .try_aopen = true, -+ .aopen = aopen_args -+ } -+ }; -+ return add_simple(dir, dentry, &arg); -+} -+ -+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct super_block *sb; -+ struct dentry *parent, *h_parent, *h_dentry; -+ struct inode *h_dir, *inode; -+ struct vfsmount *h_mnt; -+ struct au_wr_dir_args wr_dir_args = { -+ .force_btgt = -1, -+ .flags = AuWrDir_TMPFILE -+ }; -+ -+ /* copy-up may happen */ -+ inode_lock(dir); -+ -+ sb = dir->i_sb; -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_di_init(dentry); -+ if (unlikely(err)) -+ goto out_si; -+ -+ err = -EBUSY; -+ parent = d_find_any_alias(dir); -+ AuDebugOn(!parent); -+ di_write_lock_parent(parent); -+ if (unlikely(d_inode(parent) != dir)) -+ goto out_parent; -+ -+ err = au_digen_test(parent, au_sigen(sb)); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ bindex = au_dbtop(parent); -+ au_set_dbtop(dentry, bindex); -+ au_set_dbbot(dentry, bindex); -+ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args); -+ bindex = err; -+ if (unlikely(err < 0)) -+ goto out_parent; -+ -+ err = -EOPNOTSUPP; -+ h_dir = au_h_iptr(dir, bindex); -+ if (unlikely(!h_dir->i_op->tmpfile)) -+ goto out_parent; -+ -+ h_mnt = au_sbr_mnt(sb, bindex); -+ err = vfsub_mnt_want_write(h_mnt); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ h_parent = au_h_dptr(parent, bindex); -+ h_dentry = vfs_tmpfile(h_parent, mode, /*open_flag*/0); -+ if (IS_ERR(h_dentry)) { -+ err = PTR_ERR(h_dentry); -+ goto out_mnt; -+ } -+ -+ au_set_dbtop(dentry, bindex); -+ au_set_dbbot(dentry, bindex); -+ au_set_h_dptr(dentry, bindex, dget(h_dentry)); -+ inode = au_new_inode(dentry, /*must_new*/1); -+ if (IS_ERR(inode)) { -+ err = PTR_ERR(inode); -+ au_set_h_dptr(dentry, bindex, NULL); -+ au_set_dbtop(dentry, -1); -+ au_set_dbbot(dentry, -1); -+ } else { -+ if (!inode->i_nlink) -+ set_nlink(inode, 1); -+ d_tmpfile(dentry, inode); -+ au_di(dentry)->di_tmpfile = 1; -+ -+ /* update without i_mutex */ -+ if (au_ibtop(dir) == au_dbtop(dentry)) -+ au_cpup_attr_timesizes(dir); -+ } -+ dput(h_dentry); -+ -+out_mnt: -+ vfsub_mnt_drop_write(h_mnt); -+out_parent: -+ di_write_unlock(parent); -+ dput(parent); -+ di_write_unlock(dentry); -+ if (unlikely(err)) { -+ au_di_fin(dentry); -+ dentry->d_fsdata = NULL; -+ } -+out_si: -+ si_read_unlock(sb); -+out: -+ inode_unlock(dir); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_link_args { -+ aufs_bindex_t bdst, bsrc; -+ struct au_pin pin; -+ struct path h_path; -+ struct dentry *src_parent, *parent; -+}; -+ -+static int au_cpup_before_link(struct dentry *src_dentry, -+ struct au_link_args *a) -+{ -+ int err; -+ struct dentry *h_src_dentry; -+ struct au_cp_generic cpg = { -+ .dentry = src_dentry, -+ .bdst = a->bdst, -+ .bsrc = a->bsrc, -+ .len = -1, -+ .pin = &a->pin, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */ -+ }; -+ -+ di_read_lock_parent(a->src_parent, AuLock_IR); -+ err = au_test_and_cpup_dirs(src_dentry, a->bdst); -+ if (unlikely(err)) -+ goto out; -+ -+ h_src_dentry = au_h_dptr(src_dentry, a->bsrc); -+ err = au_pin(&a->pin, src_dentry, a->bdst, -+ au_opt_udba(src_dentry->d_sb), -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_sio_cpup_simple(&cpg); -+ au_unpin(&a->pin); -+ -+out: -+ di_read_unlock(a->src_parent, AuLock_IR); -+ return err; -+} -+ -+static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry, -+ struct au_link_args *a) -+{ -+ int err; -+ unsigned char plink; -+ aufs_bindex_t bbot; -+ struct dentry *h_src_dentry; -+ struct inode *h_inode, *inode, *delegated; -+ struct super_block *sb; -+ struct file *h_file; -+ -+ plink = 0; -+ h_inode = NULL; -+ sb = src_dentry->d_sb; -+ inode = d_inode(src_dentry); -+ if (au_ibtop(inode) <= a->bdst) -+ h_inode = au_h_iptr(inode, a->bdst); -+ if (!h_inode || !h_inode->i_nlink) { -+ /* copyup src_dentry as the name of dentry. */ -+ bbot = au_dbbot(dentry); -+ if (bbot < a->bsrc) -+ au_set_dbbot(dentry, a->bsrc); -+ au_set_h_dptr(dentry, a->bsrc, -+ dget(au_h_dptr(src_dentry, a->bsrc))); -+ dget(a->h_path.dentry); -+ au_set_h_dptr(dentry, a->bdst, NULL); -+ AuDbg("temporary d_inode...\n"); -+ spin_lock(&dentry->d_lock); -+ dentry->d_inode = d_inode(src_dentry); /* tmp */ -+ spin_unlock(&dentry->d_lock); -+ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0); -+ if (IS_ERR(h_file)) -+ err = PTR_ERR(h_file); -+ else { -+ struct au_cp_generic cpg = { -+ .dentry = dentry, -+ .bdst = a->bdst, -+ .bsrc = -1, -+ .len = -1, -+ .pin = &a->pin, -+ .flags = AuCpup_KEEPLINO -+ }; -+ err = au_sio_cpup_simple(&cpg); -+ au_h_open_post(dentry, a->bsrc, h_file); -+ if (!err) { -+ dput(a->h_path.dentry); -+ a->h_path.dentry = au_h_dptr(dentry, a->bdst); -+ } else -+ au_set_h_dptr(dentry, a->bdst, -+ a->h_path.dentry); -+ } -+ spin_lock(&dentry->d_lock); -+ dentry->d_inode = NULL; /* restore */ -+ spin_unlock(&dentry->d_lock); -+ AuDbg("temporary d_inode...done\n"); -+ au_set_h_dptr(dentry, a->bsrc, NULL); -+ au_set_dbbot(dentry, bbot); -+ } else { -+ /* the inode of src_dentry already exists on a.bdst branch */ -+ h_src_dentry = d_find_alias(h_inode); -+ if (!h_src_dentry && au_plink_test(inode)) { -+ plink = 1; -+ h_src_dentry = au_plink_lkup(inode, a->bdst); -+ err = PTR_ERR(h_src_dentry); -+ if (IS_ERR(h_src_dentry)) -+ goto out; -+ -+ if (unlikely(d_is_negative(h_src_dentry))) { -+ dput(h_src_dentry); -+ h_src_dentry = NULL; -+ } -+ -+ } -+ if (h_src_dentry) { -+ delegated = NULL; -+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), -+ &a->h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ dput(h_src_dentry); -+ } else { -+ AuIOErr("no dentry found for hi%lu on b%d\n", -+ h_inode->i_ino, a->bdst); -+ err = -EIO; -+ } -+ } -+ -+ if (!err && !plink) -+ au_plink_append(inode, a->bdst, a->h_path.dentry); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int aufs_link(struct dentry *src_dentry, struct inode *dir, -+ struct dentry *dentry) -+{ -+ int err, rerr; -+ struct au_dtime dt; -+ struct au_link_args *a; -+ struct dentry *wh_dentry, *h_src_dentry; -+ struct inode *inode, *delegated; -+ struct super_block *sb; -+ struct au_wr_dir_args wr_dir_args = { -+ /* .force_btgt = -1, */ -+ .flags = AuWrDir_ADD_ENTRY -+ }; -+ -+ IMustLock(dir); -+ inode = d_inode(src_dentry); -+ IMustLock(inode); -+ -+ err = -ENOMEM; -+ a = kzalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ a->parent = dentry->d_parent; /* dir inode is locked */ -+ err = aufs_read_and_write_lock2(dentry, src_dentry, -+ AuLock_NOPLM | AuLock_GEN); -+ if (unlikely(err)) -+ goto out_kfree; -+ err = au_d_linkable(src_dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ err = au_d_may_add(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ a->src_parent = dget_parent(src_dentry); -+ wr_dir_args.force_btgt = au_ibtop(inode); -+ -+ di_write_lock_parent(a->parent); -+ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt); -+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin, -+ &wr_dir_args); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ err = 0; -+ sb = dentry->d_sb; -+ a->bdst = au_dbtop(dentry); -+ a->h_path.dentry = au_h_dptr(dentry, a->bdst); -+ a->h_path.mnt = au_sbr_mnt(sb, a->bdst); -+ a->bsrc = au_ibtop(inode); -+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc); -+ if (!h_src_dentry && au_di(src_dentry)->di_tmpfile) -+ h_src_dentry = dget(au_hi_wh(inode, a->bsrc)); -+ if (!h_src_dentry) { -+ a->bsrc = au_dbtop(src_dentry); -+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc); -+ AuDebugOn(!h_src_dentry); -+ } else if (IS_ERR(h_src_dentry)) { -+ err = PTR_ERR(h_src_dentry); -+ goto out_parent; -+ } -+ -+ /* -+ * aufs doesn't touch the credential so -+ * security_dentry_create_files_as() is unnecessary. -+ */ -+ if (au_opt_test(au_mntflags(sb), PLINK)) { -+ if (a->bdst < a->bsrc -+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) -+ err = au_cpup_or_link(src_dentry, dentry, a); -+ else { -+ delegated = NULL; -+ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), -+ &a->h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ } -+ dput(h_src_dentry); -+ } else { -+ /* -+ * copyup src_dentry to the branch we process, -+ * and then link(2) to it. -+ */ -+ dput(h_src_dentry); -+ if (a->bdst < a->bsrc -+ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) { -+ au_unpin(&a->pin); -+ di_write_unlock(a->parent); -+ err = au_cpup_before_link(src_dentry, a); -+ di_write_lock_parent(a->parent); -+ if (!err) -+ err = au_pin(&a->pin, dentry, a->bdst, -+ au_opt_udba(sb), -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (unlikely(err)) -+ goto out_wh; -+ } -+ if (!err) { -+ h_src_dentry = au_h_dptr(src_dentry, a->bdst); -+ err = -ENOENT; -+ if (h_src_dentry && d_is_positive(h_src_dentry)) { -+ delegated = NULL; -+ err = vfsub_link(h_src_dentry, -+ au_pinned_h_dir(&a->pin), -+ &a->h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry" -+ " for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ } -+ } -+ } -+ if (unlikely(err)) -+ goto out_unpin; -+ -+ if (wh_dentry) { -+ a->h_path.dentry = wh_dentry; -+ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path, -+ dentry); -+ if (unlikely(err)) -+ goto out_revert; -+ } -+ -+ au_dir_ts(dir, a->bdst); -+ inode_inc_iversion(dir); -+ inc_nlink(inode); -+ inode->i_ctime = dir->i_ctime; -+ d_instantiate(dentry, au_igrab(inode)); -+ if (d_unhashed(a->h_path.dentry)) -+ /* some filesystem calls d_drop() */ -+ d_drop(dentry); -+ /* some filesystems consume an inode even hardlink */ -+ au_fhsm_wrote(sb, a->bdst, /*force*/0); -+ goto out_unpin; /* success */ -+ -+out_revert: -+ /* no delegation since it is just created */ -+ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, -+ /*delegated*/NULL, /*force*/0); -+ if (unlikely(rerr)) { -+ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr); -+ err = -EIO; -+ } -+ au_dtime_revert(&dt); -+out_unpin: -+ au_unpin(&a->pin); -+out_wh: -+ dput(wh_dentry); -+out_parent: -+ di_write_unlock(a->parent); -+ dput(a->src_parent); -+out_unlock: -+ if (unlikely(err)) { -+ au_update_dbtop(dentry); -+ d_drop(dentry); -+ } -+ aufs_read_and_write_unlock2(dentry, src_dentry); -+out_kfree: -+ kfree(a); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) -+{ -+ int err, rerr; -+ aufs_bindex_t bindex; -+ unsigned char diropq; -+ struct path h_path; -+ struct dentry *wh_dentry, *parent, *opq_dentry; -+ struct inode *h_inode; -+ struct super_block *sb; -+ struct { -+ struct au_pin pin; -+ struct au_dtime dt; -+ } *a; /* reduce the stack usage */ -+ struct au_wr_dir_args wr_dir_args = { -+ .force_btgt = -1, -+ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR -+ }; -+ -+ IMustLock(dir); -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN); -+ if (unlikely(err)) -+ goto out_free; -+ err = au_d_may_add(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ parent = dentry->d_parent; /* dir inode is locked */ -+ di_write_lock_parent(parent); -+ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL, -+ &a->pin, &wr_dir_args); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ sb = dentry->d_sb; -+ bindex = au_dbtop(dentry); -+ h_path.dentry = au_h_dptr(dentry, bindex); -+ h_path.mnt = au_sbr_mnt(sb, bindex); -+ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode); -+ if (unlikely(err)) -+ goto out_unpin; -+ -+ /* make the dir opaque */ -+ diropq = 0; -+ h_inode = d_inode(h_path.dentry); -+ if (wh_dentry -+ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) { -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ opq_dentry = au_diropq_create(dentry, bindex); -+ inode_unlock(h_inode); -+ err = PTR_ERR(opq_dentry); -+ if (IS_ERR(opq_dentry)) -+ goto out_dir; -+ dput(opq_dentry); -+ diropq = 1; -+ } -+ -+ err = epilog(dir, bindex, wh_dentry, dentry); -+ if (!err) { -+ inc_nlink(dir); -+ goto out_unpin; /* success */ -+ } -+ -+ /* revert */ -+ if (diropq) { -+ AuLabel(revert opq); -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ rerr = au_diropq_remove(dentry, bindex); -+ inode_unlock(h_inode); -+ if (rerr) { -+ AuIOErr("%pd reverting diropq failed(%d, %d)\n", -+ dentry, err, rerr); -+ err = -EIO; -+ } -+ } -+ -+out_dir: -+ AuLabel(revert dir); -+ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path); -+ if (rerr) { -+ AuIOErr("%pd reverting dir failed(%d, %d)\n", -+ dentry, err, rerr); -+ err = -EIO; -+ } -+ au_dtime_revert(&a->dt); -+out_unpin: -+ au_unpin(&a->pin); -+ dput(wh_dentry); -+out_parent: -+ di_write_unlock(parent); -+out_unlock: -+ if (unlikely(err)) { -+ au_update_dbtop(dentry); -+ d_drop(dentry); -+ } -+ aufs_read_unlock(dentry, AuLock_DW); -+out_free: -+ kfree(a); -+out: -+ return err; -+} -diff --git a/fs/aufs/i_op_del.c b/fs/aufs/i_op_del.c -new file mode 100644 -index 000000000..343617d68 ---- /dev/null -+++ b/fs/aufs/i_op_del.c -@@ -0,0 +1,512 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * inode operations (del entry) -+ */ -+ -+#include "aufs.h" -+ -+/* -+ * decide if a new whiteout for @dentry is necessary or not. -+ * when it is necessary, prepare the parent dir for the upper branch whose -+ * branch index is @bcpup for creation. the actual creation of the whiteout will -+ * be done by caller. -+ * return value: -+ * 0: wh is unnecessary -+ * plus: wh is necessary -+ * minus: error -+ */ -+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup) -+{ -+ int need_wh, err; -+ aufs_bindex_t btop; -+ struct super_block *sb; -+ -+ sb = dentry->d_sb; -+ btop = au_dbtop(dentry); -+ if (*bcpup < 0) { -+ *bcpup = btop; -+ if (au_test_ro(sb, btop, d_inode(dentry))) { -+ err = AuWbrCopyup(au_sbi(sb), dentry); -+ *bcpup = err; -+ if (unlikely(err < 0)) -+ goto out; -+ } -+ } else -+ AuDebugOn(btop < *bcpup -+ || au_test_ro(sb, *bcpup, d_inode(dentry))); -+ AuDbg("bcpup %d, btop %d\n", *bcpup, btop); -+ -+ if (*bcpup != btop) { -+ err = au_cpup_dirs(dentry, *bcpup); -+ if (unlikely(err)) -+ goto out; -+ need_wh = 1; -+ } else { -+ struct au_dinfo *dinfo, *tmp; -+ -+ need_wh = -ENOMEM; -+ dinfo = au_di(dentry); -+ tmp = au_di_alloc(sb, AuLsc_DI_TMP); -+ if (tmp) { -+ au_di_cp(tmp, dinfo); -+ au_di_swap(tmp, dinfo); -+ /* returns the number of positive dentries */ -+ need_wh = au_lkup_dentry(dentry, btop + 1, -+ /* AuLkup_IGNORE_PERM */ 0); -+ au_di_swap(tmp, dinfo); -+ au_rw_write_unlock(&tmp->di_rwsem); -+ au_di_free(tmp); -+ } -+ } -+ AuDbg("need_wh %d\n", need_wh); -+ err = need_wh; -+ -+out: -+ return err; -+} -+ -+/* -+ * simple tests for the del-entry operations. -+ * following the checks in vfs, plus the parent-child relationship. -+ */ -+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent, int isdir) -+{ -+ int err; -+ umode_t h_mode; -+ struct dentry *h_dentry, *h_latest; -+ struct inode *h_inode; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (d_really_is_positive(dentry)) { -+ err = -ENOENT; -+ if (unlikely(d_is_negative(h_dentry))) -+ goto out; -+ h_inode = d_inode(h_dentry); -+ if (unlikely(!h_inode->i_nlink)) -+ goto out; -+ -+ h_mode = h_inode->i_mode; -+ if (!isdir) { -+ err = -EISDIR; -+ if (unlikely(S_ISDIR(h_mode))) -+ goto out; -+ } else if (unlikely(!S_ISDIR(h_mode))) { -+ err = -ENOTDIR; -+ goto out; -+ } -+ } else { -+ /* rename(2) case */ -+ err = -EIO; -+ if (unlikely(d_is_positive(h_dentry))) -+ goto out; -+ } -+ -+ err = -ENOENT; -+ /* expected parent dir is locked */ -+ if (unlikely(h_parent != h_dentry->d_parent)) -+ goto out; -+ err = 0; -+ -+ /* -+ * rmdir a dir may break the consistency on some filesystem. -+ * let's try heavy test. -+ */ -+ err = -EACCES; -+ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1) -+ && au_test_h_perm(d_inode(h_parent), -+ MAY_EXEC | MAY_WRITE))) -+ goto out; -+ -+ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent); -+ err = -EIO; -+ if (IS_ERR(h_latest)) -+ goto out; -+ if (h_latest == h_dentry) -+ err = 0; -+ dput(h_latest); -+ -+out: -+ return err; -+} -+ -+/* -+ * decide the branch where we operate for @dentry. the branch index will be set -+ * @rbcpup. after deciding it, 'pin' it and store the timestamps of the parent -+ * dir for reverting. -+ * when a new whiteout is necessary, create it. -+ */ -+static struct dentry* -+lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup, -+ struct au_dtime *dt, struct au_pin *pin) -+{ -+ struct dentry *wh_dentry; -+ struct super_block *sb; -+ struct path h_path; -+ int err, need_wh; -+ unsigned int udba; -+ aufs_bindex_t bcpup; -+ -+ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup); -+ wh_dentry = ERR_PTR(need_wh); -+ if (unlikely(need_wh < 0)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ udba = au_opt_udba(sb); -+ bcpup = *rbcpup; -+ err = au_pin(pin, dentry, bcpup, udba, -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ -+ h_path.dentry = au_pinned_h_parent(pin); -+ if (udba != AuOpt_UDBA_NONE -+ && au_dbtop(dentry) == bcpup) { -+ err = au_may_del(dentry, bcpup, h_path.dentry, isdir); -+ wh_dentry = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_unpin; -+ } -+ -+ h_path.mnt = au_sbr_mnt(sb, bcpup); -+ au_dtime_store(dt, au_pinned_parent(pin), &h_path); -+ wh_dentry = NULL; -+ if (!need_wh) -+ goto out; /* success, no need to create whiteout */ -+ -+ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_unpin; -+ -+ /* returns with the parent is locked and wh_dentry is dget-ed */ -+ goto out; /* success */ -+ -+out_unpin: -+ au_unpin(pin); -+out: -+ return wh_dentry; -+} -+ -+/* -+ * when removing a dir, rename it to a unique temporary whiteout-ed name first -+ * in order to be revertible and save time for removing many child whiteouts -+ * under the dir. -+ * returns 1 when there are too many child whiteout and caller should remove -+ * them asynchronously. returns 0 when the number of children is enough small to -+ * remove now or the branch fs is a remote fs. -+ * otherwise return an error. -+ */ -+static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex, -+ struct au_nhash *whlist, struct inode *dir) -+{ -+ int rmdir_later, err, dirwh; -+ struct dentry *h_dentry; -+ struct super_block *sb; -+ struct inode *inode; -+ -+ sb = dentry->d_sb; -+ SiMustAnyLock(sb); -+ h_dentry = au_h_dptr(dentry, bindex); -+ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex)); -+ if (unlikely(err)) -+ goto out; -+ -+ /* stop monitoring */ -+ inode = d_inode(dentry); -+ au_hn_free(au_hi(inode, bindex)); -+ -+ if (!au_test_fs_remote(h_dentry->d_sb)) { -+ dirwh = au_sbi(sb)->si_dirwh; -+ rmdir_later = (dirwh <= 1); -+ if (!rmdir_later) -+ rmdir_later = au_nhash_test_longer_wh(whlist, bindex, -+ dirwh); -+ if (rmdir_later) -+ return rmdir_later; -+ } -+ -+ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist); -+ if (unlikely(err)) { -+ AuIOErr("rmdir %pd, b%d failed, %d. ignored\n", -+ h_dentry, bindex, err); -+ err = 0; -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * final procedure for deleting a entry. -+ * maintain dentry and iattr. -+ */ -+static void epilog(struct inode *dir, struct dentry *dentry, -+ aufs_bindex_t bindex) -+{ -+ struct inode *inode; -+ -+ inode = d_inode(dentry); -+ d_drop(dentry); -+ inode->i_ctime = dir->i_ctime; -+ -+ au_dir_ts(dir, bindex); -+ inode_inc_iversion(dir); -+} -+ -+/* -+ * when an error happened, remove the created whiteout and revert everything. -+ */ -+static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex, -+ aufs_bindex_t bwh, struct dentry *wh_dentry, -+ struct dentry *dentry, struct au_dtime *dt) -+{ -+ int rerr; -+ struct path h_path = { -+ .dentry = wh_dentry, -+ .mnt = au_sbr_mnt(dir->i_sb, bindex) -+ }; -+ -+ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry); -+ if (!rerr) { -+ au_set_dbwh(dentry, bwh); -+ au_dtime_revert(dt); -+ return 0; -+ } -+ -+ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry, err, rerr); -+ return -EIO; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int aufs_unlink(struct inode *dir, struct dentry *dentry) -+{ -+ int err; -+ aufs_bindex_t bwh, bindex, btop; -+ struct inode *inode, *h_dir, *delegated; -+ struct dentry *parent, *wh_dentry; -+ /* to reduce stack size */ -+ struct { -+ struct au_dtime dt; -+ struct au_pin pin; -+ struct path h_path; -+ } *a; -+ -+ IMustLock(dir); -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN); -+ if (unlikely(err)) -+ goto out_free; -+ err = au_d_hashed_positive(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ err = -EISDIR; -+ if (unlikely(d_is_dir(dentry))) -+ goto out_unlock; /* possible? */ -+ -+ btop = au_dbtop(dentry); -+ bwh = au_dbwh(dentry); -+ bindex = -1; -+ parent = dentry->d_parent; /* dir inode is locked */ -+ di_write_lock_parent(parent); -+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt, -+ &a->pin); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, btop); -+ a->h_path.dentry = au_h_dptr(dentry, btop); -+ dget(a->h_path.dentry); -+ if (bindex == btop) { -+ h_dir = au_pinned_h_dir(&a->pin); -+ delegated = NULL; -+ err = vfsub_unlink(h_dir, &a->h_path, &delegated, /*force*/0); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ } else { -+ /* dir inode is locked */ -+ h_dir = d_inode(wh_dentry->d_parent); -+ IMustLock(h_dir); -+ err = 0; -+ } -+ -+ if (!err) { -+ vfsub_drop_nlink(inode); -+ epilog(dir, dentry, bindex); -+ -+ /* update target timestamps */ -+ if (bindex == btop) { -+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); -+ /*ignore*/ -+ inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime; -+ } else -+ /* todo: this timestamp may be reverted later */ -+ inode->i_ctime = h_dir->i_ctime; -+ goto out_unpin; /* success */ -+ } -+ -+ /* revert */ -+ if (wh_dentry) { -+ int rerr; -+ -+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, -+ &a->dt); -+ if (rerr) -+ err = rerr; -+ } -+ -+out_unpin: -+ au_unpin(&a->pin); -+ dput(wh_dentry); -+ dput(a->h_path.dentry); -+out_parent: -+ di_write_unlock(parent); -+out_unlock: -+ aufs_read_unlock(dentry, AuLock_DW); -+out_free: -+ kfree(a); -+out: -+ return err; -+} -+ -+int aufs_rmdir(struct inode *dir, struct dentry *dentry) -+{ -+ int err, rmdir_later; -+ aufs_bindex_t bwh, bindex, btop; -+ struct inode *inode; -+ struct dentry *parent, *wh_dentry, *h_dentry; -+ struct au_whtmp_rmdir *args; -+ /* to reduce stack size */ -+ struct { -+ struct au_dtime dt; -+ struct au_pin pin; -+ } *a; -+ -+ IMustLock(dir); -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN); -+ if (unlikely(err)) -+ goto out_free; -+ err = au_alive_dir(dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ inode = d_inode(dentry); -+ IMustLock(inode); -+ err = -ENOTDIR; -+ if (unlikely(!d_is_dir(dentry))) -+ goto out_unlock; /* possible? */ -+ -+ err = -ENOMEM; -+ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS); -+ if (unlikely(!args)) -+ goto out_unlock; -+ -+ parent = dentry->d_parent; /* dir inode is locked */ -+ di_write_lock_parent(parent); -+ err = au_test_empty(dentry, &args->whlist); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ btop = au_dbtop(dentry); -+ bwh = au_dbwh(dentry); -+ bindex = -1; -+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt, -+ &a->pin); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) -+ goto out_parent; -+ -+ h_dentry = au_h_dptr(dentry, btop); -+ dget(h_dentry); -+ rmdir_later = 0; -+ if (bindex == btop) { -+ err = renwh_and_rmdir(dentry, btop, &args->whlist, dir); -+ if (err > 0) { -+ rmdir_later = err; -+ err = 0; -+ } -+ } else { -+ /* stop monitoring */ -+ au_hn_free(au_hi(inode, btop)); -+ -+ /* dir inode is locked */ -+ IMustLock(d_inode(wh_dentry->d_parent)); -+ err = 0; -+ } -+ -+ if (!err) { -+ vfsub_dead_dir(inode); -+ au_set_dbdiropq(dentry, -1); -+ epilog(dir, dentry, bindex); -+ -+ if (rmdir_later) { -+ au_whtmp_kick_rmdir(dir, btop, h_dentry, args); -+ args = NULL; -+ } -+ -+ goto out_unpin; /* success */ -+ } -+ -+ /* revert */ -+ AuLabel(revert); -+ if (wh_dentry) { -+ int rerr; -+ -+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, -+ &a->dt); -+ if (rerr) -+ err = rerr; -+ } -+ -+out_unpin: -+ au_unpin(&a->pin); -+ dput(wh_dentry); -+ dput(h_dentry); -+out_parent: -+ di_write_unlock(parent); -+ if (args) -+ au_whtmp_rmdir_free(args); -+out_unlock: -+ aufs_read_unlock(dentry, AuLock_DW); -+out_free: -+ kfree(a); -+out: -+ AuTraceErr(err); -+ return err; -+} -diff --git a/fs/aufs/i_op_ren.c b/fs/aufs/i_op_ren.c -new file mode 100644 -index 000000000..f9e5d5d66 ---- /dev/null -+++ b/fs/aufs/i_op_ren.c -@@ -0,0 +1,1249 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * inode operation (rename entry) -+ * todo: this is crazy monster -+ */ -+ -+#include "aufs.h" -+ -+enum { AuSRC, AuDST, AuSrcDst }; -+enum { AuPARENT, AuCHILD, AuParentChild }; -+ -+#define AuRen_ISDIR_SRC 1 -+#define AuRen_ISDIR_DST (1 << 1) -+#define AuRen_ISSAMEDIR (1 << 2) -+#define AuRen_WHSRC (1 << 3) -+#define AuRen_WHDST (1 << 4) -+#define AuRen_MNT_WRITE (1 << 5) -+#define AuRen_DT_DSTDIR (1 << 6) -+#define AuRen_DIROPQ_SRC (1 << 7) -+#define AuRen_DIROPQ_DST (1 << 8) -+#define AuRen_DIRREN (1 << 9) -+#define AuRen_DROPPED_SRC (1 << 10) -+#define AuRen_DROPPED_DST (1 << 11) -+#define au_ftest_ren(flags, name) ((flags) & AuRen_##name) -+#define au_fset_ren(flags, name) \ -+ do { (flags) |= AuRen_##name; } while (0) -+#define au_fclr_ren(flags, name) \ -+ do { (flags) &= ~AuRen_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_DIRREN -+#undef AuRen_DIRREN -+#define AuRen_DIRREN 0 -+#endif -+ -+struct au_ren_args { -+ struct { -+ struct dentry *dentry, *h_dentry, *parent, *h_parent, -+ *wh_dentry; -+ struct inode *dir, *inode; -+ struct au_hinode *hdir, *hinode; -+ struct au_dtime dt[AuParentChild]; -+ aufs_bindex_t btop, bdiropq; -+ } sd[AuSrcDst]; -+ -+#define src_dentry sd[AuSRC].dentry -+#define src_dir sd[AuSRC].dir -+#define src_inode sd[AuSRC].inode -+#define src_h_dentry sd[AuSRC].h_dentry -+#define src_parent sd[AuSRC].parent -+#define src_h_parent sd[AuSRC].h_parent -+#define src_wh_dentry sd[AuSRC].wh_dentry -+#define src_hdir sd[AuSRC].hdir -+#define src_hinode sd[AuSRC].hinode -+#define src_h_dir sd[AuSRC].hdir->hi_inode -+#define src_dt sd[AuSRC].dt -+#define src_btop sd[AuSRC].btop -+#define src_bdiropq sd[AuSRC].bdiropq -+ -+#define dst_dentry sd[AuDST].dentry -+#define dst_dir sd[AuDST].dir -+#define dst_inode sd[AuDST].inode -+#define dst_h_dentry sd[AuDST].h_dentry -+#define dst_parent sd[AuDST].parent -+#define dst_h_parent sd[AuDST].h_parent -+#define dst_wh_dentry sd[AuDST].wh_dentry -+#define dst_hdir sd[AuDST].hdir -+#define dst_hinode sd[AuDST].hinode -+#define dst_h_dir sd[AuDST].hdir->hi_inode -+#define dst_dt sd[AuDST].dt -+#define dst_btop sd[AuDST].btop -+#define dst_bdiropq sd[AuDST].bdiropq -+ -+ struct dentry *h_trap; -+ struct au_branch *br; -+ struct path h_path; -+ struct au_nhash whlist; -+ aufs_bindex_t btgt, src_bwh; -+ -+ struct { -+ unsigned short auren_flags; -+ unsigned char flags; /* syscall parameter */ -+ unsigned char exchange; -+ } __packed; -+ -+ struct au_whtmp_rmdir *thargs; -+ struct dentry *h_dst; -+ struct au_hinode *h_root; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * functions for reverting. -+ * when an error happened in a single rename systemcall, we should revert -+ * everything as if nothing happened. -+ * we don't need to revert the copied-up/down the parent dir since they are -+ * harmless. -+ */ -+ -+#define RevertFailure(fmt, ...) do { \ -+ AuIOErr("revert failure: " fmt " (%d, %d)\n", \ -+ ##__VA_ARGS__, err, rerr); \ -+ err = -EIO; \ -+} while (0) -+ -+static void au_ren_do_rev_diropq(int err, struct au_ren_args *a, int idx) -+{ -+ int rerr; -+ struct dentry *d; -+#define src_or_dst(member) a->sd[idx].member -+ -+ d = src_or_dst(dentry); /* {src,dst}_dentry */ -+ au_hn_inode_lock_nested(src_or_dst(hinode), AuLsc_I_CHILD); -+ rerr = au_diropq_remove(d, a->btgt); -+ au_hn_inode_unlock(src_or_dst(hinode)); -+ au_set_dbdiropq(d, src_or_dst(bdiropq)); -+ if (rerr) -+ RevertFailure("remove diropq %pd", d); -+ -+#undef src_or_dst_ -+} -+ -+static void au_ren_rev_diropq(int err, struct au_ren_args *a) -+{ -+ if (au_ftest_ren(a->auren_flags, DIROPQ_SRC)) -+ au_ren_do_rev_diropq(err, a, AuSRC); -+ if (au_ftest_ren(a->auren_flags, DIROPQ_DST)) -+ au_ren_do_rev_diropq(err, a, AuDST); -+} -+ -+static void au_ren_rev_rename(int err, struct au_ren_args *a) -+{ -+ int rerr; -+ struct inode *delegated; -+ -+ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name, -+ a->src_h_parent); -+ rerr = PTR_ERR(a->h_path.dentry); -+ if (IS_ERR(a->h_path.dentry)) { -+ RevertFailure("lkup one %pd", a->src_dentry); -+ return; -+ } -+ -+ delegated = NULL; -+ rerr = vfsub_rename(a->dst_h_dir, -+ au_h_dptr(a->src_dentry, a->btgt), -+ a->src_h_dir, &a->h_path, &delegated, a->flags); -+ if (unlikely(rerr == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal rename\n"); -+ iput(delegated); -+ } -+ d_drop(a->h_path.dentry); -+ dput(a->h_path.dentry); -+ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */ -+ if (rerr) -+ RevertFailure("rename %pd", a->src_dentry); -+} -+ -+static void au_ren_rev_whtmp(int err, struct au_ren_args *a) -+{ -+ int rerr; -+ struct inode *delegated; -+ -+ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name, -+ a->dst_h_parent); -+ rerr = PTR_ERR(a->h_path.dentry); -+ if (IS_ERR(a->h_path.dentry)) { -+ RevertFailure("lkup one %pd", a->dst_dentry); -+ return; -+ } -+ if (d_is_positive(a->h_path.dentry)) { -+ d_drop(a->h_path.dentry); -+ dput(a->h_path.dentry); -+ return; -+ } -+ -+ delegated = NULL; -+ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path, -+ &delegated, a->flags); -+ if (unlikely(rerr == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal rename\n"); -+ iput(delegated); -+ } -+ d_drop(a->h_path.dentry); -+ dput(a->h_path.dentry); -+ if (!rerr) -+ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst)); -+ else -+ RevertFailure("rename %pd", a->h_dst); -+} -+ -+static void au_ren_rev_whsrc(int err, struct au_ren_args *a) -+{ -+ int rerr; -+ -+ a->h_path.dentry = a->src_wh_dentry; -+ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry); -+ au_set_dbwh(a->src_dentry, a->src_bwh); -+ if (rerr) -+ RevertFailure("unlink %pd", a->src_wh_dentry); -+} -+#undef RevertFailure -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * when we have to copyup the renaming entry, do it with the rename-target name -+ * in order to minimize the cost (the later actual rename is unnecessary). -+ * otherwise rename it on the target branch. -+ */ -+static int au_ren_or_cpup(struct au_ren_args *a) -+{ -+ int err; -+ struct dentry *d; -+ struct inode *delegated; -+ -+ d = a->src_dentry; -+ if (au_dbtop(d) == a->btgt) { -+ a->h_path.dentry = a->dst_h_dentry; -+ AuDebugOn(au_dbtop(d) != a->btgt); -+ delegated = NULL; -+ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt), -+ a->dst_h_dir, &a->h_path, &delegated, -+ a->flags); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal rename\n"); -+ iput(delegated); -+ } -+ } else -+ BUG(); -+ -+ if (!err && a->h_dst) -+ /* it will be set to dinfo later */ -+ dget(a->h_dst); -+ -+ return err; -+} -+ -+/* cf. aufs_rmdir() */ -+static int au_ren_del_whtmp(struct au_ren_args *a) -+{ -+ int err; -+ struct inode *dir; -+ -+ dir = a->dst_dir; -+ SiMustAnyLock(dir->i_sb); -+ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt, -+ au_sbi(dir->i_sb)->si_dirwh) -+ || au_test_fs_remote(a->h_dst->d_sb)) { -+ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist); -+ if (unlikely(err)) -+ pr_warn("failed removing whtmp dir %pd (%d), " -+ "ignored.\n", a->h_dst, err); -+ } else { -+ au_nhash_wh_free(&a->thargs->whlist); -+ a->thargs->whlist = a->whlist; -+ a->whlist.nh_num = 0; -+ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs); -+ dput(a->h_dst); -+ a->thargs = NULL; -+ } -+ -+ return 0; -+} -+ -+/* make it 'opaque' dir. */ -+static int au_ren_do_diropq(struct au_ren_args *a, int idx) -+{ -+ int err; -+ struct dentry *d, *diropq; -+#define src_or_dst(member) a->sd[idx].member -+ -+ err = 0; -+ d = src_or_dst(dentry); /* {src,dst}_dentry */ -+ src_or_dst(bdiropq) = au_dbdiropq(d); -+ src_or_dst(hinode) = au_hi(src_or_dst(inode), a->btgt); -+ au_hn_inode_lock_nested(src_or_dst(hinode), AuLsc_I_CHILD); -+ diropq = au_diropq_create(d, a->btgt); -+ au_hn_inode_unlock(src_or_dst(hinode)); -+ if (IS_ERR(diropq)) -+ err = PTR_ERR(diropq); -+ else -+ dput(diropq); -+ -+#undef src_or_dst_ -+ return err; -+} -+ -+static int au_ren_diropq(struct au_ren_args *a) -+{ -+ int err; -+ unsigned char always; -+ struct dentry *d; -+ -+ err = 0; -+ d = a->dst_dentry; /* already renamed on the branch */ -+ always = !!au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ); -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC) -+ && !au_ftest_ren(a->auren_flags, DIRREN) -+ && a->btgt != au_dbdiropq(a->src_dentry) -+ && (a->dst_wh_dentry -+ || a->btgt <= au_dbdiropq(d) -+ /* hide the lower to keep xino */ -+ /* the lowers may not be a dir, but we hide them anyway */ -+ || a->btgt < au_dbbot(d) -+ || always)) { -+ AuDbg("here\n"); -+ err = au_ren_do_diropq(a, AuSRC); -+ if (unlikely(err)) -+ goto out; -+ au_fset_ren(a->auren_flags, DIROPQ_SRC); -+ } -+ if (!a->exchange) -+ goto out; /* success */ -+ -+ d = a->src_dentry; /* already renamed on the branch */ -+ if (au_ftest_ren(a->auren_flags, ISDIR_DST) -+ && a->btgt != au_dbdiropq(a->dst_dentry) -+ && (a->btgt < au_dbdiropq(d) -+ || a->btgt < au_dbbot(d) -+ || always)) { -+ AuDbgDentry(a->src_dentry); -+ AuDbgDentry(a->dst_dentry); -+ err = au_ren_do_diropq(a, AuDST); -+ if (unlikely(err)) -+ goto out_rev_src; -+ au_fset_ren(a->auren_flags, DIROPQ_DST); -+ } -+ goto out; /* success */ -+ -+out_rev_src: -+ AuDbg("err %d, reverting src\n", err); -+ au_ren_rev_diropq(err, a); -+out: -+ return err; -+} -+ -+static int do_rename(struct au_ren_args *a) -+{ -+ int err; -+ struct dentry *d, *h_d; -+ -+ if (!a->exchange) { -+ /* prepare workqueue args for asynchronous rmdir */ -+ h_d = a->dst_h_dentry; -+ if (au_ftest_ren(a->auren_flags, ISDIR_DST) -+ /* && !au_ftest_ren(a->auren_flags, DIRREN) */ -+ && d_is_positive(h_d)) { -+ err = -ENOMEM; -+ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, -+ GFP_NOFS); -+ if (unlikely(!a->thargs)) -+ goto out; -+ a->h_dst = dget(h_d); -+ } -+ -+ /* create whiteout for src_dentry */ -+ if (au_ftest_ren(a->auren_flags, WHSRC)) { -+ a->src_bwh = au_dbwh(a->src_dentry); -+ AuDebugOn(a->src_bwh >= 0); -+ a->src_wh_dentry = au_wh_create(a->src_dentry, a->btgt, -+ a->src_h_parent); -+ err = PTR_ERR(a->src_wh_dentry); -+ if (IS_ERR(a->src_wh_dentry)) -+ goto out_thargs; -+ } -+ -+ /* lookup whiteout for dentry */ -+ if (au_ftest_ren(a->auren_flags, WHDST)) { -+ h_d = au_wh_lkup(a->dst_h_parent, -+ &a->dst_dentry->d_name, a->br); -+ err = PTR_ERR(h_d); -+ if (IS_ERR(h_d)) -+ goto out_whsrc; -+ if (d_is_negative(h_d)) -+ dput(h_d); -+ else -+ a->dst_wh_dentry = h_d; -+ } -+ -+ /* rename dentry to tmpwh */ -+ if (a->thargs) { -+ err = au_whtmp_ren(a->dst_h_dentry, a->br); -+ if (unlikely(err)) -+ goto out_whdst; -+ -+ d = a->dst_dentry; -+ au_set_h_dptr(d, a->btgt, NULL); -+ err = au_lkup_neg(d, a->btgt, /*wh*/0); -+ if (unlikely(err)) -+ goto out_whtmp; -+ a->dst_h_dentry = au_h_dptr(d, a->btgt); -+ } -+ } -+ -+ BUG_ON(d_is_positive(a->dst_h_dentry) && a->src_btop != a->btgt); -+#if 0 -+ BUG_ON(!au_ftest_ren(a->auren_flags, DIRREN) -+ && d_is_positive(a->dst_h_dentry) -+ && a->src_btop != a->btgt); -+#endif -+ -+ /* rename by vfs_rename or cpup */ -+ err = au_ren_or_cpup(a); -+ if (unlikely(err)) -+ /* leave the copied-up one */ -+ goto out_whtmp; -+ -+ /* make dir opaque */ -+ err = au_ren_diropq(a); -+ if (unlikely(err)) -+ goto out_rename; -+ -+ /* update target timestamps */ -+ if (a->exchange) { -+ AuDebugOn(au_dbtop(a->dst_dentry) != a->btgt); -+ a->h_path.dentry = au_h_dptr(a->dst_dentry, a->btgt); -+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/ -+ a->dst_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime; -+ } -+ AuDebugOn(au_dbtop(a->src_dentry) != a->btgt); -+ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt); -+ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/ -+ a->src_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime; -+ -+ if (!a->exchange) { -+ /* remove whiteout for dentry */ -+ if (a->dst_wh_dentry) { -+ a->h_path.dentry = a->dst_wh_dentry; -+ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path, -+ a->dst_dentry); -+ if (unlikely(err)) -+ goto out_diropq; -+ } -+ -+ /* remove whtmp */ -+ if (a->thargs) -+ au_ren_del_whtmp(a); /* ignore this error */ -+ -+ au_fhsm_wrote(a->src_dentry->d_sb, a->btgt, /*force*/0); -+ } -+ err = 0; -+ goto out_success; -+ -+out_diropq: -+ au_ren_rev_diropq(err, a); -+out_rename: -+ au_ren_rev_rename(err, a); -+ dput(a->h_dst); -+out_whtmp: -+ if (a->thargs) -+ au_ren_rev_whtmp(err, a); -+out_whdst: -+ dput(a->dst_wh_dentry); -+ a->dst_wh_dentry = NULL; -+out_whsrc: -+ if (a->src_wh_dentry) -+ au_ren_rev_whsrc(err, a); -+out_success: -+ dput(a->src_wh_dentry); -+ dput(a->dst_wh_dentry); -+out_thargs: -+ if (a->thargs) { -+ dput(a->h_dst); -+ au_whtmp_rmdir_free(a->thargs); -+ a->thargs = NULL; -+ } -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * test if @dentry dir can be rename destination or not. -+ * success means, it is a logically empty dir. -+ */ -+static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist) -+{ -+ return au_test_empty(dentry, whlist); -+} -+ -+/* -+ * test if @a->src_dentry dir can be rename source or not. -+ * if it can, return 0. -+ * success means, -+ * - it is a logically empty dir. -+ * - or, it exists on writable branch and has no children including whiteouts -+ * on the lower branch unless DIRREN is on. -+ */ -+static int may_rename_srcdir(struct au_ren_args *a) -+{ -+ int err; -+ unsigned int rdhash; -+ aufs_bindex_t btop, btgt; -+ struct dentry *dentry; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ -+ dentry = a->src_dentry; -+ sb = dentry->d_sb; -+ sbinfo = au_sbi(sb); -+ if (au_opt_test(sbinfo->si_mntflags, DIRREN)) -+ au_fset_ren(a->auren_flags, DIRREN); -+ -+ btgt = a->btgt; -+ btop = au_dbtop(dentry); -+ if (btop != btgt) { -+ struct au_nhash whlist; -+ -+ SiMustAnyLock(sb); -+ rdhash = sbinfo->si_rdhash; -+ if (!rdhash) -+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, -+ dentry)); -+ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_test_empty(dentry, &whlist); -+ au_nhash_wh_free(&whlist); -+ goto out; -+ } -+ -+ if (btop == au_dbtaildir(dentry)) -+ return 0; /* success */ -+ -+ err = au_test_empty_lower(dentry); -+ -+out: -+ if (err == -ENOTEMPTY) { -+ if (au_ftest_ren(a->auren_flags, DIRREN)) { -+ err = 0; -+ } else { -+ AuWarn1("renaming dir who has child(ren) on multiple " -+ "branches, is not supported\n"); -+ err = -EXDEV; -+ } -+ } -+ return err; -+} -+ -+/* side effect: sets whlist and h_dentry */ -+static int au_ren_may_dir(struct au_ren_args *a) -+{ -+ int err; -+ unsigned int rdhash; -+ struct dentry *d; -+ -+ d = a->dst_dentry; -+ SiMustAnyLock(d->d_sb); -+ -+ err = 0; -+ if (au_ftest_ren(a->auren_flags, ISDIR_DST) && a->dst_inode) { -+ rdhash = au_sbi(d->d_sb)->si_rdhash; -+ if (!rdhash) -+ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d)); -+ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ -+ if (!a->exchange) { -+ au_set_dbtop(d, a->dst_btop); -+ err = may_rename_dstdir(d, &a->whlist); -+ au_set_dbtop(d, a->btgt); -+ } else -+ err = may_rename_srcdir(a); -+ } -+ a->dst_h_dentry = au_h_dptr(d, au_dbtop(d)); -+ if (unlikely(err)) -+ goto out; -+ -+ d = a->src_dentry; -+ a->src_h_dentry = au_h_dptr(d, au_dbtop(d)); -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) { -+ err = may_rename_srcdir(a); -+ if (unlikely(err)) { -+ au_nhash_wh_free(&a->whlist); -+ a->whlist.nh_num = 0; -+ } -+ } -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * simple tests for rename. -+ * following the checks in vfs, plus the parent-child relationship. -+ */ -+static int au_may_ren(struct au_ren_args *a) -+{ -+ int err, isdir; -+ struct inode *h_inode; -+ -+ if (a->src_btop == a->btgt) { -+ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent, -+ au_ftest_ren(a->auren_flags, ISDIR_SRC)); -+ if (unlikely(err)) -+ goto out; -+ err = -EINVAL; -+ if (unlikely(a->src_h_dentry == a->h_trap)) -+ goto out; -+ } -+ -+ err = 0; -+ if (a->dst_btop != a->btgt) -+ goto out; -+ -+ err = -ENOTEMPTY; -+ if (unlikely(a->dst_h_dentry == a->h_trap)) -+ goto out; -+ -+ err = -EIO; -+ isdir = !!au_ftest_ren(a->auren_flags, ISDIR_DST); -+ if (d_really_is_negative(a->dst_dentry)) { -+ if (d_is_negative(a->dst_h_dentry)) -+ err = au_may_add(a->dst_dentry, a->btgt, -+ a->dst_h_parent, isdir); -+ } else { -+ if (unlikely(d_is_negative(a->dst_h_dentry))) -+ goto out; -+ h_inode = d_inode(a->dst_h_dentry); -+ if (h_inode->i_nlink) -+ err = au_may_del(a->dst_dentry, a->btgt, -+ a->dst_h_parent, isdir); -+ } -+ -+out: -+ if (unlikely(err == -ENOENT || err == -EEXIST)) -+ err = -EIO; -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * locking order -+ * (VFS) -+ * - src_dir and dir by lock_rename() -+ * - inode if exists -+ * (aufs) -+ * - lock all -+ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls, -+ * + si_read_lock -+ * + di_write_lock2_child() -+ * + di_write_lock_child() -+ * + ii_write_lock_child() -+ * + di_write_lock_child2() -+ * + ii_write_lock_child2() -+ * + src_parent and parent -+ * + di_write_lock_parent() -+ * + ii_write_lock_parent() -+ * + di_write_lock_parent2() -+ * + ii_write_lock_parent2() -+ * + lower src_dir and dir by vfsub_lock_rename() -+ * + verify the every relationships between child and parent. if any -+ * of them failed, unlock all and return -EBUSY. -+ */ -+static void au_ren_unlock(struct au_ren_args *a) -+{ -+ vfsub_unlock_rename(a->src_h_parent, a->src_hdir, -+ a->dst_h_parent, a->dst_hdir); -+ if (au_ftest_ren(a->auren_flags, DIRREN) -+ && a->h_root) -+ au_hn_inode_unlock(a->h_root); -+ if (au_ftest_ren(a->auren_flags, MNT_WRITE)) -+ vfsub_mnt_drop_write(au_br_mnt(a->br)); -+} -+ -+static int au_ren_lock(struct au_ren_args *a) -+{ -+ int err; -+ unsigned int udba; -+ -+ err = 0; -+ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt); -+ a->src_hdir = au_hi(a->src_dir, a->btgt); -+ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt); -+ a->dst_hdir = au_hi(a->dst_dir, a->btgt); -+ -+ err = vfsub_mnt_want_write(au_br_mnt(a->br)); -+ if (unlikely(err)) -+ goto out; -+ au_fset_ren(a->auren_flags, MNT_WRITE); -+ if (au_ftest_ren(a->auren_flags, DIRREN)) { -+ struct dentry *root; -+ struct inode *dir; -+ -+ /* -+ * sbinfo is already locked, so this ii_read_lock is -+ * unnecessary. but our debugging feature checks it. -+ */ -+ root = a->src_inode->i_sb->s_root; -+ if (root != a->src_parent && root != a->dst_parent) { -+ dir = d_inode(root); -+ ii_read_lock_parent3(dir); -+ a->h_root = au_hi(dir, a->btgt); -+ ii_read_unlock(dir); -+ au_hn_inode_lock_nested(a->h_root, AuLsc_I_PARENT3); -+ } -+ } -+ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir, -+ a->dst_h_parent, a->dst_hdir); -+ udba = au_opt_udba(a->src_dentry->d_sb); -+ if (unlikely(a->src_hdir->hi_inode != d_inode(a->src_h_parent) -+ || a->dst_hdir->hi_inode != d_inode(a->dst_h_parent))) -+ err = au_busy_or_stale(); -+ if (!err && au_dbtop(a->src_dentry) == a->btgt) -+ err = au_h_verify(a->src_h_dentry, udba, -+ d_inode(a->src_h_parent), a->src_h_parent, -+ a->br); -+ if (!err && au_dbtop(a->dst_dentry) == a->btgt) -+ err = au_h_verify(a->dst_h_dentry, udba, -+ d_inode(a->dst_h_parent), a->dst_h_parent, -+ a->br); -+ if (!err) -+ goto out; /* success */ -+ -+ err = au_busy_or_stale(); -+ au_ren_unlock(a); -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void au_ren_refresh_dir(struct au_ren_args *a) -+{ -+ struct inode *dir; -+ -+ dir = a->dst_dir; -+ inode_inc_iversion(dir); -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) { -+ /* is this updating defined in POSIX? */ -+ au_cpup_attr_timesizes(a->src_inode); -+ au_cpup_attr_nlink(dir, /*force*/1); -+ } -+ au_dir_ts(dir, a->btgt); -+ -+ if (a->exchange) { -+ dir = a->src_dir; -+ inode_inc_iversion(dir); -+ if (au_ftest_ren(a->auren_flags, ISDIR_DST)) { -+ /* is this updating defined in POSIX? */ -+ au_cpup_attr_timesizes(a->dst_inode); -+ au_cpup_attr_nlink(dir, /*force*/1); -+ } -+ au_dir_ts(dir, a->btgt); -+ } -+ -+ if (au_ftest_ren(a->auren_flags, ISSAMEDIR)) -+ return; -+ -+ dir = a->src_dir; -+ inode_inc_iversion(dir); -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC)) -+ au_cpup_attr_nlink(dir, /*force*/1); -+ au_dir_ts(dir, a->btgt); -+} -+ -+static void au_ren_refresh(struct au_ren_args *a) -+{ -+ aufs_bindex_t bbot, bindex; -+ struct dentry *d, *h_d; -+ struct inode *i, *h_i; -+ struct super_block *sb; -+ -+ d = a->dst_dentry; -+ d_drop(d); -+ if (a->h_dst) -+ /* already dget-ed by au_ren_or_cpup() */ -+ au_set_h_dptr(d, a->btgt, a->h_dst); -+ -+ i = a->dst_inode; -+ if (i) { -+ if (!a->exchange) { -+ if (!au_ftest_ren(a->auren_flags, ISDIR_DST)) -+ vfsub_drop_nlink(i); -+ else { -+ vfsub_dead_dir(i); -+ au_cpup_attr_timesizes(i); -+ } -+ au_update_dbrange(d, /*do_put_zero*/1); -+ } else -+ au_cpup_attr_nlink(i, /*force*/1); -+ } else { -+ bbot = a->btgt; -+ for (bindex = au_dbtop(d); bindex < bbot; bindex++) -+ au_set_h_dptr(d, bindex, NULL); -+ bbot = au_dbbot(d); -+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) -+ au_set_h_dptr(d, bindex, NULL); -+ au_update_dbrange(d, /*do_put_zero*/0); -+ } -+ -+ if (a->exchange -+ || au_ftest_ren(a->auren_flags, DIRREN)) { -+ d_drop(a->src_dentry); -+ if (au_ftest_ren(a->auren_flags, DIRREN)) -+ au_set_dbwh(a->src_dentry, -1); -+ return; -+ } -+ -+ d = a->src_dentry; -+ au_set_dbwh(d, -1); -+ bbot = au_dbbot(d); -+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) { -+ h_d = au_h_dptr(d, bindex); -+ if (h_d) -+ au_set_h_dptr(d, bindex, NULL); -+ } -+ au_set_dbbot(d, a->btgt); -+ -+ sb = d->d_sb; -+ i = a->src_inode; -+ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i)) -+ return; /* success */ -+ -+ bbot = au_ibbot(i); -+ for (bindex = a->btgt + 1; bindex <= bbot; bindex++) { -+ h_i = au_h_iptr(i, bindex); -+ if (h_i) { -+ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0); -+ /* ignore this error */ -+ au_set_h_iptr(i, bindex, NULL, 0); -+ } -+ } -+ au_set_ibbot(i, a->btgt); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* mainly for link(2) and rename(2) */ -+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt) -+{ -+ aufs_bindex_t bdiropq, bwh; -+ struct dentry *parent; -+ struct au_branch *br; -+ -+ parent = dentry->d_parent; -+ IMustLock(d_inode(parent)); /* dir is locked */ -+ -+ bdiropq = au_dbdiropq(parent); -+ bwh = au_dbwh(dentry); -+ br = au_sbr(dentry->d_sb, btgt); -+ if (au_br_rdonly(br) -+ || (0 <= bdiropq && bdiropq < btgt) -+ || (0 <= bwh && bwh < btgt)) -+ btgt = -1; -+ -+ AuDbg("btgt %d\n", btgt); -+ return btgt; -+} -+ -+/* sets src_btop, dst_btop and btgt */ -+static int au_ren_wbr(struct au_ren_args *a) -+{ -+ int err; -+ struct au_wr_dir_args wr_dir_args = { -+ /* .force_btgt = -1, */ -+ .flags = AuWrDir_ADD_ENTRY -+ }; -+ -+ a->src_btop = au_dbtop(a->src_dentry); -+ a->dst_btop = au_dbtop(a->dst_dentry); -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC) -+ || au_ftest_ren(a->auren_flags, ISDIR_DST)) -+ au_fset_wrdir(wr_dir_args.flags, ISDIR); -+ wr_dir_args.force_btgt = a->src_btop; -+ if (a->dst_inode && a->dst_btop < a->src_btop) -+ wr_dir_args.force_btgt = a->dst_btop; -+ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt); -+ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args); -+ a->btgt = err; -+ if (a->exchange) -+ au_update_dbtop(a->dst_dentry); -+ -+ return err; -+} -+ -+static void au_ren_dt(struct au_ren_args *a) -+{ -+ a->h_path.dentry = a->src_h_parent; -+ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path); -+ if (!au_ftest_ren(a->auren_flags, ISSAMEDIR)) { -+ a->h_path.dentry = a->dst_h_parent; -+ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path); -+ } -+ -+ au_fclr_ren(a->auren_flags, DT_DSTDIR); -+ if (!au_ftest_ren(a->auren_flags, ISDIR_SRC) -+ && !a->exchange) -+ return; -+ -+ a->h_path.dentry = a->src_h_dentry; -+ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path); -+ if (d_is_positive(a->dst_h_dentry)) { -+ au_fset_ren(a->auren_flags, DT_DSTDIR); -+ a->h_path.dentry = a->dst_h_dentry; -+ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path); -+ } -+} -+ -+static void au_ren_rev_dt(int err, struct au_ren_args *a) -+{ -+ struct dentry *h_d; -+ struct inode *h_inode; -+ -+ au_dtime_revert(a->src_dt + AuPARENT); -+ if (!au_ftest_ren(a->auren_flags, ISSAMEDIR)) -+ au_dtime_revert(a->dst_dt + AuPARENT); -+ -+ if (au_ftest_ren(a->auren_flags, ISDIR_SRC) && err != -EIO) { -+ h_d = a->src_dt[AuCHILD].dt_h_path.dentry; -+ h_inode = d_inode(h_d); -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ au_dtime_revert(a->src_dt + AuCHILD); -+ inode_unlock(h_inode); -+ -+ if (au_ftest_ren(a->auren_flags, DT_DSTDIR)) { -+ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry; -+ h_inode = d_inode(h_d); -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ au_dtime_revert(a->dst_dt + AuCHILD); -+ inode_unlock(h_inode); -+ } -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry, -+ struct inode *_dst_dir, struct dentry *_dst_dentry, -+ unsigned int _flags) -+{ -+ int err, lock_flags; -+ void *rev; -+ /* reduce stack space */ -+ struct au_ren_args *a; -+ struct au_pin pin; -+ -+ AuDbg("%pd, %pd, 0x%x\n", _src_dentry, _dst_dentry, _flags); -+ IMustLock(_src_dir); -+ IMustLock(_dst_dir); -+ -+ err = -EINVAL; -+ if (unlikely(_flags & RENAME_WHITEOUT)) -+ goto out; -+ -+ err = -ENOMEM; -+ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE); -+ a = kzalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ a->flags = _flags; -+ BUILD_BUG_ON(sizeof(a->exchange) == sizeof(u8) -+ && RENAME_EXCHANGE > U8_MAX); -+ a->exchange = _flags & RENAME_EXCHANGE; -+ a->src_dir = _src_dir; -+ a->src_dentry = _src_dentry; -+ a->src_inode = NULL; -+ if (d_really_is_positive(a->src_dentry)) -+ a->src_inode = d_inode(a->src_dentry); -+ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */ -+ a->dst_dir = _dst_dir; -+ a->dst_dentry = _dst_dentry; -+ a->dst_inode = NULL; -+ if (d_really_is_positive(a->dst_dentry)) -+ a->dst_inode = d_inode(a->dst_dentry); -+ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */ -+ if (a->dst_inode) { -+ /* -+ * if EXCHANGE && src is non-dir && dst is dir, -+ * dst is not locked. -+ */ -+ /* IMustLock(a->dst_inode); */ -+ au_igrab(a->dst_inode); -+ } -+ -+ err = -ENOTDIR; -+ lock_flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN; -+ if (d_is_dir(a->src_dentry)) { -+ au_fset_ren(a->auren_flags, ISDIR_SRC); -+ if (unlikely(!a->exchange -+ && d_really_is_positive(a->dst_dentry) -+ && !d_is_dir(a->dst_dentry))) -+ goto out_free; -+ lock_flags |= AuLock_DIRS; -+ } -+ if (a->dst_inode && d_is_dir(a->dst_dentry)) { -+ au_fset_ren(a->auren_flags, ISDIR_DST); -+ if (unlikely(!a->exchange -+ && d_really_is_positive(a->src_dentry) -+ && !d_is_dir(a->src_dentry))) -+ goto out_free; -+ lock_flags |= AuLock_DIRS; -+ } -+ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry, -+ lock_flags); -+ if (unlikely(err)) -+ goto out_free; -+ -+ err = au_d_hashed_positive(a->src_dentry); -+ if (unlikely(err)) -+ goto out_unlock; -+ err = -ENOENT; -+ if (a->dst_inode) { -+ /* -+ * If it is a dir, VFS unhash it before this -+ * function. It means we cannot rely upon d_unhashed(). -+ */ -+ if (unlikely(!a->dst_inode->i_nlink)) -+ goto out_unlock; -+ if (!au_ftest_ren(a->auren_flags, ISDIR_DST)) { -+ err = au_d_hashed_positive(a->dst_dentry); -+ if (unlikely(err && !a->exchange)) -+ goto out_unlock; -+ } else if (unlikely(IS_DEADDIR(a->dst_inode))) -+ goto out_unlock; -+ } else if (unlikely(d_unhashed(a->dst_dentry))) -+ goto out_unlock; -+ -+ /* -+ * is it possible? -+ * yes, it happened (in linux-3.3-rcN) but I don't know why. -+ * there may exist a problem somewhere else. -+ */ -+ err = -EINVAL; -+ if (unlikely(d_inode(a->dst_parent) == d_inode(a->src_dentry))) -+ goto out_unlock; -+ -+ au_fset_ren(a->auren_flags, ISSAMEDIR); /* temporary */ -+ di_write_lock_parent(a->dst_parent); -+ -+ /* which branch we process */ -+ err = au_ren_wbr(a); -+ if (unlikely(err < 0)) -+ goto out_parent; -+ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt); -+ a->h_path.mnt = au_br_mnt(a->br); -+ -+ /* are they available to be renamed */ -+ err = au_ren_may_dir(a); -+ if (unlikely(err)) -+ goto out_children; -+ -+ /* prepare the writable parent dir on the same branch */ -+ if (a->dst_btop == a->btgt) { -+ au_fset_ren(a->auren_flags, WHDST); -+ } else { -+ err = au_cpup_dirs(a->dst_dentry, a->btgt); -+ if (unlikely(err)) -+ goto out_children; -+ } -+ -+ err = 0; -+ if (!a->exchange) { -+ if (a->src_dir != a->dst_dir) { -+ /* -+ * this temporary unlock is safe, -+ * because both dir->i_mutex are locked. -+ */ -+ di_write_unlock(a->dst_parent); -+ di_write_lock_parent(a->src_parent); -+ err = au_wr_dir_need_wh(a->src_dentry, -+ au_ftest_ren(a->auren_flags, -+ ISDIR_SRC), -+ &a->btgt); -+ di_write_unlock(a->src_parent); -+ di_write_lock2_parent(a->src_parent, a->dst_parent, -+ /*isdir*/1); -+ au_fclr_ren(a->auren_flags, ISSAMEDIR); -+ } else -+ err = au_wr_dir_need_wh(a->src_dentry, -+ au_ftest_ren(a->auren_flags, -+ ISDIR_SRC), -+ &a->btgt); -+ } -+ if (unlikely(err < 0)) -+ goto out_children; -+ if (err) -+ au_fset_ren(a->auren_flags, WHSRC); -+ -+ /* cpup src */ -+ if (a->src_btop != a->btgt) { -+ err = au_pin(&pin, a->src_dentry, a->btgt, -+ au_opt_udba(a->src_dentry->d_sb), -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (!err) { -+ struct au_cp_generic cpg = { -+ .dentry = a->src_dentry, -+ .bdst = a->btgt, -+ .bsrc = a->src_btop, -+ .len = -1, -+ .pin = &pin, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN -+ }; -+ AuDebugOn(au_dbtop(a->src_dentry) != a->src_btop); -+ err = au_sio_cpup_simple(&cpg); -+ au_unpin(&pin); -+ } -+ if (unlikely(err)) -+ goto out_children; -+ a->src_btop = a->btgt; -+ a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt); -+ if (!a->exchange) -+ au_fset_ren(a->auren_flags, WHSRC); -+ } -+ -+ /* cpup dst */ -+ if (a->exchange && a->dst_inode -+ && a->dst_btop != a->btgt) { -+ err = au_pin(&pin, a->dst_dentry, a->btgt, -+ au_opt_udba(a->dst_dentry->d_sb), -+ AuPin_DI_LOCKED | AuPin_MNT_WRITE); -+ if (!err) { -+ struct au_cp_generic cpg = { -+ .dentry = a->dst_dentry, -+ .bdst = a->btgt, -+ .bsrc = a->dst_btop, -+ .len = -1, -+ .pin = &pin, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN -+ }; -+ err = au_sio_cpup_simple(&cpg); -+ au_unpin(&pin); -+ } -+ if (unlikely(err)) -+ goto out_children; -+ a->dst_btop = a->btgt; -+ a->dst_h_dentry = au_h_dptr(a->dst_dentry, a->btgt); -+ } -+ -+ /* lock them all */ -+ err = au_ren_lock(a); -+ if (unlikely(err)) -+ /* leave the copied-up one */ -+ goto out_children; -+ -+ if (!a->exchange) { -+ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE)) -+ err = au_may_ren(a); -+ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN)) -+ err = -ENAMETOOLONG; -+ if (unlikely(err)) -+ goto out_hdir; -+ } -+ -+ /* store timestamps to be revertible */ -+ au_ren_dt(a); -+ -+ /* store dirren info */ -+ if (au_ftest_ren(a->auren_flags, DIRREN)) { -+ err = au_dr_rename(a->src_dentry, a->btgt, -+ &a->dst_dentry->d_name, &rev); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out_dt; -+ } -+ -+ /* here we go */ -+ err = do_rename(a); -+ if (unlikely(err)) -+ goto out_dirren; -+ -+ if (au_ftest_ren(a->auren_flags, DIRREN)) -+ au_dr_rename_fin(a->src_dentry, a->btgt, rev); -+ -+ /* update dir attributes */ -+ au_ren_refresh_dir(a); -+ -+ /* dput/iput all lower dentries */ -+ au_ren_refresh(a); -+ -+ goto out_hdir; /* success */ -+ -+out_dirren: -+ if (au_ftest_ren(a->auren_flags, DIRREN)) -+ au_dr_rename_rev(a->src_dentry, a->btgt, rev); -+out_dt: -+ au_ren_rev_dt(err, a); -+out_hdir: -+ au_ren_unlock(a); -+out_children: -+ au_nhash_wh_free(&a->whlist); -+ if (err && a->dst_inode && a->dst_btop != a->btgt) { -+ AuDbg("btop %d, btgt %d\n", a->dst_btop, a->btgt); -+ au_set_h_dptr(a->dst_dentry, a->btgt, NULL); -+ au_set_dbtop(a->dst_dentry, a->dst_btop); -+ } -+out_parent: -+ if (!err) { -+ if (d_unhashed(a->src_dentry)) -+ au_fset_ren(a->auren_flags, DROPPED_SRC); -+ if (d_unhashed(a->dst_dentry)) -+ au_fset_ren(a->auren_flags, DROPPED_DST); -+ if (!a->exchange) -+ d_move(a->src_dentry, a->dst_dentry); -+ else { -+ d_exchange(a->src_dentry, a->dst_dentry); -+ if (au_ftest_ren(a->auren_flags, DROPPED_DST)) -+ d_drop(a->dst_dentry); -+ } -+ if (au_ftest_ren(a->auren_flags, DROPPED_SRC)) -+ d_drop(a->src_dentry); -+ } else { -+ au_update_dbtop(a->dst_dentry); -+ if (!a->dst_inode) -+ d_drop(a->dst_dentry); -+ } -+ if (au_ftest_ren(a->auren_flags, ISSAMEDIR)) -+ di_write_unlock(a->dst_parent); -+ else -+ di_write_unlock2(a->src_parent, a->dst_parent); -+out_unlock: -+ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry); -+out_free: -+ iput(a->dst_inode); -+ if (a->thargs) -+ au_whtmp_rmdir_free(a->thargs); -+ kfree(a); -+out: -+ AuTraceErr(err); -+ return err; -+} -diff --git a/fs/aufs/iinfo.c b/fs/aufs/iinfo.c -new file mode 100644 -index 000000000..f6c512d96 ---- /dev/null -+++ b/fs/aufs/iinfo.c -@@ -0,0 +1,286 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * inode private data -+ */ -+ -+#include "aufs.h" -+ -+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex) -+{ -+ struct inode *h_inode; -+ struct au_hinode *hinode; -+ -+ IiMustAnyLock(inode); -+ -+ hinode = au_hinode(au_ii(inode), bindex); -+ h_inode = hinode->hi_inode; -+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); -+ return h_inode; -+} -+ -+/* todo: hard/soft set? */ -+void au_hiput(struct au_hinode *hinode) -+{ -+ au_hn_free(hinode); -+ dput(hinode->hi_whdentry); -+ iput(hinode->hi_inode); -+} -+ -+unsigned int au_hi_flags(struct inode *inode, int isdir) -+{ -+ unsigned int flags; -+ const unsigned int mnt_flags = au_mntflags(inode->i_sb); -+ -+ flags = 0; -+ if (au_opt_test(mnt_flags, XINO)) -+ au_fset_hi(flags, XINO); -+ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY)) -+ au_fset_hi(flags, HNOTIFY); -+ return flags; -+} -+ -+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, -+ struct inode *h_inode, unsigned int flags) -+{ -+ struct au_hinode *hinode; -+ struct inode *hi; -+ struct au_iinfo *iinfo = au_ii(inode); -+ -+ IiMustWriteLock(inode); -+ -+ hinode = au_hinode(iinfo, bindex); -+ hi = hinode->hi_inode; -+ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); -+ -+ if (hi) -+ au_hiput(hinode); -+ hinode->hi_inode = h_inode; -+ if (h_inode) { -+ int err; -+ struct super_block *sb = inode->i_sb; -+ struct au_branch *br; -+ -+ AuDebugOn(inode->i_mode -+ && (h_inode->i_mode & S_IFMT) -+ != (inode->i_mode & S_IFMT)); -+ if (bindex == iinfo->ii_btop) -+ au_cpup_igen(inode, h_inode); -+ br = au_sbr(sb, bindex); -+ hinode->hi_id = br->br_id; -+ if (au_ftest_hi(flags, XINO)) { -+ err = au_xino_write(sb, bindex, h_inode->i_ino, -+ inode->i_ino); -+ if (unlikely(err)) -+ AuIOErr1("failed au_xino_write() %d\n", err); -+ } -+ -+ if (au_ftest_hi(flags, HNOTIFY) -+ && au_br_hnotifyable(br->br_perm)) { -+ err = au_hn_alloc(hinode, inode); -+ if (unlikely(err)) -+ AuIOErr1("au_hn_alloc() %d\n", err); -+ } -+ } -+} -+ -+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_wh) -+{ -+ struct au_hinode *hinode; -+ -+ IiMustWriteLock(inode); -+ -+ hinode = au_hinode(au_ii(inode), bindex); -+ AuDebugOn(hinode->hi_whdentry); -+ hinode->hi_whdentry = h_wh; -+} -+ -+void au_update_iigen(struct inode *inode, int half) -+{ -+ struct au_iinfo *iinfo; -+ struct au_iigen *iigen; -+ unsigned int sigen; -+ -+ sigen = au_sigen(inode->i_sb); -+ iinfo = au_ii(inode); -+ iigen = &iinfo->ii_generation; -+ spin_lock(&iigen->ig_spin); -+ iigen->ig_generation = sigen; -+ if (half) -+ au_ig_fset(iigen->ig_flags, HALF_REFRESHED); -+ else -+ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED); -+ spin_unlock(&iigen->ig_spin); -+} -+ -+/* it may be called at remount time, too */ -+void au_update_ibrange(struct inode *inode, int do_put_zero) -+{ -+ struct au_iinfo *iinfo; -+ aufs_bindex_t bindex, bbot; -+ -+ AuDebugOn(au_is_bad_inode(inode)); -+ IiMustWriteLock(inode); -+ -+ iinfo = au_ii(inode); -+ if (do_put_zero && iinfo->ii_btop >= 0) { -+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot; -+ bindex++) { -+ struct inode *h_i; -+ -+ h_i = au_hinode(iinfo, bindex)->hi_inode; -+ if (h_i -+ && !h_i->i_nlink -+ && !(h_i->i_state & I_LINKABLE)) -+ au_set_h_iptr(inode, bindex, NULL, 0); -+ } -+ } -+ -+ iinfo->ii_btop = -1; -+ iinfo->ii_bbot = -1; -+ bbot = au_sbbot(inode->i_sb); -+ for (bindex = 0; bindex <= bbot; bindex++) -+ if (au_hinode(iinfo, bindex)->hi_inode) { -+ iinfo->ii_btop = bindex; -+ break; -+ } -+ if (iinfo->ii_btop >= 0) -+ for (bindex = bbot; bindex >= iinfo->ii_btop; bindex--) -+ if (au_hinode(iinfo, bindex)->hi_inode) { -+ iinfo->ii_bbot = bindex; -+ break; -+ } -+ AuDebugOn(iinfo->ii_btop > iinfo->ii_bbot); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_icntnr_init_once(void *_c) -+{ -+ struct au_icntnr *c = _c; -+ struct au_iinfo *iinfo = &c->iinfo; -+ -+ spin_lock_init(&iinfo->ii_generation.ig_spin); -+ au_rw_init(&iinfo->ii_rwsem); -+ inode_init_once(&c->vfs_inode); -+} -+ -+void au_hinode_init(struct au_hinode *hinode) -+{ -+ hinode->hi_inode = NULL; -+ hinode->hi_id = -1; -+ au_hn_init(hinode); -+ hinode->hi_whdentry = NULL; -+} -+ -+int au_iinfo_init(struct inode *inode) -+{ -+ struct au_iinfo *iinfo; -+ struct super_block *sb; -+ struct au_hinode *hi; -+ int nbr, i; -+ -+ sb = inode->i_sb; -+ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); -+ nbr = au_sbbot(sb) + 1; -+ if (unlikely(nbr <= 0)) -+ nbr = 1; -+ hi = kmalloc_array(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS); -+ if (hi) { -+ au_lcnt_inc(&au_sbi(sb)->si_ninodes); -+ -+ iinfo->ii_hinode = hi; -+ for (i = 0; i < nbr; i++, hi++) -+ au_hinode_init(hi); -+ -+ iinfo->ii_generation.ig_generation = au_sigen(sb); -+ iinfo->ii_btop = -1; -+ iinfo->ii_bbot = -1; -+ iinfo->ii_vdir = NULL; -+ return 0; -+ } -+ return -ENOMEM; -+} -+ -+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink) -+{ -+ int err, i; -+ struct au_hinode *hip; -+ -+ AuRwMustWriteLock(&iinfo->ii_rwsem); -+ -+ err = -ENOMEM; -+ hip = au_krealloc(iinfo->ii_hinode, sizeof(*hip) * nbr, GFP_NOFS, -+ may_shrink); -+ if (hip) { -+ iinfo->ii_hinode = hip; -+ i = iinfo->ii_bbot + 1; -+ hip += i; -+ for (; i < nbr; i++, hip++) -+ au_hinode_init(hip); -+ err = 0; -+ } -+ -+ return err; -+} -+ -+void au_iinfo_fin(struct inode *inode) -+{ -+ struct au_iinfo *iinfo; -+ struct au_hinode *hi; -+ struct super_block *sb; -+ aufs_bindex_t bindex, bbot; -+ const unsigned char unlinked = !inode->i_nlink; -+ -+ AuDebugOn(au_is_bad_inode(inode)); -+ -+ sb = inode->i_sb; -+ au_lcnt_dec(&au_sbi(sb)->si_ninodes); -+ if (si_pid_test(sb)) -+ au_xino_delete_inode(inode, unlinked); -+ else { -+ /* -+ * it is safe to hide the dependency between sbinfo and -+ * sb->s_umount. -+ */ -+ lockdep_off(); -+ si_noflush_read_lock(sb); -+ au_xino_delete_inode(inode, unlinked); -+ si_read_unlock(sb); -+ lockdep_on(); -+ } -+ -+ iinfo = au_ii(inode); -+ if (iinfo->ii_vdir) -+ au_vdir_free(iinfo->ii_vdir); -+ -+ bindex = iinfo->ii_btop; -+ if (bindex >= 0) { -+ hi = au_hinode(iinfo, bindex); -+ bbot = iinfo->ii_bbot; -+ while (bindex++ <= bbot) { -+ if (hi->hi_inode) -+ au_hiput(hi); -+ hi++; -+ } -+ } -+ kfree(iinfo->ii_hinode); -+ AuRwDestroy(&iinfo->ii_rwsem); -+} -diff --git a/fs/aufs/inode.c b/fs/aufs/inode.c -new file mode 100644 -index 000000000..50ec91179 ---- /dev/null -+++ b/fs/aufs/inode.c -@@ -0,0 +1,528 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * inode functions -+ */ -+ -+#include "aufs.h" -+ -+struct inode *au_igrab(struct inode *inode) -+{ -+ if (inode) { -+ AuDebugOn(!atomic_read(&inode->i_count)); -+ ihold(inode); -+ } -+ return inode; -+} -+ -+static void au_refresh_hinode_attr(struct inode *inode, int do_version) -+{ -+ au_cpup_attr_all(inode, /*force*/0); -+ au_update_iigen(inode, /*half*/1); -+ if (do_version) -+ inode_inc_iversion(inode); -+} -+ -+static int au_ii_refresh(struct inode *inode, int *update) -+{ -+ int err, e, nbr; -+ umode_t type; -+ aufs_bindex_t bindex, new_bindex; -+ struct super_block *sb; -+ struct au_iinfo *iinfo; -+ struct au_hinode *p, *q, tmp; -+ -+ AuDebugOn(au_is_bad_inode(inode)); -+ IiMustWriteLock(inode); -+ -+ *update = 0; -+ sb = inode->i_sb; -+ nbr = au_sbbot(sb) + 1; -+ type = inode->i_mode & S_IFMT; -+ iinfo = au_ii(inode); -+ err = au_hinode_realloc(iinfo, nbr, /*may_shrink*/0); -+ if (unlikely(err)) -+ goto out; -+ -+ AuDebugOn(iinfo->ii_btop < 0); -+ p = au_hinode(iinfo, iinfo->ii_btop); -+ for (bindex = iinfo->ii_btop; bindex <= iinfo->ii_bbot; -+ bindex++, p++) { -+ if (!p->hi_inode) -+ continue; -+ -+ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT)); -+ new_bindex = au_br_index(sb, p->hi_id); -+ if (new_bindex == bindex) -+ continue; -+ -+ if (new_bindex < 0) { -+ *update = 1; -+ au_hiput(p); -+ p->hi_inode = NULL; -+ continue; -+ } -+ -+ if (new_bindex < iinfo->ii_btop) -+ iinfo->ii_btop = new_bindex; -+ if (iinfo->ii_bbot < new_bindex) -+ iinfo->ii_bbot = new_bindex; -+ /* swap two lower inode, and loop again */ -+ q = au_hinode(iinfo, new_bindex); -+ tmp = *q; -+ *q = *p; -+ *p = tmp; -+ if (tmp.hi_inode) { -+ bindex--; -+ p--; -+ } -+ } -+ au_update_ibrange(inode, /*do_put_zero*/0); -+ au_hinode_realloc(iinfo, nbr, /*may_shrink*/1); /* harmless if err */ -+ e = au_dy_irefresh(inode); -+ if (unlikely(e && !err)) -+ err = e; -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_refresh_iop(struct inode *inode, int force_getattr) -+{ -+ int type; -+ struct au_sbinfo *sbi = au_sbi(inode->i_sb); -+ const struct inode_operations *iop -+ = force_getattr ? aufs_iop : sbi->si_iop_array; -+ -+ if (inode->i_op == iop) -+ return; -+ -+ switch (inode->i_mode & S_IFMT) { -+ case S_IFDIR: -+ type = AuIop_DIR; -+ break; -+ case S_IFLNK: -+ type = AuIop_SYMLINK; -+ break; -+ default: -+ type = AuIop_OTHER; -+ break; -+ } -+ -+ inode->i_op = iop + type; -+ /* unnecessary smp_wmb() */ -+} -+ -+int au_refresh_hinode_self(struct inode *inode) -+{ -+ int err, update; -+ -+ err = au_ii_refresh(inode, &update); -+ if (!err) -+ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode)); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_refresh_hinode(struct inode *inode, struct dentry *dentry) -+{ -+ int err, e, update; -+ unsigned int flags; -+ umode_t mode; -+ aufs_bindex_t bindex, bbot; -+ unsigned char isdir; -+ struct au_hinode *p; -+ struct au_iinfo *iinfo; -+ -+ err = au_ii_refresh(inode, &update); -+ if (unlikely(err)) -+ goto out; -+ -+ update = 0; -+ iinfo = au_ii(inode); -+ p = au_hinode(iinfo, iinfo->ii_btop); -+ mode = (inode->i_mode & S_IFMT); -+ isdir = S_ISDIR(mode); -+ flags = au_hi_flags(inode, isdir); -+ bbot = au_dbbot(dentry); -+ for (bindex = au_dbtop(dentry); bindex <= bbot; bindex++) { -+ struct inode *h_i, *h_inode; -+ struct dentry *h_d; -+ -+ h_d = au_h_dptr(dentry, bindex); -+ if (!h_d || d_is_negative(h_d)) -+ continue; -+ -+ h_inode = d_inode(h_d); -+ AuDebugOn(mode != (h_inode->i_mode & S_IFMT)); -+ if (iinfo->ii_btop <= bindex && bindex <= iinfo->ii_bbot) { -+ h_i = au_h_iptr(inode, bindex); -+ if (h_i) { -+ if (h_i == h_inode) -+ continue; -+ err = -EIO; -+ break; -+ } -+ } -+ if (bindex < iinfo->ii_btop) -+ iinfo->ii_btop = bindex; -+ if (iinfo->ii_bbot < bindex) -+ iinfo->ii_bbot = bindex; -+ au_set_h_iptr(inode, bindex, au_igrab(h_inode), flags); -+ update = 1; -+ } -+ au_update_ibrange(inode, /*do_put_zero*/0); -+ e = au_dy_irefresh(inode); -+ if (unlikely(e && !err)) -+ err = e; -+ if (!err) -+ au_refresh_hinode_attr(inode, update && isdir); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int set_inode(struct inode *inode, struct dentry *dentry) -+{ -+ int err; -+ unsigned int flags; -+ umode_t mode; -+ aufs_bindex_t bindex, btop, btail; -+ unsigned char isdir; -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ struct au_iinfo *iinfo; -+ struct inode_operations *iop; -+ -+ IiMustWriteLock(inode); -+ -+ err = 0; -+ isdir = 0; -+ iop = au_sbi(inode->i_sb)->si_iop_array; -+ btop = au_dbtop(dentry); -+ h_dentry = au_h_dptr(dentry, btop); -+ h_inode = d_inode(h_dentry); -+ mode = h_inode->i_mode; -+ switch (mode & S_IFMT) { -+ case S_IFREG: -+ btail = au_dbtail(dentry); -+ inode->i_op = iop + AuIop_OTHER; -+ inode->i_fop = &aufs_file_fop; -+ err = au_dy_iaop(inode, btop, h_inode); -+ if (unlikely(err)) -+ goto out; -+ break; -+ case S_IFDIR: -+ isdir = 1; -+ btail = au_dbtaildir(dentry); -+ inode->i_op = iop + AuIop_DIR; -+ inode->i_fop = &aufs_dir_fop; -+ break; -+ case S_IFLNK: -+ btail = au_dbtail(dentry); -+ inode->i_op = iop + AuIop_SYMLINK; -+ break; -+ case S_IFBLK: -+ case S_IFCHR: -+ case S_IFIFO: -+ case S_IFSOCK: -+ btail = au_dbtail(dentry); -+ inode->i_op = iop + AuIop_OTHER; -+ init_special_inode(inode, mode, h_inode->i_rdev); -+ break; -+ default: -+ AuIOErr("Unknown file type 0%o\n", mode); -+ err = -EIO; -+ goto out; -+ } -+ -+ /* do not set hnotify for whiteouted dirs (SHWH mode) */ -+ flags = au_hi_flags(inode, isdir); -+ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH) -+ && au_ftest_hi(flags, HNOTIFY) -+ && dentry->d_name.len > AUFS_WH_PFX_LEN -+ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) -+ au_fclr_hi(flags, HNOTIFY); -+ iinfo = au_ii(inode); -+ iinfo->ii_btop = btop; -+ iinfo->ii_bbot = btail; -+ for (bindex = btop; bindex <= btail; bindex++) { -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (h_dentry) -+ au_set_h_iptr(inode, bindex, -+ au_igrab(d_inode(h_dentry)), flags); -+ } -+ au_cpup_attr_all(inode, /*force*/1); -+ /* -+ * to force calling aufs_get_acl() every time, -+ * do not call cache_no_acl() for aufs inode. -+ */ -+ -+out: -+ return err; -+} -+ -+/* -+ * successful returns with iinfo write_locked -+ * minus: errno -+ * zero: success, matched -+ * plus: no error, but unmatched -+ */ -+static int reval_inode(struct inode *inode, struct dentry *dentry) -+{ -+ int err; -+ unsigned int gen, igflags; -+ aufs_bindex_t bindex, bbot; -+ struct inode *h_inode, *h_dinode; -+ struct dentry *h_dentry; -+ -+ /* -+ * before this function, if aufs got any iinfo lock, it must be only -+ * one, the parent dir. -+ * it can happen by UDBA and the obsoleted inode number. -+ */ -+ err = -EIO; -+ if (unlikely(inode->i_ino == parent_ino(dentry))) -+ goto out; -+ -+ err = 1; -+ ii_write_lock_new_child(inode); -+ h_dentry = au_h_dptr(dentry, au_dbtop(dentry)); -+ h_dinode = d_inode(h_dentry); -+ bbot = au_ibbot(inode); -+ for (bindex = au_ibtop(inode); bindex <= bbot; bindex++) { -+ h_inode = au_h_iptr(inode, bindex); -+ if (!h_inode || h_inode != h_dinode) -+ continue; -+ -+ err = 0; -+ gen = au_iigen(inode, &igflags); -+ if (gen == au_digen(dentry) -+ && !au_ig_ftest(igflags, HALF_REFRESHED)) -+ break; -+ -+ /* fully refresh inode using dentry */ -+ err = au_refresh_hinode(inode, dentry); -+ if (!err) -+ au_update_iigen(inode, /*half*/0); -+ break; -+ } -+ -+ if (unlikely(err)) -+ ii_write_unlock(inode); -+out: -+ return err; -+} -+ -+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ unsigned int d_type, ino_t *ino) -+{ -+ int err, idx; -+ const int isnondir = d_type != DT_DIR; -+ -+ /* prevent hardlinked inode number from race condition */ -+ if (isnondir) { -+ err = au_xinondir_enter(sb, bindex, h_ino, &idx); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ err = au_xino_read(sb, bindex, h_ino, ino); -+ if (unlikely(err)) -+ goto out_xinondir; -+ -+ if (!*ino) { -+ err = -EIO; -+ *ino = au_xino_new_ino(sb); -+ if (unlikely(!*ino)) -+ goto out_xinondir; -+ err = au_xino_write(sb, bindex, h_ino, *ino); -+ if (unlikely(err)) -+ goto out_xinondir; -+ } -+ -+out_xinondir: -+ if (isnondir && idx >= 0) -+ au_xinondir_leave(sb, bindex, h_ino, idx); -+out: -+ return err; -+} -+ -+/* successful returns with iinfo write_locked */ -+/* todo: return with unlocked? */ -+struct inode *au_new_inode(struct dentry *dentry, int must_new) -+{ -+ struct inode *inode, *h_inode; -+ struct dentry *h_dentry; -+ struct super_block *sb; -+ ino_t h_ino, ino; -+ int err, idx, hlinked; -+ aufs_bindex_t btop; -+ -+ sb = dentry->d_sb; -+ btop = au_dbtop(dentry); -+ h_dentry = au_h_dptr(dentry, btop); -+ h_inode = d_inode(h_dentry); -+ h_ino = h_inode->i_ino; -+ hlinked = !d_is_dir(h_dentry) && h_inode->i_nlink > 1; -+ -+new_ino: -+ /* -+ * stop 'race'-ing between hardlinks under different -+ * parents. -+ */ -+ if (hlinked) { -+ err = au_xinondir_enter(sb, btop, h_ino, &idx); -+ inode = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ err = au_xino_read(sb, btop, h_ino, &ino); -+ inode = ERR_PTR(err); -+ if (unlikely(err)) -+ goto out_xinondir; -+ -+ if (!ino) { -+ ino = au_xino_new_ino(sb); -+ if (unlikely(!ino)) { -+ inode = ERR_PTR(-EIO); -+ goto out_xinondir; -+ } -+ } -+ -+ AuDbg("i%lu\n", (unsigned long)ino); -+ inode = au_iget_locked(sb, ino); -+ err = PTR_ERR(inode); -+ if (IS_ERR(inode)) -+ goto out_xinondir; -+ -+ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW)); -+ if (inode->i_state & I_NEW) { -+ ii_write_lock_new_child(inode); -+ err = set_inode(inode, dentry); -+ if (!err) { -+ unlock_new_inode(inode); -+ goto out_xinondir; /* success */ -+ } -+ -+ /* -+ * iget_failed() calls iput(), but we need to call -+ * ii_write_unlock() after iget_failed(). so dirty hack for -+ * i_count. -+ */ -+ atomic_inc(&inode->i_count); -+ iget_failed(inode); -+ ii_write_unlock(inode); -+ au_xino_write(sb, btop, h_ino, /*ino*/0); -+ /* ignore this error */ -+ goto out_iput; -+ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) { -+ /* -+ * horrible race condition between lookup, readdir and copyup -+ * (or something). -+ */ -+ if (hlinked && idx >= 0) -+ au_xinondir_leave(sb, btop, h_ino, idx); -+ err = reval_inode(inode, dentry); -+ if (unlikely(err < 0)) { -+ hlinked = 0; -+ goto out_iput; -+ } -+ if (!err) -+ goto out; /* success */ -+ else if (hlinked && idx >= 0) { -+ err = au_xinondir_enter(sb, btop, h_ino, &idx); -+ if (unlikely(err)) { -+ iput(inode); -+ inode = ERR_PTR(err); -+ goto out; -+ } -+ } -+ } -+ -+ if (unlikely(au_test_fs_unique_ino(h_inode))) -+ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir," -+ " b%d, %s, %pd, hi%lu, i%lu.\n", -+ btop, au_sbtype(h_dentry->d_sb), dentry, -+ (unsigned long)h_ino, (unsigned long)ino); -+ ino = 0; -+ err = au_xino_write(sb, btop, h_ino, /*ino*/0); -+ if (!err) { -+ iput(inode); -+ if (hlinked && idx >= 0) -+ au_xinondir_leave(sb, btop, h_ino, idx); -+ goto new_ino; -+ } -+ -+out_iput: -+ iput(inode); -+ inode = ERR_PTR(err); -+out_xinondir: -+ if (hlinked && idx >= 0) -+ au_xinondir_leave(sb, btop, h_ino, idx); -+out: -+ return inode; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, -+ struct inode *inode) -+{ -+ int err; -+ struct inode *hi; -+ -+ err = au_br_rdonly(au_sbr(sb, bindex)); -+ -+ /* pseudo-link after flushed may happen out of bounds */ -+ if (!err -+ && inode -+ && au_ibtop(inode) <= bindex -+ && bindex <= au_ibbot(inode)) { -+ /* -+ * permission check is unnecessary since vfsub routine -+ * will be called later -+ */ -+ hi = au_h_iptr(inode, bindex); -+ if (hi) -+ err = IS_IMMUTABLE(hi) ? -EROFS : 0; -+ } -+ -+ return err; -+} -+ -+int au_test_h_perm(struct inode *h_inode, int mask) -+{ -+ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) -+ return 0; -+ return inode_permission(h_inode, mask); -+} -+ -+int au_test_h_perm_sio(struct inode *h_inode, int mask) -+{ -+ if (au_test_nfs(h_inode->i_sb) -+ && (mask & MAY_WRITE) -+ && S_ISDIR(h_inode->i_mode)) -+ mask |= MAY_READ; /* force permission check */ -+ return au_test_h_perm(h_inode, mask); -+} -diff --git a/fs/aufs/inode.h b/fs/aufs/inode.h -new file mode 100644 -index 000000000..28e61b270 ---- /dev/null -+++ b/fs/aufs/inode.h -@@ -0,0 +1,696 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * inode operations -+ */ -+ -+#ifndef __AUFS_INODE_H__ -+#define __AUFS_INODE_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include "rwsem.h" -+ -+struct vfsmount; -+ -+struct au_hnotify { -+#ifdef CONFIG_AUFS_HNOTIFY -+#ifdef CONFIG_AUFS_HFSNOTIFY -+ /* never use fsnotify_add_vfsmount_mark() */ -+ struct fsnotify_mark hn_mark; -+#endif -+ struct inode *hn_aufs_inode; /* no get/put */ -+#endif -+} ____cacheline_aligned_in_smp; -+ -+struct au_hinode { -+ struct inode *hi_inode; -+ aufs_bindex_t hi_id; -+#ifdef CONFIG_AUFS_HNOTIFY -+ struct au_hnotify *hi_notify; -+#endif -+ -+ /* reference to the copied-up whiteout with get/put */ -+ struct dentry *hi_whdentry; -+}; -+ -+/* ig_flags */ -+#define AuIG_HALF_REFRESHED 1 -+#define au_ig_ftest(flags, name) ((flags) & AuIG_##name) -+#define au_ig_fset(flags, name) \ -+ do { (flags) |= AuIG_##name; } while (0) -+#define au_ig_fclr(flags, name) \ -+ do { (flags) &= ~AuIG_##name; } while (0) -+ -+struct au_iigen { -+ spinlock_t ig_spin; -+ __u32 ig_generation, ig_flags; -+}; -+ -+struct au_vdir; -+struct au_iinfo { -+ struct au_iigen ii_generation; -+ struct super_block *ii_hsb1; /* no get/put */ -+ -+ struct au_rwsem ii_rwsem; -+ aufs_bindex_t ii_btop, ii_bbot; -+ __u32 ii_higen; -+ struct au_hinode *ii_hinode; -+ struct au_vdir *ii_vdir; -+}; -+ -+struct au_icntnr { -+ struct au_iinfo iinfo; -+ struct inode vfs_inode; -+ struct hlist_bl_node plink; -+} ____cacheline_aligned_in_smp; -+ -+/* au_pin flags */ -+#define AuPin_DI_LOCKED 1 -+#define AuPin_MNT_WRITE (1 << 1) -+#define au_ftest_pin(flags, name) ((flags) & AuPin_##name) -+#define au_fset_pin(flags, name) \ -+ do { (flags) |= AuPin_##name; } while (0) -+#define au_fclr_pin(flags, name) \ -+ do { (flags) &= ~AuPin_##name; } while (0) -+ -+struct au_pin { -+ /* input */ -+ struct dentry *dentry; -+ unsigned int udba; -+ unsigned char lsc_di, lsc_hi, flags; -+ aufs_bindex_t bindex; -+ -+ /* output */ -+ struct dentry *parent; -+ struct au_hinode *hdir; -+ struct vfsmount *h_mnt; -+ -+ /* temporary unlock/relock for copyup */ -+ struct dentry *h_dentry, *h_parent; -+ struct au_branch *br; -+ struct task_struct *task; -+}; -+ -+void au_pin_hdir_unlock(struct au_pin *p); -+int au_pin_hdir_lock(struct au_pin *p); -+int au_pin_hdir_relock(struct au_pin *p); -+void au_pin_hdir_acquire_nest(struct au_pin *p); -+void au_pin_hdir_release(struct au_pin *p); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct au_iinfo *au_ii(struct inode *inode) -+{ -+ BUG_ON(is_bad_inode(inode)); -+ return &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* inode.c */ -+struct inode *au_igrab(struct inode *inode); -+void au_refresh_iop(struct inode *inode, int force_getattr); -+int au_refresh_hinode_self(struct inode *inode); -+int au_refresh_hinode(struct inode *inode, struct dentry *dentry); -+int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ unsigned int d_type, ino_t *ino); -+struct inode *au_new_inode(struct dentry *dentry, int must_new); -+int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, -+ struct inode *inode); -+int au_test_h_perm(struct inode *h_inode, int mask); -+int au_test_h_perm_sio(struct inode *h_inode, int mask); -+ -+static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, -+ ino_t h_ino, unsigned int d_type, ino_t *ino) -+{ -+#ifdef CONFIG_AUFS_SHWH -+ return au_ino(sb, bindex, h_ino, d_type, ino); -+#else -+ return 0; -+#endif -+} -+ -+/* i_op.c */ -+enum { -+ AuIop_SYMLINK, -+ AuIop_DIR, -+ AuIop_OTHER, -+ AuIop_Last -+}; -+extern struct inode_operations aufs_iop[AuIop_Last], -+ aufs_iop_nogetattr[AuIop_Last]; -+ -+/* au_wr_dir flags */ -+#define AuWrDir_ADD_ENTRY 1 -+#define AuWrDir_ISDIR (1 << 1) -+#define AuWrDir_TMPFILE (1 << 2) -+#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name) -+#define au_fset_wrdir(flags, name) \ -+ do { (flags) |= AuWrDir_##name; } while (0) -+#define au_fclr_wrdir(flags, name) \ -+ do { (flags) &= ~AuWrDir_##name; } while (0) -+ -+struct au_wr_dir_args { -+ aufs_bindex_t force_btgt; -+ unsigned char flags; -+}; -+int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, -+ struct au_wr_dir_args *args); -+ -+struct dentry *au_pinned_h_parent(struct au_pin *pin); -+void au_pin_init(struct au_pin *pin, struct dentry *dentry, -+ aufs_bindex_t bindex, int lsc_di, int lsc_hi, -+ unsigned int udba, unsigned char flags); -+int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex, -+ unsigned int udba, unsigned char flags) __must_check; -+int au_do_pin(struct au_pin *pin) __must_check; -+void au_unpin(struct au_pin *pin); -+int au_reval_for_attr(struct dentry *dentry, unsigned int sigen); -+ -+#define AuIcpup_DID_CPUP 1 -+#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name) -+#define au_fset_icpup(flags, name) \ -+ do { (flags) |= AuIcpup_##name; } while (0) -+#define au_fclr_icpup(flags, name) \ -+ do { (flags) &= ~AuIcpup_##name; } while (0) -+ -+struct au_icpup_args { -+ unsigned char flags; -+ unsigned char pin_flags; -+ aufs_bindex_t btgt; -+ unsigned int udba; -+ struct au_pin pin; -+ struct path h_path; -+ struct inode *h_inode; -+}; -+ -+int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia, -+ struct au_icpup_args *a); -+ -+int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path, -+ int locked); -+ -+/* i_op_add.c */ -+int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent, int isdir); -+int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, -+ dev_t dev); -+int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname); -+int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode, -+ bool want_excl); -+struct vfsub_aopen_args; -+int au_aopen_or_create(struct inode *dir, struct dentry *dentry, -+ struct vfsub_aopen_args *args); -+int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode); -+int aufs_link(struct dentry *src_dentry, struct inode *dir, -+ struct dentry *dentry); -+int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode); -+ -+/* i_op_del.c */ -+int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup); -+int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent, int isdir); -+int aufs_unlink(struct inode *dir, struct dentry *dentry); -+int aufs_rmdir(struct inode *dir, struct dentry *dentry); -+ -+/* i_op_ren.c */ -+int au_wbr(struct dentry *dentry, aufs_bindex_t btgt); -+int aufs_rename(struct inode *src_dir, struct dentry *src_dentry, -+ struct inode *dir, struct dentry *dentry, -+ unsigned int flags); -+ -+/* iinfo.c */ -+struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex); -+void au_hiput(struct au_hinode *hinode); -+void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_wh); -+unsigned int au_hi_flags(struct inode *inode, int isdir); -+ -+/* hinode flags */ -+#define AuHi_XINO 1 -+#define AuHi_HNOTIFY (1 << 1) -+#define au_ftest_hi(flags, name) ((flags) & AuHi_##name) -+#define au_fset_hi(flags, name) \ -+ do { (flags) |= AuHi_##name; } while (0) -+#define au_fclr_hi(flags, name) \ -+ do { (flags) &= ~AuHi_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_HNOTIFY -+#undef AuHi_HNOTIFY -+#define AuHi_HNOTIFY 0 -+#endif -+ -+void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, -+ struct inode *h_inode, unsigned int flags); -+ -+void au_update_iigen(struct inode *inode, int half); -+void au_update_ibrange(struct inode *inode, int do_put_zero); -+ -+void au_icntnr_init_once(void *_c); -+void au_hinode_init(struct au_hinode *hinode); -+int au_iinfo_init(struct inode *inode); -+void au_iinfo_fin(struct inode *inode); -+int au_hinode_realloc(struct au_iinfo *iinfo, int nbr, int may_shrink); -+ -+#ifdef CONFIG_PROC_FS -+/* plink.c */ -+int au_plink_maint(struct super_block *sb, int flags); -+struct au_sbinfo; -+void au_plink_maint_leave(struct au_sbinfo *sbinfo); -+int au_plink_maint_enter(struct super_block *sb); -+#ifdef CONFIG_AUFS_DEBUG -+void au_plink_list(struct super_block *sb); -+#else -+AuStubVoid(au_plink_list, struct super_block *sb) -+#endif -+int au_plink_test(struct inode *inode); -+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex); -+void au_plink_append(struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_dentry); -+void au_plink_put(struct super_block *sb, int verbose); -+void au_plink_clean(struct super_block *sb, int verbose); -+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id); -+#else -+AuStubInt0(au_plink_maint, struct super_block *sb, int flags); -+AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo); -+AuStubInt0(au_plink_maint_enter, struct super_block *sb); -+AuStubVoid(au_plink_list, struct super_block *sb); -+AuStubInt0(au_plink_test, struct inode *inode); -+AuStub(struct dentry *, au_plink_lkup, return NULL, -+ struct inode *inode, aufs_bindex_t bindex); -+AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_dentry); -+AuStubVoid(au_plink_put, struct super_block *sb, int verbose); -+AuStubVoid(au_plink_clean, struct super_block *sb, int verbose); -+AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id); -+#endif /* CONFIG_PROC_FS */ -+ -+#ifdef CONFIG_AUFS_XATTR -+/* xattr.c */ -+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags, -+ unsigned int verbose); -+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size); -+void au_xattr_init(struct super_block *sb); -+#else -+AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *h_src, -+ int ignore_flags, unsigned int verbose); -+AuStubVoid(au_xattr_init, struct super_block *sb); -+#endif -+ -+#ifdef CONFIG_FS_POSIX_ACL -+struct posix_acl *aufs_get_acl(struct inode *inode, int type); -+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type); -+#endif -+ -+#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL) -+enum { -+ AU_XATTR_SET, -+ AU_ACL_SET -+}; -+ -+struct au_sxattr { -+ int type; -+ union { -+ struct { -+ const char *name; -+ const void *value; -+ size_t size; -+ int flags; -+ } set; -+ struct { -+ struct posix_acl *acl; -+ int type; -+ } acl_set; -+ } u; -+}; -+ssize_t au_sxattr(struct dentry *dentry, struct inode *inode, -+ struct au_sxattr *arg); -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* lock subclass for iinfo */ -+enum { -+ AuLsc_II_CHILD, /* child first */ -+ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */ -+ AuLsc_II_CHILD3, /* copyup dirs */ -+ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */ -+ AuLsc_II_PARENT2, -+ AuLsc_II_PARENT3, /* copyup dirs */ -+ AuLsc_II_NEW_CHILD -+}; -+ -+/* -+ * ii_read_lock_child, ii_write_lock_child, -+ * ii_read_lock_child2, ii_write_lock_child2, -+ * ii_read_lock_child3, ii_write_lock_child3, -+ * ii_read_lock_parent, ii_write_lock_parent, -+ * ii_read_lock_parent2, ii_write_lock_parent2, -+ * ii_read_lock_parent3, ii_write_lock_parent3, -+ * ii_read_lock_new_child, ii_write_lock_new_child, -+ */ -+#define AuReadLockFunc(name, lsc) \ -+static inline void ii_read_lock_##name(struct inode *i) \ -+{ \ -+ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ -+} -+ -+#define AuWriteLockFunc(name, lsc) \ -+static inline void ii_write_lock_##name(struct inode *i) \ -+{ \ -+ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ -+} -+ -+#define AuRWLockFuncs(name, lsc) \ -+ AuReadLockFunc(name, lsc) \ -+ AuWriteLockFunc(name, lsc) -+ -+AuRWLockFuncs(child, CHILD); -+AuRWLockFuncs(child2, CHILD2); -+AuRWLockFuncs(child3, CHILD3); -+AuRWLockFuncs(parent, PARENT); -+AuRWLockFuncs(parent2, PARENT2); -+AuRWLockFuncs(parent3, PARENT3); -+AuRWLockFuncs(new_child, NEW_CHILD); -+ -+#undef AuReadLockFunc -+#undef AuWriteLockFunc -+#undef AuRWLockFuncs -+ -+#define ii_read_unlock(i) au_rw_read_unlock(&au_ii(i)->ii_rwsem) -+#define ii_write_unlock(i) au_rw_write_unlock(&au_ii(i)->ii_rwsem) -+#define ii_downgrade_lock(i) au_rw_dgrade_lock(&au_ii(i)->ii_rwsem) -+ -+#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem) -+#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem) -+#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem) -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline void au_icntnr_init(struct au_icntnr *c) -+{ -+#ifdef CONFIG_AUFS_DEBUG -+ c->vfs_inode.i_mode = 0; -+#endif -+} -+ -+static inline unsigned int au_iigen(struct inode *inode, unsigned int *igflags) -+{ -+ unsigned int gen; -+ struct au_iinfo *iinfo; -+ struct au_iigen *iigen; -+ -+ iinfo = au_ii(inode); -+ iigen = &iinfo->ii_generation; -+ spin_lock(&iigen->ig_spin); -+ if (igflags) -+ *igflags = iigen->ig_flags; -+ gen = iigen->ig_generation; -+ spin_unlock(&iigen->ig_spin); -+ -+ return gen; -+} -+ -+/* tiny test for inode number */ -+/* tmpfs generation is too rough */ -+static inline int au_test_higen(struct inode *inode, struct inode *h_inode) -+{ -+ struct au_iinfo *iinfo; -+ -+ iinfo = au_ii(inode); -+ AuRwMustAnyLock(&iinfo->ii_rwsem); -+ return !(iinfo->ii_hsb1 == h_inode->i_sb -+ && iinfo->ii_higen == h_inode->i_generation); -+} -+ -+static inline void au_iigen_dec(struct inode *inode) -+{ -+ struct au_iinfo *iinfo; -+ struct au_iigen *iigen; -+ -+ iinfo = au_ii(inode); -+ iigen = &iinfo->ii_generation; -+ spin_lock(&iigen->ig_spin); -+ iigen->ig_generation--; -+ spin_unlock(&iigen->ig_spin); -+} -+ -+static inline int au_iigen_test(struct inode *inode, unsigned int sigen) -+{ -+ int err; -+ -+ err = 0; -+ if (unlikely(inode && au_iigen(inode, NULL) != sigen)) -+ err = -EIO; -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct au_hinode *au_hinode(struct au_iinfo *iinfo, -+ aufs_bindex_t bindex) -+{ -+ return iinfo->ii_hinode + bindex; -+} -+ -+static inline int au_is_bad_inode(struct inode *inode) -+{ -+ return !!(is_bad_inode(inode) || !au_hinode(au_ii(inode), 0)); -+} -+ -+static inline aufs_bindex_t au_ii_br_id(struct inode *inode, -+ aufs_bindex_t bindex) -+{ -+ IiMustAnyLock(inode); -+ return au_hinode(au_ii(inode), bindex)->hi_id; -+} -+ -+static inline aufs_bindex_t au_ibtop(struct inode *inode) -+{ -+ IiMustAnyLock(inode); -+ return au_ii(inode)->ii_btop; -+} -+ -+static inline aufs_bindex_t au_ibbot(struct inode *inode) -+{ -+ IiMustAnyLock(inode); -+ return au_ii(inode)->ii_bbot; -+} -+ -+static inline struct au_vdir *au_ivdir(struct inode *inode) -+{ -+ IiMustAnyLock(inode); -+ return au_ii(inode)->ii_vdir; -+} -+ -+static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex) -+{ -+ IiMustAnyLock(inode); -+ return au_hinode(au_ii(inode), bindex)->hi_whdentry; -+} -+ -+static inline void au_set_ibtop(struct inode *inode, aufs_bindex_t bindex) -+{ -+ IiMustWriteLock(inode); -+ au_ii(inode)->ii_btop = bindex; -+} -+ -+static inline void au_set_ibbot(struct inode *inode, aufs_bindex_t bindex) -+{ -+ IiMustWriteLock(inode); -+ au_ii(inode)->ii_bbot = bindex; -+} -+ -+static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir) -+{ -+ IiMustWriteLock(inode); -+ au_ii(inode)->ii_vdir = vdir; -+} -+ -+static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex) -+{ -+ IiMustAnyLock(inode); -+ return au_hinode(au_ii(inode), bindex); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct dentry *au_pinned_parent(struct au_pin *pin) -+{ -+ if (pin) -+ return pin->parent; -+ return NULL; -+} -+ -+static inline struct inode *au_pinned_h_dir(struct au_pin *pin) -+{ -+ if (pin && pin->hdir) -+ return pin->hdir->hi_inode; -+ return NULL; -+} -+ -+static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin) -+{ -+ if (pin) -+ return pin->hdir; -+ return NULL; -+} -+ -+static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry) -+{ -+ if (pin) -+ pin->dentry = dentry; -+} -+ -+static inline void au_pin_set_parent_lflag(struct au_pin *pin, -+ unsigned char lflag) -+{ -+ if (pin) { -+ if (lflag) -+ au_fset_pin(pin->flags, DI_LOCKED); -+ else -+ au_fclr_pin(pin->flags, DI_LOCKED); -+ } -+} -+ -+#if 0 /* reserved */ -+static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent) -+{ -+ if (pin) { -+ dput(pin->parent); -+ pin->parent = dget(parent); -+ } -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_branch; -+#ifdef CONFIG_AUFS_HNOTIFY -+struct au_hnotify_op { -+ void (*ctl)(struct au_hinode *hinode, int do_set); -+ int (*alloc)(struct au_hinode *hinode); -+ -+ /* -+ * if it returns true, the the caller should free hinode->hi_notify, -+ * otherwise ->free() frees it. -+ */ -+ int (*free)(struct au_hinode *hinode, -+ struct au_hnotify *hn) __must_check; -+ -+ void (*fin)(void); -+ int (*init)(void); -+ -+ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm); -+ void (*fin_br)(struct au_branch *br); -+ int (*init_br)(struct au_branch *br, int perm); -+}; -+ -+/* hnotify.c */ -+int au_hn_alloc(struct au_hinode *hinode, struct inode *inode); -+void au_hn_free(struct au_hinode *hinode); -+void au_hn_ctl(struct au_hinode *hinode, int do_set); -+void au_hn_reset(struct inode *inode, unsigned int flags); -+int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask, -+ struct qstr *h_child_qstr, struct inode *h_child_inode); -+int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm); -+int au_hnotify_init_br(struct au_branch *br, int perm); -+void au_hnotify_fin_br(struct au_branch *br); -+int __init au_hnotify_init(void); -+void au_hnotify_fin(void); -+ -+/* hfsnotify.c */ -+extern const struct au_hnotify_op au_hnotify_op; -+ -+static inline -+void au_hn_init(struct au_hinode *hinode) -+{ -+ hinode->hi_notify = NULL; -+} -+ -+static inline struct au_hnotify *au_hn(struct au_hinode *hinode) -+{ -+ return hinode->hi_notify; -+} -+ -+#else -+AuStub(int, au_hn_alloc, return -EOPNOTSUPP, -+ struct au_hinode *hinode __maybe_unused, -+ struct inode *inode __maybe_unused) -+AuStub(struct au_hnotify *, au_hn, return NULL, struct au_hinode *hinode) -+AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused) -+AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused, -+ int do_set __maybe_unused) -+AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused, -+ unsigned int flags __maybe_unused) -+AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused, -+ struct au_branch *br __maybe_unused, -+ int perm __maybe_unused) -+AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused, -+ int perm __maybe_unused) -+AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused) -+AuStubInt0(__init au_hnotify_init, void) -+AuStubVoid(au_hnotify_fin, void) -+AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused) -+#endif /* CONFIG_AUFS_HNOTIFY */ -+ -+static inline void au_hn_suspend(struct au_hinode *hdir) -+{ -+ au_hn_ctl(hdir, /*do_set*/0); -+} -+ -+static inline void au_hn_resume(struct au_hinode *hdir) -+{ -+ au_hn_ctl(hdir, /*do_set*/1); -+} -+ -+static inline void au_hn_inode_lock(struct au_hinode *hdir) -+{ -+ inode_lock(hdir->hi_inode); -+ au_hn_suspend(hdir); -+} -+ -+static inline void au_hn_inode_lock_nested(struct au_hinode *hdir, -+ unsigned int sc __maybe_unused) -+{ -+ inode_lock_nested(hdir->hi_inode, sc); -+ au_hn_suspend(hdir); -+} -+ -+#if 0 /* unused */ -+#include "vfsub.h" -+static inline void au_hn_inode_lock_shared_nested(struct au_hinode *hdir, -+ unsigned int sc) -+{ -+ inode_lock_shared_nested(hdir->hi_inode, sc); -+ au_hn_suspend(hdir); -+} -+#endif -+ -+static inline void au_hn_inode_unlock(struct au_hinode *hdir) -+{ -+ au_hn_resume(hdir); -+ inode_unlock(hdir->hi_inode); -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_INODE_H__ */ -diff --git a/fs/aufs/ioctl.c b/fs/aufs/ioctl.c -new file mode 100644 -index 000000000..279bd7498 ---- /dev/null -+++ b/fs/aufs/ioctl.c -@@ -0,0 +1,220 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * ioctl -+ * plink-management and readdir in userspace. -+ * assist the pathconf(3) wrapper library. -+ * move-down -+ * File-based Hierarchical Storage Management. -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg) -+{ -+ int err, fd; -+ aufs_bindex_t wbi, bindex, bbot; -+ struct file *h_file; -+ struct super_block *sb; -+ struct dentry *root; -+ struct au_branch *br; -+ struct aufs_wbr_fd wbrfd = { -+ .oflags = au_dir_roflags, -+ .brid = -1 -+ }; -+ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY -+ | O_NOATIME | O_CLOEXEC; -+ -+ AuDebugOn(wbrfd.oflags & ~valid); -+ -+ if (arg) { -+ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ goto out; -+ } -+ -+ err = -EINVAL; -+ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid); -+ wbrfd.oflags |= au_dir_roflags; -+ AuDbg("0%o\n", wbrfd.oflags); -+ if (unlikely(wbrfd.oflags & ~valid)) -+ goto out; -+ } -+ -+ fd = get_unused_fd_flags(0); -+ err = fd; -+ if (unlikely(fd < 0)) -+ goto out; -+ -+ h_file = ERR_PTR(-EINVAL); -+ wbi = 0; -+ br = NULL; -+ sb = path->dentry->d_sb; -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_IR); -+ bbot = au_sbbot(sb); -+ if (wbrfd.brid >= 0) { -+ wbi = au_br_index(sb, wbrfd.brid); -+ if (unlikely(wbi < 0 || wbi > bbot)) -+ goto out_unlock; -+ } -+ -+ h_file = ERR_PTR(-ENOENT); -+ br = au_sbr(sb, wbi); -+ if (!au_br_writable(br->br_perm)) { -+ if (arg) -+ goto out_unlock; -+ -+ bindex = wbi + 1; -+ wbi = -1; -+ for (; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_writable(br->br_perm)) { -+ wbi = bindex; -+ br = au_sbr(sb, wbi); -+ break; -+ } -+ } -+ } -+ AuDbg("wbi %d\n", wbi); -+ if (wbi >= 0) -+ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL, -+ /*force_wr*/0); -+ -+out_unlock: -+ aufs_read_unlock(root, AuLock_IR); -+ err = PTR_ERR(h_file); -+ if (IS_ERR(h_file)) -+ goto out_fd; -+ -+ au_lcnt_dec(&br->br_nfiles); /* cf. au_h_open() */ -+ fd_install(fd, h_file); -+ err = fd; -+ goto out; /* success */ -+ -+out_fd: -+ put_unused_fd(fd); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ long err; -+ struct dentry *dentry; -+ -+ switch (cmd) { -+ case AUFS_CTL_RDU: -+ case AUFS_CTL_RDU_INO: -+ err = au_rdu_ioctl(file, cmd, arg); -+ break; -+ -+ case AUFS_CTL_WBR_FD: -+ err = au_wbr_fd(&file->f_path, (void __user *)arg); -+ break; -+ -+ case AUFS_CTL_IBUSY: -+ err = au_ibusy_ioctl(file, arg); -+ break; -+ -+ case AUFS_CTL_BRINFO: -+ err = au_brinfo_ioctl(file, arg); -+ break; -+ -+ case AUFS_CTL_FHSM_FD: -+ dentry = file->f_path.dentry; -+ if (IS_ROOT(dentry)) -+ err = au_fhsm_fd(dentry->d_sb, arg); -+ else -+ err = -ENOTTY; -+ break; -+ -+ default: -+ /* do not call the lower */ -+ AuDbg("0x%x\n", cmd); -+ err = -ENOTTY; -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ long err; -+ -+ switch (cmd) { -+ case AUFS_CTL_MVDOWN: -+ err = au_mvdown(file->f_path.dentry, (void __user *)arg); -+ break; -+ -+ case AUFS_CTL_WBR_FD: -+ err = au_wbr_fd(&file->f_path, (void __user *)arg); -+ break; -+ -+ default: -+ /* do not call the lower */ -+ AuDbg("0x%x\n", cmd); -+ err = -ENOTTY; -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+#ifdef CONFIG_COMPAT -+long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ long err; -+ -+ switch (cmd) { -+ case AUFS_CTL_RDU: -+ case AUFS_CTL_RDU_INO: -+ err = au_rdu_compat_ioctl(file, cmd, arg); -+ break; -+ -+ case AUFS_CTL_IBUSY: -+ err = au_ibusy_compat_ioctl(file, arg); -+ break; -+ -+ case AUFS_CTL_BRINFO: -+ err = au_brinfo_compat_ioctl(file, arg); -+ break; -+ -+ default: -+ err = aufs_ioctl_dir(file, cmd, arg); -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg)); -+} -+#endif -diff --git a/fs/aufs/lcnt.h b/fs/aufs/lcnt.h -new file mode 100644 -index 000000000..5e089c93f ---- /dev/null -+++ b/fs/aufs/lcnt.h -@@ -0,0 +1,186 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * simple long counter wrapper -+ */ -+ -+#ifndef __AUFS_LCNT_H__ -+#define __AUFS_LCNT_H__ -+ -+#ifdef __KERNEL__ -+ -+#include "debug.h" -+ -+#define AuLCntATOMIC 1 -+#define AuLCntPCPUCNT 2 -+/* -+ * why does percpu_refcount require extra synchronize_rcu()s in -+ * au_br_do_free() -+ */ -+#define AuLCntPCPUREF 3 -+ -+/* #define AuLCntChosen AuLCntATOMIC */ -+#define AuLCntChosen AuLCntPCPUCNT -+/* #define AuLCntChosen AuLCntPCPUREF */ -+ -+#if AuLCntChosen == AuLCntATOMIC -+#include -+ -+typedef atomic_long_t au_lcnt_t; -+ -+static inline int au_lcnt_init(au_lcnt_t *cnt, void *release __maybe_unused) -+{ -+ atomic_long_set(cnt, 0); -+ return 0; -+} -+ -+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused) -+{ -+ /* empty */ -+} -+ -+static inline void au_lcnt_fin(au_lcnt_t *cnt __maybe_unused, -+ int do_sync __maybe_unused) -+{ -+ /* empty */ -+} -+ -+static inline void au_lcnt_inc(au_lcnt_t *cnt) -+{ -+ atomic_long_inc(cnt); -+} -+ -+static inline void au_lcnt_dec(au_lcnt_t *cnt) -+{ -+ atomic_long_dec(cnt); -+} -+ -+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev __maybe_unused) -+{ -+ return atomic_long_read(cnt); -+} -+#endif -+ -+#if AuLCntChosen == AuLCntPCPUCNT -+#include -+ -+typedef struct percpu_counter au_lcnt_t; -+ -+static inline int au_lcnt_init(au_lcnt_t *cnt, void *release __maybe_unused) -+{ -+ return percpu_counter_init(cnt, 0, GFP_NOFS); -+} -+ -+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused) -+{ -+ /* empty */ -+} -+ -+static inline void au_lcnt_fin(au_lcnt_t *cnt, int do_sync __maybe_unused) -+{ -+ percpu_counter_destroy(cnt); -+} -+ -+static inline void au_lcnt_inc(au_lcnt_t *cnt) -+{ -+ percpu_counter_inc(cnt); -+} -+ -+static inline void au_lcnt_dec(au_lcnt_t *cnt) -+{ -+ percpu_counter_dec(cnt); -+} -+ -+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev __maybe_unused) -+{ -+ s64 n; -+ -+ n = percpu_counter_sum(cnt); -+ BUG_ON(n < 0); -+ if (LONG_MAX != LLONG_MAX -+ && n > LONG_MAX) -+ AuWarn1("%s\n", "wrap-around"); -+ -+ return n; -+} -+#endif -+ -+#if AuLCntChosen == AuLCntPCPUREF -+#include -+ -+typedef struct percpu_ref au_lcnt_t; -+ -+static inline int au_lcnt_init(au_lcnt_t *cnt, percpu_ref_func_t *release) -+{ -+ if (!release) -+ release = percpu_ref_exit; -+ return percpu_ref_init(cnt, release, /*percpu mode*/0, GFP_NOFS); -+} -+ -+static inline void au_lcnt_wait_for_fin(au_lcnt_t *cnt __maybe_unused) -+{ -+ synchronize_rcu(); -+} -+ -+static inline void au_lcnt_fin(au_lcnt_t *cnt, int do_sync) -+{ -+ percpu_ref_kill(cnt); -+ if (do_sync) -+ au_lcnt_wait_for_fin(cnt); -+} -+ -+static inline void au_lcnt_inc(au_lcnt_t *cnt) -+{ -+ percpu_ref_get(cnt); -+} -+ -+static inline void au_lcnt_dec(au_lcnt_t *cnt) -+{ -+ percpu_ref_put(cnt); -+} -+ -+/* -+ * avoid calling this func as possible. -+ */ -+static inline long au_lcnt_read(au_lcnt_t *cnt, int do_rev) -+{ -+ long l; -+ -+ percpu_ref_switch_to_atomic_sync(cnt); -+ l = atomic_long_read(&cnt->count); -+ if (do_rev) -+ percpu_ref_switch_to_percpu(cnt); -+ -+ /* percpu_ref is initialized by 1 instead of 0 */ -+ return l - 1; -+} -+#endif -+ -+#ifdef CONFIG_AUFS_DEBUG -+#define AuLCntZero(val) do { \ -+ long l = val; \ -+ if (l) \ -+ AuDbg("%s = %ld\n", #val, l); \ -+} while (0) -+#else -+#define AuLCntZero(val) do {} while (0) -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_LCNT_H__ */ -diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c -new file mode 100644 -index 000000000..0c6af623a ---- /dev/null -+++ b/fs/aufs/loop.c -@@ -0,0 +1,148 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * support for loopback block device as a branch -+ */ -+ -+#include "aufs.h" -+ -+/* added into drivers/block/loop.c */ -+static struct file *(*backing_file_func)(struct super_block *sb); -+ -+/* -+ * test if two lower dentries have overlapping branches. -+ */ -+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding) -+{ -+ struct super_block *h_sb; -+ struct file *backing_file; -+ -+ if (unlikely(!backing_file_func)) { -+ /* don't load "loop" module here */ -+ backing_file_func = symbol_get(loop_backing_file); -+ if (unlikely(!backing_file_func)) -+ /* "loop" module is not loaded */ -+ return 0; -+ } -+ -+ h_sb = h_adding->d_sb; -+ backing_file = backing_file_func(h_sb); -+ if (!backing_file) -+ return 0; -+ -+ h_adding = backing_file->f_path.dentry; -+ /* -+ * h_adding can be local NFS. -+ * in this case aufs cannot detect the loop. -+ */ -+ if (unlikely(h_adding->d_sb == sb)) -+ return 1; -+ return !!au_test_subdir(h_adding, sb->s_root); -+} -+ -+/* true if a kernel thread named 'loop[0-9].*' accesses a file */ -+int au_test_loopback_kthread(void) -+{ -+ int ret; -+ struct task_struct *tsk = current; -+ char c, comm[sizeof(tsk->comm)]; -+ -+ ret = 0; -+ if (tsk->flags & PF_KTHREAD) { -+ get_task_comm(comm, tsk); -+ c = comm[4]; -+ ret = ('0' <= c && c <= '9' -+ && !strncmp(comm, "loop", 4)); -+ } -+ -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define au_warn_loopback_step 16 -+static int au_warn_loopback_nelem = au_warn_loopback_step; -+static unsigned long *au_warn_loopback_array; -+ -+void au_warn_loopback(struct super_block *h_sb) -+{ -+ int i, new_nelem; -+ unsigned long *a, magic; -+ static DEFINE_SPINLOCK(spin); -+ -+ magic = h_sb->s_magic; -+ spin_lock(&spin); -+ a = au_warn_loopback_array; -+ for (i = 0; i < au_warn_loopback_nelem && *a; i++) -+ if (a[i] == magic) { -+ spin_unlock(&spin); -+ return; -+ } -+ -+ /* h_sb is new to us, print it */ -+ if (i < au_warn_loopback_nelem) { -+ a[i] = magic; -+ goto pr; -+ } -+ -+ /* expand the array */ -+ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step; -+ a = au_kzrealloc(au_warn_loopback_array, -+ au_warn_loopback_nelem * sizeof(unsigned long), -+ new_nelem * sizeof(unsigned long), GFP_ATOMIC, -+ /*may_shrink*/0); -+ if (a) { -+ au_warn_loopback_nelem = new_nelem; -+ au_warn_loopback_array = a; -+ a[i] = magic; -+ goto pr; -+ } -+ -+ spin_unlock(&spin); -+ AuWarn1("realloc failed, ignored\n"); -+ return; -+ -+pr: -+ spin_unlock(&spin); -+ pr_warn("you may want to try another patch for loopback file " -+ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic); -+} -+ -+int au_loopback_init(void) -+{ -+ int err; -+ struct super_block *sb __maybe_unused; -+ -+ BUILD_BUG_ON(sizeof(sb->s_magic) != sizeof(unsigned long)); -+ -+ err = 0; -+ au_warn_loopback_array = kcalloc(au_warn_loopback_step, -+ sizeof(unsigned long), GFP_NOFS); -+ if (unlikely(!au_warn_loopback_array)) -+ err = -ENOMEM; -+ -+ return err; -+} -+ -+void au_loopback_fin(void) -+{ -+ if (backing_file_func) -+ symbol_put(loop_backing_file); -+ kfree(au_warn_loopback_array); -+} -diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h -new file mode 100644 -index 000000000..048a6504f ---- /dev/null -+++ b/fs/aufs/loop.h -@@ -0,0 +1,53 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * support for loopback mount as a branch -+ */ -+ -+#ifndef __AUFS_LOOP_H__ -+#define __AUFS_LOOP_H__ -+ -+#ifdef __KERNEL__ -+ -+struct dentry; -+struct super_block; -+ -+#ifdef CONFIG_AUFS_BDEV_LOOP -+/* drivers/block/loop.c */ -+struct file *loop_backing_file(struct super_block *sb); -+ -+/* loop.c */ -+int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding); -+int au_test_loopback_kthread(void); -+void au_warn_loopback(struct super_block *h_sb); -+ -+int au_loopback_init(void); -+void au_loopback_fin(void); -+#else -+AuStubInt0(au_test_loopback_overlap, struct super_block *sb, -+ struct dentry *h_adding) -+AuStubInt0(au_test_loopback_kthread, void) -+AuStubVoid(au_warn_loopback, struct super_block *h_sb) -+ -+AuStubInt0(au_loopback_init, void) -+AuStubVoid(au_loopback_fin, void) -+#endif /* BLK_DEV_LOOP */ -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_LOOP_H__ */ -diff --git a/fs/aufs/magic.mk b/fs/aufs/magic.mk -new file mode 100644 -index 000000000..7bc9eef3f ---- /dev/null -+++ b/fs/aufs/magic.mk -@@ -0,0 +1,31 @@ -+# SPDX-License-Identifier: GPL-2.0 -+ -+# defined in ${srctree}/fs/fuse/inode.c -+# tristate -+ifdef CONFIG_FUSE_FS -+ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546 -+endif -+ -+# defined in ${srctree}/fs/xfs/xfs_sb.h -+# tristate -+ifdef CONFIG_XFS_FS -+ccflags-y += -DXFS_SB_MAGIC=0x58465342 -+endif -+ -+# defined in ${srctree}/fs/configfs/mount.c -+# tristate -+ifdef CONFIG_CONFIGFS_FS -+ccflags-y += -DCONFIGFS_MAGIC=0x62656570 -+endif -+ -+# defined in ${srctree}/fs/ubifs/ubifs.h -+# tristate -+ifdef CONFIG_UBIFS_FS -+ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905 -+endif -+ -+# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h -+# tristate -+ifdef CONFIG_HFSPLUS_FS -+ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b -+endif -diff --git a/fs/aufs/module.c b/fs/aufs/module.c -new file mode 100644 -index 000000000..5f5f67e64 ---- /dev/null -+++ b/fs/aufs/module.c -@@ -0,0 +1,273 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * module global variables and operations -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+/* shrinkable realloc */ -+void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink) -+{ -+ size_t sz; -+ int diff; -+ -+ sz = 0; -+ diff = -1; -+ if (p) { -+#if 0 /* unused */ -+ if (!new_sz) { -+ kfree(p); -+ p = NULL; -+ goto out; -+ } -+#else -+ AuDebugOn(!new_sz); -+#endif -+ sz = ksize(p); -+ diff = au_kmidx_sub(sz, new_sz); -+ } -+ if (sz && !diff) -+ goto out; -+ -+ if (sz < new_sz) -+ /* expand or SLOB */ -+ p = krealloc(p, new_sz, gfp); -+ else if (new_sz < sz && may_shrink) { -+ /* shrink */ -+ void *q; -+ -+ q = kmalloc(new_sz, gfp); -+ if (q) { -+ if (p) { -+ memcpy(q, p, new_sz); -+ kfree(p); -+ } -+ p = q; -+ } else -+ p = NULL; -+ } -+ -+out: -+ return p; -+} -+ -+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp, -+ int may_shrink) -+{ -+ p = au_krealloc(p, new_sz, gfp, may_shrink); -+ if (p && new_sz > nused) -+ memset(p + nused, 0, new_sz - nused); -+ return p; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * aufs caches -+ */ -+struct kmem_cache *au_cache[AuCache_Last]; -+ -+static void au_cache_fin(void) -+{ -+ int i; -+ -+ /* -+ * Make sure all delayed rcu free inodes are flushed before we -+ * destroy cache. -+ */ -+ rcu_barrier(); -+ -+ /* excluding AuCache_HNOTIFY */ -+ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last); -+ for (i = 0; i < AuCache_HNOTIFY; i++) { -+ kmem_cache_destroy(au_cache[i]); -+ au_cache[i] = NULL; -+ } -+} -+ -+static int __init au_cache_init(void) -+{ -+ au_cache[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once); -+ if (au_cache[AuCache_DINFO]) -+ /* SLAB_DESTROY_BY_RCU */ -+ au_cache[AuCache_ICNTNR] = AuCacheCtor(au_icntnr, -+ au_icntnr_init_once); -+ if (au_cache[AuCache_ICNTNR]) -+ au_cache[AuCache_FINFO] = AuCacheCtor(au_finfo, -+ au_fi_init_once); -+ if (au_cache[AuCache_FINFO]) -+ au_cache[AuCache_VDIR] = AuCache(au_vdir); -+ if (au_cache[AuCache_VDIR]) -+ au_cache[AuCache_DEHSTR] = AuCache(au_vdir_dehstr); -+ if (au_cache[AuCache_DEHSTR]) -+ return 0; -+ -+ au_cache_fin(); -+ return -ENOMEM; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_dir_roflags; -+ -+#ifdef CONFIG_AUFS_SBILIST -+/* -+ * iterate_supers_type() doesn't protect us from -+ * remounting (branch management) -+ */ -+struct hlist_bl_head au_sbilist; -+#endif -+ -+/* -+ * functions for module interface. -+ */ -+MODULE_LICENSE("GPL"); -+/* MODULE_LICENSE("GPL v2"); */ -+MODULE_AUTHOR("Junjiro R. Okajima "); -+MODULE_DESCRIPTION(AUFS_NAME -+ " -- Advanced multi layered unification filesystem"); -+MODULE_VERSION(AUFS_VERSION); -+MODULE_ALIAS_FS(AUFS_NAME); -+ -+/* this module parameter has no meaning when SYSFS is disabled */ -+int sysaufs_brs = 1; -+MODULE_PARM_DESC(brs, "use /fs/aufs/si_*/brN"); -+module_param_named(brs, sysaufs_brs, int, 0444); -+ -+/* this module parameter has no meaning when USER_NS is disabled */ -+bool au_userns; -+MODULE_PARM_DESC(allow_userns, "allow unprivileged to mount under userns"); -+module_param_named(allow_userns, au_userns, bool, 0444); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */ -+ -+int au_seq_path(struct seq_file *seq, struct path *path) -+{ -+ int err; -+ -+ err = seq_path(seq, path, au_esc_chars); -+ if (err >= 0) -+ err = 0; -+ else -+ err = -ENOMEM; -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int __init aufs_init(void) -+{ -+ int err, i; -+ char *p; -+ -+ p = au_esc_chars; -+ for (i = 1; i <= ' '; i++) -+ *p++ = i; -+ *p++ = '\\'; -+ *p++ = '\x7f'; -+ *p = 0; -+ -+ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE); -+ -+ memcpy(aufs_iop_nogetattr, aufs_iop, sizeof(aufs_iop)); -+ for (i = 0; i < AuIop_Last; i++) -+ aufs_iop_nogetattr[i].getattr = NULL; -+ -+ memset(au_cache, 0, sizeof(au_cache)); /* including hnotify */ -+ -+ au_sbilist_init(); -+ sysaufs_brs_init(); -+ au_debug_init(); -+ au_dy_init(); -+ err = sysaufs_init(); -+ if (unlikely(err)) -+ goto out; -+ err = dbgaufs_init(); -+ if (unlikely(err)) -+ goto out_sysaufs; -+ err = au_procfs_init(); -+ if (unlikely(err)) -+ goto out_dbgaufs; -+ err = au_wkq_init(); -+ if (unlikely(err)) -+ goto out_procfs; -+ err = au_loopback_init(); -+ if (unlikely(err)) -+ goto out_wkq; -+ err = au_hnotify_init(); -+ if (unlikely(err)) -+ goto out_loopback; -+ err = au_sysrq_init(); -+ if (unlikely(err)) -+ goto out_hin; -+ err = au_cache_init(); -+ if (unlikely(err)) -+ goto out_sysrq; -+ -+ aufs_fs_type.fs_flags |= au_userns ? FS_USERNS_MOUNT : 0; -+ err = register_filesystem(&aufs_fs_type); -+ if (unlikely(err)) -+ goto out_cache; -+ -+ /* since we define pr_fmt, call printk directly */ -+ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n"); -+ goto out; /* success */ -+ -+out_cache: -+ au_cache_fin(); -+out_sysrq: -+ au_sysrq_fin(); -+out_hin: -+ au_hnotify_fin(); -+out_loopback: -+ au_loopback_fin(); -+out_wkq: -+ au_wkq_fin(); -+out_procfs: -+ au_procfs_fin(); -+out_dbgaufs: -+ dbgaufs_fin(); -+out_sysaufs: -+ sysaufs_fin(); -+ au_dy_fin(); -+out: -+ return err; -+} -+ -+static void __exit aufs_exit(void) -+{ -+ unregister_filesystem(&aufs_fs_type); -+ au_cache_fin(); -+ au_sysrq_fin(); -+ au_hnotify_fin(); -+ au_loopback_fin(); -+ au_wkq_fin(); -+ au_procfs_fin(); -+ dbgaufs_fin(); -+ sysaufs_fin(); -+ au_dy_fin(); -+} -+ -+module_init(aufs_init); -+module_exit(aufs_exit); -diff --git a/fs/aufs/module.h b/fs/aufs/module.h -new file mode 100644 -index 000000000..000761049 ---- /dev/null -+++ b/fs/aufs/module.h -@@ -0,0 +1,102 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * module initialization and module-global -+ */ -+ -+#ifndef __AUFS_MODULE_H__ -+#define __AUFS_MODULE_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+struct path; -+struct seq_file; -+ -+/* module parameters */ -+extern int sysaufs_brs; -+extern bool au_userns; -+ -+/* ---------------------------------------------------------------------- */ -+ -+extern int au_dir_roflags; -+ -+void *au_krealloc(void *p, unsigned int new_sz, gfp_t gfp, int may_shrink); -+void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp, -+ int may_shrink); -+ -+static inline int au_kmidx_sub(size_t sz, size_t new_sz) -+{ -+#ifndef CONFIG_SLOB -+ return kmalloc_index(sz) - kmalloc_index(new_sz); -+#else -+ return -1; /* SLOB is untested */ -+#endif -+} -+ -+int au_seq_path(struct seq_file *seq, struct path *path); -+ -+#ifdef CONFIG_PROC_FS -+/* procfs.c */ -+int __init au_procfs_init(void); -+void au_procfs_fin(void); -+#else -+AuStubInt0(au_procfs_init, void); -+AuStubVoid(au_procfs_fin, void); -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* kmem cache */ -+enum { -+ AuCache_DINFO, -+ AuCache_ICNTNR, -+ AuCache_FINFO, -+ AuCache_VDIR, -+ AuCache_DEHSTR, -+ AuCache_HNOTIFY, /* must be last */ -+ AuCache_Last -+}; -+ -+extern struct kmem_cache *au_cache[AuCache_Last]; -+ -+#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD) -+#define AuCache(type) KMEM_CACHE(type, AuCacheFlags) -+#define AuCacheCtor(type, ctor) \ -+ kmem_cache_create(#type, sizeof(struct type), \ -+ __alignof__(struct type), AuCacheFlags, ctor) -+ -+#define AuCacheFuncs(name, index) \ -+static inline struct au_##name *au_cache_alloc_##name(void) \ -+{ return kmem_cache_alloc(au_cache[AuCache_##index], GFP_NOFS); } \ -+static inline void au_cache_free_##name(struct au_##name *p) \ -+{ kmem_cache_free(au_cache[AuCache_##index], p); } -+ -+AuCacheFuncs(dinfo, DINFO); -+AuCacheFuncs(icntnr, ICNTNR); -+AuCacheFuncs(finfo, FINFO); -+AuCacheFuncs(vdir, VDIR); -+AuCacheFuncs(vdir_dehstr, DEHSTR); -+#ifdef CONFIG_AUFS_HNOTIFY -+AuCacheFuncs(hnotify, HNOTIFY); -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_MODULE_H__ */ -diff --git a/fs/aufs/mvdown.c b/fs/aufs/mvdown.c -new file mode 100644 -index 000000000..9603ef739 ---- /dev/null -+++ b/fs/aufs/mvdown.c -@@ -0,0 +1,705 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2011-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * move-down, opposite of copy-up -+ */ -+ -+#include "aufs.h" -+ -+struct au_mvd_args { -+ struct { -+ struct super_block *h_sb; -+ struct dentry *h_parent; -+ struct au_hinode *hdir; -+ struct inode *h_dir, *h_inode; -+ struct au_pin pin; -+ } info[AUFS_MVDOWN_NARRAY]; -+ -+ struct aufs_mvdown mvdown; -+ struct dentry *dentry, *parent; -+ struct inode *inode, *dir; -+ struct super_block *sb; -+ aufs_bindex_t bopq, bwh, bfound; -+ unsigned char rename_lock; -+}; -+ -+#define mvd_errno mvdown.au_errno -+#define mvd_bsrc mvdown.stbr[AUFS_MVDOWN_UPPER].bindex -+#define mvd_src_brid mvdown.stbr[AUFS_MVDOWN_UPPER].brid -+#define mvd_bdst mvdown.stbr[AUFS_MVDOWN_LOWER].bindex -+#define mvd_dst_brid mvdown.stbr[AUFS_MVDOWN_LOWER].brid -+ -+#define mvd_h_src_sb info[AUFS_MVDOWN_UPPER].h_sb -+#define mvd_h_src_parent info[AUFS_MVDOWN_UPPER].h_parent -+#define mvd_hdir_src info[AUFS_MVDOWN_UPPER].hdir -+#define mvd_h_src_dir info[AUFS_MVDOWN_UPPER].h_dir -+#define mvd_h_src_inode info[AUFS_MVDOWN_UPPER].h_inode -+#define mvd_pin_src info[AUFS_MVDOWN_UPPER].pin -+ -+#define mvd_h_dst_sb info[AUFS_MVDOWN_LOWER].h_sb -+#define mvd_h_dst_parent info[AUFS_MVDOWN_LOWER].h_parent -+#define mvd_hdir_dst info[AUFS_MVDOWN_LOWER].hdir -+#define mvd_h_dst_dir info[AUFS_MVDOWN_LOWER].h_dir -+#define mvd_h_dst_inode info[AUFS_MVDOWN_LOWER].h_inode -+#define mvd_pin_dst info[AUFS_MVDOWN_LOWER].pin -+ -+#define AU_MVD_PR(flag, ...) do { \ -+ if (flag) \ -+ pr_err(__VA_ARGS__); \ -+ } while (0) -+ -+static int find_lower_writable(struct au_mvd_args *a) -+{ -+ struct super_block *sb; -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ sb = a->sb; -+ bindex = a->mvd_bsrc; -+ bbot = au_sbbot(sb); -+ if (a->mvdown.flags & AUFS_MVDOWN_FHSM_LOWER) -+ for (bindex++; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_fhsm(br->br_perm) -+ && !sb_rdonly(au_br_sb(br))) -+ return bindex; -+ } -+ else if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER)) -+ for (bindex++; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (!au_br_rdonly(br)) -+ return bindex; -+ } -+ else -+ for (bindex++; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (!sb_rdonly(au_br_sb(br))) { -+ if (au_br_rdonly(br)) -+ a->mvdown.flags -+ |= AUFS_MVDOWN_ROLOWER_R; -+ return bindex; -+ } -+ } -+ -+ return -1; -+} -+ -+/* make the parent dir on bdst */ -+static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ -+ err = 0; -+ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc); -+ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst); -+ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc); -+ a->mvd_h_dst_parent = NULL; -+ if (au_dbbot(a->parent) >= a->mvd_bdst) -+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst); -+ if (!a->mvd_h_dst_parent) { -+ err = au_cpdown_dirs(a->dentry, a->mvd_bdst); -+ if (unlikely(err)) { -+ AU_MVD_PR(dmsg, "cpdown_dirs failed\n"); -+ goto out; -+ } -+ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst); -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* lock them all */ -+static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct dentry *h_trap; -+ -+ a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc); -+ a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst); -+ err = au_pin(&a->mvd_pin_dst, a->dentry, a->mvd_bdst, -+ au_opt_udba(a->sb), -+ AuPin_MNT_WRITE | AuPin_DI_LOCKED); -+ AuTraceErr(err); -+ if (unlikely(err)) { -+ AU_MVD_PR(dmsg, "pin_dst failed\n"); -+ goto out; -+ } -+ -+ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) { -+ a->rename_lock = 0; -+ au_pin_init(&a->mvd_pin_src, a->dentry, a->mvd_bsrc, -+ AuLsc_DI_PARENT, AuLsc_I_PARENT3, -+ au_opt_udba(a->sb), -+ AuPin_MNT_WRITE | AuPin_DI_LOCKED); -+ err = au_do_pin(&a->mvd_pin_src); -+ AuTraceErr(err); -+ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent); -+ if (unlikely(err)) { -+ AU_MVD_PR(dmsg, "pin_src failed\n"); -+ goto out_dst; -+ } -+ goto out; /* success */ -+ } -+ -+ a->rename_lock = 1; -+ au_pin_hdir_unlock(&a->mvd_pin_dst); -+ err = au_pin(&a->mvd_pin_src, a->dentry, a->mvd_bsrc, -+ au_opt_udba(a->sb), -+ AuPin_MNT_WRITE | AuPin_DI_LOCKED); -+ AuTraceErr(err); -+ a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent); -+ if (unlikely(err)) { -+ AU_MVD_PR(dmsg, "pin_src failed\n"); -+ au_pin_hdir_lock(&a->mvd_pin_dst); -+ goto out_dst; -+ } -+ au_pin_hdir_unlock(&a->mvd_pin_src); -+ h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src, -+ a->mvd_h_dst_parent, a->mvd_hdir_dst); -+ if (h_trap) { -+ err = (h_trap != a->mvd_h_src_parent); -+ if (err) -+ err = (h_trap != a->mvd_h_dst_parent); -+ } -+ BUG_ON(err); /* it should never happen */ -+ if (unlikely(a->mvd_h_src_dir != au_pinned_h_dir(&a->mvd_pin_src))) { -+ err = -EBUSY; -+ AuTraceErr(err); -+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src, -+ a->mvd_h_dst_parent, a->mvd_hdir_dst); -+ au_pin_hdir_lock(&a->mvd_pin_src); -+ au_unpin(&a->mvd_pin_src); -+ au_pin_hdir_lock(&a->mvd_pin_dst); -+ goto out_dst; -+ } -+ goto out; /* success */ -+ -+out_dst: -+ au_unpin(&a->mvd_pin_dst); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ if (!a->rename_lock) -+ au_unpin(&a->mvd_pin_src); -+ else { -+ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src, -+ a->mvd_h_dst_parent, a->mvd_hdir_dst); -+ au_pin_hdir_lock(&a->mvd_pin_src); -+ au_unpin(&a->mvd_pin_src); -+ au_pin_hdir_lock(&a->mvd_pin_dst); -+ } -+ au_unpin(&a->mvd_pin_dst); -+} -+ -+/* copy-down the file */ -+static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct au_cp_generic cpg = { -+ .dentry = a->dentry, -+ .bdst = a->mvd_bdst, -+ .bsrc = a->mvd_bsrc, -+ .len = -1, -+ .pin = &a->mvd_pin_dst, -+ .flags = AuCpup_DTIME | AuCpup_HOPEN -+ }; -+ -+ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst); -+ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER) -+ au_fset_cpup(cpg.flags, OVERWRITE); -+ if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER) -+ au_fset_cpup(cpg.flags, RWDST); -+ err = au_sio_cpdown_simple(&cpg); -+ if (unlikely(err)) -+ AU_MVD_PR(dmsg, "cpdown failed\n"); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * unlink the whiteout on bdst if exist which may be created by UDBA while we -+ * were sleeping -+ */ -+static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct path h_path; -+ struct au_branch *br; -+ struct inode *delegated; -+ -+ br = au_sbr(a->sb, a->mvd_bdst); -+ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br); -+ err = PTR_ERR(h_path.dentry); -+ if (IS_ERR(h_path.dentry)) { -+ AU_MVD_PR(dmsg, "wh_lkup failed\n"); -+ goto out; -+ } -+ -+ err = 0; -+ if (d_is_positive(h_path.dentry)) { -+ h_path.mnt = au_br_mnt(br); -+ delegated = NULL; -+ err = vfsub_unlink(d_inode(a->mvd_h_dst_parent), &h_path, -+ &delegated, /*force*/0); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ if (unlikely(err)) -+ AU_MVD_PR(dmsg, "wh_unlink failed\n"); -+ } -+ dput(h_path.dentry); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* -+ * unlink the topmost h_dentry -+ */ -+static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct path h_path; -+ struct inode *delegated; -+ -+ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc); -+ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc); -+ delegated = NULL; -+ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, &delegated, /*force*/0); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ if (unlikely(err)) -+ AU_MVD_PR(dmsg, "unlink failed\n"); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+/* Since mvdown succeeded, we ignore an error of this function */ -+static void au_do_stfs(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct au_branch *br; -+ -+ a->mvdown.flags |= AUFS_MVDOWN_STFS_FAILED; -+ br = au_sbr(a->sb, a->mvd_bsrc); -+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_UPPER].stfs); -+ if (!err) { -+ br = au_sbr(a->sb, a->mvd_bdst); -+ a->mvdown.stbr[AUFS_MVDOWN_LOWER].brid = br->br_id; -+ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_LOWER].stfs); -+ } -+ if (!err) -+ a->mvdown.flags &= ~AUFS_MVDOWN_STFS_FAILED; -+ else -+ AU_MVD_PR(dmsg, "statfs failed (%d), ignored\n", err); -+} -+ -+/* -+ * copy-down the file and unlink the bsrc file. -+ * - unlink the bdst whout if exist -+ * - copy-down the file (with whtmp name and rename) -+ * - unlink the bsrc file -+ */ -+static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ -+ err = au_do_mkdir(dmsg, a); -+ if (!err) -+ err = au_do_lock(dmsg, a); -+ if (unlikely(err)) -+ goto out; -+ -+ /* -+ * do not revert the activities we made on bdst since they should be -+ * harmless in aufs. -+ */ -+ -+ err = au_do_cpdown(dmsg, a); -+ if (!err) -+ err = au_do_unlink_wh(dmsg, a); -+ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) -+ err = au_do_unlink(dmsg, a); -+ if (unlikely(err)) -+ goto out_unlock; -+ -+ AuDbg("%pd2, 0x%x, %d --> %d\n", -+ a->dentry, a->mvdown.flags, a->mvd_bsrc, a->mvd_bdst); -+ if (find_lower_writable(a) < 0) -+ a->mvdown.flags |= AUFS_MVDOWN_BOTTOM; -+ -+ if (a->mvdown.flags & AUFS_MVDOWN_STFS) -+ au_do_stfs(dmsg, a); -+ -+ /* maintain internal array */ -+ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) { -+ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL); -+ au_set_dbtop(a->dentry, a->mvd_bdst); -+ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0); -+ au_set_ibtop(a->inode, a->mvd_bdst); -+ } else { -+ /* hide the lower */ -+ au_set_h_dptr(a->dentry, a->mvd_bdst, NULL); -+ au_set_dbbot(a->dentry, a->mvd_bsrc); -+ au_set_h_iptr(a->inode, a->mvd_bdst, NULL, /*flags*/0); -+ au_set_ibbot(a->inode, a->mvd_bsrc); -+ } -+ if (au_dbbot(a->dentry) < a->mvd_bdst) -+ au_set_dbbot(a->dentry, a->mvd_bdst); -+ if (au_ibbot(a->inode) < a->mvd_bdst) -+ au_set_ibbot(a->inode, a->mvd_bdst); -+ -+out_unlock: -+ au_do_unlock(dmsg, a); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* make sure the file is idle */ -+static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err, plinked; -+ -+ err = 0; -+ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK); -+ if (au_dbtop(a->dentry) == a->mvd_bsrc -+ && au_dcount(a->dentry) == 1 -+ && atomic_read(&a->inode->i_count) == 1 -+ /* && a->mvd_h_src_inode->i_nlink == 1 */ -+ && (!plinked || !au_plink_test(a->inode)) -+ && a->inode->i_nlink == 1) -+ goto out; -+ -+ err = -EBUSY; -+ AU_MVD_PR(dmsg, -+ "b%d, d{b%d, c%d?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n", -+ a->mvd_bsrc, au_dbtop(a->dentry), au_dcount(a->dentry), -+ atomic_read(&a->inode->i_count), a->inode->i_nlink, -+ a->mvd_h_src_inode->i_nlink, -+ plinked, plinked ? au_plink_test(a->inode) : 0); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* make sure the parent dir is fine */ -+static int au_mvd_args_parent(const unsigned char dmsg, -+ struct au_mvd_args *a) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ -+ err = 0; -+ if (unlikely(au_alive_dir(a->parent))) { -+ err = -ENOENT; -+ AU_MVD_PR(dmsg, "parent dir is dead\n"); -+ goto out; -+ } -+ -+ a->bopq = au_dbdiropq(a->parent); -+ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst); -+ AuDbg("b%d\n", bindex); -+ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst) -+ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) { -+ err = -EINVAL; -+ a->mvd_errno = EAU_MVDOWN_OPAQUE; -+ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n", -+ a->bopq, a->mvd_bdst); -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_mvd_args_intermediate(const unsigned char dmsg, -+ struct au_mvd_args *a) -+{ -+ int err; -+ struct au_dinfo *dinfo, *tmp; -+ -+ /* lookup the next lower positive entry */ -+ err = -ENOMEM; -+ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP); -+ if (unlikely(!tmp)) -+ goto out; -+ -+ a->bfound = -1; -+ a->bwh = -1; -+ dinfo = au_di(a->dentry); -+ au_di_cp(tmp, dinfo); -+ au_di_swap(tmp, dinfo); -+ -+ /* returns the number of positive dentries */ -+ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1, -+ /* AuLkup_IGNORE_PERM */ 0); -+ if (!err) -+ a->bwh = au_dbwh(a->dentry); -+ else if (err > 0) -+ a->bfound = au_dbtop(a->dentry); -+ -+ au_di_swap(tmp, dinfo); -+ au_rw_write_unlock(&tmp->di_rwsem); -+ au_di_free(tmp); -+ if (unlikely(err < 0)) -+ AU_MVD_PR(dmsg, "failed look-up lower\n"); -+ -+ /* -+ * here, we have these cases. -+ * bfound == -1 -+ * no positive dentry under bsrc. there are more sub-cases. -+ * bwh < 0 -+ * there no whiteout, we can safely move-down. -+ * bwh <= bsrc -+ * impossible -+ * bsrc < bwh && bwh < bdst -+ * there is a whiteout on RO branch. cannot proceed. -+ * bwh == bdst -+ * there is a whiteout on the RW target branch. it should -+ * be removed. -+ * bdst < bwh -+ * there is a whiteout somewhere unrelated branch. -+ * -1 < bfound && bfound <= bsrc -+ * impossible. -+ * bfound < bdst -+ * found, but it is on RO branch between bsrc and bdst. cannot -+ * proceed. -+ * bfound == bdst -+ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return -+ * error. -+ * bdst < bfound -+ * found, after we create the file on bdst, it will be hidden. -+ */ -+ -+ AuDebugOn(a->bfound == -1 -+ && a->bwh != -1 -+ && a->bwh <= a->mvd_bsrc); -+ AuDebugOn(-1 < a->bfound -+ && a->bfound <= a->mvd_bsrc); -+ -+ err = -EINVAL; -+ if (a->bfound == -1 -+ && a->mvd_bsrc < a->bwh -+ && a->bwh != -1 -+ && a->bwh < a->mvd_bdst) { -+ a->mvd_errno = EAU_MVDOWN_WHITEOUT; -+ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n", -+ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh); -+ goto out; -+ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) { -+ a->mvd_errno = EAU_MVDOWN_UPPER; -+ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n", -+ a->mvd_bdst, a->bfound); -+ goto out; -+ } -+ -+ err = 0; /* success */ -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ -+ err = 0; -+ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER) -+ && a->bfound == a->mvd_bdst) -+ err = -EEXIST; -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a) -+{ -+ int err; -+ struct au_branch *br; -+ -+ err = -EISDIR; -+ if (unlikely(S_ISDIR(a->inode->i_mode))) -+ goto out; -+ -+ err = -EINVAL; -+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER)) -+ a->mvd_bsrc = au_ibtop(a->inode); -+ else { -+ a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid); -+ if (unlikely(a->mvd_bsrc < 0 -+ || (a->mvd_bsrc < au_dbtop(a->dentry) -+ || au_dbbot(a->dentry) < a->mvd_bsrc -+ || !au_h_dptr(a->dentry, a->mvd_bsrc)) -+ || (a->mvd_bsrc < au_ibtop(a->inode) -+ || au_ibbot(a->inode) < a->mvd_bsrc -+ || !au_h_iptr(a->inode, a->mvd_bsrc)))) { -+ a->mvd_errno = EAU_MVDOWN_NOUPPER; -+ AU_MVD_PR(dmsg, "no upper\n"); -+ goto out; -+ } -+ } -+ if (unlikely(a->mvd_bsrc == au_sbbot(a->sb))) { -+ a->mvd_errno = EAU_MVDOWN_BOTTOM; -+ AU_MVD_PR(dmsg, "on the bottom\n"); -+ goto out; -+ } -+ a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc); -+ br = au_sbr(a->sb, a->mvd_bsrc); -+ err = au_br_rdonly(br); -+ if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) { -+ if (unlikely(err)) -+ goto out; -+ } else if (!(vfsub_native_ro(a->mvd_h_src_inode) -+ || IS_APPEND(a->mvd_h_src_inode))) { -+ if (err) -+ a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R; -+ /* go on */ -+ } else -+ goto out; -+ -+ err = -EINVAL; -+ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) { -+ a->mvd_bdst = find_lower_writable(a); -+ if (unlikely(a->mvd_bdst < 0)) { -+ a->mvd_errno = EAU_MVDOWN_BOTTOM; -+ AU_MVD_PR(dmsg, "no writable lower branch\n"); -+ goto out; -+ } -+ } else { -+ a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid); -+ if (unlikely(a->mvd_bdst < 0 -+ || au_sbbot(a->sb) < a->mvd_bdst)) { -+ a->mvd_errno = EAU_MVDOWN_NOLOWERBR; -+ AU_MVD_PR(dmsg, "no lower brid\n"); -+ goto out; -+ } -+ } -+ -+ err = au_mvd_args_busy(dmsg, a); -+ if (!err) -+ err = au_mvd_args_parent(dmsg, a); -+ if (!err) -+ err = au_mvd_args_intermediate(dmsg, a); -+ if (!err) -+ err = au_mvd_args_exist(dmsg, a); -+ if (!err) -+ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg) -+{ -+ int err, e; -+ unsigned char dmsg; -+ struct au_mvd_args *args; -+ struct inode *inode; -+ -+ inode = d_inode(dentry); -+ err = -EPERM; -+ if (unlikely(!capable(CAP_SYS_ADMIN))) -+ goto out; -+ -+ err = -ENOMEM; -+ args = kmalloc(sizeof(*args), GFP_NOFS); -+ if (unlikely(!args)) -+ goto out; -+ -+ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown)); -+ if (!err) -+ err = !access_ok(VERIFY_WRITE, uarg, sizeof(*uarg)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ goto out_free; -+ } -+ AuDbg("flags 0x%x\n", args->mvdown.flags); -+ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R); -+ args->mvdown.au_errno = 0; -+ args->dentry = dentry; -+ args->inode = inode; -+ args->sb = dentry->d_sb; -+ -+ err = -ENOENT; -+ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG); -+ args->parent = dget_parent(dentry); -+ args->dir = d_inode(args->parent); -+ inode_lock_nested(args->dir, I_MUTEX_PARENT); -+ dput(args->parent); -+ if (unlikely(args->parent != dentry->d_parent)) { -+ AU_MVD_PR(dmsg, "parent dir is moved\n"); -+ goto out_dir; -+ } -+ -+ inode_lock_nested(inode, I_MUTEX_CHILD); -+ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_NOPLMW); -+ if (unlikely(err)) -+ goto out_inode; -+ -+ di_write_lock_parent(args->parent); -+ err = au_mvd_args(dmsg, args); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ err = au_do_mvdown(dmsg, args); -+ if (unlikely(err)) -+ goto out_parent; -+ -+ au_cpup_attr_timesizes(args->dir); -+ au_cpup_attr_timesizes(inode); -+ if (!(args->mvdown.flags & AUFS_MVDOWN_KUPPER)) -+ au_cpup_igen(inode, au_h_iptr(inode, args->mvd_bdst)); -+ /* au_digen_dec(dentry); */ -+ -+out_parent: -+ di_write_unlock(args->parent); -+ aufs_read_unlock(dentry, AuLock_DW); -+out_inode: -+ inode_unlock(inode); -+out_dir: -+ inode_unlock(args->dir); -+out_free: -+ e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown)); -+ if (unlikely(e)) -+ err = -EFAULT; -+ kfree(args); -+out: -+ AuTraceErr(err); -+ return err; -+} -diff --git a/fs/aufs/opts.c b/fs/aufs/opts.c -new file mode 100644 -index 000000000..3a8ba2867 ---- /dev/null -+++ b/fs/aufs/opts.c -@@ -0,0 +1,1877 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * mount options/flags -+ */ -+ -+#include -+#include /* a distribution requires */ -+#include -+#include "aufs.h" -+ -+/* ---------------------------------------------------------------------- */ -+ -+enum { -+ Opt_br, -+ Opt_add, Opt_del, Opt_mod, Opt_append, Opt_prepend, -+ Opt_idel, Opt_imod, -+ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, -+ Opt_rdblk_def, Opt_rdhash_def, -+ Opt_xino, Opt_noxino, -+ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino, -+ Opt_trunc_xino_path, Opt_itrunc_xino, -+ Opt_trunc_xib, Opt_notrunc_xib, -+ Opt_shwh, Opt_noshwh, -+ Opt_plink, Opt_noplink, Opt_list_plink, -+ Opt_udba, -+ Opt_dio, Opt_nodio, -+ Opt_diropq_a, Opt_diropq_w, -+ Opt_warn_perm, Opt_nowarn_perm, -+ Opt_wbr_copyup, Opt_wbr_create, -+ Opt_fhsm_sec, -+ Opt_verbose, Opt_noverbose, -+ Opt_sum, Opt_nosum, Opt_wsum, -+ Opt_dirperm1, Opt_nodirperm1, -+ Opt_dirren, Opt_nodirren, -+ Opt_acl, Opt_noacl, -+ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err -+}; -+ -+static match_table_t options = { -+ {Opt_br, "br=%s"}, -+ {Opt_br, "br:%s"}, -+ -+ {Opt_add, "add=%d:%s"}, -+ {Opt_add, "add:%d:%s"}, -+ {Opt_add, "ins=%d:%s"}, -+ {Opt_add, "ins:%d:%s"}, -+ {Opt_append, "append=%s"}, -+ {Opt_append, "append:%s"}, -+ {Opt_prepend, "prepend=%s"}, -+ {Opt_prepend, "prepend:%s"}, -+ -+ {Opt_del, "del=%s"}, -+ {Opt_del, "del:%s"}, -+ /* {Opt_idel, "idel:%d"}, */ -+ {Opt_mod, "mod=%s"}, -+ {Opt_mod, "mod:%s"}, -+ /* {Opt_imod, "imod:%d:%s"}, */ -+ -+ {Opt_dirwh, "dirwh=%d"}, -+ -+ {Opt_xino, "xino=%s"}, -+ {Opt_noxino, "noxino"}, -+ {Opt_trunc_xino, "trunc_xino"}, -+ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"}, -+ {Opt_notrunc_xino, "notrunc_xino"}, -+ {Opt_trunc_xino_path, "trunc_xino=%s"}, -+ {Opt_itrunc_xino, "itrunc_xino=%d"}, -+ /* {Opt_zxino, "zxino=%s"}, */ -+ {Opt_trunc_xib, "trunc_xib"}, -+ {Opt_notrunc_xib, "notrunc_xib"}, -+ -+#ifdef CONFIG_PROC_FS -+ {Opt_plink, "plink"}, -+#else -+ {Opt_ignore_silent, "plink"}, -+#endif -+ -+ {Opt_noplink, "noplink"}, -+ -+#ifdef CONFIG_AUFS_DEBUG -+ {Opt_list_plink, "list_plink"}, -+#endif -+ -+ {Opt_udba, "udba=%s"}, -+ -+ {Opt_dio, "dio"}, -+ {Opt_nodio, "nodio"}, -+ -+#ifdef CONFIG_AUFS_DIRREN -+ {Opt_dirren, "dirren"}, -+ {Opt_nodirren, "nodirren"}, -+#else -+ {Opt_ignore, "dirren"}, -+ {Opt_ignore_silent, "nodirren"}, -+#endif -+ -+#ifdef CONFIG_AUFS_FHSM -+ {Opt_fhsm_sec, "fhsm_sec=%d"}, -+#else -+ {Opt_ignore, "fhsm_sec=%d"}, -+#endif -+ -+ {Opt_diropq_a, "diropq=always"}, -+ {Opt_diropq_a, "diropq=a"}, -+ {Opt_diropq_w, "diropq=whiteouted"}, -+ {Opt_diropq_w, "diropq=w"}, -+ -+ {Opt_warn_perm, "warn_perm"}, -+ {Opt_nowarn_perm, "nowarn_perm"}, -+ -+ /* keep them temporary */ -+ {Opt_ignore_silent, "nodlgt"}, -+ {Opt_ignore, "clean_plink"}, -+ -+#ifdef CONFIG_AUFS_SHWH -+ {Opt_shwh, "shwh"}, -+#endif -+ {Opt_noshwh, "noshwh"}, -+ -+ {Opt_dirperm1, "dirperm1"}, -+ {Opt_nodirperm1, "nodirperm1"}, -+ -+ {Opt_verbose, "verbose"}, -+ {Opt_verbose, "v"}, -+ {Opt_noverbose, "noverbose"}, -+ {Opt_noverbose, "quiet"}, -+ {Opt_noverbose, "q"}, -+ {Opt_noverbose, "silent"}, -+ -+ {Opt_sum, "sum"}, -+ {Opt_nosum, "nosum"}, -+ {Opt_wsum, "wsum"}, -+ -+ {Opt_rdcache, "rdcache=%d"}, -+ {Opt_rdblk, "rdblk=%d"}, -+ {Opt_rdblk_def, "rdblk=def"}, -+ {Opt_rdhash, "rdhash=%d"}, -+ {Opt_rdhash_def, "rdhash=def"}, -+ -+ {Opt_wbr_create, "create=%s"}, -+ {Opt_wbr_create, "create_policy=%s"}, -+ {Opt_wbr_copyup, "cpup=%s"}, -+ {Opt_wbr_copyup, "copyup=%s"}, -+ {Opt_wbr_copyup, "copyup_policy=%s"}, -+ -+ /* generic VFS flag */ -+#ifdef CONFIG_FS_POSIX_ACL -+ {Opt_acl, "acl"}, -+ {Opt_noacl, "noacl"}, -+#else -+ {Opt_ignore, "acl"}, -+ {Opt_ignore_silent, "noacl"}, -+#endif -+ -+ /* internal use for the scripts */ -+ {Opt_ignore_silent, "si=%s"}, -+ -+ {Opt_br, "dirs=%s"}, -+ {Opt_ignore, "debug=%d"}, -+ {Opt_ignore, "delete=whiteout"}, -+ {Opt_ignore, "delete=all"}, -+ {Opt_ignore, "imap=%s"}, -+ -+ /* temporary workaround, due to old mount(8)? */ -+ {Opt_ignore_silent, "relatime"}, -+ -+ {Opt_err, NULL} -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static const char *au_parser_pattern(int val, match_table_t tbl) -+{ -+ struct match_token *p; -+ -+ p = tbl; -+ while (p->pattern) { -+ if (p->token == val) -+ return p->pattern; -+ p++; -+ } -+ BUG(); -+ return "??"; -+} -+ -+static const char *au_optstr(int *val, match_table_t tbl) -+{ -+ struct match_token *p; -+ int v; -+ -+ v = *val; -+ if (!v) -+ goto out; -+ p = tbl; -+ while (p->pattern) { -+ if (p->token -+ && (v & p->token) == p->token) { -+ *val &= ~p->token; -+ return p->pattern; -+ } -+ p++; -+ } -+ -+out: -+ return NULL; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static match_table_t brperm = { -+ {AuBrPerm_RO, AUFS_BRPERM_RO}, -+ {AuBrPerm_RR, AUFS_BRPERM_RR}, -+ {AuBrPerm_RW, AUFS_BRPERM_RW}, -+ {0, NULL} -+}; -+ -+static match_table_t brattr = { -+ /* general */ -+ {AuBrAttr_COO_REG, AUFS_BRATTR_COO_REG}, -+ {AuBrAttr_COO_ALL, AUFS_BRATTR_COO_ALL}, -+ /* 'unpin' attrib is meaningless since linux-3.18-rc1 */ -+ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN}, -+#ifdef CONFIG_AUFS_FHSM -+ {AuBrAttr_FHSM, AUFS_BRATTR_FHSM}, -+#endif -+#ifdef CONFIG_AUFS_XATTR -+ {AuBrAttr_ICEX, AUFS_BRATTR_ICEX}, -+ {AuBrAttr_ICEX_SEC, AUFS_BRATTR_ICEX_SEC}, -+ {AuBrAttr_ICEX_SYS, AUFS_BRATTR_ICEX_SYS}, -+ {AuBrAttr_ICEX_TR, AUFS_BRATTR_ICEX_TR}, -+ {AuBrAttr_ICEX_USR, AUFS_BRATTR_ICEX_USR}, -+ {AuBrAttr_ICEX_OTH, AUFS_BRATTR_ICEX_OTH}, -+#endif -+ -+ /* ro/rr branch */ -+ {AuBrRAttr_WH, AUFS_BRRATTR_WH}, -+ -+ /* rw branch */ -+ {AuBrWAttr_MOO, AUFS_BRWATTR_MOO}, -+ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH}, -+ -+ {0, NULL} -+}; -+ -+static int br_attr_val(char *str, match_table_t table, substring_t args[]) -+{ -+ int attr, v; -+ char *p; -+ -+ attr = 0; -+ do { -+ p = strchr(str, '+'); -+ if (p) -+ *p = 0; -+ v = match_token(str, table, args); -+ if (v) { -+ if (v & AuBrAttr_CMOO_Mask) -+ attr &= ~AuBrAttr_CMOO_Mask; -+ attr |= v; -+ } else { -+ if (p) -+ *p = '+'; -+ pr_warn("ignored branch attribute %s\n", str); -+ break; -+ } -+ if (p) -+ str = p + 1; -+ } while (p); -+ -+ return attr; -+} -+ -+static int au_do_optstr_br_attr(au_br_perm_str_t *str, int perm) -+{ -+ int sz; -+ const char *p; -+ char *q; -+ -+ q = str->a; -+ *q = 0; -+ p = au_optstr(&perm, brattr); -+ if (p) { -+ sz = strlen(p); -+ memcpy(q, p, sz + 1); -+ q += sz; -+ } else -+ goto out; -+ -+ do { -+ p = au_optstr(&perm, brattr); -+ if (p) { -+ *q++ = '+'; -+ sz = strlen(p); -+ memcpy(q, p, sz + 1); -+ q += sz; -+ } -+ } while (p); -+ -+out: -+ return q - str->a; -+} -+ -+static int noinline_for_stack br_perm_val(char *perm) -+{ -+ int val, bad, sz; -+ char *p; -+ substring_t args[MAX_OPT_ARGS]; -+ au_br_perm_str_t attr; -+ -+ p = strchr(perm, '+'); -+ if (p) -+ *p = 0; -+ val = match_token(perm, brperm, args); -+ if (!val) { -+ if (p) -+ *p = '+'; -+ pr_warn("ignored branch permission %s\n", perm); -+ val = AuBrPerm_RO; -+ goto out; -+ } -+ if (!p) -+ goto out; -+ -+ val |= br_attr_val(p + 1, brattr, args); -+ -+ bad = 0; -+ switch (val & AuBrPerm_Mask) { -+ case AuBrPerm_RO: -+ case AuBrPerm_RR: -+ bad = val & AuBrWAttr_Mask; -+ val &= ~AuBrWAttr_Mask; -+ break; -+ case AuBrPerm_RW: -+ bad = val & AuBrRAttr_Mask; -+ val &= ~AuBrRAttr_Mask; -+ break; -+ } -+ -+ /* -+ * 'unpin' attrib becomes meaningless since linux-3.18-rc1, but aufs -+ * does not treat it as an error, just warning. -+ * this is a tiny guard for the user operation. -+ */ -+ if (val & AuBrAttr_UNPIN) { -+ bad |= AuBrAttr_UNPIN; -+ val &= ~AuBrAttr_UNPIN; -+ } -+ -+ if (unlikely(bad)) { -+ sz = au_do_optstr_br_attr(&attr, bad); -+ AuDebugOn(!sz); -+ pr_warn("ignored branch attribute %s\n", attr.a); -+ } -+ -+out: -+ return val; -+} -+ -+void au_optstr_br_perm(au_br_perm_str_t *str, int perm) -+{ -+ au_br_perm_str_t attr; -+ const char *p; -+ char *q; -+ int sz; -+ -+ q = str->a; -+ p = au_optstr(&perm, brperm); -+ AuDebugOn(!p || !*p); -+ sz = strlen(p); -+ memcpy(q, p, sz + 1); -+ q += sz; -+ -+ sz = au_do_optstr_br_attr(&attr, perm); -+ if (sz) { -+ *q++ = '+'; -+ memcpy(q, attr.a, sz + 1); -+ } -+ -+ AuDebugOn(strlen(str->a) >= sizeof(str->a)); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static match_table_t udbalevel = { -+ {AuOpt_UDBA_REVAL, "reval"}, -+ {AuOpt_UDBA_NONE, "none"}, -+#ifdef CONFIG_AUFS_HNOTIFY -+ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */ -+#ifdef CONFIG_AUFS_HFSNOTIFY -+ {AuOpt_UDBA_HNOTIFY, "fsnotify"}, -+#endif -+#endif -+ {-1, NULL} -+}; -+ -+static int noinline_for_stack udba_val(char *str) -+{ -+ substring_t args[MAX_OPT_ARGS]; -+ -+ return match_token(str, udbalevel, args); -+} -+ -+const char *au_optstr_udba(int udba) -+{ -+ return au_parser_pattern(udba, udbalevel); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static match_table_t au_wbr_create_policy = { -+ {AuWbrCreate_TDP, "tdp"}, -+ {AuWbrCreate_TDP, "top-down-parent"}, -+ {AuWbrCreate_RR, "rr"}, -+ {AuWbrCreate_RR, "round-robin"}, -+ {AuWbrCreate_MFS, "mfs"}, -+ {AuWbrCreate_MFS, "most-free-space"}, -+ {AuWbrCreate_MFSV, "mfs:%d"}, -+ {AuWbrCreate_MFSV, "most-free-space:%d"}, -+ -+ /* top-down regardless the parent, and then mfs */ -+ {AuWbrCreate_TDMFS, "tdmfs:%d"}, -+ {AuWbrCreate_TDMFSV, "tdmfs:%d:%d"}, -+ -+ {AuWbrCreate_MFSRR, "mfsrr:%d"}, -+ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"}, -+ {AuWbrCreate_PMFS, "pmfs"}, -+ {AuWbrCreate_PMFSV, "pmfs:%d"}, -+ {AuWbrCreate_PMFSRR, "pmfsrr:%d"}, -+ {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"}, -+ -+ {-1, NULL} -+}; -+ -+static int au_wbr_mfs_wmark(substring_t *arg, char *str, -+ struct au_opt_wbr_create *create) -+{ -+ int err; -+ unsigned long long ull; -+ -+ err = 0; -+ if (!match_u64(arg, &ull)) -+ create->mfsrr_watermark = ull; -+ else { -+ pr_err("bad integer in %s\n", str); -+ err = -EINVAL; -+ } -+ -+ return err; -+} -+ -+static int au_wbr_mfs_sec(substring_t *arg, char *str, -+ struct au_opt_wbr_create *create) -+{ -+ int n, err; -+ -+ err = 0; -+ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC) -+ create->mfs_second = n; -+ else { -+ pr_err("bad integer in %s\n", str); -+ err = -EINVAL; -+ } -+ -+ return err; -+} -+ -+static int noinline_for_stack -+au_wbr_create_val(char *str, struct au_opt_wbr_create *create) -+{ -+ int err, e; -+ substring_t args[MAX_OPT_ARGS]; -+ -+ err = match_token(str, au_wbr_create_policy, args); -+ create->wbr_create = err; -+ switch (err) { -+ case AuWbrCreate_MFSRRV: -+ case AuWbrCreate_TDMFSV: -+ case AuWbrCreate_PMFSRRV: -+ e = au_wbr_mfs_wmark(&args[0], str, create); -+ if (!e) -+ e = au_wbr_mfs_sec(&args[1], str, create); -+ if (unlikely(e)) -+ err = e; -+ break; -+ case AuWbrCreate_MFSRR: -+ case AuWbrCreate_TDMFS: -+ case AuWbrCreate_PMFSRR: -+ e = au_wbr_mfs_wmark(&args[0], str, create); -+ if (unlikely(e)) { -+ err = e; -+ break; -+ } -+ /*FALLTHROUGH*/ -+ case AuWbrCreate_MFS: -+ case AuWbrCreate_PMFS: -+ create->mfs_second = AUFS_MFS_DEF_SEC; -+ break; -+ case AuWbrCreate_MFSV: -+ case AuWbrCreate_PMFSV: -+ e = au_wbr_mfs_sec(&args[0], str, create); -+ if (unlikely(e)) -+ err = e; -+ break; -+ } -+ -+ return err; -+} -+ -+const char *au_optstr_wbr_create(int wbr_create) -+{ -+ return au_parser_pattern(wbr_create, au_wbr_create_policy); -+} -+ -+static match_table_t au_wbr_copyup_policy = { -+ {AuWbrCopyup_TDP, "tdp"}, -+ {AuWbrCopyup_TDP, "top-down-parent"}, -+ {AuWbrCopyup_BUP, "bup"}, -+ {AuWbrCopyup_BUP, "bottom-up-parent"}, -+ {AuWbrCopyup_BU, "bu"}, -+ {AuWbrCopyup_BU, "bottom-up"}, -+ {-1, NULL} -+}; -+ -+static int noinline_for_stack au_wbr_copyup_val(char *str) -+{ -+ substring_t args[MAX_OPT_ARGS]; -+ -+ return match_token(str, au_wbr_copyup_policy, args); -+} -+ -+const char *au_optstr_wbr_copyup(int wbr_copyup) -+{ -+ return au_parser_pattern(wbr_copyup, au_wbr_copyup_policy); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY; -+ -+static void dump_opts(struct au_opts *opts) -+{ -+#ifdef CONFIG_AUFS_DEBUG -+ /* reduce stack space */ -+ union { -+ struct au_opt_add *add; -+ struct au_opt_del *del; -+ struct au_opt_mod *mod; -+ struct au_opt_xino *xino; -+ struct au_opt_xino_itrunc *xino_itrunc; -+ struct au_opt_wbr_create *create; -+ } u; -+ struct au_opt *opt; -+ -+ opt = opts->opt; -+ while (opt->type != Opt_tail) { -+ switch (opt->type) { -+ case Opt_add: -+ u.add = &opt->add; -+ AuDbg("add {b%d, %s, 0x%x, %p}\n", -+ u.add->bindex, u.add->pathname, u.add->perm, -+ u.add->path.dentry); -+ break; -+ case Opt_del: -+ case Opt_idel: -+ u.del = &opt->del; -+ AuDbg("del {%s, %p}\n", -+ u.del->pathname, u.del->h_path.dentry); -+ break; -+ case Opt_mod: -+ case Opt_imod: -+ u.mod = &opt->mod; -+ AuDbg("mod {%s, 0x%x, %p}\n", -+ u.mod->path, u.mod->perm, u.mod->h_root); -+ break; -+ case Opt_append: -+ u.add = &opt->add; -+ AuDbg("append {b%d, %s, 0x%x, %p}\n", -+ u.add->bindex, u.add->pathname, u.add->perm, -+ u.add->path.dentry); -+ break; -+ case Opt_prepend: -+ u.add = &opt->add; -+ AuDbg("prepend {b%d, %s, 0x%x, %p}\n", -+ u.add->bindex, u.add->pathname, u.add->perm, -+ u.add->path.dentry); -+ break; -+ case Opt_dirwh: -+ AuDbg("dirwh %d\n", opt->dirwh); -+ break; -+ case Opt_rdcache: -+ AuDbg("rdcache %d\n", opt->rdcache); -+ break; -+ case Opt_rdblk: -+ AuDbg("rdblk %u\n", opt->rdblk); -+ break; -+ case Opt_rdblk_def: -+ AuDbg("rdblk_def\n"); -+ break; -+ case Opt_rdhash: -+ AuDbg("rdhash %u\n", opt->rdhash); -+ break; -+ case Opt_rdhash_def: -+ AuDbg("rdhash_def\n"); -+ break; -+ case Opt_xino: -+ u.xino = &opt->xino; -+ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file); -+ break; -+ case Opt_trunc_xino: -+ AuLabel(trunc_xino); -+ break; -+ case Opt_notrunc_xino: -+ AuLabel(notrunc_xino); -+ break; -+ case Opt_trunc_xino_path: -+ case Opt_itrunc_xino: -+ u.xino_itrunc = &opt->xino_itrunc; -+ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex); -+ break; -+ case Opt_noxino: -+ AuLabel(noxino); -+ break; -+ case Opt_trunc_xib: -+ AuLabel(trunc_xib); -+ break; -+ case Opt_notrunc_xib: -+ AuLabel(notrunc_xib); -+ break; -+ case Opt_shwh: -+ AuLabel(shwh); -+ break; -+ case Opt_noshwh: -+ AuLabel(noshwh); -+ break; -+ case Opt_dirperm1: -+ AuLabel(dirperm1); -+ break; -+ case Opt_nodirperm1: -+ AuLabel(nodirperm1); -+ break; -+ case Opt_plink: -+ AuLabel(plink); -+ break; -+ case Opt_noplink: -+ AuLabel(noplink); -+ break; -+ case Opt_list_plink: -+ AuLabel(list_plink); -+ break; -+ case Opt_udba: -+ AuDbg("udba %d, %s\n", -+ opt->udba, au_optstr_udba(opt->udba)); -+ break; -+ case Opt_dio: -+ AuLabel(dio); -+ break; -+ case Opt_nodio: -+ AuLabel(nodio); -+ break; -+ case Opt_diropq_a: -+ AuLabel(diropq_a); -+ break; -+ case Opt_diropq_w: -+ AuLabel(diropq_w); -+ break; -+ case Opt_warn_perm: -+ AuLabel(warn_perm); -+ break; -+ case Opt_nowarn_perm: -+ AuLabel(nowarn_perm); -+ break; -+ case Opt_verbose: -+ AuLabel(verbose); -+ break; -+ case Opt_noverbose: -+ AuLabel(noverbose); -+ break; -+ case Opt_sum: -+ AuLabel(sum); -+ break; -+ case Opt_nosum: -+ AuLabel(nosum); -+ break; -+ case Opt_wsum: -+ AuLabel(wsum); -+ break; -+ case Opt_wbr_create: -+ u.create = &opt->wbr_create; -+ AuDbg("create %d, %s\n", u.create->wbr_create, -+ au_optstr_wbr_create(u.create->wbr_create)); -+ switch (u.create->wbr_create) { -+ case AuWbrCreate_MFSV: -+ case AuWbrCreate_PMFSV: -+ AuDbg("%d sec\n", u.create->mfs_second); -+ break; -+ case AuWbrCreate_MFSRR: -+ case AuWbrCreate_TDMFS: -+ AuDbg("%llu watermark\n", -+ u.create->mfsrr_watermark); -+ break; -+ case AuWbrCreate_MFSRRV: -+ case AuWbrCreate_TDMFSV: -+ case AuWbrCreate_PMFSRRV: -+ AuDbg("%llu watermark, %d sec\n", -+ u.create->mfsrr_watermark, -+ u.create->mfs_second); -+ break; -+ } -+ break; -+ case Opt_wbr_copyup: -+ AuDbg("copyup %d, %s\n", opt->wbr_copyup, -+ au_optstr_wbr_copyup(opt->wbr_copyup)); -+ break; -+ case Opt_fhsm_sec: -+ AuDbg("fhsm_sec %u\n", opt->fhsm_second); -+ break; -+ case Opt_dirren: -+ AuLabel(dirren); -+ break; -+ case Opt_nodirren: -+ AuLabel(nodirren); -+ break; -+ case Opt_acl: -+ AuLabel(acl); -+ break; -+ case Opt_noacl: -+ AuLabel(noacl); -+ break; -+ default: -+ BUG(); -+ } -+ opt++; -+ } -+#endif -+} -+ -+void au_opts_free(struct au_opts *opts) -+{ -+ struct au_opt *opt; -+ -+ opt = opts->opt; -+ while (opt->type != Opt_tail) { -+ switch (opt->type) { -+ case Opt_add: -+ case Opt_append: -+ case Opt_prepend: -+ path_put(&opt->add.path); -+ break; -+ case Opt_del: -+ case Opt_idel: -+ path_put(&opt->del.h_path); -+ break; -+ case Opt_mod: -+ case Opt_imod: -+ dput(opt->mod.h_root); -+ break; -+ case Opt_xino: -+ fput(opt->xino.file); -+ break; -+ } -+ opt++; -+ } -+} -+ -+static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags, -+ aufs_bindex_t bindex) -+{ -+ int err; -+ struct au_opt_add *add = &opt->add; -+ char *p; -+ -+ add->bindex = bindex; -+ add->perm = AuBrPerm_RO; -+ add->pathname = opt_str; -+ p = strchr(opt_str, '='); -+ if (p) { -+ *p++ = 0; -+ if (*p) -+ add->perm = br_perm_val(p); -+ } -+ -+ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path); -+ if (!err) { -+ if (!p) { -+ add->perm = AuBrPerm_RO; -+ if (au_test_fs_rr(add->path.dentry->d_sb)) -+ add->perm = AuBrPerm_RR; -+ else if (!bindex && !(sb_flags & SB_RDONLY)) -+ add->perm = AuBrPerm_RW; -+ } -+ opt->type = Opt_add; -+ goto out; -+ } -+ pr_err("lookup failed %s (%d)\n", add->pathname, err); -+ err = -EINVAL; -+ -+out: -+ return err; -+} -+ -+static int au_opts_parse_del(struct au_opt_del *del, substring_t args[]) -+{ -+ int err; -+ -+ del->pathname = args[0].from; -+ AuDbg("del path %s\n", del->pathname); -+ -+ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path); -+ if (unlikely(err)) -+ pr_err("lookup failed %s (%d)\n", del->pathname, err); -+ -+ return err; -+} -+ -+#if 0 /* reserved for future use */ -+static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex, -+ struct au_opt_del *del, substring_t args[]) -+{ -+ int err; -+ struct dentry *root; -+ -+ err = -EINVAL; -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_FLUSH); -+ if (bindex < 0 || au_sbbot(sb) < bindex) { -+ pr_err("out of bounds, %d\n", bindex); -+ goto out; -+ } -+ -+ err = 0; -+ del->h_path.dentry = dget(au_h_dptr(root, bindex)); -+ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex)); -+ -+out: -+ aufs_read_unlock(root, !AuLock_IR); -+ return err; -+} -+#endif -+ -+static int noinline_for_stack -+au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[]) -+{ -+ int err; -+ struct path path; -+ char *p; -+ -+ err = -EINVAL; -+ mod->path = args[0].from; -+ p = strchr(mod->path, '='); -+ if (unlikely(!p)) { -+ pr_err("no permission %s\n", args[0].from); -+ goto out; -+ } -+ -+ *p++ = 0; -+ err = vfsub_kern_path(mod->path, lkup_dirflags, &path); -+ if (unlikely(err)) { -+ pr_err("lookup failed %s (%d)\n", mod->path, err); -+ goto out; -+ } -+ -+ mod->perm = br_perm_val(p); -+ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p); -+ mod->h_root = dget(path.dentry); -+ path_put(&path); -+ -+out: -+ return err; -+} -+ -+#if 0 /* reserved for future use */ -+static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex, -+ struct au_opt_mod *mod, substring_t args[]) -+{ -+ int err; -+ struct dentry *root; -+ -+ err = -EINVAL; -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_FLUSH); -+ if (bindex < 0 || au_sbbot(sb) < bindex) { -+ pr_err("out of bounds, %d\n", bindex); -+ goto out; -+ } -+ -+ err = 0; -+ mod->perm = br_perm_val(args[1].from); -+ AuDbg("mod path %s, perm 0x%x, %s\n", -+ mod->path, mod->perm, args[1].from); -+ mod->h_root = dget(au_h_dptr(root, bindex)); -+ -+out: -+ aufs_read_unlock(root, !AuLock_IR); -+ return err; -+} -+#endif -+ -+static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino, -+ substring_t args[]) -+{ -+ int err; -+ struct file *file; -+ -+ file = au_xino_create(sb, args[0].from, /*silent*/0); -+ err = PTR_ERR(file); -+ if (IS_ERR(file)) -+ goto out; -+ -+ err = -EINVAL; -+ if (unlikely(file->f_path.dentry->d_sb == sb)) { -+ fput(file); -+ pr_err("%s must be outside\n", args[0].from); -+ goto out; -+ } -+ -+ err = 0; -+ xino->file = file; -+ xino->path = args[0].from; -+ -+out: -+ return err; -+} -+ -+static int noinline_for_stack -+au_opts_parse_xino_itrunc_path(struct super_block *sb, -+ struct au_opt_xino_itrunc *xino_itrunc, -+ substring_t args[]) -+{ -+ int err; -+ aufs_bindex_t bbot, bindex; -+ struct path path; -+ struct dentry *root; -+ -+ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path); -+ if (unlikely(err)) { -+ pr_err("lookup failed %s (%d)\n", args[0].from, err); -+ goto out; -+ } -+ -+ xino_itrunc->bindex = -1; -+ root = sb->s_root; -+ aufs_read_lock(root, AuLock_FLUSH); -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ if (au_h_dptr(root, bindex) == path.dentry) { -+ xino_itrunc->bindex = bindex; -+ break; -+ } -+ } -+ aufs_read_unlock(root, !AuLock_IR); -+ path_put(&path); -+ -+ if (unlikely(xino_itrunc->bindex < 0)) { -+ pr_err("no such branch %s\n", args[0].from); -+ err = -EINVAL; -+ } -+ -+out: -+ return err; -+} -+ -+/* called without aufs lock */ -+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts) -+{ -+ int err, n, token; -+ aufs_bindex_t bindex; -+ unsigned char skipped; -+ struct dentry *root; -+ struct au_opt *opt, *opt_tail; -+ char *opt_str; -+ /* reduce the stack space */ -+ union { -+ struct au_opt_xino_itrunc *xino_itrunc; -+ struct au_opt_wbr_create *create; -+ } u; -+ struct { -+ substring_t args[MAX_OPT_ARGS]; -+ } *a; -+ -+ err = -ENOMEM; -+ a = kmalloc(sizeof(*a), GFP_NOFS); -+ if (unlikely(!a)) -+ goto out; -+ -+ root = sb->s_root; -+ err = 0; -+ bindex = 0; -+ opt = opts->opt; -+ opt_tail = opt + opts->max_opt - 1; -+ opt->type = Opt_tail; -+ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) { -+ err = -EINVAL; -+ skipped = 0; -+ token = match_token(opt_str, options, a->args); -+ switch (token) { -+ case Opt_br: -+ err = 0; -+ while (!err && (opt_str = strsep(&a->args[0].from, ":")) -+ && *opt_str) { -+ err = opt_add(opt, opt_str, opts->sb_flags, -+ bindex++); -+ if (unlikely(!err && ++opt > opt_tail)) { -+ err = -E2BIG; -+ break; -+ } -+ opt->type = Opt_tail; -+ skipped = 1; -+ } -+ break; -+ case Opt_add: -+ if (unlikely(match_int(&a->args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ bindex = n; -+ err = opt_add(opt, a->args[1].from, opts->sb_flags, -+ bindex); -+ if (!err) -+ opt->type = token; -+ break; -+ case Opt_append: -+ err = opt_add(opt, a->args[0].from, opts->sb_flags, -+ /*dummy bindex*/1); -+ if (!err) -+ opt->type = token; -+ break; -+ case Opt_prepend: -+ err = opt_add(opt, a->args[0].from, opts->sb_flags, -+ /*bindex*/0); -+ if (!err) -+ opt->type = token; -+ break; -+ case Opt_del: -+ err = au_opts_parse_del(&opt->del, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+#if 0 /* reserved for future use */ -+ case Opt_idel: -+ del->pathname = "(indexed)"; -+ if (unlikely(match_int(&args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ err = au_opts_parse_idel(sb, n, &opt->del, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+#endif -+ case Opt_mod: -+ err = au_opts_parse_mod(&opt->mod, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+#ifdef IMOD /* reserved for future use */ -+ case Opt_imod: -+ u.mod->path = "(indexed)"; -+ if (unlikely(match_int(&a->args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ err = au_opts_parse_imod(sb, n, &opt->mod, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+#endif -+ case Opt_xino: -+ err = au_opts_parse_xino(sb, &opt->xino, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+ -+ case Opt_trunc_xino_path: -+ err = au_opts_parse_xino_itrunc_path -+ (sb, &opt->xino_itrunc, a->args); -+ if (!err) -+ opt->type = token; -+ break; -+ -+ case Opt_itrunc_xino: -+ u.xino_itrunc = &opt->xino_itrunc; -+ if (unlikely(match_int(&a->args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ u.xino_itrunc->bindex = n; -+ aufs_read_lock(root, AuLock_FLUSH); -+ if (n < 0 || au_sbbot(sb) < n) { -+ pr_err("out of bounds, %d\n", n); -+ aufs_read_unlock(root, !AuLock_IR); -+ break; -+ } -+ aufs_read_unlock(root, !AuLock_IR); -+ err = 0; -+ opt->type = token; -+ break; -+ -+ case Opt_dirwh: -+ if (unlikely(match_int(&a->args[0], &opt->dirwh))) -+ break; -+ err = 0; -+ opt->type = token; -+ break; -+ -+ case Opt_rdcache: -+ if (unlikely(match_int(&a->args[0], &n))) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ if (unlikely(n > AUFS_RDCACHE_MAX)) { -+ pr_err("rdcache must be smaller than %d\n", -+ AUFS_RDCACHE_MAX); -+ break; -+ } -+ opt->rdcache = n; -+ err = 0; -+ opt->type = token; -+ break; -+ case Opt_rdblk: -+ if (unlikely(match_int(&a->args[0], &n) -+ || n < 0 -+ || n > KMALLOC_MAX_SIZE)) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ if (unlikely(n && n < NAME_MAX)) { -+ pr_err("rdblk must be larger than %d\n", -+ NAME_MAX); -+ break; -+ } -+ opt->rdblk = n; -+ err = 0; -+ opt->type = token; -+ break; -+ case Opt_rdhash: -+ if (unlikely(match_int(&a->args[0], &n) -+ || n < 0 -+ || n * sizeof(struct hlist_head) -+ > KMALLOC_MAX_SIZE)) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ opt->rdhash = n; -+ err = 0; -+ opt->type = token; -+ break; -+ -+ case Opt_trunc_xino: -+ case Opt_notrunc_xino: -+ case Opt_noxino: -+ case Opt_trunc_xib: -+ case Opt_notrunc_xib: -+ case Opt_shwh: -+ case Opt_noshwh: -+ case Opt_dirperm1: -+ case Opt_nodirperm1: -+ case Opt_plink: -+ case Opt_noplink: -+ case Opt_list_plink: -+ case Opt_dio: -+ case Opt_nodio: -+ case Opt_diropq_a: -+ case Opt_diropq_w: -+ case Opt_warn_perm: -+ case Opt_nowarn_perm: -+ case Opt_verbose: -+ case Opt_noverbose: -+ case Opt_sum: -+ case Opt_nosum: -+ case Opt_wsum: -+ case Opt_rdblk_def: -+ case Opt_rdhash_def: -+ case Opt_dirren: -+ case Opt_nodirren: -+ case Opt_acl: -+ case Opt_noacl: -+ err = 0; -+ opt->type = token; -+ break; -+ -+ case Opt_udba: -+ opt->udba = udba_val(a->args[0].from); -+ if (opt->udba >= 0) { -+ err = 0; -+ opt->type = token; -+ } else -+ pr_err("wrong value, %s\n", opt_str); -+ break; -+ -+ case Opt_wbr_create: -+ u.create = &opt->wbr_create; -+ u.create->wbr_create -+ = au_wbr_create_val(a->args[0].from, u.create); -+ if (u.create->wbr_create >= 0) { -+ err = 0; -+ opt->type = token; -+ } else -+ pr_err("wrong value, %s\n", opt_str); -+ break; -+ case Opt_wbr_copyup: -+ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from); -+ if (opt->wbr_copyup >= 0) { -+ err = 0; -+ opt->type = token; -+ } else -+ pr_err("wrong value, %s\n", opt_str); -+ break; -+ -+ case Opt_fhsm_sec: -+ if (unlikely(match_int(&a->args[0], &n) -+ || n < 0)) { -+ pr_err("bad integer in %s\n", opt_str); -+ break; -+ } -+ if (sysaufs_brs) { -+ opt->fhsm_second = n; -+ opt->type = token; -+ } else -+ pr_warn("ignored %s\n", opt_str); -+ err = 0; -+ break; -+ -+ case Opt_ignore: -+ pr_warn("ignored %s\n", opt_str); -+ /*FALLTHROUGH*/ -+ case Opt_ignore_silent: -+ skipped = 1; -+ err = 0; -+ break; -+ case Opt_err: -+ pr_err("unknown option %s\n", opt_str); -+ break; -+ } -+ -+ if (!err && !skipped) { -+ if (unlikely(++opt > opt_tail)) { -+ err = -E2BIG; -+ opt--; -+ opt->type = Opt_tail; -+ break; -+ } -+ opt->type = Opt_tail; -+ } -+ } -+ -+ kfree(a); -+ dump_opts(opts); -+ if (unlikely(err)) -+ au_opts_free(opts); -+ -+out: -+ return err; -+} -+ -+static int au_opt_wbr_create(struct super_block *sb, -+ struct au_opt_wbr_create *create) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ err = 1; /* handled */ -+ sbinfo = au_sbi(sb); -+ if (sbinfo->si_wbr_create_ops->fin) { -+ err = sbinfo->si_wbr_create_ops->fin(sb); -+ if (!err) -+ err = 1; -+ } -+ -+ sbinfo->si_wbr_create = create->wbr_create; -+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create; -+ switch (create->wbr_create) { -+ case AuWbrCreate_MFSRRV: -+ case AuWbrCreate_MFSRR: -+ case AuWbrCreate_TDMFS: -+ case AuWbrCreate_TDMFSV: -+ case AuWbrCreate_PMFSRR: -+ case AuWbrCreate_PMFSRRV: -+ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark; -+ /*FALLTHROUGH*/ -+ case AuWbrCreate_MFS: -+ case AuWbrCreate_MFSV: -+ case AuWbrCreate_PMFS: -+ case AuWbrCreate_PMFSV: -+ sbinfo->si_wbr_mfs.mfs_expire -+ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC); -+ break; -+ } -+ -+ if (sbinfo->si_wbr_create_ops->init) -+ sbinfo->si_wbr_create_ops->init(sb); /* ignore */ -+ -+ return err; -+} -+ -+/* -+ * returns, -+ * plus: processed without an error -+ * zero: unprocessed -+ */ -+static int au_opt_simple(struct super_block *sb, struct au_opt *opt, -+ struct au_opts *opts) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ err = 1; /* handled */ -+ sbinfo = au_sbi(sb); -+ switch (opt->type) { -+ case Opt_udba: -+ sbinfo->si_mntflags &= ~AuOptMask_UDBA; -+ sbinfo->si_mntflags |= opt->udba; -+ opts->given_udba |= opt->udba; -+ break; -+ -+ case Opt_plink: -+ au_opt_set(sbinfo->si_mntflags, PLINK); -+ break; -+ case Opt_noplink: -+ if (au_opt_test(sbinfo->si_mntflags, PLINK)) -+ au_plink_put(sb, /*verbose*/1); -+ au_opt_clr(sbinfo->si_mntflags, PLINK); -+ break; -+ case Opt_list_plink: -+ if (au_opt_test(sbinfo->si_mntflags, PLINK)) -+ au_plink_list(sb); -+ break; -+ -+ case Opt_dio: -+ au_opt_set(sbinfo->si_mntflags, DIO); -+ au_fset_opts(opts->flags, REFRESH_DYAOP); -+ break; -+ case Opt_nodio: -+ au_opt_clr(sbinfo->si_mntflags, DIO); -+ au_fset_opts(opts->flags, REFRESH_DYAOP); -+ break; -+ -+ case Opt_fhsm_sec: -+ au_fhsm_set(sbinfo, opt->fhsm_second); -+ break; -+ -+ case Opt_diropq_a: -+ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ); -+ break; -+ case Opt_diropq_w: -+ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ); -+ break; -+ -+ case Opt_warn_perm: -+ au_opt_set(sbinfo->si_mntflags, WARN_PERM); -+ break; -+ case Opt_nowarn_perm: -+ au_opt_clr(sbinfo->si_mntflags, WARN_PERM); -+ break; -+ -+ case Opt_verbose: -+ au_opt_set(sbinfo->si_mntflags, VERBOSE); -+ break; -+ case Opt_noverbose: -+ au_opt_clr(sbinfo->si_mntflags, VERBOSE); -+ break; -+ -+ case Opt_sum: -+ au_opt_set(sbinfo->si_mntflags, SUM); -+ break; -+ case Opt_wsum: -+ au_opt_clr(sbinfo->si_mntflags, SUM); -+ au_opt_set(sbinfo->si_mntflags, SUM_W); -+ case Opt_nosum: -+ au_opt_clr(sbinfo->si_mntflags, SUM); -+ au_opt_clr(sbinfo->si_mntflags, SUM_W); -+ break; -+ -+ case Opt_wbr_create: -+ err = au_opt_wbr_create(sb, &opt->wbr_create); -+ break; -+ case Opt_wbr_copyup: -+ sbinfo->si_wbr_copyup = opt->wbr_copyup; -+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup; -+ break; -+ -+ case Opt_dirwh: -+ sbinfo->si_dirwh = opt->dirwh; -+ break; -+ -+ case Opt_rdcache: -+ sbinfo->si_rdcache -+ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC); -+ break; -+ case Opt_rdblk: -+ sbinfo->si_rdblk = opt->rdblk; -+ break; -+ case Opt_rdblk_def: -+ sbinfo->si_rdblk = AUFS_RDBLK_DEF; -+ break; -+ case Opt_rdhash: -+ sbinfo->si_rdhash = opt->rdhash; -+ break; -+ case Opt_rdhash_def: -+ sbinfo->si_rdhash = AUFS_RDHASH_DEF; -+ break; -+ -+ case Opt_shwh: -+ au_opt_set(sbinfo->si_mntflags, SHWH); -+ break; -+ case Opt_noshwh: -+ au_opt_clr(sbinfo->si_mntflags, SHWH); -+ break; -+ -+ case Opt_dirperm1: -+ au_opt_set(sbinfo->si_mntflags, DIRPERM1); -+ break; -+ case Opt_nodirperm1: -+ au_opt_clr(sbinfo->si_mntflags, DIRPERM1); -+ break; -+ -+ case Opt_trunc_xino: -+ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO); -+ break; -+ case Opt_notrunc_xino: -+ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO); -+ break; -+ -+ case Opt_trunc_xino_path: -+ case Opt_itrunc_xino: -+ err = au_xino_trunc(sb, opt->xino_itrunc.bindex, -+ /*idx_begin*/0); -+ if (!err) -+ err = 1; -+ break; -+ -+ case Opt_trunc_xib: -+ au_fset_opts(opts->flags, TRUNC_XIB); -+ break; -+ case Opt_notrunc_xib: -+ au_fclr_opts(opts->flags, TRUNC_XIB); -+ break; -+ -+ case Opt_dirren: -+ err = 1; -+ if (!au_opt_test(sbinfo->si_mntflags, DIRREN)) { -+ err = au_dr_opt_set(sb); -+ if (!err) -+ err = 1; -+ } -+ if (err == 1) -+ au_opt_set(sbinfo->si_mntflags, DIRREN); -+ break; -+ case Opt_nodirren: -+ err = 1; -+ if (au_opt_test(sbinfo->si_mntflags, DIRREN)) { -+ err = au_dr_opt_clr(sb, au_ftest_opts(opts->flags, -+ DR_FLUSHED)); -+ if (!err) -+ err = 1; -+ } -+ if (err == 1) -+ au_opt_clr(sbinfo->si_mntflags, DIRREN); -+ break; -+ -+ case Opt_acl: -+ sb->s_flags |= SB_POSIXACL; -+ break; -+ case Opt_noacl: -+ sb->s_flags &= ~SB_POSIXACL; -+ break; -+ -+ default: -+ err = 0; -+ break; -+ } -+ -+ return err; -+} -+ -+/* -+ * returns tri-state. -+ * plus: processed without an error -+ * zero: unprocessed -+ * minus: error -+ */ -+static int au_opt_br(struct super_block *sb, struct au_opt *opt, -+ struct au_opts *opts) -+{ -+ int err, do_refresh; -+ -+ err = 0; -+ switch (opt->type) { -+ case Opt_append: -+ opt->add.bindex = au_sbbot(sb) + 1; -+ if (opt->add.bindex < 0) -+ opt->add.bindex = 0; -+ goto add; -+ case Opt_prepend: -+ opt->add.bindex = 0; -+ add: /* indented label */ -+ case Opt_add: -+ err = au_br_add(sb, &opt->add, -+ au_ftest_opts(opts->flags, REMOUNT)); -+ if (!err) { -+ err = 1; -+ au_fset_opts(opts->flags, REFRESH); -+ } -+ break; -+ -+ case Opt_del: -+ case Opt_idel: -+ err = au_br_del(sb, &opt->del, -+ au_ftest_opts(opts->flags, REMOUNT)); -+ if (!err) { -+ err = 1; -+ au_fset_opts(opts->flags, TRUNC_XIB); -+ au_fset_opts(opts->flags, REFRESH); -+ } -+ break; -+ -+ case Opt_mod: -+ case Opt_imod: -+ err = au_br_mod(sb, &opt->mod, -+ au_ftest_opts(opts->flags, REMOUNT), -+ &do_refresh); -+ if (!err) { -+ err = 1; -+ if (do_refresh) -+ au_fset_opts(opts->flags, REFRESH); -+ } -+ break; -+ } -+ return err; -+} -+ -+static int au_opt_xino(struct super_block *sb, struct au_opt *opt, -+ struct au_opt_xino **opt_xino, -+ struct au_opts *opts) -+{ -+ int err; -+ -+ err = 0; -+ switch (opt->type) { -+ case Opt_xino: -+ err = au_xino_set(sb, &opt->xino, -+ !!au_ftest_opts(opts->flags, REMOUNT)); -+ if (unlikely(err)) -+ break; -+ -+ *opt_xino = &opt->xino; -+ break; -+ -+ case Opt_noxino: -+ au_xino_clr(sb); -+ *opt_xino = (void *)-1; -+ break; -+ } -+ -+ return err; -+} -+ -+int au_opts_verify(struct super_block *sb, unsigned long sb_flags, -+ unsigned int pending) -+{ -+ int err, fhsm; -+ aufs_bindex_t bindex, bbot; -+ unsigned char do_plink, skip, do_free, can_no_dreval; -+ struct au_branch *br; -+ struct au_wbr *wbr; -+ struct dentry *root, *dentry; -+ struct inode *dir, *h_dir; -+ struct au_sbinfo *sbinfo; -+ struct au_hinode *hdir; -+ -+ SiMustAnyLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA)); -+ -+ if (!(sb_flags & SB_RDONLY)) { -+ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0)))) -+ pr_warn("first branch should be rw\n"); -+ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH))) -+ pr_warn_once("shwh should be used with ro\n"); -+ } -+ -+ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY) -+ && !au_opt_test(sbinfo->si_mntflags, XINO)) -+ pr_warn_once("udba=*notify requires xino\n"); -+ -+ if (au_opt_test(sbinfo->si_mntflags, DIRPERM1)) -+ pr_warn_once("dirperm1 breaks the protection" -+ " by the permission bits on the lower branch\n"); -+ -+ err = 0; -+ fhsm = 0; -+ root = sb->s_root; -+ dir = d_inode(root); -+ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK); -+ can_no_dreval = !!au_opt_test((sbinfo->si_mntflags | pending), -+ UDBA_NONE); -+ bbot = au_sbbot(sb); -+ for (bindex = 0; !err && bindex <= bbot; bindex++) { -+ skip = 0; -+ h_dir = au_h_iptr(dir, bindex); -+ br = au_sbr(sb, bindex); -+ -+ if ((br->br_perm & AuBrAttr_ICEX) -+ && !h_dir->i_op->listxattr) -+ br->br_perm &= ~AuBrAttr_ICEX; -+#if 0 -+ if ((br->br_perm & AuBrAttr_ICEX_SEC) -+ && (au_br_sb(br)->s_flags & SB_NOSEC)) -+ br->br_perm &= ~AuBrAttr_ICEX_SEC; -+#endif -+ -+ do_free = 0; -+ wbr = br->br_wbr; -+ if (wbr) -+ wbr_wh_read_lock(wbr); -+ -+ if (!au_br_writable(br->br_perm)) { -+ do_free = !!wbr; -+ skip = (!wbr -+ || (!wbr->wbr_whbase -+ && !wbr->wbr_plink -+ && !wbr->wbr_orph)); -+ } else if (!au_br_wh_linkable(br->br_perm)) { -+ /* skip = (!br->br_whbase && !br->br_orph); */ -+ skip = (!wbr || !wbr->wbr_whbase); -+ if (skip && wbr) { -+ if (do_plink) -+ skip = !!wbr->wbr_plink; -+ else -+ skip = !wbr->wbr_plink; -+ } -+ } else { -+ /* skip = (br->br_whbase && br->br_ohph); */ -+ skip = (wbr && wbr->wbr_whbase); -+ if (skip) { -+ if (do_plink) -+ skip = !!wbr->wbr_plink; -+ else -+ skip = !wbr->wbr_plink; -+ } -+ } -+ if (wbr) -+ wbr_wh_read_unlock(wbr); -+ -+ if (can_no_dreval) { -+ dentry = br->br_path.dentry; -+ spin_lock(&dentry->d_lock); -+ if (dentry->d_flags & -+ (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE)) -+ can_no_dreval = 0; -+ spin_unlock(&dentry->d_lock); -+ } -+ -+ if (au_br_fhsm(br->br_perm)) { -+ fhsm++; -+ AuDebugOn(!br->br_fhsm); -+ } -+ -+ if (skip) -+ continue; -+ -+ hdir = au_hi(dir, bindex); -+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT); -+ if (wbr) -+ wbr_wh_write_lock(wbr); -+ err = au_wh_init(br, sb); -+ if (wbr) -+ wbr_wh_write_unlock(wbr); -+ au_hn_inode_unlock(hdir); -+ -+ if (!err && do_free) { -+ kfree(wbr); -+ br->br_wbr = NULL; -+ } -+ } -+ -+ if (can_no_dreval) -+ au_fset_si(sbinfo, NO_DREVAL); -+ else -+ au_fclr_si(sbinfo, NO_DREVAL); -+ -+ if (fhsm >= 2) { -+ au_fset_si(sbinfo, FHSM); -+ for (bindex = bbot; bindex >= 0; bindex--) { -+ br = au_sbr(sb, bindex); -+ if (au_br_fhsm(br->br_perm)) { -+ au_fhsm_set_bottom(sb, bindex); -+ break; -+ } -+ } -+ } else { -+ au_fclr_si(sbinfo, FHSM); -+ au_fhsm_set_bottom(sb, -1); -+ } -+ -+ return err; -+} -+ -+int au_opts_mount(struct super_block *sb, struct au_opts *opts) -+{ -+ int err; -+ unsigned int tmp; -+ aufs_bindex_t bindex, bbot; -+ struct au_opt *opt; -+ struct au_opt_xino *opt_xino, xino; -+ struct au_sbinfo *sbinfo; -+ struct au_branch *br; -+ struct inode *dir; -+ -+ SiMustWriteLock(sb); -+ -+ err = 0; -+ opt_xino = NULL; -+ opt = opts->opt; -+ while (err >= 0 && opt->type != Opt_tail) -+ err = au_opt_simple(sb, opt++, opts); -+ if (err > 0) -+ err = 0; -+ else if (unlikely(err < 0)) -+ goto out; -+ -+ /* disable xino and udba temporary */ -+ sbinfo = au_sbi(sb); -+ tmp = sbinfo->si_mntflags; -+ au_opt_clr(sbinfo->si_mntflags, XINO); -+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL); -+ -+ opt = opts->opt; -+ while (err >= 0 && opt->type != Opt_tail) -+ err = au_opt_br(sb, opt++, opts); -+ if (err > 0) -+ err = 0; -+ else if (unlikely(err < 0)) -+ goto out; -+ -+ bbot = au_sbbot(sb); -+ if (unlikely(bbot < 0)) { -+ err = -EINVAL; -+ pr_err("no branches\n"); -+ goto out; -+ } -+ -+ if (au_opt_test(tmp, XINO)) -+ au_opt_set(sbinfo->si_mntflags, XINO); -+ opt = opts->opt; -+ while (!err && opt->type != Opt_tail) -+ err = au_opt_xino(sb, opt++, &opt_xino, opts); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_opts_verify(sb, sb->s_flags, tmp); -+ if (unlikely(err)) -+ goto out; -+ -+ /* restore xino */ -+ if (au_opt_test(tmp, XINO) && !opt_xino) { -+ xino.file = au_xino_def(sb); -+ err = PTR_ERR(xino.file); -+ if (IS_ERR(xino.file)) -+ goto out; -+ -+ err = au_xino_set(sb, &xino, /*remount*/0); -+ fput(xino.file); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ /* restore udba */ -+ tmp &= AuOptMask_UDBA; -+ sbinfo->si_mntflags &= ~AuOptMask_UDBA; -+ sbinfo->si_mntflags |= tmp; -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ err = au_hnotify_reset_br(tmp, br, br->br_perm); -+ if (unlikely(err)) -+ AuIOErr("hnotify failed on br %d, %d, ignored\n", -+ bindex, err); -+ /* go on even if err */ -+ } -+ if (au_opt_test(tmp, UDBA_HNOTIFY)) { -+ dir = d_inode(sb->s_root); -+ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO); -+ } -+ -+out: -+ return err; -+} -+ -+int au_opts_remount(struct super_block *sb, struct au_opts *opts) -+{ -+ int err, rerr; -+ unsigned char no_dreval; -+ struct inode *dir; -+ struct au_opt_xino *opt_xino; -+ struct au_opt *opt; -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ err = au_dr_opt_flush(sb); -+ if (unlikely(err)) -+ goto out; -+ au_fset_opts(opts->flags, DR_FLUSHED); -+ -+ dir = d_inode(sb->s_root); -+ sbinfo = au_sbi(sb); -+ opt_xino = NULL; -+ opt = opts->opt; -+ while (err >= 0 && opt->type != Opt_tail) { -+ err = au_opt_simple(sb, opt, opts); -+ if (!err) -+ err = au_opt_br(sb, opt, opts); -+ if (!err) -+ err = au_opt_xino(sb, opt, &opt_xino, opts); -+ opt++; -+ } -+ if (err > 0) -+ err = 0; -+ AuTraceErr(err); -+ /* go on even err */ -+ -+ no_dreval = !!au_ftest_si(sbinfo, NO_DREVAL); -+ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0); -+ if (unlikely(rerr && !err)) -+ err = rerr; -+ -+ if (no_dreval != !!au_ftest_si(sbinfo, NO_DREVAL)) -+ au_fset_opts(opts->flags, REFRESH_IDOP); -+ -+ if (au_ftest_opts(opts->flags, TRUNC_XIB)) { -+ rerr = au_xib_trunc(sb); -+ if (unlikely(rerr && !err)) -+ err = rerr; -+ } -+ -+ /* will be handled by the caller */ -+ if (!au_ftest_opts(opts->flags, REFRESH) -+ && (opts->given_udba -+ || au_opt_test(sbinfo->si_mntflags, XINO) -+ || au_ftest_opts(opts->flags, REFRESH_IDOP) -+ )) -+ au_fset_opts(opts->flags, REFRESH); -+ -+ AuDbg("status 0x%x\n", opts->flags); -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+unsigned int au_opt_udba(struct super_block *sb) -+{ -+ return au_mntflags(sb) & AuOptMask_UDBA; -+} -diff --git a/fs/aufs/opts.h b/fs/aufs/opts.h -new file mode 100644 -index 000000000..fd167bd0f ---- /dev/null -+++ b/fs/aufs/opts.h -@@ -0,0 +1,225 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * mount options/flags -+ */ -+ -+#ifndef __AUFS_OPTS_H__ -+#define __AUFS_OPTS_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+struct file; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* mount flags */ -+#define AuOpt_XINO 1 /* external inode number bitmap -+ and translation table */ -+#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */ -+#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */ -+#define AuOpt_UDBA_REVAL (1 << 3) -+#define AuOpt_UDBA_HNOTIFY (1 << 4) -+#define AuOpt_SHWH (1 << 5) /* show whiteout */ -+#define AuOpt_PLINK (1 << 6) /* pseudo-link */ -+#define AuOpt_DIRPERM1 (1 << 7) /* ignore the lower dir's perm -+ bits */ -+#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */ -+#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */ -+#define AuOpt_SUM_W (1 << 11) /* unimplemented */ -+#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */ -+#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */ -+#define AuOpt_DIO (1 << 14) /* direct io */ -+#define AuOpt_DIRREN (1 << 15) /* directory rename */ -+ -+#ifndef CONFIG_AUFS_HNOTIFY -+#undef AuOpt_UDBA_HNOTIFY -+#define AuOpt_UDBA_HNOTIFY 0 -+#endif -+#ifndef CONFIG_AUFS_DIRREN -+#undef AuOpt_DIRREN -+#define AuOpt_DIRREN 0 -+#endif -+#ifndef CONFIG_AUFS_SHWH -+#undef AuOpt_SHWH -+#define AuOpt_SHWH 0 -+#endif -+ -+#define AuOpt_Def (AuOpt_XINO \ -+ | AuOpt_UDBA_REVAL \ -+ | AuOpt_PLINK \ -+ /* | AuOpt_DIRPERM1 */ \ -+ | AuOpt_WARN_PERM) -+#define AuOptMask_UDBA (AuOpt_UDBA_NONE \ -+ | AuOpt_UDBA_REVAL \ -+ | AuOpt_UDBA_HNOTIFY) -+ -+#define au_opt_test(flags, name) (flags & AuOpt_##name) -+#define au_opt_set(flags, name) do { \ -+ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \ -+ ((flags) |= AuOpt_##name); \ -+} while (0) -+#define au_opt_set_udba(flags, name) do { \ -+ (flags) &= ~AuOptMask_UDBA; \ -+ ((flags) |= AuOpt_##name); \ -+} while (0) -+#define au_opt_clr(flags, name) do { \ -+ ((flags) &= ~AuOpt_##name); \ -+} while (0) -+ -+static inline unsigned int au_opts_plink(unsigned int mntflags) -+{ -+#ifdef CONFIG_PROC_FS -+ return mntflags; -+#else -+ return mntflags & ~AuOpt_PLINK; -+#endif -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* policies to select one among multiple writable branches */ -+enum { -+ AuWbrCreate_TDP, /* top down parent */ -+ AuWbrCreate_RR, /* round robin */ -+ AuWbrCreate_MFS, /* most free space */ -+ AuWbrCreate_MFSV, /* mfs with seconds */ -+ AuWbrCreate_MFSRR, /* mfs then rr */ -+ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */ -+ AuWbrCreate_TDMFS, /* top down regardless parent and mfs */ -+ AuWbrCreate_TDMFSV, /* top down regardless parent and mfs */ -+ AuWbrCreate_PMFS, /* parent and mfs */ -+ AuWbrCreate_PMFSV, /* parent and mfs with seconds */ -+ AuWbrCreate_PMFSRR, /* parent, mfs and round-robin */ -+ AuWbrCreate_PMFSRRV, /* plus seconds */ -+ -+ AuWbrCreate_Def = AuWbrCreate_TDP -+}; -+ -+enum { -+ AuWbrCopyup_TDP, /* top down parent */ -+ AuWbrCopyup_BUP, /* bottom up parent */ -+ AuWbrCopyup_BU, /* bottom up */ -+ -+ AuWbrCopyup_Def = AuWbrCopyup_TDP -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_opt_add { -+ aufs_bindex_t bindex; -+ char *pathname; -+ int perm; -+ struct path path; -+}; -+ -+struct au_opt_del { -+ char *pathname; -+ struct path h_path; -+}; -+ -+struct au_opt_mod { -+ char *path; -+ int perm; -+ struct dentry *h_root; -+}; -+ -+struct au_opt_xino { -+ char *path; -+ struct file *file; -+}; -+ -+struct au_opt_xino_itrunc { -+ aufs_bindex_t bindex; -+}; -+ -+struct au_opt_wbr_create { -+ int wbr_create; -+ int mfs_second; -+ unsigned long long mfsrr_watermark; -+}; -+ -+struct au_opt { -+ int type; -+ union { -+ struct au_opt_xino xino; -+ struct au_opt_xino_itrunc xino_itrunc; -+ struct au_opt_add add; -+ struct au_opt_del del; -+ struct au_opt_mod mod; -+ int dirwh; -+ int rdcache; -+ unsigned int rdblk; -+ unsigned int rdhash; -+ int udba; -+ struct au_opt_wbr_create wbr_create; -+ int wbr_copyup; -+ unsigned int fhsm_second; -+ }; -+}; -+ -+/* opts flags */ -+#define AuOpts_REMOUNT 1 -+#define AuOpts_REFRESH (1 << 1) -+#define AuOpts_TRUNC_XIB (1 << 2) -+#define AuOpts_REFRESH_DYAOP (1 << 3) -+#define AuOpts_REFRESH_IDOP (1 << 4) -+#define AuOpts_DR_FLUSHED (1 << 5) -+#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name) -+#define au_fset_opts(flags, name) \ -+ do { (flags) |= AuOpts_##name; } while (0) -+#define au_fclr_opts(flags, name) \ -+ do { (flags) &= ~AuOpts_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_DIRREN -+#undef AuOpts_DR_FLUSHED -+#define AuOpts_DR_FLUSHED 0 -+#endif -+ -+struct au_opts { -+ struct au_opt *opt; -+ int max_opt; -+ -+ unsigned int given_udba; -+ unsigned int flags; -+ unsigned long sb_flags; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* opts.c */ -+void au_optstr_br_perm(au_br_perm_str_t *str, int perm); -+const char *au_optstr_udba(int udba); -+const char *au_optstr_wbr_copyup(int wbr_copyup); -+const char *au_optstr_wbr_create(int wbr_create); -+ -+void au_opts_free(struct au_opts *opts); -+struct super_block; -+int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts); -+int au_opts_verify(struct super_block *sb, unsigned long sb_flags, -+ unsigned int pending); -+int au_opts_mount(struct super_block *sb, struct au_opts *opts); -+int au_opts_remount(struct super_block *sb, struct au_opts *opts); -+ -+unsigned int au_opt_udba(struct super_block *sb); -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_OPTS_H__ */ -diff --git a/fs/aufs/plink.c b/fs/aufs/plink.c -new file mode 100644 -index 000000000..83b80ede3 ---- /dev/null -+++ b/fs/aufs/plink.c -@@ -0,0 +1,516 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * pseudo-link -+ */ -+ -+#include "aufs.h" -+ -+/* -+ * the pseudo-link maintenance mode. -+ * during a user process maintains the pseudo-links, -+ * prohibit adding a new plink and branch manipulation. -+ * -+ * Flags -+ * NOPLM: -+ * For entry functions which will handle plink, and i_mutex is already held -+ * in VFS. -+ * They cannot wait and should return an error at once. -+ * Callers has to check the error. -+ * NOPLMW: -+ * For entry functions which will handle plink, but i_mutex is not held -+ * in VFS. -+ * They can wait the plink maintenance mode to finish. -+ * -+ * They behave like F_SETLK and F_SETLKW. -+ * If the caller never handle plink, then both flags are unnecessary. -+ */ -+ -+int au_plink_maint(struct super_block *sb, int flags) -+{ -+ int err; -+ pid_t pid, ppid; -+ struct task_struct *parent, *prev; -+ struct au_sbinfo *sbi; -+ -+ SiMustAnyLock(sb); -+ -+ err = 0; -+ if (!au_opt_test(au_mntflags(sb), PLINK)) -+ goto out; -+ -+ sbi = au_sbi(sb); -+ pid = sbi->si_plink_maint_pid; -+ if (!pid || pid == current->pid) -+ goto out; -+ -+ /* todo: it highly depends upon /sbin/mount.aufs */ -+ prev = NULL; -+ parent = current; -+ ppid = 0; -+ rcu_read_lock(); -+ while (1) { -+ parent = rcu_dereference(parent->real_parent); -+ if (parent == prev) -+ break; -+ ppid = task_pid_vnr(parent); -+ if (pid == ppid) { -+ rcu_read_unlock(); -+ goto out; -+ } -+ prev = parent; -+ } -+ rcu_read_unlock(); -+ -+ if (au_ftest_lock(flags, NOPLMW)) { -+ /* if there is no i_mutex lock in VFS, we don't need to wait */ -+ /* AuDebugOn(!lockdep_depth(current)); */ -+ while (sbi->si_plink_maint_pid) { -+ si_read_unlock(sb); -+ /* gave up wake_up_bit() */ -+ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid); -+ -+ if (au_ftest_lock(flags, FLUSH)) -+ au_nwt_flush(&sbi->si_nowait); -+ si_noflush_read_lock(sb); -+ } -+ } else if (au_ftest_lock(flags, NOPLM)) { -+ AuDbg("ppid %d, pid %d\n", ppid, pid); -+ err = -EAGAIN; -+ } -+ -+out: -+ return err; -+} -+ -+void au_plink_maint_leave(struct au_sbinfo *sbinfo) -+{ -+ spin_lock(&sbinfo->si_plink_maint_lock); -+ sbinfo->si_plink_maint_pid = 0; -+ spin_unlock(&sbinfo->si_plink_maint_lock); -+ wake_up_all(&sbinfo->si_plink_wq); -+} -+ -+int au_plink_maint_enter(struct super_block *sb) -+{ -+ int err; -+ struct au_sbinfo *sbinfo; -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ /* make sure i am the only one in this fs */ -+ si_write_lock(sb, AuLock_FLUSH); -+ if (au_opt_test(au_mntflags(sb), PLINK)) { -+ spin_lock(&sbinfo->si_plink_maint_lock); -+ if (!sbinfo->si_plink_maint_pid) -+ sbinfo->si_plink_maint_pid = current->pid; -+ else -+ err = -EBUSY; -+ spin_unlock(&sbinfo->si_plink_maint_lock); -+ } -+ si_write_unlock(sb); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_DEBUG -+void au_plink_list(struct super_block *sb) -+{ -+ int i; -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ struct au_icntnr *icntnr; -+ -+ SiMustAnyLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); -+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM)); -+ -+ for (i = 0; i < AuPlink_NHASH; i++) { -+ hbl = sbinfo->si_plink + i; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink) -+ AuDbg("%lu\n", icntnr->vfs_inode.i_ino); -+ hlist_bl_unlock(hbl); -+ } -+} -+#endif -+ -+/* is the inode pseudo-linked? */ -+int au_plink_test(struct inode *inode) -+{ -+ int found, i; -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ struct au_icntnr *icntnr; -+ -+ sbinfo = au_sbi(inode->i_sb); -+ AuRwMustAnyLock(&sbinfo->si_rwsem); -+ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK)); -+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM)); -+ -+ found = 0; -+ i = au_plink_hash(inode->i_ino); -+ hbl = sbinfo->si_plink + i; -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink) -+ if (&icntnr->vfs_inode == inode) { -+ found = 1; -+ break; -+ } -+ hlist_bl_unlock(hbl); -+ return found; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * generate a name for plink. -+ * the file will be stored under AUFS_WH_PLINKDIR. -+ */ -+/* 20 is max digits length of ulong 64 */ -+#define PLINK_NAME_LEN ((20 + 1) * 2) -+ -+static int plink_name(char *name, int len, struct inode *inode, -+ aufs_bindex_t bindex) -+{ -+ int rlen; -+ struct inode *h_inode; -+ -+ h_inode = au_h_iptr(inode, bindex); -+ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino); -+ return rlen; -+} -+ -+struct au_do_plink_lkup_args { -+ struct dentry **errp; -+ struct qstr *tgtname; -+ struct dentry *h_parent; -+ struct au_branch *br; -+}; -+ -+static struct dentry *au_do_plink_lkup(struct qstr *tgtname, -+ struct dentry *h_parent, -+ struct au_branch *br) -+{ -+ struct dentry *h_dentry; -+ struct inode *h_inode; -+ -+ h_inode = d_inode(h_parent); -+ inode_lock_shared_nested(h_inode, AuLsc_I_CHILD2); -+ h_dentry = vfsub_lkup_one(tgtname, h_parent); -+ inode_unlock_shared(h_inode); -+ return h_dentry; -+} -+ -+static void au_call_do_plink_lkup(void *args) -+{ -+ struct au_do_plink_lkup_args *a = args; -+ *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br); -+} -+ -+/* lookup the plink-ed @inode under the branch at @bindex */ -+struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex) -+{ -+ struct dentry *h_dentry, *h_parent; -+ struct au_branch *br; -+ int wkq_err; -+ char a[PLINK_NAME_LEN]; -+ struct qstr tgtname = QSTR_INIT(a, 0); -+ -+ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM)); -+ -+ br = au_sbr(inode->i_sb, bindex); -+ h_parent = br->br_wbr->wbr_plink; -+ tgtname.len = plink_name(a, sizeof(a), inode, bindex); -+ -+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) { -+ struct au_do_plink_lkup_args args = { -+ .errp = &h_dentry, -+ .tgtname = &tgtname, -+ .h_parent = h_parent, -+ .br = br -+ }; -+ -+ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args); -+ if (unlikely(wkq_err)) -+ h_dentry = ERR_PTR(wkq_err); -+ } else -+ h_dentry = au_do_plink_lkup(&tgtname, h_parent, br); -+ -+ return h_dentry; -+} -+ -+/* create a pseudo-link */ -+static int do_whplink(struct qstr *tgt, struct dentry *h_parent, -+ struct dentry *h_dentry, struct au_branch *br) -+{ -+ int err; -+ struct path h_path = { -+ .mnt = au_br_mnt(br) -+ }; -+ struct inode *h_dir, *delegated; -+ -+ h_dir = d_inode(h_parent); -+ inode_lock_nested(h_dir, AuLsc_I_CHILD2); -+again: -+ h_path.dentry = vfsub_lkup_one(tgt, h_parent); -+ err = PTR_ERR(h_path.dentry); -+ if (IS_ERR(h_path.dentry)) -+ goto out; -+ -+ err = 0; -+ /* wh.plink dir is not monitored */ -+ /* todo: is it really safe? */ -+ if (d_is_positive(h_path.dentry) -+ && d_inode(h_path.dentry) != d_inode(h_dentry)) { -+ delegated = NULL; -+ err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ dput(h_path.dentry); -+ h_path.dentry = NULL; -+ if (!err) -+ goto again; -+ } -+ if (!err && d_is_negative(h_path.dentry)) { -+ delegated = NULL; -+ err = vfsub_link(h_dentry, h_dir, &h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ } -+ dput(h_path.dentry); -+ -+out: -+ inode_unlock(h_dir); -+ return err; -+} -+ -+struct do_whplink_args { -+ int *errp; -+ struct qstr *tgt; -+ struct dentry *h_parent; -+ struct dentry *h_dentry; -+ struct au_branch *br; -+}; -+ -+static void call_do_whplink(void *args) -+{ -+ struct do_whplink_args *a = args; -+ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br); -+} -+ -+static int whplink(struct dentry *h_dentry, struct inode *inode, -+ aufs_bindex_t bindex, struct au_branch *br) -+{ -+ int err, wkq_err; -+ struct au_wbr *wbr; -+ struct dentry *h_parent; -+ char a[PLINK_NAME_LEN]; -+ struct qstr tgtname = QSTR_INIT(a, 0); -+ -+ wbr = au_sbr(inode->i_sb, bindex)->br_wbr; -+ h_parent = wbr->wbr_plink; -+ tgtname.len = plink_name(a, sizeof(a), inode, bindex); -+ -+ /* always superio. */ -+ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) { -+ struct do_whplink_args args = { -+ .errp = &err, -+ .tgt = &tgtname, -+ .h_parent = h_parent, -+ .h_dentry = h_dentry, -+ .br = br -+ }; -+ wkq_err = au_wkq_wait(call_do_whplink, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } else -+ err = do_whplink(&tgtname, h_parent, h_dentry, br); -+ -+ return err; -+} -+ -+/* -+ * create a new pseudo-link for @h_dentry on @bindex. -+ * the linked inode is held in aufs @inode. -+ */ -+void au_plink_append(struct inode *inode, aufs_bindex_t bindex, -+ struct dentry *h_dentry) -+{ -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos; -+ struct au_icntnr *icntnr; -+ int found, err, cnt, i; -+ -+ sb = inode->i_sb; -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); -+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM)); -+ -+ found = au_plink_test(inode); -+ if (found) -+ return; -+ -+ i = au_plink_hash(inode->i_ino); -+ hbl = sbinfo->si_plink + i; -+ au_igrab(inode); -+ -+ hlist_bl_lock(hbl); -+ hlist_bl_for_each_entry(icntnr, pos, hbl, plink) { -+ if (&icntnr->vfs_inode == inode) { -+ found = 1; -+ break; -+ } -+ } -+ if (!found) { -+ icntnr = container_of(inode, struct au_icntnr, vfs_inode); -+ hlist_bl_add_head(&icntnr->plink, hbl); -+ } -+ hlist_bl_unlock(hbl); -+ if (!found) { -+ cnt = au_hbl_count(hbl); -+#define msg "unexpectedly unbalanced or too many pseudo-links" -+ if (cnt > AUFS_PLINK_WARN) -+ AuWarn1(msg ", %d\n", cnt); -+#undef msg -+ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex)); -+ if (unlikely(err)) { -+ pr_warn("err %d, damaged pseudo link.\n", err); -+ au_hbl_del(&icntnr->plink, hbl); -+ iput(&icntnr->vfs_inode); -+ } -+ } else -+ iput(&icntnr->vfs_inode); -+} -+ -+/* free all plinks */ -+void au_plink_put(struct super_block *sb, int verbose) -+{ -+ int i, warned; -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos, *tmp; -+ struct au_icntnr *icntnr; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); -+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM)); -+ -+ /* no spin_lock since sbinfo is write-locked */ -+ warned = 0; -+ for (i = 0; i < AuPlink_NHASH; i++) { -+ hbl = sbinfo->si_plink + i; -+ if (!warned && verbose && !hlist_bl_empty(hbl)) { -+ pr_warn("pseudo-link is not flushed"); -+ warned = 1; -+ } -+ hlist_bl_for_each_entry_safe(icntnr, pos, tmp, hbl, plink) -+ iput(&icntnr->vfs_inode); -+ INIT_HLIST_BL_HEAD(hbl); -+ } -+} -+ -+void au_plink_clean(struct super_block *sb, int verbose) -+{ -+ struct dentry *root; -+ -+ root = sb->s_root; -+ aufs_write_lock(root); -+ if (au_opt_test(au_mntflags(sb), PLINK)) -+ au_plink_put(sb, verbose); -+ aufs_write_unlock(root); -+} -+ -+static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id) -+{ -+ int do_put; -+ aufs_bindex_t btop, bbot, bindex; -+ -+ do_put = 0; -+ btop = au_ibtop(inode); -+ bbot = au_ibbot(inode); -+ if (btop >= 0) { -+ for (bindex = btop; bindex <= bbot; bindex++) { -+ if (!au_h_iptr(inode, bindex) -+ || au_ii_br_id(inode, bindex) != br_id) -+ continue; -+ au_set_h_iptr(inode, bindex, NULL, 0); -+ do_put = 1; -+ break; -+ } -+ if (do_put) -+ for (bindex = btop; bindex <= bbot; bindex++) -+ if (au_h_iptr(inode, bindex)) { -+ do_put = 0; -+ break; -+ } -+ } else -+ do_put = 1; -+ -+ return do_put; -+} -+ -+/* free the plinks on a branch specified by @br_id */ -+void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id) -+{ -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_head *hbl; -+ struct hlist_bl_node *pos, *tmp; -+ struct au_icntnr *icntnr; -+ struct inode *inode; -+ int i, do_put; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); -+ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM)); -+ -+ /* no bit_lock since sbinfo is write-locked */ -+ for (i = 0; i < AuPlink_NHASH; i++) { -+ hbl = sbinfo->si_plink + i; -+ hlist_bl_for_each_entry_safe(icntnr, pos, tmp, hbl, plink) { -+ inode = au_igrab(&icntnr->vfs_inode); -+ ii_write_lock_child(inode); -+ do_put = au_plink_do_half_refresh(inode, br_id); -+ if (do_put) { -+ hlist_bl_del(&icntnr->plink); -+ iput(inode); -+ } -+ ii_write_unlock(inode); -+ iput(inode); -+ } -+ } -+} -diff --git a/fs/aufs/poll.c b/fs/aufs/poll.c -new file mode 100644 -index 000000000..a653b6c74 ---- /dev/null -+++ b/fs/aufs/poll.c -@@ -0,0 +1,51 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * poll operation -+ * There is only one filesystem which implements ->poll operation, currently. -+ */ -+ -+#include "aufs.h" -+ -+__poll_t aufs_poll(struct file *file, struct poll_table_struct *pt) -+{ -+ __poll_t mask; -+ struct file *h_file; -+ struct super_block *sb; -+ -+ /* We should pretend an error happened. */ -+ mask = EPOLLERR /* | EPOLLIN | EPOLLOUT */; -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); -+ -+ h_file = au_read_pre(file, /*keep_fi*/0, /*lsc*/0); -+ if (IS_ERR(h_file)) { -+ AuDbg("h_file %ld\n", PTR_ERR(h_file)); -+ goto out; -+ } -+ -+ mask = vfs_poll(h_file, pt); -+ fput(h_file); /* instead of au_read_post() */ -+ -+out: -+ si_read_unlock(sb); -+ if (mask & EPOLLERR) -+ AuDbg("mask 0x%x\n", mask); -+ return mask; -+} -diff --git a/fs/aufs/posix_acl.c b/fs/aufs/posix_acl.c -new file mode 100644 -index 000000000..9ce21ec98 ---- /dev/null -+++ b/fs/aufs/posix_acl.c -@@ -0,0 +1,103 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2014-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * posix acl operations -+ */ -+ -+#include -+#include "aufs.h" -+ -+struct posix_acl *aufs_get_acl(struct inode *inode, int type) -+{ -+ struct posix_acl *acl; -+ int err; -+ aufs_bindex_t bindex; -+ struct inode *h_inode; -+ struct super_block *sb; -+ -+ acl = NULL; -+ sb = inode->i_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ ii_read_lock_child(inode); -+ if (!(sb->s_flags & SB_POSIXACL)) -+ goto out; -+ -+ bindex = au_ibtop(inode); -+ h_inode = au_h_iptr(inode, bindex); -+ if (unlikely(!h_inode -+ || ((h_inode->i_mode & S_IFMT) -+ != (inode->i_mode & S_IFMT)))) { -+ err = au_busy_or_stale(); -+ acl = ERR_PTR(err); -+ goto out; -+ } -+ -+ /* always topmost only */ -+ acl = get_acl(h_inode, type); -+ if (!IS_ERR_OR_NULL(acl)) -+ set_cached_acl(inode, type, acl); -+ -+out: -+ ii_read_unlock(inode); -+ si_read_unlock(sb); -+ -+ AuTraceErrPtr(acl); -+ return acl; -+} -+ -+int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type) -+{ -+ int err; -+ ssize_t ssz; -+ struct dentry *dentry; -+ struct au_sxattr arg = { -+ .type = AU_ACL_SET, -+ .u.acl_set = { -+ .acl = acl, -+ .type = type -+ }, -+ }; -+ -+ IMustLock(inode); -+ -+ if (inode->i_ino == AUFS_ROOT_INO) -+ dentry = dget(inode->i_sb->s_root); -+ else { -+ dentry = d_find_alias(inode); -+ if (!dentry) -+ dentry = d_find_any_alias(inode); -+ if (!dentry) { -+ pr_warn("cannot handle this inode, " -+ "please report to aufs-users ML\n"); -+ err = -ENOENT; -+ goto out; -+ } -+ } -+ -+ ssz = au_sxattr(dentry, inode, &arg); -+ dput(dentry); -+ err = ssz; -+ if (ssz >= 0) { -+ err = 0; -+ set_cached_acl(inode, type, acl); -+ } -+ -+out: -+ return err; -+} -diff --git a/fs/aufs/procfs.c b/fs/aufs/procfs.c -new file mode 100644 -index 000000000..100dbcfeb ---- /dev/null -+++ b/fs/aufs/procfs.c -@@ -0,0 +1,171 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2010-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * procfs interfaces -+ */ -+ -+#include -+#include "aufs.h" -+ -+static int au_procfs_plm_release(struct inode *inode, struct file *file) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ sbinfo = file->private_data; -+ if (sbinfo) { -+ au_plink_maint_leave(sbinfo); -+ kobject_put(&sbinfo->si_kobj); -+ } -+ -+ return 0; -+} -+ -+static void au_procfs_plm_write_clean(struct file *file) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ sbinfo = file->private_data; -+ if (sbinfo) -+ au_plink_clean(sbinfo->si_sb, /*verbose*/0); -+} -+ -+static int au_procfs_plm_write_si(struct file *file, unsigned long id) -+{ -+ int err; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_node *pos; -+ -+ err = -EBUSY; -+ if (unlikely(file->private_data)) -+ goto out; -+ -+ sb = NULL; -+ /* don't use au_sbilist_lock() here */ -+ hlist_bl_lock(&au_sbilist); -+ hlist_bl_for_each_entry(sbinfo, pos, &au_sbilist, si_list) -+ if (id == sysaufs_si_id(sbinfo)) { -+ kobject_get(&sbinfo->si_kobj); -+ sb = sbinfo->si_sb; -+ break; -+ } -+ hlist_bl_unlock(&au_sbilist); -+ -+ err = -EINVAL; -+ if (unlikely(!sb)) -+ goto out; -+ -+ err = au_plink_maint_enter(sb); -+ if (!err) -+ /* keep kobject_get() */ -+ file->private_data = sbinfo; -+ else -+ kobject_put(&sbinfo->si_kobj); -+out: -+ return err; -+} -+ -+/* -+ * Accept a valid "si=xxxx" only. -+ * Once it is accepted successfully, accept "clean" too. -+ */ -+static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf, -+ size_t count, loff_t *ppos) -+{ -+ ssize_t err; -+ unsigned long id; -+ /* last newline is allowed */ -+ char buf[3 + sizeof(unsigned long) * 2 + 1]; -+ -+ err = -EACCES; -+ if (unlikely(!capable(CAP_SYS_ADMIN))) -+ goto out; -+ -+ err = -EINVAL; -+ if (unlikely(count > sizeof(buf))) -+ goto out; -+ -+ err = copy_from_user(buf, ubuf, count); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ goto out; -+ } -+ buf[count] = 0; -+ -+ err = -EINVAL; -+ if (!strcmp("clean", buf)) { -+ au_procfs_plm_write_clean(file); -+ goto out_success; -+ } else if (unlikely(strncmp("si=", buf, 3))) -+ goto out; -+ -+ err = kstrtoul(buf + 3, 16, &id); -+ if (unlikely(err)) -+ goto out; -+ -+ err = au_procfs_plm_write_si(file, id); -+ if (unlikely(err)) -+ goto out; -+ -+out_success: -+ err = count; /* success */ -+out: -+ return err; -+} -+ -+static const struct file_operations au_procfs_plm_fop = { -+ .write = au_procfs_plm_write, -+ .release = au_procfs_plm_release, -+ .owner = THIS_MODULE -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct proc_dir_entry *au_procfs_dir; -+ -+void au_procfs_fin(void) -+{ -+ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir); -+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL); -+} -+ -+int __init au_procfs_init(void) -+{ -+ int err; -+ struct proc_dir_entry *entry; -+ -+ err = -ENOMEM; -+ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL); -+ if (unlikely(!au_procfs_dir)) -+ goto out; -+ -+ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | 0200, -+ au_procfs_dir, &au_procfs_plm_fop); -+ if (unlikely(!entry)) -+ goto out_dir; -+ -+ err = 0; -+ goto out; /* success */ -+ -+ -+out_dir: -+ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL); -+out: -+ return err; -+} -diff --git a/fs/aufs/rdu.c b/fs/aufs/rdu.c -new file mode 100644 -index 000000000..60f4957b7 ---- /dev/null -+++ b/fs/aufs/rdu.c -@@ -0,0 +1,382 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * readdir in userspace. -+ */ -+ -+#include -+#include -+#include -+#include "aufs.h" -+ -+/* bits for struct aufs_rdu.flags */ -+#define AuRdu_CALLED 1 -+#define AuRdu_CONT (1 << 1) -+#define AuRdu_FULL (1 << 2) -+#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name) -+#define au_fset_rdu(flags, name) \ -+ do { (flags) |= AuRdu_##name; } while (0) -+#define au_fclr_rdu(flags, name) \ -+ do { (flags) &= ~AuRdu_##name; } while (0) -+ -+struct au_rdu_arg { -+ struct dir_context ctx; -+ struct aufs_rdu *rdu; -+ union au_rdu_ent_ul ent; -+ unsigned long end; -+ -+ struct super_block *sb; -+ int err; -+}; -+ -+static int au_rdu_fill(struct dir_context *ctx, const char *name, int nlen, -+ loff_t offset, u64 h_ino, unsigned int d_type) -+{ -+ int err, len; -+ struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx); -+ struct aufs_rdu *rdu = arg->rdu; -+ struct au_rdu_ent ent; -+ -+ err = 0; -+ arg->err = 0; -+ au_fset_rdu(rdu->cookie.flags, CALLED); -+ len = au_rdu_len(nlen); -+ if (arg->ent.ul + len < arg->end) { -+ ent.ino = h_ino; -+ ent.bindex = rdu->cookie.bindex; -+ ent.type = d_type; -+ ent.nlen = nlen; -+ if (unlikely(nlen > AUFS_MAX_NAMELEN)) -+ ent.type = DT_UNKNOWN; -+ -+ /* unnecessary to support mmap_sem since this is a dir */ -+ err = -EFAULT; -+ if (copy_to_user(arg->ent.e, &ent, sizeof(ent))) -+ goto out; -+ if (copy_to_user(arg->ent.e->name, name, nlen)) -+ goto out; -+ /* the terminating NULL */ -+ if (__put_user(0, arg->ent.e->name + nlen)) -+ goto out; -+ err = 0; -+ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */ -+ arg->ent.ul += len; -+ rdu->rent++; -+ } else { -+ err = -EFAULT; -+ au_fset_rdu(rdu->cookie.flags, FULL); -+ rdu->full = 1; -+ rdu->tail = arg->ent; -+ } -+ -+out: -+ /* AuTraceErr(err); */ -+ return err; -+} -+ -+static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg) -+{ -+ int err; -+ loff_t offset; -+ struct au_rdu_cookie *cookie = &arg->rdu->cookie; -+ -+ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */ -+ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET); -+ err = offset; -+ if (unlikely(offset != cookie->h_pos)) -+ goto out; -+ -+ err = 0; -+ do { -+ arg->err = 0; -+ au_fclr_rdu(cookie->flags, CALLED); -+ /* smp_mb(); */ -+ err = vfsub_iterate_dir(h_file, &arg->ctx); -+ if (err >= 0) -+ err = arg->err; -+ } while (!err -+ && au_ftest_rdu(cookie->flags, CALLED) -+ && !au_ftest_rdu(cookie->flags, FULL)); -+ cookie->h_pos = h_file->f_pos; -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_rdu(struct file *file, struct aufs_rdu *rdu) -+{ -+ int err; -+ aufs_bindex_t bbot; -+ struct au_rdu_arg arg = { -+ .ctx = { -+ .actor = au_rdu_fill -+ } -+ }; -+ struct dentry *dentry; -+ struct inode *inode; -+ struct file *h_file; -+ struct au_rdu_cookie *cookie = &rdu->cookie; -+ -+ err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ goto out; -+ } -+ rdu->rent = 0; -+ rdu->tail = rdu->ent; -+ rdu->full = 0; -+ arg.rdu = rdu; -+ arg.ent = rdu->ent; -+ arg.end = arg.ent.ul; -+ arg.end += rdu->sz; -+ -+ err = -ENOTDIR; -+ if (unlikely(!file->f_op->iterate && !file->f_op->iterate_shared)) -+ goto out; -+ -+ err = security_file_permission(file, MAY_READ); -+ AuTraceErr(err); -+ if (unlikely(err)) -+ goto out; -+ -+ dentry = file->f_path.dentry; -+ inode = d_inode(dentry); -+ inode_lock_shared(inode); -+ -+ arg.sb = inode->i_sb; -+ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out_mtx; -+ err = au_alive_dir(dentry); -+ if (unlikely(err)) -+ goto out_si; -+ /* todo: reval? */ -+ fi_read_lock(file); -+ -+ err = -EAGAIN; -+ if (unlikely(au_ftest_rdu(cookie->flags, CONT) -+ && cookie->generation != au_figen(file))) -+ goto out_unlock; -+ -+ err = 0; -+ if (!rdu->blk) { -+ rdu->blk = au_sbi(arg.sb)->si_rdblk; -+ if (!rdu->blk) -+ rdu->blk = au_dir_size(file, /*dentry*/NULL); -+ } -+ bbot = au_fbtop(file); -+ if (cookie->bindex < bbot) -+ cookie->bindex = bbot; -+ bbot = au_fbbot_dir(file); -+ /* AuDbg("b%d, b%d\n", cookie->bindex, bbot); */ -+ for (; !err && cookie->bindex <= bbot; -+ cookie->bindex++, cookie->h_pos = 0) { -+ h_file = au_hf_dir(file, cookie->bindex); -+ if (!h_file) -+ continue; -+ -+ au_fclr_rdu(cookie->flags, FULL); -+ err = au_rdu_do(h_file, &arg); -+ AuTraceErr(err); -+ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err)) -+ break; -+ } -+ AuDbg("rent %llu\n", rdu->rent); -+ -+ if (!err && !au_ftest_rdu(cookie->flags, CONT)) { -+ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH); -+ au_fset_rdu(cookie->flags, CONT); -+ cookie->generation = au_figen(file); -+ } -+ -+ ii_read_lock_child(inode); -+ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibtop(inode))); -+ ii_read_unlock(inode); -+ -+out_unlock: -+ fi_read_unlock(file); -+out_si: -+ si_read_unlock(arg.sb); -+out_mtx: -+ inode_unlock_shared(inode); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu) -+{ -+ int err; -+ ino_t ino; -+ unsigned long long nent; -+ union au_rdu_ent_ul *u; -+ struct au_rdu_ent ent; -+ struct super_block *sb; -+ -+ err = 0; -+ nent = rdu->nent; -+ u = &rdu->ent; -+ sb = file->f_path.dentry->d_sb; -+ si_read_lock(sb, AuLock_FLUSH); -+ while (nent-- > 0) { -+ /* unnecessary to support mmap_sem since this is a dir */ -+ err = copy_from_user(&ent, u->e, sizeof(ent)); -+ if (!err) -+ err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ break; -+ } -+ -+ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */ -+ if (!ent.wh) -+ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino); -+ else -+ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type, -+ &ino); -+ if (unlikely(err)) { -+ AuTraceErr(err); -+ break; -+ } -+ -+ err = __put_user(ino, &u->e->ino); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ break; -+ } -+ u->ul += au_rdu_len(ent.nlen); -+ } -+ si_read_unlock(sb); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_rdu_verify(struct aufs_rdu *rdu) -+{ -+ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | " -+ "%llu, b%d, 0x%x, g%u}\n", -+ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ], -+ rdu->blk, -+ rdu->rent, rdu->shwh, rdu->full, -+ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags, -+ rdu->cookie.generation); -+ -+ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu)) -+ return 0; -+ -+ AuDbg("%u:%u\n", -+ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu)); -+ return -EINVAL; -+} -+ -+long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ long err, e; -+ struct aufs_rdu rdu; -+ void __user *p = (void __user *)arg; -+ -+ err = copy_from_user(&rdu, p, sizeof(rdu)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ goto out; -+ } -+ err = au_rdu_verify(&rdu); -+ if (unlikely(err)) -+ goto out; -+ -+ switch (cmd) { -+ case AUFS_CTL_RDU: -+ err = au_rdu(file, &rdu); -+ if (unlikely(err)) -+ break; -+ -+ e = copy_to_user(p, &rdu, sizeof(rdu)); -+ if (unlikely(e)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ } -+ break; -+ case AUFS_CTL_RDU_INO: -+ err = au_rdu_ino(file, &rdu); -+ break; -+ -+ default: -+ /* err = -ENOTTY; */ -+ err = -EINVAL; -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+#ifdef CONFIG_COMPAT -+long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ long err, e; -+ struct aufs_rdu rdu; -+ void __user *p = compat_ptr(arg); -+ -+ /* todo: get_user()? */ -+ err = copy_from_user(&rdu, p, sizeof(rdu)); -+ if (unlikely(err)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ goto out; -+ } -+ rdu.ent.e = compat_ptr(rdu.ent.ul); -+ err = au_rdu_verify(&rdu); -+ if (unlikely(err)) -+ goto out; -+ -+ switch (cmd) { -+ case AUFS_CTL_RDU: -+ err = au_rdu(file, &rdu); -+ if (unlikely(err)) -+ break; -+ -+ rdu.ent.ul = ptr_to_compat(rdu.ent.e); -+ rdu.tail.ul = ptr_to_compat(rdu.tail.e); -+ e = copy_to_user(p, &rdu, sizeof(rdu)); -+ if (unlikely(e)) { -+ err = -EFAULT; -+ AuTraceErr(err); -+ } -+ break; -+ case AUFS_CTL_RDU_INO: -+ err = au_rdu_ino(file, &rdu); -+ break; -+ -+ default: -+ /* err = -ENOTTY; */ -+ err = -EINVAL; -+ } -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+#endif -diff --git a/fs/aufs/rwsem.h b/fs/aufs/rwsem.h -new file mode 100644 -index 000000000..bcb538eed ---- /dev/null -+++ b/fs/aufs/rwsem.h -@@ -0,0 +1,73 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * simple read-write semaphore wrappers -+ */ -+ -+#ifndef __AUFS_RWSEM_H__ -+#define __AUFS_RWSEM_H__ -+ -+#ifdef __KERNEL__ -+ -+#include "debug.h" -+ -+/* in the future, the name 'au_rwsem' will be totally gone */ -+#define au_rwsem rw_semaphore -+ -+/* to debug easier, do not make them inlined functions */ -+#define AuRwMustNoWaiters(rw) AuDebugOn(rwsem_is_contended(rw)) -+/* rwsem_is_locked() is unusable */ -+#define AuRwMustReadLock(rw) AuDebugOn(!lockdep_recursing(current) \ -+ && debug_locks \ -+ && !lockdep_is_held_type(rw, 1)) -+#define AuRwMustWriteLock(rw) AuDebugOn(!lockdep_recursing(current) \ -+ && debug_locks \ -+ && !lockdep_is_held_type(rw, 0)) -+#define AuRwMustAnyLock(rw) AuDebugOn(!lockdep_recursing(current) \ -+ && debug_locks \ -+ && !lockdep_is_held(rw)) -+#define AuRwDestroy(rw) AuDebugOn(!lockdep_recursing(current) \ -+ && debug_locks \ -+ && lockdep_is_held(rw)) -+ -+#define au_rw_init(rw) init_rwsem(rw) -+ -+#define au_rw_init_wlock(rw) do { \ -+ au_rw_init(rw); \ -+ down_write(rw); \ -+ } while (0) -+ -+#define au_rw_init_wlock_nested(rw, lsc) do { \ -+ au_rw_init(rw); \ -+ down_write_nested(rw, lsc); \ -+ } while (0) -+ -+#define au_rw_read_lock(rw) down_read(rw) -+#define au_rw_read_lock_nested(rw, lsc) down_read_nested(rw, lsc) -+#define au_rw_read_unlock(rw) up_read(rw) -+#define au_rw_dgrade_lock(rw) downgrade_write(rw) -+#define au_rw_write_lock(rw) down_write(rw) -+#define au_rw_write_lock_nested(rw, lsc) down_write_nested(rw, lsc) -+#define au_rw_write_unlock(rw) up_write(rw) -+/* why is not _nested version defined? */ -+#define au_rw_read_trylock(rw) down_read_trylock(rw) -+#define au_rw_write_trylock(rw) down_write_trylock(rw) -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_RWSEM_H__ */ -diff --git a/fs/aufs/sbinfo.c b/fs/aufs/sbinfo.c -new file mode 100644 -index 000000000..a013c7517 ---- /dev/null -+++ b/fs/aufs/sbinfo.c -@@ -0,0 +1,313 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * superblock private data -+ */ -+ -+#include "aufs.h" -+ -+/* -+ * they are necessary regardless sysfs is disabled. -+ */ -+void au_si_free(struct kobject *kobj) -+{ -+ int i; -+ struct au_sbinfo *sbinfo; -+ char *locked __maybe_unused; /* debug only */ -+ -+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); -+ for (i = 0; i < AuPlink_NHASH; i++) -+ AuDebugOn(!hlist_bl_empty(sbinfo->si_plink + i)); -+ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len)); -+ -+ AuLCntZero(au_lcnt_read(&sbinfo->si_ninodes, /*do_rev*/0)); -+ au_lcnt_fin(&sbinfo->si_ninodes, /*do_sync*/0); -+ AuLCntZero(au_lcnt_read(&sbinfo->si_nfiles, /*do_rev*/0)); -+ au_lcnt_fin(&sbinfo->si_nfiles, /*do_sync*/0); -+ -+ dbgaufs_si_fin(sbinfo); -+ au_rw_write_lock(&sbinfo->si_rwsem); -+ au_br_free(sbinfo); -+ au_rw_write_unlock(&sbinfo->si_rwsem); -+ -+ kfree(sbinfo->si_branch); -+ mutex_destroy(&sbinfo->si_xib_mtx); -+ AuRwDestroy(&sbinfo->si_rwsem); -+ -+ au_lcnt_wait_for_fin(&sbinfo->si_ninodes); -+ /* si_nfiles is waited too */ -+ kfree(sbinfo); -+} -+ -+int au_si_alloc(struct super_block *sb) -+{ -+ int err, i; -+ struct au_sbinfo *sbinfo; -+ -+ err = -ENOMEM; -+ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS); -+ if (unlikely(!sbinfo)) -+ goto out; -+ -+ /* will be reallocated separately */ -+ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS); -+ if (unlikely(!sbinfo->si_branch)) -+ goto out_sbinfo; -+ -+ err = sysaufs_si_init(sbinfo); -+ if (!err) { -+ dbgaufs_si_null(sbinfo); -+ err = dbgaufs_si_init(sbinfo); -+ if (unlikely(err)) -+ kobject_put(&sbinfo->si_kobj); -+ } -+ if (unlikely(err)) -+ goto out_br; -+ -+ au_nwt_init(&sbinfo->si_nowait); -+ au_rw_init_wlock(&sbinfo->si_rwsem); -+ -+ au_lcnt_init(&sbinfo->si_ninodes, /*release*/NULL); -+ au_lcnt_init(&sbinfo->si_nfiles, /*release*/NULL); -+ -+ sbinfo->si_bbot = -1; -+ sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2; -+ -+ sbinfo->si_wbr_copyup = AuWbrCopyup_Def; -+ sbinfo->si_wbr_create = AuWbrCreate_Def; -+ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup; -+ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create; -+ -+ au_fhsm_init(sbinfo); -+ -+ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def); -+ -+ sbinfo->si_xino_jiffy = jiffies; -+ sbinfo->si_xino_expire -+ = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC); -+ mutex_init(&sbinfo->si_xib_mtx); -+ /* leave si_xib_last_pindex and si_xib_next_bit */ -+ -+ INIT_HLIST_BL_HEAD(&sbinfo->si_aopen); -+ -+ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC); -+ sbinfo->si_rdblk = AUFS_RDBLK_DEF; -+ sbinfo->si_rdhash = AUFS_RDHASH_DEF; -+ sbinfo->si_dirwh = AUFS_DIRWH_DEF; -+ -+ for (i = 0; i < AuPlink_NHASH; i++) -+ INIT_HLIST_BL_HEAD(sbinfo->si_plink + i); -+ init_waitqueue_head(&sbinfo->si_plink_wq); -+ spin_lock_init(&sbinfo->si_plink_maint_lock); -+ -+ INIT_HLIST_BL_HEAD(&sbinfo->si_files); -+ -+ /* with getattr by default */ -+ sbinfo->si_iop_array = aufs_iop; -+ -+ /* leave other members for sysaufs and si_mnt. */ -+ sbinfo->si_sb = sb; -+ sb->s_fs_info = sbinfo; -+ si_pid_set(sb); -+ return 0; /* success */ -+ -+out_br: -+ kfree(sbinfo->si_branch); -+out_sbinfo: -+ kfree(sbinfo); -+out: -+ return err; -+} -+ -+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink) -+{ -+ int err, sz; -+ struct au_branch **brp; -+ -+ AuRwMustWriteLock(&sbinfo->si_rwsem); -+ -+ err = -ENOMEM; -+ sz = sizeof(*brp) * (sbinfo->si_bbot + 1); -+ if (unlikely(!sz)) -+ sz = sizeof(*brp); -+ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS, -+ may_shrink); -+ if (brp) { -+ sbinfo->si_branch = brp; -+ err = 0; -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+unsigned int au_sigen_inc(struct super_block *sb) -+{ -+ unsigned int gen; -+ struct inode *inode; -+ -+ SiMustWriteLock(sb); -+ -+ gen = ++au_sbi(sb)->si_generation; -+ au_update_digen(sb->s_root); -+ inode = d_inode(sb->s_root); -+ au_update_iigen(inode, /*half*/0); -+ inode_inc_iversion(inode); -+ return gen; -+} -+ -+aufs_bindex_t au_new_br_id(struct super_block *sb) -+{ -+ aufs_bindex_t br_id; -+ int i; -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ for (i = 0; i <= AUFS_BRANCH_MAX; i++) { -+ br_id = ++sbinfo->si_last_br_id; -+ AuDebugOn(br_id < 0); -+ if (br_id && au_br_index(sb, br_id) < 0) -+ return br_id; -+ } -+ -+ return -1; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* it is ok that new 'nwt' tasks are appended while we are sleeping */ -+int si_read_lock(struct super_block *sb, int flags) -+{ -+ int err; -+ -+ err = 0; -+ if (au_ftest_lock(flags, FLUSH)) -+ au_nwt_flush(&au_sbi(sb)->si_nowait); -+ -+ si_noflush_read_lock(sb); -+ err = au_plink_maint(sb, flags); -+ if (unlikely(err)) -+ si_read_unlock(sb); -+ -+ return err; -+} -+ -+int si_write_lock(struct super_block *sb, int flags) -+{ -+ int err; -+ -+ if (au_ftest_lock(flags, FLUSH)) -+ au_nwt_flush(&au_sbi(sb)->si_nowait); -+ -+ si_noflush_write_lock(sb); -+ err = au_plink_maint(sb, flags); -+ if (unlikely(err)) -+ si_write_unlock(sb); -+ -+ return err; -+} -+ -+/* dentry and super_block lock. call at entry point */ -+int aufs_read_lock(struct dentry *dentry, int flags) -+{ -+ int err; -+ struct super_block *sb; -+ -+ sb = dentry->d_sb; -+ err = si_read_lock(sb, flags); -+ if (unlikely(err)) -+ goto out; -+ -+ if (au_ftest_lock(flags, DW)) -+ di_write_lock_child(dentry); -+ else -+ di_read_lock_child(dentry, flags); -+ -+ if (au_ftest_lock(flags, GEN)) { -+ err = au_digen_test(dentry, au_sigen(sb)); -+ if (!au_opt_test(au_mntflags(sb), UDBA_NONE)) -+ AuDebugOn(!err && au_dbrange_test(dentry)); -+ else if (!err) -+ err = au_dbrange_test(dentry); -+ if (unlikely(err)) -+ aufs_read_unlock(dentry, flags); -+ } -+ -+out: -+ return err; -+} -+ -+void aufs_read_unlock(struct dentry *dentry, int flags) -+{ -+ if (au_ftest_lock(flags, DW)) -+ di_write_unlock(dentry); -+ else -+ di_read_unlock(dentry, flags); -+ si_read_unlock(dentry->d_sb); -+} -+ -+void aufs_write_lock(struct dentry *dentry) -+{ -+ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW); -+ di_write_lock_child(dentry); -+} -+ -+void aufs_write_unlock(struct dentry *dentry) -+{ -+ di_write_unlock(dentry); -+ si_write_unlock(dentry->d_sb); -+} -+ -+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags) -+{ -+ int err; -+ unsigned int sigen; -+ struct super_block *sb; -+ -+ sb = d1->d_sb; -+ err = si_read_lock(sb, flags); -+ if (unlikely(err)) -+ goto out; -+ -+ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIRS)); -+ -+ if (au_ftest_lock(flags, GEN)) { -+ sigen = au_sigen(sb); -+ err = au_digen_test(d1, sigen); -+ AuDebugOn(!err && au_dbrange_test(d1)); -+ if (!err) { -+ err = au_digen_test(d2, sigen); -+ AuDebugOn(!err && au_dbrange_test(d2)); -+ } -+ if (unlikely(err)) -+ aufs_read_and_write_unlock2(d1, d2); -+ } -+ -+out: -+ return err; -+} -+ -+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2) -+{ -+ di_write_unlock2(d1, d2); -+ si_read_unlock(d1->d_sb); -+} -diff --git a/fs/aufs/super.c b/fs/aufs/super.c -new file mode 100644 -index 000000000..a09c846ea ---- /dev/null -+++ b/fs/aufs/super.c -@@ -0,0 +1,1048 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * mount and super_block operations -+ */ -+ -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+/* -+ * super_operations -+ */ -+static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused) -+{ -+ struct au_icntnr *c; -+ -+ c = au_cache_alloc_icntnr(); -+ if (c) { -+ au_icntnr_init(c); -+ inode_set_iversion(&c->vfs_inode, 1); /* sigen(sb); */ -+ c->iinfo.ii_hinode = NULL; -+ return &c->vfs_inode; -+ } -+ return NULL; -+} -+ -+static void aufs_destroy_inode_cb(struct rcu_head *head) -+{ -+ struct inode *inode = container_of(head, struct inode, i_rcu); -+ -+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode)); -+} -+ -+static void aufs_destroy_inode(struct inode *inode) -+{ -+ if (!au_is_bad_inode(inode)) -+ au_iinfo_fin(inode); -+ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb); -+} -+ -+struct inode *au_iget_locked(struct super_block *sb, ino_t ino) -+{ -+ struct inode *inode; -+ int err; -+ -+ inode = iget_locked(sb, ino); -+ if (unlikely(!inode)) { -+ inode = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ if (!(inode->i_state & I_NEW)) -+ goto out; -+ -+ err = au_xigen_new(inode); -+ if (!err) -+ err = au_iinfo_init(inode); -+ if (!err) -+ inode_inc_iversion(inode); -+ else { -+ iget_failed(inode); -+ inode = ERR_PTR(err); -+ } -+ -+out: -+ /* never return NULL */ -+ AuDebugOn(!inode); -+ AuTraceErrPtr(inode); -+ return inode; -+} -+ -+/* lock free root dinfo */ -+static int au_show_brs(struct seq_file *seq, struct super_block *sb) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct path path; -+ struct au_hdentry *hdp; -+ struct au_branch *br; -+ au_br_perm_str_t perm; -+ -+ err = 0; -+ bbot = au_sbbot(sb); -+ bindex = 0; -+ hdp = au_hdentry(au_di(sb->s_root), bindex); -+ for (; !err && bindex <= bbot; bindex++, hdp++) { -+ br = au_sbr(sb, bindex); -+ path.mnt = au_br_mnt(br); -+ path.dentry = hdp->hd_dentry; -+ err = au_seq_path(seq, &path); -+ if (!err) { -+ au_optstr_br_perm(&perm, br->br_perm); -+ seq_printf(seq, "=%s", perm.a); -+ if (bindex != bbot) -+ seq_putc(seq, ':'); -+ } -+ } -+ if (unlikely(err || seq_has_overflowed(seq))) -+ err = -E2BIG; -+ -+ return err; -+} -+ -+static void au_gen_fmt(char *fmt, int len __maybe_unused, const char *pat, -+ const char *append) -+{ -+ char *p; -+ -+ p = fmt; -+ while (*pat != ':') -+ *p++ = *pat++; -+ *p++ = *pat++; -+ strcpy(p, append); -+ AuDebugOn(strlen(fmt) >= len); -+} -+ -+static void au_show_wbr_create(struct seq_file *m, int v, -+ struct au_sbinfo *sbinfo) -+{ -+ const char *pat; -+ char fmt[32]; -+ struct au_wbr_mfs *mfs; -+ -+ AuRwMustAnyLock(&sbinfo->si_rwsem); -+ -+ seq_puts(m, ",create="); -+ pat = au_optstr_wbr_create(v); -+ mfs = &sbinfo->si_wbr_mfs; -+ switch (v) { -+ case AuWbrCreate_TDP: -+ case AuWbrCreate_RR: -+ case AuWbrCreate_MFS: -+ case AuWbrCreate_PMFS: -+ seq_puts(m, pat); -+ break; -+ case AuWbrCreate_MFSRR: -+ case AuWbrCreate_TDMFS: -+ case AuWbrCreate_PMFSRR: -+ au_gen_fmt(fmt, sizeof(fmt), pat, "%llu"); -+ seq_printf(m, fmt, mfs->mfsrr_watermark); -+ break; -+ case AuWbrCreate_MFSV: -+ case AuWbrCreate_PMFSV: -+ au_gen_fmt(fmt, sizeof(fmt), pat, "%lu"); -+ seq_printf(m, fmt, -+ jiffies_to_msecs(mfs->mfs_expire) -+ / MSEC_PER_SEC); -+ break; -+ case AuWbrCreate_MFSRRV: -+ case AuWbrCreate_TDMFSV: -+ case AuWbrCreate_PMFSRRV: -+ au_gen_fmt(fmt, sizeof(fmt), pat, "%llu:%lu"); -+ seq_printf(m, fmt, mfs->mfsrr_watermark, -+ jiffies_to_msecs(mfs->mfs_expire) / MSEC_PER_SEC); -+ break; -+ default: -+ BUG(); -+ } -+} -+ -+static int au_show_xino(struct seq_file *seq, struct super_block *sb) -+{ -+#ifdef CONFIG_SYSFS -+ return 0; -+#else -+ int err; -+ const int len = sizeof(AUFS_XINO_FNAME) - 1; -+ aufs_bindex_t bindex, brid; -+ struct qstr *name; -+ struct file *f; -+ struct dentry *d, *h_root; -+ struct au_branch *br; -+ -+ AuRwMustAnyLock(&sbinfo->si_rwsem); -+ -+ err = 0; -+ f = au_sbi(sb)->si_xib; -+ if (!f) -+ goto out; -+ -+ /* stop printing the default xino path on the first writable branch */ -+ h_root = NULL; -+ bindex = au_xi_root(sb, f->f_path.dentry); -+ if (bindex >= 0) { -+ br = au_sbr_sb(sb, bindex); -+ h_root = au_br_dentry(br); -+ } -+ -+ d = f->f_path.dentry; -+ name = &d->d_name; -+ /* safe ->d_parent because the file is unlinked */ -+ if (d->d_parent == h_root -+ && name->len == len -+ && !memcmp(name->name, AUFS_XINO_FNAME, len)) -+ goto out; -+ -+ seq_puts(seq, ",xino="); -+ err = au_xino_path(seq, f); -+ -+out: -+ return err; -+#endif -+} -+ -+/* seq_file will re-call me in case of too long string */ -+static int aufs_show_options(struct seq_file *m, struct dentry *dentry) -+{ -+ int err; -+ unsigned int mnt_flags, v; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ -+#define AuBool(name, str) do { \ -+ v = au_opt_test(mnt_flags, name); \ -+ if (v != au_opt_test(AuOpt_Def, name)) \ -+ seq_printf(m, ",%s" #str, v ? "" : "no"); \ -+} while (0) -+ -+#define AuStr(name, str) do { \ -+ v = mnt_flags & AuOptMask_##name; \ -+ if (v != (AuOpt_Def & AuOptMask_##name)) \ -+ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \ -+} while (0) -+ -+#define AuUInt(name, str, val) do { \ -+ if (val != AUFS_##name##_DEF) \ -+ seq_printf(m, "," #str "=%u", val); \ -+} while (0) -+ -+ sb = dentry->d_sb; -+ if (sb->s_flags & SB_POSIXACL) -+ seq_puts(m, ",acl"); -+#if 0 -+ if (sb->s_flags & SB_I_VERSION) -+ seq_puts(m, ",i_version"); -+#endif -+ -+ /* lock free root dinfo */ -+ si_noflush_read_lock(sb); -+ sbinfo = au_sbi(sb); -+ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo)); -+ -+ mnt_flags = au_mntflags(sb); -+ if (au_opt_test(mnt_flags, XINO)) { -+ err = au_show_xino(m, sb); -+ if (unlikely(err)) -+ goto out; -+ } else -+ seq_puts(m, ",noxino"); -+ -+ AuBool(TRUNC_XINO, trunc_xino); -+ AuStr(UDBA, udba); -+ AuBool(SHWH, shwh); -+ AuBool(PLINK, plink); -+ AuBool(DIO, dio); -+ AuBool(DIRPERM1, dirperm1); -+ -+ v = sbinfo->si_wbr_create; -+ if (v != AuWbrCreate_Def) -+ au_show_wbr_create(m, v, sbinfo); -+ -+ v = sbinfo->si_wbr_copyup; -+ if (v != AuWbrCopyup_Def) -+ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v)); -+ -+ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ); -+ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ)) -+ seq_printf(m, ",diropq=%c", v ? 'a' : 'w'); -+ -+ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh); -+ -+ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC; -+ AuUInt(RDCACHE, rdcache, v); -+ -+ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk); -+ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash); -+ -+ au_fhsm_show(m, sbinfo); -+ -+ AuBool(DIRREN, dirren); -+ AuBool(SUM, sum); -+ /* AuBool(SUM_W, wsum); */ -+ AuBool(WARN_PERM, warn_perm); -+ AuBool(VERBOSE, verbose); -+ -+out: -+ /* be sure to print "br:" last */ -+ if (!sysaufs_brs) { -+ seq_puts(m, ",br:"); -+ au_show_brs(m, sb); -+ } -+ si_read_unlock(sb); -+ return 0; -+ -+#undef AuBool -+#undef AuStr -+#undef AuUInt -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* sum mode which returns the summation for statfs(2) */ -+ -+static u64 au_add_till_max(u64 a, u64 b) -+{ -+ u64 old; -+ -+ old = a; -+ a += b; -+ if (old <= a) -+ return a; -+ return ULLONG_MAX; -+} -+ -+static u64 au_mul_till_max(u64 a, long mul) -+{ -+ u64 old; -+ -+ old = a; -+ a *= mul; -+ if (old <= a) -+ return a; -+ return ULLONG_MAX; -+} -+ -+static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf) -+{ -+ int err; -+ long bsize, factor; -+ u64 blocks, bfree, bavail, files, ffree; -+ aufs_bindex_t bbot, bindex, i; -+ unsigned char shared; -+ struct path h_path; -+ struct super_block *h_sb; -+ -+ err = 0; -+ bsize = LONG_MAX; -+ files = 0; -+ ffree = 0; -+ blocks = 0; -+ bfree = 0; -+ bavail = 0; -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ h_path.mnt = au_sbr_mnt(sb, bindex); -+ h_sb = h_path.mnt->mnt_sb; -+ shared = 0; -+ for (i = 0; !shared && i < bindex; i++) -+ shared = (au_sbr_sb(sb, i) == h_sb); -+ if (shared) -+ continue; -+ -+ /* sb->s_root for NFS is unreliable */ -+ h_path.dentry = h_path.mnt->mnt_root; -+ err = vfs_statfs(&h_path, buf); -+ if (unlikely(err)) -+ goto out; -+ -+ if (bsize > buf->f_bsize) { -+ /* -+ * we will reduce bsize, so we have to expand blocks -+ * etc. to match them again -+ */ -+ factor = (bsize / buf->f_bsize); -+ blocks = au_mul_till_max(blocks, factor); -+ bfree = au_mul_till_max(bfree, factor); -+ bavail = au_mul_till_max(bavail, factor); -+ bsize = buf->f_bsize; -+ } -+ -+ factor = (buf->f_bsize / bsize); -+ blocks = au_add_till_max(blocks, -+ au_mul_till_max(buf->f_blocks, factor)); -+ bfree = au_add_till_max(bfree, -+ au_mul_till_max(buf->f_bfree, factor)); -+ bavail = au_add_till_max(bavail, -+ au_mul_till_max(buf->f_bavail, factor)); -+ files = au_add_till_max(files, buf->f_files); -+ ffree = au_add_till_max(ffree, buf->f_ffree); -+ } -+ -+ buf->f_bsize = bsize; -+ buf->f_blocks = blocks; -+ buf->f_bfree = bfree; -+ buf->f_bavail = bavail; -+ buf->f_files = files; -+ buf->f_ffree = ffree; -+ buf->f_frsize = 0; -+ -+out: -+ return err; -+} -+ -+static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf) -+{ -+ int err; -+ struct path h_path; -+ struct super_block *sb; -+ -+ /* lock free root dinfo */ -+ sb = dentry->d_sb; -+ si_noflush_read_lock(sb); -+ if (!au_opt_test(au_mntflags(sb), SUM)) { -+ /* sb->s_root for NFS is unreliable */ -+ h_path.mnt = au_sbr_mnt(sb, 0); -+ h_path.dentry = h_path.mnt->mnt_root; -+ err = vfs_statfs(&h_path, buf); -+ } else -+ err = au_statfs_sum(sb, buf); -+ si_read_unlock(sb); -+ -+ if (!err) { -+ buf->f_type = AUFS_SUPER_MAGIC; -+ buf->f_namelen = AUFS_MAX_NAMELEN; -+ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid)); -+ } -+ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */ -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int aufs_sync_fs(struct super_block *sb, int wait) -+{ -+ int err, e; -+ aufs_bindex_t bbot, bindex; -+ struct au_branch *br; -+ struct super_block *h_sb; -+ -+ err = 0; -+ si_noflush_read_lock(sb); -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (!au_br_writable(br->br_perm)) -+ continue; -+ -+ h_sb = au_sbr_sb(sb, bindex); -+ e = vfsub_sync_filesystem(h_sb, wait); -+ if (unlikely(e && !err)) -+ err = e; -+ /* go on even if an error happens */ -+ } -+ si_read_unlock(sb); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* final actions when unmounting a file system */ -+static void aufs_put_super(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ sbinfo = au_sbi(sb); -+ if (sbinfo) -+ kobject_put(&sbinfo->si_kobj); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, -+ struct super_block *sb, void *arg) -+{ -+ void *array; -+ unsigned long long n, sz; -+ -+ array = NULL; -+ n = 0; -+ if (!*hint) -+ goto out; -+ -+ if (*hint > ULLONG_MAX / sizeof(array)) { -+ array = ERR_PTR(-EMFILE); -+ pr_err("hint %llu\n", *hint); -+ goto out; -+ } -+ -+ sz = sizeof(array) * *hint; -+ array = kzalloc(sz, GFP_NOFS); -+ if (unlikely(!array)) -+ array = vzalloc(sz); -+ if (unlikely(!array)) { -+ array = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ -+ n = cb(sb, array, *hint, arg); -+ AuDebugOn(n > *hint); -+ -+out: -+ *hint = n; -+ return array; -+} -+ -+static unsigned long long au_iarray_cb(struct super_block *sb, void *a, -+ unsigned long long max __maybe_unused, -+ void *arg) -+{ -+ unsigned long long n; -+ struct inode **p, *inode; -+ struct list_head *head; -+ -+ n = 0; -+ p = a; -+ head = arg; -+ spin_lock(&sb->s_inode_list_lock); -+ list_for_each_entry(inode, head, i_sb_list) { -+ if (!au_is_bad_inode(inode) -+ && au_ii(inode)->ii_btop >= 0) { -+ spin_lock(&inode->i_lock); -+ if (atomic_read(&inode->i_count)) { -+ au_igrab(inode); -+ *p++ = inode; -+ n++; -+ AuDebugOn(n > max); -+ } -+ spin_unlock(&inode->i_lock); -+ } -+ } -+ spin_unlock(&sb->s_inode_list_lock); -+ -+ return n; -+} -+ -+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max) -+{ -+ struct au_sbinfo *sbi; -+ -+ sbi = au_sbi(sb); -+ *max = au_lcnt_read(&sbi->si_ninodes, /*do_rev*/1); -+ return au_array_alloc(max, au_iarray_cb, sb, &sb->s_inodes); -+} -+ -+void au_iarray_free(struct inode **a, unsigned long long max) -+{ -+ unsigned long long ull; -+ -+ for (ull = 0; ull < max; ull++) -+ iput(a[ull]); -+ kvfree(a); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * refresh dentry and inode at remount time. -+ */ -+/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */ -+static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags, -+ struct dentry *parent) -+{ -+ int err; -+ -+ di_write_lock_child(dentry); -+ di_read_lock_parent(parent, AuLock_IR); -+ err = au_refresh_dentry(dentry, parent); -+ if (!err && dir_flags) -+ au_hn_reset(d_inode(dentry), dir_flags); -+ di_read_unlock(parent, AuLock_IR); -+ di_write_unlock(dentry); -+ -+ return err; -+} -+ -+static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen, -+ struct au_sbinfo *sbinfo, -+ const unsigned int dir_flags, unsigned int do_idop) -+{ -+ int err; -+ struct dentry *parent; -+ -+ err = 0; -+ parent = dget_parent(dentry); -+ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) { -+ if (d_really_is_positive(dentry)) { -+ if (!d_is_dir(dentry)) -+ err = au_do_refresh(dentry, /*dir_flags*/0, -+ parent); -+ else { -+ err = au_do_refresh(dentry, dir_flags, parent); -+ if (unlikely(err)) -+ au_fset_si(sbinfo, FAILED_REFRESH_DIR); -+ } -+ } else -+ err = au_do_refresh(dentry, /*dir_flags*/0, parent); -+ AuDbgDentry(dentry); -+ } -+ dput(parent); -+ -+ if (!err) { -+ if (do_idop) -+ au_refresh_dop(dentry, /*force_reval*/0); -+ } else -+ au_refresh_dop(dentry, /*force_reval*/1); -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_refresh_d(struct super_block *sb, unsigned int do_idop) -+{ -+ int err, i, j, ndentry, e; -+ unsigned int sigen; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry **dentries, *d; -+ struct au_sbinfo *sbinfo; -+ struct dentry *root = sb->s_root; -+ const unsigned int dir_flags = au_hi_flags(d_inode(root), /*isdir*/1); -+ -+ if (do_idop) -+ au_refresh_dop(root, /*force_reval*/0); -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_dcsub_pages(&dpages, root, NULL, NULL); -+ if (unlikely(err)) -+ goto out_dpages; -+ -+ sigen = au_sigen(sb); -+ sbinfo = au_sbi(sb); -+ for (i = 0; i < dpages.ndpage; i++) { -+ dpage = dpages.dpages + i; -+ dentries = dpage->dentries; -+ ndentry = dpage->ndentry; -+ for (j = 0; j < ndentry; j++) { -+ d = dentries[j]; -+ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags, -+ do_idop); -+ if (unlikely(e && !err)) -+ err = e; -+ /* go on even err */ -+ } -+ } -+ -+out_dpages: -+ au_dpages_free(&dpages); -+out: -+ return err; -+} -+ -+static int au_refresh_i(struct super_block *sb, unsigned int do_idop) -+{ -+ int err, e; -+ unsigned int sigen; -+ unsigned long long max, ull; -+ struct inode *inode, **array; -+ -+ array = au_iarray_alloc(sb, &max); -+ err = PTR_ERR(array); -+ if (IS_ERR(array)) -+ goto out; -+ -+ err = 0; -+ sigen = au_sigen(sb); -+ for (ull = 0; ull < max; ull++) { -+ inode = array[ull]; -+ if (unlikely(!inode)) -+ break; -+ -+ e = 0; -+ ii_write_lock_child(inode); -+ if (au_iigen(inode, NULL) != sigen) { -+ e = au_refresh_hinode_self(inode); -+ if (unlikely(e)) { -+ au_refresh_iop(inode, /*force_getattr*/1); -+ pr_err("error %d, i%lu\n", e, inode->i_ino); -+ if (!err) -+ err = e; -+ /* go on even if err */ -+ } -+ } -+ if (!e && do_idop) -+ au_refresh_iop(inode, /*force_getattr*/0); -+ ii_write_unlock(inode); -+ } -+ -+ au_iarray_free(array, max); -+ -+out: -+ return err; -+} -+ -+static void au_remount_refresh(struct super_block *sb, unsigned int do_idop) -+{ -+ int err, e; -+ unsigned int udba; -+ aufs_bindex_t bindex, bbot; -+ struct dentry *root; -+ struct inode *inode; -+ struct au_branch *br; -+ struct au_sbinfo *sbi; -+ -+ au_sigen_inc(sb); -+ sbi = au_sbi(sb); -+ au_fclr_si(sbi, FAILED_REFRESH_DIR); -+ -+ root = sb->s_root; -+ DiMustNoWaiters(root); -+ inode = d_inode(root); -+ IiMustNoWaiters(inode); -+ -+ udba = au_opt_udba(sb); -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ err = au_hnotify_reset_br(udba, br, br->br_perm); -+ if (unlikely(err)) -+ AuIOErr("hnotify failed on br %d, %d, ignored\n", -+ bindex, err); -+ /* go on even if err */ -+ } -+ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1)); -+ -+ if (do_idop) { -+ if (au_ftest_si(sbi, NO_DREVAL)) { -+ AuDebugOn(sb->s_d_op == &aufs_dop_noreval); -+ sb->s_d_op = &aufs_dop_noreval; -+ AuDebugOn(sbi->si_iop_array == aufs_iop_nogetattr); -+ sbi->si_iop_array = aufs_iop_nogetattr; -+ } else { -+ AuDebugOn(sb->s_d_op == &aufs_dop); -+ sb->s_d_op = &aufs_dop; -+ AuDebugOn(sbi->si_iop_array == aufs_iop); -+ sbi->si_iop_array = aufs_iop; -+ } -+ pr_info("reset to %ps and %ps\n", -+ sb->s_d_op, sbi->si_iop_array); -+ } -+ -+ di_write_unlock(root); -+ err = au_refresh_d(sb, do_idop); -+ e = au_refresh_i(sb, do_idop); -+ if (unlikely(e && !err)) -+ err = e; -+ /* aufs_write_lock() calls ..._child() */ -+ di_write_lock_child(root); -+ -+ au_cpup_attr_all(inode, /*force*/1); -+ -+ if (unlikely(err)) -+ AuIOErr("refresh failed, ignored, %d\n", err); -+} -+ -+/* stop extra interpretation of errno in mount(8), and strange error messages */ -+static int cvt_err(int err) -+{ -+ AuTraceErr(err); -+ -+ switch (err) { -+ case -ENOENT: -+ case -ENOTDIR: -+ case -EEXIST: -+ case -EIO: -+ err = -EINVAL; -+ } -+ return err; -+} -+ -+static int aufs_remount_fs(struct super_block *sb, int *flags, char *data) -+{ -+ int err, do_dx; -+ unsigned int mntflags; -+ struct au_opts opts = { -+ .opt = NULL -+ }; -+ struct dentry *root; -+ struct inode *inode; -+ struct au_sbinfo *sbinfo; -+ -+ err = 0; -+ root = sb->s_root; -+ if (!data || !*data) { -+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (!err) { -+ di_write_lock_child(root); -+ err = au_opts_verify(sb, *flags, /*pending*/0); -+ aufs_write_unlock(root); -+ } -+ goto out; -+ } -+ -+ err = -ENOMEM; -+ opts.opt = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!opts.opt)) -+ goto out; -+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); -+ opts.flags = AuOpts_REMOUNT; -+ opts.sb_flags = *flags; -+ -+ /* parse it before aufs lock */ -+ err = au_opts_parse(sb, data, &opts); -+ if (unlikely(err)) -+ goto out_opts; -+ -+ sbinfo = au_sbi(sb); -+ inode = d_inode(root); -+ inode_lock(inode); -+ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out_mtx; -+ di_write_lock_child(root); -+ -+ /* au_opts_remount() may return an error */ -+ err = au_opts_remount(sb, &opts); -+ au_opts_free(&opts); -+ -+ if (au_ftest_opts(opts.flags, REFRESH)) -+ au_remount_refresh(sb, au_ftest_opts(opts.flags, REFRESH_IDOP)); -+ -+ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) { -+ mntflags = au_mntflags(sb); -+ do_dx = !!au_opt_test(mntflags, DIO); -+ au_dy_arefresh(do_dx); -+ } -+ -+ au_fhsm_wrote_all(sb, /*force*/1); /* ?? */ -+ aufs_write_unlock(root); -+ -+out_mtx: -+ inode_unlock(inode); -+out_opts: -+ free_page((unsigned long)opts.opt); -+out: -+ err = cvt_err(err); -+ AuTraceErr(err); -+ return err; -+} -+ -+static const struct super_operations aufs_sop = { -+ .alloc_inode = aufs_alloc_inode, -+ .destroy_inode = aufs_destroy_inode, -+ /* always deleting, no clearing */ -+ .drop_inode = generic_delete_inode, -+ .show_options = aufs_show_options, -+ .statfs = aufs_statfs, -+ .put_super = aufs_put_super, -+ .sync_fs = aufs_sync_fs, -+ .remount_fs = aufs_remount_fs -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int alloc_root(struct super_block *sb) -+{ -+ int err; -+ struct inode *inode; -+ struct dentry *root; -+ -+ err = -ENOMEM; -+ inode = au_iget_locked(sb, AUFS_ROOT_INO); -+ err = PTR_ERR(inode); -+ if (IS_ERR(inode)) -+ goto out; -+ -+ inode->i_op = aufs_iop + AuIop_DIR; /* with getattr by default */ -+ inode->i_fop = &aufs_dir_fop; -+ inode->i_mode = S_IFDIR; -+ set_nlink(inode, 2); -+ unlock_new_inode(inode); -+ -+ root = d_make_root(inode); -+ if (unlikely(!root)) -+ goto out; -+ err = PTR_ERR(root); -+ if (IS_ERR(root)) -+ goto out; -+ -+ err = au_di_init(root); -+ if (!err) { -+ sb->s_root = root; -+ return 0; /* success */ -+ } -+ dput(root); -+ -+out: -+ return err; -+} -+ -+static int aufs_fill_super(struct super_block *sb, void *raw_data, -+ int silent __maybe_unused) -+{ -+ int err; -+ struct au_opts opts = { -+ .opt = NULL -+ }; -+ struct au_sbinfo *sbinfo; -+ struct dentry *root; -+ struct inode *inode; -+ char *arg = raw_data; -+ -+ if (unlikely(!arg || !*arg)) { -+ err = -EINVAL; -+ pr_err("no arg\n"); -+ goto out; -+ } -+ -+ err = -ENOMEM; -+ opts.opt = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!opts.opt)) -+ goto out; -+ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); -+ opts.sb_flags = sb->s_flags; -+ -+ err = au_si_alloc(sb); -+ if (unlikely(err)) -+ goto out_opts; -+ sbinfo = au_sbi(sb); -+ -+ /* all timestamps always follow the ones on the branch */ -+ sb->s_flags |= SB_NOATIME | SB_NODIRATIME; -+ sb->s_flags |= SB_I_VERSION; /* do we really need this? */ -+ sb->s_op = &aufs_sop; -+ sb->s_d_op = &aufs_dop; -+ sb->s_magic = AUFS_SUPER_MAGIC; -+ sb->s_maxbytes = 0; -+ sb->s_stack_depth = 1; -+ au_export_init(sb); -+ au_xattr_init(sb); -+ -+ err = alloc_root(sb); -+ if (unlikely(err)) { -+ si_write_unlock(sb); -+ goto out_info; -+ } -+ root = sb->s_root; -+ inode = d_inode(root); -+ -+ /* -+ * actually we can parse options regardless aufs lock here. -+ * but at remount time, parsing must be done before aufs lock. -+ * so we follow the same rule. -+ */ -+ ii_write_lock_parent(inode); -+ aufs_write_unlock(root); -+ err = au_opts_parse(sb, arg, &opts); -+ if (unlikely(err)) -+ goto out_root; -+ -+ /* lock vfs_inode first, then aufs. */ -+ inode_lock(inode); -+ aufs_write_lock(root); -+ err = au_opts_mount(sb, &opts); -+ au_opts_free(&opts); -+ if (!err && au_ftest_si(sbinfo, NO_DREVAL)) { -+ sb->s_d_op = &aufs_dop_noreval; -+ pr_info("%ps\n", sb->s_d_op); -+ au_refresh_dop(root, /*force_reval*/0); -+ sbinfo->si_iop_array = aufs_iop_nogetattr; -+ au_refresh_iop(inode, /*force_getattr*/0); -+ } -+ aufs_write_unlock(root); -+ inode_unlock(inode); -+ if (!err) -+ goto out_opts; /* success */ -+ -+out_root: -+ dput(root); -+ sb->s_root = NULL; -+out_info: -+ kobject_put(&sbinfo->si_kobj); -+ sb->s_fs_info = NULL; -+out_opts: -+ free_page((unsigned long)opts.opt); -+out: -+ AuTraceErr(err); -+ err = cvt_err(err); -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags, -+ const char *dev_name __maybe_unused, -+ void *raw_data) -+{ -+ struct dentry *root; -+ -+ /* all timestamps always follow the ones on the branch */ -+ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */ -+ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super); -+ if (IS_ERR(root)) -+ goto out; -+ -+ au_sbilist_add(root->d_sb); -+ -+out: -+ return root; -+} -+ -+static void aufs_kill_sb(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ sbinfo = au_sbi(sb); -+ if (sbinfo) { -+ au_sbilist_del(sb); -+ aufs_write_lock(sb->s_root); -+ au_fhsm_fin(sb); -+ if (sbinfo->si_wbr_create_ops->fin) -+ sbinfo->si_wbr_create_ops->fin(sb); -+ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) { -+ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE); -+ au_remount_refresh(sb, /*do_idop*/0); -+ } -+ if (au_opt_test(sbinfo->si_mntflags, PLINK)) -+ au_plink_put(sb, /*verbose*/1); -+ au_xino_clr(sb); -+ au_dr_opt_flush(sb); -+ sbinfo->si_sb = NULL; -+ aufs_write_unlock(sb->s_root); -+ au_nwt_flush(&sbinfo->si_nowait); -+ } -+ kill_anon_super(sb); -+} -+ -+struct file_system_type aufs_fs_type = { -+ .name = AUFS_FSTYPE, -+ /* a race between rename and others */ -+ .fs_flags = FS_RENAME_DOES_D_MOVE, -+ .mount = aufs_mount, -+ .kill_sb = aufs_kill_sb, -+ /* no need to __module_get() and module_put(). */ -+ .owner = THIS_MODULE, -+}; -diff --git a/fs/aufs/super.h b/fs/aufs/super.h -new file mode 100644 -index 000000000..79e47da4e ---- /dev/null -+++ b/fs/aufs/super.h -@@ -0,0 +1,589 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * super_block operations -+ */ -+ -+#ifndef __AUFS_SUPER_H__ -+#define __AUFS_SUPER_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include "hbl.h" -+#include "lcnt.h" -+#include "rwsem.h" -+#include "wkq.h" -+ -+/* policies to select one among multiple writable branches */ -+struct au_wbr_copyup_operations { -+ int (*copyup)(struct dentry *dentry); -+}; -+ -+#define AuWbr_DIR 1 /* target is a dir */ -+#define AuWbr_PARENT (1 << 1) /* always require a parent */ -+ -+#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name) -+#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; } -+#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; } -+ -+struct au_wbr_create_operations { -+ int (*create)(struct dentry *dentry, unsigned int flags); -+ int (*init)(struct super_block *sb); -+ int (*fin)(struct super_block *sb); -+}; -+ -+struct au_wbr_mfs { -+ struct mutex mfs_lock; /* protect this structure */ -+ unsigned long mfs_jiffy; -+ unsigned long mfs_expire; -+ aufs_bindex_t mfs_bindex; -+ -+ unsigned long long mfsrr_bytes; -+ unsigned long long mfsrr_watermark; -+}; -+ -+#define AuPlink_NHASH 100 -+static inline int au_plink_hash(ino_t ino) -+{ -+ return ino % AuPlink_NHASH; -+} -+ -+/* File-based Hierarchical Storage Management */ -+struct au_fhsm { -+#ifdef CONFIG_AUFS_FHSM -+ /* allow only one process who can receive the notification */ -+ spinlock_t fhsm_spin; -+ pid_t fhsm_pid; -+ wait_queue_head_t fhsm_wqh; -+ atomic_t fhsm_readable; -+ -+ /* these are protected by si_rwsem */ -+ unsigned long fhsm_expire; -+ aufs_bindex_t fhsm_bottom; -+#endif -+}; -+ -+struct au_branch; -+struct au_sbinfo { -+ /* nowait tasks in the system-wide workqueue */ -+ struct au_nowait_tasks si_nowait; -+ -+ /* -+ * tried sb->s_umount, but failed due to the dependency between i_mutex. -+ * rwsem for au_sbinfo is necessary. -+ */ -+ struct au_rwsem si_rwsem; -+ -+ /* -+ * dirty approach to protect sb->sb_inodes and ->s_files (gone) from -+ * remount. -+ */ -+ au_lcnt_t si_ninodes, si_nfiles; -+ -+ /* branch management */ -+ unsigned int si_generation; -+ -+ /* see AuSi_ flags */ -+ unsigned char au_si_status; -+ -+ aufs_bindex_t si_bbot; -+ -+ /* dirty trick to keep br_id plus */ -+ unsigned int si_last_br_id : -+ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1; -+ struct au_branch **si_branch; -+ -+ /* policy to select a writable branch */ -+ unsigned char si_wbr_copyup; -+ unsigned char si_wbr_create; -+ struct au_wbr_copyup_operations *si_wbr_copyup_ops; -+ struct au_wbr_create_operations *si_wbr_create_ops; -+ -+ /* round robin */ -+ atomic_t si_wbr_rr_next; -+ -+ /* most free space */ -+ struct au_wbr_mfs si_wbr_mfs; -+ -+ /* File-based Hierarchical Storage Management */ -+ struct au_fhsm si_fhsm; -+ -+ /* mount flags */ -+ /* include/asm-ia64/siginfo.h defines a macro named si_flags */ -+ unsigned int si_mntflags; -+ -+ /* external inode number (bitmap and translation table) */ -+ vfs_readf_t si_xread; -+ vfs_writef_t si_xwrite; -+ loff_t si_ximaxent; /* max entries in a xino */ -+ -+ struct file *si_xib; -+ struct mutex si_xib_mtx; /* protect xib members */ -+ unsigned long *si_xib_buf; -+ unsigned long si_xib_last_pindex; -+ int si_xib_next_bit; -+ -+ unsigned long si_xino_jiffy; -+ unsigned long si_xino_expire; -+ /* reserved for future use */ -+ /* unsigned long long si_xib_limit; */ /* Max xib file size */ -+ -+#ifdef CONFIG_AUFS_EXPORT -+ /* i_generation */ -+ /* todo: make xigen file an array to support many inode numbers */ -+ struct file *si_xigen; -+ atomic_t si_xigen_next; -+#endif -+ -+ /* dirty trick to support atomic_open */ -+ struct hlist_bl_head si_aopen; -+ -+ /* vdir parameters */ -+ unsigned long si_rdcache; /* max cache time in jiffies */ -+ unsigned int si_rdblk; /* deblk size */ -+ unsigned int si_rdhash; /* hash size */ -+ -+ /* -+ * If the number of whiteouts are larger than si_dirwh, leave all of -+ * them after au_whtmp_ren to reduce the cost of rmdir(2). -+ * future fsck.aufs or kernel thread will remove them later. -+ * Otherwise, remove all whiteouts and the dir in rmdir(2). -+ */ -+ unsigned int si_dirwh; -+ -+ /* pseudo_link list */ -+ struct hlist_bl_head si_plink[AuPlink_NHASH]; -+ wait_queue_head_t si_plink_wq; -+ spinlock_t si_plink_maint_lock; -+ pid_t si_plink_maint_pid; -+ -+ /* file list */ -+ struct hlist_bl_head si_files; -+ -+ /* with/without getattr, brother of sb->s_d_op */ -+ struct inode_operations *si_iop_array; -+ -+ /* -+ * sysfs and lifetime management. -+ * this is not a small structure and it may be a waste of memory in case -+ * of sysfs is disabled, particularly when many aufs-es are mounted. -+ * but using sysfs is majority. -+ */ -+ struct kobject si_kobj; -+#ifdef CONFIG_DEBUG_FS -+ struct dentry *si_dbgaufs; -+ struct dentry *si_dbgaufs_plink; -+ struct dentry *si_dbgaufs_xib; -+#ifdef CONFIG_AUFS_EXPORT -+ struct dentry *si_dbgaufs_xigen; -+#endif -+#endif -+ -+#ifdef CONFIG_AUFS_SBILIST -+ struct hlist_bl_node si_list; -+#endif -+ -+ /* dirty, necessary for unmounting, sysfs and sysrq */ -+ struct super_block *si_sb; -+}; -+ -+/* sbinfo status flags */ -+/* -+ * set true when refresh_dirs() failed at remount time. -+ * then try refreshing dirs at access time again. -+ * if it is false, refreshing dirs at access time is unnecessary -+ */ -+#define AuSi_FAILED_REFRESH_DIR 1 -+#define AuSi_FHSM (1 << 1) /* fhsm is active now */ -+#define AuSi_NO_DREVAL (1 << 2) /* disable all d_revalidate */ -+ -+#ifndef CONFIG_AUFS_FHSM -+#undef AuSi_FHSM -+#define AuSi_FHSM 0 -+#endif -+ -+static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi, -+ unsigned int flag) -+{ -+ AuRwMustAnyLock(&sbi->si_rwsem); -+ return sbi->au_si_status & flag; -+} -+#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name) -+#define au_fset_si(sbinfo, name) do { \ -+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \ -+ (sbinfo)->au_si_status |= AuSi_##name; \ -+} while (0) -+#define au_fclr_si(sbinfo, name) do { \ -+ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \ -+ (sbinfo)->au_si_status &= ~AuSi_##name; \ -+} while (0) -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* policy to select one among writable branches */ -+#define AuWbrCopyup(sbinfo, ...) \ -+ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__)) -+#define AuWbrCreate(sbinfo, ...) \ -+ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__)) -+ -+/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */ -+#define AuLock_DW 1 /* write-lock dentry */ -+#define AuLock_IR (1 << 1) /* read-lock inode */ -+#define AuLock_IW (1 << 2) /* write-lock inode */ -+#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */ -+#define AuLock_DIRS (1 << 4) /* target is a pair of dirs */ -+ /* except RENAME_EXCHANGE */ -+#define AuLock_NOPLM (1 << 5) /* return err in plm mode */ -+#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */ -+#define AuLock_GEN (1 << 7) /* test digen/iigen */ -+#define au_ftest_lock(flags, name) ((flags) & AuLock_##name) -+#define au_fset_lock(flags, name) \ -+ do { (flags) |= AuLock_##name; } while (0) -+#define au_fclr_lock(flags, name) \ -+ do { (flags) &= ~AuLock_##name; } while (0) -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* super.c */ -+extern struct file_system_type aufs_fs_type; -+struct inode *au_iget_locked(struct super_block *sb, ino_t ino); -+typedef unsigned long long (*au_arraycb_t)(struct super_block *sb, void *array, -+ unsigned long long max, void *arg); -+void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, -+ struct super_block *sb, void *arg); -+struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max); -+void au_iarray_free(struct inode **a, unsigned long long max); -+ -+/* sbinfo.c */ -+void au_si_free(struct kobject *kobj); -+int au_si_alloc(struct super_block *sb); -+int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr, int may_shrink); -+ -+unsigned int au_sigen_inc(struct super_block *sb); -+aufs_bindex_t au_new_br_id(struct super_block *sb); -+ -+int si_read_lock(struct super_block *sb, int flags); -+int si_write_lock(struct super_block *sb, int flags); -+int aufs_read_lock(struct dentry *dentry, int flags); -+void aufs_read_unlock(struct dentry *dentry, int flags); -+void aufs_write_lock(struct dentry *dentry); -+void aufs_write_unlock(struct dentry *dentry); -+int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags); -+void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2); -+ -+/* wbr_policy.c */ -+extern struct au_wbr_copyup_operations au_wbr_copyup_ops[]; -+extern struct au_wbr_create_operations au_wbr_create_ops[]; -+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst); -+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex); -+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t btop); -+ -+/* mvdown.c */ -+int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg); -+ -+#ifdef CONFIG_AUFS_FHSM -+/* fhsm.c */ -+ -+static inline pid_t au_fhsm_pid(struct au_fhsm *fhsm) -+{ -+ pid_t pid; -+ -+ spin_lock(&fhsm->fhsm_spin); -+ pid = fhsm->fhsm_pid; -+ spin_unlock(&fhsm->fhsm_spin); -+ -+ return pid; -+} -+ -+void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force); -+void au_fhsm_wrote_all(struct super_block *sb, int force); -+int au_fhsm_fd(struct super_block *sb, int oflags); -+int au_fhsm_br_alloc(struct au_branch *br); -+void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex); -+void au_fhsm_fin(struct super_block *sb); -+void au_fhsm_init(struct au_sbinfo *sbinfo); -+void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec); -+void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo); -+#else -+AuStubVoid(au_fhsm_wrote, struct super_block *sb, aufs_bindex_t bindex, -+ int force) -+AuStubVoid(au_fhsm_wrote_all, struct super_block *sb, int force) -+AuStub(int, au_fhsm_fd, return -EOPNOTSUPP, struct super_block *sb, int oflags) -+AuStub(pid_t, au_fhsm_pid, return 0, struct au_fhsm *fhsm) -+AuStubInt0(au_fhsm_br_alloc, struct au_branch *br) -+AuStubVoid(au_fhsm_set_bottom, struct super_block *sb, aufs_bindex_t bindex) -+AuStubVoid(au_fhsm_fin, struct super_block *sb) -+AuStubVoid(au_fhsm_init, struct au_sbinfo *sbinfo) -+AuStubVoid(au_fhsm_set, struct au_sbinfo *sbinfo, unsigned int sec) -+AuStubVoid(au_fhsm_show, struct seq_file *seq, struct au_sbinfo *sbinfo) -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct au_sbinfo *au_sbi(struct super_block *sb) -+{ -+ return sb->s_fs_info; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_EXPORT -+int au_test_nfsd(void); -+void au_export_init(struct super_block *sb); -+void au_xigen_inc(struct inode *inode); -+int au_xigen_new(struct inode *inode); -+int au_xigen_set(struct super_block *sb, struct path *path); -+void au_xigen_clr(struct super_block *sb); -+ -+static inline int au_busy_or_stale(void) -+{ -+ if (!au_test_nfsd()) -+ return -EBUSY; -+ return -ESTALE; -+} -+#else -+AuStubInt0(au_test_nfsd, void) -+AuStubVoid(au_export_init, struct super_block *sb) -+AuStubVoid(au_xigen_inc, struct inode *inode) -+AuStubInt0(au_xigen_new, struct inode *inode) -+AuStubInt0(au_xigen_set, struct super_block *sb, struct path *path) -+AuStubVoid(au_xigen_clr, struct super_block *sb) -+AuStub(int, au_busy_or_stale, return -EBUSY, void) -+#endif /* CONFIG_AUFS_EXPORT */ -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_SBILIST -+/* module.c */ -+extern struct hlist_bl_head au_sbilist; -+ -+static inline void au_sbilist_init(void) -+{ -+ INIT_HLIST_BL_HEAD(&au_sbilist); -+} -+ -+static inline void au_sbilist_add(struct super_block *sb) -+{ -+ au_hbl_add(&au_sbi(sb)->si_list, &au_sbilist); -+} -+ -+static inline void au_sbilist_del(struct super_block *sb) -+{ -+ au_hbl_del(&au_sbi(sb)->si_list, &au_sbilist); -+} -+ -+#ifdef CONFIG_AUFS_MAGIC_SYSRQ -+static inline void au_sbilist_lock(void) -+{ -+ hlist_bl_lock(&au_sbilist); -+} -+ -+static inline void au_sbilist_unlock(void) -+{ -+ hlist_bl_unlock(&au_sbilist); -+} -+#define AuGFP_SBILIST GFP_ATOMIC -+#else -+AuStubVoid(au_sbilist_lock, void) -+AuStubVoid(au_sbilist_unlock, void) -+#define AuGFP_SBILIST GFP_NOFS -+#endif /* CONFIG_AUFS_MAGIC_SYSRQ */ -+#else -+AuStubVoid(au_sbilist_init, void) -+AuStubVoid(au_sbilist_add, struct super_block *sb) -+AuStubVoid(au_sbilist_del, struct super_block *sb) -+AuStubVoid(au_sbilist_lock, void) -+AuStubVoid(au_sbilist_unlock, void) -+#define AuGFP_SBILIST GFP_NOFS -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo) -+{ -+ /* -+ * This function is a dynamic '__init' function actually, -+ * so the tiny check for si_rwsem is unnecessary. -+ */ -+ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ -+#ifdef CONFIG_DEBUG_FS -+ sbinfo->si_dbgaufs = NULL; -+ sbinfo->si_dbgaufs_plink = NULL; -+ sbinfo->si_dbgaufs_xib = NULL; -+#ifdef CONFIG_AUFS_EXPORT -+ sbinfo->si_dbgaufs_xigen = NULL; -+#endif -+#endif -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* current->atomic_flags */ -+/* this value should never corrupt the ones defined in linux/sched.h */ -+#define PFA_AUFS 7 -+ -+TASK_PFA_TEST(AUFS, test_aufs) /* task_test_aufs */ -+TASK_PFA_SET(AUFS, aufs) /* task_set_aufs */ -+TASK_PFA_CLEAR(AUFS, aufs) /* task_clear_aufs */ -+ -+static inline int si_pid_test(struct super_block *sb) -+{ -+ return !!task_test_aufs(current); -+} -+ -+static inline void si_pid_clr(struct super_block *sb) -+{ -+ AuDebugOn(!task_test_aufs(current)); -+ task_clear_aufs(current); -+} -+ -+static inline void si_pid_set(struct super_block *sb) -+{ -+ AuDebugOn(task_test_aufs(current)); -+ task_set_aufs(current); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* lock superblock. mainly for entry point functions */ -+#define __si_read_lock(sb) au_rw_read_lock(&au_sbi(sb)->si_rwsem) -+#define __si_write_lock(sb) au_rw_write_lock(&au_sbi(sb)->si_rwsem) -+#define __si_read_trylock(sb) au_rw_read_trylock(&au_sbi(sb)->si_rwsem) -+#define __si_write_trylock(sb) au_rw_write_trylock(&au_sbi(sb)->si_rwsem) -+/* -+#define __si_read_trylock_nested(sb) \ -+ au_rw_read_trylock_nested(&au_sbi(sb)->si_rwsem) -+#define __si_write_trylock_nested(sb) \ -+ au_rw_write_trylock_nested(&au_sbi(sb)->si_rwsem) -+*/ -+ -+#define __si_read_unlock(sb) au_rw_read_unlock(&au_sbi(sb)->si_rwsem) -+#define __si_write_unlock(sb) au_rw_write_unlock(&au_sbi(sb)->si_rwsem) -+#define __si_downgrade_lock(sb) au_rw_dgrade_lock(&au_sbi(sb)->si_rwsem) -+ -+#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem) -+#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem) -+#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem) -+ -+static inline void si_noflush_read_lock(struct super_block *sb) -+{ -+ __si_read_lock(sb); -+ si_pid_set(sb); -+} -+ -+static inline int si_noflush_read_trylock(struct super_block *sb) -+{ -+ int locked; -+ -+ locked = __si_read_trylock(sb); -+ if (locked) -+ si_pid_set(sb); -+ return locked; -+} -+ -+static inline void si_noflush_write_lock(struct super_block *sb) -+{ -+ __si_write_lock(sb); -+ si_pid_set(sb); -+} -+ -+static inline int si_noflush_write_trylock(struct super_block *sb) -+{ -+ int locked; -+ -+ locked = __si_write_trylock(sb); -+ if (locked) -+ si_pid_set(sb); -+ return locked; -+} -+ -+#if 0 /* reserved */ -+static inline int si_read_trylock(struct super_block *sb, int flags) -+{ -+ if (au_ftest_lock(flags, FLUSH)) -+ au_nwt_flush(&au_sbi(sb)->si_nowait); -+ return si_noflush_read_trylock(sb); -+} -+#endif -+ -+static inline void si_read_unlock(struct super_block *sb) -+{ -+ si_pid_clr(sb); -+ __si_read_unlock(sb); -+} -+ -+#if 0 /* reserved */ -+static inline int si_write_trylock(struct super_block *sb, int flags) -+{ -+ if (au_ftest_lock(flags, FLUSH)) -+ au_nwt_flush(&au_sbi(sb)->si_nowait); -+ return si_noflush_write_trylock(sb); -+} -+#endif -+ -+static inline void si_write_unlock(struct super_block *sb) -+{ -+ si_pid_clr(sb); -+ __si_write_unlock(sb); -+} -+ -+#if 0 /* reserved */ -+static inline void si_downgrade_lock(struct super_block *sb) -+{ -+ __si_downgrade_lock(sb); -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline aufs_bindex_t au_sbbot(struct super_block *sb) -+{ -+ SiMustAnyLock(sb); -+ return au_sbi(sb)->si_bbot; -+} -+ -+static inline unsigned int au_mntflags(struct super_block *sb) -+{ -+ SiMustAnyLock(sb); -+ return au_sbi(sb)->si_mntflags; -+} -+ -+static inline unsigned int au_sigen(struct super_block *sb) -+{ -+ SiMustAnyLock(sb); -+ return au_sbi(sb)->si_generation; -+} -+ -+static inline struct au_branch *au_sbr(struct super_block *sb, -+ aufs_bindex_t bindex) -+{ -+ SiMustAnyLock(sb); -+ return au_sbi(sb)->si_branch[0 + bindex]; -+} -+ -+static inline loff_t au_xi_maxent(struct super_block *sb) -+{ -+ SiMustAnyLock(sb); -+ return au_sbi(sb)->si_ximaxent; -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_SUPER_H__ */ -diff --git a/fs/aufs/sysaufs.c b/fs/aufs/sysaufs.c -new file mode 100644 -index 000000000..cb34a53f3 ---- /dev/null -+++ b/fs/aufs/sysaufs.c -@@ -0,0 +1,93 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * sysfs interface and lifetime management -+ * they are necessary regardless sysfs is disabled. -+ */ -+ -+#include -+#include "aufs.h" -+ -+unsigned long sysaufs_si_mask; -+struct kset *sysaufs_kset; -+ -+#define AuSiAttr(_name) { \ -+ .attr = { .name = __stringify(_name), .mode = 0444 }, \ -+ .show = sysaufs_si_##_name, \ -+} -+ -+static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path); -+struct attribute *sysaufs_si_attrs[] = { -+ &sysaufs_si_attr_xi_path.attr, -+ NULL, -+}; -+ -+static const struct sysfs_ops au_sbi_ops = { -+ .show = sysaufs_si_show -+}; -+ -+static struct kobj_type au_sbi_ktype = { -+ .release = au_si_free, -+ .sysfs_ops = &au_sbi_ops, -+ .default_attrs = sysaufs_si_attrs -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+int sysaufs_si_init(struct au_sbinfo *sbinfo) -+{ -+ int err; -+ -+ sbinfo->si_kobj.kset = sysaufs_kset; -+ /* cf. sysaufs_name() */ -+ err = kobject_init_and_add -+ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL, -+ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo)); -+ -+ return err; -+} -+ -+void sysaufs_fin(void) -+{ -+ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group); -+ kset_unregister(sysaufs_kset); -+} -+ -+int __init sysaufs_init(void) -+{ -+ int err; -+ -+ do { -+ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask)); -+ } while (!sysaufs_si_mask); -+ -+ err = -EINVAL; -+ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj); -+ if (unlikely(!sysaufs_kset)) -+ goto out; -+ err = PTR_ERR(sysaufs_kset); -+ if (IS_ERR(sysaufs_kset)) -+ goto out; -+ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group); -+ if (unlikely(err)) -+ kset_unregister(sysaufs_kset); -+ -+out: -+ return err; -+} -diff --git a/fs/aufs/sysaufs.h b/fs/aufs/sysaufs.h -new file mode 100644 -index 000000000..9a64191c5 ---- /dev/null -+++ b/fs/aufs/sysaufs.h -@@ -0,0 +1,102 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * sysfs interface and mount lifetime management -+ */ -+ -+#ifndef __SYSAUFS_H__ -+#define __SYSAUFS_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include "module.h" -+ -+struct super_block; -+struct au_sbinfo; -+ -+struct sysaufs_si_attr { -+ struct attribute attr; -+ int (*show)(struct seq_file *seq, struct super_block *sb); -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* sysaufs.c */ -+extern unsigned long sysaufs_si_mask; -+extern struct kset *sysaufs_kset; -+extern struct attribute *sysaufs_si_attrs[]; -+int sysaufs_si_init(struct au_sbinfo *sbinfo); -+int __init sysaufs_init(void); -+void sysaufs_fin(void); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* some people doesn't like to show a pointer in kernel */ -+static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo) -+{ -+ return sysaufs_si_mask ^ (unsigned long)sbinfo; -+} -+ -+#define SysaufsSiNamePrefix "si_" -+#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16) -+static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name) -+{ -+ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx", -+ sysaufs_si_id(sbinfo)); -+} -+ -+struct au_branch; -+#ifdef CONFIG_SYSFS -+/* sysfs.c */ -+extern struct attribute_group *sysaufs_attr_group; -+ -+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb); -+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, -+ char *buf); -+long au_brinfo_ioctl(struct file *file, unsigned long arg); -+#ifdef CONFIG_COMPAT -+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg); -+#endif -+ -+void sysaufs_br_init(struct au_branch *br); -+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex); -+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex); -+ -+#define sysaufs_brs_init() do {} while (0) -+ -+#else -+#define sysaufs_attr_group NULL -+ -+AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb) -+AuStub(ssize_t, sysaufs_si_show, return 0, struct kobject *kobj, -+ struct attribute *attr, char *buf) -+AuStubVoid(sysaufs_br_init, struct au_branch *br) -+AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex) -+AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex) -+ -+static inline void sysaufs_brs_init(void) -+{ -+ sysaufs_brs = 0; -+} -+ -+#endif /* CONFIG_SYSFS */ -+ -+#endif /* __KERNEL__ */ -+#endif /* __SYSAUFS_H__ */ -diff --git a/fs/aufs/sysfs.c b/fs/aufs/sysfs.c -new file mode 100644 -index 000000000..89a4cbf66 ---- /dev/null -+++ b/fs/aufs/sysfs.c -@@ -0,0 +1,373 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * sysfs interface -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+#ifdef CONFIG_AUFS_FS_MODULE -+/* this entry violates the "one line per file" policy of sysfs */ -+static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr, -+ char *buf) -+{ -+ ssize_t err; -+ static char *conf = -+/* this file is generated at compiling */ -+#include "conf.str" -+ ; -+ -+ err = snprintf(buf, PAGE_SIZE, conf); -+ if (unlikely(err >= PAGE_SIZE)) -+ err = -EFBIG; -+ return err; -+} -+ -+static struct kobj_attribute au_config_attr = __ATTR_RO(config); -+#endif -+ -+static struct attribute *au_attr[] = { -+#ifdef CONFIG_AUFS_FS_MODULE -+ &au_config_attr.attr, -+#endif -+ NULL, /* need to NULL terminate the list of attributes */ -+}; -+ -+static struct attribute_group sysaufs_attr_group_body = { -+ .attrs = au_attr -+}; -+ -+struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body; -+ -+/* ---------------------------------------------------------------------- */ -+ -+int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb) -+{ -+ int err; -+ -+ SiMustAnyLock(sb); -+ -+ err = 0; -+ if (au_opt_test(au_mntflags(sb), XINO)) { -+ err = au_xino_path(seq, au_sbi(sb)->si_xib); -+ seq_putc(seq, '\n'); -+ } -+ return err; -+} -+ -+/* -+ * the lifetime of branch is independent from the entry under sysfs. -+ * sysfs handles the lifetime of the entry, and never call ->show() after it is -+ * unlinked. -+ */ -+static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb, -+ aufs_bindex_t bindex, int idx) -+{ -+ int err; -+ struct path path; -+ struct dentry *root; -+ struct au_branch *br; -+ au_br_perm_str_t perm; -+ -+ AuDbg("b%d\n", bindex); -+ -+ err = 0; -+ root = sb->s_root; -+ di_read_lock_parent(root, !AuLock_IR); -+ br = au_sbr(sb, bindex); -+ -+ switch (idx) { -+ case AuBrSysfs_BR: -+ path.mnt = au_br_mnt(br); -+ path.dentry = au_h_dptr(root, bindex); -+ err = au_seq_path(seq, &path); -+ if (!err) { -+ au_optstr_br_perm(&perm, br->br_perm); -+ seq_printf(seq, "=%s\n", perm.a); -+ } -+ break; -+ case AuBrSysfs_BRID: -+ seq_printf(seq, "%d\n", br->br_id); -+ break; -+ } -+ di_read_unlock(root, !AuLock_IR); -+ if (unlikely(err || seq_has_overflowed(seq))) -+ err = -E2BIG; -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static struct seq_file *au_seq(char *p, ssize_t len) -+{ -+ struct seq_file *seq; -+ -+ seq = kzalloc(sizeof(*seq), GFP_NOFS); -+ if (seq) { -+ /* mutex_init(&seq.lock); */ -+ seq->buf = p; -+ seq->size = len; -+ return seq; /* success */ -+ } -+ -+ seq = ERR_PTR(-ENOMEM); -+ return seq; -+} -+ -+#define SysaufsBr_PREFIX "br" -+#define SysaufsBrid_PREFIX "brid" -+ -+/* todo: file size may exceed PAGE_SIZE */ -+ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, -+ char *buf) -+{ -+ ssize_t err; -+ int idx; -+ long l; -+ aufs_bindex_t bbot; -+ struct au_sbinfo *sbinfo; -+ struct super_block *sb; -+ struct seq_file *seq; -+ char *name; -+ struct attribute **cattr; -+ -+ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); -+ sb = sbinfo->si_sb; -+ -+ /* -+ * prevent a race condition between sysfs and aufs. -+ * for instance, sysfs_file_read() calls sysfs_get_active_two() which -+ * prohibits maintaining the sysfs entries. -+ * hew we acquire read lock after sysfs_get_active_two(). -+ * on the other hand, the remount process may maintain the sysfs/aufs -+ * entries after acquiring write lock. -+ * it can cause a deadlock. -+ * simply we gave up processing read here. -+ */ -+ err = -EBUSY; -+ if (unlikely(!si_noflush_read_trylock(sb))) -+ goto out; -+ -+ seq = au_seq(buf, PAGE_SIZE); -+ err = PTR_ERR(seq); -+ if (IS_ERR(seq)) -+ goto out_unlock; -+ -+ name = (void *)attr->name; -+ cattr = sysaufs_si_attrs; -+ while (*cattr) { -+ if (!strcmp(name, (*cattr)->name)) { -+ err = container_of(*cattr, struct sysaufs_si_attr, attr) -+ ->show(seq, sb); -+ goto out_seq; -+ } -+ cattr++; -+ } -+ -+ if (!strncmp(name, SysaufsBrid_PREFIX, -+ sizeof(SysaufsBrid_PREFIX) - 1)) { -+ idx = AuBrSysfs_BRID; -+ name += sizeof(SysaufsBrid_PREFIX) - 1; -+ } else if (!strncmp(name, SysaufsBr_PREFIX, -+ sizeof(SysaufsBr_PREFIX) - 1)) { -+ idx = AuBrSysfs_BR; -+ name += sizeof(SysaufsBr_PREFIX) - 1; -+ } else -+ BUG(); -+ -+ err = kstrtol(name, 10, &l); -+ if (!err) { -+ bbot = au_sbbot(sb); -+ if (l <= bbot) -+ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx); -+ else -+ err = -ENOENT; -+ } -+ -+out_seq: -+ if (!err) { -+ err = seq->count; -+ /* sysfs limit */ -+ if (unlikely(err == PAGE_SIZE)) -+ err = -EFBIG; -+ } -+ kfree(seq); -+out_unlock: -+ si_read_unlock(sb); -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_brinfo(struct super_block *sb, union aufs_brinfo __user *arg) -+{ -+ int err; -+ int16_t brid; -+ aufs_bindex_t bindex, bbot; -+ size_t sz; -+ char *buf; -+ struct seq_file *seq; -+ struct au_branch *br; -+ -+ si_read_lock(sb, AuLock_FLUSH); -+ bbot = au_sbbot(sb); -+ err = bbot + 1; -+ if (!arg) -+ goto out; -+ -+ err = -ENOMEM; -+ buf = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!buf)) -+ goto out; -+ -+ seq = au_seq(buf, PAGE_SIZE); -+ err = PTR_ERR(seq); -+ if (IS_ERR(seq)) -+ goto out_buf; -+ -+ sz = sizeof(*arg) - offsetof(union aufs_brinfo, path); -+ for (bindex = 0; bindex <= bbot; bindex++, arg++) { -+ err = !access_ok(VERIFY_WRITE, arg, sizeof(*arg)); -+ if (unlikely(err)) -+ break; -+ -+ br = au_sbr(sb, bindex); -+ brid = br->br_id; -+ BUILD_BUG_ON(sizeof(brid) != sizeof(arg->id)); -+ err = __put_user(brid, &arg->id); -+ if (unlikely(err)) -+ break; -+ -+ BUILD_BUG_ON(sizeof(br->br_perm) != sizeof(arg->perm)); -+ err = __put_user(br->br_perm, &arg->perm); -+ if (unlikely(err)) -+ break; -+ -+ err = au_seq_path(seq, &br->br_path); -+ if (unlikely(err)) -+ break; -+ seq_putc(seq, '\0'); -+ if (!seq_has_overflowed(seq)) { -+ err = copy_to_user(arg->path, seq->buf, seq->count); -+ seq->count = 0; -+ if (unlikely(err)) -+ break; -+ } else { -+ err = -E2BIG; -+ goto out_seq; -+ } -+ } -+ if (unlikely(err)) -+ err = -EFAULT; -+ -+out_seq: -+ kfree(seq); -+out_buf: -+ free_page((unsigned long)buf); -+out: -+ si_read_unlock(sb); -+ return err; -+} -+ -+long au_brinfo_ioctl(struct file *file, unsigned long arg) -+{ -+ return au_brinfo(file->f_path.dentry->d_sb, (void __user *)arg); -+} -+ -+#ifdef CONFIG_COMPAT -+long au_brinfo_compat_ioctl(struct file *file, unsigned long arg) -+{ -+ return au_brinfo(file->f_path.dentry->d_sb, compat_ptr(arg)); -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+void sysaufs_br_init(struct au_branch *br) -+{ -+ int i; -+ struct au_brsysfs *br_sysfs; -+ struct attribute *attr; -+ -+ br_sysfs = br->br_sysfs; -+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) { -+ attr = &br_sysfs->attr; -+ sysfs_attr_init(attr); -+ attr->name = br_sysfs->name; -+ attr->mode = 0444; -+ br_sysfs++; -+ } -+} -+ -+void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ struct au_branch *br; -+ struct kobject *kobj; -+ struct au_brsysfs *br_sysfs; -+ int i; -+ aufs_bindex_t bbot; -+ -+ if (!sysaufs_brs) -+ return; -+ -+ kobj = &au_sbi(sb)->si_kobj; -+ bbot = au_sbbot(sb); -+ for (; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ br_sysfs = br->br_sysfs; -+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) { -+ sysfs_remove_file(kobj, &br_sysfs->attr); -+ br_sysfs++; -+ } -+ } -+} -+ -+void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ int err, i; -+ aufs_bindex_t bbot; -+ struct kobject *kobj; -+ struct au_branch *br; -+ struct au_brsysfs *br_sysfs; -+ -+ if (!sysaufs_brs) -+ return; -+ -+ kobj = &au_sbi(sb)->si_kobj; -+ bbot = au_sbbot(sb); -+ for (; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ br_sysfs = br->br_sysfs; -+ snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name), -+ SysaufsBr_PREFIX "%d", bindex); -+ snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name), -+ SysaufsBrid_PREFIX "%d", bindex); -+ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) { -+ err = sysfs_create_file(kobj, &br_sysfs->attr); -+ if (unlikely(err)) -+ pr_warn("failed %s under sysfs(%d)\n", -+ br_sysfs->name, err); -+ br_sysfs++; -+ } -+ } -+} -diff --git a/fs/aufs/sysrq.c b/fs/aufs/sysrq.c -new file mode 100644 -index 000000000..2dbf23741 ---- /dev/null -+++ b/fs/aufs/sysrq.c -@@ -0,0 +1,160 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * magic sysrq handler -+ */ -+ -+/* #include */ -+#include -+#include "aufs.h" -+ -+/* ---------------------------------------------------------------------- */ -+ -+static void sysrq_sb(struct super_block *sb) -+{ -+ char *plevel; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ struct hlist_bl_head *files; -+ struct hlist_bl_node *pos; -+ struct au_finfo *finfo; -+ -+ plevel = au_plevel; -+ au_plevel = KERN_WARNING; -+ -+ /* since we define pr_fmt, call printk directly */ -+#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str) -+ -+ sbinfo = au_sbi(sb); -+ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo)); -+ pr("superblock\n"); -+ au_dpri_sb(sb); -+ -+#if 0 -+ pr("root dentry\n"); -+ au_dpri_dentry(sb->s_root); -+ pr("root inode\n"); -+ au_dpri_inode(d_inode(sb->s_root)); -+#endif -+ -+#if 0 -+ do { -+ int err, i, j, ndentry; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ -+ err = au_dpages_init(&dpages, GFP_ATOMIC); -+ if (unlikely(err)) -+ break; -+ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL); -+ if (!err) -+ for (i = 0; i < dpages.ndpage; i++) { -+ dpage = dpages.dpages + i; -+ ndentry = dpage->ndentry; -+ for (j = 0; j < ndentry; j++) -+ au_dpri_dentry(dpage->dentries[j]); -+ } -+ au_dpages_free(&dpages); -+ } while (0); -+#endif -+ -+#if 1 -+ { -+ struct inode *i; -+ -+ pr("isolated inode\n"); -+ spin_lock(&sb->s_inode_list_lock); -+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) { -+ spin_lock(&i->i_lock); -+ if (1 || hlist_empty(&i->i_dentry)) -+ au_dpri_inode(i); -+ spin_unlock(&i->i_lock); -+ } -+ spin_unlock(&sb->s_inode_list_lock); -+ } -+#endif -+ pr("files\n"); -+ files = &au_sbi(sb)->si_files; -+ hlist_bl_lock(files); -+ hlist_bl_for_each_entry(finfo, pos, files, fi_hlist) { -+ umode_t mode; -+ -+ file = finfo->fi_file; -+ mode = file_inode(file)->i_mode; -+ if (!special_file(mode)) -+ au_dpri_file(file); -+ } -+ hlist_bl_unlock(files); -+ pr("done\n"); -+ -+#undef pr -+ au_plevel = plevel; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* module parameter */ -+static char *aufs_sysrq_key = "a"; -+module_param_named(sysrq, aufs_sysrq_key, charp, 0444); -+MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME); -+ -+static void au_sysrq(int key __maybe_unused) -+{ -+ struct au_sbinfo *sbinfo; -+ struct hlist_bl_node *pos; -+ -+ lockdep_off(); -+ au_sbilist_lock(); -+ hlist_bl_for_each_entry(sbinfo, pos, &au_sbilist, si_list) -+ sysrq_sb(sbinfo->si_sb); -+ au_sbilist_unlock(); -+ lockdep_on(); -+} -+ -+static struct sysrq_key_op au_sysrq_op = { -+ .handler = au_sysrq, -+ .help_msg = "Aufs", -+ .action_msg = "Aufs", -+ .enable_mask = SYSRQ_ENABLE_DUMP -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+int __init au_sysrq_init(void) -+{ -+ int err; -+ char key; -+ -+ err = -1; -+ key = *aufs_sysrq_key; -+ if ('a' <= key && key <= 'z') -+ err = register_sysrq_key(key, &au_sysrq_op); -+ if (unlikely(err)) -+ pr_err("err %d, sysrq=%c\n", err, key); -+ return err; -+} -+ -+void au_sysrq_fin(void) -+{ -+ int err; -+ -+ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op); -+ if (unlikely(err)) -+ pr_err("err %d (ignored)\n", err); -+} -diff --git a/fs/aufs/vdir.c b/fs/aufs/vdir.c -new file mode 100644 -index 000000000..f83ca0689 ---- /dev/null -+++ b/fs/aufs/vdir.c -@@ -0,0 +1,895 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * virtual or vertical directory -+ */ -+ -+#include "aufs.h" -+ -+static unsigned int calc_size(int nlen) -+{ -+ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t)); -+} -+ -+static int set_deblk_end(union au_vdir_deblk_p *p, -+ union au_vdir_deblk_p *deblk_end) -+{ -+ if (calc_size(0) <= deblk_end->deblk - p->deblk) { -+ p->de->de_str.len = 0; -+ /* smp_mb(); */ -+ return 0; -+ } -+ return -1; /* error */ -+} -+ -+/* returns true or false */ -+static int is_deblk_end(union au_vdir_deblk_p *p, -+ union au_vdir_deblk_p *deblk_end) -+{ -+ if (calc_size(0) <= deblk_end->deblk - p->deblk) -+ return !p->de->de_str.len; -+ return 1; -+} -+ -+static unsigned char *last_deblk(struct au_vdir *vdir) -+{ -+ return vdir->vd_deblk[vdir->vd_nblk - 1]; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* estimate the appropriate size for name hash table */ -+unsigned int au_rdhash_est(loff_t sz) -+{ -+ unsigned int n; -+ -+ n = UINT_MAX; -+ sz >>= 10; -+ if (sz < n) -+ n = sz; -+ if (sz < AUFS_RDHASH_DEF) -+ n = AUFS_RDHASH_DEF; -+ /* pr_info("n %u\n", n); */ -+ return n; -+} -+ -+/* -+ * the allocated memory has to be freed by -+ * au_nhash_wh_free() or au_nhash_de_free(). -+ */ -+int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp) -+{ -+ struct hlist_head *head; -+ unsigned int u; -+ size_t sz; -+ -+ sz = sizeof(*nhash->nh_head) * num_hash; -+ head = kmalloc(sz, gfp); -+ if (head) { -+ nhash->nh_num = num_hash; -+ nhash->nh_head = head; -+ for (u = 0; u < num_hash; u++) -+ INIT_HLIST_HEAD(head++); -+ return 0; /* success */ -+ } -+ -+ return -ENOMEM; -+} -+ -+static void nhash_count(struct hlist_head *head) -+{ -+#if 0 -+ unsigned long n; -+ struct hlist_node *pos; -+ -+ n = 0; -+ hlist_for_each(pos, head) -+ n++; -+ pr_info("%lu\n", n); -+#endif -+} -+ -+static void au_nhash_wh_do_free(struct hlist_head *head) -+{ -+ struct au_vdir_wh *pos; -+ struct hlist_node *node; -+ -+ hlist_for_each_entry_safe(pos, node, head, wh_hash) -+ kfree(pos); -+} -+ -+static void au_nhash_de_do_free(struct hlist_head *head) -+{ -+ struct au_vdir_dehstr *pos; -+ struct hlist_node *node; -+ -+ hlist_for_each_entry_safe(pos, node, head, hash) -+ au_cache_free_vdir_dehstr(pos); -+} -+ -+static void au_nhash_do_free(struct au_nhash *nhash, -+ void (*free)(struct hlist_head *head)) -+{ -+ unsigned int n; -+ struct hlist_head *head; -+ -+ n = nhash->nh_num; -+ if (!n) -+ return; -+ -+ head = nhash->nh_head; -+ while (n-- > 0) { -+ nhash_count(head); -+ free(head++); -+ } -+ kfree(nhash->nh_head); -+} -+ -+void au_nhash_wh_free(struct au_nhash *whlist) -+{ -+ au_nhash_do_free(whlist, au_nhash_wh_do_free); -+} -+ -+static void au_nhash_de_free(struct au_nhash *delist) -+{ -+ au_nhash_do_free(delist, au_nhash_de_do_free); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, -+ int limit) -+{ -+ int num; -+ unsigned int u, n; -+ struct hlist_head *head; -+ struct au_vdir_wh *pos; -+ -+ num = 0; -+ n = whlist->nh_num; -+ head = whlist->nh_head; -+ for (u = 0; u < n; u++, head++) -+ hlist_for_each_entry(pos, head, wh_hash) -+ if (pos->wh_bindex == btgt && ++num > limit) -+ return 1; -+ return 0; -+} -+ -+static struct hlist_head *au_name_hash(struct au_nhash *nhash, -+ unsigned char *name, -+ unsigned int len) -+{ -+ unsigned int v; -+ /* const unsigned int magic_bit = 12; */ -+ -+ AuDebugOn(!nhash->nh_num || !nhash->nh_head); -+ -+ v = 0; -+ if (len > 8) -+ len = 8; -+ while (len--) -+ v += *name++; -+ /* v = hash_long(v, magic_bit); */ -+ v %= nhash->nh_num; -+ return nhash->nh_head + v; -+} -+ -+static int au_nhash_test_name(struct au_vdir_destr *str, const char *name, -+ int nlen) -+{ -+ return str->len == nlen && !memcmp(str->name, name, nlen); -+} -+ -+/* returns found or not */ -+int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen) -+{ -+ struct hlist_head *head; -+ struct au_vdir_wh *pos; -+ struct au_vdir_destr *str; -+ -+ head = au_name_hash(whlist, name, nlen); -+ hlist_for_each_entry(pos, head, wh_hash) { -+ str = &pos->wh_str; -+ AuDbg("%.*s\n", str->len, str->name); -+ if (au_nhash_test_name(str, name, nlen)) -+ return 1; -+ } -+ return 0; -+} -+ -+/* returns found(true) or not */ -+static int test_known(struct au_nhash *delist, char *name, int nlen) -+{ -+ struct hlist_head *head; -+ struct au_vdir_dehstr *pos; -+ struct au_vdir_destr *str; -+ -+ head = au_name_hash(delist, name, nlen); -+ hlist_for_each_entry(pos, head, hash) { -+ str = pos->str; -+ AuDbg("%.*s\n", str->len, str->name); -+ if (au_nhash_test_name(str, name, nlen)) -+ return 1; -+ } -+ return 0; -+} -+ -+static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino, -+ unsigned char d_type) -+{ -+#ifdef CONFIG_AUFS_SHWH -+ wh->wh_ino = ino; -+ wh->wh_type = d_type; -+#endif -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino, -+ unsigned int d_type, aufs_bindex_t bindex, -+ unsigned char shwh) -+{ -+ int err; -+ struct au_vdir_destr *str; -+ struct au_vdir_wh *wh; -+ -+ AuDbg("%.*s\n", nlen, name); -+ AuDebugOn(!whlist->nh_num || !whlist->nh_head); -+ -+ err = -ENOMEM; -+ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS); -+ if (unlikely(!wh)) -+ goto out; -+ -+ err = 0; -+ wh->wh_bindex = bindex; -+ if (shwh) -+ au_shwh_init_wh(wh, ino, d_type); -+ str = &wh->wh_str; -+ str->len = nlen; -+ memcpy(str->name, name, nlen); -+ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen)); -+ /* smp_mb(); */ -+ -+out: -+ return err; -+} -+ -+static int append_deblk(struct au_vdir *vdir) -+{ -+ int err; -+ unsigned long ul; -+ const unsigned int deblk_sz = vdir->vd_deblk_sz; -+ union au_vdir_deblk_p p, deblk_end; -+ unsigned char **o; -+ -+ err = -ENOMEM; -+ o = au_krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1), -+ GFP_NOFS, /*may_shrink*/0); -+ if (unlikely(!o)) -+ goto out; -+ -+ vdir->vd_deblk = o; -+ p.deblk = kmalloc(deblk_sz, GFP_NOFS); -+ if (p.deblk) { -+ ul = vdir->vd_nblk++; -+ vdir->vd_deblk[ul] = p.deblk; -+ vdir->vd_last.ul = ul; -+ vdir->vd_last.p.deblk = p.deblk; -+ deblk_end.deblk = p.deblk + deblk_sz; -+ err = set_deblk_end(&p, &deblk_end); -+ } -+ -+out: -+ return err; -+} -+ -+static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino, -+ unsigned int d_type, struct au_nhash *delist) -+{ -+ int err; -+ unsigned int sz; -+ const unsigned int deblk_sz = vdir->vd_deblk_sz; -+ union au_vdir_deblk_p p, *room, deblk_end; -+ struct au_vdir_dehstr *dehstr; -+ -+ p.deblk = last_deblk(vdir); -+ deblk_end.deblk = p.deblk + deblk_sz; -+ room = &vdir->vd_last.p; -+ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk -+ || !is_deblk_end(room, &deblk_end)); -+ -+ sz = calc_size(nlen); -+ if (unlikely(sz > deblk_end.deblk - room->deblk)) { -+ err = append_deblk(vdir); -+ if (unlikely(err)) -+ goto out; -+ -+ p.deblk = last_deblk(vdir); -+ deblk_end.deblk = p.deblk + deblk_sz; -+ /* smp_mb(); */ -+ AuDebugOn(room->deblk != p.deblk); -+ } -+ -+ err = -ENOMEM; -+ dehstr = au_cache_alloc_vdir_dehstr(); -+ if (unlikely(!dehstr)) -+ goto out; -+ -+ dehstr->str = &room->de->de_str; -+ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen)); -+ room->de->de_ino = ino; -+ room->de->de_type = d_type; -+ room->de->de_str.len = nlen; -+ memcpy(room->de->de_str.name, name, nlen); -+ -+ err = 0; -+ room->deblk += sz; -+ if (unlikely(set_deblk_end(room, &deblk_end))) -+ err = append_deblk(vdir); -+ /* smp_mb(); */ -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_vdir_free(struct au_vdir *vdir) -+{ -+ unsigned char **deblk; -+ -+ deblk = vdir->vd_deblk; -+ while (vdir->vd_nblk--) -+ kfree(*deblk++); -+ kfree(vdir->vd_deblk); -+ au_cache_free_vdir(vdir); -+} -+ -+static struct au_vdir *alloc_vdir(struct file *file) -+{ -+ struct au_vdir *vdir; -+ struct super_block *sb; -+ int err; -+ -+ sb = file->f_path.dentry->d_sb; -+ SiMustAnyLock(sb); -+ -+ err = -ENOMEM; -+ vdir = au_cache_alloc_vdir(); -+ if (unlikely(!vdir)) -+ goto out; -+ -+ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS); -+ if (unlikely(!vdir->vd_deblk)) -+ goto out_free; -+ -+ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk; -+ if (!vdir->vd_deblk_sz) { -+ /* estimate the appropriate size for deblk */ -+ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL); -+ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */ -+ } -+ vdir->vd_nblk = 0; -+ vdir->vd_version = 0; -+ vdir->vd_jiffy = 0; -+ err = append_deblk(vdir); -+ if (!err) -+ return vdir; /* success */ -+ -+ kfree(vdir->vd_deblk); -+ -+out_free: -+ au_cache_free_vdir(vdir); -+out: -+ vdir = ERR_PTR(err); -+ return vdir; -+} -+ -+static int reinit_vdir(struct au_vdir *vdir) -+{ -+ int err; -+ union au_vdir_deblk_p p, deblk_end; -+ -+ while (vdir->vd_nblk > 1) { -+ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]); -+ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */ -+ vdir->vd_nblk--; -+ } -+ p.deblk = vdir->vd_deblk[0]; -+ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz; -+ err = set_deblk_end(&p, &deblk_end); -+ /* keep vd_dblk_sz */ -+ vdir->vd_last.ul = 0; -+ vdir->vd_last.p.deblk = vdir->vd_deblk[0]; -+ vdir->vd_version = 0; -+ vdir->vd_jiffy = 0; -+ /* smp_mb(); */ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define AuFillVdir_CALLED 1 -+#define AuFillVdir_WHABLE (1 << 1) -+#define AuFillVdir_SHWH (1 << 2) -+#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name) -+#define au_fset_fillvdir(flags, name) \ -+ do { (flags) |= AuFillVdir_##name; } while (0) -+#define au_fclr_fillvdir(flags, name) \ -+ do { (flags) &= ~AuFillVdir_##name; } while (0) -+ -+#ifndef CONFIG_AUFS_SHWH -+#undef AuFillVdir_SHWH -+#define AuFillVdir_SHWH 0 -+#endif -+ -+struct fillvdir_arg { -+ struct dir_context ctx; -+ struct file *file; -+ struct au_vdir *vdir; -+ struct au_nhash delist; -+ struct au_nhash whlist; -+ aufs_bindex_t bindex; -+ unsigned int flags; -+ int err; -+}; -+ -+static int fillvdir(struct dir_context *ctx, const char *__name, int nlen, -+ loff_t offset __maybe_unused, u64 h_ino, -+ unsigned int d_type) -+{ -+ struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx); -+ char *name = (void *)__name; -+ struct super_block *sb; -+ ino_t ino; -+ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH); -+ -+ arg->err = 0; -+ sb = arg->file->f_path.dentry->d_sb; -+ au_fset_fillvdir(arg->flags, CALLED); -+ /* smp_mb(); */ -+ if (nlen <= AUFS_WH_PFX_LEN -+ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { -+ if (test_known(&arg->delist, name, nlen) -+ || au_nhash_test_known_wh(&arg->whlist, name, nlen)) -+ goto out; /* already exists or whiteouted */ -+ -+ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino); -+ if (!arg->err) { -+ if (unlikely(nlen > AUFS_MAX_NAMELEN)) -+ d_type = DT_UNKNOWN; -+ arg->err = append_de(arg->vdir, name, nlen, ino, -+ d_type, &arg->delist); -+ } -+ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) { -+ name += AUFS_WH_PFX_LEN; -+ nlen -= AUFS_WH_PFX_LEN; -+ if (au_nhash_test_known_wh(&arg->whlist, name, nlen)) -+ goto out; /* already whiteouted */ -+ -+ ino = 0; /* just to suppress a warning */ -+ if (shwh) -+ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type, -+ &ino); -+ if (!arg->err) { -+ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN) -+ d_type = DT_UNKNOWN; -+ arg->err = au_nhash_append_wh -+ (&arg->whlist, name, nlen, ino, d_type, -+ arg->bindex, shwh); -+ } -+ } -+ -+out: -+ if (!arg->err) -+ arg->vdir->vd_jiffy = jiffies; -+ /* smp_mb(); */ -+ AuTraceErr(arg->err); -+ return arg->err; -+} -+ -+static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir, -+ struct au_nhash *whlist, struct au_nhash *delist) -+{ -+#ifdef CONFIG_AUFS_SHWH -+ int err; -+ unsigned int nh, u; -+ struct hlist_head *head; -+ struct au_vdir_wh *pos; -+ struct hlist_node *n; -+ char *p, *o; -+ struct au_vdir_destr *destr; -+ -+ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH)); -+ -+ err = -ENOMEM; -+ o = p = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!p)) -+ goto out; -+ -+ err = 0; -+ nh = whlist->nh_num; -+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); -+ p += AUFS_WH_PFX_LEN; -+ for (u = 0; u < nh; u++) { -+ head = whlist->nh_head + u; -+ hlist_for_each_entry_safe(pos, n, head, wh_hash) { -+ destr = &pos->wh_str; -+ memcpy(p, destr->name, destr->len); -+ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN, -+ pos->wh_ino, pos->wh_type, delist); -+ if (unlikely(err)) -+ break; -+ } -+ } -+ -+ free_page((unsigned long)o); -+ -+out: -+ AuTraceErr(err); -+ return err; -+#else -+ return 0; -+#endif -+} -+ -+static int au_do_read_vdir(struct fillvdir_arg *arg) -+{ -+ int err; -+ unsigned int rdhash; -+ loff_t offset; -+ aufs_bindex_t bbot, bindex, btop; -+ unsigned char shwh; -+ struct file *hf, *file; -+ struct super_block *sb; -+ -+ file = arg->file; -+ sb = file->f_path.dentry->d_sb; -+ SiMustAnyLock(sb); -+ -+ rdhash = au_sbi(sb)->si_rdhash; -+ if (!rdhash) -+ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL)); -+ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS); -+ if (unlikely(err)) -+ goto out_delist; -+ -+ err = 0; -+ arg->flags = 0; -+ shwh = 0; -+ if (au_opt_test(au_mntflags(sb), SHWH)) { -+ shwh = 1; -+ au_fset_fillvdir(arg->flags, SHWH); -+ } -+ btop = au_fbtop(file); -+ bbot = au_fbbot_dir(file); -+ for (bindex = btop; !err && bindex <= bbot; bindex++) { -+ hf = au_hf_dir(file, bindex); -+ if (!hf) -+ continue; -+ -+ offset = vfsub_llseek(hf, 0, SEEK_SET); -+ err = offset; -+ if (unlikely(offset)) -+ break; -+ -+ arg->bindex = bindex; -+ au_fclr_fillvdir(arg->flags, WHABLE); -+ if (shwh -+ || (bindex != bbot -+ && au_br_whable(au_sbr_perm(sb, bindex)))) -+ au_fset_fillvdir(arg->flags, WHABLE); -+ do { -+ arg->err = 0; -+ au_fclr_fillvdir(arg->flags, CALLED); -+ /* smp_mb(); */ -+ err = vfsub_iterate_dir(hf, &arg->ctx); -+ if (err >= 0) -+ err = arg->err; -+ } while (!err && au_ftest_fillvdir(arg->flags, CALLED)); -+ -+ /* -+ * dir_relax() may be good for concurrency, but aufs should not -+ * use it since it will cause a lockdep problem. -+ */ -+ } -+ -+ if (!err && shwh) -+ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist); -+ -+ au_nhash_wh_free(&arg->whlist); -+ -+out_delist: -+ au_nhash_de_free(&arg->delist); -+out: -+ return err; -+} -+ -+static int read_vdir(struct file *file, int may_read) -+{ -+ int err; -+ unsigned long expire; -+ unsigned char do_read; -+ struct fillvdir_arg arg = { -+ .ctx = { -+ .actor = fillvdir -+ } -+ }; -+ struct inode *inode; -+ struct au_vdir *vdir, *allocated; -+ -+ err = 0; -+ inode = file_inode(file); -+ IMustLock(inode); -+ IiMustWriteLock(inode); -+ SiMustAnyLock(inode->i_sb); -+ -+ allocated = NULL; -+ do_read = 0; -+ expire = au_sbi(inode->i_sb)->si_rdcache; -+ vdir = au_ivdir(inode); -+ if (!vdir) { -+ do_read = 1; -+ vdir = alloc_vdir(file); -+ err = PTR_ERR(vdir); -+ if (IS_ERR(vdir)) -+ goto out; -+ err = 0; -+ allocated = vdir; -+ } else if (may_read -+ && (!inode_eq_iversion(inode, vdir->vd_version) -+ || time_after(jiffies, vdir->vd_jiffy + expire))) { -+ do_read = 1; -+ err = reinit_vdir(vdir); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ if (!do_read) -+ return 0; /* success */ -+ -+ arg.file = file; -+ arg.vdir = vdir; -+ err = au_do_read_vdir(&arg); -+ if (!err) { -+ /* file->f_pos = 0; */ /* todo: ctx->pos? */ -+ vdir->vd_version = inode_query_iversion(inode); -+ vdir->vd_last.ul = 0; -+ vdir->vd_last.p.deblk = vdir->vd_deblk[0]; -+ if (allocated) -+ au_set_ivdir(inode, allocated); -+ } else if (allocated) -+ au_vdir_free(allocated); -+ -+out: -+ return err; -+} -+ -+static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src) -+{ -+ int err, rerr; -+ unsigned long ul, n; -+ const unsigned int deblk_sz = src->vd_deblk_sz; -+ -+ AuDebugOn(tgt->vd_nblk != 1); -+ -+ err = -ENOMEM; -+ if (tgt->vd_nblk < src->vd_nblk) { -+ unsigned char **p; -+ -+ p = au_krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk, -+ GFP_NOFS, /*may_shrink*/0); -+ if (unlikely(!p)) -+ goto out; -+ tgt->vd_deblk = p; -+ } -+ -+ if (tgt->vd_deblk_sz != deblk_sz) { -+ unsigned char *p; -+ -+ tgt->vd_deblk_sz = deblk_sz; -+ p = au_krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS, -+ /*may_shrink*/1); -+ if (unlikely(!p)) -+ goto out; -+ tgt->vd_deblk[0] = p; -+ } -+ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz); -+ tgt->vd_version = src->vd_version; -+ tgt->vd_jiffy = src->vd_jiffy; -+ -+ n = src->vd_nblk; -+ for (ul = 1; ul < n; ul++) { -+ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz, -+ GFP_NOFS); -+ if (unlikely(!tgt->vd_deblk[ul])) -+ goto out; -+ tgt->vd_nblk++; -+ } -+ tgt->vd_nblk = n; -+ tgt->vd_last.ul = tgt->vd_last.ul; -+ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul]; -+ tgt->vd_last.p.deblk += src->vd_last.p.deblk -+ - src->vd_deblk[src->vd_last.ul]; -+ /* smp_mb(); */ -+ return 0; /* success */ -+ -+out: -+ rerr = reinit_vdir(tgt); -+ BUG_ON(rerr); -+ return err; -+} -+ -+int au_vdir_init(struct file *file) -+{ -+ int err; -+ struct inode *inode; -+ struct au_vdir *vdir_cache, *allocated; -+ -+ /* test file->f_pos here instead of ctx->pos */ -+ err = read_vdir(file, !file->f_pos); -+ if (unlikely(err)) -+ goto out; -+ -+ allocated = NULL; -+ vdir_cache = au_fvdir_cache(file); -+ if (!vdir_cache) { -+ vdir_cache = alloc_vdir(file); -+ err = PTR_ERR(vdir_cache); -+ if (IS_ERR(vdir_cache)) -+ goto out; -+ allocated = vdir_cache; -+ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) { -+ /* test file->f_pos here instead of ctx->pos */ -+ err = reinit_vdir(vdir_cache); -+ if (unlikely(err)) -+ goto out; -+ } else -+ return 0; /* success */ -+ -+ inode = file_inode(file); -+ err = copy_vdir(vdir_cache, au_ivdir(inode)); -+ if (!err) { -+ file->f_version = inode_query_iversion(inode); -+ if (allocated) -+ au_set_fvdir_cache(file, allocated); -+ } else if (allocated) -+ au_vdir_free(allocated); -+ -+out: -+ return err; -+} -+ -+static loff_t calc_offset(struct au_vdir *vdir) -+{ -+ loff_t offset; -+ union au_vdir_deblk_p p; -+ -+ p.deblk = vdir->vd_deblk[vdir->vd_last.ul]; -+ offset = vdir->vd_last.p.deblk - p.deblk; -+ offset += vdir->vd_deblk_sz * vdir->vd_last.ul; -+ return offset; -+} -+ -+/* returns true or false */ -+static int seek_vdir(struct file *file, struct dir_context *ctx) -+{ -+ int valid; -+ unsigned int deblk_sz; -+ unsigned long ul, n; -+ loff_t offset; -+ union au_vdir_deblk_p p, deblk_end; -+ struct au_vdir *vdir_cache; -+ -+ valid = 1; -+ vdir_cache = au_fvdir_cache(file); -+ offset = calc_offset(vdir_cache); -+ AuDbg("offset %lld\n", offset); -+ if (ctx->pos == offset) -+ goto out; -+ -+ vdir_cache->vd_last.ul = 0; -+ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0]; -+ if (!ctx->pos) -+ goto out; -+ -+ valid = 0; -+ deblk_sz = vdir_cache->vd_deblk_sz; -+ ul = div64_u64(ctx->pos, deblk_sz); -+ AuDbg("ul %lu\n", ul); -+ if (ul >= vdir_cache->vd_nblk) -+ goto out; -+ -+ n = vdir_cache->vd_nblk; -+ for (; ul < n; ul++) { -+ p.deblk = vdir_cache->vd_deblk[ul]; -+ deblk_end.deblk = p.deblk + deblk_sz; -+ offset = ul; -+ offset *= deblk_sz; -+ while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) { -+ unsigned int l; -+ -+ l = calc_size(p.de->de_str.len); -+ offset += l; -+ p.deblk += l; -+ } -+ if (!is_deblk_end(&p, &deblk_end)) { -+ valid = 1; -+ vdir_cache->vd_last.ul = ul; -+ vdir_cache->vd_last.p = p; -+ break; -+ } -+ } -+ -+out: -+ /* smp_mb(); */ -+ if (!valid) -+ AuDbg("valid %d\n", !valid); -+ return valid; -+} -+ -+int au_vdir_fill_de(struct file *file, struct dir_context *ctx) -+{ -+ unsigned int l, deblk_sz; -+ union au_vdir_deblk_p deblk_end; -+ struct au_vdir *vdir_cache; -+ struct au_vdir_de *de; -+ -+ if (!seek_vdir(file, ctx)) -+ return 0; -+ -+ vdir_cache = au_fvdir_cache(file); -+ deblk_sz = vdir_cache->vd_deblk_sz; -+ while (1) { -+ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul]; -+ deblk_end.deblk += deblk_sz; -+ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) { -+ de = vdir_cache->vd_last.p.de; -+ AuDbg("%.*s, off%lld, i%lu, dt%d\n", -+ de->de_str.len, de->de_str.name, ctx->pos, -+ (unsigned long)de->de_ino, de->de_type); -+ if (unlikely(!dir_emit(ctx, de->de_str.name, -+ de->de_str.len, de->de_ino, -+ de->de_type))) { -+ /* todo: ignore the error caused by udba? */ -+ /* return err; */ -+ return 0; -+ } -+ -+ l = calc_size(de->de_str.len); -+ vdir_cache->vd_last.p.deblk += l; -+ ctx->pos += l; -+ } -+ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) { -+ vdir_cache->vd_last.ul++; -+ vdir_cache->vd_last.p.deblk -+ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul]; -+ ctx->pos = deblk_sz * vdir_cache->vd_last.ul; -+ continue; -+ } -+ break; -+ } -+ -+ /* smp_mb(); */ -+ return 0; -+} -diff --git a/fs/aufs/vfsub.c b/fs/aufs/vfsub.c -new file mode 100644 -index 000000000..de22e6eae ---- /dev/null -+++ b/fs/aufs/vfsub.c -@@ -0,0 +1,902 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * sub-routines for VFS -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "aufs.h" -+ -+#ifdef CONFIG_AUFS_BR_FUSE -+int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb) -+{ -+ if (!au_test_fuse(h_sb) || !au_userns) -+ return 0; -+ -+ return is_current_mnt_ns(mnt) ? 0 : -EACCES; -+} -+#endif -+ -+int vfsub_sync_filesystem(struct super_block *h_sb, int wait) -+{ -+ int err; -+ -+ lockdep_off(); -+ down_read(&h_sb->s_umount); -+ err = __sync_filesystem(h_sb, wait); -+ up_read(&h_sb->s_umount); -+ lockdep_on(); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int vfsub_update_h_iattr(struct path *h_path, int *did) -+{ -+ int err; -+ struct kstat st; -+ struct super_block *h_sb; -+ -+ /* for remote fs, leave work for its getattr or d_revalidate */ -+ /* for bad i_attr fs, handle them in aufs_getattr() */ -+ /* still some fs may acquire i_mutex. we need to skip them */ -+ err = 0; -+ if (!did) -+ did = &err; -+ h_sb = h_path->dentry->d_sb; -+ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb)); -+ if (*did) -+ err = vfsub_getattr(h_path, &st); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct file *vfsub_dentry_open(struct path *path, int flags) -+{ -+ struct file *file; -+ -+ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */, -+ current_cred()); -+ if (!IS_ERR_OR_NULL(file) -+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) -+ i_readcount_inc(d_inode(path->dentry)); -+ -+ return file; -+} -+ -+struct file *vfsub_filp_open(const char *path, int oflags, int mode) -+{ -+ struct file *file; -+ -+ lockdep_off(); -+ file = filp_open(path, -+ oflags /* | __FMODE_NONOTIFY */, -+ mode); -+ lockdep_on(); -+ if (IS_ERR(file)) -+ goto out; -+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ -+ -+out: -+ return file; -+} -+ -+/* -+ * Ideally this function should call VFS:do_last() in order to keep all its -+ * checkings. But it is very hard for aufs to regenerate several VFS internal -+ * structure such as nameidata. This is a second (or third) best approach. -+ * cf. linux/fs/namei.c:do_last(), lookup_open() and atomic_open(). -+ */ -+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry, -+ struct vfsub_aopen_args *args) -+{ -+ int err; -+ struct au_branch *br = args->br; -+ struct file *file = args->file; -+ /* copied from linux/fs/namei.c:atomic_open() */ -+ struct dentry *const DENTRY_NOT_SET = (void *)-1UL; -+ -+ IMustLock(dir); -+ AuDebugOn(!dir->i_op->atomic_open); -+ -+ err = au_br_test_oflag(args->open_flag, br); -+ if (unlikely(err)) -+ goto out; -+ -+ au_lcnt_inc(&br->br_nfiles); -+ file->f_path.dentry = DENTRY_NOT_SET; -+ file->f_path.mnt = au_br_mnt(br); -+ AuDbg("%ps\n", dir->i_op->atomic_open); -+ err = dir->i_op->atomic_open(dir, dentry, file, args->open_flag, -+ args->create_mode); -+ if (unlikely(err < 0)) { -+ au_lcnt_dec(&br->br_nfiles); -+ goto out; -+ } -+ -+ /* temporary workaround for nfsv4 branch */ -+ if (au_test_nfs(dir->i_sb)) -+ nfs_mark_for_revalidate(dir); -+ -+ if (file->f_mode & FMODE_CREATED) -+ fsnotify_create(dir, dentry); -+ if (!(file->f_mode & FMODE_OPENED)) { -+ au_lcnt_dec(&br->br_nfiles); -+ goto out; -+ } -+ -+ /* todo: call VFS:may_open() here */ -+ /* todo: ima_file_check() too? */ -+ if (!err && (args->open_flag & __FMODE_EXEC)) -+ err = deny_write_access(file); -+ if (!err) -+ fsnotify_open(file); -+ else -+ au_lcnt_dec(&br->br_nfiles); -+ /* note that the file is created and still opened */ -+ -+out: -+ return err; -+} -+ -+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path) -+{ -+ int err; -+ -+ err = kern_path(name, flags, path); -+ if (!err && d_is_positive(path->dentry)) -+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/ -+ return err; -+} -+ -+struct dentry *vfsub_lookup_one_len_unlocked(const char *name, -+ struct dentry *parent, int len) -+{ -+ struct path path = { -+ .mnt = NULL -+ }; -+ -+ path.dentry = lookup_one_len_unlocked(name, parent, len); -+ if (IS_ERR(path.dentry)) -+ goto out; -+ if (d_is_positive(path.dentry)) -+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/ -+ -+out: -+ AuTraceErrPtr(path.dentry); -+ return path.dentry; -+} -+ -+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, -+ int len) -+{ -+ struct path path = { -+ .mnt = NULL -+ }; -+ -+ /* VFS checks it too, but by WARN_ON_ONCE() */ -+ IMustLock(d_inode(parent)); -+ -+ path.dentry = lookup_one_len(name, parent, len); -+ if (IS_ERR(path.dentry)) -+ goto out; -+ if (d_is_positive(path.dentry)) -+ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/ -+ -+out: -+ AuTraceErrPtr(path.dentry); -+ return path.dentry; -+} -+ -+void vfsub_call_lkup_one(void *args) -+{ -+ struct vfsub_lkup_one_args *a = args; -+ *a->errp = vfsub_lkup_one(a->name, a->parent); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1, -+ struct dentry *d2, struct au_hinode *hdir2) -+{ -+ struct dentry *d; -+ -+ lockdep_off(); -+ d = lock_rename(d1, d2); -+ lockdep_on(); -+ au_hn_suspend(hdir1); -+ if (hdir1 != hdir2) -+ au_hn_suspend(hdir2); -+ -+ return d; -+} -+ -+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1, -+ struct dentry *d2, struct au_hinode *hdir2) -+{ -+ au_hn_resume(hdir1); -+ if (hdir1 != hdir2) -+ au_hn_resume(hdir2); -+ lockdep_off(); -+ unlock_rename(d1, d2); -+ lockdep_on(); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl) -+{ -+ int err; -+ struct dentry *d; -+ -+ IMustLock(dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_mknod(path, d, mode, 0); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_create(dir, path->dentry, mode, want_excl); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = *path; -+ int did; -+ -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = path->dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+int vfsub_symlink(struct inode *dir, struct path *path, const char *symname) -+{ -+ int err; -+ struct dentry *d; -+ -+ IMustLock(dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_symlink(path, d, symname); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_symlink(dir, path->dentry, symname); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = *path; -+ int did; -+ -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = path->dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev) -+{ -+ int err; -+ struct dentry *d; -+ -+ IMustLock(dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_mknod(path, d, mode, new_encode_dev(dev)); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_mknod(dir, path->dentry, mode, dev); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = *path; -+ int did; -+ -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = path->dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+static int au_test_nlink(struct inode *inode) -+{ -+ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */ -+ -+ if (!au_test_fs_no_limit_nlink(inode->i_sb) -+ || inode->i_nlink < link_max) -+ return 0; -+ return -EMLINK; -+} -+ -+int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path, -+ struct inode **delegated_inode) -+{ -+ int err; -+ struct dentry *d; -+ -+ IMustLock(dir); -+ -+ err = au_test_nlink(d_inode(src_dentry)); -+ if (unlikely(err)) -+ return err; -+ -+ /* we don't call may_linkat() */ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_link(src_dentry, path, d); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_link(src_dentry, dir, path->dentry, delegated_inode); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = *path; -+ int did; -+ -+ /* fuse has different memory inode for the same inumber */ -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = path->dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ tmp.dentry = src_dentry; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, -+ struct inode *dir, struct path *path, -+ struct inode **delegated_inode, unsigned int flags) -+{ -+ int err; -+ struct path tmp = { -+ .mnt = path->mnt -+ }; -+ struct dentry *d; -+ -+ IMustLock(dir); -+ IMustLock(src_dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ tmp.dentry = src_dentry->d_parent; -+ err = security_path_rename(&tmp, src_dentry, path, d, /*flags*/0); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_rename(src_dir, src_dentry, dir, path->dentry, -+ delegated_inode, flags); -+ lockdep_on(); -+ if (!err) { -+ int did; -+ -+ tmp.dentry = d->d_parent; -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = src_dentry; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ tmp.dentry = src_dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+int vfsub_mkdir(struct inode *dir, struct path *path, int mode) -+{ -+ int err; -+ struct dentry *d; -+ -+ IMustLock(dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_mkdir(path, d, mode); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_mkdir(dir, path->dentry, mode); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = *path; -+ int did; -+ -+ vfsub_update_h_iattr(&tmp, &did); -+ if (did) { -+ tmp.dentry = path->dentry->d_parent; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); -+ } -+ /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+int vfsub_rmdir(struct inode *dir, struct path *path) -+{ -+ int err; -+ struct dentry *d; -+ -+ IMustLock(dir); -+ -+ d = path->dentry; -+ path->dentry = d->d_parent; -+ err = security_path_rmdir(path, d); -+ path->dentry = d; -+ if (unlikely(err)) -+ goto out; -+ -+ lockdep_off(); -+ err = vfs_rmdir(dir, path->dentry); -+ lockdep_on(); -+ if (!err) { -+ struct path tmp = { -+ .dentry = path->dentry->d_parent, -+ .mnt = path->mnt -+ }; -+ -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/ -+ } -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* todo: support mmap_sem? */ -+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, -+ loff_t *ppos) -+{ -+ ssize_t err; -+ -+ lockdep_off(); -+ err = vfs_read(file, ubuf, count, ppos); -+ lockdep_on(); -+ if (err >= 0) -+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ -+ return err; -+} -+ -+/* todo: kernel_read()? */ -+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, -+ loff_t *ppos) -+{ -+ ssize_t err; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ char __user *u; -+ } buf; -+ -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ err = vfsub_read_u(file, buf.u, count, ppos); -+ set_fs(oldfs); -+ return err; -+} -+ -+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, -+ loff_t *ppos) -+{ -+ ssize_t err; -+ -+ lockdep_off(); -+ err = vfs_write(file, ubuf, count, ppos); -+ lockdep_on(); -+ if (err >= 0) -+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ -+ return err; -+} -+ -+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos) -+{ -+ ssize_t err; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ const char __user *u; -+ } buf; -+ -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ err = vfsub_write_u(file, buf.u, count, ppos); -+ set_fs(oldfs); -+ return err; -+} -+ -+int vfsub_flush(struct file *file, fl_owner_t id) -+{ -+ int err; -+ -+ err = 0; -+ if (file->f_op->flush) { -+ if (!au_test_nfs(file->f_path.dentry->d_sb)) -+ err = file->f_op->flush(file, id); -+ else { -+ lockdep_off(); -+ err = file->f_op->flush(file, id); -+ lockdep_on(); -+ } -+ if (!err) -+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); -+ /*ignore*/ -+ } -+ return err; -+} -+ -+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx) -+{ -+ int err; -+ -+ AuDbg("%pD, ctx{%ps, %llu}\n", file, ctx->actor, ctx->pos); -+ -+ lockdep_off(); -+ err = iterate_dir(file, ctx); -+ lockdep_on(); -+ if (err >= 0) -+ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ -+ -+ return err; -+} -+ -+long vfsub_splice_to(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags) -+{ -+ long err; -+ -+ lockdep_off(); -+ err = do_splice_to(in, ppos, pipe, len, flags); -+ lockdep_on(); -+ file_accessed(in); -+ if (err >= 0) -+ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/ -+ return err; -+} -+ -+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, -+ loff_t *ppos, size_t len, unsigned int flags) -+{ -+ long err; -+ -+ lockdep_off(); -+ err = do_splice_from(pipe, out, ppos, len, flags); -+ lockdep_on(); -+ if (err >= 0) -+ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/ -+ return err; -+} -+ -+int vfsub_fsync(struct file *file, struct path *path, int datasync) -+{ -+ int err; -+ -+ /* file can be NULL */ -+ lockdep_off(); -+ err = vfs_fsync(file, datasync); -+ lockdep_on(); -+ if (!err) { -+ if (!path) { -+ AuDebugOn(!file); -+ path = &file->f_path; -+ } -+ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/ -+ } -+ return err; -+} -+ -+/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */ -+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr, -+ struct file *h_file) -+{ -+ int err; -+ struct inode *h_inode; -+ struct super_block *h_sb; -+ -+ if (!h_file) { -+ err = vfsub_truncate(h_path, length); -+ goto out; -+ } -+ -+ h_inode = d_inode(h_path->dentry); -+ h_sb = h_inode->i_sb; -+ lockdep_off(); -+ sb_start_write(h_sb); -+ lockdep_on(); -+ err = locks_verify_truncate(h_inode, h_file, length); -+ if (!err) -+ err = security_path_truncate(h_path); -+ if (!err) { -+ lockdep_off(); -+ err = do_truncate(h_path->dentry, length, attr, h_file); -+ lockdep_on(); -+ } -+ lockdep_off(); -+ sb_end_write(h_sb); -+ lockdep_on(); -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_vfsub_mkdir_args { -+ int *errp; -+ struct inode *dir; -+ struct path *path; -+ int mode; -+}; -+ -+static void au_call_vfsub_mkdir(void *args) -+{ -+ struct au_vfsub_mkdir_args *a = args; -+ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode); -+} -+ -+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode) -+{ -+ int err, do_sio, wkq_err; -+ -+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE); -+ if (!do_sio) { -+ lockdep_off(); -+ err = vfsub_mkdir(dir, path, mode); -+ lockdep_on(); -+ } else { -+ struct au_vfsub_mkdir_args args = { -+ .errp = &err, -+ .dir = dir, -+ .path = path, -+ .mode = mode -+ }; -+ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ return err; -+} -+ -+struct au_vfsub_rmdir_args { -+ int *errp; -+ struct inode *dir; -+ struct path *path; -+}; -+ -+static void au_call_vfsub_rmdir(void *args) -+{ -+ struct au_vfsub_rmdir_args *a = args; -+ *a->errp = vfsub_rmdir(a->dir, a->path); -+} -+ -+int vfsub_sio_rmdir(struct inode *dir, struct path *path) -+{ -+ int err, do_sio, wkq_err; -+ -+ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE); -+ if (!do_sio) { -+ lockdep_off(); -+ err = vfsub_rmdir(dir, path); -+ lockdep_on(); -+ } else { -+ struct au_vfsub_rmdir_args args = { -+ .errp = &err, -+ .dir = dir, -+ .path = path -+ }; -+ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct notify_change_args { -+ int *errp; -+ struct path *path; -+ struct iattr *ia; -+ struct inode **delegated_inode; -+}; -+ -+static void call_notify_change(void *args) -+{ -+ struct notify_change_args *a = args; -+ struct inode *h_inode; -+ -+ h_inode = d_inode(a->path->dentry); -+ IMustLock(h_inode); -+ -+ *a->errp = -EPERM; -+ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) { -+ lockdep_off(); -+ *a->errp = notify_change(a->path->dentry, a->ia, -+ a->delegated_inode); -+ lockdep_on(); -+ if (!*a->errp) -+ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/ -+ } -+ AuTraceErr(*a->errp); -+} -+ -+int vfsub_notify_change(struct path *path, struct iattr *ia, -+ struct inode **delegated_inode) -+{ -+ int err; -+ struct notify_change_args args = { -+ .errp = &err, -+ .path = path, -+ .ia = ia, -+ .delegated_inode = delegated_inode -+ }; -+ -+ call_notify_change(&args); -+ -+ return err; -+} -+ -+int vfsub_sio_notify_change(struct path *path, struct iattr *ia, -+ struct inode **delegated_inode) -+{ -+ int err, wkq_err; -+ struct notify_change_args args = { -+ .errp = &err, -+ .path = path, -+ .ia = ia, -+ .delegated_inode = delegated_inode -+ }; -+ -+ wkq_err = au_wkq_wait(call_notify_change, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct unlink_args { -+ int *errp; -+ struct inode *dir; -+ struct path *path; -+ struct inode **delegated_inode; -+}; -+ -+static void call_unlink(void *args) -+{ -+ struct unlink_args *a = args; -+ struct dentry *d = a->path->dentry; -+ struct inode *h_inode; -+ const int stop_sillyrename = (au_test_nfs(d->d_sb) -+ && au_dcount(d) == 1); -+ -+ IMustLock(a->dir); -+ -+ a->path->dentry = d->d_parent; -+ *a->errp = security_path_unlink(a->path, d); -+ a->path->dentry = d; -+ if (unlikely(*a->errp)) -+ return; -+ -+ if (!stop_sillyrename) -+ dget(d); -+ h_inode = NULL; -+ if (d_is_positive(d)) { -+ h_inode = d_inode(d); -+ ihold(h_inode); -+ } -+ -+ lockdep_off(); -+ *a->errp = vfs_unlink(a->dir, d, a->delegated_inode); -+ lockdep_on(); -+ if (!*a->errp) { -+ struct path tmp = { -+ .dentry = d->d_parent, -+ .mnt = a->path->mnt -+ }; -+ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/ -+ } -+ -+ if (!stop_sillyrename) -+ dput(d); -+ if (h_inode) -+ iput(h_inode); -+ -+ AuTraceErr(*a->errp); -+} -+ -+/* -+ * @dir: must be locked. -+ * @dentry: target dentry. -+ */ -+int vfsub_unlink(struct inode *dir, struct path *path, -+ struct inode **delegated_inode, int force) -+{ -+ int err; -+ struct unlink_args args = { -+ .errp = &err, -+ .dir = dir, -+ .path = path, -+ .delegated_inode = delegated_inode -+ }; -+ -+ if (!force) -+ call_unlink(&args); -+ else { -+ int wkq_err; -+ -+ wkq_err = au_wkq_wait(call_unlink, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ -+ return err; -+} -diff --git a/fs/aufs/vfsub.h b/fs/aufs/vfsub.h -new file mode 100644 -index 000000000..c0564abaa ---- /dev/null -+++ b/fs/aufs/vfsub.h -@@ -0,0 +1,355 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * sub-routines for VFS -+ */ -+ -+#ifndef __AUFS_VFSUB_H__ -+#define __AUFS_VFSUB_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+#include -+#include "debug.h" -+ -+/* copied from linux/fs/internal.h */ -+/* todo: BAD approach!! */ -+extern void __mnt_drop_write(struct vfsmount *); -+extern struct file *alloc_empty_file(int, const struct cred *); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* lock subclass for lower inode */ -+/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */ -+/* reduce? gave up. */ -+enum { -+ AuLsc_I_Begin = I_MUTEX_PARENT2, /* 5 */ -+ AuLsc_I_PARENT, /* lower inode, parent first */ -+ AuLsc_I_PARENT2, /* copyup dirs */ -+ AuLsc_I_PARENT3, /* copyup wh */ -+ AuLsc_I_CHILD, -+ AuLsc_I_CHILD2, -+ AuLsc_I_End -+}; -+ -+/* to debug easier, do not make them inlined functions */ -+#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx)) -+#define IMustLock(i) AuDebugOn(!inode_is_locked(i)) -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline void vfsub_drop_nlink(struct inode *inode) -+{ -+ AuDebugOn(!inode->i_nlink); -+ drop_nlink(inode); -+} -+ -+static inline void vfsub_dead_dir(struct inode *inode) -+{ -+ AuDebugOn(!S_ISDIR(inode->i_mode)); -+ inode->i_flags |= S_DEAD; -+ clear_nlink(inode); -+} -+ -+static inline int vfsub_native_ro(struct inode *inode) -+{ -+ return sb_rdonly(inode->i_sb) -+ || IS_RDONLY(inode) -+ /* || IS_APPEND(inode) */ -+ || IS_IMMUTABLE(inode); -+} -+ -+#ifdef CONFIG_AUFS_BR_FUSE -+int vfsub_test_mntns(struct vfsmount *mnt, struct super_block *h_sb); -+#else -+AuStubInt0(vfsub_test_mntns, struct vfsmount *mnt, struct super_block *h_sb); -+#endif -+ -+int vfsub_sync_filesystem(struct super_block *h_sb, int wait); -+ -+/* ---------------------------------------------------------------------- */ -+ -+int vfsub_update_h_iattr(struct path *h_path, int *did); -+struct file *vfsub_dentry_open(struct path *path, int flags); -+struct file *vfsub_filp_open(const char *path, int oflags, int mode); -+struct au_branch; -+struct vfsub_aopen_args { -+ struct file *file; -+ unsigned int open_flag; -+ umode_t create_mode; -+ struct au_branch *br; -+}; -+int vfsub_atomic_open(struct inode *dir, struct dentry *dentry, -+ struct vfsub_aopen_args *args); -+int vfsub_kern_path(const char *name, unsigned int flags, struct path *path); -+ -+struct dentry *vfsub_lookup_one_len_unlocked(const char *name, -+ struct dentry *parent, int len); -+struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, -+ int len); -+ -+struct vfsub_lkup_one_args { -+ struct dentry **errp; -+ struct qstr *name; -+ struct dentry *parent; -+}; -+ -+static inline struct dentry *vfsub_lkup_one(struct qstr *name, -+ struct dentry *parent) -+{ -+ return vfsub_lookup_one_len(name->name, parent, name->len); -+} -+ -+void vfsub_call_lkup_one(void *args); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline int vfsub_mnt_want_write(struct vfsmount *mnt) -+{ -+ int err; -+ -+ lockdep_off(); -+ err = mnt_want_write(mnt); -+ lockdep_on(); -+ return err; -+} -+ -+static inline void vfsub_mnt_drop_write(struct vfsmount *mnt) -+{ -+ lockdep_off(); -+ mnt_drop_write(mnt); -+ lockdep_on(); -+} -+ -+#if 0 /* reserved */ -+static inline void vfsub_mnt_drop_write_file(struct file *file) -+{ -+ lockdep_off(); -+ mnt_drop_write_file(file); -+ lockdep_on(); -+} -+#endif -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_hinode; -+struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1, -+ struct dentry *d2, struct au_hinode *hdir2); -+void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1, -+ struct dentry *d2, struct au_hinode *hdir2); -+ -+int vfsub_create(struct inode *dir, struct path *path, int mode, -+ bool want_excl); -+int vfsub_symlink(struct inode *dir, struct path *path, -+ const char *symname); -+int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev); -+int vfsub_link(struct dentry *src_dentry, struct inode *dir, -+ struct path *path, struct inode **delegated_inode); -+int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry, -+ struct inode *hdir, struct path *path, -+ struct inode **delegated_inode, unsigned int flags); -+int vfsub_mkdir(struct inode *dir, struct path *path, int mode); -+int vfsub_rmdir(struct inode *dir, struct path *path); -+ -+/* ---------------------------------------------------------------------- */ -+ -+ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, -+ loff_t *ppos); -+ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, -+ loff_t *ppos); -+ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, -+ loff_t *ppos); -+ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, -+ loff_t *ppos); -+int vfsub_flush(struct file *file, fl_owner_t id); -+int vfsub_iterate_dir(struct file *file, struct dir_context *ctx); -+ -+static inline loff_t vfsub_f_size_read(struct file *file) -+{ -+ return i_size_read(file_inode(file)); -+} -+ -+static inline unsigned int vfsub_file_flags(struct file *file) -+{ -+ unsigned int flags; -+ -+ spin_lock(&file->f_lock); -+ flags = file->f_flags; -+ spin_unlock(&file->f_lock); -+ -+ return flags; -+} -+ -+static inline int vfsub_file_execed(struct file *file) -+{ -+ /* todo: direct access f_flags */ -+ return !!(vfsub_file_flags(file) & __FMODE_EXEC); -+} -+ -+#if 0 /* reserved */ -+static inline void vfsub_file_accessed(struct file *h_file) -+{ -+ file_accessed(h_file); -+ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/ -+} -+#endif -+ -+#if 0 /* reserved */ -+static inline void vfsub_touch_atime(struct vfsmount *h_mnt, -+ struct dentry *h_dentry) -+{ -+ struct path h_path = { -+ .dentry = h_dentry, -+ .mnt = h_mnt -+ }; -+ touch_atime(&h_path); -+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/ -+} -+#endif -+ -+static inline int vfsub_update_time(struct inode *h_inode, -+ struct timespec64 *ts, int flags) -+{ -+ return update_time(h_inode, ts, flags); -+ /* no vfsub_update_h_iattr() since we don't have struct path */ -+} -+ -+#ifdef CONFIG_FS_POSIX_ACL -+static inline int vfsub_acl_chmod(struct inode *h_inode, umode_t h_mode) -+{ -+ int err; -+ -+ err = posix_acl_chmod(h_inode, h_mode); -+ if (err == -EOPNOTSUPP) -+ err = 0; -+ return err; -+} -+#else -+AuStubInt0(vfsub_acl_chmod, struct inode *h_inode, umode_t h_mode); -+#endif -+ -+long vfsub_splice_to(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags); -+long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, -+ loff_t *ppos, size_t len, unsigned int flags); -+ -+static inline long vfsub_truncate(struct path *path, loff_t length) -+{ -+ long err; -+ -+ lockdep_off(); -+ err = vfs_truncate(path, length); -+ lockdep_on(); -+ return err; -+} -+ -+int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr, -+ struct file *h_file); -+int vfsub_fsync(struct file *file, struct path *path, int datasync); -+ -+/* -+ * re-use branch fs's ioctl(FICLONE) while aufs itself doesn't support such -+ * ioctl. -+ */ -+static inline int vfsub_clone_file_range(struct file *src, struct file *dst, -+ u64 len) -+{ -+ int err; -+ -+ lockdep_off(); -+ err = vfs_clone_file_range(src, 0, dst, 0, len); -+ lockdep_on(); -+ -+ return err; -+} -+ -+/* copy_file_range(2) is a systemcall */ -+static inline ssize_t vfsub_copy_file_range(struct file *src, loff_t src_pos, -+ struct file *dst, loff_t dst_pos, -+ size_t len, unsigned int flags) -+{ -+ ssize_t ssz; -+ -+ lockdep_off(); -+ ssz = vfs_copy_file_range(src, src_pos, dst, dst_pos, len, flags); -+ lockdep_on(); -+ -+ return ssz; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin) -+{ -+ loff_t err; -+ -+ lockdep_off(); -+ err = vfs_llseek(file, offset, origin); -+ lockdep_on(); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode); -+int vfsub_sio_rmdir(struct inode *dir, struct path *path); -+int vfsub_sio_notify_change(struct path *path, struct iattr *ia, -+ struct inode **delegated_inode); -+int vfsub_notify_change(struct path *path, struct iattr *ia, -+ struct inode **delegated_inode); -+int vfsub_unlink(struct inode *dir, struct path *path, -+ struct inode **delegated_inode, int force); -+ -+static inline int vfsub_getattr(const struct path *path, struct kstat *st) -+{ -+ return vfs_getattr(path, st, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline int vfsub_setxattr(struct dentry *dentry, const char *name, -+ const void *value, size_t size, int flags) -+{ -+ int err; -+ -+ lockdep_off(); -+ err = vfs_setxattr(dentry, name, value, size, flags); -+ lockdep_on(); -+ -+ return err; -+} -+ -+static inline int vfsub_removexattr(struct dentry *dentry, const char *name) -+{ -+ int err; -+ -+ lockdep_off(); -+ err = vfs_removexattr(dentry, name); -+ lockdep_on(); -+ -+ return err; -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_VFSUB_H__ */ -diff --git a/fs/aufs/wbr_policy.c b/fs/aufs/wbr_policy.c -new file mode 100644 -index 000000000..6e97c806a ---- /dev/null -+++ b/fs/aufs/wbr_policy.c -@@ -0,0 +1,830 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * policies for selecting one among multiple writable branches -+ */ -+ -+#include -+#include "aufs.h" -+ -+/* subset of cpup_attr() */ -+static noinline_for_stack -+int au_cpdown_attr(struct path *h_path, struct dentry *h_src) -+{ -+ int err, sbits; -+ struct iattr ia; -+ struct inode *h_isrc; -+ -+ h_isrc = d_inode(h_src); -+ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID; -+ ia.ia_mode = h_isrc->i_mode; -+ ia.ia_uid = h_isrc->i_uid; -+ ia.ia_gid = h_isrc->i_gid; -+ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID)); -+ au_cpup_attr_flags(d_inode(h_path->dentry), h_isrc->i_flags); -+ /* no delegation since it is just created */ -+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL); -+ -+ /* is this nfs only? */ -+ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) { -+ ia.ia_valid = ATTR_FORCE | ATTR_MODE; -+ ia.ia_mode = h_isrc->i_mode; -+ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL); -+ } -+ -+ return err; -+} -+ -+#define AuCpdown_PARENT_OPQ 1 -+#define AuCpdown_WHED (1 << 1) -+#define AuCpdown_MADE_DIR (1 << 2) -+#define AuCpdown_DIROPQ (1 << 3) -+#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name) -+#define au_fset_cpdown(flags, name) \ -+ do { (flags) |= AuCpdown_##name; } while (0) -+#define au_fclr_cpdown(flags, name) \ -+ do { (flags) &= ~AuCpdown_##name; } while (0) -+ -+static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst, -+ unsigned int *flags) -+{ -+ int err; -+ struct dentry *opq_dentry; -+ -+ opq_dentry = au_diropq_create(dentry, bdst); -+ err = PTR_ERR(opq_dentry); -+ if (IS_ERR(opq_dentry)) -+ goto out; -+ dput(opq_dentry); -+ au_fset_cpdown(*flags, DIROPQ); -+ -+out: -+ return err; -+} -+ -+static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent, -+ struct inode *dir, aufs_bindex_t bdst) -+{ -+ int err; -+ struct path h_path; -+ struct au_branch *br; -+ -+ br = au_sbr(dentry->d_sb, bdst); -+ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br); -+ err = PTR_ERR(h_path.dentry); -+ if (IS_ERR(h_path.dentry)) -+ goto out; -+ -+ err = 0; -+ if (d_is_positive(h_path.dentry)) { -+ h_path.mnt = au_br_mnt(br); -+ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path, -+ dentry); -+ } -+ dput(h_path.dentry); -+ -+out: -+ return err; -+} -+ -+static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst, -+ struct au_pin *pin, -+ struct dentry *h_parent, void *arg) -+{ -+ int err, rerr; -+ aufs_bindex_t bopq, btop; -+ struct path h_path; -+ struct dentry *parent; -+ struct inode *h_dir, *h_inode, *inode, *dir; -+ unsigned int *flags = arg; -+ -+ btop = au_dbtop(dentry); -+ /* dentry is di-locked */ -+ parent = dget_parent(dentry); -+ dir = d_inode(parent); -+ h_dir = d_inode(h_parent); -+ AuDebugOn(h_dir != au_h_iptr(dir, bdst)); -+ IMustLock(h_dir); -+ -+ err = au_lkup_neg(dentry, bdst, /*wh*/0); -+ if (unlikely(err < 0)) -+ goto out; -+ h_path.dentry = au_h_dptr(dentry, bdst); -+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst); -+ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path, 0755); -+ if (unlikely(err)) -+ goto out_put; -+ au_fset_cpdown(*flags, MADE_DIR); -+ -+ bopq = au_dbdiropq(dentry); -+ au_fclr_cpdown(*flags, WHED); -+ au_fclr_cpdown(*flags, DIROPQ); -+ if (au_dbwh(dentry) == bdst) -+ au_fset_cpdown(*flags, WHED); -+ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst) -+ au_fset_cpdown(*flags, PARENT_OPQ); -+ h_inode = d_inode(h_path.dentry); -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ if (au_ftest_cpdown(*flags, WHED)) { -+ err = au_cpdown_dir_opq(dentry, bdst, flags); -+ if (unlikely(err)) { -+ inode_unlock(h_inode); -+ goto out_dir; -+ } -+ } -+ -+ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, btop)); -+ inode_unlock(h_inode); -+ if (unlikely(err)) -+ goto out_opq; -+ -+ if (au_ftest_cpdown(*flags, WHED)) { -+ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst); -+ if (unlikely(err)) -+ goto out_opq; -+ } -+ -+ inode = d_inode(dentry); -+ if (au_ibbot(inode) < bdst) -+ au_set_ibbot(inode, bdst); -+ au_set_h_iptr(inode, bdst, au_igrab(h_inode), -+ au_hi_flags(inode, /*isdir*/1)); -+ au_fhsm_wrote(dentry->d_sb, bdst, /*force*/0); -+ goto out; /* success */ -+ -+ /* revert */ -+out_opq: -+ if (au_ftest_cpdown(*flags, DIROPQ)) { -+ inode_lock_nested(h_inode, AuLsc_I_CHILD); -+ rerr = au_diropq_remove(dentry, bdst); -+ inode_unlock(h_inode); -+ if (unlikely(rerr)) { -+ AuIOErr("failed removing diropq for %pd b%d (%d)\n", -+ dentry, bdst, rerr); -+ err = -EIO; -+ goto out; -+ } -+ } -+out_dir: -+ if (au_ftest_cpdown(*flags, MADE_DIR)) { -+ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path); -+ if (unlikely(rerr)) { -+ AuIOErr("failed removing %pd b%d (%d)\n", -+ dentry, bdst, rerr); -+ err = -EIO; -+ } -+ } -+out_put: -+ au_set_h_dptr(dentry, bdst, NULL); -+ if (au_dbbot(dentry) == bdst) -+ au_update_dbbot(dentry); -+out: -+ dput(parent); -+ return err; -+} -+ -+int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst) -+{ -+ int err; -+ unsigned int flags; -+ -+ flags = 0; -+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* policies for create */ -+ -+int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ int err, i, j, ndentry; -+ aufs_bindex_t bopq; -+ struct au_dcsub_pages dpages; -+ struct au_dpage *dpage; -+ struct dentry **dentries, *parent, *d; -+ -+ err = au_dpages_init(&dpages, GFP_NOFS); -+ if (unlikely(err)) -+ goto out; -+ parent = dget_parent(dentry); -+ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0); -+ if (unlikely(err)) -+ goto out_free; -+ -+ err = bindex; -+ for (i = 0; i < dpages.ndpage; i++) { -+ dpage = dpages.dpages + i; -+ dentries = dpage->dentries; -+ ndentry = dpage->ndentry; -+ for (j = 0; j < ndentry; j++) { -+ d = dentries[j]; -+ di_read_lock_parent2(d, !AuLock_IR); -+ bopq = au_dbdiropq(d); -+ di_read_unlock(d, !AuLock_IR); -+ if (bopq >= 0 && bopq < err) -+ err = bopq; -+ } -+ } -+ -+out_free: -+ dput(parent); -+ au_dpages_free(&dpages); -+out: -+ return err; -+} -+ -+static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex) -+{ -+ for (; bindex >= 0; bindex--) -+ if (!au_br_rdonly(au_sbr(sb, bindex))) -+ return bindex; -+ return -EROFS; -+} -+ -+/* top down parent */ -+static int au_wbr_create_tdp(struct dentry *dentry, -+ unsigned int flags __maybe_unused) -+{ -+ int err; -+ aufs_bindex_t btop, bindex; -+ struct super_block *sb; -+ struct dentry *parent, *h_parent; -+ -+ sb = dentry->d_sb; -+ btop = au_dbtop(dentry); -+ err = btop; -+ if (!au_br_rdonly(au_sbr(sb, btop))) -+ goto out; -+ -+ err = -EROFS; -+ parent = dget_parent(dentry); -+ for (bindex = au_dbtop(parent); bindex < btop; bindex++) { -+ h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || d_is_negative(h_parent)) -+ continue; -+ -+ if (!au_br_rdonly(au_sbr(sb, bindex))) { -+ err = bindex; -+ break; -+ } -+ } -+ dput(parent); -+ -+ /* bottom up here */ -+ if (unlikely(err < 0)) { -+ err = au_wbr_bu(sb, btop - 1); -+ if (err >= 0) -+ err = au_wbr_nonopq(dentry, err); -+ } -+ -+out: -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* an exception for the policy other than tdp */ -+static int au_wbr_create_exp(struct dentry *dentry) -+{ -+ int err; -+ aufs_bindex_t bwh, bdiropq; -+ struct dentry *parent; -+ -+ err = -1; -+ bwh = au_dbwh(dentry); -+ parent = dget_parent(dentry); -+ bdiropq = au_dbdiropq(parent); -+ if (bwh >= 0) { -+ if (bdiropq >= 0) -+ err = min(bdiropq, bwh); -+ else -+ err = bwh; -+ AuDbg("%d\n", err); -+ } else if (bdiropq >= 0) { -+ err = bdiropq; -+ AuDbg("%d\n", err); -+ } -+ dput(parent); -+ -+ if (err >= 0) -+ err = au_wbr_nonopq(dentry, err); -+ -+ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err))) -+ err = -1; -+ -+ AuDbg("%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* round robin */ -+static int au_wbr_create_init_rr(struct super_block *sb) -+{ -+ int err; -+ -+ err = au_wbr_bu(sb, au_sbbot(sb)); -+ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */ -+ /* smp_mb(); */ -+ -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags) -+{ -+ int err, nbr; -+ unsigned int u; -+ aufs_bindex_t bindex, bbot; -+ struct super_block *sb; -+ atomic_t *next; -+ -+ err = au_wbr_create_exp(dentry); -+ if (err >= 0) -+ goto out; -+ -+ sb = dentry->d_sb; -+ next = &au_sbi(sb)->si_wbr_rr_next; -+ bbot = au_sbbot(sb); -+ nbr = bbot + 1; -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ if (!au_ftest_wbr(flags, DIR)) { -+ err = atomic_dec_return(next) + 1; -+ /* modulo for 0 is meaningless */ -+ if (unlikely(!err)) -+ err = atomic_dec_return(next) + 1; -+ } else -+ err = atomic_read(next); -+ AuDbg("%d\n", err); -+ u = err; -+ err = u % nbr; -+ AuDbg("%d\n", err); -+ if (!au_br_rdonly(au_sbr(sb, err))) -+ break; -+ err = -EROFS; -+ } -+ -+ if (err >= 0) -+ err = au_wbr_nonopq(dentry, err); -+ -+out: -+ AuDbg("%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* most free space */ -+static void au_mfs(struct dentry *dentry, struct dentry *parent) -+{ -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_wbr_mfs *mfs; -+ struct dentry *h_parent; -+ aufs_bindex_t bindex, bbot; -+ int err; -+ unsigned long long b, bavail; -+ struct path h_path; -+ /* reduce the stack usage */ -+ struct kstatfs *st; -+ -+ st = kmalloc(sizeof(*st), GFP_NOFS); -+ if (unlikely(!st)) { -+ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM); -+ return; -+ } -+ -+ bavail = 0; -+ sb = dentry->d_sb; -+ mfs = &au_sbi(sb)->si_wbr_mfs; -+ MtxMustLock(&mfs->mfs_lock); -+ mfs->mfs_bindex = -EROFS; -+ mfs->mfsrr_bytes = 0; -+ if (!parent) { -+ bindex = 0; -+ bbot = au_sbbot(sb); -+ } else { -+ bindex = au_dbtop(parent); -+ bbot = au_dbtaildir(parent); -+ } -+ -+ for (; bindex <= bbot; bindex++) { -+ if (parent) { -+ h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || d_is_negative(h_parent)) -+ continue; -+ } -+ br = au_sbr(sb, bindex); -+ if (au_br_rdonly(br)) -+ continue; -+ -+ /* sb->s_root for NFS is unreliable */ -+ h_path.mnt = au_br_mnt(br); -+ h_path.dentry = h_path.mnt->mnt_root; -+ err = vfs_statfs(&h_path, st); -+ if (unlikely(err)) { -+ AuWarn1("failed statfs, b%d, %d\n", bindex, err); -+ continue; -+ } -+ -+ /* when the available size is equal, select the lower one */ -+ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail) -+ || sizeof(b) < sizeof(st->f_bsize)); -+ b = st->f_bavail * st->f_bsize; -+ br->br_wbr->wbr_bytes = b; -+ if (b >= bavail) { -+ bavail = b; -+ mfs->mfs_bindex = bindex; -+ mfs->mfs_jiffy = jiffies; -+ } -+ } -+ -+ mfs->mfsrr_bytes = bavail; -+ AuDbg("b%d\n", mfs->mfs_bindex); -+ kfree(st); -+} -+ -+static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags) -+{ -+ int err; -+ struct dentry *parent; -+ struct super_block *sb; -+ struct au_wbr_mfs *mfs; -+ -+ err = au_wbr_create_exp(dentry); -+ if (err >= 0) -+ goto out; -+ -+ sb = dentry->d_sb; -+ parent = NULL; -+ if (au_ftest_wbr(flags, PARENT)) -+ parent = dget_parent(dentry); -+ mfs = &au_sbi(sb)->si_wbr_mfs; -+ mutex_lock(&mfs->mfs_lock); -+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire) -+ || mfs->mfs_bindex < 0 -+ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex))) -+ au_mfs(dentry, parent); -+ mutex_unlock(&mfs->mfs_lock); -+ err = mfs->mfs_bindex; -+ dput(parent); -+ -+ if (err >= 0) -+ err = au_wbr_nonopq(dentry, err); -+ -+out: -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+static int au_wbr_create_init_mfs(struct super_block *sb) -+{ -+ struct au_wbr_mfs *mfs; -+ -+ mfs = &au_sbi(sb)->si_wbr_mfs; -+ mutex_init(&mfs->mfs_lock); -+ mfs->mfs_jiffy = 0; -+ mfs->mfs_bindex = -EROFS; -+ -+ return 0; -+} -+ -+static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused) -+{ -+ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock); -+ return 0; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* top down regardless parent, and then mfs */ -+static int au_wbr_create_tdmfs(struct dentry *dentry, -+ unsigned int flags __maybe_unused) -+{ -+ int err; -+ aufs_bindex_t bwh, btail, bindex, bfound, bmfs; -+ unsigned long long watermark; -+ struct super_block *sb; -+ struct au_wbr_mfs *mfs; -+ struct au_branch *br; -+ struct dentry *parent; -+ -+ sb = dentry->d_sb; -+ mfs = &au_sbi(sb)->si_wbr_mfs; -+ mutex_lock(&mfs->mfs_lock); -+ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire) -+ || mfs->mfs_bindex < 0) -+ au_mfs(dentry, /*parent*/NULL); -+ watermark = mfs->mfsrr_watermark; -+ bmfs = mfs->mfs_bindex; -+ mutex_unlock(&mfs->mfs_lock); -+ -+ /* another style of au_wbr_create_exp() */ -+ bwh = au_dbwh(dentry); -+ parent = dget_parent(dentry); -+ btail = au_dbtaildir(parent); -+ if (bwh >= 0 && bwh < btail) -+ btail = bwh; -+ -+ err = au_wbr_nonopq(dentry, btail); -+ if (unlikely(err < 0)) -+ goto out; -+ btail = err; -+ bfound = -1; -+ for (bindex = 0; bindex <= btail; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_rdonly(br)) -+ continue; -+ if (br->br_wbr->wbr_bytes > watermark) { -+ bfound = bindex; -+ break; -+ } -+ } -+ err = bfound; -+ if (err < 0) -+ err = bmfs; -+ -+out: -+ dput(parent); -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* most free space and then round robin */ -+static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags) -+{ -+ int err; -+ struct au_wbr_mfs *mfs; -+ -+ err = au_wbr_create_mfs(dentry, flags); -+ if (err >= 0) { -+ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs; -+ mutex_lock(&mfs->mfs_lock); -+ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark) -+ err = au_wbr_create_rr(dentry, flags); -+ mutex_unlock(&mfs->mfs_lock); -+ } -+ -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+static int au_wbr_create_init_mfsrr(struct super_block *sb) -+{ -+ int err; -+ -+ au_wbr_create_init_mfs(sb); /* ignore */ -+ err = au_wbr_create_init_rr(sb); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* top down parent and most free space */ -+static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags) -+{ -+ int err, e2; -+ unsigned long long b; -+ aufs_bindex_t bindex, btop, bbot; -+ struct super_block *sb; -+ struct dentry *parent, *h_parent; -+ struct au_branch *br; -+ -+ err = au_wbr_create_tdp(dentry, flags); -+ if (unlikely(err < 0)) -+ goto out; -+ parent = dget_parent(dentry); -+ btop = au_dbtop(parent); -+ bbot = au_dbtaildir(parent); -+ if (btop == bbot) -+ goto out_parent; /* success */ -+ -+ e2 = au_wbr_create_mfs(dentry, flags); -+ if (e2 < 0) -+ goto out_parent; /* success */ -+ -+ /* when the available size is equal, select upper one */ -+ sb = dentry->d_sb; -+ br = au_sbr(sb, err); -+ b = br->br_wbr->wbr_bytes; -+ AuDbg("b%d, %llu\n", err, b); -+ -+ for (bindex = btop; bindex <= bbot; bindex++) { -+ h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || d_is_negative(h_parent)) -+ continue; -+ -+ br = au_sbr(sb, bindex); -+ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) { -+ b = br->br_wbr->wbr_bytes; -+ err = bindex; -+ AuDbg("b%d, %llu\n", err, b); -+ } -+ } -+ -+ if (err >= 0) -+ err = au_wbr_nonopq(dentry, err); -+ -+out_parent: -+ dput(parent); -+out: -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * - top down parent -+ * - most free space with parent -+ * - most free space round-robin regardless parent -+ */ -+static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags) -+{ -+ int err; -+ unsigned long long watermark; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_wbr_mfs *mfs; -+ -+ err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT); -+ if (unlikely(err < 0)) -+ goto out; -+ -+ sb = dentry->d_sb; -+ br = au_sbr(sb, err); -+ mfs = &au_sbi(sb)->si_wbr_mfs; -+ mutex_lock(&mfs->mfs_lock); -+ watermark = mfs->mfsrr_watermark; -+ mutex_unlock(&mfs->mfs_lock); -+ if (br->br_wbr->wbr_bytes < watermark) -+ /* regardless the parent dir */ -+ err = au_wbr_create_mfsrr(dentry, flags); -+ -+out: -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* policies for copyup */ -+ -+/* top down parent */ -+static int au_wbr_copyup_tdp(struct dentry *dentry) -+{ -+ return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0); -+} -+ -+/* bottom up parent */ -+static int au_wbr_copyup_bup(struct dentry *dentry) -+{ -+ int err; -+ aufs_bindex_t bindex, btop; -+ struct dentry *parent, *h_parent; -+ struct super_block *sb; -+ -+ err = -EROFS; -+ sb = dentry->d_sb; -+ parent = dget_parent(dentry); -+ btop = au_dbtop(parent); -+ for (bindex = au_dbtop(dentry); bindex >= btop; bindex--) { -+ h_parent = au_h_dptr(parent, bindex); -+ if (!h_parent || d_is_negative(h_parent)) -+ continue; -+ -+ if (!au_br_rdonly(au_sbr(sb, bindex))) { -+ err = bindex; -+ break; -+ } -+ } -+ dput(parent); -+ -+ /* bottom up here */ -+ if (unlikely(err < 0)) -+ err = au_wbr_bu(sb, btop - 1); -+ -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+/* bottom up */ -+int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t btop) -+{ -+ int err; -+ -+ err = au_wbr_bu(dentry->d_sb, btop); -+ AuDbg("b%d\n", err); -+ if (err > btop) -+ err = au_wbr_nonopq(dentry, err); -+ -+ AuDbg("b%d\n", err); -+ return err; -+} -+ -+static int au_wbr_copyup_bu(struct dentry *dentry) -+{ -+ int err; -+ aufs_bindex_t btop; -+ -+ btop = au_dbtop(dentry); -+ err = au_wbr_do_copyup_bu(dentry, btop); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_wbr_copyup_operations au_wbr_copyup_ops[] = { -+ [AuWbrCopyup_TDP] = { -+ .copyup = au_wbr_copyup_tdp -+ }, -+ [AuWbrCopyup_BUP] = { -+ .copyup = au_wbr_copyup_bup -+ }, -+ [AuWbrCopyup_BU] = { -+ .copyup = au_wbr_copyup_bu -+ } -+}; -+ -+struct au_wbr_create_operations au_wbr_create_ops[] = { -+ [AuWbrCreate_TDP] = { -+ .create = au_wbr_create_tdp -+ }, -+ [AuWbrCreate_RR] = { -+ .create = au_wbr_create_rr, -+ .init = au_wbr_create_init_rr -+ }, -+ [AuWbrCreate_MFS] = { -+ .create = au_wbr_create_mfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_MFSV] = { -+ .create = au_wbr_create_mfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_MFSRR] = { -+ .create = au_wbr_create_mfsrr, -+ .init = au_wbr_create_init_mfsrr, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_MFSRRV] = { -+ .create = au_wbr_create_mfsrr, -+ .init = au_wbr_create_init_mfsrr, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_TDMFS] = { -+ .create = au_wbr_create_tdmfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_TDMFSV] = { -+ .create = au_wbr_create_tdmfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_PMFS] = { -+ .create = au_wbr_create_pmfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_PMFSV] = { -+ .create = au_wbr_create_pmfs, -+ .init = au_wbr_create_init_mfs, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_PMFSRR] = { -+ .create = au_wbr_create_pmfsrr, -+ .init = au_wbr_create_init_mfsrr, -+ .fin = au_wbr_create_fin_mfs -+ }, -+ [AuWbrCreate_PMFSRRV] = { -+ .create = au_wbr_create_pmfsrr, -+ .init = au_wbr_create_init_mfsrr, -+ .fin = au_wbr_create_fin_mfs -+ } -+}; -diff --git a/fs/aufs/whout.c b/fs/aufs/whout.c -new file mode 100644 -index 000000000..2325c2ee5 ---- /dev/null -+++ b/fs/aufs/whout.c -@@ -0,0 +1,1062 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * whiteout for logical deletion and opaque directory -+ */ -+ -+#include "aufs.h" -+ -+#define WH_MASK 0444 -+ -+/* -+ * If a directory contains this file, then it is opaque. We start with the -+ * .wh. flag so that it is blocked by lookup. -+ */ -+static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ, -+ sizeof(AUFS_WH_DIROPQ) - 1); -+ -+/* -+ * generate whiteout name, which is NOT terminated by NULL. -+ * @name: original d_name.name -+ * @len: original d_name.len -+ * @wh: whiteout qstr -+ * returns zero when succeeds, otherwise error. -+ * succeeded value as wh->name should be freed by kfree(). -+ */ -+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name) -+{ -+ char *p; -+ -+ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN)) -+ return -ENAMETOOLONG; -+ -+ wh->len = name->len + AUFS_WH_PFX_LEN; -+ p = kmalloc(wh->len, GFP_NOFS); -+ wh->name = p; -+ if (p) { -+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); -+ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len); -+ /* smp_mb(); */ -+ return 0; -+ } -+ return -ENOMEM; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * test if the @wh_name exists under @h_parent. -+ * @try_sio specifies the necessary of super-io. -+ */ -+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio) -+{ -+ int err; -+ struct dentry *wh_dentry; -+ -+ if (!try_sio) -+ wh_dentry = vfsub_lkup_one(wh_name, h_parent); -+ else -+ wh_dentry = au_sio_lkup_one(wh_name, h_parent); -+ err = PTR_ERR(wh_dentry); -+ if (IS_ERR(wh_dentry)) { -+ if (err == -ENAMETOOLONG) -+ err = 0; -+ goto out; -+ } -+ -+ err = 0; -+ if (d_is_negative(wh_dentry)) -+ goto out_wh; /* success */ -+ -+ err = 1; -+ if (d_is_reg(wh_dentry)) -+ goto out_wh; /* success */ -+ -+ err = -EIO; -+ AuIOErr("%pd Invalid whiteout entry type 0%o.\n", -+ wh_dentry, d_inode(wh_dentry)->i_mode); -+ -+out_wh: -+ dput(wh_dentry); -+out: -+ return err; -+} -+ -+/* -+ * test if the @h_dentry sets opaque or not. -+ */ -+int au_diropq_test(struct dentry *h_dentry) -+{ -+ int err; -+ struct inode *h_dir; -+ -+ h_dir = d_inode(h_dentry); -+ err = au_wh_test(h_dentry, &diropq_name, -+ au_test_h_perm_sio(h_dir, MAY_EXEC)); -+ return err; -+} -+ -+/* -+ * returns a negative dentry whose name is unique and temporary. -+ */ -+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br, -+ struct qstr *prefix) -+{ -+ struct dentry *dentry; -+ int i; -+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1], -+ *name, *p; -+ /* strict atomic_t is unnecessary here */ -+ static unsigned short cnt; -+ struct qstr qs; -+ -+ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN); -+ -+ name = defname; -+ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1; -+ if (unlikely(prefix->len > DNAME_INLINE_LEN)) { -+ dentry = ERR_PTR(-ENAMETOOLONG); -+ if (unlikely(qs.len > NAME_MAX)) -+ goto out; -+ dentry = ERR_PTR(-ENOMEM); -+ name = kmalloc(qs.len + 1, GFP_NOFS); -+ if (unlikely(!name)) -+ goto out; -+ } -+ -+ /* doubly whiteout-ed */ -+ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2); -+ p = name + AUFS_WH_PFX_LEN * 2; -+ memcpy(p, prefix->name, prefix->len); -+ p += prefix->len; -+ *p++ = '.'; -+ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN); -+ -+ qs.name = name; -+ for (i = 0; i < 3; i++) { -+ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++); -+ dentry = au_sio_lkup_one(&qs, h_parent); -+ if (IS_ERR(dentry) || d_is_negative(dentry)) -+ goto out_name; -+ dput(dentry); -+ } -+ /* pr_warn("could not get random name\n"); */ -+ dentry = ERR_PTR(-EEXIST); -+ AuDbg("%.*s\n", AuLNPair(&qs)); -+ BUG(); -+ -+out_name: -+ if (name != defname) -+ kfree(name); -+out: -+ AuTraceErrPtr(dentry); -+ return dentry; -+} -+ -+/* -+ * rename the @h_dentry on @br to the whiteouted temporary name. -+ */ -+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br) -+{ -+ int err; -+ struct path h_path = { -+ .mnt = au_br_mnt(br) -+ }; -+ struct inode *h_dir, *delegated; -+ struct dentry *h_parent; -+ -+ h_parent = h_dentry->d_parent; /* dir inode is locked */ -+ h_dir = d_inode(h_parent); -+ IMustLock(h_dir); -+ -+ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name); -+ err = PTR_ERR(h_path.dentry); -+ if (IS_ERR(h_path.dentry)) -+ goto out; -+ -+ /* under the same dir, no need to lock_rename() */ -+ delegated = NULL; -+ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path, &delegated, -+ /*flags*/0); -+ AuTraceErr(err); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal rename\n"); -+ iput(delegated); -+ } -+ dput(h_path.dentry); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * functions for removing a whiteout -+ */ -+ -+static int do_unlink_wh(struct inode *h_dir, struct path *h_path) -+{ -+ int err, force; -+ struct inode *delegated; -+ -+ /* -+ * forces superio when the dir has a sticky bit. -+ * this may be a violation of unix fs semantics. -+ */ -+ force = (h_dir->i_mode & S_ISVTX) -+ && !uid_eq(current_fsuid(), d_inode(h_path->dentry)->i_uid); -+ delegated = NULL; -+ err = vfsub_unlink(h_dir, h_path, &delegated, force); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ return err; -+} -+ -+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path, -+ struct dentry *dentry) -+{ -+ int err; -+ -+ err = do_unlink_wh(h_dir, h_path); -+ if (!err && dentry) -+ au_set_dbwh(dentry, -1); -+ -+ return err; -+} -+ -+static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh, -+ struct au_branch *br) -+{ -+ int err; -+ struct path h_path = { -+ .mnt = au_br_mnt(br) -+ }; -+ -+ err = 0; -+ h_path.dentry = vfsub_lkup_one(wh, h_parent); -+ if (IS_ERR(h_path.dentry)) -+ err = PTR_ERR(h_path.dentry); -+ else { -+ if (d_is_reg(h_path.dentry)) -+ err = do_unlink_wh(d_inode(h_parent), &h_path); -+ dput(h_path.dentry); -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * initialize/clean whiteout for a branch -+ */ -+ -+static void au_wh_clean(struct inode *h_dir, struct path *whpath, -+ const int isdir) -+{ -+ int err; -+ struct inode *delegated; -+ -+ if (d_is_negative(whpath->dentry)) -+ return; -+ -+ if (isdir) -+ err = vfsub_rmdir(h_dir, whpath); -+ else { -+ delegated = NULL; -+ err = vfsub_unlink(h_dir, whpath, &delegated, /*force*/0); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ } -+ if (unlikely(err)) -+ pr_warn("failed removing %pd (%d), ignored.\n", -+ whpath->dentry, err); -+} -+ -+static int test_linkable(struct dentry *h_root) -+{ -+ struct inode *h_dir = d_inode(h_root); -+ -+ if (h_dir->i_op->link) -+ return 0; -+ -+ pr_err("%pd (%s) doesn't support link(2), use noplink and rw+nolwh\n", -+ h_root, au_sbtype(h_root->d_sb)); -+ return -ENOSYS; -+} -+ -+/* todo: should this mkdir be done in /sbin/mount.aufs helper? */ -+static int au_whdir(struct inode *h_dir, struct path *path) -+{ -+ int err; -+ -+ err = -EEXIST; -+ if (d_is_negative(path->dentry)) { -+ int mode = 0700; -+ -+ if (au_test_nfs(path->dentry->d_sb)) -+ mode |= 0111; -+ err = vfsub_mkdir(h_dir, path, mode); -+ } else if (d_is_dir(path->dentry)) -+ err = 0; -+ else -+ pr_err("unknown %pd exists\n", path->dentry); -+ -+ return err; -+} -+ -+struct au_wh_base { -+ const struct qstr *name; -+ struct dentry *dentry; -+}; -+ -+static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[], -+ struct path *h_path) -+{ -+ h_path->dentry = base[AuBrWh_BASE].dentry; -+ au_wh_clean(h_dir, h_path, /*isdir*/0); -+ h_path->dentry = base[AuBrWh_PLINK].dentry; -+ au_wh_clean(h_dir, h_path, /*isdir*/1); -+ h_path->dentry = base[AuBrWh_ORPH].dentry; -+ au_wh_clean(h_dir, h_path, /*isdir*/1); -+} -+ -+/* -+ * returns tri-state, -+ * minus: error, caller should print the message -+ * zero: success -+ * plus: error, caller should NOT print the message -+ */ -+static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr, -+ int do_plink, struct au_wh_base base[], -+ struct path *h_path) -+{ -+ int err; -+ struct inode *h_dir; -+ -+ h_dir = d_inode(h_root); -+ h_path->dentry = base[AuBrWh_BASE].dentry; -+ au_wh_clean(h_dir, h_path, /*isdir*/0); -+ h_path->dentry = base[AuBrWh_PLINK].dentry; -+ if (do_plink) { -+ err = test_linkable(h_root); -+ if (unlikely(err)) { -+ err = 1; -+ goto out; -+ } -+ -+ err = au_whdir(h_dir, h_path); -+ if (unlikely(err)) -+ goto out; -+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); -+ } else -+ au_wh_clean(h_dir, h_path, /*isdir*/1); -+ h_path->dentry = base[AuBrWh_ORPH].dentry; -+ err = au_whdir(h_dir, h_path); -+ if (unlikely(err)) -+ goto out; -+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry); -+ -+out: -+ return err; -+} -+ -+/* -+ * for the moment, aufs supports the branch filesystem which does not support -+ * link(2). testing on FAT which does not support i_op->setattr() fully either, -+ * copyup failed. finally, such filesystem will not be used as the writable -+ * branch. -+ * -+ * returns tri-state, see above. -+ */ -+static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr, -+ int do_plink, struct au_wh_base base[], -+ struct path *h_path) -+{ -+ int err; -+ struct inode *h_dir; -+ -+ WbrWhMustWriteLock(wbr); -+ -+ err = test_linkable(h_root); -+ if (unlikely(err)) { -+ err = 1; -+ goto out; -+ } -+ -+ /* -+ * todo: should this create be done in /sbin/mount.aufs helper? -+ */ -+ err = -EEXIST; -+ h_dir = d_inode(h_root); -+ if (d_is_negative(base[AuBrWh_BASE].dentry)) { -+ h_path->dentry = base[AuBrWh_BASE].dentry; -+ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true); -+ } else if (d_is_reg(base[AuBrWh_BASE].dentry)) -+ err = 0; -+ else -+ pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry); -+ if (unlikely(err)) -+ goto out; -+ -+ h_path->dentry = base[AuBrWh_PLINK].dentry; -+ if (do_plink) { -+ err = au_whdir(h_dir, h_path); -+ if (unlikely(err)) -+ goto out; -+ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); -+ } else -+ au_wh_clean(h_dir, h_path, /*isdir*/1); -+ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry); -+ -+ h_path->dentry = base[AuBrWh_ORPH].dentry; -+ err = au_whdir(h_dir, h_path); -+ if (unlikely(err)) -+ goto out; -+ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry); -+ -+out: -+ return err; -+} -+ -+/* -+ * initialize the whiteout base file/dir for @br. -+ */ -+int au_wh_init(struct au_branch *br, struct super_block *sb) -+{ -+ int err, i; -+ const unsigned char do_plink -+ = !!au_opt_test(au_mntflags(sb), PLINK); -+ struct inode *h_dir; -+ struct path path = br->br_path; -+ struct dentry *h_root = path.dentry; -+ struct au_wbr *wbr = br->br_wbr; -+ static const struct qstr base_name[] = { -+ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME, -+ sizeof(AUFS_BASE_NAME) - 1), -+ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME, -+ sizeof(AUFS_PLINKDIR_NAME) - 1), -+ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME, -+ sizeof(AUFS_ORPHDIR_NAME) - 1) -+ }; -+ struct au_wh_base base[] = { -+ [AuBrWh_BASE] = { -+ .name = base_name + AuBrWh_BASE, -+ .dentry = NULL -+ }, -+ [AuBrWh_PLINK] = { -+ .name = base_name + AuBrWh_PLINK, -+ .dentry = NULL -+ }, -+ [AuBrWh_ORPH] = { -+ .name = base_name + AuBrWh_ORPH, -+ .dentry = NULL -+ } -+ }; -+ -+ if (wbr) -+ WbrWhMustWriteLock(wbr); -+ -+ for (i = 0; i < AuBrWh_Last; i++) { -+ /* doubly whiteouted */ -+ struct dentry *d; -+ -+ d = au_wh_lkup(h_root, (void *)base[i].name, br); -+ err = PTR_ERR(d); -+ if (IS_ERR(d)) -+ goto out; -+ -+ base[i].dentry = d; -+ AuDebugOn(wbr -+ && wbr->wbr_wh[i] -+ && wbr->wbr_wh[i] != base[i].dentry); -+ } -+ -+ if (wbr) -+ for (i = 0; i < AuBrWh_Last; i++) { -+ dput(wbr->wbr_wh[i]); -+ wbr->wbr_wh[i] = NULL; -+ } -+ -+ err = 0; -+ if (!au_br_writable(br->br_perm)) { -+ h_dir = d_inode(h_root); -+ au_wh_init_ro(h_dir, base, &path); -+ } else if (!au_br_wh_linkable(br->br_perm)) { -+ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path); -+ if (err > 0) -+ goto out; -+ else if (err) -+ goto out_err; -+ } else { -+ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path); -+ if (err > 0) -+ goto out; -+ else if (err) -+ goto out_err; -+ } -+ goto out; /* success */ -+ -+out_err: -+ pr_err("an error(%d) on the writable branch %pd(%s)\n", -+ err, h_root, au_sbtype(h_root->d_sb)); -+out: -+ for (i = 0; i < AuBrWh_Last; i++) -+ dput(base[i].dentry); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * whiteouts are all hard-linked usually. -+ * when its link count reaches a ceiling, we create a new whiteout base -+ * asynchronously. -+ */ -+ -+struct reinit_br_wh { -+ struct super_block *sb; -+ struct au_branch *br; -+}; -+ -+static void reinit_br_wh(void *arg) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct path h_path; -+ struct reinit_br_wh *a = arg; -+ struct au_wbr *wbr; -+ struct inode *dir, *delegated; -+ struct dentry *h_root; -+ struct au_hinode *hdir; -+ -+ err = 0; -+ wbr = a->br->br_wbr; -+ /* big aufs lock */ -+ si_noflush_write_lock(a->sb); -+ if (!au_br_writable(a->br->br_perm)) -+ goto out; -+ bindex = au_br_index(a->sb, a->br->br_id); -+ if (unlikely(bindex < 0)) -+ goto out; -+ -+ di_read_lock_parent(a->sb->s_root, AuLock_IR); -+ dir = d_inode(a->sb->s_root); -+ hdir = au_hi(dir, bindex); -+ h_root = au_h_dptr(a->sb->s_root, bindex); -+ AuDebugOn(h_root != au_br_dentry(a->br)); -+ -+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT); -+ wbr_wh_write_lock(wbr); -+ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode, -+ h_root, a->br); -+ if (!err) { -+ h_path.dentry = wbr->wbr_whbase; -+ h_path.mnt = au_br_mnt(a->br); -+ delegated = NULL; -+ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, -+ /*force*/0); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ } else { -+ pr_warn("%pd is moved, ignored\n", wbr->wbr_whbase); -+ err = 0; -+ } -+ dput(wbr->wbr_whbase); -+ wbr->wbr_whbase = NULL; -+ if (!err) -+ err = au_wh_init(a->br, a->sb); -+ wbr_wh_write_unlock(wbr); -+ au_hn_inode_unlock(hdir); -+ di_read_unlock(a->sb->s_root, AuLock_IR); -+ if (!err) -+ au_fhsm_wrote(a->sb, bindex, /*force*/0); -+ -+out: -+ if (wbr) -+ atomic_dec(&wbr->wbr_wh_running); -+ au_lcnt_dec(&a->br->br_count); -+ si_write_unlock(a->sb); -+ au_nwt_done(&au_sbi(a->sb)->si_nowait); -+ kfree(arg); -+ if (unlikely(err)) -+ AuIOErr("err %d\n", err); -+} -+ -+static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br) -+{ -+ int do_dec, wkq_err; -+ struct reinit_br_wh *arg; -+ -+ do_dec = 1; -+ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1) -+ goto out; -+ -+ /* ignore ENOMEM */ -+ arg = kmalloc(sizeof(*arg), GFP_NOFS); -+ if (arg) { -+ /* -+ * dec(wh_running), kfree(arg) and dec(br_count) -+ * in reinit function -+ */ -+ arg->sb = sb; -+ arg->br = br; -+ au_lcnt_inc(&br->br_count); -+ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0); -+ if (unlikely(wkq_err)) { -+ atomic_dec(&br->br_wbr->wbr_wh_running); -+ au_lcnt_dec(&br->br_count); -+ kfree(arg); -+ } -+ do_dec = 0; -+ } -+ -+out: -+ if (do_dec) -+ atomic_dec(&br->br_wbr->wbr_wh_running); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * create the whiteout @wh. -+ */ -+static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex, -+ struct dentry *wh) -+{ -+ int err; -+ struct path h_path = { -+ .dentry = wh -+ }; -+ struct au_branch *br; -+ struct au_wbr *wbr; -+ struct dentry *h_parent; -+ struct inode *h_dir, *delegated; -+ -+ h_parent = wh->d_parent; /* dir inode is locked */ -+ h_dir = d_inode(h_parent); -+ IMustLock(h_dir); -+ -+ br = au_sbr(sb, bindex); -+ h_path.mnt = au_br_mnt(br); -+ wbr = br->br_wbr; -+ wbr_wh_read_lock(wbr); -+ if (wbr->wbr_whbase) { -+ delegated = NULL; -+ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path, &delegated); -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal link\n"); -+ iput(delegated); -+ } -+ if (!err || err != -EMLINK) -+ goto out; -+ -+ /* link count full. re-initialize br_whbase. */ -+ kick_reinit_br_wh(sb, br); -+ } -+ -+ /* return this error in this context */ -+ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true); -+ if (!err) -+ au_fhsm_wrote(sb, bindex, /*force*/0); -+ -+out: -+ wbr_wh_read_unlock(wbr); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * create or remove the diropq. -+ */ -+static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex, -+ unsigned int flags) -+{ -+ struct dentry *opq_dentry, *h_dentry; -+ struct super_block *sb; -+ struct au_branch *br; -+ int err; -+ -+ sb = dentry->d_sb; -+ br = au_sbr(sb, bindex); -+ h_dentry = au_h_dptr(dentry, bindex); -+ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry); -+ if (IS_ERR(opq_dentry)) -+ goto out; -+ -+ if (au_ftest_diropq(flags, CREATE)) { -+ err = link_or_create_wh(sb, bindex, opq_dentry); -+ if (!err) { -+ au_set_dbdiropq(dentry, bindex); -+ goto out; /* success */ -+ } -+ } else { -+ struct path tmp = { -+ .dentry = opq_dentry, -+ .mnt = au_br_mnt(br) -+ }; -+ err = do_unlink_wh(au_h_iptr(d_inode(dentry), bindex), &tmp); -+ if (!err) -+ au_set_dbdiropq(dentry, -1); -+ } -+ dput(opq_dentry); -+ opq_dentry = ERR_PTR(err); -+ -+out: -+ return opq_dentry; -+} -+ -+struct do_diropq_args { -+ struct dentry **errp; -+ struct dentry *dentry; -+ aufs_bindex_t bindex; -+ unsigned int flags; -+}; -+ -+static void call_do_diropq(void *args) -+{ -+ struct do_diropq_args *a = args; -+ *a->errp = do_diropq(a->dentry, a->bindex, a->flags); -+} -+ -+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, -+ unsigned int flags) -+{ -+ struct dentry *diropq, *h_dentry; -+ -+ h_dentry = au_h_dptr(dentry, bindex); -+ if (!au_test_h_perm_sio(d_inode(h_dentry), MAY_EXEC | MAY_WRITE)) -+ diropq = do_diropq(dentry, bindex, flags); -+ else { -+ int wkq_err; -+ struct do_diropq_args args = { -+ .errp = &diropq, -+ .dentry = dentry, -+ .bindex = bindex, -+ .flags = flags -+ }; -+ -+ wkq_err = au_wkq_wait(call_do_diropq, &args); -+ if (unlikely(wkq_err)) -+ diropq = ERR_PTR(wkq_err); -+ } -+ -+ return diropq; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * lookup whiteout dentry. -+ * @h_parent: lower parent dentry which must exist and be locked -+ * @base_name: name of dentry which will be whiteouted -+ * returns dentry for whiteout. -+ */ -+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, -+ struct au_branch *br) -+{ -+ int err; -+ struct qstr wh_name; -+ struct dentry *wh_dentry; -+ -+ err = au_wh_name_alloc(&wh_name, base_name); -+ wh_dentry = ERR_PTR(err); -+ if (!err) { -+ wh_dentry = vfsub_lkup_one(&wh_name, h_parent); -+ kfree(wh_name.name); -+ } -+ return wh_dentry; -+} -+ -+/* -+ * link/create a whiteout for @dentry on @bindex. -+ */ -+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent) -+{ -+ struct dentry *wh_dentry; -+ struct super_block *sb; -+ int err; -+ -+ sb = dentry->d_sb; -+ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex)); -+ if (!IS_ERR(wh_dentry) && d_is_negative(wh_dentry)) { -+ err = link_or_create_wh(sb, bindex, wh_dentry); -+ if (!err) { -+ au_set_dbwh(dentry, bindex); -+ au_fhsm_wrote(sb, bindex, /*force*/0); -+ } else { -+ dput(wh_dentry); -+ wh_dentry = ERR_PTR(err); -+ } -+ } -+ -+ return wh_dentry; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* Delete all whiteouts in this directory on branch bindex. */ -+static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist, -+ aufs_bindex_t bindex, struct au_branch *br) -+{ -+ int err; -+ unsigned long ul, n; -+ struct qstr wh_name; -+ char *p; -+ struct hlist_head *head; -+ struct au_vdir_wh *pos; -+ struct au_vdir_destr *str; -+ -+ err = -ENOMEM; -+ p = (void *)__get_free_page(GFP_NOFS); -+ wh_name.name = p; -+ if (unlikely(!wh_name.name)) -+ goto out; -+ -+ err = 0; -+ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); -+ p += AUFS_WH_PFX_LEN; -+ n = whlist->nh_num; -+ head = whlist->nh_head; -+ for (ul = 0; !err && ul < n; ul++, head++) { -+ hlist_for_each_entry(pos, head, wh_hash) { -+ if (pos->wh_bindex != bindex) -+ continue; -+ -+ str = &pos->wh_str; -+ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) { -+ memcpy(p, str->name, str->len); -+ wh_name.len = AUFS_WH_PFX_LEN + str->len; -+ err = unlink_wh_name(h_dentry, &wh_name, br); -+ if (!err) -+ continue; -+ break; -+ } -+ AuIOErr("whiteout name too long %.*s\n", -+ str->len, str->name); -+ err = -EIO; -+ break; -+ } -+ } -+ free_page((unsigned long)wh_name.name); -+ -+out: -+ return err; -+} -+ -+struct del_wh_children_args { -+ int *errp; -+ struct dentry *h_dentry; -+ struct au_nhash *whlist; -+ aufs_bindex_t bindex; -+ struct au_branch *br; -+}; -+ -+static void call_del_wh_children(void *args) -+{ -+ struct del_wh_children_args *a = args; -+ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp) -+{ -+ struct au_whtmp_rmdir *whtmp; -+ int err; -+ unsigned int rdhash; -+ -+ SiMustAnyLock(sb); -+ -+ whtmp = kzalloc(sizeof(*whtmp), gfp); -+ if (unlikely(!whtmp)) { -+ whtmp = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ -+ /* no estimation for dir size */ -+ rdhash = au_sbi(sb)->si_rdhash; -+ if (!rdhash) -+ rdhash = AUFS_RDHASH_DEF; -+ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp); -+ if (unlikely(err)) { -+ kfree(whtmp); -+ whtmp = ERR_PTR(err); -+ } -+ -+out: -+ return whtmp; -+} -+ -+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp) -+{ -+ if (whtmp->br) -+ au_lcnt_dec(&whtmp->br->br_count); -+ dput(whtmp->wh_dentry); -+ iput(whtmp->dir); -+ au_nhash_wh_free(&whtmp->whlist); -+ kfree(whtmp); -+} -+ -+/* -+ * rmdir the whiteouted temporary named dir @h_dentry. -+ * @whlist: whiteouted children. -+ */ -+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, -+ struct dentry *wh_dentry, struct au_nhash *whlist) -+{ -+ int err; -+ unsigned int h_nlink; -+ struct path h_tmp; -+ struct inode *wh_inode, *h_dir; -+ struct au_branch *br; -+ -+ h_dir = d_inode(wh_dentry->d_parent); /* dir inode is locked */ -+ IMustLock(h_dir); -+ -+ br = au_sbr(dir->i_sb, bindex); -+ wh_inode = d_inode(wh_dentry); -+ inode_lock_nested(wh_inode, AuLsc_I_CHILD); -+ -+ /* -+ * someone else might change some whiteouts while we were sleeping. -+ * it means this whlist may have an obsoleted entry. -+ */ -+ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE)) -+ err = del_wh_children(wh_dentry, whlist, bindex, br); -+ else { -+ int wkq_err; -+ struct del_wh_children_args args = { -+ .errp = &err, -+ .h_dentry = wh_dentry, -+ .whlist = whlist, -+ .bindex = bindex, -+ .br = br -+ }; -+ -+ wkq_err = au_wkq_wait(call_del_wh_children, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ } -+ inode_unlock(wh_inode); -+ -+ if (!err) { -+ h_tmp.dentry = wh_dentry; -+ h_tmp.mnt = au_br_mnt(br); -+ h_nlink = h_dir->i_nlink; -+ err = vfsub_rmdir(h_dir, &h_tmp); -+ /* some fs doesn't change the parent nlink in some cases */ -+ h_nlink -= h_dir->i_nlink; -+ } -+ -+ if (!err) { -+ if (au_ibtop(dir) == bindex) { -+ /* todo: dir->i_mutex is necessary */ -+ au_cpup_attr_timesizes(dir); -+ if (h_nlink) -+ vfsub_drop_nlink(dir); -+ } -+ return 0; /* success */ -+ } -+ -+ pr_warn("failed removing %pd(%d), ignored\n", wh_dentry, err); -+ return err; -+} -+ -+static void call_rmdir_whtmp(void *args) -+{ -+ int err; -+ aufs_bindex_t bindex; -+ struct au_whtmp_rmdir *a = args; -+ struct super_block *sb; -+ struct dentry *h_parent; -+ struct inode *h_dir; -+ struct au_hinode *hdir; -+ -+ /* rmdir by nfsd may cause deadlock with this i_mutex */ -+ /* inode_lock(a->dir); */ -+ err = -EROFS; -+ sb = a->dir->i_sb; -+ si_read_lock(sb, !AuLock_FLUSH); -+ if (!au_br_writable(a->br->br_perm)) -+ goto out; -+ bindex = au_br_index(sb, a->br->br_id); -+ if (unlikely(bindex < 0)) -+ goto out; -+ -+ err = -EIO; -+ ii_write_lock_parent(a->dir); -+ h_parent = dget_parent(a->wh_dentry); -+ h_dir = d_inode(h_parent); -+ hdir = au_hi(a->dir, bindex); -+ err = vfsub_mnt_want_write(au_br_mnt(a->br)); -+ if (unlikely(err)) -+ goto out_mnt; -+ au_hn_inode_lock_nested(hdir, AuLsc_I_PARENT); -+ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent, -+ a->br); -+ if (!err) -+ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist); -+ au_hn_inode_unlock(hdir); -+ vfsub_mnt_drop_write(au_br_mnt(a->br)); -+ -+out_mnt: -+ dput(h_parent); -+ ii_write_unlock(a->dir); -+out: -+ /* inode_unlock(a->dir); */ -+ au_whtmp_rmdir_free(a); -+ si_read_unlock(sb); -+ au_nwt_done(&au_sbi(sb)->si_nowait); -+ if (unlikely(err)) -+ AuIOErr("err %d\n", err); -+} -+ -+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, -+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args) -+{ -+ int wkq_err; -+ struct super_block *sb; -+ -+ IMustLock(dir); -+ -+ /* all post-process will be done in do_rmdir_whtmp(). */ -+ sb = dir->i_sb; -+ args->dir = au_igrab(dir); -+ args->br = au_sbr(sb, bindex); -+ au_lcnt_inc(&args->br->br_count); -+ args->wh_dentry = dget(wh_dentry); -+ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0); -+ if (unlikely(wkq_err)) { -+ pr_warn("rmdir error %pd (%d), ignored\n", wh_dentry, wkq_err); -+ au_whtmp_rmdir_free(args); -+ } -+} -diff --git a/fs/aufs/whout.h b/fs/aufs/whout.h -new file mode 100644 -index 000000000..2bbc38ba3 ---- /dev/null -+++ b/fs/aufs/whout.h -@@ -0,0 +1,86 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * whiteout for logical deletion and opaque directory -+ */ -+ -+#ifndef __AUFS_WHOUT_H__ -+#define __AUFS_WHOUT_H__ -+ -+#ifdef __KERNEL__ -+ -+#include "dir.h" -+ -+/* whout.c */ -+int au_wh_name_alloc(struct qstr *wh, const struct qstr *name); -+int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio); -+int au_diropq_test(struct dentry *h_dentry); -+struct au_branch; -+struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br, -+ struct qstr *prefix); -+int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br); -+int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path, -+ struct dentry *dentry); -+int au_wh_init(struct au_branch *br, struct super_block *sb); -+ -+/* diropq flags */ -+#define AuDiropq_CREATE 1 -+#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name) -+#define au_fset_diropq(flags, name) \ -+ do { (flags) |= AuDiropq_##name; } while (0) -+#define au_fclr_diropq(flags, name) \ -+ do { (flags) &= ~AuDiropq_##name; } while (0) -+ -+struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, -+ unsigned int flags); -+struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, -+ struct au_branch *br); -+struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, -+ struct dentry *h_parent); -+ -+/* real rmdir for the whiteout-ed dir */ -+struct au_whtmp_rmdir { -+ struct inode *dir; -+ struct au_branch *br; -+ struct dentry *wh_dentry; -+ struct au_nhash whlist; -+}; -+ -+struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp); -+void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp); -+int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, -+ struct dentry *wh_dentry, struct au_nhash *whlist); -+void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, -+ struct dentry *wh_dentry, struct au_whtmp_rmdir *args); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline struct dentry *au_diropq_create(struct dentry *dentry, -+ aufs_bindex_t bindex) -+{ -+ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE); -+} -+ -+static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex) -+{ -+ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE)); -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_WHOUT_H__ */ -diff --git a/fs/aufs/wkq.c b/fs/aufs/wkq.c -new file mode 100644 -index 000000000..55fab985c ---- /dev/null -+++ b/fs/aufs/wkq.c -@@ -0,0 +1,392 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * workqueue for asynchronous/super-io operations -+ * todo: try new credential scheme -+ */ -+ -+#include -+#include "aufs.h" -+ -+/* internal workqueue named AUFS_WKQ_NAME */ -+ -+static struct workqueue_struct *au_wkq; -+ -+struct au_wkinfo { -+ struct work_struct wk; -+ struct kobject *kobj; -+ -+ unsigned int flags; /* see wkq.h */ -+ -+ au_wkq_func_t func; -+ void *args; -+ -+#ifdef CONFIG_LOCKDEP -+ int dont_check; -+ struct held_lock **hlock; -+#endif -+ -+ struct completion *comp; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+/* -+ * Aufs passes some operations to the workqueue such as the internal copyup. -+ * This scheme looks rather unnatural for LOCKDEP debugging feature, since the -+ * job run by workqueue depends upon the locks acquired in the other task. -+ * Delegating a small operation to the workqueue, aufs passes its lockdep -+ * information too. And the job in the workqueue restores the info in order to -+ * pretend as if it acquired those locks. This is just to make LOCKDEP work -+ * correctly and expectedly. -+ */ -+ -+#ifndef CONFIG_LOCKDEP -+AuStubInt0(au_wkq_lockdep_alloc, struct au_wkinfo *wkinfo); -+AuStubVoid(au_wkq_lockdep_free, struct au_wkinfo *wkinfo); -+AuStubVoid(au_wkq_lockdep_pre, struct au_wkinfo *wkinfo); -+AuStubVoid(au_wkq_lockdep_post, struct au_wkinfo *wkinfo); -+AuStubVoid(au_wkq_lockdep_init, struct au_wkinfo *wkinfo); -+#else -+static void au_wkq_lockdep_init(struct au_wkinfo *wkinfo) -+{ -+ wkinfo->hlock = NULL; -+ wkinfo->dont_check = 0; -+} -+ -+/* -+ * 1: matched -+ * 0: unmatched -+ */ -+static int au_wkq_lockdep_test(struct lock_class_key *key, const char *name) -+{ -+ static DEFINE_SPINLOCK(spin); -+ static struct { -+ char *name; -+ struct lock_class_key *key; -+ } a[] = { -+ { .name = "&sbinfo->si_rwsem" }, -+ { .name = "&finfo->fi_rwsem" }, -+ { .name = "&dinfo->di_rwsem" }, -+ { .name = "&iinfo->ii_rwsem" } -+ }; -+ static int set; -+ int i; -+ -+ /* lockless read from 'set.' see below */ -+ if (set == ARRAY_SIZE(a)) { -+ for (i = 0; i < ARRAY_SIZE(a); i++) -+ if (a[i].key == key) -+ goto match; -+ goto unmatch; -+ } -+ -+ spin_lock(&spin); -+ if (set) -+ for (i = 0; i < ARRAY_SIZE(a); i++) -+ if (a[i].key == key) { -+ spin_unlock(&spin); -+ goto match; -+ } -+ for (i = 0; i < ARRAY_SIZE(a); i++) { -+ if (a[i].key) { -+ if (unlikely(a[i].key == key)) { /* rare but possible */ -+ spin_unlock(&spin); -+ goto match; -+ } else -+ continue; -+ } -+ if (strstr(a[i].name, name)) { -+ /* -+ * the order of these three lines is important for the -+ * lockless read above. -+ */ -+ a[i].key = key; -+ spin_unlock(&spin); -+ set++; -+ /* AuDbg("%d, %s\n", set, name); */ -+ goto match; -+ } -+ } -+ spin_unlock(&spin); -+ goto unmatch; -+ -+match: -+ return 1; -+unmatch: -+ return 0; -+} -+ -+static int au_wkq_lockdep_alloc(struct au_wkinfo *wkinfo) -+{ -+ int err, n; -+ struct task_struct *curr; -+ struct held_lock **hl, *held_locks, *p; -+ -+ err = 0; -+ curr = current; -+ wkinfo->dont_check = lockdep_recursing(curr); -+ if (wkinfo->dont_check) -+ goto out; -+ n = curr->lockdep_depth; -+ if (!n) -+ goto out; -+ -+ err = -ENOMEM; -+ wkinfo->hlock = kmalloc_array(n + 1, sizeof(*wkinfo->hlock), GFP_NOFS); -+ if (unlikely(!wkinfo->hlock)) -+ goto out; -+ -+ err = 0; -+#if 0 -+ if (0 && au_debug_test()) /* left for debugging */ -+ lockdep_print_held_locks(curr); -+#endif -+ held_locks = curr->held_locks; -+ hl = wkinfo->hlock; -+ while (n--) { -+ p = held_locks++; -+ if (au_wkq_lockdep_test(p->instance->key, p->instance->name)) -+ *hl++ = p; -+ } -+ *hl = NULL; -+ -+out: -+ return err; -+} -+ -+static void au_wkq_lockdep_free(struct au_wkinfo *wkinfo) -+{ -+ kfree(wkinfo->hlock); -+} -+ -+static void au_wkq_lockdep_pre(struct au_wkinfo *wkinfo) -+{ -+ struct held_lock *p, **hl = wkinfo->hlock; -+ int subclass; -+ -+ if (wkinfo->dont_check) -+ lockdep_off(); -+ if (!hl) -+ return; -+ while ((p = *hl++)) { /* assignment */ -+ subclass = lockdep_hlock_class(p)->subclass; -+ /* AuDbg("%s, %d\n", p->instance->name, subclass); */ -+ if (p->read) -+ rwsem_acquire_read(p->instance, subclass, 0, -+ /*p->acquire_ip*/_RET_IP_); -+ else -+ rwsem_acquire(p->instance, subclass, 0, -+ /*p->acquire_ip*/_RET_IP_); -+ } -+} -+ -+static void au_wkq_lockdep_post(struct au_wkinfo *wkinfo) -+{ -+ struct held_lock *p, **hl = wkinfo->hlock; -+ -+ if (wkinfo->dont_check) -+ lockdep_on(); -+ if (!hl) -+ return; -+ while ((p = *hl++)) /* assignment */ -+ rwsem_release(p->instance, 0, /*p->acquire_ip*/_RET_IP_); -+} -+#endif -+ -+static void wkq_func(struct work_struct *wk) -+{ -+ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk); -+ -+ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)); -+ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY); -+ -+ au_wkq_lockdep_pre(wkinfo); -+ wkinfo->func(wkinfo->args); -+ au_wkq_lockdep_post(wkinfo); -+ if (au_ftest_wkq(wkinfo->flags, WAIT)) -+ complete(wkinfo->comp); -+ else { -+ kobject_put(wkinfo->kobj); -+ module_put(THIS_MODULE); /* todo: ?? */ -+ kfree(wkinfo); -+ } -+} -+ -+/* -+ * Since struct completion is large, try allocating it dynamically. -+ */ -+#if 1 /* defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) */ -+#define AuWkqCompDeclare(name) struct completion *comp = NULL -+ -+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) -+{ -+ *comp = kmalloc(sizeof(**comp), GFP_NOFS); -+ if (*comp) { -+ init_completion(*comp); -+ wkinfo->comp = *comp; -+ return 0; -+ } -+ return -ENOMEM; -+} -+ -+static void au_wkq_comp_free(struct completion *comp) -+{ -+ kfree(comp); -+} -+ -+#else -+ -+/* no braces */ -+#define AuWkqCompDeclare(name) \ -+ DECLARE_COMPLETION_ONSTACK(_ ## name); \ -+ struct completion *comp = &_ ## name -+ -+static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) -+{ -+ wkinfo->comp = *comp; -+ return 0; -+} -+ -+static void au_wkq_comp_free(struct completion *comp __maybe_unused) -+{ -+ /* empty */ -+} -+#endif /* 4KSTACKS */ -+ -+static void au_wkq_run(struct au_wkinfo *wkinfo) -+{ -+ if (au_ftest_wkq(wkinfo->flags, NEST)) { -+ if (au_wkq_test()) { -+ AuWarn1("wkq from wkq, unless silly-rename on NFS," -+ " due to a dead dir by UDBA," -+ " or async xino write?\n"); -+ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT)); -+ } -+ } else -+ au_dbg_verify_kthread(); -+ -+ if (au_ftest_wkq(wkinfo->flags, WAIT)) { -+ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func); -+ queue_work(au_wkq, &wkinfo->wk); -+ } else { -+ INIT_WORK(&wkinfo->wk, wkq_func); -+ schedule_work(&wkinfo->wk); -+ } -+} -+ -+/* -+ * Be careful. It is easy to make deadlock happen. -+ * processA: lock, wkq and wait -+ * processB: wkq and wait, lock in wkq -+ * --> deadlock -+ */ -+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args) -+{ -+ int err; -+ AuWkqCompDeclare(comp); -+ struct au_wkinfo wkinfo = { -+ .flags = flags, -+ .func = func, -+ .args = args -+ }; -+ -+ err = au_wkq_comp_alloc(&wkinfo, &comp); -+ if (unlikely(err)) -+ goto out; -+ err = au_wkq_lockdep_alloc(&wkinfo); -+ if (unlikely(err)) -+ goto out_comp; -+ if (!err) { -+ au_wkq_run(&wkinfo); -+ /* no timeout, no interrupt */ -+ wait_for_completion(wkinfo.comp); -+ } -+ au_wkq_lockdep_free(&wkinfo); -+ -+out_comp: -+ au_wkq_comp_free(comp); -+out: -+ destroy_work_on_stack(&wkinfo.wk); -+ return err; -+} -+ -+/* -+ * Note: dget/dput() in func for aufs dentries are not supported. It will be a -+ * problem in a concurrent umounting. -+ */ -+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb, -+ unsigned int flags) -+{ -+ int err; -+ struct au_wkinfo *wkinfo; -+ -+ atomic_inc(&au_sbi(sb)->si_nowait.nw_len); -+ -+ /* -+ * wkq_func() must free this wkinfo. -+ * it highly depends upon the implementation of workqueue. -+ */ -+ err = 0; -+ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS); -+ if (wkinfo) { -+ wkinfo->kobj = &au_sbi(sb)->si_kobj; -+ wkinfo->flags = flags & ~AuWkq_WAIT; -+ wkinfo->func = func; -+ wkinfo->args = args; -+ wkinfo->comp = NULL; -+ au_wkq_lockdep_init(wkinfo); -+ kobject_get(wkinfo->kobj); -+ __module_get(THIS_MODULE); /* todo: ?? */ -+ -+ au_wkq_run(wkinfo); -+ } else { -+ err = -ENOMEM; -+ au_nwt_done(&au_sbi(sb)->si_nowait); -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+void au_nwt_init(struct au_nowait_tasks *nwt) -+{ -+ atomic_set(&nwt->nw_len, 0); -+ /* smp_mb(); */ /* atomic_set */ -+ init_waitqueue_head(&nwt->nw_wq); -+} -+ -+void au_wkq_fin(void) -+{ -+ destroy_workqueue(au_wkq); -+} -+ -+int __init au_wkq_init(void) -+{ -+ int err; -+ -+ err = 0; -+ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE); -+ if (IS_ERR(au_wkq)) -+ err = PTR_ERR(au_wkq); -+ else if (!au_wkq) -+ err = -ENOMEM; -+ -+ return err; -+} -diff --git a/fs/aufs/wkq.h b/fs/aufs/wkq.h -new file mode 100644 -index 000000000..2e50ed834 ---- /dev/null -+++ b/fs/aufs/wkq.h -@@ -0,0 +1,89 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * workqueue for asynchronous/super-io operations -+ * todo: try new credentials management scheme -+ */ -+ -+#ifndef __AUFS_WKQ_H__ -+#define __AUFS_WKQ_H__ -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+struct super_block; -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue -+ */ -+struct au_nowait_tasks { -+ atomic_t nw_len; -+ wait_queue_head_t nw_wq; -+}; -+ -+/* ---------------------------------------------------------------------- */ -+ -+typedef void (*au_wkq_func_t)(void *args); -+ -+/* wkq flags */ -+#define AuWkq_WAIT 1 -+#define AuWkq_NEST (1 << 1) -+#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name) -+#define au_fset_wkq(flags, name) \ -+ do { (flags) |= AuWkq_##name; } while (0) -+#define au_fclr_wkq(flags, name) \ -+ do { (flags) &= ~AuWkq_##name; } while (0) -+ -+/* wkq.c */ -+int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args); -+int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb, -+ unsigned int flags); -+void au_nwt_init(struct au_nowait_tasks *nwt); -+int __init au_wkq_init(void); -+void au_wkq_fin(void); -+ -+/* ---------------------------------------------------------------------- */ -+ -+static inline int au_wkq_test(void) -+{ -+ return current->flags & PF_WQ_WORKER; -+} -+ -+static inline int au_wkq_wait(au_wkq_func_t func, void *args) -+{ -+ return au_wkq_do_wait(AuWkq_WAIT, func, args); -+} -+ -+static inline void au_nwt_done(struct au_nowait_tasks *nwt) -+{ -+ if (atomic_dec_and_test(&nwt->nw_len)) -+ wake_up_all(&nwt->nw_wq); -+} -+ -+static inline int au_nwt_flush(struct au_nowait_tasks *nwt) -+{ -+ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len)); -+ return 0; -+} -+ -+#endif /* __KERNEL__ */ -+#endif /* __AUFS_WKQ_H__ */ -diff --git a/fs/aufs/xattr.c b/fs/aufs/xattr.c -new file mode 100644 -index 000000000..70b891716 ---- /dev/null -+++ b/fs/aufs/xattr.c -@@ -0,0 +1,356 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2014-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * handling xattr functions -+ */ -+ -+#include -+#include -+#include -+#include "aufs.h" -+ -+static int au_xattr_ignore(int err, char *name, unsigned int ignore_flags) -+{ -+ if (!ignore_flags) -+ goto out; -+ switch (err) { -+ case -ENOMEM: -+ case -EDQUOT: -+ goto out; -+ } -+ -+ if ((ignore_flags & AuBrAttr_ICEX) == AuBrAttr_ICEX) { -+ err = 0; -+ goto out; -+ } -+ -+#define cmp(brattr, prefix) do { \ -+ if (!strncmp(name, XATTR_##prefix##_PREFIX, \ -+ XATTR_##prefix##_PREFIX_LEN)) { \ -+ if (ignore_flags & AuBrAttr_ICEX_##brattr) \ -+ err = 0; \ -+ goto out; \ -+ } \ -+ } while (0) -+ -+ cmp(SEC, SECURITY); -+ cmp(SYS, SYSTEM); -+ cmp(TR, TRUSTED); -+ cmp(USR, USER); -+#undef cmp -+ -+ if (ignore_flags & AuBrAttr_ICEX_OTH) -+ err = 0; -+ -+out: -+ return err; -+} -+ -+static const int au_xattr_out_of_list = AuBrAttr_ICEX_OTH << 1; -+ -+static int au_do_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, -+ char *name, char **buf, unsigned int ignore_flags, -+ unsigned int verbose) -+{ -+ int err; -+ ssize_t ssz; -+ struct inode *h_idst; -+ -+ ssz = vfs_getxattr_alloc(h_src, name, buf, 0, GFP_NOFS); -+ err = ssz; -+ if (unlikely(err <= 0)) { -+ if (err == -ENODATA -+ || (err == -EOPNOTSUPP -+ && ((ignore_flags & au_xattr_out_of_list) -+ || (au_test_nfs_noacl(d_inode(h_src)) -+ && (!strcmp(name, XATTR_NAME_POSIX_ACL_ACCESS) -+ || !strcmp(name, -+ XATTR_NAME_POSIX_ACL_DEFAULT)))) -+ )) -+ err = 0; -+ if (err && (verbose || au_debug_test())) -+ pr_err("%s, err %d\n", name, err); -+ goto out; -+ } -+ -+ /* unlock it temporary */ -+ h_idst = d_inode(h_dst); -+ inode_unlock(h_idst); -+ err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0); -+ inode_lock_nested(h_idst, AuLsc_I_CHILD2); -+ if (unlikely(err)) { -+ if (verbose || au_debug_test()) -+ pr_err("%s, err %d\n", name, err); -+ err = au_xattr_ignore(err, name, ignore_flags); -+ } -+ -+out: -+ return err; -+} -+ -+int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags, -+ unsigned int verbose) -+{ -+ int err, unlocked, acl_access, acl_default; -+ ssize_t ssz; -+ struct inode *h_isrc, *h_idst; -+ char *value, *p, *o, *e; -+ -+ /* try stopping to update the source inode while we are referencing */ -+ /* there should not be the parent-child relationship between them */ -+ h_isrc = d_inode(h_src); -+ h_idst = d_inode(h_dst); -+ inode_unlock(h_idst); -+ inode_lock_shared_nested(h_isrc, AuLsc_I_CHILD); -+ inode_lock_nested(h_idst, AuLsc_I_CHILD2); -+ unlocked = 0; -+ -+ /* some filesystems don't list POSIX ACL, for example tmpfs */ -+ ssz = vfs_listxattr(h_src, NULL, 0); -+ err = ssz; -+ if (unlikely(err < 0)) { -+ AuTraceErr(err); -+ if (err == -ENODATA -+ || err == -EOPNOTSUPP) -+ err = 0; /* ignore */ -+ goto out; -+ } -+ -+ err = 0; -+ p = NULL; -+ o = NULL; -+ if (ssz) { -+ err = -ENOMEM; -+ p = kmalloc(ssz, GFP_NOFS); -+ o = p; -+ if (unlikely(!p)) -+ goto out; -+ err = vfs_listxattr(h_src, p, ssz); -+ } -+ inode_unlock_shared(h_isrc); -+ unlocked = 1; -+ AuDbg("err %d, ssz %zd\n", err, ssz); -+ if (unlikely(err < 0)) -+ goto out_free; -+ -+ err = 0; -+ e = p + ssz; -+ value = NULL; -+ acl_access = 0; -+ acl_default = 0; -+ while (!err && p < e) { -+ acl_access |= !strncmp(p, XATTR_NAME_POSIX_ACL_ACCESS, -+ sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1); -+ acl_default |= !strncmp(p, XATTR_NAME_POSIX_ACL_DEFAULT, -+ sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) -+ - 1); -+ err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags, -+ verbose); -+ p += strlen(p) + 1; -+ } -+ AuTraceErr(err); -+ ignore_flags |= au_xattr_out_of_list; -+ if (!err && !acl_access) { -+ err = au_do_cpup_xattr(h_dst, h_src, -+ XATTR_NAME_POSIX_ACL_ACCESS, &value, -+ ignore_flags, verbose); -+ AuTraceErr(err); -+ } -+ if (!err && !acl_default) { -+ err = au_do_cpup_xattr(h_dst, h_src, -+ XATTR_NAME_POSIX_ACL_DEFAULT, &value, -+ ignore_flags, verbose); -+ AuTraceErr(err); -+ } -+ -+ kfree(value); -+ -+out_free: -+ kfree(o); -+out: -+ if (!unlocked) -+ inode_unlock_shared(h_isrc); -+ AuTraceErr(err); -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_smack_reentering(struct super_block *sb) -+{ -+#if IS_ENABLED(CONFIG_SECURITY_SMACK) -+ /* -+ * as a part of lookup, smack_d_instantiate() is called, and it calls -+ * i_op->getxattr(). ouch. -+ */ -+ return si_pid_test(sb); -+#else -+ return 0; -+#endif -+} -+ -+enum { -+ AU_XATTR_LIST, -+ AU_XATTR_GET -+}; -+ -+struct au_lgxattr { -+ int type; -+ union { -+ struct { -+ char *list; -+ size_t size; -+ } list; -+ struct { -+ const char *name; -+ void *value; -+ size_t size; -+ } get; -+ } u; -+}; -+ -+static ssize_t au_lgxattr(struct dentry *dentry, struct au_lgxattr *arg) -+{ -+ ssize_t err; -+ int reenter; -+ struct path h_path; -+ struct super_block *sb; -+ -+ sb = dentry->d_sb; -+ reenter = au_smack_reentering(sb); -+ if (!reenter) { -+ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); -+ if (unlikely(err)) -+ goto out; -+ } -+ err = au_h_path_getattr(dentry, /*force*/1, &h_path, reenter); -+ if (unlikely(err)) -+ goto out_si; -+ if (unlikely(!h_path.dentry)) -+ /* illegally overlapped or something */ -+ goto out_di; /* pretending success */ -+ -+ /* always topmost entry only */ -+ switch (arg->type) { -+ case AU_XATTR_LIST: -+ err = vfs_listxattr(h_path.dentry, -+ arg->u.list.list, arg->u.list.size); -+ break; -+ case AU_XATTR_GET: -+ AuDebugOn(d_is_negative(h_path.dentry)); -+ err = vfs_getxattr(h_path.dentry, -+ arg->u.get.name, arg->u.get.value, -+ arg->u.get.size); -+ break; -+ } -+ -+out_di: -+ if (!reenter) -+ di_read_unlock(dentry, AuLock_IR); -+out_si: -+ if (!reenter) -+ si_read_unlock(sb); -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size) -+{ -+ struct au_lgxattr arg = { -+ .type = AU_XATTR_LIST, -+ .u.list = { -+ .list = list, -+ .size = size -+ }, -+ }; -+ -+ return au_lgxattr(dentry, &arg); -+} -+ -+static ssize_t au_getxattr(struct dentry *dentry, -+ struct inode *inode __maybe_unused, -+ const char *name, void *value, size_t size) -+{ -+ struct au_lgxattr arg = { -+ .type = AU_XATTR_GET, -+ .u.get = { -+ .name = name, -+ .value = value, -+ .size = size -+ }, -+ }; -+ -+ return au_lgxattr(dentry, &arg); -+} -+ -+static int au_setxattr(struct dentry *dentry, struct inode *inode, -+ const char *name, const void *value, size_t size, -+ int flags) -+{ -+ struct au_sxattr arg = { -+ .type = AU_XATTR_SET, -+ .u.set = { -+ .name = name, -+ .value = value, -+ .size = size, -+ .flags = flags -+ }, -+ }; -+ -+ return au_sxattr(dentry, inode, &arg); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_xattr_get(const struct xattr_handler *handler, -+ struct dentry *dentry, struct inode *inode, -+ const char *name, void *buffer, size_t size) -+{ -+ return au_getxattr(dentry, inode, name, buffer, size); -+} -+ -+static int au_xattr_set(const struct xattr_handler *handler, -+ struct dentry *dentry, struct inode *inode, -+ const char *name, const void *value, size_t size, -+ int flags) -+{ -+ return au_setxattr(dentry, inode, name, value, size, flags); -+} -+ -+static const struct xattr_handler au_xattr_handler = { -+ .name = "", -+ .prefix = "", -+ .get = au_xattr_get, -+ .set = au_xattr_set -+}; -+ -+static const struct xattr_handler *au_xattr_handlers[] = { -+#ifdef CONFIG_FS_POSIX_ACL -+ &posix_acl_access_xattr_handler, -+ &posix_acl_default_xattr_handler, -+#endif -+ &au_xattr_handler, /* must be last */ -+ NULL -+}; -+ -+void au_xattr_init(struct super_block *sb) -+{ -+ sb->s_xattr = au_xattr_handlers; -+} -diff --git a/fs/aufs/xino.c b/fs/aufs/xino.c -new file mode 100644 -index 000000000..1236699a3 ---- /dev/null -+++ b/fs/aufs/xino.c -@@ -0,0 +1,1890 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * external inode number translation table and bitmap -+ * -+ * things to consider -+ * - the lifetime -+ * + au_xino object -+ * + XINO files (xino, xib, xigen) -+ * + dynamic debugfs entries (xiN) -+ * + static debugfs entries (xib, xigen) -+ * + static sysfs entry (xi_path) -+ * - several entry points to handle them. -+ * + mount(2) without xino option (default) -+ * + mount(2) with xino option -+ * + mount(2) with noxino option -+ * + umount(2) -+ * + remount with add/del branches -+ * + remount with xino/noxino options -+ */ -+ -+#include -+#include -+#include "aufs.h" -+ -+static aufs_bindex_t sbr_find_shared(struct super_block *sb, aufs_bindex_t btop, -+ aufs_bindex_t bbot, -+ struct super_block *h_sb) -+{ -+ /* todo: try binary-search if the branches are many */ -+ for (; btop <= bbot; btop++) -+ if (h_sb == au_sbr_sb(sb, btop)) -+ return btop; -+ return -1; -+} -+ -+/* -+ * find another branch who is on the same filesystem of the specified -+ * branch{@btgt}. search until @bbot. -+ */ -+static aufs_bindex_t is_sb_shared(struct super_block *sb, aufs_bindex_t btgt, -+ aufs_bindex_t bbot) -+{ -+ aufs_bindex_t bindex; -+ struct super_block *tgt_sb; -+ -+ tgt_sb = au_sbr_sb(sb, btgt); -+ bindex = sbr_find_shared(sb, /*btop*/0, btgt - 1, tgt_sb); -+ if (bindex < 0) -+ bindex = sbr_find_shared(sb, btgt + 1, bbot, tgt_sb); -+ -+ return bindex; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * stop unnecessary notify events at creating xino files -+ */ -+ -+aufs_bindex_t au_xi_root(struct super_block *sb, struct dentry *dentry) -+{ -+ aufs_bindex_t bfound, bindex, bbot; -+ struct dentry *parent; -+ struct au_branch *br; -+ -+ bfound = -1; -+ parent = dentry->d_parent; /* safe d_parent access */ -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_dentry(br) == parent) { -+ bfound = bindex; -+ break; -+ } -+ } -+ -+ AuDbg("bfound b%d\n", bfound); -+ return bfound; -+} -+ -+struct au_xino_lock_dir { -+ struct au_hinode *hdir; -+ struct dentry *parent; -+ struct inode *dir; -+}; -+ -+static struct dentry *au_dget_parent_lock(struct dentry *dentry, -+ unsigned int lsc) -+{ -+ struct dentry *parent; -+ struct inode *dir; -+ -+ parent = dget_parent(dentry); -+ dir = d_inode(parent); -+ inode_lock_nested(dir, lsc); -+#if 0 /* it should not happen */ -+ spin_lock(&dentry->d_lock); -+ if (unlikely(dentry->d_parent != parent)) { -+ spin_unlock(&dentry->d_lock); -+ inode_unlock(dir); -+ dput(parent); -+ parent = NULL; -+ goto out; -+ } -+ spin_unlock(&dentry->d_lock); -+ -+out: -+#endif -+ return parent; -+} -+ -+static void au_xino_lock_dir(struct super_block *sb, struct path *xipath, -+ struct au_xino_lock_dir *ldir) -+{ -+ aufs_bindex_t bindex; -+ -+ ldir->hdir = NULL; -+ bindex = au_xi_root(sb, xipath->dentry); -+ if (bindex >= 0) { -+ /* rw branch root */ -+ ldir->hdir = au_hi(d_inode(sb->s_root), bindex); -+ au_hn_inode_lock_nested(ldir->hdir, AuLsc_I_PARENT); -+ } else { -+ /* other */ -+ ldir->parent = au_dget_parent_lock(xipath->dentry, -+ AuLsc_I_PARENT); -+ ldir->dir = d_inode(ldir->parent); -+ } -+} -+ -+static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir) -+{ -+ if (ldir->hdir) -+ au_hn_inode_unlock(ldir->hdir); -+ else { -+ inode_unlock(ldir->dir); -+ dput(ldir->parent); -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * create and set a new xino file -+ */ -+struct file *au_xino_create(struct super_block *sb, char *fpath, int silent) -+{ -+ struct file *file; -+ struct dentry *h_parent, *d; -+ struct inode *h_dir, *inode; -+ int err; -+ -+ /* -+ * at mount-time, and the xino file is the default path, -+ * hnotify is disabled so we have no notify events to ignore. -+ * when a user specified the xino, we cannot get au_hdir to be ignored. -+ */ -+ file = vfsub_filp_open(fpath, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE -+ /* | __FMODE_NONOTIFY */, -+ 0666); -+ if (IS_ERR(file)) { -+ if (!silent) -+ pr_err("open %s(%ld)\n", fpath, PTR_ERR(file)); -+ return file; -+ } -+ -+ /* keep file count */ -+ err = 0; -+ d = file->f_path.dentry; -+ h_parent = au_dget_parent_lock(d, AuLsc_I_PARENT); -+ /* mnt_want_write() is unnecessary here */ -+ h_dir = d_inode(h_parent); -+ inode = file_inode(file); -+ /* no delegation since it is just created */ -+ if (inode->i_nlink) -+ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL, -+ /*force*/0); -+ inode_unlock(h_dir); -+ dput(h_parent); -+ if (unlikely(err)) { -+ if (!silent) -+ pr_err("unlink %s(%d)\n", fpath, err); -+ goto out; -+ } -+ -+ err = -EINVAL; -+ if (unlikely(sb == d->d_sb)) { -+ if (!silent) -+ pr_err("%s must be outside\n", fpath); -+ goto out; -+ } -+ if (unlikely(au_test_fs_bad_xino(d->d_sb))) { -+ if (!silent) -+ pr_err("xino doesn't support %s(%s)\n", -+ fpath, au_sbtype(d->d_sb)); -+ goto out; -+ } -+ return file; /* success */ -+ -+out: -+ fput(file); -+ file = ERR_PTR(err); -+ return file; -+} -+ -+/* -+ * create a new xinofile at the same place/path as @base. -+ */ -+struct file *au_xino_create2(struct super_block *sb, struct path *base, -+ struct file *copy_src) -+{ -+ struct file *file; -+ struct dentry *dentry, *parent; -+ struct inode *dir, *delegated; -+ struct qstr *name; -+ struct path path; -+ int err, do_unlock; -+ struct au_xino_lock_dir ldir; -+ -+ do_unlock = 1; -+ au_xino_lock_dir(sb, base, &ldir); -+ dentry = base->dentry; -+ parent = dentry->d_parent; /* dir inode is locked */ -+ dir = d_inode(parent); -+ IMustLock(dir); -+ -+ name = &dentry->d_name; -+ path.dentry = vfsub_lookup_one_len(name->name, parent, name->len); -+ if (IS_ERR(path.dentry)) { -+ file = (void *)path.dentry; -+ pr_err("%pd lookup err %ld\n", dentry, PTR_ERR(path.dentry)); -+ goto out; -+ } -+ -+ /* no need to mnt_want_write() since we call dentry_open() later */ -+ err = vfs_create(dir, path.dentry, 0666, NULL); -+ if (unlikely(err)) { -+ file = ERR_PTR(err); -+ pr_err("%pd create err %d\n", dentry, err); -+ goto out_dput; -+ } -+ -+ path.mnt = base->mnt; -+ file = vfsub_dentry_open(&path, -+ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE -+ /* | __FMODE_NONOTIFY */); -+ if (IS_ERR(file)) { -+ pr_err("%pd open err %ld\n", dentry, PTR_ERR(file)); -+ goto out_dput; -+ } -+ -+ delegated = NULL; -+ err = vfsub_unlink(dir, &file->f_path, &delegated, /*force*/0); -+ au_xino_unlock_dir(&ldir); -+ do_unlock = 0; -+ if (unlikely(err == -EWOULDBLOCK)) { -+ pr_warn("cannot retry for NFSv4 delegation" -+ " for an internal unlink\n"); -+ iput(delegated); -+ } -+ if (unlikely(err)) { -+ pr_err("%pd unlink err %d\n", dentry, err); -+ goto out_fput; -+ } -+ -+ if (copy_src) { -+ /* no one can touch copy_src xino */ -+ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src)); -+ if (unlikely(err)) { -+ pr_err("%pd copy err %d\n", dentry, err); -+ goto out_fput; -+ } -+ } -+ goto out_dput; /* success */ -+ -+out_fput: -+ fput(file); -+ file = ERR_PTR(err); -+out_dput: -+ dput(path.dentry); -+out: -+ if (do_unlock) -+ au_xino_unlock_dir(&ldir); -+ return file; -+} -+ -+struct file *au_xino_file1(struct au_xino *xi) -+{ -+ struct file *file; -+ unsigned int u, nfile; -+ -+ file = NULL; -+ nfile = xi->xi_nfile; -+ for (u = 0; u < nfile; u++) { -+ file = xi->xi_file[u]; -+ if (file) -+ break; -+ } -+ -+ return file; -+} -+ -+static int au_xino_file_set(struct au_xino *xi, int idx, struct file *file) -+{ -+ int err; -+ struct file *f; -+ void *p; -+ -+ if (file) -+ get_file(file); -+ -+ err = 0; -+ f = NULL; -+ if (idx < xi->xi_nfile) { -+ f = xi->xi_file[idx]; -+ if (f) -+ fput(f); -+ } else { -+ p = au_kzrealloc(xi->xi_file, -+ sizeof(*xi->xi_file) * xi->xi_nfile, -+ sizeof(*xi->xi_file) * (idx + 1), -+ GFP_NOFS, /*may_shrink*/0); -+ if (p) { -+ MtxMustLock(&xi->xi_mtx); -+ xi->xi_file = p; -+ xi->xi_nfile = idx + 1; -+ } else { -+ err = -ENOMEM; -+ if (file) -+ fput(file); -+ goto out; -+ } -+ } -+ xi->xi_file[idx] = file; -+ -+out: -+ return err; -+} -+ -+/* -+ * if @xinew->xi is not set, then create new xigen file. -+ */ -+struct file *au_xi_new(struct super_block *sb, struct au_xi_new *xinew) -+{ -+ struct file *file; -+ int err; -+ -+ SiMustAnyLock(sb); -+ -+ file = au_xino_create2(sb, xinew->base, xinew->copy_src); -+ if (IS_ERR(file)) { -+ err = PTR_ERR(file); -+ pr_err("%s[%d], err %d\n", -+ xinew->xi ? "xino" : "xigen", -+ xinew->idx, err); -+ goto out; -+ } -+ -+ if (xinew->xi) -+ err = au_xino_file_set(xinew->xi, xinew->idx, file); -+ else { -+ BUG(); -+ /* todo: make xigen file an array */ -+ /* err = au_xigen_file_set(sb, xinew->idx, file); */ -+ } -+ fput(file); -+ if (unlikely(err)) -+ file = ERR_PTR(err); -+ -+out: -+ return file; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * truncate xino files -+ */ -+static int au_xino_do_trunc(struct super_block *sb, aufs_bindex_t bindex, -+ int idx, struct kstatfs *st) -+{ -+ int err; -+ blkcnt_t blocks; -+ struct file *file, *new_xino; -+ struct au_xi_new xinew = { -+ .idx = idx -+ }; -+ -+ err = 0; -+ xinew.xi = au_sbr(sb, bindex)->br_xino; -+ file = au_xino_file(xinew.xi, idx); -+ if (!file) -+ goto out; -+ -+ xinew.base = &file->f_path; -+ err = vfs_statfs(xinew.base, st); -+ if (unlikely(err)) { -+ AuErr1("statfs err %d, ignored\n", err); -+ err = 0; -+ goto out; -+ } -+ -+ blocks = file_inode(file)->i_blocks; -+ pr_info("begin truncating xino(b%d-%d), ib%llu, %llu/%llu free blks\n", -+ bindex, idx, (u64)blocks, st->f_bfree, st->f_blocks); -+ -+ xinew.copy_src = file; -+ new_xino = au_xi_new(sb, &xinew); -+ if (IS_ERR(new_xino)) { -+ err = PTR_ERR(new_xino); -+ pr_err("xino(b%d-%d), err %d, ignored\n", bindex, idx, err); -+ goto out; -+ } -+ -+ err = vfs_statfs(&new_xino->f_path, st); -+ if (!err) -+ pr_info("end truncating xino(b%d-%d), ib%llu, %llu/%llu free blks\n", -+ bindex, idx, (u64)file_inode(new_xino)->i_blocks, -+ st->f_bfree, st->f_blocks); -+ else { -+ AuErr1("statfs err %d, ignored\n", err); -+ err = 0; -+ } -+ -+out: -+ return err; -+} -+ -+int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex, int idx_begin) -+{ -+ int err, i; -+ unsigned long jiffy; -+ aufs_bindex_t bbot; -+ struct kstatfs *st; -+ struct au_branch *br; -+ struct au_xino *xi; -+ -+ err = -ENOMEM; -+ st = kmalloc(sizeof(*st), GFP_NOFS); -+ if (unlikely(!st)) -+ goto out; -+ -+ err = -EINVAL; -+ bbot = au_sbbot(sb); -+ if (unlikely(bindex < 0 || bbot < bindex)) -+ goto out_st; -+ -+ err = 0; -+ jiffy = jiffies; -+ br = au_sbr(sb, bindex); -+ xi = br->br_xino; -+ for (i = idx_begin; !err && i < xi->xi_nfile; i++) -+ err = au_xino_do_trunc(sb, bindex, i, st); -+ if (!err) -+ au_sbi(sb)->si_xino_jiffy = jiffy; -+ -+out_st: -+ kfree(st); -+out: -+ return err; -+} -+ -+struct xino_do_trunc_args { -+ struct super_block *sb; -+ struct au_branch *br; -+ int idx; -+}; -+ -+static void xino_do_trunc(void *_args) -+{ -+ struct xino_do_trunc_args *args = _args; -+ struct super_block *sb; -+ struct au_branch *br; -+ struct inode *dir; -+ int err, idx; -+ aufs_bindex_t bindex; -+ -+ err = 0; -+ sb = args->sb; -+ dir = d_inode(sb->s_root); -+ br = args->br; -+ idx = args->idx; -+ -+ si_noflush_write_lock(sb); -+ ii_read_lock_parent(dir); -+ bindex = au_br_index(sb, br->br_id); -+ err = au_xino_trunc(sb, bindex, idx); -+ ii_read_unlock(dir); -+ if (unlikely(err)) -+ pr_warn("err b%d, (%d)\n", bindex, err); -+ atomic_dec(&br->br_xino->xi_truncating); -+ au_lcnt_dec(&br->br_count); -+ si_write_unlock(sb); -+ au_nwt_done(&au_sbi(sb)->si_nowait); -+ kfree(args); -+} -+ -+/* -+ * returns the index in the xi_file array whose corresponding file is necessary -+ * to truncate, or -1 which means no need to truncate. -+ */ -+static int xino_trunc_test(struct super_block *sb, struct au_branch *br) -+{ -+ int err; -+ unsigned int u; -+ struct kstatfs st; -+ struct au_sbinfo *sbinfo; -+ struct au_xino *xi; -+ struct file *file; -+ -+ /* todo: si_xino_expire and the ratio should be customizable */ -+ sbinfo = au_sbi(sb); -+ if (time_before(jiffies, -+ sbinfo->si_xino_jiffy + sbinfo->si_xino_expire)) -+ return -1; -+ -+ /* truncation border */ -+ xi = br->br_xino; -+ for (u = 0; u < xi->xi_nfile; u++) { -+ file = au_xino_file(xi, u); -+ if (!file) -+ continue; -+ -+ err = vfs_statfs(&file->f_path, &st); -+ if (unlikely(err)) { -+ AuErr1("statfs err %d, ignored\n", err); -+ return -1; -+ } -+ if (div64_u64(st.f_bfree * 100, st.f_blocks) -+ >= AUFS_XINO_DEF_TRUNC) -+ return u; -+ } -+ -+ return -1; -+} -+ -+static void xino_try_trunc(struct super_block *sb, struct au_branch *br) -+{ -+ int idx; -+ struct xino_do_trunc_args *args; -+ int wkq_err; -+ -+ idx = xino_trunc_test(sb, br); -+ if (idx < 0) -+ return; -+ -+ if (atomic_inc_return(&br->br_xino->xi_truncating) > 1) -+ goto out; -+ -+ /* lock and kfree() will be called in trunc_xino() */ -+ args = kmalloc(sizeof(*args), GFP_NOFS); -+ if (unlikely(!args)) { -+ AuErr1("no memory\n"); -+ goto out; -+ } -+ -+ au_lcnt_inc(&br->br_count); -+ args->sb = sb; -+ args->br = br; -+ args->idx = idx; -+ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0); -+ if (!wkq_err) -+ return; /* success */ -+ -+ pr_err("wkq %d\n", wkq_err); -+ au_lcnt_dec(&br->br_count); -+ kfree(args); -+ -+out: -+ atomic_dec(&br->br_xino->xi_truncating); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_xi_calc { -+ int idx; -+ loff_t pos; -+}; -+ -+static void au_xi_calc(struct super_block *sb, ino_t h_ino, -+ struct au_xi_calc *calc) -+{ -+ loff_t maxent; -+ -+ maxent = au_xi_maxent(sb); -+ calc->idx = div64_u64_rem(h_ino, maxent, &calc->pos); -+ calc->pos *= sizeof(ino_t); -+} -+ -+static int au_xino_do_new_async(struct super_block *sb, struct au_branch *br, -+ struct au_xi_calc *calc) -+{ -+ int err; -+ struct file *file; -+ struct au_xino *xi = br->br_xino; -+ struct au_xi_new xinew = { -+ .xi = xi -+ }; -+ -+ SiMustAnyLock(sb); -+ -+ err = 0; -+ if (!xi) -+ goto out; -+ -+ mutex_lock(&xi->xi_mtx); -+ file = au_xino_file(xi, calc->idx); -+ if (file) -+ goto out_mtx; -+ -+ file = au_xino_file(xi, /*idx*/-1); -+ AuDebugOn(!file); -+ xinew.idx = calc->idx; -+ xinew.base = &file->f_path; -+ /* xinew.copy_src = NULL; */ -+ file = au_xi_new(sb, &xinew); -+ if (IS_ERR(file)) -+ err = PTR_ERR(file); -+ -+out_mtx: -+ mutex_unlock(&xi->xi_mtx); -+out: -+ return err; -+} -+ -+struct au_xino_do_new_async_args { -+ struct super_block *sb; -+ struct au_branch *br; -+ struct au_xi_calc calc; -+ ino_t ino; -+}; -+ -+static int au_xino_do_write(vfs_writef_t write, struct file *file, -+ struct au_xi_calc *calc, ino_t ino); -+ -+static void au_xino_call_do_new_async(void *args) -+{ -+ struct au_xino_do_new_async_args *a = args; -+ struct au_branch *br; -+ struct super_block *sb; -+ struct au_sbinfo *sbi; -+ struct inode *root; -+ struct file *file; -+ int err; -+ -+ br = a->br; -+ sb = a->sb; -+ sbi = au_sbi(sb); -+ si_noflush_read_lock(sb); -+ root = d_inode(sb->s_root); -+ ii_read_lock_child(root); -+ err = au_xino_do_new_async(sb, br, &a->calc); -+ if (!err) { -+ file = au_xino_file(br->br_xino, a->calc.idx); -+ if (file) -+ err = au_xino_do_write(sbi->si_xwrite, file, &a->calc, -+ a->ino); -+ if (unlikely(err)) -+ AuIOErr("err %d\n", err); -+ } else -+ AuIOErr("err %d\n", err); -+ au_lcnt_dec(&br->br_count); -+ ii_read_unlock(root); -+ si_read_unlock(sb); -+ au_nwt_done(&sbi->si_nowait); -+ kfree(args); -+} -+ -+/* -+ * create a new xino file asynchronously -+ */ -+static int au_xino_new_async(struct super_block *sb, struct au_branch *br, -+ struct au_xi_calc *calc, ino_t ino) -+{ -+ int err; -+ struct au_xino_do_new_async_args *arg; -+ -+ err = -ENOMEM; -+ arg = kmalloc(sizeof(*arg), GFP_NOFS); -+ if (unlikely(!arg)) -+ goto out; -+ -+ arg->sb = sb; -+ arg->br = br; -+ arg->calc = *calc; -+ arg->ino = ino; -+ au_lcnt_inc(&br->br_count); -+ err = au_wkq_nowait(au_xino_call_do_new_async, arg, sb, AuWkq_NEST); -+ if (unlikely(err)) { -+ pr_err("wkq %d\n", err); -+ au_lcnt_dec(&br->br_count); -+ kfree(arg); -+ } -+ -+out: -+ return err; -+} -+ -+/* -+ * read @ino from xinofile for the specified branch{@sb, @bindex} -+ * at the position of @h_ino. -+ */ -+int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ ino_t *ino) -+{ -+ int err; -+ ssize_t sz; -+ struct au_xi_calc calc; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ -+ *ino = 0; -+ if (!au_opt_test(au_mntflags(sb), XINO)) -+ return 0; /* no xino */ -+ -+ err = 0; -+ au_xi_calc(sb, h_ino, &calc); -+ file = au_xino_file(au_sbr(sb, bindex)->br_xino, calc.idx); -+ if (!file -+ || vfsub_f_size_read(file) < calc.pos + sizeof(*ino)) -+ return 0; /* no ino */ -+ -+ sbinfo = au_sbi(sb); -+ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &calc.pos); -+ if (sz == sizeof(*ino)) -+ return 0; /* success */ -+ -+ err = sz; -+ if (unlikely(sz >= 0)) { -+ err = -EIO; -+ AuIOErr("xino read error (%zd)\n", sz); -+ } -+ return err; -+} -+ -+static int au_xino_do_write(vfs_writef_t write, struct file *file, -+ struct au_xi_calc *calc, ino_t ino) -+{ -+ ssize_t sz; -+ -+ sz = xino_fwrite(write, file, &ino, sizeof(ino), &calc->pos); -+ if (sz == sizeof(ino)) -+ return 0; /* success */ -+ -+ AuIOErr("write failed (%zd)\n", sz); -+ return -EIO; -+} -+ -+/* -+ * write @ino to the xinofile for the specified branch{@sb, @bindex} -+ * at the position of @h_ino. -+ * even if @ino is zero, it is written to the xinofile and means no entry. -+ * if the size of the xino file on a specific filesystem exceeds the watermark, -+ * try truncating it. -+ */ -+int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ ino_t ino) -+{ -+ int err; -+ unsigned int mnt_flags; -+ struct au_xi_calc calc; -+ struct file *file; -+ struct au_branch *br; -+ struct au_xino *xi; -+ -+ SiMustAnyLock(sb); -+ -+ mnt_flags = au_mntflags(sb); -+ if (!au_opt_test(mnt_flags, XINO)) -+ return 0; -+ -+ au_xi_calc(sb, h_ino, &calc); -+ br = au_sbr(sb, bindex); -+ xi = br->br_xino; -+ file = au_xino_file(xi, calc.idx); -+ if (!file) { -+ /* create and write a new xino file asynchronously */ -+ err = au_xino_new_async(sb, br, &calc, ino); -+ if (!err) -+ return 0; /* success */ -+ goto out; -+ } -+ -+ err = au_xino_do_write(au_sbi(sb)->si_xwrite, file, &calc, ino); -+ if (!err) { -+ br = au_sbr(sb, bindex); -+ if (au_opt_test(mnt_flags, TRUNC_XINO) -+ && au_test_fs_trunc_xino(au_br_sb(br))) -+ xino_try_trunc(sb, br); -+ return 0; /* success */ -+ } -+ -+out: -+ AuIOErr("write failed (%d)\n", err); -+ return -EIO; -+} -+ -+static ssize_t xino_fread_wkq(vfs_readf_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos); -+ -+/* todo: unnecessary to support mmap_sem since kernel-space? */ -+ssize_t xino_fread(vfs_readf_t func, struct file *file, void *kbuf, size_t size, -+ loff_t *pos) -+{ -+ ssize_t err; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ char __user *u; -+ } buf; -+ int i; -+ const int prevent_endless = 10; -+ -+ i = 0; -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ do { -+ err = func(file, buf.u, size, pos); -+ if (err == -EINTR -+ && !au_wkq_test() -+ && fatal_signal_pending(current)) { -+ set_fs(oldfs); -+ err = xino_fread_wkq(func, file, kbuf, size, pos); -+ BUG_ON(err == -EINTR); -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ } -+ } while (i++ < prevent_endless -+ && (err == -EAGAIN || err == -EINTR)); -+ set_fs(oldfs); -+ -+#if 0 /* reserved for future use */ -+ if (err > 0) -+ fsnotify_access(file->f_path.dentry); -+#endif -+ -+ return err; -+} -+ -+struct xino_fread_args { -+ ssize_t *errp; -+ vfs_readf_t func; -+ struct file *file; -+ void *buf; -+ size_t size; -+ loff_t *pos; -+}; -+ -+static void call_xino_fread(void *args) -+{ -+ struct xino_fread_args *a = args; -+ *a->errp = xino_fread(a->func, a->file, a->buf, a->size, a->pos); -+} -+ -+static ssize_t xino_fread_wkq(vfs_readf_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos) -+{ -+ ssize_t err; -+ int wkq_err; -+ struct xino_fread_args args = { -+ .errp = &err, -+ .func = func, -+ .file = file, -+ .buf = buf, -+ .size = size, -+ .pos = pos -+ }; -+ -+ wkq_err = au_wkq_wait(call_xino_fread, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ -+ return err; -+} -+ -+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos); -+ -+static ssize_t do_xino_fwrite(vfs_writef_t func, struct file *file, void *kbuf, -+ size_t size, loff_t *pos) -+{ -+ ssize_t err; -+ mm_segment_t oldfs; -+ union { -+ void *k; -+ const char __user *u; -+ } buf; -+ int i; -+ const int prevent_endless = 10; -+ -+ i = 0; -+ buf.k = kbuf; -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ do { -+ err = func(file, buf.u, size, pos); -+ if (err == -EINTR -+ && !au_wkq_test() -+ && fatal_signal_pending(current)) { -+ set_fs(oldfs); -+ err = xino_fwrite_wkq(func, file, kbuf, size, pos); -+ BUG_ON(err == -EINTR); -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ } -+ } while (i++ < prevent_endless -+ && (err == -EAGAIN || err == -EINTR)); -+ set_fs(oldfs); -+ -+#if 0 /* reserved for future use */ -+ if (err > 0) -+ fsnotify_modify(file->f_path.dentry); -+#endif -+ -+ return err; -+} -+ -+struct do_xino_fwrite_args { -+ ssize_t *errp; -+ vfs_writef_t func; -+ struct file *file; -+ void *buf; -+ size_t size; -+ loff_t *pos; -+}; -+ -+static void call_do_xino_fwrite(void *args) -+{ -+ struct do_xino_fwrite_args *a = args; -+ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos); -+} -+ -+static ssize_t xino_fwrite_wkq(vfs_writef_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos) -+{ -+ ssize_t err; -+ int wkq_err; -+ struct do_xino_fwrite_args args = { -+ .errp = &err, -+ .func = func, -+ .file = file, -+ .buf = buf, -+ .size = size, -+ .pos = pos -+ }; -+ -+ /* -+ * it breaks RLIMIT_FSIZE and normal user's limit, -+ * users should care about quota and real 'filesystem full.' -+ */ -+ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args); -+ if (unlikely(wkq_err)) -+ err = wkq_err; -+ -+ return err; -+} -+ -+ssize_t xino_fwrite(vfs_writef_t func, struct file *file, void *buf, -+ size_t size, loff_t *pos) -+{ -+ ssize_t err; -+ -+ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) { -+ lockdep_off(); -+ err = do_xino_fwrite(func, file, buf, size, pos); -+ lockdep_on(); -+ } else { -+ lockdep_off(); -+ err = xino_fwrite_wkq(func, file, buf, size, pos); -+ lockdep_on(); -+ } -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * inode number bitmap -+ */ -+static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE; -+static ino_t xib_calc_ino(unsigned long pindex, int bit) -+{ -+ ino_t ino; -+ -+ AuDebugOn(bit < 0 || page_bits <= bit); -+ ino = AUFS_FIRST_INO + pindex * page_bits + bit; -+ return ino; -+} -+ -+static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit) -+{ -+ AuDebugOn(ino < AUFS_FIRST_INO); -+ ino -= AUFS_FIRST_INO; -+ *pindex = ino / page_bits; -+ *bit = ino % page_bits; -+} -+ -+static int xib_pindex(struct super_block *sb, unsigned long pindex) -+{ -+ int err; -+ loff_t pos; -+ ssize_t sz; -+ struct au_sbinfo *sbinfo; -+ struct file *xib; -+ unsigned long *p; -+ -+ sbinfo = au_sbi(sb); -+ MtxMustLock(&sbinfo->si_xib_mtx); -+ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE -+ || !au_opt_test(sbinfo->si_mntflags, XINO)); -+ -+ if (pindex == sbinfo->si_xib_last_pindex) -+ return 0; -+ -+ xib = sbinfo->si_xib; -+ p = sbinfo->si_xib_buf; -+ pos = sbinfo->si_xib_last_pindex; -+ pos *= PAGE_SIZE; -+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); -+ if (unlikely(sz != PAGE_SIZE)) -+ goto out; -+ -+ pos = pindex; -+ pos *= PAGE_SIZE; -+ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE) -+ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos); -+ else { -+ memset(p, 0, PAGE_SIZE); -+ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); -+ } -+ if (sz == PAGE_SIZE) { -+ sbinfo->si_xib_last_pindex = pindex; -+ return 0; /* success */ -+ } -+ -+out: -+ AuIOErr1("write failed (%zd)\n", sz); -+ err = sz; -+ if (sz >= 0) -+ err = -EIO; -+ return err; -+} -+ -+static void au_xib_clear_bit(struct inode *inode) -+{ -+ int err, bit; -+ unsigned long pindex; -+ struct super_block *sb; -+ struct au_sbinfo *sbinfo; -+ -+ AuDebugOn(inode->i_nlink); -+ -+ sb = inode->i_sb; -+ xib_calc_bit(inode->i_ino, &pindex, &bit); -+ AuDebugOn(page_bits <= bit); -+ sbinfo = au_sbi(sb); -+ mutex_lock(&sbinfo->si_xib_mtx); -+ err = xib_pindex(sb, pindex); -+ if (!err) { -+ clear_bit(bit, sbinfo->si_xib_buf); -+ sbinfo->si_xib_next_bit = bit; -+ } -+ mutex_unlock(&sbinfo->si_xib_mtx); -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * truncate a xino bitmap file -+ */ -+ -+/* todo: slow */ -+static int do_xib_restore(struct super_block *sb, struct file *file, void *page) -+{ -+ int err, bit; -+ ssize_t sz; -+ unsigned long pindex; -+ loff_t pos, pend; -+ struct au_sbinfo *sbinfo; -+ vfs_readf_t func; -+ ino_t *ino; -+ unsigned long *p; -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ MtxMustLock(&sbinfo->si_xib_mtx); -+ p = sbinfo->si_xib_buf; -+ func = sbinfo->si_xread; -+ pend = vfsub_f_size_read(file); -+ pos = 0; -+ while (pos < pend) { -+ sz = xino_fread(func, file, page, PAGE_SIZE, &pos); -+ err = sz; -+ if (unlikely(sz <= 0)) -+ goto out; -+ -+ err = 0; -+ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) { -+ if (unlikely(*ino < AUFS_FIRST_INO)) -+ continue; -+ -+ xib_calc_bit(*ino, &pindex, &bit); -+ AuDebugOn(page_bits <= bit); -+ err = xib_pindex(sb, pindex); -+ if (!err) -+ set_bit(bit, p); -+ else -+ goto out; -+ } -+ } -+ -+out: -+ return err; -+} -+ -+static int xib_restore(struct super_block *sb) -+{ -+ int err, i; -+ unsigned int nfile; -+ aufs_bindex_t bindex, bbot; -+ void *page; -+ struct au_branch *br; -+ struct au_xino *xi; -+ struct file *file; -+ -+ err = -ENOMEM; -+ page = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!page)) -+ goto out; -+ -+ err = 0; -+ bbot = au_sbbot(sb); -+ for (bindex = 0; !err && bindex <= bbot; bindex++) -+ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0) { -+ br = au_sbr(sb, bindex); -+ xi = br->br_xino; -+ nfile = xi->xi_nfile; -+ for (i = 0; i < nfile; i++) { -+ file = au_xino_file(xi, i); -+ if (file) -+ err = do_xib_restore(sb, file, page); -+ } -+ } else -+ AuDbg("skip shared b%d\n", bindex); -+ free_page((unsigned long)page); -+ -+out: -+ return err; -+} -+ -+int au_xib_trunc(struct super_block *sb) -+{ -+ int err; -+ ssize_t sz; -+ loff_t pos; -+ struct au_sbinfo *sbinfo; -+ unsigned long *p; -+ struct file *file; -+ -+ SiMustWriteLock(sb); -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ if (!au_opt_test(sbinfo->si_mntflags, XINO)) -+ goto out; -+ -+ file = sbinfo->si_xib; -+ if (vfsub_f_size_read(file) <= PAGE_SIZE) -+ goto out; -+ -+ file = au_xino_create2(sb, &sbinfo->si_xib->f_path, NULL); -+ err = PTR_ERR(file); -+ if (IS_ERR(file)) -+ goto out; -+ fput(sbinfo->si_xib); -+ sbinfo->si_xib = file; -+ -+ p = sbinfo->si_xib_buf; -+ memset(p, 0, PAGE_SIZE); -+ pos = 0; -+ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos); -+ if (unlikely(sz != PAGE_SIZE)) { -+ err = sz; -+ AuIOErr("err %d\n", err); -+ if (sz >= 0) -+ err = -EIO; -+ goto out; -+ } -+ -+ mutex_lock(&sbinfo->si_xib_mtx); -+ /* mnt_want_write() is unnecessary here */ -+ err = xib_restore(sb); -+ mutex_unlock(&sbinfo->si_xib_mtx); -+ -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct au_xino *au_xino_alloc(unsigned int nfile) -+{ -+ struct au_xino *xi; -+ -+ xi = kzalloc(sizeof(*xi), GFP_NOFS); -+ if (unlikely(!xi)) -+ goto out; -+ xi->xi_nfile = nfile; -+ xi->xi_file = kcalloc(nfile, sizeof(*xi->xi_file), GFP_NOFS); -+ if (unlikely(!xi->xi_file)) -+ goto out_free; -+ -+ xi->xi_nondir.total = 8; /* initial size */ -+ xi->xi_nondir.array = kcalloc(xi->xi_nondir.total, sizeof(ino_t), -+ GFP_NOFS); -+ if (unlikely(!xi->xi_nondir.array)) -+ goto out_file; -+ -+ spin_lock_init(&xi->xi_nondir.spin); -+ init_waitqueue_head(&xi->xi_nondir.wqh); -+ mutex_init(&xi->xi_mtx); -+ /* init_waitqueue_head(&xi->xi_wq); */ -+ /* atomic_set(&xi->xi_pending, 0); */ -+ atomic_set(&xi->xi_truncating, 0); -+ kref_init(&xi->xi_kref); -+ goto out; /* success */ -+ -+out_file: -+ kfree(xi->xi_file); -+out_free: -+ kfree(xi); -+ xi = NULL; -+out: -+ return xi; -+} -+ -+static int au_xino_init(struct au_branch *br, int idx, struct file *file) -+{ -+ int err; -+ struct au_xino *xi; -+ -+ err = 0; -+ xi = au_xino_alloc(idx + 1); -+ if (unlikely(!xi)) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ if (file) -+ get_file(file); -+ xi->xi_file[idx] = file; -+ AuDebugOn(br->br_xino); -+ br->br_xino = xi; -+ -+out: -+ return err; -+} -+ -+static void au_xino_release(struct kref *kref) -+{ -+ struct au_xino *xi; -+ int i; -+ -+ xi = container_of(kref, struct au_xino, xi_kref); -+ for (i = 0; i < xi->xi_nfile; i++) -+ if (xi->xi_file[i]) -+ fput(xi->xi_file[i]); -+ for (i = xi->xi_nondir.total - 1; i >= 0; i--) -+ AuDebugOn(xi->xi_nondir.array[i]); -+ mutex_destroy(&xi->xi_mtx); -+ kfree(xi->xi_file); -+ kfree(xi->xi_nondir.array); -+ kfree(xi); -+} -+ -+int au_xino_put(struct au_branch *br) -+{ -+ int ret; -+ struct au_xino *xi; -+ -+ ret = 0; -+ xi = br->br_xino; -+ if (xi) { -+ br->br_xino = NULL; -+ ret = kref_put(&xi->xi_kref, au_xino_release); -+ } -+ -+ return ret; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * xino mount option handlers -+ */ -+ -+/* xino bitmap */ -+static void xino_clear_xib(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ /* unnecessary to clear sbinfo->si_xread and ->si_xwrite */ -+ if (sbinfo->si_xib) -+ fput(sbinfo->si_xib); -+ sbinfo->si_xib = NULL; -+ if (sbinfo->si_xib_buf) -+ free_page((unsigned long)sbinfo->si_xib_buf); -+ sbinfo->si_xib_buf = NULL; -+} -+ -+static int au_xino_set_xib(struct super_block *sb, struct path *path) -+{ -+ int err; -+ loff_t pos; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ struct super_block *xi_sb; -+ -+ SiMustWriteLock(sb); -+ -+ sbinfo = au_sbi(sb); -+ file = au_xino_create2(sb, path, sbinfo->si_xib); -+ err = PTR_ERR(file); -+ if (IS_ERR(file)) -+ goto out; -+ if (sbinfo->si_xib) -+ fput(sbinfo->si_xib); -+ sbinfo->si_xib = file; -+ sbinfo->si_xread = vfs_readf(file); -+ sbinfo->si_xwrite = vfs_writef(file); -+ xi_sb = file_inode(file)->i_sb; -+ sbinfo->si_ximaxent = xi_sb->s_maxbytes; -+ if (unlikely(sbinfo->si_ximaxent < PAGE_SIZE)) { -+ err = -EIO; -+ pr_err("s_maxbytes(%llu) on %s is too small\n", -+ (u64)sbinfo->si_ximaxent, au_sbtype(xi_sb)); -+ goto out_unset; -+ } -+ sbinfo->si_ximaxent /= sizeof(ino_t); -+ -+ err = -ENOMEM; -+ if (!sbinfo->si_xib_buf) -+ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS); -+ if (unlikely(!sbinfo->si_xib_buf)) -+ goto out_unset; -+ -+ sbinfo->si_xib_last_pindex = 0; -+ sbinfo->si_xib_next_bit = 0; -+ if (vfsub_f_size_read(file) < PAGE_SIZE) { -+ pos = 0; -+ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf, -+ PAGE_SIZE, &pos); -+ if (unlikely(err != PAGE_SIZE)) -+ goto out_free; -+ } -+ err = 0; -+ goto out; /* success */ -+ -+out_free: -+ if (sbinfo->si_xib_buf) -+ free_page((unsigned long)sbinfo->si_xib_buf); -+ sbinfo->si_xib_buf = NULL; -+ if (err >= 0) -+ err = -EIO; -+out_unset: -+ fput(sbinfo->si_xib); -+ sbinfo->si_xib = NULL; -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+/* xino for each branch */ -+static void xino_clear_br(struct super_block *sb) -+{ -+ aufs_bindex_t bindex, bbot; -+ struct au_branch *br; -+ -+ bbot = au_sbbot(sb); -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ AuDebugOn(!br); -+ au_xino_put(br); -+ } -+} -+ -+static void au_xino_set_br_shared(struct super_block *sb, struct au_branch *br, -+ aufs_bindex_t bshared) -+{ -+ struct au_branch *brshared; -+ -+ brshared = au_sbr(sb, bshared); -+ AuDebugOn(!brshared->br_xino); -+ AuDebugOn(!brshared->br_xino->xi_file); -+ if (br->br_xino != brshared->br_xino) { -+ au_xino_get(brshared); -+ au_xino_put(br); -+ br->br_xino = brshared->br_xino; -+ } -+} -+ -+struct au_xino_do_set_br { -+ vfs_writef_t writef; -+ struct au_branch *br; -+ ino_t h_ino; -+ aufs_bindex_t bshared; -+}; -+ -+static int au_xino_do_set_br(struct super_block *sb, struct path *path, -+ struct au_xino_do_set_br *args) -+{ -+ int err; -+ struct au_xi_calc calc; -+ struct file *file; -+ struct au_branch *br; -+ struct au_xi_new xinew = { -+ .base = path -+ }; -+ -+ br = args->br; -+ xinew.xi = br->br_xino; -+ au_xi_calc(sb, args->h_ino, &calc); -+ xinew.copy_src = au_xino_file(xinew.xi, calc.idx); -+ if (args->bshared >= 0) -+ /* shared xino */ -+ au_xino_set_br_shared(sb, br, args->bshared); -+ else if (!xinew.xi) { -+ /* new xino */ -+ err = au_xino_init(br, calc.idx, xinew.copy_src); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+ /* force re-creating */ -+ xinew.xi = br->br_xino; -+ xinew.idx = calc.idx; -+ mutex_lock(&xinew.xi->xi_mtx); -+ file = au_xi_new(sb, &xinew); -+ mutex_unlock(&xinew.xi->xi_mtx); -+ err = PTR_ERR(file); -+ if (IS_ERR(file)) -+ goto out; -+ AuDebugOn(!file); -+ -+ err = au_xino_do_write(args->writef, file, &calc, AUFS_ROOT_INO); -+ if (unlikely(err)) -+ au_xino_put(br); -+ -+out: -+ AuTraceErr(err); -+ return err; -+} -+ -+static int au_xino_set_br(struct super_block *sb, struct path *path) -+{ -+ int err; -+ aufs_bindex_t bindex, bbot; -+ struct au_xino_do_set_br args; -+ struct inode *inode; -+ -+ SiMustWriteLock(sb); -+ -+ bbot = au_sbbot(sb); -+ inode = d_inode(sb->s_root); -+ args.writef = au_sbi(sb)->si_xwrite; -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ args.h_ino = au_h_iptr(inode, bindex)->i_ino; -+ args.br = au_sbr(sb, bindex); -+ args.bshared = is_sb_shared(sb, bindex, bindex - 1); -+ err = au_xino_do_set_br(sb, path, &args); -+ if (unlikely(err)) -+ break; -+ } -+ -+ AuTraceErr(err); -+ return err; -+} -+ -+void au_xino_clr(struct super_block *sb) -+{ -+ struct au_sbinfo *sbinfo; -+ -+ au_xigen_clr(sb); -+ xino_clear_xib(sb); -+ xino_clear_br(sb); -+ dbgaufs_brs_del(sb, 0); -+ sbinfo = au_sbi(sb); -+ /* lvalue, do not call au_mntflags() */ -+ au_opt_clr(sbinfo->si_mntflags, XINO); -+} -+ -+int au_xino_set(struct super_block *sb, struct au_opt_xino *xiopt, int remount) -+{ -+ int err, skip; -+ struct dentry *dentry, *parent, *cur_dentry, *cur_parent; -+ struct qstr *dname, *cur_name; -+ struct file *cur_xino; -+ struct au_sbinfo *sbinfo; -+ struct path *path, *cur_path; -+ -+ SiMustWriteLock(sb); -+ -+ err = 0; -+ sbinfo = au_sbi(sb); -+ path = &xiopt->file->f_path; -+ dentry = path->dentry; -+ parent = dget_parent(dentry); -+ if (remount) { -+ skip = 0; -+ cur_xino = sbinfo->si_xib; -+ if (cur_xino) { -+ cur_path = &cur_xino->f_path; -+ cur_dentry = cur_path->dentry; -+ cur_parent = dget_parent(cur_dentry); -+ cur_name = &cur_dentry->d_name; -+ dname = &dentry->d_name; -+ skip = (cur_parent == parent -+ && au_qstreq(dname, cur_name)); -+ dput(cur_parent); -+ } -+ if (skip) -+ goto out; -+ } -+ -+ au_opt_set(sbinfo->si_mntflags, XINO); -+ err = au_xino_set_xib(sb, path); -+ /* si_x{read,write} are set */ -+ if (!err) -+ err = au_xigen_set(sb, path); -+ if (!err) -+ err = au_xino_set_br(sb, path); -+ if (!err) { -+ dbgaufs_brs_add(sb, 0, /*topdown*/1); -+ goto out; /* success */ -+ } -+ -+ /* reset all */ -+ AuIOErr("failed setting xino(%d).\n", err); -+ au_xino_clr(sb); -+ -+out: -+ dput(parent); -+ return err; -+} -+ -+/* -+ * create a xinofile at the default place/path. -+ */ -+struct file *au_xino_def(struct super_block *sb) -+{ -+ struct file *file; -+ char *page, *p; -+ struct au_branch *br; -+ struct super_block *h_sb; -+ struct path path; -+ aufs_bindex_t bbot, bindex, bwr; -+ -+ br = NULL; -+ bbot = au_sbbot(sb); -+ bwr = -1; -+ for (bindex = 0; bindex <= bbot; bindex++) { -+ br = au_sbr(sb, bindex); -+ if (au_br_writable(br->br_perm) -+ && !au_test_fs_bad_xino(au_br_sb(br))) { -+ bwr = bindex; -+ break; -+ } -+ } -+ -+ if (bwr >= 0) { -+ file = ERR_PTR(-ENOMEM); -+ page = (void *)__get_free_page(GFP_NOFS); -+ if (unlikely(!page)) -+ goto out; -+ path.mnt = au_br_mnt(br); -+ path.dentry = au_h_dptr(sb->s_root, bwr); -+ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME)); -+ file = (void *)p; -+ if (!IS_ERR(p)) { -+ strcat(p, "/" AUFS_XINO_FNAME); -+ AuDbg("%s\n", p); -+ file = au_xino_create(sb, p, /*silent*/0); -+ } -+ free_page((unsigned long)page); -+ } else { -+ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0); -+ if (IS_ERR(file)) -+ goto out; -+ h_sb = file->f_path.dentry->d_sb; -+ if (unlikely(au_test_fs_bad_xino(h_sb))) { -+ pr_err("xino doesn't support %s(%s)\n", -+ AUFS_XINO_DEFPATH, au_sbtype(h_sb)); -+ fput(file); -+ file = ERR_PTR(-EINVAL); -+ } -+ } -+ -+out: -+ return file; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * initialize the xinofile for the specified branch @br -+ * at the place/path where @base_file indicates. -+ * test whether another branch is on the same filesystem or not, -+ * if found then share the xinofile with another branch. -+ */ -+int au_xino_init_br(struct super_block *sb, struct au_branch *br, ino_t h_ino, -+ struct path *base) -+{ -+ int err; -+ struct au_xino_do_set_br args = { -+ .h_ino = h_ino, -+ .br = br -+ }; -+ -+ args.writef = au_sbi(sb)->si_xwrite; -+ args.bshared = sbr_find_shared(sb, /*btop*/0, au_sbbot(sb), -+ au_br_sb(br)); -+ err = au_xino_do_set_br(sb, base, &args); -+ if (unlikely(err)) -+ au_xino_put(br); -+ -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* -+ * get an unused inode number from bitmap -+ */ -+ino_t au_xino_new_ino(struct super_block *sb) -+{ -+ ino_t ino; -+ unsigned long *p, pindex, ul, pend; -+ struct au_sbinfo *sbinfo; -+ struct file *file; -+ int free_bit, err; -+ -+ if (!au_opt_test(au_mntflags(sb), XINO)) -+ return iunique(sb, AUFS_FIRST_INO); -+ -+ sbinfo = au_sbi(sb); -+ mutex_lock(&sbinfo->si_xib_mtx); -+ p = sbinfo->si_xib_buf; -+ free_bit = sbinfo->si_xib_next_bit; -+ if (free_bit < page_bits && !test_bit(free_bit, p)) -+ goto out; /* success */ -+ free_bit = find_first_zero_bit(p, page_bits); -+ if (free_bit < page_bits) -+ goto out; /* success */ -+ -+ pindex = sbinfo->si_xib_last_pindex; -+ for (ul = pindex - 1; ul < ULONG_MAX; ul--) { -+ err = xib_pindex(sb, ul); -+ if (unlikely(err)) -+ goto out_err; -+ free_bit = find_first_zero_bit(p, page_bits); -+ if (free_bit < page_bits) -+ goto out; /* success */ -+ } -+ -+ file = sbinfo->si_xib; -+ pend = vfsub_f_size_read(file) / PAGE_SIZE; -+ for (ul = pindex + 1; ul <= pend; ul++) { -+ err = xib_pindex(sb, ul); -+ if (unlikely(err)) -+ goto out_err; -+ free_bit = find_first_zero_bit(p, page_bits); -+ if (free_bit < page_bits) -+ goto out; /* success */ -+ } -+ BUG(); -+ -+out: -+ set_bit(free_bit, p); -+ sbinfo->si_xib_next_bit = free_bit + 1; -+ pindex = sbinfo->si_xib_last_pindex; -+ mutex_unlock(&sbinfo->si_xib_mtx); -+ ino = xib_calc_ino(pindex, free_bit); -+ AuDbg("i%lu\n", (unsigned long)ino); -+ return ino; -+out_err: -+ mutex_unlock(&sbinfo->si_xib_mtx); -+ AuDbg("i0\n"); -+ return 0; -+} -+ -+/* for s_op->delete_inode() */ -+void au_xino_delete_inode(struct inode *inode, const int unlinked) -+{ -+ int err; -+ unsigned int mnt_flags; -+ aufs_bindex_t bindex, bbot, bi; -+ unsigned char try_trunc; -+ struct au_iinfo *iinfo; -+ struct super_block *sb; -+ struct au_hinode *hi; -+ struct inode *h_inode; -+ struct au_branch *br; -+ vfs_writef_t xwrite; -+ struct au_xi_calc calc; -+ struct file *file; -+ -+ AuDebugOn(au_is_bad_inode(inode)); -+ -+ sb = inode->i_sb; -+ mnt_flags = au_mntflags(sb); -+ if (!au_opt_test(mnt_flags, XINO) -+ || inode->i_ino == AUFS_ROOT_INO) -+ return; -+ -+ if (unlinked) { -+ au_xigen_inc(inode); -+ au_xib_clear_bit(inode); -+ } -+ -+ iinfo = au_ii(inode); -+ bindex = iinfo->ii_btop; -+ if (bindex < 0) -+ return; -+ -+ xwrite = au_sbi(sb)->si_xwrite; -+ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO); -+ hi = au_hinode(iinfo, bindex); -+ bbot = iinfo->ii_bbot; -+ for (; bindex <= bbot; bindex++, hi++) { -+ h_inode = hi->hi_inode; -+ if (!h_inode -+ || (!unlinked && h_inode->i_nlink)) -+ continue; -+ -+ /* inode may not be revalidated */ -+ bi = au_br_index(sb, hi->hi_id); -+ if (bi < 0) -+ continue; -+ -+ br = au_sbr(sb, bi); -+ au_xi_calc(sb, h_inode->i_ino, &calc); -+ file = au_xino_file(br->br_xino, calc.idx); -+ if (IS_ERR_OR_NULL(file)) -+ continue; -+ -+ err = au_xino_do_write(xwrite, file, &calc, /*ino*/0); -+ if (!err && try_trunc -+ && au_test_fs_trunc_xino(au_br_sb(br))) -+ xino_try_trunc(sb, br); -+ } -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+static int au_xinondir_find(struct au_xino *xi, ino_t h_ino) -+{ -+ int found, total, i; -+ -+ found = -1; -+ total = xi->xi_nondir.total; -+ for (i = 0; i < total; i++) { -+ if (xi->xi_nondir.array[i] != h_ino) -+ continue; -+ found = i; -+ break; -+ } -+ -+ return found; -+} -+ -+static int au_xinondir_expand(struct au_xino *xi) -+{ -+ int err, sz; -+ ino_t *p; -+ -+ BUILD_BUG_ON(KMALLOC_MAX_SIZE > INT_MAX); -+ -+ err = -ENOMEM; -+ sz = xi->xi_nondir.total * sizeof(ino_t); -+ if (unlikely(sz > KMALLOC_MAX_SIZE / 2)) -+ goto out; -+ p = au_kzrealloc(xi->xi_nondir.array, sz, sz << 1, GFP_ATOMIC, -+ /*may_shrink*/0); -+ if (p) { -+ xi->xi_nondir.array = p; -+ xi->xi_nondir.total <<= 1; -+ AuDbg("xi_nondir.total %d\n", xi->xi_nondir.total); -+ err = 0; -+ } -+ -+out: -+ return err; -+} -+ -+void au_xinondir_leave(struct super_block *sb, aufs_bindex_t bindex, -+ ino_t h_ino, int idx) -+{ -+ struct au_xino *xi; -+ -+ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO)); -+ xi = au_sbr(sb, bindex)->br_xino; -+ AuDebugOn(idx < 0 || xi->xi_nondir.total <= idx); -+ -+ spin_lock(&xi->xi_nondir.spin); -+ AuDebugOn(xi->xi_nondir.array[idx] != h_ino); -+ xi->xi_nondir.array[idx] = 0; -+ spin_unlock(&xi->xi_nondir.spin); -+ wake_up_all(&xi->xi_nondir.wqh); -+} -+ -+int au_xinondir_enter(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, -+ int *idx) -+{ -+ int err, found, empty; -+ struct au_xino *xi; -+ -+ err = 0; -+ *idx = -1; -+ if (!au_opt_test(au_mntflags(sb), XINO)) -+ goto out; /* no xino */ -+ -+ xi = au_sbr(sb, bindex)->br_xino; -+ -+again: -+ spin_lock(&xi->xi_nondir.spin); -+ found = au_xinondir_find(xi, h_ino); -+ if (found == -1) { -+ empty = au_xinondir_find(xi, /*h_ino*/0); -+ if (empty == -1) { -+ empty = xi->xi_nondir.total; -+ err = au_xinondir_expand(xi); -+ if (unlikely(err)) -+ goto out_unlock; -+ } -+ xi->xi_nondir.array[empty] = h_ino; -+ *idx = empty; -+ } else { -+ spin_unlock(&xi->xi_nondir.spin); -+ wait_event(xi->xi_nondir.wqh, -+ xi->xi_nondir.array[found] != h_ino); -+ goto again; -+ } -+ -+out_unlock: -+ spin_unlock(&xi->xi_nondir.spin); -+out: -+ return err; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+int au_xino_path(struct seq_file *seq, struct file *file) -+{ -+ int err; -+ -+ err = au_seq_path(seq, &file->f_path); -+ if (unlikely(err)) -+ goto out; -+ -+#define Deleted "\\040(deleted)" -+ seq->count -= sizeof(Deleted) - 1; -+ AuDebugOn(memcmp(seq->buf + seq->count, Deleted, -+ sizeof(Deleted) - 1)); -+#undef Deleted -+ -+out: -+ return err; -+} -diff --git a/fs/dcache.c b/fs/dcache.c -index 2e7e8d85e..328a13662 100644 ---- a/fs/dcache.c -+++ b/fs/dcache.c -@@ -1238,7 +1238,7 @@ enum d_walk_ret { - * - * The @enter() callbacks are called with d_lock held. - */ --static void d_walk(struct dentry *parent, void *data, -+void d_walk(struct dentry *parent, void *data, - enum d_walk_ret (*enter)(void *, struct dentry *)) - { - struct dentry *this_parent; -@@ -1343,6 +1343,7 @@ static void d_walk(struct dentry *parent, void *data, - seq = 1; - goto again; - } -+EXPORT_SYMBOL_GPL(d_walk); - - struct check_mount { - struct vfsmount *mnt; -@@ -2837,6 +2838,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2) - - write_sequnlock(&rename_lock); - } -+EXPORT_SYMBOL_GPL(d_exchange); - - /** - * d_ancestor - search for an ancestor -diff --git a/fs/exec.c b/fs/exec.c -index 1ebf6e5a5..a72c29465 100644 ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -109,6 +109,7 @@ bool path_noexec(const struct path *path) - return (path->mnt->mnt_flags & MNT_NOEXEC) || - (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC); - } -+EXPORT_SYMBOL_GPL(path_noexec); - - #ifdef CONFIG_USELIB - /* -diff --git a/fs/fcntl.c b/fs/fcntl.c -index 4137d9653..77513097f 100644 ---- a/fs/fcntl.c -+++ b/fs/fcntl.c -@@ -32,7 +32,7 @@ - - #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME) - --static int setfl(int fd, struct file * filp, unsigned long arg) -+int setfl(int fd, struct file * filp, unsigned long arg) - { - struct inode * inode = file_inode(filp); - int error = 0; -@@ -63,6 +63,8 @@ static int setfl(int fd, struct file * filp, unsigned long arg) - - if (filp->f_op->check_flags) - error = filp->f_op->check_flags(arg); -+ if (!error && filp->f_op->setfl) -+ error = filp->f_op->setfl(filp, arg); - if (error) - return error; - -@@ -83,6 +85,7 @@ static int setfl(int fd, struct file * filp, unsigned long arg) - out: - return error; - } -+EXPORT_SYMBOL_GPL(setfl); - - static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, - int force) -diff --git a/fs/file_table.c b/fs/file_table.c -index e49af4caf..569020fd1 100644 ---- a/fs/file_table.c -+++ b/fs/file_table.c -@@ -161,6 +161,7 @@ struct file *alloc_empty_file(int flags, const struct cred *cred) - } - return ERR_PTR(-ENFILE); - } -+EXPORT_SYMBOL_GPL(alloc_empty_file); - - /* - * Variant of alloc_empty_file() that doesn't check and modify nr_files. -@@ -323,6 +324,7 @@ void flush_delayed_fput(void) - { - delayed_fput(NULL); - } -+EXPORT_SYMBOL_GPL(flush_delayed_fput); - - static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput); - -@@ -365,6 +367,7 @@ void __fput_sync(struct file *file) - } - - EXPORT_SYMBOL(fput); -+EXPORT_SYMBOL_GPL(__fput_sync); - - void __init files_init(void) - { -diff --git a/fs/inode.c b/fs/inode.c -index 42f6d25f3..69d4a6cde 100644 ---- a/fs/inode.c -+++ b/fs/inode.c -@@ -1657,7 +1657,7 @@ EXPORT_SYMBOL(generic_update_time); - * This does the actual work of updating an inodes time or version. Must have - * had called mnt_want_write() before calling this. - */ --static int update_time(struct inode *inode, struct timespec64 *time, int flags) -+int update_time(struct inode *inode, struct timespec64 *time, int flags) - { - int (*update_time)(struct inode *, struct timespec64 *, int); - -@@ -1666,6 +1666,7 @@ static int update_time(struct inode *inode, struct timespec64 *time, int flags) - - return update_time(inode, time, flags); - } -+EXPORT_SYMBOL_GPL(update_time); - - /** - * touch_atime - update the access time -diff --git a/fs/namespace.c b/fs/namespace.c -index 99186556f..c49803ce0 100644 ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -437,6 +437,7 @@ void __mnt_drop_write(struct vfsmount *mnt) - mnt_dec_writers(real_mount(mnt)); - preempt_enable(); - } -+EXPORT_SYMBOL_GPL(__mnt_drop_write); - - /** - * mnt_drop_write - give up write access to a mount -@@ -770,6 +771,13 @@ static inline int check_mnt(struct mount *mnt) - return mnt->mnt_ns == current->nsproxy->mnt_ns; - } - -+/* for aufs, CONFIG_AUFS_BR_FUSE */ -+int is_current_mnt_ns(struct vfsmount *mnt) -+{ -+ return check_mnt(real_mount(mnt)); -+} -+EXPORT_SYMBOL_GPL(is_current_mnt_ns); -+ - /* - * vfsmount lock must be held for write - */ -@@ -1826,6 +1834,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, - } - return 0; - } -+EXPORT_SYMBOL_GPL(iterate_mounts); - - static void cleanup_group_ids(struct mount *mnt, struct mount *end) - { -diff --git a/fs/notify/group.c b/fs/notify/group.c -index c03b83662..817f22c6e 100644 ---- a/fs/notify/group.c -+++ b/fs/notify/group.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include - #include "fsnotify.h" -@@ -112,6 +113,7 @@ void fsnotify_get_group(struct fsnotify_group *group) - { - refcount_inc(&group->refcnt); - } -+EXPORT_SYMBOL_GPL(fsnotify_get_group); - - /* - * Drop a reference to a group. Free it if it's through. -@@ -121,6 +123,7 @@ void fsnotify_put_group(struct fsnotify_group *group) - if (refcount_dec_and_test(&group->refcnt)) - fsnotify_final_destroy_group(group); - } -+EXPORT_SYMBOL_GPL(fsnotify_put_group); - - /* - * Create a new fsnotify_group and hold a reference for the group returned. -@@ -150,6 +153,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops) - - return group; - } -+EXPORT_SYMBOL_GPL(fsnotify_alloc_group); - - int fsnotify_fasync(int fd, struct file *file, int on) - { -diff --git a/fs/notify/mark.c b/fs/notify/mark.c -index 59cdb2782..ce365c73f 100644 ---- a/fs/notify/mark.c -+++ b/fs/notify/mark.c -@@ -263,6 +263,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark) - queue_delayed_work(system_unbound_wq, &reaper_work, - FSNOTIFY_REAPER_DELAY); - } -+EXPORT_SYMBOL_GPL(fsnotify_put_mark); - - /* - * Get mark reference when we found the mark via lockless traversal of object -@@ -417,6 +418,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark, - mutex_unlock(&group->mark_mutex); - fsnotify_free_mark(mark); - } -+EXPORT_SYMBOL_GPL(fsnotify_destroy_mark); - - /* - * Sorting function for lists of fsnotify marks. -@@ -632,6 +634,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, fsnotify_connp_t *connp, - mutex_unlock(&group->mark_mutex); - return ret; - } -+EXPORT_SYMBOL_GPL(fsnotify_add_mark); - - /* - * Given a list of marks, find the mark associated with given group. If found -@@ -754,6 +757,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark, - fsnotify_get_group(group); - mark->group = group; - } -+EXPORT_SYMBOL_GPL(fsnotify_init_mark); - - /* - * Destroy all marks in destroy_list, waits for SRCU period to finish before -diff --git a/fs/open.c b/fs/open.c -index 0285ce7db..cb81623a8 100644 ---- a/fs/open.c -+++ b/fs/open.c -@@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, - inode_unlock(dentry->d_inode); - return ret; - } -+EXPORT_SYMBOL_GPL(do_truncate); - - long vfs_truncate(const struct path *path, loff_t length) - { -diff --git a/fs/proc/base.c b/fs/proc/base.c -index 7e9f07bf2..3ab590110 100644 ---- a/fs/proc/base.c -+++ b/fs/proc/base.c -@@ -2016,7 +2016,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path) - down_read(&mm->mmap_sem); - vma = find_exact_vma(mm, vm_start, vm_end); - if (vma && vma->vm_file) { -- *path = vma->vm_file->f_path; -+ *path = vma_pr_or_file(vma)->f_path; - path_get(path); - rc = 0; - } -diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c -index 3b63be64e..fb9913bf3 100644 ---- a/fs/proc/nommu.c -+++ b/fs/proc/nommu.c -@@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region) - file = region->vm_file; - - if (file) { -- struct inode *inode = file_inode(region->vm_file); -+ struct inode *inode; -+ -+ file = vmr_pr_or_file(region); -+ inode = file_inode(file); - dev = inode->i_sb->s_dev; - ino = inode->i_ino; - } -diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c -index 5ea1d64cb..7865a4707 100644 ---- a/fs/proc/task_mmu.c -+++ b/fs/proc/task_mmu.c -@@ -305,7 +305,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) - const char *name = NULL; - - if (file) { -- struct inode *inode = file_inode(vma->vm_file); -+ struct inode *inode; -+ -+ file = vma_pr_or_file(vma); -+ inode = file_inode(file); - dev = inode->i_sb->s_dev; - ino = inode->i_ino; - pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT; -@@ -1727,7 +1730,7 @@ static int show_numa_map(struct seq_file *m, void *v) - struct proc_maps_private *proc_priv = &numa_priv->proc_maps; - struct vm_area_struct *vma = v; - struct numa_maps *md = &numa_priv->md; -- struct file *file = vma->vm_file; -+ struct file *file = vma_pr_or_file(vma); - struct mm_struct *mm = vma->vm_mm; - struct mm_walk walk = { - .hugetlb_entry = gather_hugetlb_stats, -diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c -index 0b63d68de..400d1c594 100644 ---- a/fs/proc/task_nommu.c -+++ b/fs/proc/task_nommu.c -@@ -155,7 +155,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) - file = vma->vm_file; - - if (file) { -- struct inode *inode = file_inode(vma->vm_file); -+ struct inode *inode; -+ -+ file = vma_pr_or_file(vma); -+ inode = file_inode(file); - dev = inode->i_sb->s_dev; - ino = inode->i_ino; - pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT; -diff --git a/fs/read_write.c b/fs/read_write.c -index 8a2737f0d..d9cb9690e 100644 ---- a/fs/read_write.c -+++ b/fs/read_write.c -@@ -459,6 +459,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) - - return ret; - } -+EXPORT_SYMBOL_GPL(vfs_read); - - static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) - { -@@ -489,6 +490,30 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count, - return -EINVAL; - } - -+vfs_readf_t vfs_readf(struct file *file) -+{ -+ const struct file_operations *fop = file->f_op; -+ -+ if (fop->read) -+ return fop->read; -+ if (fop->read_iter) -+ return new_sync_read; -+ return ERR_PTR(-ENOSYS); -+} -+EXPORT_SYMBOL_GPL(vfs_readf); -+ -+vfs_writef_t vfs_writef(struct file *file) -+{ -+ const struct file_operations *fop = file->f_op; -+ -+ if (fop->write) -+ return fop->write; -+ if (fop->write_iter) -+ return new_sync_write; -+ return ERR_PTR(-ENOSYS); -+} -+EXPORT_SYMBOL_GPL(vfs_writef); -+ - ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) - { - mm_segment_t old_fs; -@@ -557,6 +582,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ - - return ret; - } -+EXPORT_SYMBOL_GPL(vfs_write); - - static inline loff_t file_pos_read(struct file *file) - { -diff --git a/fs/splice.c b/fs/splice.c -index b3daa971f..a5e3bcba0 100644 ---- a/fs/splice.c -+++ b/fs/splice.c -@@ -838,8 +838,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); - /* - * Attempt to initiate a splice from pipe to file. - */ --static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, -- loff_t *ppos, size_t len, unsigned int flags) -+long do_splice_from(struct pipe_inode_info *pipe, struct file *out, -+ loff_t *ppos, size_t len, unsigned int flags) - { - ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, - loff_t *, size_t, unsigned int); -@@ -851,13 +851,14 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, - - return splice_write(pipe, out, ppos, len, flags); - } -+EXPORT_SYMBOL_GPL(do_splice_from); - - /* - * Attempt to initiate a splice from a file to a pipe. - */ --static long do_splice_to(struct file *in, loff_t *ppos, -- struct pipe_inode_info *pipe, size_t len, -- unsigned int flags) -+long do_splice_to(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags) - { - ssize_t (*splice_read)(struct file *, loff_t *, - struct pipe_inode_info *, size_t, unsigned int); -@@ -880,6 +881,7 @@ static long do_splice_to(struct file *in, loff_t *ppos, - - return splice_read(in, ppos, pipe, len, flags); - } -+EXPORT_SYMBOL_GPL(do_splice_to); - - /** - * splice_direct_to_actor - splices data directly between two non-pipes -diff --git a/fs/sync.c b/fs/sync.c -index b54e0541a..ffd7ea438 100644 ---- a/fs/sync.c -+++ b/fs/sync.c -@@ -28,7 +28,7 @@ - * wait == 1 case since in that case write_inode() functions do - * sync_dirty_buffer() and thus effectively write one block at a time. - */ --static int __sync_filesystem(struct super_block *sb, int wait) -+int __sync_filesystem(struct super_block *sb, int wait) - { - if (wait) - sync_inodes_sb(sb); -@@ -39,6 +39,7 @@ static int __sync_filesystem(struct super_block *sb, int wait) - sb->s_op->sync_fs(sb, wait); - return __sync_blockdev(sb->s_bdev, wait); - } -+EXPORT_SYMBOL_GPL(__sync_filesystem); - - /* - * Write out and wait upon all dirty data associated with this -diff --git a/fs/xattr.c b/fs/xattr.c -index 0d6a6a4af..7ce4701b7 100644 ---- a/fs/xattr.c -+++ b/fs/xattr.c -@@ -295,6 +295,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, - *xattr_value = value; - return error; - } -+EXPORT_SYMBOL_GPL(vfs_getxattr_alloc); - - ssize_t - __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name, -diff --git a/include/linux/fs.h b/include/linux/fs.h -index 897eae8fa..7fb92a99e 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1286,6 +1286,7 @@ extern void fasync_free(struct fasync_struct *); - /* can be called from interrupts */ - extern void kill_fasync(struct fasync_struct **, int, int); - -+extern int setfl(int fd, struct file * filp, unsigned long arg); - extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force); - extern int f_setown(struct file *filp, unsigned long arg, int force); - extern void f_delown(struct file *filp); -@@ -1747,6 +1748,7 @@ struct file_operations { - ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); - unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); - int (*check_flags)(int); -+ int (*setfl)(struct file *, unsigned long); - int (*flock) (struct file *, int, struct file_lock *); - ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); - ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); -@@ -1818,6 +1820,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, - struct iovec *fast_pointer, - struct iovec **ret_pointer); - -+typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *); -+typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t, -+ loff_t *); -+vfs_readf_t vfs_readf(struct file *file); -+vfs_writef_t vfs_writef(struct file *file); -+ - extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *); - extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); - extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); -@@ -2243,6 +2251,7 @@ extern int current_umask(void); - extern void ihold(struct inode * inode); - extern void iput(struct inode *); - extern int generic_update_time(struct inode *, struct timespec64 *, int); -+extern int update_time(struct inode *, struct timespec64 *, int); - - /* /sys/fs */ - extern struct kobject *fs_kobj; -@@ -2530,6 +2539,7 @@ static inline bool sb_is_blkdev_sb(struct super_block *sb) - return false; - } - #endif -+extern int __sync_filesystem(struct super_block *, int); - extern int sync_filesystem(struct super_block *); - extern const struct file_operations def_blk_fops; - extern const struct file_operations def_chr_fops; -diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h -index b0d0b51c4..f73ffaa01 100644 ---- a/include/linux/lockdep.h -+++ b/include/linux/lockdep.h -@@ -313,6 +313,8 @@ static inline int lockdep_match_key(struct lockdep_map *lock, - return lock->key == key; - } - -+struct lock_class *lockdep_hlock_class(struct held_lock *hlock); -+ - /* - * Acquire a lock. - * -@@ -439,6 +441,7 @@ struct lockdep_map { }; - - #define lockdep_depth(tsk) (0) - -+#define lockdep_is_held(lock) (1) - #define lockdep_is_held_type(l, r) (1) - - #define lockdep_assert_held(l) do { (void)(l); } while (0) -diff --git a/include/linux/mm.h b/include/linux/mm.h -index 0416a7204..4a298a926 100644 ---- a/include/linux/mm.h -+++ b/include/linux/mm.h -@@ -1440,6 +1440,28 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping, - unmap_mapping_range(mapping, holebegin, holelen, 0); - } - -+extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int); -+extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[], -+ int); -+extern void vma_do_get_file(struct vm_area_struct *, const char[], int); -+extern void vma_do_fput(struct vm_area_struct *, const char[], int); -+ -+#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \ -+ __LINE__) -+#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \ -+ __LINE__) -+#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__) -+#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__) -+ -+#ifndef CONFIG_MMU -+extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int); -+extern void vmr_do_fput(struct vm_region *, const char[], int); -+ -+#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \ -+ __LINE__) -+#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__) -+#endif /* !CONFIG_MMU */ -+ - extern int access_process_vm(struct task_struct *tsk, unsigned long addr, - void *buf, int len, unsigned int gup_flags); - extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, -diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h -index 5ed8f6292..012297540 100644 ---- a/include/linux/mm_types.h -+++ b/include/linux/mm_types.h -@@ -239,6 +239,7 @@ struct vm_region { - unsigned long vm_top; /* region allocated to here */ - unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */ - struct file *vm_file; /* the backing file or NULL */ -+ struct file *vm_prfile; /* the virtual backing file or NULL */ - - int vm_usage; /* region usage count (access under nommu_region_sem) */ - bool vm_icache_flushed : 1; /* true if the icache has been flushed for -@@ -313,6 +314,7 @@ struct vm_area_struct { - unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE - units */ - struct file * vm_file; /* File we map to (can be NULL). */ -+ struct file *vm_prfile; /* shadow of vm_file */ - void * vm_private_data; /* was vm_pte (shared mem) */ - - atomic_long_t swap_readahead_info; -diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h -index 35942084c..24f5fd1a7 100644 ---- a/include/linux/mnt_namespace.h -+++ b/include/linux/mnt_namespace.h -@@ -6,11 +6,14 @@ - struct mnt_namespace; - struct fs_struct; - struct user_namespace; -+struct vfsmount; - - extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace *, - struct user_namespace *, struct fs_struct *); - extern void put_mnt_ns(struct mnt_namespace *ns); - -+extern int is_current_mnt_ns(struct vfsmount *mnt); -+ - extern const struct file_operations proc_mounts_operations; - extern const struct file_operations proc_mountinfo_operations; - extern const struct file_operations proc_mountstats_operations; -diff --git a/include/linux/splice.h b/include/linux/splice.h -index 74b4911ac..19789fbea 100644 ---- a/include/linux/splice.h -+++ b/include/linux/splice.h -@@ -87,4 +87,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *); - - extern const struct pipe_buf_operations page_cache_pipe_buf_ops; - extern const struct pipe_buf_operations default_pipe_buf_ops; -+ -+extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out, -+ loff_t *ppos, size_t len, unsigned int flags); -+extern long do_splice_to(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags); - #endif -diff --git a/include/uapi/linux/aufs_type.h b/include/uapi/linux/aufs_type.h -new file mode 100644 -index 000000000..8958f874b ---- /dev/null -+++ b/include/uapi/linux/aufs_type.h -@@ -0,0 +1,448 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2005-2018 Junjiro R. Okajima -+ * -+ * This program, aufs is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef __AUFS_TYPE_H__ -+#define __AUFS_TYPE_H__ -+ -+#define AUFS_NAME "aufs" -+ -+#ifdef __KERNEL__ -+/* -+ * define it before including all other headers. -+ * sched.h may use pr_* macros before defining "current", so define the -+ * no-current version first, and re-define later. -+ */ -+#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__ -+#include -+#undef pr_fmt -+#define pr_fmt(fmt) \ -+ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \ -+ (int)sizeof(current->comm), current->comm, current->pid -+#else -+#include -+#include -+#endif /* __KERNEL__ */ -+ -+#include -+ -+#define AUFS_VERSION "4.19-20181029" -+ -+/* todo? move this to linux-2.6.19/include/magic.h */ -+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') -+ -+/* ---------------------------------------------------------------------- */ -+ -+#ifdef CONFIG_AUFS_BRANCH_MAX_127 -+typedef int8_t aufs_bindex_t; -+#define AUFS_BRANCH_MAX 127 -+#else -+typedef int16_t aufs_bindex_t; -+#ifdef CONFIG_AUFS_BRANCH_MAX_511 -+#define AUFS_BRANCH_MAX 511 -+#elif defined(CONFIG_AUFS_BRANCH_MAX_1023) -+#define AUFS_BRANCH_MAX 1023 -+#elif defined(CONFIG_AUFS_BRANCH_MAX_32767) -+#define AUFS_BRANCH_MAX 32767 -+#endif -+#endif -+ -+#ifdef __KERNEL__ -+#ifndef AUFS_BRANCH_MAX -+#error unknown CONFIG_AUFS_BRANCH_MAX value -+#endif -+#endif /* __KERNEL__ */ -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define AUFS_FSTYPE AUFS_NAME -+ -+#define AUFS_ROOT_INO 2 -+#define AUFS_FIRST_INO 11 -+ -+#define AUFS_WH_PFX ".wh." -+#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1) -+#define AUFS_WH_TMP_LEN 4 -+/* a limit for rmdir/rename a dir and copyup */ -+#define AUFS_MAX_NAMELEN (NAME_MAX \ -+ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\ -+ - 1 /* dot */\ -+ - AUFS_WH_TMP_LEN) /* hex */ -+#define AUFS_XINO_FNAME "." AUFS_NAME ".xino" -+#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME -+#define AUFS_XINO_DEF_SEC 30 /* seconds */ -+#define AUFS_XINO_DEF_TRUNC 45 /* percentage */ -+#define AUFS_DIRWH_DEF 3 -+#define AUFS_RDCACHE_DEF 10 /* seconds */ -+#define AUFS_RDCACHE_MAX 3600 /* seconds */ -+#define AUFS_RDBLK_DEF 512 /* bytes */ -+#define AUFS_RDHASH_DEF 32 -+#define AUFS_WKQ_NAME AUFS_NAME "d" -+#define AUFS_MFS_DEF_SEC 30 /* seconds */ -+#define AUFS_MFS_MAX_SEC 3600 /* seconds */ -+#define AUFS_FHSM_CACHE_DEF_SEC 30 /* seconds */ -+#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */ -+ -+/* pseudo-link maintenace under /proc */ -+#define AUFS_PLINK_MAINT_NAME "plink_maint" -+#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME -+#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME -+ -+/* dirren, renamed dir */ -+#define AUFS_DR_INFO_PFX AUFS_WH_PFX ".dr." -+#define AUFS_DR_BRHINO_NAME AUFS_WH_PFX "hino" -+/* whiteouted doubly */ -+#define AUFS_WH_DR_INFO_PFX AUFS_WH_PFX AUFS_DR_INFO_PFX -+#define AUFS_WH_DR_BRHINO AUFS_WH_PFX AUFS_DR_BRHINO_NAME -+ -+#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */ -+#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME -+ -+#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME -+#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk" -+#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph" -+ -+/* doubly whiteouted */ -+#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME -+#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME -+#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME -+ -+/* branch permissions and attributes */ -+#define AUFS_BRPERM_RW "rw" -+#define AUFS_BRPERM_RO "ro" -+#define AUFS_BRPERM_RR "rr" -+#define AUFS_BRATTR_COO_REG "coo_reg" -+#define AUFS_BRATTR_COO_ALL "coo_all" -+#define AUFS_BRATTR_FHSM "fhsm" -+#define AUFS_BRATTR_UNPIN "unpin" -+#define AUFS_BRATTR_ICEX "icex" -+#define AUFS_BRATTR_ICEX_SEC "icexsec" -+#define AUFS_BRATTR_ICEX_SYS "icexsys" -+#define AUFS_BRATTR_ICEX_TR "icextr" -+#define AUFS_BRATTR_ICEX_USR "icexusr" -+#define AUFS_BRATTR_ICEX_OTH "icexoth" -+#define AUFS_BRRATTR_WH "wh" -+#define AUFS_BRWATTR_NLWH "nolwh" -+#define AUFS_BRWATTR_MOO "moo" -+ -+#define AuBrPerm_RW 1 /* writable, hardlinkable wh */ -+#define AuBrPerm_RO (1 << 1) /* readonly */ -+#define AuBrPerm_RR (1 << 2) /* natively readonly */ -+#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR) -+ -+#define AuBrAttr_COO_REG (1 << 3) /* copy-up on open */ -+#define AuBrAttr_COO_ALL (1 << 4) -+#define AuBrAttr_COO_Mask (AuBrAttr_COO_REG | AuBrAttr_COO_ALL) -+ -+#define AuBrAttr_FHSM (1 << 5) /* file-based hsm */ -+#define AuBrAttr_UNPIN (1 << 6) /* rename-able top dir of -+ branch. meaningless since -+ linux-3.18-rc1 */ -+ -+/* ignore error in copying XATTR */ -+#define AuBrAttr_ICEX_SEC (1 << 7) -+#define AuBrAttr_ICEX_SYS (1 << 8) -+#define AuBrAttr_ICEX_TR (1 << 9) -+#define AuBrAttr_ICEX_USR (1 << 10) -+#define AuBrAttr_ICEX_OTH (1 << 11) -+#define AuBrAttr_ICEX (AuBrAttr_ICEX_SEC \ -+ | AuBrAttr_ICEX_SYS \ -+ | AuBrAttr_ICEX_TR \ -+ | AuBrAttr_ICEX_USR \ -+ | AuBrAttr_ICEX_OTH) -+ -+#define AuBrRAttr_WH (1 << 12) /* whiteout-able */ -+#define AuBrRAttr_Mask AuBrRAttr_WH -+ -+#define AuBrWAttr_NoLinkWH (1 << 13) /* un-hardlinkable whiteouts */ -+#define AuBrWAttr_MOO (1 << 14) /* move-up on open */ -+#define AuBrWAttr_Mask (AuBrWAttr_NoLinkWH | AuBrWAttr_MOO) -+ -+#define AuBrAttr_CMOO_Mask (AuBrAttr_COO_Mask | AuBrWAttr_MOO) -+ -+/* #warning test userspace */ -+#ifdef __KERNEL__ -+#ifndef CONFIG_AUFS_FHSM -+#undef AuBrAttr_FHSM -+#define AuBrAttr_FHSM 0 -+#endif -+#ifndef CONFIG_AUFS_XATTR -+#undef AuBrAttr_ICEX -+#define AuBrAttr_ICEX 0 -+#undef AuBrAttr_ICEX_SEC -+#define AuBrAttr_ICEX_SEC 0 -+#undef AuBrAttr_ICEX_SYS -+#define AuBrAttr_ICEX_SYS 0 -+#undef AuBrAttr_ICEX_TR -+#define AuBrAttr_ICEX_TR 0 -+#undef AuBrAttr_ICEX_USR -+#define AuBrAttr_ICEX_USR 0 -+#undef AuBrAttr_ICEX_OTH -+#define AuBrAttr_ICEX_OTH 0 -+#endif -+#endif -+ -+/* the longest combination */ -+/* AUFS_BRATTR_ICEX and AUFS_BRATTR_ICEX_TR don't affect here */ -+#define AuBrPermStrSz sizeof(AUFS_BRPERM_RW \ -+ "+" AUFS_BRATTR_COO_REG \ -+ "+" AUFS_BRATTR_FHSM \ -+ "+" AUFS_BRATTR_UNPIN \ -+ "+" AUFS_BRATTR_ICEX_SEC \ -+ "+" AUFS_BRATTR_ICEX_SYS \ -+ "+" AUFS_BRATTR_ICEX_USR \ -+ "+" AUFS_BRATTR_ICEX_OTH \ -+ "+" AUFS_BRWATTR_NLWH) -+ -+typedef struct { -+ char a[AuBrPermStrSz]; -+} au_br_perm_str_t; -+ -+static inline int au_br_writable(int brperm) -+{ -+ return brperm & AuBrPerm_RW; -+} -+ -+static inline int au_br_whable(int brperm) -+{ -+ return brperm & (AuBrPerm_RW | AuBrRAttr_WH); -+} -+ -+static inline int au_br_wh_linkable(int brperm) -+{ -+ return !(brperm & AuBrWAttr_NoLinkWH); -+} -+ -+static inline int au_br_cmoo(int brperm) -+{ -+ return brperm & AuBrAttr_CMOO_Mask; -+} -+ -+static inline int au_br_fhsm(int brperm) -+{ -+ return brperm & AuBrAttr_FHSM; -+} -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* ioctl */ -+enum { -+ /* readdir in userspace */ -+ AuCtl_RDU, -+ AuCtl_RDU_INO, -+ -+ AuCtl_WBR_FD, /* pathconf wrapper */ -+ AuCtl_IBUSY, /* busy inode */ -+ AuCtl_MVDOWN, /* move-down */ -+ AuCtl_BR, /* info about branches */ -+ AuCtl_FHSM_FD /* connection for fhsm */ -+}; -+ -+/* borrowed from linux/include/linux/kernel.h */ -+#ifndef ALIGN -+#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1) -+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) -+#endif -+ -+/* borrowed from linux/include/linux/compiler-gcc3.h */ -+#ifndef __aligned -+#define __aligned(x) __attribute__((aligned(x))) -+#endif -+ -+#ifdef __KERNEL__ -+#ifndef __packed -+#define __packed __attribute__((packed)) -+#endif -+#endif -+ -+struct au_rdu_cookie { -+ uint64_t h_pos; -+ int16_t bindex; -+ uint8_t flags; -+ uint8_t pad; -+ uint32_t generation; -+} __aligned(8); -+ -+struct au_rdu_ent { -+ uint64_t ino; -+ int16_t bindex; -+ uint8_t type; -+ uint8_t nlen; -+ uint8_t wh; -+ char name[0]; -+} __aligned(8); -+ -+static inline int au_rdu_len(int nlen) -+{ -+ /* include the terminating NULL */ -+ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1, -+ sizeof(uint64_t)); -+} -+ -+union au_rdu_ent_ul { -+ struct au_rdu_ent __user *e; -+ uint64_t ul; -+}; -+ -+enum { -+ AufsCtlRduV_SZ, -+ AufsCtlRduV_End -+}; -+ -+struct aufs_rdu { -+ /* input */ -+ union { -+ uint64_t sz; /* AuCtl_RDU */ -+ uint64_t nent; /* AuCtl_RDU_INO */ -+ }; -+ union au_rdu_ent_ul ent; -+ uint16_t verify[AufsCtlRduV_End]; -+ -+ /* input/output */ -+ uint32_t blk; -+ -+ /* output */ -+ union au_rdu_ent_ul tail; -+ /* number of entries which were added in a single call */ -+ uint64_t rent; -+ uint8_t full; -+ uint8_t shwh; -+ -+ struct au_rdu_cookie cookie; -+} __aligned(8); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* dirren. the branch is identified by the filename who contains this */ -+struct au_drinfo { -+ uint64_t ino; -+ union { -+ uint8_t oldnamelen; -+ uint64_t _padding; -+ }; -+ uint8_t oldname[0]; -+} __aligned(8); -+ -+struct au_drinfo_fdata { -+ uint32_t magic; -+ struct au_drinfo drinfo; -+} __aligned(8); -+ -+#define AUFS_DRINFO_MAGIC_V1 ('a' << 24 | 'd' << 16 | 'r' << 8 | 0x01) -+/* future */ -+#define AUFS_DRINFO_MAGIC_V2 ('a' << 24 | 'd' << 16 | 'r' << 8 | 0x02) -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct aufs_wbr_fd { -+ uint32_t oflags; -+ int16_t brid; -+} __aligned(8); -+ -+/* ---------------------------------------------------------------------- */ -+ -+struct aufs_ibusy { -+ uint64_t ino, h_ino; -+ int16_t bindex; -+} __aligned(8); -+ -+/* ---------------------------------------------------------------------- */ -+ -+/* error code for move-down */ -+/* the actual message strings are implemented in aufs-util.git */ -+enum { -+ EAU_MVDOWN_OPAQUE = 1, -+ EAU_MVDOWN_WHITEOUT, -+ EAU_MVDOWN_UPPER, -+ EAU_MVDOWN_BOTTOM, -+ EAU_MVDOWN_NOUPPER, -+ EAU_MVDOWN_NOLOWERBR, -+ EAU_Last -+}; -+ -+/* flags for move-down */ -+#define AUFS_MVDOWN_DMSG 1 -+#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */ -+#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */ -+#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */ -+#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */ -+#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */ -+#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */ -+#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */ -+#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */ -+#define AUFS_MVDOWN_FHSM_LOWER (1 << 9) /* find fhsm attr for lower */ -+#define AUFS_MVDOWN_STFS (1 << 10) /* req. stfs */ -+#define AUFS_MVDOWN_STFS_FAILED (1 << 11) /* output: stfs is unusable */ -+#define AUFS_MVDOWN_BOTTOM (1 << 12) /* output: no more lowers */ -+ -+/* index for move-down */ -+enum { -+ AUFS_MVDOWN_UPPER, -+ AUFS_MVDOWN_LOWER, -+ AUFS_MVDOWN_NARRAY -+}; -+ -+/* -+ * additional info of move-down -+ * number of free blocks and inodes. -+ * subset of struct kstatfs, but smaller and always 64bit. -+ */ -+struct aufs_stfs { -+ uint64_t f_blocks; -+ uint64_t f_bavail; -+ uint64_t f_files; -+ uint64_t f_ffree; -+}; -+ -+struct aufs_stbr { -+ int16_t brid; /* optional input */ -+ int16_t bindex; /* output */ -+ struct aufs_stfs stfs; /* output when AUFS_MVDOWN_STFS set */ -+} __aligned(8); -+ -+struct aufs_mvdown { -+ uint32_t flags; /* input/output */ -+ struct aufs_stbr stbr[AUFS_MVDOWN_NARRAY]; /* input/output */ -+ int8_t au_errno; /* output */ -+} __aligned(8); -+ -+/* ---------------------------------------------------------------------- */ -+ -+union aufs_brinfo { -+ /* PATH_MAX may differ between kernel-space and user-space */ -+ char _spacer[4096]; -+ struct { -+ int16_t id; -+ int perm; -+ char path[0]; -+ }; -+} __aligned(8); -+ -+/* ---------------------------------------------------------------------- */ -+ -+#define AuCtlType 'A' -+#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu) -+#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu) -+#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \ -+ struct aufs_wbr_fd) -+#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy) -+#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \ -+ struct aufs_mvdown) -+#define AUFS_CTL_BRINFO _IOW(AuCtlType, AuCtl_BR, union aufs_brinfo) -+#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int) -+ -+#endif /* __AUFS_TYPE_H__ */ -diff --git a/kernel/fork.c b/kernel/fork.c -index f0b584795..fa562c364 100644 ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -505,7 +505,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, - struct inode *inode = file_inode(file); - struct address_space *mapping = file->f_mapping; - -- get_file(file); -+ vma_get_file(tmp); - if (tmp->vm_flags & VM_DENYWRITE) - atomic_dec(&inode->i_writecount); - i_mmap_lock_write(mapping); -diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c -index dd13f865a..7ac19efda 100644 ---- a/kernel/locking/lockdep.c -+++ b/kernel/locking/lockdep.c -@@ -140,7 +140,7 @@ static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES]; - unsigned long nr_lock_classes; - static struct lock_class lock_classes[MAX_LOCKDEP_KEYS]; - --static inline struct lock_class *hlock_class(struct held_lock *hlock) -+inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock) - { - if (!hlock->class_idx) { - /* -@@ -151,6 +151,8 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock) - } - return lock_classes + hlock->class_idx - 1; - } -+EXPORT_SYMBOL_GPL(lockdep_hlock_class); -+#define hlock_class(hlock) lockdep_hlock_class(hlock) - - #ifdef CONFIG_LOCK_STAT - static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], cpu_lock_stats); -diff --git a/kernel/task_work.c b/kernel/task_work.c -index 0fef39566..83fb1ecfc 100644 ---- a/kernel/task_work.c -+++ b/kernel/task_work.c -@@ -116,3 +116,4 @@ void task_work_run(void) - } while (work); - } - } -+EXPORT_SYMBOL_GPL(task_work_run); -diff --git a/mm/Makefile b/mm/Makefile -index 26ef77a38..b2869af1e 100644 ---- a/mm/Makefile -+++ b/mm/Makefile -@@ -39,7 +39,7 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \ - mm_init.o mmu_context.o percpu.o slab_common.o \ - compaction.o vmacache.o \ - interval_tree.o list_lru.o workingset.o \ -- debug.o $(mmu-y) -+ prfile.o debug.o $(mmu-y) - - obj-y += init-mm.o - -diff --git a/mm/filemap.c b/mm/filemap.c -index 52517f28e..250f675dc 100644 ---- a/mm/filemap.c -+++ b/mm/filemap.c -@@ -2700,7 +2700,7 @@ vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf) - vm_fault_t ret = VM_FAULT_LOCKED; - - sb_start_pagefault(inode->i_sb); -- file_update_time(vmf->vma->vm_file); -+ vma_file_update_time(vmf->vma); - lock_page(page); - if (page->mapping != inode->i_mapping) { - unlock_page(page); -diff --git a/mm/mmap.c b/mm/mmap.c -index f7cd9cb96..515e88a19 100644 ---- a/mm/mmap.c -+++ b/mm/mmap.c -@@ -180,7 +180,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) - if (vma->vm_ops && vma->vm_ops->close) - vma->vm_ops->close(vma); - if (vma->vm_file) -- fput(vma->vm_file); -+ vma_fput(vma); - mpol_put(vma_policy(vma)); - vm_area_free(vma); - return next; -@@ -905,7 +905,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, - if (remove_next) { - if (file) { - uprobe_munmap(next, next->vm_start, next->vm_end); -- fput(file); -+ vma_fput(vma); - } - if (next->anon_vma) - anon_vma_merge(vma, next); -@@ -1821,8 +1821,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr, - return addr; - - unmap_and_free_vma: -+ vma_fput(vma); - vma->vm_file = NULL; -- fput(file); - - /* Undo any partial mapping done by a device driver. */ - unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); -@@ -2641,7 +2641,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, - goto out_free_mpol; - - if (new->vm_file) -- get_file(new->vm_file); -+ vma_get_file(new); - - if (new->vm_ops && new->vm_ops->open) - new->vm_ops->open(new); -@@ -2660,7 +2660,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, - if (new->vm_ops && new->vm_ops->close) - new->vm_ops->close(new); - if (new->vm_file) -- fput(new->vm_file); -+ vma_fput(new); - unlink_anon_vmas(new); - out_free_mpol: - mpol_put(vma_policy(new)); -@@ -2822,7 +2822,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, - struct vm_area_struct *vma; - unsigned long populate = 0; - unsigned long ret = -EINVAL; -- struct file *file; -+ struct file *file, *prfile; - - pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.rst.\n", - current->comm, current->pid); -@@ -2897,10 +2897,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, - } - } - -- file = get_file(vma->vm_file); -+ vma_get_file(vma); -+ file = vma->vm_file; -+ prfile = vma->vm_prfile; - ret = do_mmap_pgoff(vma->vm_file, start, size, - prot, flags, pgoff, &populate, NULL); -+ if (!IS_ERR_VALUE(ret) && file && prfile) { -+ struct vm_area_struct *new_vma; -+ -+ new_vma = find_vma(mm, ret); -+ if (!new_vma->vm_prfile) -+ new_vma->vm_prfile = prfile; -+ if (new_vma != vma) -+ get_file(prfile); -+ } -+ /* -+ * two fput()s instead of vma_fput(vma), -+ * coz vma may not be available anymore. -+ */ - fput(file); -+ if (prfile) -+ fput(prfile); - out: - up_write(&mm->mmap_sem); - if (populate) -@@ -3206,7 +3223,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, - if (anon_vma_clone(new_vma, vma)) - goto out_free_mempol; - if (new_vma->vm_file) -- get_file(new_vma->vm_file); -+ vma_get_file(new_vma); - if (new_vma->vm_ops && new_vma->vm_ops->open) - new_vma->vm_ops->open(new_vma); - vma_link(mm, new_vma, prev, rb_link, rb_parent); -diff --git a/mm/nommu.c b/mm/nommu.c -index e4aac3321..b27b200f1 100644 ---- a/mm/nommu.c -+++ b/mm/nommu.c -@@ -625,7 +625,7 @@ static void __put_nommu_region(struct vm_region *region) - up_write(&nommu_region_sem); - - if (region->vm_file) -- fput(region->vm_file); -+ vmr_fput(region); - - /* IO memory and memory shared directly out of the pagecache - * from ramfs/tmpfs mustn't be released here */ -@@ -763,7 +763,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma) - if (vma->vm_ops && vma->vm_ops->close) - vma->vm_ops->close(vma); - if (vma->vm_file) -- fput(vma->vm_file); -+ vma_fput(vma); - put_nommu_region(vma->vm_region); - vm_area_free(vma); - } -@@ -1286,7 +1286,7 @@ unsigned long do_mmap(struct file *file, - goto error_just_free; - } - } -- fput(region->vm_file); -+ vmr_fput(region); - kmem_cache_free(vm_region_jar, region); - region = pregion; - result = start; -@@ -1361,7 +1361,7 @@ unsigned long do_mmap(struct file *file, - up_write(&nommu_region_sem); - error: - if (region->vm_file) -- fput(region->vm_file); -+ vmr_fput(region); - kmem_cache_free(vm_region_jar, region); - if (vma->vm_file) - fput(vma->vm_file); -diff --git a/mm/prfile.c b/mm/prfile.c -new file mode 100644 -index 000000000..a27ac3688 ---- /dev/null -+++ b/mm/prfile.c -@@ -0,0 +1,86 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Mainly for aufs which mmap(2) different file and wants to print different -+ * path in /proc/PID/maps. -+ * Call these functions via macros defined in linux/mm.h. -+ * -+ * See Documentation/filesystems/aufs/design/06mmap.txt -+ * -+ * Copyright (c) 2014-2018 Junjro R. Okajima -+ * Copyright (c) 2014 Ian Campbell -+ */ -+ -+#include -+#include -+#include -+ -+/* #define PRFILE_TRACE */ -+static inline void prfile_trace(struct file *f, struct file *pr, -+ const char func[], int line, const char func2[]) -+{ -+#ifdef PRFILE_TRACE -+ if (pr) -+ pr_info("%s:%d: %s, %pD2\n", func, line, func2, f); -+#endif -+} -+ -+void vma_do_file_update_time(struct vm_area_struct *vma, const char func[], -+ int line) -+{ -+ struct file *f = vma->vm_file, *pr = vma->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ file_update_time(f); -+ if (f && pr) -+ file_update_time(pr); -+} -+ -+struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[], -+ int line) -+{ -+ struct file *f = vma->vm_file, *pr = vma->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ return (f && pr) ? pr : f; -+} -+ -+void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line) -+{ -+ struct file *f = vma->vm_file, *pr = vma->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ get_file(f); -+ if (f && pr) -+ get_file(pr); -+} -+ -+void vma_do_fput(struct vm_area_struct *vma, const char func[], int line) -+{ -+ struct file *f = vma->vm_file, *pr = vma->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ fput(f); -+ if (f && pr) -+ fput(pr); -+} -+ -+#ifndef CONFIG_MMU -+struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[], -+ int line) -+{ -+ struct file *f = region->vm_file, *pr = region->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ return (f && pr) ? pr : f; -+} -+ -+void vmr_do_fput(struct vm_region *region, const char func[], int line) -+{ -+ struct file *f = region->vm_file, *pr = region->vm_prfile; -+ -+ prfile_trace(f, pr, func, line, __func__); -+ fput(f); -+ if (f && pr) -+ fput(pr); -+} -+#endif /* !CONFIG_MMU */ -diff --git a/security/commoncap.c b/security/commoncap.c -index 2e489d6a3..1e146dafe 100644 ---- a/security/commoncap.c -+++ b/security/commoncap.c -@@ -1336,12 +1336,14 @@ int cap_mmap_addr(unsigned long addr) - } - return ret; - } -+EXPORT_SYMBOL_GPL(cap_mmap_addr); - - int cap_mmap_file(struct file *file, unsigned long reqprot, - unsigned long prot, unsigned long flags) - { - return 0; - } -+EXPORT_SYMBOL_GPL(cap_mmap_file); - - #ifdef CONFIG_SECURITY - -diff --git a/security/device_cgroup.c b/security/device_cgroup.c -index cd97929fa..424fd2308 100644 ---- a/security/device_cgroup.c -+++ b/security/device_cgroup.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -824,3 +825,4 @@ int __devcgroup_check_permission(short type, u32 major, u32 minor, - - return 0; - } -+EXPORT_SYMBOL_GPL(__devcgroup_check_permission); -diff --git a/security/security.c b/security/security.c -index 736e78da1..b3145394c 100644 ---- a/security/security.c -+++ b/security/security.c -@@ -542,6 +542,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry) - return 0; - return call_int_hook(path_rmdir, 0, dir, dentry); - } -+EXPORT_SYMBOL_GPL(security_path_rmdir); - - int security_path_unlink(const struct path *dir, struct dentry *dentry) - { -@@ -558,6 +559,7 @@ int security_path_symlink(const struct path *dir, struct dentry *dentry, - return 0; - return call_int_hook(path_symlink, 0, dir, dentry, old_name); - } -+EXPORT_SYMBOL_GPL(security_path_symlink); - - int security_path_link(struct dentry *old_dentry, const struct path *new_dir, - struct dentry *new_dentry) -@@ -566,6 +568,7 @@ int security_path_link(struct dentry *old_dentry, const struct path *new_dir, - return 0; - return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry); - } -+EXPORT_SYMBOL_GPL(security_path_link); - - int security_path_rename(const struct path *old_dir, struct dentry *old_dentry, - const struct path *new_dir, struct dentry *new_dentry, -@@ -593,6 +596,7 @@ int security_path_truncate(const struct path *path) - return 0; - return call_int_hook(path_truncate, 0, path); - } -+EXPORT_SYMBOL_GPL(security_path_truncate); - - int security_path_chmod(const struct path *path, umode_t mode) - { -@@ -600,6 +604,7 @@ int security_path_chmod(const struct path *path, umode_t mode) - return 0; - return call_int_hook(path_chmod, 0, path, mode); - } -+EXPORT_SYMBOL_GPL(security_path_chmod); - - int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) - { -@@ -607,6 +612,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) - return 0; - return call_int_hook(path_chown, 0, path, uid, gid); - } -+EXPORT_SYMBOL_GPL(security_path_chown); - - int security_path_chroot(const struct path *path) - { -@@ -692,6 +698,7 @@ int security_inode_readlink(struct dentry *dentry) - return 0; - return call_int_hook(inode_readlink, 0, dentry); - } -+EXPORT_SYMBOL_GPL(security_inode_readlink); - - int security_inode_follow_link(struct dentry *dentry, struct inode *inode, - bool rcu) -@@ -707,6 +714,7 @@ int security_inode_permission(struct inode *inode, int mask) - return 0; - return call_int_hook(inode_permission, 0, inode, mask); - } -+EXPORT_SYMBOL_GPL(security_inode_permission); - - int security_inode_setattr(struct dentry *dentry, struct iattr *attr) - { -@@ -878,6 +886,7 @@ int security_file_permission(struct file *file, int mask) - - return fsnotify_perm(file, mask); - } -+EXPORT_SYMBOL_GPL(security_file_permission); - - int security_file_alloc(struct file *file) - { -@@ -937,6 +946,7 @@ int security_mmap_file(struct file *file, unsigned long prot, - return ret; - return ima_file_mmap(file, prot); - } -+EXPORT_SYMBOL_GPL(security_mmap_file); - - int security_mmap_addr(unsigned long addr) - { diff --git a/patch/kernel/sunxi-current/general-aufs4.19-20181029.patch.disabled b/patch/kernel/sunxi-legacy/general-aufs4.19-20181029.patch.disabled similarity index 100% rename from patch/kernel/sunxi-current/general-aufs4.19-20181029.patch.disabled rename to patch/kernel/sunxi-legacy/general-aufs4.19-20181029.patch.disabled diff --git a/patch/kernel/sunxi-legacy/general-axp20x-sysfs-interface.patch b/patch/kernel/sunxi-legacy/general-axp20x-sysfs-interface.patch index 2d3860da7..5999b340e 100644 --- a/patch/kernel/sunxi-legacy/general-axp20x-sysfs-interface.patch +++ b/patch/kernel/sunxi-legacy/general-axp20x-sysfs-interface.patch @@ -2,14 +2,6 @@ diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index a57d6e9..51b34f6 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - - #define AXP20X_OFF 0x80 - @@ -72,6 +73,7 @@ static const struct regmap_range axp20x_volatile_ranges[] = { regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE), regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L), diff --git a/patch/kernel/sunxi-legacy/general-enable-allwinner-SoCs-SID-support.patch b/patch/kernel/sunxi-legacy/general-enable-allwinner-SoCs-SID-support.patch deleted file mode 100644 index 1377a6bef..000000000 --- a/patch/kernel/sunxi-legacy/general-enable-allwinner-SoCs-SID-support.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 226c3a142138329cff8b41571fd37e7a3ced74aa Mon Sep 17 00:00:00 2001 -From: wuweidong <625769020@qq.com> -Date: Thu, 19 Apr 2018 11:35:35 +0800 -Subject: [PATCH 59/60] arm64: sunxi_arm64_defconfig: Enable - CONFIG_NVMEM_SUNXI_SID - ---- - arch/arm/boot/dts/sunxi-h3-h5.dtsi | 5 +++++ - arch/arm64/configs/sunxi_arm64_defconfig | 2 +- - 2 files changed, 6 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -index 0137e886728a..08e838caebbb 100644 ---- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi -+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -@@ -248,6 +248,11 @@ - status = "disabled"; - }; - -+ sid: eeprom@01c14000 { -+ compatible = "allwinner,sun8i-h3-sid"; -+ reg = <0x01c14000 0x400>; -+ }; -+ - usbphy: phy@1c19400 { - compatible = "allwinner,sun8i-h3-usb-phy"; - reg = <0x01c19400 0x2c>, diff --git a/patch/kernel/sunxi-legacy/general-fix-builddeb-packaging.patch b/patch/kernel/sunxi-legacy/general-fix-builddeb-packaging.patch new file mode 100644 index 000000000..cfa34ff84 --- /dev/null +++ b/patch/kernel/sunxi-legacy/general-fix-builddeb-packaging.patch @@ -0,0 +1,15 @@ +diff --git a/Makefile b/Makefile +index b37d0e8..fc1b1b5 100644 +--- a/Makefile ++++ b/Makefile +@@ -388,7 +388,9 @@ KCONFIG_CONFIG ?= .config + export KCONFIG_CONFIG + + # SHELL used by kbuild +-CONFIG_SHELL := sh ++CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ ++ else if [ -x /bin/bash ]; then echo /bin/bash; \ ++ else echo sh; fi ; fi) + + HOST_LFS_CFLAGS := $(shell getconf LFS_CFLAGS 2>/dev/null) + HOST_LFS_LDFLAGS := $(shell getconf LFS_LDFLAGS 2>/dev/null) diff --git a/patch/kernel/sunxi-legacy/general-fix-cs_gpio-spi-support.patch b/patch/kernel/sunxi-legacy/general-fix-cs_gpio-spi-support.patch new file mode 100644 index 000000000..4588287dc --- /dev/null +++ b/patch/kernel/sunxi-legacy/general-fix-cs_gpio-spi-support.patch @@ -0,0 +1,24 @@ +diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c +index 9a7def7..08c6a05 100644 +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -2884,6 +2884,19 @@ int spi_setup(struct spi_device *spi) + if (spi->controller->setup) + status = spi->controller->setup(spi); + ++ if (gpio_is_valid(spi->cs_gpio)) { ++ dev_info(&spi->dev, "spi_setup / gpio_is_valid(%d) ... doing gpio_request ...\n", spi->cs_gpio); ++ int ret = gpio_request(spi->cs_gpio, dev_name(&spi->dev)); ++ if (ret) { ++ dev_err(&spi->dev, "failed to request gpio\n"); ++ } ++ else { ++ gpio_direction_output(spi->cs_gpio, ++ !(spi->mode & SPI_CS_HIGH)); ++ dev_info(&spi->dev, "spi_setup / gpio_direction_output(%d) done !\n", spi->cs_gpio); ++ } ++ } ++ + spi_set_cs(spi, false); + + dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s%u bits/w, %u Hz max --> %d\n", diff --git a/patch/kernel/sunxi-legacy/general-increasing_DMA_block_memory_allocation_to_2048.patch b/patch/kernel/sunxi-legacy/general-increasing_DMA_block_memory_allocation_to_2048.patch deleted file mode 100644 index 8d8746273..000000000 --- a/patch/kernel/sunxi-legacy/general-increasing_DMA_block_memory_allocation_to_2048.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c -index 3216e09..21bce28 ---- a/arch/arm64/mm/dma-mapping.c -+++ b/arch/arm64/mm/dma-mapping.c -@@ -44,7 +44,7 @@ static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot, - - static struct gen_pool *atomic_pool; - --#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K -+#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_2M - static size_t atomic_pool_size __initdata = DEFAULT_DMA_COHERENT_POOL_SIZE; - - static int __init early_coherent_pool(char *p) - -diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c -index ada8eb2..8df220f ---- a/arch/arm/mm/dma-mapping.c -+++ b/arch/arm/mm/dma-mapping.c -@@ -381,7 +381,7 @@ static void __dma_free_remap(void *cpu_addr, size_t size) - VM_ARM_DMA_CONSISTENT | VM_USERMAP); - } - --#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K -+#define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_2M - static struct gen_pool *atomic_pool __ro_after_init; - - static size_t atomic_pool_size __initdata = DEFAULT_DMA_COHERENT_POOL_SIZE; diff --git a/patch/kernel/sunxi-legacy/general-spidev-remove-warnings.patch b/patch/kernel/sunxi-legacy/general-spidev-remove-warnings.patch new file mode 100644 index 000000000..5190fd02e --- /dev/null +++ b/patch/kernel/sunxi-legacy/general-spidev-remove-warnings.patch @@ -0,0 +1,22 @@ +diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c +index b0c76e262..c56f6dc4c 100644 +--- a/drivers/spi/spidev.c ++++ b/drivers/spi/spidev.c +@@ -722,12 +722,12 @@ static int spidev_probe(struct spi_device *spi) + + /* + * spidev should never be referenced in DT without a specific +- * compatible string, it is a Linux implementation thing +- * rather than a description of the hardware. ++ * compatible string, but people don't care and use DT overlays ++ * to activate SPIdev on demand + */ +- WARN(spi->dev.of_node && +- of_device_is_compatible(spi->dev.of_node, "spidev"), +- "%pOF: buggy DT: spidev listed directly in DT\n", spi->dev.of_node); ++ if (spi->dev.of_node && !of_match_device(spidev_dt_ids, &spi->dev)) { ++ dev_info(&spi->dev, "probing from DT"); ++ } + + spidev_probe_acpi(spi); + diff --git a/patch/kernel/sunxi-legacy/general-sunxi-overlays.patch b/patch/kernel/sunxi-legacy/general-sunxi-overlays.patch index 2b0c39906..934587d45 100644 --- a/patch/kernel/sunxi-legacy/general-sunxi-overlays.patch +++ b/patch/kernel/sunxi-legacy/general-sunxi-overlays.patch @@ -1,10 +1,10 @@ diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index a48dc14..68da8fc 100644 +index 965a7c0..71a672e 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile -@@ -1136,3 +1136,5 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ - aspeed-bmc-opp-witherspoon.dtb \ +@@ -1213,3 +1213,5 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ aspeed-bmc-opp-zaius.dtb \ + aspeed-bmc-portwell-neptune.dtb \ aspeed-bmc-quanta-q71l.dtb + +subdir-y := overlay @@ -1196,7 +1196,7 @@ index 0000000..9254e22 +}; diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-can.dts b/arch/arm/boot/dts/overlay/sun4i-a10-can.dts new file mode 100644 -index 0000000..4be3a38 +index 0000000..1a9511d --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun4i-a10-can.dts @@ -0,0 +1,15 @@ @@ -1210,14 +1210,14 @@ index 0000000..4be3a38 + target = <&can0>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&can0_pins_a>; ++ pinctrl-0 = <&can0_ph_pins>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-fixup.scr-cmd b/arch/arm/boot/dts/overlay/sun4i-a10-fixup.scr-cmd new file mode 100644 -index 0000000..8dd3eeb +index 0000000..d80f2fc --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun4i-a10-fixup.scr-cmd @@ -0,0 +1,124 @@ @@ -1242,10 +1242,10 @@ index 0000000..8dd3eeb + test "${param_spinor_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c05000" + test "${param_spinor_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c06000" + test "${param_spinor_spi_bus}" = "2" && setenv tmp_spi_path "spi@1c17000" -+ fdt set /soc@1c00000/${tmp_spi_path} status "okay" -+ fdt set /soc@1c00000/${tmp_spi_path}/spiflash status "okay" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spiflash status "okay" + if test -n "${param_spinor_max_freq}"; then -+ fdt set /soc@1c00000/${tmp_spi_path}/spiflash spi-max-frequency "<${param_spinor_max_freq}>" ++ fdt set /soc/${tmp_spi_path}/spiflash spi-max-frequency "<${param_spinor_max_freq}>" + fi + env delete tmp_spi_path +fi @@ -1254,19 +1254,19 @@ index 0000000..8dd3eeb + test "${param_spidev_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c05000" + test "${param_spidev_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c06000" + test "${param_spidev_spi_bus}" = "2" && setenv tmp_spi_path "spi@1c17000" -+ fdt set /soc@1c00000/${tmp_spi_path} status "okay" -+ fdt set /soc@1c00000/${tmp_spi_path}/spidev status "okay" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spidev status "okay" + if test -n "${param_spidev_max_freq}"; then -+ fdt set /soc@1c00000/${tmp_spi_path}/spidev spi-max-frequency "<${param_spidev_max_freq}>" ++ fdt set /soc/${tmp_spi_path}/spidev spi-max-frequency "<${param_spidev_max_freq}>" + fi + env delete tmp_spi_path +fi + +if test "${param_spi2_bus_pins}" = "b"; then -+ fdt get value tmp_phandle1 /soc@1c00000/pinctrl@1c20800/spi2@1 phandle -+ fdt get value tmp_phandle2 /soc@1c00000/pinctrl@1c20800/spi2_cs0@1 phandle -+ fdt set /soc@1c00000/spi@1c17000 pinctrl-0 "<${tmp_phandle1}>" -+ fdt set /soc@1c00000/spi@1c17000 pinctrl-1 "<${tmp_phandle2}>" ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/spi2@1 phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/spi2_cs0@1 phandle ++ fdt set /soc/spi@1c17000 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/spi@1c17000 pinctrl-1 "<${tmp_phandle2}>" + env delete tmp_phandle1 tmp_phandle2 +fi + @@ -1274,8 +1274,8 @@ index 0000000..8dd3eeb + setenv tmp_bank "${param_pps_pin}" + setenv tmp_pin "${param_pps_pin}" + run decompose_pin -+ fdt set /soc@1c00000/pinctrl@1c20800/pps_pins pins "${param_pps_pin}" -+ fdt get value tmp_phandle /soc@1c00000/pinctrl@1c20800 phandle ++ fdt set /soc/pinctrl@1c20800/pps_pins pins "${param_pps_pin}" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800 phandle + fdt set /pps@0 gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 0>" + env delete tmp_pin tmp_bank tmp_phandle +fi @@ -1285,14 +1285,14 @@ index 0000000..8dd3eeb +fi + +if test "${param_pwm_pins}" = "0"; then -+ fdt get value tmp_phandle /soc@1c00000/pinctrl@1c20800/pwm0@0 -+ fdt set /soc@1c00000/pwm@1c20e00 pinctrl-0 "<${tmp_phandle}>" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/pwm0@0 ++ fdt set /soc/pwm@1c20e00 pinctrl-0 "<${tmp_phandle}>" + env delete tmp_phandle +fi + +if test "${param_pwm_pins}" = "1"; then -+ fdt get value tmp_phandle /soc@1c00000/pinctrl@1c20800/pwm1@0 -+ fdt set /soc@1c00000/pwm@1c20e00 pinctrl-0 "<${tmp_phandle}>" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/pwm1@0 ++ fdt set /soc/pwm@1c20e00 pinctrl-0 "<${tmp_phandle}>" + env delete tmp_phandle +fi + @@ -1300,54 +1300,54 @@ index 0000000..8dd3eeb + setenv tmp_bank "${param_w1_pin}" + setenv tmp_pin "${param_w1_pin}" + run decompose_pin -+ fdt set /soc@1c00000/pinctrl@1c20800/w1_pins pins "${param_w1_pin}" -+ fdt get value tmp_phandle /soc@1c00000/pinctrl@1c20800 phandle ++ fdt set /soc/pinctrl@1c20800/w1_pins pins "${param_w1_pin}" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800 phandle + fdt set /onewire@0 gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 0>" + env delete tmp_pin tmp_bank tmp_phandle +fi + +if test "${param_w1_pin_int_pullup}" = "1"; then -+ fdt set /soc@1c00000/pinctrl@1c20800/w1_pins bias-pull-up ++ fdt set /soc/pinctrl@1c20800/w1_pins bias-pull-up +fi + +if test "${param_uart2_rtscts}" = "1"; then -+ fdt get value tmp_phandle /soc@1c00000/pinctrl@1c20800/uart2@0 phandle -+ fdt set /soc@1c00000/serial@1c28800 pinctrl-0 "<${tmp_phandle}>" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/uart2@0 phandle ++ fdt set /soc/serial@1c28800 pinctrl-0 "<${tmp_phandle}>" + env delete tmp_phandle +fi + +if test "${param_uart3_pins}" = "b"; then + if test "${param_uart3_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc@1c00000/pinctrl@1c20800/uart3_pins_b phandle -+ fdt get value tmp_phandle2 /soc@1c00000/pinctrl@1c20800/uart3_pins_b_rts_cts phandle -+ fdt set /soc@1c00000/serial@1c28c00 pinctrl-names "default" "default" -+ fdt set /soc@1c00000/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>" -+ fdt set /soc@1c00000/serial@1c28c00 pinctrl-1 "<${tmp_phandle2}>" ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart3_pins_b phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart3_pins_b_rts_cts phandle ++ fdt set /soc/serial@1c28c00 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@1c28c00 pinctrl-1 "<${tmp_phandle2}>" + env delete tmp_phandle1 tmp_phandle2 + else -+ fdt get value tmp_phandle /soc@1c00000/pinctrl@1c20800/uart3_pins_b phandle -+ fdt set /soc@1c00000/serial@1c28c00 pinctrl-0 "<${tmp_phandle}>" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/uart3_pins_b phandle ++ fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle}>" + env delete tmp_phandle + fi +else + if test "${param_uart3_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc@1c00000/pinctrl@1c20800/uart3_pins_a phandle -+ fdt get value tmp_phandle2 /soc@1c00000/pinctrl@1c20800/uart3_pins_a_rts_cts phandle -+ fdt set /soc@1c00000/serial@1c28c00 pinctrl-names "default" "default" -+ fdt set /soc@1c00000/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>" -+ fdt set /soc@1c00000/serial@1c28c00 pinctrl-1 "<${tmp_phandle2}>" ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart3_pins_a phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart3_pins_a_rts_cts phandle ++ fdt set /soc/serial@1c28c00 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@1c28c00 pinctrl-1 "<${tmp_phandle2}>" + env delete tmp_phandle1 tmp_phandle2 + fi +fi + +if test "${param_uart4_pins}" = "b"; then -+ fdt get value tmp_phandle /soc@1c00000/pinctrl@1c20800/uart4@1 phandle -+ fdt set /soc@1c00000/serial@1c29000 pinctrl-0 "<${tmp_phandle}>" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/uart4@1 phandle ++ fdt set /soc/serial@1c29000 pinctrl-0 "<${tmp_phandle}>" + env delete tmp_phandle +fi diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-i2c1.dts b/arch/arm/boot/dts/overlay/sun4i-a10-i2c1.dts new file mode 100644 -index 0000000..44a7ce9 +index 0000000..4c104bf --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun4i-a10-i2c1.dts @@ -0,0 +1,22 @@ @@ -1368,14 +1368,14 @@ index 0000000..44a7ce9 + target = <&i2c1>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins_a>; ++ pinctrl-0 = <&i2c1_pins>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-i2c2.dts b/arch/arm/boot/dts/overlay/sun4i-a10-i2c2.dts new file mode 100644 -index 0000000..ab3c00f +index 0000000..1c2c3e9 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun4i-a10-i2c2.dts @@ -0,0 +1,22 @@ @@ -1396,7 +1396,7 @@ index 0000000..ab3c00f + target = <&i2c2>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&i2c2_pins_a>; ++ pinctrl-0 = <&i2c2_pins>; + status = "okay"; + }; + }; @@ -1547,7 +1547,7 @@ index 0000000..6031fc5 +}; diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-pwm.dts b/arch/arm/boot/dts/overlay/sun4i-a10-pwm.dts new file mode 100644 -index 0000000..1927fc5 +index 0000000..ba88500 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun4i-a10-pwm.dts @@ -0,0 +1,15 @@ @@ -1561,14 +1561,14 @@ index 0000000..1927fc5 + target = <&pwm>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&pwm0_pins_a>, <&pwm1_pins_a>; ++ pinctrl-0 = <&pwm0_pin>, <&pwm1_pin>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-spdif-out.dts b/arch/arm/boot/dts/overlay/sun4i-a10-spdif-out.dts new file mode 100644 -index 0000000..5811e47 +index 0000000..234dfc8 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun4i-a10-spdif-out.dts @@ -0,0 +1,38 @@ @@ -1582,7 +1582,7 @@ index 0000000..5811e47 + target = <&spdif>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&spdif_tx_pins_a>; ++ pinctrl-0 = <&spdif_tx_pin>; + status = "okay"; + }; + }; @@ -1612,7 +1612,7 @@ index 0000000..5811e47 +}; diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-spi-jedec-nor.dts b/arch/arm/boot/dts/overlay/sun4i-a10-spi-jedec-nor.dts new file mode 100644 -index 0000000..9cf640f +index 0000000..ee4ff6f --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun4i-a10-spi-jedec-nor.dts @@ -0,0 +1,57 @@ @@ -1636,7 +1636,7 @@ index 0000000..9cf640f + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spiflash { ++ spiflash@0 { + compatible = "jedec,spi-nor"; + status = "disabled"; + reg = <0>; @@ -1650,7 +1650,7 @@ index 0000000..9cf640f + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spiflash { ++ spiflash@0 { + compatible = "jedec,spi-nor"; + status = "disabled"; + reg = <0>; @@ -1664,7 +1664,7 @@ index 0000000..9cf640f + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spiflash { ++ spiflash@0 { + compatible = "jedec,spi-nor"; + status = "disabled"; + reg = <0>; @@ -1675,7 +1675,7 @@ index 0000000..9cf640f +}; diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-spi-spidev.dts b/arch/arm/boot/dts/overlay/sun4i-a10-spi-spidev.dts new file mode 100644 -index 0000000..f603d6d +index 0000000..5667aec --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun4i-a10-spi-spidev.dts @@ -0,0 +1,57 @@ @@ -1699,7 +1699,7 @@ index 0000000..f603d6d + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spidev { ++ spidev@0 { + compatible = "spidev"; + status = "disabled"; + reg = <0>; @@ -1713,7 +1713,7 @@ index 0000000..f603d6d + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spidev { ++ spidev@0 { + compatible = "spidev"; + status = "disabled"; + reg = <0>; @@ -1727,7 +1727,7 @@ index 0000000..f603d6d + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spidev { ++ spidev@0 { + compatible = "spidev"; + status = "disabled"; + reg = <0>; @@ -1738,7 +1738,7 @@ index 0000000..f603d6d +}; diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-spi0.dts b/arch/arm/boot/dts/overlay/sun4i-a10-spi0.dts new file mode 100644 -index 0000000..0444262 +index 0000000..cad50d8 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun4i-a10-spi0.dts @@ -0,0 +1,23 @@ @@ -1760,14 +1760,14 @@ index 0000000..0444262 + __overlay__ { + status = "okay"; + pinctrl-names = "default", "default"; -+ pinctrl-0 = <&spi0_pins_a>; -+ pinctrl-1 = <&spi0_cs0_pins_a>; ++ pinctrl-0 = <&spi0_pi_pins>; ++ pinctrl-1 = <&spi0_cs0_pi_pin>; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-spi1.dts b/arch/arm/boot/dts/overlay/sun4i-a10-spi1.dts new file mode 100644 -index 0000000..3c3fcb8 +index 0000000..8c606d6 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun4i-a10-spi1.dts @@ -0,0 +1,22 @@ @@ -1789,13 +1789,13 @@ index 0000000..3c3fcb8 + __overlay__ { + status = "okay"; + pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_pins_a>, <&spi1_cs0_pins_a>; ++ pinctrl-0 = <&spi1_pins>, <&spi1_cs0_pin>; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-spi2.dts b/arch/arm/boot/dts/overlay/sun4i-a10-spi2.dts new file mode 100644 -index 0000000..b38e04c +index 0000000..145f285 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun4i-a10-spi2.dts @@ -0,0 +1,23 @@ @@ -1824,7 +1824,7 @@ index 0000000..b38e04c +}; diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-uart2.dts b/arch/arm/boot/dts/overlay/sun4i-a10-uart2.dts new file mode 100644 -index 0000000..41ce3e6 +index 0000000..89bb44d --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun4i-a10-uart2.dts @@ -0,0 +1,37 @@ @@ -1867,7 +1867,7 @@ index 0000000..41ce3e6 +}; diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-uart3.dts b/arch/arm/boot/dts/overlay/sun4i-a10-uart3.dts new file mode 100644 -index 0000000..0b70a65 +index 0000000..f599d92 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun4i-a10-uart3.dts @@ -0,0 +1,47 @@ @@ -1920,7 +1920,7 @@ index 0000000..0b70a65 +}; diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-uart4.dts b/arch/arm/boot/dts/overlay/sun4i-a10-uart4.dts new file mode 100644 -index 0000000..0677c63 +index 0000000..b5e562a --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun4i-a10-uart4.dts @@ -0,0 +1,37 @@ @@ -1963,7 +1963,7 @@ index 0000000..0677c63 +}; diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-uart5.dts b/arch/arm/boot/dts/overlay/sun4i-a10-uart5.dts new file mode 100644 -index 0000000..0a3ed9b +index 0000000..12c3f96 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun4i-a10-uart5.dts @@ -0,0 +1,32 @@ @@ -2001,7 +2001,7 @@ index 0000000..0a3ed9b +}; diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-uart6.dts b/arch/arm/boot/dts/overlay/sun4i-a10-uart6.dts new file mode 100644 -index 0000000..f58b411 +index 0000000..6be41d5 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun4i-a10-uart6.dts @@ -0,0 +1,32 @@ @@ -2039,7 +2039,7 @@ index 0000000..f58b411 +}; diff --git a/arch/arm/boot/dts/overlay/sun4i-a10-uart7.dts b/arch/arm/boot/dts/overlay/sun4i-a10-uart7.dts new file mode 100644 -index 0000000..65d8c68 +index 0000000..967f6af --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun4i-a10-uart7.dts @@ -0,0 +1,32 @@ @@ -2131,7 +2131,7 @@ index 0000000..60e2717 +}; diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-fixup.scr-cmd b/arch/arm/boot/dts/overlay/sun5i-a13-fixup.scr-cmd new file mode 100644 -index 0000000..db03a70 +index 0000000..9589767 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun5i-a13-fixup.scr-cmd @@ -0,0 +1,48 @@ @@ -2143,10 +2143,10 @@ index 0000000..db03a70 + test "${param_spinor_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c05000" + test "${param_spinor_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c06000" + test "${param_spinor_spi_bus}" = "2" && setenv tmp_spi_path "spi@1c17000" -+ fdt set /soc@1c00000/${tmp_spi_path} status "okay" -+ fdt set /soc@1c00000/${tmp_spi_path}/spiflash status "okay" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spiflash status "okay" + if test -n "${param_spinor_max_freq}"; then -+ fdt set /soc@1c00000/${tmp_spi_path}/spiflash spi-max-frequency "<${param_spinor_max_freq}>" ++ fdt set /soc/${tmp_spi_path}/spiflash spi-max-frequency "<${param_spinor_max_freq}>" + fi + env delete tmp_spi_path +fi @@ -2155,37 +2155,37 @@ index 0000000..db03a70 + test "${param_spidev_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c05000" + test "${param_spidev_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c06000" + test "${param_spidev_spi_bus}" = "2" && setenv tmp_spi_path "spi@1c17000" -+ fdt set /soc@1c00000/${tmp_spi_path} status "okay" -+ fdt set /soc@1c00000/${tmp_spi_path}/spidev status "okay" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spidev status "okay" + if test -n "${param_spidev_max_freq}"; then -+ fdt set /soc@1c00000/${tmp_spi_path}/spidev spi-max-frequency "<${param_spidev_max_freq}>" ++ fdt set /soc/${tmp_spi_path}/spidev spi-max-frequency "<${param_spidev_max_freq}>" + fi + env delete tmp_spi_path +fi + +if test "${param_uart1_pins}" = "b"; then -+ fdt get value tmp_phandle /soc@1c00000/pinctrl@1c28400/uart1@1 phandle -+ fdt set /soc@1c00000/serial@1c28400 pinctrl-0 "<${tmp_phandle}>" ++ fdt get value tmp_phandle /soc/pinctrl@1c28400/uart1@1 phandle ++ fdt set /soc/serial@1c28400 pinctrl-0 "<${tmp_phandle}>" + env delete tmp_phandle +fi + +if test "${param_uart2_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc@1c00000/pinctrl@1c20800/uart2@0 phandle -+ fdt get value tmp_phandle2 /soc@1c00000/pinctrl@1c20800/uart2-cts-rts@0 phandle -+ fdt set /soc@1c00000/serial@1c28800 pinctrl-0 "<${tmp_phandle1}>, <${tmp_phandle2}>" ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart2@0 phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart2-cts-rts@0 phandle ++ fdt set /soc/serial@1c28800 pinctrl-0 "<${tmp_phandle1}>, <${tmp_phandle2}>" + env delete tmp_phandle1 tmp_phandle2 +fi + +if test "${param_uart3_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc@1c00000/pinctrl@1c20800/uart3@0 phandle -+ fdt get value tmp_phandle2 /soc@1c00000/pinctrl@1c20800/uart3-cts-rts@0 phandle -+ fdt set /soc@1c00000/serial@1c28c00 pinctrl-names "default" "default" -+ fdt set /soc@1c00000/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>, <${tmp_phandle2}>" ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart3@0 phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart3-cts-rts@0 phandle ++ fdt set /soc/serial@1c28c00 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>, <${tmp_phandle2}>" + env delete tmp_phandle1 tmp_phandle2 +fi diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-i2c1.dts b/arch/arm/boot/dts/overlay/sun5i-a13-i2c1.dts new file mode 100644 -index 0000000..8d7aaff +index 0000000..444c32c --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun5i-a13-i2c1.dts @@ -0,0 +1,22 @@ @@ -2206,14 +2206,14 @@ index 0000000..8d7aaff + target = <&i2c1>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins_a>; ++ pinctrl-0 = <&i2c1_pins>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-i2c2.dts b/arch/arm/boot/dts/overlay/sun5i-a13-i2c2.dts new file mode 100644 -index 0000000..c933d05 +index 0000000..7a30681 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun5i-a13-i2c2.dts @@ -0,0 +1,22 @@ @@ -2234,14 +2234,14 @@ index 0000000..c933d05 + target = <&i2c2>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&i2c2_pins_a>; ++ pinctrl-0 = <&i2c2_pins>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-nand.dts b/arch/arm/boot/dts/overlay/sun5i-a13-nand.dts new file mode 100644 -index 0000000..669527a +index 0000000..0c5fc89 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun5i-a13-nand.dts @@ -0,0 +1,60 @@ @@ -2257,7 +2257,7 @@ index 0000000..669527a + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; -+ pinctrl-0 = <&nand_pins_a>, <&nand_cs0_pins_a>, <&nand_rb0_pins_a>; ++ pinctrl-0 = <&nand_pins>, <&nand_cs0_pin>, <&nand_rb0_pin>; + status = "okay"; + + nand@0 { @@ -2307,7 +2307,7 @@ index 0000000..669527a +}; diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-pwm.dts b/arch/arm/boot/dts/overlay/sun5i-a13-pwm.dts new file mode 100644 -index 0000000..711ff9c +index 0000000..54f5d51 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun5i-a13-pwm.dts @@ -0,0 +1,15 @@ @@ -2321,14 +2321,14 @@ index 0000000..711ff9c + target = <&pwm>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&pwm0_pins>; ++ pinctrl-0 = <&pwm0_pin>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-spi-jedec-nor.dts b/arch/arm/boot/dts/overlay/sun5i-a13-spi-jedec-nor.dts new file mode 100644 -index 0000000..168d208 +index 0000000..8cebb0b --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun5i-a13-spi-jedec-nor.dts @@ -0,0 +1,57 @@ @@ -2352,7 +2352,7 @@ index 0000000..168d208 + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spiflash { ++ spiflash@0 { + compatible = "jedec,spi-nor"; + status = "disabled"; + reg = <0>; @@ -2366,7 +2366,7 @@ index 0000000..168d208 + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spiflash { ++ spiflash@0 { + compatible = "jedec,spi-nor"; + status = "disabled"; + reg = <0>; @@ -2380,7 +2380,7 @@ index 0000000..168d208 + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spiflash { ++ spiflash@0 { + compatible = "jedec,spi-nor"; + status = "disabled"; + reg = <0>; @@ -2391,7 +2391,7 @@ index 0000000..168d208 +}; diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-spi-spidev.dts b/arch/arm/boot/dts/overlay/sun5i-a13-spi-spidev.dts new file mode 100644 -index 0000000..d2329c7 +index 0000000..ced1a0e --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun5i-a13-spi-spidev.dts @@ -0,0 +1,57 @@ @@ -2415,7 +2415,7 @@ index 0000000..d2329c7 + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spidev { ++ spidev@0 { + compatible = "spidev"; + status = "disabled"; + reg = <0>; @@ -2429,7 +2429,7 @@ index 0000000..d2329c7 + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spidev { ++ spidev@0 { + compatible = "spidev"; + status = "disabled"; + reg = <0>; @@ -2443,7 +2443,7 @@ index 0000000..d2329c7 + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spidev { ++ spidev@0 { + compatible = "spidev"; + status = "disabled"; + reg = <0>; @@ -2454,7 +2454,7 @@ index 0000000..d2329c7 +}; diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-spi0.dts b/arch/arm/boot/dts/overlay/sun5i-a13-spi0.dts new file mode 100644 -index 0000000..0a73644 +index 0000000..b23a754 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun5i-a13-spi0.dts @@ -0,0 +1,38 @@ @@ -2498,7 +2498,7 @@ index 0000000..0a73644 +}; diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-spi1.dts b/arch/arm/boot/dts/overlay/sun5i-a13-spi1.dts new file mode 100644 -index 0000000..2dc3e24 +index 0000000..cc0af5d --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun5i-a13-spi1.dts @@ -0,0 +1,39 @@ @@ -2543,7 +2543,7 @@ index 0000000..2dc3e24 +}; diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-spi2.dts b/arch/arm/boot/dts/overlay/sun5i-a13-spi2.dts new file mode 100644 -index 0000000..54ea7f9 +index 0000000..6cf5c41 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun5i-a13-spi2.dts @@ -0,0 +1,22 @@ @@ -2565,13 +2565,13 @@ index 0000000..54ea7f9 + __overlay__ { + status = "okay"; + pinctrl-names = "default"; -+ pinctrl-0 = <&spi2_pins_a>, <&spi2_cs0_pins_a>; ++ pinctrl-0 = <&spi2_pe_pins>, <&spi2_cs0_pe_pin>; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-uart0.dts b/arch/arm/boot/dts/overlay/sun5i-a13-uart0.dts new file mode 100644 -index 0000000..726514f +index 0000000..6edad42 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun5i-a13-uart0.dts @@ -0,0 +1,32 @@ @@ -2591,7 +2591,7 @@ index 0000000..726514f + fragment@1 { + target = <&pio>; + __overlay__ { -+ uart0_pins_a: uart0@0 { ++ uart0_pa_pins: uart0@0 { + pins = "PF2", "PF4"; + function = "uart0"; + }; @@ -2602,14 +2602,14 @@ index 0000000..726514f + target = <&uart0>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins_a>; ++ pinctrl-0 = <&uart0_pa_pins>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-uart1.dts b/arch/arm/boot/dts/overlay/sun5i-a13-uart1.dts new file mode 100644 -index 0000000..53d745e +index 0000000..675b701 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun5i-a13-uart1.dts @@ -0,0 +1,22 @@ @@ -2630,14 +2630,14 @@ index 0000000..53d745e + target = <&uart1>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&uart1_pins_a>; ++ pinctrl-0 = <&uart1_pe_pins>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-uart2.dts b/arch/arm/boot/dts/overlay/sun5i-a13-uart2.dts new file mode 100644 -index 0000000..89b9fc4 +index 0000000..b3c4e3d --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun5i-a13-uart2.dts @@ -0,0 +1,22 @@ @@ -2658,14 +2658,14 @@ index 0000000..89b9fc4 + target = <&uart2>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&uart2_pins_a>; ++ pinctrl-0 = <&uart2_pd_pins>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun5i-a13-uart3.dts b/arch/arm/boot/dts/overlay/sun5i-a13-uart3.dts new file mode 100644 -index 0000000..028ea08 +index 0000000..15c25d0 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun5i-a13-uart3.dts @@ -0,0 +1,22 @@ @@ -2686,7 +2686,7 @@ index 0000000..028ea08 + target = <&uart3>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&uart3_pins_a>; ++ pinctrl-0 = <&uart3_pg_pins>; + status = "okay"; + }; + }; @@ -2733,7 +2733,7 @@ index 0000000..65aebcd +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-fixup.scr-cmd b/arch/arm/boot/dts/overlay/sun7i-a20-fixup.scr-cmd new file mode 100644 -index 0000000..5a320b8 +index 0000000..db3cec8 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-fixup.scr-cmd @@ -0,0 +1,143 @@ @@ -2758,13 +2758,13 @@ index 0000000..5a320b8 + test "${param_spinor_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c05000" + test "${param_spinor_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c06000" + test "${param_spinor_spi_bus}" = "2" && setenv tmp_spi_path "spi@1c17000" -+ fdt set /soc@1c00000/${tmp_spi_path} status "okay" -+ fdt set /soc@1c00000/${tmp_spi_path}/spiflash status "okay" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spiflash status "okay" + if test -n "${param_spinor_max_freq}"; then -+ fdt set /soc@1c00000/${tmp_spi_path}/spiflash spi-max-frequency "<${param_spinor_max_freq}>" ++ fdt set /soc/${tmp_spi_path}/spiflash spi-max-frequency "<${param_spinor_max_freq}>" + fi + if test "${param_spinor_spi_bus}" = "0" && test "${param_spinor_spi_cs}" = "1"; then -+ fdt set /soc@1c00000/${tmp_spi_path}/spiflash reg "<1>" ++ fdt set /soc/${tmp_spi_path}/spiflash reg "<1>" + fi + env delete tmp_spi_path +fi @@ -2773,22 +2773,22 @@ index 0000000..5a320b8 + test "${param_spidev_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c05000" + test "${param_spidev_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c06000" + test "${param_spidev_spi_bus}" = "2" && setenv tmp_spi_path "spi@1c17000" -+ fdt set /soc@1c00000/${tmp_spi_path} status "okay" -+ fdt set /soc@1c00000/${tmp_spi_path}/spidev status "okay" ++ fdt set /soc/${tmp_spi_path} status "okay" ++ fdt set /soc/${tmp_spi_path}/spidev status "okay" + if test -n "${param_spidev_max_freq}"; then -+ fdt set /soc@1c00000/${tmp_spi_path}/spidev spi-max-frequency "<${param_spidev_max_freq}>" ++ fdt set /soc/${tmp_spi_path}/spidev spi-max-frequency "<${param_spidev_max_freq}>" + fi + if test "${param_spidev_spi_bus}" = "0" && test "${param_spidev_spi_cs}" = "1"; then -+ fdt set /soc@1c00000/${tmp_spi_path}/spidev reg "<1>" ++ fdt set /soc/${tmp_spi_path}/spidev reg "<1>" + fi + env delete tmp_spi_path +fi + +if test "${param_spi2_bus_pins}" = "b"; then -+ fdt get value tmp_phandle1 /soc@1c00000/pinctrl@1c20800/spi2@1 phandle -+ fdt get value tmp_phandle2 /soc@1c00000/pinctrl@1c20800/spi2_cs0@1 phandle -+ fdt set /soc@1c00000/spi@1c17000 pinctrl-0 "<${tmp_phandle1}>" -+ fdt set /soc@1c00000/spi@1c17000 pinctrl-1 "<${tmp_phandle2}>" ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/spi2@1 phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/spi2_cs0@1 phandle ++ fdt set /soc/spi@1c17000 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/spi@1c17000 pinctrl-1 "<${tmp_phandle2}>" + env delete tmp_phandle1 tmp_phandle2 +fi + @@ -2796,8 +2796,8 @@ index 0000000..5a320b8 + setenv tmp_bank "${param_pps_pin}" + setenv tmp_pin "${param_pps_pin}" + run decompose_pin -+ fdt set /soc@1c00000/pinctrl@1c20800/pps_pins pins "${param_pps_pin}" -+ fdt get value tmp_phandle /soc@1c00000/pinctrl@1c20800 phandle ++ fdt set /soc/pinctrl@1c20800/pps_pins pins "${param_pps_pin}" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800 phandle + fdt set /pps@0 gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 0>" + env delete tmp_pin tmp_bank tmp_phandle +fi @@ -2807,14 +2807,14 @@ index 0000000..5a320b8 +fi + +if test "${param_pwm_pins}" = "0"; then -+ fdt get value tmp_phandle /soc@1c00000/pinctrl@1c20800/pwm0@0 -+ fdt set /soc@1c00000/pwm@1c20e00 pinctrl-0 "<${tmp_phandle}>" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/pwm0@0 ++ fdt set /soc/pwm@1c20e00 pinctrl-0 "<${tmp_phandle}>" + env delete tmp_phandle +fi + +if test "${param_pwm_pins}" = "1"; then -+ fdt get value tmp_phandle /soc@1c00000/pinctrl@1c20800/pwm1@0 -+ fdt set /soc@1c00000/pwm@1c20e00 pinctrl-0 "<${tmp_phandle}>" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/pwm1@0 ++ fdt set /soc/pwm@1c20e00 pinctrl-0 "<${tmp_phandle}>" + env delete tmp_phandle +fi + @@ -2822,8 +2822,8 @@ index 0000000..5a320b8 + setenv tmp_bank "${param_w1_pin}" + setenv tmp_pin "${param_w1_pin}" + run decompose_pin -+ fdt set /soc@1c00000/pinctrl@1c20800/w1_pins pins "${param_w1_pin}" -+ fdt get value tmp_phandle /soc@1c00000/pinctrl@1c20800 phandle ++ fdt set /soc/pinctrl@1c20800/w1_pins pins "${param_w1_pin}" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800 phandle + fdt set /onewire@0 gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 0>" + env delete tmp_pin tmp_bank tmp_phandle +fi @@ -2832,57 +2832,57 @@ index 0000000..5a320b8 + setenv tmp_bank "${param_mmc2_cd_pin}" + setenv tmp_pin "${param_mmc2_cd_pin}" + run decompose_pin -+ fdt get value tmp_phandle /soc@1c00000/pinctrl@1c20800 phandle -+ fdt set /soc@1c00000/mmc@1c11000 cd-gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 1>" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800 phandle ++ fdt set /soc/mmc@1c11000 cd-gpios "<${tmp_phandle} ${tmp_bank} ${tmp_pin} 1>" +fi + +if test "${param_mmc2_non_removable}" = "1"; then -+ fdt rm /soc@1c00000/mmc@1c11000 cd-gpios -+ fdt set /soc@1c00000/mmc@1c11000 non-removable ++ fdt rm /soc/mmc@1c11000 cd-gpios ++ fdt set /soc/mmc@1c11000 non-removable +fi + +if test "${param_w1_pin_int_pullup}" = "1"; then -+ fdt set /soc@1c00000/pinctrl@1c20800/w1_pins bias-pull-up ++ fdt set /soc/pinctrl@1c20800/w1_pins bias-pull-up +fi + +if test "${param_uart2_rtscts}" = "1"; then -+ fdt get value tmp_phandle /soc@1c00000/pinctrl@1c20800/uart2@0 phandle -+ fdt set /soc@1c00000/serial@1c28800 pinctrl-0 "<${tmp_phandle}>" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/uart2-pi-pins phandle ++ fdt set /soc/serial@1c28800 pinctrl-0 "<${tmp_phandle}>" + env delete tmp_phandle +fi + +if test "${param_uart3_pins}" = "b"; then + if test "${param_uart3_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc@1c00000/pinctrl@1c20800/uart3_pins_b phandle -+ fdt get value tmp_phandle2 /soc@1c00000/pinctrl@1c20800/uart3_pins_b_rts_cts phandle -+ fdt set /soc@1c00000/serial@1c28c00 pinctrl-names "default" "default" -+ fdt set /soc@1c00000/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>" -+ fdt set /soc@1c00000/serial@1c28c00 pinctrl-1 "<${tmp_phandle2}>" ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart3-ph-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart3-cts-rts-ph-pins phandle ++ fdt set /soc/serial@1c28c00 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@1c28c00 pinctrl-1 "<${tmp_phandle2}>" + env delete tmp_phandle1 tmp_phandle2 + else -+ fdt get value tmp_phandle /soc@1c00000/pinctrl@1c20800/uart3_pins_b phandle -+ fdt set /soc@1c00000/serial@1c28c00 pinctrl-0 "<${tmp_phandle}>" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/uart3-ph-pins phandle ++ fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle}>" + env delete tmp_phandle + fi +else + if test "${param_uart3_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc@1c00000/pinctrl@1c20800/uart3_pins_a_2 phandle -+ fdt get value tmp_phandle2 /soc@1c00000/pinctrl@1c20800/uart3_pins_a_rts_cts phandle -+ fdt set /soc@1c00000/serial@1c28c00 pinctrl-names "default" "default" -+ fdt set /soc@1c00000/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>" -+ fdt set /soc@1c00000/serial@1c28c00 pinctrl-1 "<${tmp_phandle2}>" ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart3-pg-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart3-cts-rts-pg-pins phandle ++ fdt set /soc/serial@1c28c00 pinctrl-names "default" "default" ++ fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>" ++ fdt set /soc/serial@1c28c00 pinctrl-1 "<${tmp_phandle2}>" + env delete tmp_phandle1 tmp_phandle2 + fi +fi + +if test "${param_uart4_pins}" = "b"; then -+ fdt get value tmp_phandle /soc@1c00000/pinctrl@1c20800/uart4@1 phandle -+ fdt set /soc@1c00000/serial@1c29000 pinctrl-0 "<${tmp_phandle}>" ++ fdt get value tmp_phandle /soc/pinctrl@1c20800/uart4-pg-pins phandle ++ fdt set /soc/serial@1c29000 pinctrl-0 "<${tmp_phandle}>" + env delete tmp_phandle +fi diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-i2c1.dts b/arch/arm/boot/dts/overlay/sun7i-a20-i2c1.dts new file mode 100644 -index 0000000..d1146ee +index 0000000..c5f6e97 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-i2c1.dts @@ -0,0 +1,22 @@ @@ -2903,14 +2903,14 @@ index 0000000..d1146ee + target = <&i2c1>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins_a>; ++ pinctrl-0 = <&i2c1_pins>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-i2c2.dts b/arch/arm/boot/dts/overlay/sun7i-a20-i2c2.dts new file mode 100644 -index 0000000..e6b32de +index 0000000..fa93d1e --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-i2c2.dts @@ -0,0 +1,22 @@ @@ -2931,14 +2931,14 @@ index 0000000..e6b32de + target = <&i2c2>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&i2c2_pins_a>; ++ pinctrl-0 = <&i2c2_pins>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-i2c3.dts b/arch/arm/boot/dts/overlay/sun7i-a20-i2c3.dts new file mode 100644 -index 0000000..5273d06 +index 0000000..945795c --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-i2c3.dts @@ -0,0 +1,22 @@ @@ -2959,14 +2959,14 @@ index 0000000..5273d06 + target = <&i2c3>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&i2c3_pins_a>; ++ pinctrl-0 = <&i2c3_pins>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-i2c4.dts b/arch/arm/boot/dts/overlay/sun7i-a20-i2c4.dts new file mode 100644 -index 0000000..113a220 +index 0000000..4fcf08c --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-i2c4.dts @@ -0,0 +1,32 @@ @@ -2997,7 +2997,7 @@ index 0000000..113a220 + target = <&i2c4>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&i2c4_pins_a>; ++ pinctrl-0 = <&i2c4_pins>; + status = "okay"; + }; + }; @@ -3066,7 +3066,7 @@ index 0000000..e6f0a22 +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-mmc2.dts b/arch/arm/boot/dts/overlay/sun7i-a20-mmc2.dts new file mode 100644 -index 0000000..f1ddbaa +index 0000000..ede92f2 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-mmc2.dts @@ -0,0 +1,18 @@ @@ -3080,7 +3080,7 @@ index 0000000..f1ddbaa + target = <&mmc2>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&mmc2_pins_a>; ++ pinctrl-0 = <&mmc2_pins>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 7 0 1>; /* PH0, active low */ @@ -3234,7 +3234,7 @@ index 0000000..fe3e2bd +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-pwm.dts b/arch/arm/boot/dts/overlay/sun7i-a20-pwm.dts new file mode 100644 -index 0000000..a0cc469 +index 0000000..b0cfe4d --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-pwm.dts @@ -0,0 +1,15 @@ @@ -3248,14 +3248,14 @@ index 0000000..a0cc469 + target = <&pwm>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&pwm0_pins_a>, <&pwm1_pins_a>; ++ pinctrl-0 = <&pwm0_pin>, <&pwm1_pin>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-spdif-out.dts b/arch/arm/boot/dts/overlay/sun7i-a20-spdif-out.dts new file mode 100644 -index 0000000..7983ad0 +index 0000000..11a0939 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-spdif-out.dts @@ -0,0 +1,38 @@ @@ -3269,7 +3269,7 @@ index 0000000..7983ad0 + target = <&spdif>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&spdif_tx_pins_a>; ++ pinctrl-0 = <&spdif_tx_pin>; + status = "okay"; + }; + }; @@ -3299,7 +3299,7 @@ index 0000000..7983ad0 +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-spi-add-cs1.dts b/arch/arm/boot/dts/overlay/sun7i-a20-spi-add-cs1.dts new file mode 100644 -index 0000000..2de39a2 +index 0000000..c0a4ba2 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-spi-add-cs1.dts @@ -0,0 +1,16 @@ @@ -3313,15 +3313,15 @@ index 0000000..2de39a2 + target = <&spi0>; + __overlay__ { + pinctrl-names = "default", "default", "default"; -+ pinctrl-0 = <&spi0_pins_a>; -+ pinctrl-1 = <&spi0_cs0_pins_a>; -+ pinctrl-2 = <&spi0_cs1_pins_a>; ++ pinctrl-0 = <&spi0_pi_pins>; ++ pinctrl-1 = <&spi0_cs0_pi_pin>; ++ pinctrl-2 = <&spi0_cs1_pi_pin>; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-spi-jedec-nor.dts b/arch/arm/boot/dts/overlay/sun7i-a20-spi-jedec-nor.dts new file mode 100644 -index 0000000..baf59df +index 0000000..b91097e --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-spi-jedec-nor.dts @@ -0,0 +1,57 @@ @@ -3345,7 +3345,7 @@ index 0000000..baf59df + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spiflash { ++ spiflash@0 { + compatible = "jedec,spi-nor"; + status = "disabled"; + reg = <0>; @@ -3359,7 +3359,7 @@ index 0000000..baf59df + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spiflash { ++ spiflash@0 { + compatible = "jedec,spi-nor"; + status = "disabled"; + reg = <0>; @@ -3373,7 +3373,7 @@ index 0000000..baf59df + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spiflash { ++ spiflash@0 { + compatible = "jedec,spi-nor"; + status = "disabled"; + reg = <0>; @@ -3384,7 +3384,7 @@ index 0000000..baf59df +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-spi-spidev.dts b/arch/arm/boot/dts/overlay/sun7i-a20-spi-spidev.dts new file mode 100644 -index 0000000..8d0f6ac +index 0000000..a3073b2 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-spi-spidev.dts @@ -0,0 +1,57 @@ @@ -3408,7 +3408,7 @@ index 0000000..8d0f6ac + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spidev { ++ spidev@0 { + compatible = "spidev"; + status = "disabled"; + reg = <0>; @@ -3422,7 +3422,7 @@ index 0000000..8d0f6ac + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spidev { ++ spidev@0 { + compatible = "spidev"; + status = "disabled"; + reg = <0>; @@ -3436,7 +3436,7 @@ index 0000000..8d0f6ac + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spidev { ++ spidev@0 { + compatible = "spidev"; + status = "disabled"; + reg = <0>; @@ -3447,7 +3447,7 @@ index 0000000..8d0f6ac +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-spi0.dts b/arch/arm/boot/dts/overlay/sun7i-a20-spi0.dts new file mode 100644 -index 0000000..0444262 +index 0000000..cad50d8 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-spi0.dts @@ -0,0 +1,23 @@ @@ -3469,14 +3469,14 @@ index 0000000..0444262 + __overlay__ { + status = "okay"; + pinctrl-names = "default", "default"; -+ pinctrl-0 = <&spi0_pins_a>; -+ pinctrl-1 = <&spi0_cs0_pins_a>; ++ pinctrl-0 = <&spi0_pi_pins>; ++ pinctrl-1 = <&spi0_cs0_pi_pin>; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-spi1.dts b/arch/arm/boot/dts/overlay/sun7i-a20-spi1.dts new file mode 100644 -index 0000000..3c3fcb8 +index 0000000..f0218eb --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-spi1.dts @@ -0,0 +1,22 @@ @@ -3498,13 +3498,13 @@ index 0000000..3c3fcb8 + __overlay__ { + status = "okay"; + pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_pins_a>, <&spi1_cs0_pins_a>; ++ pinctrl-0 = <&spi1_pi_pins>, <&spi1_cs0_pi_pin>; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-spi2.dts b/arch/arm/boot/dts/overlay/sun7i-a20-spi2.dts new file mode 100644 -index 0000000..b38e04c +index 0000000..effba42 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-spi2.dts @@ -0,0 +1,23 @@ @@ -3526,14 +3526,14 @@ index 0000000..b38e04c + __overlay__ { + status = "okay"; + pinctrl-names = "default", "default"; -+ pinctrl-0 = <&spi2_pins_a>; -+ pinctrl-1 = <&spi2_cs0_pins_a>; ++ pinctrl-0 = <&spi2_pb_pins>; ++ pinctrl-1 = <&spi2_pb_cs0_pin>; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-uart2.dts b/arch/arm/boot/dts/overlay/sun7i-a20-uart2.dts new file mode 100644 -index 0000000..b4f7230 +index 0000000..79d1dca --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-uart2.dts @@ -0,0 +1,32 @@ @@ -3571,7 +3571,7 @@ index 0000000..b4f7230 +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-uart3.dts b/arch/arm/boot/dts/overlay/sun7i-a20-uart3.dts new file mode 100644 -index 0000000..75e79ea +index 0000000..703acbc --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-uart3.dts @@ -0,0 +1,42 @@ @@ -3619,7 +3619,7 @@ index 0000000..75e79ea +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-uart4.dts b/arch/arm/boot/dts/overlay/sun7i-a20-uart4.dts new file mode 100644 -index 0000000..008cf83 +index 0000000..1918034 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-uart4.dts @@ -0,0 +1,22 @@ @@ -3640,14 +3640,14 @@ index 0000000..008cf83 + target = <&uart4>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&uart4_pins_a>; ++ pinctrl-0 = <&uart4_pg_pins>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-uart5.dts b/arch/arm/boot/dts/overlay/sun7i-a20-uart5.dts new file mode 100644 -index 0000000..3236710 +index 0000000..a1369ee --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-uart5.dts @@ -0,0 +1,22 @@ @@ -3668,14 +3668,14 @@ index 0000000..3236710 + target = <&uart5>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&uart5_pins_a>; ++ pinctrl-0 = <&uart5_pi_pins>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-uart6.dts b/arch/arm/boot/dts/overlay/sun7i-a20-uart6.dts new file mode 100644 -index 0000000..1243538 +index 0000000..fb9efe2 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-uart6.dts @@ -0,0 +1,22 @@ @@ -3696,14 +3696,14 @@ index 0000000..1243538 + target = <&uart6>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&uart6_pins_a>; ++ pinctrl-0 = <&uart6_pi_pins>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun7i-a20-uart7.dts b/arch/arm/boot/dts/overlay/sun7i-a20-uart7.dts new file mode 100644 -index 0000000..3087271 +index 0000000..bbdca3e --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun7i-a20-uart7.dts @@ -0,0 +1,22 @@ @@ -3724,7 +3724,7 @@ index 0000000..3087271 + target = <&uart7>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&uart7_pins_a>; ++ pinctrl-0 = <&uart7_pi_pins>; + status = "okay"; + }; + }; @@ -3789,7 +3789,7 @@ index 0000000..36dbc31 +}; diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-cir.dts b/arch/arm/boot/dts/overlay/sun8i-h3-cir.dts new file mode 100644 -index 0000000..9b62fd2 +index 0000000..bf4a0ea --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun8i-h3-cir.dts @@ -0,0 +1,15 @@ @@ -3803,14 +3803,14 @@ index 0000000..9b62fd2 + target = <&ir>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&ir_pins_a>; ++ pinctrl-0 = <&r_ir_rx_pin>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-fixup.scr-cmd b/arch/arm/boot/dts/overlay/sun8i-h3-fixup.scr-cmd new file mode 100644 -index 0000000..744889c +index 0000000..142b7e5 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun8i-h3-fixup.scr-cmd @@ -0,0 +1,110 @@ @@ -3899,8 +3899,8 @@ index 0000000..744889c +fi + +if test "${param_uart1_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart1 phandle -+ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart1_rts_cts phandle ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart1-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart1-rts-cts-pins phandle + fdt set /soc/serial@1c28400 pinctrl-names "default" "default" + fdt set /soc/serial@1c28400 pinctrl-0 "<${tmp_phandle1}>" + fdt set /soc/serial@1c28400 pinctrl-1 "<${tmp_phandle2}>" @@ -3908,8 +3908,8 @@ index 0000000..744889c +fi + +if test "${param_uart2_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart2 phandle -+ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart2_rts_cts phandle ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart2-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart2-rts-cts-pins phandle + fdt set /soc/serial@1c28800 pinctrl-names "default" "default" + fdt set /soc/serial@1c28800 pinctrl-0 "<${tmp_phandle1}>" + fdt set /soc/serial@1c28800 pinctrl-1 "<${tmp_phandle2}>" @@ -3917,8 +3917,8 @@ index 0000000..744889c +fi + +if test "${param_uart3_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart3 phandle -+ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart3_rts_cts phandle ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart3-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart3-rts-cts-pins phandle + fdt set /soc/serial@1c28c00 pinctrl-names "default" "default" + fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>" + fdt set /soc/serial@1c28c00 pinctrl-1 "<${tmp_phandle2}>" @@ -3926,7 +3926,7 @@ index 0000000..744889c +fi diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-i2c0.dts b/arch/arm/boot/dts/overlay/sun8i-h3-i2c0.dts new file mode 100644 -index 0000000..b457ac7 +index 0000000..a36ac86 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun8i-h3-i2c0.dts @@ -0,0 +1,20 @@ @@ -3952,7 +3952,7 @@ index 0000000..b457ac7 +}; diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-i2c1.dts b/arch/arm/boot/dts/overlay/sun8i-h3-i2c1.dts new file mode 100644 -index 0000000..fd0928a +index 0000000..258c86d --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun8i-h3-i2c1.dts @@ -0,0 +1,20 @@ @@ -3978,7 +3978,7 @@ index 0000000..fd0928a +}; diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-i2c2.dts b/arch/arm/boot/dts/overlay/sun8i-h3-i2c2.dts new file mode 100644 -index 0000000..25b75b7 +index 0000000..a1e3284 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun8i-h3-i2c2.dts @@ -0,0 +1,20 @@ @@ -4084,7 +4084,7 @@ index 0000000..ed3b8e6 +}; diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-spdif-out.dts b/arch/arm/boot/dts/overlay/sun8i-h3-spdif-out.dts new file mode 100644 -index 0000000..c7c0141 +index 0000000..35b2d56 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun8i-h3-spdif-out.dts @@ -0,0 +1,38 @@ @@ -4098,7 +4098,7 @@ index 0000000..c7c0141 + target = <&spdif>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&spdif_tx_pins_a>; ++ pinctrl-0 = <&spdif_tx_pin>; + status = "okay"; + }; + }; @@ -4175,7 +4175,7 @@ index 0000000..bd8e256 +}; diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-spi-jedec-nor.dts b/arch/arm/boot/dts/overlay/sun8i-h3-spi-jedec-nor.dts new file mode 100644 -index 0000000..ad22a71 +index 0000000..95fa5f2 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun8i-h3-spi-jedec-nor.dts @@ -0,0 +1,42 @@ @@ -4198,7 +4198,7 @@ index 0000000..ad22a71 + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spiflash { ++ spiflash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; @@ -4212,7 +4212,7 @@ index 0000000..ad22a71 + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spiflash { ++ spiflash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; @@ -4223,7 +4223,7 @@ index 0000000..ad22a71 +}; diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-spi-spidev.dts b/arch/arm/boot/dts/overlay/sun8i-h3-spi-spidev.dts new file mode 100644 -index 0000000..180979e +index 0000000..575c970 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun8i-h3-spi-spidev.dts @@ -0,0 +1,42 @@ @@ -4246,7 +4246,7 @@ index 0000000..180979e + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spidev { ++ spidev@0 { + compatible = "spidev"; + status = "disabled"; + reg = <0>; @@ -4260,7 +4260,7 @@ index 0000000..180979e + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spidev { ++ spidev@0 { + compatible = "spidev"; + status = "disabled"; + reg = <0>; @@ -4271,7 +4271,7 @@ index 0000000..180979e +}; diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-uart1.dts b/arch/arm/boot/dts/overlay/sun8i-h3-uart1.dts new file mode 100644 -index 0000000..8a4f7e4 +index 0000000..3c10d4d --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun8i-h3-uart1.dts @@ -0,0 +1,22 @@ @@ -4299,7 +4299,7 @@ index 0000000..8a4f7e4 +}; diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-uart2.dts b/arch/arm/boot/dts/overlay/sun8i-h3-uart2.dts new file mode 100644 -index 0000000..499a1b4 +index 0000000..f16e618 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun8i-h3-uart2.dts @@ -0,0 +1,22 @@ @@ -4327,7 +4327,7 @@ index 0000000..499a1b4 +}; diff --git a/arch/arm/boot/dts/overlay/sun8i-h3-uart3.dts b/arch/arm/boot/dts/overlay/sun8i-h3-uart3.dts new file mode 100644 -index 0000000..b5734c5 +index 0000000..b1aef57 --- /dev/null +++ b/arch/arm/boot/dts/overlay/sun8i-h3-uart3.dts @@ -0,0 +1,22 @@ @@ -4521,21 +4521,21 @@ index 0000000..f4ccb7f + }; +}; diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile -index 94de6044..1e85fd7c 100644 +index fa35163..89df4ff 100644 --- a/arch/arm64/boot/dts/allwinner/Makefile +++ b/arch/arm64/boot/dts/allwinner/Makefile -@@ -14,3 +14,4 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-zero-plus.dtb - dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-nanopi-neo2.dtb - dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-nanopi-neo-plus2.dtb +@@ -31,3 +31,5 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-lite2.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-one-plus.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6.dtb ++ +subdir-y := $(dts-dirs) overlay -\ No newline at end of file diff --git a/arch/arm64/boot/dts/allwinner/overlay/Makefile b/arch/arm64/boot/dts/allwinner/overlay/Makefile new file mode 100644 -index 0000000..5cad268 +index 0000000..9b6528e --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/Makefile -@@ -0,0 +1,51 @@ +@@ -0,0 +1,58 @@ +# SPDX-License-Identifier: GPL-2.0 +dtbo-$(CONFIG_ARCH_SUNXI) += \ + sun50i-a64-i2c0.dtbo \ @@ -4571,9 +4571,11 @@ index 0000000..5cad268 + sun50i-h6-i2c0.dtbo \ + sun50i-h6-i2c1.dtbo \ + sun50i-h6-i2c2.dtbo \ ++ sun50i-h6-ruart.dtbo \ + sun50i-h6-spi-add-cs1.dtbo \ + sun50i-h6-spi-jedec-nor.dtbo \ + sun50i-h6-spi-spidev.dtbo \ ++ sun50i-h6-spi-spidev1.dtbo \ + sun50i-h6-uart1.dtbo \ + sun50i-h6-uart2.dtbo \ + sun50i-h6-uart3.dtbo \ @@ -5052,7 +5054,7 @@ index 0000000..1ac7fbc + or long wires - please use external pull-up resistor instead diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-fixup.scr-cmd b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-fixup.scr-cmd new file mode 100644 -index 0000000..6e192b5 +index 0000000..36df83c --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-fixup.scr-cmd @@ -0,0 +1,95 @@ @@ -5074,12 +5076,12 @@ index 0000000..6e192b5 + test "${param_spinor_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c68000" + test "${param_spinor_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c69000" + fdt set /soc/${tmp_spi_path} status "okay" -+ fdt set /soc/${tmp_spi_path}/spiflash status "okay" ++ fdt set /soc/${tmp_spi_path}/spiflash@0 status "okay" + if test -n "${param_spinor_max_freq}"; then -+ fdt set /soc/${tmp_spi_path}/spiflash spi-max-frequency "<${param_spinor_max_freq}>" ++ fdt set /soc/${tmp_spi_path}/spiflash@0 spi-max-frequency "<${param_spinor_max_freq}>" + fi + if test "${param_spinor_spi_cs}" = "1"; then -+ fdt set /soc/${tmp_spi_path}/spiflash reg "<1>"; ++ fdt set /soc/${tmp_spi_path}/spiflash@0 reg "<1>"; + fi + env delete tmp_spi_path +fi @@ -5126,8 +5128,8 @@ index 0000000..6e192b5 +fi + +if test "${param_uart1_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart1 phandle -+ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart1_rts_cts_pins phandle ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart1-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart1-rts-cts-pins phandle + fdt set /soc/serial@1c28400 pinctrl-names "default" "default" + fdt set /soc/serial@1c28400 pinctrl-0 "<${tmp_phandle1}>" + fdt set /soc/serial@1c28400 pinctrl-1 "<${tmp_phandle2}>" @@ -5135,8 +5137,8 @@ index 0000000..6e192b5 +fi + +if test "${param_uart2_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart2 phandle -+ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart2_rts_cts_pins phandle ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart2-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart2-rts-cts-pins phandle + fdt set /soc/serial@1c28800 pinctrl-names "default" "default" + fdt set /soc/serial@1c28800 pinctrl-0 "<${tmp_phandle1}>" + fdt set /soc/serial@1c28800 pinctrl-1 "<${tmp_phandle2}>" @@ -5144,8 +5146,8 @@ index 0000000..6e192b5 +fi + +if test "${param_uart4_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart4 phandle -+ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart4_rts_cts phandle ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart4-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart4-rts-cts-pins phandle + fdt set /soc/serial@1c29000 pinctrl-names "default" "default" + fdt set /soc/serial@1c29000 pinctrl-0 "<${tmp_phandle1}>" + fdt set /soc/serial@1c29000 pinctrl-1 "<${tmp_phandle2}>" @@ -5301,7 +5303,7 @@ index 0000000..4432aac +}; diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-spi-jedec-nor.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-spi-jedec-nor.dts new file mode 100644 -index 0000000..d67a4f6 +index 0000000..31d73e5 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-spi-jedec-nor.dts @@ -0,0 +1,34 @@ @@ -5316,7 +5318,7 @@ index 0000000..d67a4f6 + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spiflash { ++ spiflash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; @@ -5330,7 +5332,7 @@ index 0000000..d67a4f6 + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spiflash { ++ spiflash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; @@ -5341,7 +5343,7 @@ index 0000000..d67a4f6 +}; diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-spi-spidev.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-spi-spidev.dts new file mode 100644 -index 0000000..fe8fb14 +index 0000000..70d90a2 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-spi-spidev.dts @@ -0,0 +1,42 @@ @@ -5364,7 +5366,7 @@ index 0000000..fe8fb14 + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spidev { ++ spidev@0 { + compatible = "spidev"; + status = "disabled"; + reg = <0>; @@ -5378,7 +5380,7 @@ index 0000000..fe8fb14 + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spidev { ++ spidev@0 { + compatible = "spidev"; + status = "disabled"; + reg = <0>; @@ -5437,12 +5439,12 @@ index 0000000..36475fd + fragment@1 { + target = <&pio>; + __overlay__ { -+ uart2_pins: uart2_pins { ++ uart2_pins: uart2-pins { + pins = "PB0", "PB1"; + function = "uart2"; + }; + -+ uart2_rts_cts_pins: uart2_rts_cts_pins { ++ uart2_rts_cts_pins: uart2-rts-cts-pins { + pins = "PB2", "PB3"; + function = "uart2"; + }; @@ -5480,7 +5482,7 @@ index 0000000..a103a75 + fragment@1 { + target = <&pio>; + __overlay__ { -+ uart3_pins: uart3_pins { ++ uart3_pins: uart3-pins { + pins = "PD0", "PD1"; + function = "uart3"; + }; @@ -5498,7 +5500,7 @@ index 0000000..a103a75 +}; diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-uart4.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-uart4.dts new file mode 100644 -index 0000000..f84333c +index 0000000..6e4702b --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-a64-uart4.dts @@ -0,0 +1,37 @@ @@ -5511,19 +5513,19 @@ index 0000000..f84333c + fragment@0 { + target-path = "/aliases"; + __overlay__ { -+ serial3 = "/soc/serial@1c29000"; ++ serial4 = "/soc/serial@1c29000"; + }; + }; + + fragment@1 { + target = <&pio>; + __overlay__ { -+ uart4_pins: uart4_pins { ++ uart4_pins: uart4-pins { + pins = "PD2", "PD3"; + function = "uart4"; + }; + -+ uart4_rts_cts_pins: uart4_rts_cts_pins { ++ uart4_rts_cts_pins: uart4-rts-cts-pins { + pins = "PD4", "PD5"; + function = "uart4"; + }; @@ -5599,7 +5601,7 @@ index 0000000..aaa66d5 +}; diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-cir.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-cir.dts new file mode 100644 -index 0000000..74569cb +index 0000000..90c264a --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-cir.dts @@ -0,0 +1,15 @@ @@ -5613,14 +5615,14 @@ index 0000000..74569cb + target = <&ir>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&ir_pins_a>; ++ pinctrl-0 = <&r_ir_rx_pin>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-fixup.scr-cmd b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-fixup.scr-cmd new file mode 100644 -index 0000000..744889c +index 0000000..f7b89ae --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-fixup.scr-cmd @@ -0,0 +1,110 @@ @@ -5642,12 +5644,12 @@ index 0000000..744889c + test "${param_spinor_spi_bus}" = "0" && setenv tmp_spi_path "spi@1c68000" + test "${param_spinor_spi_bus}" = "1" && setenv tmp_spi_path "spi@1c69000" + fdt set /soc/${tmp_spi_path} status "okay" -+ fdt set /soc/${tmp_spi_path}/spiflash status "okay" ++ fdt set /soc/${tmp_spi_path}/spiflash@0 status "okay" + if test -n "${param_spinor_max_freq}"; then -+ fdt set /soc/${tmp_spi_path}/spiflash spi-max-frequency "<${param_spinor_max_freq}>" ++ fdt set /soc/${tmp_spi_path}/spiflash@0 spi-max-frequency "<${param_spinor_max_freq}>" + fi + if test "${param_spinor_spi_cs}" = "1"; then -+ fdt set /soc/${tmp_spi_path}/spiflash reg "<1>" ++ fdt set /soc/${tmp_spi_path}/spiflash@0 reg "<1>" + fi + env delete tmp_spi_path +fi @@ -5709,8 +5711,8 @@ index 0000000..744889c +fi + +if test "${param_uart1_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart1 phandle -+ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart1_rts_cts phandle ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart1-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart1-rts-cts-pins phandle + fdt set /soc/serial@1c28400 pinctrl-names "default" "default" + fdt set /soc/serial@1c28400 pinctrl-0 "<${tmp_phandle1}>" + fdt set /soc/serial@1c28400 pinctrl-1 "<${tmp_phandle2}>" @@ -5718,8 +5720,8 @@ index 0000000..744889c +fi + +if test "${param_uart2_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart2 phandle -+ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart2_rts_cts phandle ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart2-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart2-rts-cts-pins phandle + fdt set /soc/serial@1c28800 pinctrl-names "default" "default" + fdt set /soc/serial@1c28800 pinctrl-0 "<${tmp_phandle1}>" + fdt set /soc/serial@1c28800 pinctrl-1 "<${tmp_phandle2}>" @@ -5727,8 +5729,8 @@ index 0000000..744889c +fi + +if test "${param_uart3_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart3 phandle -+ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart3_rts_cts phandle ++ fdt get value tmp_phandle1 /soc/pinctrl@1c20800/uart3-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@1c20800/uart3-rts-cts-pins phandle + fdt set /soc/serial@1c28c00 pinctrl-names "default" "default" + fdt set /soc/serial@1c28c00 pinctrl-0 "<${tmp_phandle1}>" + fdt set /soc/serial@1c28c00 pinctrl-1 "<${tmp_phandle2}>" @@ -5736,7 +5738,7 @@ index 0000000..744889c +fi diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c0.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c0.dts new file mode 100644 -index 0000000..55d249d +index 0000000..87fbd7e --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c0.dts @@ -0,0 +1,20 @@ @@ -5762,7 +5764,7 @@ index 0000000..55d249d +}; diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c1.dts new file mode 100644 -index 0000000..2528870 +index 0000000..6008b9a --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c1.dts @@ -0,0 +1,20 @@ @@ -5788,7 +5790,7 @@ index 0000000..2528870 +}; diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c2.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c2.dts new file mode 100644 -index 0000000..ff42f01 +index 0000000..2980dbf --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-i2c2.dts @@ -0,0 +1,20 @@ @@ -5894,7 +5896,7 @@ index 0000000..6d12e84 +}; diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spdif-out.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spdif-out.dts new file mode 100644 -index 0000000..2bb301f +index 0000000..65bc51b --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spdif-out.dts @@ -0,0 +1,38 @@ @@ -5908,7 +5910,7 @@ index 0000000..2bb301f + target = <&spdif>; + __overlay__ { + pinctrl-names = "default"; -+ pinctrl-0 = <&spdif_tx_pins_a>; ++ pinctrl-0 = <&spdif_tx_pin>; + status = "okay"; + }; + }; @@ -5985,7 +5987,7 @@ index 0000000..8e3eab2 +}; diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spi-jedec-nor.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spi-jedec-nor.dts new file mode 100644 -index 0000000..d4accd9 +index 0000000..5a45808 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spi-jedec-nor.dts @@ -0,0 +1,42 @@ @@ -6008,7 +6010,7 @@ index 0000000..d4accd9 + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spiflash { ++ spiflash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; @@ -6022,7 +6024,7 @@ index 0000000..d4accd9 + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spiflash { ++ spiflash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <1000000>; @@ -6033,7 +6035,7 @@ index 0000000..d4accd9 +}; diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spi-spidev.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spi-spidev.dts new file mode 100644 -index 0000000..d8a008d +index 0000000..9b5b0f2 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-spi-spidev.dts @@ -0,0 +1,42 @@ @@ -6056,7 +6058,7 @@ index 0000000..d8a008d + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spidev { ++ spidev@0 { + compatible = "spidev"; + status = "disabled"; + reg = <0>; @@ -6070,7 +6072,7 @@ index 0000000..d8a008d + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; -+ spidev { ++ spidev@0 { + compatible = "spidev"; + status = "disabled"; + reg = <0>; @@ -6081,7 +6083,7 @@ index 0000000..d8a008d +}; diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart1.dts new file mode 100644 -index 0000000..0ce76ef +index 0000000..92e3eb4 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart1.dts @@ -0,0 +1,22 @@ @@ -6109,7 +6111,7 @@ index 0000000..0ce76ef +}; diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart2.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart2.dts new file mode 100644 -index 0000000..88cc0cd +index 0000000..521a01d --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart2.dts @@ -0,0 +1,32 @@ @@ -6129,7 +6131,7 @@ index 0000000..88cc0cd + fragment@1 { + target = <&pio>; + __overlay__ { -+ uart2_rts_cts: uart2_rts_cts { ++ uart2_rts_cts: uart2-rts-cts-pins { + pins = "PA2", "PA3"; + function = "uart2"; + }; @@ -6147,7 +6149,7 @@ index 0000000..88cc0cd +}; diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart3.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart3.dts new file mode 100644 -index 0000000..3ad6cc9 +index 0000000..639e15d --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-uart3.dts @@ -0,0 +1,32 @@ @@ -6167,7 +6169,7 @@ index 0000000..3ad6cc9 + fragment@1 { + target = <&pio>; + __overlay__ { -+ uart3_rts_cts: uart3_rts_cts { ++ uart3_rts_cts: uart3-rts-cts-pins { + pins = "PA15", "PA16"; + function = "uart3"; + }; @@ -6350,363 +6352,9 @@ index 0000000..6e99626 + }; + }; +}; -diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c0.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c0.dts -index e69de29..7e7ee8c 100644 ---- /dev/null -+++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c0.dts -@@ -0,0 +1,20 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "allwinner,sun50i-h6"; -+ -+ fragment@0 { -+ target-path = "/aliases"; -+ __overlay__ { -+ i2c0 = "/soc/i2c@5002000"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2c0>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c1.dts -index e69de29..1117698 100644 ---- /dev/null -+++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c1.dts -@@ -0,0 +1,20 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "allwinner,sun50i-h6"; -+ -+ fragment@0 { -+ target-path = "/aliases"; -+ __overlay__ { -+ i2c1 = "/soc/i2c@5002400"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2c1>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c2.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c2.dts -index e69de29..b627529 100644 ---- /dev/null -+++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c2.dts -@@ -0,0 +1,20 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "allwinner,sun50i-h6"; -+ -+ fragment@0 { -+ target-path = "/aliases"; -+ __overlay__ { -+ i2c2 = "/soc/i2c@5002800"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2c2>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-add-cs1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-add-cs1.dts -new file mode 100644 -index 0000000..0fa060f ---- /dev/null -+++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-add-cs1.dts -@@ -0,0 +1,41 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "allwinner,sun50i-h6"; -+ -+ fragment@0 { -+ target = <&pio>; -+ __overlay__ { -+ spi0_cs1: spi0_cs1 { -+ pins = "PA10"; -+ function = "gpio_out"; -+ output-high; -+ }; -+ -+ spi1_cs1: spi1_cs1 { -+ pins = "PA21"; -+ function = "gpio_out"; -+ output-high; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi0>; -+ __overlay__ { -+ pinctrl-names = "default", "default"; -+ pinctrl-1 = <&spi0_cs1>; -+ cs-gpios = <0>, <&pio 0 10 0>; /* PA10 */ -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi1>; -+ __overlay__ { -+ pinctrl-names = "default", "default"; -+ pinctrl-1 = <&spi1_cs1>; -+ cs-gpios = <0>, <&pio 0 21 0>; /* PA21 */ -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-jedec-nor.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-jedec-nor.dts -new file mode 100644 -index 0000000..3a2be38 ---- /dev/null -+++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-jedec-nor.dts -@@ -0,0 +1,42 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "allwinner,sun50i-h6"; -+ -+ fragment@0 { -+ target-path = "/aliases"; -+ __overlay__ { -+ spi0 = "/soc/spi@5010000"; -+ spi1 = "/soc/spi@5011000"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi0>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spiflash { -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <1000000>; -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spiflash { -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <1000000>; -+ status = "disabled"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-spidev.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-spidev.dts -new file mode 100644 -index 0000000..fd807d6 ---- /dev/null -+++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-spidev.dts -@@ -0,0 +1,42 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "allwinner,sun50i-h6"; -+ -+ fragment@0 { -+ target-path = "/aliases"; -+ __overlay__ { -+ spi0 = "/soc/spi@5010000"; -+ spi1 = "/soc/spi@5011000"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&spi0>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spidev { -+ compatible = "spidev"; -+ status = "disabled"; -+ reg = <0>; -+ spi-max-frequency = <1000000>; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spidev { -+ compatible = "spidev"; -+ status = "disabled"; -+ reg = <0>; -+ spi-max-frequency = <1000000>; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart1.dts -index e69de29..44aa94e 100644 ---- /dev/null -+++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart1.dts -@@ -0,0 +1,22 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "allwinner,sun50i-h6"; -+ -+ fragment@0 { -+ target-path = "/aliases"; -+ __overlay__ { -+ serial1 = "/soc/serial@5000400"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&uart1>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1_pins>; -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart2.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart2.dts -index e69de29..7a1860e 100644 ---- /dev/null -+++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart2.dts -@@ -0,0 +1,32 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "allwinner,sun50i-h6"; -+ -+ fragment@0 { -+ target-path = "/aliases"; -+ __overlay__ { -+ serial2 = "/soc/serial@5000800"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&pio>; -+ __overlay__ { -+ uart2_rts_cts: uart2_rts_cts { -+ pins = "PD21", "PD22"; -+ function = "uart2"; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&uart2>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart2_pins>; -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart3.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart3.dts -index e69de29..38a59ac 100644 ---- /dev/null -+++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart3.dts -@@ -0,0 +1,32 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "allwinner,sun50i-h6"; -+ -+ fragment@0 { -+ target-path = "/aliases"; -+ __overlay__ { -+ serial3 = "/soc/serial@5000c00"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&pio>; -+ __overlay__ { -+ uart3_rts_cts: uart3_rts_cts { -+ pins = "PD25", "PD26"; -+ function = "uart3"; -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&uart3>; -+ __overlay__ { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart3_pins>; -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-w1-gpio.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-w1-gpio.dts -new file mode 100644 -index 0000000..a4cd713 ---- /dev/null -+++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-w1-gpio.dts -@@ -0,0 +1,29 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "allwinner,sun50i-h6"; -+ -+ fragment@0 { -+ target = <&pio>; -+ __overlay__ { -+ w1_pins: w1_pins { -+ pins = "PC9"; -+ function = "gpio_in"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target-path = "/"; -+ __overlay__ { -+ onewire@0 { -+ compatible = "w1-gpio"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&w1_pins>; -+ gpios = <&pio 2 9 0>; /* PC9 */ -+ status = "okay"; -+ }; -+ }; -+ }; -+}; diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-fixup.scr-cmd b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-fixup.scr-cmd new file mode 100644 -index 0000000..fba1c4f +index 0000000..5f00458 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-fixup.scr-cmd @@ -0,0 +1,110 @@ @@ -6728,12 +6376,12 @@ index 0000000..fba1c4f + test "${param_spinor_spi_bus}" = "0" && setenv tmp_spi_path "spi@5010000" + test "${param_spinor_spi_bus}" = "1" && setenv tmp_spi_path "spi@5011000" + fdt set /soc/${tmp_spi_path} status "okay" -+ fdt set /soc/${tmp_spi_path}/spiflash status "okay" ++ fdt set /soc/${tmp_spi_path}/spiflash@0 status "okay" + if test -n "${param_spinor_max_freq}"; then -+ fdt set /soc/${tmp_spi_path}/spiflash spi-max-frequency "<${param_spinor_max_freq}>" ++ fdt set /soc/${tmp_spi_path}/spiflash@0 spi-max-frequency "<${param_spinor_max_freq}>" + fi + if test "${param_spinor_spi_cs}" = "1"; then -+ fdt set /soc/${tmp_spi_path}/spiflash reg "<1>" ++ fdt set /soc/${tmp_spi_path}/spiflash@0 reg "<1>" + fi + env delete tmp_spi_path +fi @@ -6795,8 +6443,8 @@ index 0000000..fba1c4f +fi + +if test "${param_uart1_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc/pinctrl@300b000/uart1 phandle -+ fdt get value tmp_phandle2 /soc/pinctrl@300b000/uart1_rts_cts phandle ++ fdt get value tmp_phandle1 /soc/pinctrl@300b000/uart1-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@300b000/uart1-rts-cts-pins phandle + fdt set /soc/serial@5000400 pinctrl-names "default" "default" + fdt set /soc/serial@5000400 pinctrl-0 "<${tmp_phandle1}>" + fdt set /soc/serial@5000400 pinctrl-1 "<${tmp_phandle2}>" @@ -6804,8 +6452,8 @@ index 0000000..fba1c4f +fi + +if test "${param_uart2_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc/pinctrl@300b000/uart2 phandle -+ fdt get value tmp_phandle2 /soc/pinctrl@300b000/uart2_rts_cts phandle ++ fdt get value tmp_phandle1 /soc/pinctrl@300b000/uart2-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@300b000/uart2-rts-cts-pins phandle + fdt set /soc/serial@5000800 pinctrl-names "default" "default" + fdt set /soc/serial@5000800 pinctrl-0 "<${tmp_phandle1}>" + fdt set /soc/serial@5000800 pinctrl-1 "<${tmp_phandle2}>" @@ -6813,13 +6461,428 @@ index 0000000..fba1c4f +fi + +if test "${param_uart3_rtscts}" = "1"; then -+ fdt get value tmp_phandle1 /soc/pinctrl@300b000/uart3 phandle -+ fdt get value tmp_phandle2 /soc/pinctrl@300b000/uart3_rts_cts phandle ++ fdt get value tmp_phandle1 /soc/pinctrl@300b000/uart3-pins phandle ++ fdt get value tmp_phandle2 /soc/pinctrl@300b000/uart3-rts-cts-pins phandle + fdt set /soc/serial@5000c00 pinctrl-names "default" "default" + fdt set /soc/serial@5000c00 pinctrl-0 "<${tmp_phandle1}>" + fdt set /soc/serial@5000c00 pinctrl-1 "<${tmp_phandle2}>" + env delete tmp_phandle1 tmp_phandle2 +fi +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c0.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c0.dts +new file mode 100644 +index 0000000..7e7ee8c +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c0.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c0 = "/soc/i2c@5002000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c0>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c1.dts +new file mode 100644 +index 0000000..1117698 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c1.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c1 = "/soc/i2c@5002400"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c1>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c2.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c2.dts +new file mode 100644 +index 0000000..b627529 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-i2c2.dts +@@ -0,0 +1,20 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ i2c2 = "/soc/i2c@5002800"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2c2>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-ruart.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-ruart.dts +new file mode 100644 +index 0000000..6430cb0 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-ruart.dts +@@ -0,0 +1,13 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target = <&r_uart>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-add-cs1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-add-cs1.dts +new file mode 100644 +index 0000000..0fa060f +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-add-cs1.dts +@@ -0,0 +1,41 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ spi0_cs1: spi0_cs1 { ++ pins = "PA10"; ++ function = "gpio_out"; ++ output-high; ++ }; ++ ++ spi1_cs1: spi1_cs1 { ++ pins = "PA21"; ++ function = "gpio_out"; ++ output-high; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ pinctrl-names = "default", "default"; ++ pinctrl-1 = <&spi0_cs1>; ++ cs-gpios = <0>, <&pio 0 10 0>; /* PA10 */ ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ pinctrl-names = "default", "default"; ++ pinctrl-1 = <&spi1_cs1>; ++ cs-gpios = <0>, <&pio 0 21 0>; /* PA21 */ ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-jedec-nor.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-jedec-nor.dts +new file mode 100644 +index 0000000..4f81dbb +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-jedec-nor.dts +@@ -0,0 +1,42 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc/spi@5010000"; ++ spi1 = "/soc/spi@5011000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spiflash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-spidev.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-spidev.dts +new file mode 100644 +index 0000000..bac3adc +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-spidev.dts +@@ -0,0 +1,42 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ spi0 = "/soc/spi@5010000"; ++ spi1 = "/soc/spi@5011000"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&spi0>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ status = "disabled"; ++ reg = <0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-spidev1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-spidev1.dts +new file mode 100644 +index 0000000..e194484 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-spi-spidev1.dts +@@ -0,0 +1,30 @@ ++// Enable the spidev interface ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun8i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ /* Path to the SPI controller nodes */ ++ spi1 = "/soc/spi@5011000"; ++ }; ++ }; ++ fragment@1 { ++ target = <&spi1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi1_pins>; ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spidev@0 { ++ compatible = "spidev"; ++ reg = <0x0>; ++ spi-max-frequency = <1000000>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart1.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart1.dts +new file mode 100644 +index 0000000..44aa94e +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart1.dts +@@ -0,0 +1,22 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial1 = "/soc/serial@5000400"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&uart1>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart2.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart2.dts +new file mode 100644 +index 0000000..7a1860e +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart2.dts +@@ -0,0 +1,32 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial2 = "/soc/serial@5000800"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart2_rts_cts: uart2-rts-cts-pins { ++ pins = "PD21", "PD22"; ++ function = "uart2"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart2>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart3.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart3.dts +new file mode 100644 +index 0000000..770219a +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-uart3.dts +@@ -0,0 +1,32 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target-path = "/aliases"; ++ __overlay__ { ++ serial3 = "/soc/serial@5000c00"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&pio>; ++ __overlay__ { ++ uart3_rts_cts: uart3-rts-cts-pins { ++ pins = "PD25", "PD26"; ++ function = "uart3"; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&uart3>; ++ __overlay__ { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart3_pins>; ++ status = "okay"; ++ }; ++ }; ++}; +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-w1-gpio.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-w1-gpio.dts +new file mode 100644 +index 0000000..3043c87 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h6-w1-gpio.dts +@@ -0,0 +1,29 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "allwinner,sun50i-h6"; ++ ++ fragment@0 { ++ target = <&pio>; ++ __overlay__ { ++ w1_pins: w1_pins { ++ pins = "PC9"; ++ function = "gpio_in"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target-path = "/"; ++ __overlay__ { ++ onewire@0 { ++ compatible = "w1-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&w1_pins>; ++ gpios = <&pio 2 9 0>; /* PC9 */ ++ status = "okay"; ++ }; ++ }; ++ }; ++}; diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 26e6af4..65b9435 100644 --- a/scripts/Makefile.lib @@ -6834,3 +6897,4 @@ index 26e6af4..65b9435 100644 # Add subdir path extra-y := $(addprefix $(obj)/,$(extra-y)) + diff --git a/patch/kernel/sunxi-legacy/general-sunxi-rtc-clocksource.patch b/patch/kernel/sunxi-legacy/general-sunxi-rtc-clocksource.patch.disabled similarity index 100% rename from patch/kernel/sunxi-legacy/general-sunxi-rtc-clocksource.patch rename to patch/kernel/sunxi-legacy/general-sunxi-rtc-clocksource.patch.disabled diff --git a/patch/kernel/sunxi-legacy/general_spi_bug_low_on_sck.patch b/patch/kernel/sunxi-legacy/general_spi_bug_low_on_sck.patch new file mode 100644 index 000000000..793813721 --- /dev/null +++ b/patch/kernel/sunxi-legacy/general_spi_bug_low_on_sck.patch @@ -0,0 +1,27 @@ +Index: drivers/spi/spi-sun4i.c +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- a/drivers/spi/spi-sun4i.c (date 1581011681000) ++++ b/drivers/spi/spi-sun4i.c (date 1581070363000) +@@ -389,6 +389,7 @@ + struct spi_master *master = dev_get_drvdata(dev); + struct sun4i_spi *sspi = spi_master_get_devdata(master); + int ret; ++ u32 reg; + + ret = clk_prepare_enable(sspi->hclk); + if (ret) { +@@ -401,9 +402,10 @@ + dev_err(dev, "Couldn't enable module clock\n"); + goto err; + } ++ reg = sun4i_spi_read(sspi, SUN4I_CTL_REG); + + sun4i_spi_write(sspi, SUN4I_CTL_REG, +- SUN4I_CTL_ENABLE | SUN4I_CTL_MASTER | SUN4I_CTL_TP); ++ reg | SUN4I_CTL_ENABLE | SUN4I_CTL_MASTER | SUN4I_CTL_TP); + + return 0; + diff --git a/patch/kernel/sunxi-legacy/mmc-sunxi-Fix-eMMC-usage-on-H5-boards.patch b/patch/kernel/sunxi-legacy/mmc-sunxi-Fix-eMMC-usage-on-H5-boards.patch deleted file mode 100644 index 15ff1b0f7..000000000 --- a/patch/kernel/sunxi-legacy/mmc-sunxi-Fix-eMMC-usage-on-H5-boards.patch +++ /dev/null @@ -1,59 +0,0 @@ -Subject: [PATCH v2 1/3] mmc: sunxi: Disable HS-DDR mode for H5 eMMC controller by default - -Some H5 boards seem to not have proper trace lengths for eMMC to be able -to use the default setting for the delay chains under HS-DDR mode. These -include the Bananapi M2+ H5 and NanoPi NEO Core2. However the Libre -Computer ALL-H3-CC-H5 works just fine. - -For the H5 (at least for now), default to not enabling HS-DDR modes in -the driver, and expect the device tree to signal HS-DDR capability on -boards that work. ---- - drivers/mmc/host/sunxi-mmc.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c -index 279e326e397e..7415af8c8ff6 100644 ---- a/drivers/mmc/host/sunxi-mmc.c -+++ b/drivers/mmc/host/sunxi-mmc.c -@@ -1399,7 +1399,16 @@ static int sunxi_mmc_probe(struct platform_device *pdev) - mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | - MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ; - -- if (host->cfg->clk_delays || host->use_new_timings) -+ /* -+ * Some H5 devices do not have signal traces precise enough to -+ * use HS DDR mode for their eMMC chips. -+ * -+ * We still enable HS DDR modes for all the other controller -+ * variants that support them. -+ */ -+ if ((host->cfg->clk_delays || host->use_new_timings) && -+ !of_device_is_compatible(pdev->dev.of_node, -+ "allwinner,sun50i-h5-emmc")) - mmc->caps |= MMC_CAP_1_8V_DDR | MMC_CAP_3_3V_DDR; - - ret = mmc_of_parse(mmc); - -Subject: [PATCH v2 3/3] arm64: dts: allwinner: h5: libretech-all-h3-cc: Mark eMMC HS-DDR 3.3V capable - -The Libre Computer ALL-H3-CC H5 is one of the few boards that can have -its eMMC run at HS-DDR speed mode. Mark it as such. - -Signed-off-by: Chen-Yu Tsai ---- - .../boot/dts/allwinner/sun50i-h5-libretech-all-h3-cc.dts | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-libretech-all-h3-cc.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-libretech-all-h3-cc.dts -index 95e113ce8699..d68bdfea2271 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h5-libretech-all-h3-cc.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-libretech-all-h3-cc.dts -@@ -12,3 +12,7 @@ - model = "Libre Computer Board ALL-H3-CC H5"; - compatible = "libretech,all-h3-cc-h5", "allwinner,sun50i-h5"; - }; -+ -+&mmc2 { -+ mmc-ddr-3_3v; -+}; diff --git a/patch/kernel/sunxi-legacy/nand-disable-badblock-check-for-migration.patch b/patch/kernel/sunxi-legacy/nand-disable-badblock-check-for-migration.patch index d60d42d08..0a368cfa9 100644 --- a/patch/kernel/sunxi-legacy/nand-disable-badblock-check-for-migration.patch +++ b/patch/kernel/sunxi-legacy/nand-disable-badblock-check-for-migration.patch @@ -1,32 +1,34 @@ diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c -index 77533f7..8b3b184 100644 +index 71050a0..5f36704 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c -@@ -532,11 +532,7 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int allowbbt) - { +@@ -460,10 +460,7 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int allowbbt) struct nand_chip *chip = mtd_to_nand(mtd); -- if (!chip->bbt) -- return chip->block_bad(mtd, ofs); + /* Return info from the table */ +- if (chip->bbt) +- return nand_isbad_bbt(chip, ofs, allowbbt); - -- /* Return info from the table */ -- return nand_isbad_bbt(mtd, ofs, allowbbt); +- return nand_isbad_bbm(chip, ofs); + return 0; } /** -@@ -3030,16 +3026,7 @@ static int nand_block_isbad(struct mtd_info *mtd, loff_t offs) +@@ -4283,19 +4283,7 @@ static int nand_block_isbad(struct mtd_info *mtd, loff_t offs) int chipnr = (int)(offs >> chip->chip_shift); int ret; - /* Select the NAND device */ -- nand_get_device(mtd, FL_READING); -- chip->select_chip(mtd, chipnr); +- ret = nand_get_device(chip); +- if (ret) +- return ret; - -- ret = nand_block_checkbad(mtd, offs, 0); +- nand_select_target(chip, chipnr); - -- chip->select_chip(mtd, -1); -- nand_release_device(mtd); +- ret = nand_block_checkbad(chip, offs, 0); +- +- nand_deselect_target(chip); +- nand_release_device(chip); - - return ret; + return 0; diff --git a/patch/kernel/sunxi-legacy/npi-a64-only-audio-usb.patch b/patch/kernel/sunxi-legacy/npi-a64-only-audio-usb.patch new file mode 100644 index 000000000..5d5beca50 --- /dev/null +++ b/patch/kernel/sunxi-legacy/npi-a64-only-audio-usb.patch @@ -0,0 +1,41 @@ +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts +index ec0296a85..ad2c64d51 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts +@@ -293,3 +293,36 @@ &uart0 { + &usbphy { + status = "okay"; + }; ++ ++&sound { ++status = "okay"; ++}; ++ ++&sound_hdmi { ++status = "okay"; ++}; ++ ++&usb_otg { ++dr_mode = "host"; ++status = "okay"; ++}; ++ ++&i2s1 { ++status = "okay"; ++}; ++ ++&i2s2 { ++status = "okay"; ++}; ++ ++&dai { ++status = "okay"; ++}; ++ ++&codec { ++status = "okay"; ++}; ++ ++&codec_analog { ++status = "okay"; ++}; diff --git a/patch/kernel/sunxi-current/orangepi-win-fixes.patch b/patch/kernel/sunxi-legacy/orangepi-win-fixes.patch similarity index 100% rename from patch/kernel/sunxi-current/orangepi-win-fixes.patch rename to patch/kernel/sunxi-legacy/orangepi-win-fixes.patch diff --git a/patch/kernel/sunxi-legacy/p-board-h6-add-THS.patch.disabled b/patch/kernel/sunxi-legacy/p-board-h6-add-THS.patch.disabled deleted file mode 100644 index 1aec82190..000000000 --- a/patch/kernel/sunxi-legacy/p-board-h6-add-THS.patch.disabled +++ /dev/null @@ -1,818 +0,0 @@ -From 1c44b2c7ee26d4a3b6d6710181203bf3c8491a79 Mon Sep 17 00:00:00 2001 -From: Chen-Yu Tsai -Date: Wed, 20 Jun 2018 15:13:41 +0800 -Subject: [PATCH 08/45] arm64: dts: allwinner: h6: Add LED device nodes for - Pine H64 - -The Pine H64 has 3 GPIO-controlled LEDs, which are labeled "heartbeat", -"link", and "status". - -Add device nodes for them. - -Acked-by: Maxime Ripard -Signed-off-by: Chen-Yu Tsai ---- - .../boot/dts/allwinner/sun50i-h6-pine-h64.dts | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts -index b6f2d6b2ecae..2e97173c9204 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts -@@ -20,6 +20,25 @@ - chosen { - stdout-path = "serial0:115200n8"; - }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ -+ heartbeat { -+ label = "pine-h64:green:heartbeat"; -+ gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>; /* PL4 */ -+ }; -+ -+ link { -+ label = "pine-h64:white:link"; -+ gpios = <&r_pio 0 3 GPIO_ACTIVE_HIGH>; /* PL3 */ -+ }; -+ -+ status { -+ label = "pine-h64:blue:status"; -+ gpios = <&r_pio 0 7 GPIO_ACTIVE_HIGH>; /* PL7 */ -+ }; -+ }; - }; - - &r_i2c { --- -2.17.1 - - -From 6bfc6aab9a9cd82578a7e782c83d04f4cf7fe6c4 Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Fri, 27 Jul 2018 16:22:01 +0800 -Subject: [PATCH 37/45] nvmem: sunxi-sid: add support for H6 SID - -The SID controller in Allwinner H6 SoC is similar to the one in -Allwinner A64, except the size of the eFUSE is enlarged to 512 bytes -(4Kbit). - -Add support for it. - -Signed-off-by: Icenowy Zheng ---- - .../devicetree/bindings/nvmem/allwinner,sunxi-sid.txt | 1 + - drivers/nvmem/sunxi_sid.c | 6 ++++++ - 2 files changed, 7 insertions(+) - -diff --git a/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt b/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt -index e319fe5e205a..332de580e321 100644 ---- a/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt -+++ b/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt -@@ -7,6 +7,7 @@ Required properties: - "allwinner,sun8i-a83t-sid" - "allwinner,sun8i-h3-sid" - "allwinner,sun50i-a64-sid" -+ "allwinner,sun50i-h6-sid" - - - reg: Should contain registers location and length - -diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c -index d020f89248fd..fa58c3574afa 100644 ---- a/drivers/nvmem/sunxi_sid.c -+++ b/drivers/nvmem/sunxi_sid.c -@@ -232,11 +232,17 @@ static const struct sunxi_sid_cfg sun50i_a64_cfg = { - .size = 0x100, - }; - -+static const struct sunxi_sid_cfg sun50i_h6_cfg = { -+ .value_offset = 0x200, -+ .size = 0x200, -+}; -+ - static const struct of_device_id sunxi_sid_of_match[] = { - { .compatible = "allwinner,sun4i-a10-sid", .data = &sun4i_a10_cfg }, - { .compatible = "allwinner,sun7i-a20-sid", .data = &sun7i_a20_cfg }, - { .compatible = "allwinner,sun8i-h3-sid", .data = &sun8i_h3_cfg }, - { .compatible = "allwinner,sun50i-a64-sid", .data = &sun50i_a64_cfg }, -+ { .compatible = "allwinner,sun50i-h6-sid", .data = &sun50i_h6_cfg }, - {/* sentinel */}, - }; - MODULE_DEVICE_TABLE(of, sunxi_sid_of_match); --- -2.17.1 - - -From de62065cf1b55e48049c44076500a32eac08fe2f Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Fri, 27 Jul 2018 16:24:18 +0800 -Subject: [PATCH 38/45] arm64: allwinner: dts: h6: add H6 SID device tree node - -The Allwinner H6 SoC has a SID like previous Allwinner SoCs. - -Add a device tree node for it. - -Signed-off-by: Icenowy Zheng ---- - arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -index 1a8086476514..8e3c47c7c797 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -@@ -174,6 +174,11 @@ - #interrupt-cells = <3>; - }; - -+ sid: efuse@3006000 { -+ compatible = "allwinner,sun50i-h6-sid"; -+ reg = <0x03006000 0x1000>; -+ }; -+ - pio: pinctrl@300b000 { - compatible = "allwinner,sun50i-h6-pinctrl"; - reg = <0x0300b000 0x400>; --- -2.17.1 - - -From 8cdaf449f2936b608862b0a0175dd05fb52233b1 Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Fri, 27 Jul 2018 17:34:35 +0800 -Subject: [PATCH 39/45] nvmem: sunxi-sid: fix endian - -The data in the SID is stored as little endian. However, when accessing -the SID via sunxi-sid driver, it converts little endian to big endian at -4 byte border. This makes addressing sub-4-byte items in the SID wrong. - -Fix the endian by read out the SID 4-byte words as little endian, not -big endian. - -Signed-off-by: Icenowy Zheng ---- - drivers/nvmem/sunxi_sid.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c -index fa58c3574afa..af30d62b1426 100644 ---- a/drivers/nvmem/sunxi_sid.c -+++ b/drivers/nvmem/sunxi_sid.c -@@ -63,7 +63,7 @@ static u8 sunxi_sid_read_byte(const struct sunxi_sid *sid, - { - u32 sid_key; - -- sid_key = ioread32be(sid->base + round_down(offset, 4)); -+ sid_key = readl(sid->base + round_down(offset, 4)); - sid_key >>= (offset % 4) * 8; - - return sid_key; /* Only return the last byte */ --- -2.17.1 - - -From e7690d51c51dd6c97475bef2b207244d3a5f91b3 Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Fri, 27 Jul 2018 16:18:35 +0800 -Subject: [PATCH 40/45] sun50i-h6-ths - -Signed-off-by: Icenowy Zheng ---- - drivers/thermal/Kconfig | 11 + - drivers/thermal/Makefile | 1 + - drivers/thermal/sun50i_h6_ths.c | 365 ++++++++++++++++++++++++++++++++ - 3 files changed, 377 insertions(+) - create mode 100644 drivers/thermal/sun50i_h6_ths.c - -diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig -index 82979880f985..1b302248633a 100644 ---- a/drivers/thermal/Kconfig -+++ b/drivers/thermal/Kconfig -@@ -415,6 +415,17 @@ config MTK_THERMAL - Enable this option if you want to have support for thermal management - controller present in Mediatek SoCs - -+config SUN50I_H6_THS -+ tristate "Thermal sensor driver for Allwinner H6" -+ depends on ARCH_SUNXI || COMPILE_TEST -+ depends on HAS_IOMEM -+ depends on NVMEM -+ depends on OF -+ depends on RESET_CONTROLLER -+ help -+ Enable this option if you want to have support for thermal reporting -+ on Allwinner H6. -+ - menu "Broadcom thermal drivers" - depends on ARCH_BCM || ARCH_BRCMSTB || ARCH_BCM2835 || COMPILE_TEST - source "drivers/thermal/broadcom/Kconfig" -diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile -index 610344eb3e03..bdc5ba49f170 100644 ---- a/drivers/thermal/Makefile -+++ b/drivers/thermal/Makefile -@@ -58,6 +58,7 @@ obj-$(CONFIG_QCOM_TSENS) += qcom/ - obj-y += tegra/ - obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o - obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o -+obj-$(CONFIG_SUN50I_H6_THS) += sun50i_h6_ths.o - obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o - obj-$(CONFIG_ZX2967_THERMAL) += zx2967_thermal.o - obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o -diff --git a/drivers/thermal/sun50i_h6_ths.c b/drivers/thermal/sun50i_h6_ths.c -new file mode 100644 -index 000000000000..ad3c5f3e47c7 ---- /dev/null -+++ b/drivers/thermal/sun50i_h6_ths.c -@@ -0,0 +1,365 @@ -+/* -+ * Thermal sensor driver for Allwinner H6 -+ * -+ * Copyright (C) 2018 Icenowy Zheng -+ * -+ * Based on the work of Ondřej Jirman -+ * Based on the work of Josef Gajdusek -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define THS_H6_MAX_SENSOR_NUM 4 -+ -+#define THS_H6_CTRL0 0x00 -+#define THS_H6_CTRL2 0x04 -+#define THS_H6_PER 0x08 -+#define THS_H6_DATA_INT_CTRL 0x10 -+#define THS_H6_DATA_INT_STAT 0x20 -+#define THS_H6_FILTER 0x30 -+#define THS_H6_CDATA(n) (0xa0 + 4 * (n)) -+#define THS_H6_DATA(n) (0xc0 + 4 * (n)) -+ -+#define THS_H6_CTRL0_SENSOR_ACQ0(x) ((x) << 16) -+#define THS_H6_CTRL2_SENSE_EN(n) BIT(0 + (n)) -+#define THS_H6_PER_THERMAL_PER(x) ((x) << 12) -+#define THS_H6_INT_CTRL_DATA_IRQ_EN(n) BIT(0 + (n)) -+#define THS_H6_STAT_DATA_IRQ_STS(n) BIT(0 + (n)) -+#define THS_H6_FILTER_TYPE(x) ((x) << 0) -+#define THS_H6_FILTER_EN BIT(2) -+ -+#define THS_H6_CLK_IN 240000000 /* Hz */ -+#define THS_H6_DATA_PERIOD 10 /* ms */ -+ -+#define THS_H6_FILTER_TYPE_VALUE 2 /* average over 2^(n+1) samples */ -+#define THS_H6_FILTER_DIV (1 << (THS_H6_FILTER_TYPE_VALUE + 1)) -+#define THS_H6_INT_CTRL_THERMAL_PER_VALUE \ -+ (THS_H6_DATA_PERIOD * (THS_H6_CLK_IN / 1000) / THS_H6_FILTER_DIV / 4096 - 1) -+#define THS_H6_CTRL0_SENSOR_ACQ0_VALUE 0x1df /* 20us */ -+#define THS_H6_CTRL0_UNK 0x0000002f -+ -+#define THS_H6_CAL_FT_TEMP_MASK 0x0fff -+#define THS_H6_CAL_FT_TEMP_DEVIATION_EN 0x3000 -+#define THS_H6_CAL_DEFAULT 0x800 -+#define THS_H6_CAL_VAL_MASK 0xfff -+ -+struct sun50i_h6_ths_data; -+ -+struct sun50i_h6_ths_sensor { -+ struct sun50i_h6_ths_data *data; -+ int id; -+ struct thermal_zone_device *tzd; -+ u32 val; -+}; -+ -+struct sun50i_h6_ths_cfg { -+ int sensor_num; -+ int (*calc_temp)(u32 val); -+}; -+ -+struct sun50i_h6_ths_data { -+ struct reset_control *reset; -+ struct clk *busclk; -+ void __iomem *regs; -+ const struct sun50i_h6_ths_cfg *cfg; -+ struct nvmem_cell *calcell; -+ struct sun50i_h6_ths_sensor sensors[THS_H6_MAX_SENSOR_NUM]; -+}; -+ -+static int sun50i_h6_ths_calc_temp(u32 val) -+{ -+ return (187744 - (int)((val * 1000000) / 14882)); -+} -+ -+static u16 sun50i_h6_ths_recalc_reg(u32 temp) -+{ -+ return (u16)(2794 - temp * 14882 / 1000000); -+} -+ -+static int sun50i_h6_ths_get_temp(void *_data, int *out) -+{ -+ struct sun50i_h6_ths_sensor *sensor = _data; -+ -+ if (sensor->val == 0) -+ return -EBUSY; -+ -+ /* Formula and parameters from the Allwinner 3.4 kernel */ -+ *out = sensor->data->cfg->calc_temp(sensor->val); -+ return 0; -+} -+ -+static irqreturn_t sun50i_h6_ths_irq_thread(int irq, void *_data) -+{ -+ struct sun50i_h6_ths_data *data = _data; -+ int i; -+ -+ for (i = 0; i < data->cfg->sensor_num; i++) { -+ if (!(readl(data->regs + THS_H6_DATA_INT_STAT) & -+ THS_H6_STAT_DATA_IRQ_STS(i))) -+ continue; -+ -+ writel(THS_H6_STAT_DATA_IRQ_STS(i), -+ data->regs + THS_H6_DATA_INT_STAT); -+ -+ data->sensors[i].val = readl(data->regs + THS_H6_DATA(i)); -+ if (data->sensors[i].val) -+ thermal_zone_device_update(data->sensors[i].tzd, -+ THERMAL_EVENT_TEMP_SAMPLE); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static void sun50i_h6_ths_init(struct sun50i_h6_ths_data *data) -+{ -+ u32 val; -+ int i; -+ -+ writel(THS_H6_CTRL0_SENSOR_ACQ0(THS_H6_CTRL0_SENSOR_ACQ0_VALUE) | -+ THS_H6_CTRL0_UNK, data->regs + THS_H6_CTRL0); -+ writel(THS_H6_FILTER_EN | THS_H6_FILTER_TYPE(THS_H6_FILTER_TYPE_VALUE), -+ data->regs + THS_H6_FILTER); -+ -+ val = 0; -+ for (i = 0; i < data->cfg->sensor_num; i++) -+ val |= THS_H6_CTRL2_SENSE_EN(i); -+ writel(val, data->regs + THS_H6_CTRL2); -+ -+ val = THS_H6_PER_THERMAL_PER(THS_H6_INT_CTRL_THERMAL_PER_VALUE); -+ writel(val, data->regs + THS_H6_PER); -+ -+ val = 0; -+ for (i = 0; i < data->cfg->sensor_num; i++) -+ val |= THS_H6_INT_CTRL_DATA_IRQ_EN(i); -+ writel(val, data->regs + THS_H6_DATA_INT_CTRL); -+} -+ -+static const struct thermal_zone_of_device_ops sun50i_h6_ths_thermal_ops = { -+ .get_temp = sun50i_h6_ths_get_temp, -+}; -+ -+static int sun50i_h6_ths_calibrate(struct sun50i_h6_ths_data *data) -+{ -+ u16 *caldata; -+ size_t callen; -+ int i; -+ int ft_temp; -+ s16 ft_temp_orig_reg, diff, cal_val; -+ u32 reg_val; -+ -+ caldata = nvmem_cell_read(data->calcell, &callen); -+ if (IS_ERR(caldata)) -+ return PTR_ERR(caldata); -+ -+ if (callen < 2 + 2 * data->cfg->sensor_num) -+ return -EINVAL; -+ -+ if (!caldata[0]) -+ return -EINVAL; -+ -+ /* -+ * The calbration data on H6 is stored as temperature-value -+ * pair when being filled at factory test stage. -+ * The unit of stored FT temperature is 0.1 degreee celusis. -+ */ -+ ft_temp = (caldata[0] & THS_H6_CAL_FT_TEMP_MASK) * 100; -+ ft_temp_orig_reg = sun50i_h6_ths_recalc_reg(ft_temp); -+ -+ for (i = 0; i < data->cfg->sensor_num; i++) -+ { -+ diff = (ft_temp_orig_reg - (s16)caldata[1 + i]); -+ cal_val = THS_H6_CAL_DEFAULT - diff; -+ -+ if (cal_val & ~THS_H6_CAL_VAL_MASK) { -+ pr_warn("Faulty thermal sensor %d calibration value, beyond the valid range.\n", i); -+ continue; -+ } -+ -+ if (i % 2) { -+ reg_val = readl(data->regs + THS_H6_CDATA(i / 2)); -+ reg_val &= 0xffff; -+ reg_val |= cal_val << 16; -+ writel(reg_val, data->regs + THS_H6_CDATA(i / 2)); -+ } else { -+ writel(cal_val, data->regs + THS_H6_CDATA(i / 2)); -+ } -+ } -+ -+ kfree(caldata); -+ return 0; -+} -+ -+static int sun50i_h6_ths_probe(struct platform_device *pdev) -+{ -+ struct sun50i_h6_ths_data *data; -+ struct resource *res; -+ int ret, irq, i; -+ -+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ data->cfg = of_device_get_match_data(&pdev->dev); -+ if (!data->cfg) -+ return -EINVAL; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "no memory resources defined\n"); -+ return -EINVAL; -+ } -+ -+ data->regs = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(data->regs)) { -+ ret = PTR_ERR(data->regs); -+ dev_err(&pdev->dev, "failed to ioremap THS registers: %d\n", ret); -+ return ret; -+ } -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) { -+ dev_err(&pdev->dev, "failed to get IRQ: %d\n", irq); -+ return irq; -+ } -+ -+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, -+ sun50i_h6_ths_irq_thread, IRQF_ONESHOT, -+ dev_name(&pdev->dev), data); -+ if (ret) -+ return ret; -+ -+ data->busclk = devm_clk_get(&pdev->dev, "bus"); -+ if (IS_ERR(data->busclk)) { -+ ret = PTR_ERR(data->busclk); -+ dev_err(&pdev->dev, "failed to get ahb clk: %d\n", ret); -+ return ret; -+ } -+ -+ data->reset = devm_reset_control_get(&pdev->dev, NULL); -+ if (IS_ERR(data->reset)) { -+ ret = PTR_ERR(data->reset); -+ dev_err(&pdev->dev, "failed to get reset: %d\n", ret); -+ return ret; -+ } -+ -+ ret = reset_control_deassert(data->reset); -+ if (ret) { -+ dev_err(&pdev->dev, "reset deassert failed: %d\n", ret); -+ return ret; -+ } -+ -+ ret = clk_prepare_enable(data->busclk); -+ if (ret) { -+ dev_err(&pdev->dev, "failed to enable bus clk: %d\n", ret); -+ goto err_assert_reset; -+ } -+ -+ data->calcell = devm_nvmem_cell_get(&pdev->dev, "calibration"); -+ if (IS_ERR(data->calcell)) { -+ if (PTR_ERR(data->calcell) == -EPROBE_DEFER) { -+ ret = PTR_ERR(data->calcell); -+ goto err_disable_bus; -+ } -+ /* -+ * Even if the external calibration data stored in eFUSE is -+ * not accessible, the THS hardware can still work, although -+ * the data won't be so accurate. -+ * The default value of calibration register is 0x800 for -+ * every sensor, and the calibration value is usually 0x7xx -+ * or 0x8xx, so they won't be away from the default value -+ * for a lot. -+ * So here we do not return if the calibartion data is not -+ * available, except the probe needs deferring. -+ */ -+ } else { -+ ret = sun50i_h6_ths_calibrate(data); -+ if (ret) { -+ /* Revert calibrating */ -+ for (i = 0; i < data->cfg->sensor_num; i += 2) { -+ writew(THS_H6_CAL_DEFAULT, -+ data->regs + THS_H6_CDATA(i / 2)); -+ } -+ } -+ } -+ -+ for (i = 0; i < data->cfg->sensor_num; i++) { -+ data->sensors[i].data = data; -+ data->sensors[i].id = i; -+ data->sensors[i].tzd = -+ devm_thermal_zone_of_sensor_register(&pdev->dev, -+ i, &data->sensors[i], &sun50i_h6_ths_thermal_ops); -+ if (IS_ERR(data->sensors[i].tzd)) { -+ ret = PTR_ERR(data->sensors[i].tzd); -+ dev_err(&pdev->dev, -+ "failed to register thermal zone %d: %d\n", -+ i, ret); -+ goto err_disable_bus; -+ } -+ } -+ -+ sun50i_h6_ths_init(data); -+ -+ platform_set_drvdata(pdev, data); -+ return 0; -+ -+err_disable_bus: -+ clk_disable_unprepare(data->busclk); -+err_assert_reset: -+ reset_control_assert(data->reset); -+ return ret; -+} -+ -+static int sun50i_h6_ths_remove(struct platform_device *pdev) -+{ -+ struct sun50i_h6_ths_data *data = platform_get_drvdata(pdev); -+ -+ reset_control_assert(data->reset); -+ clk_disable_unprepare(data->busclk); -+ return 0; -+} -+ -+static const struct sun50i_h6_ths_cfg sun50i_h6_ths_cfg = { -+ .sensor_num = 2, -+ .calc_temp = sun50i_h6_ths_calc_temp, -+}; -+ -+static const struct of_device_id sun50i_h6_ths_id_table[] = { -+ { .compatible = "allwinner,sun50i-h6-ths", .data = &sun50i_h6_ths_cfg }, -+ { /* sentinel */ }, -+}; -+MODULE_DEVICE_TABLE(of, sun50i_h6_ths_id_table); -+ -+static struct platform_driver sun50i_h6_ths_driver = { -+ .probe = sun50i_h6_ths_probe, -+ .remove = sun50i_h6_ths_remove, -+ .driver = { -+ .name = "sun50i_h6_ths", -+ .of_match_table = sun50i_h6_ths_id_table, -+ }, -+}; -+ -+module_platform_driver(sun50i_h6_ths_driver); -+ -+MODULE_AUTHOR("Icenowy Zheng "); -+MODULE_DESCRIPTION("Thermal sensor driver for Allwinner H6"); -+MODULE_LICENSE("GPL v2"); --- -2.17.1 - - -From b2efe78569663e3188d712699209126a535df23d Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Fri, 27 Jul 2018 16:18:42 +0800 -Subject: [PATCH 41/45] basic ths dt - -Signed-off-by: Icenowy Zheng ---- - arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 35 ++++++++++++++++++++ - 1 file changed, 35 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -index 8e3c47c7c797..cf125ebd1c7b 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - / { - interrupt-parent = <&gic>; -@@ -177,6 +178,12 @@ - sid: efuse@3006000 { - compatible = "allwinner,sun50i-h6-sid"; - reg = <0x03006000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ ths_calib: thermal-sensor-calibration@14 { -+ reg = <0x14 0x6>; -+ }; - }; - - pio: pinctrl@300b000 { -@@ -445,6 +452,18 @@ - }; - }; - -+ ths: ths@5070400 { -+ compatible = "allwinner,sun50i-h6-ths"; -+ reg = <0x05070400 0x100>; -+ interrupts = ; -+ clocks = <&ccu CLK_BUS_THS>; -+ clock-names = "bus"; -+ resets = <&ccu RST_BUS_THS>; -+ nvmem-cells = <&ths_calib>; -+ nvmem-cell-names = "calibration"; -+ #thermal-sensor-cells = <1>; -+ }; -+ - r_ccu: clock@7010000 { - compatible = "allwinner,sun50i-h6-r-ccu"; - reg = <0x07010000 0x400>; -@@ -495,4 +514,20 @@ - #size-cells = <0>; - }; - }; -+ -+ thermal-zones { -+ cpu_thermal { -+ /* milliseconds */ -+ polling-delay-passive = <250>; -+ polling-delay = <1000>; -+ thermal-sensors = <&ths 0>; -+ }; -+ -+ gpu_thermal { -+ /* milliseconds */ -+ polling-delay-passive = <250>; -+ polling-delay = <1000>; -+ thermal-sensors = <&ths 1>; -+ }; -+ }; - }; --- -2.17.1 - - -From 5568aa53d90402816fe45ce30f7aaa6e577810aa Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Fri, 27 Jul 2018 19:19:28 +0800 -Subject: [PATCH 43/45] arm64: allwinner: dts: h6: add CPU supply for Pine H64 - -The Pine H64, follows the reference design on the AXP805 DCDC -assignment, connects DCDCA (polyphased with DCDCB) to the ARM -cores' power supply. - -Add this to the device tree, to enable voltage scaling. - -Signed-off-by: Icenowy Zheng ---- - arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts -index 3c74cbed319b..fb45e68bc441 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts -@@ -92,6 +92,10 @@ - }; - }; - -+&cpu0 { -+ cpu-supply = <®_dcdca>; -+}; -+ - &mmc0 { - pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins>; --- -2.17.1 - - -From 6a83e3542e2ad0388f5ee5b9beb7774467ab08bd Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Fri, 27 Jul 2018 19:28:31 +0800 -Subject: [PATCH 44/45] bind trips - -Signed-off-by: Icenowy Zheng ---- - arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 35 ++++++++++++++++++++ - 1 file changed, 35 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -index 5cc72c943374..000a681fb515 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -@@ -540,6 +540,41 @@ - polling-delay-passive = <250>; - polling-delay = <1000>; - thermal-sensors = <&ths 0>; -+ -+ cooling-maps { -+ map0 { -+ trip = <&cpu_alert0>; -+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -+ }; -+ -+ map1 { -+ trip = <&cpu_alert1>; -+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -+ }; -+ }; -+ -+ trips { -+ cpu_alert0: cpu_alert0 { -+ /* milliCelsius */ -+ temperature = <75000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ cpu_alert1: cpu_alert1 { -+ /* milliCelsius */ -+ temperature = <90000>; -+ hysteresis = <2000>; -+ type = "hot"; -+ }; -+ -+ cpu_crit: cpu_crit { -+ /* milliCelsius */ -+ temperature = <1000000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; - }; - - gpu_thermal { --- -2.17.1 - - -From 32a3eba2d813fb311430f2275ba1dbe73c37da73 Mon Sep 17 00:00:00 2001 -From: Icenowy Zheng -Date: Fri, 27 Jul 2018 19:30:10 +0800 -Subject: [PATCH 45/45] add extra opps - -Signed-off-by: Icenowy Zheng ---- - arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -index 000a681fb515..bec8c4a46ec7 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi -@@ -41,6 +41,30 @@ - opp-microvolt = <880000>; - clock-latency-ns = <244144>; /* 8 32k periods */ - }; -+ -+ opp-1008000000 { -+ opp-hz = /bits/ 64 <1008000000>; -+ opp-microvolt = <940000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ -+ opp-1320000000 { -+ opp-hz = /bits/ 64 <1320000000>; -+ opp-microvolt = <1000000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ -+ opp-1488000000 { -+ opp-hz = /bits/ 64 <1488000000>; -+ opp-microvolt = <1060000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; -+ -+ opp-1800000000 { -+ opp-hz = /bits/ 64 <1800000000>; -+ opp-microvolt = <1160000>; -+ clock-latency-ns = <244144>; /* 8 32k periods */ -+ }; - }; - - cpus { --- -2.17.1 - diff --git a/patch/kernel/sunxi-current/patch-5.4.18-19-modified.patch b/patch/kernel/sunxi-legacy/patch-5.4.18-19-modified.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.18-19-modified.patch rename to patch/kernel/sunxi-legacy/patch-5.4.18-19-modified.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.19-20.patch b/patch/kernel/sunxi-legacy/patch-5.4.19-20.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.19-20.patch rename to patch/kernel/sunxi-legacy/patch-5.4.19-20.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.20-21.patch b/patch/kernel/sunxi-legacy/patch-5.4.20-21.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.20-21.patch rename to patch/kernel/sunxi-legacy/patch-5.4.20-21.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.21-22-modified.patch b/patch/kernel/sunxi-legacy/patch-5.4.21-22-modified.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.21-22-modified.patch rename to patch/kernel/sunxi-legacy/patch-5.4.21-22-modified.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.22-23.patch b/patch/kernel/sunxi-legacy/patch-5.4.22-23.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.22-23.patch rename to patch/kernel/sunxi-legacy/patch-5.4.22-23.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.23-24-modified.patch b/patch/kernel/sunxi-legacy/patch-5.4.23-24-modified.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.23-24-modified.patch rename to patch/kernel/sunxi-legacy/patch-5.4.23-24-modified.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.24-25.patch b/patch/kernel/sunxi-legacy/patch-5.4.24-25.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.24-25.patch rename to patch/kernel/sunxi-legacy/patch-5.4.24-25.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.25-26.patch b/patch/kernel/sunxi-legacy/patch-5.4.25-26.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.25-26.patch rename to patch/kernel/sunxi-legacy/patch-5.4.25-26.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.26-27.patch b/patch/kernel/sunxi-legacy/patch-5.4.26-27.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.26-27.patch rename to patch/kernel/sunxi-legacy/patch-5.4.26-27.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.27-28.patch b/patch/kernel/sunxi-legacy/patch-5.4.27-28.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.27-28.patch rename to patch/kernel/sunxi-legacy/patch-5.4.27-28.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.28-29-modified.patch b/patch/kernel/sunxi-legacy/patch-5.4.28-29-modified.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.28-29-modified.patch rename to patch/kernel/sunxi-legacy/patch-5.4.28-29-modified.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.29-30.patch b/patch/kernel/sunxi-legacy/patch-5.4.29-30.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.29-30.patch rename to patch/kernel/sunxi-legacy/patch-5.4.29-30.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.30-31.patch b/patch/kernel/sunxi-legacy/patch-5.4.30-31.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.30-31.patch rename to patch/kernel/sunxi-legacy/patch-5.4.30-31.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.31-32.patch b/patch/kernel/sunxi-legacy/patch-5.4.31-32.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.31-32.patch rename to patch/kernel/sunxi-legacy/patch-5.4.31-32.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.32-33-modified.patch b/patch/kernel/sunxi-legacy/patch-5.4.32-33-modified.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.32-33-modified.patch rename to patch/kernel/sunxi-legacy/patch-5.4.32-33-modified.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.33-34.patch b/patch/kernel/sunxi-legacy/patch-5.4.33-34.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.33-34.patch rename to patch/kernel/sunxi-legacy/patch-5.4.33-34.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.34-35.patch b/patch/kernel/sunxi-legacy/patch-5.4.34-35.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.34-35.patch rename to patch/kernel/sunxi-legacy/patch-5.4.34-35.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.35-36.patch b/patch/kernel/sunxi-legacy/patch-5.4.35-36.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.35-36.patch rename to patch/kernel/sunxi-legacy/patch-5.4.35-36.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.36-37.patch b/patch/kernel/sunxi-legacy/patch-5.4.36-37.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.36-37.patch rename to patch/kernel/sunxi-legacy/patch-5.4.36-37.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.37-38.patch b/patch/kernel/sunxi-legacy/patch-5.4.37-38.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.37-38.patch rename to patch/kernel/sunxi-legacy/patch-5.4.37-38.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.38-39.patch b/patch/kernel/sunxi-legacy/patch-5.4.38-39.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.38-39.patch rename to patch/kernel/sunxi-legacy/patch-5.4.38-39.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.39-40.patch b/patch/kernel/sunxi-legacy/patch-5.4.39-40.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.39-40.patch rename to patch/kernel/sunxi-legacy/patch-5.4.39-40.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.40-41.patch b/patch/kernel/sunxi-legacy/patch-5.4.40-41.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.40-41.patch rename to patch/kernel/sunxi-legacy/patch-5.4.40-41.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.41-42.patch b/patch/kernel/sunxi-legacy/patch-5.4.41-42.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.41-42.patch rename to patch/kernel/sunxi-legacy/patch-5.4.41-42.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.42-43.patch b/patch/kernel/sunxi-legacy/patch-5.4.42-43.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.42-43.patch rename to patch/kernel/sunxi-legacy/patch-5.4.42-43.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.43-44.patch b/patch/kernel/sunxi-legacy/patch-5.4.43-44.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.43-44.patch rename to patch/kernel/sunxi-legacy/patch-5.4.43-44.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.44-45.patch b/patch/kernel/sunxi-legacy/patch-5.4.44-45.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.44-45.patch rename to patch/kernel/sunxi-legacy/patch-5.4.44-45.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.45-46.patch b/patch/kernel/sunxi-legacy/patch-5.4.45-46.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.45-46.patch rename to patch/kernel/sunxi-legacy/patch-5.4.45-46.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.46-47.patch b/patch/kernel/sunxi-legacy/patch-5.4.46-47.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.46-47.patch rename to patch/kernel/sunxi-legacy/patch-5.4.46-47.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.47-48.patch b/patch/kernel/sunxi-legacy/patch-5.4.47-48.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.47-48.patch rename to patch/kernel/sunxi-legacy/patch-5.4.47-48.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.48-49.patch b/patch/kernel/sunxi-legacy/patch-5.4.48-49.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.48-49.patch rename to patch/kernel/sunxi-legacy/patch-5.4.48-49.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.49-50.patch b/patch/kernel/sunxi-legacy/patch-5.4.49-50.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.49-50.patch rename to patch/kernel/sunxi-legacy/patch-5.4.49-50.patch diff --git a/patch/kernel/sunxi-current/patch-5.4.50-51.patch b/patch/kernel/sunxi-legacy/patch-5.4.50-51.patch similarity index 100% rename from patch/kernel/sunxi-current/patch-5.4.50-51.patch rename to patch/kernel/sunxi-legacy/patch-5.4.50-51.patch diff --git a/patch/kernel/sunxi-legacy/sound-soc-codecs-enable-pcm5102a.patch b/patch/kernel/sunxi-legacy/sound-soc-codecs-enable-pcm5102a.patch new file mode 100644 index 000000000..7fab56de6 --- /dev/null +++ b/patch/kernel/sunxi-legacy/sound-soc-codecs-enable-pcm5102a.patch @@ -0,0 +1,11 @@ +--- a/sound/soc/codecs/Kconfig 2020-02-13 23:44:47.394937509 +0100 ++++ b/sound/soc/codecs/Kconfig 2020-02-13 23:47:11.571103180 +0100 +@@ -880,7 +880,7 @@ + select REGMAP_SPI + + config SND_SOC_PCM5102A +- tristate ++ tristate "Texas Instruments PCM5102A CODEC" + + config SND_SOC_PCM512x + tristate diff --git a/patch/kernel/sunxi-legacy/sunxi-h5-add-gpio-regulator-overclock.patch b/patch/kernel/sunxi-legacy/sunxi-h5-add-gpio-regulator-overclock.patch index 8a27a9380..a1bca70b7 100644 --- a/patch/kernel/sunxi-legacy/sunxi-h5-add-gpio-regulator-overclock.patch +++ b/patch/kernel/sunxi-legacy/sunxi-h5-add-gpio-regulator-overclock.patch @@ -1,19 +1,95 @@ diff --git a/arch/arm64/boot/dts/allwinner/overlay/Makefile b/arch/arm64/boot/dts/allwinner/overlay/Makefile -index 3ef0a3737..fb6bee993 100644 +index 2334e0548..66c23cff2 100644 --- a/arch/arm64/boot/dts/allwinner/overlay/Makefile +++ b/arch/arm64/boot/dts/allwinner/overlay/Makefile -@@ -13,6 +13,8 @@ dtbo-$(CONFIG_ARCH_SUNXI) += \ +@@ -14,6 +14,10 @@ dtbo-$(CONFIG_ARCH_SUNXI) += \ sun50i-a64-w1-gpio.dtbo \ sun50i-h5-analog-codec.dtbo \ sun50i-h5-cir.dtbo \ ++ sun50i-h5-cpu-clock-1.0GHz-1.1v.dtbo \ ++ sun50i-h5-cpu-clock-1.2GHz-1.3v.dtbo \ + sun50i-h5-cpu-clock-1.3GHz-1.3v.dtbo \ + sun50i-h5-gpio-regulator-1.3v.dtbo \ sun50i-h5-i2c0.dtbo \ sun50i-h5-i2c1.dtbo \ sun50i-h5-i2c2.dtbo \ +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-cpu-clock-1.0GHz-1.1v.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-cpu-clock-1.0GHz-1.1v.dts +new file mode 100644 +index 000000000..a8079e825 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-cpu-clock-1.0GHz-1.1v.dts +@@ -0,0 +1,31 @@ ++// DT overlay for CPU frequency operating points to up to 1.0GHz at a maximum CPU voltage of 1.1v ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ fragment@0 { ++ target = <&cpu0_opp_table>; ++ ++ __overlay__ { ++ compatible = "operating-points-v2"; ++ opp-shared; ++ ++ // in order to match the H5 DT cooling-maps, update the existing OP table in-place ++ // with the new voltages ++ ++ opp-960000000 { ++ opp-hz = /bits/ 64 <960000000>; ++ opp-microvolt = <1100000 1100000 1300000>; ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ }; ++ ++ opp-1008000000 { ++ opp-hz = /bits/ 64 <1008000000>; ++ opp-microvolt = <1100000 1100000 1300000>; ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ }; ++ }; ++ }; ++}; ++ +diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-cpu-clock-1.2GHz-1.3v.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-cpu-clock-1.2GHz-1.3v.dts +new file mode 100644 +index 000000000..81fd378b9 +--- /dev/null ++++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-cpu-clock-1.2GHz-1.3v.dts +@@ -0,0 +1,31 @@ ++// DT overlay for CPU frequency operating points to up to 1.2GHz at a maximum CPU voltage of 1.3v ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ fragment@0 { ++ target = <&cpu0_opp_table>; ++ ++ __overlay__ { ++ compatible = "operating-points-v2"; ++ opp-shared; ++ ++ // in order to match the H5 DT cooling-maps, update the existing OP table in-place ++ // with the new voltages ++ ++ opp-1104000000 { ++ opp-hz = /bits/ 64 <1104000000>; ++ opp-microvolt = <1300000 1300000 1300000>; ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ }; ++ ++ opp-1200000000 { ++ opp-hz = /bits/ 64 <1200000000>; ++ opp-microvolt = <1300000 1300000 1300000>; ++ clock-latency-ns = <244144>; /* 8 32k periods */ ++ }; ++ }; ++ }; ++}; ++ diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-cpu-clock-1.3GHz-1.3v.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-cpu-clock-1.3GHz-1.3v.dts new file mode 100644 -index 000000000..03cae05bd +index 000000000..ed0d9ac63 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-cpu-clock-1.3GHz-1.3v.dts @@ -0,0 +1,61 @@ @@ -33,43 +109,43 @@ index 000000000..03cae05bd + // in order to match the H5 DT cooling-maps, update the existing OP table in-place + // with the new voltages + -+ opp@1056000000 { ++ opp-1056000000 { + opp-hz = /bits/ 64 <1056000000>; + opp-microvolt = <1300000 1300000 1300000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + -+ opp@1104000000 { ++ opp-1104000000 { + opp-hz = /bits/ 64 <1104000000>; + opp-microvolt = <1300000 1300000 1300000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + -+ opp@1152000000 { ++ opp-1152000000 { + opp-hz = /bits/ 64 <1152000000>; + opp-microvolt = <1300000 1300000 1300000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + -+ opp@1200000000 { ++ opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <1300000 1300000 1300000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + -+ opp@1224000000 { ++ opp-1224000000 { + opp-hz = /bits/ 64 <1224000000>; + opp-microvolt = <1300000 1300000 1300000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + -+ opp@1248000000 { ++ opp-1248000000 { + opp-hz = /bits/ 64 <1248000000>; + opp-microvolt = <1300000 1300000 1300000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + -+ opp@1296000000 { ++ opp-1296000000 { + opp-hz = /bits/ 64 <1296000000>; + opp-microvolt = <1300000 1300000 1300000>; + clock-latency-ns = <244144>; /* 8 32k periods */ @@ -80,7 +156,7 @@ index 000000000..03cae05bd + diff --git a/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-gpio-regulator-1.3v.dts b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-gpio-regulator-1.3v.dts new file mode 100644 -index 000000000..4bf787c66 +index 000000000..8d2755c3d --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/overlay/sun50i-h5-gpio-regulator-1.3v.dts @@ -0,0 +1,38 @@ diff --git a/patch/kernel/sunxi-legacy/sunxi_neo-plus2_Support_AP6212_AP6212A_bluetooth.patch b/patch/kernel/sunxi-legacy/sunxi_neo-plus2_Support_AP6212_AP6212A_bluetooth.patch deleted file mode 100644 index 2289ab122..000000000 --- a/patch/kernel/sunxi-legacy/sunxi_neo-plus2_Support_AP6212_AP6212A_bluetooth.patch +++ /dev/null @@ -1,126 +0,0 @@ -From de8acffc1a023f92f12fa9c9a4ff9656e9be14a2 Mon Sep 17 00:00:00 2001 -From: wwd -Date: Fri, 28 Apr 2017 10:34:01 +0800 -Subject: [PATCH] arm64: sunxi: neo-plus2: Support AP6212/AP6212A bluetooth - ---- - arch/arm/boot/dts/sunxi-h3-h5.dtsi | 4 ++++ - .../allwinner/sun50i-h5-nanopi-neo-plus2.dts | 22 ++++++++++++++++++- - arch/arm64/configs/sunxi_arm64_defconfig | 4 ++-- - drivers/rtc/rtc-sun6i.c | 6 +++++ - net/rfkill/rfkill-gpio.c | 19 +++++++++++----- - 5 files changed, 47 insertions(+), 8 deletions(-) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts -index bc42210ea..60c6bfb66 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts -@@ -54,6 +54,7 @@ - - aliases { - ethernet0 = &emac; -+ serial3 = &uart3; - serial0 = &uart0; - }; - -@@ -117,6 +118,17 @@ - reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */ - post-power-on-delay-ms = <200>; - }; -+ -+ rfkill_bt { -+ compatible = "rfkill-gpio"; -+ pinctrl-names = "default"; -+ reset-gpios = <&pio 6 13 GPIO_ACTIVE_HIGH>; /* PG13 */ -+ clocks = <&osc32k>; -+ clock-frequency = <32768>; -+ rfkill-name = "sunxi-bt"; -+ rfkill-type = "bluetooth"; -+ }; -+ - }; - - &cpu0 { -@@ -200,6 +212,12 @@ - status = "okay"; - }; - -+&uart3 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart3_pins>, <&uart3_rts_cts_pins>; -+ status = "okay"; -+}; -+ - &usb_otg { - dr_mode = "host"; - status = "okay"; -diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c -index 76c01cbd56e35b..656847bdf00d57 100644 ---- a/net/rfkill/rfkill-gpio.c -+++ b/net/rfkill/rfkill-gpio.c -@@ -35,7 +35,7 @@ struct rfkill_gpio_data { - - struct rfkill *rfkill_dev; - struct clk *clk; -- -+ int clk_frequency; - bool clk_enabled; - }; - -@@ -44,13 +44,13 @@ static int rfkill_gpio_set_power(void *data, bool blocked) - struct rfkill_gpio_data *rfkill = data; - - if (!blocked && !IS_ERR(rfkill->clk) && !rfkill->clk_enabled) -- clk_enable(rfkill->clk); -+ clk_prepare_enable(rfkill->clk); - - gpiod_set_value_cansleep(rfkill->shutdown_gpio, !blocked); - gpiod_set_value_cansleep(rfkill->reset_gpio, !blocked); - - if (blocked && !IS_ERR(rfkill->clk) && rfkill->clk_enabled) -- clk_disable(rfkill->clk); -+ clk_disable_unprepare(rfkill->clk); - - rfkill->clk_enabled = !blocked; - -@@ -96,8 +96,9 @@ static int rfkill_gpio_probe(struct platform_device *pdev) - if (!rfkill) - return -ENOMEM; - -- device_property_read_string(&pdev->dev, "name", &rfkill->name); -- device_property_read_string(&pdev->dev, "type", &type_name); -+ device_property_read_string(&pdev->dev, "rfkill-name", &rfkill->name); -+ device_property_read_string(&pdev->dev, "rfkill-type", &type_name); -+ device_property_read_u32(&pdev->dev, "clock-frequency", &rfkill->clk_frequency); - - if (!rfkill->name) - rfkill->name = dev_name(&pdev->dev); -@@ -111,6 +112,9 @@ static int rfkill_gpio_probe(struct platform_device *pdev) - } - - rfkill->clk = devm_clk_get(&pdev->dev, NULL); -+ if (!IS_ERR(rfkill->clk) && rfkill->clk_frequency > 0) { -+ clk_set_rate(rfkill->clk, rfkill->clk_frequency); -+ } - - gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(gpio)) -@@ -167,6 +171,10 @@ static const struct acpi_device_id rfkill_acpi_match[] = { - }; - MODULE_DEVICE_TABLE(acpi, rfkill_acpi_match); - #endif -+static const struct of_device_id rfkill_of_match[] = { -+ { .compatible = "rfkill-gpio", }, -+ {}, -+}; - - static struct platform_driver rfkill_gpio_driver = { - .probe = rfkill_gpio_probe, -@@ -174,6 +182,7 @@ static struct platform_driver rfkill_gpio_driver = { - .driver = { - .name = "rfkill_gpio", - .acpi_match_table = ACPI_PTR(rfkill_acpi_match), -+ .of_match_table = of_match_ptr(rfkill_of_match), - }, - }; - diff --git a/patch/kernel/sunxi-legacy/ths-29-add-correct-h5-thermal-zone.patch b/patch/kernel/sunxi-legacy/ths-29-add-correct-h5-thermal-zone.patch deleted file mode 100644 index e253df53e..000000000 --- a/patch/kernel/sunxi-legacy/ths-29-add-correct-h5-thermal-zone.patch +++ /dev/null @@ -1,88 +0,0 @@ -diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -index d1890797c..6cb02c962 100644 ---- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi -+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi -@@ -1045,28 +1045,74 @@ - }; - - thermal-zones { -- cpu_thermal: cpu_thermal { -- polling-delay-passive = <330>; -+ cpu-thermal { -+ /* milliseconds */ -+ polling-delay-passive = <250>; - polling-delay = <1000>; -- thermal-sensors = <&ths 0>; -+ thermal-sensors = <&ths>; - - trips { -- cpu_hot_trip: cpu-warm { -- temperature = <65000>; -+ cpu_warm: cpu_warm { -+ temperature = <75000>; - hysteresis = <2000>; - type = "passive"; - }; -- cpu_very_hot_trip: cpu-very-hot { -+ -+ cpu_hot_pre: cpu_hot_pre { -+ temperature = <80000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ cpu_hot: cpu_hot { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ cpu_very_hot_pre: cpu_very_hot_pre { - temperature = <90000>; - hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ cpu_very_hot: cpu_very_hot { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ cpu_crit: cpu_crit { -+ temperature = <105000>; -+ hysteresis = <2000>; - type = "critical"; - }; - }; - - cooling-maps { -- cpu-warm-limit { -- trip = <&cpu_hot_trip>; -- cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -+ cpu_warm_limit_cpu { -+ trip = <&cpu_warm>; -+ cooling-device = <&cpu0 THERMAL_NO_LIMIT 2>; -+ }; -+ -+ cpu_hot_pre_limit_cpu { -+ trip = <&cpu_hot_pre>; -+ cooling-device = <&cpu0 2 3>; -+ }; -+ -+ cpu_hot_limit_cpu { -+ trip = <&cpu_hot>; -+ cooling-device = <&cpu0 3 4>; -+ }; -+ -+ cpu_very_hot_pre_limit_cpu { -+ trip = <&cpu_very_hot_pre>; -+ cooling-device = <&cpu0 5 6>; -+ }; -+ -+ cpu_very_hot_limit_cpu { -+ trip = <&cpu_very_hot>; -+ cooling-device = <&cpu0 7 THERMAL_NO_LIMIT>; - }; - }; - }; diff --git a/patch/kernel/sunxi-current/ths-49-add-h5-cpu-opp-table.patch.disabled b/patch/kernel/sunxi-legacy/ths-49-add-h5-cpu-opp-table.patch.disabled similarity index 100% rename from patch/kernel/sunxi-current/ths-49-add-h5-cpu-opp-table.patch.disabled rename to patch/kernel/sunxi-legacy/ths-49-add-h5-cpu-opp-table.patch.disabled diff --git a/patch/kernel/sunxi-current/ths-50-add-h5-opp-table-to-cpu.patch.disabled b/patch/kernel/sunxi-legacy/ths-50-add-h5-opp-table-to-cpu.patch.disabled similarity index 100% rename from patch/kernel/sunxi-current/ths-50-add-h5-opp-table-to-cpu.patch.disabled rename to patch/kernel/sunxi-legacy/ths-50-add-h5-opp-table-to-cpu.patch.disabled diff --git a/patch/kernel/sunxi-legacy/timekeeping32-tweaks-for-5.0.y.patch b/patch/kernel/sunxi-legacy/timekeeping32-tweaks-for-5.0.y.patch new file mode 100644 index 000000000..fd6935461 --- /dev/null +++ b/patch/kernel/sunxi-legacy/timekeeping32-tweaks-for-5.0.y.patch @@ -0,0 +1,20 @@ +diff --git a/include/linux/timekeeping32.h b/include/linux/timekeeping32.h +index cc59cc9..a0f5143 100644 +--- a/include/linux/timekeeping32.h ++++ b/include/linux/timekeeping32.h +@@ -43,4 +43,15 @@ static inline void getboottime(struct timespec *ts) + *ts = timespec64_to_timespec(ts64); + } + ++static inline void get_monotonic_boottime(struct timespec *ts) ++{ ++ *ts = ktime_to_timespec(ktime_get_boottime()); ++} ++ ++static inline void timekeeping_clocktai(struct timespec *ts) ++{ ++ *ts = ktime_to_timespec(ktime_get_clocktai()); ++} ++ ++ + #endif diff --git a/patch/kernel/sunxi-legacy/update-correct-h3-h5-thermal-zones.patch b/patch/kernel/sunxi-legacy/update-correct-h3-h5-thermal-zones.patch new file mode 100644 index 000000000..7515934e3 --- /dev/null +++ b/patch/kernel/sunxi-legacy/update-correct-h3-h5-thermal-zones.patch @@ -0,0 +1,201 @@ +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi +index f4af3fdcc..3b1f50791 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi +@@ -221,31 +221,73 @@ + + thermal-zones { + cpu_thermal: cpu-thermal { +- polling-delay-passive = <0>; +- polling-delay = <0>; ++ /* milliseconds */ ++ polling-delay-passive = <250>; ++ polling-delay = <1000>; + thermal-sensors = <&ths 0>; + + trips { +- cpu_hot_trip: cpu-hot { ++ cpu_warm: cpu_warm { ++ temperature = <75000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ cpu_hot_pre: cpu_hot_pre { + temperature = <80000>; + hysteresis = <2000>; + type = "passive"; + }; + +- cpu_very_hot_trip: cpu-very-hot { +- temperature = <100000>; +- hysteresis = <0>; ++ cpu_hot: cpu_hot { ++ temperature = <85000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ cpu_very_hot_pre: cpu_very_hot_pre { ++ temperature = <90000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ cpu_very_hot: cpu_very_hot { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ cpu_crit: cpu_crit { ++ temperature = <105000>; ++ hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { +- cpu-hot-limit { +- trip = <&cpu_hot_trip>; +- cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cpu_warm_limit_cpu { ++ trip = <&cpu_warm>; ++ cooling-device = <&cpu0 THERMAL_NO_LIMIT 2>; ++ }; ++ ++ cpu_hot_pre_limit_cpu { ++ trip = <&cpu_hot_pre>; ++ cooling-device = <&cpu0 2 3>; ++ }; ++ ++ cpu_hot_limit_cpu { ++ trip = <&cpu_hot>; ++ cooling-device = <&cpu0 3 4>; ++ }; ++ ++ cpu_very_hot_pre_limit_cpu { ++ trip = <&cpu_very_hot_pre>; ++ cooling-device = <&cpu0 5 6>; ++ }; ++ ++ cpu_very_hot_limit_cpu { ++ trip = <&cpu_very_hot>; ++ cooling-device = <&cpu0 7 THERMAL_NO_LIMIT>; + }; + }; + }; +diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi +index ae3f37720..74e6b3b82 100644 +--- a/arch/arm/boot/dts/sun8i-h3.dtsi ++++ b/arch/arm/boot/dts/sun8i-h3.dtsi +@@ -89,15 +89,6 @@ + }; + }; + +- thermal-zones { +- cpu-thermal { +- /* milliseconds */ +- polling-delay-passive = <250>; +- polling-delay = <1000>; +- thermal-sensors = <&ths 0>; +- }; +- }; +- + pmu { + compatible = "arm,cortex-a7-pmu"; + interrupts = , +@@ -188,32 +179,74 @@ + }; + + thermal-zones { +- cpu_thermal: cpu-thermal { +- polling-delay-passive = <0>; +- polling-delay = <0>; +- thermal-sensors = <&ths 0>; ++ cpu_thermal { ++ /* milliseconds */ ++ polling-delay-passive = <250>; ++ polling-delay = <1000>; ++ thermal-sensors = <&ths>; ++ ++ trips { ++ cpu_warm: cpu_warm { ++ temperature = <75000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; + +- trips { +- cpu_hot_trip: cpu-hot { ++ cpu_hot_pre: cpu_hot_pre { + temperature = <80000>; + hysteresis = <2000>; + type = "passive"; + }; + +- cpu_very_hot_trip: cpu-very-hot { +- temperature = <100000>; +- hysteresis = <0>; ++ cpu_hot: cpu_hot { ++ temperature = <85000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ cpu_very_hot_pre: cpu_very_hot_pre { ++ temperature = <90000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ cpu_very_hot: cpu_very_hot { ++ temperature = <95000>; ++ hysteresis = <2000>; ++ type = "passive"; ++ }; ++ ++ cpu_crit: cpu_crit { ++ temperature = <105000>; ++ hysteresis = <2000>; + type = "critical"; + }; + }; + +- cooling-maps { +- cpu-hot-limit { +- trip = <&cpu_hot_trip>; +- cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, +- <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; ++ cooling-maps { ++ cpu_warm_limit_cpu { ++ trip = <&cpu_warm>; ++ cooling-device = <&cpu0 THERMAL_NO_LIMIT 2>; ++ }; ++ ++ cpu_hot_pre_limit_cpu { ++ trip = <&cpu_hot_pre>; ++ cooling-device = <&cpu0 2 3>; ++ }; ++ ++ cpu_hot_limit_cpu { ++ trip = <&cpu_hot>; ++ cooling-device = <&cpu0 3 4>; ++ }; ++ ++ cpu_very_hot_pre_limit_cpu { ++ trip = <&cpu_very_hot_pre>; ++ cooling-device = <&cpu0 5 6>; ++ }; ++ ++ cpu_very_hot_limit_cpu { ++ trip = <&cpu_very_hot>; ++ cooling-device = <&cpu0 7 THERMAL_NO_LIMIT>; + }; + }; + }; diff --git a/patch/kernel/sunxi-legacy/wifi-4001-add-realtek-8723cs-kconfig-makefile.patch b/patch/kernel/sunxi-legacy/wifi-4001-add-realtek-8723cs-kconfig-makefile.patch index 14dde71bd..83c12df42 100644 --- a/patch/kernel/sunxi-legacy/wifi-4001-add-realtek-8723cs-kconfig-makefile.patch +++ b/patch/kernel/sunxi-legacy/wifi-4001-add-realtek-8723cs-kconfig-makefile.patch @@ -1,12 +1,15 @@ diff --git a/drivers/net/wireless/realtek/Kconfig b/drivers/net/wireless/realtek/Kconfig -index 3db988e6..5d5e0c7a 100644 +index 8ea2d8d..600c44d 100644 --- a/drivers/net/wireless/realtek/Kconfig +++ b/drivers/net/wireless/realtek/Kconfig -@@ -14,5 +14,6 @@ if WLAN_VENDOR_REALTEK +@@ -13,8 +13,9 @@ config WLAN_VENDOR_REALTEK + if WLAN_VENDOR_REALTEK + source "drivers/net/wireless/realtek/rtl818x/Kconfig" source "drivers/net/wireless/realtek/rtlwifi/Kconfig" source "drivers/net/wireless/realtek/rtl8xxxu/Kconfig" +source "drivers/net/wireless/realtek/rtl8723cs/Kconfig" + source "drivers/net/wireless/realtek/rtw88/Kconfig" endif # WLAN_VENDOR_REALTEK diff --git a/drivers/net/wireless/realtek/Makefile b/drivers/net/wireless/realtek/Makefile diff --git a/patch/kernel/sunxi-legacy/wifi-4002-add-realtek-8723cs.patch b/patch/kernel/sunxi-legacy/wifi-4002-add-realtek-8723cs.patch index 28cb60377..69d37ec09 100644 --- a/patch/kernel/sunxi-legacy/wifi-4002-add-realtek-8723cs.patch +++ b/patch/kernel/sunxi-legacy/wifi-4002-add-realtek-8723cs.patch @@ -333082,7 +333082,7 @@ index 00000000..748a4096 +static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) + ,struct net_device *sb_dev -+ ,select_queue_fallback_t fallback ++// ,select_queue_fallback_t fallback +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) + , void *accel_priv +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) @@ -338144,7 +338144,7 @@ index 00000000..8de7ff72 + goto exit; + } + -+ if (!access_ok(VERIFY_READ, priv_cmd.buf, priv_cmd.total_len)){ ++ if (!access_ok(priv_cmd.buf, priv_cmd.total_len)){ + DBG_871X("%s: failed to access memory\n", __FUNCTION__); + ret = -EFAULT; + goto exit; @@ -338818,7 +338818,7 @@ new file mode 100644 index 00000000..13e07482 --- /dev/null +++ b/drivers/net/wireless/realtek/rtl8723cs/os_dep/linux/rtw_cfgvendor.c -@@ -0,0 +1,1340 @@ +@@ -0,0 +1,1385 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2014 Realtek Corporation. All rights reserved. @@ -339993,7 +339993,10 @@ index 00000000..13e07482 + .subcmd = BRCM_VENDOR_SCMD_PRIV_STR + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = wl_cfgvendor_priv_string_handler ++ .doit = wl_cfgvendor_priv_string_handler, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) ++ .policy = VENDOR_CMD_RAW_DATA, ++#endif + }, +#if defined(GSCAN_SUPPORT) && 0 + { @@ -340002,7 +340005,10 @@ index 00000000..13e07482 + .subcmd = GSCAN_SUBCMD_GET_CAPABILITIES + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = wl_cfgvendor_gscan_get_capabilities ++ .doit = wl_cfgvendor_gscan_get_capabilities, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) ++ .policy = VENDOR_CMD_RAW_DATA, ++#endif + }, + { + { @@ -340010,7 +340016,10 @@ index 00000000..13e07482 + .subcmd = GSCAN_SUBCMD_SET_CONFIG + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = wl_cfgvendor_set_scan_cfg ++ .doit = wl_cfgvendor_set_scan_cfg, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) ++ .policy = VENDOR_CMD_RAW_DATA, ++#endif + }, + { + { @@ -340018,7 +340027,10 @@ index 00000000..13e07482 + .subcmd = GSCAN_SUBCMD_SET_SCAN_CONFIG + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = wl_cfgvendor_set_batch_scan_cfg ++ .doit = wl_cfgvendor_set_batch_scan_cfg, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) ++ .policy = VENDOR_CMD_RAW_DATA, ++#endif + }, + { + { @@ -340026,7 +340038,10 @@ index 00000000..13e07482 + .subcmd = GSCAN_SUBCMD_ENABLE_GSCAN + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = wl_cfgvendor_initiate_gscan ++ .doit = wl_cfgvendor_initiate_gscan, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) ++ .policy = VENDOR_CMD_RAW_DATA, ++#endif + }, + { + { @@ -340034,7 +340049,10 @@ index 00000000..13e07482 + .subcmd = GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = wl_cfgvendor_enable_full_scan_result ++ .doit = wl_cfgvendor_enable_full_scan_result, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) ++ .policy = VENDOR_CMD_RAW_DATA, ++#endif + }, + { + { @@ -340042,7 +340060,10 @@ index 00000000..13e07482 + .subcmd = GSCAN_SUBCMD_SET_HOTLIST + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = wl_cfgvendor_hotlist_cfg ++ .doit = wl_cfgvendor_hotlist_cfg, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) ++ .policy = VENDOR_CMD_RAW_DATA, ++#endif + }, + { + { @@ -340050,7 +340071,10 @@ index 00000000..13e07482 + .subcmd = GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = wl_cfgvendor_significant_change_cfg ++ .doit = wl_cfgvendor_significant_change_cfg, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) ++ .policy = VENDOR_CMD_RAW_DATA, ++#endif + }, + { + { @@ -340058,7 +340082,10 @@ index 00000000..13e07482 + .subcmd = GSCAN_SUBCMD_GET_SCAN_RESULTS + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = wl_cfgvendor_gscan_get_batch_results ++ .doit = wl_cfgvendor_gscan_get_batch_results, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) ++ .policy = VENDOR_CMD_RAW_DATA, ++#endif + }, + { + { @@ -340066,7 +340093,10 @@ index 00000000..13e07482 + .subcmd = GSCAN_SUBCMD_GET_CHANNEL_LIST + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = wl_cfgvendor_gscan_get_channel_list ++ .doit = wl_cfgvendor_gscan_get_channel_list, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) ++ .policy = VENDOR_CMD_RAW_DATA, ++#endif + }, +#endif /* GSCAN_SUPPORT */ +#if defined(RTT_SUPPORT) && 0 @@ -340076,7 +340106,10 @@ index 00000000..13e07482 + .subcmd = RTT_SUBCMD_SET_CONFIG + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = wl_cfgvendor_rtt_set_config ++ .doit = wl_cfgvendor_rtt_set_config, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) ++ .policy = VENDOR_CMD_RAW_DATA, ++#endif + }, + { + { @@ -340084,7 +340117,10 @@ index 00000000..13e07482 + .subcmd = RTT_SUBCMD_CANCEL_CONFIG + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = wl_cfgvendor_rtt_cancel_config ++ .doit = wl_cfgvendor_rtt_cancel_config, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) ++ .policy = VENDOR_CMD_RAW_DATA, ++#endif + }, + { + { @@ -340092,7 +340128,10 @@ index 00000000..13e07482 + .subcmd = RTT_SUBCMD_GETCAPABILITY + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = wl_cfgvendor_rtt_get_capability ++ .doit = wl_cfgvendor_rtt_get_capability, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) ++ .policy = VENDOR_CMD_RAW_DATA, ++#endif + }, +#endif /* RTT_SUPPORT */ + { @@ -340101,7 +340140,10 @@ index 00000000..13e07482 + .subcmd = ANDR_WIFI_SUBCMD_GET_FEATURE_SET + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = rtw_cfgvendor_get_feature_set ++ .doit = rtw_cfgvendor_get_feature_set, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) ++ .policy = VENDOR_CMD_RAW_DATA, ++#endif + }, + { + { @@ -340109,7 +340151,10 @@ index 00000000..13e07482 + .subcmd = ANDR_WIFI_SUBCMD_GET_FEATURE_SET_MATRIX + }, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, -+ .doit = rtw_cfgvendor_get_feature_set_matrix ++ .doit = rtw_cfgvendor_get_feature_set_matrix, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) ++ .policy = VENDOR_CMD_RAW_DATA, ++#endif + } +}; + @@ -347539,7 +347584,7 @@ index 00000000..585dab16 + ret = PTR_ERR(fp); + } + else { -+ oldfs = get_fs(); set_fs(get_ds()); ++ oldfs = get_fs(); set_fs(KERNEL_DS); + + if(1!=readFile(fp, &buf, 1)) + ret = PTR_ERR(fp); @@ -347567,7 +347612,7 @@ index 00000000..585dab16 + if( 0 == (ret=openFile(&fp,path, O_RDONLY, 0)) ){ + DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp); + -+ oldfs = get_fs(); set_fs(get_ds()); ++ oldfs = get_fs(); set_fs(KERNEL_DS); + ret=readFile(fp, buf, sz); + set_fs(oldfs); + closeFile(fp); @@ -347601,7 +347646,7 @@ index 00000000..585dab16 + if( 0 == (ret=openFile(&fp, path, O_CREAT|O_WRONLY, 0666)) ) { + DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp); + -+ oldfs = get_fs(); set_fs(get_ds()); ++ oldfs = get_fs(); set_fs(KERNEL_DS); + ret=writeFile(fp, buf, sz); + set_fs(oldfs); + closeFile(fp); diff --git a/patch/kernel/sunxi-legacy/wifi-bt-bananapi-m2-plus.patch b/patch/kernel/sunxi-legacy/wifi-bt-bananapi-m2-plus.patch deleted file mode 100644 index e7ce11539..000000000 --- a/patch/kernel/sunxi-legacy/wifi-bt-bananapi-m2-plus.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff --git a/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts b/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts -index b3283ae..46a1507 100644 ---- a/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts -+++ b/arch/arm/boot/dts/sun8i-h3-bananapi-m2-plus.dts -@@ -103,6 +103,8 @@ - compatible = "mmc-pwrseq-simple"; - pinctrl-names = "default"; - reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */ -+ clocks = <&rtc 1>; -+ clock-names = "ext_clock"; - }; - }; - -@@ -215,7 +217,19 @@ - &uart1 { - pinctrl-names = "default"; - pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; -- status = "okay"; -+ uart-has-rtscts; -+ status = "okay"; -+ -+ bluetooth { -+ compatible = "brcm,bcm43438-bt"; -+ clocks = <&rtc 1>; -+ clock-names = "lpo"; -+ vbat-supply = <®_vcc3v3>; -+ vddio-supply = <®_vcc3v3>; -+ device-wakeup-gpios = <&pio 6 13 GPIO_ACTIVE_HIGH>; /* PG13 */ -+ host-wakeup-gpios = <&pio 6 11 GPIO_ACTIVE_HIGH>; /* PG11 */ -+ shutdown-gpios = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */ -+ }; - }; - - &usb_otg { diff --git a/patch/kernel/sunxi-legacy/board-pinebook-boe-hb140wx-501-overlay.patch-disabled b/patch/kernel/sunxi-legacy/x-board-pinebook-boe-hb140wx-501-overlay.patch similarity index 100% rename from patch/kernel/sunxi-legacy/board-pinebook-boe-hb140wx-501-overlay.patch-disabled rename to patch/kernel/sunxi-legacy/x-board-pinebook-boe-hb140wx-501-overlay.patch diff --git a/patch/kernel/sunxi-legacy/xxx-a64-olinuxino-eth.patch b/patch/kernel/sunxi-legacy/xxx-a64-olinuxino-eth.patch deleted file mode 100644 index 3cf00f0c4..000000000 --- a/patch/kernel/sunxi-legacy/xxx-a64-olinuxino-eth.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 679294497be31596e1c9c61507746d72b6b05f26 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rodrigo=20Exterck=C3=B6tter=20Tj=C3=A4der?= - -Date: Wed, 26 Sep 2018 19:48:24 +0000 -Subject: [PATCH] arm64: dts: allwinner: a64: a64-olinuxino: set the PHY TX - delay -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The PHY found on the A64-OLinuXino requires a TX delay in order to -operate properly. Olimex uses a 600ps second delay in their BSP, and -that has been found to work, so let's use that value in the current -DT. - -Signed-off-by: Rodrigo Exterckötter Tjäder -Signed-off-by: Chen-Yu Tsai ---- - arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts -index 6ef3dd4c2389d..f7a4bccaa5d40 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts -@@ -105,6 +105,7 @@ - phy-mode = "rgmii"; - phy-handle = <&ext_rgmii_phy>; - phy-supply = <®_dcdc1>; -+ allwinner,tx-delay-ps = <600>; - status = "okay"; - }; - diff --git a/patch/kernel/sunxi-legacy/xxx-add-bananapim2-zero-eth.patch b/patch/kernel/sunxi-legacy/xxx-add-bananapim2-zero-eth.patch new file mode 100644 index 000000000..48b53042c --- /dev/null +++ b/patch/kernel/sunxi-legacy/xxx-add-bananapim2-zero-eth.patch @@ -0,0 +1,26 @@ +From 5100551511ef2c6f6739a0987ab5d871efdc09d3 Mon Sep 17 00:00:00 2001 +From: PJBrs +Date: Sun, 16 Feb 2020 16:36:13 +0100 +Subject: [PATCH] ARM: dts: sunxi: h2-plus-bananapi-m2-zero: Add ethernet + +This patch enables the ethernet driver for the BananaPi M2 Zero +--- + arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts +index d277d043031b..af001b12ea8f 100644 +--- a/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts ++++ b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts +@@ -151,3 +151,11 @@ + */ + status = "okay"; + }; ++ ++ ++&emac { ++ status = "okay"; ++ phy-handle = <&int_mii_phy>; ++ phy-mode = "mii"; ++ allwinner,leds-active-low; ++}; diff --git a/patch/kernel/sunxi-legacy/xxx-add-bananapim2-zero-heartbeat-led.patch b/patch/kernel/sunxi-legacy/xxx-add-bananapim2-zero-heartbeat-led.patch new file mode 100644 index 000000000..e7ca666ea --- /dev/null +++ b/patch/kernel/sunxi-legacy/xxx-add-bananapim2-zero-heartbeat-led.patch @@ -0,0 +1,19 @@ +ARM: dts: sunxi: h2-plus-bananapi-m2-zero: Power led heartbeat + +Make the BananaPi M2 Zero's powerled blink so that we can see whether the kernel is running. + +diff --git a/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts +index 6cb1cab0c..942fde97b 100644 +--- a/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts ++++ b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts +@@ -42,8 +42,8 @@ + + pwr_led { + label = "bananapi-m2-zero:red:pwr"; +- gpios = <&r_pio 0 10 GPIO_ACTIVE_LOW>; /* PL10 */ +- default-state = "on"; ++ gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; /* PL10 */ ++ linux,default-trigger = "heartbeat"; + }; + }; + diff --git a/patch/kernel/sunxi-legacy/xxx-add-bananapim2-zero-z1-HDMI-out.patch b/patch/kernel/sunxi-legacy/xxx-add-bananapim2-zero-z1-HDMI-out.patch new file mode 100644 index 000000000..0ef48b058 --- /dev/null +++ b/patch/kernel/sunxi-legacy/xxx-add-bananapim2-zero-z1-HDMI-out.patch @@ -0,0 +1,52 @@ +commit 9702424ea23471e3bdbe6a150e28a1ecdf837d2c +Author: PJBrs +Date: Fri Feb 21 08:56:04 2020 +0100 + + ARM: dts: sunxi: h2-plus-bananapi-m2-zero: Add HDMI out + + Add HDMI out, including the display engine, to the BananaPi + M2 Zero. + +diff --git a/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts +index 38e8da594e44..9051a1097258 100644 +--- a/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts ++++ b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts +@@ -26,6 +26,17 @@ + stdout-path = "serial0:115200n8"; + }; + ++ connector { ++ compatible = "hdmi-connector"; ++ type = "a"; ++ ++ port { ++ hdmi_con_in: endpoint { ++ remote-endpoint = <&hdmi_out_con>; ++ }; ++ }; ++ }; ++ + leds { + compatible = "gpio-leds"; + +@@ -140,6 +151,20 @@ + }; + }; + ++&de { ++ status = "okay"; ++}; ++ ++&hdmi { ++ status = "okay"; ++}; ++ ++&hdmi_out { ++ hdmi_out_con: endpoint { ++ remote-endpoint = <&hdmi_con_in>; ++ }; ++}; ++ + &ohci0 { + status = "okay"; + }; diff --git a/patch/kernel/sunxi-legacy/xxx-add-bananapim2-zero-z2-HDMI-audio-out.patch b/patch/kernel/sunxi-legacy/xxx-add-bananapim2-zero-z2-HDMI-audio-out.patch new file mode 100644 index 000000000..4200a2312 --- /dev/null +++ b/patch/kernel/sunxi-legacy/xxx-add-bananapim2-zero-z2-HDMI-audio-out.patch @@ -0,0 +1,35 @@ +commit 077fdce94e1a8305ead51d67441de9ee2295fac3 +Author: PJBrs +Date: Fri Feb 21 08:58:30 2020 +0100 + + ARM: dts: sunxi: h2-plus-bananapi-m2-zero: Add HDMI audio out + + Add sound over hdmi to BananaPi M2 Zero. + +diff --git a/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts +index 9051a1097258..0b702168981c 100644 +--- a/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts ++++ b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts +@@ -165,6 +165,10 @@ + }; + }; + ++&mixer0 { ++ status = "okay"; ++}; ++ + &ohci0 { + status = "okay"; + }; +@@ -217,3 +221,11 @@ + phy-mode = "mii"; + allwinner,leds-active-low; + }; ++ ++&i2s2 { ++ status = "okay"; ++}; ++ ++&sound_hdmi { ++ status = "okay"; ++}; diff --git a/patch/kernel/sunxi-legacy/xxx-add-bananapim2-zero-z3-bluetooth-wifi-rfkill.patch b/patch/kernel/sunxi-legacy/xxx-add-bananapim2-zero-z3-bluetooth-wifi-rfkill.patch new file mode 100644 index 000000000..af156abc0 --- /dev/null +++ b/patch/kernel/sunxi-legacy/xxx-add-bananapim2-zero-z3-bluetooth-wifi-rfkill.patch @@ -0,0 +1,53 @@ +commit 92bc2b5bc01fe53a18f2ec03098a757ebf78ac13 +Author: PJBrs +Date: Fri Feb 21 09:00:21 2020 +0100 + + ARM: dts: sunxi: h2-plus-bananapi-m2-zero: Bluetooth and wifi rfkill + + Add gpios for bluetooth rfkill and something with wifi. Now + I'm definitely out of my depth. + +diff --git a/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts +index 0b702168981c..146c1a9c4335 100644 +--- a/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts ++++ b/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts +@@ -47,6 +47,17 @@ + }; + }; + ++ rfkill_bt: rfkill_bt { ++ compatible = "rfkill-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&bt_pwr_pin>; ++ reset-gpios = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */ ++ clocks = <&osc32k>; ++ clock-frequency = <32768>; ++ rfkill-name = "sunxi-bt"; ++ rfkill-type = "bluetooth"; ++ }; ++ + gpio_keys { + compatible = "gpio-keys"; + +@@ -81,6 +92,21 @@ + }; + }; + ++&pio { ++ bt_pwr_pin: bt_pwr_pin { ++ pins = "PG12"; ++ function = "gpio_out"; ++ }; ++}; ++ ++ ++&r_pio { ++ wifi_en_pin: wifi_en_pin { ++ pins = "PL7"; ++ function = "gpio_out"; ++ }; ++}; ++ + &cpu0 { + cpu-supply = <®_vdd_cpux>; + diff --git a/patch/kernel/sunxi-legacy/xxx-add-nanopi-r1-and-duo2.patch b/patch/kernel/sunxi-legacy/xxx-add-nanopi-r1-and-duo2.patch index 111062f59..f2fa900e9 100644 --- a/patch/kernel/sunxi-legacy/xxx-add-nanopi-r1-and-duo2.patch +++ b/patch/kernel/sunxi-legacy/xxx-add-nanopi-r1-and-duo2.patch @@ -16,7 +16,7 @@ new file mode 100644 index 000000000..731c705a4 --- /dev/null +++ b/arch/arm/boot/dts/sun8i-h3-nanopi-r1.dts -@@ -0,0 +1,189 @@ +@@ -0,0 +1,190 @@ +/* + * Copyright (C) 2019 Igor Pecovnik + * @@ -88,15 +88,20 @@ index 000000000..731c705a4 + gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; + }; + -+ rfkill_bt { -+ compatible = "rfkill-gpio"; ++ vdd_cpux: gpio-regulator { ++ compatible = "regulator-gpio"; + pinctrl-names = "default"; -+ pinctrl-0 = <&bt_pwr_pin>; -+ reset-gpios = <&pio 6 13 GPIO_ACTIVE_HIGH>; /* PG13 */ -+ clocks = <&osc32k>; -+ clock-frequency = <32768>; -+ rfkill-name = "sunxi-bt"; -+ rfkill-type = "bluetooth"; ++ regulator-name = "vdd-cpux"; ++ regulator-type = "voltage"; ++ regulator-boot-on; ++ regulator-always-on; ++ regulator-min-microvolt = <1100000>; ++ regulator-max-microvolt = <1300000>; ++ regulator-ramp-delay = <50>; /* 4ms */ ++ gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */ ++ gpios-states = <0x1>; ++ states = <1100000 0x0 ++ 1300000 0x1>; + }; + + leds { @@ -138,12 +143,8 @@ index 000000000..731c705a4 + }; +}; + -+ -+&pio { -+ bt_pwr_pin: bt_pwr_pin@0 { -+ pins = "PG13"; -+ function = "gpio_out"; -+ }; ++&cpu0 { ++ cpu-supply = <&vdd_cpux>; +}; + +&emac { diff --git a/patch/kernel/sunxi-current/xxx-bananapim64.patch b/patch/kernel/sunxi-legacy/xxx-bananapim64.patch similarity index 100% rename from patch/kernel/sunxi-current/xxx-bananapim64.patch rename to patch/kernel/sunxi-legacy/xxx-bananapim64.patch diff --git a/patch/kernel/sunxi-legacy/xxx-olinuxino-battery-audio.patch b/patch/kernel/sunxi-legacy/xxx-olinuxino-battery-audio.patch new file mode 100644 index 000000000..39f9a336c --- /dev/null +++ b/patch/kernel/sunxi-legacy/xxx-olinuxino-battery-audio.patch @@ -0,0 +1,86 @@ +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts +index 3792566cd..42b838b1f 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts ++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts +@@ -94,6 +94,18 @@ + }; + }; + ++&codec { ++ status = "okay"; ++}; ++ ++&codec_analog { ++ status = "okay"; ++}; ++ ++&dai { ++ status = "okay"; ++}; ++ + &de { + status = "okay"; + }; +@@ -109,6 +121,14 @@ + }; + }; + ++&i2s2 { ++ status = "okay"; ++}; ++ ++&mixer0 { ++ status = "okay"; ++}; ++ + &ehci0 { + status = "okay"; + }; +@@ -194,6 +214,14 @@ + + #include "axp803.dtsi" + ++&ac_power_supply { ++ status = "okay"; ++}; ++ ++&battery_power_supply { ++ status = "okay"; ++}; ++ + ®_aldo1 { + regulator-always-on; + regulator-min-microvolt = <2800000>; +@@ -316,6 +344,32 @@ + vcc-hdmi-supply = <®_dldo1>; + }; + ++&sound { ++ status = "okay"; ++ simple-audio-card,widgets = "Microphone", "Internal Microphone Left", ++ "Microphone", "Internal Microphone Right", ++ "Headphone", "Headphone Jack"; ++ simple-audio-card,aux-devs = <&codec_analog>; ++ simple-audio-card,routing = ++ "Left DAC", "AIF1 Slot 0 Left", ++ "Right DAC", "AIF1 Slot 0 Right", ++ "INL", "LINEOUT", ++ "INR", "LINEOUT", ++ "Headphone Jack", "HP", ++ "AIF1 Slot 0 Left ADC", "Left ADC", ++ "AIF1 Slot 0 Right ADC", "Right ADC", ++ "Left ADC", "ADC", ++ "Right ADC", "ADC", ++ "Internal Microphone Left", "MBIAS", ++ "MIC1", "Internal Microphone Left", ++ "Internal Microphone Right", "HBIAS", ++ "MIC2", "Internal Microphone Right"; ++}; ++ ++&sound_hdmi { ++ status = "okay"; ++}; ++ + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; diff --git a/patch/kernel/sunxi-legacy/xxx-orangepi2-plus-regulator.patch b/patch/kernel/sunxi-legacy/xxx-orangepi2-plus-regulator.patch index c39ddb495..e77daa564 100644 --- a/patch/kernel/sunxi-legacy/xxx-orangepi2-plus-regulator.patch +++ b/patch/kernel/sunxi-legacy/xxx-orangepi2-plus-regulator.patch @@ -2,7 +2,11 @@ diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts b/arch/arm/boot/dts/sun8i index f1fc6bdca..47a5635b0 100644 --- a/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts +++ b/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts -@@ -129,6 +129,10 @@ +diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts +index 597c425..26c9cc6 100644 +--- a/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts ++++ b/arch/arm/boot/dts/sun8i-h3-orangepi-2.dts +@@ -123,6 +123,10 @@ status = "okay"; }; @@ -13,7 +17,7 @@ index f1fc6bdca..47a5635b0 100644 &ehci1 { status = "okay"; }; -@@ -179,6 +183,31 @@ +@@ -173,6 +177,31 @@ }; }; @@ -42,6 +46,6 @@ index f1fc6bdca..47a5635b0 100644 + }; +}; + - &pio { - leds_opc: led_pins { - pins = "PA15"; + ®_usb1_vbus { + gpio = <&pio 6 13 GPIO_ACTIVE_HIGH>; + status = "okay"; diff --git a/patch/kernel/sunxi-current/xxx-orangepioneplus-enable-hdmi.patch b/patch/kernel/sunxi-legacy/xxx-orangepioneplus-enable-hdmi.patch similarity index 100% rename from patch/kernel/sunxi-current/xxx-orangepioneplus-enable-hdmi.patch rename to patch/kernel/sunxi-legacy/xxx-orangepioneplus-enable-hdmi.patch diff --git a/patch/kernel/sunxi-legacy/xxx-orangepizero-plus2-default-regulator.patch b/patch/kernel/sunxi-legacy/xxx-orangepizero-plus2-default-regulator.patch index ef3168241..5636038f1 100644 --- a/patch/kernel/sunxi-legacy/xxx-orangepizero-plus2-default-regulator.patch +++ b/patch/kernel/sunxi-legacy/xxx-orangepizero-plus2-default-regulator.patch @@ -16,7 +16,7 @@ index 50ad2e4fd..e1ee1cd09 100644 + regulator-min-microvolt = <1108475>; + regulator-max-microvolt = <1307810>; + regulator-ramp-delay = <50>; /* 4ms */ -+ enable-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */ ++// enable-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */ + gpios = <&r_pio 0 6 0>; /* PL6 */ + enable-active-high; + gpios-states = <0x1>; diff --git a/patch/kernel/sunxi-legacy/xxx-pinebook-revert-pwm-polairity-TEMP-WORKAROUND.patch b/patch/kernel/sunxi-legacy/xxx-pinebook-revert-pwm-polairity-TEMP-WORKAROUND.patch deleted file mode 100644 index 7ddfa6510..000000000 --- a/patch/kernel/sunxi-legacy/xxx-pinebook-revert-pwm-polairity-TEMP-WORKAROUND.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -index c1e57597f..cf0a7b490 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts -@@ -24,7 +24,7 @@ - - backlight: backlight { - compatible = "pwm-backlight"; -- pwms = <&pwm 0 50000 0>; -+ pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>; - brightness-levels = <0 5 10 15 20 30 40 55 70 85 100>; - default-brightness-level = <2>; - enable-gpios = <&pio 3 23 GPIO_ACTIVE_HIGH>; /* PD23 */ diff --git a/patch/kernel/sunxi-current/xxx-pinebook-revert-pwm-polairity-TEMP-WORKAROUND.patch.disabled b/patch/kernel/sunxi-legacy/xxx-pinebook-revert-pwm-polairity-TEMP-WORKAROUND.patch.disabled similarity index 100% rename from patch/kernel/sunxi-current/xxx-pinebook-revert-pwm-polairity-TEMP-WORKAROUND.patch.disabled rename to patch/kernel/sunxi-legacy/xxx-pinebook-revert-pwm-polairity-TEMP-WORKAROUND.patch.disabled diff --git a/patch/kernel/sunxi-current/xxx-pineh64-model-a.patch b/patch/kernel/sunxi-legacy/xxx-pineh64-model-a.patch similarity index 100% rename from patch/kernel/sunxi-current/xxx-pineh64-model-a.patch rename to patch/kernel/sunxi-legacy/xxx-pineh64-model-a.patch diff --git a/patch/kernel/sunxi-current/xxx-pineh64-model-b.patch b/patch/kernel/sunxi-legacy/xxx-pineh64-model-b.patch similarity index 100% rename from patch/kernel/sunxi-current/xxx-pineh64-model-b.patch rename to patch/kernel/sunxi-legacy/xxx-pineh64-model-b.patch diff --git a/patch/kernel/sunxi-legacy/xxx-sun50i-h6-enable-higher-clock.patch b/patch/kernel/sunxi-legacy/xxx-sun50i-h6-enable-higher-clock.patch new file mode 100644 index 000000000..1caf50042 --- /dev/null +++ b/patch/kernel/sunxi-legacy/xxx-sun50i-h6-enable-higher-clock.patch @@ -0,0 +1,12 @@ +diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi +index fe8c57876..0ed487311 100644 +--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi ++++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi +@@ -177,7 +177,7 @@ + reg_dcdca: dcdca { + regulator-always-on; + regulator-min-microvolt = <810000>; +- regulator-max-microvolt = <1080000>; ++ regulator-max-microvolt = <1160000>; + regulator-name = "vdd-cpu"; + }; diff --git a/patch/kernel/sunxi-current/xxx-sun50i-h6-update-thermal-configuration.patch b/patch/kernel/sunxi-legacy/xxx-sun50i-h6-update-thermal-configuration.patch similarity index 100% rename from patch/kernel/sunxi-current/xxx-sun50i-h6-update-thermal-configuration.patch rename to patch/kernel/sunxi-legacy/xxx-sun50i-h6-update-thermal-configuration.patch diff --git a/patch/kernel/sunxi-current/xxx-teres-add-battery-hdmi-bits.patch.disabled b/patch/kernel/sunxi-legacy/xxx-teres-add-battery-hdmi-bits.patch.disabled similarity index 100% rename from patch/kernel/sunxi-current/xxx-teres-add-battery-hdmi-bits.patch.disabled rename to patch/kernel/sunxi-legacy/xxx-teres-add-battery-hdmi-bits.patch.disabled