mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-18 21:21:37 +00:00
dtoc: Read aliases for uclasses
Scan the aliases in the device tree to establish the number of devices within each uclass, and the sequence number of each. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
1d97269756
commit
059535291c
7 changed files with 345 additions and 3 deletions
|
@ -647,6 +647,29 @@ class DtbPlatdata():
|
|||
self._output_prop(node, node.props[pname])
|
||||
self.buf('};\n')
|
||||
|
||||
def read_aliases(self):
|
||||
"""Read the aliases and attach the information to self._alias
|
||||
|
||||
Raises:
|
||||
ValueError: The alias path is not found
|
||||
"""
|
||||
alias_node = self._fdt.GetNode('/aliases')
|
||||
if not alias_node:
|
||||
return
|
||||
re_num = re.compile('(^[a-z0-9-]+[a-z]+)([0-9]+)$')
|
||||
for prop in alias_node.props.values():
|
||||
m_alias = re_num.match(prop.name)
|
||||
if not m_alias:
|
||||
raise ValueError("Cannot decode alias '%s'" % prop.name)
|
||||
name, num = m_alias.groups()
|
||||
node = self._fdt.GetNode(prop.value)
|
||||
result = self._scan.add_uclass_alias(name, num, node)
|
||||
if result is None:
|
||||
raise ValueError("Alias '%s' path '%s' not found" %
|
||||
(prop.name, prop.value))
|
||||
elif result is False:
|
||||
print("Could not find uclass for alias '%s'" % prop.name)
|
||||
|
||||
def process_nodes(self, need_drivers):
|
||||
nodes_to_output = list(self._valid_nodes)
|
||||
|
||||
|
@ -757,6 +780,9 @@ def run_steps(args, dtb_file, include_disabled, output, output_dirs, phase,
|
|||
scan (src_src.Scanner): Scanner from a previous run. This can help speed
|
||||
up tests. Use None for normal operation
|
||||
|
||||
Returns:
|
||||
DtbPlatdata object
|
||||
|
||||
Raises:
|
||||
ValueError: if args has no command, or an unknown command
|
||||
"""
|
||||
|
@ -782,6 +808,7 @@ def run_steps(args, dtb_file, include_disabled, output, output_dirs, phase,
|
|||
plat.scan_phandles()
|
||||
if do_process:
|
||||
plat.process_nodes(False)
|
||||
plat.read_aliases()
|
||||
|
||||
cmds = args[0].split(',')
|
||||
if 'all' in cmds:
|
||||
|
@ -796,3 +823,4 @@ def run_steps(args, dtb_file, include_disabled, output, output_dirs, phase,
|
|||
plat.out_header(outfile)
|
||||
outfile.method(plat)
|
||||
plat.finish_output()
|
||||
return plat
|
||||
|
|
|
@ -116,6 +116,13 @@ class UclassDriver:
|
|||
e.g. 'pci_child_priv'
|
||||
per_child_plat (str): struct name of the per_child_plat_auto member,
|
||||
e.g. 'pci_child_plat'
|
||||
alias_num_to_node (dict): Aliases for this uclasses (for sequence
|
||||
numbers)
|
||||
key (int): Alias number, e.g. 2 for "pci2"
|
||||
value (str): Node the alias points to
|
||||
alias_path_to_num (dict): Convert a path to an alias number
|
||||
key (str): Full path to node (e.g. '/soc/pci')
|
||||
seq (int): Alias number, e.g. 2 for "pci2"
|
||||
"""
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
@ -125,6 +132,8 @@ class UclassDriver:
|
|||
self.per_dev_plat = ''
|
||||
self.per_child_priv = ''
|
||||
self.per_child_plat = ''
|
||||
self.alias_num_to_node = {}
|
||||
self.alias_path_to_num = {}
|
||||
|
||||
def __eq__(self, other):
|
||||
return (self.name == other.name and
|
||||
|
@ -622,7 +631,6 @@ class Scanner:
|
|||
self.scan_driver(pathname)
|
||||
elif fname.endswith('.h'):
|
||||
self.scan_header(pathname)
|
||||
|
||||
for fname in self._drivers_additional:
|
||||
if not isinstance(fname, str) or len(fname) == 0:
|
||||
continue
|
||||
|
@ -652,3 +660,25 @@ class Scanner:
|
|||
print("Warning: Duplicate driver name '%s' (orig=%s, dups=%s)" %
|
||||
(driver.name, driver.fname,
|
||||
', '.join([drv.fname for drv in driver.dups])))
|
||||
|
||||
def add_uclass_alias(self, name, num, node):
|
||||
"""Add an alias to a uclass
|
||||
|
||||
Args:
|
||||
name: Name of uclass, e.g. 'i2c'
|
||||
num: Alias number, e.g. 2 for alias 'i2c2'
|
||||
node: Node the alias points to, or None if None
|
||||
|
||||
Returns:
|
||||
True if the node was added
|
||||
False if the node was not added (uclass of that name not found)
|
||||
None if the node could not be added because it was None
|
||||
"""
|
||||
for uclass in self._uclass.values():
|
||||
if uclass.name == name:
|
||||
if node is None:
|
||||
return None
|
||||
uclass.alias_num_to_node[int(num)] = node
|
||||
uclass.alias_path_to_num[node.path] = int(num)
|
||||
return True
|
||||
return False
|
||||
|
|
58
tools/dtoc/test/dtoc_test_alias_bad.dts
Normal file
58
tools/dtoc/test/dtoc_test_alias_bad.dts
Normal file
|
@ -0,0 +1,58 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Test device tree file for dtoc
|
||||
*
|
||||
* Copyright 2017 Google, Inc
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
aliases {
|
||||
testbus2 = &bus2;
|
||||
testfdt1 = &testfdt_1;
|
||||
i2c4- = &i2c;
|
||||
};
|
||||
|
||||
spl-test {
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "sandbox,spl-test";
|
||||
boolval;
|
||||
intval = <1>;
|
||||
};
|
||||
|
||||
i2c: i2c {
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "sandbox,i2c";
|
||||
intval = <3>;
|
||||
};
|
||||
|
||||
spl-test3 {
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "sandbox,spl-test";
|
||||
stringarray = "one";
|
||||
longbytearray = [09 0a 0b 0c 0d 0e 0f 10];
|
||||
};
|
||||
|
||||
bus2: some-bus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "denx,u-boot-test-bus";
|
||||
reg = <3 1>;
|
||||
ping-expect = <4>;
|
||||
ping-add = <4>;
|
||||
testfdt_1: test {
|
||||
compatible = "denx,u-boot-fdt-test", "google,another-fdt-test";
|
||||
reg = <5>;
|
||||
ping-expect = <5>;
|
||||
ping-add = <5>;
|
||||
};
|
||||
|
||||
test0 {
|
||||
compatible = "google,another-fdt-test";
|
||||
};
|
||||
};
|
||||
};
|
58
tools/dtoc/test/dtoc_test_alias_bad_path.dts
Normal file
58
tools/dtoc/test/dtoc_test_alias_bad_path.dts
Normal file
|
@ -0,0 +1,58 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Test device tree file for dtoc
|
||||
*
|
||||
* Copyright 2017 Google, Inc
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
aliases {
|
||||
testbus2 = &bus2;
|
||||
testfdt1 = &testfdt_1;
|
||||
i2c4 = "/does/not/exist";
|
||||
};
|
||||
|
||||
spl-test {
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "sandbox,spl-test";
|
||||
boolval;
|
||||
intval = <1>;
|
||||
};
|
||||
|
||||
i2c: i2c {
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "sandbox,i2c";
|
||||
intval = <3>;
|
||||
};
|
||||
|
||||
spl-test3 {
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "sandbox,spl-test";
|
||||
stringarray = "one";
|
||||
longbytearray = [09 0a 0b 0c 0d 0e 0f 10];
|
||||
};
|
||||
|
||||
bus2: some-bus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "denx,u-boot-test-bus";
|
||||
reg = <3 1>;
|
||||
ping-expect = <4>;
|
||||
ping-add = <4>;
|
||||
testfdt_1: test {
|
||||
compatible = "denx,u-boot-fdt-test", "google,another-fdt-test";
|
||||
reg = <5>;
|
||||
ping-expect = <5>;
|
||||
ping-add = <5>;
|
||||
};
|
||||
|
||||
test0 {
|
||||
compatible = "google,another-fdt-test";
|
||||
};
|
||||
};
|
||||
};
|
58
tools/dtoc/test/dtoc_test_alias_bad_uc.dts
Normal file
58
tools/dtoc/test/dtoc_test_alias_bad_uc.dts
Normal file
|
@ -0,0 +1,58 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Test device tree file for dtoc
|
||||
*
|
||||
* Copyright 2017 Google, Inc
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
aliases {
|
||||
testbus2 = &bus2;
|
||||
testfdt1 = &testfdt_1;
|
||||
other1 = &testfdt_1;
|
||||
};
|
||||
|
||||
spl-test {
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "sandbox,spl-test";
|
||||
boolval;
|
||||
intval = <1>;
|
||||
};
|
||||
|
||||
i2c: i2c {
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "sandbox,i2c";
|
||||
intval = <3>;
|
||||
};
|
||||
|
||||
spl-test3 {
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "sandbox,spl-test";
|
||||
stringarray = "one";
|
||||
longbytearray = [09 0a 0b 0c 0d 0e 0f 10];
|
||||
};
|
||||
|
||||
bus2: some-bus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "denx,u-boot-test-bus";
|
||||
reg = <3 1>;
|
||||
ping-expect = <4>;
|
||||
ping-add = <4>;
|
||||
testfdt_1: test {
|
||||
compatible = "denx,u-boot-fdt-test", "google,another-fdt-test";
|
||||
reg = <5>;
|
||||
ping-expect = <5>;
|
||||
ping-add = <5>;
|
||||
};
|
||||
|
||||
test0 {
|
||||
compatible = "google,another-fdt-test";
|
||||
};
|
||||
};
|
||||
};
|
58
tools/dtoc/test/dtoc_test_inst.dts
Normal file
58
tools/dtoc/test/dtoc_test_inst.dts
Normal file
|
@ -0,0 +1,58 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Test device tree file for dtoc
|
||||
*
|
||||
* Copyright 2017 Google, Inc
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
aliases {
|
||||
testbus2 = &bus2;
|
||||
testfdt1 = &testfdt_1;
|
||||
i2c4 = &i2c;
|
||||
};
|
||||
|
||||
spl-test {
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "sandbox,spl-test";
|
||||
boolval;
|
||||
intval = <1>;
|
||||
};
|
||||
|
||||
i2c: i2c {
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "sandbox,i2c";
|
||||
intval = <3>;
|
||||
};
|
||||
|
||||
spl-test3 {
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "sandbox,spl-test";
|
||||
stringarray = "one";
|
||||
longbytearray = [09 0a 0b 0c 0d 0e 0f 10];
|
||||
};
|
||||
|
||||
bus2: some-bus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "denx,u-boot-test-bus";
|
||||
reg = <3 1>;
|
||||
ping-expect = <4>;
|
||||
ping-add = <4>;
|
||||
testfdt_1: test {
|
||||
compatible = "denx,u-boot-fdt-test", "google,another-fdt-test";
|
||||
reg = <5>;
|
||||
ping-expect = <5>;
|
||||
ping-add = <5>;
|
||||
};
|
||||
|
||||
test0 {
|
||||
compatible = "google,another-fdt-test";
|
||||
};
|
||||
};
|
||||
};
|
|
@ -137,9 +137,12 @@ class TestDtoc(unittest.TestCase):
|
|||
args (list of str): List of arguments for dtoc
|
||||
dtb_file (str): Filename of .dtb file
|
||||
output (str): Filename of output file
|
||||
|
||||
Returns:
|
||||
DtbPlatdata object
|
||||
"""
|
||||
dtb_platdata.run_steps(args, dtb_file, False, output, [], None,
|
||||
warning_disabled=True, scan=copy_scan())
|
||||
return dtb_platdata.run_steps(args, dtb_file, False, output, [], None,
|
||||
warning_disabled=True, scan=copy_scan())
|
||||
|
||||
def test_name(self):
|
||||
"""Test conversion of device tree names to C identifiers"""
|
||||
|
@ -1040,3 +1043,52 @@ U_BOOT_DRVINFO(spl_test2) = {
|
|||
|
||||
gpio = scan._drivers['sandbox_gpio']
|
||||
self.assertFalse(gpio.used)
|
||||
|
||||
def test_alias_read(self):
|
||||
"""Test obtaining aliases"""
|
||||
dtb_file = get_dtb_file('dtoc_test_inst.dts')
|
||||
output = tools.GetOutputFilename('output')
|
||||
plat = self.run_test(['struct'], dtb_file, output)
|
||||
|
||||
scan = plat._scan
|
||||
testfdt_node = plat._fdt.GetNode('/some-bus/test')
|
||||
self.assertIn('UCLASS_TEST_FDT', scan._uclass)
|
||||
uc = scan._uclass['UCLASS_TEST_FDT']
|
||||
self.assertEqual({1: testfdt_node}, uc.alias_num_to_node)
|
||||
self.assertEqual({'/some-bus/test': 1}, uc.alias_path_to_num)
|
||||
|
||||
# Try adding an alias that doesn't exist
|
||||
self.assertFalse(scan.add_uclass_alias('fred', 3, None))
|
||||
|
||||
# Try adding an alias for a missing node
|
||||
self.assertIsNone(scan.add_uclass_alias('testfdt', 3, None))
|
||||
|
||||
def test_alias_read_bad(self):
|
||||
"""Test invalid alias property name"""
|
||||
dtb_file = get_dtb_file('dtoc_test_alias_bad.dts')
|
||||
output = tools.GetOutputFilename('output')
|
||||
with self.assertRaises(ValueError) as exc:
|
||||
plat = self.run_test(['struct'], dtb_file, output)
|
||||
self.assertIn("Cannot decode alias 'i2c4-'", str(exc.exception))
|
||||
|
||||
def test_alias_read_bad_path(self):
|
||||
"""Test alias pointing to a non-existent node"""
|
||||
# This line may produce a warning, so capture it:
|
||||
# Warning (alias_paths): /aliases:i2c4: aliases property is not a valid
|
||||
# node (/does/not/exist)
|
||||
dtb_file = get_dtb_file('dtoc_test_alias_bad_path.dts', True)
|
||||
|
||||
output = tools.GetOutputFilename('output')
|
||||
with self.assertRaises(ValueError) as exc:
|
||||
plat = self.run_test(['struct'], dtb_file, output)
|
||||
self.assertIn("Alias 'i2c4' path '/does/not/exist' not found",
|
||||
str(exc.exception))
|
||||
|
||||
def test_alias_read_bad_uclass(self):
|
||||
"""Test alias for a uclass that doesn't exist"""
|
||||
dtb_file = get_dtb_file('dtoc_test_alias_bad_uc.dts')
|
||||
output = tools.GetOutputFilename('output')
|
||||
with test_util.capture_sys_output() as (stdout, _):
|
||||
plat = self.run_test(['struct'], dtb_file, output)
|
||||
self.assertEqual("Could not find uclass for alias 'other1'",
|
||||
stdout.getvalue().strip())
|
||||
|
|
Loading…
Add table
Reference in a new issue