summaryrefslogtreecommitdiff
path: root/scripts/dtc/treesource.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-02-11 18:27:08 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2026-02-11 18:27:08 -0800
commit098b6e44cbaa2d526d06af90c862d13fb414a0ec (patch)
tree2fb8ca29a59b2f60846bfaa3573c0e8aa55507a4 /scripts/dtc/treesource.c
parentc6e62d002b7f0613f02d8707c80f2a7bd66808a0 (diff)
parenta16f91f80735e653b88370b840d5c771f2c175c5 (diff)
Merge tag 'devicetree-for-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux
Pull devicetree updates from Rob Herring: "DT core: - Sync dtc/libfdt with upstream v1.7.2-62-ga26ef6400bd8 - Add a for_each_compatible_node_scoped() loop and convert users in cpufreq, dmaengine, clk, cdx, powerpc and Arm - Simplify of/platform.c with scoped loop helpers - Add fw_devlink tracking for "mmc-pwrseq" - Optimize fw_devlink callback code size for pinctrl-N properties - Replace strcmp_suffix() with strends() DT bindings: - Support building single binding targets - Convert google,goldfish-fb, cznic,turris-mox-rwtm, ti,prm-inst - Add bindings for Freescale AVIC, Realtek RTD1xxx system controllers, Microchip 25AA010A EEPROM, OnSemi FIN3385, IEI WT61P803 PUZZLE, Delta Electronics DPS-800-AB power supply, Infineon IR35221 Digital Multi-phase Controller, Infineon PXE1610 Digital Dual Output 6+1 VR12.5 & VR13 CPU Controller, socionext,uniphier-smpctrl, and xlnx,zynqmp-firmware - Lots of trivial binding fixes to address warnings in DTS files. These are mostly for arm64 platforms which is getting closer to be warning free. Some public shaming has helped. - Fix I2C bus node names in examples - Drop obsolete brcm,vulcan-soc binding - Drop unreferenced binding headers" * tag 'devicetree-for-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (60 commits) dt-bindings: interrupt-controller: Add compatiblie string fsl,imx(1|25|27|31|35)-avic dt-bindings: soc: imx: add fsl,aips and fsl,emi compatible strings dt-bindings: display: bridge: lt8912b: Drop reset gpio requirement dt-bindings: firmware: fsl,scu: Mark multi-channel MU layouts as deprecated cpufreq: s5pv210: Simplify with scoped for each OF child loop dmaengine: fsl_raid: Simplify with scoped for each OF child loop clk: imx: imx31: Simplify with scoped for each OF child loop clk: imx: imx27: Simplify with scoped for each OF child loop cdx: Use mutex guard to simplify error handling cdx: Simplify with scoped for each OF child loop powerpc/wii: Simplify with scoped for each OF child loop powerpc/fsp2: Simplify with scoped for each OF child loop ARM: exynos: Simplify with scoped for each OF child loop ARM: at91: Simplify with scoped for each OF child loop of: Add for_each_compatible_node_scoped() helper dt-bindings: Fix emails with spaces or missing brackets scripts/dtc: Update to upstream version v1.7.2-62-ga26ef6400bd8 dt-bindings: crypto: inside-secure,safexcel: Mandate only ring IRQs dt-bindings: crypto: inside-secure,safexcel: Add SoC compatibles of: reserved_mem: Fix placement of __free() annotation ...
Diffstat (limited to 'scripts/dtc/treesource.c')
-rw-r--r--scripts/dtc/treesource.c114
1 files changed, 83 insertions, 31 deletions
diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c
index d25f01fc6937..bf648bf6c21a 100644
--- a/scripts/dtc/treesource.c
+++ b/scripts/dtc/treesource.c
@@ -173,23 +173,59 @@ static struct marker **add_marker(struct marker **mi,
return &nm->next;
}
-static void add_string_markers(struct property *prop)
+void property_add_marker(struct property *prop,
+ enum markertype type, unsigned int offset, char *ref)
{
- int l, len = prop->val.len;
- const char *p = prop->val.val;
+ add_marker(&prop->val.markers, type, offset, ref);
+}
+
+static void add_string_markers(struct property *prop, unsigned int offset, int len)
+{
+ int l;
+ const char *p = prop->val.val + offset;
struct marker **mi = &prop->val.markers;
for (l = strlen(p) + 1; l < len; l += strlen(p + l) + 1)
- mi = add_marker(mi, TYPE_STRING, l, NULL);
+ mi = add_marker(mi, TYPE_STRING, offset + l, NULL);
+}
+
+void add_phandle_marker(struct dt_info *dti, struct property *prop, unsigned int offset)
+{
+ cell_t phandle;
+ struct node *refn;
+ char *ref;
+
+ if (prop->val.len < offset + 4) {
+ if (quiet < 1)
+ fprintf(stderr,
+ "Warning: property %s too short to contain a phandle at offset %u\n",
+ prop->name, offset);
+ return;
+ }
+
+ phandle = dtb_ld32(prop->val.val + offset);
+ refn = get_node_by_phandle(dti->dt, phandle);
+
+ if (!refn) {
+ if (quiet < 1)
+ fprintf(stderr,
+ "Warning: node referenced by phandle 0x%x in property %s not found\n",
+ phandle, prop->name);
+ return;
+ }
+
+ if (refn->labels)
+ ref = refn->labels->label;
+ else
+ ref = refn->fullpath;
+
+ add_marker(&prop->val.markers, REF_PHANDLE, offset, ref);
}
-static enum markertype guess_value_type(struct property *prop)
+static enum markertype guess_value_type(struct property *prop, unsigned int offset, int len)
{
- int len = prop->val.len;
- const char *p = prop->val.val;
- struct marker *m = prop->val.markers;
+ const char *p = prop->val.val + offset;
int nnotstring = 0, nnul = 0;
- int nnotstringlbl = 0, nnotcelllbl = 0;
int i;
for (i = 0; i < len; i++) {
@@ -199,30 +235,49 @@ static enum markertype guess_value_type(struct property *prop)
nnul++;
}
- for_each_marker_of_type(m, LABEL) {
- if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0'))
- nnotstringlbl++;
- if ((m->offset % sizeof(cell_t)) != 0)
- nnotcelllbl++;
- }
-
- if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul <= (len-nnul))
- && (nnotstringlbl == 0)) {
+ if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul <= len - nnul)) {
if (nnul > 1)
- add_string_markers(prop);
+ add_string_markers(prop, offset, len);
return TYPE_STRING;
- } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) {
+ } else if ((len % sizeof(cell_t)) == 0) {
return TYPE_UINT32;
}
return TYPE_UINT8;
}
+static void guess_type_markers(struct property *prop)
+{
+ struct marker **m = &prop->val.markers;
+ unsigned int offset = 0;
+
+ for (m = &prop->val.markers; *m; m = &((*m)->next)) {
+ if (is_type_marker((*m)->type))
+ /* assume the whole property is already marked */
+ return;
+
+ if ((*m)->offset > offset) {
+ m = add_marker(m, guess_value_type(prop, offset, (*m)->offset - offset),
+ offset, NULL);
+
+ offset = (*m)->offset;
+ }
+
+ if ((*m)->type == REF_PHANDLE) {
+ m = add_marker(m, TYPE_UINT32, offset, NULL);
+ offset += 4;
+ }
+ }
+
+ if (offset < prop->val.len)
+ add_marker(m, guess_value_type(prop, offset, prop->val.len - offset),
+ offset, NULL);
+}
+
static void write_propval(FILE *f, struct property *prop)
{
size_t len = prop->val.len;
- struct marker *m = prop->val.markers;
- struct marker dummy_marker;
+ struct marker *m;
enum markertype emit_type = TYPE_NONE;
char *srcstr;
@@ -241,14 +296,8 @@ static void write_propval(FILE *f, struct property *prop)
fprintf(f, " =");
- if (!next_type_marker(m)) {
- /* data type information missing, need to guess */
- dummy_marker.type = guess_value_type(prop);
- dummy_marker.next = prop->val.markers;
- dummy_marker.offset = 0;
- dummy_marker.ref = NULL;
- m = &dummy_marker;
- }
+ guess_type_markers(prop);
+ m = prop->val.markers;
for_each_marker(m) {
size_t chunk_len = (m->next ? m->next->offset : len) - m->offset;
@@ -369,7 +418,10 @@ void dt_to_source(FILE *f, struct dt_info *dti)
{
struct reserve_info *re;
- fprintf(f, "/dts-v1/;\n\n");
+ fprintf(f, "/dts-v1/;\n");
+ if (dti->dtsflags & DTSF_PLUGIN)
+ fprintf(f, "/plugin/;\n");
+ fprintf(f, "\n");
for (re = dti->reservelist; re; re = re->next) {
struct label *l;