xref: /OK3568_Linux_fs/kernel/scripts/dtc/dt_to_config (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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