Browse Source

Merge tag 'devicetree-for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux

Pull DeviceTree updates from Rob Herring:

 - Sync dtc with upstream version v1.4.6-21-g84e414b0b5bc. This adds new
   warnings which are either fixed or disabled by default (enabled with
   W=1).

 - Validate an untrusted offset in DT overlay function
   update_usages_of_a_phandle_reference

 - Fix a use after free error of_platform_device_destroy

 - Fix an off by 1 string errors in unittest

 - Avoid creating a struct device for OPP nodes

 - Update DT specific submitting-patches.txt with patch content and
   subject requirements.

 - Move some bindings to their proper subsystem locations

 - Add vendor prefixes for Kaohsiung, SiFive, Avnet, Wi2Wi, Logic PD,
   and ArcherMind

 - Add documentation for "no-gpio-delays" property in FSI bus GPIO
   master

 - Add compatible for r8a77990 SoC ravb ethernet block

 - More wack-a-mole removal of 'status' property in examples

* tag 'devicetree-for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (25 commits)
  dt-bindings: submitting-patches: add guidance on patch content and subject
  of: platform: stop accessing invalid dev in of_platform_device_destroy
  dt-bindings: net: ravb: Add support for r8a77990 SoC
  dt-bindings: Add vendor prefix for ArcherMind
  dt-bindings: fsi-master-gpio: Document "no-gpio-delays" property
  dt-bindings: Add vendor prefix for Logic PD
  of: overlay: validate offset from property fixups
  of: unittest: for strings, account for trailing \0 in property length field
  drm: rcar-du: disable dtc graph-endpoint warnings on DT overlays
  kbuild: disable new dtc graph and unit-address warnings
  scripts/dtc: Update to upstream version v1.4.6-21-g84e414b0b5bc
  MAINTAINERS: add keyword for devicetree overlay notifiers
  dt-bindings: define vendor prefix for Wi2Wi, Inc.
  dt-bindings: Add vendor prefix for Avnet, Inc.
  dt-bindings: Relocate Tegra20 memory controller bindings
  dt-bindings: Add "sifive" vendor prefix
  dt-bindings: exynos: move ADC binding to iio/adc/ directory
  dt-bindings: powerpc/4xx: move 4xx NDFC and EMAC bindings to subsystem directories
  dt-bindings: move various RNG bindings to rng/ directory
  dt-bindings: move various timer bindings to timer/ directory
  ...
Linus Torvalds 7 years ago
parent
commit
289cf155d9
45 changed files with 320 additions and 49 deletions
  1. 1 1
      Documentation/devicetree/bindings/arm/ux500/boards.txt
  2. 0 1
      Documentation/devicetree/bindings/dma/k3dma.txt
  3. 0 1
      Documentation/devicetree/bindings/dma/ti-edma.txt
  4. 4 0
      Documentation/devicetree/bindings/fsi/fsi-master-gpio.txt
  5. 0 0
      Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.txt
  6. 0 0
      Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
  7. 0 2
      Documentation/devicetree/bindings/mips/lantiq/rcu.txt
  8. 0 4
      Documentation/devicetree/bindings/mmc/tmio_mmc.txt
  9. 0 0
      Documentation/devicetree/bindings/mtd/ibm,ndfc.txt
  10. 0 4
      Documentation/devicetree/bindings/mtd/mtk-nand.txt
  11. 0 0
      Documentation/devicetree/bindings/net/ibm,emac.txt
  12. 1 0
      Documentation/devicetree/bindings/net/renesas,ravb.txt
  13. 0 7
      Documentation/devicetree/bindings/pci/xgene-pci.txt
  14. 0 1
      Documentation/devicetree/bindings/pps/pps-gpio.txt
  15. 1 1
      Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt
  16. 0 0
      Documentation/devicetree/bindings/rng/samsung,exynos4-rng.txt
  17. 0 0
      Documentation/devicetree/bindings/rng/sparc_sun_oracle_rng.txt
  18. 8 1
      Documentation/devicetree/bindings/submitting-patches.txt
  19. 3 3
      Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt
  20. 0 0
      Documentation/devicetree/bindings/timer/altr,timer-1.0.txt
  21. 0 0
      Documentation/devicetree/bindings/timer/arm,arch_timer.txt
  22. 0 0
      Documentation/devicetree/bindings/timer/arm,armv7m-systick.txt
  23. 0 0
      Documentation/devicetree/bindings/timer/arm,global_timer.txt
  24. 0 0
      Documentation/devicetree/bindings/timer/arm,twd.txt
  25. 0 0
      Documentation/devicetree/bindings/timer/fsl,gtm.txt
  26. 0 0
      Documentation/devicetree/bindings/timer/mrvl,mmp-timer.txt
  27. 0 0
      Documentation/devicetree/bindings/timer/qcom,msm-timer.txt
  28. 0 0
      Documentation/devicetree/bindings/timer/st,spear-timer.txt
  29. 0 0
      Documentation/devicetree/bindings/timer/ti,c64x+timer64.txt
  30. 0 0
      Documentation/devicetree/bindings/timer/ti,timer.txt
  31. 0 0
      Documentation/devicetree/bindings/timer/via,vt8500-timer.txt
  32. 6 0
      Documentation/devicetree/bindings/vendor-prefixes.txt
  33. 2 0
      MAINTAINERS
  34. 7 0
      drivers/gpu/drm/rcar-du/Makefile
  35. 0 1
      drivers/of/of_numa.c
  36. 14 2
      drivers/of/platform.c
  37. 5 0
      drivers/of/resolver.c
  38. 4 4
      drivers/of/unittest.c
  39. 3 0
      scripts/Makefile.lib
  40. 198 1
      scripts/dtc/checks.c
  41. 7 0
      scripts/dtc/dtc-lexer.l
  42. 28 11
      scripts/dtc/dtc-parser.y
  43. 4 0
      scripts/dtc/dtc.h
  44. 23 3
      scripts/dtc/livetree.c
  45. 1 1
      scripts/dtc/version_gen.h

+ 1 - 1
Documentation/devicetree/bindings/arm/ux500/boards.txt

@@ -26,7 +26,7 @@ interrupt-controller:
 	see binding for interrupt-controller/arm,gic.txt
 
 timer:
-	see binding for arm/twd.txt
+	see binding for timer/arm,twd.txt
 
 clocks:
 	see binding for clocks/ux500.txt

+ 0 - 1
Documentation/devicetree/bindings/dma/k3dma.txt

@@ -23,7 +23,6 @@ Controller:
 			dma-requests = <27>;
 			interrupts = <0 12 4>;
 			clocks = <&pclk>;
-			status = "disable";
 		};
 
 Client:

+ 0 - 1
Documentation/devicetree/bindings/dma/ti-edma.txt

@@ -190,7 +190,6 @@ mmc0: mmc@23000000 {
 	power-domains = <&k2g_pds 0xb>;
 	clocks = <&k2g_clks 0xb 1>, <&k2g_clks 0xb 2>;
 	clock-names = "fck", "mmchsdb_fck";
-	status = "disabled";
 };
 
 ------------------------------------------------------------------------------

+ 4 - 0
Documentation/devicetree/bindings/fsi/fsi-master-gpio.txt

@@ -11,6 +11,10 @@ Optional properties:
  - trans-gpios = <gpio-descriptor>;	: GPIO for voltage translator enable
  - mux-gpios = <gpio-descriptor>;	: GPIO for pin multiplexing with other
                                           functions (eg, external FSI masters)
+ - no-gpio-delays;			: Don't add extra delays between GPIO
+                                          accesses. This is useful when the HW
+					  GPIO block is running at a low enough
+					  frequency.
 
 Examples:
 

+ 0 - 0
Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt → Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.txt


+ 0 - 0
Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt → Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt


+ 0 - 2
Documentation/devicetree/bindings/mips/lantiq/rcu.txt

@@ -61,7 +61,6 @@ Example of the RCU bindings on a xRX200 SoC:
 		usb_phy0: usb2-phy@18 {
 			compatible = "lantiq,xrx200-usb2-phy";
 			reg = <0x18 4>, <0x38 4>;
-			status = "disabled";
 
 			resets = <&reset1 4 4>, <&reset0 4 4>;
 			reset-names = "phy", "ctrl";
@@ -71,7 +70,6 @@ Example of the RCU bindings on a xRX200 SoC:
 		usb_phy1: usb2-phy@34 {
 			compatible = "lantiq,xrx200-usb2-phy";
 			reg = <0x34 4>, <0x3C 4>;
-			status = "disabled";
 
 			resets = <&reset1 5 4>, <&reset0 4 4>;
 			reset-names = "phy", "ctrl";

+ 0 - 4
Documentation/devicetree/bindings/mmc/tmio_mmc.txt

@@ -69,7 +69,6 @@ Example: R8A7790 (R-Car H2) SDHI controller nodes
 		max-frequency = <195000000>;
 		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
 		resets = <&cpg 314>;
-		status = "disabled";
 	};
 
 	sdhi1: sd@ee120000 {
@@ -83,7 +82,6 @@ Example: R8A7790 (R-Car H2) SDHI controller nodes
 		max-frequency = <195000000>;
 		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
 		resets = <&cpg 313>;
-		status = "disabled";
 	};
 
 	sdhi2: sd@ee140000 {
@@ -97,7 +95,6 @@ Example: R8A7790 (R-Car H2) SDHI controller nodes
 		max-frequency = <97500000>;
 		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
 		resets = <&cpg 312>;
-		status = "disabled";
 	};
 
 	sdhi3: sd@ee160000 {
@@ -111,5 +108,4 @@ Example: R8A7790 (R-Car H2) SDHI controller nodes
 		max-frequency = <97500000>;
 		power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
 		resets = <&cpg 311>;
-		status = "disabled";
 	};

+ 0 - 0
Documentation/devicetree/bindings/powerpc/4xx/ndfc.txt → Documentation/devicetree/bindings/mtd/ibm,ndfc.txt


+ 0 - 4
Documentation/devicetree/bindings/mtd/mtk-nand.txt

@@ -20,7 +20,6 @@ Required NFI properties:
 - interrupts:			Interrupts of NFI.
 - clocks:			NFI required clocks.
 - clock-names:			NFI clocks internal name.
-- status:			Disabled default. Then set "okay" by platform.
 - ecc-engine:			Required ECC Engine node.
 - #address-cells:		NAND chip index, should be 1.
 - #size-cells:			Should be 0.
@@ -34,7 +33,6 @@ Example:
 		clocks = <&pericfg CLK_PERI_NFI>,
 			 <&pericfg CLK_PERI_NFI_PAD>;
 		clock-names = "nfi_clk", "pad_clk";
-		status = "disabled";
 		ecc-engine = <&bch>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -152,7 +150,6 @@ Required BCH properties:
 - interrupts:	Interrupts of ECC.
 - clocks:	ECC required clocks.
 - clock-names:	ECC clocks internal name.
-- status:	Disabled default. Then set "okay" by platform.
 
 Example:
 
@@ -162,5 +159,4 @@ Example:
 		interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&pericfg CLK_PERI_NFI_ECC>;
 		clock-names = "nfiecc_clk";
-		status = "disabled";
 	};

+ 0 - 0
Documentation/devicetree/bindings/powerpc/4xx/emac.txt → Documentation/devicetree/bindings/net/ibm,emac.txt


+ 1 - 0
Documentation/devicetree/bindings/net/renesas,ravb.txt

@@ -21,6 +21,7 @@ Required properties:
       - "renesas,etheravb-r8a77965" for the R8A77965 SoC.
       - "renesas,etheravb-r8a77970" for the R8A77970 SoC.
       - "renesas,etheravb-r8a77980" for the R8A77980 SoC.
+      - "renesas,etheravb-r8a77990" for the R8A77990 SoC.
       - "renesas,etheravb-r8a77995" for the R8A77995 SoC.
       - "renesas,etheravb-rcar-gen3" as a fallback for the above
 		R-Car Gen3 devices.

+ 0 - 7
Documentation/devicetree/bindings/pci/xgene-pci.txt

@@ -25,8 +25,6 @@ Optional properties:
 
 Example:
 
-SoC-specific DT Entry:
-
 	pcie0: pcie@1f2b0000 {
 		status = "disabled";
 		device_type = "pci";
@@ -50,8 +48,3 @@ SoC-specific DT Entry:
 		clocks = <&pcie0clk 0>;
 	};
 
-
-Board-specific DT Entry:
-	&pcie0 {
-		status = "ok";
-	};

+ 0 - 1
Documentation/devicetree/bindings/pps/pps-gpio.txt

@@ -20,5 +20,4 @@ Example:
 		assert-falling-edge;
 
 		compatible = "pps-gpio";
-		status = "okay";
 	};

+ 1 - 1
Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt

@@ -2,7 +2,7 @@
 
 Required properties:
 - compatible: Shall contain "ti,omap-dmtimer-pwm".
-- ti,timers: phandle to PWM capable OMAP timer. See arm/omap/timer.txt for info
+- ti,timers: phandle to PWM capable OMAP timer. See timer/ti,timer.txt for info
   about these timers.
 - #pwm-cells: Should be 3. See pwm.txt in this directory for a description of
   the cells format.

+ 0 - 0
Documentation/devicetree/bindings/crypto/samsung,exynos-rng4.txt → Documentation/devicetree/bindings/rng/samsung,exynos4-rng.txt


+ 0 - 0
Documentation/devicetree/bindings/sparc_sun_oracle_rng.txt → Documentation/devicetree/bindings/rng/sparc_sun_oracle_rng.txt


+ 8 - 1
Documentation/devicetree/bindings/submitting-patches.txt

@@ -6,7 +6,14 @@ I. For patch submitters
   0) Normal patch submission rules from Documentation/process/submitting-patches.rst
      applies.
 
-  1) The Documentation/ portion of the patch should be a separate patch.
+  1) The Documentation/ and include/dt-bindings/ portion of the patch should
+     be a separate patch. The preferred subject prefix for binding patches is:
+
+       "dt-bindings: <binding dir>: ..."
+
+     The 80 characters of the subject are precious. It is recommended to not
+     use "Documentation" or "doc" because that is implied. All bindings are
+     docs. Repeating "binding" again should also be avoided.
 
   2) Submit the entire series to the devicetree mailinglist at
 

+ 3 - 3
Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt

@@ -27,9 +27,9 @@ Example:
 
 	tsc: thermal@e6198000 {
 		compatible = "renesas,r8a7795-thermal";
-		reg = <0 0xe6198000 0 0x68>,
-		      <0 0xe61a0000 0 0x5c>,
-		      <0 0xe61a8000 0 0x5c>;
+		reg = <0 0xe6198000 0 0x100>,
+		      <0 0xe61a0000 0 0x100>,
+		      <0 0xe61a8000 0 0x100>;
 		interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;

+ 0 - 0
Documentation/devicetree/bindings/nios2/timer.txt → Documentation/devicetree/bindings/timer/altr,timer-1.0.txt


+ 0 - 0
Documentation/devicetree/bindings/arm/arch_timer.txt → Documentation/devicetree/bindings/timer/arm,arch_timer.txt


+ 0 - 0
Documentation/devicetree/bindings/arm/armv7m_systick.txt → Documentation/devicetree/bindings/timer/arm,armv7m-systick.txt


+ 0 - 0
Documentation/devicetree/bindings/arm/global_timer.txt → Documentation/devicetree/bindings/timer/arm,global_timer.txt


+ 0 - 0
Documentation/devicetree/bindings/arm/twd.txt → Documentation/devicetree/bindings/timer/arm,twd.txt


+ 0 - 0
Documentation/devicetree/bindings/powerpc/fsl/gtm.txt → Documentation/devicetree/bindings/timer/fsl,gtm.txt


+ 0 - 0
Documentation/devicetree/bindings/arm/mrvl/timer.txt → Documentation/devicetree/bindings/timer/mrvl,mmp-timer.txt


+ 0 - 0
Documentation/devicetree/bindings/arm/msm/timer.txt → Documentation/devicetree/bindings/timer/qcom,msm-timer.txt


+ 0 - 0
Documentation/devicetree/bindings/arm/spear-timer.txt → Documentation/devicetree/bindings/timer/st,spear-timer.txt


+ 0 - 0
Documentation/devicetree/bindings/c6x/timer64.txt → Documentation/devicetree/bindings/timer/ti,c64x+timer64.txt


+ 0 - 0
Documentation/devicetree/bindings/arm/omap/timer.txt → Documentation/devicetree/bindings/timer/ti,timer.txt


+ 0 - 0
Documentation/devicetree/bindings/arm/vt8500/via,vt8500-timer.txt → Documentation/devicetree/bindings/timer/via,vt8500-timer.txt


+ 6 - 0
Documentation/devicetree/bindings/vendor-prefixes.txt

@@ -32,6 +32,7 @@ andestech	Andes Technology Corporation
 apm	Applied Micro Circuits Corporation (APM)
 aptina	Aptina Imaging
 arasan	Arasan Chip Systems
+archermind ArcherMind Technology (Nanjing) Co., Ltd.
 arctic	Arctic Sand
 aries	Aries Embedded GmbH
 arm	ARM Ltd.
@@ -47,6 +48,7 @@ auvidea Auvidea GmbH
 avago	Avago Technologies
 avia	avia semiconductor
 avic	Shanghai AVIC Optoelectronics Co., Ltd.
+avnet	Avnet, Inc.
 axentia	Axentia Technologies AB
 axis	Axis Communications AB
 bananapi BIPAI KEJI LIMITED
@@ -186,6 +188,7 @@ khadas	Khadas
 kiebackpeter    Kieback & Peter GmbH
 kinetic Kinetic Technologies
 kingnovel	Kingnovel Technology Co., Ltd.
+koe	Kaohsiung Opto-Electronics Inc.
 kosagi	Sutajio Ko-Usagi PTE Ltd.
 kyo	Kyocera Corporation
 lacie	LaCie
@@ -200,6 +203,7 @@ linaro	Linaro Limited
 linksys	Belkin International, Inc. (Linksys)
 linux	Linux-specific binding
 lltc	Linear Technology Corporation
+logicpd	Logic PD, Inc.
 lsi	LSI Corp. (LSI Logic)
 lwn	Liebherr-Werk Nenzing GmbH
 macnica	Macnica Americas
@@ -320,6 +324,7 @@ sgx	SGX Sensortech
 sharp	Sharp Corporation
 shimafuji	Shimafuji Electric, Inc.
 si-en	Si-En Technology Ltd.
+sifive	SiFive, Inc.
 sigma	Sigma Designs, Inc.
 sii	Seiko Instruments, Inc.
 sil	Silicon Image
@@ -395,6 +400,7 @@ vot	Vision Optical Technology Co., Ltd.
 wd	Western Digital Corp.
 wetek	WeTek Electronics, limited.
 wexler	Wexler
+wi2wi	Wi2Wi, Inc.
 winbond Winbond Electronics corp.
 winstar	Winstar Display Corp.
 wlf	Wolfson Microelectronics

+ 2 - 0
MAINTAINERS

@@ -10510,12 +10510,14 @@ F:	drivers/infiniband/ulp/opa_vnic
 
 OPEN FIRMWARE AND DEVICE TREE OVERLAYS
 M:	Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+M:	Frank Rowand <frowand.list@gmail.com>
 L:	devicetree@vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/dynamic-resolution-notes.txt
 F:	Documentation/devicetree/overlay-notes.txt
 F:	drivers/of/overlay.c
 F:	drivers/of/resolver.c
+K:	of_overlay_notifier_
 
 OPEN FIRMWARE AND FLATTENED DEVICE TREE
 M:	Rob Herring <robh+dt@kernel.org>

+ 7 - 0
drivers/gpu/drm/rcar-du/Makefile

@@ -17,3 +17,10 @@ rcar-du-drm-$(CONFIG_DRM_RCAR_VSP)	+= rcar_du_vsp.o
 obj-$(CONFIG_DRM_RCAR_DU)		+= rcar-du-drm.o
 obj-$(CONFIG_DRM_RCAR_DW_HDMI)		+= rcar_dw_hdmi.o
 obj-$(CONFIG_DRM_RCAR_LVDS)		+= rcar_lvds.o
+
+# 'remote-endpoint' is fixed up at run-time
+DTC_FLAGS_rcar_du_of_lvds_r8a7790 += -Wno-graph_endpoint
+DTC_FLAGS_rcar_du_of_lvds_r8a7791 += -Wno-graph_endpoint
+DTC_FLAGS_rcar_du_of_lvds_r8a7793 += -Wno-graph_endpoint
+DTC_FLAGS_rcar_du_of_lvds_r8a7795 += -Wno-graph_endpoint
+DTC_FLAGS_rcar_du_of_lvds_r8a7796 += -Wno-graph_endpoint

+ 0 - 1
drivers/of/of_numa.c

@@ -177,7 +177,6 @@ int of_node_to_nid(struct device_node *device)
 
 	return NUMA_NO_NODE;
 }
-EXPORT_SYMBOL(of_node_to_nid);
 
 int __init of_numa_init(void)
 {

+ 14 - 2
drivers/of/platform.c

@@ -32,6 +32,11 @@ const struct of_device_id of_default_bus_match_table[] = {
 	{} /* Empty terminated list */
 };
 
+static const struct of_device_id of_skipped_node_table[] = {
+	{ .compatible = "operating-points-v2", },
+	{} /* Empty terminated list */
+};
+
 static int of_dev_node_match(struct device *dev, void *data)
 {
 	return dev->of_node == data;
@@ -356,6 +361,12 @@ static int of_platform_bus_create(struct device_node *bus,
 		return 0;
 	}
 
+	/* Skip nodes for which we don't want to create devices */
+	if (unlikely(of_match_node(of_skipped_node_table, bus))) {
+		pr_debug("%s() - skipping %pOF node\n", __func__, bus);
+		return 0;
+	}
+
 	if (of_node_check_flag(bus, OF_POPULATED_BUS)) {
 		pr_debug("%s() - skipping %pOF, already populated\n",
 			__func__, bus);
@@ -537,6 +548,9 @@ int of_platform_device_destroy(struct device *dev, void *data)
 	if (of_node_check_flag(dev->of_node, OF_POPULATED_BUS))
 		device_for_each_child(dev, NULL, of_platform_device_destroy);
 
+	of_node_clear_flag(dev->of_node, OF_POPULATED);
+	of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
+
 	if (dev->bus == &platform_bus_type)
 		platform_device_unregister(to_platform_device(dev));
 #ifdef CONFIG_ARM_AMBA
@@ -544,8 +558,6 @@ int of_platform_device_destroy(struct device *dev, void *data)
 		amba_device_unregister(to_amba_device(dev));
 #endif
 
-	of_node_clear_flag(dev->of_node, OF_POPULATED);
-	of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(of_platform_device_destroy);

+ 5 - 0
drivers/of/resolver.c

@@ -122,6 +122,11 @@ static int update_usages_of_a_phandle_reference(struct device_node *overlay,
 			goto err_fail;
 		}
 
+		if (offset < 0 || offset + sizeof(__be32) > prop->length) {
+			err = -EINVAL;
+			goto err_fail;
+		}
+
 		*(__be32 *)(prop->value + offset) = cpu_to_be32(phandle);
 	}
 

+ 4 - 4
drivers/of/unittest.c

@@ -165,20 +165,20 @@ static void __init of_unittest_dynamic(void)
 	/* Add a new property - should pass*/
 	prop->name = "new-property";
 	prop->value = "new-property-data";
-	prop->length = strlen(prop->value);
+	prop->length = strlen(prop->value) + 1;
 	unittest(of_add_property(np, prop) == 0, "Adding a new property failed\n");
 
 	/* Try to add an existing property - should fail */
 	prop++;
 	prop->name = "new-property";
 	prop->value = "new-property-data-should-fail";
-	prop->length = strlen(prop->value);
+	prop->length = strlen(prop->value) + 1;
 	unittest(of_add_property(np, prop) != 0,
 		 "Adding an existing property should have failed\n");
 
 	/* Try to modify an existing property - should pass */
 	prop->value = "modify-property-data-should-pass";
-	prop->length = strlen(prop->value);
+	prop->length = strlen(prop->value) + 1;
 	unittest(of_update_property(np, prop) == 0,
 		 "Updating an existing property should have passed\n");
 
@@ -186,7 +186,7 @@ static void __init of_unittest_dynamic(void)
 	prop++;
 	prop->name = "modify-property";
 	prop->value = "modify-missing-property-data-should-pass";
-	prop->length = strlen(prop->value);
+	prop->length = strlen(prop->value) + 1;
 	unittest(of_update_property(np, prop) == 0,
 		 "Updating a missing property should have passed\n");
 

+ 3 - 0
scripts/Makefile.lib

@@ -251,6 +251,9 @@ DTC_FLAGS += -Wno-unit_address_vs_reg \
 	-Wno-unit_address_format \
 	-Wno-avoid_unnecessary_addr_size \
 	-Wno-alias_paths \
+	-Wno-graph_child_address \
+	-Wno-graph_port \
+	-Wno-unique_unit_address \
 	-Wno-pci_device_reg
 endif
 

+ 198 - 1
scripts/dtc/checks.c

@@ -255,7 +255,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, dti, node, "Duplicate node name");
+				FAIL(c, dti, child2, "Duplicate node name");
 }
 ERROR(duplicate_node_names, check_duplicate_node_names, NULL);
 
@@ -317,6 +317,11 @@ static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti,
 	const char *unitname = get_unitname(node);
 	struct property *prop = get_property(node, "reg");
 
+	if (get_subnode(node, "__overlay__")) {
+		/* HACK: Overlay fragments are a special case */
+		return;
+	}
+
 	if (!prop) {
 		prop = get_property(node, "ranges");
 		if (prop && !prop->val.len)
@@ -579,6 +584,8 @@ static void fixup_phandle_references(struct check *c, struct dt_info *dti,
 
 			phandle = get_node_phandle(dt, refnode);
 			*((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
+
+			reference_node(refnode);
 		}
 	}
 }
@@ -609,11 +616,21 @@ static void fixup_path_references(struct check *c, struct dt_info *dti,
 			path = refnode->fullpath;
 			prop->val = data_insert_at_marker(prop->val, m, path,
 							  strlen(path) + 1);
+
+			reference_node(refnode);
 		}
 	}
 }
 ERROR(path_references, fixup_path_references, NULL, &duplicate_node_names);
 
+static void fixup_omit_unused_nodes(struct check *c, struct dt_info *dti,
+				    struct node *node)
+{
+	if (node->omit_if_unused && !node->is_referenced)
+		delete_node(node);
+}
+ERROR(omit_unused_nodes, fixup_omit_unused_nodes, NULL, &phandle_references, &path_references);
+
 /*
  * Semantic checks
  */
@@ -1017,6 +1034,36 @@ static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *d
 }
 WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size);
 
+static void check_unique_unit_address(struct check *c, struct dt_info *dti,
+					      struct node *node)
+{
+	struct node *childa;
+
+	if (node->addr_cells < 0 || node->size_cells < 0)
+		return;
+
+	if (!node->children)
+		return;
+
+	for_each_child(node, childa) {
+		struct node *childb;
+		const char *addr_a = get_unitname(childa);
+
+		if (!strlen(addr_a))
+			continue;
+
+		for_each_child(node, childb) {
+			const char *addr_b = get_unitname(childb);
+			if (childa == childb)
+				break;
+
+			if (streq(addr_a, addr_b))
+				FAIL(c, dti, childb, "duplicate unit-address (also used in node %s)", childa->fullpath);
+		}
+	}
+}
+WARNING(unique_unit_address, check_unique_unit_address, NULL, &avoid_default_addr_size);
+
 static void check_obsolete_chosen_interrupt_controller(struct check *c,
 						       struct dt_info *dti,
 						       struct node *node)
@@ -1357,6 +1404,152 @@ static void check_interrupts_property(struct check *c,
 }
 WARNING(interrupts_property, check_interrupts_property, &phandle_references);
 
+static const struct bus_type graph_port_bus = {
+	.name = "graph-port",
+};
+
+static const struct bus_type graph_ports_bus = {
+	.name = "graph-ports",
+};
+
+static void check_graph_nodes(struct check *c, struct dt_info *dti,
+			      struct node *node)
+{
+	struct node *child;
+
+	for_each_child(node, child) {
+		if (!(strprefixeq(child->name, child->basenamelen, "endpoint") ||
+		      get_property(child, "remote-endpoint")))
+			continue;
+
+		node->bus = &graph_port_bus;
+
+		/* The parent of 'port' nodes can be either 'ports' or a device */
+		if (!node->parent->bus &&
+		    (streq(node->parent->name, "ports") || get_property(node, "reg")))
+			node->parent->bus = &graph_ports_bus;
+
+		break;
+	}
+
+}
+WARNING(graph_nodes, check_graph_nodes, NULL);
+
+static void check_graph_child_address(struct check *c, struct dt_info *dti,
+				      struct node *node)
+{
+	int cnt = 0;
+	struct node *child;
+
+	if (node->bus != &graph_ports_bus && node->bus != &graph_port_bus)
+		return;
+
+	for_each_child(node, child) {
+		struct property *prop = get_property(child, "reg");
+
+		/* No error if we have any non-zero unit address */
+		if (prop && propval_cell(prop) != 0)
+			return;
+
+		cnt++;
+	}
+
+	if (cnt == 1 && node->addr_cells != -1)
+		FAIL(c, dti, node, "graph node has single child node '%s', #address-cells/#size-cells are not necessary",
+		     node->children->name);
+}
+WARNING(graph_child_address, check_graph_child_address, NULL, &graph_nodes);
+
+static void check_graph_reg(struct check *c, struct dt_info *dti,
+			    struct node *node)
+{
+	char unit_addr[9];
+	const char *unitname = get_unitname(node);
+	struct property *prop;
+
+	prop = get_property(node, "reg");
+	if (!prop || !unitname)
+		return;
+
+	if (!(prop->val.val && prop->val.len == sizeof(cell_t))) {
+		FAIL(c, dti, node, "graph node malformed 'reg' property");
+		return;
+	}
+
+	snprintf(unit_addr, sizeof(unit_addr), "%x", propval_cell(prop));
+	if (!streq(unitname, unit_addr))
+		FAIL(c, dti, node, "graph node unit address error, expected \"%s\"",
+		     unit_addr);
+
+	if (node->parent->addr_cells != 1)
+		FAIL_PROP(c, dti, node, get_property(node, "#address-cells"),
+			  "graph node '#address-cells' is %d, must be 1",
+			  node->parent->addr_cells);
+	if (node->parent->size_cells != 0)
+		FAIL_PROP(c, dti, node, get_property(node, "#size-cells"),
+			  "graph node '#size-cells' is %d, must be 0",
+			  node->parent->size_cells);
+}
+
+static void check_graph_port(struct check *c, struct dt_info *dti,
+			     struct node *node)
+{
+	if (node->bus != &graph_port_bus)
+		return;
+
+	if (!strprefixeq(node->name, node->basenamelen, "port"))
+		FAIL(c, dti, node, "graph port node name should be 'port'");
+
+	check_graph_reg(c, dti, node);
+}
+WARNING(graph_port, check_graph_port, NULL, &graph_nodes);
+
+static struct node *get_remote_endpoint(struct check *c, struct dt_info *dti,
+					struct node *endpoint)
+{
+	int phandle;
+	struct node *node;
+	struct property *prop;
+
+	prop = get_property(endpoint, "remote-endpoint");
+	if (!prop)
+		return NULL;
+
+	phandle = propval_cell(prop);
+	/* Give up if this is an overlay with external references */
+	if (phandle == 0 || phandle == -1)
+		return NULL;
+
+	node = get_node_by_phandle(dti->dt, phandle);
+	if (!node)
+		FAIL_PROP(c, dti, endpoint, prop, "graph phandle is not valid");
+
+	return node;
+}
+
+static void check_graph_endpoint(struct check *c, struct dt_info *dti,
+				 struct node *node)
+{
+	struct node *remote_node;
+
+	if (!node->parent || node->parent->bus != &graph_port_bus)
+		return;
+
+	if (!strprefixeq(node->name, node->basenamelen, "endpoint"))
+		FAIL(c, dti, node, "graph endpont node name should be 'endpoint'");
+
+	check_graph_reg(c, dti, node);
+
+	remote_node = get_remote_endpoint(c, dti, node);
+	if (!remote_node)
+		return;
+
+	if (get_remote_endpoint(c, dti, remote_node) != node)
+		FAIL(c, dti, node, "graph connection to node '%s' is not bidirectional",
+		     remote_node->fullpath);
+}
+WARNING(graph_endpoint, check_graph_endpoint, NULL, &graph_nodes);
+
 static struct check *check_table[] = {
 	&duplicate_node_names, &duplicate_property_names,
 	&node_name_chars, &node_name_format, &property_name_chars,
@@ -1366,6 +1559,7 @@ static struct check *check_table[] = {
 
 	&explicit_phandles,
 	&phandle_references, &path_references,
+	&omit_unused_nodes,
 
 	&address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
 	&device_type_is_string, &model_is_string, &status_is_string,
@@ -1390,6 +1584,7 @@ static struct check *check_table[] = {
 
 	&avoid_default_addr_size,
 	&avoid_unnecessary_addr_size,
+	&unique_unit_address,
 	&obsolete_chosen_interrupt_controller,
 	&chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path,
 
@@ -1416,6 +1611,8 @@ static struct check *check_table[] = {
 
 	&alias_paths,
 
+	&graph_nodes, &graph_child_address, &graph_port, &graph_endpoint,
+
 	&always_fail,
 };
 

+ 7 - 0
scripts/dtc/dtc-lexer.l

@@ -153,6 +153,13 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
 			return DT_DEL_NODE;
 		}
 
+<*>"/omit-if-no-ref/"	{
+			DPRINT("Keyword: /omit-if-no-ref/\n");
+			DPRINT("<PROPNODENAME>\n");
+			BEGIN(PROPNODENAME);
+			return DT_OMIT_NO_REF;
+		}
+
 <*>{LABEL}:	{
 			DPRINT("Label: %s\n", yytext);
 			yylval.labelref = xstrdup(yytext);

+ 28 - 11
scripts/dtc/dtc-parser.y

@@ -63,6 +63,7 @@ extern bool treesource_error;
 %token DT_BITS
 %token DT_DEL_PROP
 %token DT_DEL_NODE
+%token DT_OMIT_NO_REF
 %token <propnodename> DT_PROPNODENAME
 %token <integer> DT_LITERAL
 %token <integer> DT_CHAR_LITERAL
@@ -190,18 +191,18 @@ devicetree:
 		}
 	| devicetree DT_REF nodedef
 		{
-			struct node *target = get_node_by_ref($1, $2);
-
-			if (target) {
-				merge_nodes(target, $3);
+			/*
+			 * We rely on the rule being always:
+			 *   versioninfo plugindecl memreserves devicetree
+			 * so $-1 is what we want (plugindecl)
+			 */
+			if ($<flags>-1 & DTSF_PLUGIN) {
+				add_orphan_node($1, $3, $2);
 			} else {
-				/*
-				 * We rely on the rule being always:
-				 *   versioninfo plugindecl memreserves devicetree
-				 * so $-1 is what we want (plugindecl)
-				 */
-				if ($<flags>-1 & DTSF_PLUGIN)
-					add_orphan_node($1, $3, $2);
+				struct node *target = get_node_by_ref($1, $2);
+
+				if (target)
+					merge_nodes(target, $3);
 				else
 					ERROR(&@2, "Label or path %s not found", $2);
 			}
@@ -217,6 +218,18 @@ devicetree:
 				ERROR(&@3, "Label or path %s not found", $3);
 
 
+			$$ = $1;
+		}
+	| devicetree DT_OMIT_NO_REF DT_REF ';'
+		{
+			struct node *target = get_node_by_ref($1, $3);
+
+			if (target)
+				omit_node_if_unused(target);
+			else
+				ERROR(&@3, "Label or path %s not found", $3);
+
+
 			$$ = $1;
 		}
 	;
@@ -523,6 +536,10 @@ subnode:
 		{
 			$$ = name_node(build_node_delete(), $2);
 		}
+	| DT_OMIT_NO_REF subnode
+		{
+			$$ = omit_node_if_unused($2);
+		}
 	| DT_LABEL subnode
 		{
 			add_label(&$2->labels, $1);

+ 4 - 0
scripts/dtc/dtc.h

@@ -168,6 +168,8 @@ struct node {
 
 	struct label *labels;
 	const struct bus_type *bus;
+
+	bool omit_if_unused, is_referenced;
 };
 
 #define for_each_label_withdel(l0, l) \
@@ -202,6 +204,8 @@ struct property *reverse_properties(struct property *first);
 struct node *build_node(struct property *proplist, struct node *children);
 struct node *build_node_delete(void);
 struct node *name_node(struct node *node, char *name);
+struct node *omit_node_if_unused(struct node *node);
+struct node *reference_node(struct node *node);
 struct node *chain_node(struct node *first, struct node *list);
 struct node *merge_nodes(struct node *old_node, struct node *new_node);
 struct node *add_orphan_node(struct node *old_node, struct node *new_node, char *ref);

+ 23 - 3
scripts/dtc/livetree.c

@@ -134,6 +134,20 @@ struct node *name_node(struct node *node, char *name)
 	return node;
 }
 
+struct node *omit_node_if_unused(struct node *node)
+{
+	node->omit_if_unused = 1;
+
+	return node;
+}
+
+struct node *reference_node(struct node *node)
+{
+	node->is_referenced = 1;
+
+	return node;
+}
+
 struct node *merge_nodes(struct node *old_node, struct node *new_node)
 {
 	struct property *new_prop, *old_prop;
@@ -224,10 +238,16 @@ struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref)
 	struct data d = empty_data;
 	char *name;
 
-	d = data_add_marker(d, REF_PHANDLE, ref);
-	d = data_append_integer(d, 0xffffffff, 32);
+	if (ref[0] == '/') {
+		d = data_append_data(d, ref, strlen(ref) + 1);
 
-	p = build_property("target", d);
+		p = build_property("target-path", d);
+	} else {
+		d = data_add_marker(d, REF_PHANDLE, ref);
+		d = data_append_integer(d, 0xffffffff, 32);
+
+		p = build_property("target", d);
+	}
 
 	xasprintf(&name, "fragment@%u",
 			next_orphan_fragment++);

+ 1 - 1
scripts/dtc/version_gen.h

@@ -1 +1 @@
-#define DTC_VERSION "DTC 1.4.6-gaadd0b65"
+#define DTC_VERSION "DTC 1.4.6-g84e414b0"