diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-19 18:15:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-19 18:15:07 -0400 |
commit | 31e182363b39d84031eadf0caf6d99fd9eb056f0 (patch) | |
tree | 82dfe8293c9880ad521f67f3afc20a2fe55efddd | |
parent | 1200b6809dfd9d73bc4c7db76d288c35fa4b2ebe (diff) | |
parent | 5027e19db8cee24e189f8afa53b548e1ac5d0c1d (diff) |
Merge tag 'devicetree-for-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux
Pull DeviceTree updates from Rob Herring:
- new tool 'dtx_diff' to diff DT files
- sync kernel's dtc/libfdt to current dtc repo master
- fix for reserved memory regions located in highmem
- document standard unit suffixes for DT properties
- various DT binding doc updates
* tag 'devicetree-for-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux:
of: Add vendor prefix for eGalax_eMPIA Technology Inc
Input: ads7846: Add description how to use internal reference (ADS7846)
ARM: realview: add EB syscon variants to bindings
devicetree: bindings: ARM: Use "uV" for micro-volt
serial: fsl-imx-uart: Fix typo in fsl,dte-mode description
of: add 'const' for of_property_*_string*() parameter '*np'
of/unittest: fix infinite loop in of_unittest_destroy_tracked_overlays()
of: alloc anywhere from memblock if range not specified
kbuild: Allow using host dtc instead of kernel's copy
of: resolver: Add missing of_node_get and of_node_put
of: Add United Radiant Technology Corporation vendor prefix
dt/bindings: add documentation on standard property unit suffixes
scripts/dtc: Update to upstream commit b06e55c88b9b
ARM: boot: Add an implementation of strnlen for libfdt
scripts/dtc: dtx_diff - add info to error message
dtc: create tool to diff device trees
25 files changed, 827 insertions, 133 deletions
diff --git a/Documentation/devicetree/bindings/arm/arm-boards b/Documentation/devicetree/bindings/arm/arm-boards index 1a709970e7f7..100db7347747 100644 --- a/Documentation/devicetree/bindings/arm/arm-boards +++ b/Documentation/devicetree/bindings/arm/arm-boards | |||
@@ -123,7 +123,9 @@ Required nodes: | |||
123 | 123 | ||
124 | - syscon: some subnode of the RealView SoC node must be a | 124 | - syscon: some subnode of the RealView SoC node must be a |
125 | system controller node pointing to the control registers, | 125 | system controller node pointing to the control registers, |
126 | with the compatible string set to one of these tuples: | 126 | with the compatible string set to one of these: |
127 | "arm,realview-eb11mp-revb-syscon", "arm,realview-eb-syscon", "syscon" | ||
128 | "arm,realview-eb11mp-revc-syscon", "arm,realview-eb-syscon", "syscon" | ||
127 | "arm,realview-eb-syscon", "syscon" | 129 | "arm,realview-eb-syscon", "syscon" |
128 | "arm,realview-pb1176-syscon", "syscon" | 130 | "arm,realview-pb1176-syscon", "syscon" |
129 | "arm,realview-pb11mp-syscon", "syscon" | 131 | "arm,realview-pb11mp-syscon", "syscon" |
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index ae9be074d09f..afcf50f050ad 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt | |||
@@ -250,7 +250,7 @@ nodes to be present and contain the properties described below. | |||
250 | Usage: optional | 250 | Usage: optional |
251 | Value type: <prop-encoded-array> | 251 | Value type: <prop-encoded-array> |
252 | Definition: A u32 value that represents the running time dynamic | 252 | Definition: A u32 value that represents the running time dynamic |
253 | power coefficient in units of mW/MHz/uVolt^2. The | 253 | power coefficient in units of mW/MHz/uV^2. The |
254 | coefficient can either be calculated from power | 254 | coefficient can either be calculated from power |
255 | measurements or derived by analysis. | 255 | measurements or derived by analysis. |
256 | 256 | ||
diff --git a/Documentation/devicetree/bindings/input/ads7846.txt b/Documentation/devicetree/bindings/input/ads7846.txt index 33a1638b61d6..c6cfe2e3ed41 100644 --- a/Documentation/devicetree/bindings/input/ads7846.txt +++ b/Documentation/devicetree/bindings/input/ads7846.txt | |||
@@ -29,6 +29,8 @@ Optional properties: | |||
29 | ti,vref-delay-usecs vref supply delay in usecs, 0 for | 29 | ti,vref-delay-usecs vref supply delay in usecs, 0 for |
30 | external vref (u16). | 30 | external vref (u16). |
31 | ti,vref-mv The VREF voltage, in millivolts (u16). | 31 | ti,vref-mv The VREF voltage, in millivolts (u16). |
32 | Set to 0 to use internal refernce | ||
33 | (ADS7846). | ||
32 | ti,keep-vref-on set to keep vref on for differential | 34 | ti,keep-vref-on set to keep vref on for differential |
33 | measurements as well | 35 | measurements as well |
34 | ti,swap-xy swap x and y axis | 36 | ti,swap-xy swap x and y axis |
diff --git a/Documentation/devicetree/bindings/property-units.txt b/Documentation/devicetree/bindings/property-units.txt new file mode 100644 index 000000000000..12278d79f6c0 --- /dev/null +++ b/Documentation/devicetree/bindings/property-units.txt | |||
@@ -0,0 +1,39 @@ | |||
1 | Standard Unit Suffixes for Property names | ||
2 | |||
3 | Properties which have a unit of measure are recommended to have a unit | ||
4 | suffix appended to the property name. The list below contains the | ||
5 | recommended suffixes. Other variations exist in bindings, but should not | ||
6 | be used in new bindings or added here. The inconsistency in the unit | ||
7 | prefixes is due to selecting the most commonly used variants. | ||
8 | |||
9 | It is also recommended to use the units listed here and not add additional | ||
10 | unit prefixes. | ||
11 | |||
12 | Time/Frequency | ||
13 | ---------------------------------------- | ||
14 | -mhz : megahertz | ||
15 | -hz : Hertz (preferred) | ||
16 | -sec : seconds | ||
17 | -ms : milliseconds | ||
18 | -us : microseconds | ||
19 | -ns : nanoseconds | ||
20 | |||
21 | Distance | ||
22 | ---------------------------------------- | ||
23 | -mm : millimeters | ||
24 | |||
25 | Electricity | ||
26 | ---------------------------------------- | ||
27 | -microamp : micro amps | ||
28 | -ohms : Ohms | ||
29 | -micro-ohms : micro Ohms | ||
30 | -microvolt : micro volts | ||
31 | |||
32 | Temperature | ||
33 | ---------------------------------------- | ||
34 | -celsius : Degrees Celsius | ||
35 | -millicelsius : Degreee milli-Celsius | ||
36 | |||
37 | Pressure | ||
38 | ---------------------------------------- | ||
39 | -kpascal : kiloPascal | ||
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 156731cc649c..787d4225c8ab 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt | |||
@@ -72,6 +72,7 @@ dmo Data Modul AG | |||
72 | ea Embedded Artists AB | 72 | ea Embedded Artists AB |
73 | ebv EBV Elektronik | 73 | ebv EBV Elektronik |
74 | edt Emerging Display Technologies | 74 | edt Emerging Display Technologies |
75 | eeti eGalax_eMPIA Technology Inc | ||
75 | elan Elan Microelectronic Corp. | 76 | elan Elan Microelectronic Corp. |
76 | emmicro EM Microelectronic | 77 | emmicro EM Microelectronic |
77 | energymicro Silicon Laboratories (formerly Energy Micro AS) | 78 | energymicro Silicon Laboratories (formerly Energy Micro AS) |
@@ -247,6 +248,7 @@ tplink TP-LINK Technologies Co., Ltd. | |||
247 | tronfy Tronfy | 248 | tronfy Tronfy |
248 | truly Truly Semiconductors Limited | 249 | truly Truly Semiconductors Limited |
249 | upisemi uPI Semiconductor Corp. | 250 | upisemi uPI Semiconductor Corp. |
251 | urt United Radiant Technology Corporation | ||
250 | usi Universal Scientific Industrial Co., Ltd. | 252 | usi Universal Scientific Industrial Co., Ltd. |
251 | v3 V3 Semiconductor | 253 | v3 V3 Semiconductor |
252 | variscite Variscite Ltd. | 254 | variscite Variscite Ltd. |
diff --git a/arch/arm/boot/compressed/string.c b/arch/arm/boot/compressed/string.c index 36e53ef9200f..689467448736 100644 --- a/arch/arm/boot/compressed/string.c +++ b/arch/arm/boot/compressed/string.c | |||
@@ -65,6 +65,15 @@ size_t strlen(const char *s) | |||
65 | return sc - s; | 65 | return sc - s; |
66 | } | 66 | } |
67 | 67 | ||
68 | size_t strnlen(const char *s, size_t count) | ||
69 | { | ||
70 | const char *sc; | ||
71 | |||
72 | for (sc = s; count-- && *sc != '\0'; ++sc) | ||
73 | /* nothing */; | ||
74 | return sc - s; | ||
75 | } | ||
76 | |||
68 | int memcmp(const void *cs, const void *ct, size_t count) | 77 | int memcmp(const void *cs, const void *ct, size_t count) |
69 | { | 78 | { |
70 | const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count; | 79 | const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count; |
diff --git a/drivers/of/base.c b/drivers/of/base.c index 017dd94f16ea..b299de2b3afa 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -1341,10 +1341,10 @@ EXPORT_SYMBOL_GPL(of_property_read_u64_array); | |||
1341 | * | 1341 | * |
1342 | * The out_string pointer is modified only if a valid string can be decoded. | 1342 | * The out_string pointer is modified only if a valid string can be decoded. |
1343 | */ | 1343 | */ |
1344 | int of_property_read_string(struct device_node *np, const char *propname, | 1344 | int of_property_read_string(const struct device_node *np, const char *propname, |
1345 | const char **out_string) | 1345 | const char **out_string) |
1346 | { | 1346 | { |
1347 | struct property *prop = of_find_property(np, propname, NULL); | 1347 | const struct property *prop = of_find_property(np, propname, NULL); |
1348 | if (!prop) | 1348 | if (!prop) |
1349 | return -EINVAL; | 1349 | return -EINVAL; |
1350 | if (!prop->value) | 1350 | if (!prop->value) |
@@ -1365,10 +1365,10 @@ EXPORT_SYMBOL_GPL(of_property_read_string); | |||
1365 | * This function searches a string list property and returns the index | 1365 | * This function searches a string list property and returns the index |
1366 | * of a specific string value. | 1366 | * of a specific string value. |
1367 | */ | 1367 | */ |
1368 | int of_property_match_string(struct device_node *np, const char *propname, | 1368 | int of_property_match_string(const struct device_node *np, const char *propname, |
1369 | const char *string) | 1369 | const char *string) |
1370 | { | 1370 | { |
1371 | struct property *prop = of_find_property(np, propname, NULL); | 1371 | const struct property *prop = of_find_property(np, propname, NULL); |
1372 | size_t l; | 1372 | size_t l; |
1373 | int i; | 1373 | int i; |
1374 | const char *p, *end; | 1374 | const char *p, *end; |
@@ -1404,10 +1404,11 @@ EXPORT_SYMBOL_GPL(of_property_match_string); | |||
1404 | * Don't call this function directly. It is a utility helper for the | 1404 | * Don't call this function directly. It is a utility helper for the |
1405 | * of_property_read_string*() family of functions. | 1405 | * of_property_read_string*() family of functions. |
1406 | */ | 1406 | */ |
1407 | int of_property_read_string_helper(struct device_node *np, const char *propname, | 1407 | int of_property_read_string_helper(const struct device_node *np, |
1408 | const char **out_strs, size_t sz, int skip) | 1408 | const char *propname, const char **out_strs, |
1409 | size_t sz, int skip) | ||
1409 | { | 1410 | { |
1410 | struct property *prop = of_find_property(np, propname, NULL); | 1411 | const struct property *prop = of_find_property(np, propname, NULL); |
1411 | int l = 0, i = 0; | 1412 | int l = 0, i = 0; |
1412 | const char *p, *end; | 1413 | const char *p, *end; |
1413 | 1414 | ||
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index 1a3556a9e9ea..ed01c0172e4a 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c | |||
@@ -32,11 +32,13 @@ int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size, | |||
32 | phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap, | 32 | phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap, |
33 | phys_addr_t *res_base) | 33 | phys_addr_t *res_base) |
34 | { | 34 | { |
35 | phys_addr_t base; | ||
35 | /* | 36 | /* |
36 | * We use __memblock_alloc_base() because memblock_alloc_base() | 37 | * We use __memblock_alloc_base() because memblock_alloc_base() |
37 | * panic()s on allocation failure. | 38 | * panic()s on allocation failure. |
38 | */ | 39 | */ |
39 | phys_addr_t base = __memblock_alloc_base(size, align, end); | 40 | end = !end ? MEMBLOCK_ALLOC_ANYWHERE : end; |
41 | base = __memblock_alloc_base(size, align, end); | ||
40 | if (!base) | 42 | if (!base) |
41 | return -ENOMEM; | 43 | return -ENOMEM; |
42 | 44 | ||
diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index 640eb4cb46e3..d313d492f278 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c | |||
@@ -36,12 +36,14 @@ static struct device_node *__of_find_node_by_full_name(struct device_node *node, | |||
36 | 36 | ||
37 | /* check */ | 37 | /* check */ |
38 | if (of_node_cmp(node->full_name, full_name) == 0) | 38 | if (of_node_cmp(node->full_name, full_name) == 0) |
39 | return node; | 39 | return of_node_get(node); |
40 | 40 | ||
41 | for_each_child_of_node(node, child) { | 41 | for_each_child_of_node(node, child) { |
42 | found = __of_find_node_by_full_name(child, full_name); | 42 | found = __of_find_node_by_full_name(child, full_name); |
43 | if (found != NULL) | 43 | if (found != NULL) { |
44 | of_node_put(child); | ||
44 | return found; | 45 | return found; |
46 | } | ||
45 | } | 47 | } |
46 | 48 | ||
47 | return NULL; | 49 | return NULL; |
@@ -174,6 +176,7 @@ static int __of_adjust_phandle_ref(struct device_node *node, | |||
174 | if (of_prop_cmp(sprop->name, propstr) == 0) | 176 | if (of_prop_cmp(sprop->name, propstr) == 0) |
175 | break; | 177 | break; |
176 | } | 178 | } |
179 | of_node_put(refnode); | ||
177 | 180 | ||
178 | if (!sprop) { | 181 | if (!sprop) { |
179 | pr_err("%s: Could not find property '%s'\n", | 182 | pr_err("%s: Could not find property '%s'\n", |
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 979b6e415cea..e986e6ee52e0 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c | |||
@@ -1165,6 +1165,11 @@ static void of_unittest_destroy_tracked_overlays(void) | |||
1165 | continue; | 1165 | continue; |
1166 | 1166 | ||
1167 | ret = of_overlay_destroy(id + overlay_first_id); | 1167 | ret = of_overlay_destroy(id + overlay_first_id); |
1168 | if (ret == -ENODEV) { | ||
1169 | pr_warn("%s: no overlay to destroy for #%d\n", | ||
1170 | __func__, id + overlay_first_id); | ||
1171 | continue; | ||
1172 | } | ||
1168 | if (ret != 0) { | 1173 | if (ret != 0) { |
1169 | defers++; | 1174 | defers++; |
1170 | pr_warn("%s: overlay destroy failed for #%d\n", | 1175 | pr_warn("%s: overlay destroy failed for #%d\n", |
diff --git a/include/linux/of.h b/include/linux/of.h index dc6e39696b64..7fcb681baadf 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
@@ -296,13 +296,13 @@ extern int of_property_read_u64_array(const struct device_node *np, | |||
296 | u64 *out_values, | 296 | u64 *out_values, |
297 | size_t sz); | 297 | size_t sz); |
298 | 298 | ||
299 | extern int of_property_read_string(struct device_node *np, | 299 | extern int of_property_read_string(const struct device_node *np, |
300 | const char *propname, | 300 | const char *propname, |
301 | const char **out_string); | 301 | const char **out_string); |
302 | extern int of_property_match_string(struct device_node *np, | 302 | extern int of_property_match_string(const struct device_node *np, |
303 | const char *propname, | 303 | const char *propname, |
304 | const char *string); | 304 | const char *string); |
305 | extern int of_property_read_string_helper(struct device_node *np, | 305 | extern int of_property_read_string_helper(const struct device_node *np, |
306 | const char *propname, | 306 | const char *propname, |
307 | const char **out_strs, size_t sz, int index); | 307 | const char **out_strs, size_t sz, int index); |
308 | extern int of_device_is_compatible(const struct device_node *device, | 308 | extern int of_device_is_compatible(const struct device_node *device, |
@@ -538,14 +538,14 @@ static inline int of_property_read_u64_array(const struct device_node *np, | |||
538 | return -ENOSYS; | 538 | return -ENOSYS; |
539 | } | 539 | } |
540 | 540 | ||
541 | static inline int of_property_read_string(struct device_node *np, | 541 | static inline int of_property_read_string(const struct device_node *np, |
542 | const char *propname, | 542 | const char *propname, |
543 | const char **out_string) | 543 | const char **out_string) |
544 | { | 544 | { |
545 | return -ENOSYS; | 545 | return -ENOSYS; |
546 | } | 546 | } |
547 | 547 | ||
548 | static inline int of_property_read_string_helper(struct device_node *np, | 548 | static inline int of_property_read_string_helper(const struct device_node *np, |
549 | const char *propname, | 549 | const char *propname, |
550 | const char **out_strs, size_t sz, int index) | 550 | const char **out_strs, size_t sz, int index) |
551 | { | 551 | { |
@@ -571,7 +571,7 @@ static inline int of_property_read_u64(const struct device_node *np, | |||
571 | return -ENOSYS; | 571 | return -ENOSYS; |
572 | } | 572 | } |
573 | 573 | ||
574 | static inline int of_property_match_string(struct device_node *np, | 574 | static inline int of_property_match_string(const struct device_node *np, |
575 | const char *propname, | 575 | const char *propname, |
576 | const char *string) | 576 | const char *string) |
577 | { | 577 | { |
@@ -773,7 +773,7 @@ static inline int of_property_count_u64_elems(const struct device_node *np, | |||
773 | * | 773 | * |
774 | * If @out_strs is NULL, the number of strings in the property is returned. | 774 | * If @out_strs is NULL, the number of strings in the property is returned. |
775 | */ | 775 | */ |
776 | static inline int of_property_read_string_array(struct device_node *np, | 776 | static inline int of_property_read_string_array(const struct device_node *np, |
777 | const char *propname, const char **out_strs, | 777 | const char *propname, const char **out_strs, |
778 | size_t sz) | 778 | size_t sz) |
779 | { | 779 | { |
@@ -792,7 +792,7 @@ static inline int of_property_read_string_array(struct device_node *np, | |||
792 | * does not have a value, and -EILSEQ if the string is not null-terminated | 792 | * does not have a value, and -EILSEQ if the string is not null-terminated |
793 | * within the length of the property data. | 793 | * within the length of the property data. |
794 | */ | 794 | */ |
795 | static inline int of_property_count_strings(struct device_node *np, | 795 | static inline int of_property_count_strings(const struct device_node *np, |
796 | const char *propname) | 796 | const char *propname) |
797 | { | 797 | { |
798 | return of_property_read_string_helper(np, propname, NULL, 0, 0); | 798 | return of_property_read_string_helper(np, propname, NULL, 0, 0); |
@@ -816,7 +816,7 @@ static inline int of_property_count_strings(struct device_node *np, | |||
816 | * | 816 | * |
817 | * The out_string pointer is modified only if a valid string can be decoded. | 817 | * The out_string pointer is modified only if a valid string can be decoded. |
818 | */ | 818 | */ |
819 | static inline int of_property_read_string_index(struct device_node *np, | 819 | static inline int of_property_read_string_index(const struct device_node *np, |
820 | const char *propname, | 820 | const char *propname, |
821 | int index, const char **output) | 821 | int index, const char **output) |
822 | { | 822 | { |
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 2edbcadb3d7f..ad50d5859ac4 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib | |||
@@ -269,6 +269,7 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \ | |||
269 | 269 | ||
270 | # DTC | 270 | # DTC |
271 | # --------------------------------------------------------------------------- | 271 | # --------------------------------------------------------------------------- |
272 | DTC ?= $(objtree)/scripts/dtc/dtc | ||
272 | 273 | ||
273 | # Generate an assembly file to wrap the output of the device tree compiler | 274 | # Generate an assembly file to wrap the output of the device tree compiler |
274 | quiet_cmd_dt_S_dtb= DTB $@ | 275 | quiet_cmd_dt_S_dtb= DTB $@ |
@@ -291,7 +292,7 @@ $(obj)/%.dtb.S: $(obj)/%.dtb | |||
291 | quiet_cmd_dtc = DTC $@ | 292 | quiet_cmd_dtc = DTC $@ |
292 | cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ | 293 | cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ |
293 | $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ | 294 | $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ |
294 | $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \ | 295 | $(DTC) -O dtb -o $@ -b 0 \ |
295 | -i $(dir $<) $(DTC_FLAGS) \ | 296 | -i $(dir $<) $(DTC_FLAGS) \ |
296 | -d $(depfile).dtc.tmp $(dtc-tmp) ; \ | 297 | -d $(depfile).dtc.tmp $(dtc-tmp) ; \ |
297 | cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) | 298 | cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) |
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c index e81a8c74b8d2..0c03ac9159c1 100644 --- a/scripts/dtc/checks.c +++ b/scripts/dtc/checks.c | |||
@@ -560,7 +560,7 @@ static void check_reg_format(struct check *c, struct node *dt, | |||
560 | size_cells = node_size_cells(node->parent); | 560 | size_cells = node_size_cells(node->parent); |
561 | entrylen = (addr_cells + size_cells) * sizeof(cell_t); | 561 | entrylen = (addr_cells + size_cells) * sizeof(cell_t); |
562 | 562 | ||
563 | if ((prop->val.len % entrylen) != 0) | 563 | if (!entrylen || (prop->val.len % entrylen) != 0) |
564 | FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) " | 564 | FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) " |
565 | "(#address-cells == %d, #size-cells == %d)", | 565 | "(#address-cells == %d, #size-cells == %d)", |
566 | node->fullpath, prop->val.len, addr_cells, size_cells); | 566 | node->fullpath, prop->val.len, addr_cells, size_cells); |
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l index 0ee1caf03dd0..790fbf6cf2d7 100644 --- a/scripts/dtc/dtc-lexer.l +++ b/scripts/dtc/dtc-lexer.l | |||
@@ -73,24 +73,32 @@ static void lexical_error(const char *fmt, ...); | |||
73 | } | 73 | } |
74 | 74 | ||
75 | <*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? { | 75 | <*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? { |
76 | char *line, *tmp, *fn; | 76 | char *line, *fnstart, *fnend; |
77 | struct data fn; | ||
77 | /* skip text before line # */ | 78 | /* skip text before line # */ |
78 | line = yytext; | 79 | line = yytext; |
79 | while (!isdigit((unsigned char)*line)) | 80 | while (!isdigit((unsigned char)*line)) |
80 | line++; | 81 | line++; |
81 | /* skip digits in line # */ | 82 | |
82 | tmp = line; | 83 | /* regexp ensures that first and list " |
83 | while (!isspace((unsigned char)*tmp)) | 84 | * in the whole yytext are those at |
84 | tmp++; | 85 | * beginning and end of the filename string */ |
85 | /* "NULL"-terminate line # */ | 86 | fnstart = memchr(yytext, '"', yyleng); |
86 | *tmp = '\0'; | 87 | for (fnend = yytext + yyleng - 1; |
87 | /* start of filename */ | 88 | *fnend != '"'; fnend--) |
88 | fn = strchr(tmp + 1, '"') + 1; | 89 | ; |
89 | /* strip trailing " from filename */ | 90 | assert(fnstart && fnend && (fnend > fnstart)); |
90 | tmp = strchr(fn, '"'); | 91 | |
91 | *tmp = 0; | 92 | fn = data_copy_escape_string(fnstart + 1, |
93 | fnend - fnstart - 1); | ||
94 | |||
95 | /* Don't allow nuls in filenames */ | ||
96 | if (memchr(fn.val, '\0', fn.len - 1)) | ||
97 | lexical_error("nul in line number directive"); | ||
98 | |||
92 | /* -1 since #line is the number of the next line */ | 99 | /* -1 since #line is the number of the next line */ |
93 | srcpos_set_line(xstrdup(fn), atoi(line) - 1); | 100 | srcpos_set_line(xstrdup(fn.val), atoi(line) - 1); |
101 | data_free(fn); | ||
94 | } | 102 | } |
95 | 103 | ||
96 | <*><<EOF>> { | 104 | <*><<EOF>> { |
@@ -153,7 +161,10 @@ static void lexical_error(const char *fmt, ...); | |||
153 | errno = 0; | 161 | errno = 0; |
154 | yylval.integer = strtoull(yytext, &e, 0); | 162 | yylval.integer = strtoull(yytext, &e, 0); |
155 | 163 | ||
156 | assert(!(*e) || !e[strspn(e, "UL")]); | 164 | if (*e && e[strspn(e, "UL")]) { |
165 | lexical_error("Bad integer literal '%s'", | ||
166 | yytext); | ||
167 | } | ||
157 | 168 | ||
158 | if (errno == ERANGE) | 169 | if (errno == ERANGE) |
159 | lexical_error("Integer literal '%s' out of range", | 170 | lexical_error("Integer literal '%s' out of range", |
diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped index 11cd78e72305..ba525c2f9fc2 100644 --- a/scripts/dtc/dtc-lexer.lex.c_shipped +++ b/scripts/dtc/dtc-lexer.lex.c_shipped | |||
@@ -951,31 +951,39 @@ case 2: | |||
951 | YY_RULE_SETUP | 951 | YY_RULE_SETUP |
952 | #line 75 "dtc-lexer.l" | 952 | #line 75 "dtc-lexer.l" |
953 | { | 953 | { |
954 | char *line, *tmp, *fn; | 954 | char *line, *fnstart, *fnend; |
955 | struct data fn; | ||
955 | /* skip text before line # */ | 956 | /* skip text before line # */ |
956 | line = yytext; | 957 | line = yytext; |
957 | while (!isdigit((unsigned char)*line)) | 958 | while (!isdigit((unsigned char)*line)) |
958 | line++; | 959 | line++; |
959 | /* skip digits in line # */ | 960 | |
960 | tmp = line; | 961 | /* regexp ensures that first and list " |
961 | while (!isspace((unsigned char)*tmp)) | 962 | * in the whole yytext are those at |
962 | tmp++; | 963 | * beginning and end of the filename string */ |
963 | /* "NULL"-terminate line # */ | 964 | fnstart = memchr(yytext, '"', yyleng); |
964 | *tmp = '\0'; | 965 | for (fnend = yytext + yyleng - 1; |
965 | /* start of filename */ | 966 | *fnend != '"'; fnend--) |
966 | fn = strchr(tmp + 1, '"') + 1; | 967 | ; |
967 | /* strip trailing " from filename */ | 968 | assert(fnstart && fnend && (fnend > fnstart)); |
968 | tmp = strchr(fn, '"'); | 969 | |
969 | *tmp = 0; | 970 | fn = data_copy_escape_string(fnstart + 1, |
971 | fnend - fnstart - 1); | ||
972 | |||
973 | /* Don't allow nuls in filenames */ | ||
974 | if (memchr(fn.val, '\0', fn.len - 1)) | ||
975 | lexical_error("nul in line number directive"); | ||
976 | |||
970 | /* -1 since #line is the number of the next line */ | 977 | /* -1 since #line is the number of the next line */ |
971 | srcpos_set_line(xstrdup(fn), atoi(line) - 1); | 978 | srcpos_set_line(xstrdup(fn.val), atoi(line) - 1); |
979 | data_free(fn); | ||
972 | } | 980 | } |
973 | YY_BREAK | 981 | YY_BREAK |
974 | case YY_STATE_EOF(INITIAL): | 982 | case YY_STATE_EOF(INITIAL): |
975 | case YY_STATE_EOF(BYTESTRING): | 983 | case YY_STATE_EOF(BYTESTRING): |
976 | case YY_STATE_EOF(PROPNODENAME): | 984 | case YY_STATE_EOF(PROPNODENAME): |
977 | case YY_STATE_EOF(V1): | 985 | case YY_STATE_EOF(V1): |
978 | #line 96 "dtc-lexer.l" | 986 | #line 104 "dtc-lexer.l" |
979 | { | 987 | { |
980 | if (!pop_input_file()) { | 988 | if (!pop_input_file()) { |
981 | yyterminate(); | 989 | yyterminate(); |
@@ -985,7 +993,7 @@ case YY_STATE_EOF(V1): | |||
985 | case 3: | 993 | case 3: |
986 | /* rule 3 can match eol */ | 994 | /* rule 3 can match eol */ |
987 | YY_RULE_SETUP | 995 | YY_RULE_SETUP |
988 | #line 102 "dtc-lexer.l" | 996 | #line 110 "dtc-lexer.l" |
989 | { | 997 | { |
990 | DPRINT("String: %s\n", yytext); | 998 | DPRINT("String: %s\n", yytext); |
991 | yylval.data = data_copy_escape_string(yytext+1, | 999 | yylval.data = data_copy_escape_string(yytext+1, |
@@ -995,7 +1003,7 @@ YY_RULE_SETUP | |||
995 | YY_BREAK | 1003 | YY_BREAK |
996 | case 4: | 1004 | case 4: |
997 | YY_RULE_SETUP | 1005 | YY_RULE_SETUP |
998 | #line 109 "dtc-lexer.l" | 1006 | #line 117 "dtc-lexer.l" |
999 | { | 1007 | { |
1000 | DPRINT("Keyword: /dts-v1/\n"); | 1008 | DPRINT("Keyword: /dts-v1/\n"); |
1001 | dts_version = 1; | 1009 | dts_version = 1; |
@@ -1005,7 +1013,7 @@ YY_RULE_SETUP | |||
1005 | YY_BREAK | 1013 | YY_BREAK |
1006 | case 5: | 1014 | case 5: |
1007 | YY_RULE_SETUP | 1015 | YY_RULE_SETUP |
1008 | #line 116 "dtc-lexer.l" | 1016 | #line 124 "dtc-lexer.l" |
1009 | { | 1017 | { |
1010 | DPRINT("Keyword: /memreserve/\n"); | 1018 | DPRINT("Keyword: /memreserve/\n"); |
1011 | BEGIN_DEFAULT(); | 1019 | BEGIN_DEFAULT(); |
@@ -1014,7 +1022,7 @@ YY_RULE_SETUP | |||
1014 | YY_BREAK | 1022 | YY_BREAK |
1015 | case 6: | 1023 | case 6: |
1016 | YY_RULE_SETUP | 1024 | YY_RULE_SETUP |
1017 | #line 122 "dtc-lexer.l" | 1025 | #line 130 "dtc-lexer.l" |
1018 | { | 1026 | { |
1019 | DPRINT("Keyword: /bits/\n"); | 1027 | DPRINT("Keyword: /bits/\n"); |
1020 | BEGIN_DEFAULT(); | 1028 | BEGIN_DEFAULT(); |
@@ -1023,7 +1031,7 @@ YY_RULE_SETUP | |||
1023 | YY_BREAK | 1031 | YY_BREAK |
1024 | case 7: | 1032 | case 7: |
1025 | YY_RULE_SETUP | 1033 | YY_RULE_SETUP |
1026 | #line 128 "dtc-lexer.l" | 1034 | #line 136 "dtc-lexer.l" |
1027 | { | 1035 | { |
1028 | DPRINT("Keyword: /delete-property/\n"); | 1036 | DPRINT("Keyword: /delete-property/\n"); |
1029 | DPRINT("<PROPNODENAME>\n"); | 1037 | DPRINT("<PROPNODENAME>\n"); |
@@ -1033,7 +1041,7 @@ YY_RULE_SETUP | |||
1033 | YY_BREAK | 1041 | YY_BREAK |
1034 | case 8: | 1042 | case 8: |
1035 | YY_RULE_SETUP | 1043 | YY_RULE_SETUP |
1036 | #line 135 "dtc-lexer.l" | 1044 | #line 143 "dtc-lexer.l" |
1037 | { | 1045 | { |
1038 | DPRINT("Keyword: /delete-node/\n"); | 1046 | DPRINT("Keyword: /delete-node/\n"); |
1039 | DPRINT("<PROPNODENAME>\n"); | 1047 | DPRINT("<PROPNODENAME>\n"); |
@@ -1043,7 +1051,7 @@ YY_RULE_SETUP | |||
1043 | YY_BREAK | 1051 | YY_BREAK |
1044 | case 9: | 1052 | case 9: |
1045 | YY_RULE_SETUP | 1053 | YY_RULE_SETUP |
1046 | #line 142 "dtc-lexer.l" | 1054 | #line 150 "dtc-lexer.l" |
1047 | { | 1055 | { |
1048 | DPRINT("Label: %s\n", yytext); | 1056 | DPRINT("Label: %s\n", yytext); |
1049 | yylval.labelref = xstrdup(yytext); | 1057 | yylval.labelref = xstrdup(yytext); |
@@ -1053,7 +1061,7 @@ YY_RULE_SETUP | |||
1053 | YY_BREAK | 1061 | YY_BREAK |
1054 | case 10: | 1062 | case 10: |
1055 | YY_RULE_SETUP | 1063 | YY_RULE_SETUP |
1056 | #line 149 "dtc-lexer.l" | 1064 | #line 157 "dtc-lexer.l" |
1057 | { | 1065 | { |
1058 | char *e; | 1066 | char *e; |
1059 | DPRINT("Integer Literal: '%s'\n", yytext); | 1067 | DPRINT("Integer Literal: '%s'\n", yytext); |
@@ -1061,7 +1069,10 @@ YY_RULE_SETUP | |||
1061 | errno = 0; | 1069 | errno = 0; |
1062 | yylval.integer = strtoull(yytext, &e, 0); | 1070 | yylval.integer = strtoull(yytext, &e, 0); |
1063 | 1071 | ||
1064 | assert(!(*e) || !e[strspn(e, "UL")]); | 1072 | if (*e && e[strspn(e, "UL")]) { |
1073 | lexical_error("Bad integer literal '%s'", | ||
1074 | yytext); | ||
1075 | } | ||
1065 | 1076 | ||
1066 | if (errno == ERANGE) | 1077 | if (errno == ERANGE) |
1067 | lexical_error("Integer literal '%s' out of range", | 1078 | lexical_error("Integer literal '%s' out of range", |
@@ -1076,7 +1087,7 @@ YY_RULE_SETUP | |||
1076 | case 11: | 1087 | case 11: |
1077 | /* rule 11 can match eol */ | 1088 | /* rule 11 can match eol */ |
1078 | YY_RULE_SETUP | 1089 | YY_RULE_SETUP |
1079 | #line 168 "dtc-lexer.l" | 1090 | #line 179 "dtc-lexer.l" |
1080 | { | 1091 | { |
1081 | struct data d; | 1092 | struct data d; |
1082 | DPRINT("Character literal: %s\n", yytext); | 1093 | DPRINT("Character literal: %s\n", yytext); |
@@ -1100,7 +1111,7 @@ YY_RULE_SETUP | |||
1100 | YY_BREAK | 1111 | YY_BREAK |
1101 | case 12: | 1112 | case 12: |
1102 | YY_RULE_SETUP | 1113 | YY_RULE_SETUP |
1103 | #line 189 "dtc-lexer.l" | 1114 | #line 200 "dtc-lexer.l" |
1104 | { /* label reference */ | 1115 | { /* label reference */ |
1105 | DPRINT("Ref: %s\n", yytext+1); | 1116 | DPRINT("Ref: %s\n", yytext+1); |
1106 | yylval.labelref = xstrdup(yytext+1); | 1117 | yylval.labelref = xstrdup(yytext+1); |
@@ -1109,7 +1120,7 @@ YY_RULE_SETUP | |||
1109 | YY_BREAK | 1120 | YY_BREAK |
1110 | case 13: | 1121 | case 13: |
1111 | YY_RULE_SETUP | 1122 | YY_RULE_SETUP |
1112 | #line 195 "dtc-lexer.l" | 1123 | #line 206 "dtc-lexer.l" |
1113 | { /* new-style path reference */ | 1124 | { /* new-style path reference */ |
1114 | yytext[yyleng-1] = '\0'; | 1125 | yytext[yyleng-1] = '\0'; |
1115 | DPRINT("Ref: %s\n", yytext+2); | 1126 | DPRINT("Ref: %s\n", yytext+2); |
@@ -1119,7 +1130,7 @@ YY_RULE_SETUP | |||
1119 | YY_BREAK | 1130 | YY_BREAK |
1120 | case 14: | 1131 | case 14: |
1121 | YY_RULE_SETUP | 1132 | YY_RULE_SETUP |
1122 | #line 202 "dtc-lexer.l" | 1133 | #line 213 "dtc-lexer.l" |
1123 | { | 1134 | { |
1124 | yylval.byte = strtol(yytext, NULL, 16); | 1135 | yylval.byte = strtol(yytext, NULL, 16); |
1125 | DPRINT("Byte: %02x\n", (int)yylval.byte); | 1136 | DPRINT("Byte: %02x\n", (int)yylval.byte); |
@@ -1128,7 +1139,7 @@ YY_RULE_SETUP | |||
1128 | YY_BREAK | 1139 | YY_BREAK |
1129 | case 15: | 1140 | case 15: |
1130 | YY_RULE_SETUP | 1141 | YY_RULE_SETUP |
1131 | #line 208 "dtc-lexer.l" | 1142 | #line 219 "dtc-lexer.l" |
1132 | { | 1143 | { |
1133 | DPRINT("/BYTESTRING\n"); | 1144 | DPRINT("/BYTESTRING\n"); |
1134 | BEGIN_DEFAULT(); | 1145 | BEGIN_DEFAULT(); |
@@ -1137,7 +1148,7 @@ YY_RULE_SETUP | |||
1137 | YY_BREAK | 1148 | YY_BREAK |
1138 | case 16: | 1149 | case 16: |
1139 | YY_RULE_SETUP | 1150 | YY_RULE_SETUP |
1140 | #line 214 "dtc-lexer.l" | 1151 | #line 225 "dtc-lexer.l" |
1141 | { | 1152 | { |
1142 | DPRINT("PropNodeName: %s\n", yytext); | 1153 | DPRINT("PropNodeName: %s\n", yytext); |
1143 | yylval.propnodename = xstrdup((yytext[0] == '\\') ? | 1154 | yylval.propnodename = xstrdup((yytext[0] == '\\') ? |
@@ -1148,7 +1159,7 @@ YY_RULE_SETUP | |||
1148 | YY_BREAK | 1159 | YY_BREAK |
1149 | case 17: | 1160 | case 17: |
1150 | YY_RULE_SETUP | 1161 | YY_RULE_SETUP |
1151 | #line 222 "dtc-lexer.l" | 1162 | #line 233 "dtc-lexer.l" |
1152 | { | 1163 | { |
1153 | DPRINT("Binary Include\n"); | 1164 | DPRINT("Binary Include\n"); |
1154 | return DT_INCBIN; | 1165 | return DT_INCBIN; |
@@ -1157,64 +1168,64 @@ YY_RULE_SETUP | |||
1157 | case 18: | 1168 | case 18: |
1158 | /* rule 18 can match eol */ | 1169 | /* rule 18 can match eol */ |
1159 | YY_RULE_SETUP | 1170 | YY_RULE_SETUP |
1160 | #line 227 "dtc-lexer.l" | 1171 | #line 238 "dtc-lexer.l" |
1161 | /* eat whitespace */ | 1172 | /* eat whitespace */ |
1162 | YY_BREAK | 1173 | YY_BREAK |
1163 | case 19: | 1174 | case 19: |
1164 | /* rule 19 can match eol */ | 1175 | /* rule 19 can match eol */ |
1165 | YY_RULE_SETUP | 1176 | YY_RULE_SETUP |
1166 | #line 228 "dtc-lexer.l" | 1177 | #line 239 "dtc-lexer.l" |
1167 | /* eat C-style comments */ | 1178 | /* eat C-style comments */ |
1168 | YY_BREAK | 1179 | YY_BREAK |
1169 | case 20: | 1180 | case 20: |
1170 | /* rule 20 can match eol */ | 1181 | /* rule 20 can match eol */ |
1171 | YY_RULE_SETUP | 1182 | YY_RULE_SETUP |
1172 | #line 229 "dtc-lexer.l" | 1183 | #line 240 "dtc-lexer.l" |
1173 | /* eat C++-style comments */ | 1184 | /* eat C++-style comments */ |
1174 | YY_BREAK | 1185 | YY_BREAK |
1175 | case 21: | 1186 | case 21: |
1176 | YY_RULE_SETUP | 1187 | YY_RULE_SETUP |
1177 | #line 231 "dtc-lexer.l" | 1188 | #line 242 "dtc-lexer.l" |
1178 | { return DT_LSHIFT; }; | 1189 | { return DT_LSHIFT; }; |
1179 | YY_BREAK | 1190 | YY_BREAK |
1180 | case 22: | 1191 | case 22: |
1181 | YY_RULE_SETUP | 1192 | YY_RULE_SETUP |
1182 | #line 232 "dtc-lexer.l" | 1193 | #line 243 "dtc-lexer.l" |
1183 | { return DT_RSHIFT; }; | 1194 | { return DT_RSHIFT; }; |
1184 | YY_BREAK | 1195 | YY_BREAK |
1185 | case 23: | 1196 | case 23: |
1186 | YY_RULE_SETUP | 1197 | YY_RULE_SETUP |
1187 | #line 233 "dtc-lexer.l" | 1198 | #line 244 "dtc-lexer.l" |
1188 | { return DT_LE; }; | 1199 | { return DT_LE; }; |
1189 | YY_BREAK | 1200 | YY_BREAK |
1190 | case 24: | 1201 | case 24: |
1191 | YY_RULE_SETUP | 1202 | YY_RULE_SETUP |
1192 | #line 234 "dtc-lexer.l" | 1203 | #line 245 "dtc-lexer.l" |
1193 | { return DT_GE; }; | 1204 | { return DT_GE; }; |
1194 | YY_BREAK | 1205 | YY_BREAK |
1195 | case 25: | 1206 | case 25: |
1196 | YY_RULE_SETUP | 1207 | YY_RULE_SETUP |
1197 | #line 235 "dtc-lexer.l" | 1208 | #line 246 "dtc-lexer.l" |
1198 | { return DT_EQ; }; | 1209 | { return DT_EQ; }; |
1199 | YY_BREAK | 1210 | YY_BREAK |
1200 | case 26: | 1211 | case 26: |
1201 | YY_RULE_SETUP | 1212 | YY_RULE_SETUP |
1202 | #line 236 "dtc-lexer.l" | 1213 | #line 247 "dtc-lexer.l" |
1203 | { return DT_NE; }; | 1214 | { return DT_NE; }; |
1204 | YY_BREAK | 1215 | YY_BREAK |
1205 | case 27: | 1216 | case 27: |
1206 | YY_RULE_SETUP | 1217 | YY_RULE_SETUP |
1207 | #line 237 "dtc-lexer.l" | 1218 | #line 248 "dtc-lexer.l" |
1208 | { return DT_AND; }; | 1219 | { return DT_AND; }; |
1209 | YY_BREAK | 1220 | YY_BREAK |
1210 | case 28: | 1221 | case 28: |
1211 | YY_RULE_SETUP | 1222 | YY_RULE_SETUP |
1212 | #line 238 "dtc-lexer.l" | 1223 | #line 249 "dtc-lexer.l" |
1213 | { return DT_OR; }; | 1224 | { return DT_OR; }; |
1214 | YY_BREAK | 1225 | YY_BREAK |
1215 | case 29: | 1226 | case 29: |
1216 | YY_RULE_SETUP | 1227 | YY_RULE_SETUP |
1217 | #line 240 "dtc-lexer.l" | 1228 | #line 251 "dtc-lexer.l" |
1218 | { | 1229 | { |
1219 | DPRINT("Char: %c (\\x%02x)\n", yytext[0], | 1230 | DPRINT("Char: %c (\\x%02x)\n", yytext[0], |
1220 | (unsigned)yytext[0]); | 1231 | (unsigned)yytext[0]); |
@@ -1232,10 +1243,10 @@ YY_RULE_SETUP | |||
1232 | YY_BREAK | 1243 | YY_BREAK |
1233 | case 30: | 1244 | case 30: |
1234 | YY_RULE_SETUP | 1245 | YY_RULE_SETUP |
1235 | #line 255 "dtc-lexer.l" | 1246 | #line 266 "dtc-lexer.l" |
1236 | ECHO; | 1247 | ECHO; |
1237 | YY_BREAK | 1248 | YY_BREAK |
1238 | #line 1239 "dtc-lexer.lex.c" | 1249 | #line 1250 "dtc-lexer.lex.c" |
1239 | 1250 | ||
1240 | case YY_END_OF_BUFFER: | 1251 | case YY_END_OF_BUFFER: |
1241 | { | 1252 | { |
@@ -2195,7 +2206,7 @@ void yyfree (void * ptr ) | |||
2195 | 2206 | ||
2196 | #define YYTABLES_NAME "yytables" | 2207 | #define YYTABLES_NAME "yytables" |
2197 | 2208 | ||
2198 | #line 254 "dtc-lexer.l" | 2209 | #line 265 "dtc-lexer.l" |
2199 | 2210 | ||
2200 | 2211 | ||
2201 | 2212 | ||
diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped index 116458c8dfc4..31cec50a1265 100644 --- a/scripts/dtc/dtc-parser.tab.c_shipped +++ b/scripts/dtc/dtc-parser.tab.c_shipped | |||
@@ -499,9 +499,9 @@ static const yytype_uint16 yyrline[] = | |||
499 | 298, 303, 322, 336, 343, 344, 345, 352, 356, 357, | 499 | 298, 303, 322, 336, 343, 344, 345, 352, 356, 357, |
500 | 361, 362, 366, 367, 371, 372, 376, 377, 381, 382, | 500 | 361, 362, 366, 367, 371, 372, 376, 377, 381, 382, |
501 | 386, 387, 388, 392, 393, 394, 395, 396, 400, 401, | 501 | 386, 387, 388, 392, 393, 394, 395, 396, 400, 401, |
502 | 402, 406, 407, 408, 412, 413, 414, 415, 419, 420, | 502 | 402, 406, 407, 408, 412, 413, 422, 431, 435, 436, |
503 | 421, 422, 427, 430, 434, 442, 445, 449, 457, 461, | 503 | 437, 438, 443, 446, 450, 458, 461, 465, 473, 477, |
504 | 465 | 504 | 481 |
505 | }; | 505 | }; |
506 | #endif | 506 | #endif |
507 | 507 | ||
@@ -1909,111 +1909,125 @@ yyreduce: | |||
1909 | break; | 1909 | break; |
1910 | 1910 | ||
1911 | case 65: | 1911 | case 65: |
1912 | #line 413 "dtc-parser.y" /* yacc.c:1646 */ | 1912 | #line 414 "dtc-parser.y" /* yacc.c:1646 */ |
1913 | { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); } | 1913 | { |
1914 | #line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */ | 1914 | if ((yyvsp[0].integer) != 0) { |
1915 | (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); | ||
1916 | } else { | ||
1917 | ERROR(&(yyloc), "Division by zero"); | ||
1918 | (yyval.integer) = 0; | ||
1919 | } | ||
1920 | } | ||
1921 | #line 1922 "dtc-parser.tab.c" /* yacc.c:1646 */ | ||
1915 | break; | 1922 | break; |
1916 | 1923 | ||
1917 | case 66: | 1924 | case 66: |
1918 | #line 414 "dtc-parser.y" /* yacc.c:1646 */ | 1925 | #line 423 "dtc-parser.y" /* yacc.c:1646 */ |
1919 | { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); } | 1926 | { |
1920 | #line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */ | 1927 | if ((yyvsp[0].integer) != 0) { |
1928 | (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); | ||
1929 | } else { | ||
1930 | ERROR(&(yyloc), "Division by zero"); | ||
1931 | (yyval.integer) = 0; | ||
1932 | } | ||
1933 | } | ||
1934 | #line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */ | ||
1921 | break; | 1935 | break; |
1922 | 1936 | ||
1923 | case 69: | 1937 | case 69: |
1924 | #line 420 "dtc-parser.y" /* yacc.c:1646 */ | 1938 | #line 436 "dtc-parser.y" /* yacc.c:1646 */ |
1925 | { (yyval.integer) = -(yyvsp[0].integer); } | 1939 | { (yyval.integer) = -(yyvsp[0].integer); } |
1926 | #line 1927 "dtc-parser.tab.c" /* yacc.c:1646 */ | 1940 | #line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */ |
1927 | break; | 1941 | break; |
1928 | 1942 | ||
1929 | case 70: | 1943 | case 70: |
1930 | #line 421 "dtc-parser.y" /* yacc.c:1646 */ | 1944 | #line 437 "dtc-parser.y" /* yacc.c:1646 */ |
1931 | { (yyval.integer) = ~(yyvsp[0].integer); } | 1945 | { (yyval.integer) = ~(yyvsp[0].integer); } |
1932 | #line 1933 "dtc-parser.tab.c" /* yacc.c:1646 */ | 1946 | #line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ |
1933 | break; | 1947 | break; |
1934 | 1948 | ||
1935 | case 71: | 1949 | case 71: |
1936 | #line 422 "dtc-parser.y" /* yacc.c:1646 */ | 1950 | #line 438 "dtc-parser.y" /* yacc.c:1646 */ |
1937 | { (yyval.integer) = !(yyvsp[0].integer); } | 1951 | { (yyval.integer) = !(yyvsp[0].integer); } |
1938 | #line 1939 "dtc-parser.tab.c" /* yacc.c:1646 */ | 1952 | #line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */ |
1939 | break; | 1953 | break; |
1940 | 1954 | ||
1941 | case 72: | 1955 | case 72: |
1942 | #line 427 "dtc-parser.y" /* yacc.c:1646 */ | 1956 | #line 443 "dtc-parser.y" /* yacc.c:1646 */ |
1943 | { | 1957 | { |
1944 | (yyval.data) = empty_data; | 1958 | (yyval.data) = empty_data; |
1945 | } | 1959 | } |
1946 | #line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ | 1960 | #line 1961 "dtc-parser.tab.c" /* yacc.c:1646 */ |
1947 | break; | 1961 | break; |
1948 | 1962 | ||
1949 | case 73: | 1963 | case 73: |
1950 | #line 431 "dtc-parser.y" /* yacc.c:1646 */ | 1964 | #line 447 "dtc-parser.y" /* yacc.c:1646 */ |
1951 | { | 1965 | { |
1952 | (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); | 1966 | (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); |
1953 | } | 1967 | } |
1954 | #line 1955 "dtc-parser.tab.c" /* yacc.c:1646 */ | 1968 | #line 1969 "dtc-parser.tab.c" /* yacc.c:1646 */ |
1955 | break; | 1969 | break; |
1956 | 1970 | ||
1957 | case 74: | 1971 | case 74: |
1958 | #line 435 "dtc-parser.y" /* yacc.c:1646 */ | 1972 | #line 451 "dtc-parser.y" /* yacc.c:1646 */ |
1959 | { | 1973 | { |
1960 | (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); | 1974 | (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); |
1961 | } | 1975 | } |
1962 | #line 1963 "dtc-parser.tab.c" /* yacc.c:1646 */ | 1976 | #line 1977 "dtc-parser.tab.c" /* yacc.c:1646 */ |
1963 | break; | 1977 | break; |
1964 | 1978 | ||
1965 | case 75: | 1979 | case 75: |
1966 | #line 442 "dtc-parser.y" /* yacc.c:1646 */ | 1980 | #line 458 "dtc-parser.y" /* yacc.c:1646 */ |
1967 | { | 1981 | { |
1968 | (yyval.nodelist) = NULL; | 1982 | (yyval.nodelist) = NULL; |
1969 | } | 1983 | } |
1970 | #line 1971 "dtc-parser.tab.c" /* yacc.c:1646 */ | 1984 | #line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */ |
1971 | break; | 1985 | break; |
1972 | 1986 | ||
1973 | case 76: | 1987 | case 76: |
1974 | #line 446 "dtc-parser.y" /* yacc.c:1646 */ | 1988 | #line 462 "dtc-parser.y" /* yacc.c:1646 */ |
1975 | { | 1989 | { |
1976 | (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); | 1990 | (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); |
1977 | } | 1991 | } |
1978 | #line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */ | 1992 | #line 1993 "dtc-parser.tab.c" /* yacc.c:1646 */ |
1979 | break; | 1993 | break; |
1980 | 1994 | ||
1981 | case 77: | 1995 | case 77: |
1982 | #line 450 "dtc-parser.y" /* yacc.c:1646 */ | 1996 | #line 466 "dtc-parser.y" /* yacc.c:1646 */ |
1983 | { | 1997 | { |
1984 | ERROR(&(yylsp[0]), "Properties must precede subnodes"); | 1998 | ERROR(&(yylsp[0]), "Properties must precede subnodes"); |
1985 | YYERROR; | 1999 | YYERROR; |
1986 | } | 2000 | } |
1987 | #line 1988 "dtc-parser.tab.c" /* yacc.c:1646 */ | 2001 | #line 2002 "dtc-parser.tab.c" /* yacc.c:1646 */ |
1988 | break; | 2002 | break; |
1989 | 2003 | ||
1990 | case 78: | 2004 | case 78: |
1991 | #line 458 "dtc-parser.y" /* yacc.c:1646 */ | 2005 | #line 474 "dtc-parser.y" /* yacc.c:1646 */ |
1992 | { | 2006 | { |
1993 | (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); | 2007 | (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); |
1994 | } | 2008 | } |
1995 | #line 1996 "dtc-parser.tab.c" /* yacc.c:1646 */ | 2009 | #line 2010 "dtc-parser.tab.c" /* yacc.c:1646 */ |
1996 | break; | 2010 | break; |
1997 | 2011 | ||
1998 | case 79: | 2012 | case 79: |
1999 | #line 462 "dtc-parser.y" /* yacc.c:1646 */ | 2013 | #line 478 "dtc-parser.y" /* yacc.c:1646 */ |
2000 | { | 2014 | { |
2001 | (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); | 2015 | (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); |
2002 | } | 2016 | } |
2003 | #line 2004 "dtc-parser.tab.c" /* yacc.c:1646 */ | 2017 | #line 2018 "dtc-parser.tab.c" /* yacc.c:1646 */ |
2004 | break; | 2018 | break; |
2005 | 2019 | ||
2006 | case 80: | 2020 | case 80: |
2007 | #line 466 "dtc-parser.y" /* yacc.c:1646 */ | 2021 | #line 482 "dtc-parser.y" /* yacc.c:1646 */ |
2008 | { | 2022 | { |
2009 | add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); | 2023 | add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); |
2010 | (yyval.node) = (yyvsp[0].node); | 2024 | (yyval.node) = (yyvsp[0].node); |
2011 | } | 2025 | } |
2012 | #line 2013 "dtc-parser.tab.c" /* yacc.c:1646 */ | 2026 | #line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */ |
2013 | break; | 2027 | break; |
2014 | 2028 | ||
2015 | 2029 | ||
2016 | #line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */ | 2030 | #line 2031 "dtc-parser.tab.c" /* yacc.c:1646 */ |
2017 | default: break; | 2031 | default: break; |
2018 | } | 2032 | } |
2019 | /* User semantic actions sometimes alter yychar, and that requires | 2033 | /* User semantic actions sometimes alter yychar, and that requires |
@@ -2248,7 +2262,7 @@ yyreturn: | |||
2248 | #endif | 2262 | #endif |
2249 | return yyresult; | 2263 | return yyresult; |
2250 | } | 2264 | } |
2251 | #line 472 "dtc-parser.y" /* yacc.c:1906 */ | 2265 | #line 488 "dtc-parser.y" /* yacc.c:1906 */ |
2252 | 2266 | ||
2253 | 2267 | ||
2254 | void yyerror(char const *s) | 2268 | void yyerror(char const *s) |
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y index 5a897e36562d..000873f070fd 100644 --- a/scripts/dtc/dtc-parser.y +++ b/scripts/dtc/dtc-parser.y | |||
@@ -410,8 +410,24 @@ integer_add: | |||
410 | 410 | ||
411 | integer_mul: | 411 | integer_mul: |
412 | integer_mul '*' integer_unary { $$ = $1 * $3; } | 412 | integer_mul '*' integer_unary { $$ = $1 * $3; } |
413 | | integer_mul '/' integer_unary { $$ = $1 / $3; } | 413 | | integer_mul '/' integer_unary |
414 | | integer_mul '%' integer_unary { $$ = $1 % $3; } | 414 | { |
415 | if ($3 != 0) { | ||
416 | $$ = $1 / $3; | ||
417 | } else { | ||
418 | ERROR(&@$, "Division by zero"); | ||
419 | $$ = 0; | ||
420 | } | ||
421 | } | ||
422 | | integer_mul '%' integer_unary | ||
423 | { | ||
424 | if ($3 != 0) { | ||
425 | $$ = $1 % $3; | ||
426 | } else { | ||
427 | ERROR(&@$, "Division by zero"); | ||
428 | $$ = 0; | ||
429 | } | ||
430 | } | ||
415 | | integer_unary | 431 | | integer_unary |
416 | ; | 432 | ; |
417 | 433 | ||
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c index 8c4add69a765..5fa23c406266 100644 --- a/scripts/dtc/dtc.c +++ b/scripts/dtc/dtc.c | |||
@@ -18,6 +18,8 @@ | |||
18 | * USA | 18 | * USA |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <sys/stat.h> | ||
22 | |||
21 | #include "dtc.h" | 23 | #include "dtc.h" |
22 | #include "srcpos.h" | 24 | #include "srcpos.h" |
23 | 25 | ||
@@ -104,11 +106,56 @@ static const char * const usage_opts_help[] = { | |||
104 | NULL, | 106 | NULL, |
105 | }; | 107 | }; |
106 | 108 | ||
109 | static const char *guess_type_by_name(const char *fname, const char *fallback) | ||
110 | { | ||
111 | const char *s; | ||
112 | |||
113 | s = strrchr(fname, '.'); | ||
114 | if (s == NULL) | ||
115 | return fallback; | ||
116 | if (!strcasecmp(s, ".dts")) | ||
117 | return "dts"; | ||
118 | if (!strcasecmp(s, ".dtb")) | ||
119 | return "dtb"; | ||
120 | return fallback; | ||
121 | } | ||
122 | |||
123 | static const char *guess_input_format(const char *fname, const char *fallback) | ||
124 | { | ||
125 | struct stat statbuf; | ||
126 | uint32_t magic; | ||
127 | FILE *f; | ||
128 | |||
129 | if (stat(fname, &statbuf) != 0) | ||
130 | return fallback; | ||
131 | |||
132 | if (S_ISDIR(statbuf.st_mode)) | ||
133 | return "fs"; | ||
134 | |||
135 | if (!S_ISREG(statbuf.st_mode)) | ||
136 | return fallback; | ||
137 | |||
138 | f = fopen(fname, "r"); | ||
139 | if (f == NULL) | ||
140 | return fallback; | ||
141 | if (fread(&magic, 4, 1, f) != 1) { | ||
142 | fclose(f); | ||
143 | return fallback; | ||
144 | } | ||
145 | fclose(f); | ||
146 | |||
147 | magic = fdt32_to_cpu(magic); | ||
148 | if (magic == FDT_MAGIC) | ||
149 | return "dtb"; | ||
150 | |||
151 | return guess_type_by_name(fname, fallback); | ||
152 | } | ||
153 | |||
107 | int main(int argc, char *argv[]) | 154 | int main(int argc, char *argv[]) |
108 | { | 155 | { |
109 | struct boot_info *bi; | 156 | struct boot_info *bi; |
110 | const char *inform = "dts"; | 157 | const char *inform = NULL; |
111 | const char *outform = "dts"; | 158 | const char *outform = NULL; |
112 | const char *outname = "-"; | 159 | const char *outname = "-"; |
113 | const char *depname = NULL; | 160 | const char *depname = NULL; |
114 | bool force = false, sort = false; | 161 | bool force = false, sort = false; |
@@ -213,6 +260,17 @@ int main(int argc, char *argv[]) | |||
213 | fprintf(depfile, "%s:", outname); | 260 | fprintf(depfile, "%s:", outname); |
214 | } | 261 | } |
215 | 262 | ||
263 | if (inform == NULL) | ||
264 | inform = guess_input_format(arg, "dts"); | ||
265 | if (outform == NULL) { | ||
266 | outform = guess_type_by_name(outname, NULL); | ||
267 | if (outform == NULL) { | ||
268 | if (streq(inform, "dts")) | ||
269 | outform = "dtb"; | ||
270 | else | ||
271 | outform = "dts"; | ||
272 | } | ||
273 | } | ||
216 | if (streq(inform, "dts")) | 274 | if (streq(inform, "dts")) |
217 | bi = dt_from_source(arg); | 275 | bi = dt_from_source(arg); |
218 | else if (streq(inform, "fs")) | 276 | else if (streq(inform, "fs")) |
diff --git a/scripts/dtc/dtx_diff b/scripts/dtc/dtx_diff new file mode 100755 index 000000000000..959ab2646d38 --- /dev/null +++ b/scripts/dtc/dtx_diff | |||
@@ -0,0 +1,349 @@ | |||
1 | #! /bin/bash | ||
2 | |||
3 | # Copyright (C) 2015 Frank Rowand | ||
4 | # | ||
5 | # This program is free software; you can redistribute it and/or modify | ||
6 | # it under the terms of the GNU General Public License as published by | ||
7 | # the Free Software Foundation; version 2 of the License. | ||
8 | |||
9 | |||
10 | usage() { | ||
11 | |||
12 | # use spaces instead of tabs in the usage message | ||
13 | cat >&2 <<eod | ||
14 | |||
15 | Usage: | ||
16 | |||
17 | `basename $0` DTx | ||
18 | decompile DTx | ||
19 | |||
20 | `basename $0` DTx_1 DTx_2 | ||
21 | diff DTx_1 and DTx_2 | ||
22 | |||
23 | |||
24 | -f print full dts in diff (--unified=99999) | ||
25 | -h synonym for --help | ||
26 | -help synonym for --help | ||
27 | --help print this message and exit | ||
28 | -s SRCTREE linux kernel source tree is at path SRCTREE | ||
29 | (default is current directory) | ||
30 | -S linux kernel source tree is at root of current git repo | ||
31 | -u unsorted, do not sort DTx | ||
32 | |||
33 | |||
34 | Each DTx is processed by the dtc compiler to produce a sorted dts source | ||
35 | file. If DTx is a dts source file then it is pre-processed in the same | ||
36 | manner as done for the compile of the dts source file in the Linux kernel | ||
37 | build system ('#include' and '/include/' directives are processed). | ||
38 | |||
39 | If two DTx are provided, the resulting dts source files are diffed. | ||
40 | |||
41 | If DTx is a directory, it is treated as a DT subtree, such as | ||
42 | /proc/device-tree. | ||
43 | |||
44 | If DTx contains the binary blob magic value in the first four bytes, | ||
45 | it is treated as a binary blob (aka .dtb or FDT). | ||
46 | |||
47 | Otherwise DTx is treated as a dts source file (aka .dts). | ||
48 | |||
49 | If this script is not run from the root of the linux source tree, | ||
50 | and DTx utilizes '#include' or '/include/' then the path of the | ||
51 | linux source tree can be provided by '-s SRCTREE' or '-S' so that | ||
52 | include paths will be set properly. | ||
53 | |||
54 | The shell variable \${ARCH} must provide the architecture containing | ||
55 | the dts source file for include paths to be set properly for '#include' | ||
56 | or '/include/' to be processed. | ||
57 | |||
58 | If DTx_1 and DTx_2 are in different architectures, then this script | ||
59 | may not work since \${ARCH} is part of the include path. Two possible | ||
60 | workarounds: | ||
61 | |||
62 | `basename $0` \\ | ||
63 | <(ARCH=arch_of_dtx_1 `basename $0` DTx_1) \\ | ||
64 | <(ARCH=arch_of_dtx_2 `basename $0` DTx_2) | ||
65 | |||
66 | `basename $0` ARCH=arch_of_dtx_1 DTx_1 >tmp_dtx_1.dts | ||
67 | `basename $0` ARCH=arch_of_dtx_2 DTx_2 >tmp_dtx_2.dts | ||
68 | `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts | ||
69 | rm tmp_dtx_1.dts tmp_dtx_2.dts | ||
70 | |||
71 | If DTx_1 and DTx_2 are in different directories, then this script will | ||
72 | add the path of DTx_1 and DTx_2 to the include paths. If DTx_2 includes | ||
73 | a local file that exists in both the path of DTx_1 and DTx_2 then the | ||
74 | file in the path of DTx_1 will incorrectly be included. Possible | ||
75 | workaround: | ||
76 | |||
77 | `basename $0` DTx_1 >tmp_dtx_1.dts | ||
78 | `basename $0` DTx_2 >tmp_dtx_2.dts | ||
79 | `basename $0` tmp_dtx_1.dts tmp_dtx_2.dts | ||
80 | rm tmp_dtx_1.dts tmp_dtx_2.dts | ||
81 | |||
82 | eod | ||
83 | } | ||
84 | |||
85 | |||
86 | compile_to_dts() { | ||
87 | |||
88 | dtx="$1" | ||
89 | |||
90 | if [ -d "${dtx}" ] ; then | ||
91 | |||
92 | # ----- input is file tree | ||
93 | |||
94 | if ( ! ${DTC} -I fs ${dtx} ) ; then | ||
95 | exit 3 | ||
96 | fi | ||
97 | |||
98 | elif [ -f "${dtx}" ] && [ -r "${dtx}" ] ; then | ||
99 | |||
100 | magic=`hexdump -n 4 -e '/1 "%02x"' ${dtx}` | ||
101 | if [ "${magic}" = "d00dfeed" ] ; then | ||
102 | |||
103 | # ----- input is FDT (binary blob) | ||
104 | |||
105 | if ( ! ${DTC} -I dtb ${dtx} ) ; then | ||
106 | exit 3 | ||
107 | fi | ||
108 | |||
109 | return | ||
110 | |||
111 | fi | ||
112 | |||
113 | # ----- input is DTS (source) | ||
114 | |||
115 | if ( cpp ${cpp_flags} -x assembler-with-cpp ${dtx} \ | ||
116 | | ${DTC} -I dts ) ; then | ||
117 | return | ||
118 | fi | ||
119 | |||
120 | echo "" >&2 | ||
121 | echo "Possible hints to resolve the above error:" >&2 | ||
122 | echo " (hints might not fix the problem)" >&2 | ||
123 | |||
124 | hint_given=0 | ||
125 | |||
126 | if [ "${ARCH}" = "" ] ; then | ||
127 | hint_given=1 | ||
128 | echo "" >&2 | ||
129 | echo " shell variable \$ARCH not set" >&2 | ||
130 | fi | ||
131 | |||
132 | dtx_arch=`echo "/${dtx}" | sed -e 's|.*/arch/||' -e 's|/.*||'` | ||
133 | |||
134 | if [ "${dtx_arch}" != "" -a "${dtx_arch}" != "${ARCH}" ] ; then | ||
135 | hint_given=1 | ||
136 | echo "" >&2 | ||
137 | echo " architecture ${dtx_arch} is in file path," >&2 | ||
138 | echo " but does not match shell variable \$ARCH" >&2 | ||
139 | echo " >>\$ARCH<< is: >>${ARCH}<<" >&2 | ||
140 | fi | ||
141 | |||
142 | if [ ! -d ${srctree}/arch/${ARCH} ] ; then | ||
143 | hint_given=1 | ||
144 | echo "" >&2 | ||
145 | echo " ${srctree}/arch/${ARCH}/ does not exist" >&2 | ||
146 | echo " Is \$ARCH='${ARCH}' correct?" >&2 | ||
147 | echo " Possible fix: use '-s' option" >&2 | ||
148 | |||
149 | git_root=`git rev-parse --show-toplevel 2>/dev/null` | ||
150 | if [ -d ${git_root}/arch/ ] ; then | ||
151 | echo " Possible fix: use '-S' option" >&2 | ||
152 | fi | ||
153 | fi | ||
154 | |||
155 | if [ $hint_given = 0 ] ; then | ||
156 | echo "" >&2 | ||
157 | echo " No hints available." >&2 | ||
158 | fi | ||
159 | |||
160 | echo "" >&2 | ||
161 | |||
162 | exit 3 | ||
163 | |||
164 | else | ||
165 | echo "" >&2 | ||
166 | echo "ERROR: ${dtx} does not exist or is not readable" >&2 | ||
167 | echo "" >&2 | ||
168 | exit 2 | ||
169 | fi | ||
170 | |||
171 | } | ||
172 | |||
173 | |||
174 | # ----- start of script | ||
175 | |||
176 | cmd_diff=0 | ||
177 | diff_flags="-u" | ||
178 | dtx_file_1="" | ||
179 | dtx_file_2="" | ||
180 | dtc_sort="-s" | ||
181 | help=0 | ||
182 | srctree="" | ||
183 | |||
184 | |||
185 | while [ $# -gt 0 ] ; do | ||
186 | |||
187 | case $1 in | ||
188 | |||
189 | -f ) | ||
190 | diff_flags="--unified=999999" | ||
191 | shift | ||
192 | ;; | ||
193 | |||
194 | -h | -help | --help ) | ||
195 | help=1 | ||
196 | shift | ||
197 | ;; | ||
198 | |||
199 | -s ) | ||
200 | srctree="$2" | ||
201 | shift 2 | ||
202 | ;; | ||
203 | |||
204 | -S ) | ||
205 | git_root=`git rev-parse --show-toplevel 2>/dev/null` | ||
206 | srctree="${git_root}" | ||
207 | shift | ||
208 | ;; | ||
209 | |||
210 | -u ) | ||
211 | dtc_sort="" | ||
212 | shift | ||
213 | ;; | ||
214 | |||
215 | *) | ||
216 | if [ "${dtx_file_1}" = "" ] ; then | ||
217 | dtx_file_1="$1" | ||
218 | elif [ "${dtx_file_2}" = "" ] ; then | ||
219 | dtx_file_2="$1" | ||
220 | else | ||
221 | echo "" >&2 | ||
222 | echo "ERROR: Unexpected parameter: $1" >&2 | ||
223 | echo "" >&2 | ||
224 | exit 2 | ||
225 | fi | ||
226 | shift | ||
227 | ;; | ||
228 | |||
229 | esac | ||
230 | |||
231 | done | ||
232 | |||
233 | if [ "${srctree}" = "" ] ; then | ||
234 | srctree="." | ||
235 | fi | ||
236 | |||
237 | if [ "${dtx_file_2}" != "" ]; then | ||
238 | cmd_diff=1 | ||
239 | fi | ||
240 | |||
241 | if (( ${help} )) ; then | ||
242 | usage | ||
243 | exit 1 | ||
244 | fi | ||
245 | |||
246 | # this must follow check for ${help} | ||
247 | if [ "${dtx_file_1}" = "" ]; then | ||
248 | echo "" >&2 | ||
249 | echo "ERROR: parameter DTx required" >&2 | ||
250 | echo "" >&2 | ||
251 | exit 2 | ||
252 | fi | ||
253 | |||
254 | |||
255 | # ----- prefer dtc from linux kernel, allow fallback to dtc in $PATH | ||
256 | |||
257 | if [ "${KBUILD_OUTPUT:0:2}" = ".." ] ; then | ||
258 | __KBUILD_OUTPUT="${srctree}/${KBUILD_OUTPUT}" | ||
259 | elif [ "${KBUILD_OUTPUT}" = "" ] ; then | ||
260 | __KBUILD_OUTPUT="." | ||
261 | else | ||
262 | __KBUILD_OUTPUT="${KBUILD_OUTPUT}" | ||
263 | fi | ||
264 | |||
265 | DTC="${__KBUILD_OUTPUT}/scripts/dtc/dtc" | ||
266 | |||
267 | if [ ! -x ${DTC} ] ; then | ||
268 | __DTC="dtc" | ||
269 | if grep -q "^CONFIG_DTC=y" ${__KBUILD_OUTPUT}/.config ; then | ||
270 | make_command=' | ||
271 | make scripts' | ||
272 | else | ||
273 | make_command=' | ||
274 | Enable CONFIG_DTC in the kernel configuration | ||
275 | make scripts' | ||
276 | fi | ||
277 | if ( ! which ${__DTC} >/dev/null ) ; then | ||
278 | |||
279 | # use spaces instead of tabs in the error message | ||
280 | cat >&2 <<eod | ||
281 | |||
282 | ERROR: unable to find a 'dtc' program | ||
283 | |||
284 | Preferred 'dtc' (built from Linux kernel source tree) was not found or | ||
285 | is not executable. | ||
286 | |||
287 | 'dtc' is: ${DTC} | ||
288 | |||
289 | If it does not exist, create it from the root of the Linux source tree: | ||
290 | ${make_command} | ||
291 | |||
292 | If not at the root of the Linux kernel source tree -s SRCTREE or -S | ||
293 | may need to be specified to find 'dtc'. | ||
294 | |||
295 | If 'O=\${dir}' is specified in your Linux builds, this script requires | ||
296 | 'export KBUILD_OUTPUT=\${dir}' or add \${dir}/scripts/dtc to \$PATH | ||
297 | before running. | ||
298 | |||
299 | If \${KBUILD_OUTPUT} is a relative path, then '-s SRCDIR', -S, or run | ||
300 | this script from the root of the Linux kernel source tree is required. | ||
301 | |||
302 | Fallback '${__DTC}' was also not in \${PATH} or is not executable. | ||
303 | |||
304 | eod | ||
305 | exit 2 | ||
306 | fi | ||
307 | DTC=${__DTC} | ||
308 | fi | ||
309 | |||
310 | |||
311 | # ----- cpp and dtc flags same as for linux source tree build of .dtb files, | ||
312 | # plus directories of the dtx file(s) | ||
313 | |||
314 | dtx_path_1_dtc_include="-i `dirname ${dtx_file_1}`" | ||
315 | |||
316 | dtx_path_2_dtc_include="" | ||
317 | if (( ${cmd_diff} )) ; then | ||
318 | dtx_path_2_dtc_include="-i `dirname ${dtx_file_2}`" | ||
319 | fi | ||
320 | |||
321 | cpp_flags="\ | ||
322 | -nostdinc \ | ||
323 | -I${srctree}/arch/${ARCH}/boot/dts \ | ||
324 | -I${srctree}/arch/${ARCH}/boot/dts/include \ | ||
325 | -I${srctree}/drivers/of/testcase-data \ | ||
326 | -undef -D__DTS__" | ||
327 | |||
328 | dtc_flags="\ | ||
329 | -i ${srctree}/arch/${ARCH}/boot/dts/ \ | ||
330 | -i ${srctree}/kernel/dts \ | ||
331 | ${dtx_path_1_dtc_include} \ | ||
332 | ${dtx_path_2_dtc_include}" | ||
333 | |||
334 | DTC="${DTC} ${dtc_flags} -O dts -qq -f ${dtc_sort} -o -" | ||
335 | |||
336 | |||
337 | # ----- do the diff or decompile | ||
338 | |||
339 | if (( ${cmd_diff} )) ; then | ||
340 | |||
341 | diff ${diff_flags} \ | ||
342 | <(compile_to_dts "${dtx_file_1}") \ | ||
343 | <(compile_to_dts "${dtx_file_2}") | ||
344 | |||
345 | else | ||
346 | |||
347 | compile_to_dts "${dtx_file_1}" | ||
348 | |||
349 | fi | ||
diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c index 2ce6a44179de..22286a1aaeaf 100644 --- a/scripts/dtc/libfdt/fdt.c +++ b/scripts/dtc/libfdt/fdt.c | |||
@@ -76,18 +76,19 @@ int fdt_check_header(const void *fdt) | |||
76 | 76 | ||
77 | const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) | 77 | const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) |
78 | { | 78 | { |
79 | const char *p; | 79 | unsigned absoffset = offset + fdt_off_dt_struct(fdt); |
80 | |||
81 | if ((absoffset < offset) | ||
82 | || ((absoffset + len) < absoffset) | ||
83 | || (absoffset + len) > fdt_totalsize(fdt)) | ||
84 | return NULL; | ||
80 | 85 | ||
81 | if (fdt_version(fdt) >= 0x11) | 86 | if (fdt_version(fdt) >= 0x11) |
82 | if (((offset + len) < offset) | 87 | if (((offset + len) < offset) |
83 | || ((offset + len) > fdt_size_dt_struct(fdt))) | 88 | || ((offset + len) > fdt_size_dt_struct(fdt))) |
84 | return NULL; | 89 | return NULL; |
85 | 90 | ||
86 | p = _fdt_offset_ptr(fdt, offset); | 91 | return _fdt_offset_ptr(fdt, offset); |
87 | |||
88 | if (p + len < p) | ||
89 | return NULL; | ||
90 | return p; | ||
91 | } | 92 | } |
92 | 93 | ||
93 | uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) | 94 | uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) |
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c index a65e4b5b72b6..e5b313682007 100644 --- a/scripts/dtc/libfdt/fdt_ro.c +++ b/scripts/dtc/libfdt/fdt_ro.c | |||
@@ -538,6 +538,106 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str) | |||
538 | return 0; | 538 | return 0; |
539 | } | 539 | } |
540 | 540 | ||
541 | int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property) | ||
542 | { | ||
543 | const char *list, *end; | ||
544 | int length, count = 0; | ||
545 | |||
546 | list = fdt_getprop(fdt, nodeoffset, property, &length); | ||
547 | if (!list) | ||
548 | return -length; | ||
549 | |||
550 | end = list + length; | ||
551 | |||
552 | while (list < end) { | ||
553 | length = strnlen(list, end - list) + 1; | ||
554 | |||
555 | /* Abort if the last string isn't properly NUL-terminated. */ | ||
556 | if (list + length > end) | ||
557 | return -FDT_ERR_BADVALUE; | ||
558 | |||
559 | list += length; | ||
560 | count++; | ||
561 | } | ||
562 | |||
563 | return count; | ||
564 | } | ||
565 | |||
566 | int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property, | ||
567 | const char *string) | ||
568 | { | ||
569 | int length, len, idx = 0; | ||
570 | const char *list, *end; | ||
571 | |||
572 | list = fdt_getprop(fdt, nodeoffset, property, &length); | ||
573 | if (!list) | ||
574 | return -length; | ||
575 | |||
576 | len = strlen(string) + 1; | ||
577 | end = list + length; | ||
578 | |||
579 | while (list < end) { | ||
580 | length = strnlen(list, end - list) + 1; | ||
581 | |||
582 | /* Abort if the last string isn't properly NUL-terminated. */ | ||
583 | if (list + length > end) | ||
584 | return -FDT_ERR_BADVALUE; | ||
585 | |||
586 | if (length == len && memcmp(list, string, length) == 0) | ||
587 | return idx; | ||
588 | |||
589 | list += length; | ||
590 | idx++; | ||
591 | } | ||
592 | |||
593 | return -FDT_ERR_NOTFOUND; | ||
594 | } | ||
595 | |||
596 | const char *fdt_stringlist_get(const void *fdt, int nodeoffset, | ||
597 | const char *property, int idx, | ||
598 | int *lenp) | ||
599 | { | ||
600 | const char *list, *end; | ||
601 | int length; | ||
602 | |||
603 | list = fdt_getprop(fdt, nodeoffset, property, &length); | ||
604 | if (!list) { | ||
605 | if (lenp) | ||
606 | *lenp = length; | ||
607 | |||
608 | return NULL; | ||
609 | } | ||
610 | |||
611 | end = list + length; | ||
612 | |||
613 | while (list < end) { | ||
614 | length = strnlen(list, end - list) + 1; | ||
615 | |||
616 | /* Abort if the last string isn't properly NUL-terminated. */ | ||
617 | if (list + length > end) { | ||
618 | if (lenp) | ||
619 | *lenp = -FDT_ERR_BADVALUE; | ||
620 | |||
621 | return NULL; | ||
622 | } | ||
623 | |||
624 | if (idx == 0) { | ||
625 | if (lenp) | ||
626 | *lenp = length - 1; | ||
627 | |||
628 | return list; | ||
629 | } | ||
630 | |||
631 | list += length; | ||
632 | idx--; | ||
633 | } | ||
634 | |||
635 | if (lenp) | ||
636 | *lenp = -FDT_ERR_NOTFOUND; | ||
637 | |||
638 | return NULL; | ||
639 | } | ||
640 | |||
541 | int fdt_node_check_compatible(const void *fdt, int nodeoffset, | 641 | int fdt_node_check_compatible(const void *fdt, int nodeoffset, |
542 | const char *compatible) | 642 | const char *compatible) |
543 | { | 643 | { |
diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c index 70adec6c371b..8be02b1f68f3 100644 --- a/scripts/dtc/libfdt/fdt_rw.c +++ b/scripts/dtc/libfdt/fdt_rw.c | |||
@@ -101,6 +101,8 @@ static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen) | |||
101 | 101 | ||
102 | if (((p + oldlen) < p) || ((p + oldlen) > end)) | 102 | if (((p + oldlen) < p) || ((p + oldlen) > end)) |
103 | return -FDT_ERR_BADOFFSET; | 103 | return -FDT_ERR_BADOFFSET; |
104 | if ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt)) | ||
105 | return -FDT_ERR_BADOFFSET; | ||
104 | if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt))) | 106 | if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt))) |
105 | return -FDT_ERR_NOSPACE; | 107 | return -FDT_ERR_NOSPACE; |
106 | memmove(p + newlen, p + oldlen, end - p - oldlen); | 108 | memmove(p + newlen, p + oldlen, end - p - oldlen); |
diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h index ea35ac3c9be4..59ca33976e56 100644 --- a/scripts/dtc/libfdt/libfdt.h +++ b/scripts/dtc/libfdt/libfdt.h | |||
@@ -121,7 +121,12 @@ | |||
121 | /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells | 121 | /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells |
122 | * or similar property with a bad format or value */ | 122 | * or similar property with a bad format or value */ |
123 | 123 | ||
124 | #define FDT_ERR_MAX 14 | 124 | #define FDT_ERR_BADVALUE 15 |
125 | /* FDT_ERR_BADVALUE: Device tree has a property with an unexpected | ||
126 | * value. For example: a property expected to contain a string list | ||
127 | * is not NUL-terminated within the length of its value. */ | ||
128 | |||
129 | #define FDT_ERR_MAX 15 | ||
125 | 130 | ||
126 | /**********************************************************************/ | 131 | /**********************************************************************/ |
127 | /* Low-level functions (you probably don't need these) */ | 132 | /* Low-level functions (you probably don't need these) */ |
@@ -457,8 +462,8 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt, | |||
457 | * @namelen: number of characters of name to consider | 462 | * @namelen: number of characters of name to consider |
458 | * @lenp: pointer to an integer variable (will be overwritten) or NULL | 463 | * @lenp: pointer to an integer variable (will be overwritten) or NULL |
459 | * | 464 | * |
460 | * Identical to fdt_get_property_namelen(), but only examine the first | 465 | * Identical to fdt_get_property(), but only examine the first namelen |
461 | * namelen characters of name for matching the property name. | 466 | * characters of name for matching the property name. |
462 | */ | 467 | */ |
463 | const struct fdt_property *fdt_get_property_namelen(const void *fdt, | 468 | const struct fdt_property *fdt_get_property_namelen(const void *fdt, |
464 | int nodeoffset, | 469 | int nodeoffset, |
@@ -868,6 +873,68 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset, | |||
868 | */ | 873 | */ |
869 | int fdt_stringlist_contains(const char *strlist, int listlen, const char *str); | 874 | int fdt_stringlist_contains(const char *strlist, int listlen, const char *str); |
870 | 875 | ||
876 | /** | ||
877 | * fdt_stringlist_count - count the number of strings in a string list | ||
878 | * @fdt: pointer to the device tree blob | ||
879 | * @nodeoffset: offset of a tree node | ||
880 | * @property: name of the property containing the string list | ||
881 | * @return: | ||
882 | * the number of strings in the given property | ||
883 | * -FDT_ERR_BADVALUE if the property value is not NUL-terminated | ||
884 | * -FDT_ERR_NOTFOUND if the property does not exist | ||
885 | */ | ||
886 | int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property); | ||
887 | |||
888 | /** | ||
889 | * fdt_stringlist_search - find a string in a string list and return its index | ||
890 | * @fdt: pointer to the device tree blob | ||
891 | * @nodeoffset: offset of a tree node | ||
892 | * @property: name of the property containing the string list | ||
893 | * @string: string to look up in the string list | ||
894 | * | ||
895 | * Note that it is possible for this function to succeed on property values | ||
896 | * that are not NUL-terminated. That's because the function will stop after | ||
897 | * finding the first occurrence of @string. This can for example happen with | ||
898 | * small-valued cell properties, such as #address-cells, when searching for | ||
899 | * the empty string. | ||
900 | * | ||
901 | * @return: | ||
902 | * the index of the string in the list of strings | ||
903 | * -FDT_ERR_BADVALUE if the property value is not NUL-terminated | ||
904 | * -FDT_ERR_NOTFOUND if the property does not exist or does not contain | ||
905 | * the given string | ||
906 | */ | ||
907 | int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property, | ||
908 | const char *string); | ||
909 | |||
910 | /** | ||
911 | * fdt_stringlist_get() - obtain the string at a given index in a string list | ||
912 | * @fdt: pointer to the device tree blob | ||
913 | * @nodeoffset: offset of a tree node | ||
914 | * @property: name of the property containing the string list | ||
915 | * @index: index of the string to return | ||
916 | * @lenp: return location for the string length or an error code on failure | ||
917 | * | ||
918 | * Note that this will successfully extract strings from properties with | ||
919 | * non-NUL-terminated values. For example on small-valued cell properties | ||
920 | * this function will return the empty string. | ||
921 | * | ||
922 | * If non-NULL, the length of the string (on success) or a negative error-code | ||
923 | * (on failure) will be stored in the integer pointer to by lenp. | ||
924 | * | ||
925 | * @return: | ||
926 | * A pointer to the string at the given index in the string list or NULL on | ||
927 | * failure. On success the length of the string will be stored in the memory | ||
928 | * location pointed to by the lenp parameter, if non-NULL. On failure one of | ||
929 | * the following negative error codes will be returned in the lenp parameter | ||
930 | * (if non-NULL): | ||
931 | * -FDT_ERR_BADVALUE if the property value is not NUL-terminated | ||
932 | * -FDT_ERR_NOTFOUND if the property does not exist | ||
933 | */ | ||
934 | const char *fdt_stringlist_get(const void *fdt, int nodeoffset, | ||
935 | const char *property, int index, | ||
936 | int *lenp); | ||
937 | |||
871 | /**********************************************************************/ | 938 | /**********************************************************************/ |
872 | /* Read-only functions (addressing related) */ | 939 | /* Read-only functions (addressing related) */ |
873 | /**********************************************************************/ | 940 | /**********************************************************************/ |
diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c index 9d65226df9e4..fb124eea4919 100644 --- a/scripts/dtc/util.c +++ b/scripts/dtc/util.c | |||
@@ -152,7 +152,6 @@ char get_escape_char(const char *s, int *i) | |||
152 | int j = *i + 1; | 152 | int j = *i + 1; |
153 | char val; | 153 | char val; |
154 | 154 | ||
155 | assert(c); | ||
156 | switch (c) { | 155 | switch (c) { |
157 | case 'a': | 156 | case 'a': |
158 | val = '\a'; | 157 | val = '\a'; |
@@ -349,7 +348,6 @@ int utilfdt_decode_type(const char *fmt, int *type, int *size) | |||
349 | void utilfdt_print_data(const char *data, int len) | 348 | void utilfdt_print_data(const char *data, int len) |
350 | { | 349 | { |
351 | int i; | 350 | int i; |
352 | const char *p = data; | ||
353 | const char *s; | 351 | const char *s; |
354 | 352 | ||
355 | /* no data, don't print */ | 353 | /* no data, don't print */ |
@@ -376,6 +374,7 @@ void utilfdt_print_data(const char *data, int len) | |||
376 | i < (len - 1) ? " " : ""); | 374 | i < (len - 1) ? " " : ""); |
377 | printf(">"); | 375 | printf(">"); |
378 | } else { | 376 | } else { |
377 | const unsigned char *p = (const unsigned char *)data; | ||
379 | printf(" = ["); | 378 | printf(" = ["); |
380 | for (i = 0; i < len; i++) | 379 | for (i = 0; i < len; i++) |
381 | printf("%02x%s", *p++, i < len - 1 ? " " : ""); | 380 | printf("%02x%s", *p++, i < len - 1 ? " " : ""); |
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h index 5b8c7d53d608..11d93e6d8220 100644 --- a/scripts/dtc/version_gen.h +++ b/scripts/dtc/version_gen.h | |||
@@ -1 +1 @@ | |||
#define DTC_VERSION "DTC 1.4.1-g9d3649bd" | #define DTC_VERSION "DTC 1.4.1-gb06e55c8" | ||