diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 77b3e9d..54fa9b8 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -6,9 +6,6 @@ config HAVE_AT91_USB_CLK bool -config HAVE_AT91_PIO4 - bool - config COMMON_CLK_AT91 bool select COMMON_CLK @@ -142,7 +139,6 @@ bool select CPU_ARM920T select HAS_AT91_ETHER - select HAVE_AT91_DBGU0 select HAVE_AT91_USB_CLK select PINCTRL_AT91 diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig index e922880..220b635 100644 --- a/arch/arm/mach-omap/Kconfig +++ b/arch/arm/mach-omap/Kconfig @@ -19,9 +19,6 @@ menu "OMAP Features" depends on ARCH_OMAP -config MACH_OMAP - bool - config ARCH_OMAP3 bool select CPU_V7 diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 06ad188..fd9084f 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -72,7 +72,6 @@ Say Y here if you are using a Mainstone board config MACH_MIOA701 bool "Mitac Mio A701" - select BCH_CONST_PARAMS select PWM select POLLER help diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig index 3d8fc8b..2da875c 100644 --- a/arch/arm/mach-socfpga/Kconfig +++ b/arch/arm/mach-socfpga/Kconfig @@ -8,11 +8,6 @@ bool prompt "Build preloader image" -config ARCH_TEXT_BASE - hex - default 0x00100000 if MACH_SOCFPGA_CYCLONE5 - default 0xffe00000 if MACH_SOCFPGA_ARRIA10 - comment "Altera SoCFPGA System-on-Chip" config ARCH_SOCFPGA_CYCLONE5 diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 160732f..f144d34 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -4,9 +4,6 @@ hex default 0x0 -config BOARDINFO - default "" - # --------------------------------------------------------- config ARCH_TEGRA_2x_SOC diff --git a/arch/mips/mach-ath79/Kconfig b/arch/mips/mach-ath79/Kconfig index 97eea6a..9dab5fc 100644 --- a/arch/mips/mach-ath79/Kconfig +++ b/arch/mips/mach-ath79/Kconfig @@ -6,6 +6,9 @@ config SOC_QCA_AR9344 bool +config SOC_QCA_QCA4531 + bool + if DEBUG_LL choice prompt "DEBUG_LL driver" diff --git a/arch/powerpc/mach-mpc5xxx/Kconfig b/arch/powerpc/mach-mpc5xxx/Kconfig index 180aa32..4da947d 100644 --- a/arch/powerpc/mach-mpc5xxx/Kconfig +++ b/arch/powerpc/mach-mpc5xxx/Kconfig @@ -34,17 +34,4 @@ depends on MACH_PHYCORE_MPC5200B_TINY default y -menu "Board specific settings" - -config MACH_PHYCORE_MPC5200B_TINY_REV - int "Board Revision" - default 1 - depends on MACH_PHYCORE_MPC5200B_TINY - help - Revision 0 and revision 1 of the tiny board have - incompatible flash settings. Unless you have a very - old board you should set this option to 1 - -endmenu - endif diff --git a/arch/x86/mach-i386/Kconfig b/arch/x86/mach-i386/Kconfig index b64d21f..2d0bfb4 100644 --- a/arch/x86/mach-i386/Kconfig +++ b/arch/x86/mach-i386/Kconfig @@ -3,26 +3,11 @@ if X86_BOOTLOADER -config X86_GENERIC_HAS_ISA - bool "ISA support" - help - Say Y here if the target supports a ISA bus - -config X86_GENERIC_HAS_PCI - bool "PCI support" - help - Say Y here if the target supports a PCI bus - config X86_GENERIC_HAS_VIDEO bool "video support" help Say Y here if the target supports a video output -config X86_GENERIC_HAS_USB - bool "USB support" - help - Say Y here if the target supports a USB interface - endif endmenu diff --git a/commands/Kconfig b/commands/Kconfig index a0c2828..8de98ef 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -28,22 +28,6 @@ help List clock configuration. -config CMD_AT91MUX - bool "at91mux" - default y - depends on ARCH_AT91 - help - List MUX configuration - - Usage: at91mux [-pb] - - Dump current MUX configuration. If a BANK or PIN has been - specified dump pin details. - - Options: - -p PIN pin number - -b BANK bank number - config CMD_ARM_CPUINFO bool "cpuinfo command" default y @@ -809,7 +793,7 @@ select FILETYPE prompt "filetype" help -Detect file type + Detect file type Usage: filetype [-vsl] FILE diff --git a/common/Kconfig b/common/Kconfig index f514e3b..460ac48 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -144,9 +144,6 @@ which is done within the script "scripts/setlocalversion".) -config BOARDINFO - string - config BANNER bool "display banner" default y diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index d202d76..9bb4985 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -7,9 +7,6 @@ config HAS_CS8900 bool -config HAS_DESIGNWARE_ETH - bool - config HAS_DM9000 bool diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index 3628a88..b3cfb65 100644 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c @@ -273,7 +273,7 @@ { enc28j60_regw_write(priv, ERDPTL, addr); - if (IS_ENABLED(CONFIG_ENC28J60_WRITEVERIFY)) { + if (IS_ENABLED(CONFIG_DRIVER_NET_ENC28J60_WRITEVERIFY)) { u16 reg; reg = enc28j60_regw_read(priv, ERDPTL); if (reg != addr) @@ -293,7 +293,7 @@ /* Set the write pointer to start of transmit buffer area */ enc28j60_regw_write(priv, EWRPTL, TXSTART_INIT); - if (IS_ENABLED(CONFIG_ENC28J60_WRITEVERIFY)) { + if (IS_ENABLED(CONFIG_DRIVER_NET_ENC28J60_WRITEVERIFY)) { u16 reg; reg = enc28j60_regw_read(priv, EWRPTL); if (reg != TXSTART_INIT) @@ -710,7 +710,7 @@ enc28j60_packet_write(priv, packet_length, packet); /* readback and verify written data */ - if (IS_ENABLED(CONFIG_ENC28J60_WRITEVERIFY)) { + if (IS_ENABLED(CONFIG_DRIVER_NET_ENC28J60_WRITEVERIFY)) { int test_len, k; u8 test_buf[64]; /* limit the test to the first 64 bytes */ int okflag; @@ -808,7 +808,7 @@ enc28j60_regw_write(priv, ERXRDPTL, erxrdpt); - if (IS_ENABLED(CONFIG_ENC28J60_WRITEVERIFY)) { + if (IS_ENABLED(CONFIG_DRIVER_NET_ENC28J60_WRITEVERIFY)) { u16 reg; reg = enc28j60_regw_read(priv, ERXRDPTL); if (reg != erxrdpt) diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 9ed86af..23be25d 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -18,10 +18,6 @@ config OF_ADDRESS_PCI bool -config OF_NET - depends on NET - def_bool y - config OF_GPIO depends on GPIOLIB depends on OFDEVICE diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig index 8e56dd7..eb4a755 100644 --- a/drivers/phy/freescale/Kconfig +++ b/drivers/phy/freescale/Kconfig @@ -1,4 +1,4 @@ config PHY_FSL_IMX8MQ_USB bool "Freescale i.MX8M USB3 PHY" - default SOC_IMX8MQ + default ARCH_IMX8MQ diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 589b0e7..6de9d94 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -93,8 +93,6 @@ The pinmux controller found on the Tegra 124 line of SoCs used for the SerDes lanes. -source "drivers/pinctrl/mvebu/Kconfig" - config PINCTRL_VF610 bool default y if ARCH_VF610 diff --git a/drivers/pinctrl/mvebu/Kconfig b/drivers/pinctrl/mvebu/Kconfig deleted file mode 100644 index af20cad..0000000 --- a/drivers/pinctrl/mvebu/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -config PINCTRL_ARMADA_370 - default y if ARCH_ARMADA_370 - bool - -config PINCTRL_ARMADA_XP - bool - default y if ARCH_ARMADA_XP - -config PINCTRL_DOVE - bool - default y if ARCH_DOVE - -config PINCTRL_KIRKWOOD - bool - default y if ARCH_KIRKWOOD diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 048f208..9befc5e 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -16,7 +16,7 @@ config RESET_IMX7 bool "i.MX7 Reset Driver" - default SOC_IMX7D + default ARCH_IMX7 select MFD_SYSCON help This enables the reset controller driver for i.MX7 SoCs. diff --git a/lib/Kconfig b/lib/Kconfig index 081fffb..b4a8079 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -68,6 +68,9 @@ source "lib/lzo/Kconfig" +config BCH_CONST_PARAMS + bool + config BCH bool diff --git a/scripts/kconfig-lint.py b/scripts/kconfig-lint.py new file mode 100755 index 0000000..a154e9c --- /dev/null +++ b/scripts/kconfig-lint.py @@ -0,0 +1,329 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2019 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 AND ISC + +""" +Linter for the Zephyr Kconfig files. Pass --help to see +available checks. By default, all checks are enabled. + +Some of the checks rely on heuristics and can get tripped up +by things like preprocessor magic, so manual checking is +still needed. 'git grep' is handy. +""" + +import argparse +import os +import re +import shlex +import subprocess +import sys +import tempfile + +TOP_DIR = os.path.join(os.path.dirname(__file__), "..") + +import kconfiglib + + +def main(): + init_kconfig() + + args = parse_args() + if args.checks: + checks = args.checks + else: + # Run all checks if no checks were specified + checks = (check_always_n, + check_unused, + check_undefined, + check_pointless_menuconfigs, + check_missing_config_prefix) + + first = True + for check in checks: + if not first: + print() + first = False + check() + + +def parse_args(): + # args.checks is set to a list of check functions to run + + parser = argparse.ArgumentParser( + formatter_class=argparse.RawTextHelpFormatter, + description=__doc__) + + parser.add_argument( + "-n", "--check-always-n", + action="append_const", dest="checks", const=check_always_n, + help="""\ +List symbols that can never be anything but n/empty. These +are detected as symbols with no prompt or defaults that +aren't selected or implied. +""") + + parser.add_argument( + "-u", "--check-unused", + action="append_const", dest="checks", const=check_unused, + help="""\ +List symbols that might be unused. + +Heuristic: + + - Isn't referenced in Kconfig + - Isn't referenced as CONFIG_ outside Kconfig + (besides possibly as CONFIG_=) + - Isn't selecting/implying other symbols + - Isn't a choice symbol + +C preprocessor magic can trip up this check.""") + + parser.add_argument( + "-U", "--check-undefined", + action="append_const", dest="checks", const=check_undefined, + help="""\ +List symbols that are used in a Kconfig file but are undefined +""") + + parser.add_argument( + "-m", "--check-pointless-menuconfigs", + action="append_const", dest="checks", const=check_pointless_menuconfigs, + help="""\ +List symbols defined with 'menuconfig' where the menu is +empty due to the symbol not being followed by stuff that +depends on it""") + + parser.add_argument( + "-p", "--check-missing-config-prefix", + action="append_const", dest="checks", const=check_missing_config_prefix, + help="""\ +Look for references like + + #if MACRO + #if(n)def MACRO + defined(MACRO) + IS_ENABLED(MACRO) + +where MACRO is the name of a defined Kconfig symbol but +doesn't have a CONFIG_ prefix. Could be a typo. + +Macros that are #define'd somewhere are not flagged.""") + + return parser.parse_args() + + +def check_always_n(): + print_header("Symbols that can't be anything but n/empty") + for sym in kconf.unique_defined_syms: + if not has_prompt(sym) and not is_selected_or_implied(sym) and \ + not has_defaults(sym): + print(name_and_locs(sym)) + + +def check_unused(): + print_header("Symbols that look unused") + referenced = referenced_sym_names() + for sym in kconf.unique_defined_syms: + if not is_selecting_or_implying(sym) and not sym.choice and \ + sym.name not in referenced: + print(name_and_locs(sym)) + +def check_undefined(): + print_header("Symbols that are used, but undefined") + for name, sym in kconf.syms.items(): + if not sym.nodes: + # Undefined symbol. We skip some of the uninteresting ones. + + # Due to how Kconfig works, integer literals show up as symbols + # (from e.g. 'default 1'). Skip those. + try: + int(name, 0) + continue + except ValueError: + # Interesting undefined symbol + print(name) + + +def check_pointless_menuconfigs(): + print_header("menuconfig symbols with empty menus") + for node in kconf.node_iter(): + if node.is_menuconfig and not node.list and \ + isinstance(node.item, kconfiglib.Symbol): + print("{0.item.name:40} {0.filename}:{0.linenr}".format(node)) + + +def check_missing_config_prefix(): + print_header("Symbol references that might be missing a CONFIG_ prefix") + + # Paths to modules + modpaths = [TOP_DIR] + + # Gather #define'd macros that might overlap with symbol names, so that + # they don't trigger false positives + defined = set() + for modpath in modpaths: + regex = r"#\s*define\s+([A-Z0-9_]+)\b" + defines = run(("git", "grep", "--extended-regexp", regex), + cwd=modpath, check=False) + # Could pass --only-matching to git grep as well, but it was added + # pretty recently (2018) + defined.update(re.findall(regex, defines)) + + # Filter out symbols whose names are #define'd too. Preserve definition + # order to make the output consistent. + syms = [sym for sym in kconf.unique_defined_syms + if sym.name not in defined] + + # grep for symbol references in #ifdef/defined() that are missing a CONFIG_ + # prefix. Work around an "argument list too long" error from 'git grep' by + # checking symbols in batches. + for batch in split_list(syms, 200): + # grep for '#if((n)def) ', 'defined(', and + # 'IS_ENABLED(', with a missing CONFIG_ prefix + regex = r"(?:#\s*if(?:n?def)\s+|\bdefined\s*\(\s*|IS_ENABLED\(\s*)(?:" + \ + "|".join(sym.name for sym in batch) + r")\b" + cmd = ("git", "grep", "--line-number", "-I", "--perl-regexp", regex) + + for modpath in modpaths: + print(run(cmd, cwd=modpath, check=False), end="") + + +def split_list(lst, batch_size): + # check_missing_config_prefix() helper generator that splits a list into + # equal-sized batches (possibly with a shorter batch at the end) + + for i in range(0, len(lst), batch_size): + yield lst[i:i + batch_size] + + +def print_header(s): + print(s + "\n" + len(s)*"=") + + +def init_kconfig(): + global kconf + + os.environ.update( + srctree=TOP_DIR, + KCONFIG_DOC_MODE="1", + ARCH_DIR="arch", + SRCARCH="*") + + kconf = kconfiglib.Kconfig(suppress_traceback=True) + + +def referenced_sym_names(): + # Returns the names of all symbols referenced inside and outside the + # Kconfig files (that we can detect), without any "CONFIG_" prefix + + return referenced_in_kconfig() | referenced_outside_kconfig() + + +def referenced_in_kconfig(): + # Returns the names of all symbols referenced inside the Kconfig files + + return {ref.name + for node in kconf.node_iter() + for ref in node.referenced + if isinstance(ref, kconfiglib.Symbol)} + + +def referenced_outside_kconfig(): + # Returns the names of all symbols referenced outside the Kconfig files + + regex = r"\bCONFIG_[A-Z0-9_]+\b" + + res = set() + + # 'git grep' all modules + for modpath in [TOP_DIR]: + for line in run(("git", "grep", "-h", "-I", "--extended-regexp", regex), + cwd=modpath).splitlines(): + # Don't record lines starting with "CONFIG_FOO=" or "# CONFIG_FOO=" + # as references, so that symbols that are only assigned in .config + # files are not included + if re.match(r"[\s#]*CONFIG_[A-Z0-9_]+=.*", line): + continue + + # Could pass --only-matching to git grep as well, but it was added + # pretty recently (2018) + for match in re.findall(regex, line): + res.add(match[7:]) # Strip "CONFIG_" + + return res + + +def has_prompt(sym): + return any(node.prompt for node in sym.nodes) + + +def is_selected_or_implied(sym): + return sym.rev_dep is not kconf.n or sym.weak_rev_dep is not kconf.n + + +def has_defaults(sym): + return bool(sym.defaults) + + +def is_selecting_or_implying(sym): + return sym.selects or sym.implies + + +def name_and_locs(sym): + # Returns a string with the name and definition location(s) for 'sym' + + return "{:40} {}".format( + sym.name, + ", ".join("{0.filename}:{0.linenr}".format(node) for node in sym.nodes)) + + +def run(cmd, cwd=TOP_DIR, check=True): + # Runs 'cmd' with subprocess, returning the decoded stdout output. 'cwd' is + # the working directory. It defaults to the top-level Zephyr directory. + # Exits with an error if the command exits with a non-zero return code if + # 'check' is True. + + cmd_s = " ".join(shlex.quote(word) for word in cmd) + + try: + process = subprocess.Popen( + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd) + except OSError as e: + err("Failed to run '{}': {}".format(cmd_s, e)) + + stdout, stderr = process.communicate() + # errors="ignore" temporarily works around + # https://github.com/zephyrproject-rtos/esp-idf/pull/2 + stdout = stdout.decode("utf-8", errors="ignore") + stderr = stderr.decode("utf-8") + if check and process.returncode: + err("""\ +'{}' exited with status {}. + +===stdout=== +{} +===stderr=== +{}""".format(cmd_s, process.returncode, stdout, stderr)) + + if stderr: + warn("'{}' wrote to stderr:\n{}".format(cmd_s, stderr)) + + return stdout + + +def err(msg): + sys.exit(executable() + "error: " + msg) + + +def warn(msg): + print(executable() + "warning: " + msg, file=sys.stderr) + + +def executable(): + cmd = sys.argv[0] # Empty string if missing + return cmd + ": " if cmd else "" + + +if __name__ == "__main__": + main()