18c2ecf20Sopenharmony_ci#!/usr/bin/env perl
28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0-only
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci# Copyright 2016 by Frank Rowand
58c2ecf20Sopenharmony_ci# Copyright 2016 by Gaurav Minocha
68c2ecf20Sopenharmony_ci#
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ciuse strict 'refs';
98c2ecf20Sopenharmony_ciuse strict subs;
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ciuse Getopt::Long;
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci$VUFX = "160610a";
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci$script_name = $0;
168c2ecf20Sopenharmony_ci$script_name =~ s|^.*/||;
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci# ----- constants for print_flags()
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci# Position in string $pr_flags.  Range of 0..($num_pr_flags - 1).
228c2ecf20Sopenharmony_ci$pr_flag_pos_mcompatible       = 0;
238c2ecf20Sopenharmony_ci$pr_flag_pos_driver            = 1;
248c2ecf20Sopenharmony_ci$pr_flag_pos_mdriver           = 2;
258c2ecf20Sopenharmony_ci$pr_flag_pos_config            = 3;
268c2ecf20Sopenharmony_ci$pr_flag_pos_mconfig           = 4;
278c2ecf20Sopenharmony_ci$pr_flag_pos_node_not_enabled  = 5;
288c2ecf20Sopenharmony_ci$pr_flag_pos_white_list        = 6;
298c2ecf20Sopenharmony_ci$pr_flag_pos_hard_coded        = 7;
308c2ecf20Sopenharmony_ci$pr_flag_pos_config_hard_coded = 8;
318c2ecf20Sopenharmony_ci$pr_flag_pos_config_none       = 9;
328c2ecf20Sopenharmony_ci$pr_flag_pos_config_m          = 10;
338c2ecf20Sopenharmony_ci$pr_flag_pos_config_y          = 11;
348c2ecf20Sopenharmony_ci$pr_flag_pos_config_test_fail  = 12;
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci$num_pr_flags = $pr_flag_pos_config_test_fail + 1;
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci# flags in @pr_flag_value must be unique values to allow simple regular
398c2ecf20Sopenharmony_ci# expessions to work for --include_flags and --exclude_flags.
408c2ecf20Sopenharmony_ci# Convention: use upper case letters for potential issues or problems.
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci@pr_flag_value = ('M', 'd', 'D', 'c', 'C', 'E', 'W', 'H', 'x', 'n', 'm', 'y', 'F');
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci@pr_flag_help = (
458c2ecf20Sopenharmony_ci    "multiple compatibles found for this node",
468c2ecf20Sopenharmony_ci    "driver found for this compatible",
478c2ecf20Sopenharmony_ci    "multiple drivers found for this compatible",
488c2ecf20Sopenharmony_ci    "kernel config found for this driver",
498c2ecf20Sopenharmony_ci    "multiple config options found for this driver",
508c2ecf20Sopenharmony_ci    "node is not enabled",
518c2ecf20Sopenharmony_ci    "compatible is white listed",
528c2ecf20Sopenharmony_ci    "matching driver and/or kernel config is hard coded",
538c2ecf20Sopenharmony_ci    "kernel config hard coded in Makefile",
548c2ecf20Sopenharmony_ci    "one or more kernel config file options is not set",
558c2ecf20Sopenharmony_ci    "one or more kernel config file options is set to 'm'",
568c2ecf20Sopenharmony_ci    "one or more kernel config file options is set to 'y'",
578c2ecf20Sopenharmony_ci    "one of more kernel config file options fails to have correct value"
588c2ecf20Sopenharmony_ci);
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci# -----
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci%driver_config = ();   # driver config array, indexed by driver source file
648c2ecf20Sopenharmony_ci%driver_count = ();    # driver_cnt, indexed by compatible
658c2ecf20Sopenharmony_ci%compat_driver = ();   # compatible driver array, indexed by compatible
668c2ecf20Sopenharmony_ci%existing_config = (); # existing config symbols present in given config file
678c2ecf20Sopenharmony_ci                       # expected values are: "y", "m", a decimal number, a
688c2ecf20Sopenharmony_ci                       # hex number, or a string
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci# ----- magic compatibles, do not have a driver
718c2ecf20Sopenharmony_ci#
728c2ecf20Sopenharmony_ci# Will not search for drivers for these compatibles.
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci%compat_white_list = (
758c2ecf20Sopenharmony_ci       'none'                  => '1',
768c2ecf20Sopenharmony_ci       'pci'                   => '1',
778c2ecf20Sopenharmony_ci       'simple-bus'            => '1',
788c2ecf20Sopenharmony_ci);
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci# Will not search for drivers for these compatibles.
818c2ecf20Sopenharmony_ci#
828c2ecf20Sopenharmony_ci# These compatibles have a very large number of false positives.
838c2ecf20Sopenharmony_ci#
848c2ecf20Sopenharmony_ci# 'hardcoded_no_driver' is a magic value.  Other code knows this
858c2ecf20Sopenharmony_ci# magic value.  Do not use 'no_driver' here!
868c2ecf20Sopenharmony_ci#
878c2ecf20Sopenharmony_ci# Revisit each 'hardcoded_no_driver' to see how the compatible
888c2ecf20Sopenharmony_ci# is used.  Are there drivers that can be provided?
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci%driver_hard_code_list = (
918c2ecf20Sopenharmony_ci       'cache'                 => ['hardcoded_no_driver'],
928c2ecf20Sopenharmony_ci       'eeprom'                => ['hardcoded_no_driver'],
938c2ecf20Sopenharmony_ci       'gpio'                  => ['hardcoded_no_driver'],
948c2ecf20Sopenharmony_ci       'gpio-keys'             => ['drivers/input/keyboard/gpio_keys.c'],
958c2ecf20Sopenharmony_ci       'i2c-gpio'              => ['drivers/i2c/busses/i2c-gpio.c'],
968c2ecf20Sopenharmony_ci       'isa'                   => ['arch/mips/mti-malta/malta-dt.c',
978c2ecf20Sopenharmony_ci                                    'arch/x86/kernel/devicetree.c'],
988c2ecf20Sopenharmony_ci       'led'                   => ['hardcoded_no_driver'],
998c2ecf20Sopenharmony_ci       'm25p32'                => ['hardcoded_no_driver'],
1008c2ecf20Sopenharmony_ci       'm25p64'                => ['hardcoded_no_driver'],
1018c2ecf20Sopenharmony_ci       'm25p80'                => ['hardcoded_no_driver'],
1028c2ecf20Sopenharmony_ci       'mtd-ram'               => ['drivers/mtd/maps/physmap_of.c'],
1038c2ecf20Sopenharmony_ci       'pwm-backlight'         => ['drivers/video/backlight/pwm_bl.c'],
1048c2ecf20Sopenharmony_ci       'spidev'                => ['hardcoded_no_driver'],
1058c2ecf20Sopenharmony_ci       'syscon'                => ['drivers/mfd/syscon.c'],
1068c2ecf20Sopenharmony_ci       'tlv320aic23'           => ['hardcoded_no_driver'],
1078c2ecf20Sopenharmony_ci       'wm8731'                => ['hardcoded_no_driver'],
1088c2ecf20Sopenharmony_ci);
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci# Use these config options instead of searching makefiles
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci%driver_config_hard_code_list = (
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci       # this one needed even if %driver_hard_code_list is empty
1158c2ecf20Sopenharmony_ci       'no_driver'                             => ['no_config'],
1168c2ecf20Sopenharmony_ci       'hardcoded_no_driver'                   => ['no_config'],
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci       # drivers/usb/host/ehci-ppc-of.c
1198c2ecf20Sopenharmony_ci       # drivers/usb/host/ehci-xilinx-of.c
1208c2ecf20Sopenharmony_ci       #  are included from:
1218c2ecf20Sopenharmony_ci       #    drivers/usb/host/ehci-hcd.c
1228c2ecf20Sopenharmony_ci       #  thus the search of Makefile for the included .c files is incorrect
1238c2ecf20Sopenharmony_ci       # ehci-hcd.c wraps the includes with ifdef CONFIG_USB_EHCI_HCD_..._OF
1248c2ecf20Sopenharmony_ci       #
1258c2ecf20Sopenharmony_ci       # similar model for ohci-hcd.c (but no ohci-xilinx-of.c)
1268c2ecf20Sopenharmony_ci       #
1278c2ecf20Sopenharmony_ci       # similarly, uhci-hcd.c includes uhci-platform.c
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci       'drivers/usb/host/ehci-ppc-of.c'        => ['CONFIG_USB_EHCI_HCD',
1308c2ecf20Sopenharmony_ci                                                   'CONFIG_USB_EHCI_HCD_PPC_OF'],
1318c2ecf20Sopenharmony_ci       'drivers/usb/host/ohci-ppc-of.c'        => ['CONFIG_USB_OHCI_HCD',
1328c2ecf20Sopenharmony_ci                                                   'CONFIG_USB_OHCI_HCD_PPC_OF'],
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci       'drivers/usb/host/ehci-xilinx-of.c'     => ['CONFIG_USB_EHCI_HCD',
1358c2ecf20Sopenharmony_ci                                                   'CONFIG_USB_EHCI_HCD_XILINX'],
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci       'drivers/usb/host/uhci-platform.c'      => ['CONFIG_USB_UHCI_HCD',
1388c2ecf20Sopenharmony_ci                                                   'CONFIG_USB_UHCI_PLATFORM'],
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci       # scan_makefile will find only one of these config options:
1418c2ecf20Sopenharmony_ci       #    ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_LS1021A),)
1428c2ecf20Sopenharmony_ci       'arch/arm/mach-imx/platsmp.c'           => ['CONFIG_SOC_IMX6 && CONFIG_SMP',
1438c2ecf20Sopenharmony_ci                                                   'CONFIG_SOC_LS1021A && CONFIG_SMP'],
1448c2ecf20Sopenharmony_ci);
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci# 'virt/kvm/arm/.*' are controlled by makefiles in other directories,
1488c2ecf20Sopenharmony_ci# using relative paths, such as 'KVM := ../../../virt/kvm'.  Do not
1498c2ecf20Sopenharmony_ci# add complexity to find_kconfig() to deal with this.  There is a long
1508c2ecf20Sopenharmony_ci# term intent to change the kvm related makefiles to the normal kernel
1518c2ecf20Sopenharmony_ci# style.  After that is done, this entry can be removed from the
1528c2ecf20Sopenharmony_ci# black_list_driver.
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci@black_list_driver = (
1558c2ecf20Sopenharmony_ci       # kvm no longer a problem after commit 503a62862e8f in 4.7-rc1
1568c2ecf20Sopenharmony_ci       # 'virt/kvm/arm/.*',
1578c2ecf20Sopenharmony_ci);
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_cisub usage()
1618c2ecf20Sopenharmony_ci{
1628c2ecf20Sopenharmony_ci       print
1638c2ecf20Sopenharmony_ci"
1648c2ecf20Sopenharmony_ciUsage: $script_name [options] device-tree...
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci    device_tree is: dts_file | dtb_file | proc_device-tree
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ciValid options:
1708c2ecf20Sopenharmony_ci     -c FILE             Read kernel config options from FILE
1718c2ecf20Sopenharmony_ci    --config FILE        synonym for 'c'
1728c2ecf20Sopenharmony_ci    --config-format      config file friendly output format
1738c2ecf20Sopenharmony_ci    --exclude-flag FLAG  exclude entries with a matching flag
1748c2ecf20Sopenharmony_ci     -h                  Display this message and exit
1758c2ecf20Sopenharmony_ci    --help               synonym for 'h'
1768c2ecf20Sopenharmony_ci    --black-list-driver  use driver black list
1778c2ecf20Sopenharmony_ci    --white-list-config  use config white list
1788c2ecf20Sopenharmony_ci    --white-list-driver  use driver white list
1798c2ecf20Sopenharmony_ci    --include-flag FLAG  include only entries with a matching flag
1808c2ecf20Sopenharmony_ci    --include-suspect    include only entries with an uppercase flag
1818c2ecf20Sopenharmony_ci    --short-name         do not show the path portion of the node name
1828c2ecf20Sopenharmony_ci    --show-lists         report of white and black lists
1838c2ecf20Sopenharmony_ci    --version            Display program version and exit
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci  Report driver source files that match the compatibles in the device
1878c2ecf20Sopenharmony_ci  tree file and the kernel config options that enable the driver source
1888c2ecf20Sopenharmony_ci  files.
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci  This program must be run in the root directory of a Linux kernel
1918c2ecf20Sopenharmony_ci  source tree.
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci  The default format is a report that is intended to be easily human
1948c2ecf20Sopenharmony_ci  scannable.
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci  An alternate format can be selected by --config-format.  This will
1978c2ecf20Sopenharmony_ci  create output that can easily be edited to create a fragment that can
1988c2ecf20Sopenharmony_ci  be appended to the existing kernel config file.  Each entry consists of
1998c2ecf20Sopenharmony_ci  multiple lines.  The first line reports flags, the node path, compatible
2008c2ecf20Sopenharmony_ci  value, driver file matching the compatible, configuration options, and
2018c2ecf20Sopenharmony_ci  current values of the configuration options.  For each configuration
2028c2ecf20Sopenharmony_ci  option, the following lines report the current value and the value that
2038c2ecf20Sopenharmony_ci  is required for the driver file to be included in the kernel.
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci  If a large number of drivers or config options is listed for a node,
2068c2ecf20Sopenharmony_ci  and the '$pr_flag_value[$pr_flag_pos_hard_coded]' flag is set consider using --white-list-config and/or
2078c2ecf20Sopenharmony_ci  --white-list-driver.  If the white list option suppresses the correct
2088c2ecf20Sopenharmony_ci  entry please report that as a bug.
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci  CAUTION:
2118c2ecf20Sopenharmony_ci     This program uses heuristics to guess which driver(s) support each
2128c2ecf20Sopenharmony_ci     compatible string and which config option(s) enables the driver(s).
2138c2ecf20Sopenharmony_ci     Do not believe that the reported information is fully correct.
2148c2ecf20Sopenharmony_ci     This program is intended to aid the process of determining the
2158c2ecf20Sopenharmony_ci     proper kernel configuration for a device tree, but this is not
2168c2ecf20Sopenharmony_ci     a fully automated process -- human involvement may still be
2178c2ecf20Sopenharmony_ci     required!
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ci     The driver match heuristic used is to search for source files
2208c2ecf20Sopenharmony_ci     containing the compatible string enclosed in quotes.
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci     This program might not be able to find all drivers matching a
2238c2ecf20Sopenharmony_ci     compatible string.
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci     Some makefiles are overly clever.  This program was not made
2268c2ecf20Sopenharmony_ci     complex enough to handle them.  If no config option is listed
2278c2ecf20Sopenharmony_ci     for a driver, look at the makefile for the driver source file.
2288c2ecf20Sopenharmony_ci     Even if a config option is listed for a driver, some other
2298c2ecf20Sopenharmony_ci     available config options may not be listed.
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci  FLAG values:
2328c2ecf20Sopenharmony_ci";
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci       for ($k = 0; $k < $num_pr_flags; $k++) {
2358c2ecf20Sopenharmony_ci               printf "     %s   %s\n", $pr_flag_value[$k], $pr_flag_help[$k];
2368c2ecf20Sopenharmony_ci       }
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci       print
2398c2ecf20Sopenharmony_ci"
2408c2ecf20Sopenharmony_ci     Upper case letters indicate potential issues or problems.
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci  The flag:
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci";
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_ci       $k = $pr_flag_pos_hard_coded;
2478c2ecf20Sopenharmony_ci       printf "     %s   %s\n", $pr_flag_value[$k], $pr_flag_help[$k];
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci       print
2508c2ecf20Sopenharmony_ci"
2518c2ecf20Sopenharmony_ci  will be set if the config or driver is in the white lists, even if
2528c2ecf20Sopenharmony_ci  --white-list-config and --white-list-driver are not specified.
2538c2ecf20Sopenharmony_ci  This is a hint that 1) many of these reported lines are likely to
2548c2ecf20Sopenharmony_ci  be incorrect, and 2) using those options will reduce the number of
2558c2ecf20Sopenharmony_ci  drivers and/or config options reported.
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_ci  --white-list-config and --white-list-driver may not be accurate if this
2588c2ecf20Sopenharmony_ci  program is not well maintained.  Use them with appropriate skepticism.
2598c2ecf20Sopenharmony_ci  Use the --show-lists option to report the values in the list.
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_ci  Return value:
2628c2ecf20Sopenharmony_ci    0   if no error
2638c2ecf20Sopenharmony_ci    1   error processing command line
2648c2ecf20Sopenharmony_ci    2   unable to open or read kernel config file
2658c2ecf20Sopenharmony_ci    3   unable to open or process input device tree file(s)
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ci  EXAMPLES:
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_ci     dt_to_config arch/arm/boot/dts/my_dts_file.dts
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_ci       Basic report.
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci     dt_to_config \\
2748c2ecf20Sopenharmony_ci        --config \${KBUILD_OUTPUT}/.config \\
2758c2ecf20Sopenharmony_ci        arch/\${ARCH}/boot/dts/my_dts_file.dts
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci       Full report, with config file issues noted.
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci     dt_to_config --include-suspect \\
2808c2ecf20Sopenharmony_ci        --config \${KBUILD_OUTPUT}/.config \\
2818c2ecf20Sopenharmony_ci        arch/\${ARCH}/boot/dts/my_dts_file.dts
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci       Report of node / compatible string / driver tuples that should
2848c2ecf20Sopenharmony_ci       be further investigated.  A node may have multiple compatible
2858c2ecf20Sopenharmony_ci       strings.  A compatible string may be matched by multiple drivers.
2868c2ecf20Sopenharmony_ci       A driver may have config file issues noted.  The compatible string
2878c2ecf20Sopenharmony_ci       and/or driver may be in the white lists.
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ci     dt_to_config --include-suspect --config-format \\
2908c2ecf20Sopenharmony_ci        --config ${KBUILD_OUTPUT}/.config \\
2918c2ecf20Sopenharmony_ci        arch/\${ARCH}/boot/dts/my_dts_file.dts
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ci       Report of node / compatible string / driver tuples that should
2948c2ecf20Sopenharmony_ci       be further investigated.  The report can be edited to uncomment
2958c2ecf20Sopenharmony_ci       the config options to select the desired tuple for a given node.
2968c2ecf20Sopenharmony_ci       A node may have multiple compatible strings.  A compatible string
2978c2ecf20Sopenharmony_ci       may be matched by multiple drivers.  A driver may have config file
2988c2ecf20Sopenharmony_ci       issues noted.  The compatible string and/or driver may be in the
2998c2ecf20Sopenharmony_ci       white lists.
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_ci";
3028c2ecf20Sopenharmony_ci}
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_cisub set_flag()
3058c2ecf20Sopenharmony_ci{
3068c2ecf20Sopenharmony_ci       # pr_flags_ref is a reference to $pr_flags
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_ci       my $pr_flags_ref = shift;
3098c2ecf20Sopenharmony_ci       my $pos          = shift;
3108c2ecf20Sopenharmony_ci
3118c2ecf20Sopenharmony_ci       substr $$pr_flags_ref, $pos, 1, $pr_flag_value[$pos];
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_ci       return $pr_flags;
3148c2ecf20Sopenharmony_ci}
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_cisub print_flags()
3178c2ecf20Sopenharmony_ci{
3188c2ecf20Sopenharmony_ci       # return 1 if anything printed, else 0
3198c2ecf20Sopenharmony_ci
3208c2ecf20Sopenharmony_ci       # some fields of pn_arg_ref might not be used in this function, but
3218c2ecf20Sopenharmony_ci       # extract all of them anyway.
3228c2ecf20Sopenharmony_ci       my $pn_arg_ref     = shift;
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ci       my $compat         = $pn_arg_ref->{compat};
3258c2ecf20Sopenharmony_ci       my $compatible_cnt = $pn_arg_ref->{compatible_cnt};
3268c2ecf20Sopenharmony_ci       my $config         = $pn_arg_ref->{config};
3278c2ecf20Sopenharmony_ci       my $config_cnt     = $pn_arg_ref->{config_cnt};
3288c2ecf20Sopenharmony_ci       my $driver         = $pn_arg_ref->{driver};
3298c2ecf20Sopenharmony_ci       my $driver_cnt     = $pn_arg_ref->{driver_cnt};
3308c2ecf20Sopenharmony_ci       my $full_node      = $pn_arg_ref->{full_node};
3318c2ecf20Sopenharmony_ci       my $node           = $pn_arg_ref->{node};
3328c2ecf20Sopenharmony_ci       my $node_enabled   = $pn_arg_ref->{node_enabled};
3338c2ecf20Sopenharmony_ci       my $white_list     = $pn_arg_ref->{white_list};
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_ci       my $pr_flags       = '-' x $num_pr_flags;
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci       # ----- set flags in $pr_flags
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci       if ($compatible_cnt > 1) {
3418c2ecf20Sopenharmony_ci               &set_flag(\$pr_flags, $pr_flag_pos_mcompatible);
3428c2ecf20Sopenharmony_ci       }
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_ci       if ($config_cnt > 1) {
3458c2ecf20Sopenharmony_ci               &set_flag(\$pr_flags, $pr_flag_pos_mconfig);
3468c2ecf20Sopenharmony_ci       }
3478c2ecf20Sopenharmony_ci
3488c2ecf20Sopenharmony_ci       if ($driver_cnt >= 1) {
3498c2ecf20Sopenharmony_ci               &set_flag(\$pr_flags, $pr_flag_pos_driver);
3508c2ecf20Sopenharmony_ci       }
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_ci       if ($driver_cnt > 1) {
3538c2ecf20Sopenharmony_ci               &set_flag(\$pr_flags, $pr_flag_pos_mdriver);
3548c2ecf20Sopenharmony_ci       }
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci       # These strings are the same way the linux kernel tests.
3578c2ecf20Sopenharmony_ci       # The ePapr lists of values is slightly different.
3588c2ecf20Sopenharmony_ci       if (!(
3598c2ecf20Sopenharmony_ci             ($node_enabled eq "") ||
3608c2ecf20Sopenharmony_ci             ($node_enabled eq "ok") ||
3618c2ecf20Sopenharmony_ci             ($node_enabled eq "okay")
3628c2ecf20Sopenharmony_ci            )) {
3638c2ecf20Sopenharmony_ci               &set_flag(\$pr_flags, $pr_flag_pos_node_not_enabled);
3648c2ecf20Sopenharmony_ci       }
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_ci       if ($white_list) {
3678c2ecf20Sopenharmony_ci               &set_flag(\$pr_flags, $pr_flag_pos_white_list);
3688c2ecf20Sopenharmony_ci       }
3698c2ecf20Sopenharmony_ci
3708c2ecf20Sopenharmony_ci       if (exists($driver_hard_code_list{$compat}) ||
3718c2ecf20Sopenharmony_ci           (exists($driver_config_hard_code_list{$driver}) &&
3728c2ecf20Sopenharmony_ci            ($driver ne "no_driver"))) {
3738c2ecf20Sopenharmony_ci               &set_flag(\$pr_flags, $pr_flag_pos_hard_coded);
3748c2ecf20Sopenharmony_ci       }
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci       my @configs = split(' && ', $config);
3778c2ecf20Sopenharmony_ci       for $configs (@configs) {
3788c2ecf20Sopenharmony_ci               $not = $configs =~ /^!/;
3798c2ecf20Sopenharmony_ci               $configs =~ s/^!//;
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_ci               if (($configs ne "no_config") && ($configs ne "no_makefile")) {
3828c2ecf20Sopenharmony_ci                       &set_flag(\$pr_flags, $pr_flag_pos_config);
3838c2ecf20Sopenharmony_ci               }
3848c2ecf20Sopenharmony_ci
3858c2ecf20Sopenharmony_ci               if (($config_cnt >= 1) &&
3868c2ecf20Sopenharmony_ci                   ($configs !~ /CONFIG_/) &&
3878c2ecf20Sopenharmony_ci                   (($configs ne "no_config") && ($configs ne "no_makefile"))) {
3888c2ecf20Sopenharmony_ci                       &set_flag(\$pr_flags, $pr_flag_pos_config_hard_coded);
3898c2ecf20Sopenharmony_ci               }
3908c2ecf20Sopenharmony_ci
3918c2ecf20Sopenharmony_ci               my $existing_config = $existing_config{$configs};
3928c2ecf20Sopenharmony_ci               if ($existing_config eq "m") {
3938c2ecf20Sopenharmony_ci                       &set_flag(\$pr_flags, $pr_flag_pos_config_m);
3948c2ecf20Sopenharmony_ci                       # Possible fail, depends on whether built in or
3958c2ecf20Sopenharmony_ci                       # module is desired.
3968c2ecf20Sopenharmony_ci                       &set_flag(\$pr_flags, $pr_flag_pos_config_test_fail);
3978c2ecf20Sopenharmony_ci               } elsif ($existing_config eq "y") {
3988c2ecf20Sopenharmony_ci                       &set_flag(\$pr_flags, $pr_flag_pos_config_y);
3998c2ecf20Sopenharmony_ci                       if ($not) {
4008c2ecf20Sopenharmony_ci                               &set_flag(\$pr_flags, $pr_flag_pos_config_test_fail);
4018c2ecf20Sopenharmony_ci                       }
4028c2ecf20Sopenharmony_ci               } elsif (($config_file) && ($configs =~ /CONFIG_/)) {
4038c2ecf20Sopenharmony_ci                       &set_flag(\$pr_flags, $pr_flag_pos_config_none);
4048c2ecf20Sopenharmony_ci                       if (!$not) {
4058c2ecf20Sopenharmony_ci                               &set_flag(\$pr_flags, $pr_flag_pos_config_test_fail);
4068c2ecf20Sopenharmony_ci                       }
4078c2ecf20Sopenharmony_ci               }
4088c2ecf20Sopenharmony_ci       }
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_ci       # ----- include / exclude filters
4118c2ecf20Sopenharmony_ci
4128c2ecf20Sopenharmony_ci       if ($include_flag_pattern && ($pr_flags !~ m/$include_flag_pattern/)) {
4138c2ecf20Sopenharmony_ci               return 0;
4148c2ecf20Sopenharmony_ci       }
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_ci       if ($exclude_flag_pattern && ($pr_flags =~ m/$exclude_flag_pattern/)) {
4178c2ecf20Sopenharmony_ci               return 0;
4188c2ecf20Sopenharmony_ci       }
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci       if ($config_format) {
4218c2ecf20Sopenharmony_ci               print "# ";
4228c2ecf20Sopenharmony_ci       }
4238c2ecf20Sopenharmony_ci       print "$pr_flags : ";
4248c2ecf20Sopenharmony_ci
4258c2ecf20Sopenharmony_ci       return 1;
4268c2ecf20Sopenharmony_ci}
4278c2ecf20Sopenharmony_ci
4288c2ecf20Sopenharmony_ci
4298c2ecf20Sopenharmony_cisub print_node()
4308c2ecf20Sopenharmony_ci{
4318c2ecf20Sopenharmony_ci       # return number of lines printed
4328c2ecf20Sopenharmony_ci
4338c2ecf20Sopenharmony_ci       # some fields of pn_arg_ref might not be used in this function, but
4348c2ecf20Sopenharmony_ci       # extract all of them anyway.
4358c2ecf20Sopenharmony_ci       my $pn_arg_ref     = shift;
4368c2ecf20Sopenharmony_ci
4378c2ecf20Sopenharmony_ci       my $compat         = $pn_arg_ref->{compat};
4388c2ecf20Sopenharmony_ci       my $compatible_cnt = $pn_arg_ref->{compatible_cnt};
4398c2ecf20Sopenharmony_ci       my $config         = $pn_arg_ref->{config};
4408c2ecf20Sopenharmony_ci       my $config_cnt     = $pn_arg_ref->{config_cnt};
4418c2ecf20Sopenharmony_ci       my $driver         = $pn_arg_ref->{driver};
4428c2ecf20Sopenharmony_ci       my $driver_cnt     = $pn_arg_ref->{driver_cnt};
4438c2ecf20Sopenharmony_ci       my $full_node      = $pn_arg_ref->{full_node};
4448c2ecf20Sopenharmony_ci       my $node           = $pn_arg_ref->{node};
4458c2ecf20Sopenharmony_ci       my $node_enabled   = $pn_arg_ref->{node_enabled};
4468c2ecf20Sopenharmony_ci       my $white_list     = $pn_arg_ref->{white_list};
4478c2ecf20Sopenharmony_ci
4488c2ecf20Sopenharmony_ci       my $separator;
4498c2ecf20Sopenharmony_ci
4508c2ecf20Sopenharmony_ci       if (! &print_flags($pn_arg_ref)) {
4518c2ecf20Sopenharmony_ci               return 0;
4528c2ecf20Sopenharmony_ci       }
4538c2ecf20Sopenharmony_ci
4548c2ecf20Sopenharmony_ci
4558c2ecf20Sopenharmony_ci       if ($short_name) {
4568c2ecf20Sopenharmony_ci               print "$node";
4578c2ecf20Sopenharmony_ci       } else {
4588c2ecf20Sopenharmony_ci               print "$full_node";
4598c2ecf20Sopenharmony_ci       }
4608c2ecf20Sopenharmony_ci       print " : $compat : $driver : $config : ";
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci       my @configs = split(' && ', $config);
4638c2ecf20Sopenharmony_ci
4648c2ecf20Sopenharmony_ci       if ($config_file) {
4658c2ecf20Sopenharmony_ci               for $configs (@configs) {
4668c2ecf20Sopenharmony_ci                       $configs =~ s/^!//;
4678c2ecf20Sopenharmony_ci                       my $existing_config = $existing_config{$configs};
4688c2ecf20Sopenharmony_ci                       if (!$existing_config) {
4698c2ecf20Sopenharmony_ci                               # check for /-m/, /-y/, or /-objs/
4708c2ecf20Sopenharmony_ci                               if ($configs !~ /CONFIG_/) {
4718c2ecf20Sopenharmony_ci                                       $existing_config = "x";
4728c2ecf20Sopenharmony_ci                               };
4738c2ecf20Sopenharmony_ci                       };
4748c2ecf20Sopenharmony_ci                       if ($existing_config) {
4758c2ecf20Sopenharmony_ci                               print "$separator", "$existing_config";
4768c2ecf20Sopenharmony_ci                               $separator = ", ";
4778c2ecf20Sopenharmony_ci                       } else {
4788c2ecf20Sopenharmony_ci                               print "$separator", "n";
4798c2ecf20Sopenharmony_ci                               $separator = ", ";
4808c2ecf20Sopenharmony_ci                       }
4818c2ecf20Sopenharmony_ci               }
4828c2ecf20Sopenharmony_ci       } else {
4838c2ecf20Sopenharmony_ci               print "none";
4848c2ecf20Sopenharmony_ci       }
4858c2ecf20Sopenharmony_ci
4868c2ecf20Sopenharmony_ci       print "\n";
4878c2ecf20Sopenharmony_ci
4888c2ecf20Sopenharmony_ci       if ($config_format) {
4898c2ecf20Sopenharmony_ci               for $configs (@configs) {
4908c2ecf20Sopenharmony_ci                       $not = $configs =~ /^!/;
4918c2ecf20Sopenharmony_ci                       $configs =~ s/^!//;
4928c2ecf20Sopenharmony_ci                       my $existing_config = $existing_config{$configs};
4938c2ecf20Sopenharmony_ci
4948c2ecf20Sopenharmony_ci                       if ($not) {
4958c2ecf20Sopenharmony_ci                               if ($configs !~ /CONFIG_/) {
4968c2ecf20Sopenharmony_ci                                       print "# $configs\n";
4978c2ecf20Sopenharmony_ci                               } elsif ($existing_config eq "m") {
4988c2ecf20Sopenharmony_ci                                       print "# $configs is m\n";
4998c2ecf20Sopenharmony_ci                                       print "# $configs=n\n";
5008c2ecf20Sopenharmony_ci                               } elsif ($existing_config eq "y") {
5018c2ecf20Sopenharmony_ci                                       print "# $configs is set\n";
5028c2ecf20Sopenharmony_ci                                       print "# $configs=n\n";
5038c2ecf20Sopenharmony_ci                               } else {
5048c2ecf20Sopenharmony_ci                                       print "# $configs is not set\n";
5058c2ecf20Sopenharmony_ci                                       print "# $configs=n\n";
5068c2ecf20Sopenharmony_ci                               }
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_ci                       } else {
5098c2ecf20Sopenharmony_ci                               if ($configs !~ /CONFIG_/) {
5108c2ecf20Sopenharmony_ci                                       print "# $configs\n";
5118c2ecf20Sopenharmony_ci                               } elsif ($existing_config eq "m") {
5128c2ecf20Sopenharmony_ci                                       print "# $configs is m\n";
5138c2ecf20Sopenharmony_ci                                       print "# $configs=y\n";
5148c2ecf20Sopenharmony_ci                               } elsif ($existing_config eq "y") {
5158c2ecf20Sopenharmony_ci                                       print "# $configs is set\n";
5168c2ecf20Sopenharmony_ci                                       print "# $configs=y\n";
5178c2ecf20Sopenharmony_ci                               } else {
5188c2ecf20Sopenharmony_ci                                       print "# $configs is not set\n";
5198c2ecf20Sopenharmony_ci                                       print "# $configs=y\n";
5208c2ecf20Sopenharmony_ci                               }
5218c2ecf20Sopenharmony_ci                       }
5228c2ecf20Sopenharmony_ci               }
5238c2ecf20Sopenharmony_ci       }
5248c2ecf20Sopenharmony_ci
5258c2ecf20Sopenharmony_ci       return 1;
5268c2ecf20Sopenharmony_ci}
5278c2ecf20Sopenharmony_ci
5288c2ecf20Sopenharmony_ci
5298c2ecf20Sopenharmony_cisub scan_makefile
5308c2ecf20Sopenharmony_ci{
5318c2ecf20Sopenharmony_ci       my $pn_arg_ref    = shift;
5328c2ecf20Sopenharmony_ci       my $driver        = shift;
5338c2ecf20Sopenharmony_ci
5348c2ecf20Sopenharmony_ci       # ----- Find Kconfig symbols that enable driver
5358c2ecf20Sopenharmony_ci
5368c2ecf20Sopenharmony_ci       my ($dir, $base) = $driver =~ m{(.*)/(.*).c};
5378c2ecf20Sopenharmony_ci
5388c2ecf20Sopenharmony_ci       my $makefile = $dir . "/Makefile";
5398c2ecf20Sopenharmony_ci       if (! -r $makefile) {
5408c2ecf20Sopenharmony_ci               $makefile = $dir . "/Kbuild";
5418c2ecf20Sopenharmony_ci       }
5428c2ecf20Sopenharmony_ci       if (! -r $makefile) {
5438c2ecf20Sopenharmony_ci               my $config;
5448c2ecf20Sopenharmony_ci
5458c2ecf20Sopenharmony_ci               $config = 'no_makefile';
5468c2ecf20Sopenharmony_ci               push @{ $driver_config{$driver} }, $config;
5478c2ecf20Sopenharmony_ci               return;
5488c2ecf20Sopenharmony_ci       }
5498c2ecf20Sopenharmony_ci
5508c2ecf20Sopenharmony_ci       if (!open(MAKEFILE_FILE, "<", "$makefile")) {
5518c2ecf20Sopenharmony_ci               return;
5528c2ecf20Sopenharmony_ci       }
5538c2ecf20Sopenharmony_ci
5548c2ecf20Sopenharmony_ci       my $line;
5558c2ecf20Sopenharmony_ci       my @config;
5568c2ecf20Sopenharmony_ci       my @if_config;
5578c2ecf20Sopenharmony_ci       my @make_var;
5588c2ecf20Sopenharmony_ci
5598c2ecf20Sopenharmony_ci       NEXT_LINE:
5608c2ecf20Sopenharmony_ci       while ($next_line = <MAKEFILE_FILE>) {
5618c2ecf20Sopenharmony_ci               my $config;
5628c2ecf20Sopenharmony_ci               my $if_config;
5638c2ecf20Sopenharmony_ci               my $ifdef;
5648c2ecf20Sopenharmony_ci               my $ifeq;
5658c2ecf20Sopenharmony_ci               my $ifndef;
5668c2ecf20Sopenharmony_ci               my $ifneq;
5678c2ecf20Sopenharmony_ci               my $ifdef_config;
5688c2ecf20Sopenharmony_ci               my $ifeq_config;
5698c2ecf20Sopenharmony_ci               my $ifndef_config;
5708c2ecf20Sopenharmony_ci               my $ifneq_config;
5718c2ecf20Sopenharmony_ci
5728c2ecf20Sopenharmony_ci               chomp($next_line);
5738c2ecf20Sopenharmony_ci               $line = $line . $next_line;
5748c2ecf20Sopenharmony_ci               if ($next_line =~ /\\$/) {
5758c2ecf20Sopenharmony_ci                       $line =~ s/\\$/ /;
5768c2ecf20Sopenharmony_ci                       next NEXT_LINE;
5778c2ecf20Sopenharmony_ci               }
5788c2ecf20Sopenharmony_ci               if ($line =~ /^\s*#/) {
5798c2ecf20Sopenharmony_ci                       $line = "";
5808c2ecf20Sopenharmony_ci                       next NEXT_LINE;
5818c2ecf20Sopenharmony_ci               }
5828c2ecf20Sopenharmony_ci
5838c2ecf20Sopenharmony_ci               # -----  condition ... else ... endif
5848c2ecf20Sopenharmony_ci
5858c2ecf20Sopenharmony_ci               if ($line =~ /^([ ]\s*|)else\b/) {
5868c2ecf20Sopenharmony_ci                       $if_config = "!" . pop @if_config;
5878c2ecf20Sopenharmony_ci                       $if_config =~ s/^!!//;
5888c2ecf20Sopenharmony_ci                       push @if_config, $if_config;
5898c2ecf20Sopenharmony_ci                       $line =~ s/^([ ]\s*|)else\b//;
5908c2ecf20Sopenharmony_ci               }
5918c2ecf20Sopenharmony_ci
5928c2ecf20Sopenharmony_ci               ($null, $ifeq_config,  $ifeq_config_val )  = $line =~ /^([ ]\s*|)ifeq\b.*\b(CONFIG_[A-Za-z0-9_]*)(.*)/;
5938c2ecf20Sopenharmony_ci               ($null, $ifneq_config, $ifneq_config_val)  = $line =~ /^([ ]\s*|)ifneq\b.*\b(CONFIG_[A-Za-z0-9_]*)(.*)/;
5948c2ecf20Sopenharmony_ci               ($null, $ifdef_config)                     = $line =~ /^([ ]\s*|)ifdef\b.*\b(CONFIG_[A-Za-z0-9_]*)/;
5958c2ecf20Sopenharmony_ci               ($null, $ifndef_config)                    = $line =~ /^([ ]\s*|)ifndef\b.*\b(CONFIG_[A-Za-z0-9_]*)/;
5968c2ecf20Sopenharmony_ci
5978c2ecf20Sopenharmony_ci               ($null, $ifeq)   = $line =~ /^([ ]\s*|)ifeq\b\s*(.*)/;
5988c2ecf20Sopenharmony_ci               ($null, $ifneq)  = $line =~ /^([ ]\s*|)ifneq\b\s*(.*)/;
5998c2ecf20Sopenharmony_ci               ($null, $ifdef)  = $line =~ /^([ ]\s*|)ifdef\b\s*(.*)/;
6008c2ecf20Sopenharmony_ci               ($null, $ifndef) = $line =~ /^([ ]\s*|)ifndef\b\s*(.*)/;
6018c2ecf20Sopenharmony_ci
6028c2ecf20Sopenharmony_ci               # Order of tests is important.  Prefer "CONFIG_*" regex match over
6038c2ecf20Sopenharmony_ci               # less specific regex match.
6048c2ecf20Sopenharmony_ci               if ($ifdef_config) {
6058c2ecf20Sopenharmony_ci                       $if_config = $ifdef_config;
6068c2ecf20Sopenharmony_ci               } elsif ($ifeq_config) {
6078c2ecf20Sopenharmony_ci                       if ($ifeq_config_val =~ /y/) {
6088c2ecf20Sopenharmony_ci                               $if_config = $ifeq_config;
6098c2ecf20Sopenharmony_ci                       } else {
6108c2ecf20Sopenharmony_ci                               $if_config = "!" . $ifeq_config;
6118c2ecf20Sopenharmony_ci                       }
6128c2ecf20Sopenharmony_ci               } elsif ($ifndef_config) {
6138c2ecf20Sopenharmony_ci                       $if_config = "!" . $ifndef_config;
6148c2ecf20Sopenharmony_ci               } elsif ($ifneq_config) {
6158c2ecf20Sopenharmony_ci                       if ($ifneq_config_val =~ /y/) {
6168c2ecf20Sopenharmony_ci                               $if_config = "!" . $ifneq_config;
6178c2ecf20Sopenharmony_ci                       } else {
6188c2ecf20Sopenharmony_ci                               $if_config = $ifneq_config;
6198c2ecf20Sopenharmony_ci                       }
6208c2ecf20Sopenharmony_ci               } elsif ($ifdef) {
6218c2ecf20Sopenharmony_ci                       $if_config = $ifdef;
6228c2ecf20Sopenharmony_ci               } elsif ($ifeq) {
6238c2ecf20Sopenharmony_ci                       $if_config = $ifeq;
6248c2ecf20Sopenharmony_ci               } elsif ($ifndef) {
6258c2ecf20Sopenharmony_ci                       $if_config = "!" . $ifndef;
6268c2ecf20Sopenharmony_ci               } elsif ($ifneq) {
6278c2ecf20Sopenharmony_ci                       $if_config = "!" . $ifneq;
6288c2ecf20Sopenharmony_ci               } else {
6298c2ecf20Sopenharmony_ci                       $if_config = "";
6308c2ecf20Sopenharmony_ci               }
6318c2ecf20Sopenharmony_ci               $if_config =~ s/^!!//;
6328c2ecf20Sopenharmony_ci
6338c2ecf20Sopenharmony_ci               if ($if_config) {
6348c2ecf20Sopenharmony_ci                       push @if_config, $if_config;
6358c2ecf20Sopenharmony_ci                       $line = "";
6368c2ecf20Sopenharmony_ci                       next NEXT_LINE;
6378c2ecf20Sopenharmony_ci               }
6388c2ecf20Sopenharmony_ci
6398c2ecf20Sopenharmony_ci               if ($line =~ /^([ ]\s*|)endif\b/) {
6408c2ecf20Sopenharmony_ci                       pop @if_config;
6418c2ecf20Sopenharmony_ci                       $line = "";
6428c2ecf20Sopenharmony_ci                       next NEXT_LINE;
6438c2ecf20Sopenharmony_ci               }
6448c2ecf20Sopenharmony_ci
6458c2ecf20Sopenharmony_ci               # ----- simple CONFIG_* = *.[co]  or  xxx [+:?]*= *.[co]
6468c2ecf20Sopenharmony_ci               # Most makefiles select on *.o, but
6478c2ecf20Sopenharmony_ci               # arch/powerpc/boot/Makefile selects on *.c
6488c2ecf20Sopenharmony_ci
6498c2ecf20Sopenharmony_ci               ($config) = $line =~ /(CONFIG_[A-Za-z0-9_]+).*\b$base.[co]\b/;
6508c2ecf20Sopenharmony_ci
6518c2ecf20Sopenharmony_ci               # ----- match a make variable instead of *.[co]
6528c2ecf20Sopenharmony_ci               # Recursively expanded variables are not handled.
6538c2ecf20Sopenharmony_ci
6548c2ecf20Sopenharmony_ci               if (!$config) {
6558c2ecf20Sopenharmony_ci                       my $make_var;
6568c2ecf20Sopenharmony_ci                       ($make_var) = $line =~ /\s*(\S+?)\s*[+:\?]*=.*\b$base.[co]\b/;
6578c2ecf20Sopenharmony_ci                       if ($make_var) {
6588c2ecf20Sopenharmony_ci                               if ($make_var =~ /[a-zA-Z0-9]+-[ym]/) {
6598c2ecf20Sopenharmony_ci                                       $config = $make_var;
6608c2ecf20Sopenharmony_ci                               } elsif ($make_var =~ /[a-zA-Z0-9]+-objs/) {
6618c2ecf20Sopenharmony_ci                                       $config = $make_var;
6628c2ecf20Sopenharmony_ci                               } else {
6638c2ecf20Sopenharmony_ci                                       push @make_var, $make_var;
6648c2ecf20Sopenharmony_ci                               }
6658c2ecf20Sopenharmony_ci                       }
6668c2ecf20Sopenharmony_ci               }
6678c2ecf20Sopenharmony_ci
6688c2ecf20Sopenharmony_ci               if (!$config) {
6698c2ecf20Sopenharmony_ci                       for $make_var (@make_var) {
6708c2ecf20Sopenharmony_ci                               ($config) = $line =~ /(CONFIG_[A-Za-z0-9_]+).*\b$make_var\b/;
6718c2ecf20Sopenharmony_ci                               last if ($config);
6728c2ecf20Sopenharmony_ci                       }
6738c2ecf20Sopenharmony_ci               }
6748c2ecf20Sopenharmony_ci
6758c2ecf20Sopenharmony_ci               if (!$config) {
6768c2ecf20Sopenharmony_ci                       for $make_var (@make_var) {
6778c2ecf20Sopenharmony_ci                               ($config) = $line =~ /\s*(\S+?)\s*[+:\?]*=.*\b$make_var\b/;
6788c2ecf20Sopenharmony_ci                               last if ($config);
6798c2ecf20Sopenharmony_ci                       }
6808c2ecf20Sopenharmony_ci               }
6818c2ecf20Sopenharmony_ci
6828c2ecf20Sopenharmony_ci               # ----- next if no config found
6838c2ecf20Sopenharmony_ci
6848c2ecf20Sopenharmony_ci               if (!$config) {
6858c2ecf20Sopenharmony_ci                       $line = "";
6868c2ecf20Sopenharmony_ci                       next NEXT_LINE;
6878c2ecf20Sopenharmony_ci               }
6888c2ecf20Sopenharmony_ci
6898c2ecf20Sopenharmony_ci               for $if_config (@if_config) {
6908c2ecf20Sopenharmony_ci                       $config = $if_config . " && " . $config;
6918c2ecf20Sopenharmony_ci               }
6928c2ecf20Sopenharmony_ci
6938c2ecf20Sopenharmony_ci               push @{ $driver_config{$driver} }, $config;
6948c2ecf20Sopenharmony_ci
6958c2ecf20Sopenharmony_ci               $line = "";
6968c2ecf20Sopenharmony_ci       }
6978c2ecf20Sopenharmony_ci
6988c2ecf20Sopenharmony_ci       close(MAKEFILE_FILE);
6998c2ecf20Sopenharmony_ci
7008c2ecf20Sopenharmony_ci}
7018c2ecf20Sopenharmony_ci
7028c2ecf20Sopenharmony_ci
7038c2ecf20Sopenharmony_cisub find_kconfig
7048c2ecf20Sopenharmony_ci{
7058c2ecf20Sopenharmony_ci       my $pn_arg_ref    = shift;
7068c2ecf20Sopenharmony_ci       my $driver        = shift;
7078c2ecf20Sopenharmony_ci
7088c2ecf20Sopenharmony_ci       my $lines_printed = 0;
7098c2ecf20Sopenharmony_ci       my @configs;
7108c2ecf20Sopenharmony_ci
7118c2ecf20Sopenharmony_ci       if (!@{ $driver_config{$driver} }) {
7128c2ecf20Sopenharmony_ci               &scan_makefile($pn_arg_ref, $driver);
7138c2ecf20Sopenharmony_ci               if (!@{ $driver_config{$driver} }) {
7148c2ecf20Sopenharmony_ci                       push @{ $driver_config{$driver} }, "no_config";
7158c2ecf20Sopenharmony_ci               }
7168c2ecf20Sopenharmony_ci       }
7178c2ecf20Sopenharmony_ci
7188c2ecf20Sopenharmony_ci       @configs = @{ $driver_config{$driver} };
7198c2ecf20Sopenharmony_ci
7208c2ecf20Sopenharmony_ci       $$pn_arg_ref{config_cnt} = $#configs + 1;
7218c2ecf20Sopenharmony_ci       for my $config (@configs) {
7228c2ecf20Sopenharmony_ci               $$pn_arg_ref{config} = $config;
7238c2ecf20Sopenharmony_ci               $lines_printed += &print_node($pn_arg_ref);
7248c2ecf20Sopenharmony_ci       }
7258c2ecf20Sopenharmony_ci
7268c2ecf20Sopenharmony_ci       return $lines_printed;
7278c2ecf20Sopenharmony_ci}
7288c2ecf20Sopenharmony_ci
7298c2ecf20Sopenharmony_ci
7308c2ecf20Sopenharmony_cisub handle_compatible()
7318c2ecf20Sopenharmony_ci{
7328c2ecf20Sopenharmony_ci       my $full_node     = shift;
7338c2ecf20Sopenharmony_ci       my $node          = shift;
7348c2ecf20Sopenharmony_ci       my $compatible    = shift;
7358c2ecf20Sopenharmony_ci       my $node_enabled  = shift;
7368c2ecf20Sopenharmony_ci
7378c2ecf20Sopenharmony_ci       my $compat;
7388c2ecf20Sopenharmony_ci       my $lines_printed = 0;
7398c2ecf20Sopenharmony_ci       my %pn_arg        = ();
7408c2ecf20Sopenharmony_ci
7418c2ecf20Sopenharmony_ci       return if (!$node or !$compatible);
7428c2ecf20Sopenharmony_ci
7438c2ecf20Sopenharmony_ci       # Do not process compatible property of root node,
7448c2ecf20Sopenharmony_ci       # it is used to match board, not to bind a driver.
7458c2ecf20Sopenharmony_ci       return if ($node eq "/");
7468c2ecf20Sopenharmony_ci
7478c2ecf20Sopenharmony_ci       $pn_arg{full_node}    = $full_node;
7488c2ecf20Sopenharmony_ci       $pn_arg{node}         = $node;
7498c2ecf20Sopenharmony_ci       $pn_arg{node_enabled} = $node_enabled;
7508c2ecf20Sopenharmony_ci
7518c2ecf20Sopenharmony_ci       my @compatibles = split('", "', $compatible);
7528c2ecf20Sopenharmony_ci
7538c2ecf20Sopenharmony_ci       $compatibles[0] =~ s/^"//;
7548c2ecf20Sopenharmony_ci       $compatibles[$#compatibles] =~ s/"$//;
7558c2ecf20Sopenharmony_ci
7568c2ecf20Sopenharmony_ci       $pn_arg{compatible_cnt} = $#compatibles + 1;
7578c2ecf20Sopenharmony_ci
7588c2ecf20Sopenharmony_ci       COMPAT:
7598c2ecf20Sopenharmony_ci       for $compat (@compatibles) {
7608c2ecf20Sopenharmony_ci
7618c2ecf20Sopenharmony_ci               $pn_arg{compat}     = $compat;
7628c2ecf20Sopenharmony_ci               $pn_arg{driver_cnt} = 0;
7638c2ecf20Sopenharmony_ci               $pn_arg{white_list} = 0;
7648c2ecf20Sopenharmony_ci
7658c2ecf20Sopenharmony_ci               if (exists($compat_white_list{$compat})) {
7668c2ecf20Sopenharmony_ci                       $pn_arg{white_list} = 1;
7678c2ecf20Sopenharmony_ci                       $pn_arg{driver}     = "no_driver";
7688c2ecf20Sopenharmony_ci                       $pn_arg{config_cnt} = 1;
7698c2ecf20Sopenharmony_ci                       $pn_arg{config}     = "no_config";
7708c2ecf20Sopenharmony_ci                       $lines_printed += &print_node(\%pn_arg);
7718c2ecf20Sopenharmony_ci                       next COMPAT;
7728c2ecf20Sopenharmony_ci               }
7738c2ecf20Sopenharmony_ci
7748c2ecf20Sopenharmony_ci               # ----- if compat previously seen, use cached info
7758c2ecf20Sopenharmony_ci
7768c2ecf20Sopenharmony_ci               if (exists($compat_driver{$compat})) {
7778c2ecf20Sopenharmony_ci                       for my $driver (@{ $compat_driver{$compat} }) {
7788c2ecf20Sopenharmony_ci                               $pn_arg{driver}     = $driver;
7798c2ecf20Sopenharmony_ci                               $pn_arg{driver_cnt} = $driver_count{$compat};
7808c2ecf20Sopenharmony_ci                               $pn_arg{config_cnt} = $#{ $driver_config{$driver}} + 1;
7818c2ecf20Sopenharmony_ci
7828c2ecf20Sopenharmony_ci                               for my $config (@{ $driver_config{$driver} }) {
7838c2ecf20Sopenharmony_ci                                       $pn_arg{config} = $config;
7848c2ecf20Sopenharmony_ci                                       $lines_printed += &print_node(\%pn_arg);
7858c2ecf20Sopenharmony_ci                               }
7868c2ecf20Sopenharmony_ci
7878c2ecf20Sopenharmony_ci                               if (!@{ $driver_config{$driver} }) {
7888c2ecf20Sopenharmony_ci                                       # no config cached yet
7898c2ecf20Sopenharmony_ci                                       # $driver in %driver_hard_code_list
7908c2ecf20Sopenharmony_ci                                       # but not %driver_config_hard_code_list
7918c2ecf20Sopenharmony_ci                                       $lines_printed += &find_kconfig(\%pn_arg, $driver);
7928c2ecf20Sopenharmony_ci                               }
7938c2ecf20Sopenharmony_ci                       }
7948c2ecf20Sopenharmony_ci                       next COMPAT;
7958c2ecf20Sopenharmony_ci               }
7968c2ecf20Sopenharmony_ci
7978c2ecf20Sopenharmony_ci
7988c2ecf20Sopenharmony_ci               # ----- Find drivers (source files that contain compatible)
7998c2ecf20Sopenharmony_ci
8008c2ecf20Sopenharmony_ci               # this will miss arch/sparc/include/asm/parport.h
8018c2ecf20Sopenharmony_ci               # It is better to move the compatible out of the .h
8028c2ecf20Sopenharmony_ci               # than to add *.h. to the files list, because *.h generates
8038c2ecf20Sopenharmony_ci               # a lot of false negatives.
8048c2ecf20Sopenharmony_ci               my $files = '"*.c"';
8058c2ecf20Sopenharmony_ci               my $drivers = `git grep -l '"$compat"' -- $files`;
8068c2ecf20Sopenharmony_ci               chomp($drivers);
8078c2ecf20Sopenharmony_ci               if ($drivers eq "") {
8088c2ecf20Sopenharmony_ci                       $pn_arg{driver} = "no_driver";
8098c2ecf20Sopenharmony_ci                       $pn_arg{config_cnt} = 1;
8108c2ecf20Sopenharmony_ci                       $pn_arg{config} = "no_config";
8118c2ecf20Sopenharmony_ci                       push @{ $compat_driver{$compat} }, "no_driver";
8128c2ecf20Sopenharmony_ci                       $lines_printed += &print_node(\%pn_arg);
8138c2ecf20Sopenharmony_ci                       next COMPAT;
8148c2ecf20Sopenharmony_ci               }
8158c2ecf20Sopenharmony_ci
8168c2ecf20Sopenharmony_ci               my @drivers = split("\n", $drivers);
8178c2ecf20Sopenharmony_ci               $driver_count{$compat} = $#drivers + 1;
8188c2ecf20Sopenharmony_ci               $pn_arg{driver_cnt}    = $#drivers + 1;
8198c2ecf20Sopenharmony_ci
8208c2ecf20Sopenharmony_ci               DRIVER:
8218c2ecf20Sopenharmony_ci               for my $driver (@drivers) {
8228c2ecf20Sopenharmony_ci                       push @{ $compat_driver{$compat} }, $driver;
8238c2ecf20Sopenharmony_ci                       $pn_arg{driver} = $driver;
8248c2ecf20Sopenharmony_ci
8258c2ecf20Sopenharmony_ci                       # ----- if driver previously seen, use cached info
8268c2ecf20Sopenharmony_ci
8278c2ecf20Sopenharmony_ci                       $pn_arg{config_cnt} = $#{ $driver_config{$driver} } + 1;
8288c2ecf20Sopenharmony_ci                       for my $config (@{ $driver_config{$driver} }) {
8298c2ecf20Sopenharmony_ci                               $pn_arg{config} = $config;
8308c2ecf20Sopenharmony_ci                               $lines_printed += &print_node(\%pn_arg);
8318c2ecf20Sopenharmony_ci                       }
8328c2ecf20Sopenharmony_ci                       if (@{ $driver_config{$driver} }) {
8338c2ecf20Sopenharmony_ci                               next DRIVER;
8348c2ecf20Sopenharmony_ci                       }
8358c2ecf20Sopenharmony_ci
8368c2ecf20Sopenharmony_ci                       if ($black_list_driver) {
8378c2ecf20Sopenharmony_ci                               for $black (@black_list_driver) {
8388c2ecf20Sopenharmony_ci                                       next DRIVER if ($driver =~ /^$black$/);
8398c2ecf20Sopenharmony_ci                               }
8408c2ecf20Sopenharmony_ci                       }
8418c2ecf20Sopenharmony_ci
8428c2ecf20Sopenharmony_ci
8438c2ecf20Sopenharmony_ci                       # ----- Find Kconfig symbols that enable driver
8448c2ecf20Sopenharmony_ci
8458c2ecf20Sopenharmony_ci                       $lines_printed += &find_kconfig(\%pn_arg, $driver);
8468c2ecf20Sopenharmony_ci
8478c2ecf20Sopenharmony_ci               }
8488c2ecf20Sopenharmony_ci       }
8498c2ecf20Sopenharmony_ci
8508c2ecf20Sopenharmony_ci       # White space (line) between nodes for readability.
8518c2ecf20Sopenharmony_ci       # Each node may report several compatibles.
8528c2ecf20Sopenharmony_ci       # For each compatible, multiple drivers may be reported.
8538c2ecf20Sopenharmony_ci       # For each driver, multiple CONFIG_ options may be reported.
8548c2ecf20Sopenharmony_ci       if ($lines_printed) {
8558c2ecf20Sopenharmony_ci               print "\n";
8568c2ecf20Sopenharmony_ci       }
8578c2ecf20Sopenharmony_ci}
8588c2ecf20Sopenharmony_ci
8598c2ecf20Sopenharmony_cisub read_dts()
8608c2ecf20Sopenharmony_ci{
8618c2ecf20Sopenharmony_ci       my $file         = shift;
8628c2ecf20Sopenharmony_ci
8638c2ecf20Sopenharmony_ci       my $compatible   = "";
8648c2ecf20Sopenharmony_ci       my $line;
8658c2ecf20Sopenharmony_ci       my $node         = "";
8668c2ecf20Sopenharmony_ci       my $node_enabled = "";
8678c2ecf20Sopenharmony_ci
8688c2ecf20Sopenharmony_ci       if (! -r $file) {
8698c2ecf20Sopenharmony_ci               print STDERR "file '$file' is not readable or does not exist\n";
8708c2ecf20Sopenharmony_ci               exit 3;
8718c2ecf20Sopenharmony_ci       }
8728c2ecf20Sopenharmony_ci
8738c2ecf20Sopenharmony_ci       if (!open(DT_FILE, "-|", "$dtx_diff $file")) {
8748c2ecf20Sopenharmony_ci               print STDERR "\n";
8758c2ecf20Sopenharmony_ci               print STDERR "shell command failed:\n";
8768c2ecf20Sopenharmony_ci               print STDERR "   $dtx_diff $file\n";
8778c2ecf20Sopenharmony_ci               print STDERR "\n";
8788c2ecf20Sopenharmony_ci               exit 3;
8798c2ecf20Sopenharmony_ci       }
8808c2ecf20Sopenharmony_ci
8818c2ecf20Sopenharmony_ci       FILE:
8828c2ecf20Sopenharmony_ci       while ($line = <DT_FILE>) {
8838c2ecf20Sopenharmony_ci               chomp($line);
8848c2ecf20Sopenharmony_ci
8858c2ecf20Sopenharmony_ci               if ($line =~ /{/) {
8868c2ecf20Sopenharmony_ci
8878c2ecf20Sopenharmony_ci                       &handle_compatible($full_node, $node, $compatible,
8888c2ecf20Sopenharmony_ci                                          $node_enabled);
8898c2ecf20Sopenharmony_ci
8908c2ecf20Sopenharmony_ci                       while ($end_node_count-- > 0) {
8918c2ecf20Sopenharmony_ci                               pop @full_node;
8928c2ecf20Sopenharmony_ci                       };
8938c2ecf20Sopenharmony_ci                       $end_node_count = 0;
8948c2ecf20Sopenharmony_ci                       $full_node = @full_node[-1];
8958c2ecf20Sopenharmony_ci
8968c2ecf20Sopenharmony_ci                       $node = $line;
8978c2ecf20Sopenharmony_ci                       $node =~ s/^\s*(.*)\s+\{.*/$1/;
8988c2ecf20Sopenharmony_ci                       $node =~ s/.*: //;
8998c2ecf20Sopenharmony_ci                       if ($node eq '/' ) {
9008c2ecf20Sopenharmony_ci                               $full_node = '/';
9018c2ecf20Sopenharmony_ci                       } elsif ($full_node ne '/') {
9028c2ecf20Sopenharmony_ci                               $full_node = $full_node . '/' . $node;
9038c2ecf20Sopenharmony_ci                       } else {
9048c2ecf20Sopenharmony_ci                               $full_node = '/' . $node;
9058c2ecf20Sopenharmony_ci                       }
9068c2ecf20Sopenharmony_ci                       push @full_node, $full_node;
9078c2ecf20Sopenharmony_ci
9088c2ecf20Sopenharmony_ci                       $compatible = "";
9098c2ecf20Sopenharmony_ci                       $node_enabled = "";
9108c2ecf20Sopenharmony_ci                       next FILE;
9118c2ecf20Sopenharmony_ci               }
9128c2ecf20Sopenharmony_ci
9138c2ecf20Sopenharmony_ci               if ($line =~ /}/) {
9148c2ecf20Sopenharmony_ci                       $end_node_count++;
9158c2ecf20Sopenharmony_ci               }
9168c2ecf20Sopenharmony_ci
9178c2ecf20Sopenharmony_ci               if ($line =~ /(\s+|^)status =/) {
9188c2ecf20Sopenharmony_ci                       $node_enabled = $line;
9198c2ecf20Sopenharmony_ci                       $node_enabled =~ s/^\t*//;
9208c2ecf20Sopenharmony_ci                       $node_enabled =~ s/^status = "//;
9218c2ecf20Sopenharmony_ci                       $node_enabled =~ s/";$//;
9228c2ecf20Sopenharmony_ci                       next FILE;
9238c2ecf20Sopenharmony_ci               }
9248c2ecf20Sopenharmony_ci
9258c2ecf20Sopenharmony_ci               if ($line =~ /(\s+|^)compatible =/) {
9268c2ecf20Sopenharmony_ci                       # Extract all compatible entries for this device
9278c2ecf20Sopenharmony_ci                       # White space matching here and in handle_compatible() is
9288c2ecf20Sopenharmony_ci                       # precise, because input format is the output of dtc,
9298c2ecf20Sopenharmony_ci                       # which is invoked by dtx_diff.
9308c2ecf20Sopenharmony_ci                       $compatible = $line;
9318c2ecf20Sopenharmony_ci                       $compatible =~ s/^\t*//;
9328c2ecf20Sopenharmony_ci                       $compatible =~ s/^compatible = //;
9338c2ecf20Sopenharmony_ci                       $compatible =~ s/;$//;
9348c2ecf20Sopenharmony_ci               }
9358c2ecf20Sopenharmony_ci       }
9368c2ecf20Sopenharmony_ci
9378c2ecf20Sopenharmony_ci       &handle_compatible($full_node, $node, $compatible, $node_enabled);
9388c2ecf20Sopenharmony_ci
9398c2ecf20Sopenharmony_ci       close(DT_FILE);
9408c2ecf20Sopenharmony_ci}
9418c2ecf20Sopenharmony_ci
9428c2ecf20Sopenharmony_ci
9438c2ecf20Sopenharmony_cisub read_config_file()
9448c2ecf20Sopenharmony_ci{
9458c2ecf20Sopenharmony_ci       if (! -r $config_file) {
9468c2ecf20Sopenharmony_ci               print STDERR "file '$config_file' is not readable or does not exist\n";
9478c2ecf20Sopenharmony_ci               exit 2;
9488c2ecf20Sopenharmony_ci       }
9498c2ecf20Sopenharmony_ci
9508c2ecf20Sopenharmony_ci       if (!open(CONFIG_FILE, "<", "$config_file")) {
9518c2ecf20Sopenharmony_ci               print STDERR "open $config_file failed\n";
9528c2ecf20Sopenharmony_ci               exit 2;
9538c2ecf20Sopenharmony_ci       }
9548c2ecf20Sopenharmony_ci
9558c2ecf20Sopenharmony_ci       my @line;
9568c2ecf20Sopenharmony_ci
9578c2ecf20Sopenharmony_ci       LINE:
9588c2ecf20Sopenharmony_ci       while ($line = <CONFIG_FILE>) {
9598c2ecf20Sopenharmony_ci               chomp($line);
9608c2ecf20Sopenharmony_ci               next LINE if ($line =~ /^\s*#/);
9618c2ecf20Sopenharmony_ci               next LINE if ($line =~ /^\s*$/);
9628c2ecf20Sopenharmony_ci               @line = split /=/, $line;
9638c2ecf20Sopenharmony_ci               $existing_config{@line[0]} = @line[1];
9648c2ecf20Sopenharmony_ci       }
9658c2ecf20Sopenharmony_ci
9668c2ecf20Sopenharmony_ci       close(CONFIG_FILE);
9678c2ecf20Sopenharmony_ci}
9688c2ecf20Sopenharmony_ci
9698c2ecf20Sopenharmony_ci
9708c2ecf20Sopenharmony_cisub cmd_line_err()
9718c2ecf20Sopenharmony_ci{
9728c2ecf20Sopenharmony_ci       my $msg = shift;
9738c2ecf20Sopenharmony_ci
9748c2ecf20Sopenharmony_ci       print STDERR "\n";
9758c2ecf20Sopenharmony_ci       print STDERR "   ERROR processing command line options\n";
9768c2ecf20Sopenharmony_ci       print STDERR "         $msg\n" if ($msg ne "");
9778c2ecf20Sopenharmony_ci       print STDERR "\n";
9788c2ecf20Sopenharmony_ci       print STDERR "   For help, type '$script_name --help'\n";
9798c2ecf20Sopenharmony_ci       print STDERR "\n";
9808c2ecf20Sopenharmony_ci}
9818c2ecf20Sopenharmony_ci
9828c2ecf20Sopenharmony_ci
9838c2ecf20Sopenharmony_ci# -----------------------------------------------------------------------------
9848c2ecf20Sopenharmony_ci# program entry point
9858c2ecf20Sopenharmony_ci
9868c2ecf20Sopenharmony_ciGetopt::Long::Configure("no_ignore_case", "bundling");
9878c2ecf20Sopenharmony_ci
9888c2ecf20Sopenharmony_ciif (!GetOptions(
9898c2ecf20Sopenharmony_ci       "c=s"               => \$config_file,
9908c2ecf20Sopenharmony_ci       "config=s"          => \$config_file,
9918c2ecf20Sopenharmony_ci       "config-format"     => \$config_format,
9928c2ecf20Sopenharmony_ci       "exclude-flag=s"    => \@exclude_flag,
9938c2ecf20Sopenharmony_ci       "h"                 => \$help,
9948c2ecf20Sopenharmony_ci       "help"              => \$help,
9958c2ecf20Sopenharmony_ci       "black-list-driver" => \$black_list_driver,
9968c2ecf20Sopenharmony_ci       "white-list-config" => \$white_list_config,
9978c2ecf20Sopenharmony_ci       "white-list-driver" => \$white_list_driver,
9988c2ecf20Sopenharmony_ci       "include-flag=s"    => \@include_flag,
9998c2ecf20Sopenharmony_ci       "include-suspect"   => \$include_suspect,
10008c2ecf20Sopenharmony_ci       "short-name"        => \$short_name,
10018c2ecf20Sopenharmony_ci       "show-lists"        => \$show_lists,
10028c2ecf20Sopenharmony_ci       "version"           => \$version,
10038c2ecf20Sopenharmony_ci       )) {
10048c2ecf20Sopenharmony_ci
10058c2ecf20Sopenharmony_ci       &cmd_line_err();
10068c2ecf20Sopenharmony_ci
10078c2ecf20Sopenharmony_ci       exit 1;
10088c2ecf20Sopenharmony_ci}
10098c2ecf20Sopenharmony_ci
10108c2ecf20Sopenharmony_ci
10118c2ecf20Sopenharmony_cimy $exit_after_messages = 0;
10128c2ecf20Sopenharmony_ci
10138c2ecf20Sopenharmony_ciif ($version) {
10148c2ecf20Sopenharmony_ci       print STDERR "\n$script_name  $VUFX\n\n";
10158c2ecf20Sopenharmony_ci       $exit_after_messages = 1;
10168c2ecf20Sopenharmony_ci}
10178c2ecf20Sopenharmony_ci
10188c2ecf20Sopenharmony_ci
10198c2ecf20Sopenharmony_ciif ($help) {
10208c2ecf20Sopenharmony_ci       &usage;
10218c2ecf20Sopenharmony_ci       $exit_after_messages = 1;
10228c2ecf20Sopenharmony_ci}
10238c2ecf20Sopenharmony_ci
10248c2ecf20Sopenharmony_ci
10258c2ecf20Sopenharmony_ciif ($show_lists) {
10268c2ecf20Sopenharmony_ci
10278c2ecf20Sopenharmony_ci       print "\n";
10288c2ecf20Sopenharmony_ci       print "These compatibles are hard coded to have no driver.\n";
10298c2ecf20Sopenharmony_ci       print "\n";
10308c2ecf20Sopenharmony_ci       for my $compat (sort keys %compat_white_list) {
10318c2ecf20Sopenharmony_ci               print "   $compat\n";
10328c2ecf20Sopenharmony_ci       }
10338c2ecf20Sopenharmony_ci
10348c2ecf20Sopenharmony_ci
10358c2ecf20Sopenharmony_ci       print "\n\n";
10368c2ecf20Sopenharmony_ci       print "The driver for these compatibles is hard coded (white list).\n";
10378c2ecf20Sopenharmony_ci       print "\n";
10388c2ecf20Sopenharmony_ci       my $max_compat_len = 0;
10398c2ecf20Sopenharmony_ci       for my $compat (sort keys %driver_hard_code_list) {
10408c2ecf20Sopenharmony_ci               if (length $compat > $max_compat_len) {
10418c2ecf20Sopenharmony_ci                       $max_compat_len = length $compat;
10428c2ecf20Sopenharmony_ci               }
10438c2ecf20Sopenharmony_ci       }
10448c2ecf20Sopenharmony_ci       for my $compat (sort keys %driver_hard_code_list) {
10458c2ecf20Sopenharmony_ci               if (($driver ne "hardcoded_no_driver") && ($driver ne "no_driver")) {
10468c2ecf20Sopenharmony_ci                       my $first = 1;
10478c2ecf20Sopenharmony_ci                       for my $driver (@{ $driver_hard_code_list{$compat} }) {
10488c2ecf20Sopenharmony_ci                               if ($first) {
10498c2ecf20Sopenharmony_ci                                       print "   $compat";
10508c2ecf20Sopenharmony_ci                                       print " " x ($max_compat_len - length $compat);
10518c2ecf20Sopenharmony_ci                                       $first = 0;
10528c2ecf20Sopenharmony_ci                               } else {
10538c2ecf20Sopenharmony_ci                                       print "   ", " " x $max_compat_len;
10548c2ecf20Sopenharmony_ci                               }
10558c2ecf20Sopenharmony_ci                               print "  $driver\n";
10568c2ecf20Sopenharmony_ci                       }
10578c2ecf20Sopenharmony_ci               }
10588c2ecf20Sopenharmony_ci       }
10598c2ecf20Sopenharmony_ci
10608c2ecf20Sopenharmony_ci
10618c2ecf20Sopenharmony_ci       print "\n\n";
10628c2ecf20Sopenharmony_ci       print "The configuration option for these drivers is hard coded (white list).\n";
10638c2ecf20Sopenharmony_ci       print "\n";
10648c2ecf20Sopenharmony_ci       my $max_driver_len = 0;
10658c2ecf20Sopenharmony_ci       for my $driver (sort keys %driver_config_hard_code_list) {
10668c2ecf20Sopenharmony_ci               if (length $driver > $max_driver_len) {
10678c2ecf20Sopenharmony_ci                       $max_driver_len = length $driver;
10688c2ecf20Sopenharmony_ci               }
10698c2ecf20Sopenharmony_ci       }
10708c2ecf20Sopenharmony_ci       for my $driver (sort keys %driver_config_hard_code_list) {
10718c2ecf20Sopenharmony_ci               if (($driver ne "hardcoded_no_driver") && ($driver ne "no_driver")) {
10728c2ecf20Sopenharmony_ci                       my $first = 1;
10738c2ecf20Sopenharmony_ci                       for my $config (@{ $driver_config_hard_code_list{$driver} }) {
10748c2ecf20Sopenharmony_ci                               if ($first) {
10758c2ecf20Sopenharmony_ci                                       print "   $driver";
10768c2ecf20Sopenharmony_ci                                       print " " x ($max_driver_len - length $driver);
10778c2ecf20Sopenharmony_ci                                       $first = 0;
10788c2ecf20Sopenharmony_ci                               } else {
10798c2ecf20Sopenharmony_ci                                       print "   ", " " x $max_driver_len;
10808c2ecf20Sopenharmony_ci                               }
10818c2ecf20Sopenharmony_ci                               print "  $config\n";
10828c2ecf20Sopenharmony_ci                       }
10838c2ecf20Sopenharmony_ci               }
10848c2ecf20Sopenharmony_ci       }
10858c2ecf20Sopenharmony_ci
10868c2ecf20Sopenharmony_ci
10878c2ecf20Sopenharmony_ci       print "\n\n";
10888c2ecf20Sopenharmony_ci       print "These drivers are black listed.\n";
10898c2ecf20Sopenharmony_ci       print "\n";
10908c2ecf20Sopenharmony_ci       for my $driver (@black_list_driver) {
10918c2ecf20Sopenharmony_ci               print "   $driver\n";
10928c2ecf20Sopenharmony_ci       }
10938c2ecf20Sopenharmony_ci
10948c2ecf20Sopenharmony_ci       print "\n";
10958c2ecf20Sopenharmony_ci
10968c2ecf20Sopenharmony_ci       $exit_after_messages = 1;
10978c2ecf20Sopenharmony_ci}
10988c2ecf20Sopenharmony_ci
10998c2ecf20Sopenharmony_ci
11008c2ecf20Sopenharmony_ciif ($exit_after_messages) {
11018c2ecf20Sopenharmony_ci       exit 0;
11028c2ecf20Sopenharmony_ci}
11038c2ecf20Sopenharmony_ci
11048c2ecf20Sopenharmony_ci
11058c2ecf20Sopenharmony_ci$exclude_flag_pattern = "[";
11068c2ecf20Sopenharmony_cifor my $exclude_flag (@exclude_flag) {
11078c2ecf20Sopenharmony_ci       $exclude_flag_pattern = $exclude_flag_pattern . $exclude_flag;
11088c2ecf20Sopenharmony_ci}
11098c2ecf20Sopenharmony_ci$exclude_flag_pattern = $exclude_flag_pattern . "]";
11108c2ecf20Sopenharmony_ci# clean up if empty
11118c2ecf20Sopenharmony_ci$exclude_flag_pattern =~ s/^\[\]$//;
11128c2ecf20Sopenharmony_ci
11138c2ecf20Sopenharmony_ci
11148c2ecf20Sopenharmony_ci$include_flag_pattern = "[";
11158c2ecf20Sopenharmony_cifor my $include_flag (@include_flag) {
11168c2ecf20Sopenharmony_ci       $include_flag_pattern = $include_flag_pattern . $include_flag;
11178c2ecf20Sopenharmony_ci}
11188c2ecf20Sopenharmony_ci$include_flag_pattern = $include_flag_pattern . "]";
11198c2ecf20Sopenharmony_ci# clean up if empty
11208c2ecf20Sopenharmony_ci$include_flag_pattern =~ s/^\[\]$//;
11218c2ecf20Sopenharmony_ci
11228c2ecf20Sopenharmony_ci
11238c2ecf20Sopenharmony_ciif ($exclude_flag_pattern) {
11248c2ecf20Sopenharmony_ci       my $found = 0;
11258c2ecf20Sopenharmony_ci       for $pr_flag_value (@pr_flag_value) {
11268c2ecf20Sopenharmony_ci               if ($exclude_flag_pattern =~ m/$pr_flag_value/) {
11278c2ecf20Sopenharmony_ci                       $found = 1;
11288c2ecf20Sopenharmony_ci               }
11298c2ecf20Sopenharmony_ci       }
11308c2ecf20Sopenharmony_ci       if (!$found) {
11318c2ecf20Sopenharmony_ci               &cmd_line_err("invalid value for FLAG in --exclude-flag\n");
11328c2ecf20Sopenharmony_ci               exit 1
11338c2ecf20Sopenharmony_ci       }
11348c2ecf20Sopenharmony_ci}
11358c2ecf20Sopenharmony_ci
11368c2ecf20Sopenharmony_ciif ($include_flag_pattern) {
11378c2ecf20Sopenharmony_ci       my $found = 0;
11388c2ecf20Sopenharmony_ci       for $pr_flag_value (@pr_flag_value) {
11398c2ecf20Sopenharmony_ci               if ($include_flag_pattern =~ m/$pr_flag_value/) {
11408c2ecf20Sopenharmony_ci                       $found = 1;
11418c2ecf20Sopenharmony_ci               }
11428c2ecf20Sopenharmony_ci       }
11438c2ecf20Sopenharmony_ci       if (!$found) {
11448c2ecf20Sopenharmony_ci               &cmd_line_err("invalid value for FLAG in --include-flag\n");
11458c2ecf20Sopenharmony_ci               exit 1
11468c2ecf20Sopenharmony_ci       }
11478c2ecf20Sopenharmony_ci}
11488c2ecf20Sopenharmony_ci
11498c2ecf20Sopenharmony_ciif ($include_suspect) {
11508c2ecf20Sopenharmony_ci       $include_flag_pattern =~ s/\[//;
11518c2ecf20Sopenharmony_ci       $include_flag_pattern =~ s/\]//;
11528c2ecf20Sopenharmony_ci       $include_flag_pattern = "[" . $include_flag_pattern . "A-Z]";
11538c2ecf20Sopenharmony_ci}
11548c2ecf20Sopenharmony_ci
11558c2ecf20Sopenharmony_ciif ($exclude_flag_pattern =~ m/$include_flag_pattern/) {
11568c2ecf20Sopenharmony_ci       &cmd_line_err("the same flag appears in both --exclude-flag and --include-flag or --include-suspect\n");
11578c2ecf20Sopenharmony_ci       exit 1
11588c2ecf20Sopenharmony_ci}
11598c2ecf20Sopenharmony_ci
11608c2ecf20Sopenharmony_ci
11618c2ecf20Sopenharmony_ci# ($#ARGV < 0) is valid for --help, --version
11628c2ecf20Sopenharmony_ciif ($#ARGV < 0) {
11638c2ecf20Sopenharmony_ci       &cmd_line_err("device-tree... is required");
11648c2ecf20Sopenharmony_ci       exit 1
11658c2ecf20Sopenharmony_ci}
11668c2ecf20Sopenharmony_ci
11678c2ecf20Sopenharmony_ci
11688c2ecf20Sopenharmony_ciif ($config_file) {
11698c2ecf20Sopenharmony_ci       &read_config_file();
11708c2ecf20Sopenharmony_ci}
11718c2ecf20Sopenharmony_ci
11728c2ecf20Sopenharmony_ci
11738c2ecf20Sopenharmony_ci# avoid pushing duplicates for this value
11748c2ecf20Sopenharmony_ci$driver = "hardcoded_no_driver";
11758c2ecf20Sopenharmony_cifor $config ( @{ $driver_config_hard_code_list{$driver} } ) {
11768c2ecf20Sopenharmony_ci       push @{ $driver_config{$driver} }, $config;
11778c2ecf20Sopenharmony_ci}
11788c2ecf20Sopenharmony_ci
11798c2ecf20Sopenharmony_ciif ($white_list_driver) {
11808c2ecf20Sopenharmony_ci       for my $compat (keys %driver_hard_code_list) {
11818c2ecf20Sopenharmony_ci               for my $driver (@{ $driver_hard_code_list{$compat} }) {
11828c2ecf20Sopenharmony_ci                       push @{ $compat_driver{$compat} }, $driver;
11838c2ecf20Sopenharmony_ci                       if ($driver ne "hardcoded_no_driver") {
11848c2ecf20Sopenharmony_ci                               $driver_count{$compat} = scalar @{ $compat_driver{$compat} };
11858c2ecf20Sopenharmony_ci                       }
11868c2ecf20Sopenharmony_ci               }
11878c2ecf20Sopenharmony_ci       }
11888c2ecf20Sopenharmony_ci}
11898c2ecf20Sopenharmony_ci
11908c2ecf20Sopenharmony_ciif ($white_list_config) {
11918c2ecf20Sopenharmony_ci       for my $driver (keys %driver_config_hard_code_list) {
11928c2ecf20Sopenharmony_ci               if ($driver ne "hardcoded_no_driver") {
11938c2ecf20Sopenharmony_ci                       for $config ( @{ $driver_config_hard_code_list{$driver} } ) {
11948c2ecf20Sopenharmony_ci                               push @{ $driver_config{$driver} }, $config;
11958c2ecf20Sopenharmony_ci                       }
11968c2ecf20Sopenharmony_ci               }
11978c2ecf20Sopenharmony_ci       }
11988c2ecf20Sopenharmony_ci}
11998c2ecf20Sopenharmony_ci
12008c2ecf20Sopenharmony_ciif (-x "scripts/dtc/dtx_diff") {
12018c2ecf20Sopenharmony_ci       $dtx_diff = "scripts/dtc/dtx_diff";
12028c2ecf20Sopenharmony_ci} else {
12038c2ecf20Sopenharmony_ci
12048c2ecf20Sopenharmony_ci       print STDERR "\n";
12058c2ecf20Sopenharmony_ci       print STDERR "$script_name must be run from the root directory of a Linux kernel tree\n";
12068c2ecf20Sopenharmony_ci       print STDERR "\n";
12078c2ecf20Sopenharmony_ci       exit 3;
12088c2ecf20Sopenharmony_ci}
12098c2ecf20Sopenharmony_ci
12108c2ecf20Sopenharmony_cifor $file (@ARGV) {
12118c2ecf20Sopenharmony_ci       &read_dts($file);
12128c2ecf20Sopenharmony_ci}
1213