From 4f1727a7e31c192d294280b0379b522f57b54d31 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 4 Jul 2021 12:19:47 -0600 Subject: dtoc: Add a stdout check in test_normalized_name() This test captures output but does not always check it. Add the missing code and drop the old comment. Signed-off-by: Simon Glass --- tools/dtoc/test_src_scan.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'tools/dtoc/test_src_scan.py') diff --git a/tools/dtoc/test_src_scan.py b/tools/dtoc/test_src_scan.py index d6da03849f..4e38b25a2f 100644 --- a/tools/dtoc/test_src_scan.py +++ b/tools/dtoc/test_src_scan.py @@ -171,8 +171,7 @@ class TestSrcScan(unittest.TestCase): self.assertEqual([], aliases) self.assertEqual(1, len(scan._missing_drivers)) self.assertEqual({'rockchip_rk3288_grf'}, scan._missing_drivers) - #'WARNING: the driver rockchip_rk3288_grf was not found in the driver list', - #stdout.getvalue().strip()) + self.assertEqual('', stdout.getvalue().strip()) i2c = 'I2C_UCLASS' compat = {'rockchip,rk3288-grf': 'ROCKCHIP_SYSCON_GRF', -- cgit v1.2.3 From 86ff01e890a72fb2b8cefab542d4b9123fe83036 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 4 Jul 2021 12:19:48 -0600 Subject: dtoc: Detect unexpected suffix on .of_match Some rockchip drivers use a suffix on the of_match line which is not strictly valid. At present this causes the parsing to fail. Fix this and offer a warning. Signed-off-by: Simon Glass --- tools/dtoc/src_scan.py | 12 ++++-- tools/dtoc/test_src_scan.py | 92 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 3 deletions(-) (limited to 'tools/dtoc/test_src_scan.py') diff --git a/tools/dtoc/src_scan.py b/tools/dtoc/src_scan.py index 6e8e1ba51a..847677757d 100644 --- a/tools/dtoc/src_scan.py +++ b/tools/dtoc/src_scan.py @@ -468,7 +468,7 @@ class Scanner: # Matches the references to the udevice_id list re_of_match = re.compile( - r'\.of_match\s*=\s*(of_match_ptr\()?([a-z0-9_]+)(\))?,') + r'\.of_match\s*=\s*(of_match_ptr\()?([a-z0-9_]+)([^,]*),') re_phase = re.compile('^\s*DM_PHASE\((.*)\).*$') re_hdr = re.compile('^\s*DM_HEADER\((.*)\).*$') @@ -514,6 +514,11 @@ class Scanner: driver.uclass_id = m_id.group(1) elif m_of_match: compat = m_of_match.group(2) + suffix = m_of_match.group(3) + if suffix and suffix != ')': + self._warnings[driver.name].add( + "%s: Warning: unexpected suffix '%s' on .of_match line for compat '%s'" % + (fname, suffix, compat)) elif m_phase: driver.phase = m_phase.group(1) elif m_hdr: @@ -586,13 +591,14 @@ class Scanner: def show_warnings(self): """Show any warnings that have been collected""" used_drivers = [drv.name for drv in self._drivers.values() if drv.used] - missing = self._missing_drivers + missing = self._missing_drivers.copy() for name in sorted(self._warnings.keys()): if name in missing or name in used_drivers: warns = sorted(list(self._warnings[name])) - # For now there is only ever one warning print('%s: %s' % (name, warns[0])) indent = ' ' * len(name) + for warn in warns[1:]: + print('%-s: %s' % (indent, warn)) if name in missing: missing.remove(name) print() diff --git a/tools/dtoc/test_src_scan.py b/tools/dtoc/test_src_scan.py index 4e38b25a2f..62500e80fe 100644 --- a/tools/dtoc/test_src_scan.py +++ b/tools/dtoc/test_src_scan.py @@ -20,6 +20,9 @@ from patman import tools OUR_PATH = os.path.dirname(os.path.realpath(__file__)) +EXPECT_WARN = {'rockchip_rk3288_grf': + {'WARNING: the driver rockchip_rk3288_grf was not found in the driver list'}} + class FakeNode: """Fake Node object for testing""" def __init__(self): @@ -152,6 +155,7 @@ class TestSrcScan(unittest.TestCase): 'nvidia,tegra20-i2c-dvc': 'TYPE_DVC'}, drv.compat) self.assertEqual('i2c_bus', drv.priv) self.assertEqual(1, len(scan._drivers)) + self.assertEqual({}, scan._warnings) def test_normalized_name(self): """Test operation of get_normalized_compat_name()""" @@ -172,6 +176,7 @@ class TestSrcScan(unittest.TestCase): self.assertEqual(1, len(scan._missing_drivers)) self.assertEqual({'rockchip_rk3288_grf'}, scan._missing_drivers) self.assertEqual('', stdout.getvalue().strip()) + self.assertEqual(EXPECT_WARN, scan._warnings) i2c = 'I2C_UCLASS' compat = {'rockchip,rk3288-grf': 'ROCKCHIP_SYSCON_GRF', @@ -188,6 +193,7 @@ class TestSrcScan(unittest.TestCase): self.assertEqual('', stdout.getvalue().strip()) self.assertEqual('rockchip_rk3288_grf', name) self.assertEqual([], aliases) + self.assertEqual(EXPECT_WARN, scan._warnings) prop.value = 'rockchip,rk3288-srf' with test_util.capture_sys_output() as (stdout, _): @@ -195,6 +201,7 @@ class TestSrcScan(unittest.TestCase): self.assertEqual('', stdout.getvalue().strip()) self.assertEqual('rockchip_rk3288_grf', name) self.assertEqual(['rockchip_rk3288_srf'], aliases) + self.assertEqual(EXPECT_WARN, scan._warnings) def test_scan_errors(self): """Test detection of scanning errors""" @@ -489,3 +496,88 @@ U_BOOT_DRIVER(%s) = { self.assertEqual(3, seq) self.assertEqual({'mypath': 3}, uc.alias_path_to_num) self.assertEqual({2: node, 3: node}, uc.alias_num_to_node) + + def test_scan_warnings(self): + """Test detection of scanning warnings""" + buff = ''' +static const struct udevice_id tegra_i2c_ids[] = { + { .compatible = "nvidia,tegra114-i2c", .data = TYPE_114 }, + { } +}; + +U_BOOT_DRIVER(i2c_tegra) = { + .name = "i2c_tegra", + .id = UCLASS_I2C, + .of_match = tegra_i2c_ids + 1, +}; +''' + # The '+ 1' above should generate a warning + + prop = FakeProp() + prop.name = 'compatible' + prop.value = 'rockchip,rk3288-grf' + node = FakeNode() + node.props = {'compatible': prop} + + # get_normalized_compat_name() uses this to check for root node + node.parent = FakeNode() + + scan = src_scan.Scanner(None, None) + scan._parse_driver('file.c', buff) + self.assertEqual( + {'i2c_tegra': + {"file.c: Warning: unexpected suffix ' + 1' on .of_match line for compat 'tegra_i2c_ids'"}}, + scan._warnings) + + tprop = FakeProp() + tprop.name = 'compatible' + tprop.value = 'nvidia,tegra114-i2c' + tnode = FakeNode() + tnode.props = {'compatible': tprop} + + # get_normalized_compat_name() uses this to check for root node + tnode.parent = FakeNode() + + with test_util.capture_sys_output() as (stdout, _): + scan.get_normalized_compat_name(node) + scan.get_normalized_compat_name(tnode) + self.assertEqual('', stdout.getvalue().strip()) + + self.assertEqual(2, len(scan._missing_drivers)) + self.assertEqual({'rockchip_rk3288_grf', 'nvidia_tegra114_i2c'}, + scan._missing_drivers) + with test_util.capture_sys_output() as (stdout, _): + scan.show_warnings() + self.assertIn('rockchip_rk3288_grf', stdout.getvalue()) + + # This should show just the rockchip warning, since the tegra driver + # is not in self._missing_drivers + scan._missing_drivers.remove('nvidia_tegra114_i2c') + with test_util.capture_sys_output() as (stdout, _): + scan.show_warnings() + self.assertIn('rockchip_rk3288_grf', stdout.getvalue()) + self.assertNotIn('tegra_i2c_ids', stdout.getvalue()) + + # Do a similar thing with used drivers. By marking the tegra driver as + # used, the warning related to that driver will be shown + drv = scan._drivers['i2c_tegra'] + drv.used = True + with test_util.capture_sys_output() as (stdout, _): + scan.show_warnings() + self.assertIn('rockchip_rk3288_grf', stdout.getvalue()) + self.assertIn('tegra_i2c_ids', stdout.getvalue()) + + # Add a warning to make sure multiple warnings are shown + scan._warnings['i2c_tegra'].update( + scan._warnings['nvidia_tegra114_i2c']) + del scan._warnings['nvidia_tegra114_i2c'] + with test_util.capture_sys_output() as (stdout, _): + scan.show_warnings() + self.assertEqual('''i2c_tegra: WARNING: the driver nvidia_tegra114_i2c was not found in the driver list + : file.c: Warning: unexpected suffix ' + 1' on .of_match line for compat 'tegra_i2c_ids' + +rockchip_rk3288_grf: WARNING: the driver rockchip_rk3288_grf was not found in the driver list + +''', + stdout.getvalue()) + self.assertIn('tegra_i2c_ids', stdout.getvalue()) -- cgit v1.2.3 From 43ba4926702ca0c6d896b8d318b4c596979d2f32 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 4 Jul 2021 12:19:49 -0600 Subject: dtoc: Detect drivers which do not parse correctly At present if a driver is missing a uclass or compatible stirng, this is silently ignored. This makes sense in most cases, particularly for the compatible string, since it is not required except when the driver is used with of-platdata. But it is also not very helpful. When there is some sort of problem with a driver, the missing compatible string (for example) may be the cause. Add a warning in this case, showing it only for drivers which are used by the build. Signed-off-by: Simon Glass Reviewed-by: Walter Lozano --- tools/dtoc/src_scan.py | 7 ++++++- tools/dtoc/test_src_scan.py | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) (limited to 'tools/dtoc/test_src_scan.py') diff --git a/tools/dtoc/src_scan.py b/tools/dtoc/src_scan.py index 847677757d..3bef59d616 100644 --- a/tools/dtoc/src_scan.py +++ b/tools/dtoc/src_scan.py @@ -546,7 +546,12 @@ class Scanner: # The driver does not have a uclass or compat string. # The first is required but the second is not, so just # ignore this. - pass + if not driver.uclass_id: + warn = 'Missing .uclass' + else: + warn = 'Missing .compatible' + self._warnings[driver.name].add('%s in %s' % + (warn, fname)) driver = None ids_name = None compat = None diff --git a/tools/dtoc/test_src_scan.py b/tools/dtoc/test_src_scan.py index 62500e80fe..f03cf8ed7c 100644 --- a/tools/dtoc/test_src_scan.py +++ b/tools/dtoc/test_src_scan.py @@ -581,3 +581,41 @@ rockchip_rk3288_grf: WARNING: the driver rockchip_rk3288_grf was not found in th ''', stdout.getvalue()) self.assertIn('tegra_i2c_ids', stdout.getvalue()) + + def scan_uclass_warning(self): + """Test a missing .uclass in the driver""" + buff = ''' +static const struct udevice_id tegra_i2c_ids[] = { + { .compatible = "nvidia,tegra114-i2c", .data = TYPE_114 }, + { } +}; + +U_BOOT_DRIVER(i2c_tegra) = { + .name = "i2c_tegra", + .of_match = tegra_i2c_ids, +}; +''' + scan = src_scan.Scanner(None, None) + scan._parse_driver('file.c', buff) + self.assertEqual( + {'i2c_tegra': {'Missing .uclass in file.c'}}, + scan._warnings) + + def scan_compat_warning(self): + """Test a missing .compatible in the driver""" + buff = ''' +static const struct udevice_id tegra_i2c_ids[] = { + { .compatible = "nvidia,tegra114-i2c", .data = TYPE_114 }, + { } +}; + +U_BOOT_DRIVER(i2c_tegra) = { + .name = "i2c_tegra", + .id = UCLASS_I2C, +}; +''' + scan = src_scan.Scanner(None, None) + scan._parse_driver('file.c', buff) + self.assertEqual( + {'i2c_tegra': {'Missing .compatible in file.c'}}, + scan._warnings) -- cgit v1.2.3