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