Selaa lähdekoodia

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

Pull DeviceTree updates from Rob Herring:
 "Pretty standard stuff with dtc upstream sync being the biggest piece.

   - Sync dtc to upstream commit 0931cea3ba20. This picks up overlay
     support in dtc.

   - Set dma_ops for reserved memory users.

   - Make references to IOMMU consistent in DT bindings.

   - Cleanup references to pm_power_off in bindings.

   - Move some display bindings that snuck into the old bindings/video/
     path.

   - Fix some wrong documentation paths caused from binding
     restructuring.

   - Vendor prefixes for Faraday and Fujitsu.

   - Fix an of_node ref counting leak in of_find_node_opts_by_path

   - Introduce new graph helper of_graph_get_remote_node() which will be
     used by DRM drivers in 4.12"

* tag 'devicetree-for-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (27 commits)
  DT: add Faraday Tec. as vendor
  of: introduce of_graph_get_remote_node
  of: Add missing space at end of pr_fmt().
  of: make of_device_make_bus_id() static
  of: fix of_node leak caused in of_find_node_opts_by_path
  dt-bindings: net: remove reference to fixed link support
  dt-bindings: power: reset: qnap-poweroff: Drop reference to pm_power_off
  dt-bindings: power: reset: gpio-poweroff: Drop reference to pm_power_off
  dt-bindings: mfd: as3722: Drop reference to pm_power_off
  dt-bindings: display: move ANX7814 and SiI8620 bridge bindings
  of/unittest: Swap arguments of of_unittest_apply_overlay()
  Documentation: usb: fix wrong documentation paths
  serial: fsl-imx-uart.txt: Remove generic property
  devicetree: Add Fujitsu Ltd. vendor prefix
  Documentation: display: fix wrong documentation paths
  of: remove redundant memset in overlay
  bus:qcom : Fix typo in qcom,ebi2.txt
  dt-bindings: qman: Remove pool channel node
  Documentation: panel-dpi: fix path to display-timing.txt
  devicetree: bindings: clk: mvebu: fix description for sata1 on Armada XP
  ...
Linus Torvalds 8 vuotta sitten
vanhempi
commit
be5165a51d
66 muutettua tiedostoa jossa 1781 lisäystä ja 1100 poistoa
  1. 3 3
      Documentation/devicetree/bindings/bus/qcom,ebi2.txt
  2. 1 1
      Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
  3. 1 1
      Documentation/devicetree/bindings/display/arm,pl11x.txt
  4. 1 1
      Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
  5. 0 0
      Documentation/devicetree/bindings/display/bridge/anx7814.txt
  6. 0 0
      Documentation/devicetree/bindings/display/bridge/sil-sii8620.txt
  7. 1 1
      Documentation/devicetree/bindings/display/cirrus,clps711x-fb.txt
  8. 1 1
      Documentation/devicetree/bindings/display/exynos/exynos7-decon.txt
  9. 1 1
      Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt
  10. 1 1
      Documentation/devicetree/bindings/display/imx/fsl,imx-fb.txt
  11. 1 1
      Documentation/devicetree/bindings/display/imx/ldb.txt
  12. 1 1
      Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
  13. 1 1
      Documentation/devicetree/bindings/display/msm/dsi.txt
  14. 1 1
      Documentation/devicetree/bindings/display/msm/edp.txt
  15. 1 1
      Documentation/devicetree/bindings/display/msm/hdmi.txt
  16. 1 1
      Documentation/devicetree/bindings/display/panel/panel-dpi.txt
  17. 1 1
      Documentation/devicetree/bindings/display/panel/samsung,ld9040.txt
  18. 1 1
      Documentation/devicetree/bindings/display/panel/samsung,s6e8aa0.txt
  19. 1 1
      Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
  20. 1 1
      Documentation/devicetree/bindings/display/tilcdc/panel.txt
  21. 5 5
      Documentation/devicetree/bindings/iommu/arm,smmu.txt
  22. 1 2
      Documentation/devicetree/bindings/mfd/as3722.txt
  23. 2 2
      Documentation/devicetree/bindings/mfd/omap-usb-host.txt
  24. 1 3
      Documentation/devicetree/bindings/net/marvell-pp2.txt
  25. 3 3
      Documentation/devicetree/bindings/pci/pci-iommu.txt
  26. 5 5
      Documentation/devicetree/bindings/power/reset/gpio-poweroff.txt
  27. 1 2
      Documentation/devicetree/bindings/power/reset/qnap-poweroff.txt
  28. 3 1
      Documentation/devicetree/bindings/serial/fsl-imx-uart.txt
  29. 0 20
      Documentation/devicetree/bindings/soc/fsl/qman-portals.txt
  30. 0 1
      Documentation/devicetree/bindings/usb/ehci-omap.txt
  31. 2 0
      Documentation/devicetree/bindings/vendor-prefixes.txt
  32. 40 0
      drivers/of/base.c
  33. 1 1
      drivers/of/fdt.c
  34. 12 7
      drivers/of/irq.c
  35. 9 1
      drivers/of/of_pci_irq.c
  36. 4 0
      drivers/of/of_reserved_mem.c
  37. 0 2
      drivers/of/overlay.c
  38. 1 1
      drivers/of/platform.c
  39. 0 1
      drivers/of/resolver.c
  40. 2 3
      drivers/of/unittest.c
  41. 0 1
      include/linux/of_device.h
  42. 8 0
      include/linux/of_graph.h
  43. 181 168
      scripts/dtc/checks.c
  44. 13 8
      scripts/dtc/dtc-lexer.l
  45. 331 319
      scripts/dtc/dtc-lexer.lex.c_shipped
  46. 392 360
      scripts/dtc/dtc-parser.tab.c_shipped
  47. 29 25
      scripts/dtc/dtc-parser.tab.h_shipped
  48. 30 4
      scripts/dtc/dtc-parser.y
  49. 57 12
      scripts/dtc/dtc.c
  50. 27 12
      scripts/dtc/dtc.h
  51. 27 14
      scripts/dtc/flattree.c
  52. 2 3
      scripts/dtc/fstree.c
  53. 1 1
      scripts/dtc/libfdt/Makefile.libfdt
  54. 28 2
      scripts/dtc/libfdt/fdt_ro.c
  55. 1 5
      scripts/dtc/libfdt/fdt_rw.c
  56. 6 0
      scripts/dtc/libfdt/fdt_strerror.c
  57. 25 4
      scripts/dtc/libfdt/fdt_wip.c
  58. 180 30
      scripts/dtc/libfdt/libfdt.h
  59. 1 0
      scripts/dtc/libfdt/libfdt_env.h
  60. 283 16
      scripts/dtc/livetree.c
  61. 8 27
      scripts/dtc/srcpos.c
  62. 0 1
      scripts/dtc/srcpos.h
  63. 7 7
      scripts/dtc/treesource.c
  64. 30 0
      scripts/dtc/util.c
  65. 1 0
      scripts/dtc/util.h
  66. 1 1
      scripts/dtc/version_gen.h

+ 3 - 3
Documentation/devicetree/bindings/bus/qcom,ebi2.txt

@@ -51,7 +51,7 @@ Required properties:
 - compatible: should be one of:
 - compatible: should be one of:
   "qcom,msm8660-ebi2"
   "qcom,msm8660-ebi2"
   "qcom,apq8060-ebi2"
   "qcom,apq8060-ebi2"
-- #address-cells: shoule be <2>: the first cell is the chipselect,
+- #address-cells: should be <2>: the first cell is the chipselect,
   the second cell is the offset inside the memory range
   the second cell is the offset inside the memory range
 - #size-cells: should be <1>
 - #size-cells: should be <1>
 - ranges: should be set to:
 - ranges: should be set to:
@@ -64,7 +64,7 @@ Required properties:
 - reg: two ranges of registers: EBI2 config and XMEM config areas
 - reg: two ranges of registers: EBI2 config and XMEM config areas
 - reg-names: should be "ebi2", "xmem"
 - reg-names: should be "ebi2", "xmem"
 - clocks: two clocks, EBI_2X and EBI
 - clocks: two clocks, EBI_2X and EBI
-- clock-names: shoule be "ebi2x", "ebi2"
+- clock-names: should be "ebi2x", "ebi2"
 
 
 Optional subnodes:
 Optional subnodes:
 - Nodes inside the EBI2 will be considered device nodes.
 - Nodes inside the EBI2 will be considered device nodes.
@@ -100,7 +100,7 @@ Optional properties arrays for FAST chip selects:
   assertion, with respect to the cycle where ADV (address valid) is asserted.
   assertion, with respect to the cycle where ADV (address valid) is asserted.
   2 means 2 cycles between ADV and OE. Valid values 0, 1, 2 or 3.
   2 means 2 cycles between ADV and OE. Valid values 0, 1, 2 or 3.
 - qcom,xmem-read-hold-cycles: the length in cycles of the first segment of a
 - qcom,xmem-read-hold-cycles: the length in cycles of the first segment of a
-  read transfer. For a single read trandfer this will be the time from CS
+  read transfer. For a single read transfer this will be the time from CS
   assertion to OE assertion. Valid values 0 thru 15.
   assertion to OE assertion. Valid values 0 thru 15.
 
 
 
 

+ 1 - 1
Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt

@@ -117,7 +117,7 @@ ID	Clock	Peripheral
 25	tdm	Time Division Mplx
 25	tdm	Time Division Mplx
 28	xor1	XOR DMA 1
 28	xor1	XOR DMA 1
 29	sata1lnk
 29	sata1lnk
-30	sata1	SATA Host 0
+30	sata1	SATA Host 1
 
 
 The following is a list of provided IDs for Dove:
 The following is a list of provided IDs for Dove:
 ID	Clock	Peripheral
 ID	Clock	Peripheral

+ 1 - 1
Documentation/devicetree/bindings/display/arm,pl11x.txt

@@ -22,7 +22,7 @@ Required properties:
 
 
 - clocks: contains phandle and clock specifier pairs for the entries
 - clocks: contains phandle and clock specifier pairs for the entries
 	in the clock-names property. See
 	in the clock-names property. See
-	Documentation/devicetree/binding/clock/clock-bindings.txt
+	Documentation/devicetree/bindings/clock/clock-bindings.txt
 
 
 Optional properties:
 Optional properties:
 
 

+ 1 - 1
Documentation/devicetree/bindings/display/bridge/analogix_dp.txt

@@ -33,7 +33,7 @@ Optional properties for dp-controller:
 		in Documentation/devicetree/bindings/media/video-interfaces.txt,
 		in Documentation/devicetree/bindings/media/video-interfaces.txt,
 		please refer to the SoC specific binding document:
 		please refer to the SoC specific binding document:
 		* Documentation/devicetree/bindings/display/exynos/exynos_dp.txt
 		* Documentation/devicetree/bindings/display/exynos/exynos_dp.txt
-		* Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
+		* Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
 
 
 [1]: Documentation/devicetree/bindings/media/video-interfaces.txt
 [1]: Documentation/devicetree/bindings/media/video-interfaces.txt
 -------------------------------------------------------------------------------
 -------------------------------------------------------------------------------

+ 0 - 0
Documentation/devicetree/bindings/video/bridge/anx7814.txt → Documentation/devicetree/bindings/display/bridge/anx7814.txt


+ 0 - 0
Documentation/devicetree/bindings/video/bridge/sil-sii8620.txt → Documentation/devicetree/bindings/display/bridge/sil-sii8620.txt


+ 1 - 1
Documentation/devicetree/bindings/display/cirrus,clps711x-fb.txt

@@ -6,7 +6,7 @@ Required properties:
               location and size of the framebuffer memory.
               location and size of the framebuffer memory.
 - clocks    : phandle + clock specifier pair of the FB reference clock.
 - clocks    : phandle + clock specifier pair of the FB reference clock.
 - display   : phandle to a display node as described in
 - display   : phandle to a display node as described in
-              Documentation/devicetree/bindings/display/display-timing.txt.
+              Documentation/devicetree/bindings/display/panel/display-timing.txt.
               Additionally, the display node has to define properties:
               Additionally, the display node has to define properties:
   - bits-per-pixel: Bits per pixel.
   - bits-per-pixel: Bits per pixel.
   - ac-prescale   : LCD AC bias frequency. This frequency is the required
   - ac-prescale   : LCD AC bias frequency. This frequency is the required

+ 1 - 1
Documentation/devicetree/bindings/display/exynos/exynos7-decon.txt

@@ -38,7 +38,7 @@ Optional Properties:
 		Can be used in case timings cannot be provided otherwise
 		Can be used in case timings cannot be provided otherwise
 		or to override timings provided by the panel.
 		or to override timings provided by the panel.
 
 
-[1]: Documentation/devicetree/bindings/display/display-timing.txt
+[1]: Documentation/devicetree/bindings/display/panel/display-timing.txt
 
 
 Example:
 Example:
 
 

+ 1 - 1
Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt

@@ -83,7 +83,7 @@ in [2]. The following are properties specific to those nodes:
 		3 - for parallel output,
 		3 - for parallel output,
 		4 - for write-back interface
 		4 - for write-back interface
 
 
-[1]: Documentation/devicetree/bindings/display/display-timing.txt
+[1]: Documentation/devicetree/bindings/display/panel/display-timing.txt
 [2]: Documentation/devicetree/bindings/media/video-interfaces.txt
 [2]: Documentation/devicetree/bindings/media/video-interfaces.txt
 
 
 Example:
 Example:

+ 1 - 1
Documentation/devicetree/bindings/display/imx/fsl,imx-fb.txt

@@ -9,7 +9,7 @@ Required properties:
 
 
 Required nodes:
 Required nodes:
 - display: Phandle to a display node as described in
 - display: Phandle to a display node as described in
-	Documentation/devicetree/bindings/display/display-timing.txt
+	Documentation/devicetree/bindings/display/panel/display-timing.txt
 	Additional, the display node has to define properties:
 	Additional, the display node has to define properties:
 	- bits-per-pixel: Bits per pixel
 	- bits-per-pixel: Bits per pixel
 	- fsl,pcr: LCDC PCR value
 	- fsl,pcr: LCDC PCR value

+ 1 - 1
Documentation/devicetree/bindings/display/imx/ldb.txt

@@ -64,7 +64,7 @@ Required properties:
 Optional properties (required if display-timings are used):
 Optional properties (required if display-timings are used):
  - ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
  - ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
  - display-timings : A node that describes the display timings as defined in
  - display-timings : A node that describes the display timings as defined in
-   Documentation/devicetree/bindings/display/display-timing.txt.
+   Documentation/devicetree/bindings/display/panel/display-timing.txt.
  - fsl,data-mapping : should be "spwg" or "jeida"
  - fsl,data-mapping : should be "spwg" or "jeida"
                       This describes how the color bits are laid out in the
                       This describes how the color bits are laid out in the
                       serialized LVDS signal.
                       serialized LVDS signal.

+ 1 - 1
Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt

@@ -55,7 +55,7 @@ Required properties (DMA function blocks):
 	"mediatek,<chip>-disp-rdma"
 	"mediatek,<chip>-disp-rdma"
 	"mediatek,<chip>-disp-wdma"
 	"mediatek,<chip>-disp-wdma"
 - larb: Should contain a phandle pointing to the local arbiter device as defined
 - larb: Should contain a phandle pointing to the local arbiter device as defined
-  in Documentation/devicetree/bindings/soc/mediatek/mediatek,smi-larb.txt
+  in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
 - iommus: Should point to the respective IOMMU block with master port as
 - iommus: Should point to the respective IOMMU block with master port as
   argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
   argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
   for details.
   for details.

+ 1 - 1
Documentation/devicetree/bindings/display/msm/dsi.txt

@@ -108,7 +108,7 @@ Optional properties:
 - qcom,dsi-phy-regulator-ldo-mode: Boolean value indicating if the LDO mode PHY
 - qcom,dsi-phy-regulator-ldo-mode: Boolean value indicating if the LDO mode PHY
   regulator is wanted.
   regulator is wanted.
 
 
-[1] Documentation/devicetree/bindings/clocks/clock-bindings.txt
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
 [2] Documentation/devicetree/bindings/graph.txt
 [2] Documentation/devicetree/bindings/graph.txt
 [3] Documentation/devicetree/bindings/media/video-interfaces.txt
 [3] Documentation/devicetree/bindings/media/video-interfaces.txt
 [4] Documentation/devicetree/bindings/display/panel/
 [4] Documentation/devicetree/bindings/display/panel/

+ 1 - 1
Documentation/devicetree/bindings/display/msm/edp.txt

@@ -10,7 +10,7 @@ Required properties:
 - interrupts: The interrupt signal from the eDP block.
 - interrupts: The interrupt signal from the eDP block.
 - power-domains: Should be <&mmcc MDSS_GDSC>.
 - power-domains: Should be <&mmcc MDSS_GDSC>.
 - clocks: device clocks
 - clocks: device clocks
-  See Documentation/devicetree/bindings/clocks/clock-bindings.txt for details.
+  See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
 - clock-names: the following clocks are required:
 - clock-names: the following clocks are required:
   * "core_clk"
   * "core_clk"
   * "iface_clk"
   * "iface_clk"

+ 1 - 1
Documentation/devicetree/bindings/display/msm/hdmi.txt

@@ -49,7 +49,7 @@ Required properties:
     * "hdmi_tx_l4"
     * "hdmi_tx_l4"
 - power-domains: Should be <&mmcc MDSS_GDSC>.
 - power-domains: Should be <&mmcc MDSS_GDSC>.
 - clocks: device clocks
 - clocks: device clocks
-  See Documentation/devicetree/bindings/clocks/clock-bindings.txt for details.
+  See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
 - core-vdda-supply: phandle to vdda regulator device node
 - core-vdda-supply: phandle to vdda regulator device node
 
 
 Example:
 Example:

+ 1 - 1
Documentation/devicetree/bindings/display/panel/panel-dpi.txt

@@ -12,7 +12,7 @@ Optional properties:
 
 
 Required nodes:
 Required nodes:
 - "panel-timing" containing video timings
 - "panel-timing" containing video timings
-  (Documentation/devicetree/bindings/display/display-timing.txt)
+  (Documentation/devicetree/bindings/display/panel/display-timing.txt)
 - Video port for DPI input
 - Video port for DPI input
 
 
 Example
 Example

+ 1 - 1
Documentation/devicetree/bindings/display/panel/samsung,ld9040.txt

@@ -20,7 +20,7 @@ The device node can contain one 'port' child node with one child
 'endpoint' node, according to the bindings defined in [3]. This
 'endpoint' node, according to the bindings defined in [3]. This
 node should describe panel's video bus.
 node should describe panel's video bus.
 
 
-[1]: Documentation/devicetree/bindings/display/display-timing.txt
+[1]: Documentation/devicetree/bindings/display/panel/display-timing.txt
 [2]: Documentation/devicetree/bindings/spi/spi-bus.txt
 [2]: Documentation/devicetree/bindings/spi/spi-bus.txt
 [3]: Documentation/devicetree/bindings/media/video-interfaces.txt
 [3]: Documentation/devicetree/bindings/media/video-interfaces.txt
 
 

+ 1 - 1
Documentation/devicetree/bindings/display/panel/samsung,s6e8aa0.txt

@@ -21,7 +21,7 @@ The device node can contain one 'port' child node with one child
 'endpoint' node, according to the bindings defined in [2]. This
 'endpoint' node, according to the bindings defined in [2]. This
 node should describe panel's video bus.
 node should describe panel's video bus.
 
 
-[1]: Documentation/devicetree/bindings/display/display-timing.txt
+[1]: Documentation/devicetree/bindings/display/panel/display-timing.txt
 [2]: Documentation/devicetree/bindings/media/video-interfaces.txt
 [2]: Documentation/devicetree/bindings/media/video-interfaces.txt
 
 
 Example:
 Example:

+ 1 - 1
Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt

@@ -35,7 +35,7 @@ Optional property for different chips:
 	       Required elements: "grf"
 	       Required elements: "grf"
 
 
 For the below properties, please refer to Analogix DP binding document:
 For the below properties, please refer to Analogix DP binding document:
- * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
+ * Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
 - phys (required)
 - phys (required)
 - phy-names (required)
 - phy-names (required)
 - hpd-gpios (optional)
 - hpd-gpios (optional)

+ 1 - 1
Documentation/devicetree/bindings/display/tilcdc/panel.txt

@@ -15,7 +15,7 @@ Required properties:
  - display-timings: typical videomode of lcd panel.  Multiple video modes
  - display-timings: typical videomode of lcd panel.  Multiple video modes
    can be listed if the panel supports multiple timings, but the 'native-mode'
    can be listed if the panel supports multiple timings, but the 'native-mode'
    should be the preferred/default resolution.  Refer to
    should be the preferred/default resolution.  Refer to
-   Documentation/devicetree/bindings/display/display-timing.txt for display
+   Documentation/devicetree/bindings/display/panel/display-timing.txt for display
    timing binding details.
    timing binding details.
 
 
 Optional properties:
 Optional properties:

+ 5 - 5
Documentation/devicetree/bindings/iommu/arm,smmu.txt

@@ -36,15 +36,15 @@ conditions.
                   combined interrupt, it must be listed multiple times.
                   combined interrupt, it must be listed multiple times.
 
 
 - #iommu-cells  : See Documentation/devicetree/bindings/iommu/iommu.txt
 - #iommu-cells  : See Documentation/devicetree/bindings/iommu/iommu.txt
-                  for details. With a value of 1, each "iommus" entry
+                  for details. With a value of 1, each IOMMU specifier
                   represents a distinct stream ID emitted by that device
                   represents a distinct stream ID emitted by that device
                   into the relevant SMMU.
                   into the relevant SMMU.
 
 
                   SMMUs with stream matching support and complex masters
                   SMMUs with stream matching support and complex masters
-                  may use a value of 2, where the second cell represents
-                  an SMR mask to combine with the ID in the first cell.
-                  Care must be taken to ensure the set of matched IDs
-                  does not result in conflicts.
+                  may use a value of 2, where the second cell of the
+                  IOMMU specifier represents an SMR mask to combine with
+                  the ID in the first cell.  Care must be taken to ensure
+                  the set of matched IDs does not result in conflicts.
 
 
 ** System MMU optional properties:
 ** System MMU optional properties:
 
 

+ 1 - 2
Documentation/devicetree/bindings/mfd/as3722.txt

@@ -122,8 +122,7 @@ Following are properties of regulator subnode.
 
 
 Power-off:
 Power-off:
 =========
 =========
-AS3722 supports the system power off by turning off all its rail. This
-is provided through pm_power_off.
+AS3722 supports the system power off by turning off all its rails.
 The device node should have the following properties to enable this
 The device node should have the following properties to enable this
 functionality
 functionality
 ams,system-power-controller: Boolean, to enable the power off functionality
 ams,system-power-controller: Boolean, to enable the power off functionality

+ 2 - 2
Documentation/devicetree/bindings/mfd/omap-usb-host.txt

@@ -64,8 +64,8 @@ Required properties if child node exists:
 Properties for children:
 Properties for children:
 
 
 The OMAP HS USB Host subsystem contains EHCI and OHCI controllers.
 The OMAP HS USB Host subsystem contains EHCI and OHCI controllers.
-See Documentation/devicetree/bindings/usb/omap-ehci.txt and
-omap3-ohci.txt
+See Documentation/devicetree/bindings/usb/ehci-omap.txt and
+Documentation/devicetree/bindings/usb/ohci-omap3.txt.
 
 
 Example for OMAP4:
 Example for OMAP4:
 
 

+ 1 - 3
Documentation/devicetree/bindings/net/marvell-pp2.txt

@@ -27,9 +27,7 @@ Optional properties (port):
 
 
 - marvell,loopback: port is loopback mode
 - marvell,loopback: port is loopback mode
 - phy: a phandle to a phy node defining the PHY address (as the reg
 - phy: a phandle to a phy node defining the PHY address (as the reg
-  property, a single integer). Note: if this property isn't present,
-  then fixed link is assumed, and the 'fixed-link' property is
-  mandatory.
+  property, a single integer).
 
 
 Example:
 Example:
 
 

+ 3 - 3
Documentation/devicetree/bindings/pci/pci-iommu.txt

@@ -32,17 +32,17 @@ PCI root complex
 Optional properties
 Optional properties
 -------------------
 -------------------
 
 
-- iommu-map: Maps a Requester ID to an IOMMU and associated iommu-specifier
+- iommu-map: Maps a Requester ID to an IOMMU and associated IOMMU specifier
   data.
   data.
 
 
   The property is an arbitrary number of tuples of
   The property is an arbitrary number of tuples of
   (rid-base,iommu,iommu-base,length).
   (rid-base,iommu,iommu-base,length).
 
 
   Any RID r in the interval [rid-base, rid-base + length) is associated with
   Any RID r in the interval [rid-base, rid-base + length) is associated with
-  the listed IOMMU, with the iommu-specifier (r - rid-base + iommu-base).
+  the listed IOMMU, with the IOMMU specifier (r - rid-base + iommu-base).
 
 
 - iommu-map-mask: A mask to be applied to each Requester ID prior to being
 - iommu-map-mask: A mask to be applied to each Requester ID prior to being
-  mapped to an iommu-specifier per the iommu-map property.
+  mapped to an IOMMU specifier per the iommu-map property.
 
 
 
 
 Example (1)
 Example (1)

+ 5 - 5
Documentation/devicetree/bindings/power/reset/gpio-poweroff.txt

@@ -2,12 +2,12 @@ Driver a GPIO line that can be used to turn the power off.
 
 
 The driver supports both level triggered and edge triggered power off.
 The driver supports both level triggered and edge triggered power off.
 At driver load time, the driver will request the given gpio line and
 At driver load time, the driver will request the given gpio line and
-install a pm_power_off handler. If the optional properties 'input' is
-not found, the GPIO line will be driven in the inactive
+install a handler to power off the system. If the optional properties
+'input' is not found, the GPIO line will be driven in the inactive
 state. Otherwise its configured as an input.
 state. Otherwise its configured as an input.
 
 
-When the pm_power_off is called, the gpio is configured as an output,
-and drive active, so triggering a level triggered power off
+When the power-off handler is called, the gpio is configured as an
+output, and drive active, so triggering a level triggered power off
 condition. This will also cause an inactive->active edge condition, so
 condition. This will also cause an inactive->active edge condition, so
 triggering positive edge triggered power off. After a delay of 100ms,
 triggering positive edge triggered power off. After a delay of 100ms,
 the GPIO is set to inactive, thus causing an active->inactive edge,
 the GPIO is set to inactive, thus causing an active->inactive edge,
@@ -24,7 +24,7 @@ Required properties:
 
 
 Optional properties:
 Optional properties:
 - input : Initially configure the GPIO line as an input. Only reconfigure
 - input : Initially configure the GPIO line as an input. Only reconfigure
-  it to an output when the pm_power_off function is called. If this optional
+  it to an output when the power-off handler is called. If this optional
   property is not specified, the GPIO is initialized as an output in its
   property is not specified, the GPIO is initialized as an output in its
   inactive state.
   inactive state.
 
 

+ 1 - 2
Documentation/devicetree/bindings/power/reset/qnap-poweroff.txt

@@ -3,8 +3,7 @@
 QNAP NAS devices have a microcontroller controlling the main power
 QNAP NAS devices have a microcontroller controlling the main power
 supply. This microcontroller is connected to UART1 of the Kirkwood and
 supply. This microcontroller is connected to UART1 of the Kirkwood and
 Orion5x SoCs. Sending the character 'A', at 19200 baud, tells the
 Orion5x SoCs. Sending the character 'A', at 19200 baud, tells the
-microcontroller to turn the power off. This driver adds a handler to
-pm_power_off which is called to turn the power off.
+microcontroller to turn the power off.
 
 
 Synology NAS devices use a similar scheme, but a different baud rate,
 Synology NAS devices use a similar scheme, but a different baud rate,
 9600, and a different character, '1'.
 9600, and a different character, '1'.

+ 3 - 1
Documentation/devicetree/bindings/serial/fsl-imx-uart.txt

@@ -6,11 +6,13 @@ Required properties:
 - interrupts : Should contain uart interrupt
 - interrupts : Should contain uart interrupt
 
 
 Optional properties:
 Optional properties:
-- uart-has-rtscts : Indicate the uart has rts and cts
 - fsl,irda-mode : Indicate the uart supports irda mode
 - fsl,irda-mode : Indicate the uart supports irda mode
 - fsl,dte-mode : Indicate the uart works in DTE mode. The uart works
 - fsl,dte-mode : Indicate the uart works in DTE mode. The uart works
                   in DCE mode by default.
                   in DCE mode by default.
 
 
+Please check Documentation/devicetree/bindings/serial/serial.txt
+for the complete list of generic properties.
+
 Note: Each uart controller should have an alias correctly numbered
 Note: Each uart controller should have an alias correctly numbered
 in "aliases" node.
 in "aliases" node.
 
 

+ 0 - 20
Documentation/devicetree/bindings/soc/fsl/qman-portals.txt

@@ -5,7 +5,6 @@ Copyright (C) 2008 - 2014 Freescale Semiconductor Inc.
 CONTENTS
 CONTENTS
 
 
 	- QMan Portal
 	- QMan Portal
-	- QMan Pool Channel
 	- Example
 	- Example
 
 
 QMan Portal Node
 QMan Portal Node
@@ -82,25 +81,6 @@ These subnodes should have the following properties:
 	Definition:	The phandle to the particular hardware device that this
 	Definition:	The phandle to the particular hardware device that this
 			portal is connected to.
 			portal is connected to.
 
 
-DPAA QMan Pool Channel Nodes
-
-Pool Channels are defined with the following properties.
-
-PROPERTIES
-
-- compatible
-	Usage:		Required
-	Value type:	<stringlist>
-	Definition:	Must include "fsl,qman-pool-channel"
-			May include "fsl,<SoC>-qman-pool-channel"
-
-- fsl,qman-channel-id
-	Usage:		Required
-	Value type:	<u32>
-	Definition:	The hardware index of the channel. This can also be
-			determined by dividing any of the channel's 8 work queue
-			IDs by 8
-
 EXAMPLE
 EXAMPLE
 
 
 The example below shows a (P4080) QMan portals container/bus node with two portals
 The example below shows a (P4080) QMan portals container/bus node with two portals

+ 0 - 1
Documentation/devicetree/bindings/usb/ehci-omap.txt

@@ -29,4 +29,3 @@ usbhsehci: ehci@4a064c00 {
 &usbhsehci {
 &usbhsehci {
 	phys = <&hsusb1_phy 0 &hsusb3_phy>;
 	phys = <&hsusb1_phy 0 &hsusb3_phy>;
 };
 };
-

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

@@ -104,11 +104,13 @@ everest	Everest Semiconductor Co. Ltd.
 everspin	Everspin Technologies, Inc.
 everspin	Everspin Technologies, Inc.
 excito	Excito
 excito	Excito
 ezchip	EZchip Semiconductor
 ezchip	EZchip Semiconductor
+faraday	Faraday Technology Corporation
 fcs	Fairchild Semiconductor
 fcs	Fairchild Semiconductor
 firefly	Firefly
 firefly	Firefly
 focaltech	FocalTech Systems Co.,Ltd
 focaltech	FocalTech Systems Co.,Ltd
 friendlyarm	Guangzhou FriendlyARM Computer Tech Co., Ltd
 friendlyarm	Guangzhou FriendlyARM Computer Tech Co., Ltd
 fsl	Freescale Semiconductor
 fsl	Freescale Semiconductor
+fujitsu	Fujitsu Ltd.
 ge	General Electric Company
 ge	General Electric Company
 geekbuying	GeekBuying
 geekbuying	GeekBuying
 gef	GE Fanuc Intelligent Platforms Embedded Systems, Inc.
 gef	GE Fanuc Intelligent Platforms Embedded Systems, Inc.

+ 40 - 0
drivers/of/base.c

@@ -843,8 +843,11 @@ struct device_node *of_find_node_opts_by_path(const char *path, const char **opt
 	if (!np)
 	if (!np)
 		np = of_node_get(of_root);
 		np = of_node_get(of_root);
 	while (np && *path == '/') {
 	while (np && *path == '/') {
+		struct device_node *tmp = np;
+
 		path++; /* Increment past '/' delimiter */
 		path++; /* Increment past '/' delimiter */
 		np = __of_find_node_by_path(np, path);
 		np = __of_find_node_by_path(np, path);
+		of_node_put(tmp);
 		path = strchrnul(path, '/');
 		path = strchrnul(path, '/');
 		if (separator && separator < path)
 		if (separator && separator < path)
 			break;
 			break;
@@ -2495,3 +2498,40 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
 	return of_get_next_parent(np);
 	return of_get_next_parent(np);
 }
 }
 EXPORT_SYMBOL(of_graph_get_remote_port);
 EXPORT_SYMBOL(of_graph_get_remote_port);
+
+/**
+ * of_graph_get_remote_node() - get remote parent device_node for given port/endpoint
+ * @node: pointer to parent device_node containing graph port/endpoint
+ * @port: identifier (value of reg property) of the parent port node
+ * @endpoint: identifier (value of reg property) of the endpoint node
+ *
+ * Return: Remote device node associated with remote endpoint node linked
+ *	   to @node. Use of_node_put() on it when done.
+ */
+struct device_node *of_graph_get_remote_node(const struct device_node *node,
+					     u32 port, u32 endpoint)
+{
+	struct device_node *endpoint_node, *remote;
+
+	endpoint_node = of_graph_get_endpoint_by_regs(node, port, endpoint);
+	if (!endpoint_node) {
+		pr_debug("no valid endpoint (%d, %d) for node %s\n",
+			 port, endpoint, node->full_name);
+		return NULL;
+	}
+
+	remote = of_graph_get_remote_port_parent(endpoint_node);
+	of_node_put(endpoint_node);
+	if (!remote) {
+		pr_debug("no valid remote node\n");
+		return NULL;
+	}
+
+	if (!of_device_is_available(remote)) {
+		pr_debug("not available for remote node\n");
+		return NULL;
+	}
+
+	return remote;
+}
+EXPORT_SYMBOL(of_graph_get_remote_node);

+ 1 - 1
drivers/of/fdt.c

@@ -9,7 +9,7 @@
  * version 2 as published by the Free Software Foundation.
  * version 2 as published by the Free Software Foundation.
  */
  */
 
 
-#define pr_fmt(fmt)	"OF: fdt:" fmt
+#define pr_fmt(fmt)	"OF: fdt: " fmt
 
 
 #include <linux/crc32.h>
 #include <linux/crc32.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>

+ 12 - 7
drivers/of/irq.c

@@ -104,7 +104,7 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
 	const __be32 *match_array = initial_match_array;
 	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] = ~0 };
 	u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
 	u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
-	int imaplen, match, i;
+	int imaplen, match, i, rc = -EINVAL;
 
 
 #ifdef DEBUG
 #ifdef DEBUG
 	of_print_phandle_args("of_irq_parse_raw: ", out_irq);
 	of_print_phandle_args("of_irq_parse_raw: ", out_irq);
@@ -134,7 +134,7 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
 	pr_debug("of_irq_parse_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize);
 	pr_debug("of_irq_parse_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize);
 
 
 	if (out_irq->args_count != intsize)
 	if (out_irq->args_count != intsize)
-		return -EINVAL;
+		goto fail;
 
 
 	/* Look for this #address-cells. We have to implement the old linux
 	/* Look for this #address-cells. We have to implement the old linux
 	 * trick of looking for the parent here as some device-trees rely on it
 	 * trick of looking for the parent here as some device-trees rely on it
@@ -153,8 +153,10 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
 	pr_debug(" -> addrsize=%d\n", addrsize);
 	pr_debug(" -> addrsize=%d\n", addrsize);
 
 
 	/* Range check so that the temporary buffer doesn't overflow */
 	/* Range check so that the temporary buffer doesn't overflow */
-	if (WARN_ON(addrsize + intsize > MAX_PHANDLE_ARGS))
+	if (WARN_ON(addrsize + intsize > MAX_PHANDLE_ARGS)) {
+		rc = -EFAULT;
 		goto fail;
 		goto fail;
+	}
 
 
 	/* Precalculate the match array - this simplifies match loop */
 	/* Precalculate the match array - this simplifies match loop */
 	for (i = 0; i < addrsize; i++)
 	for (i = 0; i < addrsize; i++)
@@ -240,10 +242,11 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
 			    newintsize, newaddrsize);
 			    newintsize, newaddrsize);
 
 
 			/* Check for malformed properties */
 			/* Check for malformed properties */
-			if (WARN_ON(newaddrsize + newintsize > MAX_PHANDLE_ARGS))
-				goto fail;
-			if (imaplen < (newaddrsize + newintsize))
+			if (WARN_ON(newaddrsize + newintsize > MAX_PHANDLE_ARGS)
+			    || (imaplen < (newaddrsize + newintsize))) {
+				rc = -EFAULT;
 				goto fail;
 				goto fail;
+			}
 
 
 			imap += newaddrsize + newintsize;
 			imap += newaddrsize + newintsize;
 			imaplen -= newaddrsize + newintsize;
 			imaplen -= newaddrsize + newintsize;
@@ -271,11 +274,13 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
 		ipar = newpar;
 		ipar = newpar;
 		newpar = NULL;
 		newpar = NULL;
 	}
 	}
+	rc = -ENOENT; /* No interrupt-map found */
+
  fail:
  fail:
 	of_node_put(ipar);
 	of_node_put(ipar);
 	of_node_put(newpar);
 	of_node_put(newpar);
 
 
-	return -EINVAL;
+	return rc;
 }
 }
 EXPORT_SYMBOL_GPL(of_irq_parse_raw);
 EXPORT_SYMBOL_GPL(of_irq_parse_raw);
 
 

+ 9 - 1
drivers/of/of_pci_irq.c

@@ -93,7 +93,15 @@ int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq
 		goto err;
 		goto err;
 	return 0;
 	return 0;
 err:
 err:
-	dev_err(&pdev->dev, "of_irq_parse_pci() failed with rc=%d\n", rc);
+	if (rc == -ENOENT) {
+		dev_warn(&pdev->dev,
+			"%s: no interrupt-map found, INTx interrupts not available\n",
+			__func__);
+		pr_warn_once("%s: possibly some PCI slots don't have level triggered interrupts capability\n",
+			__func__);
+	} else {
+		dev_err(&pdev->dev, "%s: failed with rc=%d\n", __func__, rc);
+	}
 	return rc;
 	return rc;
 }
 }
 EXPORT_SYMBOL_GPL(of_irq_parse_pci);
 EXPORT_SYMBOL_GPL(of_irq_parse_pci);

+ 4 - 0
drivers/of/of_reserved_mem.c

@@ -354,6 +354,10 @@ int of_reserved_mem_device_init_by_idx(struct device *dev,
 		mutex_lock(&of_rmem_assigned_device_mutex);
 		mutex_lock(&of_rmem_assigned_device_mutex);
 		list_add(&rd->list, &of_rmem_assigned_device_list);
 		list_add(&rd->list, &of_rmem_assigned_device_list);
 		mutex_unlock(&of_rmem_assigned_device_mutex);
 		mutex_unlock(&of_rmem_assigned_device_mutex);
+		/* ensure that dma_ops is set for virtual devices
+		 * using reserved memory
+		 */
+		of_dma_configure(dev, np);
 
 
 		dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
 		dev_info(dev, "assigned reserved memory node %s\n", rmem->name);
 	} else {
 	} else {

+ 0 - 2
drivers/of/overlay.c

@@ -18,7 +18,6 @@
 #include <linux/string.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
 #include <linux/ctype.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
-#include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/idr.h>
 #include <linux/idr.h>
@@ -314,7 +313,6 @@ static int of_build_overlay_info(struct of_overlay *ov,
 
 
 	cnt = 0;
 	cnt = 0;
 	for_each_child_of_node(tree, node) {
 	for_each_child_of_node(tree, node) {
-		memset(&ovinfo[cnt], 0, sizeof(*ovinfo));
 		err = of_fill_overlay_info(ov, node, &ovinfo[cnt]);
 		err = of_fill_overlay_info(ov, node, &ovinfo[cnt]);
 		if (err == 0)
 		if (err == 0)
 			cnt++;
 			cnt++;

+ 1 - 1
drivers/of/platform.c

@@ -76,7 +76,7 @@ EXPORT_SYMBOL(of_find_device_by_node);
  * derive a unique name. If it cannot, then it will prepend names from
  * derive a unique name. If it cannot, then it will prepend names from
  * parent nodes until a unique name can be derived.
  * parent nodes until a unique name can be derived.
  */
  */
-void of_device_make_bus_id(struct device *dev)
+static void of_device_make_bus_id(struct device *dev)
 {
 {
 	struct device_node *node = dev->of_node;
 	struct device_node *node = dev->of_node;
 	const __be32 *reg;
 	const __be32 *reg;

+ 0 - 1
drivers/of/resolver.c

@@ -18,7 +18,6 @@
 #include <linux/string.h>
 #include <linux/string.h>
 #include <linux/ctype.h>
 #include <linux/ctype.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
-#include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 
 
 /* illegal phandle value (set when unresolved) */
 /* illegal phandle value (set when unresolved) */

+ 2 - 3
drivers/of/unittest.c

@@ -17,7 +17,6 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
-#include <linux/of_platform.h>
 
 
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/i2c-mux.h>
 #include <linux/i2c-mux.h>
@@ -1181,7 +1180,7 @@ static void of_unittest_destroy_tracked_overlays(void)
 	} while (defers > 0);
 	} while (defers > 0);
 }
 }
 
 
-static int of_unittest_apply_overlay(int unittest_nr, int overlay_nr,
+static int of_unittest_apply_overlay(int overlay_nr, int unittest_nr,
 		int *overlay_id)
 		int *overlay_id)
 {
 {
 	struct device_node *np = NULL;
 	struct device_node *np = NULL;
@@ -1840,7 +1839,7 @@ static void of_unittest_overlay_i2c_15(void)
 	int ret;
 	int ret;
 
 
 	/* device should enable */
 	/* device should enable */
-	ret = of_unittest_apply_overlay_check(16, 15, 0, 1, I2C_OVERLAY);
+	ret = of_unittest_apply_overlay_check(15, 15, 0, 1, I2C_OVERLAY);
 	if (ret != 0)
 	if (ret != 0)
 		return;
 		return;
 
 

+ 0 - 1
include/linux/of_device.h

@@ -13,7 +13,6 @@ struct device;
 #ifdef CONFIG_OF
 #ifdef CONFIG_OF
 extern const struct of_device_id *of_match_device(
 extern const struct of_device_id *of_match_device(
 	const struct of_device_id *matches, const struct device *dev);
 	const struct of_device_id *matches, const struct device *dev);
-extern void of_device_make_bus_id(struct device *dev);
 
 
 /**
 /**
  * of_driver_match_device - Tell if a driver's of_match_table matches a device.
  * of_driver_match_device - Tell if a driver's of_match_table matches a device.

+ 8 - 0
include/linux/of_graph.h

@@ -51,6 +51,8 @@ struct device_node *of_graph_get_endpoint_by_regs(
 struct device_node *of_graph_get_remote_port_parent(
 struct device_node *of_graph_get_remote_port_parent(
 					const struct device_node *node);
 					const struct device_node *node);
 struct device_node *of_graph_get_remote_port(const struct device_node *node);
 struct device_node *of_graph_get_remote_port(const struct device_node *node);
+struct device_node *of_graph_get_remote_node(const struct device_node *node,
+					     u32 port, u32 endpoint);
 #else
 #else
 
 
 static inline int of_graph_parse_endpoint(const struct device_node *node,
 static inline int of_graph_parse_endpoint(const struct device_node *node,
@@ -89,6 +91,12 @@ static inline struct device_node *of_graph_get_remote_port(
 {
 {
 	return NULL;
 	return NULL;
 }
 }
+static inline struct device_node *of_graph_get_remote_node(
+					const struct device_node *node,
+					u32 port, u32 endpoint)
+{
+	return NULL;
+}
 
 
 #endif /* CONFIG_OF */
 #endif /* CONFIG_OF */
 
 

+ 181 - 168
scripts/dtc/checks.c

@@ -40,16 +40,11 @@ enum checkstatus {
 
 
 struct check;
 struct check;
 
 
-typedef void (*tree_check_fn)(struct check *c, struct node *dt);
-typedef void (*node_check_fn)(struct check *c, struct node *dt, struct node *node);
-typedef void (*prop_check_fn)(struct check *c, struct node *dt,
-			      struct node *node, struct property *prop);
+typedef void (*check_fn)(struct check *c, struct dt_info *dti, struct node *node);
 
 
 struct check {
 struct check {
 	const char *name;
 	const char *name;
-	tree_check_fn tree_fn;
-	node_check_fn node_fn;
-	prop_check_fn prop_fn;
+	check_fn fn;
 	void *data;
 	void *data;
 	bool warn, error;
 	bool warn, error;
 	enum checkstatus status;
 	enum checkstatus status;
@@ -58,45 +53,24 @@ struct check {
 	struct check **prereq;
 	struct check **prereq;
 };
 };
 
 
-#define CHECK_ENTRY(nm, tfn, nfn, pfn, d, w, e, ...)	       \
-	static struct check *nm##_prereqs[] = { __VA_ARGS__ }; \
-	static struct check nm = { \
-		.name = #nm, \
-		.tree_fn = (tfn), \
-		.node_fn = (nfn), \
-		.prop_fn = (pfn), \
-		.data = (d), \
-		.warn = (w), \
-		.error = (e), \
+#define CHECK_ENTRY(_nm, _fn, _d, _w, _e, ...)	       \
+	static struct check *_nm##_prereqs[] = { __VA_ARGS__ }; \
+	static struct check _nm = { \
+		.name = #_nm, \
+		.fn = (_fn), \
+		.data = (_d), \
+		.warn = (_w), \
+		.error = (_e), \
 		.status = UNCHECKED, \
 		.status = UNCHECKED, \
-		.num_prereqs = ARRAY_SIZE(nm##_prereqs), \
-		.prereq = nm##_prereqs, \
+		.num_prereqs = ARRAY_SIZE(_nm##_prereqs), \
+		.prereq = _nm##_prereqs, \
 	};
 	};
-#define WARNING(nm, tfn, nfn, pfn, d, ...) \
-	CHECK_ENTRY(nm, tfn, nfn, pfn, d, true, false, __VA_ARGS__)
-#define ERROR(nm, tfn, nfn, pfn, d, ...) \
-	CHECK_ENTRY(nm, tfn, nfn, pfn, d, false, true, __VA_ARGS__)
-#define CHECK(nm, tfn, nfn, pfn, d, ...) \
-	CHECK_ENTRY(nm, tfn, nfn, pfn, d, false, false, __VA_ARGS__)
-
-#define TREE_WARNING(nm, d, ...) \
-	WARNING(nm, check_##nm, NULL, NULL, d, __VA_ARGS__)
-#define TREE_ERROR(nm, d, ...) \
-	ERROR(nm, check_##nm, NULL, NULL, d, __VA_ARGS__)
-#define TREE_CHECK(nm, d, ...) \
-	CHECK(nm, check_##nm, NULL, NULL, d, __VA_ARGS__)
-#define NODE_WARNING(nm, d, ...) \
-	WARNING(nm, NULL, check_##nm, NULL, d,  __VA_ARGS__)
-#define NODE_ERROR(nm, d, ...) \
-	ERROR(nm, NULL, check_##nm, NULL, d, __VA_ARGS__)
-#define NODE_CHECK(nm, d, ...) \
-	CHECK(nm, NULL, check_##nm, NULL, d, __VA_ARGS__)
-#define PROP_WARNING(nm, d, ...) \
-	WARNING(nm, NULL, NULL, check_##nm, d, __VA_ARGS__)
-#define PROP_ERROR(nm, d, ...) \
-	ERROR(nm, NULL, NULL, check_##nm, d, __VA_ARGS__)
-#define PROP_CHECK(nm, d, ...) \
-	CHECK(nm, NULL, NULL, check_##nm, d, __VA_ARGS__)
+#define WARNING(_nm, _fn, _d, ...) \
+	CHECK_ENTRY(_nm, _fn, _d, true, false, __VA_ARGS__)
+#define ERROR(_nm, _fn, _d, ...) \
+	CHECK_ENTRY(_nm, _fn, _d, false, true, __VA_ARGS__)
+#define CHECK(_nm, _fn, _d, ...) \
+	CHECK_ENTRY(_nm, _fn, _d, false, false, __VA_ARGS__)
 
 
 #ifdef __GNUC__
 #ifdef __GNUC__
 static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
 static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
@@ -123,27 +97,21 @@ static inline void check_msg(struct check *c, const char *fmt, ...)
 		check_msg((c), __VA_ARGS__); \
 		check_msg((c), __VA_ARGS__); \
 	} while (0)
 	} while (0)
 
 
-static void check_nodes_props(struct check *c, struct node *dt, struct node *node)
+static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node)
 {
 {
 	struct node *child;
 	struct node *child;
-	struct property *prop;
 
 
 	TRACE(c, "%s", node->fullpath);
 	TRACE(c, "%s", node->fullpath);
-	if (c->node_fn)
-		c->node_fn(c, dt, node);
-
-	if (c->prop_fn)
-		for_each_property(node, prop) {
-			TRACE(c, "%s\t'%s'", node->fullpath, prop->name);
-			c->prop_fn(c, dt, node, prop);
-		}
+	if (c->fn)
+		c->fn(c, dti, node);
 
 
 	for_each_child(node, child)
 	for_each_child(node, child)
-		check_nodes_props(c, dt, child);
+		check_nodes_props(c, dti, child);
 }
 }
 
 
-static bool run_check(struct check *c, struct node *dt)
+static bool run_check(struct check *c, struct dt_info *dti)
 {
 {
+	struct node *dt = dti->dt;
 	bool error = false;
 	bool error = false;
 	int i;
 	int i;
 
 
@@ -156,7 +124,7 @@ static bool run_check(struct check *c, struct node *dt)
 
 
 	for (i = 0; i < c->num_prereqs; i++) {
 	for (i = 0; i < c->num_prereqs; i++) {
 		struct check *prq = c->prereq[i];
 		struct check *prq = c->prereq[i];
-		error = error || run_check(prq, dt);
+		error = error || run_check(prq, dti);
 		if (prq->status != PASSED) {
 		if (prq->status != PASSED) {
 			c->status = PREREQ;
 			c->status = PREREQ;
 			check_msg(c, "Failed prerequisite '%s'",
 			check_msg(c, "Failed prerequisite '%s'",
@@ -167,11 +135,8 @@ static bool run_check(struct check *c, struct node *dt)
 	if (c->status != UNCHECKED)
 	if (c->status != UNCHECKED)
 		goto out;
 		goto out;
 
 
-	if (c->node_fn || c->prop_fn)
-		check_nodes_props(c, dt, dt);
+	check_nodes_props(c, dti, dt);
 
 
-	if (c->tree_fn)
-		c->tree_fn(c, dt);
 	if (c->status == UNCHECKED)
 	if (c->status == UNCHECKED)
 		c->status = PASSED;
 		c->status = PASSED;
 
 
@@ -189,13 +154,14 @@ out:
  */
  */
 
 
 /* A check which always fails, for testing purposes only */
 /* A check which always fails, for testing purposes only */
-static inline void check_always_fail(struct check *c, struct node *dt)
+static inline void check_always_fail(struct check *c, struct dt_info *dti,
+				     struct node *node)
 {
 {
 	FAIL(c, "always_fail check");
 	FAIL(c, "always_fail check");
 }
 }
-TREE_CHECK(always_fail, NULL);
+CHECK(always_fail, check_always_fail, NULL);
 
 
-static void check_is_string(struct check *c, struct node *root,
+static void check_is_string(struct check *c, struct dt_info *dti,
 			    struct node *node)
 			    struct node *node)
 {
 {
 	struct property *prop;
 	struct property *prop;
@@ -210,11 +176,11 @@ static void check_is_string(struct check *c, struct node *root,
 		     propname, node->fullpath);
 		     propname, node->fullpath);
 }
 }
 #define WARNING_IF_NOT_STRING(nm, propname) \
 #define WARNING_IF_NOT_STRING(nm, propname) \
-	WARNING(nm, NULL, check_is_string, NULL, (propname))
+	WARNING(nm, check_is_string, (propname))
 #define ERROR_IF_NOT_STRING(nm, propname) \
 #define ERROR_IF_NOT_STRING(nm, propname) \
-	ERROR(nm, NULL, check_is_string, NULL, (propname))
+	ERROR(nm, check_is_string, (propname))
 
 
-static void check_is_cell(struct check *c, struct node *root,
+static void check_is_cell(struct check *c, struct dt_info *dti,
 			  struct node *node)
 			  struct node *node)
 {
 {
 	struct property *prop;
 	struct property *prop;
@@ -229,15 +195,15 @@ static void check_is_cell(struct check *c, struct node *root,
 		     propname, node->fullpath);
 		     propname, node->fullpath);
 }
 }
 #define WARNING_IF_NOT_CELL(nm, propname) \
 #define WARNING_IF_NOT_CELL(nm, propname) \
-	WARNING(nm, NULL, check_is_cell, NULL, (propname))
+	WARNING(nm, check_is_cell, (propname))
 #define ERROR_IF_NOT_CELL(nm, propname) \
 #define ERROR_IF_NOT_CELL(nm, propname) \
-	ERROR(nm, NULL, check_is_cell, NULL, (propname))
+	ERROR(nm, check_is_cell, (propname))
 
 
 /*
 /*
  * Structural check functions
  * Structural check functions
  */
  */
 
 
-static void check_duplicate_node_names(struct check *c, struct node *dt,
+static void check_duplicate_node_names(struct check *c, struct dt_info *dti,
 				       struct node *node)
 				       struct node *node)
 {
 {
 	struct node *child, *child2;
 	struct node *child, *child2;
@@ -250,9 +216,9 @@ static void check_duplicate_node_names(struct check *c, struct node *dt,
 				FAIL(c, "Duplicate node name %s",
 				FAIL(c, "Duplicate node name %s",
 				     child->fullpath);
 				     child->fullpath);
 }
 }
-NODE_ERROR(duplicate_node_names, NULL);
+ERROR(duplicate_node_names, check_duplicate_node_names, NULL);
 
 
-static void check_duplicate_property_names(struct check *c, struct node *dt,
+static void check_duplicate_property_names(struct check *c, struct dt_info *dti,
 					   struct node *node)
 					   struct node *node)
 {
 {
 	struct property *prop, *prop2;
 	struct property *prop, *prop2;
@@ -267,14 +233,14 @@ static void check_duplicate_property_names(struct check *c, struct node *dt,
 		}
 		}
 	}
 	}
 }
 }
-NODE_ERROR(duplicate_property_names, NULL);
+ERROR(duplicate_property_names, check_duplicate_property_names, NULL);
 
 
 #define LOWERCASE	"abcdefghijklmnopqrstuvwxyz"
 #define LOWERCASE	"abcdefghijklmnopqrstuvwxyz"
 #define UPPERCASE	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 #define UPPERCASE	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 #define DIGITS		"0123456789"
 #define DIGITS		"0123456789"
 #define PROPNODECHARS	LOWERCASE UPPERCASE DIGITS ",._+*#?-"
 #define PROPNODECHARS	LOWERCASE UPPERCASE DIGITS ",._+*#?-"
 
 
-static void check_node_name_chars(struct check *c, struct node *dt,
+static void check_node_name_chars(struct check *c, struct dt_info *dti,
 				  struct node *node)
 				  struct node *node)
 {
 {
 	int n = strspn(node->name, c->data);
 	int n = strspn(node->name, c->data);
@@ -283,19 +249,19 @@ static void check_node_name_chars(struct check *c, struct node *dt,
 		FAIL(c, "Bad character '%c' in node %s",
 		FAIL(c, "Bad character '%c' in node %s",
 		     node->name[n], node->fullpath);
 		     node->name[n], node->fullpath);
 }
 }
-NODE_ERROR(node_name_chars, PROPNODECHARS "@");
+ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@");
 
 
-static void check_node_name_format(struct check *c, struct node *dt,
+static void check_node_name_format(struct check *c, struct dt_info *dti,
 				   struct node *node)
 				   struct node *node)
 {
 {
 	if (strchr(get_unitname(node), '@'))
 	if (strchr(get_unitname(node), '@'))
 		FAIL(c, "Node %s has multiple '@' characters in name",
 		FAIL(c, "Node %s has multiple '@' characters in name",
 		     node->fullpath);
 		     node->fullpath);
 }
 }
-NODE_ERROR(node_name_format, NULL, &node_name_chars);
+ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars);
 
 
-static void check_unit_address_vs_reg(struct check *c, struct node *dt,
-			     struct node *node)
+static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti,
+				      struct node *node)
 {
 {
 	const char *unitname = get_unitname(node);
 	const char *unitname = get_unitname(node);
 	struct property *prop = get_property(node, "reg");
 	struct property *prop = get_property(node, "reg");
@@ -316,18 +282,22 @@ static void check_unit_address_vs_reg(struct check *c, struct node *dt,
 			    node->fullpath);
 			    node->fullpath);
 	}
 	}
 }
 }
-NODE_WARNING(unit_address_vs_reg, NULL);
+WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL);
 
 
-static void check_property_name_chars(struct check *c, struct node *dt,
-				      struct node *node, struct property *prop)
+static void check_property_name_chars(struct check *c, struct dt_info *dti,
+				      struct node *node)
 {
 {
-	int n = strspn(prop->name, c->data);
+	struct property *prop;
+
+	for_each_property(node, prop) {
+		int n = strspn(prop->name, c->data);
 
 
-	if (n < strlen(prop->name))
-		FAIL(c, "Bad character '%c' in property name \"%s\", node %s",
-		     prop->name[n], prop->name, node->fullpath);
+		if (n < strlen(prop->name))
+			FAIL(c, "Bad character '%c' in property name \"%s\", node %s",
+			     prop->name[n], prop->name, node->fullpath);
+	}
 }
 }
-PROP_ERROR(property_name_chars, PROPNODECHARS);
+ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS);
 
 
 #define DESCLABEL_FMT	"%s%s%s%s%s"
 #define DESCLABEL_FMT	"%s%s%s%s%s"
 #define DESCLABEL_ARGS(node,prop,mark)		\
 #define DESCLABEL_ARGS(node,prop,mark)		\
@@ -336,10 +306,11 @@ PROP_ERROR(property_name_chars, PROPNODECHARS);
 	((prop) ? (prop)->name : ""), \
 	((prop) ? (prop)->name : ""), \
 	((prop) ? "' in " : ""), (node)->fullpath
 	((prop) ? "' in " : ""), (node)->fullpath
 
 
-static void check_duplicate_label(struct check *c, struct node *dt,
+static void check_duplicate_label(struct check *c, struct dt_info *dti,
 				  const char *label, struct node *node,
 				  const char *label, struct node *node,
 				  struct property *prop, struct marker *mark)
 				  struct property *prop, struct marker *mark)
 {
 {
+	struct node *dt = dti->dt;
 	struct node *othernode = NULL;
 	struct node *othernode = NULL;
 	struct property *otherprop = NULL;
 	struct property *otherprop = NULL;
 	struct marker *othermark = NULL;
 	struct marker *othermark = NULL;
@@ -362,44 +333,43 @@ static void check_duplicate_label(struct check *c, struct node *dt,
 		     DESCLABEL_ARGS(othernode, otherprop, othermark));
 		     DESCLABEL_ARGS(othernode, otherprop, othermark));
 }
 }
 
 
-static void check_duplicate_label_node(struct check *c, struct node *dt,
+static void check_duplicate_label_node(struct check *c, struct dt_info *dti,
 				       struct node *node)
 				       struct node *node)
 {
 {
 	struct label *l;
 	struct label *l;
+	struct property *prop;
 
 
 	for_each_label(node->labels, l)
 	for_each_label(node->labels, l)
-		check_duplicate_label(c, dt, l->label, node, NULL, NULL);
-}
-static void check_duplicate_label_prop(struct check *c, struct node *dt,
-				       struct node *node, struct property *prop)
-{
-	struct marker *m = prop->val.markers;
-	struct label *l;
+		check_duplicate_label(c, dti, l->label, node, NULL, NULL);
+
+	for_each_property(node, prop) {
+		struct marker *m = prop->val.markers;
 
 
-	for_each_label(prop->labels, l)
-		check_duplicate_label(c, dt, l->label, node, prop, NULL);
+		for_each_label(prop->labels, l)
+			check_duplicate_label(c, dti, l->label, node, prop, NULL);
 
 
-	for_each_marker_of_type(m, LABEL)
-		check_duplicate_label(c, dt, m->ref, node, prop, m);
+		for_each_marker_of_type(m, LABEL)
+			check_duplicate_label(c, dti, m->ref, node, prop, m);
+	}
 }
 }
-ERROR(duplicate_label, NULL, check_duplicate_label_node,
-      check_duplicate_label_prop, NULL);
+ERROR(duplicate_label, check_duplicate_label_node, NULL);
 
 
-static void check_explicit_phandles(struct check *c, struct node *root,
-				    struct node *node, struct property *prop)
+static cell_t check_phandle_prop(struct check *c, struct dt_info *dti,
+				 struct node *node, const char *propname)
 {
 {
+	struct node *root = dti->dt;
+	struct property *prop;
 	struct marker *m;
 	struct marker *m;
-	struct node *other;
 	cell_t phandle;
 	cell_t phandle;
 
 
-	if (!streq(prop->name, "phandle")
-	    && !streq(prop->name, "linux,phandle"))
-		return;
+	prop = get_property(node, propname);
+	if (!prop)
+		return 0;
 
 
 	if (prop->val.len != sizeof(cell_t)) {
 	if (prop->val.len != sizeof(cell_t)) {
 		FAIL(c, "%s has bad length (%d) %s property",
 		FAIL(c, "%s has bad length (%d) %s property",
 		     node->fullpath, prop->val.len, prop->name);
 		     node->fullpath, prop->val.len, prop->name);
-		return;
+		return 0;
 	}
 	}
 
 
 	m = prop->val.markers;
 	m = prop->val.markers;
@@ -411,14 +381,13 @@ static void check_explicit_phandles(struct check *c, struct node *root,
 			 * by construction. */ {
 			 * by construction. */ {
 			FAIL(c, "%s in %s is a reference to another node",
 			FAIL(c, "%s in %s is a reference to another node",
 			     prop->name, node->fullpath);
 			     prop->name, node->fullpath);
-			return;
 		}
 		}
 		/* But setting this node's phandle equal to its own
 		/* But setting this node's phandle equal to its own
 		 * phandle is allowed - that means allocate a unique
 		 * phandle is allowed - that means allocate a unique
 		 * phandle for this node, even if it's not otherwise
 		 * phandle for this node, even if it's not otherwise
 		 * referenced.  The value will be filled in later, so
 		 * referenced.  The value will be filled in later, so
-		 * no further checking for now. */
-		return;
+		 * we treat it as having no phandle data for now. */
+		return 0;
 	}
 	}
 
 
 	phandle = propval_cell(prop);
 	phandle = propval_cell(prop);
@@ -426,12 +395,36 @@ static void check_explicit_phandles(struct check *c, struct node *root,
 	if ((phandle == 0) || (phandle == -1)) {
 	if ((phandle == 0) || (phandle == -1)) {
 		FAIL(c, "%s has bad value (0x%x) in %s property",
 		FAIL(c, "%s has bad value (0x%x) in %s property",
 		     node->fullpath, phandle, prop->name);
 		     node->fullpath, phandle, prop->name);
-		return;
+		return 0;
 	}
 	}
 
 
-	if (node->phandle && (node->phandle != phandle))
-		FAIL(c, "%s has %s property which replaces existing phandle information",
-		     node->fullpath, prop->name);
+	return phandle;
+}
+
+static void check_explicit_phandles(struct check *c, struct dt_info *dti,
+				    struct node *node)
+{
+	struct node *root = dti->dt;
+	struct node *other;
+	cell_t phandle, linux_phandle;
+
+	/* Nothing should have assigned phandles yet */
+	assert(!node->phandle);
+
+	phandle = check_phandle_prop(c, dti, node, "phandle");
+
+	linux_phandle = check_phandle_prop(c, dti, node, "linux,phandle");
+
+	if (!phandle && !linux_phandle)
+		/* No valid phandles; nothing further to check */
+		return;
+
+	if (linux_phandle && phandle && (phandle != linux_phandle))
+		FAIL(c, "%s has mismatching 'phandle' and 'linux,phandle'"
+		     " properties", node->fullpath);
+
+	if (linux_phandle && !phandle)
+		phandle = linux_phandle;
 
 
 	other = get_node_by_phandle(root, phandle);
 	other = get_node_by_phandle(root, phandle);
 	if (other && (other != node)) {
 	if (other && (other != node)) {
@@ -442,9 +435,9 @@ static void check_explicit_phandles(struct check *c, struct node *root,
 
 
 	node->phandle = phandle;
 	node->phandle = phandle;
 }
 }
-PROP_ERROR(explicit_phandles, NULL);
+ERROR(explicit_phandles, check_explicit_phandles, NULL);
 
 
-static void check_name_properties(struct check *c, struct node *root,
+static void check_name_properties(struct check *c, struct dt_info *dti,
 				  struct node *node)
 				  struct node *node)
 {
 {
 	struct property **pp, *prop = NULL;
 	struct property **pp, *prop = NULL;
@@ -472,60 +465,73 @@ static void check_name_properties(struct check *c, struct node *root,
 	}
 	}
 }
 }
 ERROR_IF_NOT_STRING(name_is_string, "name");
 ERROR_IF_NOT_STRING(name_is_string, "name");
-NODE_ERROR(name_properties, NULL, &name_is_string);
+ERROR(name_properties, check_name_properties, NULL, &name_is_string);
 
 
 /*
 /*
  * Reference fixup functions
  * Reference fixup functions
  */
  */
 
 
-static void fixup_phandle_references(struct check *c, struct node *dt,
-				     struct node *node, struct property *prop)
+static void fixup_phandle_references(struct check *c, struct dt_info *dti,
+				     struct node *node)
 {
 {
-	struct marker *m = prop->val.markers;
-	struct node *refnode;
-	cell_t phandle;
+	struct node *dt = dti->dt;
+	struct property *prop;
 
 
-	for_each_marker_of_type(m, REF_PHANDLE) {
-		assert(m->offset + sizeof(cell_t) <= prop->val.len);
+	for_each_property(node, prop) {
+		struct marker *m = prop->val.markers;
+		struct node *refnode;
+		cell_t phandle;
+
+		for_each_marker_of_type(m, REF_PHANDLE) {
+			assert(m->offset + sizeof(cell_t) <= prop->val.len);
+
+			refnode = get_node_by_ref(dt, m->ref);
+			if (! refnode) {
+				if (!(dti->dtsflags & DTSF_PLUGIN))
+					FAIL(c, "Reference to non-existent node or "
+							"label \"%s\"\n", m->ref);
+				else /* mark the entry as unresolved */
+					*((cell_t *)(prop->val.val + m->offset)) =
+						cpu_to_fdt32(0xffffffff);
+				continue;
+			}
 
 
-		refnode = get_node_by_ref(dt, m->ref);
-		if (! refnode) {
-			FAIL(c, "Reference to non-existent node or label \"%s\"\n",
-			     m->ref);
-			continue;
+			phandle = get_node_phandle(dt, refnode);
+			*((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
 		}
 		}
-
-		phandle = get_node_phandle(dt, refnode);
-		*((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
 	}
 	}
 }
 }
-ERROR(phandle_references, NULL, NULL, fixup_phandle_references, NULL,
+ERROR(phandle_references, fixup_phandle_references, NULL,
       &duplicate_node_names, &explicit_phandles);
       &duplicate_node_names, &explicit_phandles);
 
 
-static void fixup_path_references(struct check *c, struct node *dt,
-				  struct node *node, struct property *prop)
+static void fixup_path_references(struct check *c, struct dt_info *dti,
+				  struct node *node)
 {
 {
-	struct marker *m = prop->val.markers;
-	struct node *refnode;
-	char *path;
-
-	for_each_marker_of_type(m, REF_PATH) {
-		assert(m->offset <= prop->val.len);
-
-		refnode = get_node_by_ref(dt, m->ref);
-		if (!refnode) {
-			FAIL(c, "Reference to non-existent node or label \"%s\"\n",
-			     m->ref);
-			continue;
-		}
+	struct node *dt = dti->dt;
+	struct property *prop;
+
+	for_each_property(node, prop) {
+		struct marker *m = prop->val.markers;
+		struct node *refnode;
+		char *path;
+
+		for_each_marker_of_type(m, REF_PATH) {
+			assert(m->offset <= prop->val.len);
 
 
-		path = refnode->fullpath;
-		prop->val = data_insert_at_marker(prop->val, m, path,
-						  strlen(path) + 1);
+			refnode = get_node_by_ref(dt, m->ref);
+			if (!refnode) {
+				FAIL(c, "Reference to non-existent node or label \"%s\"\n",
+				     m->ref);
+				continue;
+			}
+
+			path = refnode->fullpath;
+			prop->val = data_insert_at_marker(prop->val, m, path,
+							  strlen(path) + 1);
+		}
 	}
 	}
 }
 }
-ERROR(path_references, NULL, NULL, fixup_path_references, NULL,
-      &duplicate_node_names);
+ERROR(path_references, fixup_path_references, NULL, &duplicate_node_names);
 
 
 /*
 /*
  * Semantic checks
  * Semantic checks
@@ -538,7 +544,7 @@ WARNING_IF_NOT_STRING(device_type_is_string, "device_type");
 WARNING_IF_NOT_STRING(model_is_string, "model");
 WARNING_IF_NOT_STRING(model_is_string, "model");
 WARNING_IF_NOT_STRING(status_is_string, "status");
 WARNING_IF_NOT_STRING(status_is_string, "status");
 
 
-static void fixup_addr_size_cells(struct check *c, struct node *dt,
+static void fixup_addr_size_cells(struct check *c, struct dt_info *dti,
 				  struct node *node)
 				  struct node *node)
 {
 {
 	struct property *prop;
 	struct property *prop;
@@ -554,7 +560,7 @@ static void fixup_addr_size_cells(struct check *c, struct node *dt,
 	if (prop)
 	if (prop)
 		node->size_cells = propval_cell(prop);
 		node->size_cells = propval_cell(prop);
 }
 }
-WARNING(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL,
+WARNING(addr_size_cells, fixup_addr_size_cells, NULL,
 	&address_cells_is_cell, &size_cells_is_cell);
 	&address_cells_is_cell, &size_cells_is_cell);
 
 
 #define node_addr_cells(n) \
 #define node_addr_cells(n) \
@@ -562,7 +568,7 @@ WARNING(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL,
 #define node_size_cells(n) \
 #define node_size_cells(n) \
 	(((n)->size_cells == -1) ? 1 : (n)->size_cells)
 	(((n)->size_cells == -1) ? 1 : (n)->size_cells)
 
 
-static void check_reg_format(struct check *c, struct node *dt,
+static void check_reg_format(struct check *c, struct dt_info *dti,
 			     struct node *node)
 			     struct node *node)
 {
 {
 	struct property *prop;
 	struct property *prop;
@@ -589,9 +595,9 @@ static void check_reg_format(struct check *c, struct node *dt,
 		     "(#address-cells == %d, #size-cells == %d)",
 		     "(#address-cells == %d, #size-cells == %d)",
 		     node->fullpath, prop->val.len, addr_cells, size_cells);
 		     node->fullpath, prop->val.len, addr_cells, size_cells);
 }
 }
-NODE_WARNING(reg_format, NULL, &addr_size_cells);
+WARNING(reg_format, check_reg_format, NULL, &addr_size_cells);
 
 
-static void check_ranges_format(struct check *c, struct node *dt,
+static void check_ranges_format(struct check *c, struct dt_info *dti,
 				struct node *node)
 				struct node *node)
 {
 {
 	struct property *prop;
 	struct property *prop;
@@ -630,12 +636,12 @@ static void check_ranges_format(struct check *c, struct node *dt,
 		     p_addr_cells, c_addr_cells, c_size_cells);
 		     p_addr_cells, c_addr_cells, c_size_cells);
 	}
 	}
 }
 }
-NODE_WARNING(ranges_format, NULL, &addr_size_cells);
+WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells);
 
 
 /*
 /*
  * Style checks
  * Style checks
  */
  */
-static void check_avoid_default_addr_size(struct check *c, struct node *dt,
+static void check_avoid_default_addr_size(struct check *c, struct dt_info *dti,
 					  struct node *node)
 					  struct node *node)
 {
 {
 	struct property *reg, *ranges;
 	struct property *reg, *ranges;
@@ -657,14 +663,21 @@ static void check_avoid_default_addr_size(struct check *c, struct node *dt,
 		FAIL(c, "Relying on default #size-cells value for %s",
 		FAIL(c, "Relying on default #size-cells value for %s",
 		     node->fullpath);
 		     node->fullpath);
 }
 }
-NODE_WARNING(avoid_default_addr_size, NULL, &addr_size_cells);
+WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL,
+	&addr_size_cells);
 
 
 static void check_obsolete_chosen_interrupt_controller(struct check *c,
 static void check_obsolete_chosen_interrupt_controller(struct check *c,
-						       struct node *dt)
+						       struct dt_info *dti,
+						       struct node *node)
 {
 {
+	struct node *dt = dti->dt;
 	struct node *chosen;
 	struct node *chosen;
 	struct property *prop;
 	struct property *prop;
 
 
+	if (node != dt)
+		return;
+
+
 	chosen = get_node_by_path(dt, "/chosen");
 	chosen = get_node_by_path(dt, "/chosen");
 	if (!chosen)
 	if (!chosen)
 		return;
 		return;
@@ -674,7 +687,8 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c,
 		FAIL(c, "/chosen has obsolete \"interrupt-controller\" "
 		FAIL(c, "/chosen has obsolete \"interrupt-controller\" "
 		     "property");
 		     "property");
 }
 }
-TREE_WARNING(obsolete_chosen_interrupt_controller, NULL);
+WARNING(obsolete_chosen_interrupt_controller,
+	check_obsolete_chosen_interrupt_controller, NULL);
 
 
 static struct check *check_table[] = {
 static struct check *check_table[] = {
 	&duplicate_node_names, &duplicate_property_names,
 	&duplicate_node_names, &duplicate_property_names,
@@ -760,9 +774,8 @@ void parse_checks_option(bool warn, bool error, const char *arg)
 	die("Unrecognized check name \"%s\"\n", name);
 	die("Unrecognized check name \"%s\"\n", name);
 }
 }
 
 
-void process_checks(bool force, struct boot_info *bi)
+void process_checks(bool force, struct dt_info *dti)
 {
 {
-	struct node *dt = bi->dt;
 	int i;
 	int i;
 	int error = 0;
 	int error = 0;
 
 
@@ -770,7 +783,7 @@ void process_checks(bool force, struct boot_info *bi)
 		struct check *c = check_table[i];
 		struct check *c = check_table[i];
 
 
 		if (c->warn || c->error)
 		if (c->warn || c->error)
-			error = error || run_check(c, dt);
+			error = error || run_check(c, dti);
 	}
 	}
 
 
 	if (error) {
 	if (error) {

+ 13 - 8
scripts/dtc/dtc-lexer.l

@@ -121,6 +121,11 @@ static void lexical_error(const char *fmt, ...);
 			return DT_V1;
 			return DT_V1;
 		}
 		}
 
 
+<*>"/plugin/"	{
+			DPRINT("Keyword: /plugin/\n");
+			return DT_PLUGIN;
+		}
+
 <*>"/memreserve/"	{
 <*>"/memreserve/"	{
 			DPRINT("Keyword: /memreserve/\n");
 			DPRINT("Keyword: /memreserve/\n");
 			BEGIN_DEFAULT();
 			BEGIN_DEFAULT();
@@ -184,16 +189,16 @@ static void lexical_error(const char *fmt, ...);
 			if (d.len == 1) {
 			if (d.len == 1) {
 				lexical_error("Empty character literal");
 				lexical_error("Empty character literal");
 				yylval.integer = 0;
 				yylval.integer = 0;
-				return DT_CHAR_LITERAL;
-			}
+			} else {
+				yylval.integer = (unsigned char)d.val[0];
 
 
-			yylval.integer = (unsigned char)d.val[0];
-
-			if (d.len > 2)
-				lexical_error("Character literal has %d"
-					      " characters instead of 1",
-					      d.len - 1);
+				if (d.len > 2)
+					lexical_error("Character literal has %d"
+						      " characters instead of 1",
+						      d.len - 1);
+			}
 
 
+			data_free(d);
 			return DT_CHAR_LITERAL;
 			return DT_CHAR_LITERAL;
 		}
 		}
 
 

+ 331 - 319
scripts/dtc/dtc-lexer.lex.c_shipped

@@ -8,8 +8,8 @@
 
 
 #define FLEX_SCANNER
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 39
+#define YY_FLEX_MINOR_VERSION 6
+#define YY_FLEX_SUBMINOR_VERSION 1
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #define FLEX_BETA
 #endif
 #endif
@@ -88,25 +88,13 @@ typedef unsigned int flex_uint32_t;
 
 
 #endif /* ! FLEXINT_H */
 #endif /* ! FLEXINT_H */
 
 
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else	/* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif	/* defined (__STDC__) */
-#endif	/* ! __cplusplus */
-
-#ifdef YY_USE_CONST
+/* TODO: this is always defined, so inline it */
 #define yyconst const
 #define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
 #else
 #else
-#define yyconst
+#define yynoreturn
 #endif
 #endif
 
 
 /* Returned upon end-of-file. */
 /* Returned upon end-of-file. */
@@ -167,7 +155,7 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE;
 typedef size_t yy_size_t;
 typedef size_t yy_size_t;
 #endif
 #endif
 
 
-extern yy_size_t yyleng;
+extern int yyleng;
 
 
 extern FILE *yyin, *yyout;
 extern FILE *yyin, *yyout;
 
 
@@ -206,12 +194,12 @@ struct yy_buffer_state
 	/* Size of input buffer in bytes, not including room for EOB
 	/* Size of input buffer in bytes, not including room for EOB
 	 * characters.
 	 * characters.
 	 */
 	 */
-	yy_size_t yy_buf_size;
+	int yy_buf_size;
 
 
 	/* Number of characters read into yy_ch_buf, not including EOB
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 * characters.
 	 */
 	 */
-	yy_size_t yy_n_chars;
+	int yy_n_chars;
 
 
 	/* Whether we "own" the buffer - i.e., we know we created it,
 	/* Whether we "own" the buffer - i.e., we know we created it,
 	 * and can realloc() it to grow it, and should free() it to
 	 * and can realloc() it to grow it, and should free() it to
@@ -234,7 +222,7 @@ struct yy_buffer_state
 
 
     int yy_bs_lineno; /**< The line count. */
     int yy_bs_lineno; /**< The line count. */
     int yy_bs_column; /**< The column count. */
     int yy_bs_column; /**< The column count. */
-    
+
 	/* Whether to try to fill the input buffer when we reach the
 	/* Whether to try to fill the input buffer when we reach the
 	 * end of it.
 	 * end of it.
 	 */
 	 */
@@ -262,7 +250,7 @@ struct yy_buffer_state
 /* Stack of input buffers. */
 /* Stack of input buffers. */
 static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
 static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
 static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
 static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
 
 
 /* We provide macros for accessing buffer states in case in the
 /* We provide macros for accessing buffer states in case in the
  * future we want to put the buffer states in a more general
  * future we want to put the buffer states in a more general
@@ -281,11 +269,11 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
 
 
 /* yy_hold_char holds the character lost when yytext is formed. */
 /* yy_hold_char holds the character lost when yytext is formed. */
 static char yy_hold_char;
 static char yy_hold_char;
-static yy_size_t yy_n_chars;		/* number of characters read into yy_ch_buf */
-yy_size_t yyleng;
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+int yyleng;
 
 
 /* Points to current character in buffer. */
 /* Points to current character in buffer. */
-static char *yy_c_buf_p = (char *) 0;
+static char *yy_c_buf_p = NULL;
 static int yy_init = 0;		/* whether we need to initialize */
 static int yy_init = 0;		/* whether we need to initialize */
 static int yy_start = 0;	/* start state number */
 static int yy_start = 0;	/* start state number */
 
 
@@ -310,7 +298,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
 
 
 YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
 YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
 YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
 YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len  );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
 
 
 void *yyalloc (yy_size_t  );
 void *yyalloc (yy_size_t  );
 void *yyrealloc (void *,yy_size_t  );
 void *yyrealloc (void *,yy_size_t  );
@@ -342,12 +330,12 @@ void yyfree (void *  );
 
 
 /* Begin user sect3 */
 /* Begin user sect3 */
 
 
-#define yywrap() 1
+#define yywrap() (/*CONSTCOND*/1)
 #define YY_SKIP_YYWRAP
 #define YY_SKIP_YYWRAP
 
 
 typedef unsigned char YY_CHAR;
 typedef unsigned char YY_CHAR;
 
 
-FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+FILE *yyin = NULL, *yyout = NULL;
 
 
 typedef int yy_state_type;
 typedef int yy_state_type;
 
 
@@ -356,25 +344,28 @@ extern int yylineno;
 int yylineno = 1;
 int yylineno = 1;
 
 
 extern char *yytext;
 extern char *yytext;
+#ifdef yytext_ptr
+#undef yytext_ptr
+#endif
 #define yytext_ptr yytext
 #define yytext_ptr yytext
 
 
 static yy_state_type yy_get_previous_state (void );
 static yy_state_type yy_get_previous_state (void );
 static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
 static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
 static int yy_get_next_buffer (void );
 static int yy_get_next_buffer (void );
-static void yy_fatal_error (yyconst char msg[]  );
+static void yynoreturn yy_fatal_error (yyconst char* msg  );
 
 
 /* Done after the current pattern has been matched and before the
 /* Done after the current pattern has been matched and before the
  * corresponding action - sets up yytext.
  * corresponding action - sets up yytext.
  */
  */
 #define YY_DO_BEFORE_ACTION \
 #define YY_DO_BEFORE_ACTION \
 	(yytext_ptr) = yy_bp; \
 	(yytext_ptr) = yy_bp; \
-	yyleng = (size_t) (yy_cp - yy_bp); \
+	yyleng = (int) (yy_cp - yy_bp); \
 	(yy_hold_char) = *yy_cp; \
 	(yy_hold_char) = *yy_cp; \
 	*yy_cp = '\0'; \
 	*yy_cp = '\0'; \
 	(yy_c_buf_p) = yy_cp;
 	(yy_c_buf_p) = yy_cp;
 
 
-#define YY_NUM_RULES 30
-#define YY_END_OF_BUFFER 31
+#define YY_NUM_RULES 31
+#define YY_END_OF_BUFFER 32
 /* This struct is not used in this scanner,
 /* This struct is not used in this scanner,
    but its presence is necessary. */
    but its presence is necessary. */
 struct yy_trans_info
 struct yy_trans_info
@@ -382,28 +373,29 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	flex_int32_t yy_nxt;
 	};
 	};
-static yyconst flex_int16_t yy_accept[159] =
+static yyconst flex_int16_t yy_accept[166] =
     {   0,
     {   0,
-        0,    0,    0,    0,    0,    0,    0,    0,   31,   29,
-       18,   18,   29,   29,   29,   29,   29,   29,   29,   29,
-       29,   29,   29,   29,   29,   29,   15,   16,   16,   29,
-       16,   10,   10,   18,   26,    0,    3,    0,   27,   12,
-        0,    0,   11,    0,    0,    0,    0,    0,    0,    0,
-       21,   23,   25,   24,   22,    0,    9,   28,    0,    0,
-        0,   14,   14,   16,   16,   16,   10,   10,   10,    0,
-       12,    0,   11,    0,    0,    0,   20,    0,    0,    0,
-        0,    0,    0,    0,    0,   16,   10,   10,   10,    0,
-       13,   19,    0,    0,    0,    0,    0,    0,    0,    0,
-
-        0,   16,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,   16,    6,    0,    0,    0,    0,    0,    0,    2,
-        0,    0,    0,    0,    0,    0,    0,    0,    4,   17,
-        0,    0,    2,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    1,    0,    0,    0,    0,
-        5,    8,    0,    0,    0,    0,    7,    0
+        0,    0,    0,    0,    0,    0,    0,    0,   32,   30,
+       19,   19,   30,   30,   30,   30,   30,   30,   30,   30,
+       30,   30,   30,   30,   30,   30,   16,   17,   17,   30,
+       17,   11,   11,   19,   27,    0,    3,    0,   28,   13,
+        0,    0,   12,    0,    0,    0,    0,    0,    0,    0,
+        0,   22,   24,   26,   25,   23,    0,   10,   29,    0,
+        0,    0,   15,   15,   17,   17,   17,   11,   11,   11,
+        0,   13,    0,   12,    0,    0,    0,   21,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,   17,   11,   11,
+       11,    0,   14,   20,    0,    0,    0,    0,    0,    0,
+
+        0,    0,    0,    0,   17,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,   17,    7,    0,    0,    0,
+        0,    0,    0,    0,    2,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    4,   18,    0,    0,    5,    2,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    1,    0,    0,    0,    0,    6,    9,    0,
+        0,    0,    0,    8,    0
     } ;
     } ;
 
 
-static yyconst flex_int32_t yy_ec[256] =
+static yyconst YY_CHAR yy_ec[256] =
     {   0,
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         4,    4,    4,    1,    1,    1,    1,    1,    1,    1,
         4,    4,    4,    1,    1,    1,    1,    1,    1,    1,
@@ -416,9 +408,9 @@ static yyconst flex_int32_t yy_ec[256] =
        22,   22,   22,   22,   24,   22,   22,   25,   22,   22,
        22,   22,   22,   22,   24,   22,   22,   25,   22,   22,
         1,   26,   27,    1,   22,    1,   21,   28,   29,   30,
         1,   26,   27,    1,   22,    1,   21,   28,   29,   30,
 
 
-       31,   21,   22,   22,   32,   22,   22,   33,   34,   35,
-       36,   37,   22,   38,   39,   40,   41,   42,   22,   25,
-       43,   22,   44,   45,   46,    1,    1,    1,    1,    1,
+       31,   21,   32,   22,   33,   22,   22,   34,   35,   36,
+       37,   38,   22,   39,   40,   41,   42,   43,   22,   25,
+       44,   22,   45,   46,   47,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -435,163 +427,165 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1
         1,    1,    1,    1,    1
     } ;
     } ;
 
 
-static yyconst flex_int32_t yy_meta[47] =
+static yyconst YY_CHAR yy_meta[48] =
     {   0,
     {   0,
         1,    1,    1,    1,    1,    1,    2,    3,    1,    2,
         1,    1,    1,    1,    1,    1,    2,    3,    1,    2,
         2,    2,    4,    5,    5,    5,    6,    1,    1,    1,
         2,    2,    4,    5,    5,    5,    6,    1,    1,    1,
         7,    8,    8,    8,    8,    1,    1,    7,    7,    7,
         7,    8,    8,    8,    8,    1,    1,    7,    7,    7,
         7,    8,    8,    8,    8,    8,    8,    8,    8,    8,
         7,    8,    8,    8,    8,    8,    8,    8,    8,    8,
-        8,    8,    8,    3,    1,    4
+        8,    8,    8,    8,    3,    1,    4
     } ;
     } ;
 
 
-static yyconst flex_int16_t yy_base[173] =
+static yyconst flex_uint16_t yy_base[180] =
     {   0,
     {   0,
-        0,  383,   34,  382,   65,  381,   37,  105,  387,  391,
-       54,  111,  367,  110,  109,  109,  112,   41,  366,  104,
-      367,  338,  124,  117,    0,  144,  391,    0,  121,    0,
-      135,  155,  140,  179,  391,  160,  391,  379,  391,    0,
-      368,  141,  391,  167,  370,  376,  346,  103,  342,  345,
-      391,  391,  391,  391,  391,  358,  391,  391,  175,  342,
-      338,  391,  355,    0,  185,  339,  184,  347,  346,    0,
-        0,  322,  175,  357,  175,  363,  352,  324,  330,  323,
-      332,  326,  201,  324,  329,  322,  391,  333,  181,  309,
-      391,  341,  340,  313,  320,  338,  178,  311,  146,  317,
-
-      314,  315,  335,  331,  303,  300,  309,  299,  308,  188,
-      336,  335,  391,  305,  320,  281,  283,  271,  203,  288,
-      281,  271,  266,  264,  245,  242,  208,  104,  391,  391,
-      244,  218,  204,  219,  206,  224,  201,  212,  204,  229,
-      215,  208,  207,  200,  219,  391,  233,  221,  200,  181,
-      391,  391,  149,  122,   86,   41,  391,  391,  245,  251,
-      259,  263,  267,  273,  280,  284,  292,  300,  304,  310,
-      318,  326
+        0,  393,   35,  392,   66,  391,   38,  107,  397,  401,
+       55,  113,  377,  112,  111,  111,  114,   42,  376,  106,
+      377,  347,  126,  120,    0,  147,  401,    0,  124,    0,
+      137,  158,  170,  163,  401,  153,  401,  389,  401,    0,
+      378,  120,  401,  131,  380,  386,  355,  139,  351,  355,
+      351,  401,  401,  401,  401,  401,  367,  401,  401,  185,
+      350,  346,  401,  364,    0,  185,  347,  189,  356,  355,
+        0,    0,  330,  180,  366,  141,  372,  361,  332,  338,
+      331,  341,  334,  326,  205,  331,  337,  329,  401,  341,
+      167,  316,  401,  349,  348,  320,  328,  346,  180,  318,
+
+      324,  209,  324,  320,  322,  342,  338,  309,  306,  315,
+      305,  315,  312,  192,  342,  341,  401,  293,  306,  282,
+      268,  252,  255,  203,  285,  282,  272,  268,  252,  233,
+      232,  239,  208,  107,  401,  401,  238,  211,  401,  211,
+      212,  208,  228,  203,  215,  207,  233,  222,  212,  211,
+      203,  227,  401,  237,  225,  204,  185,  401,  401,  149,
+      128,   88,   42,  401,  401,  253,  259,  267,  271,  275,
+      281,  288,  292,  300,  308,  312,  318,  326,  334
     } ;
     } ;
 
 
-static yyconst flex_int16_t yy_def[173] =
+static yyconst flex_int16_t yy_def[180] =
     {   0,
     {   0,
-      158,    1,    1,    3,  158,    5,    1,    1,  158,  158,
-      158,  158,  158,  159,  160,  161,  158,  158,  158,  158,
-      162,  158,  158,  158,  163,  162,  158,  164,  165,  164,
-      164,  158,  158,  158,  158,  159,  158,  159,  158,  166,
-      158,  161,  158,  161,  167,  168,  158,  158,  158,  158,
-      158,  158,  158,  158,  158,  162,  158,  158,  158,  158,
-      158,  158,  162,  164,  165,  164,  158,  158,  158,  169,
-      166,  170,  161,  167,  167,  168,  158,  158,  158,  158,
-      158,  158,  158,  158,  158,  164,  158,  158,  169,  170,
-      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
-
-      158,  164,  158,  158,  158,  158,  158,  158,  158,  171,
-      158,  164,  158,  158,  158,  158,  158,  158,  171,  158,
-      171,  158,  158,  158,  158,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
-      172,  158,  158,  158,  172,  158,  172,  158,  158,  158,
-      158,  158,  158,  158,  158,  158,  158,    0,  158,  158,
-      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
-      158,  158
+      165,    1,    1,    3,  165,    5,    1,    1,  165,  165,
+      165,  165,  165,  166,  167,  168,  165,  165,  165,  165,
+      169,  165,  165,  165,  170,  169,  165,  171,  172,  171,
+      171,  165,  165,  165,  165,  166,  165,  166,  165,  173,
+      165,  168,  165,  168,  174,  175,  165,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  169,  165,  165,  165,
+      165,  165,  165,  169,  171,  172,  171,  165,  165,  165,
+      176,  173,  177,  168,  174,  174,  175,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  165,  171,  165,  165,
+      176,  177,  165,  165,  165,  165,  165,  165,  165,  165,
+
+      165,  165,  165,  165,  171,  165,  165,  165,  165,  165,
+      165,  165,  165,  178,  165,  171,  165,  165,  165,  165,
+      165,  165,  165,  178,  165,  178,  165,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  165,  179,  165,  165,
+      165,  179,  165,  179,  165,  165,  165,  165,  165,  165,
+      165,  165,  165,  165,    0,  165,  165,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  165,  165,  165
     } ;
     } ;
 
 
-static yyconst flex_int16_t yy_nxt[438] =
+static yyconst flex_uint16_t yy_nxt[449] =
     {   0,
     {   0,
        10,   11,   12,   11,   13,   14,   10,   15,   16,   10,
        10,   11,   12,   11,   13,   14,   10,   15,   16,   10,
        10,   10,   17,   10,   10,   10,   10,   18,   19,   20,
        10,   10,   17,   10,   10,   10,   10,   18,   19,   20,
        21,   21,   21,   21,   21,   10,   10,   21,   21,   21,
        21,   21,   21,   21,   21,   10,   10,   21,   21,   21,
        21,   21,   21,   21,   21,   21,   21,   21,   21,   21,
        21,   21,   21,   21,   21,   21,   21,   21,   21,   21,
-       21,   21,   21,   10,   22,   10,   24,   25,   25,   25,
-       32,   33,   33,  157,   26,   34,   34,   34,   51,   52,
-       27,   26,   26,   26,   26,   10,   11,   12,   11,   13,
-       14,   28,   15,   16,   28,   28,   28,   24,   28,   28,
-       28,   10,   18,   19,   20,   29,   29,   29,   29,   29,
-       30,   10,   29,   29,   29,   29,   29,   29,   29,   29,
-
-       29,   29,   29,   29,   29,   29,   29,   29,   10,   22,
-       10,   23,   34,   34,   34,   37,   39,   43,   32,   33,
-       33,   45,   54,   55,   46,   59,   45,   64,  156,   46,
-       64,   64,   64,   79,   44,   38,   59,   57,  134,   47,
-      135,   48,   80,   49,   47,   50,   48,   99,   61,   43,
-       50,  110,   41,   67,   67,   67,   60,   63,   63,   63,
-       57,  155,   68,   69,   63,   37,   44,   66,   67,   67,
-       67,   63,   63,   63,   63,   73,   59,   68,   69,   70,
-       34,   34,   34,   43,   75,   38,  154,   92,   83,   83,
-       83,   64,   44,  120,   64,   64,   64,   67,   67,   67,
-
-       44,   57,   99,   68,   69,  107,   68,   69,  120,  127,
-      108,  153,  152,  121,   83,   83,   83,  133,  133,  133,
-      146,  133,  133,  133,  146,  140,  140,  140,  121,  141,
-      140,  140,  140,  151,  141,  158,  150,  149,  148,  144,
-      147,  143,  142,  139,  147,   36,   36,   36,   36,   36,
-       36,   36,   36,   40,  138,  137,  136,   40,   40,   42,
-       42,   42,   42,   42,   42,   42,   42,   56,   56,   56,
-       56,   62,  132,   62,   64,  131,  130,   64,  129,   64,
-       64,   65,  128,  158,   65,   65,   65,   65,   71,  127,
-       71,   71,   74,   74,   74,   74,   74,   74,   74,   74,
-
-       76,   76,   76,   76,   76,   76,   76,   76,   89,  126,
-       89,   90,  125,   90,   90,  124,   90,   90,  119,  119,
-      119,  119,  119,  119,  119,  119,  145,  145,  145,  145,
-      145,  145,  145,  145,  123,  122,   59,   59,  118,  117,
-      116,  115,  114,  113,   45,  112,  108,  111,  109,  106,
-      105,  104,   46,  103,   91,   87,  102,  101,  100,   98,
-       97,   96,   95,   94,   93,   77,   75,   91,   88,   87,
-       86,   57,   85,   84,   57,   82,   81,   78,   77,   75,
-       72,  158,   58,   57,   53,   35,  158,   31,   23,   23,
-        9,  158,  158,  158,  158,  158,  158,  158,  158,  158,
-
-      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,  158,  158,  158
+       21,   21,   21,   21,   10,   22,   10,   24,   25,   25,
+       25,   32,   33,   33,  164,   26,   34,   34,   34,   52,
+       53,   27,   26,   26,   26,   26,   10,   11,   12,   11,
+       13,   14,   28,   15,   16,   28,   28,   28,   24,   28,
+       28,   28,   10,   18,   19,   20,   29,   29,   29,   29,
+       29,   30,   10,   29,   29,   29,   29,   29,   29,   29,
+
+       29,   29,   29,   29,   29,   29,   29,   29,   29,   29,
+       10,   22,   10,   23,   34,   34,   34,   37,   39,   43,
+       32,   33,   33,   45,   55,   56,   46,   60,   43,   45,
+       65,  163,   46,   65,   65,   65,   44,   38,   60,   74,
+       58,   47,  141,   48,  142,   44,   49,   47,   50,   48,
+       76,   51,   62,   94,   50,   41,   44,   51,   37,   61,
+       64,   64,   64,   58,   34,   34,   34,   64,  162,   80,
+       67,   68,   68,   68,   64,   64,   64,   64,   38,   81,
+       69,   70,   71,   68,   68,   68,   60,  161,   43,   69,
+       70,   65,   69,   70,   65,   65,   65,  125,   85,   85,
+
+       85,   58,   68,   68,   68,   44,  102,  110,  125,  133,
+      102,   69,   70,  111,  114,  160,  159,  126,   85,   85,
+       85,  140,  140,  140,  140,  140,  140,  153,  126,  147,
+      147,  147,  153,  148,  147,  147,  147,  158,  148,  165,
+      157,  156,  155,  151,  150,  149,  146,  154,  145,  144,
+      143,  139,  154,   36,   36,   36,   36,   36,   36,   36,
+       36,   40,  138,  137,  136,   40,   40,   42,   42,   42,
+       42,   42,   42,   42,   42,   57,   57,   57,   57,   63,
+      135,   63,   65,  134,  165,   65,  133,   65,   65,   66,
+      132,  131,   66,   66,   66,   66,   72,  130,   72,   72,
+
+       75,   75,   75,   75,   75,   75,   75,   75,   77,   77,
+       77,   77,   77,   77,   77,   77,   91,  129,   91,   92,
+      128,   92,   92,  127,   92,   92,  124,  124,  124,  124,
+      124,  124,  124,  124,  152,  152,  152,  152,  152,  152,
+      152,  152,   60,   60,  123,  122,  121,  120,  119,  118,
+      117,   45,  116,  111,  115,  113,  112,  109,  108,  107,
+       46,  106,   93,   89,  105,  104,  103,  101,  100,   99,
+       98,   97,   96,   95,   78,   76,   93,   90,   89,   88,
+       58,   87,   86,   58,   84,   83,   82,   79,   78,   76,
+       73,  165,   59,   58,   54,   35,  165,   31,   23,   23,
+
+        9,  165,  165,  165,  165,  165,  165,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  165,  165
     } ;
     } ;
 
 
-static yyconst flex_int16_t yy_chk[438] =
+static yyconst flex_int16_t yy_chk[449] =
     {   0,
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    3,    3,    3,    3,
-        7,    7,    7,  156,    3,   11,   11,   11,   18,   18,
-        3,    3,    3,    3,    3,    5,    5,    5,    5,    5,
+        1,    1,    1,    1,    1,    1,    1,    3,    3,    3,
+        3,    7,    7,    7,  163,    3,   11,   11,   11,   18,
+       18,    3,    3,    3,    3,    3,    5,    5,    5,    5,
         5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
         5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
         5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
         5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
         5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
         5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
 
 
         5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
         5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
-        5,    8,   12,   12,   12,   14,   15,   16,    8,    8,
-        8,   17,   20,   20,   17,   23,   24,   29,  155,   24,
-       29,   29,   29,   48,   16,   14,   31,   29,  128,   17,
-      128,   17,   48,   17,   24,   17,   24,   99,   24,   42,
-       24,   99,   15,   33,   33,   33,   23,   26,   26,   26,
-       26,  154,   33,   33,   26,   36,   42,   31,   32,   32,
-       32,   26,   26,   26,   26,   44,   59,   32,   32,   32,
-       34,   34,   34,   73,   75,   36,  153,   75,   59,   59,
-       59,   65,   44,  110,   65,   65,   65,   67,   67,   67,
-
-       73,   65,   83,   89,   89,   97,   67,   67,  119,  127,
-       97,  150,  149,  110,   83,   83,   83,  133,  133,  133,
-      141,  127,  127,  127,  145,  136,  136,  136,  119,  136,
-      140,  140,  140,  148,  140,  147,  144,  143,  142,  139,
-      141,  138,  137,  135,  145,  159,  159,  159,  159,  159,
-      159,  159,  159,  160,  134,  132,  131,  160,  160,  161,
-      161,  161,  161,  161,  161,  161,  161,  162,  162,  162,
-      162,  163,  126,  163,  164,  125,  124,  164,  123,  164,
-      164,  165,  122,  121,  165,  165,  165,  165,  166,  120,
-      166,  166,  167,  167,  167,  167,  167,  167,  167,  167,
-
-      168,  168,  168,  168,  168,  168,  168,  168,  169,  118,
-      169,  170,  117,  170,  170,  116,  170,  170,  171,  171,
-      171,  171,  171,  171,  171,  171,  172,  172,  172,  172,
-      172,  172,  172,  172,  115,  114,  112,  111,  109,  108,
-      107,  106,  105,  104,  103,  102,  101,  100,   98,   96,
-       95,   94,   93,   92,   90,   88,   86,   85,   84,   82,
-       81,   80,   79,   78,   77,   76,   74,   72,   69,   68,
-       66,   63,   61,   60,   56,   50,   49,   47,   46,   45,
+        5,    5,    5,    8,   12,   12,   12,   14,   15,   16,
+        8,    8,    8,   17,   20,   20,   17,   23,   42,   24,
+       29,  162,   24,   29,   29,   29,   16,   14,   31,   44,
+       29,   17,  134,   17,  134,   42,   17,   24,   17,   24,
+       76,   17,   24,   76,   24,   15,   44,   24,   36,   23,
+       26,   26,   26,   26,   34,   34,   34,   26,  161,   48,
+       31,   32,   32,   32,   26,   26,   26,   26,   36,   48,
+       32,   32,   32,   33,   33,   33,   60,  160,   74,   91,
+       91,   66,   33,   33,   66,   66,   66,  114,   60,   60,
+
+       60,   66,   68,   68,   68,   74,   85,   99,  124,  133,
+      102,   68,   68,   99,  102,  157,  156,  114,   85,   85,
+       85,  133,  133,  133,  140,  140,  140,  148,  124,  143,
+      143,  143,  152,  143,  147,  147,  147,  155,  147,  154,
+      151,  150,  149,  146,  145,  144,  142,  148,  141,  138,
+      137,  132,  152,  166,  166,  166,  166,  166,  166,  166,
+      166,  167,  131,  130,  129,  167,  167,  168,  168,  168,
+      168,  168,  168,  168,  168,  169,  169,  169,  169,  170,
+      128,  170,  171,  127,  126,  171,  125,  171,  171,  172,
+      123,  122,  172,  172,  172,  172,  173,  121,  173,  173,
+
+      174,  174,  174,  174,  174,  174,  174,  174,  175,  175,
+      175,  175,  175,  175,  175,  175,  176,  120,  176,  177,
+      119,  177,  177,  118,  177,  177,  178,  178,  178,  178,
+      178,  178,  178,  178,  179,  179,  179,  179,  179,  179,
+      179,  179,  116,  115,  113,  112,  111,  110,  109,  108,
+      107,  106,  105,  104,  103,  101,  100,   98,   97,   96,
+       95,   94,   92,   90,   88,   87,   86,   84,   83,   82,
+       81,   80,   79,   78,   77,   75,   73,   70,   69,   67,
+       64,   62,   61,   57,   51,   50,   49,   47,   46,   45,
        41,   38,   22,   21,   19,   13,    9,    6,    4,    2,
        41,   38,   22,   21,   19,   13,    9,    6,    4,    2,
-      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
 
 
-      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,  158,  158,  158,  158,  158,  158,
-      158,  158,  158,  158,  158,  158,  158
+      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  165,  165,  165,  165,
+      165,  165,  165,  165,  165,  165,  165,  165
     } ;
     } ;
 
 
 static yy_state_type yy_last_accepting_state;
 static yy_state_type yy_last_accepting_state;
@@ -662,7 +656,7 @@ static int dts_version = 1;
 static void push_input_file(const char *filename);
 static void push_input_file(const char *filename);
 static bool pop_input_file(void);
 static bool pop_input_file(void);
 static void lexical_error(const char *fmt, ...);
 static void lexical_error(const char *fmt, ...);
-#line 666 "dtc-lexer.lex.c"
+#line 660 "dtc-lexer.lex.c"
 
 
 #define INITIAL 0
 #define INITIAL 0
 #define BYTESTRING 1
 #define BYTESTRING 1
@@ -698,19 +692,19 @@ void yyset_extra (YY_EXTRA_TYPE user_defined  );
 
 
 FILE *yyget_in (void );
 FILE *yyget_in (void );
 
 
-void yyset_in  (FILE * in_str  );
+void yyset_in  (FILE * _in_str  );
 
 
 FILE *yyget_out (void );
 FILE *yyget_out (void );
 
 
-void yyset_out  (FILE * out_str  );
+void yyset_out  (FILE * _out_str  );
 
 
-yy_size_t yyget_leng (void );
+			int yyget_leng (void );
 
 
 char *yyget_text (void );
 char *yyget_text (void );
 
 
 int yyget_lineno (void );
 int yyget_lineno (void );
 
 
-void yyset_lineno (int line_number  );
+void yyset_lineno (int _line_number  );
 
 
 /* Macros after this point can all be overridden by user definitions in
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
  * section 1.
@@ -724,6 +718,10 @@ extern int yywrap (void );
 #endif
 #endif
 #endif
 #endif
 
 
+#ifndef YY_NO_UNPUT
+    
+#endif
+
 #ifndef yytext_ptr
 #ifndef yytext_ptr
 static void yy_flex_strncpy (char *,yyconst char *,int );
 static void yy_flex_strncpy (char *,yyconst char *,int );
 #endif
 #endif
@@ -757,7 +755,7 @@ static int input (void );
 /* This used to be an fputs(), but since the string might contain NUL's,
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  * we now use fwrite().
  */
  */
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
 #endif
 #endif
 
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -781,7 +779,7 @@ static int input (void );
 	else \
 	else \
 		{ \
 		{ \
 		errno=0; \
 		errno=0; \
-		while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+		while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
 			{ \
 			{ \
 			if( errno != EINTR) \
 			if( errno != EINTR) \
 				{ \
 				{ \
@@ -836,7 +834,7 @@ extern int yylex (void);
 
 
 /* Code executed at the end of each rule. */
 /* Code executed at the end of each rule. */
 #ifndef YY_BREAK
 #ifndef YY_BREAK
-#define YY_BREAK break;
+#define YY_BREAK /*LINTED*/break;
 #endif
 #endif
 
 
 #define YY_RULE_SETUP \
 #define YY_RULE_SETUP \
@@ -849,9 +847,9 @@ extern int yylex (void);
  */
  */
 YY_DECL
 YY_DECL
 {
 {
-	register yy_state_type yy_current_state;
-	register char *yy_cp, *yy_bp;
-	register int yy_act;
+	yy_state_type yy_current_state;
+	char *yy_cp, *yy_bp;
+	int yy_act;
     
     
 	if ( !(yy_init) )
 	if ( !(yy_init) )
 		{
 		{
@@ -882,9 +880,9 @@ YY_DECL
 	{
 	{
 #line 68 "dtc-lexer.l"
 #line 68 "dtc-lexer.l"
 
 
-#line 886 "dtc-lexer.lex.c"
+#line 884 "dtc-lexer.lex.c"
 
 
-	while ( 1 )		/* loops until end-of-file is reached */
+	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
 		{
 		yy_cp = (yy_c_buf_p);
 		yy_cp = (yy_c_buf_p);
 
 
@@ -901,7 +899,7 @@ YY_DECL
 yy_match:
 yy_match:
 		do
 		do
 			{
 			{
-			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
+			YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
 			if ( yy_accept[yy_current_state] )
 			if ( yy_accept[yy_current_state] )
 				{
 				{
 				(yy_last_accepting_state) = yy_current_state;
 				(yy_last_accepting_state) = yy_current_state;
@@ -910,13 +908,13 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 159 )
+				if ( yy_current_state >= 166 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 				}
-			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
 			++yy_cp;
 			++yy_cp;
 			}
 			}
-		while ( yy_current_state != 158 );
+		while ( yy_current_state != 165 );
 		yy_cp = (yy_last_accepting_cpos);
 		yy_cp = (yy_last_accepting_cpos);
 		yy_current_state = (yy_last_accepting_state);
 		yy_current_state = (yy_last_accepting_state);
 
 
@@ -1014,24 +1012,32 @@ YY_RULE_SETUP
 case 5:
 case 5:
 YY_RULE_SETUP
 YY_RULE_SETUP
 #line 124 "dtc-lexer.l"
 #line 124 "dtc-lexer.l"
+{
+			DPRINT("Keyword: /plugin/\n");
+			return DT_PLUGIN;
+		}
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 129 "dtc-lexer.l"
 {
 {
 			DPRINT("Keyword: /memreserve/\n");
 			DPRINT("Keyword: /memreserve/\n");
 			BEGIN_DEFAULT();
 			BEGIN_DEFAULT();
 			return DT_MEMRESERVE;
 			return DT_MEMRESERVE;
 		}
 		}
 	YY_BREAK
 	YY_BREAK
-case 6:
+case 7:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 130 "dtc-lexer.l"
+#line 135 "dtc-lexer.l"
 {
 {
 			DPRINT("Keyword: /bits/\n");
 			DPRINT("Keyword: /bits/\n");
 			BEGIN_DEFAULT();
 			BEGIN_DEFAULT();
 			return DT_BITS;
 			return DT_BITS;
 		}
 		}
 	YY_BREAK
 	YY_BREAK
-case 7:
+case 8:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 136 "dtc-lexer.l"
+#line 141 "dtc-lexer.l"
 {
 {
 			DPRINT("Keyword: /delete-property/\n");
 			DPRINT("Keyword: /delete-property/\n");
 			DPRINT("<PROPNODENAME>\n");
 			DPRINT("<PROPNODENAME>\n");
@@ -1039,9 +1045,9 @@ YY_RULE_SETUP
 			return DT_DEL_PROP;
 			return DT_DEL_PROP;
 		}
 		}
 	YY_BREAK
 	YY_BREAK
-case 8:
+case 9:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 143 "dtc-lexer.l"
+#line 148 "dtc-lexer.l"
 {
 {
 			DPRINT("Keyword: /delete-node/\n");
 			DPRINT("Keyword: /delete-node/\n");
 			DPRINT("<PROPNODENAME>\n");
 			DPRINT("<PROPNODENAME>\n");
@@ -1049,9 +1055,9 @@ YY_RULE_SETUP
 			return DT_DEL_NODE;
 			return DT_DEL_NODE;
 		}
 		}
 	YY_BREAK
 	YY_BREAK
-case 9:
+case 10:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 150 "dtc-lexer.l"
+#line 155 "dtc-lexer.l"
 {
 {
 			DPRINT("Label: %s\n", yytext);
 			DPRINT("Label: %s\n", yytext);
 			yylval.labelref = xstrdup(yytext);
 			yylval.labelref = xstrdup(yytext);
@@ -1059,9 +1065,9 @@ YY_RULE_SETUP
 			return DT_LABEL;
 			return DT_LABEL;
 		}
 		}
 	YY_BREAK
 	YY_BREAK
-case 10:
+case 11:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 157 "dtc-lexer.l"
+#line 162 "dtc-lexer.l"
 {
 {
 			char *e;
 			char *e;
 			DPRINT("Integer Literal: '%s'\n", yytext);
 			DPRINT("Integer Literal: '%s'\n", yytext);
@@ -1084,10 +1090,10 @@ YY_RULE_SETUP
 			return DT_LITERAL;
 			return DT_LITERAL;
 		}
 		}
 	YY_BREAK
 	YY_BREAK
-case 11:
-/* rule 11 can match eol */
+case 12:
+/* rule 12 can match eol */
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 179 "dtc-lexer.l"
+#line 184 "dtc-lexer.l"
 {
 {
 			struct data d;
 			struct data d;
 			DPRINT("Character literal: %s\n", yytext);
 			DPRINT("Character literal: %s\n", yytext);
@@ -1096,31 +1102,31 @@ YY_RULE_SETUP
 			if (d.len == 1) {
 			if (d.len == 1) {
 				lexical_error("Empty character literal");
 				lexical_error("Empty character literal");
 				yylval.integer = 0;
 				yylval.integer = 0;
-				return DT_CHAR_LITERAL;
-			}
-
-			yylval.integer = (unsigned char)d.val[0];
+			} else {
+				yylval.integer = (unsigned char)d.val[0];
 
 
-			if (d.len > 2)
-				lexical_error("Character literal has %d"
-					      " characters instead of 1",
-					      d.len - 1);
+				if (d.len > 2)
+					lexical_error("Character literal has %d"
+						      " characters instead of 1",
+						      d.len - 1);
+			}
 
 
+			data_free(d);
 			return DT_CHAR_LITERAL;
 			return DT_CHAR_LITERAL;
 		}
 		}
 	YY_BREAK
 	YY_BREAK
-case 12:
+case 13:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 200 "dtc-lexer.l"
+#line 205 "dtc-lexer.l"
 {	/* label reference */
 {	/* label reference */
 			DPRINT("Ref: %s\n", yytext+1);
 			DPRINT("Ref: %s\n", yytext+1);
 			yylval.labelref = xstrdup(yytext+1);
 			yylval.labelref = xstrdup(yytext+1);
 			return DT_REF;
 			return DT_REF;
 		}
 		}
 	YY_BREAK
 	YY_BREAK
-case 13:
+case 14:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 206 "dtc-lexer.l"
+#line 211 "dtc-lexer.l"
 {	/* new-style path reference */
 {	/* new-style path reference */
 			yytext[yyleng-1] = '\0';
 			yytext[yyleng-1] = '\0';
 			DPRINT("Ref: %s\n", yytext+2);
 			DPRINT("Ref: %s\n", yytext+2);
@@ -1128,27 +1134,27 @@ YY_RULE_SETUP
 			return DT_REF;
 			return DT_REF;
 		}
 		}
 	YY_BREAK
 	YY_BREAK
-case 14:
+case 15:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 213 "dtc-lexer.l"
+#line 218 "dtc-lexer.l"
 {
 {
 			yylval.byte = strtol(yytext, NULL, 16);
 			yylval.byte = strtol(yytext, NULL, 16);
 			DPRINT("Byte: %02x\n", (int)yylval.byte);
 			DPRINT("Byte: %02x\n", (int)yylval.byte);
 			return DT_BYTE;
 			return DT_BYTE;
 		}
 		}
 	YY_BREAK
 	YY_BREAK
-case 15:
+case 16:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 219 "dtc-lexer.l"
+#line 224 "dtc-lexer.l"
 {
 {
 			DPRINT("/BYTESTRING\n");
 			DPRINT("/BYTESTRING\n");
 			BEGIN_DEFAULT();
 			BEGIN_DEFAULT();
 			return ']';
 			return ']';
 		}
 		}
 	YY_BREAK
 	YY_BREAK
-case 16:
+case 17:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 225 "dtc-lexer.l"
+#line 230 "dtc-lexer.l"
 {
 {
 			DPRINT("PropNodeName: %s\n", yytext);
 			DPRINT("PropNodeName: %s\n", yytext);
 			yylval.propnodename = xstrdup((yytext[0] == '\\') ?
 			yylval.propnodename = xstrdup((yytext[0] == '\\') ?
@@ -1157,75 +1163,75 @@ YY_RULE_SETUP
 			return DT_PROPNODENAME;
 			return DT_PROPNODENAME;
 		}
 		}
 	YY_BREAK
 	YY_BREAK
-case 17:
+case 18:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 233 "dtc-lexer.l"
+#line 238 "dtc-lexer.l"
 {
 {
 			DPRINT("Binary Include\n");
 			DPRINT("Binary Include\n");
 			return DT_INCBIN;
 			return DT_INCBIN;
 		}
 		}
 	YY_BREAK
 	YY_BREAK
-case 18:
-/* rule 18 can match eol */
-YY_RULE_SETUP
-#line 238 "dtc-lexer.l"
-/* eat whitespace */
-	YY_BREAK
 case 19:
 case 19:
 /* rule 19 can match eol */
 /* rule 19 can match eol */
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 239 "dtc-lexer.l"
-/* eat C-style comments */
+#line 243 "dtc-lexer.l"
+/* eat whitespace */
 	YY_BREAK
 	YY_BREAK
 case 20:
 case 20:
 /* rule 20 can match eol */
 /* rule 20 can match eol */
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 240 "dtc-lexer.l"
-/* eat C++-style comments */
+#line 244 "dtc-lexer.l"
+/* eat C-style comments */
 	YY_BREAK
 	YY_BREAK
 case 21:
 case 21:
+/* rule 21 can match eol */
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 242 "dtc-lexer.l"
-{ return DT_LSHIFT; };
+#line 245 "dtc-lexer.l"
+/* eat C++-style comments */
 	YY_BREAK
 	YY_BREAK
 case 22:
 case 22:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 243 "dtc-lexer.l"
-{ return DT_RSHIFT; };
+#line 247 "dtc-lexer.l"
+{ return DT_LSHIFT; };
 	YY_BREAK
 	YY_BREAK
 case 23:
 case 23:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 244 "dtc-lexer.l"
-{ return DT_LE; };
+#line 248 "dtc-lexer.l"
+{ return DT_RSHIFT; };
 	YY_BREAK
 	YY_BREAK
 case 24:
 case 24:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 245 "dtc-lexer.l"
-{ return DT_GE; };
+#line 249 "dtc-lexer.l"
+{ return DT_LE; };
 	YY_BREAK
 	YY_BREAK
 case 25:
 case 25:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 246 "dtc-lexer.l"
-{ return DT_EQ; };
+#line 250 "dtc-lexer.l"
+{ return DT_GE; };
 	YY_BREAK
 	YY_BREAK
 case 26:
 case 26:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 247 "dtc-lexer.l"
-{ return DT_NE; };
+#line 251 "dtc-lexer.l"
+{ return DT_EQ; };
 	YY_BREAK
 	YY_BREAK
 case 27:
 case 27:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 248 "dtc-lexer.l"
-{ return DT_AND; };
+#line 252 "dtc-lexer.l"
+{ return DT_NE; };
 	YY_BREAK
 	YY_BREAK
 case 28:
 case 28:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 249 "dtc-lexer.l"
-{ return DT_OR; };
+#line 253 "dtc-lexer.l"
+{ return DT_AND; };
 	YY_BREAK
 	YY_BREAK
 case 29:
 case 29:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 251 "dtc-lexer.l"
+#line 254 "dtc-lexer.l"
+{ return DT_OR; };
+	YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 256 "dtc-lexer.l"
 {
 {
 			DPRINT("Char: %c (\\x%02x)\n", yytext[0],
 			DPRINT("Char: %c (\\x%02x)\n", yytext[0],
 				(unsigned)yytext[0]);
 				(unsigned)yytext[0]);
@@ -1241,12 +1247,12 @@ YY_RULE_SETUP
 			return yytext[0];
 			return yytext[0];
 		}
 		}
 	YY_BREAK
 	YY_BREAK
-case 30:
+case 31:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 266 "dtc-lexer.l"
+#line 271 "dtc-lexer.l"
 ECHO;
 ECHO;
 	YY_BREAK
 	YY_BREAK
-#line 1250 "dtc-lexer.lex.c"
+#line 1256 "dtc-lexer.lex.c"
 
 
 	case YY_END_OF_BUFFER:
 	case YY_END_OF_BUFFER:
 		{
 		{
@@ -1388,9 +1394,9 @@ ECHO;
  */
  */
 static int yy_get_next_buffer (void)
 static int yy_get_next_buffer (void)
 {
 {
-    	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
-	register char *source = (yytext_ptr);
-	register int number_to_move, i;
+    	char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+	char *source = (yytext_ptr);
+	yy_size_t number_to_move, i;
 	int ret_val;
 	int ret_val;
 
 
 	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
 	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
@@ -1419,7 +1425,7 @@ static int yy_get_next_buffer (void)
 	/* Try to read more data. */
 	/* Try to read more data. */
 
 
 	/* First move last chars to start of buffer. */
 	/* First move last chars to start of buffer. */
-	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+	number_to_move = (yy_size_t) ((yy_c_buf_p) - (yytext_ptr)) - 1;
 
 
 	for ( i = 0; i < number_to_move; ++i )
 	for ( i = 0; i < number_to_move; ++i )
 		*(dest++) = *(source++);
 		*(dest++) = *(source++);
@@ -1432,7 +1438,7 @@ static int yy_get_next_buffer (void)
 
 
 	else
 	else
 		{
 		{
-			yy_size_t num_to_read =
+			int num_to_read =
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 
 
 		while ( num_to_read <= 0 )
 		while ( num_to_read <= 0 )
@@ -1446,7 +1452,7 @@ static int yy_get_next_buffer (void)
 
 
 			if ( b->yy_is_our_buffer )
 			if ( b->yy_is_our_buffer )
 				{
 				{
-				yy_size_t new_size = b->yy_buf_size * 2;
+				int new_size = b->yy_buf_size * 2;
 
 
 				if ( new_size <= 0 )
 				if ( new_size <= 0 )
 					b->yy_buf_size += b->yy_buf_size / 8;
 					b->yy_buf_size += b->yy_buf_size / 8;
@@ -1459,7 +1465,7 @@ static int yy_get_next_buffer (void)
 				}
 				}
 			else
 			else
 				/* Can't grow it, we don't own it. */
 				/* Can't grow it, we don't own it. */
-				b->yy_ch_buf = 0;
+				b->yy_ch_buf = NULL;
 
 
 			if ( ! b->yy_ch_buf )
 			if ( ! b->yy_ch_buf )
 				YY_FATAL_ERROR(
 				YY_FATAL_ERROR(
@@ -1501,9 +1507,9 @@ static int yy_get_next_buffer (void)
 	else
 	else
 		ret_val = EOB_ACT_CONTINUE_SCAN;
 		ret_val = EOB_ACT_CONTINUE_SCAN;
 
 
-	if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+	if ((int) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
 		/* Extend the array by 50%, plus the number we really need. */
 		/* Extend the array by 50%, plus the number we really need. */
-		yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+		int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
 		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
 		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
 		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
 		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
 			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
 			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
@@ -1522,15 +1528,15 @@ static int yy_get_next_buffer (void)
 
 
     static yy_state_type yy_get_previous_state (void)
     static yy_state_type yy_get_previous_state (void)
 {
 {
-	register yy_state_type yy_current_state;
-	register char *yy_cp;
+	yy_state_type yy_current_state;
+	char *yy_cp;
     
     
 	yy_current_state = (yy_start);
 	yy_current_state = (yy_start);
 	yy_current_state += YY_AT_BOL();
 	yy_current_state += YY_AT_BOL();
 
 
 	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
 	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
 		{
 		{
-		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
 		if ( yy_accept[yy_current_state] )
 		if ( yy_accept[yy_current_state] )
 			{
 			{
 			(yy_last_accepting_state) = yy_current_state;
 			(yy_last_accepting_state) = yy_current_state;
@@ -1539,10 +1545,10 @@ static int yy_get_next_buffer (void)
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 159 )
+			if ( yy_current_state >= 166 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 			}
-		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
 		}
 		}
 
 
 	return yy_current_state;
 	return yy_current_state;
@@ -1555,10 +1561,10 @@ static int yy_get_next_buffer (void)
  */
  */
     static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
     static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
 {
 {
-	register int yy_is_jam;
-    	register char *yy_cp = (yy_c_buf_p);
+	int yy_is_jam;
+    	char *yy_cp = (yy_c_buf_p);
 
 
-	register YY_CHAR yy_c = 1;
+	YY_CHAR yy_c = 1;
 	if ( yy_accept[yy_current_state] )
 	if ( yy_accept[yy_current_state] )
 		{
 		{
 		(yy_last_accepting_state) = yy_current_state;
 		(yy_last_accepting_state) = yy_current_state;
@@ -1567,15 +1573,19 @@ static int yy_get_next_buffer (void)
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 159 )
+		if ( yy_current_state >= 166 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 		}
-	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 158);
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
+	yy_is_jam = (yy_current_state == 165);
 
 
 		return yy_is_jam ? 0 : yy_current_state;
 		return yy_is_jam ? 0 : yy_current_state;
 }
 }
 
 
+#ifndef YY_NO_UNPUT
+
+#endif
+
 #ifndef YY_NO_INPUT
 #ifndef YY_NO_INPUT
 #ifdef __cplusplus
 #ifdef __cplusplus
     static int yyinput (void)
     static int yyinput (void)
@@ -1600,7 +1610,7 @@ static int yy_get_next_buffer (void)
 
 
 		else
 		else
 			{ /* need more input */
 			{ /* need more input */
-			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
+			int offset = (yy_c_buf_p) - (yytext_ptr);
 			++(yy_c_buf_p);
 			++(yy_c_buf_p);
 
 
 			switch ( yy_get_next_buffer(  ) )
 			switch ( yy_get_next_buffer(  ) )
@@ -1624,7 +1634,7 @@ static int yy_get_next_buffer (void)
 				case EOB_ACT_END_OF_FILE:
 				case EOB_ACT_END_OF_FILE:
 					{
 					{
 					if ( yywrap( ) )
 					if ( yywrap( ) )
-						return EOF;
+						return 0;
 
 
 					if ( ! (yy_did_buffer_switch_on_eof) )
 					if ( ! (yy_did_buffer_switch_on_eof) )
 						YY_NEW_FILE;
 						YY_NEW_FILE;
@@ -1727,7 +1737,7 @@ static void yy_load_buffer_state  (void)
 	if ( ! b )
 	if ( ! b )
 		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
 
-	b->yy_buf_size = size;
+	b->yy_buf_size = (yy_size_t)size;
 
 
 	/* yy_ch_buf has to be 2 characters longer than the size given because
 	/* yy_ch_buf has to be 2 characters longer than the size given because
 	 * we need to put in 2 end-of-buffer characters.
 	 * we need to put in 2 end-of-buffer characters.
@@ -1874,7 +1884,7 @@ void yypop_buffer_state (void)
  */
  */
 static void yyensure_buffer_stack (void)
 static void yyensure_buffer_stack (void)
 {
 {
-	yy_size_t num_to_alloc;
+	int num_to_alloc;
     
     
 	if (!(yy_buffer_stack)) {
 	if (!(yy_buffer_stack)) {
 
 
@@ -1882,15 +1892,15 @@ static void yyensure_buffer_stack (void)
 		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
 		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
 		 * immediate realloc on the next call.
 		 * immediate realloc on the next call.
          */
          */
-		num_to_alloc = 1;
+      num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
 		(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
 		(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
 								(num_to_alloc * sizeof(struct yy_buffer_state*)
 								(num_to_alloc * sizeof(struct yy_buffer_state*)
 								);
 								);
 		if ( ! (yy_buffer_stack) )
 		if ( ! (yy_buffer_stack) )
 			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
 			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-								  
+
 		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
 		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-				
+
 		(yy_buffer_stack_max) = num_to_alloc;
 		(yy_buffer_stack_max) = num_to_alloc;
 		(yy_buffer_stack_top) = 0;
 		(yy_buffer_stack_top) = 0;
 		return;
 		return;
@@ -1899,7 +1909,7 @@ static void yyensure_buffer_stack (void)
 	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
 	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
 
 
 		/* Increase the buffer to prepare for a possible push. */
 		/* Increase the buffer to prepare for a possible push. */
-		int grow_size = 8 /* arbitrary grow size */;
+		yy_size_t grow_size = 8 /* arbitrary grow size */;
 
 
 		num_to_alloc = (yy_buffer_stack_max) + grow_size;
 		num_to_alloc = (yy_buffer_stack_max) + grow_size;
 		(yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
 		(yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
@@ -1919,7 +1929,7 @@ static void yyensure_buffer_stack (void)
  * @param base the character buffer
  * @param base the character buffer
  * @param size the size in bytes of the character buffer
  * @param size the size in bytes of the character buffer
  * 
  * 
- * @return the newly allocated buffer state object. 
+ * @return the newly allocated buffer state object.
  */
  */
 YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
 YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
 {
 {
@@ -1929,7 +1939,7 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
 	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
 	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
 	     base[size-1] != YY_END_OF_BUFFER_CHAR )
 	     base[size-1] != YY_END_OF_BUFFER_CHAR )
 		/* They forgot to leave room for the EOB's. */
 		/* They forgot to leave room for the EOB's. */
-		return 0;
+		return NULL;
 
 
 	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
 	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
 	if ( ! b )
 	if ( ! b )
@@ -1938,7 +1948,7 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
 	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
 	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
 	b->yy_buf_pos = b->yy_ch_buf = base;
 	b->yy_buf_pos = b->yy_ch_buf = base;
 	b->yy_is_our_buffer = 0;
 	b->yy_is_our_buffer = 0;
-	b->yy_input_file = 0;
+	b->yy_input_file = NULL;
 	b->yy_n_chars = b->yy_buf_size;
 	b->yy_n_chars = b->yy_buf_size;
 	b->yy_is_interactive = 0;
 	b->yy_is_interactive = 0;
 	b->yy_at_bol = 1;
 	b->yy_at_bol = 1;
@@ -1961,7 +1971,7 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
 YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
 YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
 {
 {
     
     
-	return yy_scan_bytes(yystr,strlen(yystr) );
+	return yy_scan_bytes(yystr,(int) strlen(yystr) );
 }
 }
 
 
 /** Setup the input buffer state to scan the given bytes. The next call to yylex() will
 /** Setup the input buffer state to scan the given bytes. The next call to yylex() will
@@ -1971,7 +1981,7 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
  * 
  * 
  * @return the newly allocated buffer state object.
  * @return the newly allocated buffer state object.
  */
  */
-YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len )
+YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
 {
 {
 	YY_BUFFER_STATE b;
 	YY_BUFFER_STATE b;
 	char *buf;
 	char *buf;
@@ -1979,7 +1989,7 @@ YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len
 	yy_size_t i;
 	yy_size_t i;
     
     
 	/* Get memory for full buffer, including space for trailing EOB's. */
 	/* Get memory for full buffer, including space for trailing EOB's. */
-	n = _yybytes_len + 2;
+	n = (yy_size_t) _yybytes_len + 2;
 	buf = (char *) yyalloc(n  );
 	buf = (char *) yyalloc(n  );
 	if ( ! buf )
 	if ( ! buf )
 		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
 		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
@@ -2005,9 +2015,9 @@ YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len
 #define YY_EXIT_FAILURE 2
 #define YY_EXIT_FAILURE 2
 #endif
 #endif
 
 
-static void yy_fatal_error (yyconst char* msg )
+static void yynoreturn yy_fatal_error (yyconst char* msg )
 {
 {
-    	(void) fprintf( stderr, "%s\n", msg );
+			(void) fprintf( stderr, "%s\n", msg );
 	exit( YY_EXIT_FAILURE );
 	exit( YY_EXIT_FAILURE );
 }
 }
 
 
@@ -2035,7 +2045,7 @@ static void yy_fatal_error (yyconst char* msg )
  */
  */
 int yyget_lineno  (void)
 int yyget_lineno  (void)
 {
 {
-        
+    
     return yylineno;
     return yylineno;
 }
 }
 
 
@@ -2058,7 +2068,7 @@ FILE *yyget_out  (void)
 /** Get the length of the current token.
 /** Get the length of the current token.
  * 
  * 
  */
  */
-yy_size_t yyget_leng  (void)
+int yyget_leng  (void)
 {
 {
         return yyleng;
         return yyleng;
 }
 }
@@ -2073,29 +2083,29 @@ char *yyget_text  (void)
 }
 }
 
 
 /** Set the current line number.
 /** Set the current line number.
- * @param line_number
+ * @param _line_number line number
  * 
  * 
  */
  */
-void yyset_lineno (int  line_number )
+void yyset_lineno (int  _line_number )
 {
 {
     
     
-    yylineno = line_number;
+    yylineno = _line_number;
 }
 }
 
 
 /** Set the input stream. This does not discard the current
 /** Set the input stream. This does not discard the current
  * input buffer.
  * input buffer.
- * @param in_str A readable stream.
+ * @param _in_str A readable stream.
  * 
  * 
  * @see yy_switch_to_buffer
  * @see yy_switch_to_buffer
  */
  */
-void yyset_in (FILE *  in_str )
+void yyset_in (FILE *  _in_str )
 {
 {
-        yyin = in_str ;
+        yyin = _in_str ;
 }
 }
 
 
-void yyset_out (FILE *  out_str )
+void yyset_out (FILE *  _out_str )
 {
 {
-        yyout = out_str ;
+        yyout = _out_str ;
 }
 }
 
 
 int yyget_debug  (void)
 int yyget_debug  (void)
@@ -2103,9 +2113,9 @@ int yyget_debug  (void)
         return yy_flex_debug;
         return yy_flex_debug;
 }
 }
 
 
-void yyset_debug (int  bdebug )
+void yyset_debug (int  _bdebug )
 {
 {
-        yy_flex_debug = bdebug ;
+        yy_flex_debug = _bdebug ;
 }
 }
 
 
 static int yy_init_globals (void)
 static int yy_init_globals (void)
@@ -2114,10 +2124,10 @@ static int yy_init_globals (void)
      * This function is called from yylex_destroy(), so don't allocate here.
      * This function is called from yylex_destroy(), so don't allocate here.
      */
      */
 
 
-    (yy_buffer_stack) = 0;
+    (yy_buffer_stack) = NULL;
     (yy_buffer_stack_top) = 0;
     (yy_buffer_stack_top) = 0;
     (yy_buffer_stack_max) = 0;
     (yy_buffer_stack_max) = 0;
-    (yy_c_buf_p) = (char *) 0;
+    (yy_c_buf_p) = NULL;
     (yy_init) = 0;
     (yy_init) = 0;
     (yy_start) = 0;
     (yy_start) = 0;
 
 
@@ -2126,8 +2136,8 @@ static int yy_init_globals (void)
     yyin = stdin;
     yyin = stdin;
     yyout = stdout;
     yyout = stdout;
 #else
 #else
-    yyin = (FILE *) 0;
-    yyout = (FILE *) 0;
+    yyin = NULL;
+    yyout = NULL;
 #endif
 #endif
 
 
     /* For future reference: Set errno on error, since we are called by
     /* For future reference: Set errno on error, since we are called by
@@ -2165,7 +2175,8 @@ int yylex_destroy  (void)
 #ifndef yytext_ptr
 #ifndef yytext_ptr
 static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
 static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
 {
 {
-	register int i;
+		
+	int i;
 	for ( i = 0; i < n; ++i )
 	for ( i = 0; i < n; ++i )
 		s1[i] = s2[i];
 		s1[i] = s2[i];
 }
 }
@@ -2174,7 +2185,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
 #ifdef YY_NEED_STRLEN
 #ifdef YY_NEED_STRLEN
 static int yy_flex_strlen (yyconst char * s )
 static int yy_flex_strlen (yyconst char * s )
 {
 {
-	register int n;
+	int n;
 	for ( n = 0; s[n]; ++n )
 	for ( n = 0; s[n]; ++n )
 		;
 		;
 
 
@@ -2184,11 +2195,12 @@ static int yy_flex_strlen (yyconst char * s )
 
 
 void *yyalloc (yy_size_t  size )
 void *yyalloc (yy_size_t  size )
 {
 {
-	return (void *) malloc( size );
+			return malloc(size);
 }
 }
 
 
 void *yyrealloc  (void * ptr, yy_size_t  size )
 void *yyrealloc  (void * ptr, yy_size_t  size )
 {
 {
+		
 	/* The cast to (char *) in the following accommodates both
 	/* The cast to (char *) in the following accommodates both
 	 * implementations that use char* generic pointers, and those
 	 * implementations that use char* generic pointers, and those
 	 * that use void* generic pointers.  It works with the latter
 	 * that use void* generic pointers.  It works with the latter
@@ -2196,17 +2208,17 @@ void *yyrealloc  (void * ptr, yy_size_t  size )
 	 * any pointer type to void*, and deal with argument conversions
 	 * any pointer type to void*, and deal with argument conversions
 	 * as though doing an assignment.
 	 * as though doing an assignment.
 	 */
 	 */
-	return (void *) realloc( (char *) ptr, size );
+	return realloc(ptr, size);
 }
 }
 
 
 void yyfree (void * ptr )
 void yyfree (void * ptr )
 {
 {
-	free( (char *) ptr );	/* see yyrealloc() for (char *) cast */
+			free( (char *) ptr );	/* see yyrealloc() for (char *) cast */
 }
 }
 
 
 #define YYTABLES_NAME "yytables"
 #define YYTABLES_NAME "yytables"
 
 
-#line 265 "dtc-lexer.l"
+#line 271 "dtc-lexer.l"
 
 
 
 
 
 

+ 392 - 360
scripts/dtc/dtc-parser.tab.c_shipped

@@ -1,8 +1,8 @@
-/* A Bison parser, made by GNU Bison 3.0.2.  */
+/* A Bison parser, made by GNU Bison 3.0.4.  */
 
 
 /* Bison implementation for Yacc-like parsers in C
 /* Bison implementation for Yacc-like parsers in C
 
 
-   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
 
 
    This program is free software: you can redistribute it and/or modify
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    it under the terms of the GNU General Public License as published by
@@ -44,7 +44,7 @@
 #define YYBISON 1
 #define YYBISON 1
 
 
 /* Bison version.  */
 /* Bison version.  */
-#define YYBISON_VERSION "3.0.2"
+#define YYBISON_VERSION "3.0.4"
 
 
 /* Skeleton name.  */
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
 #define YYSKELETON_NAME "yacc.c"
@@ -65,6 +65,7 @@
 #line 20 "dtc-parser.y" /* yacc.c:339  */
 #line 20 "dtc-parser.y" /* yacc.c:339  */
 
 
 #include <stdio.h>
 #include <stdio.h>
+#include <inttypes.h>
 
 
 #include "dtc.h"
 #include "dtc.h"
 #include "srcpos.h"
 #include "srcpos.h"
@@ -77,10 +78,10 @@ extern void yyerror(char const *s);
 		treesource_error = true; \
 		treesource_error = true; \
 	} while (0)
 	} while (0)
 
 
-extern struct boot_info *the_boot_info;
+extern struct dt_info *parser_output;
 extern bool treesource_error;
 extern bool treesource_error;
 
 
-#line 84 "dtc-parser.tab.c" /* yacc.c:339  */
+#line 85 "dtc-parser.tab.c" /* yacc.c:339  */
 
 
 # ifndef YY_NULLPTR
 # ifndef YY_NULLPTR
 #  if defined __cplusplus && 201103L <= __cplusplus
 #  if defined __cplusplus && 201103L <= __cplusplus
@@ -116,35 +117,36 @@ extern int yydebug;
   enum yytokentype
   enum yytokentype
   {
   {
     DT_V1 = 258,
     DT_V1 = 258,
-    DT_MEMRESERVE = 259,
-    DT_LSHIFT = 260,
-    DT_RSHIFT = 261,
-    DT_LE = 262,
-    DT_GE = 263,
-    DT_EQ = 264,
-    DT_NE = 265,
-    DT_AND = 266,
-    DT_OR = 267,
-    DT_BITS = 268,
-    DT_DEL_PROP = 269,
-    DT_DEL_NODE = 270,
-    DT_PROPNODENAME = 271,
-    DT_LITERAL = 272,
-    DT_CHAR_LITERAL = 273,
-    DT_BYTE = 274,
-    DT_STRING = 275,
-    DT_LABEL = 276,
-    DT_REF = 277,
-    DT_INCBIN = 278
+    DT_PLUGIN = 259,
+    DT_MEMRESERVE = 260,
+    DT_LSHIFT = 261,
+    DT_RSHIFT = 262,
+    DT_LE = 263,
+    DT_GE = 264,
+    DT_EQ = 265,
+    DT_NE = 266,
+    DT_AND = 267,
+    DT_OR = 268,
+    DT_BITS = 269,
+    DT_DEL_PROP = 270,
+    DT_DEL_NODE = 271,
+    DT_PROPNODENAME = 272,
+    DT_LITERAL = 273,
+    DT_CHAR_LITERAL = 274,
+    DT_BYTE = 275,
+    DT_STRING = 276,
+    DT_LABEL = 277,
+    DT_REF = 278,
+    DT_INCBIN = 279
   };
   };
 #endif
 #endif
 
 
 /* Value type.  */
 /* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE YYSTYPE;
+
 union YYSTYPE
 union YYSTYPE
 {
 {
-#line 38 "dtc-parser.y" /* yacc.c:355  */
+#line 39 "dtc-parser.y" /* yacc.c:355  */
 
 
 	char *propnodename;
 	char *propnodename;
 	char *labelref;
 	char *labelref;
@@ -162,9 +164,12 @@ union YYSTYPE
 	struct node *nodelist;
 	struct node *nodelist;
 	struct reserve_info *re;
 	struct reserve_info *re;
 	uint64_t integer;
 	uint64_t integer;
+	unsigned int flags;
 
 
-#line 167 "dtc-parser.tab.c" /* yacc.c:355  */
+#line 170 "dtc-parser.tab.c" /* yacc.c:355  */
 };
 };
+
+typedef union YYSTYPE YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define YYSTYPE_IS_TRIVIAL 1
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_DECLARED 1
 #endif
 #endif
@@ -192,7 +197,7 @@ int yyparse (void);
 
 
 /* Copy the second part of user declarations.  */
 /* Copy the second part of user declarations.  */
 
 
-#line 196 "dtc-parser.tab.c" /* yacc.c:358  */
+#line 201 "dtc-parser.tab.c" /* yacc.c:358  */
 
 
 #ifdef short
 #ifdef short
 # undef short
 # undef short
@@ -434,23 +439,23 @@ union yyalloc
 #endif /* !YYCOPY_NEEDED */
 #endif /* !YYCOPY_NEEDED */
 
 
 /* YYFINAL -- State number of the termination state.  */
 /* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  4
+#define YYFINAL  6
 /* YYLAST -- Last index in YYTABLE.  */
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   136
+#define YYLAST   138
 
 
 /* YYNTOKENS -- Number of terminals.  */
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  47
+#define YYNTOKENS  48
 /* YYNNTS -- Number of nonterminals.  */
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  28
+#define YYNNTS  30
 /* YYNRULES -- Number of rules.  */
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  80
+#define YYNRULES  84
 /* YYNSTATES -- Number of states.  */
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  144
+#define YYNSTATES  149
 
 
 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
    by yylex, with out-of-bounds checking.  */
    by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   278
+#define YYMAXUTOK   279
 
 
 #define YYTRANSLATE(YYX)                                                \
 #define YYTRANSLATE(YYX)                                                \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -462,16 +467,16 @@ static const yytype_uint8 yytranslate[] =
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    46,     2,     2,     2,    44,    40,     2,
-      32,    34,    43,    41,    33,    42,     2,    25,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,    37,    24,
-      35,    28,    29,    36,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,    47,     2,     2,     2,    45,    41,     2,
+      33,    35,    44,    42,    34,    43,     2,    26,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,    38,    25,
+      36,    29,    30,    37,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,    30,     2,    31,    39,     2,     2,     2,     2,     2,
+       2,    31,     2,    32,    40,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    26,    38,    27,    45,     2,     2,     2,
+       2,     2,     2,    27,    39,    28,    46,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -486,22 +491,22 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
-      15,    16,    17,    18,    19,    20,    21,    22,    23
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24
 };
 };
 
 
 #if YYDEBUG
 #if YYDEBUG
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 static const yytype_uint16 yyrline[] =
 {
 {
-       0,   104,   104,   113,   116,   123,   127,   135,   139,   144,
-     155,   165,   180,   188,   191,   198,   202,   206,   210,   218,
-     222,   226,   230,   234,   250,   260,   268,   271,   275,   282,
-     298,   303,   322,   336,   343,   344,   345,   352,   356,   357,
-     361,   362,   366,   367,   371,   372,   376,   377,   381,   382,
-     386,   387,   388,   392,   393,   394,   395,   396,   400,   401,
-     402,   406,   407,   408,   412,   413,   422,   431,   435,   436,
-     437,   438,   443,   446,   450,   458,   461,   465,   473,   477,
-     481
+       0,   109,   109,   117,   121,   128,   129,   139,   142,   149,
+     153,   161,   165,   170,   181,   191,   206,   214,   217,   224,
+     228,   232,   236,   244,   248,   252,   256,   260,   276,   286,
+     294,   297,   301,   308,   324,   329,   348,   362,   369,   370,
+     371,   378,   382,   383,   387,   388,   392,   393,   397,   398,
+     402,   403,   407,   408,   412,   413,   414,   418,   419,   420,
+     421,   422,   426,   427,   428,   432,   433,   434,   438,   439,
+     448,   457,   461,   462,   463,   464,   469,   472,   476,   484,
+     487,   491,   499,   503,   507
 };
 };
 #endif
 #endif
 
 
@@ -510,19 +515,20 @@ static const yytype_uint16 yyrline[] =
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
 static const char *const yytname[] =
 {
 {
-  "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_LSHIFT",
-  "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", "DT_OR",
-  "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", "DT_LITERAL",
-  "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF",
-  "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", "']'",
-  "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", "'+'",
-  "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile",
-  "memreserves", "memreserve", "devicetree", "nodedef", "proplist",
-  "propdef", "propdata", "propdataprefix", "arrayprefix", "integer_prim",
-  "integer_expr", "integer_trinary", "integer_or", "integer_and",
-  "integer_bitor", "integer_bitxor", "integer_bitand", "integer_eq",
-  "integer_rela", "integer_shift", "integer_add", "integer_mul",
-  "integer_unary", "bytestring", "subnodes", "subnode", YY_NULLPTR
+  "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE",
+  "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND",
+  "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME",
+  "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL",
+  "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['",
+  "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'",
+  "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile",
+  "header", "headers", "memreserves", "memreserve", "devicetree",
+  "nodedef", "proplist", "propdef", "propdata", "propdataprefix",
+  "arrayprefix", "integer_prim", "integer_expr", "integer_trinary",
+  "integer_or", "integer_and", "integer_bitor", "integer_bitxor",
+  "integer_bitand", "integer_eq", "integer_rela", "integer_shift",
+  "integer_add", "integer_mul", "integer_unary", "bytestring", "subnodes",
+  "subnode", YY_NULLPTR
 };
 };
 #endif
 #endif
 
 
@@ -533,16 +539,16 @@ static const yytype_uint16 yytoknum[] =
 {
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
-     275,   276,   277,   278,    59,    47,   123,   125,    61,    62,
-      91,    93,    40,    44,    41,    60,    63,    58,   124,    94,
-      38,    43,    45,    42,    37,   126,    33
+     275,   276,   277,   278,   279,    59,    47,   123,   125,    61,
+      62,    91,    93,    40,    44,    41,    60,    63,    58,   124,
+      94,    38,    43,    45,    42,    37,   126,    33
 };
 };
 # endif
 # endif
 
 
-#define YYPACT_NINF -81
+#define YYPACT_NINF -44
 
 
 #define yypact_value_is_default(Yystate) \
 #define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-81)))
+  (!!((Yystate) == (-44)))
 
 
 #define YYTABLE_NINF -1
 #define YYTABLE_NINF -1
 
 
@@ -553,21 +559,21 @@ static const yytype_uint16 yytoknum[] =
      STATE-NUM.  */
      STATE-NUM.  */
 static const yytype_int8 yypact[] =
 static const yytype_int8 yypact[] =
 {
 {
-      16,   -11,    21,    10,   -81,    25,    10,    19,    10,   -81,
-     -81,    -9,    25,   -81,     2,    51,   -81,    -9,    -9,    -9,
-     -81,     1,   -81,    -6,    50,    14,    28,    29,    36,     3,
-      58,    44,    -3,   -81,    47,   -81,   -81,    65,    68,     2,
-       2,   -81,   -81,   -81,   -81,    -9,    -9,    -9,    -9,    -9,
-      -9,    -9,    -9,    -9,    -9,    -9,    -9,    -9,    -9,    -9,
-      -9,    -9,    -9,    -9,   -81,    63,    69,     2,   -81,   -81,
-      50,    57,    14,    28,    29,    36,     3,     3,    58,    58,
-      58,    58,    44,    44,    -3,    -3,   -81,   -81,   -81,    79,
-      80,    -8,    63,   -81,    72,    63,   -81,   -81,    -9,    76,
-      77,   -81,   -81,   -81,   -81,   -81,    78,   -81,   -81,   -81,
-     -81,   -81,    35,     4,   -81,   -81,   -81,   -81,    86,   -81,
-     -81,   -81,    73,   -81,   -81,    33,    71,    84,    39,   -81,
-     -81,   -81,   -81,   -81,    41,   -81,   -81,   -81,    25,   -81,
-      74,    25,    75,   -81
+      14,    27,    61,    14,     8,    18,   -44,   -44,    37,     8,
+      40,     8,    64,   -44,   -44,   -12,    37,   -44,    50,    52,
+     -44,   -44,   -12,   -12,   -12,   -44,    51,   -44,    -4,    78,
+      53,    54,    55,    17,     2,    30,    38,    -3,   -44,    66,
+     -44,   -44,    70,    72,    50,    50,   -44,   -44,   -44,   -44,
+     -12,   -12,   -12,   -12,   -12,   -12,   -12,   -12,   -12,   -12,
+     -12,   -12,   -12,   -12,   -12,   -12,   -12,   -12,   -12,   -44,
+       3,    73,    50,   -44,   -44,    78,    59,    53,    54,    55,
+      17,     2,     2,    30,    30,    30,    30,    38,    38,    -3,
+      -3,   -44,   -44,   -44,    82,    83,    44,     3,   -44,    74,
+       3,   -44,   -44,   -12,    76,    79,   -44,   -44,   -44,   -44,
+     -44,    80,   -44,   -44,   -44,   -44,   -44,   -10,    36,   -44,
+     -44,   -44,   -44,    85,   -44,   -44,   -44,    75,   -44,   -44,
+      21,    71,    88,    -6,   -44,   -44,   -44,   -44,   -44,    11,
+     -44,   -44,   -44,    37,   -44,    77,    37,    81,   -44
 };
 };
 
 
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -575,37 +581,37 @@ static const yytype_int8 yypact[] =
      means the default is an error.  */
      means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 static const yytype_uint8 yydefact[] =
 {
 {
-       0,     0,     0,     3,     1,     0,     0,     0,     3,    34,
-      35,     0,     0,     6,     0,     2,     4,     0,     0,     0,
-      68,     0,    37,    38,    40,    42,    44,    46,    48,    50,
-      53,    60,    63,    67,     0,    13,     7,     0,     0,     0,
-       0,    69,    70,    71,    36,     0,     0,     0,     0,     0,
+       0,     0,     0,     5,     7,     3,     1,     6,     0,     0,
+       0,     7,     0,    38,    39,     0,     0,    10,     0,     2,
+       8,     4,     0,     0,     0,    72,     0,    41,    42,    44,
+      46,    48,    50,    52,    54,    57,    64,    67,    71,     0,
+      17,    11,     0,     0,     0,     0,    73,    74,    75,    40,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     5,    75,     0,     0,    10,     8,
-      41,     0,    43,    45,    47,    49,    51,    52,    56,    57,
-      55,    54,    58,    59,    61,    62,    65,    64,    66,     0,
-       0,     0,     0,    14,     0,    75,    11,     9,     0,     0,
-       0,    16,    26,    78,    18,    80,     0,    77,    76,    39,
-      17,    79,     0,     0,    12,    25,    15,    27,     0,    19,
-      28,    22,     0,    72,    30,     0,     0,     0,     0,    33,
-      32,    20,    31,    29,     0,    73,    74,    21,     0,    24,
-       0,     0,     0,    23
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     9,
+      79,     0,     0,    14,    12,    45,     0,    47,    49,    51,
+      53,    55,    56,    60,    61,    59,    58,    62,    63,    65,
+      66,    69,    68,    70,     0,     0,     0,     0,    18,     0,
+      79,    15,    13,     0,     0,     0,    20,    30,    82,    22,
+      84,     0,    81,    80,    43,    21,    83,     0,     0,    16,
+      29,    19,    31,     0,    23,    32,    26,     0,    76,    34,
+       0,     0,     0,     0,    37,    36,    24,    35,    33,     0,
+      77,    78,    25,     0,    28,     0,     0,     0,    27
 };
 };
 
 
   /* YYPGOTO[NTERM-NUM].  */
   /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int8 yypgoto[] =
 static const yytype_int8 yypgoto[] =
 {
 {
-     -81,   -81,   100,   104,   -81,   -38,   -81,   -80,   -81,   -81,
-     -81,    -5,    66,    13,   -81,    70,    67,    81,    64,    82,
-      37,    27,    34,    38,   -14,   -81,    22,    24
+     -44,   -44,   -44,   103,    99,   104,   -44,   -43,   -44,   -21,
+     -44,   -44,   -44,    -8,    63,     9,   -44,    65,    67,    68,
+      69,    62,    26,     4,    22,    23,   -19,   -44,    20,    28
 };
 };
 
 
   /* YYDEFGOTO[NTERM-NUM].  */
   /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 static const yytype_int16 yydefgoto[] =
 {
 {
-      -1,     2,     7,     8,    15,    36,    65,    93,   112,   113,
-     125,    20,    21,    22,    23,    24,    25,    26,    27,    28,
-      29,    30,    31,    32,    33,   128,    94,    95
+      -1,     2,     3,     4,    10,    11,    19,    41,    70,    98,
+     117,   118,   130,    25,    26,    27,    28,    29,    30,    31,
+      32,    33,    34,    35,    36,    37,    38,   133,    99,   100
 };
 };
 
 
   /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
   /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
@@ -613,87 +619,87 @@ static const yytype_int16 yydefgoto[] =
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_uint8 yytable[] =
 static const yytype_uint8 yytable[] =
 {
 {
-      12,    68,    69,    41,    42,    43,    45,    34,     9,    10,
-      53,    54,   104,     3,     5,   107,   101,   118,    35,     1,
-     102,     4,    61,    11,   119,   120,   121,   122,    35,    97,
-      46,     6,    55,    17,   123,    44,    18,    19,    56,   124,
-      62,    63,     9,    10,    14,    51,    52,    86,    87,    88,
-       9,    10,    48,   103,   129,   130,   115,    11,   135,   116,
-     136,    47,   131,    57,    58,    11,    37,    49,   117,    50,
-     137,    64,    38,    39,   138,   139,    40,    89,    90,    91,
-      78,    79,    80,    81,    92,    59,    60,    66,    76,    77,
-      67,    82,    83,    96,    98,    99,   100,    84,    85,   106,
-     110,   111,   114,   126,   134,   127,   133,   141,    16,   143,
-      13,   109,    71,    74,    72,    70,   105,   108,     0,     0,
-     132,     0,     0,     0,     0,     0,     0,     0,     0,    73,
-       0,     0,    75,   140,     0,     0,   142
+      16,    73,    74,    46,    47,    48,    13,    14,    39,    50,
+      58,    59,   120,     8,   140,   121,   141,     1,    94,    95,
+      96,    15,    12,    66,   122,    97,   142,    56,    57,   102,
+       9,    22,    60,    51,    23,    24,    62,    63,    61,    13,
+      14,    67,    68,   134,   135,   143,   144,    91,    92,    93,
+     123,   136,     5,   108,    15,    13,    14,   124,   125,   126,
+     127,     6,    83,    84,    85,    86,    18,   128,    42,   106,
+      15,    40,   129,   107,    43,    44,   109,    40,    45,   112,
+      64,    65,    81,    82,    87,    88,    49,    89,    90,    21,
+      52,    69,    53,    71,    54,    72,    55,   103,   101,   104,
+     105,   115,   111,   131,   116,   119,     7,   138,   132,   139,
+      20,   146,   114,    17,    76,    75,   148,    80,     0,    77,
+     113,    78,   137,    79,     0,   110,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,   145,     0,     0,   147
 };
 };
 
 
 static const yytype_int16 yycheck[] =
 static const yytype_int16 yycheck[] =
 {
 {
-       5,    39,    40,    17,    18,    19,    12,    12,    17,    18,
-       7,     8,    92,    24,     4,    95,    24,    13,    26,     3,
-      28,     0,    25,    32,    20,    21,    22,    23,    26,    67,
-      36,    21,    29,    42,    30,    34,    45,    46,    35,    35,
-      43,    44,    17,    18,    25,     9,    10,    61,    62,    63,
-      17,    18,    38,    91,    21,    22,    21,    32,    19,    24,
-      21,    11,    29,     5,     6,    32,    15,    39,    33,    40,
-      31,    24,    21,    22,    33,    34,    25,    14,    15,    16,
-      53,    54,    55,    56,    21,    41,    42,    22,    51,    52,
-      22,    57,    58,    24,    37,    16,    16,    59,    60,    27,
-      24,    24,    24,    17,    20,    32,    35,    33,     8,    34,
-       6,    98,    46,    49,    47,    45,    92,    95,    -1,    -1,
-     125,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    48,
-      -1,    -1,    50,   138,    -1,    -1,   141
+       8,    44,    45,    22,    23,    24,    18,    19,    16,    13,
+       8,     9,    22,     5,    20,    25,    22,     3,    15,    16,
+      17,    33,     4,    26,    34,    22,    32,    10,    11,    72,
+      22,    43,    30,    37,    46,    47,     6,     7,    36,    18,
+      19,    44,    45,    22,    23,    34,    35,    66,    67,    68,
+      14,    30,    25,    96,    33,    18,    19,    21,    22,    23,
+      24,     0,    58,    59,    60,    61,    26,    31,    16,    25,
+      33,    27,    36,    29,    22,    23,    97,    27,    26,   100,
+      42,    43,    56,    57,    62,    63,    35,    64,    65,    25,
+      12,    25,    39,    23,    40,    23,    41,    38,    25,    17,
+      17,    25,    28,    18,    25,    25,     3,    36,    33,    21,
+      11,    34,   103,     9,    51,    50,    35,    55,    -1,    52,
+     100,    53,   130,    54,    -1,    97,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,   143,    -1,    -1,   146
 };
 };
 
 
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
      symbol of state STATE-NUM.  */
      symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 static const yytype_uint8 yystos[] =
 {
 {
-       0,     3,    48,    24,     0,     4,    21,    49,    50,    17,
-      18,    32,    58,    50,    25,    51,    49,    42,    45,    46,
-      58,    59,    60,    61,    62,    63,    64,    65,    66,    67,
-      68,    69,    70,    71,    58,    26,    52,    15,    21,    22,
-      25,    71,    71,    71,    34,    12,    36,    11,    38,    39,
-      40,     9,    10,     7,     8,    29,    35,     5,     6,    41,
-      42,    25,    43,    44,    24,    53,    22,    22,    52,    52,
-      62,    59,    63,    64,    65,    66,    67,    67,    68,    68,
-      68,    68,    69,    69,    70,    70,    71,    71,    71,    14,
-      15,    16,    21,    54,    73,    74,    24,    52,    37,    16,
-      16,    24,    28,    52,    54,    74,    27,    54,    73,    60,
-      24,    24,    55,    56,    24,    21,    24,    33,    13,    20,
-      21,    22,    23,    30,    35,    57,    17,    32,    72,    21,
-      22,    29,    58,    35,    20,    19,    21,    31,    33,    34,
-      58,    33,    58,    34
+       0,     3,    49,    50,    51,    25,     0,    51,     5,    22,
+      52,    53,     4,    18,    19,    33,    61,    53,    26,    54,
+      52,    25,    43,    46,    47,    61,    62,    63,    64,    65,
+      66,    67,    68,    69,    70,    71,    72,    73,    74,    61,
+      27,    55,    16,    22,    23,    26,    74,    74,    74,    35,
+      13,    37,    12,    39,    40,    41,    10,    11,     8,     9,
+      30,    36,     6,     7,    42,    43,    26,    44,    45,    25,
+      56,    23,    23,    55,    55,    65,    62,    66,    67,    68,
+      69,    70,    70,    71,    71,    71,    71,    72,    72,    73,
+      73,    74,    74,    74,    15,    16,    17,    22,    57,    76,
+      77,    25,    55,    38,    17,    17,    25,    29,    55,    57,
+      77,    28,    57,    76,    63,    25,    25,    58,    59,    25,
+      22,    25,    34,    14,    21,    22,    23,    24,    31,    36,
+      60,    18,    33,    75,    22,    23,    30,    61,    36,    21,
+      20,    22,    32,    34,    35,    61,    34,    61,    35
 };
 };
 
 
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 static const yytype_uint8 yyr1[] =
 {
 {
-       0,    47,    48,    49,    49,    50,    50,    51,    51,    51,
-      51,    51,    52,    53,    53,    54,    54,    54,    54,    55,
-      55,    55,    55,    55,    55,    55,    56,    56,    56,    57,
-      57,    57,    57,    57,    58,    58,    58,    59,    60,    60,
-      61,    61,    62,    62,    63,    63,    64,    64,    65,    65,
-      66,    66,    66,    67,    67,    67,    67,    67,    68,    68,
-      68,    69,    69,    69,    70,    70,    70,    70,    71,    71,
-      71,    71,    72,    72,    72,    73,    73,    73,    74,    74,
-      74
+       0,    48,    49,    50,    50,    51,    51,    52,    52,    53,
+      53,    54,    54,    54,    54,    54,    55,    56,    56,    57,
+      57,    57,    57,    58,    58,    58,    58,    58,    58,    58,
+      59,    59,    59,    60,    60,    60,    60,    60,    61,    61,
+      61,    62,    63,    63,    64,    64,    65,    65,    66,    66,
+      67,    67,    68,    68,    69,    69,    69,    70,    70,    70,
+      70,    70,    71,    71,    71,    72,    72,    72,    73,    73,
+      73,    73,    74,    74,    74,    74,    75,    75,    75,    76,
+      76,    76,    77,    77,    77
 };
 };
 
 
   /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
   /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 static const yytype_uint8 yyr2[] =
 {
 {
-       0,     2,     4,     0,     2,     4,     2,     2,     3,     4,
-       3,     4,     5,     0,     2,     4,     2,     3,     2,     2,
-       3,     4,     2,     9,     5,     2,     0,     2,     2,     3,
-       1,     2,     2,     2,     1,     1,     3,     1,     1,     5,
-       1,     3,     1,     3,     1,     3,     1,     3,     1,     3,
-       1,     3,     3,     1,     3,     3,     3,     3,     3,     3,
-       1,     3,     3,     1,     3,     3,     3,     1,     1,     2,
-       2,     2,     0,     2,     2,     0,     2,     2,     2,     3,
-       2
+       0,     2,     3,     2,     4,     1,     2,     0,     2,     4,
+       2,     2,     3,     4,     3,     4,     5,     0,     2,     4,
+       2,     3,     2,     2,     3,     4,     2,     9,     5,     2,
+       0,     2,     2,     3,     1,     2,     2,     2,     1,     1,
+       3,     1,     1,     5,     1,     3,     1,     3,     1,     3,
+       1,     3,     1,     3,     1,     3,     3,     1,     3,     3,
+       3,     3,     3,     3,     1,     3,     3,     1,     3,     3,
+       3,     1,     1,     2,     2,     2,     0,     2,     2,     0,
+       2,     2,     2,     3,     2
 };
 };
 
 
 
 
@@ -1463,65 +1469,91 @@ yyreduce:
   switch (yyn)
   switch (yyn)
     {
     {
         case 2:
         case 2:
-#line 105 "dtc-parser.y" /* yacc.c:1646  */
+#line 110 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
-			the_boot_info = build_boot_info((yyvsp[-1].re), (yyvsp[0].node),
-							guess_boot_cpuid((yyvsp[0].node)));
+			parser_output = build_dt_info((yyvsp[-2].flags), (yyvsp[-1].re), (yyvsp[0].node),
+			                              guess_boot_cpuid((yyvsp[0].node)));
 		}
 		}
-#line 1472 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1478 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
   case 3:
   case 3:
-#line 113 "dtc-parser.y" /* yacc.c:1646  */
+#line 118 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
-			(yyval.re) = NULL;
+			(yyval.flags) = DTSF_V1;
 		}
 		}
-#line 1480 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1486 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
   case 4:
   case 4:
-#line 117 "dtc-parser.y" /* yacc.c:1646  */
+#line 122 "dtc-parser.y" /* yacc.c:1646  */
+    {
+			(yyval.flags) = DTSF_V1 | DTSF_PLUGIN;
+		}
+#line 1494 "dtc-parser.tab.c" /* yacc.c:1646  */
+    break;
+
+  case 6:
+#line 130 "dtc-parser.y" /* yacc.c:1646  */
+    {
+			if ((yyvsp[0].flags) != (yyvsp[-1].flags))
+				ERROR(&(yylsp[0]), "Header flags don't match earlier ones");
+			(yyval.flags) = (yyvsp[-1].flags);
+		}
+#line 1504 "dtc-parser.tab.c" /* yacc.c:1646  */
+    break;
+
+  case 7:
+#line 139 "dtc-parser.y" /* yacc.c:1646  */
+    {
+			(yyval.re) = NULL;
+		}
+#line 1512 "dtc-parser.tab.c" /* yacc.c:1646  */
+    break;
+
+  case 8:
+#line 143 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re));
 			(yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re));
 		}
 		}
-#line 1488 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1520 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 5:
-#line 124 "dtc-parser.y" /* yacc.c:1646  */
+  case 9:
+#line 150 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer));
 			(yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer));
 		}
 		}
-#line 1496 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1528 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 6:
-#line 128 "dtc-parser.y" /* yacc.c:1646  */
+  case 10:
+#line 154 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref));
 			add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref));
 			(yyval.re) = (yyvsp[0].re);
 			(yyval.re) = (yyvsp[0].re);
 		}
 		}
-#line 1505 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1537 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 7:
-#line 136 "dtc-parser.y" /* yacc.c:1646  */
+  case 11:
+#line 162 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.node) = name_node((yyvsp[0].node), "");
 			(yyval.node) = name_node((yyvsp[0].node), "");
 		}
 		}
-#line 1513 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1545 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 8:
-#line 140 "dtc-parser.y" /* yacc.c:1646  */
+  case 12:
+#line 166 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node));
 			(yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node));
 		}
 		}
-#line 1521 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1553 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 9:
-#line 145 "dtc-parser.y" /* yacc.c:1646  */
+  case 13:
+#line 171 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
 			struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
 
 
@@ -1532,11 +1564,11 @@ yyreduce:
 				ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
 				ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
 			(yyval.node) = (yyvsp[-3].node);
 			(yyval.node) = (yyvsp[-3].node);
 		}
 		}
-#line 1536 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1568 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 10:
-#line 156 "dtc-parser.y" /* yacc.c:1646  */
+  case 14:
+#line 182 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref));
 			struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref));
 
 
@@ -1546,11 +1578,11 @@ yyreduce:
 				ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
 				ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
 			(yyval.node) = (yyvsp[-2].node);
 			(yyval.node) = (yyvsp[-2].node);
 		}
 		}
-#line 1550 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1582 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 11:
-#line 166 "dtc-parser.y" /* yacc.c:1646  */
+  case 15:
+#line 192 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
 			struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
 
 
@@ -1562,100 +1594,100 @@ yyreduce:
 
 
 			(yyval.node) = (yyvsp[-3].node);
 			(yyval.node) = (yyvsp[-3].node);
 		}
 		}
-#line 1566 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1598 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 12:
-#line 181 "dtc-parser.y" /* yacc.c:1646  */
+  case 16:
+#line 207 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
 			(yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
 		}
 		}
-#line 1574 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1606 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 13:
-#line 188 "dtc-parser.y" /* yacc.c:1646  */
+  case 17:
+#line 214 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.proplist) = NULL;
 			(yyval.proplist) = NULL;
 		}
 		}
-#line 1582 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1614 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 14:
-#line 192 "dtc-parser.y" /* yacc.c:1646  */
+  case 18:
+#line 218 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
 			(yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
 		}
 		}
-#line 1590 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1622 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 15:
-#line 199 "dtc-parser.y" /* yacc.c:1646  */
+  case 19:
+#line 225 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
 			(yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
 		}
 		}
-#line 1598 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1630 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 16:
-#line 203 "dtc-parser.y" /* yacc.c:1646  */
+  case 20:
+#line 229 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
 			(yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
 		}
 		}
-#line 1606 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1638 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 17:
-#line 207 "dtc-parser.y" /* yacc.c:1646  */
+  case 21:
+#line 233 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
 			(yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
 		}
 		}
-#line 1614 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1646 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 18:
-#line 211 "dtc-parser.y" /* yacc.c:1646  */
+  case 22:
+#line 237 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref));
 			add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref));
 			(yyval.prop) = (yyvsp[0].prop);
 			(yyval.prop) = (yyvsp[0].prop);
 		}
 		}
-#line 1623 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1655 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 19:
-#line 219 "dtc-parser.y" /* yacc.c:1646  */
+  case 23:
+#line 245 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data));
 			(yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data));
 		}
 		}
-#line 1631 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1663 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 20:
-#line 223 "dtc-parser.y" /* yacc.c:1646  */
+  case 24:
+#line 249 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data);
 			(yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data);
 		}
 		}
-#line 1639 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1671 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 21:
-#line 227 "dtc-parser.y" /* yacc.c:1646  */
+  case 25:
+#line 253 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data));
 			(yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data));
 		}
 		}
-#line 1647 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1679 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 22:
-#line 231 "dtc-parser.y" /* yacc.c:1646  */
+  case 26:
+#line 257 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref));
 			(yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref));
 		}
 		}
-#line 1655 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1687 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 23:
-#line 235 "dtc-parser.y" /* yacc.c:1646  */
+  case 27:
+#line 261 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL);
 			FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL);
 			struct data d;
 			struct data d;
@@ -1671,11 +1703,11 @@ yyreduce:
 			(yyval.data) = data_merge((yyvsp[-8].data), d);
 			(yyval.data) = data_merge((yyvsp[-8].data), d);
 			fclose(f);
 			fclose(f);
 		}
 		}
-#line 1675 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1707 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 24:
-#line 251 "dtc-parser.y" /* yacc.c:1646  */
+  case 28:
+#line 277 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL);
 			FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL);
 			struct data d = empty_data;
 			struct data d = empty_data;
@@ -1685,43 +1717,43 @@ yyreduce:
 			(yyval.data) = data_merge((yyvsp[-4].data), d);
 			(yyval.data) = data_merge((yyvsp[-4].data), d);
 			fclose(f);
 			fclose(f);
 		}
 		}
-#line 1689 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1721 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 25:
-#line 261 "dtc-parser.y" /* yacc.c:1646  */
+  case 29:
+#line 287 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
 			(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
 		}
 		}
-#line 1697 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1729 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 26:
-#line 268 "dtc-parser.y" /* yacc.c:1646  */
+  case 30:
+#line 294 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.data) = empty_data;
 			(yyval.data) = empty_data;
 		}
 		}
-#line 1705 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1737 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 27:
-#line 272 "dtc-parser.y" /* yacc.c:1646  */
+  case 31:
+#line 298 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.data) = (yyvsp[-1].data);
 			(yyval.data) = (yyvsp[-1].data);
 		}
 		}
-#line 1713 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1745 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 28:
-#line 276 "dtc-parser.y" /* yacc.c:1646  */
+  case 32:
+#line 302 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
 			(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
 		}
 		}
-#line 1721 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1753 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 29:
-#line 283 "dtc-parser.y" /* yacc.c:1646  */
+  case 33:
+#line 309 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			unsigned long long bits;
 			unsigned long long bits;
 
 
@@ -1737,20 +1769,20 @@ yyreduce:
 			(yyval.array).data = empty_data;
 			(yyval.array).data = empty_data;
 			(yyval.array).bits = bits;
 			(yyval.array).bits = bits;
 		}
 		}
-#line 1741 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1773 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 30:
-#line 299 "dtc-parser.y" /* yacc.c:1646  */
+  case 34:
+#line 325 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.array).data = empty_data;
 			(yyval.array).data = empty_data;
 			(yyval.array).bits = 32;
 			(yyval.array).bits = 32;
 		}
 		}
-#line 1750 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1782 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 31:
-#line 304 "dtc-parser.y" /* yacc.c:1646  */
+  case 35:
+#line 330 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			if ((yyvsp[-1].array).bits < 64) {
 			if ((yyvsp[-1].array).bits < 64) {
 				uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1;
 				uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1;
@@ -1769,11 +1801,11 @@ yyreduce:
 
 
 			(yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits);
 			(yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits);
 		}
 		}
-#line 1773 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1805 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 32:
-#line 323 "dtc-parser.y" /* yacc.c:1646  */
+  case 36:
+#line 349 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits);
 			uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits);
 
 
@@ -1787,129 +1819,129 @@ yyreduce:
 
 
 			(yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits);
 			(yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits);
 		}
 		}
-#line 1791 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1823 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 33:
-#line 337 "dtc-parser.y" /* yacc.c:1646  */
+  case 37:
+#line 363 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref));
 			(yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref));
 		}
 		}
-#line 1799 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1831 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 36:
-#line 346 "dtc-parser.y" /* yacc.c:1646  */
+  case 40:
+#line 372 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.integer) = (yyvsp[-1].integer);
 			(yyval.integer) = (yyvsp[-1].integer);
 		}
 		}
-#line 1807 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1839 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 39:
-#line 357 "dtc-parser.y" /* yacc.c:1646  */
+  case 43:
+#line 383 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); }
     { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); }
-#line 1813 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1845 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 41:
-#line 362 "dtc-parser.y" /* yacc.c:1646  */
+  case 45:
+#line 388 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); }
     { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); }
-#line 1819 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1851 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 43:
-#line 367 "dtc-parser.y" /* yacc.c:1646  */
+  case 47:
+#line 393 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); }
     { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); }
-#line 1825 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1857 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 45:
-#line 372 "dtc-parser.y" /* yacc.c:1646  */
+  case 49:
+#line 398 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); }
     { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); }
-#line 1831 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1863 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 47:
-#line 377 "dtc-parser.y" /* yacc.c:1646  */
+  case 51:
+#line 403 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); }
     { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); }
-#line 1837 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1869 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 49:
-#line 382 "dtc-parser.y" /* yacc.c:1646  */
+  case 53:
+#line 408 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); }
     { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); }
-#line 1843 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1875 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 51:
-#line 387 "dtc-parser.y" /* yacc.c:1646  */
+  case 55:
+#line 413 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); }
     { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); }
-#line 1849 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1881 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 52:
-#line 388 "dtc-parser.y" /* yacc.c:1646  */
+  case 56:
+#line 414 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); }
     { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); }
-#line 1855 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1887 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 54:
-#line 393 "dtc-parser.y" /* yacc.c:1646  */
+  case 58:
+#line 419 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); }
     { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); }
-#line 1861 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1893 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 55:
-#line 394 "dtc-parser.y" /* yacc.c:1646  */
+  case 59:
+#line 420 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); }
     { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); }
-#line 1867 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1899 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 56:
-#line 395 "dtc-parser.y" /* yacc.c:1646  */
+  case 60:
+#line 421 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); }
     { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); }
-#line 1873 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1905 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 57:
-#line 396 "dtc-parser.y" /* yacc.c:1646  */
+  case 61:
+#line 422 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); }
     { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); }
-#line 1879 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1911 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 58:
-#line 400 "dtc-parser.y" /* yacc.c:1646  */
+  case 62:
+#line 426 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); }
     { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); }
-#line 1885 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1917 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 59:
-#line 401 "dtc-parser.y" /* yacc.c:1646  */
+  case 63:
+#line 427 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); }
     { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); }
-#line 1891 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1923 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 61:
-#line 406 "dtc-parser.y" /* yacc.c:1646  */
+  case 65:
+#line 432 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); }
     { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); }
-#line 1897 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1929 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 62:
-#line 407 "dtc-parser.y" /* yacc.c:1646  */
+  case 66:
+#line 433 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); }
     { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); }
-#line 1903 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1935 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 64:
-#line 412 "dtc-parser.y" /* yacc.c:1646  */
+  case 68:
+#line 438 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); }
     { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); }
-#line 1909 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1941 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 65:
-#line 414 "dtc-parser.y" /* yacc.c:1646  */
+  case 69:
+#line 440 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			if ((yyvsp[0].integer) != 0) {
 			if ((yyvsp[0].integer) != 0) {
 				(yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer);
 				(yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer);
@@ -1918,11 +1950,11 @@ yyreduce:
 				(yyval.integer) = 0;
 				(yyval.integer) = 0;
 			}
 			}
 		}
 		}
-#line 1922 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1954 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 66:
-#line 423 "dtc-parser.y" /* yacc.c:1646  */
+  case 70:
+#line 449 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			if ((yyvsp[0].integer) != 0) {
 			if ((yyvsp[0].integer) != 0) {
 				(yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer);
 				(yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer);
@@ -1931,103 +1963,103 @@ yyreduce:
 				(yyval.integer) = 0;
 				(yyval.integer) = 0;
 			}
 			}
 		}
 		}
-#line 1935 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1967 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 69:
-#line 436 "dtc-parser.y" /* yacc.c:1646  */
+  case 73:
+#line 462 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = -(yyvsp[0].integer); }
     { (yyval.integer) = -(yyvsp[0].integer); }
-#line 1941 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1973 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 70:
-#line 437 "dtc-parser.y" /* yacc.c:1646  */
+  case 74:
+#line 463 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = ~(yyvsp[0].integer); }
     { (yyval.integer) = ~(yyvsp[0].integer); }
-#line 1947 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1979 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 71:
-#line 438 "dtc-parser.y" /* yacc.c:1646  */
+  case 75:
+#line 464 "dtc-parser.y" /* yacc.c:1646  */
     { (yyval.integer) = !(yyvsp[0].integer); }
     { (yyval.integer) = !(yyvsp[0].integer); }
-#line 1953 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1985 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 72:
-#line 443 "dtc-parser.y" /* yacc.c:1646  */
+  case 76:
+#line 469 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.data) = empty_data;
 			(yyval.data) = empty_data;
 		}
 		}
-#line 1961 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 1993 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 73:
-#line 447 "dtc-parser.y" /* yacc.c:1646  */
+  case 77:
+#line 473 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte));
 			(yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte));
 		}
 		}
-#line 1969 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2001 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 74:
-#line 451 "dtc-parser.y" /* yacc.c:1646  */
+  case 78:
+#line 477 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
 			(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
 		}
 		}
-#line 1977 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2009 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 75:
-#line 458 "dtc-parser.y" /* yacc.c:1646  */
+  case 79:
+#line 484 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.nodelist) = NULL;
 			(yyval.nodelist) = NULL;
 		}
 		}
-#line 1985 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2017 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 76:
-#line 462 "dtc-parser.y" /* yacc.c:1646  */
+  case 80:
+#line 488 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist));
 			(yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist));
 		}
 		}
-#line 1993 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2025 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 77:
-#line 466 "dtc-parser.y" /* yacc.c:1646  */
+  case 81:
+#line 492 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			ERROR(&(yylsp[0]), "Properties must precede subnodes");
 			ERROR(&(yylsp[0]), "Properties must precede subnodes");
 			YYERROR;
 			YYERROR;
 		}
 		}
-#line 2002 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2034 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 78:
-#line 474 "dtc-parser.y" /* yacc.c:1646  */
+  case 82:
+#line 500 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename));
 			(yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename));
 		}
 		}
-#line 2010 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2042 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 79:
-#line 478 "dtc-parser.y" /* yacc.c:1646  */
+  case 83:
+#line 504 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			(yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename));
 			(yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename));
 		}
 		}
-#line 2018 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2050 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
-  case 80:
-#line 482 "dtc-parser.y" /* yacc.c:1646  */
+  case 84:
+#line 508 "dtc-parser.y" /* yacc.c:1646  */
     {
     {
 			add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref));
 			add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref));
 			(yyval.node) = (yyvsp[0].node);
 			(yyval.node) = (yyvsp[0].node);
 		}
 		}
-#line 2027 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2059 "dtc-parser.tab.c" /* yacc.c:1646  */
     break;
     break;
 
 
 
 
-#line 2031 "dtc-parser.tab.c" /* yacc.c:1646  */
+#line 2063 "dtc-parser.tab.c" /* yacc.c:1646  */
       default: break;
       default: break;
     }
     }
   /* User semantic actions sometimes alter yychar, and that requires
   /* User semantic actions sometimes alter yychar, and that requires
@@ -2262,7 +2294,7 @@ yyreturn:
 #endif
 #endif
   return yyresult;
   return yyresult;
 }
 }
-#line 488 "dtc-parser.y" /* yacc.c:1906  */
+#line 514 "dtc-parser.y" /* yacc.c:1906  */
 
 
 
 
 void yyerror(char const *s)
 void yyerror(char const *s)

+ 29 - 25
scripts/dtc/dtc-parser.tab.h_shipped

@@ -1,8 +1,8 @@
-/* A Bison parser, made by GNU Bison 3.0.2.  */
+/* A Bison parser, made by GNU Bison 3.0.4.  */
 
 
 /* Bison interface for Yacc-like parsers in C
 /* Bison interface for Yacc-like parsers in C
 
 
-   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
 
 
    This program is free software: you can redistribute it and/or modify
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    it under the terms of the GNU General Public License as published by
@@ -46,35 +46,36 @@ extern int yydebug;
   enum yytokentype
   enum yytokentype
   {
   {
     DT_V1 = 258,
     DT_V1 = 258,
-    DT_MEMRESERVE = 259,
-    DT_LSHIFT = 260,
-    DT_RSHIFT = 261,
-    DT_LE = 262,
-    DT_GE = 263,
-    DT_EQ = 264,
-    DT_NE = 265,
-    DT_AND = 266,
-    DT_OR = 267,
-    DT_BITS = 268,
-    DT_DEL_PROP = 269,
-    DT_DEL_NODE = 270,
-    DT_PROPNODENAME = 271,
-    DT_LITERAL = 272,
-    DT_CHAR_LITERAL = 273,
-    DT_BYTE = 274,
-    DT_STRING = 275,
-    DT_LABEL = 276,
-    DT_REF = 277,
-    DT_INCBIN = 278
+    DT_PLUGIN = 259,
+    DT_MEMRESERVE = 260,
+    DT_LSHIFT = 261,
+    DT_RSHIFT = 262,
+    DT_LE = 263,
+    DT_GE = 264,
+    DT_EQ = 265,
+    DT_NE = 266,
+    DT_AND = 267,
+    DT_OR = 268,
+    DT_BITS = 269,
+    DT_DEL_PROP = 270,
+    DT_DEL_NODE = 271,
+    DT_PROPNODENAME = 272,
+    DT_LITERAL = 273,
+    DT_CHAR_LITERAL = 274,
+    DT_BYTE = 275,
+    DT_STRING = 276,
+    DT_LABEL = 277,
+    DT_REF = 278,
+    DT_INCBIN = 279
   };
   };
 #endif
 #endif
 
 
 /* Value type.  */
 /* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE YYSTYPE;
+
 union YYSTYPE
 union YYSTYPE
 {
 {
-#line 38 "dtc-parser.y" /* yacc.c:1909  */
+#line 39 "dtc-parser.y" /* yacc.c:1909  */
 
 
 	char *propnodename;
 	char *propnodename;
 	char *labelref;
 	char *labelref;
@@ -92,9 +93,12 @@ union YYSTYPE
 	struct node *nodelist;
 	struct node *nodelist;
 	struct reserve_info *re;
 	struct reserve_info *re;
 	uint64_t integer;
 	uint64_t integer;
+	unsigned int flags;
 
 
-#line 97 "dtc-parser.tab.h" /* yacc.c:1909  */
+#line 99 "dtc-parser.tab.h" /* yacc.c:1909  */
 };
 };
+
+typedef union YYSTYPE YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define YYSTYPE_IS_TRIVIAL 1
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_DECLARED 1
 #endif
 #endif

+ 30 - 4
scripts/dtc/dtc-parser.y

@@ -19,6 +19,7 @@
  */
  */
 %{
 %{
 #include <stdio.h>
 #include <stdio.h>
+#include <inttypes.h>
 
 
 #include "dtc.h"
 #include "dtc.h"
 #include "srcpos.h"
 #include "srcpos.h"
@@ -31,7 +32,7 @@ extern void yyerror(char const *s);
 		treesource_error = true; \
 		treesource_error = true; \
 	} while (0)
 	} while (0)
 
 
-extern struct boot_info *the_boot_info;
+extern struct dt_info *parser_output;
 extern bool treesource_error;
 extern bool treesource_error;
 %}
 %}
 
 
@@ -52,9 +53,11 @@ extern bool treesource_error;
 	struct node *nodelist;
 	struct node *nodelist;
 	struct reserve_info *re;
 	struct reserve_info *re;
 	uint64_t integer;
 	uint64_t integer;
+	unsigned int flags;
 }
 }
 
 
 %token DT_V1
 %token DT_V1
+%token DT_PLUGIN
 %token DT_MEMRESERVE
 %token DT_MEMRESERVE
 %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR
 %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR
 %token DT_BITS
 %token DT_BITS
@@ -71,6 +74,8 @@ extern bool treesource_error;
 
 
 %type <data> propdata
 %type <data> propdata
 %type <data> propdataprefix
 %type <data> propdataprefix
+%type <flags> header
+%type <flags> headers
 %type <re> memreserve
 %type <re> memreserve
 %type <re> memreserves
 %type <re> memreserves
 %type <array> arrayprefix
 %type <array> arrayprefix
@@ -101,10 +106,31 @@ extern bool treesource_error;
 %%
 %%
 
 
 sourcefile:
 sourcefile:
-	  DT_V1 ';' memreserves devicetree
+	  headers memreserves devicetree
 		{
 		{
-			the_boot_info = build_boot_info($3, $4,
-							guess_boot_cpuid($4));
+			parser_output = build_dt_info($1, $2, $3,
+			                              guess_boot_cpuid($3));
+		}
+	;
+
+header:
+	  DT_V1 ';'
+		{
+			$$ = DTSF_V1;
+		}
+	| DT_V1 ';' DT_PLUGIN ';'
+		{
+			$$ = DTSF_V1 | DTSF_PLUGIN;
+		}
+	;
+
+headers:
+	  header
+	| header headers
+		{
+			if ($2 != $1)
+				ERROR(&@2, "Header flags don't match earlier ones");
+			$$ = $1;
 		}
 		}
 	;
 	;
 
 

+ 57 - 12
scripts/dtc/dtc.c

@@ -30,7 +30,16 @@ int quiet;		/* Level of quietness */
 int reservenum;		/* Number of memory reservation slots */
 int reservenum;		/* Number of memory reservation slots */
 int minsize;		/* Minimum blob size */
 int minsize;		/* Minimum blob size */
 int padsize;		/* Additional padding to blob */
 int padsize;		/* Additional padding to blob */
+int alignsize;		/* Additional padding to blob accroding to the alignsize */
 int phandle_format = PHANDLE_BOTH;	/* Use linux,phandle or phandle properties */
 int phandle_format = PHANDLE_BOTH;	/* Use linux,phandle or phandle properties */
+int generate_symbols;	/* enable symbols & fixup support */
+int generate_fixups;		/* suppress generation of fixups on symbol support */
+int auto_label_aliases;		/* auto generate labels -> aliases */
+
+static int is_power_of_2(int x)
+{
+	return (x > 0) && ((x & (x - 1)) == 0);
+}
 
 
 static void fill_fullpaths(struct node *tree, const char *prefix)
 static void fill_fullpaths(struct node *tree, const char *prefix)
 {
 {
@@ -53,7 +62,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
 #define FDT_VERSION(version)	_FDT_VERSION(version)
 #define FDT_VERSION(version)	_FDT_VERSION(version)
 #define _FDT_VERSION(version)	#version
 #define _FDT_VERSION(version)	#version
 static const char usage_synopsis[] = "dtc [options] <input file>";
 static const char usage_synopsis[] = "dtc [options] <input file>";
-static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv";
+static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@Ahv";
 static struct option const usage_long_opts[] = {
 static struct option const usage_long_opts[] = {
 	{"quiet",            no_argument, NULL, 'q'},
 	{"quiet",            no_argument, NULL, 'q'},
 	{"in-format",         a_argument, NULL, 'I'},
 	{"in-format",         a_argument, NULL, 'I'},
@@ -64,6 +73,7 @@ static struct option const usage_long_opts[] = {
 	{"reserve",           a_argument, NULL, 'R'},
 	{"reserve",           a_argument, NULL, 'R'},
 	{"space",             a_argument, NULL, 'S'},
 	{"space",             a_argument, NULL, 'S'},
 	{"pad",               a_argument, NULL, 'p'},
 	{"pad",               a_argument, NULL, 'p'},
+	{"align",             a_argument, NULL, 'a'},
 	{"boot-cpu",          a_argument, NULL, 'b'},
 	{"boot-cpu",          a_argument, NULL, 'b'},
 	{"force",            no_argument, NULL, 'f'},
 	{"force",            no_argument, NULL, 'f'},
 	{"include",           a_argument, NULL, 'i'},
 	{"include",           a_argument, NULL, 'i'},
@@ -71,6 +81,8 @@ static struct option const usage_long_opts[] = {
 	{"phandle",           a_argument, NULL, 'H'},
 	{"phandle",           a_argument, NULL, 'H'},
 	{"warning",           a_argument, NULL, 'W'},
 	{"warning",           a_argument, NULL, 'W'},
 	{"error",             a_argument, NULL, 'E'},
 	{"error",             a_argument, NULL, 'E'},
+	{"symbols",	     no_argument, NULL, '@'},
+	{"auto-alias",       no_argument, NULL, 'A'},
 	{"help",             no_argument, NULL, 'h'},
 	{"help",             no_argument, NULL, 'h'},
 	{"version",          no_argument, NULL, 'v'},
 	{"version",          no_argument, NULL, 'v'},
 	{NULL,               no_argument, NULL, 0x0},
 	{NULL,               no_argument, NULL, 0x0},
@@ -91,6 +103,7 @@ static const char * const usage_opts_help[] = {
 	"\n\tMake space for <number> reserve map entries (for dtb and asm output)",
 	"\n\tMake space for <number> reserve map entries (for dtb and asm output)",
 	"\n\tMake the blob at least <bytes> long (extra space)",
 	"\n\tMake the blob at least <bytes> long (extra space)",
 	"\n\tAdd padding to the blob of <bytes> long (extra space)",
 	"\n\tAdd padding to the blob of <bytes> long (extra space)",
+	"\n\tMake the blob align to the <bytes> (extra space)",
 	"\n\tSet the physical boot cpu",
 	"\n\tSet the physical boot cpu",
 	"\n\tTry to produce output even if the input tree has errors",
 	"\n\tTry to produce output even if the input tree has errors",
 	"\n\tAdd a path to search for include files",
 	"\n\tAdd a path to search for include files",
@@ -101,6 +114,8 @@ static const char * const usage_opts_help[] = {
 	 "\t\tboth   - Both \"linux,phandle\" and \"phandle\" properties",
 	 "\t\tboth   - Both \"linux,phandle\" and \"phandle\" properties",
 	"\n\tEnable/disable warnings (prefix with \"no-\")",
 	"\n\tEnable/disable warnings (prefix with \"no-\")",
 	"\n\tEnable/disable errors (prefix with \"no-\")",
 	"\n\tEnable/disable errors (prefix with \"no-\")",
+	"\n\tEnable generation of symbols",
+	"\n\tEnable auto-alias of labels",
 	"\n\tPrint this help and exit",
 	"\n\tPrint this help and exit",
 	"\n\tPrint version and exit",
 	"\n\tPrint version and exit",
 	NULL,
 	NULL,
@@ -153,7 +168,7 @@ static const char *guess_input_format(const char *fname, const char *fallback)
 
 
 int main(int argc, char *argv[])
 int main(int argc, char *argv[])
 {
 {
-	struct boot_info *bi;
+	struct dt_info *dti;
 	const char *inform = NULL;
 	const char *inform = NULL;
 	const char *outform = NULL;
 	const char *outform = NULL;
 	const char *outname = "-";
 	const char *outname = "-";
@@ -169,6 +184,7 @@ int main(int argc, char *argv[])
 	reservenum = 0;
 	reservenum = 0;
 	minsize    = 0;
 	minsize    = 0;
 	padsize    = 0;
 	padsize    = 0;
+	alignsize  = 0;
 
 
 	while ((opt = util_getopt_long()) != EOF) {
 	while ((opt = util_getopt_long()) != EOF) {
 		switch (opt) {
 		switch (opt) {
@@ -196,6 +212,12 @@ int main(int argc, char *argv[])
 		case 'p':
 		case 'p':
 			padsize = strtol(optarg, NULL, 0);
 			padsize = strtol(optarg, NULL, 0);
 			break;
 			break;
+		case 'a':
+			alignsize = strtol(optarg, NULL, 0);
+			if (!is_power_of_2(alignsize))
+				die("Invalid argument \"%d\" to -a option\n",
+				    optarg);
+			break;
 		case 'f':
 		case 'f':
 			force = true;
 			force = true;
 			break;
 			break;
@@ -234,6 +256,13 @@ int main(int argc, char *argv[])
 			parse_checks_option(false, true, optarg);
 			parse_checks_option(false, true, optarg);
 			break;
 			break;
 
 
+		case '@':
+			generate_symbols = 1;
+			break;
+		case 'A':
+			auto_label_aliases = 1;
+			break;
+
 		case 'h':
 		case 'h':
 			usage(NULL);
 			usage(NULL);
 		default:
 		default:
@@ -272,11 +301,11 @@ int main(int argc, char *argv[])
 		}
 		}
 	}
 	}
 	if (streq(inform, "dts"))
 	if (streq(inform, "dts"))
-		bi = dt_from_source(arg);
+		dti = dt_from_source(arg);
 	else if (streq(inform, "fs"))
 	else if (streq(inform, "fs"))
-		bi = dt_from_fs(arg);
+		dti = dt_from_fs(arg);
 	else if(streq(inform, "dtb"))
 	else if(streq(inform, "dtb"))
-		bi = dt_from_blob(arg);
+		dti = dt_from_blob(arg);
 	else
 	else
 		die("Unknown input format \"%s\"\n", inform);
 		die("Unknown input format \"%s\"\n", inform);
 
 
@@ -286,13 +315,29 @@ int main(int argc, char *argv[])
 	}
 	}
 
 
 	if (cmdline_boot_cpuid != -1)
 	if (cmdline_boot_cpuid != -1)
-		bi->boot_cpuid_phys = cmdline_boot_cpuid;
+		dti->boot_cpuid_phys = cmdline_boot_cpuid;
+
+	fill_fullpaths(dti->dt, "");
+	process_checks(force, dti);
+
+	/* on a plugin, generate by default */
+	if (dti->dtsflags & DTSF_PLUGIN) {
+		generate_fixups = 1;
+	}
 
 
-	fill_fullpaths(bi->dt, "");
-	process_checks(force, bi);
+	if (auto_label_aliases)
+		generate_label_tree(dti, "aliases", false);
+
+	if (generate_symbols)
+		generate_label_tree(dti, "__symbols__", true);
+
+	if (generate_fixups) {
+		generate_fixups_tree(dti, "__fixups__");
+		generate_local_fixups_tree(dti, "__local_fixups__");
+	}
 
 
 	if (sort)
 	if (sort)
-		sort_tree(bi);
+		sort_tree(dti);
 
 
 	if (streq(outname, "-")) {
 	if (streq(outname, "-")) {
 		outf = stdout;
 		outf = stdout;
@@ -304,11 +349,11 @@ int main(int argc, char *argv[])
 	}
 	}
 
 
 	if (streq(outform, "dts")) {
 	if (streq(outform, "dts")) {
-		dt_to_source(outf, bi);
+		dt_to_source(outf, dti);
 	} else if (streq(outform, "dtb")) {
 	} else if (streq(outform, "dtb")) {
-		dt_to_blob(outf, bi, outversion);
+		dt_to_blob(outf, dti, outversion);
 	} else if (streq(outform, "asm")) {
 	} else if (streq(outform, "asm")) {
-		dt_to_asm(outf, bi, outversion);
+		dt_to_asm(outf, dti, outversion);
 	} else if (streq(outform, "null")) {
 	} else if (streq(outform, "null")) {
 		/* do nothing */
 		/* do nothing */
 	} else {
 	} else {

+ 27 - 12
scripts/dtc/dtc.h

@@ -53,7 +53,11 @@ extern int quiet;		/* Level of quietness */
 extern int reservenum;		/* Number of memory reservation slots */
 extern int reservenum;		/* Number of memory reservation slots */
 extern int minsize;		/* Minimum blob size */
 extern int minsize;		/* Minimum blob size */
 extern int padsize;		/* Additional padding to blob */
 extern int padsize;		/* Additional padding to blob */
+extern int alignsize;		/* Additional padding to blob accroding to the alignsize */
 extern int phandle_format;	/* Use linux,phandle or phandle properties */
 extern int phandle_format;	/* Use linux,phandle or phandle properties */
+extern int generate_symbols;	/* generate symbols for nodes with labels */
+extern int generate_fixups;	/* generate fixups */
+extern int auto_label_aliases;	/* auto generate labels -> aliases */
 
 
 #define PHANDLE_LEGACY	0x1
 #define PHANDLE_LEGACY	0x1
 #define PHANDLE_EPAPR	0x2
 #define PHANDLE_EPAPR	0x2
@@ -201,6 +205,8 @@ void delete_property(struct property *prop);
 void add_child(struct node *parent, struct node *child);
 void add_child(struct node *parent, struct node *child);
 void delete_node_by_name(struct node *parent, char *name);
 void delete_node_by_name(struct node *parent, char *name);
 void delete_node(struct node *node);
 void delete_node(struct node *node);
+void append_to_property(struct node *node,
+			char *name, const void *data, int len);
 
 
 const char *get_unitname(struct node *node);
 const char *get_unitname(struct node *node);
 struct property *get_property(struct node *node, const char *propname);
 struct property *get_property(struct node *node, const char *propname);
@@ -235,35 +241,44 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list,
 				       struct reserve_info *new);
 				       struct reserve_info *new);
 
 
 
 
-struct boot_info {
+struct dt_info {
+	unsigned int dtsflags;
 	struct reserve_info *reservelist;
 	struct reserve_info *reservelist;
-	struct node *dt;		/* the device tree */
 	uint32_t boot_cpuid_phys;
 	uint32_t boot_cpuid_phys;
+	struct node *dt;		/* the device tree */
 };
 };
 
 
-struct boot_info *build_boot_info(struct reserve_info *reservelist,
-				  struct node *tree, uint32_t boot_cpuid_phys);
-void sort_tree(struct boot_info *bi);
+/* DTS version flags definitions */
+#define DTSF_V1		0x0001	/* /dts-v1/ */
+#define DTSF_PLUGIN	0x0002	/* /plugin/ */
+
+struct dt_info *build_dt_info(unsigned int dtsflags,
+			      struct reserve_info *reservelist,
+			      struct node *tree, uint32_t boot_cpuid_phys);
+void sort_tree(struct dt_info *dti);
+void generate_label_tree(struct dt_info *dti, char *name, bool allocph);
+void generate_fixups_tree(struct dt_info *dti, char *name);
+void generate_local_fixups_tree(struct dt_info *dti, char *name);
 
 
 /* Checks */
 /* Checks */
 
 
 void parse_checks_option(bool warn, bool error, const char *arg);
 void parse_checks_option(bool warn, bool error, const char *arg);
-void process_checks(bool force, struct boot_info *bi);
+void process_checks(bool force, struct dt_info *dti);
 
 
 /* Flattened trees */
 /* Flattened trees */
 
 
-void dt_to_blob(FILE *f, struct boot_info *bi, int version);
-void dt_to_asm(FILE *f, struct boot_info *bi, int version);
+void dt_to_blob(FILE *f, struct dt_info *dti, int version);
+void dt_to_asm(FILE *f, struct dt_info *dti, int version);
 
 
-struct boot_info *dt_from_blob(const char *fname);
+struct dt_info *dt_from_blob(const char *fname);
 
 
 /* Tree source */
 /* Tree source */
 
 
-void dt_to_source(FILE *f, struct boot_info *bi);
-struct boot_info *dt_from_source(const char *f);
+void dt_to_source(FILE *f, struct dt_info *dti);
+struct dt_info *dt_from_source(const char *f);
 
 
 /* FS trees */
 /* FS trees */
 
 
-struct boot_info *dt_from_fs(const char *dirname);
+struct dt_info *dt_from_fs(const char *dirname);
 
 
 #endif /* _DTC_H */
 #endif /* _DTC_H */

+ 27 - 14
scripts/dtc/flattree.c

@@ -366,7 +366,7 @@ static void make_fdt_header(struct fdt_header *fdt,
 		fdt->size_dt_struct = cpu_to_fdt32(dtsize);
 		fdt->size_dt_struct = cpu_to_fdt32(dtsize);
 }
 }
 
 
-void dt_to_blob(FILE *f, struct boot_info *bi, int version)
+void dt_to_blob(FILE *f, struct dt_info *dti, int version)
 {
 {
 	struct version_info *vi = NULL;
 	struct version_info *vi = NULL;
 	int i;
 	int i;
@@ -384,29 +384,36 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version)
 	if (!vi)
 	if (!vi)
 		die("Unknown device tree blob version %d\n", version);
 		die("Unknown device tree blob version %d\n", version);
 
 
-	flatten_tree(bi->dt, &bin_emitter, &dtbuf, &strbuf, vi);
+	flatten_tree(dti->dt, &bin_emitter, &dtbuf, &strbuf, vi);
 	bin_emit_cell(&dtbuf, FDT_END);
 	bin_emit_cell(&dtbuf, FDT_END);
 
 
-	reservebuf = flatten_reserve_list(bi->reservelist, vi);
+	reservebuf = flatten_reserve_list(dti->reservelist, vi);
 
 
 	/* Make header */
 	/* Make header */
 	make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len,
 	make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len,
-			bi->boot_cpuid_phys);
+			dti->boot_cpuid_phys);
 
 
 	/*
 	/*
 	 * If the user asked for more space than is used, adjust the totalsize.
 	 * If the user asked for more space than is used, adjust the totalsize.
 	 */
 	 */
 	if (minsize > 0) {
 	if (minsize > 0) {
 		padlen = minsize - fdt32_to_cpu(fdt.totalsize);
 		padlen = minsize - fdt32_to_cpu(fdt.totalsize);
-		if ((padlen < 0) && (quiet < 1))
-			fprintf(stderr,
-				"Warning: blob size %d >= minimum size %d\n",
-				fdt32_to_cpu(fdt.totalsize), minsize);
+		if (padlen < 0) {
+			padlen = 0;
+			if (quiet < 1)
+				fprintf(stderr,
+					"Warning: blob size %d >= minimum size %d\n",
+					fdt32_to_cpu(fdt.totalsize), minsize);
+		}
 	}
 	}
 
 
 	if (padsize > 0)
 	if (padsize > 0)
 		padlen = padsize;
 		padlen = padsize;
 
 
+	if (alignsize > 0)
+		padlen = ALIGN(fdt32_to_cpu(fdt.totalsize) + padlen, alignsize)
+			- fdt32_to_cpu(fdt.totalsize);
+
 	if (padlen > 0) {
 	if (padlen > 0) {
 		int tsize = fdt32_to_cpu(fdt.totalsize);
 		int tsize = fdt32_to_cpu(fdt.totalsize);
 		tsize += padlen;
 		tsize += padlen;
@@ -460,7 +467,7 @@ static void dump_stringtable_asm(FILE *f, struct data strbuf)
 	}
 	}
 }
 }
 
 
-void dt_to_asm(FILE *f, struct boot_info *bi, int version)
+void dt_to_asm(FILE *f, struct dt_info *dti, int version)
 {
 {
 	struct version_info *vi = NULL;
 	struct version_info *vi = NULL;
 	int i;
 	int i;
@@ -500,7 +507,7 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version)
 
 
 	if (vi->flags & FTF_BOOTCPUID) {
 	if (vi->flags & FTF_BOOTCPUID) {
 		fprintf(f, "\t/* boot_cpuid_phys */\n");
 		fprintf(f, "\t/* boot_cpuid_phys */\n");
-		asm_emit_cell(f, bi->boot_cpuid_phys);
+		asm_emit_cell(f, dti->boot_cpuid_phys);
 	}
 	}
 
 
 	if (vi->flags & FTF_STRTABSIZE) {
 	if (vi->flags & FTF_STRTABSIZE) {
@@ -530,7 +537,7 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version)
 	 * Use .long on high and low halfs of u64s to avoid .quad
 	 * Use .long on high and low halfs of u64s to avoid .quad
 	 * as it appears .quad isn't available in some assemblers.
 	 * as it appears .quad isn't available in some assemblers.
 	 */
 	 */
-	for (re = bi->reservelist; re; re = re->next) {
+	for (re = dti->reservelist; re; re = re->next) {
 		struct label *l;
 		struct label *l;
 
 
 		for_each_label(re->labels, l) {
 		for_each_label(re->labels, l) {
@@ -550,7 +557,7 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version)
 	fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n");
 	fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n");
 
 
 	emit_label(f, symprefix, "struct_start");
 	emit_label(f, symprefix, "struct_start");
-	flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi);
+	flatten_tree(dti->dt, &asm_emitter, f, &strbuf, vi);
 
 
 	fprintf(f, "\t/* FDT_END */\n");
 	fprintf(f, "\t/* FDT_END */\n");
 	asm_emit_cell(f, FDT_END);
 	asm_emit_cell(f, FDT_END);
@@ -572,6 +579,8 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version)
 	if (padsize > 0) {
 	if (padsize > 0) {
 		fprintf(f, "\t.space\t%d, 0\n", padsize);
 		fprintf(f, "\t.space\t%d, 0\n", padsize);
 	}
 	}
+	if (alignsize > 0)
+		asm_emit_align(f, alignsize);
 	emit_label(f, symprefix, "blob_abs_end");
 	emit_label(f, symprefix, "blob_abs_end");
 
 
 	data_free(strbuf);
 	data_free(strbuf);
@@ -797,11 +806,15 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
 		}
 		}
 	} while (val != FDT_END_NODE);
 	} while (val != FDT_END_NODE);
 
 
+	if (node->name != flatname) {
+		free(flatname);
+	}
+
 	return node;
 	return node;
 }
 }
 
 
 
 
-struct boot_info *dt_from_blob(const char *fname)
+struct dt_info *dt_from_blob(const char *fname)
 {
 {
 	FILE *f;
 	FILE *f;
 	uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys;
 	uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys;
@@ -929,5 +942,5 @@ struct boot_info *dt_from_blob(const char *fname)
 
 
 	fclose(f);
 	fclose(f);
 
 
-	return build_boot_info(reservelist, tree, boot_cpuid_phys);
+	return build_dt_info(DTSF_V1, reservelist, tree, boot_cpuid_phys);
 }
 }

+ 2 - 3
scripts/dtc/fstree.c

@@ -79,13 +79,12 @@ static struct node *read_fstree(const char *dirname)
 	return tree;
 	return tree;
 }
 }
 
 
-struct boot_info *dt_from_fs(const char *dirname)
+struct dt_info *dt_from_fs(const char *dirname)
 {
 {
 	struct node *tree;
 	struct node *tree;
 
 
 	tree = read_fstree(dirname);
 	tree = read_fstree(dirname);
 	tree = name_node(tree, "");
 	tree = name_node(tree, "");
 
 
-	return build_boot_info(NULL, tree, guess_boot_cpuid(tree));
+	return build_dt_info(DTSF_V1, NULL, tree, guess_boot_cpuid(tree));
 }
 }
-

+ 1 - 1
scripts/dtc/libfdt/Makefile.libfdt

@@ -7,5 +7,5 @@ LIBFDT_soname = libfdt.$(SHAREDLIB_EXT).1
 LIBFDT_INCLUDES = fdt.h libfdt.h libfdt_env.h
 LIBFDT_INCLUDES = fdt.h libfdt.h libfdt_env.h
 LIBFDT_VERSION = version.lds
 LIBFDT_VERSION = version.lds
 LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c \
 LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c \
-	fdt_addresses.c
+	fdt_addresses.c fdt_overlay.c
 LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
 LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)

+ 28 - 2
scripts/dtc/libfdt/fdt_ro.c

@@ -88,6 +88,32 @@ static int _fdt_string_eq(const void *fdt, int stroffset,
 	return (strlen(p) == len) && (memcmp(p, s, len) == 0);
 	return (strlen(p) == len) && (memcmp(p, s, len) == 0);
 }
 }
 
 
+uint32_t fdt_get_max_phandle(const void *fdt)
+{
+	uint32_t max_phandle = 0;
+	int offset;
+
+	for (offset = fdt_next_node(fdt, -1, NULL);;
+	     offset = fdt_next_node(fdt, offset, NULL)) {
+		uint32_t phandle;
+
+		if (offset == -FDT_ERR_NOTFOUND)
+			return max_phandle;
+
+		if (offset < 0)
+			return (uint32_t)-1;
+
+		phandle = fdt_get_phandle(fdt, offset);
+		if (phandle == (uint32_t)-1)
+			continue;
+
+		if (phandle > max_phandle)
+			max_phandle = phandle;
+	}
+
+	return 0;
+}
+
 int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
 int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
 {
 {
 	FDT_CHECK_HEADER(fdt);
 	FDT_CHECK_HEADER(fdt);
@@ -545,7 +571,7 @@ int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property)
 
 
 	list = fdt_getprop(fdt, nodeoffset, property, &length);
 	list = fdt_getprop(fdt, nodeoffset, property, &length);
 	if (!list)
 	if (!list)
-		return -length;
+		return length;
 
 
 	end = list + length;
 	end = list + length;
 
 
@@ -571,7 +597,7 @@ int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,
 
 
 	list = fdt_getprop(fdt, nodeoffset, property, &length);
 	list = fdt_getprop(fdt, nodeoffset, property, &length);
 	if (!list)
 	if (!list)
-		return -length;
+		return length;
 
 
 	len = strlen(string) + 1;
 	len = strlen(string) + 1;
 	end = list + length;
 	end = list + length;

+ 1 - 5
scripts/dtc/libfdt/fdt_rw.c

@@ -191,17 +191,13 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
 int fdt_del_mem_rsv(void *fdt, int n)
 int fdt_del_mem_rsv(void *fdt, int n)
 {
 {
 	struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
 	struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
-	int err;
 
 
 	FDT_RW_CHECK_HEADER(fdt);
 	FDT_RW_CHECK_HEADER(fdt);
 
 
 	if (n >= fdt_num_mem_rsv(fdt))
 	if (n >= fdt_num_mem_rsv(fdt))
 		return -FDT_ERR_NOTFOUND;
 		return -FDT_ERR_NOTFOUND;
 
 
-	err = _fdt_splice_mem_rsv(fdt, re, 1, 0);
-	if (err)
-		return err;
-	return 0;
+	return _fdt_splice_mem_rsv(fdt, re, 1, 0);
 }
 }
 
 
 static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
 static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,

+ 6 - 0
scripts/dtc/libfdt/fdt_strerror.c

@@ -69,6 +69,7 @@ static struct fdt_errtabent fdt_errtable[] = {
 
 
 	FDT_ERRTABENT(FDT_ERR_BADOFFSET),
 	FDT_ERRTABENT(FDT_ERR_BADOFFSET),
 	FDT_ERRTABENT(FDT_ERR_BADPATH),
 	FDT_ERRTABENT(FDT_ERR_BADPATH),
+	FDT_ERRTABENT(FDT_ERR_BADPHANDLE),
 	FDT_ERRTABENT(FDT_ERR_BADSTATE),
 	FDT_ERRTABENT(FDT_ERR_BADSTATE),
 
 
 	FDT_ERRTABENT(FDT_ERR_TRUNCATED),
 	FDT_ERRTABENT(FDT_ERR_TRUNCATED),
@@ -76,6 +77,11 @@ static struct fdt_errtabent fdt_errtable[] = {
 	FDT_ERRTABENT(FDT_ERR_BADVERSION),
 	FDT_ERRTABENT(FDT_ERR_BADVERSION),
 	FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),
 	FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),
 	FDT_ERRTABENT(FDT_ERR_BADLAYOUT),
 	FDT_ERRTABENT(FDT_ERR_BADLAYOUT),
+	FDT_ERRTABENT(FDT_ERR_INTERNAL),
+	FDT_ERRTABENT(FDT_ERR_BADNCELLS),
+	FDT_ERRTABENT(FDT_ERR_BADVALUE),
+	FDT_ERRTABENT(FDT_ERR_BADOVERLAY),
+	FDT_ERRTABENT(FDT_ERR_NOPHANDLES),
 };
 };
 #define FDT_ERRTABSIZE	(sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
 #define FDT_ERRTABSIZE	(sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
 
 

+ 25 - 4
scripts/dtc/libfdt/fdt_wip.c

@@ -55,21 +55,42 @@
 
 
 #include "libfdt_internal.h"
 #include "libfdt_internal.h"
 
 
+int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
+					const char *name, int namelen,
+					uint32_t idx, const void *val,
+					int len)
+{
+	void *propval;
+	int proplen;
+
+	propval = fdt_getprop_namelen_w(fdt, nodeoffset, name, namelen,
+					&proplen);
+	if (!propval)
+		return proplen;
+
+	if (proplen < (len + idx))
+		return -FDT_ERR_NOSPACE;
+
+	memcpy((char *)propval + idx, val, len);
+	return 0;
+}
+
 int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
 int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
 			const void *val, int len)
 			const void *val, int len)
 {
 {
-	void *propval;
+	const void *propval;
 	int proplen;
 	int proplen;
 
 
-	propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen);
+	propval = fdt_getprop(fdt, nodeoffset, name, &proplen);
 	if (! propval)
 	if (! propval)
 		return proplen;
 		return proplen;
 
 
 	if (proplen != len)
 	if (proplen != len)
 		return -FDT_ERR_NOSPACE;
 		return -FDT_ERR_NOSPACE;
 
 
-	memcpy(propval, val, len);
-	return 0;
+	return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,
+						   strlen(name), 0,
+						   val, len);
 }
 }
 
 
 static void _fdt_nop_region(void *start, int len)
 static void _fdt_nop_region(void *start, int len)

+ 180 - 30
scripts/dtc/libfdt/libfdt.h

@@ -61,7 +61,7 @@
 #define FDT_ERR_NOTFOUND	1
 #define FDT_ERR_NOTFOUND	1
 	/* FDT_ERR_NOTFOUND: The requested node or property does not exist */
 	/* FDT_ERR_NOTFOUND: The requested node or property does not exist */
 #define FDT_ERR_EXISTS		2
 #define FDT_ERR_EXISTS		2
-	/* FDT_ERR_EXISTS: Attemped to create a node or property which
+	/* FDT_ERR_EXISTS: Attempted to create a node or property which
 	 * already exists */
 	 * already exists */
 #define FDT_ERR_NOSPACE		3
 #define FDT_ERR_NOSPACE		3
 	/* FDT_ERR_NOSPACE: Operation needed to expand the device
 	/* FDT_ERR_NOSPACE: Operation needed to expand the device
@@ -79,8 +79,10 @@
 	 * (e.g. missing a leading / for a function which requires an
 	 * (e.g. missing a leading / for a function which requires an
 	 * absolute path) */
 	 * absolute path) */
 #define FDT_ERR_BADPHANDLE	6
 #define FDT_ERR_BADPHANDLE	6
-	/* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle
-	 * value.  phandle values of 0 and -1 are not permitted. */
+	/* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle.
+	 * This can be caused either by an invalid phandle property
+	 * length, or the phandle value was either 0 or -1, which are
+	 * not permitted. */
 #define FDT_ERR_BADSTATE	7
 #define FDT_ERR_BADSTATE	7
 	/* FDT_ERR_BADSTATE: Function was passed an incomplete device
 	/* FDT_ERR_BADSTATE: Function was passed an incomplete device
 	 * tree created by the sequential-write functions, which is
 	 * tree created by the sequential-write functions, which is
@@ -126,7 +128,16 @@
 	 * value. For example: a property expected to contain a string list
 	 * value. For example: a property expected to contain a string list
 	 * is not NUL-terminated within the length of its value. */
 	 * is not NUL-terminated within the length of its value. */
 
 
-#define FDT_ERR_MAX		15
+#define FDT_ERR_BADOVERLAY	16
+	/* FDT_ERR_BADOVERLAY: The device tree overlay, while
+	 * correctly structured, cannot be applied due to some
+	 * unexpected or missing value, property or node. */
+
+#define FDT_ERR_NOPHANDLES	17
+	/* FDT_ERR_NOPHANDLES: The device tree doesn't have any
+	 * phandle available anymore without causing an overflow */
+
+#define FDT_ERR_MAX		17
 
 
 /**********************************************************************/
 /**********************************************************************/
 /* Low-level functions (you probably don't need these)                */
 /* Low-level functions (you probably don't need these)                */
@@ -168,27 +179,55 @@ int fdt_first_subnode(const void *fdt, int offset);
  */
  */
 int fdt_next_subnode(const void *fdt, int offset);
 int fdt_next_subnode(const void *fdt, int offset);
 
 
+/**
+ * fdt_for_each_subnode - iterate over all subnodes of a parent
+ *
+ * @node:	child node (int, lvalue)
+ * @fdt:	FDT blob (const void *)
+ * @parent:	parent node (int)
+ *
+ * This is actually a wrapper around a for loop and would be used like so:
+ *
+ *	fdt_for_each_subnode(node, fdt, parent) {
+ *		Use node
+ *		...
+ *	}
+ *
+ *	if ((node < 0) && (node != -FDT_ERR_NOT_FOUND)) {
+ *		Error handling
+ *	}
+ *
+ * Note that this is implemented as a macro and @node is used as
+ * iterator in the loop. The parent variable be constant or even a
+ * literal.
+ *
+ */
+#define fdt_for_each_subnode(node, fdt, parent)		\
+	for (node = fdt_first_subnode(fdt, parent);	\
+	     node >= 0;					\
+	     node = fdt_next_subnode(fdt, node))
+
 /**********************************************************************/
 /**********************************************************************/
 /* General functions                                                  */
 /* General functions                                                  */
 /**********************************************************************/
 /**********************************************************************/
 
 
 #define fdt_get_header(fdt, field) \
 #define fdt_get_header(fdt, field) \
 	(fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
 	(fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
-#define fdt_magic(fdt) 			(fdt_get_header(fdt, magic))
+#define fdt_magic(fdt)			(fdt_get_header(fdt, magic))
 #define fdt_totalsize(fdt)		(fdt_get_header(fdt, totalsize))
 #define fdt_totalsize(fdt)		(fdt_get_header(fdt, totalsize))
 #define fdt_off_dt_struct(fdt)		(fdt_get_header(fdt, off_dt_struct))
 #define fdt_off_dt_struct(fdt)		(fdt_get_header(fdt, off_dt_struct))
 #define fdt_off_dt_strings(fdt)		(fdt_get_header(fdt, off_dt_strings))
 #define fdt_off_dt_strings(fdt)		(fdt_get_header(fdt, off_dt_strings))
 #define fdt_off_mem_rsvmap(fdt)		(fdt_get_header(fdt, off_mem_rsvmap))
 #define fdt_off_mem_rsvmap(fdt)		(fdt_get_header(fdt, off_mem_rsvmap))
 #define fdt_version(fdt)		(fdt_get_header(fdt, version))
 #define fdt_version(fdt)		(fdt_get_header(fdt, version))
-#define fdt_last_comp_version(fdt) 	(fdt_get_header(fdt, last_comp_version))
-#define fdt_boot_cpuid_phys(fdt) 	(fdt_get_header(fdt, boot_cpuid_phys))
-#define fdt_size_dt_strings(fdt) 	(fdt_get_header(fdt, size_dt_strings))
+#define fdt_last_comp_version(fdt)	(fdt_get_header(fdt, last_comp_version))
+#define fdt_boot_cpuid_phys(fdt)	(fdt_get_header(fdt, boot_cpuid_phys))
+#define fdt_size_dt_strings(fdt)	(fdt_get_header(fdt, size_dt_strings))
 #define fdt_size_dt_struct(fdt)		(fdt_get_header(fdt, size_dt_struct))
 #define fdt_size_dt_struct(fdt)		(fdt_get_header(fdt, size_dt_struct))
 
 
 #define __fdt_set_hdr(name) \
 #define __fdt_set_hdr(name) \
 	static inline void fdt_set_##name(void *fdt, uint32_t val) \
 	static inline void fdt_set_##name(void *fdt, uint32_t val) \
 	{ \
 	{ \
-		struct fdt_header *fdth = (struct fdt_header*)fdt; \
+		struct fdt_header *fdth = (struct fdt_header *)fdt; \
 		fdth->name = cpu_to_fdt32(val); \
 		fdth->name = cpu_to_fdt32(val); \
 	}
 	}
 __fdt_set_hdr(magic);
 __fdt_set_hdr(magic);
@@ -258,6 +297,21 @@ int fdt_move(const void *fdt, void *buf, int bufsize);
  */
  */
 const char *fdt_string(const void *fdt, int stroffset);
 const char *fdt_string(const void *fdt, int stroffset);
 
 
+/**
+ * fdt_get_max_phandle - retrieves the highest phandle in a tree
+ * @fdt: pointer to the device tree blob
+ *
+ * fdt_get_max_phandle retrieves the highest phandle in the given
+ * device tree. This will ignore badly formatted phandles, or phandles
+ * with a value of 0 or -1.
+ *
+ * returns:
+ *      the highest phandle on success
+ *      0, if no phandle was found in the device tree
+ *      -1, if an error occurred
+ */
+uint32_t fdt_get_max_phandle(const void *fdt);
+
 /**
 /**
  * fdt_num_mem_rsv - retrieve the number of memory reserve map entries
  * fdt_num_mem_rsv - retrieve the number of memory reserve map entries
  * @fdt: pointer to the device tree blob
  * @fdt: pointer to the device tree blob
@@ -318,8 +372,9 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
  * returns:
  * returns:
  *	structure block offset of the requested subnode (>=0), on success
  *	structure block offset of the requested subnode (>=0), on success
  *	-FDT_ERR_NOTFOUND, if the requested subnode does not exist
  *	-FDT_ERR_NOTFOUND, if the requested subnode does not exist
- *	-FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
- *      -FDT_ERR_BADMAGIC,
+ *	-FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE
+ *		tag
+ *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADSTATE,
  *	-FDT_ERR_BADSTATE,
  *	-FDT_ERR_BADSTRUCTURE,
  *	-FDT_ERR_BADSTRUCTURE,
@@ -351,7 +406,8 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen);
  * address).
  * address).
  *
  *
  * returns:
  * returns:
- *	structure block offset of the node with the requested path (>=0), on success
+ *	structure block offset of the node with the requested path (>=0), on
+ *		success
  *	-FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
  *	-FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
  *	-FDT_ERR_NOTFOUND, if the requested node does not exist
  *	-FDT_ERR_NOTFOUND, if the requested node does not exist
  *      -FDT_ERR_BADMAGIC,
  *      -FDT_ERR_BADMAGIC,
@@ -375,10 +431,12 @@ int fdt_path_offset(const void *fdt, const char *path);
  *
  *
  * returns:
  * returns:
  *	pointer to the node's name, on success
  *	pointer to the node's name, on success
- *		If lenp is non-NULL, *lenp contains the length of that name (>=0)
+ *		If lenp is non-NULL, *lenp contains the length of that name
+ *			(>=0)
  *	NULL, on error
  *	NULL, on error
  *		if lenp is non-NULL *lenp contains an error code (<0):
  *		if lenp is non-NULL *lenp contains an error code (<0):
- *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE
+ *			tag
  *		-FDT_ERR_BADMAGIC,
  *		-FDT_ERR_BADMAGIC,
  *		-FDT_ERR_BADVERSION,
  *		-FDT_ERR_BADVERSION,
  *		-FDT_ERR_BADSTATE, standard meanings
  *		-FDT_ERR_BADSTATE, standard meanings
@@ -426,6 +484,33 @@ int fdt_first_property_offset(const void *fdt, int nodeoffset);
  */
  */
 int fdt_next_property_offset(const void *fdt, int offset);
 int fdt_next_property_offset(const void *fdt, int offset);
 
 
+/**
+ * fdt_for_each_property_offset - iterate over all properties of a node
+ *
+ * @property_offset:	property offset (int, lvalue)
+ * @fdt:		FDT blob (const void *)
+ * @node:		node offset (int)
+ *
+ * This is actually a wrapper around a for loop and would be used like so:
+ *
+ *	fdt_for_each_property_offset(property, fdt, node) {
+ *		Use property
+ *		...
+ *	}
+ *
+ *	if ((property < 0) && (property != -FDT_ERR_NOT_FOUND)) {
+ *		Error handling
+ *	}
+ *
+ * Note that this is implemented as a macro and property is used as
+ * iterator in the loop. The node variable can be constant or even a
+ * literal.
+ */
+#define fdt_for_each_property_offset(property, fdt, node)	\
+	for (property = fdt_first_property_offset(fdt, node);	\
+	     property >= 0;					\
+	     property = fdt_next_property_offset(fdt, property))
+
 /**
 /**
  * fdt_get_property_by_offset - retrieve the property at a given offset
  * fdt_get_property_by_offset - retrieve the property at a given offset
  * @fdt: pointer to the device tree blob
  * @fdt: pointer to the device tree blob
@@ -490,7 +575,8 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt,
  *	NULL, on error
  *	NULL, on error
  *		if lenp is non-NULL, *lenp contains an error code (<0):
  *		if lenp is non-NULL, *lenp contains an error code (<0):
  *		-FDT_ERR_NOTFOUND, node does not have named property
  *		-FDT_ERR_NOTFOUND, node does not have named property
- *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE
+ *			tag
  *		-FDT_ERR_BADMAGIC,
  *		-FDT_ERR_BADMAGIC,
  *		-FDT_ERR_BADVERSION,
  *		-FDT_ERR_BADVERSION,
  *		-FDT_ERR_BADSTATE,
  *		-FDT_ERR_BADSTATE,
@@ -554,6 +640,13 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset,
  */
  */
 const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
 const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
 				const char *name, int namelen, int *lenp);
 				const char *name, int namelen, int *lenp);
+static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset,
+					  const char *name, int namelen,
+					  int *lenp)
+{
+	return (void *)(uintptr_t)fdt_getprop_namelen(fdt, nodeoffset, name,
+						      namelen, lenp);
+}
 
 
 /**
 /**
  * fdt_getprop - retrieve the value of a given property
  * fdt_getprop - retrieve the value of a given property
@@ -575,7 +668,8 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
  *	NULL, on error
  *	NULL, on error
  *		if lenp is non-NULL, *lenp contains an error code (<0):
  *		if lenp is non-NULL, *lenp contains an error code (<0):
  *		-FDT_ERR_NOTFOUND, node does not have named property
  *		-FDT_ERR_NOTFOUND, node does not have named property
- *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ *		-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE
+ *			tag
  *		-FDT_ERR_BADMAGIC,
  *		-FDT_ERR_BADMAGIC,
  *		-FDT_ERR_BADVERSION,
  *		-FDT_ERR_BADVERSION,
  *		-FDT_ERR_BADSTATE,
  *		-FDT_ERR_BADSTATE,
@@ -617,7 +711,7 @@ const char *fdt_get_alias_namelen(const void *fdt,
 				  const char *name, int namelen);
 				  const char *name, int namelen);
 
 
 /**
 /**
- * fdt_get_alias - retreive the path referenced by a given alias
+ * fdt_get_alias - retrieve the path referenced by a given alias
  * @fdt: pointer to the device tree blob
  * @fdt: pointer to the device tree blob
  * @name: name of the alias th look up
  * @name: name of the alias th look up
  *
  *
@@ -647,7 +741,7 @@ const char *fdt_get_alias(const void *fdt, const char *name);
  *	0, on success
  *	0, on success
  *		buf contains the absolute path of the node at
  *		buf contains the absolute path of the node at
  *		nodeoffset, as a NUL-terminated string.
  *		nodeoffset, as a NUL-terminated string.
- * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ *	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
  *	-FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
  *	-FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
  *		characters and will not fit in the given buffer.
  *		characters and will not fit in the given buffer.
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADMAGIC,
@@ -677,11 +771,11 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
  * structure from the start to nodeoffset.
  * structure from the start to nodeoffset.
  *
  *
  * returns:
  * returns:
-
  *	structure block offset of the node at node offset's ancestor
  *	structure block offset of the node at node offset's ancestor
  *		of depth supernodedepth (>=0), on success
  *		of depth supernodedepth (>=0), on success
- * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
-*	-FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset
+ *	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ *	-FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of
+ *		nodeoffset
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADSTATE,
  *	-FDT_ERR_BADSTATE,
@@ -703,7 +797,7 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
  *
  *
  * returns:
  * returns:
  *	depth of the node at nodeoffset (>=0), on success
  *	depth of the node at nodeoffset (>=0), on success
- * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ *	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADSTATE,
  *	-FDT_ERR_BADSTATE,
@@ -726,7 +820,7 @@ int fdt_node_depth(const void *fdt, int nodeoffset);
  * returns:
  * returns:
  *	structure block offset of the parent of the node at nodeoffset
  *	structure block offset of the parent of the node at nodeoffset
  *		(>=0), on success
  *		(>=0), on success
- * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ *	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADSTATE,
  *	-FDT_ERR_BADSTATE,
@@ -766,7 +860,7 @@ int fdt_parent_offset(const void *fdt, int nodeoffset);
  *		 on success
  *		 on success
  *	-FDT_ERR_NOTFOUND, no node matching the criterion exists in the
  *	-FDT_ERR_NOTFOUND, no node matching the criterion exists in the
  *		tree after startoffset
  *		tree after startoffset
- * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ *	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADSTATE,
  *	-FDT_ERR_BADSTATE,
@@ -813,7 +907,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
  *	1, if the node has a 'compatible' property, but it does not list
  *	1, if the node has a 'compatible' property, but it does not list
  *		the given string
  *		the given string
  *	-FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
  *	-FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
- * 	-FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
+ *	-FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADSTATE,
  *	-FDT_ERR_BADSTATE,
@@ -850,7 +944,7 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset,
  *		 on success
  *		 on success
  *	-FDT_ERR_NOTFOUND, no node matching the criterion exists in the
  *	-FDT_ERR_NOTFOUND, no node matching the criterion exists in the
  *		tree after startoffset
  *		tree after startoffset
- * 	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
+ *	-FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADSTATE,
  *	-FDT_ERR_BADSTATE,
@@ -960,7 +1054,8 @@ const char *fdt_stringlist_get(const void *fdt, int nodeoffset,
  * returns:
  * returns:
  *	0 <= n < FDT_MAX_NCELLS, on success
  *	0 <= n < FDT_MAX_NCELLS, on success
  *      2, if the node has no #address-cells property
  *      2, if the node has no #address-cells property
- *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid #address-cells property
+ *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
+ *		#address-cells property
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADSTATE,
  *	-FDT_ERR_BADSTATE,
@@ -980,7 +1075,8 @@ int fdt_address_cells(const void *fdt, int nodeoffset);
  * returns:
  * returns:
  *	0 <= n < FDT_MAX_NCELLS, on success
  *	0 <= n < FDT_MAX_NCELLS, on success
  *      2, if the node has no #address-cells property
  *      2, if the node has no #address-cells property
- *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid #size-cells property
+ *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
+ *		#size-cells property
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADMAGIC,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADVERSION,
  *	-FDT_ERR_BADSTATE,
  *	-FDT_ERR_BADSTATE,
@@ -994,6 +1090,27 @@ int fdt_size_cells(const void *fdt, int nodeoffset);
 /* Write-in-place functions                                           */
 /* Write-in-place functions                                           */
 /**********************************************************************/
 /**********************************************************************/
 
 
+/**
+ * fdt_setprop_inplace_namelen_partial - change a property's value,
+ *                                       but not its size
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @namelen: number of characters of name to consider
+ * @idx: index of the property to change in the array
+ * @val: pointer to data to replace the property value with
+ * @len: length of the property value
+ *
+ * Identical to fdt_setprop_inplace(), but modifies the given property
+ * starting from the given index, and using only the first characters
+ * 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.
+ */
+int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
+					const char *name, int namelen,
+					uint32_t idx, const void *val,
+					int len);
+
 /**
 /**
  * fdt_setprop_inplace - change a property's value, but not its size
  * fdt_setprop_inplace - change a property's value, but not its size
  * @fdt: pointer to the device tree blob
  * @fdt: pointer to the device tree blob
@@ -1604,9 +1721,11 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
  * change the offsets of some existing nodes.
  * change the offsets of some existing nodes.
 
 
  * returns:
  * returns:
- *	structure block offset of the created nodeequested subnode (>=0), on success
+ *	structure block offset of the created nodeequested subnode (>=0), on
+ *		success
  *	-FDT_ERR_NOTFOUND, if the requested subnode does not exist
  *	-FDT_ERR_NOTFOUND, if the requested subnode does not exist
- *	-FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
+ *	-FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE
+ *		tag
  *	-FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of
  *	-FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of
  *		the given name
  *		the given name
  *	-FDT_ERR_NOSPACE, if there is insufficient free space in the
  *	-FDT_ERR_NOSPACE, if there is insufficient free space in the
@@ -1644,6 +1763,37 @@ int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
  */
  */
 int fdt_del_node(void *fdt, int nodeoffset);
 int fdt_del_node(void *fdt, int nodeoffset);
 
 
+/**
+ * fdt_overlay_apply - Applies a DT overlay on a base DT
+ * @fdt: pointer to the base device tree blob
+ * @fdto: pointer to the device tree overlay blob
+ *
+ * fdt_overlay_apply() will apply the given device tree overlay on the
+ * given base device tree.
+ *
+ * Expect the base device tree to be modified, even if the function
+ * returns an error.
+ *
+ * returns:
+ *	0, on success
+ *	-FDT_ERR_NOSPACE, there's not enough space in the base device tree
+ *	-FDT_ERR_NOTFOUND, the overlay points to some inexistant nodes or
+ *		properties in the base DT
+ *	-FDT_ERR_BADPHANDLE,
+ *	-FDT_ERR_BADOVERLAY,
+ *	-FDT_ERR_NOPHANDLES,
+ *	-FDT_ERR_INTERNAL,
+ *	-FDT_ERR_BADLAYOUT,
+ *	-FDT_ERR_BADMAGIC,
+ *	-FDT_ERR_BADOFFSET,
+ *	-FDT_ERR_BADPATH,
+ *	-FDT_ERR_BADVERSION,
+ *	-FDT_ERR_BADSTRUCTURE,
+ *	-FDT_ERR_BADSTATE,
+ *	-FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_overlay_apply(void *fdt, void *fdto);
+
 /**********************************************************************/
 /**********************************************************************/
 /* Debugging / informational functions                                */
 /* Debugging / informational functions                                */
 /**********************************************************************/
 /**********************************************************************/

+ 1 - 0
scripts/dtc/libfdt/libfdt_env.h

@@ -54,6 +54,7 @@
 
 
 #include <stddef.h>
 #include <stddef.h>
 #include <stdint.h>
 #include <stdint.h>
+#include <stdlib.h>
 #include <string.h>
 #include <string.h>
 
 
 #ifdef __CHECKER__
 #ifdef __CHECKER__

+ 283 - 16
scripts/dtc/livetree.c

@@ -204,7 +204,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
 			}
 			}
 		}
 		}
 
 
-		/* if no collision occured, add child to the old node. */
+		/* if no collision occurred, add child to the old node. */
 		if (new_child)
 		if (new_child)
 			add_child(old_node, new_child);
 			add_child(old_node, new_child);
 	}
 	}
@@ -296,6 +296,23 @@ void delete_node(struct node *node)
 	delete_labels(&node->labels);
 	delete_labels(&node->labels);
 }
 }
 
 
+void append_to_property(struct node *node,
+				    char *name, const void *data, int len)
+{
+	struct data d;
+	struct property *p;
+
+	p = get_property(node, name);
+	if (p) {
+		d = data_append_data(p->val, data, len);
+		p->val = d;
+	} else {
+		d = data_append_data(empty_data, data, len);
+		p = build_property(name, d);
+		add_property(node, p);
+	}
+}
+
 struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
 struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
 {
 {
 	struct reserve_info *new = xmalloc(sizeof(*new));
 	struct reserve_info *new = xmalloc(sizeof(*new));
@@ -335,17 +352,19 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list,
 	return list;
 	return list;
 }
 }
 
 
-struct boot_info *build_boot_info(struct reserve_info *reservelist,
-				  struct node *tree, uint32_t boot_cpuid_phys)
+struct dt_info *build_dt_info(unsigned int dtsflags,
+			      struct reserve_info *reservelist,
+			      struct node *tree, uint32_t boot_cpuid_phys)
 {
 {
-	struct boot_info *bi;
+	struct dt_info *dti;
 
 
-	bi = xmalloc(sizeof(*bi));
-	bi->reservelist = reservelist;
-	bi->dt = tree;
-	bi->boot_cpuid_phys = boot_cpuid_phys;
+	dti = xmalloc(sizeof(*dti));
+	dti->dtsflags = dtsflags;
+	dti->reservelist = reservelist;
+	dti->dt = tree;
+	dti->boot_cpuid_phys = boot_cpuid_phys;
 
 
-	return bi;
+	return dti;
 }
 }
 
 
 /*
 /*
@@ -592,12 +611,12 @@ static int cmp_reserve_info(const void *ax, const void *bx)
 		return 0;
 		return 0;
 }
 }
 
 
-static void sort_reserve_entries(struct boot_info *bi)
+static void sort_reserve_entries(struct dt_info *dti)
 {
 {
 	struct reserve_info *ri, **tbl;
 	struct reserve_info *ri, **tbl;
 	int n = 0, i = 0;
 	int n = 0, i = 0;
 
 
-	for (ri = bi->reservelist;
+	for (ri = dti->reservelist;
 	     ri;
 	     ri;
 	     ri = ri->next)
 	     ri = ri->next)
 		n++;
 		n++;
@@ -607,14 +626,14 @@ static void sort_reserve_entries(struct boot_info *bi)
 
 
 	tbl = xmalloc(n * sizeof(*tbl));
 	tbl = xmalloc(n * sizeof(*tbl));
 
 
-	for (ri = bi->reservelist;
+	for (ri = dti->reservelist;
 	     ri;
 	     ri;
 	     ri = ri->next)
 	     ri = ri->next)
 		tbl[i++] = ri;
 		tbl[i++] = ri;
 
 
 	qsort(tbl, n, sizeof(*tbl), cmp_reserve_info);
 	qsort(tbl, n, sizeof(*tbl), cmp_reserve_info);
 
 
-	bi->reservelist = tbl[0];
+	dti->reservelist = tbl[0];
 	for (i = 0; i < (n-1); i++)
 	for (i = 0; i < (n-1); i++)
 		tbl[i]->next = tbl[i+1];
 		tbl[i]->next = tbl[i+1];
 	tbl[n-1]->next = NULL;
 	tbl[n-1]->next = NULL;
@@ -704,8 +723,256 @@ static void sort_node(struct node *node)
 		sort_node(c);
 		sort_node(c);
 }
 }
 
 
-void sort_tree(struct boot_info *bi)
+void sort_tree(struct dt_info *dti)
+{
+	sort_reserve_entries(dti);
+	sort_node(dti->dt);
+}
+
+/* utility helper to avoid code duplication */
+static struct node *build_and_name_child_node(struct node *parent, char *name)
+{
+	struct node *node;
+
+	node = build_node(NULL, NULL);
+	name_node(node, xstrdup(name));
+	add_child(parent, node);
+
+	return node;
+}
+
+static struct node *build_root_node(struct node *dt, char *name)
+{
+	struct node *an;
+
+	an = get_subnode(dt, name);
+	if (!an)
+		an = build_and_name_child_node(dt, name);
+
+	if (!an)
+		die("Could not build root node /%s\n", name);
+
+	return an;
+}
+
+static bool any_label_tree(struct dt_info *dti, struct node *node)
+{
+	struct node *c;
+
+	if (node->labels)
+		return true;
+
+	for_each_child(node, c)
+		if (any_label_tree(dti, c))
+			return true;
+
+	return false;
+}
+
+static void generate_label_tree_internal(struct dt_info *dti,
+					 struct node *an, struct node *node,
+					 bool allocph)
+{
+	struct node *dt = dti->dt;
+	struct node *c;
+	struct property *p;
+	struct label *l;
+
+	/* if there are labels */
+	if (node->labels) {
+
+		/* now add the label in the node */
+		for_each_label(node->labels, l) {
+
+			/* check whether the label already exists */
+			p = get_property(an, l->label);
+			if (p) {
+				fprintf(stderr, "WARNING: label %s already"
+					" exists in /%s", l->label,
+					an->name);
+				continue;
+			}
+
+			/* insert it */
+			p = build_property(l->label,
+				data_copy_mem(node->fullpath,
+						strlen(node->fullpath) + 1));
+			add_property(an, p);
+		}
+
+		/* force allocation of a phandle for this node */
+		if (allocph)
+			(void)get_node_phandle(dt, node);
+	}
+
+	for_each_child(node, c)
+		generate_label_tree_internal(dti, an, c, allocph);
+}
+
+static bool any_fixup_tree(struct dt_info *dti, struct node *node)
+{
+	struct node *c;
+	struct property *prop;
+	struct marker *m;
+
+	for_each_property(node, prop) {
+		m = prop->val.markers;
+		for_each_marker_of_type(m, REF_PHANDLE) {
+			if (!get_node_by_ref(dti->dt, m->ref))
+				return true;
+		}
+	}
+
+	for_each_child(node, c) {
+		if (any_fixup_tree(dti, c))
+			return true;
+	}
+
+	return false;
+}
+
+static void add_fixup_entry(struct dt_info *dti, struct node *fn,
+			    struct node *node, struct property *prop,
+			    struct marker *m)
 {
 {
-	sort_reserve_entries(bi);
-	sort_node(bi->dt);
+	char *entry;
+
+	/* m->ref can only be a REF_PHANDLE, but check anyway */
+	assert(m->type == REF_PHANDLE);
+
+	/* there shouldn't be any ':' in the arguments */
+	if (strchr(node->fullpath, ':') || strchr(prop->name, ':'))
+		die("arguments should not contain ':'\n");
+
+	xasprintf(&entry, "%s:%s:%u",
+			node->fullpath, prop->name, m->offset);
+	append_to_property(fn, m->ref, entry, strlen(entry) + 1);
+}
+
+static void generate_fixups_tree_internal(struct dt_info *dti,
+					  struct node *fn,
+					  struct node *node)
+{
+	struct node *dt = dti->dt;
+	struct node *c;
+	struct property *prop;
+	struct marker *m;
+	struct node *refnode;
+
+	for_each_property(node, prop) {
+		m = prop->val.markers;
+		for_each_marker_of_type(m, REF_PHANDLE) {
+			refnode = get_node_by_ref(dt, m->ref);
+			if (!refnode)
+				add_fixup_entry(dti, fn, node, prop, m);
+		}
+	}
+
+	for_each_child(node, c)
+		generate_fixups_tree_internal(dti, fn, c);
+}
+
+static bool any_local_fixup_tree(struct dt_info *dti, struct node *node)
+{
+	struct node *c;
+	struct property *prop;
+	struct marker *m;
+
+	for_each_property(node, prop) {
+		m = prop->val.markers;
+		for_each_marker_of_type(m, REF_PHANDLE) {
+			if (get_node_by_ref(dti->dt, m->ref))
+				return true;
+		}
+	}
+
+	for_each_child(node, c) {
+		if (any_local_fixup_tree(dti, c))
+			return true;
+	}
+
+	return false;
+}
+
+static void add_local_fixup_entry(struct dt_info *dti,
+		struct node *lfn, struct node *node,
+		struct property *prop, struct marker *m,
+		struct node *refnode)
+{
+	struct node *wn, *nwn;	/* local fixup node, walk node, new */
+	uint32_t value_32;
+	char **compp;
+	int i, depth;
+
+	/* walk back retreiving depth */
+	depth = 0;
+	for (wn = node; wn; wn = wn->parent)
+		depth++;
+
+	/* allocate name array */
+	compp = xmalloc(sizeof(*compp) * depth);
+
+	/* store names in the array */
+	for (wn = node, i = depth - 1; wn; wn = wn->parent, i--)
+		compp[i] = wn->name;
+
+	/* walk the path components creating nodes if they don't exist */
+	for (wn = lfn, i = 1; i < depth; i++, wn = nwn) {
+		/* if no node exists, create it */
+		nwn = get_subnode(wn, compp[i]);
+		if (!nwn)
+			nwn = build_and_name_child_node(wn, compp[i]);
+	}
+
+	free(compp);
+
+	value_32 = cpu_to_fdt32(m->offset);
+	append_to_property(wn, prop->name, &value_32, sizeof(value_32));
+}
+
+static void generate_local_fixups_tree_internal(struct dt_info *dti,
+						struct node *lfn,
+						struct node *node)
+{
+	struct node *dt = dti->dt;
+	struct node *c;
+	struct property *prop;
+	struct marker *m;
+	struct node *refnode;
+
+	for_each_property(node, prop) {
+		m = prop->val.markers;
+		for_each_marker_of_type(m, REF_PHANDLE) {
+			refnode = get_node_by_ref(dt, m->ref);
+			if (refnode)
+				add_local_fixup_entry(dti, lfn, node, prop, m, refnode);
+		}
+	}
+
+	for_each_child(node, c)
+		generate_local_fixups_tree_internal(dti, lfn, c);
+}
+
+void generate_label_tree(struct dt_info *dti, char *name, bool allocph)
+{
+	if (!any_label_tree(dti, dti->dt))
+		return;
+	generate_label_tree_internal(dti, build_root_node(dti->dt, name),
+				     dti->dt, allocph);
+}
+
+void generate_fixups_tree(struct dt_info *dti, char *name)
+{
+	if (!any_fixup_tree(dti, dti->dt))
+		return;
+	generate_fixups_tree_internal(dti, build_root_node(dti->dt, name),
+				      dti->dt);
+}
+
+void generate_local_fixups_tree(struct dt_info *dti, char *name)
+{
+	if (!any_local_fixup_tree(dti, dti->dt))
+		return;
+	generate_local_fixups_tree_internal(dti, build_root_node(dti->dt, name),
+					    dti->dt);
 }
 }

+ 8 - 27
scripts/dtc/srcpos.c

@@ -246,46 +246,27 @@ srcpos_copy(struct srcpos *pos)
 	return pos_new;
 	return pos_new;
 }
 }
 
 
-
-
-void
-srcpos_dump(struct srcpos *pos)
-{
-	printf("file        : \"%s\"\n",
-	       pos->file ? (char *) pos->file : "<no file>");
-	printf("first_line  : %d\n", pos->first_line);
-	printf("first_column: %d\n", pos->first_column);
-	printf("last_line   : %d\n", pos->last_line);
-	printf("last_column : %d\n", pos->last_column);
-	printf("file        : %s\n", pos->file->name);
-}
-
-
 char *
 char *
 srcpos_string(struct srcpos *pos)
 srcpos_string(struct srcpos *pos)
 {
 {
 	const char *fname = "<no-file>";
 	const char *fname = "<no-file>";
 	char *pos_str;
 	char *pos_str;
-	int rc;
 
 
 	if (pos)
 	if (pos)
 		fname = pos->file->name;
 		fname = pos->file->name;
 
 
 
 
 	if (pos->first_line != pos->last_line)
 	if (pos->first_line != pos->last_line)
-		rc = asprintf(&pos_str, "%s:%d.%d-%d.%d", fname,
-			      pos->first_line, pos->first_column,
-			      pos->last_line, pos->last_column);
+		xasprintf(&pos_str, "%s:%d.%d-%d.%d", fname,
+			  pos->first_line, pos->first_column,
+			  pos->last_line, pos->last_column);
 	else if (pos->first_column != pos->last_column)
 	else if (pos->first_column != pos->last_column)
-		rc = asprintf(&pos_str, "%s:%d.%d-%d", fname,
-			      pos->first_line, pos->first_column,
-			      pos->last_column);
+		xasprintf(&pos_str, "%s:%d.%d-%d", fname,
+			  pos->first_line, pos->first_column,
+			  pos->last_column);
 	else
 	else
-		rc = asprintf(&pos_str, "%s:%d.%d", fname,
-			      pos->first_line, pos->first_column);
-
-	if (rc == -1)
-		die("Couldn't allocate in srcpos string");
+		xasprintf(&pos_str, "%s:%d.%d", fname,
+			  pos->first_line, pos->first_column);
 
 
 	return pos_str;
 	return pos_str;
 }
 }

+ 0 - 1
scripts/dtc/srcpos.h

@@ -105,7 +105,6 @@ extern struct srcpos srcpos_empty;
 extern void srcpos_update(struct srcpos *pos, const char *text, int len);
 extern void srcpos_update(struct srcpos *pos, const char *text, int len);
 extern struct srcpos *srcpos_copy(struct srcpos *pos);
 extern struct srcpos *srcpos_copy(struct srcpos *pos);
 extern char *srcpos_string(struct srcpos *pos);
 extern char *srcpos_string(struct srcpos *pos);
-extern void srcpos_dump(struct srcpos *pos);
 
 
 extern void srcpos_verror(struct srcpos *pos, const char *prefix,
 extern void srcpos_verror(struct srcpos *pos, const char *prefix,
 			  const char *fmt, va_list va)
 			  const char *fmt, va_list va)

+ 7 - 7
scripts/dtc/treesource.c

@@ -25,12 +25,12 @@ extern FILE *yyin;
 extern int yyparse(void);
 extern int yyparse(void);
 extern YYLTYPE yylloc;
 extern YYLTYPE yylloc;
 
 
-struct boot_info *the_boot_info;
+struct dt_info *parser_output;
 bool treesource_error;
 bool treesource_error;
 
 
-struct boot_info *dt_from_source(const char *fname)
+struct dt_info *dt_from_source(const char *fname)
 {
 {
-	the_boot_info = NULL;
+	parser_output = NULL;
 	treesource_error = false;
 	treesource_error = false;
 
 
 	srcfile_push(fname);
 	srcfile_push(fname);
@@ -43,7 +43,7 @@ struct boot_info *dt_from_source(const char *fname)
 	if (treesource_error)
 	if (treesource_error)
 		die("Syntax error parsing input tree\n");
 		die("Syntax error parsing input tree\n");
 
 
-	return the_boot_info;
+	return parser_output;
 }
 }
 
 
 static void write_prefix(FILE *f, int level)
 static void write_prefix(FILE *f, int level)
@@ -263,13 +263,13 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level)
 }
 }
 
 
 
 
-void dt_to_source(FILE *f, struct boot_info *bi)
+void dt_to_source(FILE *f, struct dt_info *dti)
 {
 {
 	struct reserve_info *re;
 	struct reserve_info *re;
 
 
 	fprintf(f, "/dts-v1/;\n\n");
 	fprintf(f, "/dts-v1/;\n\n");
 
 
-	for (re = bi->reservelist; re; re = re->next) {
+	for (re = dti->reservelist; re; re = re->next) {
 		struct label *l;
 		struct label *l;
 
 
 		for_each_label(re->labels, l)
 		for_each_label(re->labels, l)
@@ -279,6 +279,6 @@ void dt_to_source(FILE *f, struct boot_info *bi)
 			(unsigned long long)re->re.size);
 			(unsigned long long)re->re.size);
 	}
 	}
 
 
-	write_tree_source_node(f, bi->dt, 0);
+	write_tree_source_node(f, dti->dt, 0);
 }
 }
 
 

+ 30 - 0
scripts/dtc/util.c

@@ -46,6 +46,36 @@ char *xstrdup(const char *s)
 	return d;
 	return d;
 }
 }
 
 
+/* based in part from (3) vsnprintf */
+int xasprintf(char **strp, const char *fmt, ...)
+{
+	int n, size = 128;	/* start with 128 bytes */
+	char *p;
+	va_list ap;
+
+	/* initial pointer is NULL making the fist realloc to be malloc */
+	p = NULL;
+	while (1) {
+		p = xrealloc(p, size);
+
+		/* Try to print in the allocated space. */
+		va_start(ap, fmt);
+		n = vsnprintf(p, size, fmt, ap);
+		va_end(ap);
+
+		/* If that worked, return the string. */
+		if (n > -1 && n < size)
+			break;
+		/* Else try again with more space. */
+		if (n > -1)	/* glibc 2.1 */
+			size = n + 1; /* precisely what is needed */
+		else		/* glibc 2.0 */
+			size *= 2; /* twice the old size */
+	}
+	*strp = p;
+	return strlen(p);
+}
+
 char *join_path(const char *path, const char *name)
 char *join_path(const char *path, const char *name)
 {
 {
 	int lenp = strlen(path);
 	int lenp = strlen(path);

+ 1 - 0
scripts/dtc/util.h

@@ -59,6 +59,7 @@ static inline void *xrealloc(void *p, size_t len)
 }
 }
 
 
 extern char *xstrdup(const char *s);
 extern char *xstrdup(const char *s);
+extern int xasprintf(char **strp, const char *fmt, ...);
 extern char *join_path(const char *path, const char *name);
 extern char *join_path(const char *path, const char *name);
 
 
 /**
 /**

+ 1 - 1
scripts/dtc/version_gen.h

@@ -1 +1 @@
-#define DTC_VERSION "DTC 1.4.1-g53bf130b"
+#define DTC_VERSION "DTC 1.4.2-g0931cea3"