Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull DeviceTree updates from Rob Herring:
"A bigger diffstat than usual with the kbuild changes and a tree wide
fix in the binding documentation.

Summary:

- kbuild cleanups and improvements for dtbs

- Code clean-up of overlay code and fixing for some long standing
memory leak and race condition in applying overlays

- Improvements to DT memory usage making sysfs/kobjects optional and
skipping unflattening of disabled nodes. This is part of kernel
tinification efforts.

- Final piece of removing storing the full path for every DT node.
The prerequisite conversion of printk's to use device_node format
specifier happened in 4.14.

- Sync with current upstream dtc. This brings additional checks to
dtb compiling.

- Binding doc tree wide removal of leading 0s from examples

- RTC binding documentation adding missing devices and some
consolidation of duplicated bindings

- Vendor prefix documentation for nutsboard, Silicon Storage
Technology, shimafuji, Tecon Microprocessor Technologies, DH
electronics GmbH, Opal Kelly, and Next Thing"

* tag 'devicetree-for-4.15' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (55 commits)
dt-bindings: usb: add #phy-cells to usb-nop-xceiv
dt-bindings: Remove leading zeros from bindings notation
kbuild: handle dtb-y and CONFIG_OF_ALL_DTBS natively in Makefile.lib
MIPS: dts: remove bogus bcm96358nb4ser.dtb from dtb-y entry
kbuild: clean up *.dtb and *.dtb.S patterns from top-level Makefile
.gitignore: move *.dtb and *.dtb.S patterns to the top-level .gitignore
.gitignore: sort normal pattern rules alphabetically
dt-bindings: add vendor prefix for Next Thing Co.
scripts/dtc: Update to upstream version v1.4.5-6-gc1e55a5513e9
of: dynamic: fix memory leak related to properties of __of_node_dup
of: overlay: make pr_err() string unique
of: overlay: pr_err from return NOTIFY_OK to overlay apply/remove
of: overlay: remove unneeded check for NULL kbasename()
of: overlay: remove a dependency on device node full_name
of: overlay: simplify applying symbols from an overlay
of: overlay: avoid race condition between applying multiple overlays
of: overlay: loosen overly strict phandle clash check
of: overlay: expand check of whether overlay changeset can be removed
of: overlay: detect cases where device tree may become corrupt
of: overlay: minor restructuring
...

+3180 -1483
+26 -24
.gitignore
··· 7 7 # command after changing this file, to see if there are 8 8 # any tracked files which get ignored after the change. 9 9 # 10 - # Normal rules 10 + # Normal rules (sorted alphabetically) 11 11 # 12 12 .* 13 + *.a 14 + *.bin 15 + *.bz2 16 + *.c.[012]*.* 17 + *.dtb 18 + *.dtb.S 19 + *.dwo 20 + *.elf 21 + *.gcno 22 + *.gz 23 + *.i 24 + *.ko 25 + *.ll 26 + *.lst 27 + *.lz4 28 + *.lzma 29 + *.lzo 30 + *.mod.c 13 31 *.o 14 32 *.o.* 15 - *.a 33 + *.order 34 + *.patch 16 35 *.s 17 - *.ko 18 36 *.so 19 37 *.so.dbg 20 - *.mod.c 21 - *.i 22 - *.lst 23 - *.symtypes 24 - *.order 25 - *.elf 26 - *.bin 27 - *.tar 28 - *.gz 29 - *.bz2 30 - *.lzma 31 - *.xz 32 - *.lz4 33 - *.lzo 34 - *.patch 35 - *.gcno 36 - *.ll 37 - modules.builtin 38 - Module.symvers 39 - *.dwo 40 38 *.su 41 - *.c.[012]*.* 39 + *.symtypes 40 + *.tar 41 + *.xz 42 + Module.symvers 43 + modules.builtin 42 44 43 45 # 44 46 # Top-level generic files
+1 -1
Documentation/devicetree/bindings/arm/samsung/pmu.txt
··· 62 62 63 63 Example of clock consumer : 64 64 65 - usb3503: usb3503@08 { 65 + usb3503: usb3503@8 { 66 66 /* ... */ 67 67 clock-names = "refclk"; 68 68 clocks = <&pmu_system_controller 0>;
+1 -1
Documentation/devicetree/bindings/arm/samsung/samsung-boards.txt
··· 71 71 - compatible: only "samsung,secure-firmware" is currently supported 72 72 - reg: address of non-secure SYSRAM used for communication with firmware 73 73 74 - firmware@0203F000 { 74 + firmware@203F000 { 75 75 compatible = "samsung,secure-firmware"; 76 76 reg = <0x0203F000 0x1000>; 77 77 };
+1 -1
Documentation/devicetree/bindings/arm/sp810.txt
··· 33 33 property with the highest frequency 34 34 35 35 Example: 36 - v2m_sysctl: sysctl@020000 { 36 + v2m_sysctl: sysctl@20000 { 37 37 compatible = "arm,sp810", "arm,primecell"; 38 38 reg = <0x020000 0x1000>; 39 39 clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
+1 -1
Documentation/devicetree/bindings/arm/vexpress-sysreg.txt
··· 37 37 compatible = "arm,vexpress-sysreg"; 38 38 reg = <0x10000000 0x1000>; 39 39 40 - v2m_led_gpios: sys_led@08 { 40 + v2m_led_gpios: sys_led@8 { 41 41 compatible = "arm,vexpress-sysreg,sys_led"; 42 42 gpio-controller; 43 43 #gpio-cells = <2>;
+1 -1
Documentation/devicetree/bindings/ata/ahci-platform.txt
··· 56 56 interrupts = <115>; 57 57 }; 58 58 59 - ahci: sata@01c18000 { 59 + ahci: sata@1c18000 { 60 60 compatible = "allwinner,sun4i-a10-ahci"; 61 61 reg = <0x01c18000 0x1000>; 62 62 interrupts = <56>;
+1 -1
Documentation/devicetree/bindings/ata/imx-sata.txt
··· 25 25 26 26 Examples: 27 27 28 - sata@02200000 { 28 + sata@2200000 { 29 29 compatible = "fsl,imx6q-ahci"; 30 30 reg = <0x02200000 0x4000>; 31 31 interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>;
+1 -1
Documentation/devicetree/bindings/bus/imx-weim.txt
··· 61 61 62 62 Example for an imx6q-sabreauto board, the NOR flash connected to the WEIM: 63 63 64 - weim: weim@021b8000 { 64 + weim: weim@21b8000 { 65 65 compatible = "fsl,imx6q-weim"; 66 66 reg = <0x021b8000 0x4000>; 67 67 clocks = <&clks 196>;
+1 -1
Documentation/devicetree/bindings/bus/sunxi-rsb.txt
··· 28 28 29 29 Example: 30 30 31 - rsb@01f03400 { 31 + rsb@1f03400 { 32 32 compatible = "allwinner,sun8i-a23-rsb"; 33 33 reg = <0x01f03400 0x400>; 34 34 interrupts = <0 39 4>;
+1 -1
Documentation/devicetree/bindings/clock/arm-syscon-icst.txt
··· 59 59 compatible = "syscon"; 60 60 reg = <0x10000000 0x1000>; 61 61 62 - oscclk0: osc0@0c { 62 + oscclk0: osc0@c { 63 63 compatible = "arm,syscon-icst307"; 64 64 #clock-cells = <0>; 65 65 lock-offset = <0x20>;
+1 -1
Documentation/devicetree/bindings/clock/clk-exynos-audss.txt
··· 80 80 controller. Refer to the standard clock bindings for information 81 81 about 'clocks' and 'clock-names' property. 82 82 83 - i2s0: i2s@03830000 { 83 + i2s0: i2s@3830000 { 84 84 compatible = "samsung,i2s-v5"; 85 85 reg = <0x03830000 0x100>; 86 86 dmas = <&pdma0 10
+1 -1
Documentation/devicetree/bindings/clock/clk-s5pv210-audss.txt
··· 43 43 controller. Refer to the standard clock bindings for information 44 44 about 'clocks' and 'clock-names' property. 45 45 46 - i2s0: i2s@03830000 { 46 + i2s0: i2s@3830000 { 47 47 /* ... */ 48 48 clock-names = "iis", "i2s_opclk0", 49 49 "i2s_opclk1";
+1 -1
Documentation/devicetree/bindings/clock/dove-divider-clock.txt
··· 21 21 a size of 8. 22 22 - #clock-cells : from common clock binding; shall be set to 1 23 23 24 - divider_clk: core-clock@0064 { 24 + divider_clk: core-clock@64 { 25 25 compatible = "marvell,dove-divider-clock"; 26 26 reg = <0x0064 0x8>; 27 27 #clock-cells = <1>;
+2 -2
Documentation/devicetree/bindings/clock/imx1-clock.txt
··· 10 10 for the full list of i.MX1 clock IDs. 11 11 12 12 Examples: 13 - clks: ccm@0021b000 { 13 + clks: ccm@21b000 { 14 14 #clock-cells = <1>; 15 15 compatible = "fsl,imx1-ccm"; 16 16 reg = <0x0021b000 0x1000>; 17 17 }; 18 18 19 - pwm: pwm@00208000 { 19 + pwm: pwm@208000 { 20 20 #pwm-cells = <2>; 21 21 compatible = "fsl,imx1-pwm"; 22 22 reg = <0x00208000 0x1000>;
+2 -2
Documentation/devicetree/bindings/clock/imx6q-clock.txt
··· 14 14 15 15 #include <dt-bindings/clock/imx6qdl-clock.h> 16 16 17 - clks: ccm@020c4000 { 17 + clks: ccm@20c4000 { 18 18 compatible = "fsl,imx6q-ccm"; 19 19 reg = <0x020c4000 0x4000>; 20 20 interrupts = <0 87 0x04 0 88 0x04>; 21 21 #clock-cells = <1>; 22 22 }; 23 23 24 - uart1: serial@02020000 { 24 + uart1: serial@2020000 { 25 25 compatible = "fsl,imx6q-uart", "fsl,imx21-uart"; 26 26 reg = <0x02020000 0x4000>; 27 27 interrupts = <0 26 0x04>;
+2 -2
Documentation/devicetree/bindings/clock/maxim,max77686.txt
··· 46 46 /* ... */ 47 47 48 48 Node of the MFD chip 49 - max77686: max77686@09 { 49 + max77686: max77686@9 { 50 50 compatible = "maxim,max77686"; 51 51 interrupt-parent = <&wakeup_eint>; 52 52 interrupts = <26 0>; ··· 71 71 /* ... */ 72 72 73 73 Node of the MFD chip 74 - max77802: max77802@09 { 74 + max77802: max77802@9 { 75 75 compatible = "maxim,max77802"; 76 76 interrupt-parent = <&wakeup_eint>; 77 77 interrupts = <26 0>;
+1 -1
Documentation/devicetree/bindings/clock/st/st,clkgen.txt
··· 42 42 43 43 Example: 44 44 45 - clockgen-a@090ff000 { 45 + clockgen-a@90ff000 { 46 46 compatible = "st,clkgen-c32"; 47 47 reg = <0x90ff000 0x1000>; 48 48
+2 -2
Documentation/devicetree/bindings/clock/sunxi-ccu.txt
··· 36 36 - "iosc": the SoC's internal frequency oscillator 37 37 38 38 Example for generic CCU: 39 - ccu: clock@01c20000 { 39 + ccu: clock@1c20000 { 40 40 compatible = "allwinner,sun8i-h3-ccu"; 41 41 reg = <0x01c20000 0x400>; 42 42 clocks = <&osc24M>, <&osc32k>; ··· 46 46 }; 47 47 48 48 Example for PRCM CCU: 49 - r_ccu: clock@01f01400 { 49 + r_ccu: clock@1f01400 { 50 50 compatible = "allwinner,sun50i-a64-r-ccu"; 51 51 reg = <0x01f01400 0x100>; 52 52 clocks = <&osc24M>, <&osc32k>, <&iosc>, <&ccu CLK_PLL_PERIPH0>;
+8 -8
Documentation/devicetree/bindings/clock/sunxi.txt
··· 137 137 138 138 For example: 139 139 140 - osc24M: clk@01c20050 { 140 + osc24M: clk@1c20050 { 141 141 #clock-cells = <0>; 142 142 compatible = "allwinner,sun4i-a10-osc-clk"; 143 143 reg = <0x01c20050 0x4>; ··· 145 145 clock-output-names = "osc24M"; 146 146 }; 147 147 148 - pll1: clk@01c20000 { 148 + pll1: clk@1c20000 { 149 149 #clock-cells = <0>; 150 150 compatible = "allwinner,sun4i-a10-pll1-clk"; 151 151 reg = <0x01c20000 0x4>; ··· 153 153 clock-output-names = "pll1"; 154 154 }; 155 155 156 - pll5: clk@01c20020 { 156 + pll5: clk@1c20020 { 157 157 #clock-cells = <1>; 158 158 compatible = "allwinner,sun4i-pll5-clk"; 159 159 reg = <0x01c20020 0x4>; ··· 161 161 clock-output-names = "pll5_ddr", "pll5_other"; 162 162 }; 163 163 164 - pll6: clk@01c20028 { 164 + pll6: clk@1c20028 { 165 165 #clock-cells = <1>; 166 166 compatible = "allwinner,sun6i-a31-pll6-clk"; 167 167 reg = <0x01c20028 0x4>; ··· 169 169 clock-output-names = "pll6", "pll6x2"; 170 170 }; 171 171 172 - cpu: cpu@01c20054 { 172 + cpu: cpu@1c20054 { 173 173 #clock-cells = <0>; 174 174 compatible = "allwinner,sun4i-a10-cpu-clk"; 175 175 reg = <0x01c20054 0x4>; ··· 177 177 clock-output-names = "cpu"; 178 178 }; 179 179 180 - mmc0_clk: clk@01c20088 { 180 + mmc0_clk: clk@1c20088 { 181 181 #clock-cells = <1>; 182 182 compatible = "allwinner,sun4i-a10-mmc-clk"; 183 183 reg = <0x01c20088 0x4>; ··· 199 199 clock-output-names = "gmac_int_tx"; 200 200 }; 201 201 202 - gmac_clk: clk@01c20164 { 202 + gmac_clk: clk@1c20164 { 203 203 #clock-cells = <0>; 204 204 compatible = "allwinner,sun7i-a20-gmac-clk"; 205 205 reg = <0x01c20164 0x4>; ··· 211 211 clock-output-names = "gmac"; 212 212 }; 213 213 214 - mmc_config_clk: clk@01c13000 { 214 + mmc_config_clk: clk@1c13000 { 215 215 compatible = "allwinner,sun9i-a80-mmc-config-clk"; 216 216 reg = <0x01c13000 0x10>; 217 217 clocks = <&ahb0_gates 8>;
+1 -1
Documentation/devicetree/bindings/clock/ti,cdce706.txt
··· 25 25 }; 26 26 }; 27 27 ... 28 - i2c0: i2c-master@0d090000 { 28 + i2c0: i2c-master@d090000 { 29 29 ... 30 30 cdce706: clock-synth@69 { 31 31 compatible = "ti,cdce706";
+1 -1
Documentation/devicetree/bindings/crypto/sun4i-ss.txt
··· 14 14 - reset-names : must contain "ahb" 15 15 16 16 Example: 17 - crypto: crypto-engine@01c15000 { 17 + crypto: crypto-engine@1c15000 { 18 18 compatible = "allwinner,sun4i-a10-crypto"; 19 19 reg = <0x01c15000 0x1000>; 20 20 interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+1 -1
Documentation/devicetree/bindings/display/etnaviv/etnaviv-drm.txt
··· 42 42 43 43 example: 44 44 45 - gpu_3d: gpu@00130000 { 45 + gpu_3d: gpu@130000 { 46 46 compatible = "vivante,gc"; 47 47 reg = <0x00130000 0x4000>; 48 48 interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
+2 -2
Documentation/devicetree/bindings/display/imx/hdmi.txt
··· 32 32 33 33 Example: 34 34 35 - gpr: iomuxc-gpr@020e0000 { 35 + gpr: iomuxc-gpr@20e0000 { 36 36 /* ... */ 37 37 }; 38 38 39 - hdmi: hdmi@0120000 { 39 + hdmi: hdmi@120000 { 40 40 #address-cells = <1>; 41 41 #size-cells = <0>; 42 42 compatible = "fsl,imx6q-hdmi";
+1 -1
Documentation/devicetree/bindings/display/simple-framebuffer.txt
··· 78 78 stdout-path = "display0"; 79 79 }; 80 80 81 - soc@01c00000 { 81 + soc@1c00000 { 82 82 lcdc0: lcdc@1c0c000 { 83 83 compatible = "allwinner,sun4i-a10-lcdc"; 84 84 ...
+2 -2
Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
··· 266 266 }; 267 267 }; 268 268 269 - hdmi: hdmi@01c16000 { 269 + hdmi: hdmi@1c16000 { 270 270 compatible = "allwinner,sun5i-a10s-hdmi"; 271 271 reg = <0x01c16000 0x1000>; 272 272 interrupts = <58>; ··· 305 305 }; 306 306 }; 307 307 308 - tve0: tv-encoder@01c0a000 { 308 + tve0: tv-encoder@1c0a000 { 309 309 compatible = "allwinner,sun4i-a10-tv-encoder"; 310 310 reg = <0x01c0a000 0x1000>; 311 311 clocks = <&ahb_gates 34>;
+2 -2
Documentation/devicetree/bindings/dma/sun4i-dma.txt
··· 12 12 second cell holding the request line number. 13 13 14 14 Example: 15 - dma: dma-controller@01c02000 { 15 + dma: dma-controller@1c02000 { 16 16 compatible = "allwinner,sun4i-a10-dma"; 17 17 reg = <0x01c02000 0x1000>; 18 18 interrupts = <27>; ··· 32 32 3. The port ID as specified in the datasheet 33 33 34 34 Example: 35 - spi2: spi@01c17000 { 35 + spi2: spi@1c17000 { 36 36 compatible = "allwinner,sun4i-a10-spi"; 37 37 reg = <0x01c17000 0x1000>; 38 38 interrupts = <0 12 4>;
+1 -1
Documentation/devicetree/bindings/dma/sun6i-dma.txt
··· 64 64 2. The port ID as specified in the datasheet 65 65 66 66 Example: 67 - spi2: spi@01c6a000 { 67 + spi2: spi@1c6a000 { 68 68 compatible = "allwinner,sun6i-a31-spi"; 69 69 reg = <0x01c6a000 0x1000>; 70 70 interrupts = <0 67 4>;
+3 -3
Documentation/devicetree/bindings/dma/ti-edma.txt
··· 142 142 }; 143 143 144 144 2. 145 - edma1: edma@02728000 { 145 + edma1: edma@2728000 { 146 146 compatible = "ti,k2g-edma3-tpcc", "ti,edma3-tpcc"; 147 147 reg = <0x02728000 0x8000>; 148 148 reg-names = "edma3_cc"; ··· 165 165 power-domains = <&k2g_pds 0x4f>; 166 166 }; 167 167 168 - edma1_tptc0: tptc@027b0000 { 168 + edma1_tptc0: tptc@27b0000 { 169 169 compatible = "ti,k2g-edma3-tptc", "ti,edma3-tptc"; 170 170 reg = <0x027b0000 0x400>; 171 171 power-domains = <&k2g_pds 0x4f>; 172 172 }; 173 173 174 - edma1_tptc1: tptc@027b8000 { 174 + edma1_tptc1: tptc@27b8000 { 175 175 compatible = "ti, k2g-edma3-tptc", "ti,edma3-tptc"; 176 176 reg = <0x027b8000 0x400>; 177 177 power-domains = <&k2g_pds 0x4f>;
+1 -1
Documentation/devicetree/bindings/dma/zxdma.txt
··· 26 26 Client: 27 27 Use specific request line passing from dmax 28 28 For example, spdif0 tx channel request line is 4 29 - spdif0: spdif0@0b004000 { 29 + spdif0: spdif0@b004000 { 30 30 #sound-dai-cells = <0>; 31 31 compatible = "zte,zx296702-spdif"; 32 32 reg = <0x0b004000 0x1000>;
+1 -1
Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
··· 66 66 67 67 Example: 68 68 69 - hsp_top0: hsp@03c00000 { 69 + hsp_top0: hsp@3c00000 { 70 70 ... 71 71 #mbox-cells = <2>; 72 72 };
+1 -1
Documentation/devicetree/bindings/gpio/gpio-dsp-keystone.txt
··· 25 25 bindings used by client devices. 26 26 27 27 Example: 28 - dspgpio0: keystone_dsp_gpio@02620240 { 28 + dspgpio0: keystone_dsp_gpio@2620240 { 29 29 compatible = "ti,keystone-dsp-gpio"; 30 30 ti,syscon-dev = <&devctrl 0x240>; 31 31 gpio-controller;
+1 -1
Documentation/devicetree/bindings/gpio/gpio-tz1090-pdc.txt
··· 30 30 31 31 Example: 32 32 33 - pdc_gpios: gpio-controller@02006500 { 33 + pdc_gpios: gpio-controller@2006500 { 34 34 gpio-controller; 35 35 #gpio-cells = <2>; 36 36
+1 -1
Documentation/devicetree/bindings/gpio/gpio-tz1090.txt
··· 59 59 60 60 Example: 61 61 62 - gpios: gpio-controller@02005800 { 62 + gpios: gpio-controller@2005800 { 63 63 #address-cells = <1>; 64 64 #size-cells = <0>; 65 65 compatible = "img,tz1090-gpio";
+1 -1
Documentation/devicetree/bindings/i2c/i2c-axxia.txt
··· 17 17 18 18 Example : 19 19 20 - i2c@02010084000 { 20 + i2c@2010084000 { 21 21 compatible = "lsi,api2c"; 22 22 device_type = "i2c"; 23 23 #address-cells = <1>;
+1 -1
Documentation/devicetree/bindings/i2c/i2c-sunxi-p2wi.txt
··· 24 24 25 25 Example: 26 26 27 - p2wi@01f03400 { 27 + p2wi@1f03400 { 28 28 compatible = "allwinner,sun6i-a31-p2wi"; 29 29 reg = <0x01f03400 0x400>; 30 30 interrupts = <0 39 4>;
+1 -1
Documentation/devicetree/bindings/iio/magnetometer/ak8974.txt
··· 19 19 20 20 Example: 21 21 22 - ak8974@0f { 22 + ak8974@f { 23 23 compatible = "asahi-kasei,ak8974"; 24 24 reg = <0x0f>; 25 25 avdd-supply = <&foo_reg>;
+1 -1
Documentation/devicetree/bindings/iio/magnetometer/ak8975.txt
··· 13 13 14 14 Example: 15 15 16 - ak8975@0c { 16 + ak8975@c { 17 17 compatible = "asahi-kasei,ak8975"; 18 18 reg = <0x0c>; 19 19 gpios = <&gpj0 7 0>;
+1 -1
Documentation/devicetree/bindings/input/sun4i-lradc-keys.txt
··· 19 19 20 20 #include <dt-bindings/input/input.h> 21 21 22 - lradc: lradc@01c22800 { 22 + lradc: lradc@1c22800 { 23 23 compatible = "allwinner,sun4i-a10-lradc-keys"; 24 24 reg = <0x01c22800 0x100>; 25 25 interrupts = <31>;
+1 -1
Documentation/devicetree/bindings/input/touchscreen/egalax-ts.txt
··· 10 10 11 11 Example: 12 12 13 - egalax_ts@04 { 13 + touchscreen@4 { 14 14 compatible = "eeti,egalax_ts"; 15 15 reg = <0x04>; 16 16 interrupt-parent = <&gpio1>;
+1 -1
Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
··· 21 21 each read. Valid values are 1, 4, 8, 16 and 32. 22 22 23 23 Example: 24 - tsc: tsc@02040000 { 24 + tsc: tsc@2040000 { 25 25 compatible = "fsl,imx6ul-tsc"; 26 26 reg = <0x02040000 0x4000>, <0x0219c000 0x4000>; 27 27 interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+1 -1
Documentation/devicetree/bindings/interrupt-controller/allwinner,sunxi-nmi.txt
··· 20 20 21 21 Example: 22 22 23 - sc-nmi-intc@01c00030 { 23 + sc-nmi-intc@1c00030 { 24 24 compatible = "allwinner,sun7i-a20-sc-nmi"; 25 25 interrupt-controller; 26 26 #interrupt-cells = <2>;
+1 -1
Documentation/devicetree/bindings/interrupt-controller/ti,keystone-irq.txt
··· 20 20 Interrupt Controllers bindings used by client devices. 21 21 22 22 Example: 23 - kirq0: keystone_irq0@026202a0 { 23 + kirq0: keystone_irq0@26202a0 { 24 24 compatible = "ti,keystone-irq"; 25 25 ti,syscon-dev = <&devctrl 0x2a0>; 26 26 interrupts = <GIC_SPI 4 IRQ_TYPE_EDGE_RISING>;
+1 -1
Documentation/devicetree/bindings/iommu/qcom,iommu.txt
··· 115 115 iommus = <&apps_iommu 4>; 116 116 }; 117 117 118 - gpu@01c00000 { 118 + gpu@1c00000 { 119 119 ... 120 120 iommus = <&gpu_iommu 1>, <&gpu_iommu 2>; 121 121 };
+1 -1
Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
··· 53 53 #iommu-cells = <1>; 54 54 }; 55 55 56 - vsp1@fe928000 { 56 + vsp@fe928000 { 57 57 ... 58 58 iommus = <&ipmmu_mx 13>; 59 59 ...
+8 -8
Documentation/devicetree/bindings/leds/register-bit-led.txt
··· 32 32 compatible = "arm,realview-pb1176-syscon", "syscon"; 33 33 reg = <0x10000000 0x1000>; 34 34 35 - led@08.0 { 35 + led@8.0 { 36 36 compatible = "register-bit-led"; 37 37 offset = <0x08>; 38 38 mask = <0x01>; ··· 40 40 linux,default-trigger = "heartbeat"; 41 41 default-state = "on"; 42 42 }; 43 - led@08.1 { 43 + led@8.1 { 44 44 compatible = "register-bit-led"; 45 45 offset = <0x08>; 46 46 mask = <0x02>; ··· 48 48 linux,default-trigger = "mmc0"; 49 49 default-state = "off"; 50 50 }; 51 - led@08.2 { 51 + led@8.2 { 52 52 compatible = "register-bit-led"; 53 53 offset = <0x08>; 54 54 mask = <0x04>; ··· 56 56 linux,default-trigger = "cpu0"; 57 57 default-state = "off"; 58 58 }; 59 - led@08.3 { 59 + led@8.3 { 60 60 compatible = "register-bit-led"; 61 61 offset = <0x08>; 62 62 mask = <0x08>; 63 63 label = "versatile:3"; 64 64 default-state = "off"; 65 65 }; 66 - led@08.4 { 66 + led@8.4 { 67 67 compatible = "register-bit-led"; 68 68 offset = <0x08>; 69 69 mask = <0x10>; 70 70 label = "versatile:4"; 71 71 default-state = "off"; 72 72 }; 73 - led@08.5 { 73 + led@8.5 { 74 74 compatible = "register-bit-led"; 75 75 offset = <0x08>; 76 76 mask = <0x20>; 77 77 label = "versatile:5"; 78 78 default-state = "off"; 79 79 }; 80 - led@08.6 { 80 + led@8.6 { 81 81 compatible = "register-bit-led"; 82 82 offset = <0x08>; 83 83 mask = <0x40>; 84 84 label = "versatile:6"; 85 85 default-state = "off"; 86 86 }; 87 - led@08.7 { 87 + led@8.7 { 88 88 compatible = "register-bit-led"; 89 89 offset = <0x08>; 90 90 mask = <0x80>;
+1 -1
Documentation/devicetree/bindings/mailbox/ti,message-manager.txt
··· 29 29 Example(K2G): 30 30 ------------ 31 31 32 - msgmgr: msgmgr@02a00000 { 32 + msgmgr: msgmgr@2a00000 { 33 33 compatible = "ti,k2g-message-manager"; 34 34 #mbox-cells = <2>; 35 35 reg-names = "queue_proxy_region", "queue_state_debug_region";
+2 -2
Documentation/devicetree/bindings/marvell.txt
··· 446 446 that services interrupts for this device. 447 447 448 448 Example Discovery CPU Error node: 449 - cpu-error@0070 { 449 + cpu-error@70 { 450 450 compatible = "marvell,mv64360-cpu-error"; 451 451 reg = <0x70 0x10 0x128 0x28>; 452 452 interrupts = <3>; ··· 466 466 that services interrupts for this device. 467 467 468 468 Example Discovery SRAM Controller node: 469 - sram-ctrl@0380 { 469 + sram-ctrl@380 { 470 470 compatible = "marvell,mv64360-sram-ctrl"; 471 471 reg = <0x380 0x80>; 472 472 interrupts = <13>;
+1 -1
Documentation/devicetree/bindings/media/i2c/tc358743.txt
··· 27 27 28 28 Example: 29 29 30 - tc358743@0f { 30 + tc358743@f { 31 31 compatible = "toshiba,tc358743"; 32 32 reg = <0x0f>; 33 33 clocks = <&hdmi_osc>;
+1 -1
Documentation/devicetree/bindings/media/img-ir-rev1.txt
··· 25 25 26 26 Example: 27 27 28 - ir@02006200 { 28 + ir@2006200 { 29 29 compatible = "img,ir-rev1"; 30 30 reg = <0x02006200 0x100>; 31 31 interrupts = <29 4>;
+1 -1
Documentation/devicetree/bindings/media/renesas,vsp1.txt
··· 22 22 23 23 Example: R8A7790 (R-Car H2) VSP1-S node 24 24 25 - vsp1@fe928000 { 25 + vsp@fe928000 { 26 26 compatible = "renesas,vsp1"; 27 27 reg = <0 0xfe928000 0 0x8000>; 28 28 interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>;
+1 -1
Documentation/devicetree/bindings/media/stih-cec.txt
··· 13 13 14 14 Example for STIH407: 15 15 16 - sti-cec@094a087c { 16 + sti-cec@94a087c { 17 17 compatible = "st,stih-cec"; 18 18 reg = <0x94a087c 0x64>; 19 19 clocks = <&clk_sysin>;
+1 -1
Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
··· 50 50 51 51 /* stih410 SoC b2120 + b2004a + stv0367-pll(NIMB) + stv0367-tda18212 (NIMA) DT example) */ 52 52 53 - c8sectpfe@08a20000 { 53 + c8sectpfe@8a20000 { 54 54 compatible = "st,stih407-c8sectpfe"; 55 55 reg = <0x08a20000 0x10000>, <0x08a00000 0x4000>; 56 56 reg-names = "stfe", "stfe-ram";
+1 -1
Documentation/devicetree/bindings/media/sunxi-ir.txt
··· 14 14 15 15 Example: 16 16 17 - ir0: ir@01c21800 { 17 + ir0: ir@1c21800 { 18 18 compatible = "allwinner,sun4i-a10-ir"; 19 19 clocks = <&apb0_gates 6>, <&ir0_clk>; 20 20 clock-names = "apb", "ir";
+1 -1
Documentation/devicetree/bindings/mfd/max77686.txt
··· 19 19 20 20 Example: 21 21 22 - max77686: pmic@09 { 22 + max77686: pmic@9 { 23 23 compatible = "maxim,max77686"; 24 24 interrupt-parent = <&wakeup_eint>; 25 25 interrupts = <26 0>;
+1 -1
Documentation/devicetree/bindings/mfd/max77802.txt
··· 18 18 19 19 Example: 20 20 21 - max77802: pmic@09 { 21 + max77802: pmic@9 { 22 22 compatible = "maxim,max77802"; 23 23 interrupt-parent = <&intc>; 24 24 interrupts = <26 IRQ_TYPE_NONE>;
+1 -1
Documentation/devicetree/bindings/mfd/mfd.txt
··· 41 41 compatible = "syscon", "simple-mfd"; 42 42 reg = <0x01000 0x1000>; 43 43 44 - led@08.0 { 44 + led@8.0 { 45 45 compatible = "register-bit-led"; 46 46 offset = <0x08>; 47 47 mask = <0x01>;
+2 -2
Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
··· 10 10 - #io-channel-cells: shall be 0, 11 11 12 12 Example: 13 - ths: ths@01c25000 { 13 + ths: ths@1c25000 { 14 14 compatible = "allwinner,sun8i-a33-ths"; 15 15 reg = <0x01c25000 0x100>; 16 16 #thermal-sensor-cells = <0>; ··· 47 47 48 48 Example: 49 49 50 - rtp: rtp@01c25000 { 50 + rtp: rtp@1c25000 { 51 51 compatible = "allwinner,sun4i-a10-ts"; 52 52 reg = <0x01c25000 0x100>; 53 53 interrupts = <29>;
+1 -1
Documentation/devicetree/bindings/mfd/sun6i-prcm.txt
··· 15 15 16 16 Example: 17 17 18 - prcm: prcm@01f01400 { 18 + prcm: prcm@1f01400 { 19 19 compatible = "allwinner,sun6i-a31-prcm"; 20 20 reg = <0x01f01400 0x200>; 21 21
+1 -1
Documentation/devicetree/bindings/mfd/syscon.txt
··· 18 18 performed on the device. 19 19 20 20 Examples: 21 - gpr: iomuxc-gpr@020e0000 { 21 + gpr: iomuxc-gpr@20e0000 { 22 22 compatible = "fsl,imx6q-iomuxc-gpr", "syscon"; 23 23 reg = <0x020e0000 0x38>; 24 24 };
+1 -1
Documentation/devicetree/bindings/mmc/mmc.txt
··· 146 146 147 147 Example with sdio function subnode: 148 148 149 - mmc3: mmc@01c12000 { 149 + mmc3: mmc@1c12000 { 150 150 #address-cells = <1>; 151 151 #size-cells = <0>; 152 152
+2 -2
Documentation/devicetree/bindings/mmc/sdhci-st.txt
··· 74 74 75 75 /* Example SD stih407 family configuration */ 76 76 77 - mmc1: sdhci@09080000 { 77 + mmc1: sdhci@9080000 { 78 78 compatible = "st,sdhci-stih407", "st,sdhci"; 79 79 reg = <0x09080000 0x7ff>; 80 80 reg-names = "mmc"; ··· 90 90 91 91 /* Example eMMC stih407 family configuration */ 92 92 93 - mmc0: sdhci@09060000 { 93 + mmc0: sdhci@9060000 { 94 94 compatible = "st,sdhci-stih407", "st,sdhci"; 95 95 reg = <0x09060000 0x7ff>, <0x9061008 0x20>; 96 96 reg-names = "mmc", "top-mmc-delay";
+2 -2
Documentation/devicetree/bindings/mmc/sunxi-mmc.txt
··· 29 29 30 30 Examples: 31 31 - Within .dtsi: 32 - mmc0: mmc@01c0f000 { 32 + mmc0: mmc@1c0f000 { 33 33 compatible = "allwinner,sun5i-a13-mmc"; 34 34 reg = <0x01c0f000 0x1000>; 35 35 clocks = <&ahb_gates 8>, <&mmc0_clk>, <&mmc0_output_clk>, <&mmc0_sample_clk>; ··· 39 39 }; 40 40 41 41 - Within dts: 42 - mmc0: mmc@01c0f000 { 42 + mmc0: mmc@1c0f000 { 43 43 pinctrl-names = "default", "default"; 44 44 pinctrl-0 = <&mmc0_pins_a>; 45 45 pinctrl-1 = <&mmc0_cd_pin_reference_design>;
+1 -1
Documentation/devicetree/bindings/mtd/sunxi-nand.txt
··· 31 31 32 32 33 33 Examples: 34 - nfc: nand@01c03000 { 34 + nfc: nand@1c03000 { 35 35 compatible = "allwinner,sun4i-a10-nand"; 36 36 reg = <0x01c03000 0x1000>; 37 37 interrupts = <0 37 1>;
+1 -1
Documentation/devicetree/bindings/net/allwinner,sun4i-emac.txt
··· 10 10 11 11 Example: 12 12 13 - emac: ethernet@01c0b000 { 13 + emac: ethernet@1c0b000 { 14 14 compatible = "allwinner,sun4i-a10-emac"; 15 15 reg = <0x01c0b000 0x1000>; 16 16 interrupts = <55>;
+2 -2
Documentation/devicetree/bindings/net/allwinner,sun4i-mdio.txt
··· 9 9 - phy-supply: phandle to a regulator if the PHY needs one 10 10 11 11 Example at the SoC level: 12 - mdio@01c0b080 { 12 + mdio@1c0b080 { 13 13 compatible = "allwinner,sun4i-a10-mdio"; 14 14 reg = <0x01c0b080 0x14>; 15 15 #address-cells = <1>; ··· 18 18 19 19 And at the board level: 20 20 21 - mdio@01c0b080 { 21 + mdio@1c0b080 { 22 22 phy-supply = <&reg_emac_3v3>; 23 23 24 24 phy0: ethernet-phy@0 {
+1 -1
Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.txt
··· 15 15 16 16 Examples: 17 17 18 - gmac: ethernet@01c50000 { 18 + gmac: ethernet@1c50000 { 19 19 compatible = "allwinner,sun7i-a20-gmac"; 20 20 reg = <0x01c50000 0x10000>, 21 21 <0x01c20164 0x4>;
+1 -1
Documentation/devicetree/bindings/net/brcm,bcmgenet.txt
··· 109 109 reg = <0xf0ba0000 0xfc4c>; 110 110 interrupts = <0x0 0x18 0x0>, <0x0 0x19 0x0>; 111 111 112 - mdio@0e14 { 112 + mdio@e14 { 113 113 compatible = "brcm,genet-mdio-v4"; 114 114 #address-cells = <0x1>; 115 115 #size-cells = <0x0>;
+1 -1
Documentation/devicetree/bindings/net/can/m_can.txt
··· 45 45 46 46 Example: 47 47 SoC dtsi: 48 - m_can1: can@020e8000 { 48 + m_can1: can@20e8000 { 49 49 compatible = "bosch,m_can"; 50 50 reg = <0x020e8000 0x4000>, <0x02298000 0x4000>; 51 51 reg-names = "m_can", "message_ram";
+2 -2
Documentation/devicetree/bindings/net/can/sun4i_can.txt
··· 19 19 allwinner,pull = <0>; 20 20 }; 21 21 ... 22 - can0: can@01c2bc00 { 22 + can0: can@1c2bc00 { 23 23 compatible = "allwinner,sun4i-a10-can"; 24 24 reg = <0x01c2bc00 0x400>; 25 25 interrupts = <0 26 4>; ··· 29 29 30 30 Board specific .dts file: 31 31 32 - can0: can@01c2bc00 { 32 + can0: can@1c2bc00 { 33 33 pinctrl-names = "default"; 34 34 pinctrl-0 = <&can0_pins_a>; 35 35 status = "okay";
+1 -1
Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt
··· 20 20 21 21 Example: 22 22 23 - mmc3: mmc@01c12000 { 23 + mmc3: mmc@1c12000 { 24 24 #address-cells = <1>; 25 25 #size-cells = <0>; 26 26
+2 -2
Documentation/devicetree/bindings/nvmem/allwinner,sunxi-sid.txt
··· 13 13 bindings/nvmem/nvmem.txt 14 14 15 15 Example for sun4i: 16 - sid@01c23800 { 16 + sid@1c23800 { 17 17 compatible = "allwinner,sun4i-a10-sid"; 18 18 reg = <0x01c23800 0x10> 19 19 }; 20 20 21 21 Example for sun7i: 22 - sid@01c23800 { 22 + sid@1c23800 { 23 23 compatible = "allwinner,sun7i-a20-sid"; 24 24 reg = <0x01c23800 0x200> 25 25 };
+1 -1
Documentation/devicetree/bindings/nvmem/brcm,ocotp.txt
··· 10 10 11 11 Example: 12 12 13 - otp: otp@0301c800 { 13 + otp: otp@301c800 { 14 14 compatible = "brcm,ocotp"; 15 15 reg = <0x0301c800 0x2c>; 16 16 brcm,ocotp-size = <2048>;
+1 -1
Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
··· 19 19 20 20 Example: 21 21 22 - ocotp: ocotp@021bc000 { 22 + ocotp: ocotp@21bc000 { 23 23 compatible = "fsl,imx6q-ocotp", "syscon"; 24 24 reg = <0x021bc000 0x4000>; 25 25 clocks = <&clks IMX6QDL_CLK_IIM>;
+1 -1
Documentation/devicetree/bindings/nvmem/nvmem.txt
··· 33 33 For example: 34 34 35 35 /* Provider */ 36 - qfprom: qfprom@00700000 { 36 + qfprom: qfprom@700000 { 37 37 ... 38 38 39 39 /* Data cells */
+1 -1
Documentation/devicetree/bindings/nvmem/qfprom.txt
··· 12 12 13 13 Example: 14 14 15 - qfprom: qfprom@00700000 { 15 + qfprom: qfprom@700000 { 16 16 compatible = "qcom,qfprom"; 17 17 reg = <0x00700000 0x8000>; 18 18 ...
+6 -6
Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
··· 255 255 256 256 SoC DTSI: 257 257 258 - pcie-controller@00003000 { 258 + pcie-controller@3000 { 259 259 compatible = "nvidia,tegra30-pcie"; 260 260 device_type = "pci"; 261 261 reg = <0x00003000 0x00000800 /* PADS registers */ ··· 334 334 335 335 Board DTS: 336 336 337 - pcie-controller@00003000 { 337 + pcie-controller@3000 { 338 338 status = "okay"; 339 339 340 340 avdd-pexa-supply = <&ldo1_reg>; ··· 360 360 361 361 SoC DTSI: 362 362 363 - pcie-controller@01003000 { 363 + pcie-controller@1003000 { 364 364 compatible = "nvidia,tegra124-pcie"; 365 365 device_type = "pci"; 366 366 reg = <0x0 0x01003000 0x0 0x00000800 /* PADS registers */ ··· 425 425 426 426 Board DTS: 427 427 428 - pcie-controller@01003000 { 428 + pcie-controller@1003000 { 429 429 status = "okay"; 430 430 431 431 avddio-pex-supply = <&vdd_1v05_run>; ··· 456 456 457 457 SoC DTSI: 458 458 459 - pcie-controller@01003000 { 459 + pcie-controller@1003000 { 460 460 compatible = "nvidia,tegra210-pcie"; 461 461 device_type = "pci"; 462 462 reg = <0x0 0x01003000 0x0 0x00000800 /* PADS registers */ ··· 521 521 522 522 Board DTS: 523 523 524 - pcie-controller@01003000 { 524 + pcie-controller@1003000 { 525 525 status = "okay"; 526 526 527 527 avdd-pll-uerefe-supply = <&avdd_1v05_pll>;
+1 -1
Documentation/devicetree/bindings/phy/brcm,cygnus-pcie-phy.txt
··· 15 15 - #phy-cells: must be 0 16 16 17 17 Example: 18 - pcie_phy: phy@0301d0a0 { 18 + pcie_phy: phy@301d0a0 { 19 19 compatible = "brcm,cygnus-pcie-phy"; 20 20 reg = <0x0301d0a0 0x14>; 21 21
+1 -1
Documentation/devicetree/bindings/phy/mxs-usb-phy.txt
··· 23 23 the 17.78mA TX reference current. Default: 100 24 24 25 25 Example: 26 - usbphy1: usbphy@020c9000 { 26 + usbphy1: usbphy@20c9000 { 27 27 compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy"; 28 28 reg = <0x020c9000 0x1000>; 29 29 interrupts = <0 44 0x04>;
+1 -1
Documentation/devicetree/bindings/phy/sun9i-usb-phy.txt
··· 25 25 The driver will only use those matching the phy_type. 26 26 27 27 Example: 28 - usbphy1: phy@00a01800 { 28 + usbphy1: phy@a01800 { 29 29 compatible = "allwinner,sun9i-a80-usb-phy"; 30 30 reg = <0x00a01800 0x4>; 31 31 clocks = <&usb_phy_clk 2>, <&usb_phy_clk 10>,
+1 -1
Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
··· 89 89 90 90 Examples: 91 91 92 - pio: pinctrl@01c20800 { 92 + pio: pinctrl@1c20800 { 93 93 compatible = "allwinner,sun5i-a13-pinctrl"; 94 94 reg = <0x01c20800 0x400>; 95 95 #address-cells = <1>;
+2 -2
Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt
··· 58 58 configurations by referring to the phandle of that pin configuration node. 59 59 60 60 Examples: 61 - usdhc@0219c000 { /* uSDHC4 */ 61 + usdhc@219c000 { /* uSDHC4 */ 62 62 non-removable; 63 63 vmmc-supply = <&reg_3p3v>; 64 64 pinctrl-names = "default"; 65 65 pinctrl-0 = <&pinctrl_usdhc4_1>; 66 66 }; 67 67 68 - iomuxc@020e0000 { 68 + iomuxc@20e0000 { 69 69 compatible = "fsl,imx6q-iomuxc"; 70 70 reg = <0x020e0000 0x4000>; 71 71
+2 -2
Documentation/devicetree/bindings/pinctrl/img,tz1090-pdc-pinctrl.txt
··· 89 89 90 90 Example: 91 91 92 - pinctrl_pdc: pinctrl@02006500 { 92 + pinctrl_pdc: pinctrl@2006500 { 93 93 #gpio-range-cells = <3>; 94 94 compatible = "img,tz1090-pdc-pinctrl"; 95 95 reg = <0x02006500 0x100>; ··· 121 121 }; 122 122 }; 123 123 124 - ir: ir@02006200 { 124 + ir: ir@2006200 { 125 125 pinctrl-names = "default"; 126 126 pinctrl-0 = <&irmod_default>; 127 127 };
+2 -2
Documentation/devicetree/bindings/pinctrl/img,tz1090-pinctrl.txt
··· 197 197 198 198 Example: 199 199 200 - pinctrl: pinctrl@02005800 { 200 + pinctrl: pinctrl@2005800 { 201 201 #gpio-range-cells = <3>; 202 202 compatible = "img,tz1090-pinctrl"; 203 203 reg = <0x02005800 0xe4>; ··· 221 221 }; 222 222 }; 223 223 224 - uart@02004b00 { 224 + uart@2004b00 { 225 225 pinctrl-names = "default"; 226 226 pinctrl-0 = <&uart0_default>; 227 227 };
+1 -1
Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-xusb-padctl.txt
··· 97 97 Board file extract: 98 98 ------------------- 99 99 100 - pcie-controller@01003000 { 100 + pcie-controller@1003000 { 101 101 ... 102 102 103 103 phys = <&padctl 0>;
+1 -1
Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
··· 86 86 reg = <0 0x1020C020 0 0x1000>; 87 87 }; 88 88 89 - pinctrl@01c20800 { 89 + pinctrl@1c20800 { 90 90 compatible = "mediatek,mt8135-pinctrl"; 91 91 reg = <0 0x1000B000 0 0x1000>; 92 92 mediatek,pctl-regmap = <&syscfg_pctl_a &syscfg_pctl_b>;
+1 -1
Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt
··· 89 89 interrupt-names = "irqmux"; 90 90 ranges = <0 0x09610000 0x6000>; 91 91 92 - pio0: gpio@09610000 { 92 + pio0: gpio@9610000 { 93 93 gpio-controller; 94 94 #gpio-cells = <2>; 95 95 interrupt-controller;
+1 -1
Documentation/devicetree/bindings/pinctrl/qcom,msm8996-pinctrl.txt
··· 175 175 176 176 Example: 177 177 178 - tlmm: pinctrl@01010000 { 178 + tlmm: pinctrl@1010000 { 179 179 compatible = "qcom,msm8996-pinctrl"; 180 180 reg = <0x01010000 0x300000>; 181 181 interrupts = <0 208 0>;
+2 -2
Documentation/devicetree/bindings/power/fsl,imx-gpc.txt
··· 40 40 41 41 Example: 42 42 43 - gpc: gpc@020dc000 { 43 + gpc: gpc@20dc000 { 44 44 compatible = "fsl,imx6q-gpc"; 45 45 reg = <0x020dc000 0x4000>; 46 46 interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>, ··· 80 80 81 81 Example of a device that is part of the PU power domain: 82 82 83 - vpu: vpu@02040000 { 83 + vpu: vpu@2040000 { 84 84 reg = <0x02040000 0x3c000>; 85 85 /* ... */ 86 86 power-domains = <&pd_pu>;
+1 -1
Documentation/devicetree/bindings/power/reset/imx-snvs-poweroff.txt
··· 10 10 -reg: Specifies the physical address of the SNVS_LPCR register 11 11 12 12 Example: 13 - snvs@020cc000 { 13 + snvs@20cc000 { 14 14 compatible = "fsl,sec-v4.0-mon", "simple-bus"; 15 15 #address-cells = <1>; 16 16 #size-cells = <1>;
+2 -2
Documentation/devicetree/bindings/power/reset/keystone-reset.txt
··· 37 37 Setup keystone reset so that in case software reset or 38 38 WDT0 is triggered it issues hard reset for SoC. 39 39 40 - pllctrl: pll-controller@02310000 { 40 + pllctrl: pll-controller@2310000 { 41 41 compatible = "ti,keystone-pllctrl", "syscon"; 42 42 reg = <0x02310000 0x200>; 43 43 }; 44 44 45 - devctrl: device-state-control@02620000 { 45 + devctrl: device-state-control@2620000 { 46 46 compatible = "ti,keystone-devctrl", "syscon"; 47 47 reg = <0x02620000 0x1000>; 48 48 };
+1 -1
Documentation/devicetree/bindings/powerpc/fsl/mcu-mpc8349emitx.txt
··· 8 8 9 9 Example: 10 10 11 - mcu@0a { 11 + mcu@a { 12 12 #gpio-cells = <2>; 13 13 compatible = "fsl,mc9s08qg8-mpc8349emitx", 14 14 "fsl,mcu-mpc8349emitx";
+1 -1
Documentation/devicetree/bindings/pwm/pwm-sun4i.txt
··· 14 14 15 15 Example: 16 16 17 - pwm: pwm@01c20e00 { 17 + pwm: pwm@1c20e00 { 18 18 compatible = "allwinner,sun7i-a20-pwm"; 19 19 reg = <0x01c20e00 0xc>; 20 20 clocks = <&osc24M>;
+1 -1
Documentation/devicetree/bindings/regulator/max77686.txt
··· 40 40 41 41 Example: 42 42 43 - max77686: pmic@09 { 43 + max77686: pmic@9 { 44 44 compatible = "maxim,max77686"; 45 45 interrupt-parent = <&wakeup_eint>; 46 46 interrupts = <26 IRQ_TYPE_NONE>;
+1 -1
Documentation/devicetree/bindings/regulator/max77802.txt
··· 71 71 72 72 Example: 73 73 74 - max77802@09 { 74 + max77802@9 { 75 75 compatible = "maxim,max77802"; 76 76 interrupt-parent = <&wakeup_eint>; 77 77 interrupts = <26 0>;
+1 -1
Documentation/devicetree/bindings/reset/allwinner,sunxi-clock-reset.txt
··· 14 14 15 15 example: 16 16 17 - ahb1_rst: reset@01c202c0 { 17 + ahb1_rst: reset@1c202c0 { 18 18 #reset-cells = <1>; 19 19 compatible = "allwinner,sun6i-a31-ahb1-reset"; 20 20 reg = <0x01c202c0 0xc>;
+3 -3
Documentation/devicetree/bindings/reset/fsl,imx-src.txt
··· 14 14 15 15 example: 16 16 17 - src: src@020d8000 { 17 + src: src@20d8000 { 18 18 compatible = "fsl,imx6q-src"; 19 19 reg = <0x020d8000 0x4000>; 20 20 interrupts = <0 91 0x04 0 96 0x04>; ··· 33 33 34 34 example: 35 35 36 - ipu1: ipu@02400000 { 36 + ipu1: ipu@2400000 { 37 37 resets = <&src 2>; 38 38 }; 39 - ipu2: ipu@02800000 { 39 + ipu2: ipu@2800000 { 40 40 resets = <&src 4>; 41 41 }; 42 42
+1 -1
Documentation/devicetree/bindings/reset/ti-syscon-reset.txt
··· 67 67 68 68 / { 69 69 soc { 70 - psc: power-sleep-controller@02350000 { 70 + psc: power-sleep-controller@2350000 { 71 71 compatible = "syscon", "simple-mfd"; 72 72 reg = <0x02350000 0x1000>; 73 73
-18
Documentation/devicetree/bindings/rtc/dallas,ds1339.txt
··· 1 - * Dallas DS1339 I2C Serial Real-Time Clock 2 - 3 - Required properties: 4 - - compatible: Should contain "dallas,ds1339". 5 - - reg: I2C address for chip 6 - 7 - Optional properties: 8 - - trickle-resistor-ohms : Selected resistor for trickle charger 9 - Values usable for ds1339 are 250, 2000, 4000 10 - Should be given if trickle charger should be enabled 11 - - trickle-diode-disable : Do not use internal trickle charger diode 12 - Should be given if internal trickle charger diode should be disabled 13 - Example: 14 - ds1339: rtc@68 { 15 - compatible = "dallas,ds1339"; 16 - trickle-resistor-ohms = <250>; 17 - reg = <0x68>; 18 - };
+44
Documentation/devicetree/bindings/rtc/rtc-ds1307.txt
··· 1 + Dallas DS1307 and compatible RTC 2 + 3 + Required properties: 4 + - compatible: should be one of: 5 + "dallas,ds1307", 6 + "dallas,ds1308", 7 + "dallas,ds1337", 8 + "dallas,ds1338", 9 + "dallas,ds1339", 10 + "dallas,ds1388", 11 + "dallas,ds1340", 12 + "dallas,ds1341", 13 + "maxim,ds3231", 14 + "st,m41t0", 15 + "st,m41t00", 16 + "microchip,mcp7940x", 17 + "microchip,mcp7941x", 18 + "pericom,pt7c4338", 19 + "epson,rx8025", 20 + "isil,isl12057" 21 + - reg: I2C bus address of the device 22 + 23 + Optional properties: 24 + - interrupt-parent: phandle for the interrupt controller. 25 + - interrupts: rtc alarm interrupt. 26 + - clock-output-names: From common clock binding to override the default output 27 + clock name 28 + - wakeup-source: Enables wake up of host system on alarm 29 + - trickle-resistor-ohms : ds1339, ds1340 and ds 1388 only 30 + Selected resistor for trickle charger 31 + Possible values are 250, 2000, 4000 32 + Should be given if trickle charger should be enabled 33 + - trickle-diode-disable : ds1339, ds1340 and ds 1388 only 34 + Do not use internal trickle charger diode 35 + Should be given if internal trickle charger diode should be disabled 36 + 37 + Example: 38 + rtc1: ds1339@68 { 39 + compatible = "dallas,ds1339"; 40 + reg = <0x68>; 41 + interrupt-parent = <&gpio4>; 42 + interrupts = <20 0>; 43 + trickle-resistor-ohms = <250>; 44 + };
+31
Documentation/devicetree/bindings/rtc/rtc-m41t80.txt
··· 1 + ST M41T80 family of RTC and compatible 2 + 3 + Required properties: 4 + - compatible: should be one of: 5 + "st,m41t62", 6 + "st,m41t65", 7 + "st,m41t80", 8 + "st,m41t81", 9 + "st,m41t81s", 10 + "st,m41t82", 11 + "st,m41t83", 12 + "st,m41t84", 13 + "st,m41t85", 14 + "st,m41t87", 15 + "microcrystal,rv4162", 16 + - reg: I2C bus address of the device 17 + 18 + Optional properties: 19 + - interrupt-parent: phandle for the interrupt controller. 20 + - interrupts: rtc alarm interrupt. 21 + - clock-output-names: From common clock binding to override the default output 22 + clock name 23 + - wakeup-source: Enables wake up of host system on alarm 24 + 25 + Example: 26 + rtc@68 { 27 + compatible = "st,m41t80"; 28 + reg = <0x68>; 29 + interrupt-parent = <&UIC0>; 30 + interrupts = <0x9 0x8>; 31 + };
+13
Documentation/devicetree/bindings/rtc/sirf,prima2-sysrtc.txt
··· 1 + SiRFSoC Real Time Clock 2 + 3 + Required properties: 4 + - compatible: must be "sirf,prima2-sysrtc" 5 + - reg: address range of rtc register set. 6 + - interrupts: rtc alarm interrupts. 7 + 8 + Example: 9 + rtc@2000 { 10 + compatible = "sirf,prima2-sysrtc"; 11 + reg = <0x2000 0x1000>; 12 + interrupts = <52 53 54>; 13 + };
+17
Documentation/devicetree/bindings/rtc/stericsson,coh901331.txt
··· 1 + ST-Ericsson COH 901 331 Real Time Clock 2 + 3 + Required properties: 4 + - compatible: must be "stericsson,coh901331" 5 + - reg: address range of rtc register set. 6 + - interrupt-parent: phandle for the interrupt controller. 7 + - interrupts: rtc alarm interrupt. 8 + - clocks: phandle to the rtc clock source 9 + 10 + Example: 11 + rtc: rtc@c0017000 { 12 + compatible = "stericsson,coh901331"; 13 + reg = <0xc0017000 0x1000>; 14 + interrupt-parent = <&vicb>; 15 + interrupts = <10>; 16 + clocks = <&rtc_clk>; 17 + };
+1 -1
Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
··· 17 17 18 18 Example: 19 19 20 - rtc: rtc@01f00000 { 20 + rtc: rtc@1f00000 { 21 21 compatible = "allwinner,sun6i-a31-rtc"; 22 22 reg = <0x01f00000 0x54>; 23 23 interrupts = <0 40 4>, <0 41 4>;
+1 -1
Documentation/devicetree/bindings/rtc/sunxi-rtc.txt
··· 10 10 11 11 Example: 12 12 13 - rtc: rtc@01c20d00 { 13 + rtc: rtc@1c20d00 { 14 14 compatible = "allwinner,sun4i-a10-rtc"; 15 15 reg = <0x01c20d00 0x20>; 16 16 interrupts = <24>;
+1 -1
Documentation/devicetree/bindings/soc/fsl/cpm_qe/qe/par_io.txt
··· 18 18 #size-cells = <0>; 19 19 device_type = "par_io"; 20 20 num-ports = <7>; 21 - ucc_pin@01 { 21 + ucc_pin@1 { 22 22 ...... 23 23 }; 24 24
+1 -1
Documentation/devicetree/bindings/soc/fsl/cpm_qe/qe/pincfg.txt
··· 26 26 interrupts. 27 27 28 28 Example: 29 - ucc_pin@01 { 29 + ucc_pin@1 { 30 30 pio-map = < 31 31 /* port pin dir open_drain assignment has_irq */ 32 32 0 3 1 0 1 0 /* TxD0 */
+1 -1
Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
··· 51 51 52 52 Example (K2G): 53 53 -------------------- 54 - uart0: serial@02530c00 { 54 + uart0: serial@2530c00 { 55 55 compatible = "ns16550a"; 56 56 ... 57 57 power-domains = <&k2g_pds 0x002c>;
+1 -1
Documentation/devicetree/bindings/sound/cdns,xtfpga-i2s.txt
··· 9 9 10 10 Examples: 11 11 12 - i2s0: xtfpga-i2s@0d080000 { 12 + i2s0: xtfpga-i2s@d080000 { 13 13 #sound-dai-cells = <0>; 14 14 compatible = "cdns,xtfpga-i2s"; 15 15 reg = <0x0d080000 0x40>;
+1 -1
Documentation/devicetree/bindings/sound/fsl,asrc.txt
··· 41 41 42 42 Example: 43 43 44 - asrc: asrc@02034000 { 44 + asrc: asrc@2034000 { 45 45 compatible = "fsl,imx53-asrc"; 46 46 reg = <0x02034000 0x4000>; 47 47 interrupts = <0 50 IRQ_TYPE_LEVEL_HIGH>;
+1 -1
Documentation/devicetree/bindings/sound/fsl,esai.txt
··· 48 48 49 49 Example: 50 50 51 - esai: esai@02024000 { 51 + esai: esai@2024000 { 52 52 compatible = "fsl,imx35-esai"; 53 53 reg = <0x02024000 0x4000>; 54 54 interrupts = <0 51 0x04>;
+1 -1
Documentation/devicetree/bindings/sound/fsl,spdif.txt
··· 39 39 40 40 Example: 41 41 42 - spdif: spdif@02004000 { 42 + spdif: spdif@2004000 { 43 43 compatible = "fsl,imx35-spdif"; 44 44 reg = <0x02004000 0x4000>; 45 45 interrupts = <0 52 0x04>;
+1 -1
Documentation/devicetree/bindings/sound/imx-audmux.txt
··· 22 22 23 23 Example: 24 24 25 - audmux@021d8000 { 25 + audmux@21d8000 { 26 26 compatible = "fsl,imx6q-audmux", "fsl,imx31-audmux"; 27 27 reg = <0x021d8000 0x4000>; 28 28 };
+1 -1
Documentation/devicetree/bindings/sound/samsung-i2s.txt
··· 63 63 64 64 Example: 65 65 66 - i2s0: i2s@03830000 { 66 + i2s0: i2s@3830000 { 67 67 compatible = "samsung,s5pv210-i2s"; 68 68 reg = <0x03830000 0x100>; 69 69 dmas = <&pdma0 10
+2 -2
Documentation/devicetree/bindings/sound/sun4i-codec.txt
··· 62 62 block in the PRCM. 63 63 64 64 Example: 65 - codec: codec@01c22c00 { 65 + codec: codec@1c22c00 { 66 66 #sound-dai-cells = <0>; 67 67 compatible = "allwinner,sun7i-a20-codec"; 68 68 reg = <0x01c22c00 0x40>; ··· 73 73 dma-names = "rx", "tx"; 74 74 }; 75 75 76 - codec: codec@01c22c00 { 76 + codec: codec@1c22c00 { 77 77 #sound-dai-cells = <0>; 78 78 compatible = "allwinner,sun6i-a31-codec"; 79 79 reg = <0x01c22c00 0x98>;
+1 -1
Documentation/devicetree/bindings/sound/sun4i-i2s.txt
··· 28 28 29 29 Example: 30 30 31 - i2s0: i2s@01c22400 { 31 + i2s0: i2s@1c22400 { 32 32 #sound-dai-cells = <0>; 33 33 compatible = "allwinner,sun4i-a10-i2s"; 34 34 reg = <0x01c22400 0x400>;
+1 -1
Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt
··· 48 48 sound-dai = <&codec>; 49 49 }; 50 50 51 - soc@01c00000 { 51 + soc@1c00000 { 52 52 [...] 53 53 54 54 audio-codec@1c22e00 {
+1 -1
Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
··· 10 10 - reg: must contain the registers location and length 11 11 12 12 Example: 13 - prcm: prcm@01f01400 { 13 + prcm: prcm@1f01400 { 14 14 codec_analog: codec-analog { 15 15 compatible = "allwinner,sun8i-a23-codec-analog"; 16 16 };
+1 -1
Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt
··· 31 31 32 32 Example: 33 33 34 - spdif: spdif@01c21000 { 34 + spdif: spdif@1c21000 { 35 35 compatible = "allwinner,sun4i-a10-spdif"; 36 36 reg = <0x01c21000 0x40>; 37 37 interrupts = <13>;
+1 -1
Documentation/devicetree/bindings/sound/zte,zx-spdif.txt
··· 16 16 * dma/dma.txt 17 17 18 18 Example: 19 - spdif0: spdif0@0b004000 { 19 + spdif0: spdif0@b004000 { 20 20 compatible = "zte,zx296702-spdif"; 21 21 reg = <0x0b004000 0x1000>; 22 22 clocks = <&lsp0clk ZX296702_SPDIF0_DIV>;
+1 -1
Documentation/devicetree/bindings/spi/spi-sun4i.txt
··· 12 12 13 13 Example: 14 14 15 - spi1: spi@01c06000 { 15 + spi1: spi@1c06000 { 16 16 compatible = "allwinner,sun4i-a10-spi"; 17 17 reg = <0x01c06000 0x1000>; 18 18 interrupts = <11>;
+2 -2
Documentation/devicetree/bindings/spi/spi-sun6i.txt
··· 19 19 20 20 Example: 21 21 22 - spi1: spi@01c69000 { 22 + spi1: spi@1c69000 { 23 23 compatible = "allwinner,sun6i-a31-spi"; 24 24 reg = <0x01c69000 0x1000>; 25 25 interrupts = <0 66 4>; ··· 28 28 resets = <&ahb1_rst 21>; 29 29 }; 30 30 31 - spi0: spi@01c68000 { 31 + spi0: spi@1c68000 { 32 32 compatible = "allwinner,sun8i-h3-spi"; 33 33 reg = <0x01c68000 0x1000>; 34 34 interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+1 -1
Documentation/devicetree/bindings/sram/samsung-sram.txt
··· 19 19 20 20 Example: 21 21 22 - sysram@02020000 { 22 + sysram@2020000 { 23 23 compatible = "mmio-sram"; 24 24 reg = <0x02020000 0x54000>; 25 25 #address-cells = <1>;
+2 -2
Documentation/devicetree/bindings/sram/sunxi-sram.txt
··· 47 47 48 48 Example 49 49 ------- 50 - sram-controller@01c00000 { 50 + sram-controller@1c00000 { 51 51 compatible = "allwinner,sun4i-a10-sram-controller"; 52 52 reg = <0x01c00000 0x30>; 53 53 #address-cells = <1>; ··· 68 68 }; 69 69 }; 70 70 71 - emac: ethernet@01c0b000 { 71 + emac: ethernet@1c0b000 { 72 72 compatible = "allwinner,sun4i-a10-emac"; 73 73 ... 74 74
+1 -1
Documentation/devicetree/bindings/timer/allwinner,sun5i-a13-hstimer.txt
··· 14 14 15 15 Example: 16 16 17 - timer@01c60000 { 17 + timer@1c60000 { 18 18 compatible = "allwinner,sun7i-a20-hstimer"; 19 19 reg = <0x01c60000 0x1000>; 20 20 interrupts = <0 51 1>,
+5 -8
Documentation/devicetree/bindings/trivial-devices.txt
··· 36 36 capella,cm32181 CM32181: Ambient Light Sensor 37 37 capella,cm3232 CM3232: Ambient Light Sensor 38 38 cirrus,cs42l51 Cirrus Logic CS42L51 audio codec 39 - dallas,ds1307 64 x 8, Serial, I2C Real-Time Clock 40 - dallas,ds1338 I2C RTC with 56-Byte NV RAM 41 - dallas,ds1340 I2C RTC with Trickle Charger 42 39 dallas,ds1374 I2C, 32-Bit Binary Counter Watchdog RTC with Trickle Charger and Reset Input/Output 43 40 dallas,ds1631 High-Precision Digital Thermometer 41 + dallas,ds1672 Dallas DS1672 Real-time Clock 44 42 dallas,ds1682 Total-Elapsed-Time Recorder with Alarm 45 43 dallas,ds1775 Tiny Digital Thermometer and Thermostat 46 44 dallas,ds3232 Extremely Accurate I²C RTC with Integrated Crystal and SRAM ··· 52 54 domintech,dmard09 DMARD09: 3-axis Accelerometer 53 55 domintech,dmard10 DMARD10: 3-axis Accelerometer 54 56 epson,rx8010 I2C-BUS INTERFACE REAL TIME CLOCK MODULE 55 - epson,rx8025 High-Stability. I2C-Bus INTERFACE REAL TIME CLOCK MODULE 56 57 epson,rx8581 I2C-BUS INTERFACE REAL TIME CLOCK MODULE 58 + emmicro,em3027 EM Microelectronic EM3027 Real-time Clock 57 59 fsl,mag3110 MAG3110: Xtrinsic High Accuracy, 3D Magnetometer 58 60 fsl,mc13892 MC13892: Power Management Integrated Circuit (PMIC) for i.MX35/51 59 61 fsl,mma7660 MMA7660FC: 3-Axis Orientation/Motion Detection Sensor ··· 65 67 infineon,slb9635tt Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz) 66 68 infineon,slb9645tt Infineon SLB9645 I2C TPM (new protocol, max 400khz) 67 69 isil,isl1208 Intersil ISL1208 Low Power RTC with Battery Backed SRAM 70 + isil,isl1218 Intersil ISL1218 Low Power RTC with Battery Backed SRAM 71 + isil,isl12022 Intersil ISL12022 Real-time Clock 68 72 isil,isl29028 Intersil ISL29028 Ambient Light and Proximity Sensor 69 73 isil,isl29030 Intersil ISL29030 Ambient Light and Proximity Sensor 70 74 maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator ··· 156 156 nxp,pca9557 8-bit I2C-bus and SMBus I/O port with reset 157 157 nxp,pcf2127 Real-time clock 158 158 nxp,pcf2129 Real-time clock 159 + nxp,pcf8523 Real-time Clock 159 160 nxp,pcf8563 Real-time clock/calendar 160 161 nxp,pcf85063 Tiny Real-Time Clock 161 162 oki,ml86v7667 OKI ML86V7667 video decoder ··· 176 175 silabs,si7020 Relative Humidity and Temperature Sensors 177 176 skyworks,sky81452 Skyworks SKY81452: Six-Channel White LED Driver with Touch Panel Bias Supply 178 177 st,24c256 i2c serial eeprom (24cxx) 179 - st,m41t0 Serial real-time clock (RTC) 180 - st,m41t00 Serial real-time clock (RTC) 181 - st,m41t62 Serial real-time clock (RTC) with alarm 182 - st,m41t80 M41T80 - SERIAL ACCESS RTC WITH ALARMS 183 178 taos,tsl2550 Ambient Light Sensor with SMBUS/Two Wire Serial Interface 184 179 ti,ads7828 8-Channels, 12-bit ADC 185 180 ti,ads7830 8-Channels, 8-bit ADC
+1 -1
Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt
··· 16 16 17 17 Example: 18 18 19 - usb_otg: usb@01c13000 { 19 + usb_otg: usb@1c13000 { 20 20 compatible = "allwinner,sun4i-a10-musb"; 21 21 reg = <0x01c13000 0x0400>; 22 22 clocks = <&ahb_gates 0>;
+1 -1
Documentation/devicetree/bindings/usb/am33xx-usb.txt
··· 181 181 "tx14", "tx15"; 182 182 }; 183 183 184 - cppi41dma: dma-controller@07402000 { 184 + cppi41dma: dma-controller@7402000 { 185 185 compatible = "ti,am3359-cppi41"; 186 186 reg = <0x47400000 0x1000 187 187 0x47402000 0x1000
+2 -2
Documentation/devicetree/bindings/usb/atmel-usb.txt
··· 18 18 - atmel,oc-gpio: If present, specifies a gpio that needs to be 19 19 activated for the overcurrent detection. 20 20 21 - usb0: ohci@00500000 { 21 + usb0: ohci@500000 { 22 22 compatible = "atmel,at91rm9200-ohci", "usb-ohci"; 23 23 reg = <0x00500000 0x100000>; 24 24 clocks = <&uhphs_clk>, <&uhphs_clk>, <&uhpck>; ··· 39 39 "ehci_clk" for the peripheral clock 40 40 "usb_clk" for the UTMI clock 41 41 42 - usb1: ehci@00800000 { 42 + usb1: ehci@800000 { 43 43 compatible = "atmel,at91sam9g45-ehci", "usb-ehci"; 44 44 reg = <0x00800000 0x100000>; 45 45 interrupts = <22 4>;
+1 -1
Documentation/devicetree/bindings/usb/ohci-da8xx.txt
··· 13 13 14 14 Example: 15 15 16 - ohci: usb@0225000 { 16 + ohci: usb@225000 { 17 17 compatible = "ti,da830-ohci"; 18 18 reg = <0x225000 0x1000>; 19 19 interrupts = <59>;
+1 -1
Documentation/devicetree/bindings/usb/usb-ehci.txt
··· 30 30 }; 31 31 32 32 Example (Allwinner sun4i A10 SoC): 33 - ehci0: usb@01c14000 { 33 + ehci0: usb@1c14000 { 34 34 compatible = "allwinner,sun4i-a10-ehci", "generic-ehci"; 35 35 reg = <0x01c14000 0x100>; 36 36 interrupts = <39>;
+2
Documentation/devicetree/bindings/usb/usb-nop-xceiv.txt
··· 2 2 3 3 Required properties: 4 4 - compatible: should be usb-nop-xceiv 5 + - #phy-cells: Must be 0 5 6 6 7 Optional properties: 7 8 - clocks: phandle to the PHY clock. Use as per Documentation/devicetree ··· 34 33 reset-gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; 35 34 vbus-detect-gpio = <&gpio2 13 GPIO_ACTIVE_HIGH>; 36 35 vbus-regulator = <&vbus_regulator>; 36 + #phy-cells = <0>; 37 37 }; 38 38 39 39 hsusb1_phy is a NOP USB PHY device that gets its clock from an oscillator
+1 -1
Documentation/devicetree/bindings/usb/usb-ohci.txt
··· 19 19 20 20 Example: 21 21 22 - ohci0: usb@01c14400 { 22 + ohci0: usb@1c14400 { 23 23 compatible = "allwinner,sun4i-a10-ohci", "generic-ohci"; 24 24 reg = <0x01c14400 0x100>; 25 25 interrupts = <64>;
+1 -1
Documentation/devicetree/bindings/usb/usb3503.txt
··· 26 26 clock frequencies table is used) 27 27 28 28 Examples: 29 - usb3503@08 { 29 + usb3503@8 { 30 30 compatible = "smsc,usb3503"; 31 31 reg = <0x08>; 32 32 connect-gpios = <&gpx3 0 1>;
+1 -1
Documentation/devicetree/bindings/usb/usbmisc-imx.txt
··· 10 10 - reg: Should contain registers location and length 11 11 12 12 Examples: 13 - usbmisc@02184800 { 13 + usbmisc@2184800 { 14 14 #index-cells = <1>; 15 15 compatible = "fsl,imx6q-usbmisc"; 16 16 reg = <0x02184800 0x200>;
+7
Documentation/devicetree/bindings/vendor-prefixes.txt
··· 83 83 delta Delta Electronics, Inc. 84 84 denx Denx Software Engineering 85 85 devantech Devantech, Ltd. 86 + dh DH electronics GmbH 86 87 digi Digi International Inc. 87 88 digilent Diglent, Inc. 88 89 dioo Dioo Microcircuit Co., Ltd ··· 231 230 netron-dy Netron DY 232 231 netxeon Shenzhen Netxeon Technology CO., LTD 233 232 nexbox Nexbox 233 + nextthing Next Thing Co. 234 234 newhaven Newhaven Display International 235 235 ni National Instruments 236 236 nintendo Nintendo 237 237 nlt NLT Technologies, Ltd. 238 238 nokia Nokia 239 239 nordic Nordic Semiconductor 240 + nutsboard NutsBoard 240 241 nuvoton Nuvoton Technology Corporation 241 242 nvd New Vision Display 242 243 nvidia NVIDIA ··· 249 246 onion Onion Corporation 250 247 onnn ON Semiconductor Corp. 251 248 ontat On Tat Industrial Company 249 + opalkelly Opal Kelly Incorporated 252 250 opencores OpenCores.org 253 251 openrisc OpenRISC.io 254 252 option Option NV ··· 302 298 sff Small Form Factor Committee 303 299 sgx SGX Sensortech 304 300 sharp Sharp Corporation 301 + shimafuji Shimafuji Electric, Inc. 305 302 si-en Si-En Technology Ltd. 306 303 sigma Sigma Designs, Inc. 307 304 sii Seiko Instruments, Inc. ··· 324 319 sony Sony Corporation 325 320 spansion Spansion Inc. 326 321 sprd Spreadtrum Communications Inc. 322 + sst Silicon Storage Technology, Inc. 327 323 st STMicroelectronics 328 324 starry Starry Electronic Technology (ShenZhen) Co., LTD 329 325 startek Startek ··· 346 340 ti Texas Instruments 347 341 tianma Tianma Micro-electronics Co., Ltd. 348 342 tlm Trusted Logic Mobility 343 + tmt Tecon Microprocessor Technologies, LLC. 349 344 topeet Topeet 350 345 toradex Toradex AG 351 346 toshiba Toshiba Corporation
+1 -1
Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
··· 13 13 14 14 Example: 15 15 16 - wdt: watchdog@010000000 { 16 + wdt: watchdog@10000000 { 17 17 compatible = "mediatek,mt6589-wdt"; 18 18 reg = <0x10000000 0x18>; 19 19 };
+1 -1
Documentation/devicetree/bindings/watchdog/sunxi-wdt.txt
··· 8 8 9 9 Example: 10 10 11 - wdt: watchdog@01c20c90 { 11 + wdt: watchdog@1c20c90 { 12 12 compatible = "allwinner,sun4i-a10-wdt"; 13 13 reg = <0x01c20c90 0x10>; 14 14 };
+6 -6
Documentation/devicetree/overlay-notes.txt
··· 87 87 88 88 The API is quite easy to use. 89 89 90 - 1. Call of_overlay_create() to create and apply an overlay. The return value 91 - is a cookie identifying this overlay. 90 + 1. Call of_overlay_apply() to create and apply an overlay changeset. The return 91 + value is an error or a cookie identifying this overlay. 92 92 93 - 2. Call of_overlay_destroy() to remove and cleanup the overlay previously 94 - created via the call to of_overlay_create(). Removal of an overlay that 95 - is stacked by another will not be permitted. 93 + 2. Call of_overlay_remove() to remove and cleanup the overlay changeset 94 + previously created via the call to of_overlay_apply(). Removal of an overlay 95 + changeset that is stacked by another will not be permitted. 96 96 97 97 Finally, if you need to remove all overlays in one-go, just call 98 - of_overlay_destroy_all() which will remove every single one in the correct 98 + of_overlay_remove_all() which will remove every single one in the correct 99 99 order. 100 100 101 101 Overlay DTS Format
-1
Documentation/kbuild/makefiles.txt
··· 1158 1158 1159 1159 Example: 1160 1160 targets += $(dtb-y) 1161 - clean-files += *.dtb 1162 1161 DTC_FLAGS ?= -p 1024 1163 1162 1164 1163 --- 6.8 Custom kbuild commands
+1 -1
Makefile
··· 1550 1550 $(call cmd,rmfiles) 1551 1551 @find $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \ 1552 1552 \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ 1553 - -o -name '*.ko.*' \ 1553 + -o -name '*.ko.*' -o -name '*.dtb' -o -name '*.dtb.S' \ 1554 1554 -o -name '*.dwo' \ 1555 1555 -o -name '*.su' \ 1556 1556 -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
-1
arch/arc/boot/.gitignore
··· 1 - *.dtb* 2 1 uImage
+3 -5
arch/arc/boot/dts/Makefile
··· 11 11 12 12 .SECONDARY: $(obj)/$(builtindtb-y).dtb.S 13 13 14 - dtstree := $(srctree)/$(src) 15 - dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts)) 16 - 17 - always := $(dtb-y) 18 - clean-files := *.dtb *.dtb.S 14 + # for CONFIG_OF_ALL_DTBS test 15 + dtstree := $(srctree)/$(src) 16 + dtb- := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
-1
arch/arm/boot/.gitignore
··· 3 3 xipImage 4 4 bootpImage 5 5 uImage 6 - *.dtb
-6
arch/arm/boot/dts/Makefile
··· 1070 1070 aspeed-bmc-opp-romulus.dtb \ 1071 1071 aspeed-ast2500-evb.dtb 1072 1072 endif 1073 - 1074 - dtstree := $(srctree)/$(src) 1075 - dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts)) 1076 - 1077 - always := $(dtb-y) 1078 - clean-files := *.dtb
-1
arch/arm64/boot/dts/.gitignore
··· 1 - *.dtb
+25 -33
arch/arm64/boot/dts/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 - dts-dirs += actions 3 - dts-dirs += al 4 - dts-dirs += allwinner 5 - dts-dirs += altera 6 - dts-dirs += amd 7 - dts-dirs += amlogic 8 - dts-dirs += apm 9 - dts-dirs += arm 10 - dts-dirs += broadcom 11 - dts-dirs += cavium 12 - dts-dirs += exynos 13 - dts-dirs += freescale 14 - dts-dirs += hisilicon 15 - dts-dirs += marvell 16 - dts-dirs += mediatek 17 - dts-dirs += nvidia 18 - dts-dirs += qcom 19 - dts-dirs += realtek 20 - dts-dirs += renesas 21 - dts-dirs += rockchip 22 - dts-dirs += socionext 23 - dts-dirs += sprd 24 - dts-dirs += xilinx 25 - dts-dirs += lg 26 - dts-dirs += zte 27 - 28 - subdir-y := $(dts-dirs) 29 - 30 - dtstree := $(srctree)/$(src) 31 - 32 - dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(foreach d,$(dts-dirs), $(wildcard $(dtstree)/$(d)/*.dts))) 33 - 34 - always := $(dtb-y) 2 + subdir-y += actions 3 + subdir-y += al 4 + subdir-y += allwinner 5 + subdir-y += altera 6 + subdir-y += amd 7 + subdir-y += amlogic 8 + subdir-y += apm 9 + subdir-y += arm 10 + subdir-y += broadcom 11 + subdir-y += cavium 12 + subdir-y += exynos 13 + subdir-y += freescale 14 + subdir-y += hisilicon 15 + subdir-y += marvell 16 + subdir-y += mediatek 17 + subdir-y += nvidia 18 + subdir-y += qcom 19 + subdir-y += realtek 20 + subdir-y += renesas 21 + subdir-y += rockchip 22 + subdir-y += socionext 23 + subdir-y += sprd 24 + subdir-y += xilinx 25 + subdir-y += lg 26 + subdir-y += zte
-4
arch/arm64/boot/dts/actions/Makefile
··· 1 1 dtb-$(CONFIG_ARCH_ACTIONS) += s900-bubblegum-96.dtb 2 - 3 - always := $(dtb-y) 4 - subdir-y := $(dts-dirs) 5 - clean-files := *.dtb
-4
arch/arm64/boot/dts/al/Makefile
··· 1 1 dtb-$(CONFIG_ARCH_ALPINE) += alpine-v2-evp.dtb 2 - 3 - always := $(dtb-y) 4 - subdir-y := $(dts-dirs) 5 - clean-files := *.dtb
-4
arch/arm64/boot/dts/allwinner/Makefile
··· 9 9 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-prime.dtb 10 10 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-zero-plus2.dtb 11 11 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-nanopi-neo2.dtb 12 - 13 - always := $(dtb-y) 14 - subdir-y := $(dts-dirs) 15 - clean-files := *.dtb
-4
arch/arm64/boot/dts/altera/Makefile
··· 1 1 dtb-$(CONFIG_ARCH_STRATIX10) += socfpga_stratix10_socdk.dtb 2 - 3 - always := $(dtb-y) 4 - subdir-y := $(dts-dirs) 5 - clean-files := *.dtb
-4
arch/arm64/boot/dts/amd/Makefile
··· 2 2 dtb-$(CONFIG_ARCH_SEATTLE) += amd-overdrive.dtb \ 3 3 amd-overdrive-rev-b0.dtb amd-overdrive-rev-b1.dtb \ 4 4 husky.dtb 5 - 6 - always := $(dtb-y) 7 - subdir-y := $(dts-dirs) 8 - clean-files := *.dtb
-4
arch/arm64/boot/dts/amlogic/Makefile
··· 20 20 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-q200.dtb 21 21 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-q201.dtb 22 22 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-rbox-pro.dtb 23 - 24 - always := $(dtb-y) 25 - subdir-y := $(dts-dirs) 26 - clean-files := *.dtb
-4
arch/arm64/boot/dts/apm/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 dtb-$(CONFIG_ARCH_XGENE) += apm-mustang.dtb 3 3 dtb-$(CONFIG_ARCH_XGENE) += apm-merlin.dtb 4 - 5 - always := $(dtb-y) 6 - subdir-y := $(dts-dirs) 7 - clean-files := *.dtb
-4
arch/arm64/boot/dts/arm/Makefile
··· 3 3 dtb-$(CONFIG_ARCH_VEXPRESS) += juno.dtb juno-r1.dtb juno-r2.dtb 4 4 dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb 5 5 dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2f-1xv7-ca53x2.dtb 6 - 7 - always := $(dtb-y) 8 - subdir-y := $(dts-dirs) 9 - clean-files := *.dtb
+2 -5
arch/arm64/boot/dts/broadcom/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rpi-3-b.dtb 3 3 4 - dts-dirs += northstar2 5 - dts-dirs += stingray 6 - always := $(dtb-y) 7 - subdir-y := $(dts-dirs) 8 - clean-files := *.dtb 4 + subdir-y += northstar2 5 + subdir-y += stingray
-4
arch/arm64/boot/dts/broadcom/northstar2/Makefile
··· 1 1 dtb-$(CONFIG_ARCH_BCM_IPROC) += ns2-svk.dtb 2 2 dtb-$(CONFIG_ARCH_BCM_IPROC) += ns2-xmc.dtb 3 - 4 - always := $(dtb-y) 5 - subdir-y := $(dts-dirs) 6 - clean-files := *.dtb
-4
arch/arm64/boot/dts/broadcom/stingray/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 dtb-$(CONFIG_ARCH_BCM_IPROC) += bcm958742k.dtb 3 3 dtb-$(CONFIG_ARCH_BCM_IPROC) += bcm958742t.dtb 4 - 5 - always := $(dtb-y) 6 - subdir-y := $(dts-dirs) 7 - clean-files := *.dtb
-4
arch/arm64/boot/dts/cavium/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 dtb-$(CONFIG_ARCH_THUNDER) += thunder-88xx.dtb 3 3 dtb-$(CONFIG_ARCH_THUNDER2) += thunder2-99xx.dtb 4 - 5 - always := $(dtb-y) 6 - subdir-y := $(dts-dirs) 7 - clean-files := *.dtb
-4
arch/arm64/boot/dts/exynos/Makefile
··· 3 3 exynos5433-tm2.dtb \ 4 4 exynos5433-tm2e.dtb \ 5 5 exynos7-espresso.dtb 6 - 7 - always := $(dtb-y) 8 - subdir-y := $(dts-dirs) 9 - clean-files := *.dtb
-4
arch/arm64/boot/dts/freescale/Makefile
··· 13 13 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-simu.dtb 14 14 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-qds.dtb 15 15 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-rdb.dtb 16 - 17 - always := $(dtb-y) 18 - subdir-y := $(dts-dirs) 19 - clean-files := *.dtb
-4
arch/arm64/boot/dts/hisilicon/Makefile
··· 5 5 dtb-$(CONFIG_ARCH_HISI) += hip05-d02.dtb 6 6 dtb-$(CONFIG_ARCH_HISI) += hip06-d03.dtb 7 7 dtb-$(CONFIG_ARCH_HISI) += hip07-d05.dtb 8 - 9 - always := $(dtb-y) 10 - subdir-y := $(dts-dirs) 11 - clean-files := *.dtb
-4
arch/arm64/boot/dts/lg/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 dtb-$(CONFIG_ARCH_LG1K) += lg1312-ref.dtb 3 3 dtb-$(CONFIG_ARCH_LG1K) += lg1313-ref.dtb 4 - 5 - always := $(dtb-y) 6 - subdir-y := $(dts-dirs) 7 - clean-files := *.dtb
-4
arch/arm64/boot/dts/marvell/Makefile
··· 10 10 dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-db.dtb 11 11 dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-mcbin.dtb 12 12 dtb-$(CONFIG_ARCH_MVEBU) += armada-8080-db.dtb 13 - 14 - always := $(dtb-y) 15 - subdir-y := $(dts-dirs) 16 - clean-files := *.dtb
-4
arch/arm64/boot/dts/mediatek/Makefile
··· 5 5 dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb 6 6 dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb 7 7 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb 8 - 9 - always := $(dtb-y) 10 - subdir-y := $(dts-dirs) 11 - clean-files := *.dtb
-3
arch/arm64/boot/dts/nvidia/Makefile
··· 5 5 dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2571.dtb 6 6 dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-smaug.dtb 7 7 dtb-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186-p2771-0000.dtb 8 - 9 - always := $(dtb-y) 10 - clean-files := *.dtb
-4
arch/arm64/boot/dts/qcom/Makefile
··· 6 6 dtb-$(CONFIG_ARCH_QCOM) += msm8992-bullhead-rev-101.dtb 7 7 dtb-$(CONFIG_ARCH_QCOM) += msm8994-angler-rev-101.dtb 8 8 dtb-$(CONFIG_ARCH_QCOM) += msm8996-mtp.dtb 9 - 10 - always := $(dtb-y) 11 - subdir-y := $(dts-dirs) 12 - clean-files := *.dtb
-4
arch/arm64/boot/dts/realtek/Makefile
··· 1 1 dtb-$(CONFIG_ARCH_REALTEK) += rtd1295-zidoo-x9s.dtb 2 - 3 - always := $(dtb-y) 4 - subdir-y := $(dts-dirs) 5 - clean-files := *.dtb
-3
arch/arm64/boot/dts/renesas/Makefile
··· 4 4 dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-es1-salvator-x.dtb r8a7795-es1-h3ulcb.dtb 5 5 dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-x.dtb r8a7796-m3ulcb.dtb 6 6 dtb-$(CONFIG_ARCH_R8A77995) += r8a77995-draak.dtb 7 - 8 - always := $(dtb-y) 9 - clean-files := *.dtb
-4
arch/arm64/boot/dts/rockchip/Makefile
··· 11 11 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-kevin.dtb 12 12 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb 13 13 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb 14 - 15 - always := $(dtb-y) 16 - subdir-y := $(dts-dirs) 17 - clean-files := *.dtb
-3
arch/arm64/boot/dts/socionext/Makefile
··· 5 5 uniphier-ld20-global.dtb \ 6 6 uniphier-ld20-ref.dtb \ 7 7 uniphier-pxs3-ref.dtb 8 - 9 - always := $(dtb-y) 10 - clean-files := *.dtb
-4
arch/arm64/boot/dts/sprd/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 dtb-$(CONFIG_ARCH_SPRD) += sc9836-openphone.dtb \ 3 3 sp9860g-1h10.dtb 4 - 5 - always := $(dtb-y) 6 - subdir-y := $(dts-dirs) 7 - clean-files := *.dtb
-4
arch/arm64/boot/dts/xilinx/Makefile
··· 1 1 dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-ep108.dtb 2 - 3 - always := $(dtb-y) 4 - subdir-y := $(dts-dirs) 5 - clean-files := *.dtb
-4
arch/arm64/boot/dts/zte/Makefile
··· 1 1 dtb-$(CONFIG_ARCH_ZX) += zx296718-evb.dtb 2 2 dtb-$(CONFIG_ARCH_ZX) += zx296718-pcbox.dtb 3 - 4 - always := $(dtb-y) 5 - subdir-y := $(dts-dirs) 6 - clean-files := *.dtb
-2
arch/c6x/boot/dts/Makefile
··· 17 17 $(call if_changed,cp) 18 18 19 19 $(obj)/linked_dtb.o: $(obj)/builtin.dtb 20 - 21 - clean-files := *.dtb
-2
arch/cris/boot/dts/Makefile
··· 3 3 ifneq ($(CONFIG_BUILTIN_DTB),"") 4 4 obj-$(CONFIG_OF) += $(BUILTIN_DTB) 5 5 endif 6 - 7 - clean-files := *.dtb.S
-6
arch/h8300/boot/dts/Makefile
··· 8 8 dtb-$(CONFIG_H8300H_SIM) := h8300h_sim.dtb 9 9 dtb-$(CONFIG_H8S_SIM) := h8s_sim.dtb 10 10 dtb-$(CONFIG_H8S_EDOSK2674) := edosk2674.dtb 11 - 12 - dtstree := $(srctree)/$(src) 13 - dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts)) 14 - 15 - always := $(dtb-y) 16 - clean-files := *.dtb.S *.dtb
-1
arch/metag/boot/.gitignore
··· 1 1 vmlinux* 2 2 uImage* 3 3 ramdisk.* 4 - *.dtb*
-6
arch/metag/boot/dts/Makefile
··· 13 13 dtb-$(CONFIG_METAG_BUILTIN_DTB) += $(builtindtb-y).dtb 14 14 obj-$(CONFIG_METAG_BUILTIN_DTB) += $(builtindtb-y).dtb.o 15 15 16 - dtstree := $(srctree)/$(src) 17 - dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts)) 18 - 19 16 .SECONDARY: $(obj)/$(builtindtb-y).dtb.S 20 - 21 - always += $(dtb-y) 22 - clean-files += *.dtb *.dtb.S
-1
arch/microblaze/boot/.gitignore
··· 1 - *.dtb 2 1 linux.bin* 3 2 simpleImage.*
+1 -1
arch/microblaze/boot/Makefile
··· 35 35 $(call if_changed,strip) 36 36 @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' 37 37 38 - clean-files += simpleImage.*.unstrip linux.bin.ub dts/*.dtb 38 + clean-files += simpleImage.*.unstrip linux.bin.ub
-1
arch/mips/boot/.gitignore
··· 5 5 zImage.tmp 6 6 calc_vmlinuz_load_addr 7 7 uImage 8 - *.dtb
+13 -20
arch/mips/boot/dts/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 - dts-dirs += brcm 3 - dts-dirs += cavium-octeon 4 - dts-dirs += img 5 - dts-dirs += ingenic 6 - dts-dirs += lantiq 7 - dts-dirs += mti 8 - dts-dirs += netlogic 9 - dts-dirs += ni 10 - dts-dirs += pic32 11 - dts-dirs += qca 12 - dts-dirs += ralink 13 - dts-dirs += xilfpga 2 + subdir-y += brcm 3 + subdir-y += cavium-octeon 4 + subdir-y += img 5 + subdir-y += ingenic 6 + subdir-y += lantiq 7 + subdir-y += mti 8 + subdir-y += netlogic 9 + subdir-y += ni 10 + subdir-y += pic32 11 + subdir-y += qca 12 + subdir-y += ralink 13 + subdir-y += xilfpga 14 14 15 - obj-y := $(addsuffix /, $(dts-dirs)) 16 - 17 - dtstree := $(srctree)/$(src) 18 - dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(foreach d,$(dts-dirs), $(wildcard $(dtstree)/$(d)/*.dts))) 19 - 20 - always := $(dtb-y) 21 - subdir-y := $(dts-dirs) 22 - clean-files := *.dtb *.dtb.S 15 + obj-$(CONFIG_BUILTIN_DTB) := $(addsuffix /, $(subdir-y))
-4
arch/mips/boot/dts/brcm/Makefile
··· 23 23 bcm63268-comtrend-vr-3032u.dtb \ 24 24 bcm93384wvg.dtb \ 25 25 bcm93384wvg_viper.dtb \ 26 - bcm96358nb4ser.dtb \ 27 26 bcm96368mvwg.dtb \ 28 27 bcm9ejtagprb.dtb \ 29 28 bcm97125cbmb.dtb \ ··· 38 39 39 40 # Force kbuild to make empty built-in.o if necessary 40 41 obj- += dummy.o 41 - 42 - always := $(dtb-y) 43 - clean-files := *.dtb *.dtb.S
-3
arch/mips/boot/dts/cavium-octeon/Makefile
··· 5 5 6 6 # Force kbuild to make empty built-in.o if necessary 7 7 obj- += dummy.o 8 - 9 - always := $(dtb-y) 10 - clean-files := *.dtb *.dtb.S
-3
arch/mips/boot/dts/img/Makefile
··· 6 6 7 7 # Force kbuild to make empty built-in.o if necessary 8 8 obj- += dummy.o 9 - 10 - always := $(dtb-y) 11 - clean-files := *.dtb *.dtb.S
-3
arch/mips/boot/dts/ingenic/Makefile
··· 6 6 7 7 # Force kbuild to make empty built-in.o if necessary 8 8 obj- += dummy.o 9 - 10 - always := $(dtb-y) 11 - clean-files := *.dtb *.dtb.S
-3
arch/mips/boot/dts/lantiq/Makefile
··· 5 5 6 6 # Force kbuild to make empty built-in.o if necessary 7 7 obj- += dummy.o 8 - 9 - always := $(dtb-y) 10 - clean-files := *.dtb *.dtb.S
-3
arch/mips/boot/dts/mti/Makefile
··· 6 6 7 7 # Force kbuild to make empty built-in.o if necessary 8 8 obj- += dummy.o 9 - 10 - always := $(dtb-y) 11 - clean-files := *.dtb *.dtb.S
-3
arch/mips/boot/dts/netlogic/Makefile
··· 9 9 10 10 # Force kbuild to make empty built-in.o if necessary 11 11 obj- += dummy.o 12 - 13 - always := $(dtb-y) 14 - clean-files := *.dtb *.dtb.S
-3
arch/mips/boot/dts/ni/Makefile
··· 2 2 3 3 # Force kbuild to make empty built-in.o if necessary 4 4 obj- += dummy.o 5 - 6 - always := $(dtb-y) 7 - clean-files := *.dtb *.dtb.S
-3
arch/mips/boot/dts/pic32/Makefile
··· 8 8 9 9 # Force kbuild to make empty built-in.o if necessary 10 10 obj- += dummy.o 11 - 12 - always := $(dtb-y) 13 - clean-files := *.dtb *.dtb.S
-3
arch/mips/boot/dts/qca/Makefile
··· 8 8 9 9 # Force kbuild to make empty built-in.o if necessary 10 10 obj- += dummy.o 11 - 12 - always := $(dtb-y) 13 - clean-files := *.dtb *.dtb.S
-3
arch/mips/boot/dts/ralink/Makefile
··· 10 10 11 11 # Force kbuild to make empty built-in.o if necessary 12 12 obj- += dummy.o 13 - 14 - always := $(dtb-y) 15 - clean-files := *.dtb *.dtb.S
-3
arch/mips/boot/dts/xilfpga/Makefile
··· 5 5 6 6 # Force kbuild to make empty built-in.o if necessary 7 7 obj- += dummy.o 8 - 9 - always := $(dtb-y) 10 - clean-files := *.dtb *.dtb.S
-1
arch/nios2/boot/.gitignore
··· 1 - *.dtb 2 1 vmImage
-2
arch/nios2/boot/Makefile
··· 53 53 54 54 $(obj)/dtbs: $(addprefix $(obj)/, $(dtb-y)) 55 55 56 - clean-files := *.dtb 57 - 58 56 install: 59 57 sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
-2
arch/openrisc/boot/dts/Makefile
··· 6 6 endif 7 7 obj-y += $(BUILTIN_DTB) 8 8 9 - clean-files := *.dtb.S 10 - 11 9 #DTC_FLAGS ?= -p 1024
-1
arch/powerpc/boot/.gitignore
··· 18 18 uImage 19 19 cuImage.* 20 20 dtbImage.* 21 - *.dtb 22 21 treeImage.* 23 22 vmlinux.strip 24 23 zImage
+1 -1
arch/powerpc/boot/Makefile
··· 440 440 clean-files += $(image-) $(initrd-) cuImage.* dtbImage.* treeImage.* \ 441 441 zImage zImage.initrd zImage.chrp zImage.coff zImage.holly \ 442 442 zImage.miboot zImage.pmac zImage.pseries \ 443 - zImage.maple simpleImage.* otheros.bld *.dtb 443 + zImage.maple simpleImage.* otheros.bld 444 444 445 445 # clean up files cached by wrapper 446 446 clean-kernel-base := vmlinux.strip vmlinux.bin
+6 -18
arch/powerpc/platforms/pseries/dlpar.c
··· 75 75 return prop; 76 76 } 77 77 78 - static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa, 79 - const char *path) 78 + static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa) 80 79 { 81 80 struct device_node *dn; 82 - char *name; 83 - 84 - /* If parent node path is "/" advance path to NULL terminator to 85 - * prevent double leading slashs in full_name. 86 - */ 87 - if (!path[1]) 88 - path++; 81 + const char *name; 89 82 90 83 dn = kzalloc(sizeof(*dn), GFP_KERNEL); 91 84 if (!dn) 92 85 return NULL; 93 86 94 - name = (char *)ccwa + be32_to_cpu(ccwa->name_offset); 95 - dn->full_name = kasprintf(GFP_KERNEL, "%s/%s", path, name); 87 + name = (const char *)ccwa + be32_to_cpu(ccwa->name_offset); 88 + dn->full_name = kstrdup(name, GFP_KERNEL); 96 89 if (!dn->full_name) { 97 90 kfree(dn); 98 91 return NULL; ··· 141 148 struct property *last_property = NULL; 142 149 struct cc_workarea *ccwa; 143 150 char *data_buf; 144 - const char *parent_path = parent->full_name; 145 151 int cc_token; 146 152 int rc = -1; 147 153 ··· 174 182 break; 175 183 176 184 case NEXT_SIBLING: 177 - dn = dlpar_parse_cc_node(ccwa, parent_path); 185 + dn = dlpar_parse_cc_node(ccwa); 178 186 if (!dn) 179 187 goto cc_error; 180 188 ··· 184 192 break; 185 193 186 194 case NEXT_CHILD: 187 - if (first_dn) 188 - parent_path = last_dn->full_name; 189 - 190 - dn = dlpar_parse_cc_node(ccwa, parent_path); 195 + dn = dlpar_parse_cc_node(ccwa); 191 196 if (!dn) 192 197 goto cc_error; 193 198 ··· 215 226 216 227 case PREV_PARENT: 217 228 last_dn = last_dn->parent; 218 - parent_path = last_dn->parent->full_name; 219 229 break; 220 230 221 231 case CALL_AGAIN:
+1 -1
arch/powerpc/platforms/pseries/reconfig.c
··· 33 33 if (!np) 34 34 goto out_err; 35 35 36 - np->full_name = kstrdup(path, GFP_KERNEL); 36 + np->full_name = kstrdup(kbasename(path), GFP_KERNEL); 37 37 if (!np->full_name) 38 38 goto out_err; 39 39
-2
arch/sh/boot/dts/Makefile
··· 1 1 obj-$(CONFIG_USE_BUILTIN_DTB) += $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_SOURCE)).dtb.o 2 - 3 - clean-files := *.dtb.S
-1
arch/xtensa/boot/.gitignore
··· 1 1 uImage 2 2 zImage.redboot 3 - *.dtb
+3 -6
arch/xtensa/boot/dts/Makefile
··· 12 12 obj-$(CONFIG_OF) += $(BUILTIN_DTB) 13 13 endif 14 14 15 - dtstree := $(srctree)/$(src) 16 - dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts)) 17 - 18 - always += $(dtb-y) 19 - clean-files += *.dtb *.dtb.S 20 - 15 + # for CONFIG_OF_ALL_DTBS test 16 + dtstree := $(srctree)/$(src) 17 + dtb- := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
+1 -1
drivers/base/core.c
··· 1571 1571 int error; 1572 1572 1573 1573 if (of_node) { 1574 - error = sysfs_create_link(&dev->kobj, &of_node->kobj,"of_node"); 1574 + error = sysfs_create_link(&dev->kobj, of_node_kobj(of_node), "of_node"); 1575 1575 if (error) 1576 1576 dev_warn(dev, "Error %d creating of_node link\n",error); 1577 1577 /* An error here doesn't warrant bringing down the device */
+5 -9
drivers/gpu/drm/tilcdc/tilcdc_slave_compat.c
··· 145 145 __dtb_tilcdc_slave_compat_begin; 146 146 static void *overlay_data; 147 147 struct device_node *overlay; 148 - int ret; 149 148 150 149 if (!size) { 151 150 pr_warn("%s: No overlay data\n", __func__); ··· 163 164 } 164 165 165 166 of_node_set_flag(overlay, OF_DETACHED); 166 - ret = of_resolve_phandles(overlay); 167 - if (ret) { 168 - pr_err("%s: Failed to resolve phandles: %d\n", __func__, ret); 169 - return NULL; 170 - } 171 167 172 168 return overlay; 173 169 } ··· 198 204 /* For all memory needed for the overlay tree. This memory can 199 205 be freed after the overlay has been applied. */ 200 206 struct kfree_table kft; 201 - int ret; 207 + int ovcs_id, ret; 202 208 203 209 if (kfree_table_init(&kft)) 204 210 return; ··· 241 247 242 248 tilcdc_node_disable(slave); 243 249 244 - ret = of_overlay_create(overlay); 250 + ovcs_id = 0; 251 + ret = of_overlay_apply(overlay, &ovcs_id); 245 252 if (ret) 246 - pr_err("%s: Creating overlay failed: %d\n", __func__, ret); 253 + pr_err("%s: Applying overlay changeset failed: %d\n", 254 + __func__, ret); 247 255 else 248 256 pr_info("%s: ti,tilcdc,slave node successfully converted\n", 249 257 __func__);
+4
drivers/of/Kconfig
··· 46 46 config OF_PROMTREE 47 47 bool 48 48 49 + config OF_KOBJ 50 + def_bool SYSFS 51 + 49 52 # Hardly any platforms need this. It is safe to select, but only do so if you 50 53 # need it. 51 54 config OF_DYNAMIC 52 55 bool "Support for dynamic device trees" if OF_UNITTEST 56 + select OF_KOBJ 53 57 help 54 58 On some platforms, the device tree can be manipulated at runtime. 55 59 While this option is selected automatically on such platforms, you
+1
drivers/of/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 obj-y = base.o device.o platform.o property.o 3 + obj-$(CONFIG_OF_KOBJ) += kobj.o 3 4 obj-$(CONFIG_OF_DYNAMIC) += dynamic.o 4 5 obj-$(CONFIG_OF_FLATTREE) += fdt.o 5 6 obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o
+1 -134
drivers/of/base.c
··· 95 95 } 96 96 #endif 97 97 98 - #ifndef CONFIG_OF_DYNAMIC 99 - static void of_node_release(struct kobject *kobj) 100 - { 101 - /* Without CONFIG_OF_DYNAMIC, no nodes gets freed */ 102 - } 103 - #endif /* CONFIG_OF_DYNAMIC */ 104 - 105 - struct kobj_type of_node_ktype = { 106 - .release = of_node_release, 107 - }; 108 - 109 - static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj, 110 - struct bin_attribute *bin_attr, char *buf, 111 - loff_t offset, size_t count) 112 - { 113 - struct property *pp = container_of(bin_attr, struct property, attr); 114 - return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length); 115 - } 116 - 117 - /* always return newly allocated name, caller must free after use */ 118 - static const char *safe_name(struct kobject *kobj, const char *orig_name) 119 - { 120 - const char *name = orig_name; 121 - struct kernfs_node *kn; 122 - int i = 0; 123 - 124 - /* don't be a hero. After 16 tries give up */ 125 - while (i < 16 && (kn = sysfs_get_dirent(kobj->sd, name))) { 126 - sysfs_put(kn); 127 - if (name != orig_name) 128 - kfree(name); 129 - name = kasprintf(GFP_KERNEL, "%s#%i", orig_name, ++i); 130 - } 131 - 132 - if (name == orig_name) { 133 - name = kstrdup(orig_name, GFP_KERNEL); 134 - } else { 135 - pr_warn("Duplicate name in %s, renamed to \"%s\"\n", 136 - kobject_name(kobj), name); 137 - } 138 - return name; 139 - } 140 - 141 - int __of_add_property_sysfs(struct device_node *np, struct property *pp) 142 - { 143 - int rc; 144 - 145 - /* Important: Don't leak passwords */ 146 - bool secure = strncmp(pp->name, "security-", 9) == 0; 147 - 148 - if (!IS_ENABLED(CONFIG_SYSFS)) 149 - return 0; 150 - 151 - if (!of_kset || !of_node_is_attached(np)) 152 - return 0; 153 - 154 - sysfs_bin_attr_init(&pp->attr); 155 - pp->attr.attr.name = safe_name(&np->kobj, pp->name); 156 - pp->attr.attr.mode = secure ? 0400 : 0444; 157 - pp->attr.size = secure ? 0 : pp->length; 158 - pp->attr.read = of_node_property_read; 159 - 160 - rc = sysfs_create_bin_file(&np->kobj, &pp->attr); 161 - WARN(rc, "error adding attribute %s to node %pOF\n", pp->name, np); 162 - return rc; 163 - } 164 - 165 - int __of_attach_node_sysfs(struct device_node *np) 166 - { 167 - const char *name; 168 - struct kobject *parent; 169 - struct property *pp; 170 - int rc; 171 - 172 - if (!IS_ENABLED(CONFIG_SYSFS)) 173 - return 0; 174 - 175 - if (!of_kset) 176 - return 0; 177 - 178 - np->kobj.kset = of_kset; 179 - if (!np->parent) { 180 - /* Nodes without parents are new top level trees */ 181 - name = safe_name(&of_kset->kobj, "base"); 182 - parent = NULL; 183 - } else { 184 - name = safe_name(&np->parent->kobj, kbasename(np->full_name)); 185 - parent = &np->parent->kobj; 186 - } 187 - if (!name) 188 - return -ENOMEM; 189 - rc = kobject_add(&np->kobj, parent, "%s", name); 190 - kfree(name); 191 - if (rc) 192 - return rc; 193 - 194 - for_each_property_of_node(np, pp) 195 - __of_add_property_sysfs(np, pp); 196 - 197 - return 0; 198 - } 199 - 200 98 void __init of_core_init(void) 201 99 { 202 100 struct device_node *np; ··· 658 760 } 659 761 EXPORT_SYMBOL(of_get_child_by_name); 660 762 661 - static struct device_node *__of_find_node_by_path(struct device_node *parent, 763 + struct device_node *__of_find_node_by_path(struct device_node *parent, 662 764 const char *path) 663 765 { 664 766 struct device_node *child; ··· 1402 1504 return 0; 1403 1505 } 1404 1506 1405 - void __of_sysfs_remove_bin_file(struct device_node *np, struct property *prop) 1406 - { 1407 - sysfs_remove_bin_file(&np->kobj, &prop->attr); 1408 - kfree(prop->attr.attr.name); 1409 - } 1410 - 1411 - void __of_remove_property_sysfs(struct device_node *np, struct property *prop) 1412 - { 1413 - if (!IS_ENABLED(CONFIG_SYSFS)) 1414 - return; 1415 - 1416 - /* at early boot, bail here and defer setup to of_init() */ 1417 - if (of_kset && of_node_is_attached(np)) 1418 - __of_sysfs_remove_bin_file(np, prop); 1419 - } 1420 - 1421 1507 /** 1422 1508 * of_remove_property - Remove a property from a node. 1423 1509 * ··· 1459 1577 } 1460 1578 1461 1579 return 0; 1462 - } 1463 - 1464 - void __of_update_property_sysfs(struct device_node *np, struct property *newprop, 1465 - struct property *oldprop) 1466 - { 1467 - if (!IS_ENABLED(CONFIG_SYSFS)) 1468 - return; 1469 - 1470 - /* At early boot, bail out and defer setup to of_init() */ 1471 - if (!of_kset) 1472 - return; 1473 - 1474 - if (oldprop) 1475 - __of_sysfs_remove_bin_file(np, oldprop); 1476 - __of_add_property_sysfs(np, newprop); 1477 1580 } 1478 1581 1479 1582 /*
+135 -55
drivers/of/dynamic.c
··· 16 16 17 17 #include "of_private.h" 18 18 19 + static struct device_node *kobj_to_device_node(struct kobject *kobj) 20 + { 21 + return container_of(kobj, struct device_node, kobj); 22 + } 23 + 19 24 /** 20 25 * of_node_get() - Increment refcount of a node 21 26 * @node: Node to inc refcount, NULL is supported to simplify writing of ··· 47 42 kobject_put(&node->kobj); 48 43 } 49 44 EXPORT_SYMBOL(of_node_put); 50 - 51 - void __of_detach_node_sysfs(struct device_node *np) 52 - { 53 - struct property *pp; 54 - 55 - if (!IS_ENABLED(CONFIG_SYSFS)) 56 - return; 57 - 58 - BUG_ON(!of_node_is_initialized(np)); 59 - if (!of_kset) 60 - return; 61 - 62 - /* only remove properties if on sysfs */ 63 - if (of_node_is_attached(np)) { 64 - for_each_property_of_node(np, pp) 65 - __of_sysfs_remove_bin_file(np, pp); 66 - kobject_del(&np->kobj); 67 - } 68 - 69 - /* finally remove the kobj_init ref */ 70 - of_node_put(np); 71 - } 72 45 73 46 static BLOCKING_NOTIFIER_HEAD(of_reconfig_chain); 74 47 ··· 298 315 } 299 316 EXPORT_SYMBOL_GPL(of_detach_node); 300 317 318 + static void property_list_free(struct property *prop_list) 319 + { 320 + struct property *prop, *next; 321 + 322 + for (prop = prop_list; prop != NULL; prop = next) { 323 + next = prop->next; 324 + kfree(prop->name); 325 + kfree(prop->value); 326 + kfree(prop); 327 + } 328 + } 329 + 301 330 /** 302 331 * of_node_release() - release a dynamically allocated node 303 332 * @kref: kref element of the node to be released ··· 319 324 void of_node_release(struct kobject *kobj) 320 325 { 321 326 struct device_node *node = kobj_to_device_node(kobj); 322 - struct property *prop = node->properties; 323 327 324 328 /* We should never be releasing nodes that haven't been detached. */ 325 329 if (!of_node_check_flag(node, OF_DETACHED)) { ··· 329 335 if (!of_node_check_flag(node, OF_DYNAMIC)) 330 336 return; 331 337 332 - while (prop) { 333 - struct property *next = prop->next; 334 - kfree(prop->name); 335 - kfree(prop->value); 336 - kfree(prop); 337 - prop = next; 338 + property_list_free(node->properties); 339 + property_list_free(node->deadprops); 338 340 339 - if (!prop) { 340 - prop = node->deadprops; 341 - node->deadprops = NULL; 342 - } 343 - } 344 341 kfree(node->full_name); 345 342 kfree(node->data); 346 343 kfree(node); ··· 493 508 } 494 509 } 495 510 496 - static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool revert) 511 + static int __of_changeset_entry_notify(struct of_changeset_entry *ce, 512 + bool revert) 497 513 { 498 514 struct of_reconfig_data rd; 499 515 struct of_changeset_entry ce_inverted; 500 - int ret; 516 + int ret = 0; 501 517 502 518 if (revert) { 503 519 __of_changeset_entry_invert(ce, &ce_inverted); ··· 520 534 default: 521 535 pr_err("invalid devicetree changeset action: %i\n", 522 536 (int)ce->action); 523 - return; 537 + ret = -EINVAL; 524 538 } 525 539 526 540 if (ret) 527 541 pr_err("changeset notifier error @%pOF\n", ce->np); 542 + return ret; 528 543 } 529 544 530 545 static int __of_changeset_entry_apply(struct of_changeset_entry *ce) ··· 659 672 } 660 673 EXPORT_SYMBOL_GPL(of_changeset_destroy); 661 674 662 - int __of_changeset_apply(struct of_changeset *ocs) 675 + /* 676 + * Apply the changeset entries in @ocs. 677 + * If apply fails, an attempt is made to revert the entries that were 678 + * successfully applied. 679 + * 680 + * If multiple revert errors occur then only the final revert error is reported. 681 + * 682 + * Returns 0 on success, a negative error value in case of an error. 683 + * If a revert error occurs, it is returned in *ret_revert. 684 + */ 685 + int __of_changeset_apply_entries(struct of_changeset *ocs, int *ret_revert) 663 686 { 664 687 struct of_changeset_entry *ce; 665 - int ret; 688 + int ret, ret_tmp; 666 689 667 - /* perform the rest of the work */ 668 690 pr_debug("changeset: applying...\n"); 669 691 list_for_each_entry(ce, &ocs->entries, node) { 670 692 ret = __of_changeset_entry_apply(ce); 671 693 if (ret) { 672 694 pr_err("Error applying changeset (%d)\n", ret); 673 - list_for_each_entry_continue_reverse(ce, &ocs->entries, node) 674 - __of_changeset_entry_revert(ce); 695 + list_for_each_entry_continue_reverse(ce, &ocs->entries, 696 + node) { 697 + ret_tmp = __of_changeset_entry_revert(ce); 698 + if (ret_tmp) 699 + *ret_revert = ret_tmp; 700 + } 675 701 return ret; 676 702 } 677 703 } 678 - pr_debug("changeset: applied, emitting notifiers.\n"); 704 + 705 + return 0; 706 + } 707 + 708 + /* 709 + * Returns 0 on success, a negative error value in case of an error. 710 + * 711 + * If multiple changset entry notification errors occur then only the 712 + * final notification error is reported. 713 + */ 714 + int __of_changeset_apply_notify(struct of_changeset *ocs) 715 + { 716 + struct of_changeset_entry *ce; 717 + int ret = 0, ret_tmp; 718 + 719 + pr_debug("changeset: emitting notifiers.\n"); 679 720 680 721 /* drop the global lock while emitting notifiers */ 681 722 mutex_unlock(&of_mutex); 682 - list_for_each_entry(ce, &ocs->entries, node) 683 - __of_changeset_entry_notify(ce, 0); 723 + list_for_each_entry(ce, &ocs->entries, node) { 724 + ret_tmp = __of_changeset_entry_notify(ce, 0); 725 + if (ret_tmp) 726 + ret = ret_tmp; 727 + } 684 728 mutex_lock(&of_mutex); 685 729 pr_debug("changeset: notifiers sent.\n"); 686 730 687 - return 0; 731 + return ret; 732 + } 733 + 734 + /* 735 + * Returns 0 on success, a negative error value in case of an error. 736 + * 737 + * If a changeset entry apply fails, an attempt is made to revert any 738 + * previous entries in the changeset. If any of the reverts fails, 739 + * that failure is not reported. Thus the state of the device tree 740 + * is unknown if an apply error occurs. 741 + */ 742 + static int __of_changeset_apply(struct of_changeset *ocs) 743 + { 744 + int ret, ret_revert = 0; 745 + 746 + ret = __of_changeset_apply_entries(ocs, &ret_revert); 747 + if (!ret) 748 + ret = __of_changeset_apply_notify(ocs); 749 + 750 + return ret; 688 751 } 689 752 690 753 /** ··· 761 724 } 762 725 EXPORT_SYMBOL_GPL(of_changeset_apply); 763 726 764 - int __of_changeset_revert(struct of_changeset *ocs) 727 + /* 728 + * Revert the changeset entries in @ocs. 729 + * If revert fails, an attempt is made to re-apply the entries that were 730 + * successfully removed. 731 + * 732 + * If multiple re-apply errors occur then only the final apply error is 733 + * reported. 734 + * 735 + * Returns 0 on success, a negative error value in case of an error. 736 + * If an apply error occurs, it is returned in *ret_apply. 737 + */ 738 + int __of_changeset_revert_entries(struct of_changeset *ocs, int *ret_apply) 765 739 { 766 740 struct of_changeset_entry *ce; 767 - int ret; 741 + int ret, ret_tmp; 768 742 769 743 pr_debug("changeset: reverting...\n"); 770 744 list_for_each_entry_reverse(ce, &ocs->entries, node) { 771 745 ret = __of_changeset_entry_revert(ce); 772 746 if (ret) { 773 747 pr_err("Error reverting changeset (%d)\n", ret); 774 - list_for_each_entry_continue(ce, &ocs->entries, node) 775 - __of_changeset_entry_apply(ce); 748 + list_for_each_entry_continue(ce, &ocs->entries, node) { 749 + ret_tmp = __of_changeset_entry_apply(ce); 750 + if (ret_tmp) 751 + *ret_apply = ret_tmp; 752 + } 776 753 return ret; 777 754 } 778 755 } 779 - pr_debug("changeset: reverted, emitting notifiers.\n"); 756 + 757 + return 0; 758 + } 759 + 760 + /* 761 + * If multiple changset entry notification errors occur then only the 762 + * final notification error is reported. 763 + */ 764 + int __of_changeset_revert_notify(struct of_changeset *ocs) 765 + { 766 + struct of_changeset_entry *ce; 767 + int ret = 0, ret_tmp; 768 + 769 + pr_debug("changeset: emitting notifiers.\n"); 780 770 781 771 /* drop the global lock while emitting notifiers */ 782 772 mutex_unlock(&of_mutex); 783 - list_for_each_entry_reverse(ce, &ocs->entries, node) 784 - __of_changeset_entry_notify(ce, 1); 773 + list_for_each_entry_reverse(ce, &ocs->entries, node) { 774 + ret_tmp = __of_changeset_entry_notify(ce, 1); 775 + if (ret_tmp) 776 + ret = ret_tmp; 777 + } 785 778 mutex_lock(&of_mutex); 786 779 pr_debug("changeset: notifiers sent.\n"); 787 780 788 - return 0; 781 + return ret; 782 + } 783 + 784 + static int __of_changeset_revert(struct of_changeset *ocs) 785 + { 786 + int ret, ret_reply; 787 + 788 + ret_reply = 0; 789 + ret = __of_changeset_revert_entries(ocs, &ret_reply); 790 + 791 + if (!ret) 792 + ret = __of_changeset_revert_notify(ocs); 793 + 794 + return ret; 789 795 } 790 796 791 797 /** ··· 855 775 EXPORT_SYMBOL_GPL(of_changeset_revert); 856 776 857 777 /** 858 - * of_changeset_action - Perform a changeset action 778 + * of_changeset_action - Add an action to the tail of the changeset list 859 779 * 860 780 * @ocs: changeset pointer 861 781 * @action: action to perform
+30 -61
drivers/of/fdt.c
··· 132 132 return false; 133 133 } 134 134 135 + static bool of_fdt_device_is_available(const void *blob, unsigned long node) 136 + { 137 + const char *status = fdt_getprop(blob, node, "status", NULL); 138 + 139 + if (!status) 140 + return true; 141 + 142 + if (!strcmp(status, "ok") || !strcmp(status, "okay")) 143 + return true; 144 + 145 + return false; 146 + } 147 + 135 148 /** 136 149 * of_fdt_match - Return true if node matches a list of compatible values 137 150 */ ··· 279 266 *pprev = NULL; 280 267 } 281 268 282 - static unsigned int populate_node(const void *blob, 283 - int offset, 284 - void **mem, 285 - struct device_node *dad, 286 - unsigned int fpsize, 287 - struct device_node **pnp, 288 - bool dryrun) 269 + static bool populate_node(const void *blob, 270 + int offset, 271 + void **mem, 272 + struct device_node *dad, 273 + struct device_node **pnp, 274 + bool dryrun) 289 275 { 290 276 struct device_node *np; 291 277 const char *pathp; 292 278 unsigned int l, allocl; 293 - int new_format = 0; 294 279 295 280 pathp = fdt_get_name(blob, offset, &l); 296 281 if (!pathp) { 297 282 *pnp = NULL; 298 - return 0; 283 + return false; 299 284 } 300 285 301 286 allocl = ++l; 302 - 303 - /* version 0x10 has a more compact unit name here instead of the full 304 - * path. we accumulate the full path size using "fpsize", we'll rebuild 305 - * it later. We detect this because the first character of the name is 306 - * not '/'. 307 - */ 308 - if ((*pathp) != '/') { 309 - new_format = 1; 310 - if (fpsize == 0) { 311 - /* root node: special case. fpsize accounts for path 312 - * plus terminating zero. root node only has '/', so 313 - * fpsize should be 2, but we want to avoid the first 314 - * level nodes to have two '/' so we use fpsize 1 here 315 - */ 316 - fpsize = 1; 317 - allocl = 2; 318 - l = 1; 319 - pathp = ""; 320 - } else { 321 - /* account for '/' and path size minus terminal 0 322 - * already in 'l' 323 - */ 324 - fpsize += l; 325 - allocl = fpsize; 326 - } 327 - } 328 287 329 288 np = unflatten_dt_alloc(mem, sizeof(struct device_node) + allocl, 330 289 __alignof__(struct device_node)); ··· 304 319 char *fn; 305 320 of_node_init(np); 306 321 np->full_name = fn = ((char *)np) + sizeof(*np); 307 - if (new_format) { 308 - /* rebuild full path for new format */ 309 - if (dad && dad->parent) { 310 - strcpy(fn, dad->full_name); 311 - #ifdef DEBUG 312 - if ((strlen(fn) + l + 1) != allocl) { 313 - pr_debug("%s: p: %d, l: %d, a: %d\n", 314 - pathp, (int)strlen(fn), 315 - l, allocl); 316 - } 317 - #endif 318 - fn += strlen(fn); 319 - } 320 - *(fn++) = '/'; 321 - } 322 + 322 323 memcpy(fn, pathp, l); 323 324 324 325 if (dad != NULL) { ··· 326 355 } 327 356 328 357 *pnp = np; 329 - return fpsize; 358 + return true; 330 359 } 331 360 332 361 static void reverse_nodes(struct device_node *parent) ··· 370 399 struct device_node *root; 371 400 int offset = 0, depth = 0, initial_depth = 0; 372 401 #define FDT_MAX_DEPTH 64 373 - unsigned int fpsizes[FDT_MAX_DEPTH]; 374 402 struct device_node *nps[FDT_MAX_DEPTH]; 375 403 void *base = mem; 376 404 bool dryrun = !base; ··· 388 418 depth = initial_depth = 1; 389 419 390 420 root = dad; 391 - fpsizes[depth] = dad ? strlen(of_node_full_name(dad)) : 0; 392 421 nps[depth] = dad; 393 422 394 423 for (offset = 0; ··· 396 427 if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH)) 397 428 continue; 398 429 399 - fpsizes[depth+1] = populate_node(blob, offset, &mem, 400 - nps[depth], 401 - fpsizes[depth], 402 - &nps[depth+1], dryrun); 403 - if (!fpsizes[depth+1]) 430 + if (!IS_ENABLED(CONFIG_OF_KOBJ) && 431 + !of_fdt_device_is_available(blob, offset)) 432 + continue; 433 + 434 + if (!populate_node(blob, offset, &mem, nps[depth], 435 + &nps[depth+1], dryrun)) 404 436 return mem - base; 405 437 406 438 if (!dryrun && nodepp && !*nodepp) ··· 437 467 * @mynodes: The device_node tree created by the call 438 468 * @dt_alloc: An allocator that provides a virtual address to memory 439 469 * for the resulting tree 470 + * @detached: if true set OF_DETACHED on @mynodes 440 471 * 441 472 * Returns NULL on failure or the memory chunk containing the unflattened 442 473 * device tree on success. ··· 623 652 int depth, void *data) 624 653 { 625 654 static int found; 626 - const char *status; 627 655 int err; 628 656 629 657 if (!found && depth == 1 && strcmp(uname, "reserved-memory") == 0) { ··· 642 672 return 1; 643 673 } 644 674 645 - status = of_get_flat_dt_prop(node, "status", NULL); 646 - if (status && strcmp(status, "okay") != 0 && strcmp(status, "ok") != 0) 675 + if (!of_fdt_device_is_available(initial_boot_params, node)) 647 676 return 0; 648 677 649 678 err = __reserved_mem_reserve_reg(node, uname);
+164
drivers/of/kobj.c
··· 1 + #include <linux/of.h> 2 + #include <linux/slab.h> 3 + 4 + #include "of_private.h" 5 + 6 + /* true when node is initialized */ 7 + static int of_node_is_initialized(struct device_node *node) 8 + { 9 + return node && node->kobj.state_initialized; 10 + } 11 + 12 + /* true when node is attached (i.e. present on sysfs) */ 13 + int of_node_is_attached(struct device_node *node) 14 + { 15 + return node && node->kobj.state_in_sysfs; 16 + } 17 + 18 + 19 + #ifndef CONFIG_OF_DYNAMIC 20 + static void of_node_release(struct kobject *kobj) 21 + { 22 + /* Without CONFIG_OF_DYNAMIC, no nodes gets freed */ 23 + } 24 + #endif /* CONFIG_OF_DYNAMIC */ 25 + 26 + struct kobj_type of_node_ktype = { 27 + .release = of_node_release, 28 + }; 29 + 30 + static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj, 31 + struct bin_attribute *bin_attr, char *buf, 32 + loff_t offset, size_t count) 33 + { 34 + struct property *pp = container_of(bin_attr, struct property, attr); 35 + return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length); 36 + } 37 + 38 + /* always return newly allocated name, caller must free after use */ 39 + static const char *safe_name(struct kobject *kobj, const char *orig_name) 40 + { 41 + const char *name = orig_name; 42 + struct kernfs_node *kn; 43 + int i = 0; 44 + 45 + /* don't be a hero. After 16 tries give up */ 46 + while (i < 16 && (kn = sysfs_get_dirent(kobj->sd, name))) { 47 + sysfs_put(kn); 48 + if (name != orig_name) 49 + kfree(name); 50 + name = kasprintf(GFP_KERNEL, "%s#%i", orig_name, ++i); 51 + } 52 + 53 + if (name == orig_name) { 54 + name = kstrdup(orig_name, GFP_KERNEL); 55 + } else { 56 + pr_warn("Duplicate name in %s, renamed to \"%s\"\n", 57 + kobject_name(kobj), name); 58 + } 59 + return name; 60 + } 61 + 62 + int __of_add_property_sysfs(struct device_node *np, struct property *pp) 63 + { 64 + int rc; 65 + 66 + /* Important: Don't leak passwords */ 67 + bool secure = strncmp(pp->name, "security-", 9) == 0; 68 + 69 + if (!IS_ENABLED(CONFIG_SYSFS)) 70 + return 0; 71 + 72 + if (!of_kset || !of_node_is_attached(np)) 73 + return 0; 74 + 75 + sysfs_bin_attr_init(&pp->attr); 76 + pp->attr.attr.name = safe_name(&np->kobj, pp->name); 77 + pp->attr.attr.mode = secure ? 0400 : 0444; 78 + pp->attr.size = secure ? 0 : pp->length; 79 + pp->attr.read = of_node_property_read; 80 + 81 + rc = sysfs_create_bin_file(&np->kobj, &pp->attr); 82 + WARN(rc, "error adding attribute %s to node %pOF\n", pp->name, np); 83 + return rc; 84 + } 85 + 86 + void __of_sysfs_remove_bin_file(struct device_node *np, struct property *prop) 87 + { 88 + if (!IS_ENABLED(CONFIG_SYSFS)) 89 + return; 90 + 91 + sysfs_remove_bin_file(&np->kobj, &prop->attr); 92 + kfree(prop->attr.attr.name); 93 + } 94 + 95 + void __of_remove_property_sysfs(struct device_node *np, struct property *prop) 96 + { 97 + /* at early boot, bail here and defer setup to of_init() */ 98 + if (of_kset && of_node_is_attached(np)) 99 + __of_sysfs_remove_bin_file(np, prop); 100 + } 101 + 102 + void __of_update_property_sysfs(struct device_node *np, struct property *newprop, 103 + struct property *oldprop) 104 + { 105 + /* At early boot, bail out and defer setup to of_init() */ 106 + if (!of_kset) 107 + return; 108 + 109 + if (oldprop) 110 + __of_sysfs_remove_bin_file(np, oldprop); 111 + __of_add_property_sysfs(np, newprop); 112 + } 113 + 114 + int __of_attach_node_sysfs(struct device_node *np) 115 + { 116 + const char *name; 117 + struct kobject *parent; 118 + struct property *pp; 119 + int rc; 120 + 121 + if (!of_kset) 122 + return 0; 123 + 124 + np->kobj.kset = of_kset; 125 + if (!np->parent) { 126 + /* Nodes without parents are new top level trees */ 127 + name = safe_name(&of_kset->kobj, "base"); 128 + parent = NULL; 129 + } else { 130 + name = safe_name(&np->parent->kobj, kbasename(np->full_name)); 131 + parent = &np->parent->kobj; 132 + } 133 + if (!name) 134 + return -ENOMEM; 135 + rc = kobject_add(&np->kobj, parent, "%s", name); 136 + kfree(name); 137 + if (rc) 138 + return rc; 139 + 140 + for_each_property_of_node(np, pp) 141 + __of_add_property_sysfs(np, pp); 142 + 143 + return 0; 144 + } 145 + 146 + void __of_detach_node_sysfs(struct device_node *np) 147 + { 148 + struct property *pp; 149 + 150 + BUG_ON(!of_node_is_initialized(np)); 151 + if (!of_kset) 152 + return; 153 + 154 + /* only remove properties if on sysfs */ 155 + if (of_node_is_attached(np)) { 156 + for_each_property_of_node(np, pp) 157 + __of_sysfs_remove_bin_file(np, pp); 158 + kobject_del(&np->kobj); 159 + } 160 + 161 + /* finally remove the kobj_init ref */ 162 + of_node_put(np); 163 + } 164 +
+43 -8
drivers/of/of_private.h
··· 35 35 extern struct list_head aliases_lookup; 36 36 extern struct kset *of_kset; 37 37 38 - 39 - static inline struct device_node *kobj_to_device_node(struct kobject *kobj) 40 - { 41 - return container_of(kobj, struct device_node, kobj); 42 - } 43 - 44 38 #if defined(CONFIG_OF_DYNAMIC) 45 39 extern int of_property_notify(int action, struct device_node *np, 46 40 struct property *prop, struct property *old_prop); 47 41 extern void of_node_release(struct kobject *kobj); 48 - extern int __of_changeset_apply(struct of_changeset *ocs); 49 - extern int __of_changeset_revert(struct of_changeset *ocs); 42 + extern int __of_changeset_apply_entries(struct of_changeset *ocs, 43 + int *ret_revert); 44 + extern int __of_changeset_apply_notify(struct of_changeset *ocs); 45 + extern int __of_changeset_revert_entries(struct of_changeset *ocs, 46 + int *ret_apply); 47 + extern int __of_changeset_revert_notify(struct of_changeset *ocs); 50 48 #else /* CONFIG_OF_DYNAMIC */ 51 49 static inline int of_property_notify(int action, struct device_node *np, 52 50 struct property *prop, struct property *old_prop) ··· 52 54 return 0; 53 55 } 54 56 #endif /* CONFIG_OF_DYNAMIC */ 57 + 58 + #if defined(CONFIG_OF_KOBJ) 59 + int of_node_is_attached(struct device_node *node); 60 + int __of_add_property_sysfs(struct device_node *np, struct property *pp); 61 + void __of_remove_property_sysfs(struct device_node *np, struct property *prop); 62 + void __of_update_property_sysfs(struct device_node *np, struct property *newprop, 63 + struct property *oldprop); 64 + int __of_attach_node_sysfs(struct device_node *np); 65 + void __of_detach_node_sysfs(struct device_node *np); 66 + #else 67 + static inline int __of_add_property_sysfs(struct device_node *np, struct property *pp) 68 + { 69 + return 0; 70 + } 71 + static inline void __of_remove_property_sysfs(struct device_node *np, struct property *prop) {} 72 + static inline void __of_update_property_sysfs(struct device_node *np, 73 + struct property *newprop, struct property *oldprop) {} 74 + static inline int __of_attach_node_sysfs(struct device_node *np) 75 + { 76 + return 0; 77 + } 78 + static inline void __of_detach_node_sysfs(struct device_node *np) {} 79 + #endif 80 + 81 + #if defined(CONFIG_OF_RESOLVE) 82 + int of_resolve_phandles(struct device_node *tree); 83 + #endif 84 + 85 + #if defined(CONFIG_OF_OVERLAY) 86 + void of_overlay_mutex_lock(void); 87 + void of_overlay_mutex_unlock(void); 88 + #else 89 + static inline void of_overlay_mutex_lock(void) {}; 90 + static inline void of_overlay_mutex_unlock(void) {}; 91 + #endif 55 92 56 93 #if defined(CONFIG_OF_UNITTEST) && defined(CONFIG_OF_OVERLAY) 57 94 extern void __init unittest_unflatten_overlay_base(void); ··· 110 77 struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags); 111 78 __printf(2, 3) struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...); 112 79 80 + struct device_node *__of_find_node_by_path(struct device_node *parent, 81 + const char *path); 113 82 struct device_node *__of_find_node_by_full_path(struct device_node *node, 114 83 const char *path); 115 84
+676 -381
drivers/of/overlay.c
··· 25 25 #include "of_private.h" 26 26 27 27 /** 28 - * struct of_overlay_info - Holds a single overlay info 28 + * struct fragment - info about fragment nodes in overlay expanded device tree 29 29 * @target: target of the overlay operation 30 - * @overlay: pointer to the overlay contents node 31 - * 32 - * Holds a single overlay state, including all the overlay logs & 33 - * records. 30 + * @overlay: pointer to the __overlay__ node 34 31 */ 35 - struct of_overlay_info { 32 + struct fragment { 36 33 struct device_node *target; 37 34 struct device_node *overlay; 38 - bool is_symbols_node; 39 35 }; 40 36 41 37 /** 42 - * struct of_overlay - Holds a complete overlay transaction 43 - * @node: List on which we are located 44 - * @count: Count of ovinfo structures 45 - * @ovinfo_tab: Overlay info table (count sized) 46 - * @cset: Changeset to be used 47 - * 48 - * Holds a complete overlay transaction 38 + * struct overlay_changeset 39 + * @ovcs_list: list on which we are located 40 + * @overlay_tree: expanded device tree that contains the fragment nodes 41 + * @count: count of fragment structures 42 + * @fragments: fragment nodes in the overlay expanded device tree 43 + * @symbols_fragment: last element of @fragments[] is the __symbols__ node 44 + * @cset: changeset to apply fragments to live device tree 49 45 */ 50 - struct of_overlay { 46 + struct overlay_changeset { 51 47 int id; 52 - struct list_head node; 48 + struct list_head ovcs_list; 49 + struct device_node *overlay_tree; 53 50 int count; 54 - struct of_overlay_info *ovinfo_tab; 51 + struct fragment *fragments; 52 + bool symbols_fragment; 55 53 struct of_changeset cset; 56 54 }; 57 55 58 - static int of_overlay_apply_one(struct of_overlay *ov, 59 - struct device_node *target, const struct device_node *overlay, 60 - bool is_symbols_node); 56 + /* flags are sticky - once set, do not reset */ 57 + static int devicetree_state_flags; 58 + #define DTSF_APPLY_FAIL 0x01 59 + #define DTSF_REVERT_FAIL 0x02 61 60 62 - static BLOCKING_NOTIFIER_HEAD(of_overlay_chain); 61 + /* 62 + * If a changeset apply or revert encounters an error, an attempt will 63 + * be made to undo partial changes, but may fail. If the undo fails 64 + * we do not know the state of the devicetree. 65 + */ 66 + static int devicetree_corrupt(void) 67 + { 68 + return devicetree_state_flags & 69 + (DTSF_APPLY_FAIL | DTSF_REVERT_FAIL); 70 + } 71 + 72 + static int build_changeset_next_level(struct overlay_changeset *ovcs, 73 + struct device_node *target_node, 74 + const struct device_node *overlay_node); 75 + 76 + /* 77 + * of_resolve_phandles() finds the largest phandle in the live tree. 78 + * of_overlay_apply() may add a larger phandle to the live tree. 79 + * Do not allow race between two overlays being applied simultaneously: 80 + * mutex_lock(&of_overlay_phandle_mutex) 81 + * of_resolve_phandles() 82 + * of_overlay_apply() 83 + * mutex_unlock(&of_overlay_phandle_mutex) 84 + */ 85 + static DEFINE_MUTEX(of_overlay_phandle_mutex); 86 + 87 + void of_overlay_mutex_lock(void) 88 + { 89 + mutex_lock(&of_overlay_phandle_mutex); 90 + } 91 + 92 + void of_overlay_mutex_unlock(void) 93 + { 94 + mutex_unlock(&of_overlay_phandle_mutex); 95 + } 96 + 97 + 98 + static LIST_HEAD(ovcs_list); 99 + static DEFINE_IDR(ovcs_idr); 100 + 101 + static BLOCKING_NOTIFIER_HEAD(overlay_notify_chain); 63 102 64 103 int of_overlay_notifier_register(struct notifier_block *nb) 65 104 { 66 - return blocking_notifier_chain_register(&of_overlay_chain, nb); 105 + return blocking_notifier_chain_register(&overlay_notify_chain, nb); 67 106 } 68 107 EXPORT_SYMBOL_GPL(of_overlay_notifier_register); 69 108 70 109 int of_overlay_notifier_unregister(struct notifier_block *nb) 71 110 { 72 - return blocking_notifier_chain_unregister(&of_overlay_chain, nb); 111 + return blocking_notifier_chain_unregister(&overlay_notify_chain, nb); 73 112 } 74 113 EXPORT_SYMBOL_GPL(of_overlay_notifier_unregister); 75 114 76 - static int of_overlay_notify(struct of_overlay *ov, 77 - enum of_overlay_notify_action action) 115 + static char *of_overlay_action_name[] = { 116 + "pre-apply", 117 + "post-apply", 118 + "pre-remove", 119 + "post-remove", 120 + }; 121 + 122 + static int overlay_notify(struct overlay_changeset *ovcs, 123 + enum of_overlay_notify_action action) 78 124 { 79 125 struct of_overlay_notify_data nd; 80 126 int i, ret; 81 127 82 - for (i = 0; i < ov->count; i++) { 83 - struct of_overlay_info *ovinfo = &ov->ovinfo_tab[i]; 128 + for (i = 0; i < ovcs->count; i++) { 129 + struct fragment *fragment = &ovcs->fragments[i]; 84 130 85 - nd.target = ovinfo->target; 86 - nd.overlay = ovinfo->overlay; 131 + nd.target = fragment->target; 132 + nd.overlay = fragment->overlay; 87 133 88 - ret = blocking_notifier_call_chain(&of_overlay_chain, 134 + ret = blocking_notifier_call_chain(&overlay_notify_chain, 89 135 action, &nd); 90 - if (ret) 91 - return notifier_to_errno(ret); 136 + if (ret == NOTIFY_OK || ret == NOTIFY_STOP) 137 + return 0; 138 + if (ret) { 139 + ret = notifier_to_errno(ret); 140 + pr_err("overlay changeset %s notifier error %d, target: %pOF\n", 141 + of_overlay_action_name[action], ret, nd.target); 142 + return ret; 143 + } 92 144 } 93 145 94 146 return 0; 95 147 } 96 148 97 - static struct property *dup_and_fixup_symbol_prop(struct of_overlay *ov, 98 - const struct property *prop) 149 + /* 150 + * The values of properties in the "/__symbols__" node are paths in 151 + * the ovcs->overlay_tree. When duplicating the properties, the paths 152 + * need to be adjusted to be the correct path for the live device tree. 153 + * 154 + * The paths refer to a node in the subtree of a fragment node's "__overlay__" 155 + * node, for example "/fragment@0/__overlay__/symbol_path_tail", 156 + * where symbol_path_tail can be a single node or it may be a multi-node path. 157 + * 158 + * The duplicated property value will be modified by replacing the 159 + * "/fragment_name/__overlay/" portion of the value with the target 160 + * path from the fragment node. 161 + */ 162 + static struct property *dup_and_fixup_symbol_prop( 163 + struct overlay_changeset *ovcs, const struct property *prop) 99 164 { 100 - struct of_overlay_info *ovinfo; 101 - struct property *new; 102 - const char *overlay_name; 103 - char *label_path; 104 - char *symbol_path; 165 + struct fragment *fragment; 166 + struct property *new_prop; 167 + struct device_node *fragment_node; 168 + struct device_node *overlay_node; 169 + const char *path; 170 + const char *path_tail; 105 171 const char *target_path; 106 172 int k; 107 - int label_path_len; 108 173 int overlay_name_len; 174 + int path_len; 175 + int path_tail_len; 109 176 int target_path_len; 110 177 111 178 if (!prop->value) 112 179 return NULL; 113 - symbol_path = prop->value; 114 - 115 - new = kzalloc(sizeof(*new), GFP_KERNEL); 116 - if (!new) 180 + if (strnlen(prop->value, prop->length) >= prop->length) 117 181 return NULL; 182 + path = prop->value; 183 + path_len = strlen(path); 118 184 119 - for (k = 0; k < ov->count; k++) { 120 - ovinfo = &ov->ovinfo_tab[k]; 121 - overlay_name = ovinfo->overlay->full_name; 122 - overlay_name_len = strlen(overlay_name); 123 - if (!strncasecmp(symbol_path, overlay_name, overlay_name_len)) 185 + if (path_len < 1) 186 + return NULL; 187 + fragment_node = __of_find_node_by_path(ovcs->overlay_tree, path + 1); 188 + overlay_node = __of_find_node_by_path(fragment_node, "__overlay__/"); 189 + of_node_put(fragment_node); 190 + of_node_put(overlay_node); 191 + 192 + for (k = 0; k < ovcs->count; k++) { 193 + fragment = &ovcs->fragments[k]; 194 + if (fragment->overlay == overlay_node) 124 195 break; 125 196 } 197 + if (k >= ovcs->count) 198 + return NULL; 126 199 127 - if (k >= ov->count) 128 - goto err_free; 200 + overlay_name_len = snprintf(NULL, 0, "%pOF", fragment->overlay); 129 201 130 - target_path = ovinfo->target->full_name; 202 + if (overlay_name_len > path_len) 203 + return NULL; 204 + path_tail = path + overlay_name_len; 205 + path_tail_len = strlen(path_tail); 206 + 207 + target_path = kasprintf(GFP_KERNEL, "%pOF", fragment->target); 208 + if (!target_path) 209 + return NULL; 131 210 target_path_len = strlen(target_path); 132 211 133 - label_path = symbol_path + overlay_name_len; 134 - label_path_len = strlen(label_path); 212 + new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL); 213 + if (!new_prop) 214 + goto err_free_target_path; 135 215 136 - new->name = kstrdup(prop->name, GFP_KERNEL); 137 - new->length = target_path_len + label_path_len + 1; 138 - new->value = kzalloc(new->length, GFP_KERNEL); 216 + new_prop->name = kstrdup(prop->name, GFP_KERNEL); 217 + new_prop->length = target_path_len + path_tail_len + 1; 218 + new_prop->value = kzalloc(new_prop->length, GFP_KERNEL); 219 + if (!new_prop->name || !new_prop->value) 220 + goto err_free_new_prop; 139 221 140 - if (!new->name || !new->value) 141 - goto err_free; 222 + strcpy(new_prop->value, target_path); 223 + strcpy(new_prop->value + target_path_len, path_tail); 142 224 143 - strcpy(new->value, target_path); 144 - strcpy(new->value + target_path_len, label_path); 225 + of_property_set_flag(new_prop, OF_DYNAMIC); 145 226 146 - /* mark the property as dynamic */ 147 - of_property_set_flag(new, OF_DYNAMIC); 227 + return new_prop; 148 228 149 - return new; 229 + err_free_new_prop: 230 + kfree(new_prop->name); 231 + kfree(new_prop->value); 232 + kfree(new_prop); 233 + err_free_target_path: 234 + kfree(target_path); 150 235 151 - err_free: 152 - kfree(new->name); 153 - kfree(new->value); 154 - kfree(new); 155 236 return NULL; 156 - 157 - 158 237 } 159 238 160 - static int of_overlay_apply_single_property(struct of_overlay *ov, 161 - struct device_node *target, struct property *prop, 162 - bool is_symbols_node) 239 + /** 240 + * add_changeset_property() - add @overlay_prop to overlay changeset 241 + * @ovcs: overlay changeset 242 + * @target_node: where to place @overlay_prop in live tree 243 + * @overlay_prop: property to add or update, from overlay tree 244 + * @is_symbols_prop: 1 if @overlay_prop is from node "/__symbols__" 245 + * 246 + * If @overlay_prop does not already exist in @target_node, add changeset entry 247 + * to add @overlay_prop in @target_node, else add changeset entry to update 248 + * value of @overlay_prop. 249 + * 250 + * Some special properties are not updated (no error returned). 251 + * 252 + * Update of property in symbols node is not allowed. 253 + * 254 + * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if 255 + * invalid @overlay. 256 + */ 257 + static int add_changeset_property(struct overlay_changeset *ovcs, 258 + struct device_node *target_node, 259 + struct property *overlay_prop, 260 + bool is_symbols_prop) 163 261 { 164 - struct property *propn = NULL, *tprop; 262 + struct property *new_prop = NULL, *prop; 263 + int ret = 0; 165 264 166 - /* NOTE: Multiple changes of single properties not supported */ 167 - tprop = of_find_property(target, prop->name, NULL); 265 + prop = of_find_property(target_node, overlay_prop->name, NULL); 168 266 169 - /* special properties are not meant to be updated (silent NOP) */ 170 - if (of_prop_cmp(prop->name, "name") == 0 || 171 - of_prop_cmp(prop->name, "phandle") == 0 || 172 - of_prop_cmp(prop->name, "linux,phandle") == 0) 267 + if (!of_prop_cmp(overlay_prop->name, "name") || 268 + !of_prop_cmp(overlay_prop->name, "phandle") || 269 + !of_prop_cmp(overlay_prop->name, "linux,phandle")) 173 270 return 0; 174 271 175 - if (is_symbols_node) { 176 - /* changing a property in __symbols__ node not allowed */ 177 - if (tprop) 272 + if (is_symbols_prop) { 273 + if (prop) 178 274 return -EINVAL; 179 - propn = dup_and_fixup_symbol_prop(ov, prop); 275 + new_prop = dup_and_fixup_symbol_prop(ovcs, overlay_prop); 180 276 } else { 181 - propn = __of_prop_dup(prop, GFP_KERNEL); 277 + new_prop = __of_prop_dup(overlay_prop, GFP_KERNEL); 182 278 } 183 279 184 - if (propn == NULL) 280 + if (!new_prop) 185 281 return -ENOMEM; 186 282 187 - /* not found? add */ 188 - if (tprop == NULL) 189 - return of_changeset_add_property(&ov->cset, target, propn); 283 + if (!prop) 284 + ret = of_changeset_add_property(&ovcs->cset, target_node, 285 + new_prop); 286 + else 287 + ret = of_changeset_update_property(&ovcs->cset, target_node, 288 + new_prop); 190 289 191 - /* found? update */ 192 - return of_changeset_update_property(&ov->cset, target, propn); 290 + if (ret) { 291 + kfree(new_prop->name); 292 + kfree(new_prop->value); 293 + kfree(new_prop); 294 + } 295 + return ret; 193 296 } 194 297 195 - static int of_overlay_apply_single_device_node(struct of_overlay *ov, 196 - struct device_node *target, struct device_node *child) 298 + /** 299 + * add_changeset_node() - add @node (and children) to overlay changeset 300 + * @ovcs: overlay changeset 301 + * @target_node: where to place @node in live tree 302 + * @node: node from within overlay device tree fragment 303 + * 304 + * If @node does not already exist in @target_node, add changeset entry 305 + * to add @node in @target_node. 306 + * 307 + * If @node already exists in @target_node, and the existing node has 308 + * a phandle, the overlay node is not allowed to have a phandle. 309 + * 310 + * If @node has child nodes, add the children recursively via 311 + * build_changeset_next_level(). 312 + * 313 + * NOTE: Multiple mods of created nodes not supported. 314 + * If more than one fragment contains a node that does not already exist 315 + * in the live tree, then for each fragment of_changeset_attach_node() 316 + * will add a changeset entry to add the node. When the changeset is 317 + * applied, __of_attach_node() will attach the node twice (once for 318 + * each fragment). At this point the device tree will be corrupted. 319 + * 320 + * TODO: add integrity check to ensure that multiple fragments do not 321 + * create the same node. 322 + * 323 + * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if 324 + * invalid @overlay. 325 + */ 326 + static int add_changeset_node(struct overlay_changeset *ovcs, 327 + struct device_node *target_node, struct device_node *node) 197 328 { 198 - const char *cname; 329 + const char *node_kbasename; 199 330 struct device_node *tchild; 200 331 int ret = 0; 201 332 202 - cname = kbasename(child->full_name); 203 - if (cname == NULL) 204 - return -ENOMEM; 333 + node_kbasename = kbasename(node->full_name); 205 334 206 - /* NOTE: Multiple mods of created nodes not supported */ 207 - for_each_child_of_node(target, tchild) 208 - if (!of_node_cmp(cname, kbasename(tchild->full_name))) 335 + for_each_child_of_node(target_node, tchild) 336 + if (!of_node_cmp(node_kbasename, kbasename(tchild->full_name))) 209 337 break; 210 338 211 - if (tchild != NULL) { 212 - /* new overlay phandle value conflicts with existing value */ 213 - if (child->phandle) 214 - return -EINVAL; 215 - 216 - /* apply overlay recursively */ 217 - ret = of_overlay_apply_one(ov, tchild, child, 0); 218 - of_node_put(tchild); 219 - } else { 220 - /* create empty tree as a target */ 221 - tchild = __of_node_dup(child, "%pOF/%s", target, cname); 339 + if (!tchild) { 340 + tchild = __of_node_dup(node, "%pOF/%s", 341 + target_node, node_kbasename); 222 342 if (!tchild) 223 343 return -ENOMEM; 224 344 225 - /* point to parent */ 226 - tchild->parent = target; 345 + tchild->parent = target_node; 227 346 228 - ret = of_changeset_attach_node(&ov->cset, tchild); 347 + ret = of_changeset_attach_node(&ovcs->cset, tchild); 229 348 if (ret) 230 349 return ret; 231 350 232 - ret = of_overlay_apply_one(ov, tchild, child, 0); 233 - if (ret) 234 - return ret; 351 + return build_changeset_next_level(ovcs, tchild, node); 235 352 } 353 + 354 + if (node->phandle && tchild->phandle) 355 + ret = -EINVAL; 356 + else 357 + ret = build_changeset_next_level(ovcs, tchild, node); 358 + of_node_put(tchild); 236 359 237 360 return ret; 238 361 } 239 362 240 - /* 241 - * Apply a single overlay node recursively. 363 + /** 364 + * build_changeset_next_level() - add level of overlay changeset 365 + * @ovcs: overlay changeset 366 + * @target_node: where to place @overlay_node in live tree 367 + * @overlay_node: node from within an overlay device tree fragment 242 368 * 243 - * Note that the in case of an error the target node is left 244 - * in a inconsistent state. Error recovery should be performed 245 - * by using the changeset. 369 + * Add the properties (if any) and nodes (if any) from @overlay_node to the 370 + * @ovcs->cset changeset. If an added node has child nodes, they will 371 + * be added recursively. 372 + * 373 + * Do not allow symbols node to have any children. 374 + * 375 + * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if 376 + * invalid @overlay_node. 246 377 */ 247 - static int of_overlay_apply_one(struct of_overlay *ov, 248 - struct device_node *target, const struct device_node *overlay, 249 - bool is_symbols_node) 378 + static int build_changeset_next_level(struct overlay_changeset *ovcs, 379 + struct device_node *target_node, 380 + const struct device_node *overlay_node) 250 381 { 251 382 struct device_node *child; 252 383 struct property *prop; 253 384 int ret; 254 385 255 - for_each_property_of_node(overlay, prop) { 256 - ret = of_overlay_apply_single_property(ov, target, prop, 257 - is_symbols_node); 386 + for_each_property_of_node(overlay_node, prop) { 387 + ret = add_changeset_property(ovcs, target_node, prop, 0); 258 388 if (ret) { 259 - pr_err("Failed to apply prop @%pOF/%s\n", 260 - target, prop->name); 389 + pr_debug("Failed to apply prop @%pOF/%s, err=%d\n", 390 + target_node, prop->name, ret); 261 391 return ret; 262 392 } 263 393 } 264 394 265 - /* do not allow symbols node to have any children */ 266 - if (is_symbols_node) 267 - return 0; 268 - 269 - for_each_child_of_node(overlay, child) { 270 - ret = of_overlay_apply_single_device_node(ov, target, child); 271 - if (ret != 0) { 272 - pr_err("Failed to apply single node @%pOF/%s\n", 273 - target, child->name); 395 + for_each_child_of_node(overlay_node, child) { 396 + ret = add_changeset_node(ovcs, target_node, child); 397 + if (ret) { 398 + pr_debug("Failed to apply node @%pOF/%s, err=%d\n", 399 + target_node, child->name, ret); 274 400 of_node_put(child); 275 401 return ret; 276 402 } ··· 405 279 return 0; 406 280 } 407 281 408 - /** 409 - * of_overlay_apply() - Apply @count overlays pointed at by @ovinfo_tab 410 - * @ov: Overlay to apply 411 - * 412 - * Applies the overlays given, while handling all error conditions 413 - * appropriately. Either the operation succeeds, or if it fails the 414 - * live tree is reverted to the state before the attempt. 415 - * Returns 0, or an error if the overlay attempt failed. 282 + /* 283 + * Add the properties from __overlay__ node to the @ovcs->cset changeset. 416 284 */ 417 - static int of_overlay_apply(struct of_overlay *ov) 285 + static int build_changeset_symbols_node(struct overlay_changeset *ovcs, 286 + struct device_node *target_node, 287 + const struct device_node *overlay_symbols_node) 418 288 { 419 - int i, err; 289 + struct property *prop; 290 + int ret; 420 291 421 - /* first we apply the overlays atomically */ 422 - for (i = 0; i < ov->count; i++) { 423 - struct of_overlay_info *ovinfo = &ov->ovinfo_tab[i]; 292 + for_each_property_of_node(overlay_symbols_node, prop) { 293 + ret = add_changeset_property(ovcs, target_node, prop, 1); 294 + if (ret) { 295 + pr_debug("Failed to apply prop @%pOF/%s, err=%d\n", 296 + target_node, prop->name, ret); 297 + return ret; 298 + } 299 + } 424 300 425 - err = of_overlay_apply_one(ov, ovinfo->target, ovinfo->overlay, 426 - ovinfo->is_symbols_node); 427 - if (err != 0) { 428 - pr_err("apply failed '%pOF'\n", ovinfo->target); 429 - return err; 301 + return 0; 302 + } 303 + 304 + /** 305 + * build_changeset() - populate overlay changeset in @ovcs from @ovcs->fragments 306 + * @ovcs: Overlay changeset 307 + * 308 + * Create changeset @ovcs->cset to contain the nodes and properties of the 309 + * overlay device tree fragments in @ovcs->fragments[]. If an error occurs, 310 + * any portions of the changeset that were successfully created will remain 311 + * in @ovcs->cset. 312 + * 313 + * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if 314 + * invalid overlay in @ovcs->fragments[]. 315 + */ 316 + static int build_changeset(struct overlay_changeset *ovcs) 317 + { 318 + struct fragment *fragment; 319 + int fragments_count, i, ret; 320 + 321 + /* 322 + * if there is a symbols fragment in ovcs->fragments[i] it is 323 + * the final element in the array 324 + */ 325 + if (ovcs->symbols_fragment) 326 + fragments_count = ovcs->count - 1; 327 + else 328 + fragments_count = ovcs->count; 329 + 330 + for (i = 0; i < fragments_count; i++) { 331 + fragment = &ovcs->fragments[i]; 332 + 333 + ret = build_changeset_next_level(ovcs, fragment->target, 334 + fragment->overlay); 335 + if (ret) { 336 + pr_debug("apply failed '%pOF'\n", fragment->target); 337 + return ret; 338 + } 339 + } 340 + 341 + if (ovcs->symbols_fragment) { 342 + fragment = &ovcs->fragments[ovcs->count - 1]; 343 + ret = build_changeset_symbols_node(ovcs, fragment->target, 344 + fragment->overlay); 345 + if (ret) { 346 + pr_debug("apply failed '%pOF'\n", fragment->target); 347 + return ret; 430 348 } 431 349 } 432 350 ··· 479 309 480 310 /* 481 311 * Find the target node using a number of different strategies 482 - * in order of preference 312 + * in order of preference: 483 313 * 484 - * "target" property containing the phandle of the target 485 - * "target-path" property containing the path of the target 314 + * 1) "target" property containing the phandle of the target 315 + * 2) "target-path" property containing the path of the target 486 316 */ 487 317 static struct device_node *find_target_node(struct device_node *info_node) 488 318 { ··· 490 320 u32 val; 491 321 int ret; 492 322 493 - /* first try to go by using the target as a phandle */ 494 323 ret = of_property_read_u32(info_node, "target", &val); 495 - if (ret == 0) 324 + if (!ret) 496 325 return of_find_node_by_phandle(val); 497 326 498 - /* now try to locate by path */ 499 327 ret = of_property_read_string(info_node, "target-path", &path); 500 - if (ret == 0) 328 + if (!ret) 501 329 return of_find_node_by_path(path); 502 330 503 331 pr_err("Failed to find target for node %p (%s)\n", ··· 505 337 } 506 338 507 339 /** 508 - * of_fill_overlay_info() - Fill an overlay info structure 509 - * @ov Overlay to fill 510 - * @info_node: Device node containing the overlay 511 - * @ovinfo: Pointer to the overlay info structure to fill 340 + * init_overlay_changeset() - initialize overlay changeset from overlay tree 341 + * @ovcs Overlay changeset to build 342 + * @tree: Contains all the overlay fragments and overlay fixup nodes 512 343 * 513 - * Fills an overlay info structure with the overlay information 514 - * from a device node. This device node must have a target property 515 - * which contains a phandle of the overlay target node, and an 516 - * __overlay__ child node which has the overlay contents. 517 - * Both ovinfo->target & ovinfo->overlay have their references taken. 344 + * Initialize @ovcs. Populate @ovcs->fragments with node information from 345 + * the top level of @tree. The relevant top level nodes are the fragment 346 + * nodes and the __symbols__ node. Any other top level node will be ignored. 518 347 * 519 - * Returns 0 on success, or a negative error value. 348 + * Returns 0 on success, -ENOMEM if memory allocation failure, -EINVAL if error 349 + * detected in @tree, or -ENOSPC if idr_alloc() error. 520 350 */ 521 - static int of_fill_overlay_info(struct of_overlay *ov, 522 - struct device_node *info_node, struct of_overlay_info *ovinfo) 523 - { 524 - ovinfo->overlay = of_get_child_by_name(info_node, "__overlay__"); 525 - if (ovinfo->overlay == NULL) 526 - goto err_fail; 527 - 528 - ovinfo->target = find_target_node(info_node); 529 - if (ovinfo->target == NULL) 530 - goto err_fail; 531 - 532 - return 0; 533 - 534 - err_fail: 535 - of_node_put(ovinfo->target); 536 - of_node_put(ovinfo->overlay); 537 - 538 - memset(ovinfo, 0, sizeof(*ovinfo)); 539 - return -EINVAL; 540 - } 541 - 542 - /** 543 - * of_build_overlay_info() - Build an overlay info array 544 - * @ov Overlay to build 545 - * @tree: Device node containing all the overlays 546 - * 547 - * Helper function that given a tree containing overlay information, 548 - * allocates and builds an overlay info array containing it, ready 549 - * for use using of_overlay_apply. 550 - * 551 - * Returns 0 on success with the @cntp @ovinfop pointers valid, 552 - * while on error a negative error value is returned. 553 - */ 554 - static int of_build_overlay_info(struct of_overlay *ov, 351 + static int init_overlay_changeset(struct overlay_changeset *ovcs, 555 352 struct device_node *tree) 556 353 { 557 - struct device_node *node; 558 - struct of_overlay_info *ovinfo; 559 - int cnt, err; 354 + struct device_node *node, *overlay_node; 355 + struct fragment *fragment; 356 + struct fragment *fragments; 357 + int cnt, ret; 560 358 561 - /* worst case; every child is a node */ 359 + /* 360 + * Warn for some issues. Can not return -EINVAL for these until 361 + * of_unittest_apply_overlay() is fixed to pass these checks. 362 + */ 363 + if (!of_node_check_flag(tree, OF_DYNAMIC)) 364 + pr_debug("%s() tree is not dynamic\n", __func__); 365 + 366 + if (!of_node_check_flag(tree, OF_DETACHED)) 367 + pr_debug("%s() tree is not detached\n", __func__); 368 + 369 + if (!of_node_is_root(tree)) 370 + pr_debug("%s() tree is not root\n", __func__); 371 + 372 + ovcs->overlay_tree = tree; 373 + 374 + INIT_LIST_HEAD(&ovcs->ovcs_list); 375 + 376 + of_changeset_init(&ovcs->cset); 377 + 378 + ovcs->id = idr_alloc(&ovcs_idr, ovcs, 1, 0, GFP_KERNEL); 379 + if (ovcs->id <= 0) 380 + return ovcs->id; 381 + 562 382 cnt = 0; 563 - for_each_child_of_node(tree, node) 564 - cnt++; 565 383 566 - if (of_get_child_by_name(tree, "__symbols__")) 567 - cnt++; 568 - 569 - ovinfo = kcalloc(cnt, sizeof(*ovinfo), GFP_KERNEL); 570 - if (ovinfo == NULL) 571 - return -ENOMEM; 572 - 573 - cnt = 0; 384 + /* fragment nodes */ 574 385 for_each_child_of_node(tree, node) { 575 - err = of_fill_overlay_info(ov, node, &ovinfo[cnt]); 576 - if (err == 0) 386 + overlay_node = of_get_child_by_name(node, "__overlay__"); 387 + if (overlay_node) { 577 388 cnt++; 389 + of_node_put(overlay_node); 390 + } 578 391 } 579 392 580 393 node = of_get_child_by_name(tree, "__symbols__"); 581 394 if (node) { 582 - ovinfo[cnt].overlay = node; 583 - ovinfo[cnt].target = of_find_node_by_path("/__symbols__"); 584 - ovinfo[cnt].is_symbols_node = 1; 395 + cnt++; 396 + of_node_put(node); 397 + } 585 398 586 - if (!ovinfo[cnt].target) { 587 - pr_err("no symbols in root of device tree.\n"); 588 - return -EINVAL; 399 + fragments = kcalloc(cnt, sizeof(*fragments), GFP_KERNEL); 400 + if (!fragments) { 401 + ret = -ENOMEM; 402 + goto err_free_idr; 403 + } 404 + 405 + cnt = 0; 406 + for_each_child_of_node(tree, node) { 407 + fragment = &fragments[cnt]; 408 + fragment->overlay = of_get_child_by_name(node, "__overlay__"); 409 + if (fragment->overlay) { 410 + fragment->target = find_target_node(node); 411 + if (!fragment->target) { 412 + of_node_put(fragment->overlay); 413 + ret = -EINVAL; 414 + goto err_free_fragments; 415 + } else { 416 + cnt++; 417 + } 418 + } 419 + } 420 + 421 + /* 422 + * if there is a symbols fragment in ovcs->fragments[i] it is 423 + * the final element in the array 424 + */ 425 + node = of_get_child_by_name(tree, "__symbols__"); 426 + if (node) { 427 + ovcs->symbols_fragment = 1; 428 + fragment = &fragments[cnt]; 429 + fragment->overlay = node; 430 + fragment->target = of_find_node_by_path("/__symbols__"); 431 + 432 + if (!fragment->target) { 433 + pr_err("symbols in overlay, but not in live tree\n"); 434 + ret = -EINVAL; 435 + goto err_free_fragments; 589 436 } 590 437 591 438 cnt++; 592 439 } 593 440 594 - /* if nothing filled, return error */ 595 - if (cnt == 0) { 596 - kfree(ovinfo); 597 - return -ENODEV; 441 + if (!cnt) { 442 + ret = -EINVAL; 443 + goto err_free_fragments; 598 444 } 599 445 600 - ov->count = cnt; 601 - ov->ovinfo_tab = ovinfo; 446 + ovcs->count = cnt; 447 + ovcs->fragments = fragments; 602 448 603 449 return 0; 450 + 451 + err_free_fragments: 452 + kfree(fragments); 453 + err_free_idr: 454 + idr_remove(&ovcs_idr, ovcs->id); 455 + 456 + pr_err("%s() failed, ret = %d\n", __func__, ret); 457 + 458 + return ret; 604 459 } 605 460 606 - /** 607 - * of_free_overlay_info() - Free an overlay info array 608 - * @ov Overlay to free the overlay info from 609 - * @ovinfo_tab: Array of overlay_info's to free 610 - * 611 - * Releases the memory of a previously allocated ovinfo array 612 - * by of_build_overlay_info. 613 - * Returns 0, or an error if the arguments are bogus. 614 - */ 615 - static int of_free_overlay_info(struct of_overlay *ov) 461 + static void free_overlay_changeset(struct overlay_changeset *ovcs) 616 462 { 617 - struct of_overlay_info *ovinfo; 618 463 int i; 619 464 620 - /* do it in reverse */ 621 - for (i = ov->count - 1; i >= 0; i--) { 622 - ovinfo = &ov->ovinfo_tab[i]; 465 + if (!ovcs->cset.entries.next) 466 + return; 467 + of_changeset_destroy(&ovcs->cset); 623 468 624 - of_node_put(ovinfo->target); 625 - of_node_put(ovinfo->overlay); 469 + if (ovcs->id) 470 + idr_remove(&ovcs_idr, ovcs->id); 471 + 472 + for (i = 0; i < ovcs->count; i++) { 473 + of_node_put(ovcs->fragments[i].target); 474 + of_node_put(ovcs->fragments[i].overlay); 626 475 } 627 - kfree(ov->ovinfo_tab); 476 + kfree(ovcs->fragments); 628 477 629 - return 0; 478 + kfree(ovcs); 630 479 } 631 480 632 - static LIST_HEAD(ov_list); 633 - static DEFINE_IDR(ov_idr); 634 - 635 481 /** 636 - * of_overlay_create() - Create and apply an overlay 637 - * @tree: Device node containing all the overlays 482 + * of_overlay_apply() - Create and apply an overlay changeset 483 + * @tree: Expanded overlay device tree 484 + * @ovcs_id: Pointer to overlay changeset id 638 485 * 639 - * Creates and applies an overlay while also keeping track 640 - * of the overlay in a list. This list can be used to prevent 641 - * illegal overlay removals. 486 + * Creates and applies an overlay changeset. 642 487 * 643 - * Returns the id of the created overlay, or a negative error number 488 + * If an error occurs in a pre-apply notifier, then no changes are made 489 + * to the device tree. 490 + * 491 + 492 + * A non-zero return value will not have created the changeset if error is from: 493 + * - parameter checks 494 + * - building the changeset 495 + * - overlay changset pre-apply notifier 496 + * 497 + * If an error is returned by an overlay changeset pre-apply notifier 498 + * then no further overlay changeset pre-apply notifier will be called. 499 + * 500 + * A non-zero return value will have created the changeset if error is from: 501 + * - overlay changeset entry notifier 502 + * - overlay changset post-apply notifier 503 + * 504 + * If an error is returned by an overlay changeset post-apply notifier 505 + * then no further overlay changeset post-apply notifier will be called. 506 + * 507 + * If more than one notifier returns an error, then the last notifier 508 + * error to occur is returned. 509 + * 510 + * If an error occurred while applying the overlay changeset, then an 511 + * attempt is made to revert any changes that were made to the 512 + * device tree. If there were any errors during the revert attempt 513 + * then the state of the device tree can not be determined, and any 514 + * following attempt to apply or remove an overlay changeset will be 515 + * refused. 516 + * 517 + * Returns 0 on success, or a negative error number. Overlay changeset 518 + * id is returned to *ovcs_id. 644 519 */ 645 - int of_overlay_create(struct device_node *tree) 520 + 521 + int of_overlay_apply(struct device_node *tree, int *ovcs_id) 646 522 { 647 - struct of_overlay *ov; 648 - int err, id; 523 + struct overlay_changeset *ovcs; 524 + int ret = 0, ret_revert, ret_tmp; 649 525 650 - /* allocate the overlay structure */ 651 - ov = kzalloc(sizeof(*ov), GFP_KERNEL); 652 - if (ov == NULL) 653 - return -ENOMEM; 654 - ov->id = -1; 526 + *ovcs_id = 0; 655 527 656 - INIT_LIST_HEAD(&ov->node); 528 + if (devicetree_corrupt()) { 529 + pr_err("devicetree state suspect, refuse to apply overlay\n"); 530 + ret = -EBUSY; 531 + goto out; 532 + } 657 533 658 - of_changeset_init(&ov->cset); 534 + ovcs = kzalloc(sizeof(*ovcs), GFP_KERNEL); 535 + if (!ovcs) { 536 + ret = -ENOMEM; 537 + goto out; 538 + } 539 + 540 + of_overlay_mutex_lock(); 541 + 542 + ret = of_resolve_phandles(tree); 543 + if (ret) 544 + goto err_overlay_unlock; 659 545 660 546 mutex_lock(&of_mutex); 661 547 662 - id = idr_alloc(&ov_idr, ov, 0, 0, GFP_KERNEL); 663 - if (id < 0) { 664 - err = id; 665 - goto err_destroy_trans; 666 - } 667 - ov->id = id; 548 + ret = init_overlay_changeset(ovcs, tree); 549 + if (ret) 550 + goto err_free_overlay_changeset; 668 551 669 - /* build the overlay info structures */ 670 - err = of_build_overlay_info(ov, tree); 671 - if (err) { 672 - pr_err("of_build_overlay_info() failed for tree@%pOF\n", 673 - tree); 674 - goto err_free_idr; 552 + ret = overlay_notify(ovcs, OF_OVERLAY_PRE_APPLY); 553 + if (ret) { 554 + pr_err("overlay changeset pre-apply notify error %d\n", ret); 555 + goto err_free_overlay_changeset; 675 556 } 676 557 677 - err = of_overlay_notify(ov, OF_OVERLAY_PRE_APPLY); 678 - if (err < 0) { 679 - pr_err("%s: Pre-apply notifier failed (err=%d)\n", 680 - __func__, err); 681 - goto err_free_idr; 558 + ret = build_changeset(ovcs); 559 + if (ret) 560 + goto err_free_overlay_changeset; 561 + 562 + ret_revert = 0; 563 + ret = __of_changeset_apply_entries(&ovcs->cset, &ret_revert); 564 + if (ret) { 565 + if (ret_revert) { 566 + pr_debug("overlay changeset revert error %d\n", 567 + ret_revert); 568 + devicetree_state_flags |= DTSF_APPLY_FAIL; 569 + } 570 + goto err_free_overlay_changeset; 571 + } else { 572 + ret = __of_changeset_apply_notify(&ovcs->cset); 573 + if (ret) 574 + pr_err("overlay changeset entry notify error %d\n", 575 + ret); 576 + /* fall through */ 682 577 } 683 578 684 - /* apply the overlay */ 685 - err = of_overlay_apply(ov); 686 - if (err) 687 - goto err_abort_trans; 579 + list_add_tail(&ovcs->ovcs_list, &ovcs_list); 580 + *ovcs_id = ovcs->id; 688 581 689 - /* apply the changeset */ 690 - err = __of_changeset_apply(&ov->cset); 691 - if (err) 692 - goto err_revert_overlay; 582 + ret_tmp = overlay_notify(ovcs, OF_OVERLAY_POST_APPLY); 583 + if (ret_tmp) { 584 + pr_err("overlay changeset post-apply notify error %d\n", 585 + ret_tmp); 586 + if (!ret) 587 + ret = ret_tmp; 588 + } 693 589 590 + mutex_unlock(&of_mutex); 591 + of_overlay_mutex_unlock(); 694 592 695 - /* add to the tail of the overlay list */ 696 - list_add_tail(&ov->node, &ov_list); 593 + goto out; 697 594 698 - of_overlay_notify(ov, OF_OVERLAY_POST_APPLY); 595 + err_overlay_unlock: 596 + of_overlay_mutex_unlock(); 597 + 598 + err_free_overlay_changeset: 599 + free_overlay_changeset(ovcs); 699 600 700 601 mutex_unlock(&of_mutex); 701 602 702 - return id; 603 + out: 604 + pr_debug("%s() err=%d\n", __func__, ret); 703 605 704 - err_revert_overlay: 705 - err_abort_trans: 706 - of_free_overlay_info(ov); 707 - err_free_idr: 708 - idr_remove(&ov_idr, ov->id); 709 - err_destroy_trans: 710 - of_changeset_destroy(&ov->cset); 711 - kfree(ov); 712 - mutex_unlock(&of_mutex); 713 - 714 - return err; 606 + return ret; 715 607 } 716 - EXPORT_SYMBOL_GPL(of_overlay_create); 608 + EXPORT_SYMBOL_GPL(of_overlay_apply); 717 609 718 - /* check whether the given node, lies under the given tree */ 719 - static int overlay_subtree_check(struct device_node *tree, 720 - struct device_node *dn) 610 + /* 611 + * Find @np in @tree. 612 + * 613 + * Returns 1 if @np is @tree or is contained in @tree, else 0 614 + */ 615 + static int find_node(struct device_node *tree, struct device_node *np) 721 616 { 722 617 struct device_node *child; 723 618 724 - /* match? */ 725 - if (tree == dn) 619 + if (tree == np) 726 620 return 1; 727 621 728 622 for_each_child_of_node(tree, child) { 729 - if (overlay_subtree_check(child, dn)) { 623 + if (find_node(child, np)) { 730 624 of_node_put(child); 731 625 return 1; 732 626 } ··· 797 567 return 0; 798 568 } 799 569 800 - /* check whether this overlay is the topmost */ 801 - static int overlay_is_topmost(struct of_overlay *ov, struct device_node *dn) 570 + /* 571 + * Is @remove_ce_node a child of, a parent of, or the same as any 572 + * node in an overlay changeset more topmost than @remove_ovcs? 573 + * 574 + * Returns 1 if found, else 0 575 + */ 576 + static int node_overlaps_later_cs(struct overlay_changeset *remove_ovcs, 577 + struct device_node *remove_ce_node) 802 578 { 803 - struct of_overlay *ovt; 579 + struct overlay_changeset *ovcs; 804 580 struct of_changeset_entry *ce; 805 581 806 - list_for_each_entry_reverse(ovt, &ov_list, node) { 807 - /* if we hit ourselves, we're done */ 808 - if (ovt == ov) 582 + list_for_each_entry_reverse(ovcs, &ovcs_list, ovcs_list) { 583 + if (ovcs == remove_ovcs) 809 584 break; 810 585 811 - /* check against each subtree affected by this overlay */ 812 - list_for_each_entry(ce, &ovt->cset.entries, node) { 813 - if (overlay_subtree_check(ce->np, dn)) { 814 - pr_err("%s: #%d clashes #%d @%pOF\n", 815 - __func__, ov->id, ovt->id, dn); 816 - return 0; 586 + list_for_each_entry(ce, &ovcs->cset.entries, node) { 587 + if (find_node(ce->np, remove_ce_node)) { 588 + pr_err("%s: #%d overlaps with #%d @%pOF\n", 589 + __func__, remove_ovcs->id, ovcs->id, 590 + remove_ce_node); 591 + return 1; 592 + } 593 + if (find_node(remove_ce_node, ce->np)) { 594 + pr_err("%s: #%d overlaps with #%d @%pOF\n", 595 + __func__, remove_ovcs->id, ovcs->id, 596 + remove_ce_node); 597 + return 1; 817 598 } 818 599 } 819 600 } 820 601 821 - /* overlay is topmost */ 822 - return 1; 602 + return 0; 823 603 } 824 604 825 605 /* ··· 842 602 * the one closest to the tail. If another overlay has affected this 843 603 * device node and is closest to the tail, then removal is not permited. 844 604 */ 845 - static int overlay_removal_is_ok(struct of_overlay *ov) 605 + static int overlay_removal_is_ok(struct overlay_changeset *remove_ovcs) 846 606 { 847 - struct of_changeset_entry *ce; 607 + struct of_changeset_entry *remove_ce; 848 608 849 - list_for_each_entry(ce, &ov->cset.entries, node) { 850 - if (!overlay_is_topmost(ov, ce->np)) { 851 - pr_err("overlay #%d is not topmost\n", ov->id); 609 + list_for_each_entry(remove_ce, &remove_ovcs->cset.entries, node) { 610 + if (node_overlaps_later_cs(remove_ovcs, remove_ce->np)) { 611 + pr_err("overlay #%d is not topmost\n", remove_ovcs->id); 852 612 return 0; 853 613 } 854 614 } ··· 857 617 } 858 618 859 619 /** 860 - * of_overlay_destroy() - Removes an overlay 861 - * @id: Overlay id number returned by a previous call to of_overlay_create 620 + * of_overlay_remove() - Revert and free an overlay changeset 621 + * @ovcs_id: Pointer to overlay changeset id 862 622 * 863 - * Removes an overlay if it is permissible. 623 + * Removes an overlay if it is permissible. @ovcs_id was previously returned 624 + * by of_overlay_apply(). 864 625 * 865 - * Returns 0 on success, or a negative error number 626 + * If an error occurred while attempting to revert the overlay changeset, 627 + * then an attempt is made to re-apply any changeset entry that was 628 + * reverted. If an error occurs on re-apply then the state of the device 629 + * tree can not be determined, and any following attempt to apply or remove 630 + * an overlay changeset will be refused. 631 + * 632 + * A non-zero return value will not revert the changeset if error is from: 633 + * - parameter checks 634 + * - overlay changset pre-remove notifier 635 + * - overlay changeset entry revert 636 + * 637 + * If an error is returned by an overlay changeset pre-remove notifier 638 + * then no further overlay changeset pre-remove notifier will be called. 639 + * 640 + * If more than one notifier returns an error, then the last notifier 641 + * error to occur is returned. 642 + * 643 + * A non-zero return value will revert the changeset if error is from: 644 + * - overlay changeset entry notifier 645 + * - overlay changset post-remove notifier 646 + * 647 + * If an error is returned by an overlay changeset post-remove notifier 648 + * then no further overlay changeset post-remove notifier will be called. 649 + * 650 + * Returns 0 on success, or a negative error number. *ovcs_id is set to 651 + * zero after reverting the changeset, even if a subsequent error occurs. 866 652 */ 867 - int of_overlay_destroy(int id) 653 + int of_overlay_remove(int *ovcs_id) 868 654 { 869 - struct of_overlay *ov; 870 - int err; 655 + struct overlay_changeset *ovcs; 656 + int ret, ret_apply, ret_tmp; 657 + 658 + ret = 0; 659 + 660 + if (devicetree_corrupt()) { 661 + pr_err("suspect devicetree state, refuse to remove overlay\n"); 662 + ret = -EBUSY; 663 + goto out; 664 + } 871 665 872 666 mutex_lock(&of_mutex); 873 667 874 - ov = idr_find(&ov_idr, id); 875 - if (ov == NULL) { 876 - err = -ENODEV; 877 - pr_err("destroy: Could not find overlay #%d\n", id); 878 - goto out; 668 + ovcs = idr_find(&ovcs_idr, *ovcs_id); 669 + if (!ovcs) { 670 + ret = -ENODEV; 671 + pr_err("remove: Could not find overlay #%d\n", *ovcs_id); 672 + goto out_unlock; 879 673 } 880 674 881 - /* check whether the overlay is safe to remove */ 882 - if (!overlay_removal_is_ok(ov)) { 883 - err = -EBUSY; 884 - goto out; 675 + if (!overlay_removal_is_ok(ovcs)) { 676 + ret = -EBUSY; 677 + goto out_unlock; 885 678 } 886 679 887 - of_overlay_notify(ov, OF_OVERLAY_PRE_REMOVE); 888 - list_del(&ov->node); 889 - __of_changeset_revert(&ov->cset); 890 - of_overlay_notify(ov, OF_OVERLAY_POST_REMOVE); 891 - of_free_overlay_info(ov); 892 - idr_remove(&ov_idr, id); 893 - of_changeset_destroy(&ov->cset); 894 - kfree(ov); 680 + ret = overlay_notify(ovcs, OF_OVERLAY_PRE_REMOVE); 681 + if (ret) { 682 + pr_err("overlay changeset pre-remove notify error %d\n", ret); 683 + goto out_unlock; 684 + } 895 685 896 - err = 0; 686 + list_del(&ovcs->ovcs_list); 897 687 898 - out: 688 + ret_apply = 0; 689 + ret = __of_changeset_revert_entries(&ovcs->cset, &ret_apply); 690 + if (ret) { 691 + if (ret_apply) 692 + devicetree_state_flags |= DTSF_REVERT_FAIL; 693 + goto out_unlock; 694 + } else { 695 + ret = __of_changeset_revert_notify(&ovcs->cset); 696 + if (ret) { 697 + pr_err("overlay changeset entry notify error %d\n", 698 + ret); 699 + /* fall through - changeset was reverted */ 700 + } 701 + } 702 + 703 + *ovcs_id = 0; 704 + 705 + ret_tmp = overlay_notify(ovcs, OF_OVERLAY_POST_REMOVE); 706 + if (ret_tmp) { 707 + pr_err("overlay changeset post-remove notify error %d\n", 708 + ret_tmp); 709 + if (!ret) 710 + ret = ret_tmp; 711 + } 712 + 713 + free_overlay_changeset(ovcs); 714 + 715 + out_unlock: 899 716 mutex_unlock(&of_mutex); 900 717 901 - return err; 718 + out: 719 + pr_debug("%s() err=%d\n", __func__, ret); 720 + 721 + return ret; 902 722 } 903 - EXPORT_SYMBOL_GPL(of_overlay_destroy); 723 + EXPORT_SYMBOL_GPL(of_overlay_remove); 904 724 905 725 /** 906 - * of_overlay_destroy_all() - Removes all overlays from the system 726 + * of_overlay_remove_all() - Reverts and frees all overlay changesets 907 727 * 908 728 * Removes all overlays from the system in the correct order. 909 729 * 910 730 * Returns 0 on success, or a negative error number 911 731 */ 912 - int of_overlay_destroy_all(void) 732 + int of_overlay_remove_all(void) 913 733 { 914 - struct of_overlay *ov, *ovn; 915 - 916 - mutex_lock(&of_mutex); 734 + struct overlay_changeset *ovcs, *ovcs_n; 735 + int ret; 917 736 918 737 /* the tail of list is guaranteed to be safe to remove */ 919 - list_for_each_entry_safe_reverse(ov, ovn, &ov_list, node) { 920 - list_del(&ov->node); 921 - __of_changeset_revert(&ov->cset); 922 - of_free_overlay_info(ov); 923 - idr_remove(&ov_idr, ov->id); 924 - kfree(ov); 738 + list_for_each_entry_safe_reverse(ovcs, ovcs_n, &ovcs_list, ovcs_list) { 739 + ret = of_overlay_remove(&ovcs->id); 740 + if (ret) 741 + return ret; 925 742 } 926 - 927 - mutex_unlock(&of_mutex); 928 743 929 744 return 0; 930 745 } 931 - EXPORT_SYMBOL_GPL(of_overlay_destroy_all); 746 + EXPORT_SYMBOL_GPL(of_overlay_remove_all);
+9 -6
drivers/of/resolver.c
··· 84 84 int offset, len; 85 85 int err = 0; 86 86 87 - value = kmalloc(prop_fixup->length, GFP_KERNEL); 87 + value = kmemdup(prop_fixup->value, prop_fixup->length, GFP_KERNEL); 88 88 if (!value) 89 89 return -ENOMEM; 90 - memcpy(value, prop_fixup->value, prop_fixup->length); 91 90 92 91 /* prop_fixup contains a list of tuples of path:property_name:offset */ 93 92 end = value + prop_fixup->length; ··· 164 165 struct property *prop_fix, *prop; 165 166 int err, i, count; 166 167 unsigned int off; 167 - phandle phandle; 168 168 169 169 if (!local_fixups) 170 170 return 0; ··· 193 195 if ((off + 4) > prop->length) 194 196 return -EINVAL; 195 197 196 - phandle = be32_to_cpu(*(__be32 *)(prop->value + off)); 197 - phandle += phandle_delta; 198 - *(__be32 *)(prop->value + off) = cpu_to_be32(phandle); 198 + be32_add_cpu(prop->value + off, phandle_delta); 199 199 } 200 200 } 201 201 ··· 271 275 err = -EINVAL; 272 276 goto out; 273 277 } 278 + 279 + #if 0 280 + Temporarily disable check so that old style overlay unittests 281 + do not fail when of_resolve_phandles() is moved into 282 + of_overlay_apply(). 283 + 274 284 if (!of_node_check_flag(overlay, OF_DETACHED)) { 275 285 pr_err("overlay not detached\n"); 276 286 err = -EINVAL; 277 287 goto out; 278 288 } 289 + #endif 279 290 280 291 phandle_delta = live_tree_max_phandle() + 1; 281 292 adjust_overlay_phandles(overlay, phandle_delta);
-2
drivers/of/unittest-data/.gitignore
··· 1 - testcases.dtb 2 - testcases.dtb.S
+47 -36
drivers/of/unittest.c
··· 994 994 pr_warn("%s: No tree to attach; not running tests\n", __func__); 995 995 return -ENODATA; 996 996 } 997 - of_node_set_flag(unittest_data_node, OF_DETACHED); 997 + 998 + /* 999 + * This lock normally encloses of_overlay_apply() as well as 1000 + * of_resolve_phandles(). 1001 + */ 1002 + of_overlay_mutex_lock(); 1003 + 998 1004 rc = of_resolve_phandles(unittest_data_node); 999 1005 if (rc) { 1000 1006 pr_err("%s: Failed to resolve phandles (rc=%i)\n", __func__, rc); 1007 + of_overlay_mutex_unlock(); 1001 1008 return -EINVAL; 1002 1009 } 1003 1010 ··· 1014 1007 __of_attach_node_sysfs(np); 1015 1008 of_aliases = of_find_node_by_path("/aliases"); 1016 1009 of_chosen = of_find_node_by_path("/chosen"); 1010 + of_overlay_mutex_unlock(); 1017 1011 return 0; 1018 1012 } 1019 1013 ··· 1027 1019 attach_node_and_children(np); 1028 1020 np = next; 1029 1021 } 1022 + 1023 + of_overlay_mutex_unlock(); 1024 + 1030 1025 return 0; 1031 1026 } 1032 1027 ··· 1230 1219 1231 1220 static void of_unittest_destroy_tracked_overlays(void) 1232 1221 { 1233 - int id, ret, defers; 1222 + int id, ret, defers, ovcs_id; 1234 1223 1235 1224 if (overlay_first_id < 0) 1236 1225 return; ··· 1243 1232 if (!(overlay_id_bits[BIT_WORD(id)] & BIT_MASK(id))) 1244 1233 continue; 1245 1234 1246 - ret = of_overlay_destroy(id + overlay_first_id); 1235 + ovcs_id = id + overlay_first_id; 1236 + ret = of_overlay_remove(&ovcs_id); 1247 1237 if (ret == -ENODEV) { 1248 1238 pr_warn("%s: no overlay to destroy for #%d\n", 1249 1239 __func__, id + overlay_first_id); ··· 1266 1254 int *overlay_id) 1267 1255 { 1268 1256 struct device_node *np = NULL; 1269 - int ret, id = -1; 1257 + int ret; 1270 1258 1271 1259 np = of_find_node_by_path(overlay_path(overlay_nr)); 1272 1260 if (np == NULL) { ··· 1276 1264 goto out; 1277 1265 } 1278 1266 1279 - ret = of_overlay_create(np); 1267 + *overlay_id = 0; 1268 + ret = of_overlay_apply(np, overlay_id); 1280 1269 if (ret < 0) { 1281 1270 unittest(0, "could not create overlay from \"%s\"\n", 1282 1271 overlay_path(overlay_nr)); 1283 1272 goto out; 1284 1273 } 1285 - id = ret; 1286 - of_unittest_track_overlay(id); 1274 + of_unittest_track_overlay(*overlay_id); 1287 1275 1288 1276 ret = 0; 1289 1277 1290 1278 out: 1291 1279 of_node_put(np); 1292 - 1293 - if (overlay_id) 1294 - *overlay_id = id; 1295 1280 1296 1281 return ret; 1297 1282 } ··· 1297 1288 static int of_unittest_apply_overlay_check(int overlay_nr, int unittest_nr, 1298 1289 int before, int after, enum overlay_type ovtype) 1299 1290 { 1300 - int ret; 1291 + int ret, ovcs_id; 1301 1292 1302 1293 /* unittest device must not be in before state */ 1303 1294 if (of_unittest_device_exists(unittest_nr, ovtype) != before) { ··· 1308 1299 return -EINVAL; 1309 1300 } 1310 1301 1311 - ret = of_unittest_apply_overlay(overlay_nr, unittest_nr, NULL); 1302 + ovcs_id = 0; 1303 + ret = of_unittest_apply_overlay(overlay_nr, unittest_nr, &ovcs_id); 1312 1304 if (ret != 0) { 1313 1305 /* of_unittest_apply_overlay already called unittest() */ 1314 1306 return ret; ··· 1332 1322 int unittest_nr, int before, int after, 1333 1323 enum overlay_type ovtype) 1334 1324 { 1335 - int ret, ov_id; 1325 + int ret, ovcs_id; 1336 1326 1337 1327 /* unittest device must be in before state */ 1338 1328 if (of_unittest_device_exists(unittest_nr, ovtype) != before) { ··· 1344 1334 } 1345 1335 1346 1336 /* apply the overlay */ 1347 - ret = of_unittest_apply_overlay(overlay_nr, unittest_nr, &ov_id); 1337 + ovcs_id = 0; 1338 + ret = of_unittest_apply_overlay(overlay_nr, unittest_nr, &ovcs_id); 1348 1339 if (ret != 0) { 1349 1340 /* of_unittest_apply_overlay already called unittest() */ 1350 1341 return ret; ··· 1360 1349 return -EINVAL; 1361 1350 } 1362 1351 1363 - ret = of_overlay_destroy(ov_id); 1352 + ret = of_overlay_remove(&ovcs_id); 1364 1353 if (ret != 0) { 1365 1354 unittest(0, "overlay @\"%s\" failed to be destroyed @\"%s\"\n", 1366 1355 overlay_path(overlay_nr), ··· 1462 1451 static void of_unittest_overlay_6(void) 1463 1452 { 1464 1453 struct device_node *np; 1465 - int ret, i, ov_id[2]; 1454 + int ret, i, ov_id[2], ovcs_id; 1466 1455 int overlay_nr = 6, unittest_nr = 6; 1467 1456 int before = 0, after = 1; 1468 1457 ··· 1489 1478 return; 1490 1479 } 1491 1480 1492 - ret = of_overlay_create(np); 1481 + ovcs_id = 0; 1482 + ret = of_overlay_apply(np, &ovcs_id); 1493 1483 if (ret < 0) { 1494 1484 unittest(0, "could not create overlay from \"%s\"\n", 1495 1485 overlay_path(overlay_nr + i)); 1496 1486 return; 1497 1487 } 1498 - ov_id[i] = ret; 1488 + ov_id[i] = ovcs_id; 1499 1489 of_unittest_track_overlay(ov_id[i]); 1500 1490 } 1501 1491 ··· 1514 1502 } 1515 1503 1516 1504 for (i = 1; i >= 0; i--) { 1517 - ret = of_overlay_destroy(ov_id[i]); 1505 + ovcs_id = ov_id[i]; 1506 + ret = of_overlay_remove(&ovcs_id); 1518 1507 if (ret != 0) { 1519 1508 unittest(0, "overlay @\"%s\" failed destroy @\"%s\"\n", 1520 1509 overlay_path(overlay_nr + i), ··· 1546 1533 static void of_unittest_overlay_8(void) 1547 1534 { 1548 1535 struct device_node *np; 1549 - int ret, i, ov_id[2]; 1536 + int ret, i, ov_id[2], ovcs_id; 1550 1537 int overlay_nr = 8, unittest_nr = 8; 1551 1538 1552 1539 /* we don't care about device state in this test */ ··· 1561 1548 return; 1562 1549 } 1563 1550 1564 - ret = of_overlay_create(np); 1551 + ovcs_id = 0; 1552 + ret = of_overlay_apply(np, &ovcs_id); 1565 1553 if (ret < 0) { 1566 1554 unittest(0, "could not create overlay from \"%s\"\n", 1567 1555 overlay_path(overlay_nr + i)); 1568 1556 return; 1569 1557 } 1570 - ov_id[i] = ret; 1558 + ov_id[i] = ovcs_id; 1571 1559 of_unittest_track_overlay(ov_id[i]); 1572 1560 } 1573 1561 1574 1562 /* now try to remove first overlay (it should fail) */ 1575 - ret = of_overlay_destroy(ov_id[0]); 1563 + ovcs_id = ov_id[0]; 1564 + ret = of_overlay_remove(&ovcs_id); 1576 1565 if (ret == 0) { 1577 1566 unittest(0, "overlay @\"%s\" was destroyed @\"%s\"\n", 1578 1567 overlay_path(overlay_nr + 0), ··· 1585 1570 1586 1571 /* removing them in order should work */ 1587 1572 for (i = 1; i >= 0; i--) { 1588 - ret = of_overlay_destroy(ov_id[i]); 1573 + ovcs_id = ov_id[i]; 1574 + ret = of_overlay_remove(&ovcs_id); 1589 1575 if (ret != 0) { 1590 1576 unittest(0, "overlay @\"%s\" not destroyed @\"%s\"\n", 1591 1577 overlay_path(overlay_nr + i), ··· 2160 2144 ret = 0; 2161 2145 goto out_free_data; 2162 2146 } 2163 - of_node_set_flag(info->np_overlay, OF_DETACHED); 2164 2147 2165 - ret = of_resolve_phandles(info->np_overlay); 2166 - if (ret) { 2167 - pr_err("resolve ot phandles (ret=%d), %d\n", ret, onum); 2168 - goto out_free_np_overlay; 2169 - } 2170 - 2171 - ret = of_overlay_create(info->np_overlay); 2148 + info->overlay_id = 0; 2149 + ret = of_overlay_apply(info->np_overlay, &info->overlay_id); 2172 2150 if (ret < 0) { 2173 - pr_err("of_overlay_create() (ret=%d), %d\n", ret, onum); 2151 + pr_err("of_overlay_apply() (ret=%d), %d\n", ret, onum); 2152 + of_overlay_mutex_unlock(); 2174 2153 goto out_free_np_overlay; 2175 - } else { 2176 - info->overlay_id = ret; 2177 - ret = 0; 2178 2154 } 2179 2155 2180 2156 pr_debug("__dtb_overlay_begin applied, overlay id %d\n", ret); ··· 2215 2207 * Could not fixup phandles in unittest_unflatten_overlay_base() 2216 2208 * because kmalloc() was not yet available. 2217 2209 */ 2210 + of_overlay_mutex_lock(); 2218 2211 of_resolve_phandles(overlay_base_root); 2212 + of_overlay_mutex_unlock(); 2213 + 2219 2214 2220 2215 /* 2221 2216 * do not allow overlay_base to duplicate any node already in
+24 -21
include/linux/of.h
··· 37 37 int length; 38 38 void *value; 39 39 struct property *next; 40 + #if defined(CONFIG_OF_DYNAMIC) || defined(CONFIG_SPARC) 40 41 unsigned long _flags; 42 + #endif 43 + #if defined(CONFIG_OF_PROMTREE) 41 44 unsigned int unique_id; 45 + #endif 46 + #if defined(CONFIG_OF_KOBJ) 42 47 struct bin_attribute attr; 48 + #endif 43 49 }; 44 50 45 51 #if defined(CONFIG_SPARC) ··· 64 58 struct device_node *parent; 65 59 struct device_node *child; 66 60 struct device_node *sibling; 61 + #if defined(CONFIG_OF_KOBJ) 67 62 struct kobject kobj; 63 + #endif 68 64 unsigned long _flags; 69 65 void *data; 70 66 #if defined(CONFIG_SPARC) ··· 111 103 extern const struct fwnode_operations of_fwnode_ops; 112 104 static inline void of_node_init(struct device_node *node) 113 105 { 106 + #if defined(CONFIG_OF_KOBJ) 114 107 kobject_init(&node->kobj, &of_node_ktype); 108 + #endif 115 109 node->fwnode.ops = &of_fwnode_ops; 116 110 } 117 111 118 - /* true when node is initialized */ 119 - static inline int of_node_is_initialized(struct device_node *node) 120 - { 121 - return node && node->kobj.state_initialized; 122 - } 123 - 124 - /* true when node is attached (i.e. present on sysfs) */ 125 - static inline int of_node_is_attached(struct device_node *node) 126 - { 127 - return node && node->kobj.state_in_sysfs; 128 - } 112 + #if defined(CONFIG_OF_KOBJ) 113 + #define of_node_kobj(n) (&(n)->kobj) 114 + #else 115 + #define of_node_kobj(n) NULL 116 + #endif 129 117 130 118 #ifdef CONFIG_OF_DYNAMIC 131 119 extern struct device_node *of_node_get(struct device_node *node); ··· 207 203 clear_bit(flag, &n->_flags); 208 204 } 209 205 206 + #if defined(CONFIG_OF_DYNAMIC) || defined(CONFIG_SPARC) 210 207 static inline int of_property_check_flag(struct property *p, unsigned long flag) 211 208 { 212 209 return test_bit(flag, &p->_flags); ··· 222 217 { 223 218 clear_bit(flag, &p->_flags); 224 219 } 220 + #endif 225 221 226 222 extern struct device_node *__of_find_all_nodes(struct device_node *prev); 227 223 extern struct device_node *of_find_all_nodes(struct device_node *prev); ··· 1289 1283 } 1290 1284 #endif /* CONFIG_OF_DYNAMIC */ 1291 1285 1292 - /* CONFIG_OF_RESOLVE api */ 1293 - extern int of_resolve_phandles(struct device_node *tree); 1294 - 1295 1286 /** 1296 1287 * of_device_is_system_power_controller - Tells if system-power-controller is found for device_node 1297 1288 * @np: Pointer to the given device_node ··· 1305 1302 */ 1306 1303 1307 1304 enum of_overlay_notify_action { 1308 - OF_OVERLAY_PRE_APPLY, 1305 + OF_OVERLAY_PRE_APPLY = 0, 1309 1306 OF_OVERLAY_POST_APPLY, 1310 1307 OF_OVERLAY_PRE_REMOVE, 1311 1308 OF_OVERLAY_POST_REMOVE, ··· 1319 1316 #ifdef CONFIG_OF_OVERLAY 1320 1317 1321 1318 /* ID based overlays; the API for external users */ 1322 - int of_overlay_create(struct device_node *tree); 1323 - int of_overlay_destroy(int id); 1324 - int of_overlay_destroy_all(void); 1319 + int of_overlay_apply(struct device_node *tree, int *ovcs_id); 1320 + int of_overlay_remove(int *ovcs_id); 1321 + int of_overlay_remove_all(void); 1325 1322 1326 1323 int of_overlay_notifier_register(struct notifier_block *nb); 1327 1324 int of_overlay_notifier_unregister(struct notifier_block *nb); 1328 1325 1329 1326 #else 1330 1327 1331 - static inline int of_overlay_create(struct device_node *tree) 1328 + static inline int of_overlay_apply(struct device_node *tree, int *ovcs_id) 1332 1329 { 1333 1330 return -ENOTSUPP; 1334 1331 } 1335 1332 1336 - static inline int of_overlay_destroy(int id) 1333 + static inline int of_overlay_remove(int *ovcs_id) 1337 1334 { 1338 1335 return -ENOTSUPP; 1339 1336 } 1340 1337 1341 - static inline int of_overlay_destroy_all(void) 1338 + static inline int of_overlay_remove_all(void) 1342 1339 { 1343 1340 return -ENOTSUPP; 1344 1341 }
+2 -4
scripts/Makefile.dtbinst
··· 6 6 # INSTALL_DTBS_PATH directory or the default location: 7 7 # 8 8 # $INSTALL_PATH/dtbs/$KERNELRELEASE 9 - # 10 - # Traverse through subdirectories listed in $(dts-dirs). 11 9 # ========================================================================== 12 10 13 11 src := $(obj) ··· 19 21 include scripts/Kbuild.include 20 22 include $(src)/Makefile 21 23 22 - dtbinst-files := $(dtb-y) 23 - dtbinst-dirs := $(dts-dirs) 24 + dtbinst-files := $(sort $(dtb-y) $(if $(CONFIG_OF_ALL_DTBS), $(dtb-))) 25 + dtbinst-dirs := $(subdir-y) $(subdir-m) 24 26 25 27 # Helper targets for Installing DTBs into the boot directory 26 28 quiet_cmd_dtb_install = INSTALL $<
+5
scripts/Makefile.lib
··· 70 70 real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) $(extra-y) 71 71 real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))),$($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m)),$(m))) 72 72 73 + # DTB 74 + # If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built 75 + extra-y += $(dtb-y) 76 + extra-$(CONFIG_OF_ALL_DTBS) += $(dtb-) 77 + 73 78 # Add subdir path 74 79 75 80 extra-y := $(addprefix $(obj)/,$(extra-y))
+290 -1
scripts/dtc/checks.c
··· 873 873 while (size--) 874 874 reg = (reg << 32) | fdt32_to_cpu(*(cells++)); 875 875 876 - snprintf(unit_addr, sizeof(unit_addr), "%llx", (unsigned long long)reg); 876 + snprintf(unit_addr, sizeof(unit_addr), "%"PRIx64, reg); 877 877 if (!streq(unitname, unit_addr)) 878 878 FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"", 879 879 node->fullpath, unit_addr); ··· 956 956 WARNING(obsolete_chosen_interrupt_controller, 957 957 check_obsolete_chosen_interrupt_controller, NULL); 958 958 959 + struct provider { 960 + const char *prop_name; 961 + const char *cell_name; 962 + bool optional; 963 + }; 964 + 965 + static void check_property_phandle_args(struct check *c, 966 + struct dt_info *dti, 967 + struct node *node, 968 + struct property *prop, 969 + const struct provider *provider) 970 + { 971 + struct node *root = dti->dt; 972 + int cell, cellsize = 0; 973 + 974 + if (prop->val.len % sizeof(cell_t)) { 975 + FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s", 976 + prop->name, prop->val.len, sizeof(cell_t), node->fullpath); 977 + return; 978 + } 979 + 980 + for (cell = 0; cell < prop->val.len / sizeof(cell_t); cell += cellsize + 1) { 981 + struct node *provider_node; 982 + struct property *cellprop; 983 + int phandle; 984 + 985 + phandle = propval_cell_n(prop, cell); 986 + /* 987 + * Some bindings use a cell value 0 or -1 to skip over optional 988 + * entries when each index position has a specific definition. 989 + */ 990 + if (phandle == 0 || phandle == -1) { 991 + /* Give up if this is an overlay with external references */ 992 + if (dti->dtsflags & DTSF_PLUGIN) 993 + break; 994 + 995 + cellsize = 0; 996 + continue; 997 + } 998 + 999 + /* If we have markers, verify the current cell is a phandle */ 1000 + if (prop->val.markers) { 1001 + struct marker *m = prop->val.markers; 1002 + for_each_marker_of_type(m, REF_PHANDLE) { 1003 + if (m->offset == (cell * sizeof(cell_t))) 1004 + break; 1005 + } 1006 + if (!m) 1007 + FAIL(c, dti, "Property '%s', cell %d is not a phandle reference in %s", 1008 + prop->name, cell, node->fullpath); 1009 + } 1010 + 1011 + provider_node = get_node_by_phandle(root, phandle); 1012 + if (!provider_node) { 1013 + FAIL(c, dti, "Could not get phandle node for %s:%s(cell %d)", 1014 + node->fullpath, prop->name, cell); 1015 + break; 1016 + } 1017 + 1018 + cellprop = get_property(provider_node, provider->cell_name); 1019 + if (cellprop) { 1020 + cellsize = propval_cell(cellprop); 1021 + } else if (provider->optional) { 1022 + cellsize = 0; 1023 + } else { 1024 + FAIL(c, dti, "Missing property '%s' in node %s or bad phandle (referred from %s:%s[%d])", 1025 + provider->cell_name, 1026 + provider_node->fullpath, 1027 + node->fullpath, prop->name, cell); 1028 + break; 1029 + } 1030 + 1031 + if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) { 1032 + FAIL(c, dti, "%s property size (%d) too small for cell size %d in %s", 1033 + prop->name, prop->val.len, cellsize, node->fullpath); 1034 + } 1035 + } 1036 + } 1037 + 1038 + static void check_provider_cells_property(struct check *c, 1039 + struct dt_info *dti, 1040 + struct node *node) 1041 + { 1042 + struct provider *provider = c->data; 1043 + struct property *prop; 1044 + 1045 + prop = get_property(node, provider->prop_name); 1046 + if (!prop) 1047 + return; 1048 + 1049 + check_property_phandle_args(c, dti, node, prop, provider); 1050 + } 1051 + #define WARNING_PROPERTY_PHANDLE_CELLS(nm, propname, cells_name, ...) \ 1052 + static struct provider nm##_provider = { (propname), (cells_name), __VA_ARGS__ }; \ 1053 + WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &phandle_references); 1054 + 1055 + WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells"); 1056 + WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells"); 1057 + WARNING_PROPERTY_PHANDLE_CELLS(dmas, "dmas", "#dma-cells"); 1058 + WARNING_PROPERTY_PHANDLE_CELLS(hwlocks, "hwlocks", "#hwlock-cells"); 1059 + WARNING_PROPERTY_PHANDLE_CELLS(interrupts_extended, "interrupts-extended", "#interrupt-cells"); 1060 + WARNING_PROPERTY_PHANDLE_CELLS(io_channels, "io-channels", "#io-channel-cells"); 1061 + WARNING_PROPERTY_PHANDLE_CELLS(iommus, "iommus", "#iommu-cells"); 1062 + WARNING_PROPERTY_PHANDLE_CELLS(mboxes, "mboxes", "#mbox-cells"); 1063 + WARNING_PROPERTY_PHANDLE_CELLS(msi_parent, "msi-parent", "#msi-cells", true); 1064 + WARNING_PROPERTY_PHANDLE_CELLS(mux_controls, "mux-controls", "#mux-control-cells"); 1065 + WARNING_PROPERTY_PHANDLE_CELLS(phys, "phys", "#phy-cells"); 1066 + WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells"); 1067 + WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells"); 1068 + WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells"); 1069 + WARNING_PROPERTY_PHANDLE_CELLS(sound_dais, "sound-dais", "#sound-dai-cells"); 1070 + WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells"); 1071 + 1072 + static bool prop_is_gpio(struct property *prop) 1073 + { 1074 + char *str; 1075 + 1076 + /* 1077 + * *-gpios and *-gpio can appear in property names, 1078 + * so skip over any false matches (only one known ATM) 1079 + */ 1080 + if (strstr(prop->name, "nr-gpio")) 1081 + return false; 1082 + 1083 + str = strrchr(prop->name, '-'); 1084 + if (str) 1085 + str++; 1086 + else 1087 + str = prop->name; 1088 + if (!(streq(str, "gpios") || streq(str, "gpio"))) 1089 + return false; 1090 + 1091 + return true; 1092 + } 1093 + 1094 + static void check_gpios_property(struct check *c, 1095 + struct dt_info *dti, 1096 + struct node *node) 1097 + { 1098 + struct property *prop; 1099 + 1100 + /* Skip GPIO hog nodes which have 'gpios' property */ 1101 + if (get_property(node, "gpio-hog")) 1102 + return; 1103 + 1104 + for_each_property(node, prop) { 1105 + struct provider provider; 1106 + 1107 + if (!prop_is_gpio(prop)) 1108 + continue; 1109 + 1110 + provider.prop_name = prop->name; 1111 + provider.cell_name = "#gpio-cells"; 1112 + provider.optional = false; 1113 + check_property_phandle_args(c, dti, node, prop, &provider); 1114 + } 1115 + 1116 + } 1117 + WARNING(gpios_property, check_gpios_property, NULL, &phandle_references); 1118 + 1119 + static void check_deprecated_gpio_property(struct check *c, 1120 + struct dt_info *dti, 1121 + struct node *node) 1122 + { 1123 + struct property *prop; 1124 + 1125 + for_each_property(node, prop) { 1126 + char *str; 1127 + 1128 + if (!prop_is_gpio(prop)) 1129 + continue; 1130 + 1131 + str = strstr(prop->name, "gpio"); 1132 + if (!streq(str, "gpio")) 1133 + continue; 1134 + 1135 + FAIL(c, dti, "'[*-]gpio' is deprecated, use '[*-]gpios' instead for %s:%s", 1136 + node->fullpath, prop->name); 1137 + } 1138 + 1139 + } 1140 + CHECK(deprecated_gpio_property, check_deprecated_gpio_property, NULL); 1141 + 1142 + static bool node_is_interrupt_provider(struct node *node) 1143 + { 1144 + struct property *prop; 1145 + 1146 + prop = get_property(node, "interrupt-controller"); 1147 + if (prop) 1148 + return true; 1149 + 1150 + prop = get_property(node, "interrupt-map"); 1151 + if (prop) 1152 + return true; 1153 + 1154 + return false; 1155 + } 1156 + static void check_interrupts_property(struct check *c, 1157 + struct dt_info *dti, 1158 + struct node *node) 1159 + { 1160 + struct node *root = dti->dt; 1161 + struct node *irq_node = NULL, *parent = node; 1162 + struct property *irq_prop, *prop = NULL; 1163 + int irq_cells, phandle; 1164 + 1165 + irq_prop = get_property(node, "interrupts"); 1166 + if (!irq_prop) 1167 + return; 1168 + 1169 + if (irq_prop->val.len % sizeof(cell_t)) 1170 + FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s", 1171 + irq_prop->name, irq_prop->val.len, sizeof(cell_t), 1172 + node->fullpath); 1173 + 1174 + while (parent && !prop) { 1175 + if (parent != node && node_is_interrupt_provider(parent)) { 1176 + irq_node = parent; 1177 + break; 1178 + } 1179 + 1180 + prop = get_property(parent, "interrupt-parent"); 1181 + if (prop) { 1182 + phandle = propval_cell(prop); 1183 + /* Give up if this is an overlay with external references */ 1184 + if ((phandle == 0 || phandle == -1) && 1185 + (dti->dtsflags & DTSF_PLUGIN)) 1186 + return; 1187 + 1188 + irq_node = get_node_by_phandle(root, phandle); 1189 + if (!irq_node) { 1190 + FAIL(c, dti, "Bad interrupt-parent phandle for %s", 1191 + node->fullpath); 1192 + return; 1193 + } 1194 + if (!node_is_interrupt_provider(irq_node)) 1195 + FAIL(c, dti, 1196 + "Missing interrupt-controller or interrupt-map property in %s", 1197 + irq_node->fullpath); 1198 + 1199 + break; 1200 + } 1201 + 1202 + parent = parent->parent; 1203 + } 1204 + 1205 + if (!irq_node) { 1206 + FAIL(c, dti, "Missing interrupt-parent for %s", node->fullpath); 1207 + return; 1208 + } 1209 + 1210 + prop = get_property(irq_node, "#interrupt-cells"); 1211 + if (!prop) { 1212 + FAIL(c, dti, "Missing #interrupt-cells in interrupt-parent %s", 1213 + irq_node->fullpath); 1214 + return; 1215 + } 1216 + 1217 + irq_cells = propval_cell(prop); 1218 + if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) { 1219 + FAIL(c, dti, 1220 + "interrupts size is (%d), expected multiple of %d in %s", 1221 + irq_prop->val.len, (int)(irq_cells * sizeof(cell_t)), 1222 + node->fullpath); 1223 + } 1224 + } 1225 + WARNING(interrupts_property, check_interrupts_property, &phandle_references); 1226 + 959 1227 static struct check *check_table[] = { 960 1228 &duplicate_node_names, &duplicate_property_names, 961 1229 &node_name_chars, &node_name_format, &property_name_chars, ··· 1254 986 1255 987 &avoid_default_addr_size, 1256 988 &obsolete_chosen_interrupt_controller, 989 + 990 + &clocks_property, 991 + &cooling_device_property, 992 + &dmas_property, 993 + &hwlocks_property, 994 + &interrupts_extended_property, 995 + &io_channels_property, 996 + &iommus_property, 997 + &mboxes_property, 998 + &msi_parent_property, 999 + &mux_controls_property, 1000 + &phys_property, 1001 + &power_domains_property, 1002 + &pwms_property, 1003 + &resets_property, 1004 + &sound_dais_property, 1005 + &thermal_sensors_property, 1006 + 1007 + &deprecated_gpio_property, 1008 + &gpios_property, 1009 + &interrupts_property, 1257 1010 1258 1011 &always_fail, 1259 1012 };
+5 -5
scripts/dtc/dtc-lexer.lex.c_shipped
··· 1397 1397 { 1398 1398 char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; 1399 1399 char *source = (yytext_ptr); 1400 - yy_size_t number_to_move, i; 1400 + int number_to_move, i; 1401 1401 int ret_val; 1402 1402 1403 1403 if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) ··· 1426 1426 /* Try to read more data. */ 1427 1427 1428 1428 /* First move last chars to start of buffer. */ 1429 - number_to_move = (yy_size_t) ((yy_c_buf_p) - (yytext_ptr)) - 1; 1429 + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); 1430 1430 1431 1431 for ( i = 0; i < number_to_move; ++i ) 1432 1432 *(dest++) = *(source++); ··· 1508 1508 else 1509 1509 ret_val = EOB_ACT_CONTINUE_SCAN; 1510 1510 1511 - if ((int) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { 1511 + if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { 1512 1512 /* Extend the array by 50%, plus the number we really need. */ 1513 1513 int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); 1514 1514 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); ··· 1987 1987 YY_BUFFER_STATE b; 1988 1988 char *buf; 1989 1989 yy_size_t n; 1990 - yy_size_t i; 1990 + int i; 1991 1991 1992 1992 /* Get memory for full buffer, including space for trailing EOB's. */ 1993 - n = (yy_size_t) _yybytes_len + 2; 1993 + n = (yy_size_t) (_yybytes_len + 2); 1994 1994 buf = (char *) yyalloc(n ); 1995 1995 if ( ! buf ) 1996 1996 YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+261 -243
scripts/dtc/dtc-parser.tab.c_shipped
··· 448 448 /* YYNNTS -- Number of nonterminals. */ 449 449 #define YYNNTS 30 450 450 /* YYNRULES -- Number of rules. */ 451 - #define YYNRULES 84 451 + #define YYNRULES 85 452 452 /* YYNSTATES -- Number of states. */ 453 453 #define YYNSTATES 149 454 454 ··· 499 499 static const yytype_uint16 yyrline[] = 500 500 { 501 501 0, 109, 109, 117, 121, 128, 129, 139, 142, 149, 502 - 153, 161, 165, 170, 181, 191, 206, 214, 217, 224, 503 - 228, 232, 236, 244, 248, 252, 256, 260, 276, 286, 504 - 294, 297, 301, 308, 324, 329, 348, 362, 369, 370, 505 - 371, 378, 382, 383, 387, 388, 392, 393, 397, 398, 506 - 402, 403, 407, 408, 412, 413, 414, 418, 419, 420, 507 - 421, 422, 426, 427, 428, 432, 433, 434, 438, 439, 508 - 448, 457, 461, 462, 463, 464, 469, 472, 476, 484, 509 - 487, 491, 499, 503, 507 502 + 153, 161, 165, 170, 181, 200, 213, 220, 228, 231, 503 + 238, 242, 246, 250, 258, 262, 266, 270, 274, 290, 504 + 300, 308, 311, 315, 322, 338, 343, 362, 376, 383, 505 + 384, 385, 392, 396, 397, 401, 402, 406, 407, 411, 506 + 412, 416, 417, 421, 422, 426, 427, 428, 432, 433, 507 + 434, 435, 436, 440, 441, 442, 446, 447, 448, 452, 508 + 453, 462, 471, 475, 476, 477, 478, 483, 486, 490, 509 + 498, 501, 505, 513, 517, 521 510 510 }; 511 511 #endif 512 512 ··· 582 582 static const yytype_uint8 yydefact[] = 583 583 { 584 584 0, 0, 0, 5, 7, 3, 1, 6, 0, 0, 585 - 0, 7, 0, 38, 39, 0, 0, 10, 0, 2, 586 - 8, 4, 0, 0, 0, 72, 0, 41, 42, 44, 587 - 46, 48, 50, 52, 54, 57, 64, 67, 71, 0, 588 - 17, 11, 0, 0, 0, 0, 73, 74, 75, 40, 585 + 16, 7, 0, 39, 40, 0, 0, 10, 0, 2, 586 + 8, 4, 0, 0, 0, 73, 0, 42, 43, 45, 587 + 47, 49, 51, 53, 55, 58, 65, 68, 72, 0, 588 + 18, 11, 0, 0, 0, 0, 74, 75, 76, 41, 589 589 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 590 590 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 591 - 79, 0, 0, 14, 12, 45, 0, 47, 49, 51, 592 - 53, 55, 56, 60, 61, 59, 58, 62, 63, 65, 593 - 66, 69, 68, 70, 0, 0, 0, 0, 18, 0, 594 - 79, 15, 13, 0, 0, 0, 20, 30, 82, 22, 595 - 84, 0, 81, 80, 43, 21, 83, 0, 0, 16, 596 - 29, 19, 31, 0, 23, 32, 26, 0, 76, 34, 597 - 0, 0, 0, 0, 37, 36, 24, 35, 33, 0, 598 - 77, 78, 25, 0, 28, 0, 0, 0, 27 591 + 80, 0, 0, 14, 12, 46, 0, 48, 50, 52, 592 + 54, 56, 57, 61, 62, 60, 59, 63, 64, 66, 593 + 67, 70, 69, 71, 0, 0, 0, 0, 19, 0, 594 + 80, 15, 13, 0, 0, 0, 21, 31, 83, 23, 595 + 85, 0, 82, 81, 44, 22, 84, 0, 0, 17, 596 + 30, 20, 32, 0, 24, 33, 27, 0, 77, 35, 597 + 0, 0, 0, 0, 38, 37, 25, 36, 34, 0, 598 + 78, 79, 26, 0, 29, 0, 0, 0, 28 599 599 }; 600 600 601 601 /* YYPGOTO[NTERM-NUM]. */ ··· 678 678 static const yytype_uint8 yyr1[] = 679 679 { 680 680 0, 48, 49, 50, 50, 51, 51, 52, 52, 53, 681 - 53, 54, 54, 54, 54, 54, 55, 56, 56, 57, 682 - 57, 57, 57, 58, 58, 58, 58, 58, 58, 58, 683 - 59, 59, 59, 60, 60, 60, 60, 60, 61, 61, 684 - 61, 62, 63, 63, 64, 64, 65, 65, 66, 66, 685 - 67, 67, 68, 68, 69, 69, 69, 70, 70, 70, 686 - 70, 70, 71, 71, 71, 72, 72, 72, 73, 73, 687 - 73, 73, 74, 74, 74, 74, 75, 75, 75, 76, 688 - 76, 76, 77, 77, 77 681 + 53, 54, 54, 54, 54, 54, 54, 55, 56, 56, 682 + 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 683 + 58, 59, 59, 59, 60, 60, 60, 60, 60, 61, 684 + 61, 61, 62, 63, 63, 64, 64, 65, 65, 66, 685 + 66, 67, 67, 68, 68, 69, 69, 69, 70, 70, 686 + 70, 70, 70, 71, 71, 71, 72, 72, 72, 73, 687 + 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 688 + 76, 76, 76, 77, 77, 77 689 689 }; 690 690 691 691 /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ 692 692 static const yytype_uint8 yyr2[] = 693 693 { 694 694 0, 2, 3, 2, 4, 1, 2, 0, 2, 4, 695 - 2, 2, 3, 4, 3, 4, 5, 0, 2, 4, 696 - 2, 3, 2, 2, 3, 4, 2, 9, 5, 2, 697 - 0, 2, 2, 3, 1, 2, 2, 2, 1, 1, 698 - 3, 1, 1, 5, 1, 3, 1, 3, 1, 3, 699 - 1, 3, 1, 3, 1, 3, 3, 1, 3, 3, 700 - 3, 3, 3, 3, 1, 3, 3, 1, 3, 3, 701 - 3, 1, 1, 2, 2, 2, 0, 2, 2, 0, 702 - 2, 2, 2, 3, 2 695 + 2, 2, 3, 4, 3, 4, 0, 5, 0, 2, 696 + 4, 2, 3, 2, 2, 3, 4, 2, 9, 5, 697 + 2, 0, 2, 2, 3, 1, 2, 2, 2, 1, 698 + 1, 3, 1, 1, 5, 1, 3, 1, 3, 1, 699 + 3, 1, 3, 1, 3, 1, 3, 3, 1, 3, 700 + 3, 3, 3, 3, 3, 1, 3, 3, 1, 3, 701 + 3, 3, 1, 1, 2, 2, 2, 0, 2, 2, 702 + 0, 2, 2, 2, 3, 2 703 703 }; 704 704 705 705 ··· 1572 1572 { 1573 1573 struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); 1574 1574 1575 - if (target) 1575 + if (target) { 1576 1576 merge_nodes(target, (yyvsp[0].node)); 1577 - else 1578 - ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); 1577 + } else { 1578 + /* 1579 + * We rely on the rule being always: 1580 + * versioninfo plugindecl memreserves devicetree 1581 + * so $-1 is what we want (plugindecl) 1582 + */ 1583 + if ((yyvsp[(-1) - (3)].flags) & DTSF_PLUGIN) 1584 + add_orphan_node((yyvsp[-2].node), (yyvsp[0].node), (yyvsp[-1].labelref)); 1585 + else 1586 + ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); 1587 + } 1579 1588 (yyval.node) = (yyvsp[-2].node); 1580 1589 } 1581 - #line 1582 "dtc-parser.tab.c" /* yacc.c:1646 */ 1590 + #line 1591 "dtc-parser.tab.c" /* yacc.c:1646 */ 1582 1591 break; 1583 1592 1584 1593 case 15: 1585 - #line 192 "dtc-parser.y" /* yacc.c:1646 */ 1594 + #line 201 "dtc-parser.y" /* yacc.c:1646 */ 1586 1595 { 1587 1596 struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); 1588 1597 ··· 1603 1594 1604 1595 (yyval.node) = (yyvsp[-3].node); 1605 1596 } 1606 - #line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */ 1597 + #line 1607 "dtc-parser.tab.c" /* yacc.c:1646 */ 1607 1598 break; 1608 1599 1609 1600 case 16: 1610 - #line 207 "dtc-parser.y" /* yacc.c:1646 */ 1601 + #line 213 "dtc-parser.y" /* yacc.c:1646 */ 1611 1602 { 1612 - (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); 1603 + /* build empty node */ 1604 + (yyval.node) = name_node(build_node(NULL, NULL), ""); 1613 1605 } 1614 - #line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */ 1606 + #line 1616 "dtc-parser.tab.c" /* yacc.c:1646 */ 1615 1607 break; 1616 1608 1617 1609 case 17: 1618 - #line 214 "dtc-parser.y" /* yacc.c:1646 */ 1610 + #line 221 "dtc-parser.y" /* yacc.c:1646 */ 1619 1611 { 1620 - (yyval.proplist) = NULL; 1612 + (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); 1621 1613 } 1622 - #line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */ 1614 + #line 1624 "dtc-parser.tab.c" /* yacc.c:1646 */ 1623 1615 break; 1624 1616 1625 1617 case 18: 1626 - #line 218 "dtc-parser.y" /* yacc.c:1646 */ 1618 + #line 228 "dtc-parser.y" /* yacc.c:1646 */ 1627 1619 { 1628 - (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); 1620 + (yyval.proplist) = NULL; 1629 1621 } 1630 - #line 1622 "dtc-parser.tab.c" /* yacc.c:1646 */ 1622 + #line 1632 "dtc-parser.tab.c" /* yacc.c:1646 */ 1631 1623 break; 1632 1624 1633 1625 case 19: 1634 - #line 225 "dtc-parser.y" /* yacc.c:1646 */ 1626 + #line 232 "dtc-parser.y" /* yacc.c:1646 */ 1635 1627 { 1636 - (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); 1628 + (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); 1637 1629 } 1638 - #line 1630 "dtc-parser.tab.c" /* yacc.c:1646 */ 1630 + #line 1640 "dtc-parser.tab.c" /* yacc.c:1646 */ 1639 1631 break; 1640 1632 1641 1633 case 20: 1642 - #line 229 "dtc-parser.y" /* yacc.c:1646 */ 1634 + #line 239 "dtc-parser.y" /* yacc.c:1646 */ 1643 1635 { 1644 - (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); 1636 + (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); 1645 1637 } 1646 - #line 1638 "dtc-parser.tab.c" /* yacc.c:1646 */ 1638 + #line 1648 "dtc-parser.tab.c" /* yacc.c:1646 */ 1647 1639 break; 1648 1640 1649 1641 case 21: 1650 - #line 233 "dtc-parser.y" /* yacc.c:1646 */ 1642 + #line 243 "dtc-parser.y" /* yacc.c:1646 */ 1651 1643 { 1652 - (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); 1644 + (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); 1653 1645 } 1654 - #line 1646 "dtc-parser.tab.c" /* yacc.c:1646 */ 1646 + #line 1656 "dtc-parser.tab.c" /* yacc.c:1646 */ 1655 1647 break; 1656 1648 1657 1649 case 22: 1658 - #line 237 "dtc-parser.y" /* yacc.c:1646 */ 1650 + #line 247 "dtc-parser.y" /* yacc.c:1646 */ 1651 + { 1652 + (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); 1653 + } 1654 + #line 1664 "dtc-parser.tab.c" /* yacc.c:1646 */ 1655 + break; 1656 + 1657 + case 23: 1658 + #line 251 "dtc-parser.y" /* yacc.c:1646 */ 1659 1659 { 1660 1660 add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); 1661 1661 (yyval.prop) = (yyvsp[0].prop); 1662 1662 } 1663 - #line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */ 1664 - break; 1665 - 1666 - case 23: 1667 - #line 245 "dtc-parser.y" /* yacc.c:1646 */ 1668 - { 1669 - (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); 1670 - } 1671 - #line 1663 "dtc-parser.tab.c" /* yacc.c:1646 */ 1663 + #line 1673 "dtc-parser.tab.c" /* yacc.c:1646 */ 1672 1664 break; 1673 1665 1674 1666 case 24: 1675 - #line 249 "dtc-parser.y" /* yacc.c:1646 */ 1667 + #line 259 "dtc-parser.y" /* yacc.c:1646 */ 1676 1668 { 1677 - (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); 1669 + (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); 1678 1670 } 1679 - #line 1671 "dtc-parser.tab.c" /* yacc.c:1646 */ 1671 + #line 1681 "dtc-parser.tab.c" /* yacc.c:1646 */ 1680 1672 break; 1681 1673 1682 1674 case 25: 1683 - #line 253 "dtc-parser.y" /* yacc.c:1646 */ 1675 + #line 263 "dtc-parser.y" /* yacc.c:1646 */ 1684 1676 { 1685 - (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); 1677 + (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); 1686 1678 } 1687 - #line 1679 "dtc-parser.tab.c" /* yacc.c:1646 */ 1679 + #line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */ 1688 1680 break; 1689 1681 1690 1682 case 26: 1691 - #line 257 "dtc-parser.y" /* yacc.c:1646 */ 1683 + #line 267 "dtc-parser.y" /* yacc.c:1646 */ 1692 1684 { 1693 - (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); 1685 + (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); 1694 1686 } 1695 - #line 1687 "dtc-parser.tab.c" /* yacc.c:1646 */ 1687 + #line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */ 1696 1688 break; 1697 1689 1698 1690 case 27: 1699 - #line 261 "dtc-parser.y" /* yacc.c:1646 */ 1691 + #line 271 "dtc-parser.y" /* yacc.c:1646 */ 1692 + { 1693 + (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); 1694 + } 1695 + #line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */ 1696 + break; 1697 + 1698 + case 28: 1699 + #line 275 "dtc-parser.y" /* yacc.c:1646 */ 1700 1700 { 1701 1701 FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); 1702 1702 struct data d; ··· 1721 1703 (yyval.data) = data_merge((yyvsp[-8].data), d); 1722 1704 fclose(f); 1723 1705 } 1724 - #line 1707 "dtc-parser.tab.c" /* yacc.c:1646 */ 1706 + #line 1725 "dtc-parser.tab.c" /* yacc.c:1646 */ 1725 1707 break; 1726 1708 1727 - case 28: 1728 - #line 277 "dtc-parser.y" /* yacc.c:1646 */ 1709 + case 29: 1710 + #line 291 "dtc-parser.y" /* yacc.c:1646 */ 1729 1711 { 1730 1712 FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); 1731 1713 struct data d = empty_data; ··· 1735 1717 (yyval.data) = data_merge((yyvsp[-4].data), d); 1736 1718 fclose(f); 1737 1719 } 1738 - #line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */ 1739 - break; 1740 - 1741 - case 29: 1742 - #line 287 "dtc-parser.y" /* yacc.c:1646 */ 1743 - { 1744 - (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); 1745 - } 1746 - #line 1729 "dtc-parser.tab.c" /* yacc.c:1646 */ 1720 + #line 1739 "dtc-parser.tab.c" /* yacc.c:1646 */ 1747 1721 break; 1748 1722 1749 1723 case 30: 1750 - #line 294 "dtc-parser.y" /* yacc.c:1646 */ 1751 - { 1752 - (yyval.data) = empty_data; 1753 - } 1754 - #line 1737 "dtc-parser.tab.c" /* yacc.c:1646 */ 1755 - break; 1756 - 1757 - case 31: 1758 - #line 298 "dtc-parser.y" /* yacc.c:1646 */ 1759 - { 1760 - (yyval.data) = (yyvsp[-1].data); 1761 - } 1762 - #line 1745 "dtc-parser.tab.c" /* yacc.c:1646 */ 1763 - break; 1764 - 1765 - case 32: 1766 - #line 302 "dtc-parser.y" /* yacc.c:1646 */ 1724 + #line 301 "dtc-parser.y" /* yacc.c:1646 */ 1767 1725 { 1768 1726 (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); 1769 1727 } 1770 - #line 1753 "dtc-parser.tab.c" /* yacc.c:1646 */ 1728 + #line 1747 "dtc-parser.tab.c" /* yacc.c:1646 */ 1729 + break; 1730 + 1731 + case 31: 1732 + #line 308 "dtc-parser.y" /* yacc.c:1646 */ 1733 + { 1734 + (yyval.data) = empty_data; 1735 + } 1736 + #line 1755 "dtc-parser.tab.c" /* yacc.c:1646 */ 1737 + break; 1738 + 1739 + case 32: 1740 + #line 312 "dtc-parser.y" /* yacc.c:1646 */ 1741 + { 1742 + (yyval.data) = (yyvsp[-1].data); 1743 + } 1744 + #line 1763 "dtc-parser.tab.c" /* yacc.c:1646 */ 1771 1745 break; 1772 1746 1773 1747 case 33: 1774 - #line 309 "dtc-parser.y" /* yacc.c:1646 */ 1748 + #line 316 "dtc-parser.y" /* yacc.c:1646 */ 1749 + { 1750 + (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); 1751 + } 1752 + #line 1771 "dtc-parser.tab.c" /* yacc.c:1646 */ 1753 + break; 1754 + 1755 + case 34: 1756 + #line 323 "dtc-parser.y" /* yacc.c:1646 */ 1775 1757 { 1776 1758 unsigned long long bits; 1777 1759 ··· 1787 1769 (yyval.array).data = empty_data; 1788 1770 (yyval.array).bits = bits; 1789 1771 } 1790 - #line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */ 1772 + #line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */ 1791 1773 break; 1792 1774 1793 - case 34: 1794 - #line 325 "dtc-parser.y" /* yacc.c:1646 */ 1775 + case 35: 1776 + #line 339 "dtc-parser.y" /* yacc.c:1646 */ 1795 1777 { 1796 1778 (yyval.array).data = empty_data; 1797 1779 (yyval.array).bits = 32; 1798 1780 } 1799 - #line 1782 "dtc-parser.tab.c" /* yacc.c:1646 */ 1781 + #line 1800 "dtc-parser.tab.c" /* yacc.c:1646 */ 1800 1782 break; 1801 1783 1802 - case 35: 1803 - #line 330 "dtc-parser.y" /* yacc.c:1646 */ 1784 + case 36: 1785 + #line 344 "dtc-parser.y" /* yacc.c:1646 */ 1804 1786 { 1805 1787 if ((yyvsp[-1].array).bits < 64) { 1806 1788 uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; ··· 1819 1801 1820 1802 (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); 1821 1803 } 1822 - #line 1805 "dtc-parser.tab.c" /* yacc.c:1646 */ 1804 + #line 1823 "dtc-parser.tab.c" /* yacc.c:1646 */ 1823 1805 break; 1824 1806 1825 - case 36: 1826 - #line 349 "dtc-parser.y" /* yacc.c:1646 */ 1807 + case 37: 1808 + #line 363 "dtc-parser.y" /* yacc.c:1646 */ 1827 1809 { 1828 1810 uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); 1829 1811 ··· 1837 1819 1838 1820 (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); 1839 1821 } 1840 - #line 1823 "dtc-parser.tab.c" /* yacc.c:1646 */ 1822 + #line 1841 "dtc-parser.tab.c" /* yacc.c:1646 */ 1841 1823 break; 1842 1824 1843 - case 37: 1844 - #line 363 "dtc-parser.y" /* yacc.c:1646 */ 1825 + case 38: 1826 + #line 377 "dtc-parser.y" /* yacc.c:1646 */ 1845 1827 { 1846 1828 (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); 1847 1829 } 1848 - #line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ 1830 + #line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */ 1849 1831 break; 1850 1832 1851 - case 40: 1852 - #line 372 "dtc-parser.y" /* yacc.c:1646 */ 1833 + case 41: 1834 + #line 386 "dtc-parser.y" /* yacc.c:1646 */ 1853 1835 { 1854 1836 (yyval.integer) = (yyvsp[-1].integer); 1855 1837 } 1856 - #line 1839 "dtc-parser.tab.c" /* yacc.c:1646 */ 1857 - break; 1858 - 1859 - case 43: 1860 - #line 383 "dtc-parser.y" /* yacc.c:1646 */ 1861 - { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } 1862 - #line 1845 "dtc-parser.tab.c" /* yacc.c:1646 */ 1863 - break; 1864 - 1865 - case 45: 1866 - #line 388 "dtc-parser.y" /* yacc.c:1646 */ 1867 - { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } 1868 - #line 1851 "dtc-parser.tab.c" /* yacc.c:1646 */ 1869 - break; 1870 - 1871 - case 47: 1872 - #line 393 "dtc-parser.y" /* yacc.c:1646 */ 1873 - { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } 1874 1838 #line 1857 "dtc-parser.tab.c" /* yacc.c:1646 */ 1875 1839 break; 1876 1840 1877 - case 49: 1878 - #line 398 "dtc-parser.y" /* yacc.c:1646 */ 1879 - { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } 1841 + case 44: 1842 + #line 397 "dtc-parser.y" /* yacc.c:1646 */ 1843 + { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } 1880 1844 #line 1863 "dtc-parser.tab.c" /* yacc.c:1646 */ 1881 1845 break; 1882 1846 1883 - case 51: 1884 - #line 403 "dtc-parser.y" /* yacc.c:1646 */ 1885 - { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } 1847 + case 46: 1848 + #line 402 "dtc-parser.y" /* yacc.c:1646 */ 1849 + { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } 1886 1850 #line 1869 "dtc-parser.tab.c" /* yacc.c:1646 */ 1887 1851 break; 1888 1852 1889 - case 53: 1890 - #line 408 "dtc-parser.y" /* yacc.c:1646 */ 1891 - { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } 1853 + case 48: 1854 + #line 407 "dtc-parser.y" /* yacc.c:1646 */ 1855 + { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } 1892 1856 #line 1875 "dtc-parser.tab.c" /* yacc.c:1646 */ 1893 1857 break; 1894 1858 1895 - case 55: 1896 - #line 413 "dtc-parser.y" /* yacc.c:1646 */ 1897 - { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } 1859 + case 50: 1860 + #line 412 "dtc-parser.y" /* yacc.c:1646 */ 1861 + { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } 1898 1862 #line 1881 "dtc-parser.tab.c" /* yacc.c:1646 */ 1899 1863 break; 1900 1864 1901 - case 56: 1902 - #line 414 "dtc-parser.y" /* yacc.c:1646 */ 1903 - { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } 1865 + case 52: 1866 + #line 417 "dtc-parser.y" /* yacc.c:1646 */ 1867 + { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } 1904 1868 #line 1887 "dtc-parser.tab.c" /* yacc.c:1646 */ 1905 1869 break; 1906 1870 1907 - case 58: 1908 - #line 419 "dtc-parser.y" /* yacc.c:1646 */ 1909 - { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } 1871 + case 54: 1872 + #line 422 "dtc-parser.y" /* yacc.c:1646 */ 1873 + { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } 1910 1874 #line 1893 "dtc-parser.tab.c" /* yacc.c:1646 */ 1911 1875 break; 1912 1876 1913 - case 59: 1914 - #line 420 "dtc-parser.y" /* yacc.c:1646 */ 1915 - { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } 1877 + case 56: 1878 + #line 427 "dtc-parser.y" /* yacc.c:1646 */ 1879 + { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } 1916 1880 #line 1899 "dtc-parser.tab.c" /* yacc.c:1646 */ 1917 1881 break; 1918 1882 1919 - case 60: 1920 - #line 421 "dtc-parser.y" /* yacc.c:1646 */ 1921 - { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } 1883 + case 57: 1884 + #line 428 "dtc-parser.y" /* yacc.c:1646 */ 1885 + { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } 1922 1886 #line 1905 "dtc-parser.tab.c" /* yacc.c:1646 */ 1923 1887 break; 1924 1888 1925 - case 61: 1926 - #line 422 "dtc-parser.y" /* yacc.c:1646 */ 1927 - { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } 1889 + case 59: 1890 + #line 433 "dtc-parser.y" /* yacc.c:1646 */ 1891 + { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } 1928 1892 #line 1911 "dtc-parser.tab.c" /* yacc.c:1646 */ 1929 1893 break; 1930 1894 1931 - case 62: 1932 - #line 426 "dtc-parser.y" /* yacc.c:1646 */ 1933 - { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } 1895 + case 60: 1896 + #line 434 "dtc-parser.y" /* yacc.c:1646 */ 1897 + { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } 1934 1898 #line 1917 "dtc-parser.tab.c" /* yacc.c:1646 */ 1935 1899 break; 1936 1900 1937 - case 63: 1938 - #line 427 "dtc-parser.y" /* yacc.c:1646 */ 1939 - { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } 1901 + case 61: 1902 + #line 435 "dtc-parser.y" /* yacc.c:1646 */ 1903 + { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } 1940 1904 #line 1923 "dtc-parser.tab.c" /* yacc.c:1646 */ 1941 1905 break; 1942 1906 1943 - case 65: 1944 - #line 432 "dtc-parser.y" /* yacc.c:1646 */ 1945 - { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } 1907 + case 62: 1908 + #line 436 "dtc-parser.y" /* yacc.c:1646 */ 1909 + { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } 1946 1910 #line 1929 "dtc-parser.tab.c" /* yacc.c:1646 */ 1947 1911 break; 1948 1912 1949 - case 66: 1950 - #line 433 "dtc-parser.y" /* yacc.c:1646 */ 1951 - { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } 1913 + case 63: 1914 + #line 440 "dtc-parser.y" /* yacc.c:1646 */ 1915 + { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } 1952 1916 #line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */ 1953 1917 break; 1954 1918 1955 - case 68: 1956 - #line 438 "dtc-parser.y" /* yacc.c:1646 */ 1957 - { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } 1919 + case 64: 1920 + #line 441 "dtc-parser.y" /* yacc.c:1646 */ 1921 + { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } 1958 1922 #line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */ 1959 1923 break; 1960 1924 1925 + case 66: 1926 + #line 446 "dtc-parser.y" /* yacc.c:1646 */ 1927 + { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } 1928 + #line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ 1929 + break; 1930 + 1931 + case 67: 1932 + #line 447 "dtc-parser.y" /* yacc.c:1646 */ 1933 + { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } 1934 + #line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */ 1935 + break; 1936 + 1961 1937 case 69: 1962 - #line 440 "dtc-parser.y" /* yacc.c:1646 */ 1938 + #line 452 "dtc-parser.y" /* yacc.c:1646 */ 1939 + { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } 1940 + #line 1959 "dtc-parser.tab.c" /* yacc.c:1646 */ 1941 + break; 1942 + 1943 + case 70: 1944 + #line 454 "dtc-parser.y" /* yacc.c:1646 */ 1963 1945 { 1964 1946 if ((yyvsp[0].integer) != 0) { 1965 1947 (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); ··· 1968 1950 (yyval.integer) = 0; 1969 1951 } 1970 1952 } 1971 - #line 1954 "dtc-parser.tab.c" /* yacc.c:1646 */ 1953 + #line 1972 "dtc-parser.tab.c" /* yacc.c:1646 */ 1972 1954 break; 1973 1955 1974 - case 70: 1975 - #line 449 "dtc-parser.y" /* yacc.c:1646 */ 1956 + case 71: 1957 + #line 463 "dtc-parser.y" /* yacc.c:1646 */ 1976 1958 { 1977 1959 if ((yyvsp[0].integer) != 0) { 1978 1960 (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); ··· 1981 1963 (yyval.integer) = 0; 1982 1964 } 1983 1965 } 1984 - #line 1967 "dtc-parser.tab.c" /* yacc.c:1646 */ 1985 - break; 1986 - 1987 - case 73: 1988 - #line 462 "dtc-parser.y" /* yacc.c:1646 */ 1989 - { (yyval.integer) = -(yyvsp[0].integer); } 1990 - #line 1973 "dtc-parser.tab.c" /* yacc.c:1646 */ 1991 - break; 1992 - 1993 - case 74: 1994 - #line 463 "dtc-parser.y" /* yacc.c:1646 */ 1995 - { (yyval.integer) = ~(yyvsp[0].integer); } 1996 - #line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */ 1997 - break; 1998 - 1999 - case 75: 2000 - #line 464 "dtc-parser.y" /* yacc.c:1646 */ 2001 - { (yyval.integer) = !(yyvsp[0].integer); } 2002 1966 #line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */ 2003 1967 break; 2004 1968 1969 + case 74: 1970 + #line 476 "dtc-parser.y" /* yacc.c:1646 */ 1971 + { (yyval.integer) = -(yyvsp[0].integer); } 1972 + #line 1991 "dtc-parser.tab.c" /* yacc.c:1646 */ 1973 + break; 1974 + 1975 + case 75: 1976 + #line 477 "dtc-parser.y" /* yacc.c:1646 */ 1977 + { (yyval.integer) = ~(yyvsp[0].integer); } 1978 + #line 1997 "dtc-parser.tab.c" /* yacc.c:1646 */ 1979 + break; 1980 + 2005 1981 case 76: 2006 - #line 469 "dtc-parser.y" /* yacc.c:1646 */ 2007 - { 2008 - (yyval.data) = empty_data; 2009 - } 2010 - #line 1993 "dtc-parser.tab.c" /* yacc.c:1646 */ 1982 + #line 478 "dtc-parser.y" /* yacc.c:1646 */ 1983 + { (yyval.integer) = !(yyvsp[0].integer); } 1984 + #line 2003 "dtc-parser.tab.c" /* yacc.c:1646 */ 2011 1985 break; 2012 1986 2013 1987 case 77: 2014 - #line 473 "dtc-parser.y" /* yacc.c:1646 */ 1988 + #line 483 "dtc-parser.y" /* yacc.c:1646 */ 2015 1989 { 2016 - (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); 1990 + (yyval.data) = empty_data; 2017 1991 } 2018 - #line 2001 "dtc-parser.tab.c" /* yacc.c:1646 */ 1992 + #line 2011 "dtc-parser.tab.c" /* yacc.c:1646 */ 2019 1993 break; 2020 1994 2021 1995 case 78: 2022 - #line 477 "dtc-parser.y" /* yacc.c:1646 */ 1996 + #line 487 "dtc-parser.y" /* yacc.c:1646 */ 2023 1997 { 2024 - (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); 1998 + (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); 2025 1999 } 2026 - #line 2009 "dtc-parser.tab.c" /* yacc.c:1646 */ 2000 + #line 2019 "dtc-parser.tab.c" /* yacc.c:1646 */ 2027 2001 break; 2028 2002 2029 2003 case 79: 2030 - #line 484 "dtc-parser.y" /* yacc.c:1646 */ 2004 + #line 491 "dtc-parser.y" /* yacc.c:1646 */ 2031 2005 { 2032 - (yyval.nodelist) = NULL; 2006 + (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); 2033 2007 } 2034 - #line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */ 2008 + #line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */ 2035 2009 break; 2036 2010 2037 2011 case 80: 2038 - #line 488 "dtc-parser.y" /* yacc.c:1646 */ 2012 + #line 498 "dtc-parser.y" /* yacc.c:1646 */ 2039 2013 { 2040 - (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); 2014 + (yyval.nodelist) = NULL; 2041 2015 } 2042 - #line 2025 "dtc-parser.tab.c" /* yacc.c:1646 */ 2016 + #line 2035 "dtc-parser.tab.c" /* yacc.c:1646 */ 2043 2017 break; 2044 2018 2045 2019 case 81: 2046 - #line 492 "dtc-parser.y" /* yacc.c:1646 */ 2020 + #line 502 "dtc-parser.y" /* yacc.c:1646 */ 2021 + { 2022 + (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); 2023 + } 2024 + #line 2043 "dtc-parser.tab.c" /* yacc.c:1646 */ 2025 + break; 2026 + 2027 + case 82: 2028 + #line 506 "dtc-parser.y" /* yacc.c:1646 */ 2047 2029 { 2048 2030 ERROR(&(yylsp[0]), "Properties must precede subnodes"); 2049 2031 YYERROR; 2050 2032 } 2051 - #line 2034 "dtc-parser.tab.c" /* yacc.c:1646 */ 2052 - break; 2053 - 2054 - case 82: 2055 - #line 500 "dtc-parser.y" /* yacc.c:1646 */ 2056 - { 2057 - (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); 2058 - } 2059 - #line 2042 "dtc-parser.tab.c" /* yacc.c:1646 */ 2033 + #line 2052 "dtc-parser.tab.c" /* yacc.c:1646 */ 2060 2034 break; 2061 2035 2062 2036 case 83: 2063 - #line 504 "dtc-parser.y" /* yacc.c:1646 */ 2037 + #line 514 "dtc-parser.y" /* yacc.c:1646 */ 2064 2038 { 2065 - (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); 2039 + (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); 2066 2040 } 2067 - #line 2050 "dtc-parser.tab.c" /* yacc.c:1646 */ 2041 + #line 2060 "dtc-parser.tab.c" /* yacc.c:1646 */ 2068 2042 break; 2069 2043 2070 2044 case 84: 2071 - #line 508 "dtc-parser.y" /* yacc.c:1646 */ 2045 + #line 518 "dtc-parser.y" /* yacc.c:1646 */ 2046 + { 2047 + (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); 2048 + } 2049 + #line 2068 "dtc-parser.tab.c" /* yacc.c:1646 */ 2050 + break; 2051 + 2052 + case 85: 2053 + #line 522 "dtc-parser.y" /* yacc.c:1646 */ 2072 2054 { 2073 2055 add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); 2074 2056 (yyval.node) = (yyvsp[0].node); 2075 2057 } 2076 - #line 2059 "dtc-parser.tab.c" /* yacc.c:1646 */ 2058 + #line 2077 "dtc-parser.tab.c" /* yacc.c:1646 */ 2077 2059 break; 2078 2060 2079 2061 2080 - #line 2063 "dtc-parser.tab.c" /* yacc.c:1646 */ 2062 + #line 2081 "dtc-parser.tab.c" /* yacc.c:1646 */ 2081 2063 default: break; 2082 2064 } 2083 2065 /* User semantic actions sometimes alter yychar, and that requires ··· 2312 2294 #endif 2313 2295 return yyresult; 2314 2296 } 2315 - #line 514 "dtc-parser.y" /* yacc.c:1906 */ 2297 + #line 528 "dtc-parser.y" /* yacc.c:1906 */ 2316 2298 2317 2299 2318 2300 void yyerror(char const *s)
+17 -3
scripts/dtc/dtc-parser.y
··· 182 182 { 183 183 struct node *target = get_node_by_ref($1, $2); 184 184 185 - if (target) 185 + if (target) { 186 186 merge_nodes(target, $3); 187 - else 188 - ERROR(&@2, "Label or path %s not found", $2); 187 + } else { 188 + /* 189 + * We rely on the rule being always: 190 + * versioninfo plugindecl memreserves devicetree 191 + * so $-1 is what we want (plugindecl) 192 + */ 193 + if ($<flags>-1 & DTSF_PLUGIN) 194 + add_orphan_node($1, $3, $2); 195 + else 196 + ERROR(&@2, "Label or path %s not found", $2); 197 + } 189 198 $$ = $1; 190 199 } 191 200 | devicetree DT_DEL_NODE DT_REF ';' ··· 208 199 209 200 210 201 $$ = $1; 202 + } 203 + | /* empty */ 204 + { 205 + /* build empty node */ 206 + $$ = name_node(build_node(NULL, NULL), ""); 211 207 } 212 208 ; 213 209
+1 -1
scripts/dtc/dtc.c
··· 31 31 int minsize; /* Minimum blob size */ 32 32 int padsize; /* Additional padding to blob */ 33 33 int alignsize; /* Additional padding to blob accroding to the alignsize */ 34 - int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ 34 + int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties */ 35 35 int generate_symbols; /* enable symbols & fixup support */ 36 36 int generate_fixups; /* suppress generation of fixups on symbol support */ 37 37 int auto_label_aliases; /* auto generate labels -> aliases */
+3
scripts/dtc/dtc.h
··· 31 31 #include <ctype.h> 32 32 #include <errno.h> 33 33 #include <unistd.h> 34 + #include <inttypes.h> 34 35 35 36 #include <libfdt_env.h> 36 37 #include <fdt.h> ··· 203 202 struct node *name_node(struct node *node, char *name); 204 203 struct node *chain_node(struct node *first, struct node *list); 205 204 struct node *merge_nodes(struct node *old_node, struct node *new_node); 205 + void add_orphan_node(struct node *old_node, struct node *new_node, char *ref); 206 206 207 207 void add_property(struct node *node, struct property *prop); 208 208 void delete_property_by_name(struct node *node, char *name); ··· 217 215 const char *get_unitname(struct node *node); 218 216 struct property *get_property(struct node *node, const char *propname); 219 217 cell_t propval_cell(struct property *prop); 218 + cell_t propval_cell_n(struct property *prop, int n); 220 219 struct property *get_property_by_label(struct node *tree, const char *label, 221 220 struct node **node); 222 221 struct marker *get_marker_label(struct node *tree, const char *label,
+96
scripts/dtc/libfdt/fdt_addresses.c
··· 1 + /* 2 + * libfdt - Flat Device Tree manipulation 3 + * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au> 4 + * 5 + * libfdt is dual licensed: you can use it either under the terms of 6 + * the GPL, or the BSD license, at your option. 7 + * 8 + * a) This library is free software; you can redistribute it and/or 9 + * modify it under the terms of the GNU General Public License as 10 + * published by the Free Software Foundation; either version 2 of the 11 + * License, or (at your option) any later version. 12 + * 13 + * This library is distributed in the hope that it will be useful, 14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 + * GNU General Public License for more details. 17 + * 18 + * You should have received a copy of the GNU General Public 19 + * License along with this library; if not, write to the Free 20 + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, 21 + * MA 02110-1301 USA 22 + * 23 + * Alternatively, 24 + * 25 + * b) Redistribution and use in source and binary forms, with or 26 + * without modification, are permitted provided that the following 27 + * conditions are met: 28 + * 29 + * 1. Redistributions of source code must retain the above 30 + * copyright notice, this list of conditions and the following 31 + * disclaimer. 32 + * 2. Redistributions in binary form must reproduce the above 33 + * copyright notice, this list of conditions and the following 34 + * disclaimer in the documentation and/or other materials 35 + * provided with the distribution. 36 + * 37 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 38 + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 39 + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 40 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 41 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 42 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 43 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 44 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 45 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 46 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 47 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 48 + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 49 + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 50 + */ 51 + #include "libfdt_env.h" 52 + 53 + #include <fdt.h> 54 + #include <libfdt.h> 55 + 56 + #include "libfdt_internal.h" 57 + 58 + int fdt_address_cells(const void *fdt, int nodeoffset) 59 + { 60 + const fdt32_t *ac; 61 + int val; 62 + int len; 63 + 64 + ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len); 65 + if (!ac) 66 + return 2; 67 + 68 + if (len != sizeof(*ac)) 69 + return -FDT_ERR_BADNCELLS; 70 + 71 + val = fdt32_to_cpu(*ac); 72 + if ((val <= 0) || (val > FDT_MAX_NCELLS)) 73 + return -FDT_ERR_BADNCELLS; 74 + 75 + return val; 76 + } 77 + 78 + int fdt_size_cells(const void *fdt, int nodeoffset) 79 + { 80 + const fdt32_t *sc; 81 + int val; 82 + int len; 83 + 84 + sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len); 85 + if (!sc) 86 + return 2; 87 + 88 + if (len != sizeof(*sc)) 89 + return -FDT_ERR_BADNCELLS; 90 + 91 + val = fdt32_to_cpu(*sc); 92 + if ((val < 0) || (val > FDT_MAX_NCELLS)) 93 + return -FDT_ERR_BADNCELLS; 94 + 95 + return val; 96 + }
-1
scripts/dtc/libfdt/fdt_empty_tree.c
··· 81 81 82 82 return fdt_open_into(buf, buf, bufsize); 83 83 } 84 -
+861
scripts/dtc/libfdt/fdt_overlay.c
··· 1 + #include "libfdt_env.h" 2 + 3 + #include <fdt.h> 4 + #include <libfdt.h> 5 + 6 + #include "libfdt_internal.h" 7 + 8 + /** 9 + * overlay_get_target_phandle - retrieves the target phandle of a fragment 10 + * @fdto: pointer to the device tree overlay blob 11 + * @fragment: node offset of the fragment in the overlay 12 + * 13 + * overlay_get_target_phandle() retrieves the target phandle of an 14 + * overlay fragment when that fragment uses a phandle (target 15 + * property) instead of a path (target-path property). 16 + * 17 + * returns: 18 + * the phandle pointed by the target property 19 + * 0, if the phandle was not found 20 + * -1, if the phandle was malformed 21 + */ 22 + static uint32_t overlay_get_target_phandle(const void *fdto, int fragment) 23 + { 24 + const fdt32_t *val; 25 + int len; 26 + 27 + val = fdt_getprop(fdto, fragment, "target", &len); 28 + if (!val) 29 + return 0; 30 + 31 + if ((len != sizeof(*val)) || (fdt32_to_cpu(*val) == (uint32_t)-1)) 32 + return (uint32_t)-1; 33 + 34 + return fdt32_to_cpu(*val); 35 + } 36 + 37 + /** 38 + * overlay_get_target - retrieves the offset of a fragment's target 39 + * @fdt: Base device tree blob 40 + * @fdto: Device tree overlay blob 41 + * @fragment: node offset of the fragment in the overlay 42 + * @pathp: pointer which receives the path of the target (or NULL) 43 + * 44 + * overlay_get_target() retrieves the target offset in the base 45 + * device tree of a fragment, no matter how the actual targetting is 46 + * done (through a phandle or a path) 47 + * 48 + * returns: 49 + * the targetted node offset in the base device tree 50 + * Negative error code on error 51 + */ 52 + static int overlay_get_target(const void *fdt, const void *fdto, 53 + int fragment, char const **pathp) 54 + { 55 + uint32_t phandle; 56 + const char *path = NULL; 57 + int path_len = 0, ret; 58 + 59 + /* Try first to do a phandle based lookup */ 60 + phandle = overlay_get_target_phandle(fdto, fragment); 61 + if (phandle == (uint32_t)-1) 62 + return -FDT_ERR_BADPHANDLE; 63 + 64 + /* no phandle, try path */ 65 + if (!phandle) { 66 + /* And then a path based lookup */ 67 + path = fdt_getprop(fdto, fragment, "target-path", &path_len); 68 + if (path) 69 + ret = fdt_path_offset(fdt, path); 70 + else 71 + ret = path_len; 72 + } else 73 + ret = fdt_node_offset_by_phandle(fdt, phandle); 74 + 75 + /* 76 + * If we haven't found either a target or a 77 + * target-path property in a node that contains a 78 + * __overlay__ subnode (we wouldn't be called 79 + * otherwise), consider it a improperly written 80 + * overlay 81 + */ 82 + if (ret < 0 && path_len == -FDT_ERR_NOTFOUND) 83 + ret = -FDT_ERR_BADOVERLAY; 84 + 85 + /* return on error */ 86 + if (ret < 0) 87 + return ret; 88 + 89 + /* return pointer to path (if available) */ 90 + if (pathp) 91 + *pathp = path ? path : NULL; 92 + 93 + return ret; 94 + } 95 + 96 + /** 97 + * overlay_phandle_add_offset - Increases a phandle by an offset 98 + * @fdt: Base device tree blob 99 + * @node: Device tree overlay blob 100 + * @name: Name of the property to modify (phandle or linux,phandle) 101 + * @delta: offset to apply 102 + * 103 + * overlay_phandle_add_offset() increments a node phandle by a given 104 + * offset. 105 + * 106 + * returns: 107 + * 0 on success. 108 + * Negative error code on error 109 + */ 110 + static int overlay_phandle_add_offset(void *fdt, int node, 111 + const char *name, uint32_t delta) 112 + { 113 + const fdt32_t *val; 114 + uint32_t adj_val; 115 + int len; 116 + 117 + val = fdt_getprop(fdt, node, name, &len); 118 + if (!val) 119 + return len; 120 + 121 + if (len != sizeof(*val)) 122 + return -FDT_ERR_BADPHANDLE; 123 + 124 + adj_val = fdt32_to_cpu(*val); 125 + if ((adj_val + delta) < adj_val) 126 + return -FDT_ERR_NOPHANDLES; 127 + 128 + adj_val += delta; 129 + if (adj_val == (uint32_t)-1) 130 + return -FDT_ERR_NOPHANDLES; 131 + 132 + return fdt_setprop_inplace_u32(fdt, node, name, adj_val); 133 + } 134 + 135 + /** 136 + * overlay_adjust_node_phandles - Offsets the phandles of a node 137 + * @fdto: Device tree overlay blob 138 + * @node: Offset of the node we want to adjust 139 + * @delta: Offset to shift the phandles of 140 + * 141 + * overlay_adjust_node_phandles() adds a constant to all the phandles 142 + * of a given node. This is mainly use as part of the overlay 143 + * application process, when we want to update all the overlay 144 + * phandles to not conflict with the overlays of the base device tree. 145 + * 146 + * returns: 147 + * 0 on success 148 + * Negative error code on failure 149 + */ 150 + static int overlay_adjust_node_phandles(void *fdto, int node, 151 + uint32_t delta) 152 + { 153 + int child; 154 + int ret; 155 + 156 + ret = overlay_phandle_add_offset(fdto, node, "phandle", delta); 157 + if (ret && ret != -FDT_ERR_NOTFOUND) 158 + return ret; 159 + 160 + ret = overlay_phandle_add_offset(fdto, node, "linux,phandle", delta); 161 + if (ret && ret != -FDT_ERR_NOTFOUND) 162 + return ret; 163 + 164 + fdt_for_each_subnode(child, fdto, node) { 165 + ret = overlay_adjust_node_phandles(fdto, child, delta); 166 + if (ret) 167 + return ret; 168 + } 169 + 170 + return 0; 171 + } 172 + 173 + /** 174 + * overlay_adjust_local_phandles - Adjust the phandles of a whole overlay 175 + * @fdto: Device tree overlay blob 176 + * @delta: Offset to shift the phandles of 177 + * 178 + * overlay_adjust_local_phandles() adds a constant to all the 179 + * phandles of an overlay. This is mainly use as part of the overlay 180 + * application process, when we want to update all the overlay 181 + * phandles to not conflict with the overlays of the base device tree. 182 + * 183 + * returns: 184 + * 0 on success 185 + * Negative error code on failure 186 + */ 187 + static int overlay_adjust_local_phandles(void *fdto, uint32_t delta) 188 + { 189 + /* 190 + * Start adjusting the phandles from the overlay root 191 + */ 192 + return overlay_adjust_node_phandles(fdto, 0, delta); 193 + } 194 + 195 + /** 196 + * overlay_update_local_node_references - Adjust the overlay references 197 + * @fdto: Device tree overlay blob 198 + * @tree_node: Node offset of the node to operate on 199 + * @fixup_node: Node offset of the matching local fixups node 200 + * @delta: Offset to shift the phandles of 201 + * 202 + * overlay_update_local_nodes_references() update the phandles 203 + * pointing to a node within the device tree overlay by adding a 204 + * constant delta. 205 + * 206 + * This is mainly used as part of a device tree application process, 207 + * where you want the device tree overlays phandles to not conflict 208 + * with the ones from the base device tree before merging them. 209 + * 210 + * returns: 211 + * 0 on success 212 + * Negative error code on failure 213 + */ 214 + static int overlay_update_local_node_references(void *fdto, 215 + int tree_node, 216 + int fixup_node, 217 + uint32_t delta) 218 + { 219 + int fixup_prop; 220 + int fixup_child; 221 + int ret; 222 + 223 + fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) { 224 + const fdt32_t *fixup_val; 225 + const char *tree_val; 226 + const char *name; 227 + int fixup_len; 228 + int tree_len; 229 + int i; 230 + 231 + fixup_val = fdt_getprop_by_offset(fdto, fixup_prop, 232 + &name, &fixup_len); 233 + if (!fixup_val) 234 + return fixup_len; 235 + 236 + if (fixup_len % sizeof(uint32_t)) 237 + return -FDT_ERR_BADOVERLAY; 238 + 239 + tree_val = fdt_getprop(fdto, tree_node, name, &tree_len); 240 + if (!tree_val) { 241 + if (tree_len == -FDT_ERR_NOTFOUND) 242 + return -FDT_ERR_BADOVERLAY; 243 + 244 + return tree_len; 245 + } 246 + 247 + for (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) { 248 + fdt32_t adj_val; 249 + uint32_t poffset; 250 + 251 + poffset = fdt32_to_cpu(fixup_val[i]); 252 + 253 + /* 254 + * phandles to fixup can be unaligned. 255 + * 256 + * Use a memcpy for the architectures that do 257 + * not support unaligned accesses. 258 + */ 259 + memcpy(&adj_val, tree_val + poffset, sizeof(adj_val)); 260 + 261 + adj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta); 262 + 263 + ret = fdt_setprop_inplace_namelen_partial(fdto, 264 + tree_node, 265 + name, 266 + strlen(name), 267 + poffset, 268 + &adj_val, 269 + sizeof(adj_val)); 270 + if (ret == -FDT_ERR_NOSPACE) 271 + return -FDT_ERR_BADOVERLAY; 272 + 273 + if (ret) 274 + return ret; 275 + } 276 + } 277 + 278 + fdt_for_each_subnode(fixup_child, fdto, fixup_node) { 279 + const char *fixup_child_name = fdt_get_name(fdto, fixup_child, 280 + NULL); 281 + int tree_child; 282 + 283 + tree_child = fdt_subnode_offset(fdto, tree_node, 284 + fixup_child_name); 285 + if (tree_child == -FDT_ERR_NOTFOUND) 286 + return -FDT_ERR_BADOVERLAY; 287 + if (tree_child < 0) 288 + return tree_child; 289 + 290 + ret = overlay_update_local_node_references(fdto, 291 + tree_child, 292 + fixup_child, 293 + delta); 294 + if (ret) 295 + return ret; 296 + } 297 + 298 + return 0; 299 + } 300 + 301 + /** 302 + * overlay_update_local_references - Adjust the overlay references 303 + * @fdto: Device tree overlay blob 304 + * @delta: Offset to shift the phandles of 305 + * 306 + * overlay_update_local_references() update all the phandles pointing 307 + * to a node within the device tree overlay by adding a constant 308 + * delta to not conflict with the base overlay. 309 + * 310 + * This is mainly used as part of a device tree application process, 311 + * where you want the device tree overlays phandles to not conflict 312 + * with the ones from the base device tree before merging them. 313 + * 314 + * returns: 315 + * 0 on success 316 + * Negative error code on failure 317 + */ 318 + static int overlay_update_local_references(void *fdto, uint32_t delta) 319 + { 320 + int fixups; 321 + 322 + fixups = fdt_path_offset(fdto, "/__local_fixups__"); 323 + if (fixups < 0) { 324 + /* There's no local phandles to adjust, bail out */ 325 + if (fixups == -FDT_ERR_NOTFOUND) 326 + return 0; 327 + 328 + return fixups; 329 + } 330 + 331 + /* 332 + * Update our local references from the root of the tree 333 + */ 334 + return overlay_update_local_node_references(fdto, 0, fixups, 335 + delta); 336 + } 337 + 338 + /** 339 + * overlay_fixup_one_phandle - Set an overlay phandle to the base one 340 + * @fdt: Base Device Tree blob 341 + * @fdto: Device tree overlay blob 342 + * @symbols_off: Node offset of the symbols node in the base device tree 343 + * @path: Path to a node holding a phandle in the overlay 344 + * @path_len: number of path characters to consider 345 + * @name: Name of the property holding the phandle reference in the overlay 346 + * @name_len: number of name characters to consider 347 + * @poffset: Offset within the overlay property where the phandle is stored 348 + * @label: Label of the node referenced by the phandle 349 + * 350 + * overlay_fixup_one_phandle() resolves an overlay phandle pointing to 351 + * a node in the base device tree. 352 + * 353 + * This is part of the device tree overlay application process, when 354 + * you want all the phandles in the overlay to point to the actual 355 + * base dt nodes. 356 + * 357 + * returns: 358 + * 0 on success 359 + * Negative error code on failure 360 + */ 361 + static int overlay_fixup_one_phandle(void *fdt, void *fdto, 362 + int symbols_off, 363 + const char *path, uint32_t path_len, 364 + const char *name, uint32_t name_len, 365 + int poffset, const char *label) 366 + { 367 + const char *symbol_path; 368 + uint32_t phandle; 369 + fdt32_t phandle_prop; 370 + int symbol_off, fixup_off; 371 + int prop_len; 372 + 373 + if (symbols_off < 0) 374 + return symbols_off; 375 + 376 + symbol_path = fdt_getprop(fdt, symbols_off, label, 377 + &prop_len); 378 + if (!symbol_path) 379 + return prop_len; 380 + 381 + symbol_off = fdt_path_offset(fdt, symbol_path); 382 + if (symbol_off < 0) 383 + return symbol_off; 384 + 385 + phandle = fdt_get_phandle(fdt, symbol_off); 386 + if (!phandle) 387 + return -FDT_ERR_NOTFOUND; 388 + 389 + fixup_off = fdt_path_offset_namelen(fdto, path, path_len); 390 + if (fixup_off == -FDT_ERR_NOTFOUND) 391 + return -FDT_ERR_BADOVERLAY; 392 + if (fixup_off < 0) 393 + return fixup_off; 394 + 395 + phandle_prop = cpu_to_fdt32(phandle); 396 + return fdt_setprop_inplace_namelen_partial(fdto, fixup_off, 397 + name, name_len, poffset, 398 + &phandle_prop, 399 + sizeof(phandle_prop)); 400 + }; 401 + 402 + /** 403 + * overlay_fixup_phandle - Set an overlay phandle to the base one 404 + * @fdt: Base Device Tree blob 405 + * @fdto: Device tree overlay blob 406 + * @symbols_off: Node offset of the symbols node in the base device tree 407 + * @property: Property offset in the overlay holding the list of fixups 408 + * 409 + * overlay_fixup_phandle() resolves all the overlay phandles pointed 410 + * to in a __fixups__ property, and updates them to match the phandles 411 + * in use in the base device tree. 412 + * 413 + * This is part of the device tree overlay application process, when 414 + * you want all the phandles in the overlay to point to the actual 415 + * base dt nodes. 416 + * 417 + * returns: 418 + * 0 on success 419 + * Negative error code on failure 420 + */ 421 + static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off, 422 + int property) 423 + { 424 + const char *value; 425 + const char *label; 426 + int len; 427 + 428 + value = fdt_getprop_by_offset(fdto, property, 429 + &label, &len); 430 + if (!value) { 431 + if (len == -FDT_ERR_NOTFOUND) 432 + return -FDT_ERR_INTERNAL; 433 + 434 + return len; 435 + } 436 + 437 + do { 438 + const char *path, *name, *fixup_end; 439 + const char *fixup_str = value; 440 + uint32_t path_len, name_len; 441 + uint32_t fixup_len; 442 + char *sep, *endptr; 443 + int poffset, ret; 444 + 445 + fixup_end = memchr(value, '\0', len); 446 + if (!fixup_end) 447 + return -FDT_ERR_BADOVERLAY; 448 + fixup_len = fixup_end - fixup_str; 449 + 450 + len -= fixup_len + 1; 451 + value += fixup_len + 1; 452 + 453 + path = fixup_str; 454 + sep = memchr(fixup_str, ':', fixup_len); 455 + if (!sep || *sep != ':') 456 + return -FDT_ERR_BADOVERLAY; 457 + 458 + path_len = sep - path; 459 + if (path_len == (fixup_len - 1)) 460 + return -FDT_ERR_BADOVERLAY; 461 + 462 + fixup_len -= path_len + 1; 463 + name = sep + 1; 464 + sep = memchr(name, ':', fixup_len); 465 + if (!sep || *sep != ':') 466 + return -FDT_ERR_BADOVERLAY; 467 + 468 + name_len = sep - name; 469 + if (!name_len) 470 + return -FDT_ERR_BADOVERLAY; 471 + 472 + poffset = strtoul(sep + 1, &endptr, 10); 473 + if ((*endptr != '\0') || (endptr <= (sep + 1))) 474 + return -FDT_ERR_BADOVERLAY; 475 + 476 + ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off, 477 + path, path_len, name, name_len, 478 + poffset, label); 479 + if (ret) 480 + return ret; 481 + } while (len > 0); 482 + 483 + return 0; 484 + } 485 + 486 + /** 487 + * overlay_fixup_phandles - Resolve the overlay phandles to the base 488 + * device tree 489 + * @fdt: Base Device Tree blob 490 + * @fdto: Device tree overlay blob 491 + * 492 + * overlay_fixup_phandles() resolves all the overlay phandles pointing 493 + * to nodes in the base device tree. 494 + * 495 + * This is one of the steps of the device tree overlay application 496 + * process, when you want all the phandles in the overlay to point to 497 + * the actual base dt nodes. 498 + * 499 + * returns: 500 + * 0 on success 501 + * Negative error code on failure 502 + */ 503 + static int overlay_fixup_phandles(void *fdt, void *fdto) 504 + { 505 + int fixups_off, symbols_off; 506 + int property; 507 + 508 + /* We can have overlays without any fixups */ 509 + fixups_off = fdt_path_offset(fdto, "/__fixups__"); 510 + if (fixups_off == -FDT_ERR_NOTFOUND) 511 + return 0; /* nothing to do */ 512 + if (fixups_off < 0) 513 + return fixups_off; 514 + 515 + /* And base DTs without symbols */ 516 + symbols_off = fdt_path_offset(fdt, "/__symbols__"); 517 + if ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND))) 518 + return symbols_off; 519 + 520 + fdt_for_each_property_offset(property, fdto, fixups_off) { 521 + int ret; 522 + 523 + ret = overlay_fixup_phandle(fdt, fdto, symbols_off, property); 524 + if (ret) 525 + return ret; 526 + } 527 + 528 + return 0; 529 + } 530 + 531 + /** 532 + * overlay_apply_node - Merges a node into the base device tree 533 + * @fdt: Base Device Tree blob 534 + * @target: Node offset in the base device tree to apply the fragment to 535 + * @fdto: Device tree overlay blob 536 + * @node: Node offset in the overlay holding the changes to merge 537 + * 538 + * overlay_apply_node() merges a node into a target base device tree 539 + * node pointed. 540 + * 541 + * This is part of the final step in the device tree overlay 542 + * application process, when all the phandles have been adjusted and 543 + * resolved and you just have to merge overlay into the base device 544 + * tree. 545 + * 546 + * returns: 547 + * 0 on success 548 + * Negative error code on failure 549 + */ 550 + static int overlay_apply_node(void *fdt, int target, 551 + void *fdto, int node) 552 + { 553 + int property; 554 + int subnode; 555 + 556 + fdt_for_each_property_offset(property, fdto, node) { 557 + const char *name; 558 + const void *prop; 559 + int prop_len; 560 + int ret; 561 + 562 + prop = fdt_getprop_by_offset(fdto, property, &name, 563 + &prop_len); 564 + if (prop_len == -FDT_ERR_NOTFOUND) 565 + return -FDT_ERR_INTERNAL; 566 + if (prop_len < 0) 567 + return prop_len; 568 + 569 + ret = fdt_setprop(fdt, target, name, prop, prop_len); 570 + if (ret) 571 + return ret; 572 + } 573 + 574 + fdt_for_each_subnode(subnode, fdto, node) { 575 + const char *name = fdt_get_name(fdto, subnode, NULL); 576 + int nnode; 577 + int ret; 578 + 579 + nnode = fdt_add_subnode(fdt, target, name); 580 + if (nnode == -FDT_ERR_EXISTS) { 581 + nnode = fdt_subnode_offset(fdt, target, name); 582 + if (nnode == -FDT_ERR_NOTFOUND) 583 + return -FDT_ERR_INTERNAL; 584 + } 585 + 586 + if (nnode < 0) 587 + return nnode; 588 + 589 + ret = overlay_apply_node(fdt, nnode, fdto, subnode); 590 + if (ret) 591 + return ret; 592 + } 593 + 594 + return 0; 595 + } 596 + 597 + /** 598 + * overlay_merge - Merge an overlay into its base device tree 599 + * @fdt: Base Device Tree blob 600 + * @fdto: Device tree overlay blob 601 + * 602 + * overlay_merge() merges an overlay into its base device tree. 603 + * 604 + * This is the next to last step in the device tree overlay application 605 + * process, when all the phandles have been adjusted and resolved and 606 + * you just have to merge overlay into the base device tree. 607 + * 608 + * returns: 609 + * 0 on success 610 + * Negative error code on failure 611 + */ 612 + static int overlay_merge(void *fdt, void *fdto) 613 + { 614 + int fragment; 615 + 616 + fdt_for_each_subnode(fragment, fdto, 0) { 617 + int overlay; 618 + int target; 619 + int ret; 620 + 621 + /* 622 + * Each fragments will have an __overlay__ node. If 623 + * they don't, it's not supposed to be merged 624 + */ 625 + overlay = fdt_subnode_offset(fdto, fragment, "__overlay__"); 626 + if (overlay == -FDT_ERR_NOTFOUND) 627 + continue; 628 + 629 + if (overlay < 0) 630 + return overlay; 631 + 632 + target = overlay_get_target(fdt, fdto, fragment, NULL); 633 + if (target < 0) 634 + return target; 635 + 636 + ret = overlay_apply_node(fdt, target, fdto, overlay); 637 + if (ret) 638 + return ret; 639 + } 640 + 641 + return 0; 642 + } 643 + 644 + static int get_path_len(const void *fdt, int nodeoffset) 645 + { 646 + int len = 0, namelen; 647 + const char *name; 648 + 649 + FDT_CHECK_HEADER(fdt); 650 + 651 + for (;;) { 652 + name = fdt_get_name(fdt, nodeoffset, &namelen); 653 + if (!name) 654 + return namelen; 655 + 656 + /* root? we're done */ 657 + if (namelen == 0) 658 + break; 659 + 660 + nodeoffset = fdt_parent_offset(fdt, nodeoffset); 661 + if (nodeoffset < 0) 662 + return nodeoffset; 663 + len += namelen + 1; 664 + } 665 + 666 + /* in case of root pretend it's "/" */ 667 + if (len == 0) 668 + len++; 669 + return len; 670 + } 671 + 672 + /** 673 + * overlay_symbol_update - Update the symbols of base tree after a merge 674 + * @fdt: Base Device Tree blob 675 + * @fdto: Device tree overlay blob 676 + * 677 + * overlay_symbol_update() updates the symbols of the base tree with the 678 + * symbols of the applied overlay 679 + * 680 + * This is the last step in the device tree overlay application 681 + * process, allowing the reference of overlay symbols by subsequent 682 + * overlay operations. 683 + * 684 + * returns: 685 + * 0 on success 686 + * Negative error code on failure 687 + */ 688 + static int overlay_symbol_update(void *fdt, void *fdto) 689 + { 690 + int root_sym, ov_sym, prop, path_len, fragment, target; 691 + int len, frag_name_len, ret, rel_path_len; 692 + const char *s, *e; 693 + const char *path; 694 + const char *name; 695 + const char *frag_name; 696 + const char *rel_path; 697 + const char *target_path; 698 + char *buf; 699 + void *p; 700 + 701 + ov_sym = fdt_subnode_offset(fdto, 0, "__symbols__"); 702 + 703 + /* if no overlay symbols exist no problem */ 704 + if (ov_sym < 0) 705 + return 0; 706 + 707 + root_sym = fdt_subnode_offset(fdt, 0, "__symbols__"); 708 + 709 + /* it no root symbols exist we should create them */ 710 + if (root_sym == -FDT_ERR_NOTFOUND) 711 + root_sym = fdt_add_subnode(fdt, 0, "__symbols__"); 712 + 713 + /* any error is fatal now */ 714 + if (root_sym < 0) 715 + return root_sym; 716 + 717 + /* iterate over each overlay symbol */ 718 + fdt_for_each_property_offset(prop, fdto, ov_sym) { 719 + path = fdt_getprop_by_offset(fdto, prop, &name, &path_len); 720 + if (!path) 721 + return path_len; 722 + 723 + /* verify it's a string property (terminated by a single \0) */ 724 + if (path_len < 1 || memchr(path, '\0', path_len) != &path[path_len - 1]) 725 + return -FDT_ERR_BADVALUE; 726 + 727 + /* keep end marker to avoid strlen() */ 728 + e = path + path_len; 729 + 730 + /* format: /<fragment-name>/__overlay__/<relative-subnode-path> */ 731 + 732 + if (*path != '/') 733 + return -FDT_ERR_BADVALUE; 734 + 735 + /* get fragment name first */ 736 + s = strchr(path + 1, '/'); 737 + if (!s) 738 + return -FDT_ERR_BADOVERLAY; 739 + 740 + frag_name = path + 1; 741 + frag_name_len = s - path - 1; 742 + 743 + /* verify format; safe since "s" lies in \0 terminated prop */ 744 + len = sizeof("/__overlay__/") - 1; 745 + if ((e - s) < len || memcmp(s, "/__overlay__/", len)) 746 + return -FDT_ERR_BADOVERLAY; 747 + 748 + rel_path = s + len; 749 + rel_path_len = e - rel_path; 750 + 751 + /* find the fragment index in which the symbol lies */ 752 + ret = fdt_subnode_offset_namelen(fdto, 0, frag_name, 753 + frag_name_len); 754 + /* not found? */ 755 + if (ret < 0) 756 + return -FDT_ERR_BADOVERLAY; 757 + fragment = ret; 758 + 759 + /* an __overlay__ subnode must exist */ 760 + ret = fdt_subnode_offset(fdto, fragment, "__overlay__"); 761 + if (ret < 0) 762 + return -FDT_ERR_BADOVERLAY; 763 + 764 + /* get the target of the fragment */ 765 + ret = overlay_get_target(fdt, fdto, fragment, &target_path); 766 + if (ret < 0) 767 + return ret; 768 + target = ret; 769 + 770 + /* if we have a target path use */ 771 + if (!target_path) { 772 + ret = get_path_len(fdt, target); 773 + if (ret < 0) 774 + return ret; 775 + len = ret; 776 + } else { 777 + len = strlen(target_path); 778 + } 779 + 780 + ret = fdt_setprop_placeholder(fdt, root_sym, name, 781 + len + (len > 1) + rel_path_len + 1, &p); 782 + if (ret < 0) 783 + return ret; 784 + 785 + if (!target_path) { 786 + /* again in case setprop_placeholder changed it */ 787 + ret = overlay_get_target(fdt, fdto, fragment, &target_path); 788 + if (ret < 0) 789 + return ret; 790 + target = ret; 791 + } 792 + 793 + buf = p; 794 + if (len > 1) { /* target is not root */ 795 + if (!target_path) { 796 + ret = fdt_get_path(fdt, target, buf, len + 1); 797 + if (ret < 0) 798 + return ret; 799 + } else 800 + memcpy(buf, target_path, len + 1); 801 + 802 + } else 803 + len--; 804 + 805 + buf[len] = '/'; 806 + memcpy(buf + len + 1, rel_path, rel_path_len); 807 + buf[len + 1 + rel_path_len] = '\0'; 808 + } 809 + 810 + return 0; 811 + } 812 + 813 + int fdt_overlay_apply(void *fdt, void *fdto) 814 + { 815 + uint32_t delta = fdt_get_max_phandle(fdt); 816 + int ret; 817 + 818 + FDT_CHECK_HEADER(fdt); 819 + FDT_CHECK_HEADER(fdto); 820 + 821 + ret = overlay_adjust_local_phandles(fdto, delta); 822 + if (ret) 823 + goto err; 824 + 825 + ret = overlay_update_local_references(fdto, delta); 826 + if (ret) 827 + goto err; 828 + 829 + ret = overlay_fixup_phandles(fdt, fdto); 830 + if (ret) 831 + goto err; 832 + 833 + ret = overlay_merge(fdt, fdto); 834 + if (ret) 835 + goto err; 836 + 837 + ret = overlay_symbol_update(fdt, fdto); 838 + if (ret) 839 + goto err; 840 + 841 + /* 842 + * The overlay has been damaged, erase its magic. 843 + */ 844 + fdt_set_magic(fdto, ~0); 845 + 846 + return 0; 847 + 848 + err: 849 + /* 850 + * The overlay might have been damaged, erase its magic. 851 + */ 852 + fdt_set_magic(fdto, ~0); 853 + 854 + /* 855 + * The base device tree might have been damaged, erase its 856 + * magic. 857 + */ 858 + fdt_set_magic(fdt, ~0); 859 + 860 + return ret; 861 + }
+2 -2
scripts/dtc/libfdt/fdt_ro.c
··· 60 60 { 61 61 const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1); 62 62 63 - if (! p) 63 + if (!p) 64 64 /* short match */ 65 65 return 0; 66 66 ··· 327 327 const struct fdt_property *prop; 328 328 329 329 prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp); 330 - if (! prop) 330 + if (!prop) 331 331 return NULL; 332 332 333 333 return prop->data;
+19 -5
scripts/dtc/libfdt/fdt_rw.c
··· 207 207 int err; 208 208 209 209 *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); 210 - if (! (*prop)) 210 + if (!*prop) 211 211 return oldlen; 212 212 213 213 if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), ··· 269 269 return 0; 270 270 } 271 271 272 - int fdt_setprop(void *fdt, int nodeoffset, const char *name, 273 - const void *val, int len) 272 + int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name, 273 + int len, void **prop_data) 274 274 { 275 275 struct fdt_property *prop; 276 276 int err; ··· 283 283 if (err) 284 284 return err; 285 285 286 + *prop_data = prop->data; 287 + return 0; 288 + } 289 + 290 + int fdt_setprop(void *fdt, int nodeoffset, const char *name, 291 + const void *val, int len) 292 + { 293 + void *prop_data; 294 + int err; 295 + 296 + err = fdt_setprop_placeholder(fdt, nodeoffset, name, len, &prop_data); 297 + if (err) 298 + return err; 299 + 286 300 if (len) 287 - memcpy(prop->data, val, len); 301 + memcpy(prop_data, val, len); 288 302 return 0; 289 303 } 290 304 ··· 337 323 FDT_RW_CHECK_HEADER(fdt); 338 324 339 325 prop = fdt_get_property_w(fdt, nodeoffset, name, &len); 340 - if (! prop) 326 + if (!prop) 341 327 return len; 342 328 343 329 proplen = sizeof(*prop) + FDT_TAGALIGN(len);
+14 -2
scripts/dtc/libfdt/fdt_sw.c
··· 220 220 return offset; 221 221 } 222 222 223 - int fdt_property(void *fdt, const char *name, const void *val, int len) 223 + int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp) 224 224 { 225 225 struct fdt_property *prop; 226 226 int nameoff; ··· 238 238 prop->tag = cpu_to_fdt32(FDT_PROP); 239 239 prop->nameoff = cpu_to_fdt32(nameoff); 240 240 prop->len = cpu_to_fdt32(len); 241 - memcpy(prop->data, val, len); 241 + *valp = prop->data; 242 + return 0; 243 + } 244 + 245 + int fdt_property(void *fdt, const char *name, const void *val, int len) 246 + { 247 + void *ptr; 248 + int ret; 249 + 250 + ret = fdt_property_placeholder(fdt, name, len, &ptr); 251 + if (ret) 252 + return ret; 253 + memcpy(ptr, val, len); 242 254 return 0; 243 255 } 244 256
+2 -2
scripts/dtc/libfdt/fdt_wip.c
··· 82 82 int proplen; 83 83 84 84 propval = fdt_getprop(fdt, nodeoffset, name, &proplen); 85 - if (! propval) 85 + if (!propval) 86 86 return proplen; 87 87 88 88 if (proplen != len) ··· 107 107 int len; 108 108 109 109 prop = fdt_get_property_w(fdt, nodeoffset, name, &len); 110 - if (! prop) 110 + if (!prop) 111 111 return len; 112 112 113 113 _fdt_nop_region(prop, len + sizeof(*prop));
+47
scripts/dtc/libfdt/libfdt.h
··· 1314 1314 { 1315 1315 return fdt_property_u32(fdt, name, val); 1316 1316 } 1317 + 1318 + /** 1319 + * fdt_property_placeholder - add a new property and return a ptr to its value 1320 + * 1321 + * @fdt: pointer to the device tree blob 1322 + * @name: name of property to add 1323 + * @len: length of property value in bytes 1324 + * @valp: returns a pointer to where where the value should be placed 1325 + * 1326 + * returns: 1327 + * 0, on success 1328 + * -FDT_ERR_BADMAGIC, 1329 + * -FDT_ERR_NOSPACE, standard meanings 1330 + */ 1331 + int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp); 1332 + 1317 1333 #define fdt_property_string(fdt, name, str) \ 1318 1334 fdt_property(fdt, name, str, strlen(str)+1) 1319 1335 int fdt_end_node(void *fdt); ··· 1447 1431 */ 1448 1432 int fdt_setprop(void *fdt, int nodeoffset, const char *name, 1449 1433 const void *val, int len); 1434 + 1435 + /** 1436 + * fdt_setprop _placeholder - allocate space for a property 1437 + * @fdt: pointer to the device tree blob 1438 + * @nodeoffset: offset of the node whose property to change 1439 + * @name: name of the property to change 1440 + * @len: length of the property value 1441 + * @prop_data: return pointer to property data 1442 + * 1443 + * fdt_setprop_placeholer() allocates the named property in the given node. 1444 + * If the property exists it is resized. In either case a pointer to the 1445 + * property data is returned. 1446 + * 1447 + * This function may insert or delete data from the blob, and will 1448 + * therefore change the offsets of some existing nodes. 1449 + * 1450 + * returns: 1451 + * 0, on success 1452 + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1453 + * contain the new property value 1454 + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1455 + * -FDT_ERR_BADLAYOUT, 1456 + * -FDT_ERR_BADMAGIC, 1457 + * -FDT_ERR_BADVERSION, 1458 + * -FDT_ERR_BADSTATE, 1459 + * -FDT_ERR_BADSTRUCTURE, 1460 + * -FDT_ERR_BADLAYOUT, 1461 + * -FDT_ERR_TRUNCATED, standard meanings 1462 + */ 1463 + int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name, 1464 + int len, void **prop_data); 1450 1465 1451 1466 /** 1452 1467 * fdt_setprop_u32 - set a property to a 32-bit integer
+30 -1
scripts/dtc/livetree.c
··· 216 216 return old_node; 217 217 } 218 218 219 + void add_orphan_node(struct node *dt, struct node *new_node, char *ref) 220 + { 221 + static unsigned int next_orphan_fragment = 0; 222 + struct node *node; 223 + struct property *p; 224 + struct data d = empty_data; 225 + char *name; 226 + 227 + d = data_add_marker(d, REF_PHANDLE, ref); 228 + d = data_append_integer(d, 0xffffffff, 32); 229 + 230 + p = build_property("target", d); 231 + 232 + xasprintf(&name, "fragment@%u", 233 + next_orphan_fragment++); 234 + name_node(new_node, "__overlay__"); 235 + node = build_node(p, new_node); 236 + name_node(node, name); 237 + 238 + add_child(dt, node); 239 + } 240 + 219 241 struct node *chain_node(struct node *first, struct node *list) 220 242 { 221 243 assert(first->next_sibling == NULL); ··· 418 396 return fdt32_to_cpu(*((fdt32_t *)prop->val.val)); 419 397 } 420 398 399 + cell_t propval_cell_n(struct property *prop, int n) 400 + { 401 + assert(prop->val.len / sizeof(cell_t) >= n); 402 + return fdt32_to_cpu(*((fdt32_t *)prop->val.val + n)); 403 + } 404 + 421 405 struct property *get_property_by_label(struct node *tree, const char *label, 422 406 struct node **node) 423 407 { ··· 506 478 p = strchr(path, '/'); 507 479 508 480 for_each_child(tree, child) { 509 - if (p && strneq(path, child->name, p-path)) 481 + if (p && (strlen(child->name) == p-path) && 482 + strneq(path, child->name, p-path)) 510 483 return get_node_by_path(child, p+1); 511 484 else if (!p && streq(path, child->name)) 512 485 return child;
+3 -1
scripts/dtc/update-dtc-source.sh
··· 35 35 srcpos.h treesource.c util.c util.h version_gen.h Makefile.dtc \ 36 36 dtc-lexer.l dtc-parser.y" 37 37 DTC_GENERATED="dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h" 38 - 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" 38 + LIBFDT_SOURCE="Makefile.libfdt fdt.c fdt.h fdt_addresses.c fdt_empty_tree.c \ 39 + fdt_overlay.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c \ 40 + fdt_wip.c libfdt.h libfdt_env.h libfdt_internal.h" 39 41 40 42 get_last_dtc_version() { 41 43 git log --oneline scripts/dtc/ | grep 'upstream' | head -1 | sed -e 's/^.* \(.*\)/\1/'
+1 -1
scripts/dtc/version_gen.h
··· 1 - #define DTC_VERSION "DTC 1.4.4-g756ffc4f" 1 + #define DTC_VERSION "DTC 1.4.5-gc1e55a55"