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