Skip to content

Commit ee17657

Browse files
rruuaanngkartben
authored andcommitted
edtlib: binding: Add a title keyword
Add a 'title' keyword to the binding to provide a short description of the binding, while 'description' serves as the long description. Signed-off-by: James Roy <[email protected]>
1 parent b177591 commit ee17657

File tree

6 files changed

+86
-11
lines changed

6 files changed

+86
-11
lines changed

doc/_scripts/gen_devicetree_rest.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,14 @@ def print_binding_page(binding, base_names, vnd_lookup, driver_sources,dup_compa
580580
581581
{bus_help}
582582
''', string_io)
583-
print(to_code_block(binding.description.strip()), file=string_io)
583+
584+
if binding.title:
585+
description = ("\n\n"
586+
.join([binding.title, binding.description])
587+
.strip())
588+
else:
589+
description = binding.description.strip()
590+
print(to_code_block(description), file=string_io)
584591

585592
# Properties.
586593
print_block('''\

doc/build/dts/bindings-syntax.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ like this:
1919

2020
.. code-block:: yaml
2121
22+
# When the description text is too long, this field can
23+
# be used to improve readability, e.g.:
24+
#
25+
# title: Binding the device's hardware model.
26+
#
27+
# description |
28+
# A piece of content with 20 lines.
29+
# ...
30+
title: Concise title for the long description [optional]
31+
2232
# A high level description of the device the binding applies to:
2333
description: |
2434
This is the Vendomatic company's foo-device.
@@ -58,6 +68,14 @@ like this:
5868
5969
These keys are explained in the following sections.
6070

71+
.. _dt-bindings-title:
72+
73+
Title
74+
*****
75+
76+
Short description of the bound device, typically the hardware model.
77+
(It's optional.)
78+
6179
.. _dt-bindings-description:
6280

6381
Description

doc/build/dts/bindings-upstream.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ style:
8383

8484
.. code-block:: yaml
8585
86+
title: I'm sure you need a short title.
87+
8688
description: |
8789
My very long string
8890
goes here.

scripts/dts/python-devicetree/src/devicetree/edtlib.py

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,21 @@ class Binding:
114114
path:
115115
The absolute path to the file defining the binding.
116116
117+
title:
118+
The free-form title of the binding (optional).
119+
120+
When the content in the 'description:' is too long, the 'title:' can
121+
be used as a heading for the extended description. Typically, it serves
122+
as a description of the hardware model. For example:
123+
124+
title: Nordic GPIO
125+
126+
description: |
127+
Descriptions and example nodes related to GPIO.
128+
...
129+
117130
description:
118-
The free-form description of the binding, or None.
131+
The free-form description of the binding.
119132
120133
compatible:
121134
The compatible string the binding matches.
@@ -173,7 +186,7 @@ class Binding:
173186

174187
def __init__(self, path: Optional[str], fname2path: dict[str, str],
175188
raw: Any = None, require_compatible: bool = True,
176-
require_description: bool = True):
189+
require_description: bool = True, require_title: bool = False):
177190
"""
178191
Binding constructor.
179192
@@ -201,6 +214,12 @@ def __init__(self, path: Optional[str], fname2path: dict[str, str],
201214
"description:" line. If False, a missing "description:" is
202215
not an error. Either way, "description:" must be a string
203216
if it is present in the binding.
217+
218+
require_title:
219+
If True, it is an error if the binding does not contain a
220+
"title:" line. If False, a missing "title:" is not an error.
221+
Either way, "title:" must be a string if it is present in
222+
the binding.
204223
"""
205224
self.path: Optional[str] = path
206225
self._fname2path: dict[str, str] = fname2path
@@ -217,8 +236,8 @@ def __init__(self, path: Optional[str], fname2path: dict[str, str],
217236
self.raw: dict = self._merge_includes(raw, self.path)
218237

219238
# Recursively initialize any child bindings. These don't
220-
# require a 'compatible' or 'description' to be well defined,
221-
# but they must be dicts.
239+
# require a 'compatible', 'description' or 'title' to be well
240+
# defined, but they must be dicts.
222241
if "child-binding" in raw:
223242
if not isinstance(raw["child-binding"], dict):
224243
_err(f"malformed 'child-binding:' in {self.path}, "
@@ -232,7 +251,7 @@ def __init__(self, path: Optional[str], fname2path: dict[str, str],
232251
self.child_binding = None
233252

234253
# Make sure this is a well defined object.
235-
self._check(require_compatible, require_description)
254+
self._check(require_compatible, require_description, require_title)
236255

237256
# Initialize look up tables.
238257
self.prop2specs: dict[str, PropertySpec] = {}
@@ -251,6 +270,11 @@ def __repr__(self) -> str:
251270
basename = os.path.basename(self.path or "")
252271
return f"<Binding {basename}" + compat + ">"
253272

273+
@property
274+
def title(self) -> Optional[str]:
275+
"See the class docstring"
276+
return self.raw.get('title')
277+
254278
@property
255279
def description(self) -> Optional[str]:
256280
"See the class docstring"
@@ -364,7 +388,8 @@ def _load_raw(self, fname: str) -> dict:
364388

365389
return self._merge_includes(contents, path)
366390

367-
def _check(self, require_compatible: bool, require_description: bool):
391+
def _check(self, require_compatible: bool, require_description: bool,
392+
require_title: bool):
368393
# Does sanity checking on the binding.
369394

370395
raw = self.raw
@@ -378,6 +403,13 @@ def _check(self, require_compatible: bool, require_description: bool):
378403
elif require_compatible:
379404
_err(f"missing 'compatible' in {self.path}")
380405

406+
if "title" in raw:
407+
title = raw["title"]
408+
if not isinstance(title, str) or not title:
409+
_err(f"malformed or empty 'title' in {self.path}")
410+
elif require_title:
411+
_err(f"missing 'title' in {self.path}")
412+
381413
if "description" in raw:
382414
description = raw["description"]
383415
if not isinstance(description, str) or not description:
@@ -387,8 +419,8 @@ def _check(self, require_compatible: bool, require_description: bool):
387419

388420
# Allowed top-level keys. The 'include' key should have been
389421
# removed by _load_raw() already.
390-
ok_top = {"description", "compatible", "bus", "on-bus",
391-
"properties", "child-binding"}
422+
ok_top = {"title", "description", "compatible", "bus",
423+
"on-bus", "properties", "child-binding"}
392424

393425
# Descriptive errors for legacy bindings.
394426
legacy_errors = {
@@ -398,7 +430,6 @@ def _check(self, require_compatible: bool, require_description: bool):
398430
"parent": "use 'on-bus: <bus>' instead",
399431
"parent-bus": "use 'on-bus: <bus>' instead",
400432
"sub-node": "use 'child-binding' instead",
401-
"title": "use 'description' instead",
402433
}
403434

404435
for key in raw:
@@ -3328,7 +3359,8 @@ def _raw_default_property_for(
33283359
for name in _DEFAULT_PROP_TYPES
33293360
},
33303361
},
3331-
require_compatible=False, require_description=False,
3362+
require_compatible=False,
3363+
require_description=False,
33323364
)
33333365

33343366
_DEFAULT_PROP_SPECS: dict[str, PropertySpec] = {

scripts/dts/python-devicetree/tests/test-bindings/defaults.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# SPDX-License-Identifier: BSD-3-Clause
22

3+
title: Test binding
4+
35
description: Property default value test
46

57
compatible: "defaults"

scripts/dts/python-devicetree/tests/test_edtlib.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,20 @@ def test_bus():
531531
assert str(edt.get_node("/buses/foo-bus/node1/nested").binding_path) == \
532532
hpath("test-bindings/device-on-foo-bus.yaml")
533533

534+
def test_binding_top_key():
535+
fname2path = {'include.yaml': 'test-bindings-include/include.yaml',
536+
'include-2.yaml': 'test-bindings-include/include-2.yaml'}
537+
538+
with from_here():
539+
binding = edtlib.Binding("test-bindings/defaults.yaml", fname2path)
540+
title = binding.title
541+
description = binding.description
542+
compatible = binding.compatible
543+
544+
assert title == "Test binding"
545+
assert description == "Property default value test"
546+
assert compatible == "defaults"
547+
534548
def test_child_binding():
535549
'''Test 'child-binding:' in bindings'''
536550
with from_here():

0 commit comments

Comments
 (0)