162306a36Sopenharmony_ci#!/usr/bin/env perl
262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0-only
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci# Copyright 2016 by Frank Rowand
562306a36Sopenharmony_ci# Copyright 2016 by Gaurav Minocha
662306a36Sopenharmony_ci#
762306a36Sopenharmony_ci
862306a36Sopenharmony_ciuse strict 'refs';
962306a36Sopenharmony_ciuse strict subs;
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ciuse Getopt::Long;
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci$VUFX = "160610a";
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci$script_name = $0;
1662306a36Sopenharmony_ci$script_name =~ s|^.*/||;
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci# ----- constants for print_flags()
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci# Position in string $pr_flags.  Range of 0..($num_pr_flags - 1).
2262306a36Sopenharmony_ci$pr_flag_pos_mcompatible       = 0;
2362306a36Sopenharmony_ci$pr_flag_pos_driver            = 1;
2462306a36Sopenharmony_ci$pr_flag_pos_mdriver           = 2;
2562306a36Sopenharmony_ci$pr_flag_pos_config            = 3;
2662306a36Sopenharmony_ci$pr_flag_pos_mconfig           = 4;
2762306a36Sopenharmony_ci$pr_flag_pos_node_not_enabled  = 5;
2862306a36Sopenharmony_ci$pr_flag_pos_white_list        = 6;
2962306a36Sopenharmony_ci$pr_flag_pos_hard_coded        = 7;
3062306a36Sopenharmony_ci$pr_flag_pos_config_hard_coded = 8;
3162306a36Sopenharmony_ci$pr_flag_pos_config_none       = 9;
3262306a36Sopenharmony_ci$pr_flag_pos_config_m          = 10;
3362306a36Sopenharmony_ci$pr_flag_pos_config_y          = 11;
3462306a36Sopenharmony_ci$pr_flag_pos_config_test_fail  = 12;
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci$num_pr_flags = $pr_flag_pos_config_test_fail + 1;
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci# flags in @pr_flag_value must be unique values to allow simple regular
3962306a36Sopenharmony_ci# expessions to work for --include_flags and --exclude_flags.
4062306a36Sopenharmony_ci# Convention: use upper case letters for potential issues or problems.
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci@pr_flag_value = ('M', 'd', 'D', 'c', 'C', 'E', 'W', 'H', 'x', 'n', 'm', 'y', 'F');
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci@pr_flag_help = (
4562306a36Sopenharmony_ci    "multiple compatibles found for this node",
4662306a36Sopenharmony_ci    "driver found for this compatible",
4762306a36Sopenharmony_ci    "multiple drivers found for this compatible",
4862306a36Sopenharmony_ci    "kernel config found for this driver",
4962306a36Sopenharmony_ci    "multiple config options found for this driver",
5062306a36Sopenharmony_ci    "node is not enabled",
5162306a36Sopenharmony_ci    "compatible is white listed",
5262306a36Sopenharmony_ci    "matching driver and/or kernel config is hard coded",
5362306a36Sopenharmony_ci    "kernel config hard coded in Makefile",
5462306a36Sopenharmony_ci    "one or more kernel config file options is not set",
5562306a36Sopenharmony_ci    "one or more kernel config file options is set to 'm'",
5662306a36Sopenharmony_ci    "one or more kernel config file options is set to 'y'",
5762306a36Sopenharmony_ci    "one of more kernel config file options fails to have correct value"
5862306a36Sopenharmony_ci);
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci# -----
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci%driver_config = ();   # driver config array, indexed by driver source file
6462306a36Sopenharmony_ci%driver_count = ();    # driver_cnt, indexed by compatible
6562306a36Sopenharmony_ci%compat_driver = ();   # compatible driver array, indexed by compatible
6662306a36Sopenharmony_ci%existing_config = (); # existing config symbols present in given config file
6762306a36Sopenharmony_ci                       # expected values are: "y", "m", a decimal number, a
6862306a36Sopenharmony_ci                       # hex number, or a string
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci# ----- magic compatibles, do not have a driver
7162306a36Sopenharmony_ci#
7262306a36Sopenharmony_ci# Will not search for drivers for these compatibles.
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci%compat_white_list = (
7562306a36Sopenharmony_ci       'none'                  => '1',
7662306a36Sopenharmony_ci       'pci'                   => '1',
7762306a36Sopenharmony_ci       'simple-bus'            => '1',
7862306a36Sopenharmony_ci);
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci# Will not search for drivers for these compatibles.
8162306a36Sopenharmony_ci#
8262306a36Sopenharmony_ci# These compatibles have a very large number of false positives.
8362306a36Sopenharmony_ci#
8462306a36Sopenharmony_ci# 'hardcoded_no_driver' is a magic value.  Other code knows this
8562306a36Sopenharmony_ci# magic value.  Do not use 'no_driver' here!
8662306a36Sopenharmony_ci#
8762306a36Sopenharmony_ci# Revisit each 'hardcoded_no_driver' to see how the compatible
8862306a36Sopenharmony_ci# is used.  Are there drivers that can be provided?
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci%driver_hard_code_list = (
9162306a36Sopenharmony_ci       'cache'                 => ['hardcoded_no_driver'],
9262306a36Sopenharmony_ci       'eeprom'                => ['hardcoded_no_driver'],
9362306a36Sopenharmony_ci       'gpio'                  => ['hardcoded_no_driver'],
9462306a36Sopenharmony_ci       'gpio-keys'             => ['drivers/input/keyboard/gpio_keys.c'],
9562306a36Sopenharmony_ci       'i2c-gpio'              => ['drivers/i2c/busses/i2c-gpio.c'],
9662306a36Sopenharmony_ci       'isa'                   => ['arch/mips/mti-malta/malta-dt.c',
9762306a36Sopenharmony_ci                                    'arch/x86/kernel/devicetree.c'],
9862306a36Sopenharmony_ci       'led'                   => ['hardcoded_no_driver'],
9962306a36Sopenharmony_ci       'm25p32'                => ['hardcoded_no_driver'],
10062306a36Sopenharmony_ci       'm25p64'                => ['hardcoded_no_driver'],
10162306a36Sopenharmony_ci       'm25p80'                => ['hardcoded_no_driver'],
10262306a36Sopenharmony_ci       'mtd-ram'               => ['drivers/mtd/maps/physmap_of.c'],
10362306a36Sopenharmony_ci       'pwm-backlight'         => ['drivers/video/backlight/pwm_bl.c'],
10462306a36Sopenharmony_ci       'spidev'                => ['hardcoded_no_driver'],
10562306a36Sopenharmony_ci       'syscon'                => ['drivers/mfd/syscon.c'],
10662306a36Sopenharmony_ci       'tlv320aic23'           => ['hardcoded_no_driver'],
10762306a36Sopenharmony_ci       'wm8731'                => ['hardcoded_no_driver'],
10862306a36Sopenharmony_ci);
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci# Use these config options instead of searching makefiles
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci%driver_config_hard_code_list = (
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci       # this one needed even if %driver_hard_code_list is empty
11562306a36Sopenharmony_ci       'no_driver'                             => ['no_config'],
11662306a36Sopenharmony_ci       'hardcoded_no_driver'                   => ['no_config'],
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci       # drivers/usb/host/ehci-ppc-of.c
11962306a36Sopenharmony_ci       # drivers/usb/host/ehci-xilinx-of.c
12062306a36Sopenharmony_ci       #  are included from:
12162306a36Sopenharmony_ci       #    drivers/usb/host/ehci-hcd.c
12262306a36Sopenharmony_ci       #  thus the search of Makefile for the included .c files is incorrect
12362306a36Sopenharmony_ci       # ehci-hcd.c wraps the includes with ifdef CONFIG_USB_EHCI_HCD_..._OF
12462306a36Sopenharmony_ci       #
12562306a36Sopenharmony_ci       # similar model for ohci-hcd.c (but no ohci-xilinx-of.c)
12662306a36Sopenharmony_ci       #
12762306a36Sopenharmony_ci       # similarly, uhci-hcd.c includes uhci-platform.c
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci       'drivers/usb/host/ehci-ppc-of.c'        => ['CONFIG_USB_EHCI_HCD',
13062306a36Sopenharmony_ci                                                   'CONFIG_USB_EHCI_HCD_PPC_OF'],
13162306a36Sopenharmony_ci       'drivers/usb/host/ohci-ppc-of.c'        => ['CONFIG_USB_OHCI_HCD',
13262306a36Sopenharmony_ci                                                   'CONFIG_USB_OHCI_HCD_PPC_OF'],
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci       'drivers/usb/host/ehci-xilinx-of.c'     => ['CONFIG_USB_EHCI_HCD',
13562306a36Sopenharmony_ci                                                   'CONFIG_USB_EHCI_HCD_XILINX'],
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci       'drivers/usb/host/uhci-platform.c'      => ['CONFIG_USB_UHCI_HCD',
13862306a36Sopenharmony_ci                                                   'CONFIG_USB_UHCI_PLATFORM'],
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci       # scan_makefile will find only one of these config options:
14162306a36Sopenharmony_ci       #    ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_LS1021A),)
14262306a36Sopenharmony_ci       'arch/arm/mach-imx/platsmp.c'           => ['CONFIG_SOC_IMX6 && CONFIG_SMP',
14362306a36Sopenharmony_ci                                                   'CONFIG_SOC_LS1021A && CONFIG_SMP'],
14462306a36Sopenharmony_ci);
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci# 'virt/kvm/arm/.*' are controlled by makefiles in other directories,
14862306a36Sopenharmony_ci# using relative paths, such as 'KVM := ../../../virt/kvm'.  Do not
14962306a36Sopenharmony_ci# add complexity to find_kconfig() to deal with this.  There is a long
15062306a36Sopenharmony_ci# term intent to change the kvm related makefiles to the normal kernel
15162306a36Sopenharmony_ci# style.  After that is done, this entry can be removed from the
15262306a36Sopenharmony_ci# black_list_driver.
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci@black_list_driver = (
15562306a36Sopenharmony_ci       # kvm no longer a problem after commit 503a62862e8f in 4.7-rc1
15662306a36Sopenharmony_ci       # 'virt/kvm/arm/.*',
15762306a36Sopenharmony_ci);
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_cisub usage()
16162306a36Sopenharmony_ci{
16262306a36Sopenharmony_ci       print
16362306a36Sopenharmony_ci"
16462306a36Sopenharmony_ciUsage: $script_name [options] device-tree...
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci    device_tree is: dts_file | dtb_file | proc_device-tree
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ciValid options:
17062306a36Sopenharmony_ci     -c FILE             Read kernel config options from FILE
17162306a36Sopenharmony_ci    --config FILE        synonym for 'c'
17262306a36Sopenharmony_ci    --config-format      config file friendly output format
17362306a36Sopenharmony_ci    --exclude-flag FLAG  exclude entries with a matching flag
17462306a36Sopenharmony_ci     -h                  Display this message and exit
17562306a36Sopenharmony_ci    --help               synonym for 'h'
17662306a36Sopenharmony_ci    --black-list-driver  use driver black list
17762306a36Sopenharmony_ci    --white-list-config  use config white list
17862306a36Sopenharmony_ci    --white-list-driver  use driver white list
17962306a36Sopenharmony_ci    --include-flag FLAG  include only entries with a matching flag
18062306a36Sopenharmony_ci    --include-suspect    include only entries with an uppercase flag
18162306a36Sopenharmony_ci    --short-name         do not show the path portion of the node name
18262306a36Sopenharmony_ci    --show-lists         report of white and black lists
18362306a36Sopenharmony_ci    --version            Display program version and exit
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci  Report driver source files that match the compatibles in the device
18762306a36Sopenharmony_ci  tree file and the kernel config options that enable the driver source
18862306a36Sopenharmony_ci  files.
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci  This program must be run in the root directory of a Linux kernel
19162306a36Sopenharmony_ci  source tree.
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci  The default format is a report that is intended to be easily human
19462306a36Sopenharmony_ci  scannable.
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci  An alternate format can be selected by --config-format.  This will
19762306a36Sopenharmony_ci  create output that can easily be edited to create a fragment that can
19862306a36Sopenharmony_ci  be appended to the existing kernel config file.  Each entry consists of
19962306a36Sopenharmony_ci  multiple lines.  The first line reports flags, the node path, compatible
20062306a36Sopenharmony_ci  value, driver file matching the compatible, configuration options, and
20162306a36Sopenharmony_ci  current values of the configuration options.  For each configuration
20262306a36Sopenharmony_ci  option, the following lines report the current value and the value that
20362306a36Sopenharmony_ci  is required for the driver file to be included in the kernel.
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci  If a large number of drivers or config options is listed for a node,
20662306a36Sopenharmony_ci  and the '$pr_flag_value[$pr_flag_pos_hard_coded]' flag is set consider using --white-list-config and/or
20762306a36Sopenharmony_ci  --white-list-driver.  If the white list option suppresses the correct
20862306a36Sopenharmony_ci  entry please report that as a bug.
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci  CAUTION:
21162306a36Sopenharmony_ci     This program uses heuristics to guess which driver(s) support each
21262306a36Sopenharmony_ci     compatible string and which config option(s) enables the driver(s).
21362306a36Sopenharmony_ci     Do not believe that the reported information is fully correct.
21462306a36Sopenharmony_ci     This program is intended to aid the process of determining the
21562306a36Sopenharmony_ci     proper kernel configuration for a device tree, but this is not
21662306a36Sopenharmony_ci     a fully automated process -- human involvement may still be
21762306a36Sopenharmony_ci     required!
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci     The driver match heuristic used is to search for source files
22062306a36Sopenharmony_ci     containing the compatible string enclosed in quotes.
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci     This program might not be able to find all drivers matching a
22362306a36Sopenharmony_ci     compatible string.
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci     Some makefiles are overly clever.  This program was not made
22662306a36Sopenharmony_ci     complex enough to handle them.  If no config option is listed
22762306a36Sopenharmony_ci     for a driver, look at the makefile for the driver source file.
22862306a36Sopenharmony_ci     Even if a config option is listed for a driver, some other
22962306a36Sopenharmony_ci     available config options may not be listed.
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci  FLAG values:
23262306a36Sopenharmony_ci";
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci       for ($k = 0; $k < $num_pr_flags; $k++) {
23562306a36Sopenharmony_ci               printf "     %s   %s\n", $pr_flag_value[$k], $pr_flag_help[$k];
23662306a36Sopenharmony_ci       }
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci       print
23962306a36Sopenharmony_ci"
24062306a36Sopenharmony_ci     Upper case letters indicate potential issues or problems.
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci  The flag:
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci";
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci       $k = $pr_flag_pos_hard_coded;
24762306a36Sopenharmony_ci       printf "     %s   %s\n", $pr_flag_value[$k], $pr_flag_help[$k];
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci       print
25062306a36Sopenharmony_ci"
25162306a36Sopenharmony_ci  will be set if the config or driver is in the white lists, even if
25262306a36Sopenharmony_ci  --white-list-config and --white-list-driver are not specified.
25362306a36Sopenharmony_ci  This is a hint that 1) many of these reported lines are likely to
25462306a36Sopenharmony_ci  be incorrect, and 2) using those options will reduce the number of
25562306a36Sopenharmony_ci  drivers and/or config options reported.
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci  --white-list-config and --white-list-driver may not be accurate if this
25862306a36Sopenharmony_ci  program is not well maintained.  Use them with appropriate skepticism.
25962306a36Sopenharmony_ci  Use the --show-lists option to report the values in the list.
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci  Return value:
26262306a36Sopenharmony_ci    0   if no error
26362306a36Sopenharmony_ci    1   error processing command line
26462306a36Sopenharmony_ci    2   unable to open or read kernel config file
26562306a36Sopenharmony_ci    3   unable to open or process input device tree file(s)
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci  EXAMPLES:
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci     dt_to_config arch/arm/boot/dts/my_dts_file.dts
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci       Basic report.
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci     dt_to_config \\
27462306a36Sopenharmony_ci        --config \${KBUILD_OUTPUT}/.config \\
27562306a36Sopenharmony_ci        arch/\${ARCH}/boot/dts/my_dts_file.dts
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci       Full report, with config file issues noted.
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci     dt_to_config --include-suspect \\
28062306a36Sopenharmony_ci        --config \${KBUILD_OUTPUT}/.config \\
28162306a36Sopenharmony_ci        arch/\${ARCH}/boot/dts/my_dts_file.dts
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci       Report of node / compatible string / driver tuples that should
28462306a36Sopenharmony_ci       be further investigated.  A node may have multiple compatible
28562306a36Sopenharmony_ci       strings.  A compatible string may be matched by multiple drivers.
28662306a36Sopenharmony_ci       A driver may have config file issues noted.  The compatible string
28762306a36Sopenharmony_ci       and/or driver may be in the white lists.
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci     dt_to_config --include-suspect --config-format \\
29062306a36Sopenharmony_ci        --config ${KBUILD_OUTPUT}/.config \\
29162306a36Sopenharmony_ci        arch/\${ARCH}/boot/dts/my_dts_file.dts
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci       Report of node / compatible string / driver tuples that should
29462306a36Sopenharmony_ci       be further investigated.  The report can be edited to uncomment
29562306a36Sopenharmony_ci       the config options to select the desired tuple for a given node.
29662306a36Sopenharmony_ci       A node may have multiple compatible strings.  A compatible string
29762306a36Sopenharmony_ci       may be matched by multiple drivers.  A driver may have config file
29862306a36Sopenharmony_ci       issues noted.  The compatible string and/or driver may be in the
29962306a36Sopenharmony_ci       white lists.
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci";
30262306a36Sopenharmony_ci}
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_cisub set_flag()
30562306a36Sopenharmony_ci{
30662306a36Sopenharmony_ci       # pr_flags_ref is a reference to $pr_flags
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci       my $pr_flags_ref = shift;
30962306a36Sopenharmony_ci       my $pos          = shift;
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci       substr $$pr_flags_ref, $pos, 1, $pr_flag_value[$pos];
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci       return $pr_flags;
31462306a36Sopenharmony_ci}
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_cisub print_flags()
31762306a36Sopenharmony_ci{
31862306a36Sopenharmony_ci       # return 1 if anything printed, else 0
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci       # some fields of pn_arg_ref might not be used in this function, but
32162306a36Sopenharmony_ci       # extract all of them anyway.
32262306a36Sopenharmony_ci       my $pn_arg_ref     = shift;
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci       my $compat         = $pn_arg_ref->{compat};
32562306a36Sopenharmony_ci       my $compatible_cnt = $pn_arg_ref->{compatible_cnt};
32662306a36Sopenharmony_ci       my $config         = $pn_arg_ref->{config};
32762306a36Sopenharmony_ci       my $config_cnt     = $pn_arg_ref->{config_cnt};
32862306a36Sopenharmony_ci       my $driver         = $pn_arg_ref->{driver};
32962306a36Sopenharmony_ci       my $driver_cnt     = $pn_arg_ref->{driver_cnt};
33062306a36Sopenharmony_ci       my $full_node      = $pn_arg_ref->{full_node};
33162306a36Sopenharmony_ci       my $node           = $pn_arg_ref->{node};
33262306a36Sopenharmony_ci       my $node_enabled   = $pn_arg_ref->{node_enabled};
33362306a36Sopenharmony_ci       my $white_list     = $pn_arg_ref->{white_list};
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci       my $pr_flags       = '-' x $num_pr_flags;
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci       # ----- set flags in $pr_flags
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci       if ($compatible_cnt > 1) {
34162306a36Sopenharmony_ci               &set_flag(\$pr_flags, $pr_flag_pos_mcompatible);
34262306a36Sopenharmony_ci       }
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci       if ($config_cnt > 1) {
34562306a36Sopenharmony_ci               &set_flag(\$pr_flags, $pr_flag_pos_mconfig);
34662306a36Sopenharmony_ci       }
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci       if ($driver_cnt >= 1) {
34962306a36Sopenharmony_ci               &set_flag(\$pr_flags, $pr_flag_pos_driver);
35062306a36Sopenharmony_ci       }
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci       if ($driver_cnt > 1) {
35362306a36Sopenharmony_ci               &set_flag(\$pr_flags, $pr_flag_pos_mdriver);
35462306a36Sopenharmony_ci       }
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci       # These strings are the same way the linux kernel tests.
35762306a36Sopenharmony_ci       # The ePapr lists of values is slightly different.
35862306a36Sopenharmony_ci       if (!(
35962306a36Sopenharmony_ci             ($node_enabled eq "") ||
36062306a36Sopenharmony_ci             ($node_enabled eq "ok") ||
36162306a36Sopenharmony_ci             ($node_enabled eq "okay")
36262306a36Sopenharmony_ci            )) {
36362306a36Sopenharmony_ci               &set_flag(\$pr_flags, $pr_flag_pos_node_not_enabled);
36462306a36Sopenharmony_ci       }
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci       if ($white_list) {
36762306a36Sopenharmony_ci               &set_flag(\$pr_flags, $pr_flag_pos_white_list);
36862306a36Sopenharmony_ci       }
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci       if (exists($driver_hard_code_list{$compat}) ||
37162306a36Sopenharmony_ci           (exists($driver_config_hard_code_list{$driver}) &&
37262306a36Sopenharmony_ci            ($driver ne "no_driver"))) {
37362306a36Sopenharmony_ci               &set_flag(\$pr_flags, $pr_flag_pos_hard_coded);
37462306a36Sopenharmony_ci       }
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci       my @configs = split(' && ', $config);
37762306a36Sopenharmony_ci       for $configs (@configs) {
37862306a36Sopenharmony_ci               $not = $configs =~ /^!/;
37962306a36Sopenharmony_ci               $configs =~ s/^!//;
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci               if (($configs ne "no_config") && ($configs ne "no_makefile")) {
38262306a36Sopenharmony_ci                       &set_flag(\$pr_flags, $pr_flag_pos_config);
38362306a36Sopenharmony_ci               }
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci               if (($config_cnt >= 1) &&
38662306a36Sopenharmony_ci                   ($configs !~ /CONFIG_/) &&
38762306a36Sopenharmony_ci                   (($configs ne "no_config") && ($configs ne "no_makefile"))) {
38862306a36Sopenharmony_ci                       &set_flag(\$pr_flags, $pr_flag_pos_config_hard_coded);
38962306a36Sopenharmony_ci               }
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci               my $existing_config = $existing_config{$configs};
39262306a36Sopenharmony_ci               if ($existing_config eq "m") {
39362306a36Sopenharmony_ci                       &set_flag(\$pr_flags, $pr_flag_pos_config_m);
39462306a36Sopenharmony_ci                       # Possible fail, depends on whether built in or
39562306a36Sopenharmony_ci                       # module is desired.
39662306a36Sopenharmony_ci                       &set_flag(\$pr_flags, $pr_flag_pos_config_test_fail);
39762306a36Sopenharmony_ci               } elsif ($existing_config eq "y") {
39862306a36Sopenharmony_ci                       &set_flag(\$pr_flags, $pr_flag_pos_config_y);
39962306a36Sopenharmony_ci                       if ($not) {
40062306a36Sopenharmony_ci                               &set_flag(\$pr_flags, $pr_flag_pos_config_test_fail);
40162306a36Sopenharmony_ci                       }
40262306a36Sopenharmony_ci               } elsif (($config_file) && ($configs =~ /CONFIG_/)) {
40362306a36Sopenharmony_ci                       &set_flag(\$pr_flags, $pr_flag_pos_config_none);
40462306a36Sopenharmony_ci                       if (!$not) {
40562306a36Sopenharmony_ci                               &set_flag(\$pr_flags, $pr_flag_pos_config_test_fail);
40662306a36Sopenharmony_ci                       }
40762306a36Sopenharmony_ci               }
40862306a36Sopenharmony_ci       }
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci       # ----- include / exclude filters
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci       if ($include_flag_pattern && ($pr_flags !~ m/$include_flag_pattern/)) {
41362306a36Sopenharmony_ci               return 0;
41462306a36Sopenharmony_ci       }
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci       if ($exclude_flag_pattern && ($pr_flags =~ m/$exclude_flag_pattern/)) {
41762306a36Sopenharmony_ci               return 0;
41862306a36Sopenharmony_ci       }
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci       if ($config_format) {
42162306a36Sopenharmony_ci               print "# ";
42262306a36Sopenharmony_ci       }
42362306a36Sopenharmony_ci       print "$pr_flags : ";
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci       return 1;
42662306a36Sopenharmony_ci}
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci
42962306a36Sopenharmony_cisub print_node()
43062306a36Sopenharmony_ci{
43162306a36Sopenharmony_ci       # return number of lines printed
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ci       # some fields of pn_arg_ref might not be used in this function, but
43462306a36Sopenharmony_ci       # extract all of them anyway.
43562306a36Sopenharmony_ci       my $pn_arg_ref     = shift;
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci       my $compat         = $pn_arg_ref->{compat};
43862306a36Sopenharmony_ci       my $compatible_cnt = $pn_arg_ref->{compatible_cnt};
43962306a36Sopenharmony_ci       my $config         = $pn_arg_ref->{config};
44062306a36Sopenharmony_ci       my $config_cnt     = $pn_arg_ref->{config_cnt};
44162306a36Sopenharmony_ci       my $driver         = $pn_arg_ref->{driver};
44262306a36Sopenharmony_ci       my $driver_cnt     = $pn_arg_ref->{driver_cnt};
44362306a36Sopenharmony_ci       my $full_node      = $pn_arg_ref->{full_node};
44462306a36Sopenharmony_ci       my $node           = $pn_arg_ref->{node};
44562306a36Sopenharmony_ci       my $node_enabled   = $pn_arg_ref->{node_enabled};
44662306a36Sopenharmony_ci       my $white_list     = $pn_arg_ref->{white_list};
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci       my $separator;
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci       if (! &print_flags($pn_arg_ref)) {
45162306a36Sopenharmony_ci               return 0;
45262306a36Sopenharmony_ci       }
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci       if ($short_name) {
45662306a36Sopenharmony_ci               print "$node";
45762306a36Sopenharmony_ci       } else {
45862306a36Sopenharmony_ci               print "$full_node";
45962306a36Sopenharmony_ci       }
46062306a36Sopenharmony_ci       print " : $compat : $driver : $config : ";
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci       my @configs = split(' && ', $config);
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci       if ($config_file) {
46562306a36Sopenharmony_ci               for $configs (@configs) {
46662306a36Sopenharmony_ci                       $configs =~ s/^!//;
46762306a36Sopenharmony_ci                       my $existing_config = $existing_config{$configs};
46862306a36Sopenharmony_ci                       if (!$existing_config) {
46962306a36Sopenharmony_ci                               # check for /-m/, /-y/, or /-objs/
47062306a36Sopenharmony_ci                               if ($configs !~ /CONFIG_/) {
47162306a36Sopenharmony_ci                                       $existing_config = "x";
47262306a36Sopenharmony_ci                               };
47362306a36Sopenharmony_ci                       };
47462306a36Sopenharmony_ci                       if ($existing_config) {
47562306a36Sopenharmony_ci                               print "$separator", "$existing_config";
47662306a36Sopenharmony_ci                               $separator = ", ";
47762306a36Sopenharmony_ci                       } else {
47862306a36Sopenharmony_ci                               print "$separator", "n";
47962306a36Sopenharmony_ci                               $separator = ", ";
48062306a36Sopenharmony_ci                       }
48162306a36Sopenharmony_ci               }
48262306a36Sopenharmony_ci       } else {
48362306a36Sopenharmony_ci               print "none";
48462306a36Sopenharmony_ci       }
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci       print "\n";
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_ci       if ($config_format) {
48962306a36Sopenharmony_ci               for $configs (@configs) {
49062306a36Sopenharmony_ci                       $not = $configs =~ /^!/;
49162306a36Sopenharmony_ci                       $configs =~ s/^!//;
49262306a36Sopenharmony_ci                       my $existing_config = $existing_config{$configs};
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_ci                       if ($not) {
49562306a36Sopenharmony_ci                               if ($configs !~ /CONFIG_/) {
49662306a36Sopenharmony_ci                                       print "# $configs\n";
49762306a36Sopenharmony_ci                               } elsif ($existing_config eq "m") {
49862306a36Sopenharmony_ci                                       print "# $configs is m\n";
49962306a36Sopenharmony_ci                                       print "# $configs=n\n";
50062306a36Sopenharmony_ci                               } elsif ($existing_config eq "y") {
50162306a36Sopenharmony_ci                                       print "# $configs is set\n";
50262306a36Sopenharmony_ci                                       print "# $configs=n\n";
50362306a36Sopenharmony_ci                               } else {
50462306a36Sopenharmony_ci                                       print "# $configs is not set\n";
50562306a36Sopenharmony_ci                                       print "# $configs=n\n";
50662306a36Sopenharmony_ci                               }
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci                       } else {
50962306a36Sopenharmony_ci                               if ($configs !~ /CONFIG_/) {
51062306a36Sopenharmony_ci                                       print "# $configs\n";
51162306a36Sopenharmony_ci                               } elsif ($existing_config eq "m") {
51262306a36Sopenharmony_ci                                       print "# $configs is m\n";
51362306a36Sopenharmony_ci                                       print "# $configs=y\n";
51462306a36Sopenharmony_ci                               } elsif ($existing_config eq "y") {
51562306a36Sopenharmony_ci                                       print "# $configs is set\n";
51662306a36Sopenharmony_ci                                       print "# $configs=y\n";
51762306a36Sopenharmony_ci                               } else {
51862306a36Sopenharmony_ci                                       print "# $configs is not set\n";
51962306a36Sopenharmony_ci                                       print "# $configs=y\n";
52062306a36Sopenharmony_ci                               }
52162306a36Sopenharmony_ci                       }
52262306a36Sopenharmony_ci               }
52362306a36Sopenharmony_ci       }
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_ci       return 1;
52662306a36Sopenharmony_ci}
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_cisub scan_makefile
53062306a36Sopenharmony_ci{
53162306a36Sopenharmony_ci       my $pn_arg_ref    = shift;
53262306a36Sopenharmony_ci       my $driver        = shift;
53362306a36Sopenharmony_ci
53462306a36Sopenharmony_ci       # ----- Find Kconfig symbols that enable driver
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci       my ($dir, $base) = $driver =~ m{(.*)/(.*).c};
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ci       my $makefile = $dir . "/Makefile";
53962306a36Sopenharmony_ci       if (! -r $makefile) {
54062306a36Sopenharmony_ci               $makefile = $dir . "/Kbuild";
54162306a36Sopenharmony_ci       }
54262306a36Sopenharmony_ci       if (! -r $makefile) {
54362306a36Sopenharmony_ci               my $config;
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci               $config = 'no_makefile';
54662306a36Sopenharmony_ci               push @{ $driver_config{$driver} }, $config;
54762306a36Sopenharmony_ci               return;
54862306a36Sopenharmony_ci       }
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_ci       if (!open(MAKEFILE_FILE, "<", "$makefile")) {
55162306a36Sopenharmony_ci               return;
55262306a36Sopenharmony_ci       }
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_ci       my $line;
55562306a36Sopenharmony_ci       my @config;
55662306a36Sopenharmony_ci       my @if_config;
55762306a36Sopenharmony_ci       my @make_var;
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_ci       NEXT_LINE:
56062306a36Sopenharmony_ci       while ($next_line = <MAKEFILE_FILE>) {
56162306a36Sopenharmony_ci               my $config;
56262306a36Sopenharmony_ci               my $if_config;
56362306a36Sopenharmony_ci               my $ifdef;
56462306a36Sopenharmony_ci               my $ifeq;
56562306a36Sopenharmony_ci               my $ifndef;
56662306a36Sopenharmony_ci               my $ifneq;
56762306a36Sopenharmony_ci               my $ifdef_config;
56862306a36Sopenharmony_ci               my $ifeq_config;
56962306a36Sopenharmony_ci               my $ifndef_config;
57062306a36Sopenharmony_ci               my $ifneq_config;
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_ci               chomp($next_line);
57362306a36Sopenharmony_ci               $line = $line . $next_line;
57462306a36Sopenharmony_ci               if ($next_line =~ /\\$/) {
57562306a36Sopenharmony_ci                       $line =~ s/\\$/ /;
57662306a36Sopenharmony_ci                       next NEXT_LINE;
57762306a36Sopenharmony_ci               }
57862306a36Sopenharmony_ci               if ($line =~ /^\s*#/) {
57962306a36Sopenharmony_ci                       $line = "";
58062306a36Sopenharmony_ci                       next NEXT_LINE;
58162306a36Sopenharmony_ci               }
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ci               # -----  condition ... else ... endif
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci               if ($line =~ /^([ ]\s*|)else\b/) {
58662306a36Sopenharmony_ci                       $if_config = "!" . pop @if_config;
58762306a36Sopenharmony_ci                       $if_config =~ s/^!!//;
58862306a36Sopenharmony_ci                       push @if_config, $if_config;
58962306a36Sopenharmony_ci                       $line =~ s/^([ ]\s*|)else\b//;
59062306a36Sopenharmony_ci               }
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci               ($null, $ifeq_config,  $ifeq_config_val )  = $line =~ /^([ ]\s*|)ifeq\b.*\b(CONFIG_[A-Za-z0-9_]*)(.*)/;
59362306a36Sopenharmony_ci               ($null, $ifneq_config, $ifneq_config_val)  = $line =~ /^([ ]\s*|)ifneq\b.*\b(CONFIG_[A-Za-z0-9_]*)(.*)/;
59462306a36Sopenharmony_ci               ($null, $ifdef_config)                     = $line =~ /^([ ]\s*|)ifdef\b.*\b(CONFIG_[A-Za-z0-9_]*)/;
59562306a36Sopenharmony_ci               ($null, $ifndef_config)                    = $line =~ /^([ ]\s*|)ifndef\b.*\b(CONFIG_[A-Za-z0-9_]*)/;
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_ci               ($null, $ifeq)   = $line =~ /^([ ]\s*|)ifeq\b\s*(.*)/;
59862306a36Sopenharmony_ci               ($null, $ifneq)  = $line =~ /^([ ]\s*|)ifneq\b\s*(.*)/;
59962306a36Sopenharmony_ci               ($null, $ifdef)  = $line =~ /^([ ]\s*|)ifdef\b\s*(.*)/;
60062306a36Sopenharmony_ci               ($null, $ifndef) = $line =~ /^([ ]\s*|)ifndef\b\s*(.*)/;
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_ci               # Order of tests is important.  Prefer "CONFIG_*" regex match over
60362306a36Sopenharmony_ci               # less specific regex match.
60462306a36Sopenharmony_ci               if ($ifdef_config) {
60562306a36Sopenharmony_ci                       $if_config = $ifdef_config;
60662306a36Sopenharmony_ci               } elsif ($ifeq_config) {
60762306a36Sopenharmony_ci                       if ($ifeq_config_val =~ /y/) {
60862306a36Sopenharmony_ci                               $if_config = $ifeq_config;
60962306a36Sopenharmony_ci                       } else {
61062306a36Sopenharmony_ci                               $if_config = "!" . $ifeq_config;
61162306a36Sopenharmony_ci                       }
61262306a36Sopenharmony_ci               } elsif ($ifndef_config) {
61362306a36Sopenharmony_ci                       $if_config = "!" . $ifndef_config;
61462306a36Sopenharmony_ci               } elsif ($ifneq_config) {
61562306a36Sopenharmony_ci                       if ($ifneq_config_val =~ /y/) {
61662306a36Sopenharmony_ci                               $if_config = "!" . $ifneq_config;
61762306a36Sopenharmony_ci                       } else {
61862306a36Sopenharmony_ci                               $if_config = $ifneq_config;
61962306a36Sopenharmony_ci                       }
62062306a36Sopenharmony_ci               } elsif ($ifdef) {
62162306a36Sopenharmony_ci                       $if_config = $ifdef;
62262306a36Sopenharmony_ci               } elsif ($ifeq) {
62362306a36Sopenharmony_ci                       $if_config = $ifeq;
62462306a36Sopenharmony_ci               } elsif ($ifndef) {
62562306a36Sopenharmony_ci                       $if_config = "!" . $ifndef;
62662306a36Sopenharmony_ci               } elsif ($ifneq) {
62762306a36Sopenharmony_ci                       $if_config = "!" . $ifneq;
62862306a36Sopenharmony_ci               } else {
62962306a36Sopenharmony_ci                       $if_config = "";
63062306a36Sopenharmony_ci               }
63162306a36Sopenharmony_ci               $if_config =~ s/^!!//;
63262306a36Sopenharmony_ci
63362306a36Sopenharmony_ci               if ($if_config) {
63462306a36Sopenharmony_ci                       push @if_config, $if_config;
63562306a36Sopenharmony_ci                       $line = "";
63662306a36Sopenharmony_ci                       next NEXT_LINE;
63762306a36Sopenharmony_ci               }
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_ci               if ($line =~ /^([ ]\s*|)endif\b/) {
64062306a36Sopenharmony_ci                       pop @if_config;
64162306a36Sopenharmony_ci                       $line = "";
64262306a36Sopenharmony_ci                       next NEXT_LINE;
64362306a36Sopenharmony_ci               }
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_ci               # ----- simple CONFIG_* = *.[co]  or  xxx [+:?]*= *.[co]
64662306a36Sopenharmony_ci               # Most makefiles select on *.o, but
64762306a36Sopenharmony_ci               # arch/powerpc/boot/Makefile selects on *.c
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci               ($config) = $line =~ /(CONFIG_[A-Za-z0-9_]+).*\b$base.[co]\b/;
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_ci               # ----- match a make variable instead of *.[co]
65262306a36Sopenharmony_ci               # Recursively expanded variables are not handled.
65362306a36Sopenharmony_ci
65462306a36Sopenharmony_ci               if (!$config) {
65562306a36Sopenharmony_ci                       my $make_var;
65662306a36Sopenharmony_ci                       ($make_var) = $line =~ /\s*(\S+?)\s*[+:\?]*=.*\b$base.[co]\b/;
65762306a36Sopenharmony_ci                       if ($make_var) {
65862306a36Sopenharmony_ci                               if ($make_var =~ /[a-zA-Z0-9]+-[ym]/) {
65962306a36Sopenharmony_ci                                       $config = $make_var;
66062306a36Sopenharmony_ci                               } elsif ($make_var =~ /[a-zA-Z0-9]+-objs/) {
66162306a36Sopenharmony_ci                                       $config = $make_var;
66262306a36Sopenharmony_ci                               } else {
66362306a36Sopenharmony_ci                                       push @make_var, $make_var;
66462306a36Sopenharmony_ci                               }
66562306a36Sopenharmony_ci                       }
66662306a36Sopenharmony_ci               }
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_ci               if (!$config) {
66962306a36Sopenharmony_ci                       for $make_var (@make_var) {
67062306a36Sopenharmony_ci                               ($config) = $line =~ /(CONFIG_[A-Za-z0-9_]+).*\b$make_var\b/;
67162306a36Sopenharmony_ci                               last if ($config);
67262306a36Sopenharmony_ci                       }
67362306a36Sopenharmony_ci               }
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_ci               if (!$config) {
67662306a36Sopenharmony_ci                       for $make_var (@make_var) {
67762306a36Sopenharmony_ci                               ($config) = $line =~ /\s*(\S+?)\s*[+:\?]*=.*\b$make_var\b/;
67862306a36Sopenharmony_ci                               last if ($config);
67962306a36Sopenharmony_ci                       }
68062306a36Sopenharmony_ci               }
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci               # ----- next if no config found
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci               if (!$config) {
68562306a36Sopenharmony_ci                       $line = "";
68662306a36Sopenharmony_ci                       next NEXT_LINE;
68762306a36Sopenharmony_ci               }
68862306a36Sopenharmony_ci
68962306a36Sopenharmony_ci               for $if_config (@if_config) {
69062306a36Sopenharmony_ci                       $config = $if_config . " && " . $config;
69162306a36Sopenharmony_ci               }
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_ci               push @{ $driver_config{$driver} }, $config;
69462306a36Sopenharmony_ci
69562306a36Sopenharmony_ci               $line = "";
69662306a36Sopenharmony_ci       }
69762306a36Sopenharmony_ci
69862306a36Sopenharmony_ci       close(MAKEFILE_FILE);
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_ci}
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_cisub find_kconfig
70462306a36Sopenharmony_ci{
70562306a36Sopenharmony_ci       my $pn_arg_ref    = shift;
70662306a36Sopenharmony_ci       my $driver        = shift;
70762306a36Sopenharmony_ci
70862306a36Sopenharmony_ci       my $lines_printed = 0;
70962306a36Sopenharmony_ci       my @configs;
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_ci       if (!@{ $driver_config{$driver} }) {
71262306a36Sopenharmony_ci               &scan_makefile($pn_arg_ref, $driver);
71362306a36Sopenharmony_ci               if (!@{ $driver_config{$driver} }) {
71462306a36Sopenharmony_ci                       push @{ $driver_config{$driver} }, "no_config";
71562306a36Sopenharmony_ci               }
71662306a36Sopenharmony_ci       }
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_ci       @configs = @{ $driver_config{$driver} };
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_ci       $$pn_arg_ref{config_cnt} = $#configs + 1;
72162306a36Sopenharmony_ci       for my $config (@configs) {
72262306a36Sopenharmony_ci               $$pn_arg_ref{config} = $config;
72362306a36Sopenharmony_ci               $lines_printed += &print_node($pn_arg_ref);
72462306a36Sopenharmony_ci       }
72562306a36Sopenharmony_ci
72662306a36Sopenharmony_ci       return $lines_printed;
72762306a36Sopenharmony_ci}
72862306a36Sopenharmony_ci
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_cisub handle_compatible()
73162306a36Sopenharmony_ci{
73262306a36Sopenharmony_ci       my $full_node     = shift;
73362306a36Sopenharmony_ci       my $node          = shift;
73462306a36Sopenharmony_ci       my $compatible    = shift;
73562306a36Sopenharmony_ci       my $node_enabled  = shift;
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci       my $compat;
73862306a36Sopenharmony_ci       my $lines_printed = 0;
73962306a36Sopenharmony_ci       my %pn_arg        = ();
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_ci       return if (!$node or !$compatible);
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_ci       # Do not process compatible property of root node,
74462306a36Sopenharmony_ci       # it is used to match board, not to bind a driver.
74562306a36Sopenharmony_ci       return if ($node eq "/");
74662306a36Sopenharmony_ci
74762306a36Sopenharmony_ci       $pn_arg{full_node}    = $full_node;
74862306a36Sopenharmony_ci       $pn_arg{node}         = $node;
74962306a36Sopenharmony_ci       $pn_arg{node_enabled} = $node_enabled;
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci       my @compatibles = split('", "', $compatible);
75262306a36Sopenharmony_ci
75362306a36Sopenharmony_ci       $compatibles[0] =~ s/^"//;
75462306a36Sopenharmony_ci       $compatibles[$#compatibles] =~ s/"$//;
75562306a36Sopenharmony_ci
75662306a36Sopenharmony_ci       $pn_arg{compatible_cnt} = $#compatibles + 1;
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_ci       COMPAT:
75962306a36Sopenharmony_ci       for $compat (@compatibles) {
76062306a36Sopenharmony_ci
76162306a36Sopenharmony_ci               $pn_arg{compat}     = $compat;
76262306a36Sopenharmony_ci               $pn_arg{driver_cnt} = 0;
76362306a36Sopenharmony_ci               $pn_arg{white_list} = 0;
76462306a36Sopenharmony_ci
76562306a36Sopenharmony_ci               if (exists($compat_white_list{$compat})) {
76662306a36Sopenharmony_ci                       $pn_arg{white_list} = 1;
76762306a36Sopenharmony_ci                       $pn_arg{driver}     = "no_driver";
76862306a36Sopenharmony_ci                       $pn_arg{config_cnt} = 1;
76962306a36Sopenharmony_ci                       $pn_arg{config}     = "no_config";
77062306a36Sopenharmony_ci                       $lines_printed += &print_node(\%pn_arg);
77162306a36Sopenharmony_ci                       next COMPAT;
77262306a36Sopenharmony_ci               }
77362306a36Sopenharmony_ci
77462306a36Sopenharmony_ci               # ----- if compat previously seen, use cached info
77562306a36Sopenharmony_ci
77662306a36Sopenharmony_ci               if (exists($compat_driver{$compat})) {
77762306a36Sopenharmony_ci                       for my $driver (@{ $compat_driver{$compat} }) {
77862306a36Sopenharmony_ci                               $pn_arg{driver}     = $driver;
77962306a36Sopenharmony_ci                               $pn_arg{driver_cnt} = $driver_count{$compat};
78062306a36Sopenharmony_ci                               $pn_arg{config_cnt} = $#{ $driver_config{$driver}} + 1;
78162306a36Sopenharmony_ci
78262306a36Sopenharmony_ci                               for my $config (@{ $driver_config{$driver} }) {
78362306a36Sopenharmony_ci                                       $pn_arg{config} = $config;
78462306a36Sopenharmony_ci                                       $lines_printed += &print_node(\%pn_arg);
78562306a36Sopenharmony_ci                               }
78662306a36Sopenharmony_ci
78762306a36Sopenharmony_ci                               if (!@{ $driver_config{$driver} }) {
78862306a36Sopenharmony_ci                                       # no config cached yet
78962306a36Sopenharmony_ci                                       # $driver in %driver_hard_code_list
79062306a36Sopenharmony_ci                                       # but not %driver_config_hard_code_list
79162306a36Sopenharmony_ci                                       $lines_printed += &find_kconfig(\%pn_arg, $driver);
79262306a36Sopenharmony_ci                               }
79362306a36Sopenharmony_ci                       }
79462306a36Sopenharmony_ci                       next COMPAT;
79562306a36Sopenharmony_ci               }
79662306a36Sopenharmony_ci
79762306a36Sopenharmony_ci
79862306a36Sopenharmony_ci               # ----- Find drivers (source files that contain compatible)
79962306a36Sopenharmony_ci
80062306a36Sopenharmony_ci               # this will miss arch/sparc/include/asm/parport.h
80162306a36Sopenharmony_ci               # It is better to move the compatible out of the .h
80262306a36Sopenharmony_ci               # than to add *.h. to the files list, because *.h generates
80362306a36Sopenharmony_ci               # a lot of false negatives.
80462306a36Sopenharmony_ci               my $files = '"*.c"';
80562306a36Sopenharmony_ci               my $drivers = `git grep -l '"$compat"' -- $files`;
80662306a36Sopenharmony_ci               chomp($drivers);
80762306a36Sopenharmony_ci               if ($drivers eq "") {
80862306a36Sopenharmony_ci                       $pn_arg{driver} = "no_driver";
80962306a36Sopenharmony_ci                       $pn_arg{config_cnt} = 1;
81062306a36Sopenharmony_ci                       $pn_arg{config} = "no_config";
81162306a36Sopenharmony_ci                       push @{ $compat_driver{$compat} }, "no_driver";
81262306a36Sopenharmony_ci                       $lines_printed += &print_node(\%pn_arg);
81362306a36Sopenharmony_ci                       next COMPAT;
81462306a36Sopenharmony_ci               }
81562306a36Sopenharmony_ci
81662306a36Sopenharmony_ci               my @drivers = split("\n", $drivers);
81762306a36Sopenharmony_ci               $driver_count{$compat} = $#drivers + 1;
81862306a36Sopenharmony_ci               $pn_arg{driver_cnt}    = $#drivers + 1;
81962306a36Sopenharmony_ci
82062306a36Sopenharmony_ci               DRIVER:
82162306a36Sopenharmony_ci               for my $driver (@drivers) {
82262306a36Sopenharmony_ci                       push @{ $compat_driver{$compat} }, $driver;
82362306a36Sopenharmony_ci                       $pn_arg{driver} = $driver;
82462306a36Sopenharmony_ci
82562306a36Sopenharmony_ci                       # ----- if driver previously seen, use cached info
82662306a36Sopenharmony_ci
82762306a36Sopenharmony_ci                       $pn_arg{config_cnt} = $#{ $driver_config{$driver} } + 1;
82862306a36Sopenharmony_ci                       for my $config (@{ $driver_config{$driver} }) {
82962306a36Sopenharmony_ci                               $pn_arg{config} = $config;
83062306a36Sopenharmony_ci                               $lines_printed += &print_node(\%pn_arg);
83162306a36Sopenharmony_ci                       }
83262306a36Sopenharmony_ci                       if (@{ $driver_config{$driver} }) {
83362306a36Sopenharmony_ci                               next DRIVER;
83462306a36Sopenharmony_ci                       }
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_ci                       if ($black_list_driver) {
83762306a36Sopenharmony_ci                               for $black (@black_list_driver) {
83862306a36Sopenharmony_ci                                       next DRIVER if ($driver =~ /^$black$/);
83962306a36Sopenharmony_ci                               }
84062306a36Sopenharmony_ci                       }
84162306a36Sopenharmony_ci
84262306a36Sopenharmony_ci
84362306a36Sopenharmony_ci                       # ----- Find Kconfig symbols that enable driver
84462306a36Sopenharmony_ci
84562306a36Sopenharmony_ci                       $lines_printed += &find_kconfig(\%pn_arg, $driver);
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci               }
84862306a36Sopenharmony_ci       }
84962306a36Sopenharmony_ci
85062306a36Sopenharmony_ci       # White space (line) between nodes for readability.
85162306a36Sopenharmony_ci       # Each node may report several compatibles.
85262306a36Sopenharmony_ci       # For each compatible, multiple drivers may be reported.
85362306a36Sopenharmony_ci       # For each driver, multiple CONFIG_ options may be reported.
85462306a36Sopenharmony_ci       if ($lines_printed) {
85562306a36Sopenharmony_ci               print "\n";
85662306a36Sopenharmony_ci       }
85762306a36Sopenharmony_ci}
85862306a36Sopenharmony_ci
85962306a36Sopenharmony_cisub read_dts()
86062306a36Sopenharmony_ci{
86162306a36Sopenharmony_ci       my $file         = shift;
86262306a36Sopenharmony_ci
86362306a36Sopenharmony_ci       my $compatible   = "";
86462306a36Sopenharmony_ci       my $line;
86562306a36Sopenharmony_ci       my $node         = "";
86662306a36Sopenharmony_ci       my $node_enabled = "";
86762306a36Sopenharmony_ci
86862306a36Sopenharmony_ci       if (! -r $file) {
86962306a36Sopenharmony_ci               print STDERR "file '$file' is not readable or does not exist\n";
87062306a36Sopenharmony_ci               exit 3;
87162306a36Sopenharmony_ci       }
87262306a36Sopenharmony_ci
87362306a36Sopenharmony_ci       if (!open(DT_FILE, "-|", "$dtx_diff $file")) {
87462306a36Sopenharmony_ci               print STDERR "\n";
87562306a36Sopenharmony_ci               print STDERR "shell command failed:\n";
87662306a36Sopenharmony_ci               print STDERR "   $dtx_diff $file\n";
87762306a36Sopenharmony_ci               print STDERR "\n";
87862306a36Sopenharmony_ci               exit 3;
87962306a36Sopenharmony_ci       }
88062306a36Sopenharmony_ci
88162306a36Sopenharmony_ci       FILE:
88262306a36Sopenharmony_ci       while ($line = <DT_FILE>) {
88362306a36Sopenharmony_ci               chomp($line);
88462306a36Sopenharmony_ci
88562306a36Sopenharmony_ci               if ($line =~ /{/) {
88662306a36Sopenharmony_ci
88762306a36Sopenharmony_ci                       &handle_compatible($full_node, $node, $compatible,
88862306a36Sopenharmony_ci                                          $node_enabled);
88962306a36Sopenharmony_ci
89062306a36Sopenharmony_ci                       while ($end_node_count-- > 0) {
89162306a36Sopenharmony_ci                               pop @full_node;
89262306a36Sopenharmony_ci                       };
89362306a36Sopenharmony_ci                       $end_node_count = 0;
89462306a36Sopenharmony_ci                       $full_node = @full_node[-1];
89562306a36Sopenharmony_ci
89662306a36Sopenharmony_ci                       $node = $line;
89762306a36Sopenharmony_ci                       $node =~ s/^\s*(.*)\s+\{.*/$1/;
89862306a36Sopenharmony_ci                       $node =~ s/.*: //;
89962306a36Sopenharmony_ci                       if ($node eq '/' ) {
90062306a36Sopenharmony_ci                               $full_node = '/';
90162306a36Sopenharmony_ci                       } elsif ($full_node ne '/') {
90262306a36Sopenharmony_ci                               $full_node = $full_node . '/' . $node;
90362306a36Sopenharmony_ci                       } else {
90462306a36Sopenharmony_ci                               $full_node = '/' . $node;
90562306a36Sopenharmony_ci                       }
90662306a36Sopenharmony_ci                       push @full_node, $full_node;
90762306a36Sopenharmony_ci
90862306a36Sopenharmony_ci                       $compatible = "";
90962306a36Sopenharmony_ci                       $node_enabled = "";
91062306a36Sopenharmony_ci                       next FILE;
91162306a36Sopenharmony_ci               }
91262306a36Sopenharmony_ci
91362306a36Sopenharmony_ci               if ($line =~ /}/) {
91462306a36Sopenharmony_ci                       $end_node_count++;
91562306a36Sopenharmony_ci               }
91662306a36Sopenharmony_ci
91762306a36Sopenharmony_ci               if ($line =~ /(\s+|^)status =/) {
91862306a36Sopenharmony_ci                       $node_enabled = $line;
91962306a36Sopenharmony_ci                       $node_enabled =~ s/^\t*//;
92062306a36Sopenharmony_ci                       $node_enabled =~ s/^status = "//;
92162306a36Sopenharmony_ci                       $node_enabled =~ s/";$//;
92262306a36Sopenharmony_ci                       next FILE;
92362306a36Sopenharmony_ci               }
92462306a36Sopenharmony_ci
92562306a36Sopenharmony_ci               if ($line =~ /(\s+|^)compatible =/) {
92662306a36Sopenharmony_ci                       # Extract all compatible entries for this device
92762306a36Sopenharmony_ci                       # White space matching here and in handle_compatible() is
92862306a36Sopenharmony_ci                       # precise, because input format is the output of dtc,
92962306a36Sopenharmony_ci                       # which is invoked by dtx_diff.
93062306a36Sopenharmony_ci                       $compatible = $line;
93162306a36Sopenharmony_ci                       $compatible =~ s/^\t*//;
93262306a36Sopenharmony_ci                       $compatible =~ s/^compatible = //;
93362306a36Sopenharmony_ci                       $compatible =~ s/;$//;
93462306a36Sopenharmony_ci               }
93562306a36Sopenharmony_ci       }
93662306a36Sopenharmony_ci
93762306a36Sopenharmony_ci       &handle_compatible($full_node, $node, $compatible, $node_enabled);
93862306a36Sopenharmony_ci
93962306a36Sopenharmony_ci       close(DT_FILE);
94062306a36Sopenharmony_ci}
94162306a36Sopenharmony_ci
94262306a36Sopenharmony_ci
94362306a36Sopenharmony_cisub read_config_file()
94462306a36Sopenharmony_ci{
94562306a36Sopenharmony_ci       if (! -r $config_file) {
94662306a36Sopenharmony_ci               print STDERR "file '$config_file' is not readable or does not exist\n";
94762306a36Sopenharmony_ci               exit 2;
94862306a36Sopenharmony_ci       }
94962306a36Sopenharmony_ci
95062306a36Sopenharmony_ci       if (!open(CONFIG_FILE, "<", "$config_file")) {
95162306a36Sopenharmony_ci               print STDERR "open $config_file failed\n";
95262306a36Sopenharmony_ci               exit 2;
95362306a36Sopenharmony_ci       }
95462306a36Sopenharmony_ci
95562306a36Sopenharmony_ci       my @line;
95662306a36Sopenharmony_ci
95762306a36Sopenharmony_ci       LINE:
95862306a36Sopenharmony_ci       while ($line = <CONFIG_FILE>) {
95962306a36Sopenharmony_ci               chomp($line);
96062306a36Sopenharmony_ci               next LINE if ($line =~ /^\s*#/);
96162306a36Sopenharmony_ci               next LINE if ($line =~ /^\s*$/);
96262306a36Sopenharmony_ci               @line = split /=/, $line;
96362306a36Sopenharmony_ci               $existing_config{@line[0]} = @line[1];
96462306a36Sopenharmony_ci       }
96562306a36Sopenharmony_ci
96662306a36Sopenharmony_ci       close(CONFIG_FILE);
96762306a36Sopenharmony_ci}
96862306a36Sopenharmony_ci
96962306a36Sopenharmony_ci
97062306a36Sopenharmony_cisub cmd_line_err()
97162306a36Sopenharmony_ci{
97262306a36Sopenharmony_ci       my $msg = shift;
97362306a36Sopenharmony_ci
97462306a36Sopenharmony_ci       print STDERR "\n";
97562306a36Sopenharmony_ci       print STDERR "   ERROR processing command line options\n";
97662306a36Sopenharmony_ci       print STDERR "         $msg\n" if ($msg ne "");
97762306a36Sopenharmony_ci       print STDERR "\n";
97862306a36Sopenharmony_ci       print STDERR "   For help, type '$script_name --help'\n";
97962306a36Sopenharmony_ci       print STDERR "\n";
98062306a36Sopenharmony_ci}
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_ci
98362306a36Sopenharmony_ci# -----------------------------------------------------------------------------
98462306a36Sopenharmony_ci# program entry point
98562306a36Sopenharmony_ci
98662306a36Sopenharmony_ciGetopt::Long::Configure("no_ignore_case", "bundling");
98762306a36Sopenharmony_ci
98862306a36Sopenharmony_ciif (!GetOptions(
98962306a36Sopenharmony_ci       "c=s"               => \$config_file,
99062306a36Sopenharmony_ci       "config=s"          => \$config_file,
99162306a36Sopenharmony_ci       "config-format"     => \$config_format,
99262306a36Sopenharmony_ci       "exclude-flag=s"    => \@exclude_flag,
99362306a36Sopenharmony_ci       "h"                 => \$help,
99462306a36Sopenharmony_ci       "help"              => \$help,
99562306a36Sopenharmony_ci       "black-list-driver" => \$black_list_driver,
99662306a36Sopenharmony_ci       "white-list-config" => \$white_list_config,
99762306a36Sopenharmony_ci       "white-list-driver" => \$white_list_driver,
99862306a36Sopenharmony_ci       "include-flag=s"    => \@include_flag,
99962306a36Sopenharmony_ci       "include-suspect"   => \$include_suspect,
100062306a36Sopenharmony_ci       "short-name"        => \$short_name,
100162306a36Sopenharmony_ci       "show-lists"        => \$show_lists,
100262306a36Sopenharmony_ci       "version"           => \$version,
100362306a36Sopenharmony_ci       )) {
100462306a36Sopenharmony_ci
100562306a36Sopenharmony_ci       &cmd_line_err();
100662306a36Sopenharmony_ci
100762306a36Sopenharmony_ci       exit 1;
100862306a36Sopenharmony_ci}
100962306a36Sopenharmony_ci
101062306a36Sopenharmony_ci
101162306a36Sopenharmony_cimy $exit_after_messages = 0;
101262306a36Sopenharmony_ci
101362306a36Sopenharmony_ciif ($version) {
101462306a36Sopenharmony_ci       print STDERR "\n$script_name  $VUFX\n\n";
101562306a36Sopenharmony_ci       $exit_after_messages = 1;
101662306a36Sopenharmony_ci}
101762306a36Sopenharmony_ci
101862306a36Sopenharmony_ci
101962306a36Sopenharmony_ciif ($help) {
102062306a36Sopenharmony_ci       &usage;
102162306a36Sopenharmony_ci       $exit_after_messages = 1;
102262306a36Sopenharmony_ci}
102362306a36Sopenharmony_ci
102462306a36Sopenharmony_ci
102562306a36Sopenharmony_ciif ($show_lists) {
102662306a36Sopenharmony_ci
102762306a36Sopenharmony_ci       print "\n";
102862306a36Sopenharmony_ci       print "These compatibles are hard coded to have no driver.\n";
102962306a36Sopenharmony_ci       print "\n";
103062306a36Sopenharmony_ci       for my $compat (sort keys %compat_white_list) {
103162306a36Sopenharmony_ci               print "   $compat\n";
103262306a36Sopenharmony_ci       }
103362306a36Sopenharmony_ci
103462306a36Sopenharmony_ci
103562306a36Sopenharmony_ci       print "\n\n";
103662306a36Sopenharmony_ci       print "The driver for these compatibles is hard coded (white list).\n";
103762306a36Sopenharmony_ci       print "\n";
103862306a36Sopenharmony_ci       my $max_compat_len = 0;
103962306a36Sopenharmony_ci       for my $compat (sort keys %driver_hard_code_list) {
104062306a36Sopenharmony_ci               if (length $compat > $max_compat_len) {
104162306a36Sopenharmony_ci                       $max_compat_len = length $compat;
104262306a36Sopenharmony_ci               }
104362306a36Sopenharmony_ci       }
104462306a36Sopenharmony_ci       for my $compat (sort keys %driver_hard_code_list) {
104562306a36Sopenharmony_ci               if (($driver ne "hardcoded_no_driver") && ($driver ne "no_driver")) {
104662306a36Sopenharmony_ci                       my $first = 1;
104762306a36Sopenharmony_ci                       for my $driver (@{ $driver_hard_code_list{$compat} }) {
104862306a36Sopenharmony_ci                               if ($first) {
104962306a36Sopenharmony_ci                                       print "   $compat";
105062306a36Sopenharmony_ci                                       print " " x ($max_compat_len - length $compat);
105162306a36Sopenharmony_ci                                       $first = 0;
105262306a36Sopenharmony_ci                               } else {
105362306a36Sopenharmony_ci                                       print "   ", " " x $max_compat_len;
105462306a36Sopenharmony_ci                               }
105562306a36Sopenharmony_ci                               print "  $driver\n";
105662306a36Sopenharmony_ci                       }
105762306a36Sopenharmony_ci               }
105862306a36Sopenharmony_ci       }
105962306a36Sopenharmony_ci
106062306a36Sopenharmony_ci
106162306a36Sopenharmony_ci       print "\n\n";
106262306a36Sopenharmony_ci       print "The configuration option for these drivers is hard coded (white list).\n";
106362306a36Sopenharmony_ci       print "\n";
106462306a36Sopenharmony_ci       my $max_driver_len = 0;
106562306a36Sopenharmony_ci       for my $driver (sort keys %driver_config_hard_code_list) {
106662306a36Sopenharmony_ci               if (length $driver > $max_driver_len) {
106762306a36Sopenharmony_ci                       $max_driver_len = length $driver;
106862306a36Sopenharmony_ci               }
106962306a36Sopenharmony_ci       }
107062306a36Sopenharmony_ci       for my $driver (sort keys %driver_config_hard_code_list) {
107162306a36Sopenharmony_ci               if (($driver ne "hardcoded_no_driver") && ($driver ne "no_driver")) {
107262306a36Sopenharmony_ci                       my $first = 1;
107362306a36Sopenharmony_ci                       for my $config (@{ $driver_config_hard_code_list{$driver} }) {
107462306a36Sopenharmony_ci                               if ($first) {
107562306a36Sopenharmony_ci                                       print "   $driver";
107662306a36Sopenharmony_ci                                       print " " x ($max_driver_len - length $driver);
107762306a36Sopenharmony_ci                                       $first = 0;
107862306a36Sopenharmony_ci                               } else {
107962306a36Sopenharmony_ci                                       print "   ", " " x $max_driver_len;
108062306a36Sopenharmony_ci                               }
108162306a36Sopenharmony_ci                               print "  $config\n";
108262306a36Sopenharmony_ci                       }
108362306a36Sopenharmony_ci               }
108462306a36Sopenharmony_ci       }
108562306a36Sopenharmony_ci
108662306a36Sopenharmony_ci
108762306a36Sopenharmony_ci       print "\n\n";
108862306a36Sopenharmony_ci       print "These drivers are black listed.\n";
108962306a36Sopenharmony_ci       print "\n";
109062306a36Sopenharmony_ci       for my $driver (@black_list_driver) {
109162306a36Sopenharmony_ci               print "   $driver\n";
109262306a36Sopenharmony_ci       }
109362306a36Sopenharmony_ci
109462306a36Sopenharmony_ci       print "\n";
109562306a36Sopenharmony_ci
109662306a36Sopenharmony_ci       $exit_after_messages = 1;
109762306a36Sopenharmony_ci}
109862306a36Sopenharmony_ci
109962306a36Sopenharmony_ci
110062306a36Sopenharmony_ciif ($exit_after_messages) {
110162306a36Sopenharmony_ci       exit 0;
110262306a36Sopenharmony_ci}
110362306a36Sopenharmony_ci
110462306a36Sopenharmony_ci
110562306a36Sopenharmony_ci$exclude_flag_pattern = "[";
110662306a36Sopenharmony_cifor my $exclude_flag (@exclude_flag) {
110762306a36Sopenharmony_ci       $exclude_flag_pattern = $exclude_flag_pattern . $exclude_flag;
110862306a36Sopenharmony_ci}
110962306a36Sopenharmony_ci$exclude_flag_pattern = $exclude_flag_pattern . "]";
111062306a36Sopenharmony_ci# clean up if empty
111162306a36Sopenharmony_ci$exclude_flag_pattern =~ s/^\[\]$//;
111262306a36Sopenharmony_ci
111362306a36Sopenharmony_ci
111462306a36Sopenharmony_ci$include_flag_pattern = "[";
111562306a36Sopenharmony_cifor my $include_flag (@include_flag) {
111662306a36Sopenharmony_ci       $include_flag_pattern = $include_flag_pattern . $include_flag;
111762306a36Sopenharmony_ci}
111862306a36Sopenharmony_ci$include_flag_pattern = $include_flag_pattern . "]";
111962306a36Sopenharmony_ci# clean up if empty
112062306a36Sopenharmony_ci$include_flag_pattern =~ s/^\[\]$//;
112162306a36Sopenharmony_ci
112262306a36Sopenharmony_ci
112362306a36Sopenharmony_ciif ($exclude_flag_pattern) {
112462306a36Sopenharmony_ci       my $found = 0;
112562306a36Sopenharmony_ci       for $pr_flag_value (@pr_flag_value) {
112662306a36Sopenharmony_ci               if ($exclude_flag_pattern =~ m/$pr_flag_value/) {
112762306a36Sopenharmony_ci                       $found = 1;
112862306a36Sopenharmony_ci               }
112962306a36Sopenharmony_ci       }
113062306a36Sopenharmony_ci       if (!$found) {
113162306a36Sopenharmony_ci               &cmd_line_err("invalid value for FLAG in --exclude-flag\n");
113262306a36Sopenharmony_ci               exit 1
113362306a36Sopenharmony_ci       }
113462306a36Sopenharmony_ci}
113562306a36Sopenharmony_ci
113662306a36Sopenharmony_ciif ($include_flag_pattern) {
113762306a36Sopenharmony_ci       my $found = 0;
113862306a36Sopenharmony_ci       for $pr_flag_value (@pr_flag_value) {
113962306a36Sopenharmony_ci               if ($include_flag_pattern =~ m/$pr_flag_value/) {
114062306a36Sopenharmony_ci                       $found = 1;
114162306a36Sopenharmony_ci               }
114262306a36Sopenharmony_ci       }
114362306a36Sopenharmony_ci       if (!$found) {
114462306a36Sopenharmony_ci               &cmd_line_err("invalid value for FLAG in --include-flag\n");
114562306a36Sopenharmony_ci               exit 1
114662306a36Sopenharmony_ci       }
114762306a36Sopenharmony_ci}
114862306a36Sopenharmony_ci
114962306a36Sopenharmony_ciif ($include_suspect) {
115062306a36Sopenharmony_ci       $include_flag_pattern =~ s/\[//;
115162306a36Sopenharmony_ci       $include_flag_pattern =~ s/\]//;
115262306a36Sopenharmony_ci       $include_flag_pattern = "[" . $include_flag_pattern . "A-Z]";
115362306a36Sopenharmony_ci}
115462306a36Sopenharmony_ci
115562306a36Sopenharmony_ciif ($exclude_flag_pattern =~ m/$include_flag_pattern/) {
115662306a36Sopenharmony_ci       &cmd_line_err("the same flag appears in both --exclude-flag and --include-flag or --include-suspect\n");
115762306a36Sopenharmony_ci       exit 1
115862306a36Sopenharmony_ci}
115962306a36Sopenharmony_ci
116062306a36Sopenharmony_ci
116162306a36Sopenharmony_ci# ($#ARGV < 0) is valid for --help, --version
116262306a36Sopenharmony_ciif ($#ARGV < 0) {
116362306a36Sopenharmony_ci       &cmd_line_err("device-tree... is required");
116462306a36Sopenharmony_ci       exit 1
116562306a36Sopenharmony_ci}
116662306a36Sopenharmony_ci
116762306a36Sopenharmony_ci
116862306a36Sopenharmony_ciif ($config_file) {
116962306a36Sopenharmony_ci       &read_config_file();
117062306a36Sopenharmony_ci}
117162306a36Sopenharmony_ci
117262306a36Sopenharmony_ci
117362306a36Sopenharmony_ci# avoid pushing duplicates for this value
117462306a36Sopenharmony_ci$driver = "hardcoded_no_driver";
117562306a36Sopenharmony_cifor $config ( @{ $driver_config_hard_code_list{$driver} } ) {
117662306a36Sopenharmony_ci       push @{ $driver_config{$driver} }, $config;
117762306a36Sopenharmony_ci}
117862306a36Sopenharmony_ci
117962306a36Sopenharmony_ciif ($white_list_driver) {
118062306a36Sopenharmony_ci       for my $compat (keys %driver_hard_code_list) {
118162306a36Sopenharmony_ci               for my $driver (@{ $driver_hard_code_list{$compat} }) {
118262306a36Sopenharmony_ci                       push @{ $compat_driver{$compat} }, $driver;
118362306a36Sopenharmony_ci                       if ($driver ne "hardcoded_no_driver") {
118462306a36Sopenharmony_ci                               $driver_count{$compat} = scalar @{ $compat_driver{$compat} };
118562306a36Sopenharmony_ci                       }
118662306a36Sopenharmony_ci               }
118762306a36Sopenharmony_ci       }
118862306a36Sopenharmony_ci}
118962306a36Sopenharmony_ci
119062306a36Sopenharmony_ciif ($white_list_config) {
119162306a36Sopenharmony_ci       for my $driver (keys %driver_config_hard_code_list) {
119262306a36Sopenharmony_ci               if ($driver ne "hardcoded_no_driver") {
119362306a36Sopenharmony_ci                       for $config ( @{ $driver_config_hard_code_list{$driver} } ) {
119462306a36Sopenharmony_ci                               push @{ $driver_config{$driver} }, $config;
119562306a36Sopenharmony_ci                       }
119662306a36Sopenharmony_ci               }
119762306a36Sopenharmony_ci       }
119862306a36Sopenharmony_ci}
119962306a36Sopenharmony_ci
120062306a36Sopenharmony_ciif (-x "scripts/dtc/dtx_diff") {
120162306a36Sopenharmony_ci       $dtx_diff = "scripts/dtc/dtx_diff";
120262306a36Sopenharmony_ci} else {
120362306a36Sopenharmony_ci
120462306a36Sopenharmony_ci       print STDERR "\n";
120562306a36Sopenharmony_ci       print STDERR "$script_name must be run from the root directory of a Linux kernel tree\n";
120662306a36Sopenharmony_ci       print STDERR "\n";
120762306a36Sopenharmony_ci       exit 3;
120862306a36Sopenharmony_ci}
120962306a36Sopenharmony_ci
121062306a36Sopenharmony_cifor $file (@ARGV) {
121162306a36Sopenharmony_ci       &read_dts($file);
121262306a36Sopenharmony_ci}
1213