diff mbox series

[v5,04/14] dtoc: add support to scan drivers

Message ID 20200703110717.20339-1-walter.lozano@collabora.com
State Accepted
Headers show
Series None | expand

Commit Message

Walter Lozano July 3, 2020, 11:07 a.m. UTC
Currently dtoc scans dtbs to convert them to struct platdata and
to generate U_BOOT_DEVICE entries. These entries need to be filled
with the driver name, but at this moment the information used is the
compatible name present in the dtb. This causes that only nodes with
a compatible name that matches a driver name generate a working
entry.

In order to improve this behaviour, this patch adds to dtoc the
capability of scan drivers source code to generate a list of valid driver
names and aliases. This allows to generate U_BOOT_DEVICE entries using
valid driver names and rise a warning in the case a name is not valid.

Signed-off-by: Walter Lozano <walter.lozano@collabora.com>
---

(no changes since v1)

 tools/dtoc/dtb_platdata.py            | 91 +++++++++++++++++++++++++--
 tools/dtoc/dtoc_test_driver_alias.dts | 20 ++++++
 tools/dtoc/test_dtoc.py               | 33 ++++++++++
 3 files changed, 140 insertions(+), 4 deletions(-)
 create mode 100644 tools/dtoc/dtoc_test_driver_alias.dts

Comments

Simon Glass July 3, 2020, 4:08 p.m. UTC | #1
Hi Walter,

On Fri, 3 Jul 2020 at 05:07, Walter Lozano <walter.lozano@collabora.com> wrote:
>
> Currently dtoc scans dtbs to convert them to struct platdata and
> to generate U_BOOT_DEVICE entries. These entries need to be filled
> with the driver name, but at this moment the information used is the
> compatible name present in the dtb. This causes that only nodes with
> a compatible name that matches a driver name generate a working
> entry.
>
> In order to improve this behaviour, this patch adds to dtoc the
> capability of scan drivers source code to generate a list of valid driver
> names and aliases. This allows to generate U_BOOT_DEVICE entries using
> valid driver names and rise a warning in the case a name is not valid.
>
> Signed-off-by: Walter Lozano <walter.lozano@collabora.com>
> ---
>
> (no changes since v1)
>
>  tools/dtoc/dtb_platdata.py            | 91 +++++++++++++++++++++++++--
>  tools/dtoc/dtoc_test_driver_alias.dts | 20 ++++++
>  tools/dtoc/test_dtoc.py               | 33 ++++++++++
>  3 files changed, 140 insertions(+), 4 deletions(-)
>  create mode 100644 tools/dtoc/dtoc_test_driver_alias.dts
>

This seems to do the trick, thanks!

But there is one problem remaining - lots of warning output from the
various tests:

https://pastebin.com/K7GBPiqC

Regards,
Simon
Walter Lozano July 3, 2020, 5:44 p.m. UTC | #2
Hi Simon,

On 3/7/20 13:08, Simon Glass wrote:
> Hi Walter,
>
> On Fri, 3 Jul 2020 at 05:07, Walter Lozano <walter.lozano@collabora.com> wrote:
>> Currently dtoc scans dtbs to convert them to struct platdata and
>> to generate U_BOOT_DEVICE entries. These entries need to be filled
>> with the driver name, but at this moment the information used is the
>> compatible name present in the dtb. This causes that only nodes with
>> a compatible name that matches a driver name generate a working
>> entry.
>>
>> In order to improve this behaviour, this patch adds to dtoc the
>> capability of scan drivers source code to generate a list of valid driver
>> names and aliases. This allows to generate U_BOOT_DEVICE entries using
>> valid driver names and rise a warning in the case a name is not valid.
>>
>> Signed-off-by: Walter Lozano <walter.lozano@collabora.com>
>> ---
>>
>> (no changes since v1)
>>
>>   tools/dtoc/dtb_platdata.py            | 91 +++++++++++++++++++++++++--
>>   tools/dtoc/dtoc_test_driver_alias.dts | 20 ++++++
>>   tools/dtoc/test_dtoc.py               | 33 ++++++++++
>>   3 files changed, 140 insertions(+), 4 deletions(-)
>>   create mode 100644 tools/dtoc/dtoc_test_driver_alias.dts
>>
> This seems to do the trick, thanks!
>
> But there is one problem remaining - lots of warning output from the
> various tests:
>
> https://pastebin.com/K7GBPiqC

The warnings are removed by the next patch in the series, "[PATCH v4 
05/14] dtoc: add option to disable warnings", by adding additional 
arguments.

I thought having these two things in different patches made sense, but 
If you prefer I can re send the series with those two patches squashed.

Please confirm.

Regards,

Walter
Simon Glass July 3, 2020, 10:45 p.m. UTC | #3
Hi Walter,

On Fri, 3 Jul 2020 at 11:45, Walter Lozano <walter.lozano@collabora.com> wrote:
>
> Hi Simon,
>
> On 3/7/20 13:08, Simon Glass wrote:
> > Hi Walter,
> >
> > On Fri, 3 Jul 2020 at 05:07, Walter Lozano <walter.lozano@collabora.com> wrote:
> >> Currently dtoc scans dtbs to convert them to struct platdata and
> >> to generate U_BOOT_DEVICE entries. These entries need to be filled
> >> with the driver name, but at this moment the information used is the
> >> compatible name present in the dtb. This causes that only nodes with
> >> a compatible name that matches a driver name generate a working
> >> entry.
> >>
> >> In order to improve this behaviour, this patch adds to dtoc the
> >> capability of scan drivers source code to generate a list of valid driver
> >> names and aliases. This allows to generate U_BOOT_DEVICE entries using
> >> valid driver names and rise a warning in the case a name is not valid.
> >>
> >> Signed-off-by: Walter Lozano <walter.lozano@collabora.com>
> >> ---
> >>
> >> (no changes since v1)
> >>
> >>   tools/dtoc/dtb_platdata.py            | 91 +++++++++++++++++++++++++--
> >>   tools/dtoc/dtoc_test_driver_alias.dts | 20 ++++++
> >>   tools/dtoc/test_dtoc.py               | 33 ++++++++++
> >>   3 files changed, 140 insertions(+), 4 deletions(-)
> >>   create mode 100644 tools/dtoc/dtoc_test_driver_alias.dts
> >>
> > This seems to do the trick, thanks!
> >
> > But there is one problem remaining - lots of warning output from the
> > various tests:
> >
> > https://pastebin.com/K7GBPiqC
>
> The warnings are removed by the next patch in the series, "[PATCH v4
> 05/14] dtoc: add option to disable warnings", by adding additional
> arguments.
>
> I thought having these two things in different patches made sense, but
> If you prefer I can re send the series with those two patches squashed.
>
> Please confirm.

OK I see. Then that is fine, thanks.

Regards,
SImon
Simon Glass July 6, 2020, 1:25 a.m. UTC | #4
Hi Walter,

On Fri, 3 Jul 2020 at 11:45, Walter Lozano <walter.lozano@collabora.com> wrote:
>
> Hi Simon,
>
> On 3/7/20 13:08, Simon Glass wrote:
> > Hi Walter,
> >
> > On Fri, 3 Jul 2020 at 05:07, Walter Lozano <walter.lozano@collabora.com> wrote:
> >> Currently dtoc scans dtbs to convert them to struct platdata and
> >> to generate U_BOOT_DEVICE entries. These entries need to be filled
> >> with the driver name, but at this moment the information used is the
> >> compatible name present in the dtb. This causes that only nodes with
> >> a compatible name that matches a driver name generate a working
> >> entry.
> >>
> >> In order to improve this behaviour, this patch adds to dtoc the
> >> capability of scan drivers source code to generate a list of valid driver
> >> names and aliases. This allows to generate U_BOOT_DEVICE entries using
> >> valid driver names and rise a warning in the case a name is not valid.
> >>
> >> Signed-off-by: Walter Lozano <walter.lozano@collabora.com>
> >> ---
> >>
> >> (no changes since v1)
> >>
> >>   tools/dtoc/dtb_platdata.py            | 91 +++++++++++++++++++++++++--
> >>   tools/dtoc/dtoc_test_driver_alias.dts | 20 ++++++
> >>   tools/dtoc/test_dtoc.py               | 33 ++++++++++
> >>   3 files changed, 140 insertions(+), 4 deletions(-)
> >>   create mode 100644 tools/dtoc/dtoc_test_driver_alias.dts
> >>
> > This seems to do the trick, thanks!
> >
> > But there is one problem remaining - lots of warning output from the
> > various tests:
> >
> > https://pastebin.com/K7GBPiqC
>
> The warnings are removed by the next patch in the series, "[PATCH v4
> 05/14] dtoc: add option to disable warnings", by adding additional
> arguments.
>
> I thought having these two things in different patches made sense, but
> If you prefer I can re send the series with those two patches squashed.
>
> Please confirm.

OK I see. Then that is fine, thanks.

Regards,
SImon

Applied to u-boot-dm, thanks!
diff mbox series

Patch

diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index bc0de426a9..ae8674d85c 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -13,6 +13,8 @@  static data.
 
 import collections
 import copy
+import os
+import re
 import sys
 
 from dtoc import fdt
@@ -143,6 +145,11 @@  class DtbPlatdata(object):
         _aliases: Dict that hold aliases for compatible strings
             key: First compatible string declared in a node
             value: List of additional compatible strings declared in a node
+        _drivers: List of valid driver names found in drivers/
+        _driver_aliases: Dict that holds aliases for driver names
+            key: Driver alias declared with
+                U_BOOT_DRIVER_ALIAS(driver_alias, driver_name)
+            value: Driver name declared with U_BOOT_DRIVER(driver_name)
     """
     def __init__(self, dtb_fname, include_disabled):
         self._fdt = None
@@ -152,6 +159,38 @@  class DtbPlatdata(object):
         self._outfile = None
         self._lines = []
         self._aliases = {}
+        self._drivers = []
+        self._driver_aliases = {}
+
+    def get_normalized_compat_name(self, node):
+        """Get a node's normalized compat name
+
+        Returns a valid driver name by retrieving node's first compatible
+        string as a C identifier and performing a check against _drivers
+        and a lookup in driver_aliases printing a warning in case of failure.
+
+        Args:
+            node: Node object to check
+        Return:
+            Tuple:
+                Driver name associated with the first compatible string
+                List of C identifiers for all the other compatible strings
+                    (possibly empty)
+                In case of no match found, the return will be the same as
+                get_compat_name()
+        """
+        compat_c, aliases_c = get_compat_name(node)
+        if compat_c not in self._drivers:
+            compat_c_old = compat_c
+            compat_c = self._driver_aliases.get(compat_c)
+            if not compat_c:
+                print('WARNING: the driver %s was not found in the driver list'
+                      % (compat_c_old))
+                compat_c = compat_c_old
+            else:
+                aliases_c = [compat_c_old] + aliases_c
+
+        return compat_c, aliases_c
 
     def setup_output(self, fname):
         """Set up the output destination
@@ -246,6 +285,49 @@  class DtbPlatdata(object):
             return PhandleInfo(max_args, args)
         return None
 
+    def scan_driver(self, fn):
+        """Scan a driver file to build a list of driver names and aliases
+
+        This procedure will populate self._drivers and self._driver_aliases
+
+        Args
+            fn: Driver filename to scan
+        """
+        with open(fn) as fd:
+            buff = fd.read()
+
+            # The following re will search for driver names declared as
+            # U_BOOT_DRIVER(driver_name)
+            drivers = re.findall('U_BOOT_DRIVER\((.*)\)', buff)
+
+            for driver in drivers:
+                self._drivers.append(driver)
+
+            # The following re will search for driver aliases declared as
+            # U_BOOT_DRIVER_ALIAS(alias, driver_name)
+            driver_aliases = re.findall('U_BOOT_DRIVER_ALIAS\(\s*(\w+)\s*,\s*(\w+)\s*\)',
+                                        buff)
+
+            for alias in driver_aliases: # pragma: no cover
+                if len(alias) != 2:
+                    continue
+                self._driver_aliases[alias[1]] = alias[0]
+
+    def scan_drivers(self):
+        """Scan the driver folders to build a list of driver names and aliases
+
+        This procedure will populate self._drivers and self._driver_aliases
+
+        """
+        basedir = sys.argv[0].replace('tools/dtoc/dtoc', '')
+        if basedir == '':
+            basedir = './'
+        for (dirpath, dirnames, filenames) in os.walk(basedir):
+            for fn in filenames:
+                if not fn.endswith('.c'):
+                    continue
+                self.scan_driver(dirpath + '/' + fn)
+
     def scan_dtb(self):
         """Scan the device tree to obtain a tree of nodes and properties
 
@@ -356,7 +438,7 @@  class DtbPlatdata(object):
         """
         structs = {}
         for node in self._valid_nodes:
-            node_name, _ = get_compat_name(node)
+            node_name, _ = self.get_normalized_compat_name(node)
             fields = {}
 
             # Get a list of all the valid properties in this node.
@@ -380,14 +462,14 @@  class DtbPlatdata(object):
 
         upto = 0
         for node in self._valid_nodes:
-            node_name, _ = get_compat_name(node)
+            node_name, _ = self.get_normalized_compat_name(node)
             struct = structs[node_name]
             for name, prop in node.props.items():
                 if name not in PROP_IGNORE_LIST and name[0] != '#':
                     prop.Widen(struct[name])
             upto += 1
 
-            struct_name, aliases = get_compat_name(node)
+            struct_name, aliases = self.get_normalized_compat_name(node)
             for alias in aliases:
                 self._aliases[alias] = struct_name
 
@@ -464,7 +546,7 @@  class DtbPlatdata(object):
         Args:
             node: node to output
         """
-        struct_name, _ = get_compat_name(node)
+        struct_name, _ = self.get_normalized_compat_name(node)
         var_name = conv_name_to_c(node.name)
         self.buf('static const struct %s%s %s%s = {\n' %
                  (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
@@ -565,6 +647,7 @@  def run_steps(args, dtb_file, include_disabled, output):
         raise ValueError('Please specify a command: struct, platdata')
 
     plat = DtbPlatdata(dtb_file, include_disabled)
+    plat.scan_drivers()
     plat.scan_dtb()
     plat.scan_tree()
     plat.scan_reg_sizes()
diff --git a/tools/dtoc/dtoc_test_driver_alias.dts b/tools/dtoc/dtoc_test_driver_alias.dts
new file mode 100644
index 0000000000..da7973b2e5
--- /dev/null
+++ b/tools/dtoc/dtoc_test_driver_alias.dts
@@ -0,0 +1,20 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test device tree file for dtoc
+ *
+ * Copyright 2020 Collabora Ltd.
+ */
+
+/dts-v1/;
+
+/ {
+	gpio_a: gpios@0 {
+		u-boot,dm-pre-reloc;
+		gpio-controller;
+		compatible = "sandbox_gpio_alias";
+		#gpio-cells = <1>;
+		gpio-bank-name = "a";
+		sandbox,gpio-count = <20>;
+	};
+
+};
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
index 8498e8303c..91fc9d77f3 100755
--- a/tools/dtoc/test_dtoc.py
+++ b/tools/dtoc/test_dtoc.py
@@ -266,6 +266,39 @@  U_BOOT_DEVICE(pmic_at_9) = {
 \t.platdata_size\t= sizeof(dtv_pmic_at_9),
 };
 
+''', data)
+
+    def test_driver_alias(self):
+        """Test output from a device tree file with a driver alias"""
+        dtb_file = get_dtb_file('dtoc_test_driver_alias.dts')
+        output = tools.GetOutputFilename('output')
+        dtb_platdata.run_steps(['struct'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self._CheckStrings(HEADER + '''
+struct dtd_sandbox_gpio {
+\tconst char *\tgpio_bank_name;
+\tbool\t\tgpio_controller;
+\tfdt32_t\t\tsandbox_gpio_count;
+};
+#define dtd_sandbox_gpio_alias dtd_sandbox_gpio
+''', data)
+
+        dtb_platdata.run_steps(['platdata'], dtb_file, False, output)
+        with open(output) as infile:
+            data = infile.read()
+        self._CheckStrings(C_HEADER + '''
+static const struct dtd_sandbox_gpio dtv_gpios_at_0 = {
+\t.gpio_bank_name\t\t= "a",
+\t.gpio_controller\t= true,
+\t.sandbox_gpio_count\t= 0x14,
+};
+U_BOOT_DEVICE(gpios_at_0) = {
+\t.name\t\t= "sandbox_gpio",
+\t.platdata\t= &dtv_gpios_at_0,
+\t.platdata_size\t= sizeof(dtv_gpios_at_0),
+};
+
 ''', data)
 
     def test_phandle(self):