1*4882a593Smuzhiyun#!/usr/bin/env perl 2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only 3*4882a593Smuzhiyun 4*4882a593Smuzhiyun# Copyright 2016 by Frank Rowand 5*4882a593Smuzhiyun# Copyright 2016 by Gaurav Minocha 6*4882a593Smuzhiyun# 7*4882a593Smuzhiyun 8*4882a593Smuzhiyunuse strict 'refs'; 9*4882a593Smuzhiyunuse strict subs; 10*4882a593Smuzhiyun 11*4882a593Smuzhiyunuse Getopt::Long; 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun$VUFX = "160610a"; 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun$script_name = $0; 16*4882a593Smuzhiyun$script_name =~ s|^.*/||; 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun# ----- constants for print_flags() 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun# Position in string $pr_flags. Range of 0..($num_pr_flags - 1). 22*4882a593Smuzhiyun$pr_flag_pos_mcompatible = 0; 23*4882a593Smuzhiyun$pr_flag_pos_driver = 1; 24*4882a593Smuzhiyun$pr_flag_pos_mdriver = 2; 25*4882a593Smuzhiyun$pr_flag_pos_config = 3; 26*4882a593Smuzhiyun$pr_flag_pos_mconfig = 4; 27*4882a593Smuzhiyun$pr_flag_pos_node_not_enabled = 5; 28*4882a593Smuzhiyun$pr_flag_pos_white_list = 6; 29*4882a593Smuzhiyun$pr_flag_pos_hard_coded = 7; 30*4882a593Smuzhiyun$pr_flag_pos_config_hard_coded = 8; 31*4882a593Smuzhiyun$pr_flag_pos_config_none = 9; 32*4882a593Smuzhiyun$pr_flag_pos_config_m = 10; 33*4882a593Smuzhiyun$pr_flag_pos_config_y = 11; 34*4882a593Smuzhiyun$pr_flag_pos_config_test_fail = 12; 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun$num_pr_flags = $pr_flag_pos_config_test_fail + 1; 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun# flags in @pr_flag_value must be unique values to allow simple regular 39*4882a593Smuzhiyun# expessions to work for --include_flags and --exclude_flags. 40*4882a593Smuzhiyun# Convention: use upper case letters for potential issues or problems. 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun@pr_flag_value = ('M', 'd', 'D', 'c', 'C', 'E', 'W', 'H', 'x', 'n', 'm', 'y', 'F'); 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun@pr_flag_help = ( 45*4882a593Smuzhiyun "multiple compatibles found for this node", 46*4882a593Smuzhiyun "driver found for this compatible", 47*4882a593Smuzhiyun "multiple drivers found for this compatible", 48*4882a593Smuzhiyun "kernel config found for this driver", 49*4882a593Smuzhiyun "multiple config options found for this driver", 50*4882a593Smuzhiyun "node is not enabled", 51*4882a593Smuzhiyun "compatible is white listed", 52*4882a593Smuzhiyun "matching driver and/or kernel config is hard coded", 53*4882a593Smuzhiyun "kernel config hard coded in Makefile", 54*4882a593Smuzhiyun "one or more kernel config file options is not set", 55*4882a593Smuzhiyun "one or more kernel config file options is set to 'm'", 56*4882a593Smuzhiyun "one or more kernel config file options is set to 'y'", 57*4882a593Smuzhiyun "one of more kernel config file options fails to have correct value" 58*4882a593Smuzhiyun); 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun# ----- 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun%driver_config = (); # driver config array, indexed by driver source file 64*4882a593Smuzhiyun%driver_count = (); # driver_cnt, indexed by compatible 65*4882a593Smuzhiyun%compat_driver = (); # compatible driver array, indexed by compatible 66*4882a593Smuzhiyun%existing_config = (); # existing config symbols present in given config file 67*4882a593Smuzhiyun # expected values are: "y", "m", a decimal number, a 68*4882a593Smuzhiyun # hex number, or a string 69*4882a593Smuzhiyun 70*4882a593Smuzhiyun# ----- magic compatibles, do not have a driver 71*4882a593Smuzhiyun# 72*4882a593Smuzhiyun# Will not search for drivers for these compatibles. 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun%compat_white_list = ( 75*4882a593Smuzhiyun 'none' => '1', 76*4882a593Smuzhiyun 'pci' => '1', 77*4882a593Smuzhiyun 'simple-bus' => '1', 78*4882a593Smuzhiyun); 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun# Will not search for drivers for these compatibles. 81*4882a593Smuzhiyun# 82*4882a593Smuzhiyun# These compatibles have a very large number of false positives. 83*4882a593Smuzhiyun# 84*4882a593Smuzhiyun# 'hardcoded_no_driver' is a magic value. Other code knows this 85*4882a593Smuzhiyun# magic value. Do not use 'no_driver' here! 86*4882a593Smuzhiyun# 87*4882a593Smuzhiyun# Revisit each 'hardcoded_no_driver' to see how the compatible 88*4882a593Smuzhiyun# is used. Are there drivers that can be provided? 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun%driver_hard_code_list = ( 91*4882a593Smuzhiyun 'cache' => ['hardcoded_no_driver'], 92*4882a593Smuzhiyun 'eeprom' => ['hardcoded_no_driver'], 93*4882a593Smuzhiyun 'gpio' => ['hardcoded_no_driver'], 94*4882a593Smuzhiyun 'gpio-keys' => ['drivers/input/keyboard/gpio_keys.c'], 95*4882a593Smuzhiyun 'i2c-gpio' => ['drivers/i2c/busses/i2c-gpio.c'], 96*4882a593Smuzhiyun 'isa' => ['arch/mips/mti-malta/malta-dt.c', 97*4882a593Smuzhiyun 'arch/x86/kernel/devicetree.c'], 98*4882a593Smuzhiyun 'led' => ['hardcoded_no_driver'], 99*4882a593Smuzhiyun 'm25p32' => ['hardcoded_no_driver'], 100*4882a593Smuzhiyun 'm25p64' => ['hardcoded_no_driver'], 101*4882a593Smuzhiyun 'm25p80' => ['hardcoded_no_driver'], 102*4882a593Smuzhiyun 'mtd-ram' => ['drivers/mtd/maps/physmap_of.c'], 103*4882a593Smuzhiyun 'pwm-backlight' => ['drivers/video/backlight/pwm_bl.c'], 104*4882a593Smuzhiyun 'spidev' => ['hardcoded_no_driver'], 105*4882a593Smuzhiyun 'syscon' => ['drivers/mfd/syscon.c'], 106*4882a593Smuzhiyun 'tlv320aic23' => ['hardcoded_no_driver'], 107*4882a593Smuzhiyun 'wm8731' => ['hardcoded_no_driver'], 108*4882a593Smuzhiyun); 109*4882a593Smuzhiyun 110*4882a593Smuzhiyun# Use these config options instead of searching makefiles 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun%driver_config_hard_code_list = ( 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun # this one needed even if %driver_hard_code_list is empty 115*4882a593Smuzhiyun 'no_driver' => ['no_config'], 116*4882a593Smuzhiyun 'hardcoded_no_driver' => ['no_config'], 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun # drivers/usb/host/ehci-ppc-of.c 119*4882a593Smuzhiyun # drivers/usb/host/ehci-xilinx-of.c 120*4882a593Smuzhiyun # are included from: 121*4882a593Smuzhiyun # drivers/usb/host/ehci-hcd.c 122*4882a593Smuzhiyun # thus the search of Makefile for the included .c files is incorrect 123*4882a593Smuzhiyun # ehci-hcd.c wraps the includes with ifdef CONFIG_USB_EHCI_HCD_..._OF 124*4882a593Smuzhiyun # 125*4882a593Smuzhiyun # similar model for ohci-hcd.c (but no ohci-xilinx-of.c) 126*4882a593Smuzhiyun # 127*4882a593Smuzhiyun # similarly, uhci-hcd.c includes uhci-platform.c 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun 'drivers/usb/host/ehci-ppc-of.c' => ['CONFIG_USB_EHCI_HCD', 130*4882a593Smuzhiyun 'CONFIG_USB_EHCI_HCD_PPC_OF'], 131*4882a593Smuzhiyun 'drivers/usb/host/ohci-ppc-of.c' => ['CONFIG_USB_OHCI_HCD', 132*4882a593Smuzhiyun 'CONFIG_USB_OHCI_HCD_PPC_OF'], 133*4882a593Smuzhiyun 134*4882a593Smuzhiyun 'drivers/usb/host/ehci-xilinx-of.c' => ['CONFIG_USB_EHCI_HCD', 135*4882a593Smuzhiyun 'CONFIG_USB_EHCI_HCD_XILINX'], 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun 'drivers/usb/host/uhci-platform.c' => ['CONFIG_USB_UHCI_HCD', 138*4882a593Smuzhiyun 'CONFIG_USB_UHCI_PLATFORM'], 139*4882a593Smuzhiyun 140*4882a593Smuzhiyun # scan_makefile will find only one of these config options: 141*4882a593Smuzhiyun # ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_LS1021A),) 142*4882a593Smuzhiyun 'arch/arm/mach-imx/platsmp.c' => ['CONFIG_SOC_IMX6 && CONFIG_SMP', 143*4882a593Smuzhiyun 'CONFIG_SOC_LS1021A && CONFIG_SMP'], 144*4882a593Smuzhiyun); 145*4882a593Smuzhiyun 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun# 'virt/kvm/arm/.*' are controlled by makefiles in other directories, 148*4882a593Smuzhiyun# using relative paths, such as 'KVM := ../../../virt/kvm'. Do not 149*4882a593Smuzhiyun# add complexity to find_kconfig() to deal with this. There is a long 150*4882a593Smuzhiyun# term intent to change the kvm related makefiles to the normal kernel 151*4882a593Smuzhiyun# style. After that is done, this entry can be removed from the 152*4882a593Smuzhiyun# black_list_driver. 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun@black_list_driver = ( 155*4882a593Smuzhiyun # kvm no longer a problem after commit 503a62862e8f in 4.7-rc1 156*4882a593Smuzhiyun # 'virt/kvm/arm/.*', 157*4882a593Smuzhiyun); 158*4882a593Smuzhiyun 159*4882a593Smuzhiyun 160*4882a593Smuzhiyunsub usage() 161*4882a593Smuzhiyun{ 162*4882a593Smuzhiyun print 163*4882a593Smuzhiyun" 164*4882a593SmuzhiyunUsage: $script_name [options] device-tree... 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun device_tree is: dts_file | dtb_file | proc_device-tree 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun 169*4882a593SmuzhiyunValid options: 170*4882a593Smuzhiyun -c FILE Read kernel config options from FILE 171*4882a593Smuzhiyun --config FILE synonym for 'c' 172*4882a593Smuzhiyun --config-format config file friendly output format 173*4882a593Smuzhiyun --exclude-flag FLAG exclude entries with a matching flag 174*4882a593Smuzhiyun -h Display this message and exit 175*4882a593Smuzhiyun --help synonym for 'h' 176*4882a593Smuzhiyun --black-list-driver use driver black list 177*4882a593Smuzhiyun --white-list-config use config white list 178*4882a593Smuzhiyun --white-list-driver use driver white list 179*4882a593Smuzhiyun --include-flag FLAG include only entries with a matching flag 180*4882a593Smuzhiyun --include-suspect include only entries with an uppercase flag 181*4882a593Smuzhiyun --short-name do not show the path portion of the node name 182*4882a593Smuzhiyun --show-lists report of white and black lists 183*4882a593Smuzhiyun --version Display program version and exit 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun 186*4882a593Smuzhiyun Report driver source files that match the compatibles in the device 187*4882a593Smuzhiyun tree file and the kernel config options that enable the driver source 188*4882a593Smuzhiyun files. 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun This program must be run in the root directory of a Linux kernel 191*4882a593Smuzhiyun source tree. 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun The default format is a report that is intended to be easily human 194*4882a593Smuzhiyun scannable. 195*4882a593Smuzhiyun 196*4882a593Smuzhiyun An alternate format can be selected by --config-format. This will 197*4882a593Smuzhiyun create output that can easily be edited to create a fragment that can 198*4882a593Smuzhiyun be appended to the existing kernel config file. Each entry consists of 199*4882a593Smuzhiyun multiple lines. The first line reports flags, the node path, compatible 200*4882a593Smuzhiyun value, driver file matching the compatible, configuration options, and 201*4882a593Smuzhiyun current values of the configuration options. For each configuration 202*4882a593Smuzhiyun option, the following lines report the current value and the value that 203*4882a593Smuzhiyun is required for the driver file to be included in the kernel. 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun If a large number of drivers or config options is listed for a node, 206*4882a593Smuzhiyun and the '$pr_flag_value[$pr_flag_pos_hard_coded]' flag is set consider using --white-list-config and/or 207*4882a593Smuzhiyun --white-list-driver. If the white list option suppresses the correct 208*4882a593Smuzhiyun entry please report that as a bug. 209*4882a593Smuzhiyun 210*4882a593Smuzhiyun CAUTION: 211*4882a593Smuzhiyun This program uses heuristics to guess which driver(s) support each 212*4882a593Smuzhiyun compatible string and which config option(s) enables the driver(s). 213*4882a593Smuzhiyun Do not believe that the reported information is fully correct. 214*4882a593Smuzhiyun This program is intended to aid the process of determining the 215*4882a593Smuzhiyun proper kernel configuration for a device tree, but this is not 216*4882a593Smuzhiyun a fully automated process -- human involvement may still be 217*4882a593Smuzhiyun required! 218*4882a593Smuzhiyun 219*4882a593Smuzhiyun The driver match heuristic used is to search for source files 220*4882a593Smuzhiyun containing the compatible string enclosed in quotes. 221*4882a593Smuzhiyun 222*4882a593Smuzhiyun This program might not be able to find all drivers matching a 223*4882a593Smuzhiyun compatible string. 224*4882a593Smuzhiyun 225*4882a593Smuzhiyun Some makefiles are overly clever. This program was not made 226*4882a593Smuzhiyun complex enough to handle them. If no config option is listed 227*4882a593Smuzhiyun for a driver, look at the makefile for the driver source file. 228*4882a593Smuzhiyun Even if a config option is listed for a driver, some other 229*4882a593Smuzhiyun available config options may not be listed. 230*4882a593Smuzhiyun 231*4882a593Smuzhiyun FLAG values: 232*4882a593Smuzhiyun"; 233*4882a593Smuzhiyun 234*4882a593Smuzhiyun for ($k = 0; $k < $num_pr_flags; $k++) { 235*4882a593Smuzhiyun printf " %s %s\n", $pr_flag_value[$k], $pr_flag_help[$k]; 236*4882a593Smuzhiyun } 237*4882a593Smuzhiyun 238*4882a593Smuzhiyun print 239*4882a593Smuzhiyun" 240*4882a593Smuzhiyun Upper case letters indicate potential issues or problems. 241*4882a593Smuzhiyun 242*4882a593Smuzhiyun The flag: 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun"; 245*4882a593Smuzhiyun 246*4882a593Smuzhiyun $k = $pr_flag_pos_hard_coded; 247*4882a593Smuzhiyun printf " %s %s\n", $pr_flag_value[$k], $pr_flag_help[$k]; 248*4882a593Smuzhiyun 249*4882a593Smuzhiyun print 250*4882a593Smuzhiyun" 251*4882a593Smuzhiyun will be set if the config or driver is in the white lists, even if 252*4882a593Smuzhiyun --white-list-config and --white-list-driver are not specified. 253*4882a593Smuzhiyun This is a hint that 1) many of these reported lines are likely to 254*4882a593Smuzhiyun be incorrect, and 2) using those options will reduce the number of 255*4882a593Smuzhiyun drivers and/or config options reported. 256*4882a593Smuzhiyun 257*4882a593Smuzhiyun --white-list-config and --white-list-driver may not be accurate if this 258*4882a593Smuzhiyun program is not well maintained. Use them with appropriate skepticism. 259*4882a593Smuzhiyun Use the --show-lists option to report the values in the list. 260*4882a593Smuzhiyun 261*4882a593Smuzhiyun Return value: 262*4882a593Smuzhiyun 0 if no error 263*4882a593Smuzhiyun 1 error processing command line 264*4882a593Smuzhiyun 2 unable to open or read kernel config file 265*4882a593Smuzhiyun 3 unable to open or process input device tree file(s) 266*4882a593Smuzhiyun 267*4882a593Smuzhiyun EXAMPLES: 268*4882a593Smuzhiyun 269*4882a593Smuzhiyun dt_to_config arch/arm/boot/dts/my_dts_file.dts 270*4882a593Smuzhiyun 271*4882a593Smuzhiyun Basic report. 272*4882a593Smuzhiyun 273*4882a593Smuzhiyun dt_to_config \\ 274*4882a593Smuzhiyun --config \${KBUILD_OUTPUT}/.config \\ 275*4882a593Smuzhiyun arch/\${ARCH}/boot/dts/my_dts_file.dts 276*4882a593Smuzhiyun 277*4882a593Smuzhiyun Full report, with config file issues noted. 278*4882a593Smuzhiyun 279*4882a593Smuzhiyun dt_to_config --include-suspect \\ 280*4882a593Smuzhiyun --config \${KBUILD_OUTPUT}/.config \\ 281*4882a593Smuzhiyun arch/\${ARCH}/boot/dts/my_dts_file.dts 282*4882a593Smuzhiyun 283*4882a593Smuzhiyun Report of node / compatible string / driver tuples that should 284*4882a593Smuzhiyun be further investigated. A node may have multiple compatible 285*4882a593Smuzhiyun strings. A compatible string may be matched by multiple drivers. 286*4882a593Smuzhiyun A driver may have config file issues noted. The compatible string 287*4882a593Smuzhiyun and/or driver may be in the white lists. 288*4882a593Smuzhiyun 289*4882a593Smuzhiyun dt_to_config --include-suspect --config-format \\ 290*4882a593Smuzhiyun --config ${KBUILD_OUTPUT}/.config \\ 291*4882a593Smuzhiyun arch/\${ARCH}/boot/dts/my_dts_file.dts 292*4882a593Smuzhiyun 293*4882a593Smuzhiyun Report of node / compatible string / driver tuples that should 294*4882a593Smuzhiyun be further investigated. The report can be edited to uncomment 295*4882a593Smuzhiyun the config options to select the desired tuple for a given node. 296*4882a593Smuzhiyun A node may have multiple compatible strings. A compatible string 297*4882a593Smuzhiyun may be matched by multiple drivers. A driver may have config file 298*4882a593Smuzhiyun issues noted. The compatible string and/or driver may be in the 299*4882a593Smuzhiyun white lists. 300*4882a593Smuzhiyun 301*4882a593Smuzhiyun"; 302*4882a593Smuzhiyun} 303*4882a593Smuzhiyun 304*4882a593Smuzhiyunsub set_flag() 305*4882a593Smuzhiyun{ 306*4882a593Smuzhiyun # pr_flags_ref is a reference to $pr_flags 307*4882a593Smuzhiyun 308*4882a593Smuzhiyun my $pr_flags_ref = shift; 309*4882a593Smuzhiyun my $pos = shift; 310*4882a593Smuzhiyun 311*4882a593Smuzhiyun substr $$pr_flags_ref, $pos, 1, $pr_flag_value[$pos]; 312*4882a593Smuzhiyun 313*4882a593Smuzhiyun return $pr_flags; 314*4882a593Smuzhiyun} 315*4882a593Smuzhiyun 316*4882a593Smuzhiyunsub print_flags() 317*4882a593Smuzhiyun{ 318*4882a593Smuzhiyun # return 1 if anything printed, else 0 319*4882a593Smuzhiyun 320*4882a593Smuzhiyun # some fields of pn_arg_ref might not be used in this function, but 321*4882a593Smuzhiyun # extract all of them anyway. 322*4882a593Smuzhiyun my $pn_arg_ref = shift; 323*4882a593Smuzhiyun 324*4882a593Smuzhiyun my $compat = $pn_arg_ref->{compat}; 325*4882a593Smuzhiyun my $compatible_cnt = $pn_arg_ref->{compatible_cnt}; 326*4882a593Smuzhiyun my $config = $pn_arg_ref->{config}; 327*4882a593Smuzhiyun my $config_cnt = $pn_arg_ref->{config_cnt}; 328*4882a593Smuzhiyun my $driver = $pn_arg_ref->{driver}; 329*4882a593Smuzhiyun my $driver_cnt = $pn_arg_ref->{driver_cnt}; 330*4882a593Smuzhiyun my $full_node = $pn_arg_ref->{full_node}; 331*4882a593Smuzhiyun my $node = $pn_arg_ref->{node}; 332*4882a593Smuzhiyun my $node_enabled = $pn_arg_ref->{node_enabled}; 333*4882a593Smuzhiyun my $white_list = $pn_arg_ref->{white_list}; 334*4882a593Smuzhiyun 335*4882a593Smuzhiyun my $pr_flags = '-' x $num_pr_flags; 336*4882a593Smuzhiyun 337*4882a593Smuzhiyun 338*4882a593Smuzhiyun # ----- set flags in $pr_flags 339*4882a593Smuzhiyun 340*4882a593Smuzhiyun if ($compatible_cnt > 1) { 341*4882a593Smuzhiyun &set_flag(\$pr_flags, $pr_flag_pos_mcompatible); 342*4882a593Smuzhiyun } 343*4882a593Smuzhiyun 344*4882a593Smuzhiyun if ($config_cnt > 1) { 345*4882a593Smuzhiyun &set_flag(\$pr_flags, $pr_flag_pos_mconfig); 346*4882a593Smuzhiyun } 347*4882a593Smuzhiyun 348*4882a593Smuzhiyun if ($driver_cnt >= 1) { 349*4882a593Smuzhiyun &set_flag(\$pr_flags, $pr_flag_pos_driver); 350*4882a593Smuzhiyun } 351*4882a593Smuzhiyun 352*4882a593Smuzhiyun if ($driver_cnt > 1) { 353*4882a593Smuzhiyun &set_flag(\$pr_flags, $pr_flag_pos_mdriver); 354*4882a593Smuzhiyun } 355*4882a593Smuzhiyun 356*4882a593Smuzhiyun # These strings are the same way the linux kernel tests. 357*4882a593Smuzhiyun # The ePapr lists of values is slightly different. 358*4882a593Smuzhiyun if (!( 359*4882a593Smuzhiyun ($node_enabled eq "") || 360*4882a593Smuzhiyun ($node_enabled eq "ok") || 361*4882a593Smuzhiyun ($node_enabled eq "okay") 362*4882a593Smuzhiyun )) { 363*4882a593Smuzhiyun &set_flag(\$pr_flags, $pr_flag_pos_node_not_enabled); 364*4882a593Smuzhiyun } 365*4882a593Smuzhiyun 366*4882a593Smuzhiyun if ($white_list) { 367*4882a593Smuzhiyun &set_flag(\$pr_flags, $pr_flag_pos_white_list); 368*4882a593Smuzhiyun } 369*4882a593Smuzhiyun 370*4882a593Smuzhiyun if (exists($driver_hard_code_list{$compat}) || 371*4882a593Smuzhiyun (exists($driver_config_hard_code_list{$driver}) && 372*4882a593Smuzhiyun ($driver ne "no_driver"))) { 373*4882a593Smuzhiyun &set_flag(\$pr_flags, $pr_flag_pos_hard_coded); 374*4882a593Smuzhiyun } 375*4882a593Smuzhiyun 376*4882a593Smuzhiyun my @configs = split(' && ', $config); 377*4882a593Smuzhiyun for $configs (@configs) { 378*4882a593Smuzhiyun $not = $configs =~ /^!/; 379*4882a593Smuzhiyun $configs =~ s/^!//; 380*4882a593Smuzhiyun 381*4882a593Smuzhiyun if (($configs ne "no_config") && ($configs ne "no_makefile")) { 382*4882a593Smuzhiyun &set_flag(\$pr_flags, $pr_flag_pos_config); 383*4882a593Smuzhiyun } 384*4882a593Smuzhiyun 385*4882a593Smuzhiyun if (($config_cnt >= 1) && 386*4882a593Smuzhiyun ($configs !~ /CONFIG_/) && 387*4882a593Smuzhiyun (($configs ne "no_config") && ($configs ne "no_makefile"))) { 388*4882a593Smuzhiyun &set_flag(\$pr_flags, $pr_flag_pos_config_hard_coded); 389*4882a593Smuzhiyun } 390*4882a593Smuzhiyun 391*4882a593Smuzhiyun my $existing_config = $existing_config{$configs}; 392*4882a593Smuzhiyun if ($existing_config eq "m") { 393*4882a593Smuzhiyun &set_flag(\$pr_flags, $pr_flag_pos_config_m); 394*4882a593Smuzhiyun # Possible fail, depends on whether built in or 395*4882a593Smuzhiyun # module is desired. 396*4882a593Smuzhiyun &set_flag(\$pr_flags, $pr_flag_pos_config_test_fail); 397*4882a593Smuzhiyun } elsif ($existing_config eq "y") { 398*4882a593Smuzhiyun &set_flag(\$pr_flags, $pr_flag_pos_config_y); 399*4882a593Smuzhiyun if ($not) { 400*4882a593Smuzhiyun &set_flag(\$pr_flags, $pr_flag_pos_config_test_fail); 401*4882a593Smuzhiyun } 402*4882a593Smuzhiyun } elsif (($config_file) && ($configs =~ /CONFIG_/)) { 403*4882a593Smuzhiyun &set_flag(\$pr_flags, $pr_flag_pos_config_none); 404*4882a593Smuzhiyun if (!$not) { 405*4882a593Smuzhiyun &set_flag(\$pr_flags, $pr_flag_pos_config_test_fail); 406*4882a593Smuzhiyun } 407*4882a593Smuzhiyun } 408*4882a593Smuzhiyun } 409*4882a593Smuzhiyun 410*4882a593Smuzhiyun # ----- include / exclude filters 411*4882a593Smuzhiyun 412*4882a593Smuzhiyun if ($include_flag_pattern && ($pr_flags !~ m/$include_flag_pattern/)) { 413*4882a593Smuzhiyun return 0; 414*4882a593Smuzhiyun } 415*4882a593Smuzhiyun 416*4882a593Smuzhiyun if ($exclude_flag_pattern && ($pr_flags =~ m/$exclude_flag_pattern/)) { 417*4882a593Smuzhiyun return 0; 418*4882a593Smuzhiyun } 419*4882a593Smuzhiyun 420*4882a593Smuzhiyun if ($config_format) { 421*4882a593Smuzhiyun print "# "; 422*4882a593Smuzhiyun } 423*4882a593Smuzhiyun print "$pr_flags : "; 424*4882a593Smuzhiyun 425*4882a593Smuzhiyun return 1; 426*4882a593Smuzhiyun} 427*4882a593Smuzhiyun 428*4882a593Smuzhiyun 429*4882a593Smuzhiyunsub print_node() 430*4882a593Smuzhiyun{ 431*4882a593Smuzhiyun # return number of lines printed 432*4882a593Smuzhiyun 433*4882a593Smuzhiyun # some fields of pn_arg_ref might not be used in this function, but 434*4882a593Smuzhiyun # extract all of them anyway. 435*4882a593Smuzhiyun my $pn_arg_ref = shift; 436*4882a593Smuzhiyun 437*4882a593Smuzhiyun my $compat = $pn_arg_ref->{compat}; 438*4882a593Smuzhiyun my $compatible_cnt = $pn_arg_ref->{compatible_cnt}; 439*4882a593Smuzhiyun my $config = $pn_arg_ref->{config}; 440*4882a593Smuzhiyun my $config_cnt = $pn_arg_ref->{config_cnt}; 441*4882a593Smuzhiyun my $driver = $pn_arg_ref->{driver}; 442*4882a593Smuzhiyun my $driver_cnt = $pn_arg_ref->{driver_cnt}; 443*4882a593Smuzhiyun my $full_node = $pn_arg_ref->{full_node}; 444*4882a593Smuzhiyun my $node = $pn_arg_ref->{node}; 445*4882a593Smuzhiyun my $node_enabled = $pn_arg_ref->{node_enabled}; 446*4882a593Smuzhiyun my $white_list = $pn_arg_ref->{white_list}; 447*4882a593Smuzhiyun 448*4882a593Smuzhiyun my $separator; 449*4882a593Smuzhiyun 450*4882a593Smuzhiyun if (! &print_flags($pn_arg_ref)) { 451*4882a593Smuzhiyun return 0; 452*4882a593Smuzhiyun } 453*4882a593Smuzhiyun 454*4882a593Smuzhiyun 455*4882a593Smuzhiyun if ($short_name) { 456*4882a593Smuzhiyun print "$node"; 457*4882a593Smuzhiyun } else { 458*4882a593Smuzhiyun print "$full_node"; 459*4882a593Smuzhiyun } 460*4882a593Smuzhiyun print " : $compat : $driver : $config : "; 461*4882a593Smuzhiyun 462*4882a593Smuzhiyun my @configs = split(' && ', $config); 463*4882a593Smuzhiyun 464*4882a593Smuzhiyun if ($config_file) { 465*4882a593Smuzhiyun for $configs (@configs) { 466*4882a593Smuzhiyun $configs =~ s/^!//; 467*4882a593Smuzhiyun my $existing_config = $existing_config{$configs}; 468*4882a593Smuzhiyun if (!$existing_config) { 469*4882a593Smuzhiyun # check for /-m/, /-y/, or /-objs/ 470*4882a593Smuzhiyun if ($configs !~ /CONFIG_/) { 471*4882a593Smuzhiyun $existing_config = "x"; 472*4882a593Smuzhiyun }; 473*4882a593Smuzhiyun }; 474*4882a593Smuzhiyun if ($existing_config) { 475*4882a593Smuzhiyun print "$separator", "$existing_config"; 476*4882a593Smuzhiyun $separator = ", "; 477*4882a593Smuzhiyun } else { 478*4882a593Smuzhiyun print "$separator", "n"; 479*4882a593Smuzhiyun $separator = ", "; 480*4882a593Smuzhiyun } 481*4882a593Smuzhiyun } 482*4882a593Smuzhiyun } else { 483*4882a593Smuzhiyun print "none"; 484*4882a593Smuzhiyun } 485*4882a593Smuzhiyun 486*4882a593Smuzhiyun print "\n"; 487*4882a593Smuzhiyun 488*4882a593Smuzhiyun if ($config_format) { 489*4882a593Smuzhiyun for $configs (@configs) { 490*4882a593Smuzhiyun $not = $configs =~ /^!/; 491*4882a593Smuzhiyun $configs =~ s/^!//; 492*4882a593Smuzhiyun my $existing_config = $existing_config{$configs}; 493*4882a593Smuzhiyun 494*4882a593Smuzhiyun if ($not) { 495*4882a593Smuzhiyun if ($configs !~ /CONFIG_/) { 496*4882a593Smuzhiyun print "# $configs\n"; 497*4882a593Smuzhiyun } elsif ($existing_config eq "m") { 498*4882a593Smuzhiyun print "# $configs is m\n"; 499*4882a593Smuzhiyun print "# $configs=n\n"; 500*4882a593Smuzhiyun } elsif ($existing_config eq "y") { 501*4882a593Smuzhiyun print "# $configs is set\n"; 502*4882a593Smuzhiyun print "# $configs=n\n"; 503*4882a593Smuzhiyun } else { 504*4882a593Smuzhiyun print "# $configs is not set\n"; 505*4882a593Smuzhiyun print "# $configs=n\n"; 506*4882a593Smuzhiyun } 507*4882a593Smuzhiyun 508*4882a593Smuzhiyun } else { 509*4882a593Smuzhiyun if ($configs !~ /CONFIG_/) { 510*4882a593Smuzhiyun print "# $configs\n"; 511*4882a593Smuzhiyun } elsif ($existing_config eq "m") { 512*4882a593Smuzhiyun print "# $configs is m\n"; 513*4882a593Smuzhiyun print "# $configs=y\n"; 514*4882a593Smuzhiyun } elsif ($existing_config eq "y") { 515*4882a593Smuzhiyun print "# $configs is set\n"; 516*4882a593Smuzhiyun print "# $configs=y\n"; 517*4882a593Smuzhiyun } else { 518*4882a593Smuzhiyun print "# $configs is not set\n"; 519*4882a593Smuzhiyun print "# $configs=y\n"; 520*4882a593Smuzhiyun } 521*4882a593Smuzhiyun } 522*4882a593Smuzhiyun } 523*4882a593Smuzhiyun } 524*4882a593Smuzhiyun 525*4882a593Smuzhiyun return 1; 526*4882a593Smuzhiyun} 527*4882a593Smuzhiyun 528*4882a593Smuzhiyun 529*4882a593Smuzhiyunsub scan_makefile 530*4882a593Smuzhiyun{ 531*4882a593Smuzhiyun my $pn_arg_ref = shift; 532*4882a593Smuzhiyun my $driver = shift; 533*4882a593Smuzhiyun 534*4882a593Smuzhiyun # ----- Find Kconfig symbols that enable driver 535*4882a593Smuzhiyun 536*4882a593Smuzhiyun my ($dir, $base) = $driver =~ m{(.*)/(.*).c}; 537*4882a593Smuzhiyun 538*4882a593Smuzhiyun my $makefile = $dir . "/Makefile"; 539*4882a593Smuzhiyun if (! -r $makefile) { 540*4882a593Smuzhiyun $makefile = $dir . "/Kbuild"; 541*4882a593Smuzhiyun } 542*4882a593Smuzhiyun if (! -r $makefile) { 543*4882a593Smuzhiyun my $config; 544*4882a593Smuzhiyun 545*4882a593Smuzhiyun $config = 'no_makefile'; 546*4882a593Smuzhiyun push @{ $driver_config{$driver} }, $config; 547*4882a593Smuzhiyun return; 548*4882a593Smuzhiyun } 549*4882a593Smuzhiyun 550*4882a593Smuzhiyun if (!open(MAKEFILE_FILE, "<", "$makefile")) { 551*4882a593Smuzhiyun return; 552*4882a593Smuzhiyun } 553*4882a593Smuzhiyun 554*4882a593Smuzhiyun my $line; 555*4882a593Smuzhiyun my @config; 556*4882a593Smuzhiyun my @if_config; 557*4882a593Smuzhiyun my @make_var; 558*4882a593Smuzhiyun 559*4882a593Smuzhiyun NEXT_LINE: 560*4882a593Smuzhiyun while ($next_line = <MAKEFILE_FILE>) { 561*4882a593Smuzhiyun my $config; 562*4882a593Smuzhiyun my $if_config; 563*4882a593Smuzhiyun my $ifdef; 564*4882a593Smuzhiyun my $ifeq; 565*4882a593Smuzhiyun my $ifndef; 566*4882a593Smuzhiyun my $ifneq; 567*4882a593Smuzhiyun my $ifdef_config; 568*4882a593Smuzhiyun my $ifeq_config; 569*4882a593Smuzhiyun my $ifndef_config; 570*4882a593Smuzhiyun my $ifneq_config; 571*4882a593Smuzhiyun 572*4882a593Smuzhiyun chomp($next_line); 573*4882a593Smuzhiyun $line = $line . $next_line; 574*4882a593Smuzhiyun if ($next_line =~ /\\$/) { 575*4882a593Smuzhiyun $line =~ s/\\$/ /; 576*4882a593Smuzhiyun next NEXT_LINE; 577*4882a593Smuzhiyun } 578*4882a593Smuzhiyun if ($line =~ /^\s*#/) { 579*4882a593Smuzhiyun $line = ""; 580*4882a593Smuzhiyun next NEXT_LINE; 581*4882a593Smuzhiyun } 582*4882a593Smuzhiyun 583*4882a593Smuzhiyun # ----- condition ... else ... endif 584*4882a593Smuzhiyun 585*4882a593Smuzhiyun if ($line =~ /^([ ]\s*|)else\b/) { 586*4882a593Smuzhiyun $if_config = "!" . pop @if_config; 587*4882a593Smuzhiyun $if_config =~ s/^!!//; 588*4882a593Smuzhiyun push @if_config, $if_config; 589*4882a593Smuzhiyun $line =~ s/^([ ]\s*|)else\b//; 590*4882a593Smuzhiyun } 591*4882a593Smuzhiyun 592*4882a593Smuzhiyun ($null, $ifeq_config, $ifeq_config_val ) = $line =~ /^([ ]\s*|)ifeq\b.*\b(CONFIG_[A-Za-z0-9_]*)(.*)/; 593*4882a593Smuzhiyun ($null, $ifneq_config, $ifneq_config_val) = $line =~ /^([ ]\s*|)ifneq\b.*\b(CONFIG_[A-Za-z0-9_]*)(.*)/; 594*4882a593Smuzhiyun ($null, $ifdef_config) = $line =~ /^([ ]\s*|)ifdef\b.*\b(CONFIG_[A-Za-z0-9_]*)/; 595*4882a593Smuzhiyun ($null, $ifndef_config) = $line =~ /^([ ]\s*|)ifndef\b.*\b(CONFIG_[A-Za-z0-9_]*)/; 596*4882a593Smuzhiyun 597*4882a593Smuzhiyun ($null, $ifeq) = $line =~ /^([ ]\s*|)ifeq\b\s*(.*)/; 598*4882a593Smuzhiyun ($null, $ifneq) = $line =~ /^([ ]\s*|)ifneq\b\s*(.*)/; 599*4882a593Smuzhiyun ($null, $ifdef) = $line =~ /^([ ]\s*|)ifdef\b\s*(.*)/; 600*4882a593Smuzhiyun ($null, $ifndef) = $line =~ /^([ ]\s*|)ifndef\b\s*(.*)/; 601*4882a593Smuzhiyun 602*4882a593Smuzhiyun # Order of tests is important. Prefer "CONFIG_*" regex match over 603*4882a593Smuzhiyun # less specific regex match. 604*4882a593Smuzhiyun if ($ifdef_config) { 605*4882a593Smuzhiyun $if_config = $ifdef_config; 606*4882a593Smuzhiyun } elsif ($ifeq_config) { 607*4882a593Smuzhiyun if ($ifeq_config_val =~ /y/) { 608*4882a593Smuzhiyun $if_config = $ifeq_config; 609*4882a593Smuzhiyun } else { 610*4882a593Smuzhiyun $if_config = "!" . $ifeq_config; 611*4882a593Smuzhiyun } 612*4882a593Smuzhiyun } elsif ($ifndef_config) { 613*4882a593Smuzhiyun $if_config = "!" . $ifndef_config; 614*4882a593Smuzhiyun } elsif ($ifneq_config) { 615*4882a593Smuzhiyun if ($ifneq_config_val =~ /y/) { 616*4882a593Smuzhiyun $if_config = "!" . $ifneq_config; 617*4882a593Smuzhiyun } else { 618*4882a593Smuzhiyun $if_config = $ifneq_config; 619*4882a593Smuzhiyun } 620*4882a593Smuzhiyun } elsif ($ifdef) { 621*4882a593Smuzhiyun $if_config = $ifdef; 622*4882a593Smuzhiyun } elsif ($ifeq) { 623*4882a593Smuzhiyun $if_config = $ifeq; 624*4882a593Smuzhiyun } elsif ($ifndef) { 625*4882a593Smuzhiyun $if_config = "!" . $ifndef; 626*4882a593Smuzhiyun } elsif ($ifneq) { 627*4882a593Smuzhiyun $if_config = "!" . $ifneq; 628*4882a593Smuzhiyun } else { 629*4882a593Smuzhiyun $if_config = ""; 630*4882a593Smuzhiyun } 631*4882a593Smuzhiyun $if_config =~ s/^!!//; 632*4882a593Smuzhiyun 633*4882a593Smuzhiyun if ($if_config) { 634*4882a593Smuzhiyun push @if_config, $if_config; 635*4882a593Smuzhiyun $line = ""; 636*4882a593Smuzhiyun next NEXT_LINE; 637*4882a593Smuzhiyun } 638*4882a593Smuzhiyun 639*4882a593Smuzhiyun if ($line =~ /^([ ]\s*|)endif\b/) { 640*4882a593Smuzhiyun pop @if_config; 641*4882a593Smuzhiyun $line = ""; 642*4882a593Smuzhiyun next NEXT_LINE; 643*4882a593Smuzhiyun } 644*4882a593Smuzhiyun 645*4882a593Smuzhiyun # ----- simple CONFIG_* = *.[co] or xxx [+:?]*= *.[co] 646*4882a593Smuzhiyun # Most makefiles select on *.o, but 647*4882a593Smuzhiyun # arch/powerpc/boot/Makefile selects on *.c 648*4882a593Smuzhiyun 649*4882a593Smuzhiyun ($config) = $line =~ /(CONFIG_[A-Za-z0-9_]+).*\b$base.[co]\b/; 650*4882a593Smuzhiyun 651*4882a593Smuzhiyun # ----- match a make variable instead of *.[co] 652*4882a593Smuzhiyun # Recursively expanded variables are not handled. 653*4882a593Smuzhiyun 654*4882a593Smuzhiyun if (!$config) { 655*4882a593Smuzhiyun my $make_var; 656*4882a593Smuzhiyun ($make_var) = $line =~ /\s*(\S+?)\s*[+:\?]*=.*\b$base.[co]\b/; 657*4882a593Smuzhiyun if ($make_var) { 658*4882a593Smuzhiyun if ($make_var =~ /[a-zA-Z0-9]+-[ym]/) { 659*4882a593Smuzhiyun $config = $make_var; 660*4882a593Smuzhiyun } elsif ($make_var =~ /[a-zA-Z0-9]+-objs/) { 661*4882a593Smuzhiyun $config = $make_var; 662*4882a593Smuzhiyun } else { 663*4882a593Smuzhiyun push @make_var, $make_var; 664*4882a593Smuzhiyun } 665*4882a593Smuzhiyun } 666*4882a593Smuzhiyun } 667*4882a593Smuzhiyun 668*4882a593Smuzhiyun if (!$config) { 669*4882a593Smuzhiyun for $make_var (@make_var) { 670*4882a593Smuzhiyun ($config) = $line =~ /(CONFIG_[A-Za-z0-9_]+).*\b$make_var\b/; 671*4882a593Smuzhiyun last if ($config); 672*4882a593Smuzhiyun } 673*4882a593Smuzhiyun } 674*4882a593Smuzhiyun 675*4882a593Smuzhiyun if (!$config) { 676*4882a593Smuzhiyun for $make_var (@make_var) { 677*4882a593Smuzhiyun ($config) = $line =~ /\s*(\S+?)\s*[+:\?]*=.*\b$make_var\b/; 678*4882a593Smuzhiyun last if ($config); 679*4882a593Smuzhiyun } 680*4882a593Smuzhiyun } 681*4882a593Smuzhiyun 682*4882a593Smuzhiyun # ----- next if no config found 683*4882a593Smuzhiyun 684*4882a593Smuzhiyun if (!$config) { 685*4882a593Smuzhiyun $line = ""; 686*4882a593Smuzhiyun next NEXT_LINE; 687*4882a593Smuzhiyun } 688*4882a593Smuzhiyun 689*4882a593Smuzhiyun for $if_config (@if_config) { 690*4882a593Smuzhiyun $config = $if_config . " && " . $config; 691*4882a593Smuzhiyun } 692*4882a593Smuzhiyun 693*4882a593Smuzhiyun push @{ $driver_config{$driver} }, $config; 694*4882a593Smuzhiyun 695*4882a593Smuzhiyun $line = ""; 696*4882a593Smuzhiyun } 697*4882a593Smuzhiyun 698*4882a593Smuzhiyun close(MAKEFILE_FILE); 699*4882a593Smuzhiyun 700*4882a593Smuzhiyun} 701*4882a593Smuzhiyun 702*4882a593Smuzhiyun 703*4882a593Smuzhiyunsub find_kconfig 704*4882a593Smuzhiyun{ 705*4882a593Smuzhiyun my $pn_arg_ref = shift; 706*4882a593Smuzhiyun my $driver = shift; 707*4882a593Smuzhiyun 708*4882a593Smuzhiyun my $lines_printed = 0; 709*4882a593Smuzhiyun my @configs; 710*4882a593Smuzhiyun 711*4882a593Smuzhiyun if (!@{ $driver_config{$driver} }) { 712*4882a593Smuzhiyun &scan_makefile($pn_arg_ref, $driver); 713*4882a593Smuzhiyun if (!@{ $driver_config{$driver} }) { 714*4882a593Smuzhiyun push @{ $driver_config{$driver} }, "no_config"; 715*4882a593Smuzhiyun } 716*4882a593Smuzhiyun } 717*4882a593Smuzhiyun 718*4882a593Smuzhiyun @configs = @{ $driver_config{$driver} }; 719*4882a593Smuzhiyun 720*4882a593Smuzhiyun $$pn_arg_ref{config_cnt} = $#configs + 1; 721*4882a593Smuzhiyun for my $config (@configs) { 722*4882a593Smuzhiyun $$pn_arg_ref{config} = $config; 723*4882a593Smuzhiyun $lines_printed += &print_node($pn_arg_ref); 724*4882a593Smuzhiyun } 725*4882a593Smuzhiyun 726*4882a593Smuzhiyun return $lines_printed; 727*4882a593Smuzhiyun} 728*4882a593Smuzhiyun 729*4882a593Smuzhiyun 730*4882a593Smuzhiyunsub handle_compatible() 731*4882a593Smuzhiyun{ 732*4882a593Smuzhiyun my $full_node = shift; 733*4882a593Smuzhiyun my $node = shift; 734*4882a593Smuzhiyun my $compatible = shift; 735*4882a593Smuzhiyun my $node_enabled = shift; 736*4882a593Smuzhiyun 737*4882a593Smuzhiyun my $compat; 738*4882a593Smuzhiyun my $lines_printed = 0; 739*4882a593Smuzhiyun my %pn_arg = (); 740*4882a593Smuzhiyun 741*4882a593Smuzhiyun return if (!$node or !$compatible); 742*4882a593Smuzhiyun 743*4882a593Smuzhiyun # Do not process compatible property of root node, 744*4882a593Smuzhiyun # it is used to match board, not to bind a driver. 745*4882a593Smuzhiyun return if ($node eq "/"); 746*4882a593Smuzhiyun 747*4882a593Smuzhiyun $pn_arg{full_node} = $full_node; 748*4882a593Smuzhiyun $pn_arg{node} = $node; 749*4882a593Smuzhiyun $pn_arg{node_enabled} = $node_enabled; 750*4882a593Smuzhiyun 751*4882a593Smuzhiyun my @compatibles = split('", "', $compatible); 752*4882a593Smuzhiyun 753*4882a593Smuzhiyun $compatibles[0] =~ s/^"//; 754*4882a593Smuzhiyun $compatibles[$#compatibles] =~ s/"$//; 755*4882a593Smuzhiyun 756*4882a593Smuzhiyun $pn_arg{compatible_cnt} = $#compatibles + 1; 757*4882a593Smuzhiyun 758*4882a593Smuzhiyun COMPAT: 759*4882a593Smuzhiyun for $compat (@compatibles) { 760*4882a593Smuzhiyun 761*4882a593Smuzhiyun $pn_arg{compat} = $compat; 762*4882a593Smuzhiyun $pn_arg{driver_cnt} = 0; 763*4882a593Smuzhiyun $pn_arg{white_list} = 0; 764*4882a593Smuzhiyun 765*4882a593Smuzhiyun if (exists($compat_white_list{$compat})) { 766*4882a593Smuzhiyun $pn_arg{white_list} = 1; 767*4882a593Smuzhiyun $pn_arg{driver} = "no_driver"; 768*4882a593Smuzhiyun $pn_arg{config_cnt} = 1; 769*4882a593Smuzhiyun $pn_arg{config} = "no_config"; 770*4882a593Smuzhiyun $lines_printed += &print_node(\%pn_arg); 771*4882a593Smuzhiyun next COMPAT; 772*4882a593Smuzhiyun } 773*4882a593Smuzhiyun 774*4882a593Smuzhiyun # ----- if compat previously seen, use cached info 775*4882a593Smuzhiyun 776*4882a593Smuzhiyun if (exists($compat_driver{$compat})) { 777*4882a593Smuzhiyun for my $driver (@{ $compat_driver{$compat} }) { 778*4882a593Smuzhiyun $pn_arg{driver} = $driver; 779*4882a593Smuzhiyun $pn_arg{driver_cnt} = $driver_count{$compat}; 780*4882a593Smuzhiyun $pn_arg{config_cnt} = $#{ $driver_config{$driver}} + 1; 781*4882a593Smuzhiyun 782*4882a593Smuzhiyun for my $config (@{ $driver_config{$driver} }) { 783*4882a593Smuzhiyun $pn_arg{config} = $config; 784*4882a593Smuzhiyun $lines_printed += &print_node(\%pn_arg); 785*4882a593Smuzhiyun } 786*4882a593Smuzhiyun 787*4882a593Smuzhiyun if (!@{ $driver_config{$driver} }) { 788*4882a593Smuzhiyun # no config cached yet 789*4882a593Smuzhiyun # $driver in %driver_hard_code_list 790*4882a593Smuzhiyun # but not %driver_config_hard_code_list 791*4882a593Smuzhiyun $lines_printed += &find_kconfig(\%pn_arg, $driver); 792*4882a593Smuzhiyun } 793*4882a593Smuzhiyun } 794*4882a593Smuzhiyun next COMPAT; 795*4882a593Smuzhiyun } 796*4882a593Smuzhiyun 797*4882a593Smuzhiyun 798*4882a593Smuzhiyun # ----- Find drivers (source files that contain compatible) 799*4882a593Smuzhiyun 800*4882a593Smuzhiyun # this will miss arch/sparc/include/asm/parport.h 801*4882a593Smuzhiyun # It is better to move the compatible out of the .h 802*4882a593Smuzhiyun # than to add *.h. to the files list, because *.h generates 803*4882a593Smuzhiyun # a lot of false negatives. 804*4882a593Smuzhiyun my $files = '"*.c"'; 805*4882a593Smuzhiyun my $drivers = `git grep -l '"$compat"' -- $files`; 806*4882a593Smuzhiyun chomp($drivers); 807*4882a593Smuzhiyun if ($drivers eq "") { 808*4882a593Smuzhiyun $pn_arg{driver} = "no_driver"; 809*4882a593Smuzhiyun $pn_arg{config_cnt} = 1; 810*4882a593Smuzhiyun $pn_arg{config} = "no_config"; 811*4882a593Smuzhiyun push @{ $compat_driver{$compat} }, "no_driver"; 812*4882a593Smuzhiyun $lines_printed += &print_node(\%pn_arg); 813*4882a593Smuzhiyun next COMPAT; 814*4882a593Smuzhiyun } 815*4882a593Smuzhiyun 816*4882a593Smuzhiyun my @drivers = split("\n", $drivers); 817*4882a593Smuzhiyun $driver_count{$compat} = $#drivers + 1; 818*4882a593Smuzhiyun $pn_arg{driver_cnt} = $#drivers + 1; 819*4882a593Smuzhiyun 820*4882a593Smuzhiyun DRIVER: 821*4882a593Smuzhiyun for my $driver (@drivers) { 822*4882a593Smuzhiyun push @{ $compat_driver{$compat} }, $driver; 823*4882a593Smuzhiyun $pn_arg{driver} = $driver; 824*4882a593Smuzhiyun 825*4882a593Smuzhiyun # ----- if driver previously seen, use cached info 826*4882a593Smuzhiyun 827*4882a593Smuzhiyun $pn_arg{config_cnt} = $#{ $driver_config{$driver} } + 1; 828*4882a593Smuzhiyun for my $config (@{ $driver_config{$driver} }) { 829*4882a593Smuzhiyun $pn_arg{config} = $config; 830*4882a593Smuzhiyun $lines_printed += &print_node(\%pn_arg); 831*4882a593Smuzhiyun } 832*4882a593Smuzhiyun if (@{ $driver_config{$driver} }) { 833*4882a593Smuzhiyun next DRIVER; 834*4882a593Smuzhiyun } 835*4882a593Smuzhiyun 836*4882a593Smuzhiyun if ($black_list_driver) { 837*4882a593Smuzhiyun for $black (@black_list_driver) { 838*4882a593Smuzhiyun next DRIVER if ($driver =~ /^$black$/); 839*4882a593Smuzhiyun } 840*4882a593Smuzhiyun } 841*4882a593Smuzhiyun 842*4882a593Smuzhiyun 843*4882a593Smuzhiyun # ----- Find Kconfig symbols that enable driver 844*4882a593Smuzhiyun 845*4882a593Smuzhiyun $lines_printed += &find_kconfig(\%pn_arg, $driver); 846*4882a593Smuzhiyun 847*4882a593Smuzhiyun } 848*4882a593Smuzhiyun } 849*4882a593Smuzhiyun 850*4882a593Smuzhiyun # White space (line) between nodes for readability. 851*4882a593Smuzhiyun # Each node may report several compatibles. 852*4882a593Smuzhiyun # For each compatible, multiple drivers may be reported. 853*4882a593Smuzhiyun # For each driver, multiple CONFIG_ options may be reported. 854*4882a593Smuzhiyun if ($lines_printed) { 855*4882a593Smuzhiyun print "\n"; 856*4882a593Smuzhiyun } 857*4882a593Smuzhiyun} 858*4882a593Smuzhiyun 859*4882a593Smuzhiyunsub read_dts() 860*4882a593Smuzhiyun{ 861*4882a593Smuzhiyun my $file = shift; 862*4882a593Smuzhiyun 863*4882a593Smuzhiyun my $compatible = ""; 864*4882a593Smuzhiyun my $line; 865*4882a593Smuzhiyun my $node = ""; 866*4882a593Smuzhiyun my $node_enabled = ""; 867*4882a593Smuzhiyun 868*4882a593Smuzhiyun if (! -r $file) { 869*4882a593Smuzhiyun print STDERR "file '$file' is not readable or does not exist\n"; 870*4882a593Smuzhiyun exit 3; 871*4882a593Smuzhiyun } 872*4882a593Smuzhiyun 873*4882a593Smuzhiyun if (!open(DT_FILE, "-|", "$dtx_diff $file")) { 874*4882a593Smuzhiyun print STDERR "\n"; 875*4882a593Smuzhiyun print STDERR "shell command failed:\n"; 876*4882a593Smuzhiyun print STDERR " $dtx_diff $file\n"; 877*4882a593Smuzhiyun print STDERR "\n"; 878*4882a593Smuzhiyun exit 3; 879*4882a593Smuzhiyun } 880*4882a593Smuzhiyun 881*4882a593Smuzhiyun FILE: 882*4882a593Smuzhiyun while ($line = <DT_FILE>) { 883*4882a593Smuzhiyun chomp($line); 884*4882a593Smuzhiyun 885*4882a593Smuzhiyun if ($line =~ /{/) { 886*4882a593Smuzhiyun 887*4882a593Smuzhiyun &handle_compatible($full_node, $node, $compatible, 888*4882a593Smuzhiyun $node_enabled); 889*4882a593Smuzhiyun 890*4882a593Smuzhiyun while ($end_node_count-- > 0) { 891*4882a593Smuzhiyun pop @full_node; 892*4882a593Smuzhiyun }; 893*4882a593Smuzhiyun $end_node_count = 0; 894*4882a593Smuzhiyun $full_node = @full_node[-1]; 895*4882a593Smuzhiyun 896*4882a593Smuzhiyun $node = $line; 897*4882a593Smuzhiyun $node =~ s/^\s*(.*)\s+\{.*/$1/; 898*4882a593Smuzhiyun $node =~ s/.*: //; 899*4882a593Smuzhiyun if ($node eq '/' ) { 900*4882a593Smuzhiyun $full_node = '/'; 901*4882a593Smuzhiyun } elsif ($full_node ne '/') { 902*4882a593Smuzhiyun $full_node = $full_node . '/' . $node; 903*4882a593Smuzhiyun } else { 904*4882a593Smuzhiyun $full_node = '/' . $node; 905*4882a593Smuzhiyun } 906*4882a593Smuzhiyun push @full_node, $full_node; 907*4882a593Smuzhiyun 908*4882a593Smuzhiyun $compatible = ""; 909*4882a593Smuzhiyun $node_enabled = ""; 910*4882a593Smuzhiyun next FILE; 911*4882a593Smuzhiyun } 912*4882a593Smuzhiyun 913*4882a593Smuzhiyun if ($line =~ /}/) { 914*4882a593Smuzhiyun $end_node_count++; 915*4882a593Smuzhiyun } 916*4882a593Smuzhiyun 917*4882a593Smuzhiyun if ($line =~ /(\s+|^)status =/) { 918*4882a593Smuzhiyun $node_enabled = $line; 919*4882a593Smuzhiyun $node_enabled =~ s/^\t*//; 920*4882a593Smuzhiyun $node_enabled =~ s/^status = "//; 921*4882a593Smuzhiyun $node_enabled =~ s/";$//; 922*4882a593Smuzhiyun next FILE; 923*4882a593Smuzhiyun } 924*4882a593Smuzhiyun 925*4882a593Smuzhiyun if ($line =~ /(\s+|^)compatible =/) { 926*4882a593Smuzhiyun # Extract all compatible entries for this device 927*4882a593Smuzhiyun # White space matching here and in handle_compatible() is 928*4882a593Smuzhiyun # precise, because input format is the output of dtc, 929*4882a593Smuzhiyun # which is invoked by dtx_diff. 930*4882a593Smuzhiyun $compatible = $line; 931*4882a593Smuzhiyun $compatible =~ s/^\t*//; 932*4882a593Smuzhiyun $compatible =~ s/^compatible = //; 933*4882a593Smuzhiyun $compatible =~ s/;$//; 934*4882a593Smuzhiyun } 935*4882a593Smuzhiyun } 936*4882a593Smuzhiyun 937*4882a593Smuzhiyun &handle_compatible($full_node, $node, $compatible, $node_enabled); 938*4882a593Smuzhiyun 939*4882a593Smuzhiyun close(DT_FILE); 940*4882a593Smuzhiyun} 941*4882a593Smuzhiyun 942*4882a593Smuzhiyun 943*4882a593Smuzhiyunsub read_config_file() 944*4882a593Smuzhiyun{ 945*4882a593Smuzhiyun if (! -r $config_file) { 946*4882a593Smuzhiyun print STDERR "file '$config_file' is not readable or does not exist\n"; 947*4882a593Smuzhiyun exit 2; 948*4882a593Smuzhiyun } 949*4882a593Smuzhiyun 950*4882a593Smuzhiyun if (!open(CONFIG_FILE, "<", "$config_file")) { 951*4882a593Smuzhiyun print STDERR "open $config_file failed\n"; 952*4882a593Smuzhiyun exit 2; 953*4882a593Smuzhiyun } 954*4882a593Smuzhiyun 955*4882a593Smuzhiyun my @line; 956*4882a593Smuzhiyun 957*4882a593Smuzhiyun LINE: 958*4882a593Smuzhiyun while ($line = <CONFIG_FILE>) { 959*4882a593Smuzhiyun chomp($line); 960*4882a593Smuzhiyun next LINE if ($line =~ /^\s*#/); 961*4882a593Smuzhiyun next LINE if ($line =~ /^\s*$/); 962*4882a593Smuzhiyun @line = split /=/, $line; 963*4882a593Smuzhiyun $existing_config{@line[0]} = @line[1]; 964*4882a593Smuzhiyun } 965*4882a593Smuzhiyun 966*4882a593Smuzhiyun close(CONFIG_FILE); 967*4882a593Smuzhiyun} 968*4882a593Smuzhiyun 969*4882a593Smuzhiyun 970*4882a593Smuzhiyunsub cmd_line_err() 971*4882a593Smuzhiyun{ 972*4882a593Smuzhiyun my $msg = shift; 973*4882a593Smuzhiyun 974*4882a593Smuzhiyun print STDERR "\n"; 975*4882a593Smuzhiyun print STDERR " ERROR processing command line options\n"; 976*4882a593Smuzhiyun print STDERR " $msg\n" if ($msg ne ""); 977*4882a593Smuzhiyun print STDERR "\n"; 978*4882a593Smuzhiyun print STDERR " For help, type '$script_name --help'\n"; 979*4882a593Smuzhiyun print STDERR "\n"; 980*4882a593Smuzhiyun} 981*4882a593Smuzhiyun 982*4882a593Smuzhiyun 983*4882a593Smuzhiyun# ----------------------------------------------------------------------------- 984*4882a593Smuzhiyun# program entry point 985*4882a593Smuzhiyun 986*4882a593SmuzhiyunGetopt::Long::Configure("no_ignore_case", "bundling"); 987*4882a593Smuzhiyun 988*4882a593Smuzhiyunif (!GetOptions( 989*4882a593Smuzhiyun "c=s" => \$config_file, 990*4882a593Smuzhiyun "config=s" => \$config_file, 991*4882a593Smuzhiyun "config-format" => \$config_format, 992*4882a593Smuzhiyun "exclude-flag=s" => \@exclude_flag, 993*4882a593Smuzhiyun "h" => \$help, 994*4882a593Smuzhiyun "help" => \$help, 995*4882a593Smuzhiyun "black-list-driver" => \$black_list_driver, 996*4882a593Smuzhiyun "white-list-config" => \$white_list_config, 997*4882a593Smuzhiyun "white-list-driver" => \$white_list_driver, 998*4882a593Smuzhiyun "include-flag=s" => \@include_flag, 999*4882a593Smuzhiyun "include-suspect" => \$include_suspect, 1000*4882a593Smuzhiyun "short-name" => \$short_name, 1001*4882a593Smuzhiyun "show-lists" => \$show_lists, 1002*4882a593Smuzhiyun "version" => \$version, 1003*4882a593Smuzhiyun )) { 1004*4882a593Smuzhiyun 1005*4882a593Smuzhiyun &cmd_line_err(); 1006*4882a593Smuzhiyun 1007*4882a593Smuzhiyun exit 1; 1008*4882a593Smuzhiyun} 1009*4882a593Smuzhiyun 1010*4882a593Smuzhiyun 1011*4882a593Smuzhiyunmy $exit_after_messages = 0; 1012*4882a593Smuzhiyun 1013*4882a593Smuzhiyunif ($version) { 1014*4882a593Smuzhiyun print STDERR "\n$script_name $VUFX\n\n"; 1015*4882a593Smuzhiyun $exit_after_messages = 1; 1016*4882a593Smuzhiyun} 1017*4882a593Smuzhiyun 1018*4882a593Smuzhiyun 1019*4882a593Smuzhiyunif ($help) { 1020*4882a593Smuzhiyun &usage; 1021*4882a593Smuzhiyun $exit_after_messages = 1; 1022*4882a593Smuzhiyun} 1023*4882a593Smuzhiyun 1024*4882a593Smuzhiyun 1025*4882a593Smuzhiyunif ($show_lists) { 1026*4882a593Smuzhiyun 1027*4882a593Smuzhiyun print "\n"; 1028*4882a593Smuzhiyun print "These compatibles are hard coded to have no driver.\n"; 1029*4882a593Smuzhiyun print "\n"; 1030*4882a593Smuzhiyun for my $compat (sort keys %compat_white_list) { 1031*4882a593Smuzhiyun print " $compat\n"; 1032*4882a593Smuzhiyun } 1033*4882a593Smuzhiyun 1034*4882a593Smuzhiyun 1035*4882a593Smuzhiyun print "\n\n"; 1036*4882a593Smuzhiyun print "The driver for these compatibles is hard coded (white list).\n"; 1037*4882a593Smuzhiyun print "\n"; 1038*4882a593Smuzhiyun my $max_compat_len = 0; 1039*4882a593Smuzhiyun for my $compat (sort keys %driver_hard_code_list) { 1040*4882a593Smuzhiyun if (length $compat > $max_compat_len) { 1041*4882a593Smuzhiyun $max_compat_len = length $compat; 1042*4882a593Smuzhiyun } 1043*4882a593Smuzhiyun } 1044*4882a593Smuzhiyun for my $compat (sort keys %driver_hard_code_list) { 1045*4882a593Smuzhiyun if (($driver ne "hardcoded_no_driver") && ($driver ne "no_driver")) { 1046*4882a593Smuzhiyun my $first = 1; 1047*4882a593Smuzhiyun for my $driver (@{ $driver_hard_code_list{$compat} }) { 1048*4882a593Smuzhiyun if ($first) { 1049*4882a593Smuzhiyun print " $compat"; 1050*4882a593Smuzhiyun print " " x ($max_compat_len - length $compat); 1051*4882a593Smuzhiyun $first = 0; 1052*4882a593Smuzhiyun } else { 1053*4882a593Smuzhiyun print " ", " " x $max_compat_len; 1054*4882a593Smuzhiyun } 1055*4882a593Smuzhiyun print " $driver\n"; 1056*4882a593Smuzhiyun } 1057*4882a593Smuzhiyun } 1058*4882a593Smuzhiyun } 1059*4882a593Smuzhiyun 1060*4882a593Smuzhiyun 1061*4882a593Smuzhiyun print "\n\n"; 1062*4882a593Smuzhiyun print "The configuration option for these drivers is hard coded (white list).\n"; 1063*4882a593Smuzhiyun print "\n"; 1064*4882a593Smuzhiyun my $max_driver_len = 0; 1065*4882a593Smuzhiyun for my $driver (sort keys %driver_config_hard_code_list) { 1066*4882a593Smuzhiyun if (length $driver > $max_driver_len) { 1067*4882a593Smuzhiyun $max_driver_len = length $driver; 1068*4882a593Smuzhiyun } 1069*4882a593Smuzhiyun } 1070*4882a593Smuzhiyun for my $driver (sort keys %driver_config_hard_code_list) { 1071*4882a593Smuzhiyun if (($driver ne "hardcoded_no_driver") && ($driver ne "no_driver")) { 1072*4882a593Smuzhiyun my $first = 1; 1073*4882a593Smuzhiyun for my $config (@{ $driver_config_hard_code_list{$driver} }) { 1074*4882a593Smuzhiyun if ($first) { 1075*4882a593Smuzhiyun print " $driver"; 1076*4882a593Smuzhiyun print " " x ($max_driver_len - length $driver); 1077*4882a593Smuzhiyun $first = 0; 1078*4882a593Smuzhiyun } else { 1079*4882a593Smuzhiyun print " ", " " x $max_driver_len; 1080*4882a593Smuzhiyun } 1081*4882a593Smuzhiyun print " $config\n"; 1082*4882a593Smuzhiyun } 1083*4882a593Smuzhiyun } 1084*4882a593Smuzhiyun } 1085*4882a593Smuzhiyun 1086*4882a593Smuzhiyun 1087*4882a593Smuzhiyun print "\n\n"; 1088*4882a593Smuzhiyun print "These drivers are black listed.\n"; 1089*4882a593Smuzhiyun print "\n"; 1090*4882a593Smuzhiyun for my $driver (@black_list_driver) { 1091*4882a593Smuzhiyun print " $driver\n"; 1092*4882a593Smuzhiyun } 1093*4882a593Smuzhiyun 1094*4882a593Smuzhiyun print "\n"; 1095*4882a593Smuzhiyun 1096*4882a593Smuzhiyun $exit_after_messages = 1; 1097*4882a593Smuzhiyun} 1098*4882a593Smuzhiyun 1099*4882a593Smuzhiyun 1100*4882a593Smuzhiyunif ($exit_after_messages) { 1101*4882a593Smuzhiyun exit 0; 1102*4882a593Smuzhiyun} 1103*4882a593Smuzhiyun 1104*4882a593Smuzhiyun 1105*4882a593Smuzhiyun$exclude_flag_pattern = "["; 1106*4882a593Smuzhiyunfor my $exclude_flag (@exclude_flag) { 1107*4882a593Smuzhiyun $exclude_flag_pattern = $exclude_flag_pattern . $exclude_flag; 1108*4882a593Smuzhiyun} 1109*4882a593Smuzhiyun$exclude_flag_pattern = $exclude_flag_pattern . "]"; 1110*4882a593Smuzhiyun# clean up if empty 1111*4882a593Smuzhiyun$exclude_flag_pattern =~ s/^\[\]$//; 1112*4882a593Smuzhiyun 1113*4882a593Smuzhiyun 1114*4882a593Smuzhiyun$include_flag_pattern = "["; 1115*4882a593Smuzhiyunfor my $include_flag (@include_flag) { 1116*4882a593Smuzhiyun $include_flag_pattern = $include_flag_pattern . $include_flag; 1117*4882a593Smuzhiyun} 1118*4882a593Smuzhiyun$include_flag_pattern = $include_flag_pattern . "]"; 1119*4882a593Smuzhiyun# clean up if empty 1120*4882a593Smuzhiyun$include_flag_pattern =~ s/^\[\]$//; 1121*4882a593Smuzhiyun 1122*4882a593Smuzhiyun 1123*4882a593Smuzhiyunif ($exclude_flag_pattern) { 1124*4882a593Smuzhiyun my $found = 0; 1125*4882a593Smuzhiyun for $pr_flag_value (@pr_flag_value) { 1126*4882a593Smuzhiyun if ($exclude_flag_pattern =~ m/$pr_flag_value/) { 1127*4882a593Smuzhiyun $found = 1; 1128*4882a593Smuzhiyun } 1129*4882a593Smuzhiyun } 1130*4882a593Smuzhiyun if (!$found) { 1131*4882a593Smuzhiyun &cmd_line_err("invalid value for FLAG in --exclude-flag\n"); 1132*4882a593Smuzhiyun exit 1 1133*4882a593Smuzhiyun } 1134*4882a593Smuzhiyun} 1135*4882a593Smuzhiyun 1136*4882a593Smuzhiyunif ($include_flag_pattern) { 1137*4882a593Smuzhiyun my $found = 0; 1138*4882a593Smuzhiyun for $pr_flag_value (@pr_flag_value) { 1139*4882a593Smuzhiyun if ($include_flag_pattern =~ m/$pr_flag_value/) { 1140*4882a593Smuzhiyun $found = 1; 1141*4882a593Smuzhiyun } 1142*4882a593Smuzhiyun } 1143*4882a593Smuzhiyun if (!$found) { 1144*4882a593Smuzhiyun &cmd_line_err("invalid value for FLAG in --include-flag\n"); 1145*4882a593Smuzhiyun exit 1 1146*4882a593Smuzhiyun } 1147*4882a593Smuzhiyun} 1148*4882a593Smuzhiyun 1149*4882a593Smuzhiyunif ($include_suspect) { 1150*4882a593Smuzhiyun $include_flag_pattern =~ s/\[//; 1151*4882a593Smuzhiyun $include_flag_pattern =~ s/\]//; 1152*4882a593Smuzhiyun $include_flag_pattern = "[" . $include_flag_pattern . "A-Z]"; 1153*4882a593Smuzhiyun} 1154*4882a593Smuzhiyun 1155*4882a593Smuzhiyunif ($exclude_flag_pattern =~ m/$include_flag_pattern/) { 1156*4882a593Smuzhiyun &cmd_line_err("the same flag appears in both --exclude-flag and --include-flag or --include-suspect\n"); 1157*4882a593Smuzhiyun exit 1 1158*4882a593Smuzhiyun} 1159*4882a593Smuzhiyun 1160*4882a593Smuzhiyun 1161*4882a593Smuzhiyun# ($#ARGV < 0) is valid for --help, --version 1162*4882a593Smuzhiyunif ($#ARGV < 0) { 1163*4882a593Smuzhiyun &cmd_line_err("device-tree... is required"); 1164*4882a593Smuzhiyun exit 1 1165*4882a593Smuzhiyun} 1166*4882a593Smuzhiyun 1167*4882a593Smuzhiyun 1168*4882a593Smuzhiyunif ($config_file) { 1169*4882a593Smuzhiyun &read_config_file(); 1170*4882a593Smuzhiyun} 1171*4882a593Smuzhiyun 1172*4882a593Smuzhiyun 1173*4882a593Smuzhiyun# avoid pushing duplicates for this value 1174*4882a593Smuzhiyun$driver = "hardcoded_no_driver"; 1175*4882a593Smuzhiyunfor $config ( @{ $driver_config_hard_code_list{$driver} } ) { 1176*4882a593Smuzhiyun push @{ $driver_config{$driver} }, $config; 1177*4882a593Smuzhiyun} 1178*4882a593Smuzhiyun 1179*4882a593Smuzhiyunif ($white_list_driver) { 1180*4882a593Smuzhiyun for my $compat (keys %driver_hard_code_list) { 1181*4882a593Smuzhiyun for my $driver (@{ $driver_hard_code_list{$compat} }) { 1182*4882a593Smuzhiyun push @{ $compat_driver{$compat} }, $driver; 1183*4882a593Smuzhiyun if ($driver ne "hardcoded_no_driver") { 1184*4882a593Smuzhiyun $driver_count{$compat} = scalar @{ $compat_driver{$compat} }; 1185*4882a593Smuzhiyun } 1186*4882a593Smuzhiyun } 1187*4882a593Smuzhiyun } 1188*4882a593Smuzhiyun} 1189*4882a593Smuzhiyun 1190*4882a593Smuzhiyunif ($white_list_config) { 1191*4882a593Smuzhiyun for my $driver (keys %driver_config_hard_code_list) { 1192*4882a593Smuzhiyun if ($driver ne "hardcoded_no_driver") { 1193*4882a593Smuzhiyun for $config ( @{ $driver_config_hard_code_list{$driver} } ) { 1194*4882a593Smuzhiyun push @{ $driver_config{$driver} }, $config; 1195*4882a593Smuzhiyun } 1196*4882a593Smuzhiyun } 1197*4882a593Smuzhiyun } 1198*4882a593Smuzhiyun} 1199*4882a593Smuzhiyun 1200*4882a593Smuzhiyunif (-x "scripts/dtc/dtx_diff") { 1201*4882a593Smuzhiyun $dtx_diff = "scripts/dtc/dtx_diff"; 1202*4882a593Smuzhiyun} else { 1203*4882a593Smuzhiyun 1204*4882a593Smuzhiyun print STDERR "\n"; 1205*4882a593Smuzhiyun print STDERR "$script_name must be run from the root directory of a Linux kernel tree\n"; 1206*4882a593Smuzhiyun print STDERR "\n"; 1207*4882a593Smuzhiyun exit 3; 1208*4882a593Smuzhiyun} 1209*4882a593Smuzhiyun 1210*4882a593Smuzhiyunfor $file (@ARGV) { 1211*4882a593Smuzhiyun &read_dts($file); 1212*4882a593Smuzhiyun} 1213