Commit be5165a5 authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents c1aac62f 4e29ccdb
...@@ -51,7 +51,7 @@ Required properties: ...@@ -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: ...@@ -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: ...@@ -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.
......
...@@ -117,7 +117,7 @@ ID Clock Peripheral ...@@ -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
......
...@@ -22,7 +22,7 @@ Required properties: ...@@ -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:
......
...@@ -33,7 +33,7 @@ Optional properties for dp-controller: ...@@ -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
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
......
...@@ -6,7 +6,7 @@ Required properties: ...@@ -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
......
...@@ -38,7 +38,7 @@ Optional Properties: ...@@ -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:
......
...@@ -83,7 +83,7 @@ in [2]. The following are properties specific to those nodes: ...@@ -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:
......
...@@ -9,7 +9,7 @@ Required properties: ...@@ -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
......
...@@ -64,7 +64,7 @@ Required properties: ...@@ -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.
......
...@@ -55,7 +55,7 @@ Required properties (DMA function blocks): ...@@ -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.
......
...@@ -108,7 +108,7 @@ Optional properties: ...@@ -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/
......
...@@ -10,7 +10,7 @@ Required properties: ...@@ -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"
......
...@@ -49,7 +49,7 @@ Required properties: ...@@ -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:
......
...@@ -12,7 +12,7 @@ Optional properties: ...@@ -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
......
...@@ -20,7 +20,7 @@ The device node can contain one 'port' child node with one child ...@@ -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
......
...@@ -21,7 +21,7 @@ The device node can contain one 'port' child node with one child ...@@ -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:
......
...@@ -35,7 +35,7 @@ Optional property for different chips: ...@@ -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)
......
...@@ -15,7 +15,7 @@ Required properties: ...@@ -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:
......
...@@ -36,15 +36,15 @@ conditions. ...@@ -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 may use a value of 2, where the second cell of the
an SMR mask to combine with the ID in the first cell. IOMMU specifier represents an SMR mask to combine with
Care must be taken to ensure the set of matched IDs the ID in the first cell. Care must be taken to ensure
does not result in conflicts. the set of matched IDs does not result in conflicts.
** System MMU optional properties: ** System MMU optional properties:
......
...@@ -122,8 +122,7 @@ Following are properties of regulator subnode. ...@@ -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 AS3722 supports the system power off by turning off all its rails.
is provided through pm_power_off.
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
......
...@@ -64,8 +64,8 @@ Required properties if child node exists: ...@@ -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 See Documentation/devicetree/bindings/usb/ehci-omap.txt and
omap3-ohci.txt Documentation/devicetree/bindings/usb/ohci-omap3.txt.
Example for OMAP4: Example for OMAP4:
......
...@@ -27,9 +27,7 @@ Optional properties (port): ...@@ -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, property, a single integer).
then fixed link is assumed, and the 'fixed-link' property is
mandatory.
Example: Example:
......
...@@ -32,17 +32,17 @@ PCI root complex ...@@ -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)
......
...@@ -2,12 +2,12 @@ Driver a GPIO line that can be used to turn the power off. ...@@ -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 install a handler to power off the system. If the optional properties
not found, the GPIO line will be driven in the inactive '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, When the power-off handler is called, the gpio is configured as an
and drive active, so triggering a level triggered power off 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: ...@@ -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.
......
...@@ -3,8 +3,7 @@ ...@@ -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 microcontroller to turn the power off.
pm_power_off which is called 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'.
......
...@@ -6,11 +6,13 @@ Required properties: ...@@ -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.
......
...@@ -5,7 +5,6 @@ Copyright (C) 2008 - 2014 Freescale Semiconductor Inc. ...@@ -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: ...@@ -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
......
...@@ -29,4 +29,3 @@ usbhsehci: ehci@4a064c00 { ...@@ -29,4 +29,3 @@ usbhsehci: ehci@4a064c00 {
&usbhsehci { &usbhsehci {
phys = <&hsusb1_phy 0 &hsusb3_phy>; phys = <&hsusb1_phy 0 &hsusb3_phy>;
}; };
...@@ -104,11 +104,13 @@ everest Everest Semiconductor Co. Ltd. ...@@ -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.
......
...@@ -843,8 +843,11 @@ struct device_node *of_find_node_opts_by_path(const char *path, const char **opt ...@@ -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) ...@@ -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);
...@@ -9,7 +9,7 @@ ...@@ -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>
......
...@@ -104,7 +104,7 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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)) if (WARN_ON(newaddrsize + newintsize > MAX_PHANDLE_ARGS)
goto fail; || (imaplen < (newaddrsize + newintsize))) {
if (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) ...@@ -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);
......
...@@ -93,7 +93,15 @@ int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq ...@@ -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);
......
...@@ -354,6 +354,10 @@ int of_reserved_mem_device_init_by_idx(struct device *dev, ...@@ -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 {
......
...@@ -18,7 +18,6 @@ ...@@ -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, ...@@ -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++;
......
...@@ -76,7 +76,7 @@ EXPORT_SYMBOL(of_find_device_by_node); ...@@ -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;
......
...@@ -18,7 +18,6 @@ ...@@ -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) */
......
...@@ -17,7 +17,6 @@ ...@@ -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) ...@@ -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) ...@@ -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;
......
...@@ -13,7 +13,6 @@ struct device; ...@@ -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.
......
...@@ -51,6 +51,8 @@ struct device_node *of_graph_get_endpoint_by_regs( ...@@ -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( ...@@ -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 */
......
This diff is collapsed.
...@@ -121,6 +121,11 @@ static void lexical_error(const char *fmt, ...); ...@@ -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, ...); ...@@ -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) if (d.len > 2)
lexical_error("Character literal has %d" lexical_error("Character literal has %d"
" characters instead of 1", " characters instead of 1",
d.len - 1); d.len - 1);
}
data_free(d);
return DT_CHAR_LITERAL; return DT_CHAR_LITERAL;
} }
......
This diff is collapsed.
This diff is collapsed.
/* 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; ...@@ -46,35 +46,36 @@ extern int yydebug;
enum yytokentype enum yytokentype
{ {
DT_V1 = 258, DT_V1 = 258,
DT_MEMRESERVE = 259, DT_PLUGIN = 259,
DT_LSHIFT = 260, DT_MEMRESERVE = 260,
DT_RSHIFT = 261, DT_LSHIFT = 261,
DT_LE = 262, DT_RSHIFT = 262,
DT_GE = 263, DT_LE = 263,
DT_EQ = 264, DT_GE = 264,
DT_NE = 265, DT_EQ = 265,
DT_AND = 266, DT_NE = 266,
DT_OR = 267, DT_AND = 267,
DT_BITS = 268, DT_OR = 268,
DT_DEL_PROP = 269, DT_BITS = 269,
DT_DEL_NODE = 270, DT_DEL_PROP = 270,
DT_PROPNODENAME = 271, DT_DEL_NODE = 271,
DT_LITERAL = 272, DT_PROPNODENAME = 272,
DT_CHAR_LITERAL = 273, DT_LITERAL = 273,
DT_BYTE = 274, DT_CHAR_LITERAL = 274,
DT_STRING = 275, DT_BYTE = 275,
DT_LABEL = 276, DT_STRING = 276,
DT_REF = 277, DT_LABEL = 277,
DT_INCBIN = 278 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 ...@@ -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
......
...@@ -19,6 +19,7 @@ ...@@ -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); ...@@ -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; ...@@ -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; ...@@ -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; ...@@ -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, parser_output = build_dt_info($1, $2, $3,
guess_boot_cpuid($4)); 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;
} }
; ;
......
...@@ -30,7 +30,16 @@ int quiet; /* Level of quietness */ ...@@ -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) ...@@ -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[] = { ...@@ -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[] = { ...@@ -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[] = { ...@@ -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[] = { ...@@ -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) ...@@ -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[]) ...@@ -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[]) ...@@ -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[]) ...@@ -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[]) ...@@ -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[]) ...@@ -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, ""); if (auto_label_aliases)
process_checks(force, bi); 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[]) ...@@ -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 {
......
...@@ -53,7 +53,11 @@ extern int quiet; /* Level of quietness */ ...@@ -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); ...@@ -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, ...@@ -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, /* 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); struct node *tree, uint32_t boot_cpuid_phys);
void sort_tree(struct boot_info *bi); 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_blob(FILE *f, struct dt_info *dti, int version);
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 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); void dt_to_source(FILE *f, struct dt_info *dti);
struct boot_info *dt_from_source(const char *f); 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 */
...@@ -366,7 +366,7 @@ static void make_fdt_header(struct fdt_header *fdt, ...@@ -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) ...@@ -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)) if (padlen < 0) {
padlen = 0;
if (quiet < 1)
fprintf(stderr, fprintf(stderr,
"Warning: blob size %d >= minimum size %d\n", "Warning: blob size %d >= minimum size %d\n",
fdt32_to_cpu(fdt.totalsize), minsize); 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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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);
} }
...@@ -79,13 +79,12 @@ static struct node *read_fstree(const char *dirname) ...@@ -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));
} }
...@@ -7,5 +7,5 @@ LIBFDT_soname = libfdt.$(SHAREDLIB_EXT).1 ...@@ -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)
...@@ -88,6 +88,32 @@ static int _fdt_string_eq(const void *fdt, int stroffset, ...@@ -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) ...@@ -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, ...@@ -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;
......
...@@ -191,17 +191,13 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) ...@@ -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); return _fdt_splice_mem_rsv(fdt, re, 1, 0);
if (err)
return err;
return 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,
......
...@@ -69,6 +69,7 @@ static struct fdt_errtabent fdt_errtable[] = { ...@@ -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[] = { ...@@ -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]))
......
...@@ -55,21 +55,42 @@ ...@@ -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 fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,
return 0; strlen(name), 0,
val, len);
} }
static void _fdt_nop_region(void *start, int len) static void _fdt_nop_region(void *start, int len)
......
This diff is collapsed.
...@@ -54,6 +54,7 @@ ...@@ -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__
......
...@@ -204,7 +204,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node) ...@@ -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) ...@@ -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, ...@@ -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 dt_info *build_dt_info(unsigned int dtsflags,
struct reserve_info *reservelist,
struct node *tree, uint32_t boot_cpuid_phys) struct node *tree, uint32_t boot_cpuid_phys)
{ {
struct boot_info *bi; struct dt_info *dti;
bi = xmalloc(sizeof(*bi)); dti = xmalloc(sizeof(*dti));
bi->reservelist = reservelist; dti->dtsflags = dtsflags;
bi->dt = tree; dti->reservelist = reservelist;
bi->boot_cpuid_phys = boot_cpuid_phys; 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) ...@@ -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) ...@@ -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) ...@@ -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); char *entry;
sort_node(bi->dt);
/* 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);
} }
...@@ -246,47 +246,28 @@ srcpos_copy(struct srcpos *pos) ...@@ -246,47 +246,28 @@ 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, xasprintf(&pos_str, "%s:%d.%d-%d.%d", fname,
pos->first_line, pos->first_column, pos->first_line, pos->first_column,
pos->last_line, pos->last_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, xasprintf(&pos_str, "%s:%d.%d-%d", fname,
pos->first_line, pos->first_column, pos->first_line, pos->first_column,
pos->last_column); pos->last_column);
else else
rc = asprintf(&pos_str, "%s:%d.%d", fname, xasprintf(&pos_str, "%s:%d.%d", fname,
pos->first_line, pos->first_column); pos->first_line, pos->first_column);
if (rc == -1)
die("Couldn't allocate in srcpos string");
return pos_str; return pos_str;
} }
......
...@@ -105,7 +105,6 @@ extern struct srcpos srcpos_empty; ...@@ -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)
......
...@@ -25,12 +25,12 @@ extern FILE *yyin; ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
} }
This diff is collapsed.
...@@ -59,6 +59,7 @@ static inline void *xrealloc(void *p, size_t len) ...@@ -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);
/** /**
......
#define DTC_VERSION "DTC 1.4.1-g53bf130b" #define DTC_VERSION "DTC 1.4.2-g0931cea3"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment