summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/samsung/pmu.txt2
-rw-r--r--Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt2
-rw-r--r--Documentation/devicetree/bindings/arm/sp810.txt2
-rw-r--r--Documentation/devicetree/bindings/arm/vexpress-sysreg.txt2
-rw-r--r--Documentation/devicetree/bindings/ata/ahci-platform.txt2
-rw-r--r--Documentation/devicetree/bindings/ata/imx-sata.txt2
-rw-r--r--Documentation/devicetree/bindings/bus/imx-weim.txt2
-rw-r--r--Documentation/devicetree/bindings/bus/sunxi-rsb.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/arm-syscon-icst.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/clk-exynos-audss.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/dove-divider-clock.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/imx1-clock.txt4
-rw-r--r--Documentation/devicetree/bindings/clock/imx6q-clock.txt4
-rw-r--r--Documentation/devicetree/bindings/clock/maxim,max77686.txt4
-rw-r--r--Documentation/devicetree/bindings/clock/st/st,clkgen.txt2
-rw-r--r--Documentation/devicetree/bindings/clock/sunxi-ccu.txt4
-rw-r--r--Documentation/devicetree/bindings/clock/sunxi.txt16
-rw-r--r--Documentation/devicetree/bindings/clock/ti,cdce706.txt2
-rw-r--r--Documentation/devicetree/bindings/crypto/sun4i-ss.txt2
-rw-r--r--Documentation/devicetree/bindings/display/etnaviv/etnaviv-drm.txt2
-rw-r--r--Documentation/devicetree/bindings/display/imx/hdmi.txt4
-rw-r--r--Documentation/devicetree/bindings/display/simple-framebuffer.txt2
-rw-r--r--Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt4
-rw-r--r--Documentation/devicetree/bindings/dma/sun4i-dma.txt4
-rw-r--r--Documentation/devicetree/bindings/dma/sun6i-dma.txt2
-rw-r--r--Documentation/devicetree/bindings/dma/ti-edma.txt6
-rw-r--r--Documentation/devicetree/bindings/dma/zxdma.txt2
-rw-r--r--Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt2
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-dsp-keystone.txt2
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-tz1090-pdc.txt2
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-tz1090.txt2
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-axxia.txt2
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-sunxi-p2wi.txt2
-rw-r--r--Documentation/devicetree/bindings/iio/magnetometer/ak8974.txt2
-rw-r--r--Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt2
-rw-r--r--Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt2
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt2
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt2
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-nmi.txt2
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/ti,keystone-irq.txt2
-rw-r--r--Documentation/devicetree/bindings/iommu/qcom,iommu.txt2
-rw-r--r--Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt2
-rw-r--r--Documentation/devicetree/bindings/leds/register-bit-led.txt16
-rw-r--r--Documentation/devicetree/bindings/mailbox/ti,message-manager.txt2
-rw-r--r--Documentation/devicetree/bindings/marvell.txt4
-rw-r--r--Documentation/devicetree/bindings/media/i2c/tc358743.txt2
-rw-r--r--Documentation/devicetree/bindings/media/img-ir-rev1.txt2
-rw-r--r--Documentation/devicetree/bindings/media/renesas,vsp1.txt2
-rw-r--r--Documentation/devicetree/bindings/media/stih-cec.txt2
-rw-r--r--Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt2
-rw-r--r--Documentation/devicetree/bindings/media/sunxi-ir.txt2
-rw-r--r--Documentation/devicetree/bindings/mfd/max77686.txt2
-rw-r--r--Documentation/devicetree/bindings/mfd/max77802.txt2
-rw-r--r--Documentation/devicetree/bindings/mfd/mfd.txt2
-rw-r--r--Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt4
-rw-r--r--Documentation/devicetree/bindings/mfd/sun6i-prcm.txt2
-rw-r--r--Documentation/devicetree/bindings/mfd/syscon.txt2
-rw-r--r--Documentation/devicetree/bindings/mmc/mmc.txt2
-rw-r--r--Documentation/devicetree/bindings/mmc/sdhci-st.txt4
-rw-r--r--Documentation/devicetree/bindings/mmc/sunxi-mmc.txt4
-rw-r--r--Documentation/devicetree/bindings/mtd/sunxi-nand.txt2
-rw-r--r--Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt2
-rw-r--r--Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt4
-rw-r--r--Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.txt2
-rw-r--r--Documentation/devicetree/bindings/net/brcm,bcmgenet.txt2
-rw-r--r--Documentation/devicetree/bindings/net/can/m_can.txt2
-rw-r--r--Documentation/devicetree/bindings/net/can/sun4i_can.txt4
-rw-r--r--Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt2
-rw-r--r--Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt4
-rw-r--r--Documentation/devicetree/bindings/nvmem/brcm,ocotp.txt2
-rw-r--r--Documentation/devicetree/bindings/nvmem/imx-ocotp.txt2
-rw-r--r--Documentation/devicetree/bindings/nvmem/nvmem.txt2
-rw-r--r--Documentation/devicetree/bindings/nvmem/qfprom.txt2
-rw-r--r--Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt12
-rw-r--r--Documentation/devicetree/bindings/phy/brcm,cygnus-pcie-phy.txt2
-rw-r--r--Documentation/devicetree/bindings/phy/mxs-usb-phy.txt2
-rw-r--r--Documentation/devicetree/bindings/phy/sun9i-usb-phy.txt2
-rw-r--r--Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt2
-rw-r--r--Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt4
-rw-r--r--Documentation/devicetree/bindings/pinctrl/img,tz1090-pdc-pinctrl.txt4
-rw-r--r--Documentation/devicetree/bindings/pinctrl/img,tz1090-pinctrl.txt4
-rw-r--r--Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-xusb-padctl.txt2
-rw-r--r--Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt2
-rw-r--r--Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt2
-rw-r--r--Documentation/devicetree/bindings/pinctrl/qcom,msm8996-pinctrl.txt2
-rw-r--r--Documentation/devicetree/bindings/power/fsl,imx-gpc.txt4
-rw-r--r--Documentation/devicetree/bindings/power/reset/imx-snvs-poweroff.txt2
-rw-r--r--Documentation/devicetree/bindings/power/reset/keystone-reset.txt4
-rw-r--r--Documentation/devicetree/bindings/powerpc/fsl/mcu-mpc8349emitx.txt2
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-sun4i.txt2
-rw-r--r--Documentation/devicetree/bindings/regulator/max77686.txt2
-rw-r--r--Documentation/devicetree/bindings/regulator/max77802.txt2
-rw-r--r--Documentation/devicetree/bindings/reset/allwinner,sunxi-clock-reset.txt2
-rw-r--r--Documentation/devicetree/bindings/reset/fsl,imx-src.txt6
-rw-r--r--Documentation/devicetree/bindings/reset/ti-syscon-reset.txt2
-rw-r--r--Documentation/devicetree/bindings/rtc/dallas,ds1339.txt18
-rw-r--r--Documentation/devicetree/bindings/rtc/rtc-ds1307.txt44
-rw-r--r--Documentation/devicetree/bindings/rtc/rtc-m41t80.txt31
-rw-r--r--Documentation/devicetree/bindings/rtc/sirf,prima2-sysrtc.txt13
-rw-r--r--Documentation/devicetree/bindings/rtc/stericsson,coh901331.txt17
-rw-r--r--Documentation/devicetree/bindings/rtc/sun6i-rtc.txt2
-rw-r--r--Documentation/devicetree/bindings/rtc/sunxi-rtc.txt2
-rw-r--r--Documentation/devicetree/bindings/soc/fsl/cpm_qe/qe/par_io.txt2
-rw-r--r--Documentation/devicetree/bindings/soc/fsl/cpm_qe/qe/pincfg.txt2
-rw-r--r--Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/cdns,xtfpga-i2s.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,asrc.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,esai.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/fsl,spdif.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/imx-audmux.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/samsung-i2s.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/sun4i-codec.txt4
-rw-r--r--Documentation/devicetree/bindings/sound/sun4i-i2s.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt2
-rw-r--r--Documentation/devicetree/bindings/sound/zte,zx-spdif.txt2
-rw-r--r--Documentation/devicetree/bindings/spi/spi-sun4i.txt2
-rw-r--r--Documentation/devicetree/bindings/spi/spi-sun6i.txt4
-rw-r--r--Documentation/devicetree/bindings/sram/samsung-sram.txt2
-rw-r--r--Documentation/devicetree/bindings/sram/sunxi-sram.txt4
-rw-r--r--Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt2
-rw-r--r--Documentation/devicetree/bindings/trivial-devices.txt13
-rw-r--r--Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt2
-rw-r--r--Documentation/devicetree/bindings/usb/am33xx-usb.txt2
-rw-r--r--Documentation/devicetree/bindings/usb/atmel-usb.txt4
-rw-r--r--Documentation/devicetree/bindings/usb/ohci-da8xx.txt2
-rw-r--r--Documentation/devicetree/bindings/usb/usb-ehci.txt2
-rw-r--r--Documentation/devicetree/bindings/usb/usb-ohci.txt2
-rw-r--r--Documentation/devicetree/bindings/usb/usb3503.txt2
-rw-r--r--Documentation/devicetree/bindings/usb/usbmisc-imx.txt2
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt7
-rw-r--r--Documentation/devicetree/bindings/watchdog/mtk-wdt.txt2
-rw-r--r--Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt2
-rw-r--r--Documentation/devicetree/overlay-notes.txt12
-rw-r--r--arch/powerpc/platforms/pseries/dlpar.c24
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c2
-rw-r--r--drivers/base/core.c2
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c14
-rw-r--r--drivers/of/Kconfig4
-rw-r--r--drivers/of/Makefile1
-rw-r--r--drivers/of/base.c135
-rw-r--r--drivers/of/dynamic.c190
-rw-r--r--drivers/of/fdt.c91
-rw-r--r--drivers/of/kobj.c164
-rw-r--r--drivers/of/of_private.h51
-rw-r--r--drivers/of/overlay.c1049
-rw-r--r--drivers/of/resolver.c15
-rw-r--r--drivers/of/unittest.c83
-rw-r--r--include/linux/of.h45
-rw-r--r--scripts/dtc/checks.c291
-rw-r--r--scripts/dtc/dtc-lexer.lex.c_shipped10
-rw-r--r--scripts/dtc/dtc-parser.tab.c_shipped430
-rw-r--r--scripts/dtc/dtc-parser.y20
-rw-r--r--scripts/dtc/dtc.c2
-rw-r--r--scripts/dtc/dtc.h3
-rw-r--r--scripts/dtc/libfdt/fdt_addresses.c96
-rw-r--r--scripts/dtc/libfdt/fdt_empty_tree.c1
-rw-r--r--scripts/dtc/libfdt/fdt_overlay.c861
-rw-r--r--scripts/dtc/libfdt/fdt_ro.c4
-rw-r--r--scripts/dtc/libfdt/fdt_rw.c24
-rw-r--r--scripts/dtc/libfdt/fdt_sw.c16
-rw-r--r--scripts/dtc/libfdt/fdt_wip.c4
-rw-r--r--scripts/dtc/libfdt/libfdt.h47
-rw-r--r--scripts/dtc/livetree.c31
-rwxr-xr-xscripts/dtc/update-dtc-source.sh4
-rw-r--r--scripts/dtc/version_gen.h2
168 files changed, 3055 insertions, 1164 deletions
diff --git a/Documentation/devicetree/bindings/arm/samsung/pmu.txt b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
index bf5fc59a6938..088584a98cf4 100644
--- a/Documentation/devicetree/bindings/arm/samsung/pmu.txt
+++ b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
@@ -62,7 +62,7 @@ pmu_system_controller: system-controller@10040000 {
Example of clock consumer :
-usb3503: usb3503@08 {
+usb3503: usb3503@8 {
/* ... */
clock-names = "refclk";
clocks = <&pmu_system_controller 0>;
diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt
index 3c551894f621..fa674818e7e8 100644
--- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt
+++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt
@@ -71,7 +71,7 @@ Optional nodes:
- compatible: only "samsung,secure-firmware" is currently supported
- reg: address of non-secure SYSRAM used for communication with firmware
- firmware@0203F000 {
+ firmware@203F000 {
compatible = "samsung,secure-firmware";
reg = <0x0203F000 0x1000>;
};
diff --git a/Documentation/devicetree/bindings/arm/sp810.txt b/Documentation/devicetree/bindings/arm/sp810.txt
index 6808fb5dee40..1b2ab1ff5587 100644
--- a/Documentation/devicetree/bindings/arm/sp810.txt
+++ b/Documentation/devicetree/bindings/arm/sp810.txt
@@ -33,7 +33,7 @@ Required properties:
property with the highest frequency
Example:
- v2m_sysctl: sysctl@020000 {
+ v2m_sysctl: sysctl@20000 {
compatible = "arm,sp810", "arm,primecell";
reg = <0x020000 0x1000>;
clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
diff --git a/Documentation/devicetree/bindings/arm/vexpress-sysreg.txt b/Documentation/devicetree/bindings/arm/vexpress-sysreg.txt
index 00318d083c9e..50095802fb4a 100644
--- a/Documentation/devicetree/bindings/arm/vexpress-sysreg.txt
+++ b/Documentation/devicetree/bindings/arm/vexpress-sysreg.txt
@@ -37,7 +37,7 @@ Example:
compatible = "arm,vexpress-sysreg";
reg = <0x10000000 0x1000>;
- v2m_led_gpios: sys_led@08 {
+ v2m_led_gpios: sys_led@8 {
compatible = "arm,vexpress-sysreg,sys_led";
gpio-controller;
#gpio-cells = <2>;
diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
index fedc213b5f1a..c760ecb81381 100644
--- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
@@ -56,7 +56,7 @@ Examples:
interrupts = <115>;
};
- ahci: sata@01c18000 {
+ ahci: sata@1c18000 {
compatible = "allwinner,sun4i-a10-ahci";
reg = <0x01c18000 0x1000>;
interrupts = <56>;
diff --git a/Documentation/devicetree/bindings/ata/imx-sata.txt b/Documentation/devicetree/bindings/ata/imx-sata.txt
index fa511db18408..a3d14719e478 100644
--- a/Documentation/devicetree/bindings/ata/imx-sata.txt
+++ b/Documentation/devicetree/bindings/ata/imx-sata.txt
@@ -25,7 +25,7 @@ Optional properties:
Examples:
-sata@02200000 {
+sata@2200000 {
compatible = "fsl,imx6q-ahci";
reg = <0x02200000 0x4000>;
interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/Documentation/devicetree/bindings/bus/imx-weim.txt b/Documentation/devicetree/bindings/bus/imx-weim.txt
index 6630d842c7a3..683eaf3aed79 100644
--- a/Documentation/devicetree/bindings/bus/imx-weim.txt
+++ b/Documentation/devicetree/bindings/bus/imx-weim.txt
@@ -61,7 +61,7 @@ Timing property for child nodes. It is mandatory, not optional.
Example for an imx6q-sabreauto board, the NOR flash connected to the WEIM:
- weim: weim@021b8000 {
+ weim: weim@21b8000 {
compatible = "fsl,imx6q-weim";
reg = <0x021b8000 0x4000>;
clocks = <&clks 196>;
diff --git a/Documentation/devicetree/bindings/bus/sunxi-rsb.txt b/Documentation/devicetree/bindings/bus/sunxi-rsb.txt
index 3dd28343b6ce..eb3ed628c6f1 100644
--- a/Documentation/devicetree/bindings/bus/sunxi-rsb.txt
+++ b/Documentation/devicetree/bindings/bus/sunxi-rsb.txt
@@ -28,7 +28,7 @@ which can normally be found in the datasheet.
Example:
- rsb@01f03400 {
+ rsb@1f03400 {
compatible = "allwinner,sun8i-a23-rsb";
reg = <0x01f03400 0x400>;
interrupts = <0 39 4>;
diff --git a/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt b/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt
index 27468119fd94..4cd81742038f 100644
--- a/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt
+++ b/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt
@@ -59,7 +59,7 @@ syscon: syscon@10000000 {
compatible = "syscon";
reg = <0x10000000 0x1000>;
- oscclk0: osc0@0c {
+ oscclk0: osc0@c {
compatible = "arm,syscon-icst307";
#clock-cells = <0>;
lock-offset = <0x20>;
diff --git a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt b/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
index 0c3d6015868d..2cba012f5af0 100644
--- a/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
+++ b/Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
@@ -80,7 +80,7 @@ Example 3: I2S controller node that consumes the clock generated by the clock
controller. Refer to the standard clock bindings for information
about 'clocks' and 'clock-names' property.
-i2s0: i2s@03830000 {
+i2s0: i2s@3830000 {
compatible = "samsung,i2s-v5";
reg = <0x03830000 0x100>;
dmas = <&pdma0 10
diff --git a/Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt b/Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
index 4fc869b69d4a..f6272dcd96f4 100644
--- a/Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
+++ b/Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
@@ -43,7 +43,7 @@ Example: I2S controller node that consumes the clock generated by the clock
controller. Refer to the standard clock bindings for information
about 'clocks' and 'clock-names' property.
- i2s0: i2s@03830000 {
+ i2s0: i2s@3830000 {
/* ... */
clock-names = "iis", "i2s_opclk0",
"i2s_opclk1";
diff --git a/Documentation/devicetree/bindings/clock/dove-divider-clock.txt b/Documentation/devicetree/bindings/clock/dove-divider-clock.txt
index e3eb0f657c5e..217871f483c0 100644
--- a/Documentation/devicetree/bindings/clock/dove-divider-clock.txt
+++ b/Documentation/devicetree/bindings/clock/dove-divider-clock.txt
@@ -21,7 +21,7 @@ Required properties:
a size of 8.
- #clock-cells : from common clock binding; shall be set to 1
-divider_clk: core-clock@0064 {
+divider_clk: core-clock@64 {
compatible = "marvell,dove-divider-clock";
reg = <0x0064 0x8>;
#clock-cells = <1>;
diff --git a/Documentation/devicetree/bindings/clock/imx1-clock.txt b/Documentation/devicetree/bindings/clock/imx1-clock.txt
index b7adf4e3ea98..9823baf7acb6 100644
--- a/Documentation/devicetree/bindings/clock/imx1-clock.txt
+++ b/Documentation/devicetree/bindings/clock/imx1-clock.txt
@@ -10,13 +10,13 @@ ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx1-clock.h
for the full list of i.MX1 clock IDs.
Examples:
- clks: ccm@0021b000 {
+ clks: ccm@21b000 {
#clock-cells = <1>;
compatible = "fsl,imx1-ccm";
reg = <0x0021b000 0x1000>;
};
- pwm: pwm@00208000 {
+ pwm: pwm@208000 {
#pwm-cells = <2>;
compatible = "fsl,imx1-pwm";
reg = <0x00208000 0x1000>;
diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/Documentation/devicetree/bindings/clock/imx6q-clock.txt
index aa0a4d423ef5..a45ca67a9d5f 100644
--- a/Documentation/devicetree/bindings/clock/imx6q-clock.txt
+++ b/Documentation/devicetree/bindings/clock/imx6q-clock.txt
@@ -14,14 +14,14 @@ Examples:
#include <dt-bindings/clock/imx6qdl-clock.h>
-clks: ccm@020c4000 {
+clks: ccm@20c4000 {
compatible = "fsl,imx6q-ccm";
reg = <0x020c4000 0x4000>;
interrupts = <0 87 0x04 0 88 0x04>;
#clock-cells = <1>;
};
-uart1: serial@02020000 {
+uart1: serial@2020000 {
compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x02020000 0x4000>;
interrupts = <0 26 0x04>;
diff --git a/Documentation/devicetree/bindings/clock/maxim,max77686.txt b/Documentation/devicetree/bindings/clock/maxim,max77686.txt
index 8398a3a5e106..3472b461ca93 100644
--- a/Documentation/devicetree/bindings/clock/maxim,max77686.txt
+++ b/Documentation/devicetree/bindings/clock/maxim,max77686.txt
@@ -46,7 +46,7 @@ Example:
/* ... */
Node of the MFD chip
- max77686: max77686@09 {
+ max77686: max77686@9 {
compatible = "maxim,max77686";
interrupt-parent = <&wakeup_eint>;
interrupts = <26 0>;
@@ -71,7 +71,7 @@ Example:
/* ... */
Node of the MFD chip
- max77802: max77802@09 {
+ max77802: max77802@9 {
compatible = "maxim,max77802";
interrupt-parent = <&wakeup_eint>;
interrupts = <26 0>;
diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen.txt
index c35390f60545..7364953d0d0b 100644
--- a/Documentation/devicetree/bindings/clock/st/st,clkgen.txt
+++ b/Documentation/devicetree/bindings/clock/st/st,clkgen.txt
@@ -42,7 +42,7 @@ Required properties:
Example:
- clockgen-a@090ff000 {
+ clockgen-a@90ff000 {
compatible = "st,clkgen-c32";
reg = <0x90ff000 0x1000>;
diff --git a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
index 7eda08eb8a1e..4ca21c3a6fc9 100644
--- a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
@@ -36,7 +36,7 @@ For the PRCM CCUs on A83T/H3/A64, two more clocks are needed:
- "iosc": the SoC's internal frequency oscillator
Example for generic CCU:
-ccu: clock@01c20000 {
+ccu: clock@1c20000 {
compatible = "allwinner,sun8i-h3-ccu";
reg = <0x01c20000 0x400>;
clocks = <&osc24M>, <&osc32k>;
@@ -46,7 +46,7 @@ ccu: clock@01c20000 {
};
Example for PRCM CCU:
-r_ccu: clock@01f01400 {
+r_ccu: clock@1f01400 {
compatible = "allwinner,sun50i-a64-r-ccu";
reg = <0x01f01400 0x100>;
clocks = <&osc24M>, <&osc32k>, <&iosc>, <&ccu CLK_PLL_PERIPH0>;
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
index 8f7619d8c8d8..1a042e20b115 100644
--- a/Documentation/devicetree/bindings/clock/sunxi.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi.txt
@@ -137,7 +137,7 @@ the address block, which is related to the overall mmc block.
For example:
-osc24M: clk@01c20050 {
+osc24M: clk@1c20050 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-osc-clk";
reg = <0x01c20050 0x4>;
@@ -145,7 +145,7 @@ osc24M: clk@01c20050 {
clock-output-names = "osc24M";
};
-pll1: clk@01c20000 {
+pll1: clk@1c20000 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-pll1-clk";
reg = <0x01c20000 0x4>;
@@ -153,7 +153,7 @@ pll1: clk@01c20000 {
clock-output-names = "pll1";
};
-pll5: clk@01c20020 {
+pll5: clk@1c20020 {
#clock-cells = <1>;
compatible = "allwinner,sun4i-pll5-clk";
reg = <0x01c20020 0x4>;
@@ -161,7 +161,7 @@ pll5: clk@01c20020 {
clock-output-names = "pll5_ddr", "pll5_other";
};
-pll6: clk@01c20028 {
+pll6: clk@1c20028 {
#clock-cells = <1>;
compatible = "allwinner,sun6i-a31-pll6-clk";
reg = <0x01c20028 0x4>;
@@ -169,7 +169,7 @@ pll6: clk@01c20028 {
clock-output-names = "pll6", "pll6x2";
};
-cpu: cpu@01c20054 {
+cpu: cpu@1c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-cpu-clk";
reg = <0x01c20054 0x4>;
@@ -177,7 +177,7 @@ cpu: cpu@01c20054 {
clock-output-names = "cpu";
};
-mmc0_clk: clk@01c20088 {
+mmc0_clk: clk@1c20088 {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20088 0x4>;
@@ -199,7 +199,7 @@ gmac_int_tx_clk: clk@3 {
clock-output-names = "gmac_int_tx";
};
-gmac_clk: clk@01c20164 {
+gmac_clk: clk@1c20164 {
#clock-cells = <0>;
compatible = "allwinner,sun7i-a20-gmac-clk";
reg = <0x01c20164 0x4>;
@@ -211,7 +211,7 @@ gmac_clk: clk@01c20164 {
clock-output-names = "gmac";
};
-mmc_config_clk: clk@01c13000 {
+mmc_config_clk: clk@1c13000 {
compatible = "allwinner,sun9i-a80-mmc-config-clk";
reg = <0x01c13000 0x10>;
clocks = <&ahb0_gates 8>;
diff --git a/Documentation/devicetree/bindings/clock/ti,cdce706.txt b/Documentation/devicetree/bindings/clock/ti,cdce706.txt
index 616836e7e1e2..959d96632f5d 100644
--- a/Documentation/devicetree/bindings/clock/ti,cdce706.txt
+++ b/Documentation/devicetree/bindings/clock/ti,cdce706.txt
@@ -25,7 +25,7 @@ Example:
};
};
...
- i2c0: i2c-master@0d090000 {
+ i2c0: i2c-master@d090000 {
...
cdce706: clock-synth@69 {
compatible = "ti,cdce706";
diff --git a/Documentation/devicetree/bindings/crypto/sun4i-ss.txt b/Documentation/devicetree/bindings/crypto/sun4i-ss.txt
index 5d38e9b7033f..f2dc3d9bca92 100644
--- a/Documentation/devicetree/bindings/crypto/sun4i-ss.txt
+++ b/Documentation/devicetree/bindings/crypto/sun4i-ss.txt
@@ -14,7 +14,7 @@ Optional properties:
- reset-names : must contain "ahb"
Example:
- crypto: crypto-engine@01c15000 {
+ crypto: crypto-engine@1c15000 {
compatible = "allwinner,sun4i-a10-crypto";
reg = <0x01c15000 0x1000>;
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/Documentation/devicetree/bindings/display/etnaviv/etnaviv-drm.txt b/Documentation/devicetree/bindings/display/etnaviv/etnaviv-drm.txt
index ed5e0a7894ad..05176f1ae108 100644
--- a/Documentation/devicetree/bindings/display/etnaviv/etnaviv-drm.txt
+++ b/Documentation/devicetree/bindings/display/etnaviv/etnaviv-drm.txt
@@ -42,7 +42,7 @@ Optional properties:
example:
-gpu_3d: gpu@00130000 {
+gpu_3d: gpu@130000 {
compatible = "vivante,gc";
reg = <0x00130000 0x4000>;
interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/Documentation/devicetree/bindings/display/imx/hdmi.txt b/Documentation/devicetree/bindings/display/imx/hdmi.txt
index 66a8f86e5d12..6d021e71c9cf 100644
--- a/Documentation/devicetree/bindings/display/imx/hdmi.txt
+++ b/Documentation/devicetree/bindings/display/imx/hdmi.txt
@@ -32,11 +32,11 @@ Optional properties
Example:
- gpr: iomuxc-gpr@020e0000 {
+ gpr: iomuxc-gpr@20e0000 {
/* ... */
};
- hdmi: hdmi@0120000 {
+ hdmi: hdmi@120000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-hdmi";
diff --git a/Documentation/devicetree/bindings/display/simple-framebuffer.txt b/Documentation/devicetree/bindings/display/simple-framebuffer.txt
index 8c9e9f515c87..5a9ce511be88 100644
--- a/Documentation/devicetree/bindings/display/simple-framebuffer.txt
+++ b/Documentation/devicetree/bindings/display/simple-framebuffer.txt
@@ -78,7 +78,7 @@ chosen {
stdout-path = "display0";
};
-soc@01c00000 {
+soc@1c00000 {
lcdc0: lcdc@1c0c000 {
compatible = "allwinner,sun4i-a10-lcdc";
...
diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
index 92441086caba..b7faa6f6a326 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -266,7 +266,7 @@ connector {
};
};
-hdmi: hdmi@01c16000 {
+hdmi: hdmi@1c16000 {
compatible = "allwinner,sun5i-a10s-hdmi";
reg = <0x01c16000 0x1000>;
interrupts = <58>;
@@ -305,7 +305,7 @@ hdmi: hdmi@01c16000 {
};
};
-tve0: tv-encoder@01c0a000 {
+tve0: tv-encoder@1c0a000 {
compatible = "allwinner,sun4i-a10-tv-encoder";
reg = <0x01c0a000 0x1000>;
clocks = <&ahb_gates 34>;
diff --git a/Documentation/devicetree/bindings/dma/sun4i-dma.txt b/Documentation/devicetree/bindings/dma/sun4i-dma.txt
index 3b484380c56a..8ad556aca70b 100644
--- a/Documentation/devicetree/bindings/dma/sun4i-dma.txt
+++ b/Documentation/devicetree/bindings/dma/sun4i-dma.txt
@@ -12,7 +12,7 @@ Required properties:
second cell holding the request line number.
Example:
- dma: dma-controller@01c02000 {
+ dma: dma-controller@1c02000 {
compatible = "allwinner,sun4i-a10-dma";
reg = <0x01c02000 0x1000>;
interrupts = <27>;
@@ -32,7 +32,7 @@ The three cells in order are:
3. The port ID as specified in the datasheet
Example:
- spi2: spi@01c17000 {
+ spi2: spi@1c17000 {
compatible = "allwinner,sun4i-a10-spi";
reg = <0x01c17000 0x1000>;
interrupts = <0 12 4>;
diff --git a/Documentation/devicetree/bindings/dma/sun6i-dma.txt b/Documentation/devicetree/bindings/dma/sun6i-dma.txt
index 98fbe1a5c6dd..717851407fac 100644
--- a/Documentation/devicetree/bindings/dma/sun6i-dma.txt
+++ b/Documentation/devicetree/bindings/dma/sun6i-dma.txt
@@ -38,7 +38,7 @@ The two cells in order are:
2. The port ID as specified in the datasheet
Example:
-spi2: spi@01c6a000 {
+spi2: spi@1c6a000 {
compatible = "allwinner,sun6i-a31-spi";
reg = <0x01c6a000 0x1000>;
interrupts = <0 67 4>;
diff --git a/Documentation/devicetree/bindings/dma/ti-edma.txt b/Documentation/devicetree/bindings/dma/ti-edma.txt
index 41f0c1a07c56..66026dcf53e1 100644
--- a/Documentation/devicetree/bindings/dma/ti-edma.txt
+++ b/Documentation/devicetree/bindings/dma/ti-edma.txt
@@ -142,7 +142,7 @@ mcasp0: mcasp@48038000 {
};
2.
-edma1: edma@02728000 {
+edma1: edma@2728000 {
compatible = "ti,k2g-edma3-tpcc", "ti,edma3-tpcc";
reg = <0x02728000 0x8000>;
reg-names = "edma3_cc";
@@ -165,13 +165,13 @@ edma1: edma@02728000 {
power-domains = <&k2g_pds 0x4f>;
};
-edma1_tptc0: tptc@027b0000 {
+edma1_tptc0: tptc@27b0000 {
compatible = "ti,k2g-edma3-tptc", "ti,edma3-tptc";
reg = <0x027b0000 0x400>;
power-domains = <&k2g_pds 0x4f>;
};
-edma1_tptc1: tptc@027b8000 {
+edma1_tptc1: tptc@27b8000 {
compatible = "ti, k2g-edma3-tptc", "ti,edma3-tptc";
reg = <0x027b8000 0x400>;
power-domains = <&k2g_pds 0x4f>;
diff --git a/Documentation/devicetree/bindings/dma/zxdma.txt b/Documentation/devicetree/bindings/dma/zxdma.txt
index 3207ceb04d0b..abec59f35fde 100644
--- a/Documentation/devicetree/bindings/dma/zxdma.txt
+++ b/Documentation/devicetree/bindings/dma/zxdma.txt
@@ -26,7 +26,7 @@ Controller:
Client:
Use specific request line passing from dmax
For example, spdif0 tx channel request line is 4
- spdif0: spdif0@0b004000 {
+ spdif0: spdif0@b004000 {
#sound-dai-cells = <0>;
compatible = "zte,zx296702-spdif";
reg = <0x0b004000 0x1000>;
diff --git a/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
index e821e16ad65b..0c10802c8327 100644
--- a/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
+++ b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
@@ -66,7 +66,7 @@ See ".../sram/sram.txt" for the bindings.
Example:
-hsp_top0: hsp@03c00000 {
+hsp_top0: hsp@3c00000 {
...
#mbox-cells = <2>;
};
diff --git a/Documentation/devicetree/bindings/gpio/gpio-dsp-keystone.txt b/Documentation/devicetree/bindings/gpio/gpio-dsp-keystone.txt
index 6c7e6c7302f5..0423699d74c7 100644
--- a/Documentation/devicetree/bindings/gpio/gpio-dsp-keystone.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio-dsp-keystone.txt
@@ -25,7 +25,7 @@ Please refer to gpio.txt in this directory for details of the common GPIO
bindings used by client devices.
Example:
- dspgpio0: keystone_dsp_gpio@02620240 {
+ dspgpio0: keystone_dsp_gpio@2620240 {
compatible = "ti,keystone-dsp-gpio";
ti,syscon-dev = <&devctrl 0x240>;
gpio-controller;
diff --git a/Documentation/devicetree/bindings/gpio/gpio-tz1090-pdc.txt b/Documentation/devicetree/bindings/gpio/gpio-tz1090-pdc.txt
index 1fd98ffa8cb7..528f5ef5a893 100644
--- a/Documentation/devicetree/bindings/gpio/gpio-tz1090-pdc.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio-tz1090-pdc.txt
@@ -30,7 +30,7 @@ Optional properties:
Example:
- pdc_gpios: gpio-controller@02006500 {
+ pdc_gpios: gpio-controller@2006500 {
gpio-controller;
#gpio-cells = <2>;
diff --git a/Documentation/devicetree/bindings/gpio/gpio-tz1090.txt b/Documentation/devicetree/bindings/gpio/gpio-tz1090.txt
index 174cdf309170..b05a90e0ab29 100644
--- a/Documentation/devicetree/bindings/gpio/gpio-tz1090.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio-tz1090.txt
@@ -59,7 +59,7 @@ Required properties:
Example:
- gpios: gpio-controller@02005800 {
+ gpios: gpio-controller@2005800 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "img,tz1090-gpio";
diff --git a/Documentation/devicetree/bindings/i2c/i2c-axxia.txt b/Documentation/devicetree/bindings/i2c/i2c-axxia.txt
index 2296d782b4c2..7d53a2b79553 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-axxia.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-axxia.txt
@@ -17,7 +17,7 @@ Optional properties :
Example :
-i2c@02010084000 {
+i2c@2010084000 {
compatible = "lsi,api2c";
device_type = "i2c";
#address-cells = <1>;
diff --git a/Documentation/devicetree/bindings/i2c/i2c-sunxi-p2wi.txt b/Documentation/devicetree/bindings/i2c/i2c-sunxi-p2wi.txt
index 6b765485af7d..49df0053347a 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-sunxi-p2wi.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-sunxi-p2wi.txt
@@ -24,7 +24,7 @@ Slave device properties:
Example:
- p2wi@01f03400 {
+ p2wi@1f03400 {
compatible = "allwinner,sun6i-a31-p2wi";
reg = <0x01f03400 0x400>;
interrupts = <0 39 4>;
diff --git a/Documentation/devicetree/bindings/iio/magnetometer/ak8974.txt b/Documentation/devicetree/bindings/iio/magnetometer/ak8974.txt
index 77d5aba1bd8c..baecc4a85197 100644
--- a/Documentation/devicetree/bindings/iio/magnetometer/ak8974.txt
+++ b/Documentation/devicetree/bindings/iio/magnetometer/ak8974.txt
@@ -19,7 +19,7 @@ Optional properties:
Example:
-ak8974@0f {
+ak8974@f {
compatible = "asahi-kasei,ak8974";
reg = <0x0f>;
avdd-supply = <&foo_reg>;
diff --git a/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt b/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt
index e1e7dd3259f6..aa67ceb0d4e0 100644
--- a/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt
+++ b/Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt
@@ -13,7 +13,7 @@ Optional properties:
Example:
-ak8975@0c {
+ak8975@c {
compatible = "asahi-kasei,ak8975";
reg = <0x0c>;
gpios = <&gpj0 7 0>;
diff --git a/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
index 4357e498ef04..1458c3179a63 100644
--- a/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
+++ b/Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
@@ -19,7 +19,7 @@ Example:
#include <dt-bindings/input/input.h>
- lradc: lradc@01c22800 {
+ lradc: lradc@1c22800 {
compatible = "allwinner,sun4i-a10-lradc-keys";
reg = <0x01c22800 0x100>;
interrupts = <31>;
diff --git a/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt
index 49fa14ed155c..298e3442f143 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt
@@ -10,7 +10,7 @@ Required properties:
Example:
- egalax_ts@04 {
+ touchscreen@4 {
compatible = "eeti,egalax_ts";
reg = <0x04>;
interrupt-parent = <&gpio1>;
diff --git a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
index e67e58b61706..164915004424 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
@@ -21,7 +21,7 @@ Optional properties:
each read. Valid values are 1, 4, 8, 16 and 32.
Example:
- tsc: tsc@02040000 {
+ tsc: tsc@2040000 {
compatible = "fsl,imx6ul-tsc";
reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-nmi.txt b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-nmi.txt
index 4ae553eb333d..4903fb72d883 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-nmi.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-nmi.txt
@@ -20,7 +20,7 @@ Required properties:
Example:
-sc-nmi-intc@01c00030 {
+sc-nmi-intc@1c00030 {
compatible = "allwinner,sun7i-a20-sc-nmi";
interrupt-controller;
#interrupt-cells = <2>;
diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,keystone-irq.txt b/Documentation/devicetree/bindings/interrupt-controller/ti,keystone-irq.txt
index d9bb106bdd16..5f94d7739d8d 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/ti,keystone-irq.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/ti,keystone-irq.txt
@@ -20,7 +20,7 @@ Please refer to interrupts.txt in this directory for details of the common
Interrupt Controllers bindings used by client devices.
Example:
- kirq0: keystone_irq0@026202a0 {
+ kirq0: keystone_irq0@26202a0 {
compatible = "ti,keystone-irq";
ti,syscon-dev = <&devctrl 0x2a0>;
interrupts = <GIC_SPI 4 IRQ_TYPE_EDGE_RISING>;
diff --git a/Documentation/devicetree/bindings/iommu/qcom,iommu.txt b/Documentation/devicetree/bindings/iommu/qcom,iommu.txt
index b2641ceb2b40..059139abce35 100644
--- a/Documentation/devicetree/bindings/iommu/qcom,iommu.txt
+++ b/Documentation/devicetree/bindings/iommu/qcom,iommu.txt
@@ -115,7 +115,7 @@ to non-secure vs secure interrupt line.
iommus = <&apps_iommu 4>;
};
- gpu@01c00000 {
+ gpu@1c00000 {
...
iommus = <&gpu_iommu 1>, <&gpu_iommu 2>;
};
diff --git a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
index 3ed027cfca95..857df929a654 100644
--- a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
+++ b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
@@ -53,7 +53,7 @@ Example: R8A7791 IPMMU-MX and VSP1-D0 bus master
#iommu-cells = <1>;
};
- vsp1@fe928000 {
+ vsp@fe928000 {
...
iommus = <&ipmmu_mx 13>;
...
diff --git a/Documentation/devicetree/bindings/leds/register-bit-led.txt b/Documentation/devicetree/bindings/leds/register-bit-led.txt
index 59b56365f648..cf1ea403ba7a 100644
--- a/Documentation/devicetree/bindings/leds/register-bit-led.txt
+++ b/Documentation/devicetree/bindings/leds/register-bit-led.txt
@@ -32,7 +32,7 @@ syscon: syscon@10000000 {
compatible = "arm,realview-pb1176-syscon", "syscon";
reg = <0x10000000 0x1000>;
- led@08.0 {
+ led@8.0 {
compatible = "register-bit-led";
offset = <0x08>;
mask = <0x01>;
@@ -40,7 +40,7 @@ syscon: syscon@10000000 {
linux,default-trigger = "heartbeat";
default-state = "on";
};
- led@08.1 {
+ led@8.1 {
compatible = "register-bit-led";
offset = <0x08>;
mask = <0x02>;
@@ -48,7 +48,7 @@ syscon: syscon@10000000 {
linux,default-trigger = "mmc0";
default-state = "off";
};
- led@08.2 {
+ led@8.2 {
compatible = "register-bit-led";
offset = <0x08>;
mask = <0x04>;
@@ -56,35 +56,35 @@ syscon: syscon@10000000 {
linux,default-trigger = "cpu0";
default-state = "off";
};
- led@08.3 {
+ led@8.3 {
compatible = "register-bit-led";
offset = <0x08>;
mask = <0x08>;
label = "versatile:3";
default-state = "off";
};
- led@08.4 {
+ led@8.4 {
compatible = "register-bit-led";
offset = <0x08>;
mask = <0x10>;
label = "versatile:4";
default-state = "off";
};
- led@08.5 {
+ led@8.5 {
compatible = "register-bit-led";
offset = <0x08>;
mask = <0x20>;
label = "versatile:5";
default-state = "off";
};
- led@08.6 {
+ led@8.6 {
compatible = "register-bit-led";
offset = <0x08>;
mask = <0x40>;
label = "versatile:6";
default-state = "off";
};
- led@08.7 {
+ led@8.7 {
compatible = "register-bit-led";
offset = <0x08>;
mask = <0x80>;
diff --git a/Documentation/devicetree/bindings/mailbox/ti,message-manager.txt b/Documentation/devicetree/bindings/mailbox/ti,message-manager.txt
index b449d025049f..c3b55b3ede8a 100644
--- a/Documentation/devicetree/bindings/mailbox/ti,message-manager.txt
+++ b/Documentation/devicetree/bindings/mailbox/ti,message-manager.txt
@@ -29,7 +29,7 @@ Required properties:
Example(K2G):
------------
- msgmgr: msgmgr@02a00000 {
+ msgmgr: msgmgr@2a00000 {
compatible = "ti,k2g-message-manager";
#mbox-cells = <2>;
reg-names = "queue_proxy_region", "queue_state_debug_region";
diff --git a/Documentation/devicetree/bindings/marvell.txt b/Documentation/devicetree/bindings/marvell.txt
index ea2b16ced49b..7f722316458a 100644
--- a/Documentation/devicetree/bindings/marvell.txt
+++ b/Documentation/devicetree/bindings/marvell.txt
@@ -446,7 +446,7 @@ prefixed with the string "marvell,", for Marvell Technology Group Ltd.
that services interrupts for this device.
Example Discovery CPU Error node:
- cpu-error@0070 {
+ cpu-error@70 {
compatible = "marvell,mv64360-cpu-error";
reg = <0x70 0x10 0x128 0x28>;
interrupts = <3>;
@@ -466,7 +466,7 @@ prefixed with the string "marvell,", for Marvell Technology Group Ltd.
that services interrupts for this device.
Example Discovery SRAM Controller node:
- sram-ctrl@0380 {
+ sram-ctrl@380 {
compatible = "marvell,mv64360-sram-ctrl";
reg = <0x380 0x80>;
interrupts = <13>;
diff --git a/Documentation/devicetree/bindings/media/i2c/tc358743.txt b/Documentation/devicetree/bindings/media/i2c/tc358743.txt
index 5218921629ed..49f8bcc2ea4d 100644
--- a/Documentation/devicetree/bindings/media/i2c/tc358743.txt
+++ b/Documentation/devicetree/bindings/media/i2c/tc358743.txt
@@ -27,7 +27,7 @@ Documentation/devicetree/bindings/media/video-interfaces.txt.
Example:
- tc358743@0f {
+ tc358743@f {
compatible = "toshiba,tc358743";
reg = <0x0f>;
clocks = <&hdmi_osc>;
diff --git a/Documentation/devicetree/bindings/media/img-ir-rev1.txt b/Documentation/devicetree/bindings/media/img-ir-rev1.txt
index 5434ce61b925..ed9ec52b77e0 100644
--- a/Documentation/devicetree/bindings/media/img-ir-rev1.txt
+++ b/Documentation/devicetree/bindings/media/img-ir-rev1.txt
@@ -25,7 +25,7 @@ Optional properties:
Example:
- ir@02006200 {
+ ir@2006200 {
compatible = "img,ir-rev1";
reg = <0x02006200 0x100>;
interrupts = <29 4>;
diff --git a/Documentation/devicetree/bindings/media/renesas,vsp1.txt b/Documentation/devicetree/bindings/media/renesas,vsp1.txt
index 9b695bcbf219..16427017cb45 100644
--- a/Documentation/devicetree/bindings/media/renesas,vsp1.txt
+++ b/Documentation/devicetree/bindings/media/renesas,vsp1.txt
@@ -22,7 +22,7 @@ Optional properties:
Example: R8A7790 (R-Car H2) VSP1-S node
- vsp1@fe928000 {
+ vsp@fe928000 {
compatible = "renesas,vsp1";
reg = <0 0xfe928000 0 0x8000>;
interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/Documentation/devicetree/bindings/media/stih-cec.txt b/Documentation/devicetree/bindings/media/stih-cec.txt
index 8be2a040c6c6..ece0832fdeaf 100644
--- a/Documentation/devicetree/bindings/media/stih-cec.txt
+++ b/Documentation/devicetree/bindings/media/stih-cec.txt
@@ -13,7 +13,7 @@ Required properties:
Example for STIH407:
-sti-cec@094a087c {
+sti-cec@94a087c {
compatible = "st,stih-cec";
reg = <0x94a087c 0x64>;
clocks = <&clk_sysin>;
diff --git a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
index 6af3fc210ecc..c7888d6f6408 100644
--- a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
+++ b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
@@ -50,7 +50,7 @@ Example:
/* stih410 SoC b2120 + b2004a + stv0367-pll(NIMB) + stv0367-tda18212 (NIMA) DT example) */
- c8sectpfe@08a20000 {
+ c8sectpfe@8a20000 {
compatible = "st,stih407-c8sectpfe";
reg = <0x08a20000 0x10000>, <0x08a00000 0x4000>;
reg-names = "stfe", "stfe-ram";
diff --git a/Documentation/devicetree/bindings/media/sunxi-ir.txt b/Documentation/devicetree/bindings/media/sunxi-ir.txt
index 302a0b183cb8..91648c569b1e 100644
--- a/Documentation/devicetree/bindings/media/sunxi-ir.txt
+++ b/Documentation/devicetree/bindings/media/sunxi-ir.txt
@@ -14,7 +14,7 @@ Optional properties:
Example:
-ir0: ir@01c21800 {
+ir0: ir@1c21800 {
compatible = "allwinner,sun4i-a10-ir";
clocks = <&apb0_gates 6>, <&ir0_clk>;
clock-names = "apb", "ir";
diff --git a/Documentation/devicetree/bindings/mfd/max77686.txt b/Documentation/devicetree/bindings/mfd/max77686.txt
index 741e76688cf2..0f2587fa42cb 100644
--- a/Documentation/devicetree/bindings/mfd/max77686.txt
+++ b/Documentation/devicetree/bindings/mfd/max77686.txt
@@ -19,7 +19,7 @@ Required properties:
Example:
- max77686: pmic@09 {
+ max77686: pmic@9 {
compatible = "maxim,max77686";
interrupt-parent = <&wakeup_eint>;
interrupts = <26 0>;
diff --git a/Documentation/devicetree/bindings/mfd/max77802.txt b/Documentation/devicetree/bindings/mfd/max77802.txt
index 51fc1a60caa5..f2f3fe75901c 100644
--- a/Documentation/devicetree/bindings/mfd/max77802.txt
+++ b/Documentation/devicetree/bindings/mfd/max77802.txt
@@ -18,7 +18,7 @@ Required properties:
Example:
- max77802: pmic@09 {
+ max77802: pmic@9 {
compatible = "maxim,max77802";
interrupt-parent = <&intc>;
interrupts = <26 IRQ_TYPE_NONE>;
diff --git a/Documentation/devicetree/bindings/mfd/mfd.txt b/Documentation/devicetree/bindings/mfd/mfd.txt
index bcb6abb9d413..336c0495c8a3 100644
--- a/Documentation/devicetree/bindings/mfd/mfd.txt
+++ b/Documentation/devicetree/bindings/mfd/mfd.txt
@@ -41,7 +41,7 @@ foo@1000 {
compatible = "syscon", "simple-mfd";
reg = <0x01000 0x1000>;
- led@08.0 {
+ led@8.0 {
compatible = "register-bit-led";
offset = <0x08>;
mask = <0x01>;
diff --git a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
index badff3611a98..86dd8191b04c 100644
--- a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
+++ b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
@@ -10,7 +10,7 @@ Required properties:
- #io-channel-cells: shall be 0,
Example:
- ths: ths@01c25000 {
+ ths: ths@1c25000 {
compatible = "allwinner,sun8i-a33-ths";
reg = <0x01c25000 0x100>;
#thermal-sensor-cells = <0>;
@@ -47,7 +47,7 @@ Optional properties:
Example:
- rtp: rtp@01c25000 {
+ rtp: rtp@1c25000 {
compatible = "allwinner,sun4i-a10-ts";
reg = <0x01c25000 0x100>;
interrupts = <29>;
diff --git a/Documentation/devicetree/bindings/mfd/sun6i-prcm.txt b/Documentation/devicetree/bindings/mfd/sun6i-prcm.txt
index 03c5a551da55..dd2c06540485 100644
--- a/Documentation/devicetree/bindings/mfd/sun6i-prcm.txt
+++ b/Documentation/devicetree/bindings/mfd/sun6i-prcm.txt
@@ -15,7 +15,7 @@ The prcm node may contain several subdevices definitions:
Example:
- prcm: prcm@01f01400 {
+ prcm: prcm@1f01400 {
compatible = "allwinner,sun6i-a31-prcm";
reg = <0x01f01400 0x200>;
diff --git a/Documentation/devicetree/bindings/mfd/syscon.txt b/Documentation/devicetree/bindings/mfd/syscon.txt
index 408f768686f1..8b92d4576c42 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.txt
+++ b/Documentation/devicetree/bindings/mfd/syscon.txt
@@ -18,7 +18,7 @@ Optional property:
performed on the device.
Examples:
-gpr: iomuxc-gpr@020e0000 {
+gpr: iomuxc-gpr@20e0000 {
compatible = "fsl,imx6q-iomuxc-gpr", "syscon";
reg = <0x020e0000 0x38>;
};
diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt
index b32ade645ad9..5934157cf2cd 100644
--- a/Documentation/devicetree/bindings/mmc/mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc.txt
@@ -143,7 +143,7 @@ sdhci@ab000000 {
Example with sdio function subnode:
-mmc3: mmc@01c12000 {
+mmc3: mmc@1c12000 {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-st.txt b/Documentation/devicetree/bindings/mmc/sdhci-st.txt
index e35645598315..6b3d40ca395e 100644
--- a/Documentation/devicetree/bindings/mmc/sdhci-st.txt
+++ b/Documentation/devicetree/bindings/mmc/sdhci-st.txt
@@ -74,7 +74,7 @@ mmc0: sdhci@fe81e000 {
/* Example SD stih407 family configuration */
-mmc1: sdhci@09080000 {
+mmc1: sdhci@9080000 {
compatible = "st,sdhci-stih407", "st,sdhci";
reg = <0x09080000 0x7ff>;
reg-names = "mmc";
@@ -90,7 +90,7 @@ mmc1: sdhci@09080000 {
/* Example eMMC stih407 family configuration */
-mmc0: sdhci@09060000 {
+mmc0: sdhci@9060000 {
compatible = "st,sdhci-stih407", "st,sdhci";
reg = <0x09060000 0x7ff>, <0x9061008 0x20>;
reg-names = "mmc", "top-mmc-delay";
diff --git a/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt b/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt
index 63b57e2a10fb..132e0007d7d6 100644
--- a/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt
@@ -29,7 +29,7 @@ Optional properties:
Examples:
- Within .dtsi:
- mmc0: mmc@01c0f000 {
+ mmc0: mmc@1c0f000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c0f000 0x1000>;
clocks = <&ahb_gates 8>, <&mmc0_clk>, <&mmc0_output_clk>, <&mmc0_sample_clk>;
@@ -39,7 +39,7 @@ Examples:
};
- Within dts:
- mmc0: mmc@01c0f000 {
+ mmc0: mmc@1c0f000 {
pinctrl-names = "default", "default";
pinctrl-0 = <&mmc0_pins_a>;
pinctrl-1 = <&mmc0_cd_pin_reference_design>;
diff --git a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
index a37c67bcb43b..5e13a5cdff03 100644
--- a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
@@ -31,7 +31,7 @@ see Documentation/devicetree/bindings/mtd/nand.txt for generic bindings.
Examples:
-nfc: nand@01c03000 {
+nfc: nand@1c03000 {
compatible = "allwinner,sun4i-a10-nand";
reg = <0x01c03000 0x1000>;
interrupts = <0 37 1>;
diff --git a/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt b/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt
index 10640b17c866..e98118aef5f6 100644
--- a/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt
+++ b/Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt
@@ -10,7 +10,7 @@ Required properties:
Example:
-emac: ethernet@01c0b000 {
+emac: ethernet@1c0b000 {
compatible = "allwinner,sun4i-a10-emac";
reg = <0x01c0b000 0x1000>;
interrupts = <55>;
diff --git a/Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt b/Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt
index 4ec56413779d..ab5b8613b0ef 100644
--- a/Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt
+++ b/Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt
@@ -9,7 +9,7 @@ Optional properties:
- phy-supply: phandle to a regulator if the PHY needs one
Example at the SoC level:
-mdio@01c0b080 {
+mdio@1c0b080 {
compatible = "allwinner,sun4i-a10-mdio";
reg = <0x01c0b080 0x14>;
#address-cells = <1>;
@@ -18,7 +18,7 @@ mdio@01c0b080 {
And at the board level:
-mdio@01c0b080 {
+mdio@1c0b080 {
phy-supply = <&reg_emac_3v3>;
phy0: ethernet-phy@0 {
diff --git a/Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.txt b/Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.txt
index ea4d752389a2..8b3f953656e3 100644
--- a/Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.txt
+++ b/Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.txt
@@ -15,7 +15,7 @@ Optional properties:
Examples:
- gmac: ethernet@01c50000 {
+ gmac: ethernet@1c50000 {
compatible = "allwinner,sun7i-a20-gmac";
reg = <0x01c50000 0x10000>,
<0x01c20164 0x4>;
diff --git a/Documentation/devicetree/bindings/net/brcm,bcmgenet.txt b/Documentation/devicetree/bindings/net/brcm,bcmgenet.txt
index 26c77d985faf..3956af1d30f3 100644
--- a/Documentation/devicetree/bindings/net/brcm,bcmgenet.txt
+++ b/Documentation/devicetree/bindings/net/brcm,bcmgenet.txt
@@ -109,7 +109,7 @@ ethernet@f0ba0000 {
reg = <0xf0ba0000 0xfc4c>;
interrupts = <0x0 0x18 0x0>, <0x0 0x19 0x0>;
- mdio@0e14 {
+ mdio@e14 {
compatible = "brcm,genet-mdio-v4";
#address-cells = <0x1>;
#size-cells = <0x0>;
diff --git a/Documentation/devicetree/bindings/net/can/m_can.txt b/Documentation/devicetree/bindings/net/can/m_can.txt
index 78138333ff7a..63e90421d029 100644
--- a/Documentation/devicetree/bindings/net/can/m_can.txt
+++ b/Documentation/devicetree/bindings/net/can/m_can.txt
@@ -45,7 +45,7 @@ Required properties:
Example:
SoC dtsi:
-m_can1: can@020e8000 {
+m_can1: can@20e8000 {
compatible = "bosch,m_can";
reg = <0x020e8000 0x4000>, <0x02298000 0x4000>;
reg-names = "m_can", "message_ram";
diff --git a/Documentation/devicetree/bindings/net/can/sun4i_can.txt b/Documentation/devicetree/bindings/net/can/sun4i_can.txt
index 84ed1909df76..f69845e6feaf 100644
--- a/Documentation/devicetree/bindings/net/can/sun4i_can.txt
+++ b/Documentation/devicetree/bindings/net/can/sun4i_can.txt
@@ -19,7 +19,7 @@ SoC common .dtsi file:
allwinner,pull = <0>;
};
...
- can0: can@01c2bc00 {
+ can0: can@1c2bc00 {
compatible = "allwinner,sun4i-a10-can";
reg = <0x01c2bc00 0x400>;
interrupts = <0 26 4>;
@@ -29,7 +29,7 @@ SoC common .dtsi file:
Board specific .dts file:
- can0: can@01c2bc00 {
+ can0: can@1c2bc00 {
pinctrl-names = "default";
pinctrl-0 = <&can0_pins_a>;
status = "okay";
diff --git a/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt b/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
index b2bd4704f859..86602f264dce 100644
--- a/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
+++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
@@ -20,7 +20,7 @@ Optional properties:
Example:
-mmc3: mmc@01c12000 {
+mmc3: mmc@1c12000 {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt b/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt
index ef06d061913c..081c49c0dac0 100644
--- a/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt
+++ b/Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt
@@ -13,13 +13,13 @@ Are child nodes of qfprom, bindings of which as described in
bindings/nvmem/nvmem.txt
Example for sun4i:
- sid@01c23800 {
+ sid@1c23800 {
compatible = "allwinner,sun4i-a10-sid";
reg = <0x01c23800 0x10>
};
Example for sun7i:
- sid@01c23800 {
+ sid@1c23800 {
compatible = "allwinner,sun7i-a20-sid";
reg = <0x01c23800 0x200>
};
diff --git a/Documentation/devicetree/bindings/nvmem/brcm,ocotp.txt b/Documentation/devicetree/bindings/nvmem/brcm,ocotp.txt
index 6462e12d8de6..0415265c215a 100644
--- a/Documentation/devicetree/bindings/nvmem/brcm,ocotp.txt
+++ b/Documentation/devicetree/bindings/nvmem/brcm,ocotp.txt
@@ -10,7 +10,7 @@ Required Properties:
Example:
-otp: otp@0301c800 {
+otp: otp@301c800 {
compatible = "brcm,ocotp";
reg = <0x0301c800 0x2c>;
brcm,ocotp-size = <2048>;
diff --git a/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt b/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
index 70d791b03ea1..f162c72b4e36 100644
--- a/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
+++ b/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
@@ -19,7 +19,7 @@ Optional properties:
Example:
- ocotp: ocotp@021bc000 {
+ ocotp: ocotp@21bc000 {
compatible = "fsl,imx6q-ocotp", "syscon";
reg = <0x021bc000 0x4000>;
clocks = <&clks IMX6QDL_CLK_IIM>;
diff --git a/Documentation/devicetree/bindings/nvmem/nvmem.txt b/Documentation/devicetree/bindings/nvmem/nvmem.txt
index b52bc11e9597..fd06c09b822b 100644
--- a/Documentation/devicetree/bindings/nvmem/nvmem.txt
+++ b/Documentation/devicetree/bindings/nvmem/nvmem.txt
@@ -33,7 +33,7 @@ bits: Is pair of bit location and number of bits, which specifies offset
For example:
/* Provider */
- qfprom: qfprom@00700000 {
+ qfprom: qfprom@700000 {
...
/* Data cells */
diff --git a/Documentation/devicetree/bindings/nvmem/qfprom.txt b/Documentation/devicetree/bindings/nvmem/qfprom.txt
index 4ad68b7f5c18..26fe878d5c86 100644
--- a/Documentation/devicetree/bindings/nvmem/qfprom.txt
+++ b/Documentation/devicetree/bindings/nvmem/qfprom.txt
@@ -12,7 +12,7 @@ bindings/nvmem/nvmem.txt
Example:
- qfprom: qfprom@00700000 {
+ qfprom: qfprom@700000 {
compatible = "qcom,qfprom";
reg = <0x00700000 0x8000>;
...
diff --git a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
index 982a74ea6df9..1b4d2803dad1 100644
--- a/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
@@ -255,7 +255,7 @@ Tegra30:
SoC DTSI:
- pcie-controller@00003000 {
+ pcie-controller@3000 {
compatible = "nvidia,tegra30-pcie";
device_type = "pci";
reg = <0x00003000 0x00000800 /* PADS registers */
@@ -334,7 +334,7 @@ SoC DTSI:
Board DTS:
- pcie-controller@00003000 {
+ pcie-controller@3000 {
status = "okay";
avdd-pexa-supply = <&ldo1_reg>;
@@ -360,7 +360,7 @@ Tegra124:
SoC DTSI:
- pcie-controller@01003000 {
+ pcie-controller@1003000 {
compatible = "nvidia,tegra124-pcie";
device_type = "pci";
reg = <0x0 0x01003000 0x0 0x00000800 /* PADS registers */
@@ -425,7 +425,7 @@ SoC DTSI:
Board DTS:
- pcie-controller@01003000 {
+ pcie-controller@1003000 {
status = "okay";
avddio-pex-supply = <&vdd_1v05_run>;
@@ -456,7 +456,7 @@ Tegra210:
SoC DTSI:
- pcie-controller@01003000 {
+ pcie-controller@1003000 {
compatible = "nvidia,tegra210-pcie";
device_type = "pci";
reg = <0x0 0x01003000 0x0 0x00000800 /* PADS registers */
@@ -521,7 +521,7 @@ SoC DTSI:
Board DTS:
- pcie-controller@01003000 {
+ pcie-controller@1003000 {
status = "okay";
avdd-pll-uerefe-supply = <&avdd_1v05_pll>;
diff --git a/Documentation/devicetree/bindings/phy/brcm,cygnus-pcie-phy.txt b/Documentation/devicetree/bindings/phy/brcm,cygnus-pcie-phy.txt
index 761c4bc24a9b..10efff28b52b 100644
--- a/Documentation/devicetree/bindings/phy/brcm,cygnus-pcie-phy.txt
+++ b/Documentation/devicetree/bindings/phy/brcm,cygnus-pcie-phy.txt
@@ -15,7 +15,7 @@ Required properties For the child node:
- #phy-cells: must be 0
Example:
- pcie_phy: phy@0301d0a0 {
+ pcie_phy: phy@301d0a0 {
compatible = "brcm,cygnus-pcie-phy";
reg = <0x0301d0a0 0x14>;
diff --git a/Documentation/devicetree/bindings/phy/mxs-usb-phy.txt b/Documentation/devicetree/bindings/phy/mxs-usb-phy.txt
index 1d25b04cd05e..6ac98b3b5f57 100644
--- a/Documentation/devicetree/bindings/phy/mxs-usb-phy.txt
+++ b/Documentation/devicetree/bindings/phy/mxs-usb-phy.txt
@@ -23,7 +23,7 @@ Optional properties:
the 17.78mA TX reference current. Default: 100
Example:
-usbphy1: usbphy@020c9000 {
+usbphy1: usbphy@20c9000 {
compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
reg = <0x020c9000 0x1000>;
interrupts = <0 44 0x04>;
diff --git a/Documentation/devicetree/bindings/phy/sun9i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun9i-usb-phy.txt
index f9853156e311..64f7109aea1f 100644
--- a/Documentation/devicetree/bindings/phy/sun9i-usb-phy.txt
+++ b/Documentation/devicetree/bindings/phy/sun9i-usb-phy.txt
@@ -25,7 +25,7 @@ It is recommended to list all clocks and resets available.
The driver will only use those matching the phy_type.
Example:
- usbphy1: phy@00a01800 {
+ usbphy1: phy@a01800 {
compatible = "allwinner,sun9i-a80-usb-phy";
reg = <0x00a01800 0x4>;
clocks = <&usb_phy_clk 2>, <&usb_phy_clk 10>,
diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
index 6f2ec9af0de2..09789fdfa749 100644
--- a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
@@ -89,7 +89,7 @@ Optional subnode-properties:
Examples:
-pio: pinctrl@01c20800 {
+pio: pinctrl@1c20800 {
compatible = "allwinner,sun5i-a13-pinctrl";
reg = <0x01c20800 0x400>;
#address-cells = <1>;
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt
index 42d74f8a1bcc..a1050b5982ec 100644
--- a/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt
@@ -58,14 +58,14 @@ Some requirements for using fsl,imx-pinctrl binding:
configurations by referring to the phandle of that pin configuration node.
Examples:
-usdhc@0219c000 { /* uSDHC4 */
+usdhc@219c000 { /* uSDHC4 */
non-removable;
vmmc-supply = <&reg_3p3v>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc4_1>;
};
-iomuxc@020e0000 {
+iomuxc@20e0000 {
compatible = "fsl,imx6q-iomuxc";
reg = <0x020e0000 0x4000>;
diff --git a/Documentation/devicetree/bindings/pinctrl/img,tz1090-pdc-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/img,tz1090-pdc-pinctrl.txt
index 51b943cc9770..cf9ccdff4455 100644
--- a/Documentation/devicetree/bindings/pinctrl/img,tz1090-pdc-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/img,tz1090-pdc-pinctrl.txt
@@ -89,7 +89,7 @@ Valid values for pin and group names are:
Example:
- pinctrl_pdc: pinctrl@02006500 {
+ pinctrl_pdc: pinctrl@2006500 {
#gpio-range-cells = <3>;
compatible = "img,tz1090-pdc-pinctrl";
reg = <0x02006500 0x100>;
@@ -121,7 +121,7 @@ Example board file extracts:
};
};
- ir: ir@02006200 {
+ ir: ir@2006200 {
pinctrl-names = "default";
pinctrl-0 = <&irmod_default>;
};
diff --git a/Documentation/devicetree/bindings/pinctrl/img,tz1090-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/img,tz1090-pinctrl.txt
index 509faa87ad0e..2dfd9a3fc1e4 100644
--- a/Documentation/devicetree/bindings/pinctrl/img,tz1090-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/img,tz1090-pinctrl.txt
@@ -197,7 +197,7 @@ Valid values for pin and group names are:
Example:
- pinctrl: pinctrl@02005800 {
+ pinctrl: pinctrl@2005800 {
#gpio-range-cells = <3>;
compatible = "img,tz1090-pinctrl";
reg = <0x02005800 0xe4>;
@@ -221,7 +221,7 @@ Example board file extract:
};
};
- uart@02004b00 {
+ uart@2004b00 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_default>;
};
diff --git a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-xusb-padctl.txt b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-xusb-padctl.txt
index 4048f43a9d29..02e971c39d81 100644
--- a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-xusb-padctl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-xusb-padctl.txt
@@ -97,7 +97,7 @@ SoC file extract:
Board file extract:
-------------------
- pcie-controller@01003000 {
+ pcie-controller@1003000 {
...
phys = <&padctl 0>;
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
index 37d744750579..231fa1db7c5e 100644
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
@@ -86,7 +86,7 @@ Examples:
reg = <0 0x1020C020 0 0x1000>;
};
- pinctrl@01c20800 {
+ pinctrl@1c20800 {
compatible = "mediatek,mt8135-pinctrl";
reg = <0 0x1000B000 0 0x1000>;
mediatek,pctl-regmap = <&syscfg_pctl_a &syscfg_pctl_b>;
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt
index 013c675b5b64..48b9be48af18 100644
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt
@@ -89,7 +89,7 @@ Example:
interrupt-names = "irqmux";
ranges = <0 0x09610000 0x6000>;
- pio0: gpio@09610000 {
+ pio0: gpio@9610000 {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8996-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,msm8996-pinctrl.txt
index e312a71b2f94..aaf01e929eea 100644
--- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8996-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8996-pinctrl.txt
@@ -175,7 +175,7 @@ to specify in a pin configuration subnode:
Example:
- tlmm: pinctrl@01010000 {
+ tlmm: pinctrl@1010000 {
compatible = "qcom,msm8996-pinctrl";
reg = <0x01010000 0x300000>;
interrupts = <0 208 0>;
diff --git a/Documentation/devicetree/bindings/power/fsl,imx-gpc.txt b/Documentation/devicetree/bindings/power/fsl,imx-gpc.txt
index 6c1498958d48..e371b262d709 100644
--- a/Documentation/devicetree/bindings/power/fsl,imx-gpc.txt
+++ b/Documentation/devicetree/bindings/power/fsl,imx-gpc.txt
@@ -40,7 +40,7 @@ Optional properties:
Example:
- gpc: gpc@020dc000 {
+ gpc: gpc@20dc000 {
compatible = "fsl,imx6q-gpc";
reg = <0x020dc000 0x4000>;
interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>,
@@ -80,7 +80,7 @@ that is a phandle pointing to the power domain the device belongs to.
Example of a device that is part of the PU power domain:
- vpu: vpu@02040000 {
+ vpu: vpu@2040000 {
reg = <0x02040000 0x3c000>;
/* ... */
power-domains = <&pd_pu>;
diff --git a/Documentation/devicetree/bindings/power/reset/imx-snvs-poweroff.txt b/Documentation/devicetree/bindings/power/reset/imx-snvs-poweroff.txt
index dc7c9bad63ea..1b81fcd9fb72 100644
--- a/Documentation/devicetree/bindings/power/reset/imx-snvs-poweroff.txt
+++ b/Documentation/devicetree/bindings/power/reset/imx-snvs-poweroff.txt
@@ -10,7 +10,7 @@ Required Properties:
-reg: Specifies the physical address of the SNVS_LPCR register
Example:
- snvs@020cc000 {
+ snvs@20cc000 {
compatible = "fsl,sec-v4.0-mon", "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
diff --git a/Documentation/devicetree/bindings/power/reset/keystone-reset.txt b/Documentation/devicetree/bindings/power/reset/keystone-reset.txt
index c82f12e2d85c..c5c03789ed1e 100644
--- a/Documentation/devicetree/bindings/power/reset/keystone-reset.txt
+++ b/Documentation/devicetree/bindings/power/reset/keystone-reset.txt
@@ -37,12 +37,12 @@ Example 1:
Setup keystone reset so that in case software reset or
WDT0 is triggered it issues hard reset for SoC.
-pllctrl: pll-controller@02310000 {
+pllctrl: pll-controller@2310000 {
compatible = "ti,keystone-pllctrl", "syscon";
reg = <0x02310000 0x200>;
};
-devctrl: device-state-control@02620000 {
+devctrl: device-state-control@2620000 {
compatible = "ti,keystone-devctrl", "syscon";
reg = <0x02620000 0x1000>;
};
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/mcu-mpc8349emitx.txt b/Documentation/devicetree/bindings/powerpc/fsl/mcu-mpc8349emitx.txt
index 0f766333b6eb..37f91fa57654 100644
--- a/Documentation/devicetree/bindings/powerpc/fsl/mcu-mpc8349emitx.txt
+++ b/Documentation/devicetree/bindings/powerpc/fsl/mcu-mpc8349emitx.txt
@@ -8,7 +8,7 @@ Required properties:
Example:
-mcu@0a {
+mcu@a {
#gpio-cells = <2>;
compatible = "fsl,mc9s08qg8-mpc8349emitx",
"fsl,mcu-mpc8349emitx";
diff --git a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
index c5171660eaf9..51ff54c8b8ef 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
@@ -14,7 +14,7 @@ Required properties:
Example:
- pwm: pwm@01c20e00 {
+ pwm: pwm@1c20e00 {
compatible = "allwinner,sun7i-a20-pwm";
reg = <0x01c20e00 0xc>;
clocks = <&osc24M>;
diff --git a/Documentation/devicetree/bindings/regulator/max77686.txt b/Documentation/devicetree/bindings/regulator/max77686.txt
index 0dded64d89d3..e9f7578ca09a 100644
--- a/Documentation/devicetree/bindings/regulator/max77686.txt
+++ b/Documentation/devicetree/bindings/regulator/max77686.txt
@@ -40,7 +40,7 @@ to get matched with their hardware counterparts as follow:
Example:
- max77686: pmic@09 {
+ max77686: pmic@9 {
compatible = "maxim,max77686";
interrupt-parent = <&wakeup_eint>;
interrupts = <26 IRQ_TYPE_NONE>;
diff --git a/Documentation/devicetree/bindings/regulator/max77802.txt b/Documentation/devicetree/bindings/regulator/max77802.txt
index 879e98d3b9aa..b82943d83677 100644
--- a/Documentation/devicetree/bindings/regulator/max77802.txt
+++ b/Documentation/devicetree/bindings/regulator/max77802.txt
@@ -71,7 +71,7 @@ has not been disabled for that state using "regulator-off-in-suspend".
Example:
- max77802@09 {
+ max77802@9 {
compatible = "maxim,max77802";
interrupt-parent = <&wakeup_eint>;
interrupts = <26 0>;
diff --git a/Documentation/devicetree/bindings/reset/allwinner,sunxi-clock-reset.txt b/Documentation/devicetree/bindings/reset/allwinner,sunxi-clock-reset.txt
index c8f775714887..4ca66c96fe97 100644
--- a/Documentation/devicetree/bindings/reset/allwinner,sunxi-clock-reset.txt
+++ b/Documentation/devicetree/bindings/reset/allwinner,sunxi-clock-reset.txt
@@ -14,7 +14,7 @@ Required properties:
example:
-ahb1_rst: reset@01c202c0 {
+ahb1_rst: reset@1c202c0 {
#reset-cells = <1>;
compatible = "allwinner,sun6i-a31-ahb1-reset";
reg = <0x01c202c0 0xc>;
diff --git a/Documentation/devicetree/bindings/reset/fsl,imx-src.txt b/Documentation/devicetree/bindings/reset/fsl,imx-src.txt
index 13301777e11c..6ed79e60248a 100644
--- a/Documentation/devicetree/bindings/reset/fsl,imx-src.txt
+++ b/Documentation/devicetree/bindings/reset/fsl,imx-src.txt
@@ -14,7 +14,7 @@ Required properties:
example:
-src: src@020d8000 {
+src: src@20d8000 {
compatible = "fsl,imx6q-src";
reg = <0x020d8000 0x4000>;
interrupts = <0 91 0x04 0 96 0x04>;
@@ -33,10 +33,10 @@ reset.txt
example:
- ipu1: ipu@02400000 {
+ ipu1: ipu@2400000 {
resets = <&src 2>;
};
- ipu2: ipu@02800000 {
+ ipu2: ipu@2800000 {
resets = <&src 4>;
};
diff --git a/Documentation/devicetree/bindings/reset/ti-syscon-reset.txt b/Documentation/devicetree/bindings/reset/ti-syscon-reset.txt
index c516d24959f2..86945502ccb5 100644
--- a/Documentation/devicetree/bindings/reset/ti-syscon-reset.txt
+++ b/Documentation/devicetree/bindings/reset/ti-syscon-reset.txt
@@ -67,7 +67,7 @@ using the syscon node, and a consumer (a DSP device) on the TI Keystone 2
/ {
soc {
- psc: power-sleep-controller@02350000 {
+ psc: power-sleep-controller@2350000 {
compatible = "syscon", "simple-mfd";
reg = <0x02350000 0x1000>;
diff --git a/Documentation/devicetree/bindings/rtc/dallas,ds1339.txt b/Documentation/devicetree/bindings/rtc/dallas,ds1339.txt
deleted file mode 100644
index 916f57601a8f..000000000000
--- a/Documentation/devicetree/bindings/rtc/dallas,ds1339.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-* Dallas DS1339 I2C Serial Real-Time Clock
-
-Required properties:
-- compatible: Should contain "dallas,ds1339".
-- reg: I2C address for chip
-
-Optional properties:
-- trickle-resistor-ohms : Selected resistor for trickle charger
- Values usable for ds1339 are 250, 2000, 4000
- Should be given if trickle charger should be enabled
-- trickle-diode-disable : Do not use internal trickle charger diode
- Should be given if internal trickle charger diode should be disabled
-Example:
- ds1339: rtc@68 {
- compatible = "dallas,ds1339";
- trickle-resistor-ohms = <250>;
- reg = <0x68>;
- };
diff --git a/Documentation/devicetree/bindings/rtc/rtc-ds1307.txt b/Documentation/devicetree/bindings/rtc/rtc-ds1307.txt
new file mode 100644
index 000000000000..d28d6e7f6ae8
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/rtc-ds1307.txt
@@ -0,0 +1,44 @@
+Dallas DS1307 and compatible RTC
+
+Required properties:
+- compatible: should be one of:
+ "dallas,ds1307",
+ "dallas,ds1308",
+ "dallas,ds1337",
+ "dallas,ds1338",
+ "dallas,ds1339",
+ "dallas,ds1388",
+ "dallas,ds1340",
+ "dallas,ds1341",
+ "maxim,ds3231",
+ "st,m41t0",
+ "st,m41t00",
+ "microchip,mcp7940x",
+ "microchip,mcp7941x",
+ "pericom,pt7c4338",
+ "epson,rx8025",
+ "isil,isl12057"
+- reg: I2C bus address of the device
+
+Optional properties:
+- interrupt-parent: phandle for the interrupt controller.
+- interrupts: rtc alarm interrupt.
+- clock-output-names: From common clock binding to override the default output
+ clock name
+- wakeup-source: Enables wake up of host system on alarm
+- trickle-resistor-ohms : ds1339, ds1340 and ds 1388 only
+ Selected resistor for trickle charger
+ Possible values are 250, 2000, 4000
+ Should be given if trickle charger should be enabled
+- trickle-diode-disable : ds1339, ds1340 and ds 1388 only
+ Do not use internal trickle charger diode
+ Should be given if internal trickle charger diode should be disabled
+
+Example:
+ rtc1: ds1339@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <20 0>;
+ trickle-resistor-ohms = <250>;
+ };
diff --git a/Documentation/devicetree/bindings/rtc/rtc-m41t80.txt b/Documentation/devicetree/bindings/rtc/rtc-m41t80.txt
new file mode 100644
index 000000000000..717d93860af1
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/rtc-m41t80.txt
@@ -0,0 +1,31 @@
+ST M41T80 family of RTC and compatible
+
+Required properties:
+- compatible: should be one of:
+ "st,m41t62",
+ "st,m41t65",
+ "st,m41t80",
+ "st,m41t81",
+ "st,m41t81s",
+ "st,m41t82",
+ "st,m41t83",
+ "st,m41t84",
+ "st,m41t85",
+ "st,m41t87",
+ "microcrystal,rv4162",
+- reg: I2C bus address of the device
+
+Optional properties:
+- interrupt-parent: phandle for the interrupt controller.
+- interrupts: rtc alarm interrupt.
+- clock-output-names: From common clock binding to override the default output
+ clock name
+- wakeup-source: Enables wake up of host system on alarm
+
+Example:
+ rtc@68 {
+ compatible = "st,m41t80";
+ reg = <0x68>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <0x9 0x8>;
+ };
diff --git a/Documentation/devicetree/bindings/rtc/sirf,prima2-sysrtc.txt b/Documentation/devicetree/bindings/rtc/sirf,prima2-sysrtc.txt
new file mode 100644
index 000000000000..58885b55da21
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/sirf,prima2-sysrtc.txt
@@ -0,0 +1,13 @@
+SiRFSoC Real Time Clock
+
+Required properties:
+- compatible: must be "sirf,prima2-sysrtc"
+- reg: address range of rtc register set.
+- interrupts: rtc alarm interrupts.
+
+Example:
+ rtc@2000 {
+ compatible = "sirf,prima2-sysrtc";
+ reg = <0x2000 0x1000>;
+ interrupts = <52 53 54>;
+ };
diff --git a/Documentation/devicetree/bindings/rtc/stericsson,coh901331.txt b/Documentation/devicetree/bindings/rtc/stericsson,coh901331.txt
new file mode 100644
index 000000000000..3ebeb311335f
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/stericsson,coh901331.txt
@@ -0,0 +1,17 @@
+ST-Ericsson COH 901 331 Real Time Clock
+
+Required properties:
+- compatible: must be "stericsson,coh901331"
+- reg: address range of rtc register set.
+- interrupt-parent: phandle for the interrupt controller.
+- interrupts: rtc alarm interrupt.
+- clocks: phandle to the rtc clock source
+
+Example:
+ rtc: rtc@c0017000 {
+ compatible = "stericsson,coh901331";
+ reg = <0xc0017000 0x1000>;
+ interrupt-parent = <&vicb>;
+ interrupts = <10>;
+ clocks = <&rtc_clk>;
+ };
diff --git a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
index d5e26d313f62..12c083c1140a 100644
--- a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
+++ b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
@@ -17,7 +17,7 @@ Required properties for new device trees
Example:
-rtc: rtc@01f00000 {
+rtc: rtc@1f00000 {
compatible = "allwinner,sun6i-a31-rtc";
reg = <0x01f00000 0x54>;
interrupts = <0 40 4>, <0 41 4>;
diff --git a/Documentation/devicetree/bindings/rtc/sunxi-rtc.txt b/Documentation/devicetree/bindings/rtc/sunxi-rtc.txt
index 6983aad376c3..4a8d79c1cf08 100644
--- a/Documentation/devicetree/bindings/rtc/sunxi-rtc.txt
+++ b/Documentation/devicetree/bindings/rtc/sunxi-rtc.txt
@@ -10,7 +10,7 @@ Required properties:
Example:
-rtc: rtc@01c20d00 {
+rtc: rtc@1c20d00 {
compatible = "allwinner,sun4i-a10-rtc";
reg = <0x01c20d00 0x20>;
interrupts = <24>;
diff --git a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/qe/par_io.txt b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/qe/par_io.txt
index 60984260207b..09b1b05fa677 100644
--- a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/qe/par_io.txt
+++ b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/qe/par_io.txt
@@ -18,7 +18,7 @@ par_io@1400 {
#size-cells = <0>;
device_type = "par_io";
num-ports = <7>;
- ucc_pin@01 {
+ ucc_pin@1 {
......
};
diff --git a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/qe/pincfg.txt b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/qe/pincfg.txt
index ec6ee2e864a2..5bde8b98a8c9 100644
--- a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/qe/pincfg.txt
+++ b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/qe/pincfg.txt
@@ -26,7 +26,7 @@ Required properties:
interrupts.
Example:
- ucc_pin@01 {
+ ucc_pin@1 {
pio-map = <
/* port pin dir open_drain assignment has_irq */
0 3 1 0 1 0 /* TxD0 */
diff --git a/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt b/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
index 66e6265fb0aa..f7b00a7c0f68 100644
--- a/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
+++ b/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
@@ -51,7 +51,7 @@ of valid identifiers for k2g.
Example (K2G):
--------------------
- uart0: serial@02530c00 {
+ uart0: serial@2530c00 {
compatible = "ns16550a";
...
power-domains = <&k2g_pds 0x002c>;
diff --git a/Documentation/devicetree/bindings/sound/cdns,xtfpga-i2s.txt b/Documentation/devicetree/bindings/sound/cdns,xtfpga-i2s.txt
index befd125d18bb..860fc0da39c0 100644
--- a/Documentation/devicetree/bindings/sound/cdns,xtfpga-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/cdns,xtfpga-i2s.txt
@@ -9,7 +9,7 @@ Required properties:
Examples:
- i2s0: xtfpga-i2s@0d080000 {
+ i2s0: xtfpga-i2s@d080000 {
#sound-dai-cells = <0>;
compatible = "cdns,xtfpga-i2s";
reg = <0x0d080000 0x40>;
diff --git a/Documentation/devicetree/bindings/sound/fsl,asrc.txt b/Documentation/devicetree/bindings/sound/fsl,asrc.txt
index 65979b205893..f5a14115b459 100644
--- a/Documentation/devicetree/bindings/sound/fsl,asrc.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,asrc.txt
@@ -41,7 +41,7 @@ Required properties:
Example:
-asrc: asrc@02034000 {
+asrc: asrc@2034000 {
compatible = "fsl,imx53-asrc";
reg = <0x02034000 0x4000>;
interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/Documentation/devicetree/bindings/sound/fsl,esai.txt b/Documentation/devicetree/bindings/sound/fsl,esai.txt
index 21c401e2ccda..cacd18bb9ba6 100644
--- a/Documentation/devicetree/bindings/sound/fsl,esai.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,esai.txt
@@ -48,7 +48,7 @@ Required properties:
Example:
-esai: esai@02024000 {
+esai: esai@2024000 {
compatible = "fsl,imx35-esai";
reg = <0x02024000 0x4000>;
interrupts = <0 51 0x04>;
diff --git a/Documentation/devicetree/bindings/sound/fsl,spdif.txt b/Documentation/devicetree/bindings/sound/fsl,spdif.txt
index 0f97e54c3d43..38cfa7573441 100644
--- a/Documentation/devicetree/bindings/sound/fsl,spdif.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,spdif.txt
@@ -39,7 +39,7 @@ Required properties:
Example:
-spdif: spdif@02004000 {
+spdif: spdif@2004000 {
compatible = "fsl,imx35-spdif";
reg = <0x02004000 0x4000>;
interrupts = <0 52 0x04>;
diff --git a/Documentation/devicetree/bindings/sound/imx-audmux.txt b/Documentation/devicetree/bindings/sound/imx-audmux.txt
index b30a737e209e..2db4dcbee1b9 100644
--- a/Documentation/devicetree/bindings/sound/imx-audmux.txt
+++ b/Documentation/devicetree/bindings/sound/imx-audmux.txt
@@ -22,7 +22,7 @@ Required properties of optional child nodes:
Example:
-audmux@021d8000 {
+audmux@21d8000 {
compatible = "fsl,imx6q-audmux", "fsl,imx31-audmux";
reg = <0x021d8000 0x4000>;
};
diff --git a/Documentation/devicetree/bindings/sound/samsung-i2s.txt b/Documentation/devicetree/bindings/sound/samsung-i2s.txt
index 09e0e18591ae..bf100cd0d0f7 100644
--- a/Documentation/devicetree/bindings/sound/samsung-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/samsung-i2s.txt
@@ -63,7 +63,7 @@ Optional SoC Specific Properties:
Example:
-i2s0: i2s@03830000 {
+i2s0: i2s@3830000 {
compatible = "samsung,s5pv210-i2s";
reg = <0x03830000 0x100>;
dmas = <&pdma0 10
diff --git a/Documentation/devicetree/bindings/sound/sun4i-codec.txt b/Documentation/devicetree/bindings/sound/sun4i-codec.txt
index 2d4e10deb6f4..66579bbd3294 100644
--- a/Documentation/devicetree/bindings/sound/sun4i-codec.txt
+++ b/Documentation/devicetree/bindings/sound/sun4i-codec.txt
@@ -62,7 +62,7 @@ Required properties for the following compatibles:
block in the PRCM.
Example:
-codec: codec@01c22c00 {
+codec: codec@1c22c00 {
#sound-dai-cells = <0>;
compatible = "allwinner,sun7i-a20-codec";
reg = <0x01c22c00 0x40>;
@@ -73,7 +73,7 @@ codec: codec@01c22c00 {
dma-names = "rx", "tx";
};
-codec: codec@01c22c00 {
+codec: codec@1c22c00 {
#sound-dai-cells = <0>;
compatible = "allwinner,sun6i-a31-codec";
reg = <0x01c22c00 0x98>;
diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
index fc5da6080759..05d7135a8d2f 100644
--- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
@@ -28,7 +28,7 @@ Required properties for the following compatibles:
Example:
-i2s0: i2s@01c22400 {
+i2s0: i2s@1c22400 {
#sound-dai-cells = <0>;
compatible = "allwinner,sun4i-a10-i2s";
reg = <0x01c22400 0x400>;
diff --git a/Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt b/Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt
index 399b1b4bae22..2ca3d138528e 100644
--- a/Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt
+++ b/Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt
@@ -48,7 +48,7 @@ are similar to A33 using simple-card:
sound-dai = <&codec>;
};
- soc@01c00000 {
+ soc@1c00000 {
[...]
audio-codec@1c22e00 {
diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
index 1b6e7c4e50ab..07356758bd91 100644
--- a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
+++ b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
@@ -10,7 +10,7 @@ Required properties if not a sub-node of the PRCM node:
- reg: must contain the registers location and length
Example:
-prcm: prcm@01f01400 {
+prcm: prcm@1f01400 {
codec_analog: codec-analog {
compatible = "allwinner,sun8i-a23-codec-analog";
};
diff --git a/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt b/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt
index 70ee177901d3..0c64a209c2e9 100644
--- a/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt
+++ b/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt
@@ -31,7 +31,7 @@ Required properties:
Example:
-spdif: spdif@01c21000 {
+spdif: spdif@1c21000 {
compatible = "allwinner,sun4i-a10-spdif";
reg = <0x01c21000 0x40>;
interrupts = <13>;
diff --git a/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt b/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt
index b5a5ca4502f9..09231d7586b2 100644
--- a/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt
+++ b/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt
@@ -16,7 +16,7 @@ please check:
* dma/dma.txt
Example:
- spdif0: spdif0@0b004000 {
+ spdif0: spdif0@b004000 {
compatible = "zte,zx296702-spdif";
reg = <0x0b004000 0x1000>;
clocks = <&lsp0clk ZX296702_SPDIF0_DIV>;
diff --git a/Documentation/devicetree/bindings/spi/spi-sun4i.txt b/Documentation/devicetree/bindings/spi/spi-sun4i.txt
index 484bbff5337e..c75d604a8290 100644
--- a/Documentation/devicetree/bindings/spi/spi-sun4i.txt
+++ b/Documentation/devicetree/bindings/spi/spi-sun4i.txt
@@ -12,7 +12,7 @@ Required properties:
Example:
-spi1: spi@01c06000 {
+spi1: spi@1c06000 {
compatible = "allwinner,sun4i-a10-spi";
reg = <0x01c06000 0x1000>;
interrupts = <11>;
diff --git a/Documentation/devicetree/bindings/spi/spi-sun6i.txt b/Documentation/devicetree/bindings/spi/spi-sun6i.txt
index ab1811354cce..435a8e0731ac 100644
--- a/Documentation/devicetree/bindings/spi/spi-sun6i.txt
+++ b/Documentation/devicetree/bindings/spi/spi-sun6i.txt
@@ -19,7 +19,7 @@ Optional properties:
Example:
-spi1: spi@01c69000 {
+spi1: spi@1c69000 {
compatible = "allwinner,sun6i-a31-spi";
reg = <0x01c69000 0x1000>;
interrupts = <0 66 4>;
@@ -28,7 +28,7 @@ spi1: spi@01c69000 {
resets = <&ahb1_rst 21>;
};
-spi0: spi@01c68000 {
+spi0: spi@1c68000 {
compatible = "allwinner,sun8i-h3-spi";
reg = <0x01c68000 0x1000>;
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/Documentation/devicetree/bindings/sram/samsung-sram.txt b/Documentation/devicetree/bindings/sram/samsung-sram.txt
index 6bc474b2b885..61a9bbed303d 100644
--- a/Documentation/devicetree/bindings/sram/samsung-sram.txt
+++ b/Documentation/devicetree/bindings/sram/samsung-sram.txt
@@ -19,7 +19,7 @@ found in Documentation/devicetree/bindings/sram/sram.txt
Example:
- sysram@02020000 {
+ sysram@2020000 {
compatible = "mmio-sram";
reg = <0x02020000 0x54000>;
#address-cells = <1>;
diff --git a/Documentation/devicetree/bindings/sram/sunxi-sram.txt b/Documentation/devicetree/bindings/sram/sunxi-sram.txt
index 6bb92a1df753..d087f04a4d7f 100644
--- a/Documentation/devicetree/bindings/sram/sunxi-sram.txt
+++ b/Documentation/devicetree/bindings/sram/sunxi-sram.txt
@@ -47,7 +47,7 @@ This valid values for this argument are:
Example
-------
-sram-controller@01c00000 {
+sram-controller@1c00000 {
compatible = "allwinner,sun4i-a10-sram-controller";
reg = <0x01c00000 0x30>;
#address-cells = <1>;
@@ -68,7 +68,7 @@ sram-controller@01c00000 {
};
};
-emac: ethernet@01c0b000 {
+emac: ethernet@1c0b000 {
compatible = "allwinner,sun4i-a10-emac";
...
diff --git a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
index 8d6e4fd2468e..2c5c1be78360 100644
--- a/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
+++ b/Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
@@ -14,7 +14,7 @@ Optional properties:
Example:
-timer@01c60000 {
+timer@1c60000 {
compatible = "allwinner,sun7i-a20-hstimer";
reg = <0x01c60000 0x1000>;
interrupts = <0 51 1>,
diff --git a/Documentation/devicetree/bindings/trivial-devices.txt b/Documentation/devicetree/bindings/trivial-devices.txt
index af284fbd4d23..4b169caab0eb 100644
--- a/Documentation/devicetree/bindings/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/trivial-devices.txt
@@ -36,11 +36,9 @@ atmel,at97sc3204t i2c trusted platform module (TPM)
capella,cm32181 CM32181: Ambient Light Sensor
capella,cm3232 CM3232: Ambient Light Sensor
cirrus,cs42l51 Cirrus Logic CS42L51 audio codec
-dallas,ds1307 64 x 8, Serial, I2C Real-Time Clock
-dallas,ds1338 I2C RTC with 56-Byte NV RAM
-dallas,ds1340 I2C RTC with Trickle Charger
dallas,ds1374 I2C, 32-Bit Binary Counter Watchdog RTC with Trickle Charger and Reset Input/Output
dallas,ds1631 High-Precision Digital Thermometer
+dallas,ds1672 Dallas DS1672 Real-time Clock
dallas,ds1682 Total-Elapsed-Time Recorder with Alarm
dallas,ds1775 Tiny Digital Thermometer and Thermostat
dallas,ds3232 Extremely Accurate I²C RTC with Integrated Crystal and SRAM
@@ -54,8 +52,8 @@ dlg,da9063 DA9063: system PMIC for quad-core application processors
domintech,dmard09 DMARD09: 3-axis Accelerometer
domintech,dmard10 DMARD10: 3-axis Accelerometer
epson,rx8010 I2C-BUS INTERFACE REAL TIME CLOCK MODULE
-epson,rx8025 High-Stability. I2C-Bus INTERFACE REAL TIME CLOCK MODULE
epson,rx8581 I2C-BUS INTERFACE REAL TIME CLOCK MODULE
+emmicro,em3027 EM Microelectronic EM3027 Real-time Clock
fsl,mag3110 MAG3110: Xtrinsic High Accuracy, 3D Magnetometer
fsl,mc13892 MC13892: Power Management Integrated Circuit (PMIC) for i.MX35/51
fsl,mma7660 MMA7660FC: 3-Axis Orientation/Motion Detection Sensor
@@ -67,6 +65,8 @@ gmt,g751 G751: Digital Temperature Sensor and Thermal Watchdog with Two-Wire In
infineon,slb9635tt Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz)
infineon,slb9645tt Infineon SLB9645 I2C TPM (new protocol, max 400khz)
isil,isl1208 Intersil ISL1208 Low Power RTC with Battery Backed SRAM
+isil,isl1218 Intersil ISL1218 Low Power RTC with Battery Backed SRAM
+isil,isl12022 Intersil ISL12022 Real-time Clock
isil,isl29028 Intersil ISL29028 Ambient Light and Proximity Sensor
isil,isl29030 Intersil ISL29030 Ambient Light and Proximity Sensor
maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator
@@ -155,6 +155,7 @@ nxp,pca9556 Octal SMBus and I2C registered interface
nxp,pca9557 8-bit I2C-bus and SMBus I/O port with reset
nxp,pcf2127 Real-time clock
nxp,pcf2129 Real-time clock
+nxp,pcf8523 Real-time Clock
nxp,pcf8563 Real-time clock/calendar
nxp,pcf85063 Tiny Real-Time Clock
oki,ml86v7667 OKI ML86V7667 video decoder
@@ -174,10 +175,6 @@ sii,s35390a 2-wire CMOS real-time clock
silabs,si7020 Relative Humidity and Temperature Sensors
skyworks,sky81452 Skyworks SKY81452: Six-Channel White LED Driver with Touch Panel Bias Supply
st,24c256 i2c serial eeprom (24cxx)
-st,m41t0 Serial real-time clock (RTC)
-st,m41t00 Serial real-time clock (RTC)
-st,m41t62 Serial real-time clock (RTC) with alarm
-st,m41t80 M41T80 - SERIAL ACCESS RTC WITH ALARMS
taos,tsl2550 Ambient Light Sensor with SMBUS/Two Wire Serial Interface
ti,ads7828 8-Channels, 12-bit ADC
ti,ads7830 8-Channels, 8-bit ADC
diff --git a/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt
index cb2bd83fa89a..50abb20fe319 100644
--- a/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt
+++ b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt
@@ -16,7 +16,7 @@ Required properties:
Example:
- usb_otg: usb@01c13000 {
+ usb_otg: usb@1c13000 {
compatible = "allwinner,sun4i-a10-musb";
reg = <0x01c13000 0x0400>;
clocks = <&ahb_gates 0>;
diff --git a/Documentation/devicetree/bindings/usb/am33xx-usb.txt b/Documentation/devicetree/bindings/usb/am33xx-usb.txt
index 16920d78e1b8..7a33f22c815a 100644
--- a/Documentation/devicetree/bindings/usb/am33xx-usb.txt
+++ b/Documentation/devicetree/bindings/usb/am33xx-usb.txt
@@ -181,7 +181,7 @@ usb: usb@47400000 {
"tx14", "tx15";
};
- cppi41dma: dma-controller@07402000 {
+ cppi41dma: dma-controller@7402000 {
compatible = "ti,am3359-cppi41";
reg = <0x47400000 0x1000
0x47402000 0x1000
diff --git a/Documentation/devicetree/bindings/usb/atmel-usb.txt b/Documentation/devicetree/bindings/usb/atmel-usb.txt
index ad8ea56a9ed3..44e80153b148 100644
--- a/Documentation/devicetree/bindings/usb/atmel-usb.txt
+++ b/Documentation/devicetree/bindings/usb/atmel-usb.txt
@@ -18,7 +18,7 @@ Required properties:
- atmel,oc-gpio: If present, specifies a gpio that needs to be
activated for the overcurrent detection.
-usb0: ohci@00500000 {
+usb0: ohci@500000 {
compatible = "atmel,at91rm9200-ohci", "usb-ohci";
reg = <0x00500000 0x100000>;
clocks = <&uhphs_clk>, <&uhphs_clk>, <&uhpck>;
@@ -39,7 +39,7 @@ Required properties:
"ehci_clk" for the peripheral clock
"usb_clk" for the UTMI clock
-usb1: ehci@00800000 {
+usb1: ehci@800000 {
compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
reg = <0x00800000 0x100000>;
interrupts = <22 4>;
diff --git a/Documentation/devicetree/bindings/usb/ohci-da8xx.txt b/Documentation/devicetree/bindings/usb/ohci-da8xx.txt
index 2dc8f67eda39..24a826d5015e 100644
--- a/Documentation/devicetree/bindings/usb/ohci-da8xx.txt
+++ b/Documentation/devicetree/bindings/usb/ohci-da8xx.txt
@@ -13,7 +13,7 @@ Optional properties:
Example:
-ohci: usb@0225000 {
+ohci: usb@225000 {
compatible = "ti,da830-ohci";
reg = <0x225000 0x1000>;
interrupts = <59>;
diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt b/Documentation/devicetree/bindings/usb/usb-ehci.txt
index a12d6012a40f..3efde12b5d68 100644
--- a/Documentation/devicetree/bindings/usb/usb-ehci.txt
+++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt
@@ -30,7 +30,7 @@ Example (Sequoia 440EPx):
};
Example (Allwinner sun4i A10 SoC):
- ehci0: usb@01c14000 {
+ ehci0: usb@1c14000 {
compatible = "allwinner,sun4i-a10-ehci", "generic-ehci";
reg = <0x01c14000 0x100>;
interrupts = <39>;
diff --git a/Documentation/devicetree/bindings/usb/usb-ohci.txt b/Documentation/devicetree/bindings/usb/usb-ohci.txt
index e8766b08c93b..09e70c875bc6 100644
--- a/Documentation/devicetree/bindings/usb/usb-ohci.txt
+++ b/Documentation/devicetree/bindings/usb/usb-ohci.txt
@@ -19,7 +19,7 @@ Optional properties:
Example:
- ohci0: usb@01c14400 {
+ ohci0: usb@1c14400 {
compatible = "allwinner,sun4i-a10-ohci", "generic-ohci";
reg = <0x01c14400 0x100>;
interrupts = <64>;
diff --git a/Documentation/devicetree/bindings/usb/usb3503.txt b/Documentation/devicetree/bindings/usb/usb3503.txt
index c1a0a9191d26..057dd384d473 100644
--- a/Documentation/devicetree/bindings/usb/usb3503.txt
+++ b/Documentation/devicetree/bindings/usb/usb3503.txt
@@ -26,7 +26,7 @@ Optional properties:
clock frequencies table is used)
Examples:
- usb3503@08 {
+ usb3503@8 {
compatible = "smsc,usb3503";
reg = <0x08>;
connect-gpios = <&gpx3 0 1>;
diff --git a/Documentation/devicetree/bindings/usb/usbmisc-imx.txt b/Documentation/devicetree/bindings/usb/usbmisc-imx.txt
index f1e27faf528e..a85a631ec434 100644
--- a/Documentation/devicetree/bindings/usb/usbmisc-imx.txt
+++ b/Documentation/devicetree/bindings/usb/usbmisc-imx.txt
@@ -10,7 +10,7 @@ Required properties:
- reg: Should contain registers location and length
Examples:
-usbmisc@02184800 {
+usbmisc@2184800 {
#index-cells = <1>;
compatible = "fsl,imx6q-usbmisc";
reg = <0x02184800 0x200>;
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 1ea1fd4232ab..b2c1b8d80367 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -83,6 +83,7 @@ davicom DAVICOM Semiconductor, Inc.
delta Delta Electronics, Inc.
denx Denx Software Engineering
devantech Devantech, Ltd.
+dh DH electronics GmbH
digi Digi International Inc.
digilent Diglent, Inc.
dioo Dioo Microcircuit Co., Ltd
@@ -229,12 +230,14 @@ netlogic Broadcom Corporation (formerly NetLogic Microsystems)
netron-dy Netron DY
netxeon Shenzhen Netxeon Technology CO., LTD
nexbox Nexbox
+nextthing Next Thing Co.
newhaven Newhaven Display International
ni National Instruments
nintendo Nintendo
nlt NLT Technologies, Ltd.
nokia Nokia
nordic Nordic Semiconductor
+nutsboard NutsBoard
nuvoton Nuvoton Technology Corporation
nvd New Vision Display
nvidia NVIDIA
@@ -245,6 +248,7 @@ olimex OLIMEX Ltd.
onion Onion Corporation
onnn ON Semiconductor Corp.
ontat On Tat Industrial Company
+opalkelly Opal Kelly Incorporated
opencores OpenCores.org
option Option NV
ORCL Oracle Corporation
@@ -296,6 +300,7 @@ sensirion Sensirion AG
sff Small Form Factor Committee
sgx SGX Sensortech
sharp Sharp Corporation
+shimafuji Shimafuji Electric, Inc.
si-en Si-En Technology Ltd.
sigma Sigma Designs, Inc.
sii Seiko Instruments, Inc.
@@ -317,6 +322,7 @@ solomon Solomon Systech Limited
sony Sony Corporation
spansion Spansion Inc.
sprd Spreadtrum Communications Inc.
+sst Silicon Storage Technology, Inc.
st STMicroelectronics
starry Starry Electronic Technology (ShenZhen) Co., LTD
startek Startek
@@ -338,6 +344,7 @@ thine THine Electronics, Inc.
ti Texas Instruments
tianma Tianma Micro-electronics Co., Ltd.
tlm Trusted Logic Mobility
+tmt Tecon Microprocessor Technologies, LLC.
topeet Topeet
toradex Toradex AG
toshiba Toshiba Corporation
diff --git a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
index 235de0683bb6..5b38a30e608c 100644
--- a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
@@ -13,7 +13,7 @@ Required properties:
Example:
-wdt: watchdog@010000000 {
+wdt: watchdog@10000000 {
compatible = "mediatek,mt6589-wdt";
reg = <0x10000000 0x18>;
};
diff --git a/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt b/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt
index b8f75c51453a..62dd5baad70e 100644
--- a/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt
@@ -8,7 +8,7 @@ Required properties:
Example:
-wdt: watchdog@01c20c90 {
+wdt: watchdog@1c20c90 {
compatible = "allwinner,sun4i-a10-wdt";
reg = <0x01c20c90 0x10>;
};
diff --git a/Documentation/devicetree/overlay-notes.txt b/Documentation/devicetree/overlay-notes.txt
index eb7f2685fda1..c4aa0adf13ec 100644
--- a/Documentation/devicetree/overlay-notes.txt
+++ b/Documentation/devicetree/overlay-notes.txt
@@ -87,15 +87,15 @@ Overlay in-kernel API
The API is quite easy to use.
-1. Call of_overlay_create() to create and apply an overlay. The return value
-is a cookie identifying this overlay.
+1. Call of_overlay_apply() to create and apply an overlay changeset. The return
+value is an error or a cookie identifying this overlay.
-2. Call of_overlay_destroy() to remove and cleanup the overlay previously
-created via the call to of_overlay_create(). Removal of an overlay that
-is stacked by another will not be permitted.
+2. Call of_overlay_remove() to remove and cleanup the overlay changeset
+previously created via the call to of_overlay_apply(). Removal of an overlay
+changeset that is stacked by another will not be permitted.
Finally, if you need to remove all overlays in one-go, just call
-of_overlay_destroy_all() which will remove every single one in the correct
+of_overlay_remove_all() which will remove every single one in the correct
order.
Overlay DTS Format
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index 783f36364690..2e2efb1af511 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -75,24 +75,17 @@ static struct property *dlpar_parse_cc_property(struct cc_workarea *ccwa)
return prop;
}
-static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa,
- const char *path)
+static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa)
{
struct device_node *dn;
- char *name;
-
- /* If parent node path is "/" advance path to NULL terminator to
- * prevent double leading slashs in full_name.
- */
- if (!path[1])
- path++;
+ const char *name;
dn = kzalloc(sizeof(*dn), GFP_KERNEL);
if (!dn)
return NULL;
- name = (char *)ccwa + be32_to_cpu(ccwa->name_offset);
- dn->full_name = kasprintf(GFP_KERNEL, "%s/%s", path, name);
+ name = (const char *)ccwa + be32_to_cpu(ccwa->name_offset);
+ dn->full_name = kstrdup(name, GFP_KERNEL);
if (!dn->full_name) {
kfree(dn);
return NULL;
@@ -148,7 +141,6 @@ struct device_node *dlpar_configure_connector(__be32 drc_index,
struct property *last_property = NULL;
struct cc_workarea *ccwa;
char *data_buf;
- const char *parent_path = parent->full_name;
int cc_token;
int rc = -1;
@@ -182,7 +174,7 @@ struct device_node *dlpar_configure_connector(__be32 drc_index,
break;
case NEXT_SIBLING:
- dn = dlpar_parse_cc_node(ccwa, parent_path);
+ dn = dlpar_parse_cc_node(ccwa);
if (!dn)
goto cc_error;
@@ -192,10 +184,7 @@ struct device_node *dlpar_configure_connector(__be32 drc_index,
break;
case NEXT_CHILD:
- if (first_dn)
- parent_path = last_dn->full_name;
-
- dn = dlpar_parse_cc_node(ccwa, parent_path);
+ dn = dlpar_parse_cc_node(ccwa);
if (!dn)
goto cc_error;
@@ -226,7 +215,6 @@ struct device_node *dlpar_configure_connector(__be32 drc_index,
case PREV_PARENT:
last_dn = last_dn->parent;
- parent_path = last_dn->parent->full_name;
break;
case CALL_AGAIN:
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 296c188fd5ca..f24d8159c9e1 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -33,7 +33,7 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist
if (!np)
goto out_err;
- np->full_name = kstrdup(path, GFP_KERNEL);
+ np->full_name = kstrdup(kbasename(path), GFP_KERNEL);
if (!np->full_name)
goto out_err;
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 12ebd055724c..c07b47059538 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1571,7 +1571,7 @@ static int device_add_class_symlinks(struct device *dev)
int error;
if (of_node) {
- error = sysfs_create_link(&dev->kobj, &of_node->kobj,"of_node");
+ error = sysfs_create_link(&dev->kobj, of_node_kobj(of_node), "of_node");
if (error)
dev_warn(dev, "Error %d creating of_node link\n",error);
/* An error here doesn't warrant bringing down the device */
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c
index 623a9140493c..54025af534d4 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c
@@ -145,7 +145,6 @@ static struct device_node * __init tilcdc_get_overlay(struct kfree_table *kft)
__dtb_tilcdc_slave_compat_begin;
static void *overlay_data;
struct device_node *overlay;
- int ret;
if (!size) {
pr_warn("%s: No overlay data\n", __func__);
@@ -164,11 +163,6 @@ static struct device_node * __init tilcdc_get_overlay(struct kfree_table *kft)
}
of_node_set_flag(overlay, OF_DETACHED);
- ret = of_resolve_phandles(overlay);
- if (ret) {
- pr_err("%s: Failed to resolve phandles: %d\n", __func__, ret);
- return NULL;
- }
return overlay;
}
@@ -204,7 +198,7 @@ static void __init tilcdc_convert_slave_node(void)
/* For all memory needed for the overlay tree. This memory can
be freed after the overlay has been applied. */
struct kfree_table kft;
- int ret;
+ int ovcs_id, ret;
if (kfree_table_init(&kft))
return;
@@ -247,9 +241,11 @@ static void __init tilcdc_convert_slave_node(void)
tilcdc_node_disable(slave);
- ret = of_overlay_create(overlay);
+ ovcs_id = 0;
+ ret = of_overlay_apply(overlay, &ovcs_id);
if (ret)
- pr_err("%s: Creating overlay failed: %d\n", __func__, ret);
+ pr_err("%s: Applying overlay changeset failed: %d\n",
+ __func__, ret);
else
pr_info("%s: ti,tilcdc,slave node successfully converted\n",
__func__);
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index ba7b034b2b91..ad9a9578f9c4 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -46,10 +46,14 @@ config OF_EARLY_FLATTREE
config OF_PROMTREE
bool
+config OF_KOBJ
+ def_bool SYSFS
+
# Hardly any platforms need this. It is safe to select, but only do so if you
# need it.
config OF_DYNAMIC
bool "Support for dynamic device trees" if OF_UNITTEST
+ select OF_KOBJ
help
On some platforms, the device tree can be manipulated at runtime.
While this option is selected automatically on such platforms, you
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 97dc01c81438..83d61a7c5e82 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -1,4 +1,5 @@
obj-y = base.o device.o platform.o property.o
+obj-$(CONFIG_OF_KOBJ) += kobj.o
obj-$(CONFIG_OF_DYNAMIC) += dynamic.o
obj-$(CONFIG_OF_FLATTREE) += fdt.o
obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 260d33c0f26c..3de07e6e82a0 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -95,108 +95,6 @@ int __weak of_node_to_nid(struct device_node *np)
}
#endif
-#ifndef CONFIG_OF_DYNAMIC
-static void of_node_release(struct kobject *kobj)
-{
- /* Without CONFIG_OF_DYNAMIC, no nodes gets freed */
-}
-#endif /* CONFIG_OF_DYNAMIC */
-
-struct kobj_type of_node_ktype = {
- .release = of_node_release,
-};
-
-static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr, char *buf,
- loff_t offset, size_t count)
-{
- struct property *pp = container_of(bin_attr, struct property, attr);
- return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length);
-}
-
-/* always return newly allocated name, caller must free after use */
-static const char *safe_name(struct kobject *kobj, const char *orig_name)
-{
- const char *name = orig_name;
- struct kernfs_node *kn;
- int i = 0;
-
- /* don't be a hero. After 16 tries give up */
- while (i < 16 && (kn = sysfs_get_dirent(kobj->sd, name))) {
- sysfs_put(kn);
- if (name != orig_name)
- kfree(name);
- name = kasprintf(GFP_KERNEL, "%s#%i", orig_name, ++i);
- }
-
- if (name == orig_name) {
- name = kstrdup(orig_name, GFP_KERNEL);
- } else {
- pr_warn("Duplicate name in %s, renamed to \"%s\"\n",
- kobject_name(kobj), name);
- }
- return name;
-}
-
-int __of_add_property_sysfs(struct device_node *np, struct property *pp)
-{
- int rc;
-
- /* Important: Don't leak passwords */
- bool secure = strncmp(pp->name, "security-", 9) == 0;
-
- if (!IS_ENABLED(CONFIG_SYSFS))
- return 0;
-
- if (!of_kset || !of_node_is_attached(np))
- return 0;
-
- sysfs_bin_attr_init(&pp->attr);
- pp->attr.attr.name = safe_name(&np->kobj, pp->name);
- pp->attr.attr.mode = secure ? 0400 : 0444;
- pp->attr.size = secure ? 0 : pp->length;
- pp->attr.read = of_node_property_read;
-
- rc = sysfs_create_bin_file(&np->kobj, &pp->attr);
- WARN(rc, "error adding attribute %s to node %pOF\n", pp->name, np);
- return rc;
-}
-
-int __of_attach_node_sysfs(struct device_node *np)
-{
- const char *name;
- struct kobject *parent;
- struct property *pp;
- int rc;
-
- if (!IS_ENABLED(CONFIG_SYSFS))
- return 0;
-
- if (!of_kset)
- return 0;
-
- np->kobj.kset = of_kset;
- if (!np->parent) {
- /* Nodes without parents are new top level trees */
- name = safe_name(&of_kset->kobj, "base");
- parent = NULL;
- } else {
- name = safe_name(&np->parent->kobj, kbasename(np->full_name));
- parent = &np->parent->kobj;
- }
- if (!name)
- return -ENOMEM;
- rc = kobject_add(&np->kobj, parent, "%s", name);
- kfree(name);
- if (rc)
- return rc;
-
- for_each_property_of_node(np, pp)
- __of_add_property_sysfs(np, pp);
-
- return 0;
-}
-
void __init of_core_init(void)
{
struct device_node *np;
@@ -760,7 +658,7 @@ struct device_node *of_get_child_by_name(const struct device_node *node,
}
EXPORT_SYMBOL(of_get_child_by_name);
-static struct device_node *__of_find_node_by_path(struct device_node *parent,
+struct device_node *__of_find_node_by_path(struct device_node *parent,
const char *path)
{
struct device_node *child;
@@ -1504,22 +1402,6 @@ int __of_remove_property(struct device_node *np, struct property *prop)
return 0;
}
-void __of_sysfs_remove_bin_file(struct device_node *np, struct property *prop)
-{
- sysfs_remove_bin_file(&np->kobj, &prop->attr);
- kfree(prop->attr.attr.name);
-}
-
-void __of_remove_property_sysfs(struct device_node *np, struct property *prop)
-{
- if (!IS_ENABLED(CONFIG_SYSFS))
- return;
-
- /* at early boot, bail here and defer setup to of_init() */
- if (of_kset && of_node_is_attached(np))
- __of_sysfs_remove_bin_file(np, prop);
-}
-
/**
* of_remove_property - Remove a property from a node.
*
@@ -1579,21 +1461,6 @@ int __of_update_property(struct device_node *np, struct property *newprop,
return 0;
}
-void __of_update_property_sysfs(struct device_node *np, struct property *newprop,
- struct property *oldprop)
-{
- if (!IS_ENABLED(CONFIG_SYSFS))
- return;
-
- /* At early boot, bail out and defer setup to of_init() */
- if (!of_kset)
- return;
-
- if (oldprop)
- __of_sysfs_remove_bin_file(np, oldprop);
- __of_add_property_sysfs(np, newprop);
-}
-
/*
* of_update_property - Update a property in a node, if the property does
* not exist, add it.
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 301b6db2b48d..c454941b34ec 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -16,6 +16,11 @@
#include "of_private.h"
+static struct device_node *kobj_to_device_node(struct kobject *kobj)
+{
+ return container_of(kobj, struct device_node, kobj);
+}
+
/**
* of_node_get() - Increment refcount of a node
* @node: Node to inc refcount, NULL is supported to simplify writing of
@@ -43,28 +48,6 @@ void of_node_put(struct device_node *node)
}
EXPORT_SYMBOL(of_node_put);
-void __of_detach_node_sysfs(struct device_node *np)
-{
- struct property *pp;
-
- if (!IS_ENABLED(CONFIG_SYSFS))
- return;
-
- BUG_ON(!of_node_is_initialized(np));
- if (!of_kset)
- return;
-
- /* only remove properties if on sysfs */
- if (of_node_is_attached(np)) {
- for_each_property_of_node(np, pp)
- __of_sysfs_remove_bin_file(np, pp);
- kobject_del(&np->kobj);
- }
-
- /* finally remove the kobj_init ref */
- of_node_put(np);
-}
-
static BLOCKING_NOTIFIER_HEAD(of_reconfig_chain);
int of_reconfig_notifier_register(struct notifier_block *nb)
@@ -315,6 +298,18 @@ int of_detach_node(struct device_node *np)
}
EXPORT_SYMBOL_GPL(of_detach_node);
+static void property_list_free(struct property *prop_list)
+{
+ struct property *prop, *next;
+
+ for (prop = prop_list; prop != NULL; prop = next) {
+ next = prop->next;
+ kfree(prop->name);
+ kfree(prop->value);
+ kfree(prop);
+ }
+}
+
/**
* of_node_release() - release a dynamically allocated node
* @kref: kref element of the node to be released
@@ -324,7 +319,6 @@ EXPORT_SYMBOL_GPL(of_detach_node);
void of_node_release(struct kobject *kobj)
{
struct device_node *node = kobj_to_device_node(kobj);
- struct property *prop = node->properties;
/* We should never be releasing nodes that haven't been detached. */
if (!of_node_check_flag(node, OF_DETACHED)) {
@@ -335,18 +329,9 @@ void of_node_release(struct kobject *kobj)
if (!of_node_check_flag(node, OF_DYNAMIC))
return;
- while (prop) {
- struct property *next = prop->next;
- kfree(prop->name);
- kfree(prop->value);
- kfree(prop);
- prop = next;
+ property_list_free(node->properties);
+ property_list_free(node->deadprops);
- if (!prop) {
- prop = node->deadprops;
- node->deadprops = NULL;
- }
- }
kfree(node->full_name);
kfree(node->data);
kfree(node);
@@ -508,11 +493,12 @@ static void __of_changeset_entry_invert(struct of_changeset_entry *ce,
}
}
-static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool revert)
+static int __of_changeset_entry_notify(struct of_changeset_entry *ce,
+ bool revert)
{
struct of_reconfig_data rd;
struct of_changeset_entry ce_inverted;
- int ret;
+ int ret = 0;
if (revert) {
__of_changeset_entry_invert(ce, &ce_inverted);
@@ -534,11 +520,12 @@ static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool reve
default:
pr_err("invalid devicetree changeset action: %i\n",
(int)ce->action);
- return;
+ ret = -EINVAL;
}
if (ret)
pr_err("changeset notifier error @%pOF\n", ce->np);
+ return ret;
}
static int __of_changeset_entry_apply(struct of_changeset_entry *ce)
@@ -672,32 +659,82 @@ void of_changeset_destroy(struct of_changeset *ocs)
}
EXPORT_SYMBOL_GPL(of_changeset_destroy);
-int __of_changeset_apply(struct of_changeset *ocs)
+/*
+ * Apply the changeset entries in @ocs.
+ * If apply fails, an attempt is made to revert the entries that were
+ * successfully applied.
+ *
+ * If multiple revert errors occur then only the final revert error is reported.
+ *
+ * Returns 0 on success, a negative error value in case of an error.
+ * If a revert error occurs, it is returned in *ret_revert.
+ */
+int __of_changeset_apply_entries(struct of_changeset *ocs, int *ret_revert)
{
struct of_changeset_entry *ce;
- int ret;
+ int ret, ret_tmp;
- /* perform the rest of the work */
pr_debug("changeset: applying...\n");
list_for_each_entry(ce, &ocs->entries, node) {
ret = __of_changeset_entry_apply(ce);
if (ret) {
pr_err("Error applying changeset (%d)\n", ret);
- list_for_each_entry_continue_reverse(ce, &ocs->entries, node)
- __of_changeset_entry_revert(ce);
+ list_for_each_entry_continue_reverse(ce, &ocs->entries,
+ node) {
+ ret_tmp = __of_changeset_entry_revert(ce);
+ if (ret_tmp)
+ *ret_revert = ret_tmp;
+ }
return ret;
}
}
- pr_debug("changeset: applied, emitting notifiers.\n");
+
+ return 0;
+}
+
+/*
+ * Returns 0 on success, a negative error value in case of an error.
+ *
+ * If multiple changset entry notification errors occur then only the
+ * final notification error is reported.
+ */
+int __of_changeset_apply_notify(struct of_changeset *ocs)
+{
+ struct of_changeset_entry *ce;
+ int ret = 0, ret_tmp;
+
+ pr_debug("changeset: emitting notifiers.\n");
/* drop the global lock while emitting notifiers */
mutex_unlock(&of_mutex);
- list_for_each_entry(ce, &ocs->entries, node)
- __of_changeset_entry_notify(ce, 0);
+ list_for_each_entry(ce, &ocs->entries, node) {
+ ret_tmp = __of_changeset_entry_notify(ce, 0);
+ if (ret_tmp)
+ ret = ret_tmp;
+ }
mutex_lock(&of_mutex);
pr_debug("changeset: notifiers sent.\n");
- return 0;
+ return ret;
+}
+
+/*
+ * Returns 0 on success, a negative error value in case of an error.
+ *
+ * If a changeset entry apply fails, an attempt is made to revert any
+ * previous entries in the changeset. If any of the reverts fails,
+ * that failure is not reported. Thus the state of the device tree
+ * is unknown if an apply error occurs.
+ */
+static int __of_changeset_apply(struct of_changeset *ocs)
+{
+ int ret, ret_revert = 0;
+
+ ret = __of_changeset_apply_entries(ocs, &ret_revert);
+ if (!ret)
+ ret = __of_changeset_apply_notify(ocs);
+
+ return ret;
}
/**
@@ -724,31 +761,74 @@ int of_changeset_apply(struct of_changeset *ocs)
}
EXPORT_SYMBOL_GPL(of_changeset_apply);
-int __of_changeset_revert(struct of_changeset *ocs)
+/*
+ * Revert the changeset entries in @ocs.
+ * If revert fails, an attempt is made to re-apply the entries that were
+ * successfully removed.
+ *
+ * If multiple re-apply errors occur then only the final apply error is
+ * reported.
+ *
+ * Returns 0 on success, a negative error value in case of an error.
+ * If an apply error occurs, it is returned in *ret_apply.
+ */
+int __of_changeset_revert_entries(struct of_changeset *ocs, int *ret_apply)
{
struct of_changeset_entry *ce;
- int ret;
+ int ret, ret_tmp;
pr_debug("changeset: reverting...\n");
list_for_each_entry_reverse(ce, &ocs->entries, node) {
ret = __of_changeset_entry_revert(ce);
if (ret) {
pr_err("Error reverting changeset (%d)\n", ret);
- list_for_each_entry_continue(ce, &ocs->entries, node)
- __of_changeset_entry_apply(ce);
+ list_for_each_entry_continue(ce, &ocs->entries, node) {
+ ret_tmp = __of_changeset_entry_apply(ce);
+ if (ret_tmp)
+ *ret_apply = ret_tmp;
+ }
return ret;
}
}
- pr_debug("changeset: reverted, emitting notifiers.\n");
+
+ return 0;
+}
+
+/*
+ * If multiple changset entry notification errors occur then only the
+ * final notification error is reported.
+ */
+int __of_changeset_revert_notify(struct of_changeset *ocs)
+{
+ struct of_changeset_entry *ce;
+ int ret = 0, ret_tmp;
+
+ pr_debug("changeset: emitting notifiers.\n");
/* drop the global lock while emitting notifiers */
mutex_unlock(&of_mutex);
- list_for_each_entry_reverse(ce, &ocs->entries, node)
- __of_changeset_entry_notify(ce, 1);
+ list_for_each_entry_reverse(ce, &ocs->entries, node) {
+ ret_tmp = __of_changeset_entry_notify(ce, 1);
+ if (ret_tmp)
+ ret = ret_tmp;
+ }
mutex_lock(&of_mutex);
pr_debug("changeset: notifiers sent.\n");
- return 0;
+ return ret;
+}
+
+static int __of_changeset_revert(struct of_changeset *ocs)
+{
+ int ret, ret_reply;
+
+ ret_reply = 0;
+ ret = __of_changeset_revert_entries(ocs, &ret_reply);
+
+ if (!ret)
+ ret = __of_changeset_revert_notify(ocs);
+
+ return ret;
}
/**
@@ -775,7 +855,7 @@ int of_changeset_revert(struct of_changeset *ocs)
EXPORT_SYMBOL_GPL(of_changeset_revert);
/**
- * of_changeset_action - Perform a changeset action
+ * of_changeset_action - Add an action to the tail of the changeset list
*
* @ocs: changeset pointer
* @action: action to perform
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index ce30c9a588a4..4675e5ac4d11 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -132,6 +132,19 @@ bool of_fdt_is_big_endian(const void *blob, unsigned long node)
return false;
}
+static bool of_fdt_device_is_available(const void *blob, unsigned long node)
+{
+ const char *status = fdt_getprop(blob, node, "status", NULL);
+
+ if (!status)
+ return true;
+
+ if (!strcmp(status, "ok") || !strcmp(status, "okay"))
+ return true;
+
+ return false;
+}
+
/**
* of_fdt_match - Return true if node matches a list of compatible values
*/
@@ -266,74 +279,32 @@ static void populate_properties(const void *blob,
*pprev = NULL;
}
-static unsigned int populate_node(const void *blob,
- int offset,
- void **mem,
- struct device_node *dad,
- unsigned int fpsize,
- struct device_node **pnp,
- bool dryrun)
+static bool populate_node(const void *blob,
+ int offset,
+ void **mem,
+ struct device_node *dad,
+ struct device_node **pnp,
+ bool dryrun)
{
struct device_node *np;
const char *pathp;
unsigned int l, allocl;
- int new_format = 0;
pathp = fdt_get_name(blob, offset, &l);
if (!pathp) {
*pnp = NULL;
- return 0;
+ return false;
}
allocl = ++l;
- /* version 0x10 has a more compact unit name here instead of the full
- * path. we accumulate the full path size using "fpsize", we'll rebuild
- * it later. We detect this because the first character of the name is
- * not '/'.
- */
- if ((*pathp) != '/') {
- new_format = 1;
- if (fpsize == 0) {
- /* root node: special case. fpsize accounts for path
- * plus terminating zero. root node only has '/', so
- * fpsize should be 2, but we want to avoid the first
- * level nodes to have two '/' so we use fpsize 1 here
- */
- fpsize = 1;
- allocl = 2;
- l = 1;
- pathp = "";
- } else {
- /* account for '/' and path size minus terminal 0
- * already in 'l'
- */
- fpsize += l;
- allocl = fpsize;
- }
- }
-
np = unflatten_dt_alloc(mem, sizeof(struct device_node) + allocl,
__alignof__(struct device_node));
if (!dryrun) {
char *fn;
of_node_init(np);
np->full_name = fn = ((char *)np) + sizeof(*np);
- if (new_format) {
- /* rebuild full path for new format */
- if (dad && dad->parent) {
- strcpy(fn, dad->full_name);
-#ifdef DEBUG
- if ((strlen(fn) + l + 1) != allocl) {
- pr_debug("%s: p: %d, l: %d, a: %d\n",
- pathp, (int)strlen(fn),
- l, allocl);
- }
-#endif
- fn += strlen(fn);
- }
- *(fn++) = '/';
- }
+
memcpy(fn, pathp, l);
if (dad != NULL) {
@@ -355,7 +326,7 @@ static unsigned int populate_node(const void *blob,
}
*pnp = np;
- return fpsize;
+ return true;
}
static void reverse_nodes(struct device_node *parent)
@@ -399,7 +370,6 @@ static int unflatten_dt_nodes(const void *blob,
struct device_node *root;
int offset = 0, depth = 0, initial_depth = 0;
#define FDT_MAX_DEPTH 64
- unsigned int fpsizes[FDT_MAX_DEPTH];
struct device_node *nps[FDT_MAX_DEPTH];
void *base = mem;
bool dryrun = !base;
@@ -418,7 +388,6 @@ static int unflatten_dt_nodes(const void *blob,
depth = initial_depth = 1;
root = dad;
- fpsizes[depth] = dad ? strlen(of_node_full_name(dad)) : 0;
nps[depth] = dad;
for (offset = 0;
@@ -427,11 +396,12 @@ static int unflatten_dt_nodes(const void *blob,
if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH))
continue;
- fpsizes[depth+1] = populate_node(blob, offset, &mem,
- nps[depth],
- fpsizes[depth],
- &nps[depth+1], dryrun);
- if (!fpsizes[depth+1])
+ if (!IS_ENABLED(CONFIG_OF_KOBJ) &&
+ !of_fdt_device_is_available(blob, offset))
+ continue;
+
+ if (!populate_node(blob, offset, &mem, nps[depth],
+ &nps[depth+1], dryrun))
return mem - base;
if (!dryrun && nodepp && !*nodepp)
@@ -467,6 +437,7 @@ static int unflatten_dt_nodes(const void *blob,
* @mynodes: The device_node tree created by the call
* @dt_alloc: An allocator that provides a virtual address to memory
* for the resulting tree
+ * @detached: if true set OF_DETACHED on @mynodes
*
* Returns NULL on failure or the memory chunk containing the unflattened
* device tree on success.
@@ -652,7 +623,6 @@ static int __init __fdt_scan_reserved_mem(unsigned long node, const char *uname,
int depth, void *data)
{
static int found;
- const char *status;
int err;
if (!found && depth == 1 && strcmp(uname, "reserved-memory") == 0) {
@@ -672,8 +642,7 @@ static int __init __fdt_scan_reserved_mem(unsigned long node, const char *uname,
return 1;
}
- status = of_get_flat_dt_prop(node, "status", NULL);
- if (status && strcmp(status, "okay") != 0 && strcmp(status, "ok") != 0)
+ if (!of_fdt_device_is_available(initial_boot_params, node))
return 0;
err = __reserved_mem_reserve_reg(node, uname);
diff --git a/drivers/of/kobj.c b/drivers/of/kobj.c
new file mode 100644
index 000000000000..250fc7bb550f
--- /dev/null
+++ b/drivers/of/kobj.c
@@ -0,0 +1,164 @@
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#include "of_private.h"
+
+/* true when node is initialized */
+static int of_node_is_initialized(struct device_node *node)
+{
+ return node && node->kobj.state_initialized;
+}
+
+/* true when node is attached (i.e. present on sysfs) */
+int of_node_is_attached(struct device_node *node)
+{
+ return node && node->kobj.state_in_sysfs;
+}
+
+
+#ifndef CONFIG_OF_DYNAMIC
+static void of_node_release(struct kobject *kobj)
+{
+ /* Without CONFIG_OF_DYNAMIC, no nodes gets freed */
+}
+#endif /* CONFIG_OF_DYNAMIC */
+
+struct kobj_type of_node_ktype = {
+ .release = of_node_release,
+};
+
+static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t offset, size_t count)
+{
+ struct property *pp = container_of(bin_attr, struct property, attr);
+ return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length);
+}
+
+/* always return newly allocated name, caller must free after use */
+static const char *safe_name(struct kobject *kobj, const char *orig_name)
+{
+ const char *name = orig_name;
+ struct kernfs_node *kn;
+ int i = 0;
+
+ /* don't be a hero. After 16 tries give up */
+ while (i < 16 && (kn = sysfs_get_dirent(kobj->sd, name))) {
+ sysfs_put(kn);
+ if (name != orig_name)
+ kfree(name);
+ name = kasprintf(GFP_KERNEL, "%s#%i", orig_name, ++i);
+ }
+
+ if (name == orig_name) {
+ name = kstrdup(orig_name, GFP_KERNEL);
+ } else {
+ pr_warn("Duplicate name in %s, renamed to \"%s\"\n",
+ kobject_name(kobj), name);
+ }
+ return name;
+}
+
+int __of_add_property_sysfs(struct device_node *np, struct property *pp)
+{
+ int rc;
+
+ /* Important: Don't leak passwords */
+ bool secure = strncmp(pp->name, "security-", 9) == 0;
+
+ if (!IS_ENABLED(CONFIG_SYSFS))
+ return 0;
+
+ if (!of_kset || !of_node_is_attached(np))
+ return 0;
+
+ sysfs_bin_attr_init(&pp->attr);
+ pp->attr.attr.name = safe_name(&np->kobj, pp->name);
+ pp->attr.attr.mode = secure ? 0400 : 0444;
+ pp->attr.size = secure ? 0 : pp->length;
+ pp->attr.read = of_node_property_read;
+
+ rc = sysfs_create_bin_file(&np->kobj, &pp->attr);
+ WARN(rc, "error adding attribute %s to node %pOF\n", pp->name, np);
+ return rc;
+}
+
+void __of_sysfs_remove_bin_file(struct device_node *np, struct property *prop)
+{
+ if (!IS_ENABLED(CONFIG_SYSFS))
+ return;
+
+ sysfs_remove_bin_file(&np->kobj, &prop->attr);
+ kfree(prop->attr.attr.name);
+}
+
+void __of_remove_property_sysfs(struct device_node *np, struct property *prop)
+{
+ /* at early boot, bail here and defer setup to of_init() */
+ if (of_kset && of_node_is_attached(np))
+ __of_sysfs_remove_bin_file(np, prop);
+}
+
+void __of_update_property_sysfs(struct device_node *np, struct property *newprop,
+ struct property *oldprop)
+{
+ /* At early boot, bail out and defer setup to of_init() */
+ if (!of_kset)
+ return;
+
+ if (oldprop)
+ __of_sysfs_remove_bin_file(np, oldprop);
+ __of_add_property_sysfs(np, newprop);
+}
+
+int __of_attach_node_sysfs(struct device_node *np)
+{
+ const char *name;
+ struct kobject *parent;
+ struct property *pp;
+ int rc;
+
+ if (!of_kset)
+ return 0;
+
+ np->kobj.kset = of_kset;
+ if (!np->parent) {
+ /* Nodes without parents are new top level trees */
+ name = safe_name(&of_kset->kobj, "base");
+ parent = NULL;
+ } else {
+ name = safe_name(&np->parent->kobj, kbasename(np->full_name));
+ parent = &np->parent->kobj;
+ }
+ if (!name)
+ return -ENOMEM;
+ rc = kobject_add(&np->kobj, parent, "%s", name);
+ kfree(name);
+ if (rc)
+ return rc;
+
+ for_each_property_of_node(np, pp)
+ __of_add_property_sysfs(np, pp);
+
+ return 0;
+}
+
+void __of_detach_node_sysfs(struct device_node *np)
+{
+ struct property *pp;
+
+ BUG_ON(!of_node_is_initialized(np));
+ if (!of_kset)
+ return;
+
+ /* only remove properties if on sysfs */
+ if (of_node_is_attached(np)) {
+ for_each_property_of_node(np, pp)
+ __of_sysfs_remove_bin_file(np, pp);
+ kobject_del(&np->kobj);
+ }
+
+ /* finally remove the kobj_init ref */
+ of_node_put(np);
+}
+
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 3ae12ffbf547..92a9a3687446 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -35,18 +35,16 @@ extern struct mutex of_mutex;
extern struct list_head aliases_lookup;
extern struct kset *of_kset;
-
-static inline struct device_node *kobj_to_device_node(struct kobject *kobj)
-{
- return container_of(kobj, struct device_node, kobj);
-}
-
#if defined(CONFIG_OF_DYNAMIC)
extern int of_property_notify(int action, struct device_node *np,
struct property *prop, struct property *old_prop);
extern void of_node_release(struct kobject *kobj);
-extern int __of_changeset_apply(struct of_changeset *ocs);
-extern int __of_changeset_revert(struct of_changeset *ocs);
+extern int __of_changeset_apply_entries(struct of_changeset *ocs,
+ int *ret_revert);
+extern int __of_changeset_apply_notify(struct of_changeset *ocs);
+extern int __of_changeset_revert_entries(struct of_changeset *ocs,
+ int *ret_apply);
+extern int __of_changeset_revert_notify(struct of_changeset *ocs);
#else /* CONFIG_OF_DYNAMIC */
static inline int of_property_notify(int action, struct device_node *np,
struct property *prop, struct property *old_prop)
@@ -55,6 +53,41 @@ static inline int of_property_notify(int action, struct device_node *np,
}
#endif /* CONFIG_OF_DYNAMIC */
+#if defined(CONFIG_OF_KOBJ)
+int of_node_is_attached(struct device_node *node);
+int __of_add_property_sysfs(struct device_node *np, struct property *pp);
+void __of_remove_property_sysfs(struct device_node *np, struct property *prop);
+void __of_update_property_sysfs(struct device_node *np, struct property *newprop,
+ struct property *oldprop);
+int __of_attach_node_sysfs(struct device_node *np);
+void __of_detach_node_sysfs(struct device_node *np);
+#else
+static inline int __of_add_property_sysfs(struct device_node *np, struct property *pp)
+{
+ return 0;
+}
+static inline void __of_remove_property_sysfs(struct device_node *np, struct property *prop) {}
+static inline void __of_update_property_sysfs(struct device_node *np,
+ struct property *newprop, struct property *oldprop) {}
+static inline int __of_attach_node_sysfs(struct device_node *np)
+{
+ return 0;
+}
+static inline void __of_detach_node_sysfs(struct device_node *np) {}
+#endif
+
+#if defined(CONFIG_OF_RESOLVE)
+int of_resolve_phandles(struct device_node *tree);
+#endif
+
+#if defined(CONFIG_OF_OVERLAY)
+void of_overlay_mutex_lock(void);
+void of_overlay_mutex_unlock(void);
+#else
+static inline void of_overlay_mutex_lock(void) {};
+static inline void of_overlay_mutex_unlock(void) {};
+#endif
+
#if defined(CONFIG_OF_UNITTEST) && defined(CONFIG_OF_OVERLAY)
extern void __init unittest_unflatten_overlay_base(void);
#else
@@ -77,6 +110,8 @@ extern void *__unflatten_device_tree(const void *blob,
struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags);
__printf(2, 3) struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...);
+struct device_node *__of_find_node_by_path(struct device_node *parent,
+ const char *path);
struct device_node *__of_find_node_by_full_path(struct device_node *node,
const char *path);
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 8ecfee31ab6d..c150abb9049d 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -25,252 +25,378 @@
#include "of_private.h"
/**
- * struct of_overlay_info - Holds a single overlay info
+ * struct fragment - info about fragment nodes in overlay expanded device tree
* @target: target of the overlay operation
- * @overlay: pointer to the overlay contents node
- *
- * Holds a single overlay state, including all the overlay logs &
- * records.
+ * @overlay: pointer to the __overlay__ node
*/
-struct of_overlay_info {
+struct fragment {
struct device_node *target;
struct device_node *overlay;
- bool is_symbols_node;
};
/**
- * struct of_overlay - Holds a complete overlay transaction
- * @node: List on which we are located
- * @count: Count of ovinfo structures
- * @ovinfo_tab: Overlay info table (count sized)
- * @cset: Changeset to be used
- *
- * Holds a complete overlay transaction
+ * struct overlay_changeset
+ * @ovcs_list: list on which we are located
+ * @overlay_tree: expanded device tree that contains the fragment nodes
+ * @count: count of fragment structures
+ * @fragments: fragment nodes in the overlay expanded device tree
+ * @symbols_fragment: last element of @fragments[] is the __symbols__ node
+ * @cset: changeset to apply fragments to live device tree
*/
-struct of_overlay {
+struct overlay_changeset {
int id;
- struct list_head node;
+ struct list_head ovcs_list;
+ struct device_node *overlay_tree;
int count;
- struct of_overlay_info *ovinfo_tab;
+ struct fragment *fragments;
+ bool symbols_fragment;
struct of_changeset cset;
};
-static int of_overlay_apply_one(struct of_overlay *ov,
- struct device_node *target, const struct device_node *overlay,
- bool is_symbols_node);
+/* flags are sticky - once set, do not reset */
+static int devicetree_state_flags;
+#define DTSF_APPLY_FAIL 0x01
+#define DTSF_REVERT_FAIL 0x02
+
+/*
+ * If a changeset apply or revert encounters an error, an attempt will
+ * be made to undo partial changes, but may fail. If the undo fails
+ * we do not know the state of the devicetree.
+ */
+static int devicetree_corrupt(void)
+{
+ return devicetree_state_flags &
+ (DTSF_APPLY_FAIL | DTSF_REVERT_FAIL);
+}
+
+static int build_changeset_next_level(struct overlay_changeset *ovcs,
+ struct device_node *target_node,
+ const struct device_node *overlay_node);
+
+/*
+ * of_resolve_phandles() finds the largest phandle in the live tree.
+ * of_overlay_apply() may add a larger phandle to the live tree.
+ * Do not allow race between two overlays being applied simultaneously:
+ * mutex_lock(&of_overlay_phandle_mutex)
+ * of_resolve_phandles()
+ * of_overlay_apply()
+ * mutex_unlock(&of_overlay_phandle_mutex)
+ */
+static DEFINE_MUTEX(of_overlay_phandle_mutex);
+
+void of_overlay_mutex_lock(void)
+{
+ mutex_lock(&of_overlay_phandle_mutex);
+}
+
+void of_overlay_mutex_unlock(void)
+{
+ mutex_unlock(&of_overlay_phandle_mutex);
+}
-static BLOCKING_NOTIFIER_HEAD(of_overlay_chain);
+
+static LIST_HEAD(ovcs_list);
+static DEFINE_IDR(ovcs_idr);
+
+static BLOCKING_NOTIFIER_HEAD(overlay_notify_chain);
int of_overlay_notifier_register(struct notifier_block *nb)
{
- return blocking_notifier_chain_register(&of_overlay_chain, nb);
+ return blocking_notifier_chain_register(&overlay_notify_chain, nb);
}
EXPORT_SYMBOL_GPL(of_overlay_notifier_register);
int of_overlay_notifier_unregister(struct notifier_block *nb)
{
- return blocking_notifier_chain_unregister(&of_overlay_chain, nb);
+ return blocking_notifier_chain_unregister(&overlay_notify_chain, nb);
}
EXPORT_SYMBOL_GPL(of_overlay_notifier_unregister);
-static int of_overlay_notify(struct of_overlay *ov,
- enum of_overlay_notify_action action)
+static char *of_overlay_action_name[] = {
+ "pre-apply",
+ "post-apply",
+ "pre-remove",
+ "post-remove",
+};
+
+static int overlay_notify(struct overlay_changeset *ovcs,
+ enum of_overlay_notify_action action)
{
struct of_overlay_notify_data nd;
int i, ret;
- for (i = 0; i < ov->count; i++) {
- struct of_overlay_info *ovinfo = &ov->ovinfo_tab[i];
+ for (i = 0; i < ovcs->count; i++) {
+ struct fragment *fragment = &ovcs->fragments[i];
- nd.target = ovinfo->target;
- nd.overlay = ovinfo->overlay;
+ nd.target = fragment->target;
+ nd.overlay = fragment->overlay;
- ret = blocking_notifier_call_chain(&of_overlay_chain,
+ ret = blocking_notifier_call_chain(&overlay_notify_chain,
action, &nd);
- if (ret)
- return notifier_to_errno(ret);
+ if (ret == NOTIFY_OK || ret == NOTIFY_STOP)
+ return 0;
+ if (ret) {
+ ret = notifier_to_errno(ret);
+ pr_err("overlay changeset %s notifier error %d, target: %pOF\n",
+ of_overlay_action_name[action], ret, nd.target);
+ return ret;
+ }
}
return 0;
}
-static struct property *dup_and_fixup_symbol_prop(struct of_overlay *ov,
- const struct property *prop)
+/*
+ * The values of properties in the "/__symbols__" node are paths in
+ * the ovcs->overlay_tree. When duplicating the properties, the paths
+ * need to be adjusted to be the correct path for the live device tree.
+ *
+ * The paths refer to a node in the subtree of a fragment node's "__overlay__"
+ * node, for example "/fragment@0/__overlay__/symbol_path_tail",
+ * where symbol_path_tail can be a single node or it may be a multi-node path.
+ *
+ * The duplicated property value will be modified by replacing the
+ * "/fragment_name/__overlay/" portion of the value with the target
+ * path from the fragment node.
+ */
+static struct property *dup_and_fixup_symbol_prop(
+ struct overlay_changeset *ovcs, const struct property *prop)
{
- struct of_overlay_info *ovinfo;
- struct property *new;
- const char *overlay_name;
- char *label_path;
- char *symbol_path;
+ struct fragment *fragment;
+ struct property *new_prop;
+ struct device_node *fragment_node;
+ struct device_node *overlay_node;
+ const char *path;
+ const char *path_tail;
const char *target_path;
int k;
- int label_path_len;
int overlay_name_len;
+ int path_len;
+ int path_tail_len;
int target_path_len;
if (!prop->value)
return NULL;
- symbol_path = prop->value;
-
- new = kzalloc(sizeof(*new), GFP_KERNEL);
- if (!new)
+ if (strnlen(prop->value, prop->length) >= prop->length)
return NULL;
+ path = prop->value;
+ path_len = strlen(path);
- for (k = 0; k < ov->count; k++) {
- ovinfo = &ov->ovinfo_tab[k];
- overlay_name = ovinfo->overlay->full_name;
- overlay_name_len = strlen(overlay_name);
- if (!strncasecmp(symbol_path, overlay_name, overlay_name_len))
+ if (path_len < 1)
+ return NULL;
+ fragment_node = __of_find_node_by_path(ovcs->overlay_tree, path + 1);
+ overlay_node = __of_find_node_by_path(fragment_node, "__overlay__/");
+ of_node_put(fragment_node);
+ of_node_put(overlay_node);
+
+ for (k = 0; k < ovcs->count; k++) {
+ fragment = &ovcs->fragments[k];
+ if (fragment->overlay == overlay_node)
break;
}
+ if (k >= ovcs->count)
+ return NULL;
+
+ overlay_name_len = snprintf(NULL, 0, "%pOF", fragment->overlay);
- if (k >= ov->count)
- goto err_free;
+ if (overlay_name_len > path_len)
+ return NULL;
+ path_tail = path + overlay_name_len;
+ path_tail_len = strlen(path_tail);
- target_path = ovinfo->target->full_name;
+ target_path = kasprintf(GFP_KERNEL, "%pOF", fragment->target);
+ if (!target_path)
+ return NULL;
target_path_len = strlen(target_path);
- label_path = symbol_path + overlay_name_len;
- label_path_len = strlen(label_path);
+ new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL);
+ if (!new_prop)
+ goto err_free_target_path;
- new->name = kstrdup(prop->name, GFP_KERNEL);
- new->length = target_path_len + label_path_len + 1;
- new->value = kzalloc(new->length, GFP_KERNEL);
+ new_prop->name = kstrdup(prop->name, GFP_KERNEL);
+ new_prop->length = target_path_len + path_tail_len + 1;
+ new_prop->value = kzalloc(new_prop->length, GFP_KERNEL);
+ if (!new_prop->name || !new_prop->value)
+ goto err_free_new_prop;
- if (!new->name || !new->value)
- goto err_free;
+ strcpy(new_prop->value, target_path);
+ strcpy(new_prop->value + target_path_len, path_tail);
- strcpy(new->value, target_path);
- strcpy(new->value + target_path_len, label_path);
+ of_property_set_flag(new_prop, OF_DYNAMIC);
- /* mark the property as dynamic */
- of_property_set_flag(new, OF_DYNAMIC);
+ return new_prop;
- return new;
+err_free_new_prop:
+ kfree(new_prop->name);
+ kfree(new_prop->value);
+ kfree(new_prop);
+err_free_target_path:
+ kfree(target_path);
- err_free:
- kfree(new->name);
- kfree(new->value);
- kfree(new);
return NULL;
-
-
}
-static int of_overlay_apply_single_property(struct of_overlay *ov,
- struct device_node *target, struct property *prop,
- bool is_symbols_node)
+/**
+ * add_changeset_property() - add @overlay_prop to overlay changeset
+ * @ovcs: overlay changeset
+ * @target_node: where to place @overlay_prop in live tree
+ * @overlay_prop: property to add or update, from overlay tree
+ * @is_symbols_prop: 1 if @overlay_prop is from node "/__symbols__"
+ *
+ * If @overlay_prop does not already exist in @target_node, add changeset entry
+ * to add @overlay_prop in @target_node, else add changeset entry to update
+ * value of @overlay_prop.
+ *
+ * Some special properties are not updated (no error returned).
+ *
+ * Update of property in symbols node is not allowed.
+ *
+ * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
+ * invalid @overlay.
+ */
+static int add_changeset_property(struct overlay_changeset *ovcs,
+ struct device_node *target_node,
+ struct property *overlay_prop,
+ bool is_symbols_prop)
{
- struct property *propn = NULL, *tprop;
+ struct property *new_prop = NULL, *prop;
+ int ret = 0;
- /* NOTE: Multiple changes of single properties not supported */
- tprop = of_find_property(target, prop->name, NULL);
+ prop = of_find_property(target_node, overlay_prop->name, NULL);
- /* special properties are not meant to be updated (silent NOP) */
- if (of_prop_cmp(prop->name, "name") == 0 ||
- of_prop_cmp(prop->name, "phandle") == 0 ||
- of_prop_cmp(prop->name, "linux,phandle") == 0)
+ if (!of_prop_cmp(overlay_prop->name, "name") ||
+ !of_prop_cmp(overlay_prop->name, "phandle") ||
+ !of_prop_cmp(overlay_prop->name, "linux,phandle"))
return 0;
- if (is_symbols_node) {
- /* changing a property in __symbols__ node not allowed */
- if (tprop)
+ if (is_symbols_prop) {
+ if (prop)
return -EINVAL;
- propn = dup_and_fixup_symbol_prop(ov, prop);
+ new_prop = dup_and_fixup_symbol_prop(ovcs, overlay_prop);
} else {
- propn = __of_prop_dup(prop, GFP_KERNEL);
+ new_prop = __of_prop_dup(overlay_prop, GFP_KERNEL);
}
- if (propn == NULL)
+ if (!new_prop)
return -ENOMEM;
- /* not found? add */
- if (tprop == NULL)
- return of_changeset_add_property(&ov->cset, target, propn);
-
- /* found? update */
- return of_changeset_update_property(&ov->cset, target, propn);
+ if (!prop)
+ ret = of_changeset_add_property(&ovcs->cset, target_node,
+ new_prop);
+ else
+ ret = of_changeset_update_property(&ovcs->cset, target_node,
+ new_prop);
+
+ if (ret) {
+ kfree(new_prop->name);
+ kfree(new_prop->value);
+ kfree(new_prop);
+ }
+ return ret;
}
-static int of_overlay_apply_single_device_node(struct of_overlay *ov,
- struct device_node *target, struct device_node *child)
+/**
+ * add_changeset_node() - add @node (and children) to overlay changeset
+ * @ovcs: overlay changeset
+ * @target_node: where to place @node in live tree
+ * @node: node from within overlay device tree fragment
+ *
+ * If @node does not already exist in @target_node, add changeset entry
+ * to add @node in @target_node.
+ *
+ * If @node already exists in @target_node, and the existing node has
+ * a phandle, the overlay node is not allowed to have a phandle.
+ *
+ * If @node has child nodes, add the children recursively via
+ * build_changeset_next_level().
+ *
+ * NOTE: Multiple mods of created nodes not supported.
+ * If more than one fragment contains a node that does not already exist
+ * in the live tree, then for each fragment of_changeset_attach_node()
+ * will add a changeset entry to add the node. When the changeset is
+ * applied, __of_attach_node() will attach the node twice (once for
+ * each fragment). At this point the device tree will be corrupted.
+ *
+ * TODO: add integrity check to ensure that multiple fragments do not
+ * create the same node.
+ *
+ * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
+ * invalid @overlay.
+ */
+static int add_changeset_node(struct overlay_changeset *ovcs,
+ struct device_node *target_node, struct device_node *node)
{
- const char *cname;
+ const char *node_kbasename;
struct device_node *tchild;
int ret = 0;
- cname = kbasename(child->full_name);
- if (cname == NULL)
- return -ENOMEM;
+ node_kbasename = kbasename(node->full_name);
- /* NOTE: Multiple mods of created nodes not supported */
- for_each_child_of_node(target, tchild)
- if (!of_node_cmp(cname, kbasename(tchild->full_name)))
+ for_each_child_of_node(target_node, tchild)
+ if (!of_node_cmp(node_kbasename, kbasename(tchild->full_name)))
break;
- if (tchild != NULL) {
- /* new overlay phandle value conflicts with existing value */
- if (child->phandle)
- return -EINVAL;
-
- /* apply overlay recursively */
- ret = of_overlay_apply_one(ov, tchild, child, 0);
- of_node_put(tchild);
- } else {
- /* create empty tree as a target */
- tchild = __of_node_dup(child, "%pOF/%s", target, cname);
+ if (!tchild) {
+ tchild = __of_node_dup(node, "%pOF/%s",
+ target_node, node_kbasename);
if (!tchild)
return -ENOMEM;
- /* point to parent */
- tchild->parent = target;
+ tchild->parent = target_node;
- ret = of_changeset_attach_node(&ov->cset, tchild);
+ ret = of_changeset_attach_node(&ovcs->cset, tchild);
if (ret)
return ret;
- ret = of_overlay_apply_one(ov, tchild, child, 0);
- if (ret)
- return ret;
+ return build_changeset_next_level(ovcs, tchild, node);
}
+ if (node->phandle && tchild->phandle)
+ ret = -EINVAL;
+ else
+ ret = build_changeset_next_level(ovcs, tchild, node);
+ of_node_put(tchild);
+
return ret;
}
-/*
- * Apply a single overlay node recursively.
+/**
+ * build_changeset_next_level() - add level of overlay changeset
+ * @ovcs: overlay changeset
+ * @target_node: where to place @overlay_node in live tree
+ * @overlay_node: node from within an overlay device tree fragment
+ *
+ * Add the properties (if any) and nodes (if any) from @overlay_node to the
+ * @ovcs->cset changeset. If an added node has child nodes, they will
+ * be added recursively.
*
- * Note that the in case of an error the target node is left
- * in a inconsistent state. Error recovery should be performed
- * by using the changeset.
+ * Do not allow symbols node to have any children.
+ *
+ * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
+ * invalid @overlay_node.
*/
-static int of_overlay_apply_one(struct of_overlay *ov,
- struct device_node *target, const struct device_node *overlay,
- bool is_symbols_node)
+static int build_changeset_next_level(struct overlay_changeset *ovcs,
+ struct device_node *target_node,
+ const struct device_node *overlay_node)
{
struct device_node *child;
struct property *prop;
int ret;
- for_each_property_of_node(overlay, prop) {
- ret = of_overlay_apply_single_property(ov, target, prop,
- is_symbols_node);
+ for_each_property_of_node(overlay_node, prop) {
+ ret = add_changeset_property(ovcs, target_node, prop, 0);
if (ret) {
- pr_err("Failed to apply prop @%pOF/%s\n",
- target, prop->name);
+ pr_debug("Failed to apply prop @%pOF/%s, err=%d\n",
+ target_node, prop->name, ret);
return ret;
}
}
- /* do not allow symbols node to have any children */
- if (is_symbols_node)
- return 0;
-
- for_each_child_of_node(overlay, child) {
- ret = of_overlay_apply_single_device_node(ov, target, child);
- if (ret != 0) {
- pr_err("Failed to apply single node @%pOF/%s\n",
- target, child->name);
+ for_each_child_of_node(overlay_node, child) {
+ ret = add_changeset_node(ovcs, target_node, child);
+ if (ret) {
+ pr_debug("Failed to apply node @%pOF/%s, err=%d\n",
+ target_node, child->name, ret);
of_node_put(child);
return ret;
}
@@ -279,28 +405,72 @@ static int of_overlay_apply_one(struct of_overlay *ov,
return 0;
}
+/*
+ * Add the properties from __overlay__ node to the @ovcs->cset changeset.
+ */
+static int build_changeset_symbols_node(struct overlay_changeset *ovcs,
+ struct device_node *target_node,
+ const struct device_node *overlay_symbols_node)
+{
+ struct property *prop;
+ int ret;
+
+ for_each_property_of_node(overlay_symbols_node, prop) {
+ ret = add_changeset_property(ovcs, target_node, prop, 1);
+ if (ret) {
+ pr_debug("Failed to apply prop @%pOF/%s, err=%d\n",
+ target_node, prop->name, ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
/**
- * of_overlay_apply() - Apply @count overlays pointed at by @ovinfo_tab
- * @ov: Overlay to apply
+ * build_changeset() - populate overlay changeset in @ovcs from @ovcs->fragments
+ * @ovcs: Overlay changeset
*
- * Applies the overlays given, while handling all error conditions
- * appropriately. Either the operation succeeds, or if it fails the
- * live tree is reverted to the state before the attempt.
- * Returns 0, or an error if the overlay attempt failed.
+ * Create changeset @ovcs->cset to contain the nodes and properties of the
+ * overlay device tree fragments in @ovcs->fragments[]. If an error occurs,
+ * any portions of the changeset that were successfully created will remain
+ * in @ovcs->cset.
+ *
+ * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
+ * invalid overlay in @ovcs->fragments[].
*/
-static int of_overlay_apply(struct of_overlay *ov)
+static int build_changeset(struct overlay_changeset *ovcs)
{
- int i, err;
-
- /* first we apply the overlays atomically */
- for (i = 0; i < ov->count; i++) {
- struct of_overlay_info *ovinfo = &ov->ovinfo_tab[i];
+ struct fragment *fragment;
+ int fragments_count, i, ret;
+
+ /*
+ * if there is a symbols fragment in ovcs->fragments[i] it is
+ * the final element in the array
+ */
+ if (ovcs->symbols_fragment)
+ fragments_count = ovcs->count - 1;
+ else
+ fragments_count = ovcs->count;
+
+ for (i = 0; i < fragments_count; i++) {
+ fragment = &ovcs->fragments[i];
+
+ ret = build_changeset_next_level(ovcs, fragment->target,
+ fragment->overlay);
+ if (ret) {
+ pr_debug("apply failed '%pOF'\n", fragment->target);
+ return ret;
+ }
+ }
- err = of_overlay_apply_one(ov, ovinfo->target, ovinfo->overlay,
- ovinfo->is_symbols_node);
- if (err != 0) {
- pr_err("apply failed '%pOF'\n", ovinfo->target);
- return err;
+ if (ovcs->symbols_fragment) {
+ fragment = &ovcs->fragments[ovcs->count - 1];
+ ret = build_changeset_symbols_node(ovcs, fragment->target,
+ fragment->overlay);
+ if (ret) {
+ pr_debug("apply failed '%pOF'\n", fragment->target);
+ return ret;
}
}
@@ -309,10 +479,10 @@ static int of_overlay_apply(struct of_overlay *ov)
/*
* Find the target node using a number of different strategies
- * in order of preference
+ * in order of preference:
*
- * "target" property containing the phandle of the target
- * "target-path" property containing the path of the target
+ * 1) "target" property containing the phandle of the target
+ * 2) "target-path" property containing the path of the target
*/
static struct device_node *find_target_node(struct device_node *info_node)
{
@@ -320,14 +490,12 @@ static struct device_node *find_target_node(struct device_node *info_node)
u32 val;
int ret;
- /* first try to go by using the target as a phandle */
ret = of_property_read_u32(info_node, "target", &val);
- if (ret == 0)
+ if (!ret)
return of_find_node_by_phandle(val);
- /* now try to locate by path */
ret = of_property_read_string(info_node, "target-path", &path);
- if (ret == 0)
+ if (!ret)
return of_find_node_by_path(path);
pr_err("Failed to find target for node %p (%s)\n",
@@ -337,228 +505,290 @@ static struct device_node *find_target_node(struct device_node *info_node)
}
/**
- * of_fill_overlay_info() - Fill an overlay info structure
- * @ov Overlay to fill
- * @info_node: Device node containing the overlay
- * @ovinfo: Pointer to the overlay info structure to fill
- *
- * Fills an overlay info structure with the overlay information
- * from a device node. This device node must have a target property
- * which contains a phandle of the overlay target node, and an
- * __overlay__ child node which has the overlay contents.
- * Both ovinfo->target & ovinfo->overlay have their references taken.
- *
- * Returns 0 on success, or a negative error value.
+ * init_overlay_changeset() - initialize overlay changeset from overlay tree
+ * @ovcs Overlay changeset to build
+ * @tree: Contains all the overlay fragments and overlay fixup nodes
+ *
+ * Initialize @ovcs. Populate @ovcs->fragments with node information from
+ * the top level of @tree. The relevant top level nodes are the fragment
+ * nodes and the __symbols__ node. Any other top level node will be ignored.
+ *
+ * Returns 0 on success, -ENOMEM if memory allocation failure, -EINVAL if error
+ * detected in @tree, or -ENOSPC if idr_alloc() error.
*/
-static int of_fill_overlay_info(struct of_overlay *ov,
- struct device_node *info_node, struct of_overlay_info *ovinfo)
+static int init_overlay_changeset(struct overlay_changeset *ovcs,
+ struct device_node *tree)
{
- ovinfo->overlay = of_get_child_by_name(info_node, "__overlay__");
- if (ovinfo->overlay == NULL)
- goto err_fail;
+ struct device_node *node, *overlay_node;
+ struct fragment *fragment;
+ struct fragment *fragments;
+ int cnt, ret;
- ovinfo->target = find_target_node(info_node);
- if (ovinfo->target == NULL)
- goto err_fail;
+ /*
+ * Warn for some issues. Can not return -EINVAL for these until
+ * of_unittest_apply_overlay() is fixed to pass these checks.
+ */
+ if (!of_node_check_flag(tree, OF_DYNAMIC))
+ pr_debug("%s() tree is not dynamic\n", __func__);
- return 0;
+ if (!of_node_check_flag(tree, OF_DETACHED))
+ pr_debug("%s() tree is not detached\n", __func__);
-err_fail:
- of_node_put(ovinfo->target);
- of_node_put(ovinfo->overlay);
+ if (!of_node_is_root(tree))
+ pr_debug("%s() tree is not root\n", __func__);
- memset(ovinfo, 0, sizeof(*ovinfo));
- return -EINVAL;
-}
+ ovcs->overlay_tree = tree;
-/**
- * of_build_overlay_info() - Build an overlay info array
- * @ov Overlay to build
- * @tree: Device node containing all the overlays
- *
- * Helper function that given a tree containing overlay information,
- * allocates and builds an overlay info array containing it, ready
- * for use using of_overlay_apply.
- *
- * Returns 0 on success with the @cntp @ovinfop pointers valid,
- * while on error a negative error value is returned.
- */
-static int of_build_overlay_info(struct of_overlay *ov,
- struct device_node *tree)
-{
- struct device_node *node;
- struct of_overlay_info *ovinfo;
- int cnt, err;
+ INIT_LIST_HEAD(&ovcs->ovcs_list);
+
+ of_changeset_init(&ovcs->cset);
+
+ ovcs->id = idr_alloc(&ovcs_idr, ovcs, 1, 0, GFP_KERNEL);
+ if (ovcs->id <= 0)
+ return ovcs->id;
- /* worst case; every child is a node */
cnt = 0;
- for_each_child_of_node(tree, node)
- cnt++;
- if (of_get_child_by_name(tree, "__symbols__"))
+ /* fragment nodes */
+ for_each_child_of_node(tree, node) {
+ overlay_node = of_get_child_by_name(node, "__overlay__");
+ if (overlay_node) {
+ cnt++;
+ of_node_put(overlay_node);
+ }
+ }
+
+ node = of_get_child_by_name(tree, "__symbols__");
+ if (node) {
cnt++;
+ of_node_put(node);
+ }
- ovinfo = kcalloc(cnt, sizeof(*ovinfo), GFP_KERNEL);
- if (ovinfo == NULL)
- return -ENOMEM;
+ fragments = kcalloc(cnt, sizeof(*fragments), GFP_KERNEL);
+ if (!fragments) {
+ ret = -ENOMEM;
+ goto err_free_idr;
+ }
cnt = 0;
for_each_child_of_node(tree, node) {
- err = of_fill_overlay_info(ov, node, &ovinfo[cnt]);
- if (err == 0)
- cnt++;
+ fragment = &fragments[cnt];
+ fragment->overlay = of_get_child_by_name(node, "__overlay__");
+ if (fragment->overlay) {
+ fragment->target = find_target_node(node);
+ if (!fragment->target) {
+ of_node_put(fragment->overlay);
+ ret = -EINVAL;
+ goto err_free_fragments;
+ } else {
+ cnt++;
+ }
+ }
}
+ /*
+ * if there is a symbols fragment in ovcs->fragments[i] it is
+ * the final element in the array
+ */
node = of_get_child_by_name(tree, "__symbols__");
if (node) {
- ovinfo[cnt].overlay = node;
- ovinfo[cnt].target = of_find_node_by_path("/__symbols__");
- ovinfo[cnt].is_symbols_node = 1;
-
- if (!ovinfo[cnt].target) {
- pr_err("no symbols in root of device tree.\n");
- return -EINVAL;
+ ovcs->symbols_fragment = 1;
+ fragment = &fragments[cnt];
+ fragment->overlay = node;
+ fragment->target = of_find_node_by_path("/__symbols__");
+
+ if (!fragment->target) {
+ pr_err("symbols in overlay, but not in live tree\n");
+ ret = -EINVAL;
+ goto err_free_fragments;
}
cnt++;
}
- /* if nothing filled, return error */
- if (cnt == 0) {
- kfree(ovinfo);
- return -ENODEV;
+ if (!cnt) {
+ ret = -EINVAL;
+ goto err_free_fragments;
}
- ov->count = cnt;
- ov->ovinfo_tab = ovinfo;
+ ovcs->count = cnt;
+ ovcs->fragments = fragments;
return 0;
+
+err_free_fragments:
+ kfree(fragments);
+err_free_idr:
+ idr_remove(&ovcs_idr, ovcs->id);
+
+ pr_err("%s() failed, ret = %d\n", __func__, ret);
+
+ return ret;
}
-/**
- * of_free_overlay_info() - Free an overlay info array
- * @ov Overlay to free the overlay info from
- * @ovinfo_tab: Array of overlay_info's to free
- *
- * Releases the memory of a previously allocated ovinfo array
- * by of_build_overlay_info.
- * Returns 0, or an error if the arguments are bogus.
- */
-static int of_free_overlay_info(struct of_overlay *ov)
+static void free_overlay_changeset(struct overlay_changeset *ovcs)
{
- struct of_overlay_info *ovinfo;
int i;
- /* do it in reverse */
- for (i = ov->count - 1; i >= 0; i--) {
- ovinfo = &ov->ovinfo_tab[i];
+ if (!ovcs->cset.entries.next)
+ return;
+ of_changeset_destroy(&ovcs->cset);
+
+ if (ovcs->id)
+ idr_remove(&ovcs_idr, ovcs->id);
- of_node_put(ovinfo->target);
- of_node_put(ovinfo->overlay);
+ for (i = 0; i < ovcs->count; i++) {
+ of_node_put(ovcs->fragments[i].target);
+ of_node_put(ovcs->fragments[i].overlay);
}
- kfree(ov->ovinfo_tab);
+ kfree(ovcs->fragments);
- return 0;
+ kfree(ovcs);
}
-static LIST_HEAD(ov_list);
-static DEFINE_IDR(ov_idr);
-
/**
- * of_overlay_create() - Create and apply an overlay
- * @tree: Device node containing all the overlays
+ * of_overlay_apply() - Create and apply an overlay changeset
+ * @tree: Expanded overlay device tree
+ * @ovcs_id: Pointer to overlay changeset id
*
- * Creates and applies an overlay while also keeping track
- * of the overlay in a list. This list can be used to prevent
- * illegal overlay removals.
+ * Creates and applies an overlay changeset.
+ *
+ * If an error occurs in a pre-apply notifier, then no changes are made
+ * to the device tree.
+ *
+
+ * A non-zero return value will not have created the changeset if error is from:
+ * - parameter checks
+ * - building the changeset
+ * - overlay changset pre-apply notifier
*
- * Returns the id of the created overlay, or a negative error number
+ * If an error is returned by an overlay changeset pre-apply notifier
+ * then no further overlay changeset pre-apply notifier will be called.
+ *
+ * A non-zero return value will have created the changeset if error is from:
+ * - overlay changeset entry notifier
+ * - overlay changset post-apply notifier
+ *
+ * If an error is returned by an overlay changeset post-apply notifier
+ * then no further overlay changeset post-apply notifier will be called.
+ *
+ * If more than one notifier returns an error, then the last notifier
+ * error to occur is returned.
+ *
+ * If an error occurred while applying the overlay changeset, then an
+ * attempt is made to revert any changes that were made to the
+ * device tree. If there were any errors during the revert attempt
+ * then the state of the device tree can not be determined, and any
+ * following attempt to apply or remove an overlay changeset will be
+ * refused.
+ *
+ * Returns 0 on success, or a negative error number. Overlay changeset
+ * id is returned to *ovcs_id.
*/
-int of_overlay_create(struct device_node *tree)
+
+int of_overlay_apply(struct device_node *tree, int *ovcs_id)
{
- struct of_overlay *ov;
- int err, id;
+ struct overlay_changeset *ovcs;
+ int ret = 0, ret_revert, ret_tmp;
- /* allocate the overlay structure */
- ov = kzalloc(sizeof(*ov), GFP_KERNEL);
- if (ov == NULL)
- return -ENOMEM;
- ov->id = -1;
+ *ovcs_id = 0;
+
+ if (devicetree_corrupt()) {
+ pr_err("devicetree state suspect, refuse to apply overlay\n");
+ ret = -EBUSY;
+ goto out;
+ }
+
+ ovcs = kzalloc(sizeof(*ovcs), GFP_KERNEL);
+ if (!ovcs) {
+ ret = -ENOMEM;
+ goto out;
+ }
- INIT_LIST_HEAD(&ov->node);
+ of_overlay_mutex_lock();
- of_changeset_init(&ov->cset);
+ ret = of_resolve_phandles(tree);
+ if (ret)
+ goto err_overlay_unlock;
mutex_lock(&of_mutex);
- id = idr_alloc(&ov_idr, ov, 0, 0, GFP_KERNEL);
- if (id < 0) {
- err = id;
- goto err_destroy_trans;
- }
- ov->id = id;
+ ret = init_overlay_changeset(ovcs, tree);
+ if (ret)
+ goto err_free_overlay_changeset;
- /* build the overlay info structures */
- err = of_build_overlay_info(ov, tree);
- if (err) {
- pr_err("of_build_overlay_info() failed for tree@%pOF\n",
- tree);
- goto err_free_idr;
+ ret = overlay_notify(ovcs, OF_OVERLAY_PRE_APPLY);
+ if (ret) {
+ pr_err("overlay changeset pre-apply notify error %d\n", ret);
+ goto err_free_overlay_changeset;
}
- err = of_overlay_notify(ov, OF_OVERLAY_PRE_APPLY);
- if (err < 0) {
- pr_err("%s: Pre-apply notifier failed (err=%d)\n",
- __func__, err);
- goto err_free_idr;
+ ret = build_changeset(ovcs);
+ if (ret)
+ goto err_free_overlay_changeset;
+
+ ret_revert = 0;
+ ret = __of_changeset_apply_entries(&ovcs->cset, &ret_revert);
+ if (ret) {
+ if (ret_revert) {
+ pr_debug("overlay changeset revert error %d\n",
+ ret_revert);
+ devicetree_state_flags |= DTSF_APPLY_FAIL;
+ }
+ goto err_free_overlay_changeset;
+ } else {
+ ret = __of_changeset_apply_notify(&ovcs->cset);
+ if (ret)
+ pr_err("overlay changeset entry notify error %d\n",
+ ret);
+ /* fall through */
}
- /* apply the overlay */
- err = of_overlay_apply(ov);
- if (err)
- goto err_abort_trans;
-
- /* apply the changeset */
- err = __of_changeset_apply(&ov->cset);
- if (err)
- goto err_revert_overlay;
+ list_add_tail(&ovcs->ovcs_list, &ovcs_list);
+ *ovcs_id = ovcs->id;
+ ret_tmp = overlay_notify(ovcs, OF_OVERLAY_POST_APPLY);
+ if (ret_tmp) {
+ pr_err("overlay changeset post-apply notify error %d\n",
+ ret_tmp);
+ if (!ret)
+ ret = ret_tmp;
+ }
- /* add to the tail of the overlay list */
- list_add_tail(&ov->node, &ov_list);
+ mutex_unlock(&of_mutex);
+ of_overlay_mutex_unlock();
- of_overlay_notify(ov, OF_OVERLAY_POST_APPLY);
+ goto out;
- mutex_unlock(&of_mutex);
+err_overlay_unlock:
+ of_overlay_mutex_unlock();
- return id;
+err_free_overlay_changeset:
+ free_overlay_changeset(ovcs);
-err_revert_overlay:
-err_abort_trans:
- of_free_overlay_info(ov);
-err_free_idr:
- idr_remove(&ov_idr, ov->id);
-err_destroy_trans:
- of_changeset_destroy(&ov->cset);
- kfree(ov);
mutex_unlock(&of_mutex);
- return err;
+out:
+ pr_debug("%s() err=%d\n", __func__, ret);
+
+ return ret;
}
-EXPORT_SYMBOL_GPL(of_overlay_create);
+EXPORT_SYMBOL_GPL(of_overlay_apply);
-/* check whether the given node, lies under the given tree */
-static int overlay_subtree_check(struct device_node *tree,
- struct device_node *dn)
+/*
+ * Find @np in @tree.
+ *
+ * Returns 1 if @np is @tree or is contained in @tree, else 0
+ */
+static int find_node(struct device_node *tree, struct device_node *np)
{
struct device_node *child;
- /* match? */
- if (tree == dn)
+ if (tree == np)
return 1;
for_each_child_of_node(tree, child) {
- if (overlay_subtree_check(child, dn)) {
+ if (find_node(child, np)) {
of_node_put(child);
return 1;
}
@@ -567,29 +797,39 @@ static int overlay_subtree_check(struct device_node *tree,
return 0;
}
-/* check whether this overlay is the topmost */
-static int overlay_is_topmost(struct of_overlay *ov, struct device_node *dn)
+/*
+ * Is @remove_ce_node a child of, a parent of, or the same as any
+ * node in an overlay changeset more topmost than @remove_ovcs?
+ *
+ * Returns 1 if found, else 0
+ */
+static int node_overlaps_later_cs(struct overlay_changeset *remove_ovcs,
+ struct device_node *remove_ce_node)
{
- struct of_overlay *ovt;
+ struct overlay_changeset *ovcs;
struct of_changeset_entry *ce;
- list_for_each_entry_reverse(ovt, &ov_list, node) {
- /* if we hit ourselves, we're done */
- if (ovt == ov)
+ list_for_each_entry_reverse(ovcs, &ovcs_list, ovcs_list) {
+ if (ovcs == remove_ovcs)
break;
- /* check against each subtree affected by this overlay */
- list_for_each_entry(ce, &ovt->cset.entries, node) {
- if (overlay_subtree_check(ce->np, dn)) {
- pr_err("%s: #%d clashes #%d @%pOF\n",
- __func__, ov->id, ovt->id, dn);
- return 0;
+ list_for_each_entry(ce, &ovcs->cset.entries, node) {
+ if (find_node(ce->np, remove_ce_node)) {
+ pr_err("%s: #%d overlaps with #%d @%pOF\n",
+ __func__, remove_ovcs->id, ovcs->id,
+ remove_ce_node);
+ return 1;
+ }
+ if (find_node(remove_ce_node, ce->np)) {
+ pr_err("%s: #%d overlaps with #%d @%pOF\n",
+ __func__, remove_ovcs->id, ovcs->id,
+ remove_ce_node);
+ return 1;
}
}
}
- /* overlay is topmost */
- return 1;
+ return 0;
}
/*
@@ -602,13 +842,13 @@ static int overlay_is_topmost(struct of_overlay *ov, struct device_node *dn)
* the one closest to the tail. If another overlay has affected this
* device node and is closest to the tail, then removal is not permited.
*/
-static int overlay_removal_is_ok(struct of_overlay *ov)
+static int overlay_removal_is_ok(struct overlay_changeset *remove_ovcs)
{
- struct of_changeset_entry *ce;
+ struct of_changeset_entry *remove_ce;
- list_for_each_entry(ce, &ov->cset.entries, node) {
- if (!overlay_is_topmost(ov, ce->np)) {
- pr_err("overlay #%d is not topmost\n", ov->id);
+ list_for_each_entry(remove_ce, &remove_ovcs->cset.entries, node) {
+ if (node_overlaps_later_cs(remove_ovcs, remove_ce->np)) {
+ pr_err("overlay #%d is not topmost\n", remove_ovcs->id);
return 0;
}
}
@@ -617,75 +857,130 @@ static int overlay_removal_is_ok(struct of_overlay *ov)
}
/**
- * of_overlay_destroy() - Removes an overlay
- * @id: Overlay id number returned by a previous call to of_overlay_create
+ * of_overlay_remove() - Revert and free an overlay changeset
+ * @ovcs_id: Pointer to overlay changeset id
*
- * Removes an overlay if it is permissible.
+ * Removes an overlay if it is permissible. @ovcs_id was previously returned
+ * by of_overlay_apply().
*
- * Returns 0 on success, or a negative error number
+ * If an error occurred while attempting to revert the overlay changeset,
+ * then an attempt is made to re-apply any changeset entry that was
+ * reverted. If an error occurs on re-apply then the state of the device
+ * tree can not be determined, and any following attempt to apply or remove
+ * an overlay changeset will be refused.
+ *
+ * A non-zero return value will not revert the changeset if error is from:
+ * - parameter checks
+ * - overlay changset pre-remove notifier
+ * - overlay changeset entry revert
+ *
+ * If an error is returned by an overlay changeset pre-remove notifier
+ * then no further overlay changeset pre-remove notifier will be called.
+ *
+ * If more than one notifier returns an error, then the last notifier
+ * error to occur is returned.
+ *
+ * A non-zero return value will revert the changeset if error is from:
+ * - overlay changeset entry notifier
+ * - overlay changset post-remove notifier
+ *
+ * If an error is returned by an overlay changeset post-remove notifier
+ * then no further overlay changeset post-remove notifier will be called.
+ *
+ * Returns 0 on success, or a negative error number. *ovcs_id is set to
+ * zero after reverting the changeset, even if a subsequent error occurs.
*/
-int of_overlay_destroy(int id)
+int of_overlay_remove(int *ovcs_id)
{
- struct of_overlay *ov;
- int err;
+ struct overlay_changeset *ovcs;
+ int ret, ret_apply, ret_tmp;
- mutex_lock(&of_mutex);
+ ret = 0;
- ov = idr_find(&ov_idr, id);
- if (ov == NULL) {
- err = -ENODEV;
- pr_err("destroy: Could not find overlay #%d\n", id);
+ if (devicetree_corrupt()) {
+ pr_err("suspect devicetree state, refuse to remove overlay\n");
+ ret = -EBUSY;
goto out;
}
- /* check whether the overlay is safe to remove */
- if (!overlay_removal_is_ok(ov)) {
- err = -EBUSY;
- goto out;
+ mutex_lock(&of_mutex);
+
+ ovcs = idr_find(&ovcs_idr, *ovcs_id);
+ if (!ovcs) {
+ ret = -ENODEV;
+ pr_err("remove: Could not find overlay #%d\n", *ovcs_id);
+ goto out_unlock;
}
- of_overlay_notify(ov, OF_OVERLAY_PRE_REMOVE);
- list_del(&ov->node);
- __of_changeset_revert(&ov->cset);
- of_overlay_notify(ov, OF_OVERLAY_POST_REMOVE);
- of_free_overlay_info(ov);
- idr_remove(&ov_idr, id);
- of_changeset_destroy(&ov->cset);
- kfree(ov);
+ if (!overlay_removal_is_ok(ovcs)) {
+ ret = -EBUSY;
+ goto out_unlock;
+ }
- err = 0;
+ ret = overlay_notify(ovcs, OF_OVERLAY_PRE_REMOVE);
+ if (ret) {
+ pr_err("overlay changeset pre-remove notify error %d\n", ret);
+ goto out_unlock;
+ }
-out:
+ list_del(&ovcs->ovcs_list);
+
+ ret_apply = 0;
+ ret = __of_changeset_revert_entries(&ovcs->cset, &ret_apply);
+ if (ret) {
+ if (ret_apply)
+ devicetree_state_flags |= DTSF_REVERT_FAIL;
+ goto out_unlock;
+ } else {
+ ret = __of_changeset_revert_notify(&ovcs->cset);
+ if (ret) {
+ pr_err("overlay changeset entry notify error %d\n",
+ ret);
+ /* fall through - changeset was reverted */
+ }
+ }
+
+ *ovcs_id = 0;
+
+ ret_tmp = overlay_notify(ovcs, OF_OVERLAY_POST_REMOVE);
+ if (ret_tmp) {
+ pr_err("overlay changeset post-remove notify error %d\n",
+ ret_tmp);
+ if (!ret)
+ ret = ret_tmp;
+ }
+
+ free_overlay_changeset(ovcs);
+
+out_unlock:
mutex_unlock(&of_mutex);
- return err;
+out:
+ pr_debug("%s() err=%d\n", __func__, ret);
+
+ return ret;
}
-EXPORT_SYMBOL_GPL(of_overlay_destroy);
+EXPORT_SYMBOL_GPL(of_overlay_remove);
/**
- * of_overlay_destroy_all() - Removes all overlays from the system
+ * of_overlay_remove_all() - Reverts and frees all overlay changesets
*
* Removes all overlays from the system in the correct order.
*
* Returns 0 on success, or a negative error number
*/
-int of_overlay_destroy_all(void)
+int of_overlay_remove_all(void)
{
- struct of_overlay *ov, *ovn;
-
- mutex_lock(&of_mutex);
+ struct overlay_changeset *ovcs, *ovcs_n;
+ int ret;
/* the tail of list is guaranteed to be safe to remove */
- list_for_each_entry_safe_reverse(ov, ovn, &ov_list, node) {
- list_del(&ov->node);
- __of_changeset_revert(&ov->cset);
- of_free_overlay_info(ov);
- idr_remove(&ov_idr, ov->id);
- kfree(ov);
+ list_for_each_entry_safe_reverse(ovcs, ovcs_n, &ovcs_list, ovcs_list) {
+ ret = of_overlay_remove(&ovcs->id);
+ if (ret)
+ return ret;
}
- mutex_unlock(&of_mutex);
-
return 0;
}
-EXPORT_SYMBOL_GPL(of_overlay_destroy_all);
+EXPORT_SYMBOL_GPL(of_overlay_remove_all);
diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
index 99309cb7d372..cfaeef5f6cb1 100644
--- a/drivers/of/resolver.c
+++ b/drivers/of/resolver.c
@@ -84,10 +84,9 @@ static int update_usages_of_a_phandle_reference(struct device_node *overlay,
int offset, len;
int err = 0;
- value = kmalloc(prop_fixup->length, GFP_KERNEL);
+ value = kmemdup(prop_fixup->value, prop_fixup->length, GFP_KERNEL);
if (!value)
return -ENOMEM;
- memcpy(value, prop_fixup->value, prop_fixup->length);
/* prop_fixup contains a list of tuples of path:property_name:offset */
end = value + prop_fixup->length;
@@ -165,7 +164,6 @@ static int adjust_local_phandle_references(struct device_node *local_fixups,
struct property *prop_fix, *prop;
int err, i, count;
unsigned int off;
- phandle phandle;
if (!local_fixups)
return 0;
@@ -195,9 +193,7 @@ static int adjust_local_phandle_references(struct device_node *local_fixups,
if ((off + 4) > prop->length)
return -EINVAL;
- phandle = be32_to_cpu(*(__be32 *)(prop->value + off));
- phandle += phandle_delta;
- *(__be32 *)(prop->value + off) = cpu_to_be32(phandle);
+ be32_add_cpu(prop->value + off, phandle_delta);
}
}
@@ -275,11 +271,18 @@ int of_resolve_phandles(struct device_node *overlay)
err = -EINVAL;
goto out;
}
+
+#if 0
+ Temporarily disable check so that old style overlay unittests
+ do not fail when of_resolve_phandles() is moved into
+ of_overlay_apply().
+
if (!of_node_check_flag(overlay, OF_DETACHED)) {
pr_err("overlay not detached\n");
err = -EINVAL;
goto out;
}
+#endif
phandle_delta = live_tree_max_phandle() + 1;
adjust_overlay_phandles(overlay, phandle_delta);
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index 29a35cb1da64..273d78c1520b 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -993,10 +993,17 @@ static int __init unittest_data_add(void)
pr_warn("%s: No tree to attach; not running tests\n", __func__);
return -ENODATA;
}
- of_node_set_flag(unittest_data_node, OF_DETACHED);
+
+ /*
+ * This lock normally encloses of_overlay_apply() as well as
+ * of_resolve_phandles().
+ */
+ of_overlay_mutex_lock();
+
rc = of_resolve_phandles(unittest_data_node);
if (rc) {
pr_err("%s: Failed to resolve phandles (rc=%i)\n", __func__, rc);
+ of_overlay_mutex_unlock();
return -EINVAL;
}
@@ -1006,6 +1013,7 @@ static int __init unittest_data_add(void)
__of_attach_node_sysfs(np);
of_aliases = of_find_node_by_path("/aliases");
of_chosen = of_find_node_by_path("/chosen");
+ of_overlay_mutex_unlock();
return 0;
}
@@ -1018,6 +1026,9 @@ static int __init unittest_data_add(void)
attach_node_and_children(np);
np = next;
}
+
+ of_overlay_mutex_unlock();
+
return 0;
}
@@ -1218,7 +1229,7 @@ static void of_unittest_untrack_overlay(int id)
static void of_unittest_destroy_tracked_overlays(void)
{
- int id, ret, defers;
+ int id, ret, defers, ovcs_id;
if (overlay_first_id < 0)
return;
@@ -1231,7 +1242,8 @@ static void of_unittest_destroy_tracked_overlays(void)
if (!(overlay_id_bits[BIT_WORD(id)] & BIT_MASK(id)))
continue;
- ret = of_overlay_destroy(id + overlay_first_id);
+ ovcs_id = id + overlay_first_id;
+ ret = of_overlay_remove(&ovcs_id);
if (ret == -ENODEV) {
pr_warn("%s: no overlay to destroy for #%d\n",
__func__, id + overlay_first_id);
@@ -1253,7 +1265,7 @@ static int of_unittest_apply_overlay(int overlay_nr, int unittest_nr,
int *overlay_id)
{
struct device_node *np = NULL;
- int ret, id = -1;
+ int ret;
np = of_find_node_by_path(overlay_path(overlay_nr));
if (np == NULL) {
@@ -1263,23 +1275,20 @@ static int of_unittest_apply_overlay(int overlay_nr, int unittest_nr,
goto out;
}
- ret = of_overlay_create(np);
+ *overlay_id = 0;
+ ret = of_overlay_apply(np, overlay_id);
if (ret < 0) {
unittest(0, "could not create overlay from \"%s\"\n",
overlay_path(overlay_nr));
goto out;
}
- id = ret;
- of_unittest_track_overlay(id);
+ of_unittest_track_overlay(*overlay_id);
ret = 0;
out:
of_node_put(np);
- if (overlay_id)
- *overlay_id = id;
-
return ret;
}
@@ -1287,7 +1296,7 @@ out:
static int of_unittest_apply_overlay_check(int overlay_nr, int unittest_nr,
int before, int after, enum overlay_type ovtype)
{
- int ret;
+ int ret, ovcs_id;
/* unittest device must not be in before state */
if (of_unittest_device_exists(unittest_nr, ovtype) != before) {
@@ -1298,7 +1307,8 @@ static int of_unittest_apply_overlay_check(int overlay_nr, int unittest_nr,
return -EINVAL;
}
- ret = of_unittest_apply_overlay(overlay_nr, unittest_nr, NULL);
+ ovcs_id = 0;
+ ret = of_unittest_apply_overlay(overlay_nr, unittest_nr, &ovcs_id);
if (ret != 0) {
/* of_unittest_apply_overlay already called unittest() */
return ret;
@@ -1321,7 +1331,7 @@ static int of_unittest_apply_revert_overlay_check(int overlay_nr,
int unittest_nr, int before, int after,
enum overlay_type ovtype)
{
- int ret, ov_id;
+ int ret, ovcs_id;
/* unittest device must be in before state */
if (of_unittest_device_exists(unittest_nr, ovtype) != before) {
@@ -1333,7 +1343,8 @@ static int of_unittest_apply_revert_overlay_check(int overlay_nr,
}
/* apply the overlay */
- ret = of_unittest_apply_overlay(overlay_nr, unittest_nr, &ov_id);
+ ovcs_id = 0;
+ ret = of_unittest_apply_overlay(overlay_nr, unittest_nr, &ovcs_id);
if (ret != 0) {
/* of_unittest_apply_overlay already called unittest() */
return ret;
@@ -1348,7 +1359,7 @@ static int of_unittest_apply_revert_overlay_check(int overlay_nr,
return -EINVAL;
}
- ret = of_overlay_destroy(ov_id);
+ ret = of_overlay_remove(&ovcs_id);
if (ret != 0) {
unittest(0, "overlay @\"%s\" failed to be destroyed @\"%s\"\n",
overlay_path(overlay_nr),
@@ -1450,7 +1461,7 @@ static void of_unittest_overlay_5(void)
static void of_unittest_overlay_6(void)
{
struct device_node *np;
- int ret, i, ov_id[2];
+ int ret, i, ov_id[2], ovcs_id;
int overlay_nr = 6, unittest_nr = 6;
int before = 0, after = 1;
@@ -1477,13 +1488,14 @@ static void of_unittest_overlay_6(void)
return;
}
- ret = of_overlay_create(np);
+ ovcs_id = 0;
+ ret = of_overlay_apply(np, &ovcs_id);
if (ret < 0) {
unittest(0, "could not create overlay from \"%s\"\n",
overlay_path(overlay_nr + i));
return;
}
- ov_id[i] = ret;
+ ov_id[i] = ovcs_id;
of_unittest_track_overlay(ov_id[i]);
}
@@ -1501,7 +1513,8 @@ static void of_unittest_overlay_6(void)
}
for (i = 1; i >= 0; i--) {
- ret = of_overlay_destroy(ov_id[i]);
+ ovcs_id = ov_id[i];
+ ret = of_overlay_remove(&ovcs_id);
if (ret != 0) {
unittest(0, "overlay @\"%s\" failed destroy @\"%s\"\n",
overlay_path(overlay_nr + i),
@@ -1532,7 +1545,7 @@ static void of_unittest_overlay_6(void)
static void of_unittest_overlay_8(void)
{
struct device_node *np;
- int ret, i, ov_id[2];
+ int ret, i, ov_id[2], ovcs_id;
int overlay_nr = 8, unittest_nr = 8;
/* we don't care about device state in this test */
@@ -1547,18 +1560,20 @@ static void of_unittest_overlay_8(void)
return;
}
- ret = of_overlay_create(np);
+ ovcs_id = 0;
+ ret = of_overlay_apply(np, &ovcs_id);
if (ret < 0) {
unittest(0, "could not create overlay from \"%s\"\n",
overlay_path(overlay_nr + i));
return;
}
- ov_id[i] = ret;
+ ov_id[i] = ovcs_id;
of_unittest_track_overlay(ov_id[i]);
}
/* now try to remove first overlay (it should fail) */
- ret = of_overlay_destroy(ov_id[0]);
+ ovcs_id = ov_id[0];
+ ret = of_overlay_remove(&ovcs_id);
if (ret == 0) {
unittest(0, "overlay @\"%s\" was destroyed @\"%s\"\n",
overlay_path(overlay_nr + 0),
@@ -1569,7 +1584,8 @@ static void of_unittest_overlay_8(void)
/* removing them in order should work */
for (i = 1; i >= 0; i--) {
- ret = of_overlay_destroy(ov_id[i]);
+ ovcs_id = ov_id[i];
+ ret = of_overlay_remove(&ovcs_id);
if (ret != 0) {
unittest(0, "overlay @\"%s\" not destroyed @\"%s\"\n",
overlay_path(overlay_nr + i),
@@ -2143,21 +2159,13 @@ static int __init overlay_data_add(int onum)
ret = 0;
goto out_free_data;
}
- of_node_set_flag(info->np_overlay, OF_DETACHED);
- ret = of_resolve_phandles(info->np_overlay);
- if (ret) {
- pr_err("resolve ot phandles (ret=%d), %d\n", ret, onum);
- goto out_free_np_overlay;
- }
-
- ret = of_overlay_create(info->np_overlay);
+ info->overlay_id = 0;
+ ret = of_overlay_apply(info->np_overlay, &info->overlay_id);
if (ret < 0) {
- pr_err("of_overlay_create() (ret=%d), %d\n", ret, onum);
+ pr_err("of_overlay_apply() (ret=%d), %d\n", ret, onum);
+ of_overlay_mutex_unlock();
goto out_free_np_overlay;
- } else {
- info->overlay_id = ret;
- ret = 0;
}
pr_debug("__dtb_overlay_begin applied, overlay id %d\n", ret);
@@ -2206,7 +2214,10 @@ static __init void of_unittest_overlay_high_level(void)
* Could not fixup phandles in unittest_unflatten_overlay_base()
* because kmalloc() was not yet available.
*/
+ of_overlay_mutex_lock();
of_resolve_phandles(overlay_base_root);
+ of_overlay_mutex_unlock();
+
/*
* do not allow overlay_base to duplicate any node already in
diff --git a/include/linux/of.h b/include/linux/of.h
index cfc34117fc92..ef4c9ff5955a 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -37,9 +37,15 @@ struct property {
int length;
void *value;
struct property *next;
+#if defined(CONFIG_OF_DYNAMIC) || defined(CONFIG_SPARC)
unsigned long _flags;
+#endif
+#if defined(CONFIG_OF_PROMTREE)
unsigned int unique_id;
+#endif
+#if defined(CONFIG_OF_KOBJ)
struct bin_attribute attr;
+#endif
};
#if defined(CONFIG_SPARC)
@@ -58,7 +64,9 @@ struct device_node {
struct device_node *parent;
struct device_node *child;
struct device_node *sibling;
+#if defined(CONFIG_OF_KOBJ)
struct kobject kobj;
+#endif
unsigned long _flags;
void *data;
#if defined(CONFIG_SPARC)
@@ -103,21 +111,17 @@ extern struct kobj_type of_node_ktype;
extern const struct fwnode_operations of_fwnode_ops;
static inline void of_node_init(struct device_node *node)
{
+#if defined(CONFIG_OF_KOBJ)
kobject_init(&node->kobj, &of_node_ktype);
+#endif
node->fwnode.ops = &of_fwnode_ops;
}
-/* true when node is initialized */
-static inline int of_node_is_initialized(struct device_node *node)
-{
- return node && node->kobj.state_initialized;
-}
-
-/* true when node is attached (i.e. present on sysfs) */
-static inline int of_node_is_attached(struct device_node *node)
-{
- return node && node->kobj.state_in_sysfs;
-}
+#if defined(CONFIG_OF_KOBJ)
+#define of_node_kobj(n) (&(n)->kobj)
+#else
+#define of_node_kobj(n) NULL
+#endif
#ifdef CONFIG_OF_DYNAMIC
extern struct device_node *of_node_get(struct device_node *node);
@@ -203,6 +207,7 @@ static inline void of_node_clear_flag(struct device_node *n, unsigned long flag)
clear_bit(flag, &n->_flags);
}
+#if defined(CONFIG_OF_DYNAMIC) || defined(CONFIG_SPARC)
static inline int of_property_check_flag(struct property *p, unsigned long flag)
{
return test_bit(flag, &p->_flags);
@@ -217,6 +222,7 @@ static inline void of_property_clear_flag(struct property *p, unsigned long flag
{
clear_bit(flag, &p->_flags);
}
+#endif
extern struct device_node *__of_find_all_nodes(struct device_node *prev);
extern struct device_node *of_find_all_nodes(struct device_node *prev);
@@ -1273,9 +1279,6 @@ static inline int of_reconfig_get_state_change(unsigned long action,
}
#endif /* CONFIG_OF_DYNAMIC */
-/* CONFIG_OF_RESOLVE api */
-extern int of_resolve_phandles(struct device_node *tree);
-
/**
* of_device_is_system_power_controller - Tells if system-power-controller is found for device_node
* @np: Pointer to the given device_node
@@ -1292,7 +1295,7 @@ static inline bool of_device_is_system_power_controller(const struct device_node
*/
enum of_overlay_notify_action {
- OF_OVERLAY_PRE_APPLY,
+ OF_OVERLAY_PRE_APPLY = 0,
OF_OVERLAY_POST_APPLY,
OF_OVERLAY_PRE_REMOVE,
OF_OVERLAY_POST_REMOVE,
@@ -1306,26 +1309,26 @@ struct of_overlay_notify_data {
#ifdef CONFIG_OF_OVERLAY
/* ID based overlays; the API for external users */
-int of_overlay_create(struct device_node *tree);
-int of_overlay_destroy(int id);
-int of_overlay_destroy_all(void);
+int of_overlay_apply(struct device_node *tree, int *ovcs_id);
+int of_overlay_remove(int *ovcs_id);
+int of_overlay_remove_all(void);
int of_overlay_notifier_register(struct notifier_block *nb);
int of_overlay_notifier_unregister(struct notifier_block *nb);
#else
-static inline int of_overlay_create(struct device_node *tree)
+static inline int of_overlay_apply(struct device_node *tree, int *ovcs_id)
{
return -ENOTSUPP;
}
-static inline int of_overlay_destroy(int id)
+static inline int of_overlay_remove(int *ovcs_id)
{
return -ENOTSUPP;
}
-static inline int of_overlay_destroy_all(void)
+static inline int of_overlay_remove_all(void)
{
return -ENOTSUPP;
}
diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
index 62ea8f83d4a0..e66138449886 100644
--- a/scripts/dtc/checks.c
+++ b/scripts/dtc/checks.c
@@ -873,7 +873,7 @@ static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct no
while (size--)
reg = (reg << 32) | fdt32_to_cpu(*(cells++));
- snprintf(unit_addr, sizeof(unit_addr), "%llx", (unsigned long long)reg);
+ snprintf(unit_addr, sizeof(unit_addr), "%"PRIx64, reg);
if (!streq(unitname, unit_addr))
FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"",
node->fullpath, unit_addr);
@@ -956,6 +956,274 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c,
WARNING(obsolete_chosen_interrupt_controller,
check_obsolete_chosen_interrupt_controller, NULL);
+struct provider {
+ const char *prop_name;
+ const char *cell_name;
+ bool optional;
+};
+
+static void check_property_phandle_args(struct check *c,
+ struct dt_info *dti,
+ struct node *node,
+ struct property *prop,
+ const struct provider *provider)
+{
+ struct node *root = dti->dt;
+ int cell, cellsize = 0;
+
+ if (prop->val.len % sizeof(cell_t)) {
+ FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s",
+ prop->name, prop->val.len, sizeof(cell_t), node->fullpath);
+ return;
+ }
+
+ for (cell = 0; cell < prop->val.len / sizeof(cell_t); cell += cellsize + 1) {
+ struct node *provider_node;
+ struct property *cellprop;
+ int phandle;
+
+ phandle = propval_cell_n(prop, cell);
+ /*
+ * Some bindings use a cell value 0 or -1 to skip over optional
+ * entries when each index position has a specific definition.
+ */
+ if (phandle == 0 || phandle == -1) {
+ /* Give up if this is an overlay with external references */
+ if (dti->dtsflags & DTSF_PLUGIN)
+ break;
+
+ cellsize = 0;
+ continue;
+ }
+
+ /* If we have markers, verify the current cell is a phandle */
+ if (prop->val.markers) {
+ struct marker *m = prop->val.markers;
+ for_each_marker_of_type(m, REF_PHANDLE) {
+ if (m->offset == (cell * sizeof(cell_t)))
+ break;
+ }
+ if (!m)
+ FAIL(c, dti, "Property '%s', cell %d is not a phandle reference in %s",
+ prop->name, cell, node->fullpath);
+ }
+
+ provider_node = get_node_by_phandle(root, phandle);
+ if (!provider_node) {
+ FAIL(c, dti, "Could not get phandle node for %s:%s(cell %d)",
+ node->fullpath, prop->name, cell);
+ break;
+ }
+
+ cellprop = get_property(provider_node, provider->cell_name);
+ if (cellprop) {
+ cellsize = propval_cell(cellprop);
+ } else if (provider->optional) {
+ cellsize = 0;
+ } else {
+ FAIL(c, dti, "Missing property '%s' in node %s or bad phandle (referred from %s:%s[%d])",
+ provider->cell_name,
+ provider_node->fullpath,
+ node->fullpath, prop->name, cell);
+ break;
+ }
+
+ if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) {
+ FAIL(c, dti, "%s property size (%d) too small for cell size %d in %s",
+ prop->name, prop->val.len, cellsize, node->fullpath);
+ }
+ }
+}
+
+static void check_provider_cells_property(struct check *c,
+ struct dt_info *dti,
+ struct node *node)
+{
+ struct provider *provider = c->data;
+ struct property *prop;
+
+ prop = get_property(node, provider->prop_name);
+ if (!prop)
+ return;
+
+ check_property_phandle_args(c, dti, node, prop, provider);
+}
+#define WARNING_PROPERTY_PHANDLE_CELLS(nm, propname, cells_name, ...) \
+ static struct provider nm##_provider = { (propname), (cells_name), __VA_ARGS__ }; \
+ WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &phandle_references);
+
+WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(dmas, "dmas", "#dma-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(hwlocks, "hwlocks", "#hwlock-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(interrupts_extended, "interrupts-extended", "#interrupt-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(io_channels, "io-channels", "#io-channel-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(iommus, "iommus", "#iommu-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(mboxes, "mboxes", "#mbox-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(msi_parent, "msi-parent", "#msi-cells", true);
+WARNING_PROPERTY_PHANDLE_CELLS(mux_controls, "mux-controls", "#mux-control-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(phys, "phys", "#phy-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(sound_dais, "sound-dais", "#sound-dai-cells");
+WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells");
+
+static bool prop_is_gpio(struct property *prop)
+{
+ char *str;
+
+ /*
+ * *-gpios and *-gpio can appear in property names,
+ * so skip over any false matches (only one known ATM)
+ */
+ if (strstr(prop->name, "nr-gpio"))
+ return false;
+
+ str = strrchr(prop->name, '-');
+ if (str)
+ str++;
+ else
+ str = prop->name;
+ if (!(streq(str, "gpios") || streq(str, "gpio")))
+ return false;
+
+ return true;
+}
+
+static void check_gpios_property(struct check *c,
+ struct dt_info *dti,
+ struct node *node)
+{
+ struct property *prop;
+
+ /* Skip GPIO hog nodes which have 'gpios' property */
+ if (get_property(node, "gpio-hog"))
+ return;
+
+ for_each_property(node, prop) {
+ struct provider provider;
+
+ if (!prop_is_gpio(prop))
+ continue;
+
+ provider.prop_name = prop->name;
+ provider.cell_name = "#gpio-cells";
+ provider.optional = false;
+ check_property_phandle_args(c, dti, node, prop, &provider);
+ }
+
+}
+WARNING(gpios_property, check_gpios_property, NULL, &phandle_references);
+
+static void check_deprecated_gpio_property(struct check *c,
+ struct dt_info *dti,
+ struct node *node)
+{
+ struct property *prop;
+
+ for_each_property(node, prop) {
+ char *str;
+
+ if (!prop_is_gpio(prop))
+ continue;
+
+ str = strstr(prop->name, "gpio");
+ if (!streq(str, "gpio"))
+ continue;
+
+ FAIL(c, dti, "'[*-]gpio' is deprecated, use '[*-]gpios' instead for %s:%s",
+ node->fullpath, prop->name);
+ }
+
+}
+CHECK(deprecated_gpio_property, check_deprecated_gpio_property, NULL);
+
+static bool node_is_interrupt_provider(struct node *node)
+{
+ struct property *prop;
+
+ prop = get_property(node, "interrupt-controller");
+ if (prop)
+ return true;
+
+ prop = get_property(node, "interrupt-map");
+ if (prop)
+ return true;
+
+ return false;
+}
+static void check_interrupts_property(struct check *c,
+ struct dt_info *dti,
+ struct node *node)
+{
+ struct node *root = dti->dt;
+ struct node *irq_node = NULL, *parent = node;
+ struct property *irq_prop, *prop = NULL;
+ int irq_cells, phandle;
+
+ irq_prop = get_property(node, "interrupts");
+ if (!irq_prop)
+ return;
+
+ if (irq_prop->val.len % sizeof(cell_t))
+ FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s",
+ irq_prop->name, irq_prop->val.len, sizeof(cell_t),
+ node->fullpath);
+
+ while (parent && !prop) {
+ if (parent != node && node_is_interrupt_provider(parent)) {
+ irq_node = parent;
+ break;
+ }
+
+ prop = get_property(parent, "interrupt-parent");
+ if (prop) {
+ phandle = propval_cell(prop);
+ /* Give up if this is an overlay with external references */
+ if ((phandle == 0 || phandle == -1) &&
+ (dti->dtsflags & DTSF_PLUGIN))
+ return;
+
+ irq_node = get_node_by_phandle(root, phandle);
+ if (!irq_node) {
+ FAIL(c, dti, "Bad interrupt-parent phandle for %s",
+ node->fullpath);
+ return;
+ }
+ if (!node_is_interrupt_provider(irq_node))
+ FAIL(c, dti,
+ "Missing interrupt-controller or interrupt-map property in %s",
+ irq_node->fullpath);
+
+ break;
+ }
+
+ parent = parent->parent;
+ }
+
+ if (!irq_node) {
+ FAIL(c, dti, "Missing interrupt-parent for %s", node->fullpath);
+ return;
+ }
+
+ prop = get_property(irq_node, "#interrupt-cells");
+ if (!prop) {
+ FAIL(c, dti, "Missing #interrupt-cells in interrupt-parent %s",
+ irq_node->fullpath);
+ return;
+ }
+
+ irq_cells = propval_cell(prop);
+ if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) {
+ FAIL(c, dti,
+ "interrupts size is (%d), expected multiple of %d in %s",
+ irq_prop->val.len, (int)(irq_cells * sizeof(cell_t)),
+ node->fullpath);
+ }
+}
+WARNING(interrupts_property, check_interrupts_property, &phandle_references);
+
static struct check *check_table[] = {
&duplicate_node_names, &duplicate_property_names,
&node_name_chars, &node_name_format, &property_name_chars,
@@ -987,6 +1255,27 @@ static struct check *check_table[] = {
&avoid_default_addr_size,
&obsolete_chosen_interrupt_controller,
+ &clocks_property,
+ &cooling_device_property,
+ &dmas_property,
+ &hwlocks_property,
+ &interrupts_extended_property,
+ &io_channels_property,
+ &iommus_property,
+ &mboxes_property,
+ &msi_parent_property,
+ &mux_controls_property,
+ &phys_property,
+ &power_domains_property,
+ &pwms_property,
+ &resets_property,
+ &sound_dais_property,
+ &thermal_sensors_property,
+
+ &deprecated_gpio_property,
+ &gpios_property,
+ &interrupts_property,
+
&always_fail,
};
diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped
index 64c243772398..011bb9632ff2 100644
--- a/scripts/dtc/dtc-lexer.lex.c_shipped
+++ b/scripts/dtc/dtc-lexer.lex.c_shipped
@@ -1397,7 +1397,7 @@ static int yy_get_next_buffer (void)
{
char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
char *source = (yytext_ptr);
- yy_size_t number_to_move, i;
+ int number_to_move, i;
int ret_val;
if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
@@ -1426,7 +1426,7 @@ static int yy_get_next_buffer (void)
/* Try to read more data. */
/* First move last chars to start of buffer. */
- number_to_move = (yy_size_t) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);
for ( i = 0; i < number_to_move; ++i )
*(dest++) = *(source++);
@@ -1508,7 +1508,7 @@ static int yy_get_next_buffer (void)
else
ret_val = EOB_ACT_CONTINUE_SCAN;
- if ((int) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
/* Extend the array by 50%, plus the number we really need. */
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 );
@@ -1987,10 +1987,10 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
- yy_size_t i;
+ int i;
/* Get memory for full buffer, including space for trailing EOB's. */
- n = (yy_size_t) _yybytes_len + 2;
+ n = (yy_size_t) (_yybytes_len + 2);
buf = (char *) yyalloc(n );
if ( ! buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped
index 0a7a5ed86f04..aea514fa6928 100644
--- a/scripts/dtc/dtc-parser.tab.c_shipped
+++ b/scripts/dtc/dtc-parser.tab.c_shipped
@@ -448,7 +448,7 @@ union yyalloc
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 30
/* YYNRULES -- Number of rules. */
-#define YYNRULES 84
+#define YYNRULES 85
/* YYNSTATES -- Number of states. */
#define YYNSTATES 149
@@ -499,14 +499,14 @@ static const yytype_uint8 yytranslate[] =
static const yytype_uint16 yyrline[] =
{
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
+ 153, 161, 165, 170, 181, 200, 213, 220, 228, 231,
+ 238, 242, 246, 250, 258, 262, 266, 270, 274, 290,
+ 300, 308, 311, 315, 322, 338, 343, 362, 376, 383,
+ 384, 385, 392, 396, 397, 401, 402, 406, 407, 411,
+ 412, 416, 417, 421, 422, 426, 427, 428, 432, 433,
+ 434, 435, 436, 440, 441, 442, 446, 447, 448, 452,
+ 453, 462, 471, 475, 476, 477, 478, 483, 486, 490,
+ 498, 501, 505, 513, 517, 521
};
#endif
@@ -582,20 +582,20 @@ static const yytype_int8 yypact[] =
static const yytype_uint8 yydefact[] =
{
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,
+ 16, 7, 0, 39, 40, 0, 0, 10, 0, 2,
+ 8, 4, 0, 0, 0, 73, 0, 42, 43, 45,
+ 47, 49, 51, 53, 55, 58, 65, 68, 72, 0,
+ 18, 11, 0, 0, 0, 0, 74, 75, 76, 41,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
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
+ 80, 0, 0, 14, 12, 46, 0, 48, 50, 52,
+ 54, 56, 57, 61, 62, 60, 59, 63, 64, 66,
+ 67, 70, 69, 71, 0, 0, 0, 0, 19, 0,
+ 80, 15, 13, 0, 0, 0, 21, 31, 83, 23,
+ 85, 0, 82, 81, 44, 22, 84, 0, 0, 17,
+ 30, 20, 32, 0, 24, 33, 27, 0, 77, 35,
+ 0, 0, 0, 0, 38, 37, 25, 36, 34, 0,
+ 78, 79, 26, 0, 29, 0, 0, 0, 28
};
/* YYPGOTO[NTERM-NUM]. */
@@ -678,28 +678,28 @@ static const yytype_uint8 yystos[] =
static const yytype_uint8 yyr1[] =
{
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
+ 53, 54, 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. */
static const yytype_uint8 yyr2[] =
{
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
+ 2, 2, 3, 4, 3, 4, 0, 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
};
@@ -1572,17 +1572,26 @@ yyreduce:
{
struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref));
- if (target)
+ if (target) {
merge_nodes(target, (yyvsp[0].node));
- else
- ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
+ } else {
+ /*
+ * We rely on the rule being always:
+ * versioninfo plugindecl memreserves devicetree
+ * so $-1 is what we want (plugindecl)
+ */
+ if ((yyvsp[(-1) - (3)].flags) & DTSF_PLUGIN)
+ add_orphan_node((yyvsp[-2].node), (yyvsp[0].node), (yyvsp[-1].labelref));
+ else
+ ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
+ }
(yyval.node) = (yyvsp[-2].node);
}
-#line 1582 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1591 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 15:
-#line 192 "dtc-parser.y" /* yacc.c:1646 */
+#line 201 "dtc-parser.y" /* yacc.c:1646 */
{
struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
@@ -1594,100 +1603,109 @@ yyreduce:
(yyval.node) = (yyvsp[-3].node);
}
-#line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1607 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 16:
-#line 207 "dtc-parser.y" /* yacc.c:1646 */
+#line 213 "dtc-parser.y" /* yacc.c:1646 */
{
- (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
+ /* build empty node */
+ (yyval.node) = name_node(build_node(NULL, NULL), "");
}
-#line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1616 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 17:
-#line 214 "dtc-parser.y" /* yacc.c:1646 */
+#line 221 "dtc-parser.y" /* yacc.c:1646 */
{
- (yyval.proplist) = NULL;
+ (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist));
}
-#line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1624 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 18:
-#line 218 "dtc-parser.y" /* yacc.c:1646 */
+#line 228 "dtc-parser.y" /* yacc.c:1646 */
{
- (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
+ (yyval.proplist) = NULL;
}
-#line 1622 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1632 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 19:
-#line 225 "dtc-parser.y" /* yacc.c:1646 */
+#line 232 "dtc-parser.y" /* yacc.c:1646 */
{
- (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
+ (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist));
}
-#line 1630 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1640 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 20:
-#line 229 "dtc-parser.y" /* yacc.c:1646 */
+#line 239 "dtc-parser.y" /* yacc.c:1646 */
{
- (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
+ (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data));
}
-#line 1638 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1648 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 21:
-#line 233 "dtc-parser.y" /* yacc.c:1646 */
+#line 243 "dtc-parser.y" /* yacc.c:1646 */
{
- (yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
+ (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data);
}
-#line 1646 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1656 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
case 22:
-#line 237 "dtc-parser.y" /* yacc.c:1646 */
+#line 247 "dtc-parser.y" /* yacc.c:1646 */
+ {
+ (yyval.prop) = build_property_delete((yyvsp[-1].propnodename));
+ }
+#line 1664 "dtc-parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 23:
+#line 251 "dtc-parser.y" /* yacc.c:1646 */
{
add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref));
(yyval.prop) = (yyvsp[0].prop);
}
-#line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1673 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 23:
-#line 245 "dtc-parser.y" /* yacc.c:1646 */
+ case 24:
+#line 259 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data));
}
-#line 1663 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1681 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 24:
-#line 249 "dtc-parser.y" /* yacc.c:1646 */
+ case 25:
+#line 263 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data);
}
-#line 1671 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 25:
-#line 253 "dtc-parser.y" /* yacc.c:1646 */
+ case 26:
+#line 267 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data));
}
-#line 1679 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 26:
-#line 257 "dtc-parser.y" /* yacc.c:1646 */
+ case 27:
+#line 271 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref));
}
-#line 1687 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 27:
-#line 261 "dtc-parser.y" /* yacc.c:1646 */
+ case 28:
+#line 275 "dtc-parser.y" /* yacc.c:1646 */
{
FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL);
struct data d;
@@ -1703,11 +1721,11 @@ yyreduce:
(yyval.data) = data_merge((yyvsp[-8].data), d);
fclose(f);
}
-#line 1707 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1725 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 28:
-#line 277 "dtc-parser.y" /* yacc.c:1646 */
+ case 29:
+#line 291 "dtc-parser.y" /* yacc.c:1646 */
{
FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL);
struct data d = empty_data;
@@ -1717,43 +1735,43 @@ yyreduce:
(yyval.data) = data_merge((yyvsp[-4].data), d);
fclose(f);
}
-#line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1739 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 29:
-#line 287 "dtc-parser.y" /* yacc.c:1646 */
+ case 30:
+#line 301 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
}
-#line 1729 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1747 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 30:
-#line 294 "dtc-parser.y" /* yacc.c:1646 */
+ case 31:
+#line 308 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = empty_data;
}
-#line 1737 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1755 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 31:
-#line 298 "dtc-parser.y" /* yacc.c:1646 */
+ case 32:
+#line 312 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = (yyvsp[-1].data);
}
-#line 1745 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1763 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 32:
-#line 302 "dtc-parser.y" /* yacc.c:1646 */
+ case 33:
+#line 316 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
}
-#line 1753 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1771 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 33:
-#line 309 "dtc-parser.y" /* yacc.c:1646 */
+ case 34:
+#line 323 "dtc-parser.y" /* yacc.c:1646 */
{
unsigned long long bits;
@@ -1769,20 +1787,20 @@ yyreduce:
(yyval.array).data = empty_data;
(yyval.array).bits = bits;
}
-#line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 34:
-#line 325 "dtc-parser.y" /* yacc.c:1646 */
+ case 35:
+#line 339 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.array).data = empty_data;
(yyval.array).bits = 32;
}
-#line 1782 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1800 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 35:
-#line 330 "dtc-parser.y" /* yacc.c:1646 */
+ case 36:
+#line 344 "dtc-parser.y" /* yacc.c:1646 */
{
if ((yyvsp[-1].array).bits < 64) {
uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1;
@@ -1801,11 +1819,11 @@ yyreduce:
(yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits);
}
-#line 1805 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1823 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 36:
-#line 349 "dtc-parser.y" /* yacc.c:1646 */
+ case 37:
+#line 363 "dtc-parser.y" /* yacc.c:1646 */
{
uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits);
@@ -1819,129 +1837,129 @@ yyreduce:
(yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits);
}
-#line 1823 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1841 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 37:
-#line 363 "dtc-parser.y" /* yacc.c:1646 */
+ case 38:
+#line 377 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref));
}
-#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 40:
-#line 372 "dtc-parser.y" /* yacc.c:1646 */
+ case 41:
+#line 386 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.integer) = (yyvsp[-1].integer);
}
-#line 1839 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1857 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 43:
-#line 383 "dtc-parser.y" /* yacc.c:1646 */
+ case 44:
+#line 397 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); }
-#line 1845 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1863 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 45:
-#line 388 "dtc-parser.y" /* yacc.c:1646 */
+ case 46:
+#line 402 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); }
-#line 1851 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1869 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 47:
-#line 393 "dtc-parser.y" /* yacc.c:1646 */
+ case 48:
+#line 407 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); }
-#line 1857 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1875 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 49:
-#line 398 "dtc-parser.y" /* yacc.c:1646 */
+ case 50:
+#line 412 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); }
-#line 1863 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1881 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 51:
-#line 403 "dtc-parser.y" /* yacc.c:1646 */
+ case 52:
+#line 417 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); }
-#line 1869 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1887 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 53:
-#line 408 "dtc-parser.y" /* yacc.c:1646 */
+ case 54:
+#line 422 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); }
-#line 1875 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1893 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 55:
-#line 413 "dtc-parser.y" /* yacc.c:1646 */
+ case 56:
+#line 427 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); }
-#line 1881 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1899 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 56:
-#line 414 "dtc-parser.y" /* yacc.c:1646 */
+ case 57:
+#line 428 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); }
-#line 1887 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1905 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 58:
-#line 419 "dtc-parser.y" /* yacc.c:1646 */
+ case 59:
+#line 433 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); }
-#line 1893 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1911 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 59:
-#line 420 "dtc-parser.y" /* yacc.c:1646 */
+ case 60:
+#line 434 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); }
-#line 1899 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1917 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 60:
-#line 421 "dtc-parser.y" /* yacc.c:1646 */
+ case 61:
+#line 435 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); }
-#line 1905 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1923 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 61:
-#line 422 "dtc-parser.y" /* yacc.c:1646 */
+ case 62:
+#line 436 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); }
-#line 1911 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1929 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 62:
-#line 426 "dtc-parser.y" /* yacc.c:1646 */
+ case 63:
+#line 440 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); }
-#line 1917 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 63:
-#line 427 "dtc-parser.y" /* yacc.c:1646 */
+ case 64:
+#line 441 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); }
-#line 1923 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 65:
-#line 432 "dtc-parser.y" /* yacc.c:1646 */
+ case 66:
+#line 446 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); }
-#line 1929 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 66:
-#line 433 "dtc-parser.y" /* yacc.c:1646 */
+ case 67:
+#line 447 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); }
-#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 68:
-#line 438 "dtc-parser.y" /* yacc.c:1646 */
+ case 69:
+#line 452 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); }
-#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1959 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 69:
-#line 440 "dtc-parser.y" /* yacc.c:1646 */
+ case 70:
+#line 454 "dtc-parser.y" /* yacc.c:1646 */
{
if ((yyvsp[0].integer) != 0) {
(yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer);
@@ -1950,11 +1968,11 @@ yyreduce:
(yyval.integer) = 0;
}
}
-#line 1954 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1972 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 70:
-#line 449 "dtc-parser.y" /* yacc.c:1646 */
+ case 71:
+#line 463 "dtc-parser.y" /* yacc.c:1646 */
{
if ((yyvsp[0].integer) != 0) {
(yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer);
@@ -1963,103 +1981,103 @@ yyreduce:
(yyval.integer) = 0;
}
}
-#line 1967 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 73:
-#line 462 "dtc-parser.y" /* yacc.c:1646 */
+ case 74:
+#line 476 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = -(yyvsp[0].integer); }
-#line 1973 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1991 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 74:
-#line 463 "dtc-parser.y" /* yacc.c:1646 */
+ case 75:
+#line 477 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = ~(yyvsp[0].integer); }
-#line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 1997 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 75:
-#line 464 "dtc-parser.y" /* yacc.c:1646 */
+ case 76:
+#line 478 "dtc-parser.y" /* yacc.c:1646 */
{ (yyval.integer) = !(yyvsp[0].integer); }
-#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2003 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 76:
-#line 469 "dtc-parser.y" /* yacc.c:1646 */
+ case 77:
+#line 483 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = empty_data;
}
-#line 1993 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2011 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 77:
-#line 473 "dtc-parser.y" /* yacc.c:1646 */
+ case 78:
+#line 487 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte));
}
-#line 2001 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2019 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 78:
-#line 477 "dtc-parser.y" /* yacc.c:1646 */
+ case 79:
+#line 491 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref));
}
-#line 2009 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 79:
-#line 484 "dtc-parser.y" /* yacc.c:1646 */
+ case 80:
+#line 498 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.nodelist) = NULL;
}
-#line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2035 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 80:
-#line 488 "dtc-parser.y" /* yacc.c:1646 */
+ case 81:
+#line 502 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist));
}
-#line 2025 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2043 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 81:
-#line 492 "dtc-parser.y" /* yacc.c:1646 */
+ case 82:
+#line 506 "dtc-parser.y" /* yacc.c:1646 */
{
ERROR(&(yylsp[0]), "Properties must precede subnodes");
YYERROR;
}
-#line 2034 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2052 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 82:
-#line 500 "dtc-parser.y" /* yacc.c:1646 */
+ case 83:
+#line 514 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename));
}
-#line 2042 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2060 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 83:
-#line 504 "dtc-parser.y" /* yacc.c:1646 */
+ case 84:
+#line 518 "dtc-parser.y" /* yacc.c:1646 */
{
(yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename));
}
-#line 2050 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2068 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
- case 84:
-#line 508 "dtc-parser.y" /* yacc.c:1646 */
+ case 85:
+#line 522 "dtc-parser.y" /* yacc.c:1646 */
{
add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref));
(yyval.node) = (yyvsp[0].node);
}
-#line 2059 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2077 "dtc-parser.tab.c" /* yacc.c:1646 */
break;
-#line 2063 "dtc-parser.tab.c" /* yacc.c:1646 */
+#line 2081 "dtc-parser.tab.c" /* yacc.c:1646 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -2294,7 +2312,7 @@ yyreturn:
#endif
return yyresult;
}
-#line 514 "dtc-parser.y" /* yacc.c:1906 */
+#line 528 "dtc-parser.y" /* yacc.c:1906 */
void yyerror(char const *s)
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
index ca3f5003427c..affc81a8f9ab 100644
--- a/scripts/dtc/dtc-parser.y
+++ b/scripts/dtc/dtc-parser.y
@@ -182,10 +182,19 @@ devicetree:
{
struct node *target = get_node_by_ref($1, $2);
- if (target)
+ if (target) {
merge_nodes(target, $3);
- else
- ERROR(&@2, "Label or path %s not found", $2);
+ } else {
+ /*
+ * We rely on the rule being always:
+ * versioninfo plugindecl memreserves devicetree
+ * so $-1 is what we want (plugindecl)
+ */
+ if ($<flags>-1 & DTSF_PLUGIN)
+ add_orphan_node($1, $3, $2);
+ else
+ ERROR(&@2, "Label or path %s not found", $2);
+ }
$$ = $1;
}
| devicetree DT_DEL_NODE DT_REF ';'
@@ -200,6 +209,11 @@ devicetree:
$$ = $1;
}
+ | /* empty */
+ {
+ /* build empty node */
+ $$ = name_node(build_node(NULL, NULL), "");
+ }
;
nodedef:
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
index f5eed9d72c02..5ed873c72ad1 100644
--- a/scripts/dtc/dtc.c
+++ b/scripts/dtc/dtc.c
@@ -31,7 +31,7 @@ int reservenum; /* Number of memory reservation slots */
int minsize; /* Minimum blob size */
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_EPAPR; /* 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 */
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index fc24e17510fd..35cf926cc14a 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -31,6 +31,7 @@
#include <ctype.h>
#include <errno.h>
#include <unistd.h>
+#include <inttypes.h>
#include <libfdt_env.h>
#include <fdt.h>
@@ -202,6 +203,7 @@ struct node *build_node_delete(void);
struct node *name_node(struct node *node, char *name);
struct node *chain_node(struct node *first, struct node *list);
struct node *merge_nodes(struct node *old_node, struct node *new_node);
+void add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
void add_property(struct node *node, struct property *prop);
void delete_property_by_name(struct node *node, char *name);
@@ -215,6 +217,7 @@ void append_to_property(struct node *node,
const char *get_unitname(struct node *node);
struct property *get_property(struct node *node, const char *propname);
cell_t propval_cell(struct property *prop);
+cell_t propval_cell_n(struct property *prop, int n);
struct property *get_property_by_label(struct node *tree, const char *label,
struct node **node);
struct marker *get_marker_label(struct node *tree, const char *label,
diff --git a/scripts/dtc/libfdt/fdt_addresses.c b/scripts/dtc/libfdt/fdt_addresses.c
new file mode 100644
index 000000000000..eff4dbcc729d
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt_addresses.c
@@ -0,0 +1,96 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>
+ *
+ * libfdt is dual licensed: you can use it either under the terms of
+ * the GPL, or the BSD license, at your option.
+ *
+ * a) This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Alternatively,
+ *
+ * b) Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+int fdt_address_cells(const void *fdt, int nodeoffset)
+{
+ const fdt32_t *ac;
+ int val;
+ int len;
+
+ ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len);
+ if (!ac)
+ return 2;
+
+ if (len != sizeof(*ac))
+ return -FDT_ERR_BADNCELLS;
+
+ val = fdt32_to_cpu(*ac);
+ if ((val <= 0) || (val > FDT_MAX_NCELLS))
+ return -FDT_ERR_BADNCELLS;
+
+ return val;
+}
+
+int fdt_size_cells(const void *fdt, int nodeoffset)
+{
+ const fdt32_t *sc;
+ int val;
+ int len;
+
+ sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len);
+ if (!sc)
+ return 2;
+
+ if (len != sizeof(*sc))
+ return -FDT_ERR_BADNCELLS;
+
+ val = fdt32_to_cpu(*sc);
+ if ((val < 0) || (val > FDT_MAX_NCELLS))
+ return -FDT_ERR_BADNCELLS;
+
+ return val;
+}
diff --git a/scripts/dtc/libfdt/fdt_empty_tree.c b/scripts/dtc/libfdt/fdt_empty_tree.c
index f72d13b1d19c..f2ae9b77c285 100644
--- a/scripts/dtc/libfdt/fdt_empty_tree.c
+++ b/scripts/dtc/libfdt/fdt_empty_tree.c
@@ -81,4 +81,3 @@ int fdt_create_empty_tree(void *buf, int bufsize)
return fdt_open_into(buf, buf, bufsize);
}
-
diff --git a/scripts/dtc/libfdt/fdt_overlay.c b/scripts/dtc/libfdt/fdt_overlay.c
new file mode 100644
index 000000000000..bd81241e6658
--- /dev/null
+++ b/scripts/dtc/libfdt/fdt_overlay.c
@@ -0,0 +1,861 @@
+#include "libfdt_env.h"
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "libfdt_internal.h"
+
+/**
+ * overlay_get_target_phandle - retrieves the target phandle of a fragment
+ * @fdto: pointer to the device tree overlay blob
+ * @fragment: node offset of the fragment in the overlay
+ *
+ * overlay_get_target_phandle() retrieves the target phandle of an
+ * overlay fragment when that fragment uses a phandle (target
+ * property) instead of a path (target-path property).
+ *
+ * returns:
+ * the phandle pointed by the target property
+ * 0, if the phandle was not found
+ * -1, if the phandle was malformed
+ */
+static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
+{
+ const fdt32_t *val;
+ int len;
+
+ val = fdt_getprop(fdto, fragment, "target", &len);
+ if (!val)
+ return 0;
+
+ if ((len != sizeof(*val)) || (fdt32_to_cpu(*val) == (uint32_t)-1))
+ return (uint32_t)-1;
+
+ return fdt32_to_cpu(*val);
+}
+
+/**
+ * overlay_get_target - retrieves the offset of a fragment's target
+ * @fdt: Base device tree blob
+ * @fdto: Device tree overlay blob
+ * @fragment: node offset of the fragment in the overlay
+ * @pathp: pointer which receives the path of the target (or NULL)
+ *
+ * overlay_get_target() retrieves the target offset in the base
+ * device tree of a fragment, no matter how the actual targetting is
+ * done (through a phandle or a path)
+ *
+ * returns:
+ * the targetted node offset in the base device tree
+ * Negative error code on error
+ */
+static int overlay_get_target(const void *fdt, const void *fdto,
+ int fragment, char const **pathp)
+{
+ uint32_t phandle;
+ const char *path = NULL;
+ int path_len = 0, ret;
+
+ /* Try first to do a phandle based lookup */
+ phandle = overlay_get_target_phandle(fdto, fragment);
+ if (phandle == (uint32_t)-1)
+ return -FDT_ERR_BADPHANDLE;
+
+ /* no phandle, try path */
+ if (!phandle) {
+ /* And then a path based lookup */
+ path = fdt_getprop(fdto, fragment, "target-path", &path_len);
+ if (path)
+ ret = fdt_path_offset(fdt, path);
+ else
+ ret = path_len;
+ } else
+ ret = fdt_node_offset_by_phandle(fdt, phandle);
+
+ /*
+ * If we haven't found either a target or a
+ * target-path property in a node that contains a
+ * __overlay__ subnode (we wouldn't be called
+ * otherwise), consider it a improperly written
+ * overlay
+ */
+ if (ret < 0 && path_len == -FDT_ERR_NOTFOUND)
+ ret = -FDT_ERR_BADOVERLAY;
+
+ /* return on error */
+ if (ret < 0)
+ return ret;
+
+ /* return pointer to path (if available) */
+ if (pathp)
+ *pathp = path ? path : NULL;
+
+ return ret;
+}
+
+/**
+ * overlay_phandle_add_offset - Increases a phandle by an offset
+ * @fdt: Base device tree blob
+ * @node: Device tree overlay blob
+ * @name: Name of the property to modify (phandle or linux,phandle)
+ * @delta: offset to apply
+ *
+ * overlay_phandle_add_offset() increments a node phandle by a given
+ * offset.
+ *
+ * returns:
+ * 0 on success.
+ * Negative error code on error
+ */
+static int overlay_phandle_add_offset(void *fdt, int node,
+ const char *name, uint32_t delta)
+{
+ const fdt32_t *val;
+ uint32_t adj_val;
+ int len;
+
+ val = fdt_getprop(fdt, node, name, &len);
+ if (!val)
+ return len;
+
+ if (len != sizeof(*val))
+ return -FDT_ERR_BADPHANDLE;
+
+ adj_val = fdt32_to_cpu(*val);
+ if ((adj_val + delta) < adj_val)
+ return -FDT_ERR_NOPHANDLES;
+
+ adj_val += delta;
+ if (adj_val == (uint32_t)-1)
+ return -FDT_ERR_NOPHANDLES;
+
+ return fdt_setprop_inplace_u32(fdt, node, name, adj_val);
+}
+
+/**
+ * overlay_adjust_node_phandles - Offsets the phandles of a node
+ * @fdto: Device tree overlay blob
+ * @node: Offset of the node we want to adjust
+ * @delta: Offset to shift the phandles of
+ *
+ * overlay_adjust_node_phandles() adds a constant to all the phandles
+ * of a given node. This is mainly use as part of the overlay
+ * application process, when we want to update all the overlay
+ * phandles to not conflict with the overlays of the base device tree.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_adjust_node_phandles(void *fdto, int node,
+ uint32_t delta)
+{
+ int child;
+ int ret;
+
+ ret = overlay_phandle_add_offset(fdto, node, "phandle", delta);
+ if (ret && ret != -FDT_ERR_NOTFOUND)
+ return ret;
+
+ ret = overlay_phandle_add_offset(fdto, node, "linux,phandle", delta);
+ if (ret && ret != -FDT_ERR_NOTFOUND)
+ return ret;
+
+ fdt_for_each_subnode(child, fdto, node) {
+ ret = overlay_adjust_node_phandles(fdto, child, delta);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * overlay_adjust_local_phandles - Adjust the phandles of a whole overlay
+ * @fdto: Device tree overlay blob
+ * @delta: Offset to shift the phandles of
+ *
+ * overlay_adjust_local_phandles() adds a constant to all the
+ * phandles of an overlay. This is mainly use as part of the overlay
+ * application process, when we want to update all the overlay
+ * phandles to not conflict with the overlays of the base device tree.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_adjust_local_phandles(void *fdto, uint32_t delta)
+{
+ /*
+ * Start adjusting the phandles from the overlay root
+ */
+ return overlay_adjust_node_phandles(fdto, 0, delta);
+}
+
+/**
+ * overlay_update_local_node_references - Adjust the overlay references
+ * @fdto: Device tree overlay blob
+ * @tree_node: Node offset of the node to operate on
+ * @fixup_node: Node offset of the matching local fixups node
+ * @delta: Offset to shift the phandles of
+ *
+ * overlay_update_local_nodes_references() update the phandles
+ * pointing to a node within the device tree overlay by adding a
+ * constant delta.
+ *
+ * This is mainly used as part of a device tree application process,
+ * where you want the device tree overlays phandles to not conflict
+ * with the ones from the base device tree before merging them.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_update_local_node_references(void *fdto,
+ int tree_node,
+ int fixup_node,
+ uint32_t delta)
+{
+ int fixup_prop;
+ int fixup_child;
+ int ret;
+
+ fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) {
+ const fdt32_t *fixup_val;
+ const char *tree_val;
+ const char *name;
+ int fixup_len;
+ int tree_len;
+ int i;
+
+ fixup_val = fdt_getprop_by_offset(fdto, fixup_prop,
+ &name, &fixup_len);
+ if (!fixup_val)
+ return fixup_len;
+
+ if (fixup_len % sizeof(uint32_t))
+ return -FDT_ERR_BADOVERLAY;
+
+ tree_val = fdt_getprop(fdto, tree_node, name, &tree_len);
+ if (!tree_val) {
+ if (tree_len == -FDT_ERR_NOTFOUND)
+ return -FDT_ERR_BADOVERLAY;
+
+ return tree_len;
+ }
+
+ for (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) {
+ fdt32_t adj_val;
+ uint32_t poffset;
+
+ poffset = fdt32_to_cpu(fixup_val[i]);
+
+ /*
+ * phandles to fixup can be unaligned.
+ *
+ * Use a memcpy for the architectures that do
+ * not support unaligned accesses.
+ */
+ memcpy(&adj_val, tree_val + poffset, sizeof(adj_val));
+
+ adj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta);
+
+ ret = fdt_setprop_inplace_namelen_partial(fdto,
+ tree_node,
+ name,
+ strlen(name),
+ poffset,
+ &adj_val,
+ sizeof(adj_val));
+ if (ret == -FDT_ERR_NOSPACE)
+ return -FDT_ERR_BADOVERLAY;
+
+ if (ret)
+ return ret;
+ }
+ }
+
+ fdt_for_each_subnode(fixup_child, fdto, fixup_node) {
+ const char *fixup_child_name = fdt_get_name(fdto, fixup_child,
+ NULL);
+ int tree_child;
+
+ tree_child = fdt_subnode_offset(fdto, tree_node,
+ fixup_child_name);
+ if (tree_child == -FDT_ERR_NOTFOUND)
+ return -FDT_ERR_BADOVERLAY;
+ if (tree_child < 0)
+ return tree_child;
+
+ ret = overlay_update_local_node_references(fdto,
+ tree_child,
+ fixup_child,
+ delta);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * overlay_update_local_references - Adjust the overlay references
+ * @fdto: Device tree overlay blob
+ * @delta: Offset to shift the phandles of
+ *
+ * overlay_update_local_references() update all the phandles pointing
+ * to a node within the device tree overlay by adding a constant
+ * delta to not conflict with the base overlay.
+ *
+ * This is mainly used as part of a device tree application process,
+ * where you want the device tree overlays phandles to not conflict
+ * with the ones from the base device tree before merging them.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_update_local_references(void *fdto, uint32_t delta)
+{
+ int fixups;
+
+ fixups = fdt_path_offset(fdto, "/__local_fixups__");
+ if (fixups < 0) {
+ /* There's no local phandles to adjust, bail out */
+ if (fixups == -FDT_ERR_NOTFOUND)
+ return 0;
+
+ return fixups;
+ }
+
+ /*
+ * Update our local references from the root of the tree
+ */
+ return overlay_update_local_node_references(fdto, 0, fixups,
+ delta);
+}
+
+/**
+ * overlay_fixup_one_phandle - Set an overlay phandle to the base one
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ * @symbols_off: Node offset of the symbols node in the base device tree
+ * @path: Path to a node holding a phandle in the overlay
+ * @path_len: number of path characters to consider
+ * @name: Name of the property holding the phandle reference in the overlay
+ * @name_len: number of name characters to consider
+ * @poffset: Offset within the overlay property where the phandle is stored
+ * @label: Label of the node referenced by the phandle
+ *
+ * overlay_fixup_one_phandle() resolves an overlay phandle pointing to
+ * a node in the base device tree.
+ *
+ * This is part of the device tree overlay application process, when
+ * you want all the phandles in the overlay to point to the actual
+ * base dt nodes.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_fixup_one_phandle(void *fdt, void *fdto,
+ int symbols_off,
+ const char *path, uint32_t path_len,
+ const char *name, uint32_t name_len,
+ int poffset, const char *label)
+{
+ const char *symbol_path;
+ uint32_t phandle;
+ fdt32_t phandle_prop;
+ int symbol_off, fixup_off;
+ int prop_len;
+
+ if (symbols_off < 0)
+ return symbols_off;
+
+ symbol_path = fdt_getprop(fdt, symbols_off, label,
+ &prop_len);
+ if (!symbol_path)
+ return prop_len;
+
+ symbol_off = fdt_path_offset(fdt, symbol_path);
+ if (symbol_off < 0)
+ return symbol_off;
+
+ phandle = fdt_get_phandle(fdt, symbol_off);
+ if (!phandle)
+ return -FDT_ERR_NOTFOUND;
+
+ fixup_off = fdt_path_offset_namelen(fdto, path, path_len);
+ if (fixup_off == -FDT_ERR_NOTFOUND)
+ return -FDT_ERR_BADOVERLAY;
+ if (fixup_off < 0)
+ return fixup_off;
+
+ phandle_prop = cpu_to_fdt32(phandle);
+ return fdt_setprop_inplace_namelen_partial(fdto, fixup_off,
+ name, name_len, poffset,
+ &phandle_prop,
+ sizeof(phandle_prop));
+};
+
+/**
+ * overlay_fixup_phandle - Set an overlay phandle to the base one
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ * @symbols_off: Node offset of the symbols node in the base device tree
+ * @property: Property offset in the overlay holding the list of fixups
+ *
+ * overlay_fixup_phandle() resolves all the overlay phandles pointed
+ * to in a __fixups__ property, and updates them to match the phandles
+ * in use in the base device tree.
+ *
+ * This is part of the device tree overlay application process, when
+ * you want all the phandles in the overlay to point to the actual
+ * base dt nodes.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
+ int property)
+{
+ const char *value;
+ const char *label;
+ int len;
+
+ value = fdt_getprop_by_offset(fdto, property,
+ &label, &len);
+ if (!value) {
+ if (len == -FDT_ERR_NOTFOUND)
+ return -FDT_ERR_INTERNAL;
+
+ return len;
+ }
+
+ do {
+ const char *path, *name, *fixup_end;
+ const char *fixup_str = value;
+ uint32_t path_len, name_len;
+ uint32_t fixup_len;
+ char *sep, *endptr;
+ int poffset, ret;
+
+ fixup_end = memchr(value, '\0', len);
+ if (!fixup_end)
+ return -FDT_ERR_BADOVERLAY;
+ fixup_len = fixup_end - fixup_str;
+
+ len -= fixup_len + 1;
+ value += fixup_len + 1;
+
+ path = fixup_str;
+ sep = memchr(fixup_str, ':', fixup_len);
+ if (!sep || *sep != ':')
+ return -FDT_ERR_BADOVERLAY;
+
+ path_len = sep - path;
+ if (path_len == (fixup_len - 1))
+ return -FDT_ERR_BADOVERLAY;
+
+ fixup_len -= path_len + 1;
+ name = sep + 1;
+ sep = memchr(name, ':', fixup_len);
+ if (!sep || *sep != ':')
+ return -FDT_ERR_BADOVERLAY;
+
+ name_len = sep - name;
+ if (!name_len)
+ return -FDT_ERR_BADOVERLAY;
+
+ poffset = strtoul(sep + 1, &endptr, 10);
+ if ((*endptr != '\0') || (endptr <= (sep + 1)))
+ return -FDT_ERR_BADOVERLAY;
+
+ ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off,
+ path, path_len, name, name_len,
+ poffset, label);
+ if (ret)
+ return ret;
+ } while (len > 0);
+
+ return 0;
+}
+
+/**
+ * overlay_fixup_phandles - Resolve the overlay phandles to the base
+ * device tree
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ *
+ * overlay_fixup_phandles() resolves all the overlay phandles pointing
+ * to nodes in the base device tree.
+ *
+ * This is one of the steps of the device tree overlay application
+ * process, when you want all the phandles in the overlay to point to
+ * the actual base dt nodes.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_fixup_phandles(void *fdt, void *fdto)
+{
+ int fixups_off, symbols_off;
+ int property;
+
+ /* We can have overlays without any fixups */
+ fixups_off = fdt_path_offset(fdto, "/__fixups__");
+ if (fixups_off == -FDT_ERR_NOTFOUND)
+ return 0; /* nothing to do */
+ if (fixups_off < 0)
+ return fixups_off;
+
+ /* And base DTs without symbols */
+ symbols_off = fdt_path_offset(fdt, "/__symbols__");
+ if ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND)))
+ return symbols_off;
+
+ fdt_for_each_property_offset(property, fdto, fixups_off) {
+ int ret;
+
+ ret = overlay_fixup_phandle(fdt, fdto, symbols_off, property);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * overlay_apply_node - Merges a node into the base device tree
+ * @fdt: Base Device Tree blob
+ * @target: Node offset in the base device tree to apply the fragment to
+ * @fdto: Device tree overlay blob
+ * @node: Node offset in the overlay holding the changes to merge
+ *
+ * overlay_apply_node() merges a node into a target base device tree
+ * node pointed.
+ *
+ * This is part of the final step in the device tree overlay
+ * application process, when all the phandles have been adjusted and
+ * resolved and you just have to merge overlay into the base device
+ * tree.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_apply_node(void *fdt, int target,
+ void *fdto, int node)
+{
+ int property;
+ int subnode;
+
+ fdt_for_each_property_offset(property, fdto, node) {
+ const char *name;
+ const void *prop;
+ int prop_len;
+ int ret;
+
+ prop = fdt_getprop_by_offset(fdto, property, &name,
+ &prop_len);
+ if (prop_len == -FDT_ERR_NOTFOUND)
+ return -FDT_ERR_INTERNAL;
+ if (prop_len < 0)
+ return prop_len;
+
+ ret = fdt_setprop(fdt, target, name, prop, prop_len);
+ if (ret)
+ return ret;
+ }
+
+ fdt_for_each_subnode(subnode, fdto, node) {
+ const char *name = fdt_get_name(fdto, subnode, NULL);
+ int nnode;
+ int ret;
+
+ nnode = fdt_add_subnode(fdt, target, name);
+ if (nnode == -FDT_ERR_EXISTS) {
+ nnode = fdt_subnode_offset(fdt, target, name);
+ if (nnode == -FDT_ERR_NOTFOUND)
+ return -FDT_ERR_INTERNAL;
+ }
+
+ if (nnode < 0)
+ return nnode;
+
+ ret = overlay_apply_node(fdt, nnode, fdto, subnode);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * overlay_merge - Merge an overlay into its base device tree
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ *
+ * overlay_merge() merges an overlay into its base device tree.
+ *
+ * This is the next to last step in the device tree overlay application
+ * process, when all the phandles have been adjusted and resolved and
+ * you just have to merge overlay into the base device tree.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_merge(void *fdt, void *fdto)
+{
+ int fragment;
+
+ fdt_for_each_subnode(fragment, fdto, 0) {
+ int overlay;
+ int target;
+ int ret;
+
+ /*
+ * Each fragments will have an __overlay__ node. If
+ * they don't, it's not supposed to be merged
+ */
+ overlay = fdt_subnode_offset(fdto, fragment, "__overlay__");
+ if (overlay == -FDT_ERR_NOTFOUND)
+ continue;
+
+ if (overlay < 0)
+ return overlay;
+
+ target = overlay_get_target(fdt, fdto, fragment, NULL);
+ if (target < 0)
+ return target;
+
+ ret = overlay_apply_node(fdt, target, fdto, overlay);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int get_path_len(const void *fdt, int nodeoffset)
+{
+ int len = 0, namelen;
+ const char *name;
+
+ FDT_CHECK_HEADER(fdt);
+
+ for (;;) {
+ name = fdt_get_name(fdt, nodeoffset, &namelen);
+ if (!name)
+ return namelen;
+
+ /* root? we're done */
+ if (namelen == 0)
+ break;
+
+ nodeoffset = fdt_parent_offset(fdt, nodeoffset);
+ if (nodeoffset < 0)
+ return nodeoffset;
+ len += namelen + 1;
+ }
+
+ /* in case of root pretend it's "/" */
+ if (len == 0)
+ len++;
+ return len;
+}
+
+/**
+ * overlay_symbol_update - Update the symbols of base tree after a merge
+ * @fdt: Base Device Tree blob
+ * @fdto: Device tree overlay blob
+ *
+ * overlay_symbol_update() updates the symbols of the base tree with the
+ * symbols of the applied overlay
+ *
+ * This is the last step in the device tree overlay application
+ * process, allowing the reference of overlay symbols by subsequent
+ * overlay operations.
+ *
+ * returns:
+ * 0 on success
+ * Negative error code on failure
+ */
+static int overlay_symbol_update(void *fdt, void *fdto)
+{
+ int root_sym, ov_sym, prop, path_len, fragment, target;
+ int len, frag_name_len, ret, rel_path_len;
+ const char *s, *e;
+ const char *path;
+ const char *name;
+ const char *frag_name;
+ const char *rel_path;
+ const char *target_path;
+ char *buf;
+ void *p;
+
+ ov_sym = fdt_subnode_offset(fdto, 0, "__symbols__");
+
+ /* if no overlay symbols exist no problem */
+ if (ov_sym < 0)
+ return 0;
+
+ root_sym = fdt_subnode_offset(fdt, 0, "__symbols__");
+
+ /* it no root symbols exist we should create them */
+ if (root_sym == -FDT_ERR_NOTFOUND)
+ root_sym = fdt_add_subnode(fdt, 0, "__symbols__");
+
+ /* any error is fatal now */
+ if (root_sym < 0)
+ return root_sym;
+
+ /* iterate over each overlay symbol */
+ fdt_for_each_property_offset(prop, fdto, ov_sym) {
+ path = fdt_getprop_by_offset(fdto, prop, &name, &path_len);
+ if (!path)
+ return path_len;
+
+ /* verify it's a string property (terminated by a single \0) */
+ if (path_len < 1 || memchr(path, '\0', path_len) != &path[path_len - 1])
+ return -FDT_ERR_BADVALUE;
+
+ /* keep end marker to avoid strlen() */
+ e = path + path_len;
+
+ /* format: /<fragment-name>/__overlay__/<relative-subnode-path> */
+
+ if (*path != '/')
+ return -FDT_ERR_BADVALUE;
+
+ /* get fragment name first */
+ s = strchr(path + 1, '/');
+ if (!s)
+ return -FDT_ERR_BADOVERLAY;
+
+ frag_name = path + 1;
+ frag_name_len = s - path - 1;
+
+ /* verify format; safe since "s" lies in \0 terminated prop */
+ len = sizeof("/__overlay__/") - 1;
+ if ((e - s) < len || memcmp(s, "/__overlay__/", len))
+ return -FDT_ERR_BADOVERLAY;
+
+ rel_path = s + len;
+ rel_path_len = e - rel_path;
+
+ /* find the fragment index in which the symbol lies */
+ ret = fdt_subnode_offset_namelen(fdto, 0, frag_name,
+ frag_name_len);
+ /* not found? */
+ if (ret < 0)
+ return -FDT_ERR_BADOVERLAY;
+ fragment = ret;
+
+ /* an __overlay__ subnode must exist */
+ ret = fdt_subnode_offset(fdto, fragment, "__overlay__");
+ if (ret < 0)
+ return -FDT_ERR_BADOVERLAY;
+
+ /* get the target of the fragment */
+ ret = overlay_get_target(fdt, fdto, fragment, &target_path);
+ if (ret < 0)
+ return ret;
+ target = ret;
+
+ /* if we have a target path use */
+ if (!target_path) {
+ ret = get_path_len(fdt, target);
+ if (ret < 0)
+ return ret;
+ len = ret;
+ } else {
+ len = strlen(target_path);
+ }
+
+ ret = fdt_setprop_placeholder(fdt, root_sym, name,
+ len + (len > 1) + rel_path_len + 1, &p);
+ if (ret < 0)
+ return ret;
+
+ if (!target_path) {
+ /* again in case setprop_placeholder changed it */
+ ret = overlay_get_target(fdt, fdto, fragment, &target_path);
+ if (ret < 0)
+ return ret;
+ target = ret;
+ }
+
+ buf = p;
+ if (len > 1) { /* target is not root */
+ if (!target_path) {
+ ret = fdt_get_path(fdt, target, buf, len + 1);
+ if (ret < 0)
+ return ret;
+ } else
+ memcpy(buf, target_path, len + 1);
+
+ } else
+ len--;
+
+ buf[len] = '/';
+ memcpy(buf + len + 1, rel_path, rel_path_len);
+ buf[len + 1 + rel_path_len] = '\0';
+ }
+
+ return 0;
+}
+
+int fdt_overlay_apply(void *fdt, void *fdto)
+{
+ uint32_t delta = fdt_get_max_phandle(fdt);
+ int ret;
+
+ FDT_CHECK_HEADER(fdt);
+ FDT_CHECK_HEADER(fdto);
+
+ ret = overlay_adjust_local_phandles(fdto, delta);
+ if (ret)
+ goto err;
+
+ ret = overlay_update_local_references(fdto, delta);
+ if (ret)
+ goto err;
+
+ ret = overlay_fixup_phandles(fdt, fdto);
+ if (ret)
+ goto err;
+
+ ret = overlay_merge(fdt, fdto);
+ if (ret)
+ goto err;
+
+ ret = overlay_symbol_update(fdt, fdto);
+ if (ret)
+ goto err;
+
+ /*
+ * The overlay has been damaged, erase its magic.
+ */
+ fdt_set_magic(fdto, ~0);
+
+ return 0;
+
+err:
+ /*
+ * The overlay might have been damaged, erase its magic.
+ */
+ fdt_set_magic(fdto, ~0);
+
+ /*
+ * The base device tree might have been damaged, erase its
+ * magic.
+ */
+ fdt_set_magic(fdt, ~0);
+
+ return ret;
+}
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
index 3d00d2eee0e3..08de2cce674d 100644
--- a/scripts/dtc/libfdt/fdt_ro.c
+++ b/scripts/dtc/libfdt/fdt_ro.c
@@ -60,7 +60,7 @@ static int _fdt_nodename_eq(const void *fdt, int offset,
{
const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
- if (! p)
+ if (!p)
/* short match */
return 0;
@@ -327,7 +327,7 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
const struct fdt_property *prop;
prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
- if (! prop)
+ if (!prop)
return NULL;
return prop->data;
diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c
index 3fd5847377c9..5c3a2bb0bc6b 100644
--- a/scripts/dtc/libfdt/fdt_rw.c
+++ b/scripts/dtc/libfdt/fdt_rw.c
@@ -207,7 +207,7 @@ static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
int err;
*prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
- if (! (*prop))
+ if (!*prop)
return oldlen;
if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
@@ -269,8 +269,8 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name)
return 0;
}
-int fdt_setprop(void *fdt, int nodeoffset, const char *name,
- const void *val, int len)
+int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
+ int len, void **prop_data)
{
struct fdt_property *prop;
int err;
@@ -283,8 +283,22 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
if (err)
return err;
+ *prop_data = prop->data;
+ return 0;
+}
+
+int fdt_setprop(void *fdt, int nodeoffset, const char *name,
+ const void *val, int len)
+{
+ void *prop_data;
+ int err;
+
+ err = fdt_setprop_placeholder(fdt, nodeoffset, name, len, &prop_data);
+ if (err)
+ return err;
+
if (len)
- memcpy(prop->data, val, len);
+ memcpy(prop_data, val, len);
return 0;
}
@@ -323,7 +337,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name)
FDT_RW_CHECK_HEADER(fdt);
prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
- if (! prop)
+ if (!prop)
return len;
proplen = sizeof(*prop) + FDT_TAGALIGN(len);
diff --git a/scripts/dtc/libfdt/fdt_sw.c b/scripts/dtc/libfdt/fdt_sw.c
index 6a804859fd0c..2bd15e7aef87 100644
--- a/scripts/dtc/libfdt/fdt_sw.c
+++ b/scripts/dtc/libfdt/fdt_sw.c
@@ -220,7 +220,7 @@ static int _fdt_find_add_string(void *fdt, const char *s)
return offset;
}
-int fdt_property(void *fdt, const char *name, const void *val, int len)
+int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp)
{
struct fdt_property *prop;
int nameoff;
@@ -238,7 +238,19 @@ int fdt_property(void *fdt, const char *name, const void *val, int len)
prop->tag = cpu_to_fdt32(FDT_PROP);
prop->nameoff = cpu_to_fdt32(nameoff);
prop->len = cpu_to_fdt32(len);
- memcpy(prop->data, val, len);
+ *valp = prop->data;
+ return 0;
+}
+
+int fdt_property(void *fdt, const char *name, const void *val, int len)
+{
+ void *ptr;
+ int ret;
+
+ ret = fdt_property_placeholder(fdt, name, len, &ptr);
+ if (ret)
+ return ret;
+ memcpy(ptr, val, len);
return 0;
}
diff --git a/scripts/dtc/libfdt/fdt_wip.c b/scripts/dtc/libfdt/fdt_wip.c
index 6aaab399929c..5e859198622b 100644
--- a/scripts/dtc/libfdt/fdt_wip.c
+++ b/scripts/dtc/libfdt/fdt_wip.c
@@ -82,7 +82,7 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
int proplen;
propval = fdt_getprop(fdt, nodeoffset, name, &proplen);
- if (! propval)
+ if (!propval)
return proplen;
if (proplen != len)
@@ -107,7 +107,7 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
int len;
prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
- if (! prop)
+ if (!prop)
return len;
_fdt_nop_region(prop, len + sizeof(*prop));
diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h
index ba86caa73d01..7f83023ee109 100644
--- a/scripts/dtc/libfdt/libfdt.h
+++ b/scripts/dtc/libfdt/libfdt.h
@@ -1314,6 +1314,22 @@ static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
{
return fdt_property_u32(fdt, name, val);
}
+
+/**
+ * fdt_property_placeholder - add a new property and return a ptr to its value
+ *
+ * @fdt: pointer to the device tree blob
+ * @name: name of property to add
+ * @len: length of property value in bytes
+ * @valp: returns a pointer to where where the value should be placed
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_NOSPACE, standard meanings
+ */
+int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp);
+
#define fdt_property_string(fdt, name, str) \
fdt_property(fdt, name, str, strlen(str)+1)
int fdt_end_node(void *fdt);
@@ -1433,6 +1449,37 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
const void *val, int len);
/**
+ * fdt_setprop _placeholder - allocate space for a property
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node whose property to change
+ * @name: name of the property to change
+ * @len: length of the property value
+ * @prop_data: return pointer to property data
+ *
+ * fdt_setprop_placeholer() allocates the named property in the given node.
+ * If the property exists it is resized. In either case a pointer to the
+ * property data is returned.
+ *
+ * This function may insert or delete data from the blob, and will
+ * therefore change the offsets of some existing nodes.
+ *
+ * returns:
+ * 0, on success
+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
+ * contain the new property value
+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_BADMAGIC,
+ * -FDT_ERR_BADVERSION,
+ * -FDT_ERR_BADSTATE,
+ * -FDT_ERR_BADSTRUCTURE,
+ * -FDT_ERR_BADLAYOUT,
+ * -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name,
+ int len, void **prop_data);
+
+/**
* fdt_setprop_u32 - set a property to a 32-bit integer
* @fdt: pointer to the device tree blob
* @nodeoffset: offset of the node whose property to change
diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
index 3673de07e4e5..6846ad2fd6d2 100644
--- a/scripts/dtc/livetree.c
+++ b/scripts/dtc/livetree.c
@@ -216,6 +216,28 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
return old_node;
}
+void add_orphan_node(struct node *dt, struct node *new_node, char *ref)
+{
+ static unsigned int next_orphan_fragment = 0;
+ struct node *node;
+ struct property *p;
+ struct data d = empty_data;
+ char *name;
+
+ d = data_add_marker(d, REF_PHANDLE, ref);
+ d = data_append_integer(d, 0xffffffff, 32);
+
+ p = build_property("target", d);
+
+ xasprintf(&name, "fragment@%u",
+ next_orphan_fragment++);
+ name_node(new_node, "__overlay__");
+ node = build_node(p, new_node);
+ name_node(node, name);
+
+ add_child(dt, node);
+}
+
struct node *chain_node(struct node *first, struct node *list)
{
assert(first->next_sibling == NULL);
@@ -396,6 +418,12 @@ cell_t propval_cell(struct property *prop)
return fdt32_to_cpu(*((fdt32_t *)prop->val.val));
}
+cell_t propval_cell_n(struct property *prop, int n)
+{
+ assert(prop->val.len / sizeof(cell_t) >= n);
+ return fdt32_to_cpu(*((fdt32_t *)prop->val.val + n));
+}
+
struct property *get_property_by_label(struct node *tree, const char *label,
struct node **node)
{
@@ -478,7 +506,8 @@ struct node *get_node_by_path(struct node *tree, const char *path)
p = strchr(path, '/');
for_each_child(tree, child) {
- if (p && strneq(path, child->name, p-path))
+ if (p && (strlen(child->name) == p-path) &&
+ strneq(path, child->name, p-path))
return get_node_by_path(child, p+1);
else if (!p && streq(path, child->name))
return child;
diff --git a/scripts/dtc/update-dtc-source.sh b/scripts/dtc/update-dtc-source.sh
index b8ebcc6722d2..f3e5c596050a 100755
--- a/scripts/dtc/update-dtc-source.sh
+++ b/scripts/dtc/update-dtc-source.sh
@@ -34,7 +34,9 @@ DTC_SOURCE="checks.c data.c dtc.c dtc.h flattree.c fstree.c livetree.c srcpos.c
srcpos.h treesource.c util.c util.h version_gen.h Makefile.dtc \
dtc-lexer.l dtc-parser.y"
DTC_GENERATED="dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h"
-LIBFDT_SOURCE="Makefile.libfdt fdt.c fdt.h fdt_empty_tree.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c fdt_wip.c libfdt.h libfdt_env.h libfdt_internal.h"
+LIBFDT_SOURCE="Makefile.libfdt fdt.c fdt.h fdt_addresses.c fdt_empty_tree.c \
+ fdt_overlay.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c \
+ fdt_wip.c libfdt.h libfdt_env.h libfdt_internal.h"
get_last_dtc_version() {
git log --oneline scripts/dtc/ | grep 'upstream' | head -1 | sed -e 's/^.* \(.*\)/\1/'
diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h
index 1229e07b4912..6a4e84798966 100644
--- a/scripts/dtc/version_gen.h
+++ b/scripts/dtc/version_gen.h
@@ -1 +1 @@
-#define DTC_VERSION "DTC 1.4.4-g756ffc4f"
+#define DTC_VERSION "DTC 1.4.5-gc1e55a55"