From 93bad0678fe27ce61dd9a87cea362bdcd04958c7 Mon Sep 17 00:00:00 2001 From: Marco Franchi Date: Thu, 16 Feb 2017 10:23:44 -0200 Subject: [PATCH 01/24] dt: Add vendor prefix for Sensirion Sensirion is a sensor manufacturer, providing relative humidity sensors, temperature sensor and flow sensor solutions. Signed-off-by: Marco Franchi Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index ec0bfb9bbebd..830c9987fa02 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -265,6 +265,7 @@ sbs Smart Battery System schindler Schindler seagate Seagate Technology PLC semtech Semtech Corporation +sensirion Sensirion AG sgx SGX Sensortech sharp Sharp Corporation si-en Si-En Technology Ltd. From 0549519991ace9549170270f22cc26077ddb9490 Mon Sep 17 00:00:00 2001 From: Greentime Hu Date: Thu, 23 Feb 2017 10:53:47 +0800 Subject: [PATCH 02/24] dt-bindings: net: generalize moxart-mac to support all faraday based ftmac IP Andestech and moxa use the same faraday mac IP, so we use faraday,ftmac.txt to describe it. Signed-off-by: Greentime Hu Signed-off-by: Rob Herring --- .../net/{moxa,moxart-mac.txt => faraday,ftmac.txt} | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) rename Documentation/devicetree/bindings/net/{moxa,moxart-mac.txt => faraday,ftmac.txt} (68%) diff --git a/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt b/Documentation/devicetree/bindings/net/faraday,ftmac.txt similarity index 68% rename from Documentation/devicetree/bindings/net/moxa,moxart-mac.txt rename to Documentation/devicetree/bindings/net/faraday,ftmac.txt index 583418b2c127..be4f55e23bf7 100644 --- a/Documentation/devicetree/bindings/net/moxa,moxart-mac.txt +++ b/Documentation/devicetree/bindings/net/faraday,ftmac.txt @@ -1,8 +1,11 @@ -MOXA ART Ethernet Controller +Faraday Ethernet Controller Required properties: -- compatible : Must be "moxa,moxart-mac" +- compatible : Must contain "faraday,ftmac", as well as one of + the SoC specific identifiers: + "andestech,atmac100" + "moxa,moxart-mac" - reg : Should contain register location and length - interrupts : Should contain the mac interrupt number From b0bb7b196627640fc38bea1d5859855bfee62ee2 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Fri, 3 Mar 2017 15:41:46 +0100 Subject: [PATCH 03/24] dt-bindings: mfd: Fix path to atmel/hlcdc-dc.txt Atmel hlcdc-dc documentation is actually in Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt Signed-off-by: Richard Genoud Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt b/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt index 670831b29565..eec40be7f79a 100644 --- a/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt +++ b/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt @@ -15,7 +15,7 @@ Required properties: The HLCDC IP exposes two subdevices: - a PWM chip: see ../pwm/atmel-hlcdc-pwm.txt - - a Display Controller: see ../display/atmel-hlcdc-dc.txt + - a Display Controller: see ../display/atmel/hlcdc-dc.txt Example: From 4ed91d48259d9ddd378424d008f2e6559f7e78f8 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Fri, 3 Mar 2017 15:41:47 +0100 Subject: [PATCH 04/24] dt-bindings: display: atmel: Fix path to atmel-hlcdc.txt The relative path pointed to Documentation/devicetree/bindings/display/mfd/atmel-hlcdc.txt instead of Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt Signed-off-by: Richard Genoud Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt b/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt index ebc1a914bda3..ec94468b35be 100644 --- a/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt +++ b/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt @@ -1,7 +1,7 @@ Device-Tree bindings for Atmel's HLCDC (High LCD Controller) DRM driver The Atmel HLCDC Display Controller is subdevice of the HLCDC MFD device. -See ../mfd/atmel-hlcdc.txt for more details. +See ../../mfd/atmel-hlcdc.txt for more details. Required properties: - compatible: value should be "atmel,hlcdc-display-controller" From b8c8963076cf973186a95e6a676fe991c6bac292 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Mon, 6 Mar 2017 18:44:49 +0100 Subject: [PATCH 05/24] dt-bindings: add vendor prefix for Dioo Dioo (http://http://www.dioo.com) design and produce power analog and mixed signal IC. Signed-off-by: Jerome Brunet Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 830c9987fa02..4a27b628ee36 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -79,6 +79,7 @@ denx Denx Software Engineering devantech Devantech, Ltd. digi Digi International Inc. digilent Diglent, Inc. +dioo Dioo Microcircuit Co., Ltd dlg Dialog Semiconductor dlink D-Link Corporation dmo Data Modul AG From b7e252fcddfa573bb1ee275b53bba6cef85671d4 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 6 Mar 2017 15:38:59 +0100 Subject: [PATCH 06/24] Documentation: devicetree: move trivial-devices out of I2C realm The I2C directory is for I2C master controllers, not for clients. So, move the file describing trivial devices one layer upwards where it fits its generic nature way better. Signed-off-by: Wolfram Sang Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/{i2c => }/trivial-devices.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Documentation/devicetree/bindings/{i2c => }/trivial-devices.txt (100%) diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/trivial-devices.txt similarity index 100% rename from Documentation/devicetree/bindings/i2c/trivial-devices.txt rename to Documentation/devicetree/bindings/trivial-devices.txt From bcf54d5385abaea9c8026aae6f4eeb348671a52d Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 16 Jan 2017 14:28:39 -0600 Subject: [PATCH 07/24] of: fix of_device_get_modalias returned length when truncating buffers If the length of the modalias is greater than the buffer size, then the modalias is truncated. However the untruncated length is returned which will cause an error. Fix this to return the truncated length. If an error in the case was desired, then then we should just return -ENOMEM. The reality is no device will ever have 4KB of compatible strings to hit this case. Signed-off-by: Rob Herring Cc: Frank Rowand --- drivers/of/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/device.c b/drivers/of/device.c index b1e6bebda3f3..210432a3c4ec 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -223,7 +223,7 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) str[i] = '_'; } - return tsize; + return repend; } EXPORT_SYMBOL_GPL(of_device_get_modalias); From 0634c2958927198797bf9e55d26fb51cce4c22b4 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 22 Mar 2017 09:16:27 -0500 Subject: [PATCH 08/24] of: Add function for generating a DT modalias with a newline The modalias sysfs attr is lacking a newline for DT aliases on platform devices. The macio and ibmebus correctly add the newline, but open code it. Introduce a new function, of_device_modalias(), that fills the buffer with the modalias including the newline and update users of the old of_device_get_modalias function. Signed-off-by: Rob Herring Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: Frank Rowand Cc: linuxppc-dev@lists.ozlabs.org Acked-by: Greg Kroah-Hartman --- arch/powerpc/platforms/pseries/ibmebus.c | 5 +---- drivers/base/platform.c | 2 +- drivers/macintosh/macio_sysfs.c | 7 +------ drivers/of/device.c | 18 ++++++++++++++++-- drivers/tty/serdev/core.c | 5 +---- drivers/usb/common/ulpi.c | 2 +- include/linux/of_device.h | 7 +++---- 7 files changed, 24 insertions(+), 22 deletions(-) diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c index 99a6bf7f3bcf..b363e439ddb9 100644 --- a/arch/powerpc/platforms/pseries/ibmebus.c +++ b/arch/powerpc/platforms/pseries/ibmebus.c @@ -410,10 +410,7 @@ static ssize_t name_show(struct device *dev, static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { - ssize_t len = of_device_get_modalias(dev, buf, PAGE_SIZE - 2); - buf[len] = '\n'; - buf[len+1] = 0; - return len+1; + return of_device_modalias(dev, buf, PAGE_SIZE); } static struct device_attribute ibmebus_bus_device_attrs[] = { diff --git a/drivers/base/platform.c b/drivers/base/platform.c index c2456839214a..a102152301c8 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -847,7 +847,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a, struct platform_device *pdev = to_platform_device(dev); int len; - len = of_device_get_modalias(dev, buf, PAGE_SIZE -1); + len = of_device_modalias(dev, buf, PAGE_SIZE); if (len != -ENODEV) return len; diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c index 8eb40afbd0f5..0b1f9c76c68d 100644 --- a/drivers/macintosh/macio_sysfs.c +++ b/drivers/macintosh/macio_sysfs.c @@ -41,12 +41,7 @@ compatible_show (struct device *dev, struct device_attribute *attr, char *buf) static ssize_t modalias_show (struct device *dev, struct device_attribute *attr, char *buf) { - int len = of_device_get_modalias(dev, buf, PAGE_SIZE - 2); - - buf[len] = '\n'; - buf[len+1] = 0; - - return len+1; + return of_device_modalias(dev, buf, PAGE_SIZE); } static ssize_t devspec_show(struct device *dev, diff --git a/drivers/of/device.c b/drivers/of/device.c index 210432a3c4ec..6e2f9113b1b7 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -176,7 +176,7 @@ const void *of_device_get_match_data(const struct device *dev) } EXPORT_SYMBOL(of_device_get_match_data); -ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) +static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) { const char *compat; int cplen, i; @@ -225,7 +225,6 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) return repend; } -EXPORT_SYMBOL_GPL(of_device_get_modalias); int of_device_request_module(struct device *dev) { @@ -250,6 +249,21 @@ int of_device_request_module(struct device *dev) } EXPORT_SYMBOL_GPL(of_device_request_module); +/** + * of_device_modalias - Fill buffer with newline terminated modalias string + */ +ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len) +{ + ssize_t sl = of_device_get_modalias(dev, str, len - 2); + if (sl < 0) + return sl; + + str[sl++] = '\n'; + str[sl] = 0; + return sl; +} +EXPORT_SYMBOL_GPL(of_device_modalias); + /** * of_device_uevent - Display OF related uevent information */ diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index f4c6c90add78..531aa89ff243 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -191,10 +191,7 @@ static int serdev_drv_remove(struct device *dev) static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { - ssize_t len = of_device_get_modalias(dev, buf, PAGE_SIZE - 2); - buf[len] = '\n'; - buf[len+1] = 0; - return len+1; + return of_device_modalias(dev, buf, PAGE_SIZE); } static struct device_attribute serdev_device_attrs[] = { diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c index c9480d77810c..930e8f35f8df 100644 --- a/drivers/usb/common/ulpi.c +++ b/drivers/usb/common/ulpi.c @@ -107,7 +107,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, int len; struct ulpi *ulpi = to_ulpi_dev(dev); - len = of_device_get_modalias(dev, buf, PAGE_SIZE - 1); + len = of_device_modalias(dev, buf, PAGE_SIZE); if (len != -ENODEV) return len; diff --git a/include/linux/of_device.h b/include/linux/of_device.h index c12dace043f3..169ea0bd8eb4 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -34,8 +34,7 @@ extern void of_device_unregister(struct platform_device *ofdev); extern const void *of_device_get_match_data(const struct device *dev); -extern ssize_t of_device_get_modalias(struct device *dev, - char *str, ssize_t len); +extern ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len); extern int of_device_request_module(struct device *dev); extern void of_device_uevent(struct device *dev, struct kobj_uevent_env *env); @@ -72,8 +71,8 @@ static inline const void *of_device_get_match_data(const struct device *dev) return NULL; } -static inline int of_device_get_modalias(struct device *dev, - char *str, ssize_t len) +static inline int of_device_modalias(struct device *dev, + char *str, ssize_t len) { return -ENODEV; } From 86cef6144d273404d8cb5c0b215ada8d23e5dbeb Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 21 Mar 2017 08:28:11 -0500 Subject: [PATCH 09/24] scripts/dtc: automate getting dtc version and log in update script Further automate the dtc update script to fill in the dtc version and commit log. Signed-off-by: Rob Herring --- scripts/dtc/update-dtc-source.sh | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/scripts/dtc/update-dtc-source.sh b/scripts/dtc/update-dtc-source.sh index f5cde799db03..c92e6bd9458d 100755 --- a/scripts/dtc/update-dtc-source.sh +++ b/scripts/dtc/update-dtc-source.sh @@ -36,10 +36,19 @@ DTC_SOURCE="checks.c data.c dtc.c dtc.h flattree.c fstree.c livetree.c srcpos.c DTC_GENERATED="dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h" LIBFDT_SOURCE="Makefile.libfdt fdt.c fdt.h fdt_empty_tree.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c fdt_wip.c libfdt.h libfdt_env.h libfdt_internal.h" +get_last_dtc_version() { + git log --oneline scripts/dtc/ | grep 'upstream' | head -1 | sed -e 's/^.* \(.*\)/\1/' +} + +last_dtc_ver=$(get_last_dtc_version) + # Build DTC cd $DTC_UPSTREAM_PATH make clean make check +dtc_version=$(git describe HEAD) +dtc_log=$(git log --oneline ${last_dtc_ver}..) + # Copy the files into the Linux tree cd $DTC_LINUX_PATH @@ -60,4 +69,12 @@ sed -i -- 's/#include /#include "libfdt_env.h"/g' ./libfdt/libfdt. sed -i -- 's/#include /#include "fdt.h"/g' ./libfdt/libfdt.h git add ./libfdt/libfdt.h -git commit -e -v -m "scripts/dtc: Update to upstream version [CHANGEME]" +commit_msg=$(cat << EOF +scripts/dtc: Update to upstream version ${dtc_version} + +This adds the following commits from upstream: + +${dtc_log} +EOF +) +git commit -e -v -s -m "${commit_msg}" From 89d123106a97bf412a4c10482044c822f4b069f7 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 21 Mar 2017 09:01:08 -0500 Subject: [PATCH 10/24] scripts/dtc: Update to upstream version v1.4.4-8-g756ffc4f52f6 This adds the following commits from upstream: 756ffc4f52f6 Build pylibfdt as part of the normal build process 8cb3896358e9 Adjust libfdt.h to work with swig b40aa8359aff Mention pylibfdt in the documentation 12cfb740cc76 Add tests for pylibfdt 50f250701631 Add an initial Python library for libfdt cdbb2b6c7a3a checks: Warn on node name unit-addresses with '0x' or leading 0s 4c15d5da17cc checks: Add bus checks for simple-bus buses 33c3985226d3 checks: Add bus checks for PCI buses 558cd81bdd43 dtc: Bump version to v1.4.4 c17a811c62eb fdtput: Remove star from value_len documentation 194d5caaefcb fdtget: Use @return to document the return value d922ecdd017b tests: Make realloc_fdt() really allocate *fdt 921cc17fec29 libfdt: overlay: Check the value of the right variable 9ffdf60bf463 dtc: Simplify asm_emit_string() implementation 881012e44386 libfdt: Change names of sparse helper macros bad5b28049e5 Fix assorted sparse warnings 672ac09ea04d Clean up gcc attributes 49300f2ade6a dtc: Don't abuse struct fdt_reserve_entry fa8bc7f928ac dtc: Bump version to v1.4.3 34a9886a177f Add printf format attributes f72508e2b6ca Correct some broken printf() like format mismatches 397d5ef0203c libfdt: Add fdt_setprop_empty() 69a1bd6ad3f9 libfdt: Remove undefined behaviour setting empty properties acd1b534a592 Print output filename as part of warning messages 120775eb1cf3 dtc: Use streq() in preference to strcmp() 852e9ecbe197 checks: Add Warning for stricter node name character checking ef0e8f061534 checks: Add Warning for stricter property name character checking 00d7bb1f4b0e dtc: pos parameter to srcpos_string() can't be NULL 95d57726bca4 livetree.c: Fix memory leak 3b9c97093d6e dtc: Fix NULL pointer use in dtlabel + dtref case 43eb551426ea manual: Fix typo it -> in 4baf15f7f13f Makefile: Add tags rule Signed-off-by: Rob Herring --- scripts/dtc/checks.c | 361 +++++++++++++++++++++++---- scripts/dtc/data.c | 16 +- scripts/dtc/dtc-lexer.l | 3 +- scripts/dtc/dtc-lexer.lex.c_shipped | 77 +++--- scripts/dtc/dtc-parser.tab.c_shipped | 6 +- scripts/dtc/dtc-parser.y | 6 +- scripts/dtc/dtc.c | 9 +- scripts/dtc/dtc.h | 11 +- scripts/dtc/flattree.c | 58 ++--- scripts/dtc/libfdt/fdt_rw.c | 3 +- scripts/dtc/libfdt/libfdt.h | 51 +++- scripts/dtc/libfdt/libfdt_env.h | 26 +- scripts/dtc/livetree.c | 22 +- scripts/dtc/srcpos.c | 2 +- scripts/dtc/srcpos.h | 11 +- scripts/dtc/treesource.c | 6 +- scripts/dtc/util.c | 11 +- scripts/dtc/util.h | 24 +- scripts/dtc/version_gen.h | 2 +- 19 files changed, 523 insertions(+), 182 deletions(-) diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c index 3d18e45374c8..5adfc8f52b4f 100644 --- a/scripts/dtc/checks.c +++ b/scripts/dtc/checks.c @@ -72,17 +72,16 @@ struct check { #define CHECK(_nm, _fn, _d, ...) \ CHECK_ENTRY(_nm, _fn, _d, false, false, __VA_ARGS__) -#ifdef __GNUC__ -static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3))); -#endif -static inline void check_msg(struct check *c, const char *fmt, ...) +static inline void PRINTF(3, 4) check_msg(struct check *c, struct dt_info *dti, + const char *fmt, ...) { va_list ap; va_start(ap, fmt); if ((c->warn && (quiet < 1)) || (c->error && (quiet < 2))) { - fprintf(stderr, "%s (%s): ", + fprintf(stderr, "%s: %s (%s): ", + strcmp(dti->outname, "-") ? dti->outname : "", (c->error) ? "ERROR" : "Warning", c->name); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); @@ -90,11 +89,11 @@ static inline void check_msg(struct check *c, const char *fmt, ...) va_end(ap); } -#define FAIL(c, ...) \ - do { \ - TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ - (c)->status = FAILED; \ - check_msg((c), __VA_ARGS__); \ +#define FAIL(c, dti, ...) \ + do { \ + TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ + (c)->status = FAILED; \ + check_msg((c), dti, __VA_ARGS__); \ } while (0) static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node) @@ -127,7 +126,7 @@ static bool run_check(struct check *c, struct dt_info *dti) error = error || run_check(prq, dti); if (prq->status != PASSED) { c->status = PREREQ; - check_msg(c, "Failed prerequisite '%s'", + check_msg(c, dti, "Failed prerequisite '%s'", c->prereq[i]->name); } } @@ -157,7 +156,7 @@ out: static inline void check_always_fail(struct check *c, struct dt_info *dti, struct node *node) { - FAIL(c, "always_fail check"); + FAIL(c, dti, "always_fail check"); } CHECK(always_fail, check_always_fail, NULL); @@ -172,7 +171,7 @@ static void check_is_string(struct check *c, struct dt_info *dti, return; /* Not present, assumed ok */ if (!data_is_one_string(prop->val)) - FAIL(c, "\"%s\" property in %s is not a string", + FAIL(c, dti, "\"%s\" property in %s is not a string", propname, node->fullpath); } #define WARNING_IF_NOT_STRING(nm, propname) \ @@ -191,7 +190,7 @@ static void check_is_cell(struct check *c, struct dt_info *dti, return; /* Not present, assumed ok */ if (prop->val.len != sizeof(cell_t)) - FAIL(c, "\"%s\" property in %s is not a single cell", + FAIL(c, dti, "\"%s\" property in %s is not a single cell", propname, node->fullpath); } #define WARNING_IF_NOT_CELL(nm, propname) \ @@ -213,7 +212,7 @@ static void check_duplicate_node_names(struct check *c, struct dt_info *dti, child2; child2 = child2->next_sibling) if (streq(child->name, child2->name)) - FAIL(c, "Duplicate node name %s", + FAIL(c, dti, "Duplicate node name %s", child->fullpath); } ERROR(duplicate_node_names, check_duplicate_node_names, NULL); @@ -228,7 +227,7 @@ static void check_duplicate_property_names(struct check *c, struct dt_info *dti, if (prop2->deleted) continue; if (streq(prop->name, prop2->name)) - FAIL(c, "Duplicate property name %s in %s", + FAIL(c, dti, "Duplicate property name %s in %s", prop->name, node->fullpath); } } @@ -239,6 +238,7 @@ ERROR(duplicate_property_names, check_duplicate_property_names, NULL); #define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ" #define DIGITS "0123456789" #define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-" +#define PROPNODECHARSSTRICT LOWERCASE UPPERCASE DIGITS ",-" static void check_node_name_chars(struct check *c, struct dt_info *dti, struct node *node) @@ -246,16 +246,27 @@ static void check_node_name_chars(struct check *c, struct dt_info *dti, int n = strspn(node->name, c->data); if (n < strlen(node->name)) - FAIL(c, "Bad character '%c' in node %s", + FAIL(c, dti, "Bad character '%c' in node %s", node->name[n], node->fullpath); } ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@"); +static void check_node_name_chars_strict(struct check *c, struct dt_info *dti, + struct node *node) +{ + int n = strspn(node->name, c->data); + + if (n < node->basenamelen) + FAIL(c, dti, "Character '%c' not recommended in node %s", + node->name[n], node->fullpath); +} +CHECK(node_name_chars_strict, check_node_name_chars_strict, PROPNODECHARSSTRICT); + static void check_node_name_format(struct check *c, struct dt_info *dti, struct node *node) { if (strchr(get_unitname(node), '@')) - FAIL(c, "Node %s has multiple '@' characters in name", + FAIL(c, dti, "Node %s has multiple '@' characters in name", node->fullpath); } ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars); @@ -274,11 +285,11 @@ static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti, if (prop) { if (!unitname[0]) - FAIL(c, "Node %s has a reg or ranges property, but no unit name", + FAIL(c, dti, "Node %s has a reg or ranges property, but no unit name", node->fullpath); } else { if (unitname[0]) - FAIL(c, "Node %s has a unit name, but no reg property", + FAIL(c, dti, "Node %s has a unit name, but no reg property", node->fullpath); } } @@ -293,12 +304,44 @@ static void check_property_name_chars(struct check *c, struct dt_info *dti, int n = strspn(prop->name, c->data); if (n < strlen(prop->name)) - FAIL(c, "Bad character '%c' in property name \"%s\", node %s", + FAIL(c, dti, "Bad character '%c' in property name \"%s\", node %s", prop->name[n], prop->name, node->fullpath); } } ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS); +static void check_property_name_chars_strict(struct check *c, + struct dt_info *dti, + struct node *node) +{ + struct property *prop; + + for_each_property(node, prop) { + const char *name = prop->name; + int n = strspn(name, c->data); + + if (n == strlen(prop->name)) + continue; + + /* Certain names are whitelisted */ + if (streq(name, "device_type")) + continue; + + /* + * # is only allowed at the beginning of property names not counting + * the vendor prefix. + */ + if (name[n] == '#' && ((n == 0) || (name[n-1] == ','))) { + name += n + 1; + n = strspn(name, c->data); + } + if (n < strlen(name)) + FAIL(c, dti, "Character '%c' not recommended in property name \"%s\", node %s", + name[n], prop->name, node->fullpath); + } +} +CHECK(property_name_chars_strict, check_property_name_chars_strict, PROPNODECHARSSTRICT); + #define DESCLABEL_FMT "%s%s%s%s%s" #define DESCLABEL_ARGS(node,prop,mark) \ ((mark) ? "value of " : ""), \ @@ -327,7 +370,7 @@ static void check_duplicate_label(struct check *c, struct dt_info *dti, return; if ((othernode != node) || (otherprop != prop) || (othermark != mark)) - FAIL(c, "Duplicate label '%s' on " DESCLABEL_FMT + FAIL(c, dti, "Duplicate label '%s' on " DESCLABEL_FMT " and " DESCLABEL_FMT, label, DESCLABEL_ARGS(node, prop, mark), DESCLABEL_ARGS(othernode, otherprop, othermark)); @@ -367,7 +410,7 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, return 0; if (prop->val.len != sizeof(cell_t)) { - FAIL(c, "%s has bad length (%d) %s property", + FAIL(c, dti, "%s has bad length (%d) %s property", node->fullpath, prop->val.len, prop->name); return 0; } @@ -379,7 +422,7 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, /* "Set this node's phandle equal to some * other node's phandle". That's nonsensical * by construction. */ { - FAIL(c, "%s in %s is a reference to another node", + FAIL(c, dti, "%s in %s is a reference to another node", prop->name, node->fullpath); } /* But setting this node's phandle equal to its own @@ -393,7 +436,7 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, phandle = propval_cell(prop); if ((phandle == 0) || (phandle == -1)) { - FAIL(c, "%s has bad value (0x%x) in %s property", + FAIL(c, dti, "%s has bad value (0x%x) in %s property", node->fullpath, phandle, prop->name); return 0; } @@ -420,7 +463,7 @@ static void check_explicit_phandles(struct check *c, struct dt_info *dti, return; if (linux_phandle && phandle && (phandle != linux_phandle)) - FAIL(c, "%s has mismatching 'phandle' and 'linux,phandle'" + FAIL(c, dti, "%s has mismatching 'phandle' and 'linux,phandle'" " properties", node->fullpath); if (linux_phandle && !phandle) @@ -428,7 +471,7 @@ static void check_explicit_phandles(struct check *c, struct dt_info *dti, other = get_node_by_phandle(root, phandle); if (other && (other != node)) { - FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)", + FAIL(c, dti, "%s has duplicated phandle 0x%x (seen before at %s)", node->fullpath, phandle, other->fullpath); return; } @@ -453,7 +496,7 @@ static void check_name_properties(struct check *c, struct dt_info *dti, if ((prop->val.len != node->basenamelen+1) || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) { - FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead" + FAIL(c, dti, "\"name\" property in %s is incorrect (\"%s\" instead" " of base node name)", node->fullpath, prop->val.val); } else { /* The name property is correct, and therefore redundant. @@ -488,16 +531,16 @@ static void fixup_phandle_references(struct check *c, struct dt_info *dti, refnode = get_node_by_ref(dt, m->ref); if (! refnode) { if (!(dti->dtsflags & DTSF_PLUGIN)) - FAIL(c, "Reference to non-existent node or " + FAIL(c, dti, "Reference to non-existent node or " "label \"%s\"\n", m->ref); else /* mark the entry as unresolved */ - *((cell_t *)(prop->val.val + m->offset)) = + *((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(0xffffffff); continue; } phandle = get_node_phandle(dt, refnode); - *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); + *((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); } } } @@ -520,7 +563,7 @@ static void fixup_path_references(struct check *c, struct dt_info *dti, refnode = get_node_by_ref(dt, m->ref); if (!refnode) { - FAIL(c, "Reference to non-existent node or label \"%s\"\n", + FAIL(c, dti, "Reference to non-existent node or label \"%s\"\n", m->ref); continue; } @@ -579,19 +622,19 @@ static void check_reg_format(struct check *c, struct dt_info *dti, return; /* No "reg", that's fine */ if (!node->parent) { - FAIL(c, "Root node has a \"reg\" property"); + FAIL(c, dti, "Root node has a \"reg\" property"); return; } if (prop->val.len == 0) - FAIL(c, "\"reg\" property in %s is empty", node->fullpath); + FAIL(c, dti, "\"reg\" property in %s is empty", node->fullpath); addr_cells = node_addr_cells(node->parent); size_cells = node_size_cells(node->parent); entrylen = (addr_cells + size_cells) * sizeof(cell_t); if (!entrylen || (prop->val.len % entrylen) != 0) - FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) " + FAIL(c, dti, "\"reg\" property in %s has invalid length (%d bytes) " "(#address-cells == %d, #size-cells == %d)", node->fullpath, prop->val.len, addr_cells, size_cells); } @@ -608,7 +651,7 @@ static void check_ranges_format(struct check *c, struct dt_info *dti, return; if (!node->parent) { - FAIL(c, "Root node has a \"ranges\" property"); + FAIL(c, dti, "Root node has a \"ranges\" property"); return; } @@ -620,17 +663,17 @@ static void check_ranges_format(struct check *c, struct dt_info *dti, if (prop->val.len == 0) { if (p_addr_cells != c_addr_cells) - FAIL(c, "%s has empty \"ranges\" property but its " + FAIL(c, dti, "%s has empty \"ranges\" property but its " "#address-cells (%d) differs from %s (%d)", node->fullpath, c_addr_cells, node->parent->fullpath, p_addr_cells); if (p_size_cells != c_size_cells) - FAIL(c, "%s has empty \"ranges\" property but its " + FAIL(c, dti, "%s has empty \"ranges\" property but its " "#size-cells (%d) differs from %s (%d)", node->fullpath, c_size_cells, node->parent->fullpath, p_size_cells); } else if ((prop->val.len % entrylen) != 0) { - FAIL(c, "\"ranges\" property in %s has invalid length (%d bytes) " + FAIL(c, dti, "\"ranges\" property in %s has invalid length (%d bytes) " "(parent #address-cells == %d, child #address-cells == %d, " "#size-cells == %d)", node->fullpath, prop->val.len, p_addr_cells, c_addr_cells, c_size_cells); @@ -638,6 +681,229 @@ static void check_ranges_format(struct check *c, struct dt_info *dti, } WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells); +static const struct bus_type pci_bus = { + .name = "PCI", +}; + +static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *node) +{ + struct property *prop; + cell_t *cells; + + prop = get_property(node, "device_type"); + if (!prop || !streq(prop->val.val, "pci")) + return; + + node->bus = &pci_bus; + + if (!strneq(node->name, "pci", node->basenamelen) && + !strneq(node->name, "pcie", node->basenamelen)) + FAIL(c, dti, "Node %s node name is not \"pci\" or \"pcie\"", + node->fullpath); + + prop = get_property(node, "ranges"); + if (!prop) + FAIL(c, dti, "Node %s missing ranges for PCI bridge (or not a bridge)", + node->fullpath); + + if (node_addr_cells(node) != 3) + FAIL(c, dti, "Node %s incorrect #address-cells for PCI bridge", + node->fullpath); + if (node_size_cells(node) != 2) + FAIL(c, dti, "Node %s incorrect #size-cells for PCI bridge", + node->fullpath); + + prop = get_property(node, "bus-range"); + if (!prop) { + FAIL(c, dti, "Node %s missing bus-range for PCI bridge", + node->fullpath); + return; + } + if (prop->val.len != (sizeof(cell_t) * 2)) { + FAIL(c, dti, "Node %s bus-range must be 2 cells", + node->fullpath); + return; + } + cells = (cell_t *)prop->val.val; + if (fdt32_to_cpu(cells[0]) > fdt32_to_cpu(cells[1])) + FAIL(c, dti, "Node %s bus-range 1st cell must be less than or equal to 2nd cell", + node->fullpath); + if (fdt32_to_cpu(cells[1]) > 0xff) + FAIL(c, dti, "Node %s bus-range maximum bus number must be less than 256", + node->fullpath); +} +WARNING(pci_bridge, check_pci_bridge, NULL, + &device_type_is_string, &addr_size_cells); + +static void check_pci_device_bus_num(struct check *c, struct dt_info *dti, struct node *node) +{ + struct property *prop; + unsigned int bus_num, min_bus, max_bus; + cell_t *cells; + + if (!node->parent || (node->parent->bus != &pci_bus)) + return; + + prop = get_property(node, "reg"); + if (!prop) + return; + + cells = (cell_t *)prop->val.val; + bus_num = (fdt32_to_cpu(cells[0]) & 0x00ff0000) >> 16; + + prop = get_property(node->parent, "bus-range"); + if (!prop) { + min_bus = max_bus = 0; + } else { + cells = (cell_t *)prop->val.val; + min_bus = fdt32_to_cpu(cells[0]); + max_bus = fdt32_to_cpu(cells[0]); + } + if ((bus_num < min_bus) || (bus_num > max_bus)) + FAIL(c, dti, "Node %s PCI bus number %d out of range, expected (%d - %d)", + node->fullpath, bus_num, min_bus, max_bus); +} +WARNING(pci_device_bus_num, check_pci_device_bus_num, NULL, ®_format, &pci_bridge); + +static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct node *node) +{ + struct property *prop; + const char *unitname = get_unitname(node); + char unit_addr[5]; + unsigned int dev, func, reg; + cell_t *cells; + + if (!node->parent || (node->parent->bus != &pci_bus)) + return; + + prop = get_property(node, "reg"); + if (!prop) { + FAIL(c, dti, "Node %s missing PCI reg property", node->fullpath); + return; + } + + cells = (cell_t *)prop->val.val; + if (cells[1] || cells[2]) + FAIL(c, dti, "Node %s PCI reg config space address cells 2 and 3 must be 0", + node->fullpath); + + reg = fdt32_to_cpu(cells[0]); + dev = (reg & 0xf800) >> 11; + func = (reg & 0x700) >> 8; + + if (reg & 0xff000000) + FAIL(c, dti, "Node %s PCI reg address is not configuration space", + node->fullpath); + if (reg & 0x000000ff) + FAIL(c, dti, "Node %s PCI reg config space address register number must be 0", + node->fullpath); + + if (func == 0) { + snprintf(unit_addr, sizeof(unit_addr), "%x", dev); + if (streq(unitname, unit_addr)) + return; + } + + snprintf(unit_addr, sizeof(unit_addr), "%x,%x", dev, func); + if (streq(unitname, unit_addr)) + return; + + FAIL(c, dti, "Node %s PCI unit address format error, expected \"%s\"", + node->fullpath, unit_addr); +} +WARNING(pci_device_reg, check_pci_device_reg, NULL, ®_format, &pci_bridge); + +static const struct bus_type simple_bus = { + .name = "simple-bus", +}; + +static bool node_is_compatible(struct node *node, const char *compat) +{ + struct property *prop; + const char *str, *end; + + prop = get_property(node, "compatible"); + if (!prop) + return false; + + for (str = prop->val.val, end = str + prop->val.len; str < end; + str += strnlen(str, end - str) + 1) { + if (strneq(str, compat, end - str)) + return true; + } + return false; +} + +static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct node *node) +{ + if (node_is_compatible(node, "simple-bus")) + node->bus = &simple_bus; +} +WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL, &addr_size_cells); + +static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node) +{ + struct property *prop; + const char *unitname = get_unitname(node); + char unit_addr[17]; + unsigned int size; + uint64_t reg = 0; + cell_t *cells = NULL; + + if (!node->parent || (node->parent->bus != &simple_bus)) + return; + + prop = get_property(node, "reg"); + if (prop) + cells = (cell_t *)prop->val.val; + else { + prop = get_property(node, "ranges"); + if (prop && prop->val.len) + /* skip of child address */ + cells = ((cell_t *)prop->val.val) + node_addr_cells(node); + } + + if (!cells) { + if (node->parent->parent && !(node->bus == &simple_bus)) + FAIL(c, dti, "Node %s missing or empty reg/ranges property", node->fullpath); + return; + } + + size = node_addr_cells(node->parent); + while (size--) + reg = (reg << 32) | fdt32_to_cpu(*(cells++)); + + snprintf(unit_addr, sizeof(unit_addr), "%lx", reg); + if (!streq(unitname, unit_addr)) + FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"", + node->fullpath, unit_addr); +} +WARNING(simple_bus_reg, check_simple_bus_reg, NULL, ®_format, &simple_bus_bridge); + +static void check_unit_address_format(struct check *c, struct dt_info *dti, + struct node *node) +{ + const char *unitname = get_unitname(node); + + if (node->parent && node->parent->bus) + return; + + if (!unitname[0]) + return; + + if (!strncmp(unitname, "0x", 2)) { + FAIL(c, dti, "Node %s unit name should not have leading \"0x\"", + node->fullpath); + /* skip over 0x for next test */ + unitname += 2; + } + if (unitname[0] == '0' && isxdigit(unitname[1])) + FAIL(c, dti, "Node %s unit name should not have leading 0s", + node->fullpath); +} +WARNING(unit_address_format, check_unit_address_format, NULL, + &node_name_format, &pci_bridge, &simple_bus_bridge); + /* * Style checks */ @@ -656,11 +922,11 @@ static void check_avoid_default_addr_size(struct check *c, struct dt_info *dti, return; if (node->parent->addr_cells == -1) - FAIL(c, "Relying on default #address-cells value for %s", + FAIL(c, dti, "Relying on default #address-cells value for %s", node->fullpath); if (node->parent->size_cells == -1) - FAIL(c, "Relying on default #size-cells value for %s", + FAIL(c, dti, "Relying on default #size-cells value for %s", node->fullpath); } WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL, @@ -684,7 +950,7 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c, prop = get_property(chosen, "interrupt-controller"); if (prop) - FAIL(c, "/chosen has obsolete \"interrupt-controller\" " + FAIL(c, dti, "/chosen has obsolete \"interrupt-controller\" " "property"); } WARNING(obsolete_chosen_interrupt_controller, @@ -703,9 +969,20 @@ static struct check *check_table[] = { &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell, &device_type_is_string, &model_is_string, &status_is_string, + &property_name_chars_strict, + &node_name_chars_strict, + &addr_size_cells, ®_format, &ranges_format, &unit_address_vs_reg, + &unit_address_format, + + &pci_bridge, + &pci_device_reg, + &pci_device_bus_num, + + &simple_bus_bridge, + &simple_bus_reg, &avoid_default_addr_size, &obsolete_chosen_interrupt_controller, diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c index 8cae23746882..aa37a16c8891 100644 --- a/scripts/dtc/data.c +++ b/scripts/dtc/data.c @@ -171,9 +171,9 @@ struct data data_merge(struct data d1, struct data d2) struct data data_append_integer(struct data d, uint64_t value, int bits) { uint8_t value_8; - uint16_t value_16; - uint32_t value_32; - uint64_t value_64; + fdt16_t value_16; + fdt32_t value_32; + fdt64_t value_64; switch (bits) { case 8: @@ -197,14 +197,14 @@ struct data data_append_integer(struct data d, uint64_t value, int bits) } } -struct data data_append_re(struct data d, const struct fdt_reserve_entry *re) +struct data data_append_re(struct data d, uint64_t address, uint64_t size) { - struct fdt_reserve_entry bere; + struct fdt_reserve_entry re; - bere.address = cpu_to_fdt64(re->address); - bere.size = cpu_to_fdt64(re->size); + re.address = cpu_to_fdt64(address); + re.size = cpu_to_fdt64(size); - return data_append_data(d, &bere, sizeof(bere)); + return data_append_data(d, &re, sizeof(re)); } struct data data_append_cell(struct data d, cell_t word) diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l index c600603044f3..fd825ebba69c 100644 --- a/scripts/dtc/dtc-lexer.l +++ b/scripts/dtc/dtc-lexer.l @@ -62,7 +62,8 @@ static int dts_version = 1; static void push_input_file(const char *filename); static bool pop_input_file(void); -static void lexical_error(const char *fmt, ...); +static void PRINTF(1, 2) lexical_error(const char *fmt, ...); + %} %% diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped index 2c862bc86ad0..64c243772398 100644 --- a/scripts/dtc/dtc-lexer.lex.c_shipped +++ b/scripts/dtc/dtc-lexer.lex.c_shipped @@ -655,8 +655,9 @@ static int dts_version = 1; static void push_input_file(const char *filename); static bool pop_input_file(void); -static void lexical_error(const char *fmt, ...); -#line 660 "dtc-lexer.lex.c" +static void PRINTF(1, 2) lexical_error(const char *fmt, ...); + +#line 661 "dtc-lexer.lex.c" #define INITIAL 0 #define BYTESTRING 1 @@ -878,9 +879,9 @@ YY_DECL } { -#line 68 "dtc-lexer.l" +#line 69 "dtc-lexer.l" -#line 884 "dtc-lexer.lex.c" +#line 885 "dtc-lexer.lex.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@ -937,7 +938,7 @@ do_action: /* This label is used only to access EOF actions. */ case 1: /* rule 1 can match eol */ YY_RULE_SETUP -#line 69 "dtc-lexer.l" +#line 70 "dtc-lexer.l" { char *name = strchr(yytext, '\"') + 1; yytext[yyleng-1] = '\0'; @@ -947,7 +948,7 @@ YY_RULE_SETUP case 2: /* rule 2 can match eol */ YY_RULE_SETUP -#line 75 "dtc-lexer.l" +#line 76 "dtc-lexer.l" { char *line, *fnstart, *fnend; struct data fn; @@ -981,7 +982,7 @@ case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(BYTESTRING): case YY_STATE_EOF(PROPNODENAME): case YY_STATE_EOF(V1): -#line 104 "dtc-lexer.l" +#line 105 "dtc-lexer.l" { if (!pop_input_file()) { yyterminate(); @@ -991,7 +992,7 @@ case YY_STATE_EOF(V1): case 3: /* rule 3 can match eol */ YY_RULE_SETUP -#line 110 "dtc-lexer.l" +#line 111 "dtc-lexer.l" { DPRINT("String: %s\n", yytext); yylval.data = data_copy_escape_string(yytext+1, @@ -1001,7 +1002,7 @@ YY_RULE_SETUP YY_BREAK case 4: YY_RULE_SETUP -#line 117 "dtc-lexer.l" +#line 118 "dtc-lexer.l" { DPRINT("Keyword: /dts-v1/\n"); dts_version = 1; @@ -1011,7 +1012,7 @@ YY_RULE_SETUP YY_BREAK case 5: YY_RULE_SETUP -#line 124 "dtc-lexer.l" +#line 125 "dtc-lexer.l" { DPRINT("Keyword: /plugin/\n"); return DT_PLUGIN; @@ -1019,7 +1020,7 @@ YY_RULE_SETUP YY_BREAK case 6: YY_RULE_SETUP -#line 129 "dtc-lexer.l" +#line 130 "dtc-lexer.l" { DPRINT("Keyword: /memreserve/\n"); BEGIN_DEFAULT(); @@ -1028,7 +1029,7 @@ YY_RULE_SETUP YY_BREAK case 7: YY_RULE_SETUP -#line 135 "dtc-lexer.l" +#line 136 "dtc-lexer.l" { DPRINT("Keyword: /bits/\n"); BEGIN_DEFAULT(); @@ -1037,7 +1038,7 @@ YY_RULE_SETUP YY_BREAK case 8: YY_RULE_SETUP -#line 141 "dtc-lexer.l" +#line 142 "dtc-lexer.l" { DPRINT("Keyword: /delete-property/\n"); DPRINT("\n"); @@ -1047,7 +1048,7 @@ YY_RULE_SETUP YY_BREAK case 9: YY_RULE_SETUP -#line 148 "dtc-lexer.l" +#line 149 "dtc-lexer.l" { DPRINT("Keyword: /delete-node/\n"); DPRINT("\n"); @@ -1057,7 +1058,7 @@ YY_RULE_SETUP YY_BREAK case 10: YY_RULE_SETUP -#line 155 "dtc-lexer.l" +#line 156 "dtc-lexer.l" { DPRINT("Label: %s\n", yytext); yylval.labelref = xstrdup(yytext); @@ -1067,7 +1068,7 @@ YY_RULE_SETUP YY_BREAK case 11: YY_RULE_SETUP -#line 162 "dtc-lexer.l" +#line 163 "dtc-lexer.l" { char *e; DPRINT("Integer Literal: '%s'\n", yytext); @@ -1093,7 +1094,7 @@ YY_RULE_SETUP case 12: /* rule 12 can match eol */ YY_RULE_SETUP -#line 184 "dtc-lexer.l" +#line 185 "dtc-lexer.l" { struct data d; DPRINT("Character literal: %s\n", yytext); @@ -1117,7 +1118,7 @@ YY_RULE_SETUP YY_BREAK case 13: YY_RULE_SETUP -#line 205 "dtc-lexer.l" +#line 206 "dtc-lexer.l" { /* label reference */ DPRINT("Ref: %s\n", yytext+1); yylval.labelref = xstrdup(yytext+1); @@ -1126,7 +1127,7 @@ YY_RULE_SETUP YY_BREAK case 14: YY_RULE_SETUP -#line 211 "dtc-lexer.l" +#line 212 "dtc-lexer.l" { /* new-style path reference */ yytext[yyleng-1] = '\0'; DPRINT("Ref: %s\n", yytext+2); @@ -1136,7 +1137,7 @@ YY_RULE_SETUP YY_BREAK case 15: YY_RULE_SETUP -#line 218 "dtc-lexer.l" +#line 219 "dtc-lexer.l" { yylval.byte = strtol(yytext, NULL, 16); DPRINT("Byte: %02x\n", (int)yylval.byte); @@ -1145,7 +1146,7 @@ YY_RULE_SETUP YY_BREAK case 16: YY_RULE_SETUP -#line 224 "dtc-lexer.l" +#line 225 "dtc-lexer.l" { DPRINT("/BYTESTRING\n"); BEGIN_DEFAULT(); @@ -1154,7 +1155,7 @@ YY_RULE_SETUP YY_BREAK case 17: YY_RULE_SETUP -#line 230 "dtc-lexer.l" +#line 231 "dtc-lexer.l" { DPRINT("PropNodeName: %s\n", yytext); yylval.propnodename = xstrdup((yytext[0] == '\\') ? @@ -1165,7 +1166,7 @@ YY_RULE_SETUP YY_BREAK case 18: YY_RULE_SETUP -#line 238 "dtc-lexer.l" +#line 239 "dtc-lexer.l" { DPRINT("Binary Include\n"); return DT_INCBIN; @@ -1174,64 +1175,64 @@ YY_RULE_SETUP case 19: /* rule 19 can match eol */ YY_RULE_SETUP -#line 243 "dtc-lexer.l" +#line 244 "dtc-lexer.l" /* eat whitespace */ YY_BREAK case 20: /* rule 20 can match eol */ YY_RULE_SETUP -#line 244 "dtc-lexer.l" +#line 245 "dtc-lexer.l" /* eat C-style comments */ YY_BREAK case 21: /* rule 21 can match eol */ YY_RULE_SETUP -#line 245 "dtc-lexer.l" +#line 246 "dtc-lexer.l" /* eat C++-style comments */ YY_BREAK case 22: YY_RULE_SETUP -#line 247 "dtc-lexer.l" +#line 248 "dtc-lexer.l" { return DT_LSHIFT; }; YY_BREAK case 23: YY_RULE_SETUP -#line 248 "dtc-lexer.l" +#line 249 "dtc-lexer.l" { return DT_RSHIFT; }; YY_BREAK case 24: YY_RULE_SETUP -#line 249 "dtc-lexer.l" +#line 250 "dtc-lexer.l" { return DT_LE; }; YY_BREAK case 25: YY_RULE_SETUP -#line 250 "dtc-lexer.l" +#line 251 "dtc-lexer.l" { return DT_GE; }; YY_BREAK case 26: YY_RULE_SETUP -#line 251 "dtc-lexer.l" +#line 252 "dtc-lexer.l" { return DT_EQ; }; YY_BREAK case 27: YY_RULE_SETUP -#line 252 "dtc-lexer.l" +#line 253 "dtc-lexer.l" { return DT_NE; }; YY_BREAK case 28: YY_RULE_SETUP -#line 253 "dtc-lexer.l" +#line 254 "dtc-lexer.l" { return DT_AND; }; YY_BREAK case 29: YY_RULE_SETUP -#line 254 "dtc-lexer.l" +#line 255 "dtc-lexer.l" { return DT_OR; }; YY_BREAK case 30: YY_RULE_SETUP -#line 256 "dtc-lexer.l" +#line 257 "dtc-lexer.l" { DPRINT("Char: %c (\\x%02x)\n", yytext[0], (unsigned)yytext[0]); @@ -1249,10 +1250,10 @@ YY_RULE_SETUP YY_BREAK case 31: YY_RULE_SETUP -#line 271 "dtc-lexer.l" +#line 272 "dtc-lexer.l" ECHO; YY_BREAK -#line 1256 "dtc-lexer.lex.c" +#line 1257 "dtc-lexer.lex.c" case YY_END_OF_BUFFER: { @@ -2218,7 +2219,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 271 "dtc-lexer.l" +#line 272 "dtc-lexer.l" diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped index 2965227a1b4a..0a7a5ed86f04 100644 --- a/scripts/dtc/dtc-parser.tab.c_shipped +++ b/scripts/dtc/dtc-parser.tab.c_shipped @@ -1557,10 +1557,10 @@ yyreduce: { struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); - add_label(&target->labels, (yyvsp[-2].labelref)); - if (target) + if (target) { + add_label(&target->labels, (yyvsp[-2].labelref)); merge_nodes(target, (yyvsp[0].node)); - else + } else ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); (yyval.node) = (yyvsp[-3].node); } diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y index b2fd4d155839..ca3f5003427c 100644 --- a/scripts/dtc/dtc-parser.y +++ b/scripts/dtc/dtc-parser.y @@ -171,10 +171,10 @@ devicetree: { struct node *target = get_node_by_ref($1, $3); - add_label(&target->labels, $2); - if (target) + if (target) { + add_label(&target->labels, $2); merge_nodes(target, $4); - else + } else ERROR(&@3, "Label or path %s not found", $3); $$ = $1; } diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c index a4edf4c7aebf..f5eed9d72c02 100644 --- a/scripts/dtc/dtc.c +++ b/scripts/dtc/dtc.c @@ -138,7 +138,7 @@ static const char *guess_type_by_name(const char *fname, const char *fallback) static const char *guess_input_format(const char *fname, const char *fallback) { struct stat statbuf; - uint32_t magic; + fdt32_t magic; FILE *f; if (stat(fname, &statbuf) != 0) @@ -159,8 +159,7 @@ static const char *guess_input_format(const char *fname, const char *fallback) } fclose(f); - magic = fdt32_to_cpu(magic); - if (magic == FDT_MAGIC) + if (fdt32_to_cpu(magic) == FDT_MAGIC) return "dtb"; return guess_type_by_name(fname, fallback); @@ -216,7 +215,7 @@ int main(int argc, char *argv[]) alignsize = strtol(optarg, NULL, 0); if (!is_power_of_2(alignsize)) die("Invalid argument \"%d\" to -a option\n", - optarg); + alignsize); break; case 'f': force = true; @@ -309,6 +308,8 @@ int main(int argc, char *argv[]) else die("Unknown input format \"%s\"\n", inform); + dti->outname = outname; + if (depfile) { fputc('\n', depfile); fclose(depfile); diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h index c6f125c68ba8..fc24e17510fd 100644 --- a/scripts/dtc/dtc.h +++ b/scripts/dtc/dtc.h @@ -43,7 +43,6 @@ #define debug(...) #endif - #define DEFAULT_FDT_VERSION 17 /* @@ -114,7 +113,7 @@ struct data data_insert_at_marker(struct data d, struct marker *m, struct data data_merge(struct data d1, struct data d2); struct data data_append_cell(struct data d, cell_t word); struct data data_append_integer(struct data d, uint64_t word, int bits); -struct data data_append_re(struct data d, const struct fdt_reserve_entry *re); +struct data data_append_re(struct data d, uint64_t address, uint64_t size); struct data data_append_addr(struct data d, uint64_t addr); struct data data_append_byte(struct data d, uint8_t byte); struct data data_append_zeroes(struct data d, int len); @@ -136,6 +135,10 @@ struct label { struct label *next; }; +struct bus_type { + const char *name; +}; + struct property { bool deleted; char *name; @@ -162,6 +165,7 @@ struct node { int addr_cells, size_cells; struct label *labels; + const struct bus_type *bus; }; #define for_each_label_withdel(l0, l) \ @@ -227,7 +231,7 @@ uint32_t guess_boot_cpuid(struct node *tree); /* Boot info (tree plus memreserve information */ struct reserve_info { - struct fdt_reserve_entry re; + uint64_t address, size; struct reserve_info *next; @@ -246,6 +250,7 @@ struct dt_info { struct reserve_info *reservelist; uint32_t boot_cpuid_phys; struct node *dt; /* the device tree */ + const char *outname; /* filename being written to, "-" for stdout */ }; /* DTS version flags definitions */ diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c index ebac548b3fa8..fcf71541d8a7 100644 --- a/scripts/dtc/flattree.c +++ b/scripts/dtc/flattree.c @@ -49,7 +49,7 @@ static struct version_info { struct emitter { void (*cell)(void *, cell_t); - void (*string)(void *, char *, int); + void (*string)(void *, const char *, int); void (*align)(void *, int); void (*data)(void *, struct data); void (*beginnode)(void *, struct label *labels); @@ -64,7 +64,7 @@ static void bin_emit_cell(void *e, cell_t val) *dtbuf = data_append_cell(*dtbuf, val); } -static void bin_emit_string(void *e, char *str, int len) +static void bin_emit_string(void *e, const char *str, int len) { struct data *dtbuf = e; @@ -144,22 +144,14 @@ static void asm_emit_cell(void *e, cell_t val) (val >> 8) & 0xff, val & 0xff); } -static void asm_emit_string(void *e, char *str, int len) +static void asm_emit_string(void *e, const char *str, int len) { FILE *f = e; - char c = 0; - if (len != 0) { - /* XXX: ewww */ - c = str[len]; - str[len] = '\0'; - } - - fprintf(f, "\t.string\t\"%s\"\n", str); - - if (len != 0) { - str[len] = c; - } + if (len != 0) + fprintf(f, "\t.string\t\"%.*s\"\n", len, str); + else + fprintf(f, "\t.string\t\"%s\"\n", str); } static void asm_emit_align(void *e, int a) @@ -179,7 +171,7 @@ static void asm_emit_data(void *e, struct data d) emit_offset_label(f, m->ref, m->offset); while ((d.len - off) >= sizeof(uint32_t)) { - asm_emit_cell(e, fdt32_to_cpu(*((uint32_t *)(d.val+off)))); + asm_emit_cell(e, fdt32_to_cpu(*((fdt32_t *)(d.val+off)))); off += sizeof(uint32_t); } @@ -318,17 +310,16 @@ static struct data flatten_reserve_list(struct reserve_info *reservelist, { struct reserve_info *re; struct data d = empty_data; - static struct fdt_reserve_entry null_re = {0,0}; int j; for (re = reservelist; re; re = re->next) { - d = data_append_re(d, &re->re); + d = data_append_re(d, re->address, re->size); } /* * Add additional reserved slots if the user asked for them. */ for (j = 0; j < reservenum; j++) { - d = data_append_re(d, &null_re); + d = data_append_re(d, 0, 0); } return d; @@ -544,11 +535,11 @@ void dt_to_asm(FILE *f, struct dt_info *dti, int version) fprintf(f, "\t.globl\t%s\n", l->label); fprintf(f, "%s:\n", l->label); } - ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.address >> 32)); + ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->address >> 32)); ASM_EMIT_BELONG(f, "0x%08x", - (unsigned int)(re->re.address & 0xffffffff)); - ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size >> 32)); - ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size & 0xffffffff)); + (unsigned int)(re->address & 0xffffffff)); + ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->size >> 32)); + ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->size & 0xffffffff)); } for (i = 0; i < reservenum; i++) { fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n"); @@ -609,7 +600,7 @@ static void flat_read_chunk(struct inbuf *inb, void *p, int len) static uint32_t flat_read_word(struct inbuf *inb) { - uint32_t val; + fdt32_t val; assert(((inb->ptr - inb->base) % sizeof(val)) == 0); @@ -718,13 +709,15 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) * First pass, count entries. */ while (1) { + uint64_t address, size; + flat_read_chunk(inb, &re, sizeof(re)); - re.address = fdt64_to_cpu(re.address); - re.size = fdt64_to_cpu(re.size); - if (re.size == 0) + address = fdt64_to_cpu(re.address); + size = fdt64_to_cpu(re.size); + if (size == 0) break; - new = build_reserve_entry(re.address, re.size); + new = build_reserve_entry(address, size); reservelist = add_reserve_entry(reservelist, new); } @@ -817,6 +810,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, struct dt_info *dt_from_blob(const char *fname) { FILE *f; + fdt32_t magic_buf, totalsize_buf; uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys; uint32_t off_dt, off_str, off_mem_rsvmap; int rc; @@ -833,7 +827,7 @@ struct dt_info *dt_from_blob(const char *fname) f = srcfile_relative_open(fname, NULL); - rc = fread(&magic, sizeof(magic), 1, f); + rc = fread(&magic_buf, sizeof(magic_buf), 1, f); if (ferror(f)) die("Error reading DT blob magic number: %s\n", strerror(errno)); @@ -844,11 +838,11 @@ struct dt_info *dt_from_blob(const char *fname) die("Mysterious short read reading magic number\n"); } - magic = fdt32_to_cpu(magic); + magic = fdt32_to_cpu(magic_buf); if (magic != FDT_MAGIC) die("Blob has incorrect magic number\n"); - rc = fread(&totalsize, sizeof(totalsize), 1, f); + rc = fread(&totalsize_buf, sizeof(totalsize_buf), 1, f); if (ferror(f)) die("Error reading DT blob size: %s\n", strerror(errno)); if (rc < 1) { @@ -858,7 +852,7 @@ struct dt_info *dt_from_blob(const char *fname) die("Mysterious short read reading blob size\n"); } - totalsize = fdt32_to_cpu(totalsize); + totalsize = fdt32_to_cpu(totalsize_buf); if (totalsize < FDT_V1_SIZE) die("DT blob size (%d) is too small\n", totalsize); diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c index 2eed4f58387c..3fd5847377c9 100644 --- a/scripts/dtc/libfdt/fdt_rw.c +++ b/scripts/dtc/libfdt/fdt_rw.c @@ -283,7 +283,8 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name, if (err) return err; - memcpy(prop->data, val, len); + if (len) + memcpy(prop->data, val, len); return 0; } diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h index b842b156fa17..ba86caa73d01 100644 --- a/scripts/dtc/libfdt/libfdt.h +++ b/scripts/dtc/libfdt/libfdt.h @@ -143,7 +143,9 @@ /* Low-level functions (you probably don't need these) */ /**********************************************************************/ +#ifndef SWIG /* This function is not useful in Python */ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen); +#endif static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) { return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen); @@ -210,7 +212,6 @@ int fdt_next_subnode(const void *fdt, int offset); /**********************************************************************/ /* General functions */ /**********************************************************************/ - #define fdt_get_header(fdt, field) \ (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field)) #define fdt_magic(fdt) (fdt_get_header(fdt, magic)) @@ -354,8 +355,10 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size); * useful for finding subnodes based on a portion of a larger string, * such as a full path. */ +#ifndef SWIG /* Not available in Python */ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, const char *name, int namelen); +#endif /** * fdt_subnode_offset - find a subnode of a given node * @fdt: pointer to the device tree blob @@ -391,7 +394,9 @@ int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name); * Identical to fdt_path_offset(), but only consider the first namelen * characters of path as the path name. */ +#ifndef SWIG /* Not available in Python */ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen); +#endif /** * fdt_path_offset - find a tree node by its full path @@ -550,10 +555,12 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt, * Identical to fdt_get_property(), but only examine the first namelen * characters of name for matching the property name. */ +#ifndef SWIG /* Not available in Python */ const struct fdt_property *fdt_get_property_namelen(const void *fdt, int nodeoffset, const char *name, int namelen, int *lenp); +#endif /** * fdt_get_property - find a given property in a given node @@ -624,8 +631,10 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings */ +#ifndef SWIG /* This function is not useful in Python */ const void *fdt_getprop_by_offset(const void *fdt, int offset, const char **namep, int *lenp); +#endif /** * fdt_getprop_namelen - get property value based on substring @@ -638,6 +647,7 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, * Identical to fdt_getprop(), but only examine the first namelen * characters of name for matching the property name. */ +#ifndef SWIG /* Not available in Python */ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, const char *name, int namelen, int *lenp); static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset, @@ -647,6 +657,7 @@ static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset, return (void *)(uintptr_t)fdt_getprop_namelen(fdt, nodeoffset, name, namelen, lenp); } +#endif /** * fdt_getprop - retrieve the value of a given property @@ -707,8 +718,10 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); * Identical to fdt_get_alias(), but only examine the first namelen * characters of name for matching the alias name. */ +#ifndef SWIG /* Not available in Python */ const char *fdt_get_alias_namelen(const void *fdt, const char *name, int namelen); +#endif /** * fdt_get_alias - retrieve the path referenced by a given alias @@ -1106,10 +1119,12 @@ int fdt_size_cells(const void *fdt, int nodeoffset); * of the name. It is useful when you want to manipulate only one value of * an array and you have a string that doesn't end with \0. */ +#ifndef SWIG /* Not available in Python */ int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset, const char *name, int namelen, uint32_t idx, const void *val, int len); +#endif /** * fdt_setprop_inplace - change a property's value, but not its size @@ -1139,8 +1154,10 @@ int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings */ +#ifndef SWIG /* Not available in Python */ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, const void *val, int len); +#endif /** * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property @@ -1527,6 +1544,36 @@ static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, #define fdt_setprop_string(fdt, nodeoffset, name, str) \ fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) + +/** + * fdt_setprop_empty - set a property to an empty value + * @fdt: pointer to the device tree blob + * @nodeoffset: offset of the node whose property to change + * @name: name of the property to change + * + * fdt_setprop_empty() sets the value of the named property in the + * given node to an empty (zero length) value, or creates a new empty + * property if it does not already exist. + * + * This function may insert or delete data from the blob, and will + * therefore change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain the new property value + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_TRUNCATED, standard meanings + */ +#define fdt_setprop_empty(fdt, nodeoffset, name) \ + fdt_setprop((fdt), (nodeoffset), (name), NULL, 0) + /** * fdt_appendprop - append to or create a property * @fdt: pointer to the device tree blob @@ -1704,8 +1751,10 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name); * creating subnodes based on a portion of a larger string, such as a * full path. */ +#ifndef SWIG /* Not available in Python */ int fdt_add_subnode_namelen(void *fdt, int parentoffset, const char *name, int namelen); +#endif /** * fdt_add_subnode - creates a new node diff --git a/scripts/dtc/libfdt/libfdt_env.h b/scripts/dtc/libfdt/libfdt_env.h index 99f936dacc60..952056cddf09 100644 --- a/scripts/dtc/libfdt/libfdt_env.h +++ b/scripts/dtc/libfdt/libfdt_env.h @@ -58,16 +58,16 @@ #include #ifdef __CHECKER__ -#define __force __attribute__((force)) -#define __bitwise __attribute__((bitwise)) +#define FDT_FORCE __attribute__((force)) +#define FDT_BITWISE __attribute__((bitwise)) #else -#define __force -#define __bitwise +#define FDT_FORCE +#define FDT_BITWISE #endif -typedef uint16_t __bitwise fdt16_t; -typedef uint32_t __bitwise fdt32_t; -typedef uint64_t __bitwise fdt64_t; +typedef uint16_t FDT_BITWISE fdt16_t; +typedef uint32_t FDT_BITWISE fdt32_t; +typedef uint64_t FDT_BITWISE fdt64_t; #define EXTRACT_BYTE(x, n) ((unsigned long long)((uint8_t *)&x)[n]) #define CPU_TO_FDT16(x) ((EXTRACT_BYTE(x, 0) << 8) | EXTRACT_BYTE(x, 1)) @@ -80,29 +80,29 @@ typedef uint64_t __bitwise fdt64_t; static inline uint16_t fdt16_to_cpu(fdt16_t x) { - return (__force uint16_t)CPU_TO_FDT16(x); + return (FDT_FORCE uint16_t)CPU_TO_FDT16(x); } static inline fdt16_t cpu_to_fdt16(uint16_t x) { - return (__force fdt16_t)CPU_TO_FDT16(x); + return (FDT_FORCE fdt16_t)CPU_TO_FDT16(x); } static inline uint32_t fdt32_to_cpu(fdt32_t x) { - return (__force uint32_t)CPU_TO_FDT32(x); + return (FDT_FORCE uint32_t)CPU_TO_FDT32(x); } static inline fdt32_t cpu_to_fdt32(uint32_t x) { - return (__force fdt32_t)CPU_TO_FDT32(x); + return (FDT_FORCE fdt32_t)CPU_TO_FDT32(x); } static inline uint64_t fdt64_to_cpu(fdt64_t x) { - return (__force uint64_t)CPU_TO_FDT64(x); + return (FDT_FORCE uint64_t)CPU_TO_FDT64(x); } static inline fdt64_t cpu_to_fdt64(uint64_t x) { - return (__force fdt64_t)CPU_TO_FDT64(x); + return (FDT_FORCE fdt64_t)CPU_TO_FDT64(x); } #undef CPU_TO_FDT64 #undef CPU_TO_FDT32 diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c index afa2f67b142a..3673de07e4e5 100644 --- a/scripts/dtc/livetree.c +++ b/scripts/dtc/livetree.c @@ -242,7 +242,7 @@ void delete_property_by_name(struct node *node, char *name) struct property *prop = node->proplist; while (prop) { - if (!strcmp(prop->name, name)) { + if (streq(prop->name, name)) { delete_property(prop); return; } @@ -275,7 +275,7 @@ void delete_node_by_name(struct node *parent, char *name) struct node *node = parent->children; while (node) { - if (!strcmp(node->name, name)) { + if (streq(node->name, name)) { delete_node(node); return; } @@ -319,8 +319,8 @@ struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size) memset(new, 0, sizeof(*new)); - new->re.address = address; - new->re.size = size; + new->address = address; + new->size = size; return new; } @@ -393,7 +393,7 @@ struct property *get_property(struct node *node, const char *propname) cell_t propval_cell(struct property *prop) { assert(prop->val.len == sizeof(cell_t)); - return fdt32_to_cpu(*((cell_t *)prop->val.val)); + return fdt32_to_cpu(*((fdt32_t *)prop->val.val)); } struct property *get_property_by_label(struct node *tree, const char *label, @@ -599,13 +599,13 @@ static int cmp_reserve_info(const void *ax, const void *bx) a = *((const struct reserve_info * const *)ax); b = *((const struct reserve_info * const *)bx); - if (a->re.address < b->re.address) + if (a->address < b->address) return -1; - else if (a->re.address > b->re.address) + else if (a->address > b->address) return 1; - else if (a->re.size < b->re.size) + else if (a->size < b->size) return -1; - else if (a->re.size > b->re.size) + else if (a->size > b->size) return 1; else return 0; @@ -847,6 +847,8 @@ static void add_fixup_entry(struct dt_info *dti, struct node *fn, xasprintf(&entry, "%s:%s:%u", node->fullpath, prop->name, m->offset); append_to_property(fn, m->ref, entry, strlen(entry) + 1); + + free(entry); } static void generate_fixups_tree_internal(struct dt_info *dti, @@ -900,7 +902,7 @@ static void add_local_fixup_entry(struct dt_info *dti, struct node *refnode) { struct node *wn, *nwn; /* local fixup node, walk node, new */ - uint32_t value_32; + fdt32_t value_32; char **compp; int i, depth; diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c index aa3aad04cec4..9d38459902f3 100644 --- a/scripts/dtc/srcpos.c +++ b/scripts/dtc/srcpos.c @@ -252,7 +252,7 @@ srcpos_string(struct srcpos *pos) const char *fname = ""; char *pos_str; - if (pos) + if (pos->file && pos->file->name) fname = pos->file->name; diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h index 2cdfcd82e95e..7caca8257c6d 100644 --- a/scripts/dtc/srcpos.h +++ b/scripts/dtc/srcpos.h @@ -22,6 +22,7 @@ #include #include +#include "util.h" struct srcfile_state { FILE *f; @@ -106,12 +107,10 @@ extern void srcpos_update(struct srcpos *pos, const char *text, int len); extern struct srcpos *srcpos_copy(struct srcpos *pos); extern char *srcpos_string(struct srcpos *pos); -extern void srcpos_verror(struct srcpos *pos, const char *prefix, - const char *fmt, va_list va) - __attribute__((format(printf, 3, 0))); -extern void srcpos_error(struct srcpos *pos, const char *prefix, - const char *fmt, ...) - __attribute__((format(printf, 3, 4))); +extern void PRINTF(3, 0) srcpos_verror(struct srcpos *pos, const char *prefix, + const char *fmt, va_list va); +extern void PRINTF(3, 4) srcpos_error(struct srcpos *pos, const char *prefix, + const char *fmt, ...); extern void srcpos_set_line(char *f, int l); diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c index c9d8967969f9..2461a3d068a0 100644 --- a/scripts/dtc/treesource.c +++ b/scripts/dtc/treesource.c @@ -137,7 +137,7 @@ static void write_propval_string(FILE *f, struct data val) static void write_propval_cells(FILE *f, struct data val) { void *propend = val.val + val.len; - cell_t *cp = (cell_t *)val.val; + fdt32_t *cp = (fdt32_t *)val.val; struct marker *m = val.markers; fprintf(f, "<"); @@ -275,8 +275,8 @@ void dt_to_source(FILE *f, struct dt_info *dti) for_each_label(re->labels, l) fprintf(f, "%s: ", l->label); fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n", - (unsigned long long)re->re.address, - (unsigned long long)re->re.size); + (unsigned long long)re->address, + (unsigned long long)re->size); } write_tree_source_node(f, dti->dt, 0); diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c index 3550f86bd6df..9953c32a0244 100644 --- a/scripts/dtc/util.c +++ b/scripts/dtc/util.c @@ -396,7 +396,7 @@ void utilfdt_print_data(const char *data, int len) } while (s < data + len); } else if ((len % 4) == 0) { - const uint32_t *cell = (const uint32_t *)data; + const fdt32_t *cell = (const fdt32_t *)data; printf(" = <"); for (i = 0, len /= 4; i < len; i++) @@ -412,15 +412,16 @@ void utilfdt_print_data(const char *data, int len) } } -void util_version(void) +void NORETURN util_version(void) { printf("Version: %s\n", DTC_VERSION); exit(0); } -void util_usage(const char *errmsg, const char *synopsis, - const char *short_opts, struct option const long_opts[], - const char * const opts_help[]) +void NORETURN util_usage(const char *errmsg, const char *synopsis, + const char *short_opts, + struct option const long_opts[], + const char * const opts_help[]) { FILE *fp = errmsg ? stderr : stdout; const char a_arg[] = ""; diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h index f5c4f1b50d30..ad5f41199edb 100644 --- a/scripts/dtc/util.h +++ b/scripts/dtc/util.h @@ -25,9 +25,17 @@ * USA */ +#ifdef __GNUC__ +#define PRINTF(i, j) __attribute__((format (printf, i, j))) +#define NORETURN __attribute__((noreturn)) +#else +#define PRINTF(i, j) +#define NORETURN +#endif + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -static inline void __attribute__((noreturn)) die(const char *str, ...) +static inline void NORETURN PRINTF(1, 2) die(const char *str, ...) { va_list ap; @@ -53,13 +61,14 @@ static inline void *xrealloc(void *p, size_t len) void *new = realloc(p, len); if (!new) - die("realloc() failed (len=%d)\n", len); + die("realloc() failed (len=%zd)\n", len); return new; } extern char *xstrdup(const char *s); -extern int xasprintf(char **strp, const char *fmt, ...); + +extern int PRINTF(2, 3) xasprintf(char **strp, const char *fmt, ...); extern char *join_path(const char *path, const char *name); /** @@ -188,7 +197,7 @@ void utilfdt_print_data(const char *data, int len); /** * Show source version and exit */ -void util_version(void) __attribute__((noreturn)); +void NORETURN util_version(void); /** * Show usage and exit @@ -202,9 +211,10 @@ void util_version(void) __attribute__((noreturn)); * @param long_opts The structure of long options * @param opts_help An array of help strings (should align with long_opts) */ -void util_usage(const char *errmsg, const char *synopsis, - const char *short_opts, struct option const long_opts[], - const char * const opts_help[]) __attribute__((noreturn)); +void NORETURN util_usage(const char *errmsg, const char *synopsis, + const char *short_opts, + struct option const long_opts[], + const char * const opts_help[]); /** * Show usage and exit diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h index 16c2e53a85e3..1229e07b4912 100644 --- a/scripts/dtc/version_gen.h +++ b/scripts/dtc/version_gen.h @@ -1 +1 @@ -#define DTC_VERSION "DTC 1.4.2-g0931cea3" +#define DTC_VERSION "DTC 1.4.4-g756ffc4f" From 8654cb8d0371de3f119c657531abf2ee4423cb44 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 21 Mar 2017 09:14:20 -0500 Subject: [PATCH 11/24] dtc: update warning settings for new bus and node/property name checks dtc gained new warnings checking PCI and simple buses, unit address formatting, and stricter node and property name checking. Disable the new dtc warnings by default as there are 1000s. As before, warnings are enabled with W=1 or W=2. The strict node and property name checks are a bit subjective, so they are only enabled for W=2. Signed-off-by: Rob Herring --- scripts/Makefile.lib | 12 +++++++++++- scripts/dtc/update-dtc-source.sh | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 0a07f9014944..8066b6185d1e 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -280,7 +280,17 @@ DTC ?= $(objtree)/scripts/dtc/dtc # Disable noisy checks by default ifeq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),) -DTC_FLAGS += -Wno-unit_address_vs_reg +DTC_FLAGS += -Wno-unit_address_vs_reg \ + -Wno-simple_bus_reg \ + -Wno-unit_address_format \ + -Wno-pci_bridge \ + -Wno-pci_device_bus_num \ + -Wno-pci_device_reg +endif + +ifeq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),2) +DTC_FLAGS += -Wnode_name_chars_strict \ + -Wproperty_name_chars_strict endif # Generate an assembly file to wrap the output of the device tree compiler diff --git a/scripts/dtc/update-dtc-source.sh b/scripts/dtc/update-dtc-source.sh index c92e6bd9458d..b8ebcc6722d2 100755 --- a/scripts/dtc/update-dtc-source.sh +++ b/scripts/dtc/update-dtc-source.sh @@ -77,4 +77,5 @@ This adds the following commits from upstream: ${dtc_log} EOF ) + git commit -e -v -s -m "${commit_msg}" From ddc17771e215b2a8701f8c0f28bbe706f9a69733 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 3 Apr 2017 12:58:42 -0500 Subject: [PATCH 12/24] dt-bindings: arm,nvic: Binding for ARM NVIC interrupt controller on Cortex-M Signed-off-by: Kumar Gala Signed-off-by: Rob Herring --- .../interrupt-controller/arm,nvic.txt | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/arm,nvic.txt diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,nvic.txt b/Documentation/devicetree/bindings/interrupt-controller/arm,nvic.txt new file mode 100644 index 000000000000..386ab37a383f --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/arm,nvic.txt @@ -0,0 +1,36 @@ +* ARM Nested Vector Interrupt Controller (NVIC) + +The NVIC provides an interrupt controller that is tightly coupled to +Cortex-M based processor cores. The NVIC implemented on different SoCs +vary in the number of interrupts and priority bits per interrupt. + +Main node required properties: + +- compatible : should be one of: + "arm,v6m-nvic" + "arm,v7m-nvic" + "arm,v8m-nvic" +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode an + interrupt source. The type shall be a and the value shall be 2. + + The 1st cell contains the interrupt number for the interrupt type. + + The 2nd cell is the priority of the interrupt. + +- reg : Specifies base physical address(s) and size of the NVIC registers. + This is at a fixed address (0xe000e100) and size (0xc00). + +- arm,num-irq-priority-bits: The number of priority bits implemented by the + given SoC + +Example: + + intc: interrupt-controller@e000e100 { + compatible = "arm,v7m-nvic"; + #interrupt-cells = <2>; + #address-cells = <1>; + interrupt-controller; + reg = <0xe000e100 0xc00>; + arm,num-irq-priority-bits = <4>; + }; From ac37f761ce80386f8a8f11a181c7ce3f9695a9ca Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 6 Apr 2017 03:29:27 -0500 Subject: [PATCH 13/24] of: Add vendor prefix for Nordic Semiconductor Nordic Semiconductor is a semiconductor company specializing in ARM Cortex-M based SoCs for low-power wireless communication, especially Bluetooth. Signed-off-by: Kumar Gala Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 4a27b628ee36..5d3f7a508535 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -213,6 +213,7 @@ newhaven Newhaven Display International ni National Instruments nintendo Nintendo nokia Nokia +nordic Nordic Semiconductor nuvoton Nuvoton Technology Corporation nvd New Vision Display nvidia NVIDIA From b8475cbee5ab2eac05f9cd5dbcc94c453d3cbf10 Mon Sep 17 00:00:00 2001 From: Tyrel Datwyler Date: Mon, 17 Apr 2017 20:29:17 -0400 Subject: [PATCH 14/24] of: fix "/cpus" reference leak in of_numa_parse_cpu_nodes() The call to of_find_node_by_path("/cpus") returns the cpus device_node with its reference count incremented. There is no matching of_node_put() call in of_numa_parse_cpu_nodes() which results in a leaked reference to the "/cpus" node. This patch adds an of_node_put() to release the reference. fixes: 298535c00a2c ("of, numa: Add NUMA of binding implementation.") Signed-off-by: Tyrel Datwyler Acked-by: David Daney Cc: stable@vger.kernel.org # v4.7+ Signed-off-by: Rob Herring --- drivers/of/of_numa.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/of/of_numa.c b/drivers/of/of_numa.c index a53982a330ea..2db1f7a04baf 100644 --- a/drivers/of/of_numa.c +++ b/drivers/of/of_numa.c @@ -57,6 +57,8 @@ static void __init of_numa_parse_cpu_nodes(void) else node_set(nid, numa_nodes_parsed); } + + of_node_put(cpus); } static int __init of_numa_parse_memory_nodes(void) From 6b12e71dd46489c66405fd95c1daab8b9679e069 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 16 Apr 2017 20:01:11 +0200 Subject: [PATCH 15/24] of: Add vendor prefix for ROHM Semiconductor ROHM Semiconductor Co., Ltd. offer PMICs, touchscreen controllers etc. http://www.rohm.com/web/global/ Signed-off-by: Marek Vasut Cc: Rob Herring Cc: Geert Uytterhoeven Acked-by: Geert Uytterhoeven Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 5d3f7a508535..5b8e844a2ec3 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -260,6 +260,7 @@ richtek Richtek Technology Corporation ricoh Ricoh Co. Ltd. rikomagic Rikomagic Tech Corp. Ltd rockchip Fuzhou Rockchip Electronics Co., Ltd +rohm ROHM Semiconductor Co., Ltd samsung Samsung Semiconductor samtec Samtec/Softing company sandisk Sandisk Corporation From 09eb03f0598a9ef7e0d5eb440c6b7c15685f0cbf Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 18 Apr 2017 15:40:03 +0200 Subject: [PATCH 16/24] fpga: region: add missing DT documentation for config complete timeout Commit 42d5ec954719 ("fpga: add config complete timeout") introduced the config complete property but didn't include the corresponding DT binding documentation. Add it now. Signed-off-by: Tobias Klauser Reviewed-by: Moritz Fischer Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/fpga/fpga-region.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/fpga/fpga-region.txt b/Documentation/devicetree/bindings/fpga/fpga-region.txt index 3b32ba15a717..290ded428e81 100644 --- a/Documentation/devicetree/bindings/fpga/fpga-region.txt +++ b/Documentation/devicetree/bindings/fpga/fpga-region.txt @@ -192,6 +192,8 @@ Optional properties: - region-freeze-timeout-us : The maximum time in microseconds to wait for bridges to successfully become disabled before the region has been programmed. +- config-complete-timeout-us : The maximum time in microseconds time for the + FPGA to go to operating mode after the region has been programmed. - child nodes : devices in the FPGA after programming. In the example below, when an overlay is applied targeting fpga-region0, From 331f741679564720a49ccf355012e1a8a45686ec Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Tue, 25 Apr 2017 17:09:53 -0700 Subject: [PATCH 17/24] of: per-file dtc compiler flags The dtc compiler version that adds initial support was available in 4.11-rc1. Add the ability to set an additional dtc compiler flag is needed by overlays. Signed-off-by: Frank Rowand Acked-by: Masahiro Yamada Signed-off-by: Rob Herring --- scripts/Makefile.lib | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 8066b6185d1e..01c77403a803 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -293,6 +293,8 @@ DTC_FLAGS += -Wnode_name_chars_strict \ -Wproperty_name_chars_strict endif +DTC_FLAGS += $(DTC_FLAGS_$(basetarget)) + # Generate an assembly file to wrap the output of the device tree compiler quiet_cmd_dt_S_dtb= DTB $@ cmd_dt_S_dtb= \ From 81d0848fc8d2058c4cc645d971435c889869433b Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Tue, 25 Apr 2017 17:09:54 -0700 Subject: [PATCH 18/24] of: Add unit tests for applying overlays Existing overlay unit tests examine individual pieces of the overlay code. The new tests target the entire process of applying an overlay. Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/fdt.c | 14 +- drivers/of/of_private.h | 12 + drivers/of/unittest-data/Makefile | 17 +- drivers/of/unittest-data/overlay.dts | 53 +++ .../of/unittest-data/overlay_bad_phandle.dts | 20 ++ drivers/of/unittest-data/overlay_base.dts | 80 +++++ drivers/of/unittest.c | 317 ++++++++++++++++++ 7 files changed, 505 insertions(+), 8 deletions(-) create mode 100644 drivers/of/unittest-data/overlay.dts create mode 100644 drivers/of/unittest-data/overlay_bad_phandle.dts create mode 100644 drivers/of/unittest-data/overlay_base.dts diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index e5ce4b59e162..e33f7818bc6c 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -31,6 +31,8 @@ #include /* for COMMAND_LINE_SIZE */ #include +#include "of_private.h" + /* * of_fdt_limit_memory - limit the number of regions in the /memory node * @limit: maximum entries @@ -469,11 +471,11 @@ static int unflatten_dt_nodes(const void *blob, * Returns NULL on failure or the memory chunk containing the unflattened * device tree on success. */ -static void *__unflatten_device_tree(const void *blob, - struct device_node *dad, - struct device_node **mynodes, - void *(*dt_alloc)(u64 size, u64 align), - bool detached) +void *__unflatten_device_tree(const void *blob, + struct device_node *dad, + struct device_node **mynodes, + void *(*dt_alloc)(u64 size, u64 align), + bool detached) { int size; void *mem; @@ -1261,6 +1263,8 @@ void __init unflatten_device_tree(void) /* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */ of_alias_scan(early_init_dt_alloc_memory_arch); + + unittest_unflatten_overlay_base(); } /** diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index 18bbb4517e25..de5c604f5cc4 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -55,6 +55,18 @@ static inline int of_property_notify(int action, struct device_node *np, } #endif /* CONFIG_OF_DYNAMIC */ +#ifdef CONFIG_OF_UNITTEST +extern void __init unittest_unflatten_overlay_base(void); +#else +static inline void unittest_unflatten_overlay_base(void) {}; +#endif + +extern void *__unflatten_device_tree(const void *blob, + struct device_node *dad, + struct device_node **mynodes, + void *(*dt_alloc)(u64 size, u64 align), + bool detached); + /** * General utilities for working with live trees. * diff --git a/drivers/of/unittest-data/Makefile b/drivers/of/unittest-data/Makefile index 1ac5cc01d627..6e00a9c69e58 100644 --- a/drivers/of/unittest-data/Makefile +++ b/drivers/of/unittest-data/Makefile @@ -1,7 +1,18 @@ obj-y += testcases.dtb.o +obj-y += overlay.dtb.o +obj-y += overlay_bad_phandle.dtb.o +obj-y += overlay_base.dtb.o targets += testcases.dtb testcases.dtb.S +targets += overlay.dtb overlay.dtb.S +targets += overlay_bad_phandle.dtb overlay_bad_phandle.dtb.S +targets += overlay_base.dtb overlay_base.dtb.S -.SECONDARY: \ - $(obj)/testcases.dtb.S \ - $(obj)/testcases.dtb +.PRECIOUS: \ + $(obj)/%.dtb.S \ + $(obj)/%.dtb + +# enable creation of __symbols__ node +DTC_FLAGS_overlay := -@ +DTC_FLAGS_overlay_bad_phandle := -@ +DTC_FLAGS_overlay_base := -@ diff --git a/drivers/of/unittest-data/overlay.dts b/drivers/of/unittest-data/overlay.dts new file mode 100644 index 000000000000..6cd7e6a0c13e --- /dev/null +++ b/drivers/of/unittest-data/overlay.dts @@ -0,0 +1,53 @@ +/dts-v1/; +/plugin/; + +/ { + + fragment@0 { + target = <&electric_1>; + + __overlay__ { + status = "ok"; + + hvac_2: hvac-large-1 { + compatible = "ot,hvac-large"; + heat-range = < 40 75 >; + cool-range = < 65 80 >; + }; + }; + }; + + fragment@1 { + target = <&rides_1>; + + __overlay__ { + #address-cells = <1>; + #size-cells = <1>; + status = "ok"; + + ride@200 { + compatible = "ot,ferris-wheel"; + reg = < 0x00000200 0x100 >; + hvac-provider = < &hvac_2 >; + hvac-thermostat = < 27 32 > ; + hvac-zones = < 12 5 >; + hvac-zone-names = "operator", "snack-bar"; + spin-controller = < &spin_ctrl_1 3 >; + spin-rph = < 30 >; + gondolas = < 16 >; + gondola-capacity = < 6 >; + }; + }; + }; + + fragment@2 { + target = <&lights_2>; + + __overlay__ { + status = "ok"; + color = "purple", "white", "red", "green"; + rate = < 3 256 >; + }; + }; + +}; diff --git a/drivers/of/unittest-data/overlay_bad_phandle.dts b/drivers/of/unittest-data/overlay_bad_phandle.dts new file mode 100644 index 000000000000..270ee885a623 --- /dev/null +++ b/drivers/of/unittest-data/overlay_bad_phandle.dts @@ -0,0 +1,20 @@ +/dts-v1/; +/plugin/; + +/ { + + fragment@0 { + target = <&electric_1>; + + __overlay__ { + + // This label should cause an error when the overlay + // is applied. There is already a phandle value + // in the base tree for motor-1. + spin_ctrl_1_conflict: motor-1 { + accelerate = < 3 >; + decelerate = < 5 >; + }; + }; + }; +}; diff --git a/drivers/of/unittest-data/overlay_base.dts b/drivers/of/unittest-data/overlay_base.dts new file mode 100644 index 000000000000..5566b27fb61a --- /dev/null +++ b/drivers/of/unittest-data/overlay_base.dts @@ -0,0 +1,80 @@ +/dts-v1/; +/plugin/; + +/* + * Base device tree that overlays will be applied against. + * + * Do not add any properties in node "/". + * Do not add any nodes other than "/testcase-data-2" in node "/". + * Do not add anything that would result in dtc creating node "/__fixups__". + * dtc will create nodes "/__symbols__" and "/__local_fixups__". + */ + +/ { + testcase-data-2 { + #address-cells = <1>; + #size-cells = <1>; + + electric_1: substation@100 { + compatible = "ot,big-volts-control"; + reg = < 0x00000100 0x100 >; + status = "disabled"; + + hvac_1: hvac-medium-1 { + compatible = "ot,hvac-medium"; + heat-range = < 50 75 >; + cool-range = < 60 80 >; + }; + + spin_ctrl_1: motor-1 { + compatible = "ot,ferris-wheel-motor"; + spin = "clockwise"; + }; + + spin_ctrl_2: motor-8 { + compatible = "ot,roller-coaster-motor"; + }; + }; + + rides_1: fairway-1 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "ot,rides"; + status = "disabled"; + orientation = < 127 >; + + ride@100 { + compatible = "ot,roller-coaster"; + reg = < 0x00000100 0x100 >; + hvac-provider = < &hvac_1 >; + hvac-thermostat = < 29 > ; + hvac-zones = < 14 >; + hvac-zone-names = "operator"; + spin-controller = < &spin_ctrl_2 5 &spin_ctrl_2 7 >; + spin-controller-names = "track_1", "track_2"; + queues = < 2 >; + }; + }; + + lights_1: lights@30000 { + compatible = "ot,work-lights"; + reg = < 0x00030000 0x1000 >; + status = "disabled"; + }; + + lights_2: lights@40000 { + compatible = "ot,show-lights"; + reg = < 0x00040000 0x1000 >; + status = "disabled"; + rate = < 13 138 >; + }; + + retail_1: vending@50000 { + reg = < 0x00050000 0x1000 >; + compatible = "ot,tickets"; + status = "disabled"; + }; + + }; +}; + diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 62db55b97c10..12597ff8cfb0 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -1925,6 +1926,320 @@ out: static inline void __init of_unittest_overlay(void) { } #endif +/* + * __dtb_ot_begin[] and __dtb_ot_end[] are created by cmd_dt_S_dtb + * in scripts/Makefile.lib + */ + +#define OVERLAY_INFO_EXTERN(name) \ + extern uint8_t __dtb_##name##_begin[]; \ + extern uint8_t __dtb_##name##_end[] + +#define OVERLAY_INFO(name, expected) \ +{ .dtb_begin = __dtb_##name##_begin, \ + .dtb_end = __dtb_##name##_end, \ + .expected_result = expected, \ +} + +struct overlay_info { + uint8_t *dtb_begin; + uint8_t *dtb_end; + void *data; + struct device_node *np_overlay; + int expected_result; + int overlay_id; +}; + +OVERLAY_INFO_EXTERN(overlay_base); +OVERLAY_INFO_EXTERN(overlay); +OVERLAY_INFO_EXTERN(overlay_bad_phandle); + +#ifdef CONFIG_OF_OVERLAY + +/* order of entries is hard-coded into users of overlays[] */ +static struct overlay_info overlays[] = { + OVERLAY_INFO(overlay_base, -9999), + OVERLAY_INFO(overlay, 0), + OVERLAY_INFO(overlay_bad_phandle, -EINVAL), + {} +}; + +static struct device_node *overlay_base_root; + +/* + * Create base device tree for the overlay unittest. + * + * This is called from very early boot code. + * + * Do as much as possible the same way as done in __unflatten_device_tree + * and other early boot steps for the normal FDT so that the overlay base + * unflattened tree will have the same characteristics as the real tree + * (such as having memory allocated by the early allocator). The goal + * is to test "the real thing" as much as possible, and test "test setup + * code" as little as possible. + * + * Have to stop before resolving phandles, because that uses kmalloc. + */ +void __init unittest_unflatten_overlay_base(void) +{ + struct overlay_info *info; + u32 data_size; + u32 size; + + info = &overlays[0]; + + if (info->expected_result != -9999) { + pr_err("No dtb 'overlay_base' to attach\n"); + return; + } + + data_size = info->dtb_end - info->dtb_begin; + if (!data_size) { + pr_err("No dtb 'overlay_base' to attach\n"); + return; + } + + size = fdt_totalsize(info->dtb_begin); + if (size != data_size) { + pr_err("dtb 'overlay_base' header totalsize != actual size"); + return; + } + + info->data = early_init_dt_alloc_memory_arch(size, + roundup_pow_of_two(FDT_V17_SIZE)); + if (!info->data) { + pr_err("alloc for dtb 'overlay_base' failed"); + return; + } + + memcpy(info->data, info->dtb_begin, size); + + __unflatten_device_tree(info->data, NULL, &info->np_overlay, + early_init_dt_alloc_memory_arch, true); + overlay_base_root = info->np_overlay; +} + +/* + * The purpose of of_unittest_overlay_data_add is to add an + * overlay in the normal fashion. This is a test of the whole + * picture, instead of testing individual elements. + * + * A secondary purpose is to be able to verify that the contents of + * /proc/device-tree/ contains the updated structure and values from + * the overlay. That must be verified separately in user space. + * + * Return 0 on unexpected error. + */ +static int __init overlay_data_add(int onum) +{ + struct overlay_info *info; + int k; + int ret; + u32 size; + u32 size_from_header; + + for (k = 0, info = overlays; info; info++, k++) { + if (k == onum) + break; + } + if (onum > k) + return 0; + + size = info->dtb_end - info->dtb_begin; + if (!size) { + pr_err("no overlay to attach, %d\n", onum); + ret = 0; + } + + size_from_header = fdt_totalsize(info->dtb_begin); + if (size_from_header != size) { + pr_err("overlay header totalsize != actual size, %d", onum); + return 0; + } + + /* + * Must create permanent copy of FDT because of_fdt_unflatten_tree() + * will create pointers to the passed in FDT in the EDT. + */ + info->data = kmemdup(info->dtb_begin, size, GFP_KERNEL); + if (!info->data) { + pr_err("unable to allocate memory for data, %d\n", onum); + return 0; + } + + of_fdt_unflatten_tree(info->data, NULL, &info->np_overlay); + if (!info->np_overlay) { + pr_err("unable to unflatten overlay, %d\n", onum); + ret = 0; + goto out_free_data; + } + of_node_set_flag(info->np_overlay, OF_DETACHED); + + ret = of_resolve_phandles(info->np_overlay); + if (ret) { + pr_err("resolve ot phandles (ret=%d), %d\n", ret, onum); + goto out_free_np_overlay; + } + + ret = of_overlay_create(info->np_overlay); + if (ret < 0) { + pr_err("of_overlay_create() (ret=%d), %d\n", ret, onum); + goto out_free_np_overlay; + } else { + info->overlay_id = ret; + ret = 0; + } + + pr_debug("__dtb_overlay_begin applied, overlay id %d\n", ret); + + goto out; + +out_free_np_overlay: + /* + * info->np_overlay is the unflattened device tree + * It has not been spliced into the live tree. + */ + + /* todo: function to free unflattened device tree */ + +out_free_data: + kfree(info->data); + +out: + return (ret == info->expected_result); +} + +/* + * The purpose of of_unittest_overlay_high_level is to add an overlay + * in the normal fashion. This is a test of the whole picture, + * instead of individual elements. + * + * The first part of the function is _not_ normal overlay usage; it is + * finishing splicing the base overlay device tree into the live tree. + */ +static __init void of_unittest_overlay_high_level(void) +{ + struct device_node *last_sibling; + struct device_node *np; + struct device_node *of_symbols; + struct device_node *overlay_base_symbols; + struct device_node **pprev; + struct property *prop; + int ret; + + if (!overlay_base_root) { + unittest(0, "overlay_base_root not initialized\n"); + return; + } + + /* + * Could not fixup phandles in unittest_unflatten_overlay_base() + * because kmalloc() was not yet available. + */ + of_resolve_phandles(overlay_base_root); + + /* + * do not allow overlay_base to duplicate any node already in + * tree, this greatly simplifies the code + */ + + /* + * remove overlay_base_root node "__local_fixups", after + * being used by of_resolve_phandles() + */ + pprev = &overlay_base_root->child; + for (np = overlay_base_root->child; np; np = np->sibling) { + if (!of_node_cmp(np->name, "__local_fixups__")) { + *pprev = np->sibling; + break; + } + pprev = &np->sibling; + } + + /* remove overlay_base_root node "__symbols__" if in live tree */ + of_symbols = of_get_child_by_name(of_root, "__symbols__"); + if (of_symbols) { + /* will have to graft properties from node into live tree */ + pprev = &overlay_base_root->child; + for (np = overlay_base_root->child; np; np = np->sibling) { + if (!of_node_cmp(np->name, "__symbols__")) { + overlay_base_symbols = np; + *pprev = np->sibling; + break; + } + pprev = &np->sibling; + } + } + + for (np = overlay_base_root->child; np; np = np->sibling) { + if (of_get_child_by_name(of_root, np->name)) { + unittest(0, "illegal node name in overlay_base %s", + np->name); + return; + } + } + + /* + * overlay 'overlay_base' is not allowed to have root + * properties, so only need to splice nodes into main device tree. + * + * root node of *overlay_base_root will not be freed, it is lost + * memory. + */ + + for (np = overlay_base_root->child; np; np = np->sibling) + np->parent = of_root; + + mutex_lock(&of_mutex); + + for (np = of_root->child; np; np = np->sibling) + last_sibling = np; + + if (last_sibling) + last_sibling->sibling = overlay_base_root->child; + else + of_root->child = overlay_base_root->child; + + for_each_of_allnodes_from(overlay_base_root, np) + __of_attach_node_sysfs(np); + + if (of_symbols) { + for_each_property_of_node(overlay_base_symbols, prop) { + ret = __of_add_property(of_symbols, prop); + if (ret) { + unittest(0, + "duplicate property '%s' in overlay_base node __symbols__", + prop->name); + return; + } + ret = __of_add_property_sysfs(of_symbols, prop); + if (ret) { + unittest(0, + "unable to add property '%s' in overlay_base node __symbols__ to sysfs", + prop->name); + return; + } + } + } + + mutex_unlock(&of_mutex); + + + /* now do the normal overlay usage test */ + + unittest(overlay_data_add(1), + "Adding overlay 'overlay' failed\n"); + + unittest(overlay_data_add(2), + "Adding overlay 'overlay_bad_phandle' failed\n"); +} + +#else + +static inline __init void of_unittest_overlay_high_level(void) {} + +#endif + static int __init of_unittest(void) { struct device_node *np; @@ -1962,6 +2277,8 @@ static int __init of_unittest(void) /* Double check linkage after removing testcase data */ of_unittest_check_tree_linkage(); + of_unittest_overlay_high_level(); + pr_info("end of unittest - %i passed, %i failed\n", unittest_results.passed, unittest_results.failed); From 5d4dd65b1e98ff640c3bdb546a169e397805831e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 28 Apr 2017 11:44:12 +0200 Subject: [PATCH 19/24] of: fix unittest build without CONFIG_OF_OVERLAY We get a link error when the new tests are used by overlays are not: drivers/of/built-in.o: In function `unflatten_device_tree': (.init.text+0x967): undefined reference to `unittest_unflatten_overlay_base' This makes the #ifdef check match the symbols that lead to building the unittest_unflatten_overlay_base function. Fixes: 81d0848fc8d2 ("of: Add unit tests for applying overlays") Signed-off-by: Arnd Bergmann Reviewed-by: Frank Rowand Tested-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/of_private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index de5c604f5cc4..4ebb0149d118 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -55,7 +55,7 @@ static inline int of_property_notify(int action, struct device_node *np, } #endif /* CONFIG_OF_DYNAMIC */ -#ifdef CONFIG_OF_UNITTEST +#if defined(CONFIG_OF_UNITTEST) && defined(CONFIG_OF_OVERLAY) extern void __init unittest_unflatten_overlay_base(void); #else static inline void unittest_unflatten_overlay_base(void) {}; From ee320b33b4a316e22612ad6409517fc647f2a37c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 28 Apr 2017 11:44:11 +0200 Subject: [PATCH 20/24] of: fix uninitialized variable warning for overlay test gcc warns that an empty device tree would cause undefined behavior: drivers/of/unittest.c: In function 'of_unittest': drivers/of/unittest.c:2199:25: warning: 'last_sibling' may be used uninitialized in this function [-Wmaybe-uninitialized] This adds an initialization of the variable to zero, which we handle correctly. Fixes: 81d0848fc8d2 ("of: Add unit tests for applying overlays") Signed-off-by: Arnd Bergmann Signed-off-by: Rob Herring --- drivers/of/unittest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 12597ff8cfb0..6b8f3e6aa43c 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -2192,7 +2192,7 @@ static __init void of_unittest_overlay_high_level(void) mutex_lock(&of_mutex); - for (np = of_root->child; np; np = np->sibling) + for (last_sibling = np = of_root->child; np; np = np->sibling) last_sibling = np; if (last_sibling) From 8756cd1ded1af222fda4470b08ba547f5625e656 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 3 May 2017 22:49:50 +0300 Subject: [PATCH 21/24] of/unittest: Missing unlocks on error Static checkers complain that we should unlock before returning. Which is true. Signed-off-by: Dan Carpenter Reviewed-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/unittest.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 6b8f3e6aa43c..987a1530282a 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -2210,14 +2210,14 @@ static __init void of_unittest_overlay_high_level(void) unittest(0, "duplicate property '%s' in overlay_base node __symbols__", prop->name); - return; + goto err_unlock; } ret = __of_add_property_sysfs(of_symbols, prop); if (ret) { unittest(0, "unable to add property '%s' in overlay_base node __symbols__ to sysfs", prop->name); - return; + goto err_unlock; } } } @@ -2232,6 +2232,10 @@ static __init void of_unittest_overlay_high_level(void) unittest(overlay_data_add(2), "Adding overlay 'overlay_bad_phandle' failed\n"); + return; + +err_unlock: + mutex_unlock(&of_mutex); } #else From 91d967497f11dbb5038c7b84bc30dae684ae5ffb Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 4 May 2017 12:30:07 -0500 Subject: [PATCH 22/24] of: fix sparse warnings in of_find_next_cache_node sparse gives a warning that 'handle' is not a __be32: ../drivers/of/base.c:2261:61: warning: incorrect type in argument 1 (different base types) ../drivers/of/base.c:2261:61: expected restricted __be32 const [usertype] *p ../drivers/of/base.c:2261:61: got unsigned int const [usertype] *[assigned] handle We could just change the type, but the code can be improved by using of_parse_phandle instead of open coding it with of_get_property and of_find_node_by_phandle. Signed-off-by: Rob Herring --- drivers/of/base.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index d7c4629a3a2d..016f9d77d64d 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -2250,15 +2250,14 @@ EXPORT_SYMBOL_GPL(of_console_check); */ struct device_node *of_find_next_cache_node(const struct device_node *np) { - struct device_node *child; - const phandle *handle; + struct device_node *child, *cache_node; - handle = of_get_property(np, "l2-cache", NULL); - if (!handle) - handle = of_get_property(np, "next-level-cache", NULL); + cache_node = of_parse_phandle(np, "l2-cache", 0); + if (!cache_node) + cache_node = of_parse_phandle(np, "next-level-cache", 0); - if (handle) - return of_find_node_by_phandle(be32_to_cpup(handle)); + if (cache_node) + return cache_node; /* OF on pmac has nodes instead of properties named "l2-cache" * beneath CPU nodes. From eb3100365791b06242b8bb5c3c2854ba41dabfbc Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 4 May 2017 12:34:30 -0500 Subject: [PATCH 23/24] of: fix sparse warning in of_pci_range_parser_one sparse gives the following warning for 'pci_space': ../drivers/of/address.c:266:26: warning: incorrect type in assignment (different base types) ../drivers/of/address.c:266:26: expected unsigned int [unsigned] [usertype] pci_space ../drivers/of/address.c:266:26: got restricted __be32 const [usertype] It appears that pci_space is only ever accessed on powerpc, so the endian swap is often not needed. Cc: stable@vger.kernel.org Signed-off-by: Rob Herring --- drivers/of/address.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/address.c b/drivers/of/address.c index 02b2903fe9d2..72914cdfce2a 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -263,7 +263,7 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser, if (!parser->range || parser->range + parser->np > parser->end) return NULL; - range->pci_space = parser->range[0]; + range->pci_space = be32_to_cpup(parser->range); range->flags = of_bus_pci_get_flags(parser->range); range->pci_addr = of_read_number(parser->range + 1, ns); range->cpu_addr = of_translate_address(parser->node, From 17a70355ea576843a7ac851f1db26872a50b2850 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 4 May 2017 12:56:12 -0500 Subject: [PATCH 24/24] of: fix sparse warnings in fdt, irq, reserved mem, and resolver code sparse generates the following warnings in drivers/of/: ../drivers/of/fdt.c:63:36: warning: cast to restricted __be32 ../drivers/of/fdt.c:68:33: warning: cast to restricted __be32 ../drivers/of/irq.c:105:88: warning: incorrect type in initializer (different base types) ../drivers/of/irq.c:105:88: expected restricted __be32 ../drivers/of/irq.c:105:88: got int ../drivers/of/irq.c:526:35: warning: incorrect type in assignment (different modifiers) ../drivers/of/irq.c:526:35: expected int ( *const [usertype] irq_init_cb )( ... ) ../drivers/of/irq.c:526:35: got void const *const data ../drivers/of/of_reserved_mem.c:200:50: warning: incorrect type in initializer (different modifiers) ../drivers/of/of_reserved_mem.c:200:50: expected int ( *[usertype] initfn )( ... ) ../drivers/of/of_reserved_mem.c:200:50: got void const *const data ../drivers/of/resolver.c:95:42: warning: incorrect type in assignment (different base types) ../drivers/of/resolver.c:95:42: expected unsigned int [unsigned] [usertype] ../drivers/of/resolver.c:95:42: got restricted __be32 [usertype] All these are harmless type mismatches fixed by adjusting the types. Signed-off-by: Rob Herring --- drivers/of/fdt.c | 4 ++-- drivers/of/irq.c | 2 +- drivers/of/of_reserved_mem.c | 2 +- drivers/of/resolver.c | 2 +- include/linux/of_irq.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index e33f7818bc6c..a0972219ccfc 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -48,8 +48,8 @@ void of_fdt_limit_memory(int limit) const void *val; int nr_address_cells = OF_ROOT_NODE_ADDR_CELLS_DEFAULT; int nr_size_cells = OF_ROOT_NODE_SIZE_CELLS_DEFAULT; - const uint32_t *addr_prop; - const uint32_t *size_prop; + const __be32 *addr_prop; + const __be32 *size_prop; int root_offset; int cell_size; diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 7c56b72d1dc6..d11437cb1187 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -102,7 +102,7 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; __be32 initial_match_array[MAX_PHANDLE_ARGS]; const __be32 *match_array = initial_match_array; - const __be32 *tmp, *imap, *imask, dummy_imask[] = { [0 ... MAX_PHANDLE_ARGS] = ~0 }; + const __be32 *tmp, *imap, *imask, dummy_imask[] = { [0 ... MAX_PHANDLE_ARGS] = cpu_to_be32(~0) }; u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; int imaplen, match, i, rc = -EINVAL; diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index d507c3569a88..4dec07ea510f 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -197,7 +197,7 @@ static int __init __reserved_mem_init_node(struct reserved_mem *rmem) const struct of_device_id *i; for (i = __reservedmem_of_table; i < &__rmem_of_table_sentinel; i++) { - reservedmem_of_init_fn initfn = i->data; + int const (*initfn)(struct reserved_mem *rmem) = i->data; const char *compat = i->compatible; if (!of_flat_dt_is_compatible(rmem->fdt_node, compat)) diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index 7ae9863cb0a4..771f4844c781 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -92,7 +92,7 @@ static void adjust_overlay_phandles(struct device_node *overlay, if (phandle == OF_PHANDLE_ILLEGAL) continue; - *(uint32_t *)prop->value = cpu_to_be32(overlay->phandle); + *(__be32 *)prop->value = cpu_to_be32(overlay->phandle); } for_each_child_of_node(overlay, child) diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h index 1e0deb8e8494..ec6b11deb773 100644 --- a/include/linux/of_irq.h +++ b/include/linux/of_irq.h @@ -8,7 +8,7 @@ #include #include -typedef int (*of_irq_init_cb_t)(struct device_node *, struct device_node *); +typedef int const (*of_irq_init_cb_t)(struct device_node *, struct device_node *); /* * Workarounds only applied to 32bit powermac machines