Commit 030672ae authored by Linus Torvalds's avatar Linus Torvalds

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

Pull Devicetree updates from Rob Herring:
 "The biggest highlight here is the start of using json-schema for DT
  bindings. Being able to validate bindings has been discussed for years
  with little progress.

   - Initial support for DT bindings using json-schema language. This is
     the start of converting DT bindings from free-form text to a
     structured format.

   - Reworking of initrd address initialization. This moves to using the
     phys address instead of virt addr in the DT parsing code. This
     rework was motivated by CONFIG_DEV_BLK_INITRD causing unnecessary
     rebuilding of lots of files.

   - Fix stale phandle entries in phandle cache

   - DT overlay validation improvements. This exposed several memory
     leak bugs which have been fixed.

   - Use node name and device_type helper functions in DT code

   - Last remaining conversions to using %pOFn printk specifier instead
     of device_node.name directly

   - Create new common RTC binding doc and move all trivial RTC devices
     out of trivial-devices.txt.

   - New bindings for Freescale MAG3110 magnetometer, Cadence Sierra
     PHY, and Xen shared memory

   - Update dtc to upstream version v1.4.7-57-gf267e674d145"

* tag 'devicetree-for-4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (68 commits)
  of: __of_detach_node() - remove node from phandle cache
  of: of_node_get()/of_node_put() nodes held in phandle cache
  gpio-omap.txt: add reg and interrupts properties
  dt-bindings: mrvl,intc: fix a trivial typo
  dt-bindings: iio: magnetometer: add dt-bindings for freescale mag3110
  dt-bindings: Convert trivial-devices.txt to json-schema
  dt-bindings: arm: mrvl: amend Browstone compatible string
  dt-bindings: arm: Convert Tegra board/soc bindings to json-schema
  dt-bindings: arm: Convert ZTE board/soc bindings to json-schema
  dt-bindings: arm: Add missing Xilinx boards
  dt-bindings: arm: Convert Xilinx board/soc bindings to json-schema
  dt-bindings: arm: Convert VIA board/soc bindings to json-schema
  dt-bindings: arm: Convert ST STi board/soc bindings to json-schema
  dt-bindings: arm: Convert SPEAr board/soc bindings to json-schema
  dt-bindings: arm: Convert CSR SiRF board/soc bindings to json-schema
  dt-bindings: arm: Convert QCom board/soc bindings to json-schema
  dt-bindings: arm: Convert TI nspire board/soc bindings to json-schema
  dt-bindings: arm: Convert TI davinci board/soc bindings to json-schema
  dt-bindings: arm: Convert Calxeda board/soc bindings to json-schema
  dt-bindings: arm: Convert Altera board/soc bindings to json-schema
  ...
parents 24dc8363 5801169a
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*.bin *.bin
*.bz2 *.bz2
*.c.[012]*.* *.c.[012]*.*
*.dt.yaml
*.dtb *.dtb
*.dtb.S *.dtb.S
*.dwo *.dwo
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Makefile for Sphinx documentation # Makefile for Sphinx documentation
# #
subdir-y := subdir-y := devicetree/bindings/
# You can set these variables from the command line. # You can set these variables from the command line.
SPHINXBUILD = sphinx-build SPHINXBUILD = sphinx-build
......
*.example.dts
processed-schema.yaml
# SPDX-License-Identifier: GPL-2.0
DT_DOC_CHECKER ?= dt-doc-validate
DT_EXTRACT_EX ?= dt-extract-example
DT_MK_SCHEMA ?= dt-mk-schema
DT_MK_SCHEMA_FLAGS := $(if $(DT_SCHEMA_FILES), -u)
quiet_cmd_chk_binding = CHKDT $(patsubst $(srctree)/%,%,$<)
cmd_chk_binding = $(DT_DOC_CHECKER) $< ; \
$(DT_EXTRACT_EX) $< > $@
$(obj)/%.example.dts: $(src)/%.yaml FORCE
$(call if_changed,chk_binding)
DT_TMP_SCHEMA := processed-schema.yaml
extra-y += $(DT_TMP_SCHEMA)
quiet_cmd_mk_schema = SCHEMA $@
cmd_mk_schema = $(DT_MK_SCHEMA) $(DT_MK_SCHEMA_FLAGS) -o $@ $(filter-out FORCE, $^)
DT_DOCS = $(shell cd $(srctree)/$(src) && find * -name '*.yaml')
DT_SCHEMA_FILES ?= $(addprefix $(src)/,$(DT_DOCS))
extra-y += $(patsubst $(src)/%.yaml,%.example.dts, $(DT_SCHEMA_FILES))
extra-y += $(patsubst $(src)/%.yaml,%.example.dtb, $(DT_SCHEMA_FILES))
$(obj)/$(DT_TMP_SCHEMA): $(DT_SCHEMA_FILES) FORCE
$(call if_changed,mk_schema)
Altera's SoCFPGA platform device tree bindings
---------------------------------------------
Boards with Cyclone 5 SoC:
Required root node properties:
compatible = "altr,socfpga-cyclone5", "altr,socfpga";
Boards with Arria 5 SoC:
Required root node properties:
compatible = "altr,socfpga-arria5", "altr,socfpga";
Boards with Arria 10 SoC:
Required root node properties:
compatible = "altr,socfpga-arria10", "altr,socfpga";
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/arm/altera.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Altera's SoCFPGA platform device tree bindings
maintainers:
- Dinh Nguyen <dinguyen@kernel.org>
properties:
compatible:
items:
- enum:
- altr,socfpga-cyclone5
- altr,socfpga-arria5
- altr,socfpga-arria10
- const: altr,socfpga
...
Altera SOCFPGA Clock Manager
Required properties:
- compatible : "altr,clk-mgr"
- reg : Should contain base address and length for Clock Manager
Example:
clkmgr@ffd04000 {
compatible = "altr,clk-mgr";
reg = <0xffd04000 0x1000>;
};
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/arm/altera/socfpga-clk-manager.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Altera SOCFPGA Clock Manager
maintainers:
- Dinh Nguyen <dinguyen@kernel.org>
description: test
properties:
compatible:
items:
- const: altr,clk-mgr
reg:
maxItems: 1
required:
- compatible
examples:
- |
clkmgr@ffd04000 {
compatible = "altr,clk-mgr";
reg = <0xffd04000 0x1000>;
};
...
Calxeda Platforms Device Tree Bindings
-----------------------------------------------
Boards with Calxeda Cortex-A9 based ECX-1000 (Highbank) SOC shall have the
following properties.
Required root node properties:
- compatible = "calxeda,highbank";
Boards with Calxeda Cortex-A15 based ECX-2000 SOC shall have the following
properties.
Required root node properties:
- compatible = "calxeda,ecx-2000";
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/arm/calxeda.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Calxeda Platforms Device Tree Bindings
maintainers:
- Rob Herring <robh@kernel.org>
description: |+
Bindings for boards with Calxeda Cortex-A9 based ECX-1000 (Highbank) SOC
or Cortex-A15 based ECX-2000 SOCs
properties:
$nodename:
const: '/'
compatible:
items:
- enum:
- calxeda,highbank
- calxeda,ecx-2000
This diff is collapsed.
This diff is collapsed.
Texas Instruments DaVinci Platforms Device Tree Bindings
--------------------------------------------------------
DA850/OMAP-L138/AM18x Evaluation Module (EVM) board
Required root node properties:
- compatible = "ti,da850-evm", "ti,da850";
DA850/OMAP-L138/AM18x L138/C6748 Development Kit (LCDK) board
Required root node properties:
- compatible = "ti,da850-lcdk", "ti,da850";
EnBW AM1808 based CMC board
Required root node properties:
- compatible = "enbw,cmc", "ti,da850;
LEGO MINDSTORMS EV3 (AM1808 based)
Required root node properties:
- compatible = "lego,ev3", "ti,da850";
Generic DaVinci Boards
----------------------
DA850/OMAP-L138/AM18x generic board
Required root node properties:
- compatible = "ti,da850";
...@@ -11,4 +11,4 @@ Required root node properties: ...@@ -11,4 +11,4 @@ Required root node properties:
MMP2 Brownstone Board MMP2 Brownstone Board
Required root node properties: Required root node properties:
- compatible = "mrvl,mmp2-brownstone"; - compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2";
TI-NSPIRE calculators
Required properties:
- compatible: Compatible property value should contain "ti,nspire".
CX models should have "ti,nspire-cx"
Touchpad models should have "ti,nspire-tp"
Clickpad models should have "ti,nspire-clp"
Example:
/ {
model = "TI-NSPIRE CX";
compatible = "ti,nspire-cx";
...
* ARM Primecell Peripherals
ARM, Ltd. Primecell peripherals have a standard id register that can be used to
identify the peripheral type, vendor, and revision. This value can be used for
driver matching.
Required properties:
- compatible : should be a specific name for the peripheral and
"arm,primecell". The specific name will match the ARM
engineering name for the logic block in the form: "arm,pl???"
Optional properties:
- arm,primecell-periphid : Value to override the h/w value with
- clocks : From common clock binding. First clock is phandle to clock for apb
pclk. Additional clocks are optional and specific to those peripherals.
- clock-names : From common clock binding. Shall be "apb_pclk" for first clock.
- dmas : From common DMA binding. If present, refers to one or more dma channels.
- dma-names : From common DMA binding, needs to match the 'dmas' property.
Devices with exactly one receive and transmit channel shall name
these "rx" and "tx", respectively.
- pinctrl-<n> : Pinctrl states as described in bindings/pinctrl/pinctrl-bindings.txt
- pinctrl-names : Names corresponding to the numbered pinctrl states
- interrupts : one or more interrupt specifiers
- interrupt-names : names corresponding to the interrupts properties
Example:
serial@fff36000 {
compatible = "arm,pl011", "arm,primecell";
arm,primecell-periphid = <0x00341011>;
clocks = <&pclk>;
clock-names = "apb_pclk";
dmas = <&dma-controller 4>, <&dma-controller 5>;
dma-names = "rx", "tx";
pinctrl-0 = <&uart0_default_mux>, <&uart0_default_mode>;
pinctrl-1 = <&uart0_sleep_mode>;
pinctrl-names = "default","sleep";
interrupts = <0 11 0x4>;
};
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/arm/primecell.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ARM Primecell Peripherals
maintainers:
- Rob Herring <robh@kernel.org>
description: |+
ARM, Ltd. Primecell peripherals have a standard id register that can be used to
identify the peripheral type, vendor, and revision. This value can be used for
driver matching.
properties:
compatible:
contains:
const: arm,primecell
description:
Should be a specific name for the peripheral followed by "arm,primecell".
The specific name will match the ARM engineering name for the logic block
in the form "arm,pl???"
arm,primecell-periphid:
$ref: /schemas/types.yaml#/definitions/uint32
description: Value to override the h/w ID value
clocks:
minItems: 1
maxItems: 32
clock-names:
contains:
const: apb_pclk
additionalItems: true
...
QCOM device tree bindings
-------------------------
Some qcom based bootloaders identify the dtb blob based on a set of
device properties like SoC and platform and revisions of those components.
To support this scheme, we encode this information into the board compatible
string.
Each board must specify a top-level board compatible string with the following
format:
compatible = "qcom,<SoC>[-<soc_version>][-<foundry_id>]-<board>[/<subtype>][-<board_version>]"
The 'SoC' and 'board' elements are required. All other elements are optional.
The 'SoC' element must be one of the following strings:
apq8016
apq8074
apq8084
apq8096
msm8916
msm8974
msm8992
msm8994
msm8996
mdm9615
ipq8074
sdm845
The 'board' element must be one of the following strings:
cdp
liquid
dragonboard
mtp
sbc
hk01
The 'soc_version' and 'board_version' elements take the form of v<Major>.<Minor>
where the minor number may be omitted when it's zero, i.e. v1.0 is the same
as v1. If all versions of the 'board_version' elements match, then a
wildcard '*' should be used, e.g. 'v*'.
The 'foundry_id' and 'subtype' elements are one or more digits from 0 to 9.
Examples:
"qcom,msm8916-v1-cdp-pm8916-v2.1"
A CDP board with an msm8916 SoC, version 1 paired with a pm8916 PMIC of version
2.1.
"qcom,apq8074-v2.0-2-dragonboard/1-v0.1"
A dragonboard board v0.1 of subtype 1 with an apq8074 SoC version 2, made in
foundry 2.
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/bindings/arm/qcom.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: QCOM device tree bindings
maintainers:
- Stephen Boyd <sboyd@codeaurora.org>
description: |
Some qcom based bootloaders identify the dtb blob based on a set of
device properties like SoC and platform and revisions of those components.
To support this scheme, we encode this information into the board compatible
string.
Each board must specify a top-level board compatible string with the following
format:
compatible = "qcom,<SoC>[-<soc_version>][-<foundry_id>]-<board>[/<subtype>][-<board_version>]"
The 'SoC' and 'board' elements are required. All other elements are optional.
The 'SoC' element must be one of the following strings:
apq8016
apq8074
apq8084
apq8096
msm8916
msm8974
msm8992
msm8994
msm8996
mdm9615
ipq8074
sdm845
The 'board' element must be one of the following strings:
cdp
liquid
dragonboard
mtp
sbc
hk01
The 'soc_version' and 'board_version' elements take the form of v<Major>.<Minor>
where the minor number may be omitted when it's zero, i.e. v1.0 is the same
as v1. If all versions of the 'board_version' elements match, then a
wildcard '*' should be used, e.g. 'v*'.
The 'foundry_id' and 'subtype' elements are one or more digits from 0 to 9.
Examples:
"qcom,msm8916-v1-cdp-pm8916-v2.1"
A CDP board with an msm8916 SoC, version 1 paired with a pm8916 PMIC of version
2.1.
"qcom,apq8074-v2.0-2-dragonboard/1-v0.1"
A dragonboard board v0.1 of subtype 1 with an apq8074 SoC version 2, made in
foundry 2.
properties:
compatible:
oneOf:
- items:
- enum:
- qcom,apq8016-sbc
- const: qcom,apq8016
- items:
- enum:
- qcom,apq8064-cm-qs600
- qcom,apq8064-ifc6410
- const: qcom,apq8064
- items:
- enum:
- qcom,apq8074-dragonboard
- const: qcom,apq8074
- items:
- enum:
- qcom,apq8060-dragonboard
- qcom,msm8660-surf
- const: qcom,msm8660
- items:
- enum:
- qcom,apq8084-mtp
- qcom,apq8084-sbc
- const: qcom,apq8084
- items:
- enum:
- qcom,msm8960-cdp
- const: qcom,msm8960
- items:
- const: qcom,msm8916-mtp/1
- const: qcom,msm8916-mtp
- const: qcom,msm8916
- items:
- const: qcom,msm8996-mtp
- items:
- const: qcom,ipq4019
- items:
- enum:
- qcom,ipq8064-ap148
- const: qcom,ipq8064
- items:
- enum:
- qcom,ipq8074-hk01
- const: qcom,ipq8074
...
CSR SiRFprimaII and SiRFmarco device tree bindings.
========================================
Required root node properties:
- compatible:
- "sirf,atlas6-cb" : atlas6 "cb" evaluation board
- "sirf,atlas6" : atlas6 device based board
- "sirf,atlas7-cb" : atlas7 "cb" evaluation board
- "sirf,atlas7" : atlas7 device based board
- "sirf,prima2-cb" : prima2 "cb" evaluation board
- "sirf,prima2" : prima2 device based board
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/arm/sirf.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: CSR SiRFprimaII and SiRFmarco device tree bindings.
maintainers:
- Binghua Duan <binghua.duan@csr.com>
- Barry Song <Baohua.Song@csr.com>
properties:
$nodename:
const: '/'
compatible:
oneOf:
- items:
- const: sirf,atlas6-cb
- const: sirf,atlas6
- items:
- const: sirf,atlas7-cb
- const: sirf,atlas7
- items:
- const: sirf,prima2-cb
- const: sirf,prima2
...
ST SPEAr Platforms Device Tree Bindings
---------------------------------------
Boards with the ST SPEAr600 SoC shall have the following properties:
Required root node property:
compatible = "st,spear600";
Boards with the ST SPEAr300 SoC shall have the following properties:
Required root node property:
compatible = "st,spear300";
Boards with the ST SPEAr310 SoC shall have the following properties:
Required root node property:
compatible = "st,spear310";
Boards with the ST SPEAr320 SoC shall have the following properties:
Required root node property:
compatible = "st,spear320";
Boards with the ST SPEAr1310 SoC shall have the following properties:
Required root node property:
compatible = "st,spear1310";
Boards with the ST SPEAr1340 SoC shall have the following properties:
Required root node property:
compatible = "st,spear1340";
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/arm/spear.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ST SPEAr Platforms Device Tree Bindings
maintainers:
- Viresh Kumar <vireshk@kernel.org>
- Stefan Roese <sr@denx.de>
properties:
$nodename:
const: '/'
compatible:
items:
- enum:
- st,spear600
- st,spear300
- st,spear310
- st,spear320
- st,spear1310
- st,spear1340
...
ST STi Platforms Device Tree Bindings
---------------------------------------
Boards with the ST STiH415 SoC shall have the following properties:
Required root node property:
compatible = "st,stih415";
Boards with the ST STiH416 SoC shall have the following properties:
Required root node property:
compatible = "st,stih416";
Boards with the ST STiH407 SoC shall have the following properties:
Required root node property:
compatible = "st,stih407";
Boards with the ST STiH410 SoC shall have the following properties:
Required root node property:
compatible = "st,stih410";
Boards with the ST STiH418 SoC shall have the following properties:
Required root node property:
compatible = "st,stih418";
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/arm/sti.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ST STi Platforms Device Tree Bindings
maintainers:
- Patrice Chotard <patrice.chotard@st.com>
properties:
$nodename:
const: '/'
compatible:
items:
- enum:
- st,stih415
- st,stih416
- st,stih407
- st,stih410
- st,stih418
...
NVIDIA Tegra device tree bindings
-------------------------------------------
SoCs
-------------------------------------------
Each device tree must specify which Tegra SoC it uses, using one of the
following compatible values:
nvidia,tegra20
nvidia,tegra30
nvidia,tegra114
nvidia,tegra124
nvidia,tegra132
nvidia,tegra210
nvidia,tegra186
nvidia,tegra194
Boards
-------------------------------------------
Each device tree must specify which one or more of the following
board-specific compatible values:
ad,medcom-wide
ad,plutux
ad,tamonten
ad,tec
compal,paz00
compulab,trimslice
nvidia,beaver
nvidia,cardhu
nvidia,cardhu-a02
nvidia,cardhu-a04
nvidia,dalmore
nvidia,harmony
nvidia,jetson-tk1
nvidia,norrin
nvidia,p2371-0000
nvidia,p2371-2180
nvidia,p2571
nvidia,p2771-0000
nvidia,p2972-0000
nvidia,roth
nvidia,seaboard
nvidia,tn7
nvidia,ventana
toradex,apalis_t30
toradex,apalis_t30-eval
toradex,apalis_t30-v1.1
toradex,apalis_t30-v1.1-eval
toradex,apalis-tk1
toradex,apalis-tk1-eval
toradex,apalis-tk1-v1.2
toradex,apalis-tk1-v1.2-eval
toradex,colibri_t20
toradex,colibri_t20-eval-v3
toradex,colibri_t20-iris
toradex,colibri_t30
toradex,colibri_t30-eval-v3
Trusted Foundations
-------------------------------------------
Tegra supports the Trusted Foundation secure monitor. See the
"tlm,trusted-foundations" binding's documentation for more details.
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/arm/tegra.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NVIDIA Tegra device tree bindings
maintainers:
- Thierry Reding <thierry.reding@gmail.com>
- Jonathan Hunter <jonathanh@nvidia.com>
properties:
compatible:
oneOf:
- items:
- enum:
- compal,paz00
- compulab,trimslice
- nvidia,harmony
- nvidia,seaboard
- nvidia,ventana
- const: nvidia,tegra20
- items:
- enum:
- ad,medcom-wide
- ad,plutux
- ad,tec
- const: ad,tamonten
- const: nvidia,tegra20
- items:
- enum:
- toradex,colibri_t20-eval-v3
- toradex,colibri_t20-iris
- const: toradex,colibri_t20
- const: nvidia,tegra20
- items:
- enum:
- nvidia,beaver
- const: nvidia,tegra30
- items:
- enum:
- nvidia,cardhu-a02
- nvidia,cardhu-a04
- const: nvidia,cardhu
- const: nvidia,tegra30
- items:
- const: toradex,apalis_t30-eval
- const: toradex,apalis_t30
- const: nvidia,tegra30
- items:
- const: toradex,apalis_t30-eval-v1.1
- const: toradex,apalis_t30-eval
- const: toradex,apalis_t30-v1.1
- const: toradex,apalis_t30
- const: nvidia,tegra30
- items:
- enum:
- toradex,colibri_t30-eval-v3
- const: toradex,colibri_t30
- const: nvidia,tegra30
- items:
- enum:
- nvidia,dalmore
- nvidia,roth
- nvidia,tn7
- const: nvidia,tegra114
- items:
- enum:
- nvidia,jetson-tk1
- nvidia,venice2
- const: nvidia,tegra124
- items:
- const: toradex,apalis-tk1-eval
- const: toradex,apalis-tk1
- const: nvidia,tegra124
- items:
- const: toradex,apalis-tk1-v1.2-eval
- const: toradex,apalis-tk1-eval
- const: toradex,apalis-tk1-v1.2
- const: toradex,apalis-tk1
- const: nvidia,tegra124
- items:
- enum:
- nvidia,norrin
- const: nvidia,tegra132
- const: nvidia,tegra124
- items:
- enum:
- nvidia,p2371-0000
- nvidia,p2371-2180
- nvidia,p2571
- const: nvidia,tegra210
- items:
- enum:
- nvidia,p2771-0000
- const: nvidia,tegra186
- items:
- enum:
- nvidia,p2972-0000
- const: nvidia,tegra194
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/arm/ti/nspire.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TI-NSPIRE calculators
maintainers:
- Daniel Tang <dt.tangr@gmail.com>
properties:
$nodename:
const: '/'
compatible:
items:
- enum:
# CX models
- ti,nspire-cx
# Touchpad models
- ti,nspire-tp
# Clickpad models
- ti,nspire-clp
...
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/arm/ti/davinci.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments DaVinci Platforms Device Tree Bindings
maintainers:
- Sekhar Nori <nsekhar@ti.com>
description:
DA850/OMAP-L138/AM18x based boards
properties:
$nodename:
const: '/'
compatible:
items:
- enum:
- ti,da850-evm # DA850/OMAP-L138/AM18x Evaluation Module (EVM) board
- ti,da850-lcdk # DA850/OMAP-L138/AM18x L138/C6748 Development Kit (LCDK) board
- enbw,cmc # EnBW AM1808 based CMC board
- lego,ev3 # LEGO MINDSTORMS EV3 (AM1808 based)
- const: ti,da850
...
VIA/Wondermedia VT8500 Platforms Device Tree Bindings
---------------------------------------
Boards with the VIA VT8500 SoC shall have the following properties:
Required root node property:
compatible = "via,vt8500";
Boards with the Wondermedia WM8505 SoC shall have the following properties:
Required root node property:
compatible = "wm,wm8505";
Boards with the Wondermedia WM8650 SoC shall have the following properties:
Required root node property:
compatible = "wm,wm8650";
Boards with the Wondermedia WM8750 SoC shall have the following properties:
Required root node property:
compatible = "wm,wm8750";
Boards with the Wondermedia WM8850 SoC shall have the following properties:
Required root node property:
compatible = "wm,wm8850";
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/arm/vt8500.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: VIA/Wondermedia VT8500 Platforms Device Tree Bindings
maintainers:
- Tony Prisk <linux@prisktech.co.nz>
description: test
properties:
$nodename:
const: '/'
compatible:
items:
- enum:
- via,vt8500
- wm,wm8505
- wm,wm8650
- wm,wm8750
- wm,wm8850
Xilinx Zynq Platforms Device Tree Bindings
Boards with Zynq-7000 SOC based on an ARM Cortex A9 processor
shall have the following properties.
Required root node properties:
- compatible = "xlnx,zynq-7000";
Additional compatible strings:
- Adapteva Parallella board
"adapteva,parallella"
- Avnet MicroZed board
"avnet,zynq-microzed"
"xlnx,zynq-microzed"
- Avnet ZedBoard board
"avnet,zynq-zed"
"xlnx,zynq-zed"
- Digilent Zybo board
"digilent,zynq-zybo"
- Digilent Zybo Z7 board
"digilent,zynq-zybo-z7"
- Xilinx CC108 internal board
"xlnx,zynq-cc108"
- Xilinx ZC702 internal board
"xlnx,zynq-zc702"
- Xilinx ZC706 internal board
"xlnx,zynq-zc706"
- Xilinx ZC770 internal board, with different FMC cards
"xlnx,zynq-zc770-xm010"
"xlnx,zynq-zc770-xm011"
"xlnx,zynq-zc770-xm012"
"xlnx,zynq-zc770-xm013"
---------------------------------------------------------------
Xilinx Zynq UltraScale+ MPSoC Platforms Device Tree Bindings
Boards with ZynqMP SOC based on an ARM Cortex A53 processor
shall have the following properties.
Required root node properties:
- compatible = "xlnx,zynqmp";
Additional compatible strings:
- Xilinx internal board zc1232
"xlnx,zynqmp-zc1232-revA", "xlnx,zynqmp-zc1232"
- Xilinx internal board zc1254
"xlnx,zynqmp-zc1254-revA", "xlnx,zynqmp-zc1254"
- Xilinx internal board zc1275
"xlnx,zynqmp-zc1275-revA", "xlnx,zynqmp-zc1275"
- Xilinx internal board zc1751
"xlnx,zynqmp-zc1751"
- Xilinx 96boards compatible board zcu100
"xlnx,zynqmp-zcu100-revC", "xlnx,zynqmp-zcu100"
- Xilinx evaluation board zcu102
"xlnx,zynqmp-zcu102-revA", "xlnx,zynqmp-zcu102"
"xlnx,zynqmp-zcu102-revB", "xlnx,zynqmp-zcu102"
"xlnx,zynqmp-zcu102-rev1.0", "xlnx,zynqmp-zcu102"
- Xilinx evaluation board zcu104
"xlnx,zynqmp-zcu104-revA", "xlnx,zynqmp-zcu104"
- Xilinx evaluation board zcu106
"xlnx,zynqmp-zcu106-revA", "xlnx,zynqmp-zcu106"
- Xilinx evaluation board zcu111
"xlnx,zynqmp-zcu111-revA", "xlnx,zynqmp-zcu111"
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/arm/xilinx.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Xilinx Zynq Platforms Device Tree Bindings
maintainers:
- Michal Simek <michal.simek@xilinx.com>
description: |
Xilinx boards with Zynq-7000 SOC or Zynq UltraScale+ MPSoC
properties:
$nodename:
const: '/'
compatible:
oneOf:
- items:
- enum:
- adapteva,parallella
- digilent,zynq-zybo
- digilent,zynq-zybo-z7
- xlnx,zynq-cc108
- xlnx,zynq-zc702
- xlnx,zynq-zc706
- xlnx,zynq-zc770-xm010
- xlnx,zynq-zc770-xm011
- xlnx,zynq-zc770-xm012
- xlnx,zynq-zc770-xm013
- const: xlnx,zynq-7000
- items:
- const: avnet,zynq-microzed
- const: xlnx,zynq-microzed
- const: xlnx,zynq-7000
- items:
- const: avnet,zynq-zed
- const: xlnx,zynq-zed
- const: xlnx,zynq-7000
- items:
- enum:
- xlnx,zynqmp-zc1751
- const: xlnx,zynqmp
- description: Xilinx internal board zc1232
items:
- const: xlnx,zynqmp-zc1232-revA
- const: xlnx,zynqmp-zc1232
- const: xlnx,zynqmp
- description: Xilinx internal board zc1254
items:
- const: xlnx,zynqmp-zc1254-revA
- const: xlnx,zynqmp-zc1254
- const: xlnx,zynqmp
- description: Xilinx internal board zc1275
items:
- const: xlnx,zynqmp-zc1275-revA
- const: xlnx,zynqmp-zc1275
- const: xlnx,zynqmp
- description: Xilinx 96boards compatible board zcu100
items:
- const: xlnx,zynqmp-zcu100-revC
- const: xlnx,zynqmp-zcu100
- const: xlnx,zynqmp
- description: Xilinx 96boards compatible board Ultra96
items:
- const: avnet,ultra96-rev1
- const: avnet,ultra96
- const: xlnx,zynqmp-zcu100-revC
- const: xlnx,zynqmp-zcu100
- const: xlnx,zynqmp
- description: Xilinx evaluation board zcu102
items:
- enum:
- xlnx,zynqmp-zcu102-revA
- xlnx,zynqmp-zcu102-revB
- xlnx,zynqmp-zcu102-rev1.0
- const: xlnx,zynqmp-zcu102
- const: xlnx,zynqmp
- description: Xilinx evaluation board zcu104
items:
- enum:
- xlnx,zynqmp-zcu104-revA
- xlnx,zynqmp-zcu104-rev1.0
- const: xlnx,zynqmp-zcu104
- const: xlnx,zynqmp
- description: Xilinx evaluation board zcu106
items:
- enum:
- xlnx,zynqmp-zcu106-revA
- xlnx,zynqmp-zcu106-rev1.0
- const: xlnx,zynqmp-zcu106
- const: xlnx,zynqmp
- description: Xilinx evaluation board zcu111
items:
- enum:
- xlnx,zynqmp-zcu111-revA
- xlnx,zynqmp-zcu11-rev1.0
- const: xlnx,zynqmp-zcu111
- const: xlnx,zynqmp
...
ZTE platforms device tree bindings
---------------------------------------
- ZX296702 board:
Required root node properties:
- compatible = "zte,zx296702-ad1", "zte,zx296702"
---------------------------------------
- ZX296718 SoC:
Required root node properties:
- compatible = "zte,zx296718"
ZX296718 EVB board:
- "zte,zx296718-evb"
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/arm/zte.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ZTE platforms device tree bindings
maintainers:
- Jun Nie <jun.nie@linaro.org>
properties:
$nodename:
const: '/'
compatible:
oneOf:
- items:
- enum:
- zte,zx296702-ad1
- const: zte,zx296702
- items:
- enum:
- zte,zx296718-evb
- const: zte,zx296718
...
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
# Copyright 2018 Linaro Ltd.
%YAML 1.2
---
# All the top-level keys are standard json-schema keywords except for
# 'maintainers' and 'select'
# $id is a unique idenifier based on the filename. There may or may not be a
# file present at the URL.
$id: "http://devicetree.org/schemas/example-schema.yaml#"
# $schema is the meta-schema this schema should be validated with.
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
title: An example schema annotated with jsonschema details
maintainers:
- Rob Herring <robh@kernel.org>
description: |
A more detailed multi-line description of the binding.
Details about the hardware device and any links to datasheets can go here.
Literal blocks are marked with the '|' at the beginning. The end is marked by
indentation less than the first line of the literal block. Lines also cannot
begin with a tab character.
select: false
# 'select' is a schema applied to a DT node to determine if this binding
# schema should be applied to the node. It is optional and by default the
# possible compatible strings are extracted and used to match.
# In this case, a 'false' schema will never match.
properties:
# A dictionary of DT properties for this binding schema
compatible:
# More complicated schema can use oneOf (XOR), anyOf (OR), or allOf (AND)
# to handle different conditions.
# In this case, it's needed to handle a variable number of values as there
# isn't another way to express a constraint of the last string value.
# The boolean schema must be a list of schemas.
oneOf:
- items:
# items is a list of possible values for the property. The number of
# values is determined by the number of elements in the list.
# Order in lists is significant, order in dicts is not
# Must be one of the 1st enums followed by the 2nd enum
#
# Each element in items should be 'enum' or 'const'
- enum:
- vendor,soc4-ip
- vendor,soc3-ip
- vendor,soc2-ip
- enum:
- vendor,soc1-ip
# additionalItems being false is implied
# minItems/maxItems equal to 2 is implied
- items:
# 'const' is just a special case of an enum with a single possible value
- const: vendor,soc1-ip
reg:
# The core schema already checks that reg values are numbers, so device
# specific schema don't need to do those checks.
# The description of each element defines the order and implicitly defines
# the number of reg entries.
items:
- description: core registers
- description: aux registers
# minItems/maxItems equal to 2 is implied
reg-names:
# The core schema enforces this is a string array
items:
- const: core
- const: aux
clocks:
# Cases that have only a single entry just need to express that with maxItems
maxItems: 1
description: bus clock
clock-names:
items:
- const: bus
interrupts:
# Either 1 or 2 interrupts can be present
minItems: 1
maxItems: 2
items:
- description: tx or combined interrupt
- description: rx interrupt
description:
A variable number of interrupts warrants a description of what conditions
affect the number of interrupts. Otherwise, descriptions on standard
properties are not necessary.
interrupt-names:
# minItems must be specified here because the default would be 2
minItems: 1
maxItems: 2
items:
- const: tx irq
- const: rx irq
# Property names starting with '#' must be quoted
'#interrupt-cells':
# A simple case where the value must always be '2'.
# The core schema handles that this must be a single integer.
const: 2
interrupt-controller: true
# The core checks this is a boolean, so just have to list it here to be
# valid for this binding.
clock-frequency:
# The type is set in the core schema. Per device schema only need to set
# constraints on the possible values.
minimum: 100
maximum: 400000
# The value that should be used if the property is not present
default: 200
foo-gpios:
maxItems: 1
description: A connection of the 'foo' gpio line.
vendor,int-property:
description: Vendor specific properties must have a description
# 'allOf' is the json-schema way of subclassing a schema. Here the base
# type schema is referenced and then additional constraints on the values
# are added.
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32
- enum: [2, 4, 6, 8, 10]
vendor,bool-property:
description: Vendor specific properties must have a description
# boolean properties is one case where the json-schema 'type' keyword
# can be used directly
type: boolean
vendor,string-array-property:
description: Vendor specific properties should reference a type in the
core schema.
allOf:
- $ref: /schemas/types.yaml#/definitions/string-array
- items:
- enum: [ foo, bar ]
- enum: [ baz, boo ]
required:
- compatible
- reg
- interrupts
- interrupt-controller
examples:
# Examples are now compiled with dtc
- |
node@1000 {
compatible = "vendor,soc4-ip", "vendor,soc1-ip";
reg = <0x1000 0x80>,
<0x3000 0x80>;
reg-names = "core", "aux";
interrupts = <10>;
interrupt-controller;
};
...@@ -5,6 +5,8 @@ Required properties: ...@@ -5,6 +5,8 @@ Required properties:
- "ti,omap2-gpio" for OMAP2 controllers - "ti,omap2-gpio" for OMAP2 controllers
- "ti,omap3-gpio" for OMAP3 controllers - "ti,omap3-gpio" for OMAP3 controllers
- "ti,omap4-gpio" for OMAP4 controllers - "ti,omap4-gpio" for OMAP4 controllers
- reg : Physical base address of the controller and length of memory mapped
region.
- gpio-controller : Marks the device node as a GPIO controller. - gpio-controller : Marks the device node as a GPIO controller.
- #gpio-cells : Should be two. - #gpio-cells : Should be two.
- first cell is the pin number - first cell is the pin number
...@@ -18,6 +20,8 @@ Required properties: ...@@ -18,6 +20,8 @@ Required properties:
2 = high-to-low edge triggered. 2 = high-to-low edge triggered.
4 = active high level-sensitive. 4 = active high level-sensitive.
8 = active low level-sensitive. 8 = active low level-sensitive.
- interrupts : The interrupt the controller is rising as output when an
interrupt occures
OMAP specific properties: OMAP specific properties:
- ti,hwmods: Name of the hwmod associated to the GPIO: - ti,hwmods: Name of the hwmod associated to the GPIO:
...@@ -29,11 +33,13 @@ OMAP specific properties: ...@@ -29,11 +33,13 @@ OMAP specific properties:
Example: Example:
gpio4: gpio4 { gpio0: gpio@44e07000 {
compatible = "ti,omap4-gpio"; compatible = "ti,omap4-gpio";
ti,hwmods = "gpio4"; reg = <0x44e07000 0x1000>;
ti,hwmods = "gpio1";
gpio-controller; gpio-controller;
#gpio-cells = <2>; #gpio-cells = <2>;
interrupt-controller; interrupt-controller;
#interrupt-cells = <2>; #interrupt-cells = <2>;
interrupts = <96>;
}; };
Device-Tree bindings for i2c gpio driver
Required properties:
- compatible = "i2c-gpio";
- sda-gpios: gpio used for the sda signal, this should be flagged as
active high using open drain with (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)
from <dt-bindings/gpio/gpio.h> since the signal is by definition
open drain.
- scl-gpios: gpio used for the scl signal, this should be flagged as
active high using open drain with (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)
from <dt-bindings/gpio/gpio.h> since the signal is by definition
open drain.
Optional properties:
- i2c-gpio,scl-output-only: scl as output only
- i2c-gpio,delay-us: delay between GPIO operations (may depend on each platform)
- i2c-gpio,timeout-ms: timeout to get data
Deprecated properties, do not use in new device tree sources:
- gpios: sda and scl gpio, alternative for {sda,scl}-gpios
- i2c-gpio,sda-open-drain: this means that something outside of our
control has put the GPIO line used for SDA into open drain mode, and
that something is not the GPIO chip. It is essentially an
inconsistency flag.
- i2c-gpio,scl-open-drain: this means that something outside of our
control has put the GPIO line used for SCL into open drain mode, and
that something is not the GPIO chip. It is essentially an
inconsistency flag.
Example nodes:
#include <dt-bindings/gpio/gpio.h>
i2c@0 {
compatible = "i2c-gpio";
sda-gpios = <&pioA 23 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
scl-gpios = <&pioA 24 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
i2c-gpio,delay-us = <2>; /* ~100 kHz */
#address-cells = <1>;
#size-cells = <0>;
rv3029c2@56 {
compatible = "rv3029c2";
reg = <0x56>;
};
};
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/i2c/i2c-gpio.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Bindings for GPIO bitbanged I2C
maintainers:
- Wolfram Sang <wolfram@the-dreams.de>
allOf:
- $ref: /schemas/i2c/i2c-controller.yaml#
properties:
compatible:
items:
- const: i2c-gpio
sda-gpios:
description:
gpio used for the sda signal, this should be flagged as
active high using open drain with (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)
from <dt-bindings/gpio/gpio.h> since the signal is by definition
open drain.
maxItems: 1
scl-gpios:
description:
gpio used for the scl signal, this should be flagged as
active high using open drain with (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)
from <dt-bindings/gpio/gpio.h> since the signal is by definition
open drain.
maxItems: 1
i2c-gpio,scl-output-only:
description: scl as output only
type: boolean
i2c-gpio,delay-us:
description: delay between GPIO operations (may depend on each platform)
$ref: /schemas/types.yaml#/definitions/uint32
i2c-gpio,timeout-ms:
description: timeout to get data
$ref: /schemas/types.yaml#/definitions/uint32
# Deprecated properties, do not use in new device tree sources:
gpios:
minItems: 2
maxItems: 2
description: sda and scl gpio, alternative for {sda,scl}-gpios
i2c-gpio,sda-open-drain:
# Generate a warning if present
not: true
description: this means that something outside of our control has put
the GPIO line used for SDA into open drain mode, and that something is
not the GPIO chip. It is essentially an inconsistency flag.
i2c-gpio,scl-open-drain:
# Generate a warning if present
not: true
description: this means that something outside of our control has put the
GPIO line used for SCL into open drain mode, and that something is not
the GPIO chip. It is essentially an inconsistency flag.
required:
- compatible
- sda-gpios
- scl-gpios
...
* FREESCALE MAG3110 magnetometer sensor
Required properties:
- compatible : should be "fsl,mag3110"
- reg : the I2C address of the magnetometer
Optional properties:
- interrupts: the sole interrupt generated by the device
Refer to interrupt-controller/interrupts.txt for generic interrupt client
node bindings.
- vdd-supply: phandle to the regulator that provides power to the sensor.
- vddio-supply: phandle to the regulator that provides power to the sensor's IO.
Example:
magnetometer@e {
compatible = "fsl,mag3110";
reg = <0x0e>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c3_mag3110_int>;
interrupt-parent = <&gpio3>;
interrupts = <16 IRQ_TYPE_EDGE_RISING>;
};
...@@ -5,7 +5,7 @@ Required properties: ...@@ -5,7 +5,7 @@ Required properties:
"mrvl,mmp2-mux-intc" "mrvl,mmp2-mux-intc"
- reg : Address and length of the register set of the interrupt controller. - reg : Address and length of the register set of the interrupt controller.
If the interrupt controller is intc, address and length means the range If the interrupt controller is intc, address and length means the range
of the whold interrupt controller. If the interrupt controller is mux-intc, of the whole interrupt controller. If the interrupt controller is mux-intc,
address and length means one register. Since address of mux-intc is in the address and length means one register. Since address of mux-intc is in the
range of intc. mux-intc is secondary interrupt controller. range of intc. mux-intc is secondary interrupt controller.
- reg-names : Name of the register set of the interrupt controller. It's - reg-names : Name of the register set of the interrupt controller. It's
......
Cadence Sierra PHY
-----------------------
Required properties:
- compatible: cdns,sierra-phy-t0
- clocks: Must contain an entry in clock-names.
See ../clocks/clock-bindings.txt for details.
- clock-names: Must be "phy_clk"
- resets: Must contain an entry for each in reset-names.
See ../reset/reset.txt for details.
- reset-names: Must include "sierra_reset" and "sierra_apb".
"sierra_reset" must control the reset line to the PHY.
"sierra_apb" must control the reset line to the APB PHY
interface.
- reg: register range for the PHY.
- #address-cells: Must be 1
- #size-cells: Must be 0
Optional properties:
- cdns,autoconf: A boolean property whose presence indicates that the
PHY registers will be configured by hardware. If not
present, all sub-node optional properties must be
provided.
Sub-nodes:
Each group of PHY lanes with a single master lane should be represented as
a sub-node. Note that the actual configuration of each lane is determined by
hardware strapping, and must match the configuration specified here.
Sub-node required properties:
- #phy-cells: Generic PHY binding; must be 0.
- reg: The master lane number. This is the lowest numbered lane
in the lane group.
- resets: Must contain one entry which controls the reset line for the
master lane of the sub-node.
See ../reset/reset.txt for details.
Sub-node optional properties:
- cdns,num-lanes: Number of lanes in this group. From 1 to 4. The
group is made up of consecutive lanes.
- cdns,phy-type: Can be PHY_TYPE_PCIE or PHY_TYPE_USB3, depending on
configuration of lanes.
Example:
pcie_phy4: pcie-phy@fd240000 {
compatible = "cdns,sierra-phy-t0";
reg = <0x0 0xfd240000 0x0 0x40000>;
resets = <&phyrst 0>, <&phyrst 1>;
reset-names = "sierra_reset", "sierra_apb";
clocks = <&phyclock>;
clock-names = "phy_clk";
#address-cells = <1>;
#size-cells = <0>;
pcie0_phy0: pcie-phy@0 {
reg = <0>;
resets = <&phyrst 2>;
cdns,num-lanes = <2>;
#phy-cells = <0>;
cdns,phy-type = <PHY_TYPE_PCIE>;
};
pcie0_phy1: pcie-phy@2 {
reg = <2>;
resets = <&phyrst 4>;
cdns,num-lanes = <1>;
#phy-cells = <0>;
cdns,phy-type = <PHY_TYPE_PCIE>;
};
* Xen hypervisor reserved-memory binding
Expose one or more memory regions as reserved-memory to the guest
virtual machine. Typically, a region is configured at VM creation time
to be a shared memory area across multiple virtual machines for
communication among them.
For each of these pre-shared memory regions, a range is exposed under
the /reserved-memory node as a child node. Each range sub-node is named
xen-shmem@<address> and has the following properties:
- compatible:
compatible = "xen,shared-memory-v1"
- reg:
the base guest physical address and size of the shared memory region
- xen,offset: (borrower VMs only)
64 bit integer offset within the owner virtual machine's shared
memory region used for the mapping in the borrower VM.
- xen,id:
a string that identifies the shared memory region as specified in
the VM config file
Device-Tree bindings for Mediatek random number generator Device-Tree bindings for Mediatek random number generator
found in Mediatek SoC family found in MediaTek SoC family
Required properties: Required properties:
- compatible : Should be - compatible : Should be
"mediatek,mt7622-rng", "mediatek,mt7623-rng" : for MT7622 "mediatek,mt7622-rng", "mediatek,mt7623-rng" : for MT7622
"mediatek,mt7629-rng", "mediatek,mt7623-rng" : for MT7629
"mediatek,mt7623-rng" : for MT7623 "mediatek,mt7623-rng" : for MT7623
- clocks : list of clock specifiers, corresponding to - clocks : list of clock specifiers, corresponding to
entries in clock-names property; entries in clock-names property;
......
Generic device tree bindings for Real Time Clock devices
========================================================
This document describes generic bindings which can be used to describe Real Time
Clock devices in a device tree.
Required properties
-------------------
- compatible : name of RTC device following generic names recommended practice.
For other required properties e.g. to describe register sets,
clocks, etc. check the binding documentation of the specific driver.
Optional properties
-------------------
- start-year : if provided, the default hardware range supported by the RTC is
shifted so the first usable year is the specified one.
The following properties may not be supported by all drivers. However, if a
driver wants to support one of the below features, it should adapt the bindings
below.
- trickle-resistor-ohms : Selected resistor for trickle charger. Should be given
if trickle charger should be enabled
- trickle-diode-disable : Do not use internal trickle charger diode Should be
given if internal trickle charger diode should be
disabled
- wakeup-source : Enables wake up of host system on alarm
Trivial RTCs
------------
This is a list of trivial RTC devices that have simple device tree
bindings, consisting only of a compatible field, an address and
possibly an interrupt line.
Compatible Vendor / Chip
========== =============
abracon,abb5zes3 AB-RTCMC-32.768kHz-B5ZE-S3: Real Time Clock/Calendar Module with I2C Interface
dallas,ds1374 I2C, 32-Bit Binary Counter Watchdog RTC with Trickle Charger and Reset Input/Output
dallas,ds1672 Dallas DS1672 Real-time Clock
dallas,ds3232 Extremely Accurate I²C RTC with Integrated Crystal and SRAM
epson,rx8010 I2C-BUS INTERFACE REAL TIME CLOCK MODULE
epson,rx8581 I2C-BUS INTERFACE REAL TIME CLOCK MODULE
emmicro,em3027 EM Microelectronic EM3027 Real-time Clock
isil,isl1208 Intersil ISL1208 Low Power RTC with Battery Backed SRAM
isil,isl1218 Intersil ISL1218 Low Power RTC with Battery Backed SRAM
isil,isl12022 Intersil ISL12022 Real-time Clock
microcrystal,rv3029 Real Time Clock Module with I2C-Bus
nxp,pcf2127 Real-time clock
nxp,pcf2129 Real-time clock
nxp,pcf8523 Real-time Clock
nxp,pcf8563 Real-time clock/calendar
nxp,pcf85063 Tiny Real-Time Clock
pericom,pt7c4338 Real-time Clock Module
ricoh,r2025sd I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
ricoh,r2221tl I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
ricoh,rs5c372a I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
ricoh,rs5c372b I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
ricoh,rv5c386 I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
ricoh,rv5c387a I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
sii,s35390a 2-wire CMOS real-time clock
* ARM architected timer
ARM cores may have a per-core architected timer, which provides per-cpu timers,
or a memory mapped architected timer, which provides up to 8 frames with a
physical and optional virtual timer per frame.
The per-core architected timer is attached to a GIC to deliver its
per-processor interrupts via PPIs. The memory mapped timer is attached to a GIC
to deliver its interrupts via SPIs.
** CP15 Timer node properties:
- compatible : Should at least contain one of
"arm,armv7-timer"
"arm,armv8-timer"
- interrupts : Interrupt list for secure, non-secure, virtual and
hypervisor timers, in that order.
- clock-frequency : The frequency of the main counter, in Hz. Should be present
only where necessary to work around broken firmware which does not configure
CNTFRQ on all CPUs to a uniform correct value. Use of this property is
strongly discouraged; fix your firmware unless absolutely impossible.
- always-on : a boolean property. If present, the timer is powered through an
always-on power domain, therefore it never loses context.
- fsl,erratum-a008585 : A boolean property. Indicates the presence of
QorIQ erratum A-008585, which says that reading the counter is
unreliable unless the same value is returned by back-to-back reads.
This also affects writes to the tval register, due to the implicit
counter read.
- hisilicon,erratum-161010101 : A boolean property. Indicates the
presence of Hisilicon erratum 161010101, which says that reading the
counters is unreliable in some cases, and reads may return a value 32
beyond the correct value. This also affects writes to the tval
registers, due to the implicit counter read.
** Optional properties:
- arm,cpu-registers-not-fw-configured : Firmware does not initialize
any of the generic timer CPU registers, which contain their
architecturally-defined reset values. Only supported for 32-bit
systems which follow the ARMv7 architected reset values.
- arm,no-tick-in-suspend : The main counter does not tick when the system is in
low-power system suspend on some SoCs. This behavior does not match the
Architecture Reference Manual's specification that the system counter "must
be implemented in an always-on power domain."
Example:
timer {
compatible = "arm,cortex-a15-timer",
"arm,armv7-timer";
interrupts = <1 13 0xf08>,
<1 14 0xf08>,
<1 11 0xf08>,
<1 10 0xf08>;
clock-frequency = <100000000>;
};
** Memory mapped timer node properties:
- compatible : Should at least contain "arm,armv7-timer-mem".
- clock-frequency : The frequency of the main counter, in Hz. Should be present
only when firmware has not configured the MMIO CNTFRQ registers.
- reg : The control frame base address.
Note that #address-cells, #size-cells, and ranges shall be present to ensure
the CPU can address a frame's registers.
A timer node has up to 8 frame sub-nodes, each with the following properties:
- frame-number: 0 to 7.
- interrupts : Interrupt list for physical and virtual timers in that order.
The virtual timer interrupt is optional.
- reg : The first and second view base addresses in that order. The second view
base address is optional.
- status : "disabled" indicates the frame is not available for use. Optional.
Example:
timer@f0000000 {
compatible = "arm,armv7-timer-mem";
#address-cells = <1>;
#size-cells = <1>;
ranges;
reg = <0xf0000000 0x1000>;
clock-frequency = <50000000>;
frame@f0001000 {
frame-number = <0>
interrupts = <0 13 0x8>,
<0 14 0x8>;
reg = <0xf0001000 0x1000>,
<0xf0002000 0x1000>;
};
frame@f0003000 {
frame-number = <1>
interrupts = <0 15 0x8>;
reg = <0xf0003000 0x1000>;
};
};
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/timer/arm,arch_timer.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ARM architected timer
maintainers:
- Marc Zyngier <marc.zyngier@arm.com>
- Mark Rutland <mark.rutland@arm.com>
description: |+
ARM cores may have a per-core architected timer, which provides per-cpu timers,
or a memory mapped architected timer, which provides up to 8 frames with a
physical and optional virtual timer per frame.
The per-core architected timer is attached to a GIC to deliver its
per-processor interrupts via PPIs. The memory mapped timer is attached to a GIC
to deliver its interrupts via SPIs.
properties:
compatible:
oneOf:
- items:
- enum:
- arm,cortex-a15-timer
- enum:
- arm,armv7-timer
- items:
- enum:
- arm,armv7-timer
- items:
- enum:
- arm,armv8-timer
interrupts:
items:
- description: secure timer irq
- description: non-secure timer irq
- description: virtual timer irq
- description: hypervisor timer irq
clock-frequency:
description: The frequency of the main counter, in Hz. Should be present
only where necessary to work around broken firmware which does not configure
CNTFRQ on all CPUs to a uniform correct value. Use of this property is
strongly discouraged; fix your firmware unless absolutely impossible.
always-on:
type: boolean
description: If present, the timer is powered through an always-on power
domain, therefore it never loses context.
fsl,erratum-a008585:
type: boolean
description: Indicates the presence of QorIQ erratum A-008585, which says
that reading the counter is unreliable unless the same value is returned
by back-to-back reads. This also affects writes to the tval register, due
to the implicit counter read.
hisilicon,erratum-161010101:
type: boolean
description: Indicates the presence of Hisilicon erratum 161010101, which
says that reading the counters is unreliable in some cases, and reads may
return a value 32 beyond the correct value. This also affects writes to
the tval registers, due to the implicit counter read.
arm,cpu-registers-not-fw-configured:
type: boolean
description: Firmware does not initialize any of the generic timer CPU
registers, which contain their architecturally-defined reset values. Only
supported for 32-bit systems which follow the ARMv7 architected reset
values.
arm,no-tick-in-suspend:
type: boolean
description: The main counter does not tick when the system is in
low-power system suspend on some SoCs. This behavior does not match the
Architecture Reference Manual's specification that the system counter "must
be implemented in an always-on power domain."
required:
- compatible
oneOf:
- required:
- interrupts
- required:
- interrupts-extended
examples:
- |
timer {
compatible = "arm,cortex-a15-timer",
"arm,armv7-timer";
interrupts = <1 13 0xf08>,
<1 14 0xf08>,
<1 11 0xf08>,
<1 10 0xf08>;
clock-frequency = <100000000>;
};
...
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/timer/arm,arch_timer_mmio.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ARM memory mapped architected timer
maintainers:
- Marc Zyngier <marc.zyngier@arm.com>
- Mark Rutland <mark.rutland@arm.com>
description: |+
ARM cores may have a memory mapped architected timer, which provides up to 8
frames with a physical and optional virtual timer per frame.
The memory mapped timer is attached to a GIC to deliver its interrupts via SPIs.
properties:
compatible:
items:
- enum:
- arm,armv7-timer-mem
reg:
maxItems: 1
description: The control frame base address
'#address-cells':
enum: [1, 2]
'#size-cells':
const: 1
clock-frequency:
description: The frequency of the main counter, in Hz. Should be present
only where necessary to work around broken firmware which does not configure
CNTFRQ on all CPUs to a uniform correct value. Use of this property is
strongly discouraged; fix your firmware unless absolutely impossible.
always-on:
type: boolean
description: If present, the timer is powered through an always-on power
domain, therefore it never loses context.
arm,cpu-registers-not-fw-configured:
type: boolean
description: Firmware does not initialize any of the generic timer CPU
registers, which contain their architecturally-defined reset values. Only
supported for 32-bit systems which follow the ARMv7 architected reset
values.
arm,no-tick-in-suspend:
type: boolean
description: The main counter does not tick when the system is in
low-power system suspend on some SoCs. This behavior does not match the
Architecture Reference Manual's specification that the system counter "must
be implemented in an always-on power domain."
patternProperties:
'^frame@[0-9a-z]*$':
description: A timer node has up to 8 frame sub-nodes, each with the following properties.
properties:
frame-number:
allOf:
- $ref: "/schemas/types.yaml#/definitions/uint32"
- minimum: 0
maximum: 7
interrupts:
minItems: 1
maxItems: 2
items:
- description: physical timer irq
- description: virtual timer irq
reg :
minItems: 1
maxItems: 2
items:
- description: 1st view base address
- description: 2nd optional view base address
required:
- frame-number
- interrupts
- reg
required:
- compatible
- reg
- '#address-cells'
- '#size-cells'
examples:
- |
timer@f0000000 {
compatible = "arm,armv7-timer-mem";
#address-cells = <1>;
#size-cells = <1>;
ranges;
reg = <0xf0000000 0x1000>;
clock-frequency = <50000000>;
frame@f0001000 {
frame-number = <0>;
interrupts = <0 13 0x8>,
<0 14 0x8>;
reg = <0xf0001000 0x1000>,
<0xf0002000 0x1000>;
};
frame@f0003000 {
frame-number = <1>;
interrupts = <0 15 0x8>;
reg = <0xf0003000 0x1000>;
};
};
...
* ARM Global Timer
Cortex-A9 are often associated with a per-core Global timer.
** Timer node required properties:
- compatible : should contain
* "arm,cortex-a5-global-timer" for Cortex-A5 global timers.
* "arm,cortex-a9-global-timer" for Cortex-A9 global
timers or any compatible implementation. Note: driver
supports versions r2p0 and above.
- interrupts : One interrupt to each core
- reg : Specify the base address and the size of the GT timer
register window.
- clocks : Should be phandle to a clock.
Example:
timer@2c000600 {
compatible = "arm,cortex-a9-global-timer";
reg = <0x2c000600 0x20>;
interrupts = <1 13 0xf01>;
clocks = <&arm_periph_clk>;
};
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/timer/arm,global_timer.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ARM Global Timer
maintainers:
- Stuart Menefy <stuart.menefy@st.com>
description:
Cortex-A9 are often associated with a per-core Global timer.
properties:
compatible:
items:
- enum:
- arm,cortex-a5-global-timer
- arm,cortex-a9-global-timer
description: driver supports versions r2p0 and above.
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 1
required:
- compatible
- reg
- clocks
examples:
- |
timer@2c000600 {
compatible = "arm,cortex-a9-global-timer";
reg = <0x2c000600 0x20>;
interrupts = <1 13 0xf01>;
clocks = <&arm_periph_clk>;
};
...
This diff is collapsed.
This diff is collapsed.
Todo list for devicetree:
=== General structure ===
- Switch from custom lists to (h)list_head for nodes and properties structure
=== CONFIG_OF_DYNAMIC ===
- Switch to RCU for tree updates and get rid of global spinlock
- Document node lifecycle for CONFIG_OF_DYNAMIC
- Always set ->full_name at of_attach_node() time
- pseries: Get rid of open-coded tree modification from arch/powerpc/platforms/pseries/dlpar.c
# Writing DeviceTree Bindings in json-schema
Devicetree bindings are written using json-schema vocabulary. Schema files are
written in a JSON compatible subset of YAML. YAML is used instead of JSON as it
considered more human readable and has some advantages such as allowing
comments (Prefixed with '#').
## Schema Contents
Each schema doc is a structured json-schema which is defined by a set of
top-level properties. Generally, there is one binding defined per file. The
top-level json-schema properties used are:
- __$id__ - A json-schema unique identifier string. The string must be a valid
URI typically containing the binding's filename and path. For DT schema, it must
begin with "http://devicetree.org/schemas/". The URL is used in constructing
references to other files specified in schema "$ref" properties. A $ref values
with a leading '/' will have the hostname prepended. A $ref value a relative
path or filename only will be prepended with the hostname and path components
of the current schema file's '$id' value. A URL is used even for local files,
but there may not actually be files present at those locations.
- __$schema__ - Indicates the meta-schema the schema file adheres to.
- __title__ - A one line description on the contents of the binding schema.
- __maintainers__ - A DT specific property. Contains a list of email address(es)
for maintainers of this binding.
- __description__ - Optional. A multi-line text block containing any detailed
information about this binding. It should contain things such as what the block
or device does, standards the device conforms to, and links to datasheets for
more information.
- __select__ - Optional. A json-schema used to match nodes for applying the
schema. By default without 'select', nodes are matched against their possible
compatible string values or node name. Most bindings should not need select.
- __allOf__ - Optional. A list of other schemas to include. This is used to
include other schemas the binding conforms to. This may be schemas for a
particular class of devices such as I2C or SPI controllers.
- __properties__ - A set of sub-schema defining all the DT properties for the
binding. The exact schema syntax depends on whether properties are known,
common properties (e.g. 'interrupts') or are binding/vendor specific properties.
A property can also define a child DT node with child properties defined
under it.
For more details on properties sections, see 'Property Schema' section.
- __patternProperties__ - Optional. Similar to 'properties', but names are regex.
- __required__ - A list of DT properties from the 'properties' section that
must always be present.
- __examples__ - Optional. A list of one or more DTS hunks implementing the
binding. Note: YAML doesn't allow leading tabs, so spaces must be used instead.
Unless noted otherwise, all properties are required.
## Property Schema
The 'properties' section of the schema contains all the DT properties for a
binding. Each property contains a set of constraints using json-schema
vocabulary for that property. The properties schemas are what is used for
validation of DT files.
For common properties, only additional constraints not covered by the common
binding schema need to be defined such as how many values are valid or what
possible values are valid.
Vendor specific properties will typically need more detailed schema. With the
exception of boolean properties, they should have a reference to a type in
schemas/types.yaml. A "description" property is always required.
The Devicetree schemas don't exactly match the YAML encoded DT data produced by
dtc. They are simplified to make them more compact and avoid a bunch of
boilerplate. The tools process the schema files to produce the final schema for
validation. There are currently 2 transformations the tools perform.
The default for arrays in json-schema is they are variable sized and allow more
entries than explicitly defined. This can be restricted by defining 'minItems',
'maxItems', and 'additionalItems'. However, for DeviceTree Schemas, a fixed
size is desired in most cases, so these properties are added based on the
number of entries in an 'items' list.
The YAML Devicetree format also makes all string values an array and scalar
values a matrix (in order to define groupings) even when only a single value
is present. Single entries in schemas are fixed up to match this encoding.
## Testing
### Dependencies
The DT schema project must be installed in order to validate the DT schema
binding documents and validate DTS files using the DT schema. The DT schema
project can be installed with pip:
`pip3 install git+https://github.com/robherring/yaml-bindings.git@master`
dtc must also be built with YAML output support enabled. This requires that
libyaml and its headers be installed on the host system.
### Running checks
The DT schema binding documents must be validated using the meta-schema (the
schema for the schema) to ensure they are both valid json-schema and valid
binding schema. All of the DT binding documents can be validated using the
`dt_binding_check` target:
`make dt_binding_check`
In order to perform validation of DT source files, use the `dtbs_check` target:
`make dtbs_check`
This will first run the `dt_binding_check` which generates the processed schema.
It is also possible to run checks with a single schema file by setting the
'DT_SCHEMA_FILES' variable to a specific schema file.
`make dtbs_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/trivial-devices.yaml`
## json-schema Resources
[JSON-Schema Specifications](http://json-schema.org/)
[Using JSON Schema Book](http://usingjsonschema.com/)
...@@ -2353,7 +2353,7 @@ F: drivers/pinctrl/zte/ ...@@ -2353,7 +2353,7 @@ F: drivers/pinctrl/zte/
F: drivers/soc/zte/ F: drivers/soc/zte/
F: drivers/thermal/zx2967_thermal.c F: drivers/thermal/zx2967_thermal.c
F: drivers/watchdog/zx2967_wdt.c F: drivers/watchdog/zx2967_wdt.c
F: Documentation/devicetree/bindings/arm/zte.txt F: Documentation/devicetree/bindings/arm/zte.yaml
F: Documentation/devicetree/bindings/clock/zx2967*.txt F: Documentation/devicetree/bindings/clock/zx2967*.txt
F: Documentation/devicetree/bindings/dma/zxdma.txt F: Documentation/devicetree/bindings/dma/zxdma.txt
F: Documentation/devicetree/bindings/gpio/zx296702-gpio.txt F: Documentation/devicetree/bindings/gpio/zx296702-gpio.txt
......
...@@ -1230,10 +1230,13 @@ ifneq ($(dtstree),) ...@@ -1230,10 +1230,13 @@ ifneq ($(dtstree),)
%.dtb: prepare3 scripts_dtc %.dtb: prepare3 scripts_dtc
$(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@ $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@
PHONY += dtbs dtbs_install PHONY += dtbs dtbs_install dt_binding_check
dtbs: prepare3 scripts_dtc dtbs dtbs_check: prepare3 scripts_dtc
$(Q)$(MAKE) $(build)=$(dtstree) $(Q)$(MAKE) $(build)=$(dtstree)
dtbs_check: export CHECK_DTBS=1
dtbs_check: dt_binding_check
dtbs_install: dtbs_install:
$(Q)$(MAKE) $(dtbinst)=$(dtstree) $(Q)$(MAKE) $(dtbinst)=$(dtstree)
...@@ -1247,6 +1250,9 @@ PHONY += scripts_dtc ...@@ -1247,6 +1250,9 @@ PHONY += scripts_dtc
scripts_dtc: scripts_basic scripts_dtc: scripts_basic
$(Q)$(MAKE) $(build)=scripts/dtc $(Q)$(MAKE) $(build)=scripts/dtc
dt_binding_check: scripts_dtc
$(Q)$(MAKE) $(build)=Documentation/devicetree/bindings
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Modules # Modules
...@@ -1609,7 +1615,8 @@ clean: $(clean-dirs) ...@@ -1609,7 +1615,8 @@ clean: $(clean-dirs)
$(call cmd,rmfiles) $(call cmd,rmfiles)
@find $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \ @find $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \
\( -name '*.[aios]' -o -name '*.ko' -o -name '.*.cmd' \ \( -name '*.[aios]' -o -name '*.ko' -o -name '.*.cmd' \
-o -name '*.ko.*' -o -name '*.dtb' -o -name '*.dtb.S' \ -o -name '*.ko.*' \
-o -name '*.dtb' -o -name '*.dtb.S' -o -name '*.dt.yaml' \
-o -name '*.dwo' -o -name '*.lst' \ -o -name '*.dwo' -o -name '*.lst' \
-o -name '*.su' \ -o -name '*.su' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
......
...@@ -78,24 +78,6 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) ...@@ -78,24 +78,6 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
base, TO_MB(size), !in_use ? "Not used":""); base, TO_MB(size), !in_use ? "Not used":"");
} }
#ifdef CONFIG_BLK_DEV_INITRD
static int __init early_initrd(char *p)
{
unsigned long start, size;
char *endp;
start = memparse(p, &endp);
if (*endp == ',') {
size = memparse(endp + 1, NULL);
initrd_start = (unsigned long)__va(start);
initrd_end = (unsigned long)__va(start + size);
}
return 0;
}
early_param("initrd", early_initrd);
#endif
/* /*
* First memory setup routine called from setup_arch() * First memory setup routine called from setup_arch()
* 1. setup swapper's mm @init_mm * 1. setup swapper's mm @init_mm
...@@ -140,8 +122,11 @@ void __init setup_arch_memory(void) ...@@ -140,8 +122,11 @@ void __init setup_arch_memory(void)
memblock_reserve(low_mem_start, __pa(_end) - low_mem_start); memblock_reserve(low_mem_start, __pa(_end) - low_mem_start);
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start) if (phys_initrd_size) {
memblock_reserve(__pa(initrd_start), initrd_end - initrd_start); memblock_reserve(phys_initrd_start, phys_initrd_size);
initrd_start = (unsigned long)__va(phys_initrd_start);
initrd_end = initrd_start + phys_initrd_size;
}
#endif #endif
early_init_fdt_reserve_self(); early_init_fdt_reserve_self();
......
...@@ -50,26 +50,7 @@ unsigned long __init __clear_cr(unsigned long mask) ...@@ -50,26 +50,7 @@ unsigned long __init __clear_cr(unsigned long mask)
} }
#endif #endif
static phys_addr_t phys_initrd_start __initdata = 0; #ifdef CONFIG_BLK_DEV_INITRD
static unsigned long phys_initrd_size __initdata = 0;
static int __init early_initrd(char *p)
{
phys_addr_t start;
unsigned long size;
char *endp;
start = memparse(p, &endp);
if (*endp == ',') {
size = memparse(endp + 1, NULL);
phys_initrd_start = start;
phys_initrd_size = size;
}
return 0;
}
early_param("initrd", early_initrd);
static int __init parse_tag_initrd(const struct tag *tag) static int __init parse_tag_initrd(const struct tag *tag)
{ {
pr_warn("ATAG_INITRD is deprecated; " pr_warn("ATAG_INITRD is deprecated; "
...@@ -89,6 +70,7 @@ static int __init parse_tag_initrd2(const struct tag *tag) ...@@ -89,6 +70,7 @@ static int __init parse_tag_initrd2(const struct tag *tag)
} }
__tagtable(ATAG_INITRD2, parse_tag_initrd2); __tagtable(ATAG_INITRD2, parse_tag_initrd2);
#endif
static void __init find_limits(unsigned long *min, unsigned long *max_low, static void __init find_limits(unsigned long *min, unsigned long *max_low,
unsigned long *max_high) unsigned long *max_high)
...@@ -236,12 +218,6 @@ static void __init arm_initrd_init(void) ...@@ -236,12 +218,6 @@ static void __init arm_initrd_init(void)
phys_addr_t start; phys_addr_t start;
unsigned long size; unsigned long size;
/* FDT scan will populate initrd_start */
if (initrd_start && !phys_initrd_size) {
phys_initrd_start = __virt_to_phys(initrd_start);
phys_initrd_size = initrd_end - initrd_start;
}
initrd_start = initrd_end = 0; initrd_start = initrd_end = 0;
if (!phys_initrd_size) if (!phys_initrd_size)
......
...@@ -171,14 +171,6 @@ ...@@ -171,14 +171,6 @@
#define IOREMAP_MAX_ORDER (PMD_SHIFT) #define IOREMAP_MAX_ORDER (PMD_SHIFT)
#endif #endif
#ifdef CONFIG_BLK_DEV_INITRD
#define __early_init_dt_declare_initrd(__start, __end) \
do { \
initrd_start = (__start); \
initrd_end = (__end); \
} while (0)
#endif
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <linux/bitops.h> #include <linux/bitops.h>
......
...@@ -63,24 +63,6 @@ EXPORT_SYMBOL(memstart_addr); ...@@ -63,24 +63,6 @@ EXPORT_SYMBOL(memstart_addr);
phys_addr_t arm64_dma_phys_limit __ro_after_init; phys_addr_t arm64_dma_phys_limit __ro_after_init;
#ifdef CONFIG_BLK_DEV_INITRD
static int __init early_initrd(char *p)
{
unsigned long start, size;
char *endp;
start = memparse(p, &endp);
if (*endp == ',') {
size = memparse(endp + 1, NULL);
initrd_start = start;
initrd_end = start + size;
}
return 0;
}
early_param("initrd", early_initrd);
#endif
#ifdef CONFIG_KEXEC_CORE #ifdef CONFIG_KEXEC_CORE
/* /*
* reserve_crashkernel() - reserves memory for crash kernel * reserve_crashkernel() - reserves memory for crash kernel
...@@ -417,14 +399,14 @@ void __init arm64_memblock_init(void) ...@@ -417,14 +399,14 @@ void __init arm64_memblock_init(void)
memblock_add(__pa_symbol(_text), (u64)(_end - _text)); memblock_add(__pa_symbol(_text), (u64)(_end - _text));
} }
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && initrd_start) { if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && phys_initrd_size) {
/* /*
* Add back the memory we just removed if it results in the * Add back the memory we just removed if it results in the
* initrd to become inaccessible via the linear mapping. * initrd to become inaccessible via the linear mapping.
* Otherwise, this is a no-op * Otherwise, this is a no-op
*/ */
u64 base = initrd_start & PAGE_MASK; u64 base = phys_initrd_start & PAGE_MASK;
u64 size = PAGE_ALIGN(initrd_end) - base; u64 size = PAGE_ALIGN(phys_initrd_size);
/* /*
* We can only add back the initrd memory if we don't end up * We can only add back the initrd memory if we don't end up
...@@ -468,15 +450,11 @@ void __init arm64_memblock_init(void) ...@@ -468,15 +450,11 @@ void __init arm64_memblock_init(void)
* pagetables with memblock. * pagetables with memblock.
*/ */
memblock_reserve(__pa_symbol(_text), _end - _text); memblock_reserve(__pa_symbol(_text), _end - _text);
#ifdef CONFIG_BLK_DEV_INITRD if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && phys_initrd_size) {
if (initrd_start) {
memblock_reserve(initrd_start, initrd_end - initrd_start);
/* the generic initrd code expects virtual addresses */ /* the generic initrd code expects virtual addresses */
initrd_start = __phys_to_virt(initrd_start); initrd_start = __phys_to_virt(phys_initrd_start);
initrd_end = __phys_to_virt(initrd_end); initrd_end = initrd_start + phys_initrd_size;
} }
#endif
early_init_fdt_scan_reserved_mem(); early_init_fdt_scan_reserved_mem();
......
...@@ -21,8 +21,6 @@ ...@@ -21,8 +21,6 @@
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
DEFINE_SPINLOCK(anon_alias_lock); DEFINE_SPINLOCK(anon_alias_lock);
extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
extern unsigned long phys_initrd_start;
extern unsigned long phys_initrd_size;
/* /*
* empty_zero_page is a special page that is used for * empty_zero_page is a special page that is used for
......
...@@ -270,6 +270,8 @@ int dlpar_detach_node(struct device_node *dn) ...@@ -270,6 +270,8 @@ int dlpar_detach_node(struct device_node *dn)
if (rc) if (rc)
return rc; return rc;
of_node_put(dn);
return 0; return 0;
} }
......
...@@ -30,25 +30,6 @@ ...@@ -30,25 +30,6 @@
#include "mm.h" #include "mm.h"
static unsigned long phys_initrd_start __initdata = 0x01000000;
static unsigned long phys_initrd_size __initdata = SZ_8M;
static int __init early_initrd(char *p)
{
unsigned long start, size;
char *endp;
start = memparse(p, &endp);
if (*endp == ',') {
size = memparse(endp + 1, NULL);
phys_initrd_start = start;
phys_initrd_size = size;
}
return 0;
}
early_param("initrd", early_initrd);
/* /*
* This keeps memory configuration data used by a couple memory * This keeps memory configuration data used by a couple memory
* initialization functions, as well as show_mem() for the skipping * initialization functions, as well as show_mem() for the skipping
...@@ -156,6 +137,11 @@ void __init uc32_memblock_init(struct meminfo *mi) ...@@ -156,6 +137,11 @@ void __init uc32_memblock_init(struct meminfo *mi)
memblock_reserve(__pa(_text), _end - _text); memblock_reserve(__pa(_text), _end - _text);
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
if (!phys_initrd_size) {
phys_initrd_start = 0x01000000;
phys_initrd_size = SZ_8M;
}
if (phys_initrd_size) { if (phys_initrd_size) {
memblock_reserve(phys_initrd_start, phys_initrd_size); memblock_reserve(phys_initrd_start, phys_initrd_size);
......
...@@ -1199,8 +1199,8 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node) ...@@ -1199,8 +1199,8 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node)
part->partition_id = of_node_to_fwnode(child_part); part->partition_id = of_node_to_fwnode(child_part);
pr_info("GIC: PPI partition %s[%d] { ", pr_info("GIC: PPI partition %pOFn[%d] { ",
child_part->name, part_idx); child_part, part_idx);
n = of_property_count_elems_of_size(child_part, "affinity", n = of_property_count_elems_of_size(child_part, "affinity",
sizeof(u32)); sizeof(u32));
......
...@@ -64,14 +64,14 @@ static int __init orion_irq_init(struct device_node *np, ...@@ -64,14 +64,14 @@ static int __init orion_irq_init(struct device_node *np,
num_chips * ORION_IRQS_PER_CHIP, num_chips * ORION_IRQS_PER_CHIP,
&irq_generic_chip_ops, NULL); &irq_generic_chip_ops, NULL);
if (!orion_irq_domain) if (!orion_irq_domain)
panic("%s: unable to add irq domain\n", np->name); panic("%pOFn: unable to add irq domain\n", np);
ret = irq_alloc_domain_generic_chips(orion_irq_domain, ret = irq_alloc_domain_generic_chips(orion_irq_domain,
ORION_IRQS_PER_CHIP, 1, np->name, ORION_IRQS_PER_CHIP, 1, np->full_name,
handle_level_irq, clr, 0, handle_level_irq, clr, 0,
IRQ_GC_INIT_MASK_CACHE); IRQ_GC_INIT_MASK_CACHE);
if (ret) if (ret)
panic("%s: unable to alloc irq domain gc\n", np->name); panic("%pOFn: unable to alloc irq domain gc\n", np);
for (n = 0, base = 0; n < num_chips; n++, base += ORION_IRQS_PER_CHIP) { for (n = 0, base = 0; n < num_chips; n++, base += ORION_IRQS_PER_CHIP) {
struct irq_chip_generic *gc = struct irq_chip_generic *gc =
...@@ -80,12 +80,12 @@ static int __init orion_irq_init(struct device_node *np, ...@@ -80,12 +80,12 @@ static int __init orion_irq_init(struct device_node *np,
of_address_to_resource(np, n, &r); of_address_to_resource(np, n, &r);
if (!request_mem_region(r.start, resource_size(&r), np->name)) if (!request_mem_region(r.start, resource_size(&r), np->name))
panic("%s: unable to request mem region %d", panic("%pOFn: unable to request mem region %d",
np->name, n); np, n);
gc->reg_base = ioremap(r.start, resource_size(&r)); gc->reg_base = ioremap(r.start, resource_size(&r));
if (!gc->reg_base) if (!gc->reg_base)
panic("%s: unable to map resource %d", np->name, n); panic("%pOFn: unable to map resource %d", np, n);
gc->chip_types[0].regs.mask = ORION_IRQ_MASK; gc->chip_types[0].regs.mask = ORION_IRQ_MASK;
gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
...@@ -150,20 +150,20 @@ static int __init orion_bridge_irq_init(struct device_node *np, ...@@ -150,20 +150,20 @@ static int __init orion_bridge_irq_init(struct device_node *np,
domain = irq_domain_add_linear(np, nrirqs, domain = irq_domain_add_linear(np, nrirqs,
&irq_generic_chip_ops, NULL); &irq_generic_chip_ops, NULL);
if (!domain) { if (!domain) {
pr_err("%s: unable to add irq domain\n", np->name); pr_err("%pOFn: unable to add irq domain\n", np);
return -ENOMEM; return -ENOMEM;
} }
ret = irq_alloc_domain_generic_chips(domain, nrirqs, 1, np->name, ret = irq_alloc_domain_generic_chips(domain, nrirqs, 1, np->name,
handle_edge_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE); handle_edge_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE);
if (ret) { if (ret) {
pr_err("%s: unable to alloc irq domain gc\n", np->name); pr_err("%pOFn: unable to alloc irq domain gc\n", np);
return ret; return ret;
} }
ret = of_address_to_resource(np, 0, &r); ret = of_address_to_resource(np, 0, &r);
if (ret) { if (ret) {
pr_err("%s: unable to get resource\n", np->name); pr_err("%pOFn: unable to get resource\n", np);
return ret; return ret;
} }
...@@ -175,14 +175,14 @@ static int __init orion_bridge_irq_init(struct device_node *np, ...@@ -175,14 +175,14 @@ static int __init orion_bridge_irq_init(struct device_node *np,
/* Map the parent interrupt for the chained handler */ /* Map the parent interrupt for the chained handler */
irq = irq_of_parse_and_map(np, 0); irq = irq_of_parse_and_map(np, 0);
if (irq <= 0) { if (irq <= 0) {
pr_err("%s: unable to parse irq\n", np->name); pr_err("%pOFn: unable to parse irq\n", np);
return -EINVAL; return -EINVAL;
} }
gc = irq_get_domain_generic_chip(domain, 0); gc = irq_get_domain_generic_chip(domain, 0);
gc->reg_base = ioremap(r.start, resource_size(&r)); gc->reg_base = ioremap(r.start, resource_size(&r));
if (!gc->reg_base) { if (!gc->reg_base) {
pr_err("%s: unable to map resource\n", np->name); pr_err("%pOFn: unable to map resource\n", np);
return -ENOMEM; return -ENOMEM;
} }
......
...@@ -115,21 +115,21 @@ static int __init of_tb10x_init_irq(struct device_node *ictl, ...@@ -115,21 +115,21 @@ static int __init of_tb10x_init_irq(struct device_node *ictl,
void __iomem *reg_base; void __iomem *reg_base;
if (of_address_to_resource(ictl, 0, &mem)) { if (of_address_to_resource(ictl, 0, &mem)) {
pr_err("%s: No registers declared in DeviceTree.\n", pr_err("%pOFn: No registers declared in DeviceTree.\n",
ictl->name); ictl);
return -EINVAL; return -EINVAL;
} }
if (!request_mem_region(mem.start, resource_size(&mem), if (!request_mem_region(mem.start, resource_size(&mem),
ictl->name)) { ictl->full_name)) {
pr_err("%s: Request mem region failed.\n", ictl->name); pr_err("%pOFn: Request mem region failed.\n", ictl);
return -EBUSY; return -EBUSY;
} }
reg_base = ioremap(mem.start, resource_size(&mem)); reg_base = ioremap(mem.start, resource_size(&mem));
if (!reg_base) { if (!reg_base) {
ret = -EBUSY; ret = -EBUSY;
pr_err("%s: ioremap failed.\n", ictl->name); pr_err("%pOFn: ioremap failed.\n", ictl);
goto ioremap_fail; goto ioremap_fail;
} }
...@@ -137,8 +137,8 @@ static int __init of_tb10x_init_irq(struct device_node *ictl, ...@@ -137,8 +137,8 @@ static int __init of_tb10x_init_irq(struct device_node *ictl,
&irq_generic_chip_ops, NULL); &irq_generic_chip_ops, NULL);
if (!domain) { if (!domain) {
ret = -ENOMEM; ret = -ENOMEM;
pr_err("%s: Could not register interrupt domain.\n", pr_err("%pOFn: Could not register interrupt domain.\n",
ictl->name); ictl);
goto irq_domain_add_fail; goto irq_domain_add_fail;
} }
...@@ -147,8 +147,8 @@ static int __init of_tb10x_init_irq(struct device_node *ictl, ...@@ -147,8 +147,8 @@ static int __init of_tb10x_init_irq(struct device_node *ictl,
IRQ_NOREQUEST, IRQ_NOPROBE, IRQ_NOREQUEST, IRQ_NOPROBE,
IRQ_GC_INIT_MASK_CACHE); IRQ_GC_INIT_MASK_CACHE);
if (ret) { if (ret) {
pr_err("%s: Could not allocate generic interrupt chip.\n", pr_err("%pOFn: Could not allocate generic interrupt chip.\n",
ictl->name); ictl);
goto gc_alloc_fail; goto gc_alloc_fail;
} }
......
...@@ -2146,8 +2146,8 @@ static int gpmc_probe_generic_child(struct platform_device *pdev, ...@@ -2146,8 +2146,8 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
gpmc_s.device_width = GPMC_DEVWIDTH_16BIT; gpmc_s.device_width = GPMC_DEVWIDTH_16BIT;
break; break;
default: default:
dev_err(&pdev->dev, "%s: invalid 'nand-bus-width'\n", dev_err(&pdev->dev, "%pOFn: invalid 'nand-bus-width'\n",
child->name); child);
ret = -EINVAL; ret = -EINVAL;
goto err; goto err;
} }
...@@ -2188,8 +2188,8 @@ static int gpmc_probe_generic_child(struct platform_device *pdev, ...@@ -2188,8 +2188,8 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
ret = gpmc_cs_set_timings(cs, &gpmc_t, &gpmc_s); ret = gpmc_cs_set_timings(cs, &gpmc_t, &gpmc_s);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to set gpmc timings for: %s\n", dev_err(&pdev->dev, "failed to set gpmc timings for: %pOFn\n",
child->name); child);
goto err_cs; goto err_cs;
} }
...@@ -2217,7 +2217,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev, ...@@ -2217,7 +2217,7 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
err_child_fail: err_child_fail:
dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name); dev_err(&pdev->dev, "failed to create gpmc child %pOFn\n", child);
ret = -ENODEV; ret = -ENODEV;
err_cs: err_cs:
...@@ -2267,14 +2267,10 @@ static void gpmc_probe_dt_children(struct platform_device *pdev) ...@@ -2267,14 +2267,10 @@ static void gpmc_probe_dt_children(struct platform_device *pdev)
struct device_node *child; struct device_node *child;
for_each_available_child_of_node(pdev->dev.of_node, child) { for_each_available_child_of_node(pdev->dev.of_node, child) {
if (!child->name)
continue;
ret = gpmc_probe_generic_child(pdev, child); ret = gpmc_probe_generic_child(pdev, child);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to probe DT child '%s': %d\n", dev_err(&pdev->dev, "failed to probe DT child '%pOFn': %d\n",
child->name, ret); child, ret);
} }
} }
} }
......
...@@ -139,8 +139,8 @@ static int exynos_srom_probe(struct platform_device *pdev) ...@@ -139,8 +139,8 @@ static int exynos_srom_probe(struct platform_device *pdev)
for_each_child_of_node(np, child) { for_each_child_of_node(np, child) {
if (exynos_srom_configure_bank(srom, child)) { if (exynos_srom_configure_bank(srom, child)) {
dev_err(dev, dev_err(dev,
"Could not decode bank configuration for %s\n", "Could not decode bank configuration for %pOFn\n",
child->name); child);
bad_bank_config = true; bad_bank_config = true;
} }
} }
......
...@@ -345,7 +345,7 @@ static int load_one_timing(struct tegra_mc *mc, ...@@ -345,7 +345,7 @@ static int load_one_timing(struct tegra_mc *mc,
err = of_property_read_u32(node, "clock-frequency", &tmp); err = of_property_read_u32(node, "clock-frequency", &tmp);
if (err) { if (err) {
dev_err(mc->dev, dev_err(mc->dev,
"timing %s: failed to read rate\n", node->name); "timing %pOFn: failed to read rate\n", node);
return err; return err;
} }
...@@ -360,8 +360,8 @@ static int load_one_timing(struct tegra_mc *mc, ...@@ -360,8 +360,8 @@ static int load_one_timing(struct tegra_mc *mc,
mc->soc->num_emem_regs); mc->soc->num_emem_regs);
if (err) { if (err) {
dev_err(mc->dev, dev_err(mc->dev,
"timing %s: failed to read EMEM configuration\n", "timing %pOFn: failed to read EMEM configuration\n",
node->name); node);
return err; return err;
} }
......
...@@ -888,8 +888,8 @@ static int load_one_timing_from_dt(struct tegra_emc *emc, ...@@ -888,8 +888,8 @@ static int load_one_timing_from_dt(struct tegra_emc *emc,
err = of_property_read_u32(node, "clock-frequency", &value); err = of_property_read_u32(node, "clock-frequency", &value);
if (err) { if (err) {
dev_err(emc->dev, "timing %s: failed to read rate: %d\n", dev_err(emc->dev, "timing %pOFn: failed to read rate: %d\n",
node->name, err); node, err);
return err; return err;
} }
...@@ -900,16 +900,16 @@ static int load_one_timing_from_dt(struct tegra_emc *emc, ...@@ -900,16 +900,16 @@ static int load_one_timing_from_dt(struct tegra_emc *emc,
ARRAY_SIZE(timing->emc_burst_data)); ARRAY_SIZE(timing->emc_burst_data));
if (err) { if (err) {
dev_err(emc->dev, dev_err(emc->dev,
"timing %s: failed to read emc burst data: %d\n", "timing %pOFn: failed to read emc burst data: %d\n",
node->name, err); node, err);
return err; return err;
} }
#define EMC_READ_PROP(prop, dtprop) { \ #define EMC_READ_PROP(prop, dtprop) { \
err = of_property_read_u32(node, dtprop, &timing->prop); \ err = of_property_read_u32(node, dtprop, &timing->prop); \
if (err) { \ if (err) { \
dev_err(emc->dev, "timing %s: failed to read " #prop ": %d\n", \ dev_err(emc->dev, "timing %pOFn: failed to read " #prop ": %d\n", \
node->name, err); \ node, err); \
return err; \ return err; \
} \ } \
} }
......
...@@ -212,7 +212,7 @@ static int powernv_flash_set_driver_info(struct device *dev, ...@@ -212,7 +212,7 @@ static int powernv_flash_set_driver_info(struct device *dev,
* Going to have to check what details I need to set and how to * Going to have to check what details I need to set and how to
* get them * get them
*/ */
mtd->name = of_get_property(dev->of_node, "name", NULL); mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%pOFn", dev->of_node);
mtd->type = MTD_NORFLASH; mtd->type = MTD_NORFLASH;
mtd->flags = MTD_WRITEABLE; mtd->flags = MTD_WRITEABLE;
mtd->size = size; mtd->size = size;
......
...@@ -110,8 +110,8 @@ static int of_bus_pci_match(struct device_node *np) ...@@ -110,8 +110,8 @@ static int of_bus_pci_match(struct device_node *np)
* "vci" is for the /chaos bridge on 1st-gen PCI powermacs * "vci" is for the /chaos bridge on 1st-gen PCI powermacs
* "ht" is hypertransport * "ht" is hypertransport
*/ */
return !strcmp(np->type, "pci") || !strcmp(np->type, "pciex") || return of_node_is_type(np, "pci") || of_node_is_type(np, "pciex") ||
!strcmp(np->type, "vci") || !strcmp(np->type, "ht"); of_node_is_type(np, "vci") || of_node_is_type(np, "ht");
} }
static void of_bus_pci_count_cells(struct device_node *np, static void of_bus_pci_count_cells(struct device_node *np,
...@@ -371,7 +371,7 @@ EXPORT_SYMBOL(of_pci_range_to_resource); ...@@ -371,7 +371,7 @@ EXPORT_SYMBOL(of_pci_range_to_resource);
static int of_bus_isa_match(struct device_node *np) static int of_bus_isa_match(struct device_node *np)
{ {
return !strcmp(np->name, "isa"); return of_node_name_eq(np, "isa");
} }
static void of_bus_isa_count_cells(struct device_node *child, static void of_bus_isa_count_cells(struct device_node *child,
......
...@@ -79,6 +79,13 @@ bool of_node_name_prefix(const struct device_node *np, const char *prefix) ...@@ -79,6 +79,13 @@ bool of_node_name_prefix(const struct device_node *np, const char *prefix)
} }
EXPORT_SYMBOL(of_node_name_prefix); EXPORT_SYMBOL(of_node_name_prefix);
static bool __of_node_is_type(const struct device_node *np, const char *type)
{
const char *match = __of_get_property(np, "device_type", NULL);
return np && match && type && !strcmp(match, type);
}
int of_n_addr_cells(struct device_node *np) int of_n_addr_cells(struct device_node *np)
{ {
u32 cells; u32 cells;
...@@ -116,9 +123,6 @@ int __weak of_node_to_nid(struct device_node *np) ...@@ -116,9 +123,6 @@ int __weak of_node_to_nid(struct device_node *np)
} }
#endif #endif
static struct device_node **phandle_cache;
static u32 phandle_cache_mask;
/* /*
* Assumptions behind phandle_cache implementation: * Assumptions behind phandle_cache implementation:
* - phandle property values are in a contiguous range of 1..n * - phandle property values are in a contiguous range of 1..n
...@@ -127,6 +131,66 @@ static u32 phandle_cache_mask; ...@@ -127,6 +131,66 @@ static u32 phandle_cache_mask;
* - the phandle lookup overhead reduction provided by the cache * - the phandle lookup overhead reduction provided by the cache
* will likely be less * will likely be less
*/ */
static struct device_node **phandle_cache;
static u32 phandle_cache_mask;
/*
* Caller must hold devtree_lock.
*/
static void __of_free_phandle_cache(void)
{
u32 cache_entries = phandle_cache_mask + 1;
u32 k;
if (!phandle_cache)
return;
for (k = 0; k < cache_entries; k++)
of_node_put(phandle_cache[k]);
kfree(phandle_cache);
phandle_cache = NULL;
}
int of_free_phandle_cache(void)
{
unsigned long flags;
raw_spin_lock_irqsave(&devtree_lock, flags);
__of_free_phandle_cache();
raw_spin_unlock_irqrestore(&devtree_lock, flags);
return 0;
}
#if !defined(CONFIG_MODULES)
late_initcall_sync(of_free_phandle_cache);
#endif
/*
* Caller must hold devtree_lock.
*/
void __of_free_phandle_cache_entry(phandle handle)
{
phandle masked_handle;
struct device_node *np;
if (!handle)
return;
masked_handle = handle & phandle_cache_mask;
if (phandle_cache) {
np = phandle_cache[masked_handle];
if (np && handle == np->phandle) {
of_node_put(np);
phandle_cache[masked_handle] = NULL;
}
}
}
void of_populate_phandle_cache(void) void of_populate_phandle_cache(void)
{ {
unsigned long flags; unsigned long flags;
...@@ -136,8 +200,7 @@ void of_populate_phandle_cache(void) ...@@ -136,8 +200,7 @@ void of_populate_phandle_cache(void)
raw_spin_lock_irqsave(&devtree_lock, flags); raw_spin_lock_irqsave(&devtree_lock, flags);
kfree(phandle_cache); __of_free_phandle_cache();
phandle_cache = NULL;
for_each_of_allnodes(np) for_each_of_allnodes(np)
if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL) if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL)
...@@ -155,30 +218,15 @@ void of_populate_phandle_cache(void) ...@@ -155,30 +218,15 @@ void of_populate_phandle_cache(void)
goto out; goto out;
for_each_of_allnodes(np) for_each_of_allnodes(np)
if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL) if (np->phandle && np->phandle != OF_PHANDLE_ILLEGAL) {
of_node_get(np);
phandle_cache[np->phandle & phandle_cache_mask] = np; phandle_cache[np->phandle & phandle_cache_mask] = np;
}
out: out:
raw_spin_unlock_irqrestore(&devtree_lock, flags); raw_spin_unlock_irqrestore(&devtree_lock, flags);
} }
int of_free_phandle_cache(void)
{
unsigned long flags;
raw_spin_lock_irqsave(&devtree_lock, flags);
kfree(phandle_cache);
phandle_cache = NULL;
raw_spin_unlock_irqrestore(&devtree_lock, flags);
return 0;
}
#if !defined(CONFIG_MODULES)
late_initcall_sync(of_free_phandle_cache);
#endif
void __init of_core_init(void) void __init of_core_init(void)
{ {
struct device_node *np; struct device_node *np;
...@@ -482,14 +530,14 @@ static int __of_device_is_compatible(const struct device_node *device, ...@@ -482,14 +530,14 @@ static int __of_device_is_compatible(const struct device_node *device,
/* Matching type is better than matching name */ /* Matching type is better than matching name */
if (type && type[0]) { if (type && type[0]) {
if (!device->type || of_node_cmp(type, device->type)) if (!__of_node_is_type(device, type))
return 0; return 0;
score += 2; score += 2;
} }
/* Matching name is a bit better than not */ /* Matching name is a bit better than not */
if (name && name[0]) { if (name && name[0]) {
if (!device->name || of_node_cmp(name, device->name)) if (!of_node_name_eq(device, name))
return 0; return 0;
score++; score++;
} }
...@@ -775,7 +823,7 @@ struct device_node *of_get_next_cpu_node(struct device_node *prev) ...@@ -775,7 +823,7 @@ struct device_node *of_get_next_cpu_node(struct device_node *prev)
} }
for (; next; next = next->sibling) { for (; next; next = next->sibling) {
if (!(of_node_name_eq(next, "cpu") || if (!(of_node_name_eq(next, "cpu") ||
(next->type && !of_node_cmp(next->type, "cpu")))) __of_node_is_type(next, "cpu")))
continue; continue;
if (of_node_get(next)) if (of_node_get(next))
break; break;
...@@ -828,7 +876,7 @@ struct device_node *of_get_child_by_name(const struct device_node *node, ...@@ -828,7 +876,7 @@ struct device_node *of_get_child_by_name(const struct device_node *node,
struct device_node *child; struct device_node *child;
for_each_child_of_node(node, child) for_each_child_of_node(node, child)
if (child->name && (of_node_cmp(child->name, name) == 0)) if (of_node_name_eq(child, name))
break; break;
return child; return child;
} }
...@@ -954,8 +1002,7 @@ struct device_node *of_find_node_by_name(struct device_node *from, ...@@ -954,8 +1002,7 @@ struct device_node *of_find_node_by_name(struct device_node *from,
raw_spin_lock_irqsave(&devtree_lock, flags); raw_spin_lock_irqsave(&devtree_lock, flags);
for_each_of_allnodes_from(from, np) for_each_of_allnodes_from(from, np)
if (np->name && (of_node_cmp(np->name, name) == 0) if (of_node_name_eq(np, name) && of_node_get(np))
&& of_node_get(np))
break; break;
of_node_put(from); of_node_put(from);
raw_spin_unlock_irqrestore(&devtree_lock, flags); raw_spin_unlock_irqrestore(&devtree_lock, flags);
...@@ -983,8 +1030,7 @@ struct device_node *of_find_node_by_type(struct device_node *from, ...@@ -983,8 +1030,7 @@ struct device_node *of_find_node_by_type(struct device_node *from,
raw_spin_lock_irqsave(&devtree_lock, flags); raw_spin_lock_irqsave(&devtree_lock, flags);
for_each_of_allnodes_from(from, np) for_each_of_allnodes_from(from, np)
if (np->type && (of_node_cmp(np->type, type) == 0) if (__of_node_is_type(np, type) && of_node_get(np))
&& of_node_get(np))
break; break;
of_node_put(from); of_node_put(from);
raw_spin_unlock_irqrestore(&devtree_lock, flags); raw_spin_unlock_irqrestore(&devtree_lock, flags);
...@@ -1190,13 +1236,23 @@ struct device_node *of_find_node_by_phandle(phandle handle) ...@@ -1190,13 +1236,23 @@ struct device_node *of_find_node_by_phandle(phandle handle)
if (phandle_cache[masked_handle] && if (phandle_cache[masked_handle] &&
handle == phandle_cache[masked_handle]->phandle) handle == phandle_cache[masked_handle]->phandle)
np = phandle_cache[masked_handle]; np = phandle_cache[masked_handle];
if (np && of_node_check_flag(np, OF_DETACHED)) {
WARN_ON(1); /* did not uncache np on node removal */
of_node_put(np);
phandle_cache[masked_handle] = NULL;
np = NULL;
}
} }
if (!np) { if (!np) {
for_each_of_allnodes(np) for_each_of_allnodes(np)
if (np->phandle == handle) { if (np->phandle == handle &&
if (phandle_cache) !of_node_check_flag(np, OF_DETACHED)) {
if (phandle_cache) {
/* will put when removed from cache */
of_node_get(np);
phandle_cache[masked_handle] = np; phandle_cache[masked_handle] = np;
}
break; break;
} }
} }
...@@ -2108,9 +2164,9 @@ struct device_node *of_find_next_cache_node(const struct device_node *np) ...@@ -2108,9 +2164,9 @@ struct device_node *of_find_next_cache_node(const struct device_node *np)
/* OF on pmac has nodes instead of properties named "l2-cache" /* OF on pmac has nodes instead of properties named "l2-cache"
* beneath CPU nodes. * beneath CPU nodes.
*/ */
if (IS_ENABLED(CONFIG_PPC_PMAC) && !strcmp(np->type, "cpu")) if (IS_ENABLED(CONFIG_PPC_PMAC) && of_node_is_type(np, "cpu"))
for_each_child_of_node(np, child) for_each_child_of_node(np, child)
if (!strcmp(child->type, "cache")) if (of_node_is_type(child, "cache"))
return child; return child;
return NULL; return NULL;
......
...@@ -211,7 +211,7 @@ static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len ...@@ -211,7 +211,7 @@ static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len
/* Name & Type */ /* Name & Type */
/* %p eats all alphanum characters, so %c must be used here */ /* %p eats all alphanum characters, so %c must be used here */
csize = snprintf(str, len, "of:N%pOFn%c%s", dev->of_node, 'T', csize = snprintf(str, len, "of:N%pOFn%c%s", dev->of_node, 'T',
dev->of_node->type); of_node_get_device_type(dev->of_node));
tsize = csize; tsize = csize;
len -= csize; len -= csize;
if (str) if (str)
...@@ -281,7 +281,7 @@ EXPORT_SYMBOL_GPL(of_device_modalias); ...@@ -281,7 +281,7 @@ EXPORT_SYMBOL_GPL(of_device_modalias);
*/ */
void of_device_uevent(struct device *dev, struct kobj_uevent_env *env) void of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
{ {
const char *compat; const char *compat, *type;
struct alias_prop *app; struct alias_prop *app;
struct property *p; struct property *p;
int seen = 0; int seen = 0;
...@@ -291,8 +291,9 @@ void of_device_uevent(struct device *dev, struct kobj_uevent_env *env) ...@@ -291,8 +291,9 @@ void of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
add_uevent_var(env, "OF_NAME=%pOFn", dev->of_node); add_uevent_var(env, "OF_NAME=%pOFn", dev->of_node);
add_uevent_var(env, "OF_FULLNAME=%pOF", dev->of_node); add_uevent_var(env, "OF_FULLNAME=%pOF", dev->of_node);
if (dev->of_node->type && strcmp("<NULL>", dev->of_node->type) != 0) type = of_node_get_device_type(dev->of_node);
add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type); if (type)
add_uevent_var(env, "OF_TYPE=%s", type);
/* Since the compatible field can contain pretty much anything /* Since the compatible field can contain pretty much anything
* it's not really legal to split it out with commas. We split it * it's not really legal to split it out with commas. We split it
......
...@@ -205,15 +205,24 @@ static void __of_attach_node(struct device_node *np) ...@@ -205,15 +205,24 @@ static void __of_attach_node(struct device_node *np)
const __be32 *phandle; const __be32 *phandle;
int sz; int sz;
np->name = __of_get_property(np, "name", NULL) ? : "<NULL>"; if (!of_node_check_flag(np, OF_OVERLAY)) {
np->type = __of_get_property(np, "device_type", NULL) ? : "<NULL>"; np->name = __of_get_property(np, "name", NULL);
np->type = __of_get_property(np, "device_type", NULL);
if (!np->name)
np->name = "<NULL>";
if (!np->type)
np->type = "<NULL>";
phandle = __of_get_property(np, "phandle", &sz); phandle = __of_get_property(np, "phandle", &sz);
if (!phandle) if (!phandle)
phandle = __of_get_property(np, "linux,phandle", &sz); phandle = __of_get_property(np, "linux,phandle", &sz);
if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle) if (IS_ENABLED(CONFIG_PPC_PSERIES) && !phandle)
phandle = __of_get_property(np, "ibm,phandle", &sz); phandle = __of_get_property(np, "ibm,phandle", &sz);
np->phandle = (phandle && (sz >= 4)) ? be32_to_cpup(phandle) : 0; if (phandle && (sz >= 4))
np->phandle = be32_to_cpup(phandle);
else
np->phandle = 0;
}
np->child = NULL; np->child = NULL;
np->sibling = np->parent->child; np->sibling = np->parent->child;
...@@ -268,13 +277,13 @@ void __of_detach_node(struct device_node *np) ...@@ -268,13 +277,13 @@ void __of_detach_node(struct device_node *np)
} }
of_node_set_flag(np, OF_DETACHED); of_node_set_flag(np, OF_DETACHED);
/* race with of_find_node_by_phandle() prevented by devtree_lock */
__of_free_phandle_cache_entry(np->phandle);
} }
/** /**
* of_detach_node() - "Unplug" a node from the device tree. * of_detach_node() - "Unplug" a node from the device tree.
*
* The caller must hold a reference to the node. The memory associated with
* the node is not freed until its refcount goes to zero.
*/ */
int of_detach_node(struct device_node *np) int of_detach_node(struct device_node *np)
{ {
...@@ -330,6 +339,25 @@ void of_node_release(struct kobject *kobj) ...@@ -330,6 +339,25 @@ void of_node_release(struct kobject *kobj)
if (!of_node_check_flag(node, OF_DYNAMIC)) if (!of_node_check_flag(node, OF_DYNAMIC))
return; return;
if (of_node_check_flag(node, OF_OVERLAY)) {
if (!of_node_check_flag(node, OF_OVERLAY_FREE_CSET)) {
/* premature refcount of zero, do not free memory */
pr_err("ERROR: memory leak before free overlay changeset, %pOF\n",
node);
return;
}
/*
* If node->properties non-empty then properties were added
* to this node either by different overlay that has not
* yet been removed, or by a non-overlay mechanism.
*/
if (node->properties)
pr_err("ERROR: %s(), unexpected properties in %pOF\n",
__func__, node);
}
property_list_free(node->properties); property_list_free(node->properties);
property_list_free(node->deadprops); property_list_free(node->deadprops);
...@@ -434,6 +462,16 @@ struct device_node *__of_node_dup(const struct device_node *np, ...@@ -434,6 +462,16 @@ struct device_node *__of_node_dup(const struct device_node *np,
static void __of_changeset_entry_destroy(struct of_changeset_entry *ce) static void __of_changeset_entry_destroy(struct of_changeset_entry *ce)
{ {
if (ce->action == OF_RECONFIG_ATTACH_NODE &&
of_node_check_flag(ce->np, OF_OVERLAY)) {
if (kref_read(&ce->np->kobj.kref) > 1) {
pr_err("ERROR: memory leak, expected refcount 1 instead of %d, of_node_get()/of_node_put() unbalanced - destroy cset entry: attach overlay node %pOF\n",
kref_read(&ce->np->kobj.kref), ce->np);
} else {
of_node_set_flag(ce->np, OF_OVERLAY_FREE_CSET);
}
}
of_node_put(ce->np); of_node_put(ce->np);
list_del(&ce->node); list_del(&ce->node);
kfree(ce); kfree(ce);
......
...@@ -891,15 +891,20 @@ const void * __init of_flat_dt_match_machine(const void *default_match, ...@@ -891,15 +891,20 @@ const void * __init of_flat_dt_match_machine(const void *default_match,
} }
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
#ifndef __early_init_dt_declare_initrd
static void __early_init_dt_declare_initrd(unsigned long start, static void __early_init_dt_declare_initrd(unsigned long start,
unsigned long end) unsigned long end)
{ {
/* ARM64 would cause a BUG to occur here when CONFIG_DEBUG_VM is
* enabled since __va() is called too early. ARM64 does make use
* of phys_initrd_start/phys_initrd_size so we can skip this
* conversion.
*/
if (!IS_ENABLED(CONFIG_ARM64)) {
initrd_start = (unsigned long)__va(start); initrd_start = (unsigned long)__va(start);
initrd_end = (unsigned long)__va(end); initrd_end = (unsigned long)__va(end);
initrd_below_start_ok = 1; initrd_below_start_ok = 1;
}
} }
#endif
/** /**
* early_init_dt_check_for_initrd - Decode initrd location from flat tree * early_init_dt_check_for_initrd - Decode initrd location from flat tree
...@@ -924,6 +929,8 @@ static void __init early_init_dt_check_for_initrd(unsigned long node) ...@@ -924,6 +929,8 @@ static void __init early_init_dt_check_for_initrd(unsigned long node)
end = of_read_number(prop, len/4); end = of_read_number(prop, len/4);
__early_init_dt_declare_initrd(start, end); __early_init_dt_declare_initrd(start, end);
phys_initrd_start = start;
phys_initrd_size = end - start;
pr_debug("initrd_start=0x%llx initrd_end=0x%llx\n", pr_debug("initrd_start=0x%llx initrd_end=0x%llx\n",
(unsigned long long)start, (unsigned long long)end); (unsigned long long)start, (unsigned long long)end);
...@@ -1200,8 +1207,12 @@ bool __init early_init_dt_verify(void *params) ...@@ -1200,8 +1207,12 @@ bool __init early_init_dt_verify(void *params)
void __init early_init_dt_scan_nodes(void) void __init early_init_dt_scan_nodes(void)
{ {
int rc = 0;
/* Retrieve various information from the /chosen node */ /* Retrieve various information from the /chosen node */
of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line); rc = of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
if (!rc)
pr_warn("No chosen node found, continuing without\n");
/* Initialize {size,address}-cells info */ /* Initialize {size,address}-cells info */
of_scan_flat_dt(early_init_dt_scan_root, NULL); of_scan_flat_dt(early_init_dt_scan_root, NULL);
......
...@@ -133,6 +133,9 @@ int __of_attach_node_sysfs(struct device_node *np) ...@@ -133,6 +133,9 @@ int __of_attach_node_sysfs(struct device_node *np)
} }
if (!name) if (!name)
return -ENOMEM; return -ENOMEM;
of_node_get(np);
rc = kobject_add(&np->kobj, parent, "%s", name); rc = kobject_add(&np->kobj, parent, "%s", name);
kfree(name); kfree(name);
if (rc) if (rc)
...@@ -159,6 +162,5 @@ void __of_detach_node_sysfs(struct device_node *np) ...@@ -159,6 +162,5 @@ void __of_detach_node_sysfs(struct device_node *np)
kobject_del(&np->kobj); kobject_del(&np->kobj);
} }
/* finally remove the kobj_init ref */
of_node_put(np); of_node_put(np);
} }
...@@ -84,6 +84,10 @@ static inline void __of_detach_node_sysfs(struct device_node *np) {} ...@@ -84,6 +84,10 @@ static inline void __of_detach_node_sysfs(struct device_node *np) {}
int of_resolve_phandles(struct device_node *tree); int of_resolve_phandles(struct device_node *tree);
#endif #endif
#if defined(CONFIG_OF_DYNAMIC)
void __of_free_phandle_cache_entry(phandle handle);
#endif
#if defined(CONFIG_OF_OVERLAY) #if defined(CONFIG_OF_OVERLAY)
void of_overlay_mutex_lock(void); void of_overlay_mutex_lock(void);
void of_overlay_mutex_unlock(void); void of_overlay_mutex_unlock(void);
......
This diff is collapsed.
...@@ -21,8 +21,6 @@ ...@@ -21,8 +21,6 @@
static struct of_pdt_ops *of_pdt_prom_ops __initdata; static struct of_pdt_ops *of_pdt_prom_ops __initdata;
void __initdata (*of_pdt_build_more)(struct device_node *dp);
#if defined(CONFIG_SPARC) #if defined(CONFIG_SPARC)
unsigned int of_pdt_unique_id __initdata; unsigned int of_pdt_unique_id __initdata;
...@@ -189,9 +187,6 @@ static struct device_node * __init of_pdt_build_tree(struct device_node *parent, ...@@ -189,9 +187,6 @@ static struct device_node * __init of_pdt_build_tree(struct device_node *parent,
dp->child = of_pdt_build_tree(dp, of_pdt_prom_ops->getchild(node)); dp->child = of_pdt_build_tree(dp, of_pdt_prom_ops->getchild(node));
if (of_pdt_build_more)
of_pdt_build_more(dp);
node = of_pdt_prom_ops->getsibling(node); node = of_pdt_prom_ops->getsibling(node);
} }
......
...@@ -571,7 +571,7 @@ struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id) ...@@ -571,7 +571,7 @@ struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id)
for_each_child_of_node(parent, port) { for_each_child_of_node(parent, port) {
u32 port_id = 0; u32 port_id = 0;
if (of_node_cmp(port->name, "port") != 0) if (!of_node_name_eq(port, "port"))
continue; continue;
of_property_read_u32(port, "reg", &port_id); of_property_read_u32(port, "reg", &port_id);
if (id == port_id) if (id == port_id)
...@@ -646,7 +646,7 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, ...@@ -646,7 +646,7 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
port = of_get_next_child(parent, port); port = of_get_next_child(parent, port);
if (!port) if (!port)
return NULL; return NULL;
} while (of_node_cmp(port->name, "port")); } while (!of_node_name_eq(port, "port"));
} }
} }
EXPORT_SYMBOL(of_graph_get_next_endpoint); EXPORT_SYMBOL(of_graph_get_next_endpoint);
...@@ -715,7 +715,7 @@ struct device_node *of_graph_get_port_parent(struct device_node *node) ...@@ -715,7 +715,7 @@ struct device_node *of_graph_get_port_parent(struct device_node *node)
/* Walk 3 levels up only if there is 'ports' node. */ /* Walk 3 levels up only if there is 'ports' node. */
for (depth = 3; depth && node; depth--) { for (depth = 3; depth && node; depth--) {
node = of_get_next_parent(node); node = of_get_next_parent(node);
if (depth == 2 && of_node_cmp(node->name, "ports")) if (depth == 2 && !of_node_name_eq(node, "ports"))
break; break;
} }
return node; return node;
...@@ -893,7 +893,7 @@ of_fwnode_get_named_child_node(const struct fwnode_handle *fwnode, ...@@ -893,7 +893,7 @@ of_fwnode_get_named_child_node(const struct fwnode_handle *fwnode,
struct device_node *child; struct device_node *child;
for_each_available_child_of_node(node, child) for_each_available_child_of_node(node, child)
if (!of_node_cmp(child->name, childname)) if (of_node_name_eq(child, childname))
return of_fwnode_handle(child); return of_fwnode_handle(child);
return NULL; return NULL;
...@@ -955,7 +955,7 @@ of_fwnode_graph_get_port_parent(struct fwnode_handle *fwnode) ...@@ -955,7 +955,7 @@ of_fwnode_graph_get_port_parent(struct fwnode_handle *fwnode)
return NULL; return NULL;
/* Is this the "ports" node? If not, it's the port parent. */ /* Is this the "ports" node? If not, it's the port parent. */
if (of_node_cmp(np->name, "ports")) if (!of_node_name_eq(np, "ports"))
return of_fwnode_handle(np); return of_fwnode_handle(np);
return of_fwnode_handle(of_get_next_parent(np)); return of_fwnode_handle(of_get_next_parent(np));
......
...@@ -281,7 +281,7 @@ int of_resolve_phandles(struct device_node *overlay) ...@@ -281,7 +281,7 @@ int of_resolve_phandles(struct device_node *overlay)
adjust_overlay_phandles(overlay, phandle_delta); adjust_overlay_phandles(overlay, phandle_delta);
for_each_child_of_node(overlay, local_fixups) for_each_child_of_node(overlay, local_fixups)
if (!of_node_cmp(local_fixups->name, "__local_fixups__")) if (of_node_name_eq(local_fixups, "__local_fixups__"))
break; break;
err = adjust_local_phandle_references(local_fixups, overlay, phandle_delta); err = adjust_local_phandle_references(local_fixups, overlay, phandle_delta);
...@@ -291,7 +291,7 @@ int of_resolve_phandles(struct device_node *overlay) ...@@ -291,7 +291,7 @@ int of_resolve_phandles(struct device_node *overlay)
overlay_fixups = NULL; overlay_fixups = NULL;
for_each_child_of_node(overlay, child) { for_each_child_of_node(overlay, child) {
if (!of_node_cmp(child->name, "__fixups__")) if (of_node_name_eq(child, "__fixups__"))
overlay_fixups = child; overlay_fixups = child;
} }
......
...@@ -17,6 +17,8 @@ obj-$(CONFIG_OF_OVERLAY) += overlay.dtb.o \ ...@@ -17,6 +17,8 @@ obj-$(CONFIG_OF_OVERLAY) += overlay.dtb.o \
overlay_12.dtb.o \ overlay_12.dtb.o \
overlay_13.dtb.o \ overlay_13.dtb.o \
overlay_15.dtb.o \ overlay_15.dtb.o \
overlay_bad_add_dup_node.dtb.o \
overlay_bad_add_dup_prop.dtb.o \
overlay_bad_phandle.dtb.o \ overlay_bad_phandle.dtb.o \
overlay_bad_symbol.dtb.o \ overlay_bad_symbol.dtb.o \
overlay_base.dtb.o overlay_base.dtb.o
......
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
/plugin/;
/*
* &electric_1/motor-1 and &spin_ctrl_1 are the same node:
* /testcase-data-2/substation@100/motor-1
*
* Thus the new node "controller" in each fragment will
* result in an attempt to add the same node twice.
* This will result in an error and the overlay apply
* will fail.
*/
&electric_1 {
motor-1 {
controller {
power_bus = < 0x1 0x2 >;
};
};
};
&spin_ctrl_1 {
controller {
power_bus_emergency = < 0x101 0x102 >;
};
};
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
/plugin/;
/*
* &electric_1/motor-1 and &spin_ctrl_1 are the same node:
* /testcase-data-2/substation@100/motor-1
*
* Thus the property "rpm_avail" in each fragment will
* result in an attempt to update the same property twice.
* This will result in an error and the overlay apply
* will fail.
*/
&electric_1 {
motor-1 {
rpm_avail = < 100 >;
};
};
&spin_ctrl_1 {
rpm_avail = < 100 200 >;
};
...@@ -30,6 +30,7 @@ hvac_1: hvac-medium-1 { ...@@ -30,6 +30,7 @@ hvac_1: hvac-medium-1 {
spin_ctrl_1: motor-1 { spin_ctrl_1: motor-1 {
compatible = "ot,ferris-wheel-motor"; compatible = "ot,ferris-wheel-motor";
spin = "clockwise"; spin = "clockwise";
rpm_avail = < 50 >;
}; };
spin_ctrl_2: motor-8 { spin_ctrl_2: motor-8 {
......
This diff is collapsed.
...@@ -65,7 +65,7 @@ static int axxia_reset_probe(struct platform_device *pdev) ...@@ -65,7 +65,7 @@ static int axxia_reset_probe(struct platform_device *pdev)
syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
if (IS_ERR(syscon)) { if (IS_ERR(syscon)) {
pr_err("%s: syscon lookup failed\n", dev->of_node->name); pr_err("%pOFn: syscon lookup failed\n", dev->of_node);
return PTR_ERR(syscon); return PTR_ERR(syscon);
} }
......
...@@ -330,7 +330,7 @@ static int pm8941_wled_configure(struct pm8941_wled *wled, struct device *dev) ...@@ -330,7 +330,7 @@ static int pm8941_wled_configure(struct pm8941_wled *wled, struct device *dev)
rc = of_property_read_string(dev->of_node, "label", &wled->name); rc = of_property_read_string(dev->of_node, "label", &wled->name);
if (rc) if (rc)
wled->name = dev->of_node->name; wled->name = devm_kasprintf(dev, GFP_KERNEL, "%pOFn", dev->of_node);
*cfg = pm8941_wled_config_defaults; *cfg = pm8941_wled_config_defaults;
for (i = 0; i < ARRAY_SIZE(u32_opts); ++i) { for (i = 0; i < ARRAY_SIZE(u32_opts); ++i) {
......
...@@ -21,4 +21,7 @@ extern int initrd_below_start_ok; ...@@ -21,4 +21,7 @@ extern int initrd_below_start_ok;
extern unsigned long initrd_start, initrd_end; extern unsigned long initrd_start, initrd_end;
extern void free_initrd_mem(unsigned long, unsigned long); extern void free_initrd_mem(unsigned long, unsigned long);
extern phys_addr_t phys_initrd_start;
extern unsigned long phys_initrd_size;
extern unsigned int real_root_dev; extern unsigned int real_root_dev;
...@@ -137,11 +137,16 @@ extern struct device_node *of_aliases; ...@@ -137,11 +137,16 @@ extern struct device_node *of_aliases;
extern struct device_node *of_stdout; extern struct device_node *of_stdout;
extern raw_spinlock_t devtree_lock; extern raw_spinlock_t devtree_lock;
/* flag descriptions (need to be visible even when !CONFIG_OF) */ /*
#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */ * struct device_node flag descriptions
#define OF_DETACHED 2 /* node has been detached from the device tree */ * (need to be visible even when !CONFIG_OF)
#define OF_POPULATED 3 /* device already created for the node */ */
#define OF_POPULATED_BUS 4 /* of_platform_populate recursed to children of this node */ #define OF_DYNAMIC 1 /* (and properties) allocated via kmalloc */
#define OF_DETACHED 2 /* detached from the device tree */
#define OF_POPULATED 3 /* device already created */
#define OF_POPULATED_BUS 4 /* platform bus created for children */
#define OF_OVERLAY 5 /* allocated for an overlay */
#define OF_OVERLAY_FREE_CSET 6 /* in overlay cset being freed */
#define OF_BAD_ADDR ((u64)-1) #define OF_BAD_ADDR ((u64)-1)
...@@ -984,6 +989,12 @@ static inline int of_map_rid(struct device_node *np, u32 rid, ...@@ -984,6 +989,12 @@ static inline int of_map_rid(struct device_node *np, u32 rid,
#define of_node_cmp(s1, s2) strcasecmp((s1), (s2)) #define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
#endif #endif
static inline int of_prop_val_eq(struct property *p1, struct property *p2)
{
return p1->length == p2->length &&
!memcmp(p1->value, p2->value, (size_t)p1->length);
}
#if defined(CONFIG_OF) && defined(CONFIG_NUMA) #if defined(CONFIG_OF) && defined(CONFIG_NUMA)
extern int of_node_to_nid(struct device_node *np); extern int of_node_to_nid(struct device_node *np);
#else #else
......
...@@ -35,6 +35,4 @@ extern void *prom_early_alloc(unsigned long size); ...@@ -35,6 +35,4 @@ extern void *prom_early_alloc(unsigned long size);
/* for building the device tree */ /* for building the device tree */
extern void of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops); extern void of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops);
extern void (*of_pdt_build_more)(struct device_node *dp);
#endif /* _LINUX_OF_PDT_H */ #endif /* _LINUX_OF_PDT_H */
...@@ -16,6 +16,9 @@ int initrd_below_start_ok; ...@@ -16,6 +16,9 @@ int initrd_below_start_ok;
unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */ unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */
static int __initdata mount_initrd = 1; static int __initdata mount_initrd = 1;
phys_addr_t phys_initrd_start __initdata;
unsigned long phys_initrd_size __initdata;
static int __init no_initrd(char *str) static int __init no_initrd(char *str)
{ {
mount_initrd = 0; mount_initrd = 0;
...@@ -24,6 +27,23 @@ static int __init no_initrd(char *str) ...@@ -24,6 +27,23 @@ static int __init no_initrd(char *str)
__setup("noinitrd", no_initrd); __setup("noinitrd", no_initrd);
static int __init early_initrd(char *p)
{
phys_addr_t start;
unsigned long size;
char *endp;
start = memparse(p, &endp);
if (*endp == ',') {
size = memparse(endp + 1, NULL);
phys_initrd_start = start;
phys_initrd_size = size;
}
return 0;
}
early_param("initrd", early_initrd);
static int init_linuxrc(struct subprocess_info *info, struct cred *new) static int init_linuxrc(struct subprocess_info *info, struct cred *new)
{ {
ksys_unshare(CLONE_FS | CLONE_FILES); ksys_unshare(CLONE_FS | CLONE_FILES);
......
...@@ -61,6 +61,11 @@ real-obj-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) ...@@ -61,6 +61,11 @@ real-obj-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))
extra-y += $(dtb-y) extra-y += $(dtb-y)
extra-$(CONFIG_OF_ALL_DTBS) += $(dtb-) extra-$(CONFIG_OF_ALL_DTBS) += $(dtb-)
ifneq ($(CHECK_DTBS),)
extra-y += $(patsubst %.dtb,%.dt.yaml, $(dtb-y))
extra-$(CONFIG_OF_ALL_DTBS) += $(patsubst %.dtb,%.dt.yaml, $(dtb-))
endif
# Add subdir path # Add subdir path
extra-y := $(addprefix $(obj)/,$(extra-y)) extra-y := $(addprefix $(obj)/,$(extra-y))
...@@ -251,7 +256,7 @@ DTC_FLAGS += -Wno-unit_address_vs_reg \ ...@@ -251,7 +256,7 @@ DTC_FLAGS += -Wno-unit_address_vs_reg \
-Wno-avoid_unnecessary_addr_size \ -Wno-avoid_unnecessary_addr_size \
-Wno-alias_paths \ -Wno-alias_paths \
-Wno-graph_child_address \ -Wno-graph_child_address \
-Wno-graph_port \ -Wno-simple_bus_reg \
-Wno-unique_unit_address \ -Wno-unique_unit_address \
-Wno-pci_device_reg -Wno-pci_device_reg
endif endif
...@@ -284,13 +289,28 @@ $(obj)/%.dtb.S: $(obj)/%.dtb FORCE ...@@ -284,13 +289,28 @@ $(obj)/%.dtb.S: $(obj)/%.dtb FORCE
quiet_cmd_dtc = DTC $@ quiet_cmd_dtc = DTC $@
cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
$(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
$(DTC) -O dtb -o $@ -b 0 \ $(DTC) -O $(2) -o $@ -b 0 \
$(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \ $(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \
-d $(depfile).dtc.tmp $(dtc-tmp) ; \ -d $(depfile).dtc.tmp $(dtc-tmp) ; \
cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
$(obj)/%.dtb: $(src)/%.dts $(DTC) FORCE $(obj)/%.dtb: $(src)/%.dts $(DTC) FORCE
$(call if_changed_dep,dtc) $(call if_changed_dep,dtc,dtb)
DT_CHECKER ?= dt-validate
DT_BINDING_DIR := Documentation/devicetree/bindings
DT_TMP_SCHEMA := $(objtree)/$(DT_BINDING_DIR)/processed-schema.yaml
quiet_cmd_dtb_check = CHECK $@
cmd_dtb_check = $(DT_CHECKER) -p $(DT_TMP_SCHEMA) $@ ;
define rule_dtc_dt_yaml
$(call cmd_and_fixdep,dtc,yaml) \
$(call echo-cmd,dtb_check) $(cmd_dtb_check)
endef
$(obj)/%.dt.yaml: $(src)/%.dts $(DTC) $(DT_TMP_SCHEMA) FORCE
$(call if_changed_rule,dtc_dt_yaml)
dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
......
...@@ -12,6 +12,10 @@ dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o ...@@ -12,6 +12,10 @@ dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o
HOST_EXTRACFLAGS := -I$(src)/libfdt HOST_EXTRACFLAGS := -I$(src)/libfdt
ifeq ($(wildcard /usr/include/yaml.h),) ifeq ($(wildcard /usr/include/yaml.h),)
ifneq ($(CHECK_DTBS),)
$(error dtc needs libyaml for DT schema validation support. \
Install the necessary libyaml development package.)
endif
HOST_EXTRACFLAGS += -DNO_YAML HOST_EXTRACFLAGS += -DNO_YAML
else else
dtc-objs += yamltree.o dtc-objs += yamltree.o
......
This diff is collapsed.
...@@ -213,14 +213,14 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...); ...@@ -213,14 +213,14 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
<*>\&{LABEL} { /* label reference */ <*>\&{LABEL} { /* label reference */
DPRINT("Ref: %s\n", yytext+1); DPRINT("Ref: %s\n", yytext+1);
yylval.labelref = xstrdup(yytext+1); yylval.labelref = xstrdup(yytext+1);
return DT_REF; return DT_LABEL_REF;
} }
<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */ <*>"&{/"{PATHCHAR}*\} { /* new-style path reference */
yytext[yyleng-1] = '\0'; yytext[yyleng-1] = '\0';
DPRINT("Ref: %s\n", yytext+2); DPRINT("Ref: %s\n", yytext+2);
yylval.labelref = xstrdup(yytext+2); yylval.labelref = xstrdup(yytext+2);
return DT_REF; return DT_PATH_REF;
} }
<BYTESTRING>[0-9a-fA-F]{2} { <BYTESTRING>[0-9a-fA-F]{2} {
......
This diff is collapsed.
...@@ -35,6 +35,8 @@ int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties * ...@@ -35,6 +35,8 @@ int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties *
int generate_symbols; /* enable symbols & fixup support */ int generate_symbols; /* enable symbols & fixup support */
int generate_fixups; /* suppress generation of fixups on symbol support */ int generate_fixups; /* suppress generation of fixups on symbol support */
int auto_label_aliases; /* auto generate labels -> aliases */ int auto_label_aliases; /* auto generate labels -> aliases */
int annotate; /* Level of annotation: 1 for input source location
>1 for full input source location. */
static int is_power_of_2(int x) static int is_power_of_2(int x)
{ {
...@@ -60,7 +62,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix) ...@@ -60,7 +62,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
/* Usage related data. */ /* Usage related data. */
static const char usage_synopsis[] = "dtc [options] <input file>"; static const char usage_synopsis[] = "dtc [options] <input file>";
static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@Ahv"; static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@AThv";
static struct option const usage_long_opts[] = { static struct option const usage_long_opts[] = {
{"quiet", no_argument, NULL, 'q'}, {"quiet", no_argument, NULL, 'q'},
{"in-format", a_argument, NULL, 'I'}, {"in-format", a_argument, NULL, 'I'},
...@@ -81,6 +83,7 @@ static struct option const usage_long_opts[] = { ...@@ -81,6 +83,7 @@ static struct option const usage_long_opts[] = {
{"error", a_argument, NULL, 'E'}, {"error", a_argument, NULL, 'E'},
{"symbols", no_argument, NULL, '@'}, {"symbols", no_argument, NULL, '@'},
{"auto-alias", no_argument, NULL, 'A'}, {"auto-alias", no_argument, NULL, 'A'},
{"annotate", no_argument, NULL, 'T'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'v'},
{NULL, no_argument, NULL, 0x0}, {NULL, no_argument, NULL, 0x0},
...@@ -117,6 +120,7 @@ static const char * const usage_opts_help[] = { ...@@ -117,6 +120,7 @@ static const char * const usage_opts_help[] = {
"\n\tEnable/disable errors (prefix with \"no-\")", "\n\tEnable/disable errors (prefix with \"no-\")",
"\n\tEnable generation of symbols", "\n\tEnable generation of symbols",
"\n\tEnable auto-alias of labels", "\n\tEnable auto-alias of labels",
"\n\tAnnotate output .dts with input source file and line (-T -T for more details)",
"\n\tPrint this help and exit", "\n\tPrint this help and exit",
"\n\tPrint version and exit", "\n\tPrint version and exit",
NULL, NULL,
...@@ -264,6 +268,9 @@ int main(int argc, char *argv[]) ...@@ -264,6 +268,9 @@ int main(int argc, char *argv[])
case 'A': case 'A':
auto_label_aliases = 1; auto_label_aliases = 1;
break; break;
case 'T':
annotate++;
break;
case 'h': case 'h':
usage(NULL); usage(NULL);
...@@ -302,6 +309,8 @@ int main(int argc, char *argv[]) ...@@ -302,6 +309,8 @@ int main(int argc, char *argv[])
outform = "dts"; outform = "dts";
} }
} }
if (annotate && (!streq(inform, "dts") || !streq(outform, "dts")))
die("--annotate requires -I dts -O dts\n");
if (streq(inform, "dts")) if (streq(inform, "dts"))
dti = dt_from_source(arg); dti = dt_from_source(arg);
else if (streq(inform, "fs")) else if (streq(inform, "fs"))
......
...@@ -58,6 +58,7 @@ extern int phandle_format; /* Use linux,phandle or phandle properties */ ...@@ -58,6 +58,7 @@ extern int phandle_format; /* Use linux,phandle or phandle properties */
extern int generate_symbols; /* generate symbols for nodes with labels */ extern int generate_symbols; /* generate symbols for nodes with labels */
extern int generate_fixups; /* generate fixups */ extern int generate_fixups; /* generate fixups */
extern int auto_label_aliases; /* auto generate labels -> aliases */ extern int auto_label_aliases; /* auto generate labels -> aliases */
extern int annotate; /* annotate .dts with input source location */
#define PHANDLE_LEGACY 0x1 #define PHANDLE_LEGACY 0x1
#define PHANDLE_EPAPR 0x2 #define PHANDLE_EPAPR 0x2
...@@ -158,6 +159,7 @@ struct property { ...@@ -158,6 +159,7 @@ struct property {
struct property *next; struct property *next;
struct label *labels; struct label *labels;
struct srcpos *srcpos;
}; };
struct node { struct node {
...@@ -177,6 +179,7 @@ struct node { ...@@ -177,6 +179,7 @@ struct node {
struct label *labels; struct label *labels;
const struct bus_type *bus; const struct bus_type *bus;
struct srcpos *srcpos;
bool omit_if_unused, is_referenced; bool omit_if_unused, is_referenced;
}; };
...@@ -205,13 +208,15 @@ struct node { ...@@ -205,13 +208,15 @@ struct node {
void add_label(struct label **labels, char *label); void add_label(struct label **labels, char *label);
void delete_labels(struct label **labels); void delete_labels(struct label **labels);
struct property *build_property(char *name, struct data val); struct property *build_property(char *name, struct data val,
struct srcpos *srcpos);
struct property *build_property_delete(char *name); struct property *build_property_delete(char *name);
struct property *chain_property(struct property *first, struct property *list); struct property *chain_property(struct property *first, struct property *list);
struct property *reverse_properties(struct property *first); struct property *reverse_properties(struct property *first);
struct node *build_node(struct property *proplist, struct node *children); struct node *build_node(struct property *proplist, struct node *children,
struct node *build_node_delete(void); struct srcpos *srcpos);
struct node *build_node_delete(struct srcpos *srcpos);
struct node *name_node(struct node *node, char *name); struct node *name_node(struct node *node, char *name);
struct node *omit_node_if_unused(struct node *node); struct node *omit_node_if_unused(struct node *node);
struct node *reference_node(struct node *node); struct node *reference_node(struct node *node);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment