Commit 0080665f authored by Linus Torvalds's avatar Linus Torvalds

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

Pull devicetree updates from Rob Herring:

 - Refactor powerpc and arm64 kexec DT handling to common code. This
   enables IMA on arm64.

 - Add kbuild support for applying DT overlays at build time. The first
   user are the DT unittests.

 - Fix kerneldoc formatting and W=1 warnings in drivers/of/

 - Fix handling 64-bit flag on PCI resources

 - Bump dtschema version required to v2021.2.1

 - Enable undocumented compatible checks for dtbs_check. This allows
   tracking of missing binding schemas.

 - DT docs improvements. Regroup the DT docs and add the example schema
   and DT kernel ABI docs to the doc build.

 - Convert Broadcom Bluetooth and video-mux bindings to schema

 - Add QCom sm8250 Venus video codec binding schema

 - Add vendor prefixes for AESOP, YIC System Co., Ltd, and Siliconfile
   Technologies Inc.

 - Cleanup of DT schema type references on common properties and
   standard unit properties

* tag 'devicetree-for-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (64 commits)
  powerpc: If kexec_build_elf_info() fails return immediately from elf64_load()
  powerpc: Free fdt on error in elf64_load()
  of: overlay: Fix kerneldoc warning in of_overlay_remove()
  of: linux/of.h: fix kernel-doc warnings
  of/pci: Add IORESOURCE_MEM_64 to resource flags for 64-bit memory addresses
  dt-bindings: bcm4329-fmac: add optional brcm,ccode-map
  docs: dt: update writing-schema.rst references
  dt-bindings: media: venus: Add sm8250 dt schema
  of: base: Fix spelling issue with function param 'prop'
  docs: dt: Add DT API documentation
  of: Add missing 'Return' section in kerneldoc comments
  of: Fix kerneldoc output formatting
  docs: dt: Group DT docs into relevant sub-sections
  docs: dt: Make 'Devicetree' wording more consistent
  docs: dt: writing-schema: Include the example schema in the doc build
  docs: dt: writing-schema: Remove spurious indentation
  dt-bindings: Fix reference in submitting-patches.rst to the DT ABI doc
  dt-bindings: ddr: Add optional manufacturer and revision ID to LPDDR3
  dt-bindings: media: video-interfaces: Drop the example
  devicetree: bindings: clock: Minor typo fix in the file armada3700-tbg-clock.txt
  ...
parents 5a69e9bc 031cc263
...@@ -5,7 +5,7 @@ DT_MK_SCHEMA ?= dt-mk-schema ...@@ -5,7 +5,7 @@ DT_MK_SCHEMA ?= dt-mk-schema
DT_SCHEMA_LINT = $(shell which yamllint) DT_SCHEMA_LINT = $(shell which yamllint)
DT_SCHEMA_MIN_VERSION = 2020.8.1 DT_SCHEMA_MIN_VERSION = 2021.2.1
PHONY += check_dtschema_version PHONY += check_dtschema_version
check_dtschema_version: check_dtschema_version:
...@@ -55,6 +55,9 @@ override DTC_FLAGS := \ ...@@ -55,6 +55,9 @@ override DTC_FLAGS := \
-Wno-graph_child_address \ -Wno-graph_child_address \
-Wno-interrupt_provider -Wno-interrupt_provider
# Disable undocumented compatible checks until warning free
override DT_CHECKER_FLAGS ?=
$(obj)/processed-schema-examples.json: $(DT_DOCS) $(src)/.yamllint check_dtschema_version FORCE $(obj)/processed-schema-examples.json: $(DT_DOCS) $(src)/.yamllint check_dtschema_version FORCE
$(call if_changed_rule,chkdt) $(call if_changed_rule,chkdt)
......
...@@ -26,10 +26,7 @@ properties: ...@@ -26,10 +26,7 @@ properties:
- const: simple-mfd - const: simple-mfd
mboxes: mboxes:
$ref: '/schemas/types.yaml#/definitions/phandle' maxItems: 1
description: |
Phandle to the firmware device's Mailbox.
(See: ../mailbox/mailbox.txt for more information)
clocks: clocks:
type: object type: object
......
...@@ -258,13 +258,11 @@ properties: ...@@ -258,13 +258,11 @@ properties:
where voltage is in V, frequency is in MHz. where voltage is in V, frequency is in MHz.
power-domains: power-domains:
$ref: '/schemas/types.yaml#/definitions/phandle-array'
description: description:
List of phandles and PM domain specifiers, as defined by bindings of the List of phandles and PM domain specifiers, as defined by bindings of the
PM domain provider (see also ../power_domain.txt). PM domain provider (see also ../power_domain.txt).
power-domain-names: power-domain-names:
$ref: '/schemas/types.yaml#/definitions/string-array'
description: description:
A list of power domain name strings sorted in the same order as the A list of power domain name strings sorted in the same order as the
power-domains property. power-domains property.
......
...@@ -44,7 +44,7 @@ examples: ...@@ -44,7 +44,7 @@ examples:
- | - |
clk@1c20000 { clk@1c20000 {
#clock-cells = <0>; #clock-cells = <0>;
compatible = "allwinner,sun4i-a10-pll1"; compatible = "allwinner,sun4i-a10-pll1-clk";
reg = <0x01c20000 0x4>; reg = <0x01c20000 0x4>;
clocks = <&osc24M>; clocks = <&osc24M>;
clock-output-names = "osc24M"; clock-output-names = "osc24M";
......
* Time Base Generator Clock bindings for Marvell Armada 37xx SoCs * Time Base Generator Clock bindings for Marvell Armada 37xx SoCs
Marvell Armada 37xx SoCs provde Time Base Generator clocks which are Marvell Armada 37xx SoCs provide Time Base Generator clocks which are
used as parent clocks for the peripheral clocks. used as parent clocks for the peripheral clocks.
The TBG clock consumer should specify the desired clock by having the The TBG clock consumer should specify the desired clock by having the
......
...@@ -18,10 +18,12 @@ description: | ...@@ -18,10 +18,12 @@ description: |
properties: properties:
compatible: compatible:
oneOf: enum:
- items:
- enum:
- socionext,milbeaut-m10v-ccu - socionext,milbeaut-m10v-ccu
reg:
maxItems: 1
clocks: clocks:
maxItems: 1 maxItems: 1
description: external clock description: external clock
...@@ -41,7 +43,7 @@ examples: ...@@ -41,7 +43,7 @@ examples:
# Clock controller node: # Clock controller node:
- | - |
m10v-clk-ctrl@1d021000 { m10v-clk-ctrl@1d021000 {
compatible = "socionext,milbeaut-m10v-clk-ccu"; compatible = "socionext,milbeaut-m10v-ccu";
reg = <0x1d021000 0x4000>; reg = <0x1d021000 0x4000>;
#clock-cells = <1>; #clock-cells = <1>;
clocks = <&clki40mhz>; clocks = <&clki40mhz>;
......
...@@ -12,6 +12,9 @@ Required properties: ...@@ -12,6 +12,9 @@ Required properties:
Optional properties: Optional properties:
- manufacturer-id : <u32> Manufacturer ID value read from Mode Register 5
- revision-id : <u32 u32> Revision IDs read from Mode Registers 6 and 7
The following optional properties represent the minimum value of some AC The following optional properties represent the minimum value of some AC
timing parameters of the DDR device in terms of number of clock cycles. timing parameters of the DDR device in terms of number of clock cycles.
These values shall be obtained from the device data-sheet. These values shall be obtained from the device data-sheet.
...@@ -49,6 +52,8 @@ samsung_K3QF2F20DB: lpddr3 { ...@@ -49,6 +52,8 @@ samsung_K3QF2F20DB: lpddr3 {
compatible = "samsung,K3QF2F20DB", "jedec,lpddr3"; compatible = "samsung,K3QF2F20DB", "jedec,lpddr3";
density = <16384>; density = <16384>;
io-width = <32>; io-width = <32>;
manufacturer-id = <1>;
revision-id = <123 234>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
......
...@@ -73,7 +73,6 @@ properties: ...@@ -73,7 +73,6 @@ properties:
clock-output-names: clock-output-names:
description: description:
Name of the LCD pixel clock created. Name of the LCD pixel clock created.
$ref: /schemas/types.yaml#/definitions/string-array
maxItems: 1 maxItems: 1
dmas: dmas:
......
...@@ -77,12 +77,6 @@ examples: ...@@ -77,12 +77,6 @@ examples:
clock-output-names = "dsi1_byte", "dsi1_ddr2", "dsi1_ddr"; clock-output-names = "dsi1_byte", "dsi1_ddr2", "dsi1_ddr";
pitouchscreen: panel@0 {
compatible = "raspberrypi,touchscreen";
reg = <0>;
/* ... */
};
}; };
... ...
...@@ -2,14 +2,14 @@ Qualcomm Technologies, Inc. DPU KMS ...@@ -2,14 +2,14 @@ Qualcomm Technologies, Inc. DPU KMS
Description: Description:
Device tree bindings for MSM Mobile Display Subsytem(MDSS) that encapsulates Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
sub-blocks like DPU display controller, DSI and DP interfaces etc. sub-blocks like DPU display controller, DSI and DP interfaces etc.
The DPU display controller is found in SDM845 SoC. The DPU display controller is found in SDM845 SoC.
MDSS: MDSS:
Required properties: Required properties:
- compatible: "qcom,sdm845-mdss", "qcom,sc7180-mdss" - compatible: "qcom,sdm845-mdss", "qcom,sc7180-mdss"
- reg: physical base address and length of contoller's registers. - reg: physical base address and length of controller's registers.
- reg-names: register region names. The following region is required: - reg-names: register region names. The following region is required:
* "mdss" * "mdss"
- power-domains: a power domain consumer specifier according to - power-domains: a power domain consumer specifier according to
......
...@@ -40,7 +40,7 @@ additionalProperties: false ...@@ -40,7 +40,7 @@ additionalProperties: false
examples: examples:
- | - |
panel { panel {
compatible = "osddisplays,osd057T0559-34ts", "panel-dpi"; compatible = "startek,startek-kd050c", "panel-dpi";
label = "osddisplay"; label = "osddisplay";
power-supply = <&vcc_supply>; power-supply = <&vcc_supply>;
backlight = <&backlight>; backlight = <&backlight>;
......
...@@ -64,7 +64,7 @@ examples: ...@@ -64,7 +64,7 @@ examples:
#include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/dma/qcom-gpi.h> #include <dt-bindings/dma/qcom-gpi.h>
gpi_dma0: dma-controller@800000 { gpi_dma0: dma-controller@800000 {
compatible = "qcom,gpi-dma"; compatible = "qcom,sdm845-gpi-dma";
#dma-cells = <3>; #dma-cells = <3>;
reg = <0x00800000 0x60000>; reg = <0x00800000 0x60000>;
iommus = <&apps_smmu 0x0016 0x0>; iommus = <&apps_smmu 0x0016 0x0>;
......
...@@ -43,8 +43,7 @@ properties: ...@@ -43,8 +43,7 @@ properties:
gpio-ranges: true gpio-ranges: true
gpio-ranges-group-names: gpio-ranges-group-names: true
$ref: /schemas/types.yaml#/definitions/string-array
socionext,interrupt-ranges: socionext,interrupt-ranges:
description: | description: |
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
$id: "http://devicetree.org/schemas/i2c/xlnx,xps-iic-2.00.a.yaml#" $id: "http://devicetree.org/schemas/i2c/xlnx,xps-iic-2.00.a.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#" $schema: "http://devicetree.org/meta-schemas/core.yaml#"
title: ilinx IIC controller Device Tree Bindings title: Xilinx IIC controller Device Tree Bindings
maintainers: maintainers:
- info@mocean-labs.com - info@mocean-labs.com
......
...@@ -157,9 +157,10 @@ examples: ...@@ -157,9 +157,10 @@ examples:
i2c-scl-hz = <100000>; i2c-scl-hz = <100000>;
/* I2C device. */ /* I2C device. */
nunchuk: nunchuk@52 { eeprom@57 {
compatible = "nintendo,nunchuk"; compatible = "atmel,24c01";
reg = <0x52 0x0 0x10>; reg = <0x57 0x0 0x10>;
pagesize = <0x8>;
}; };
/* I3C device with a static I2C address. */ /* I3C device with a static I2C address. */
......
...@@ -53,11 +53,6 @@ examples: ...@@ -53,11 +53,6 @@ examples:
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
ts_adc_syscon: ts_adc_syscon@180a6000 {
compatible = "brcm,iproc-ts-adc-syscon","syscon";
reg = <0x180a6000 0xc30>;
};
adc { adc {
compatible = "brcm,iproc-static-adc"; compatible = "brcm,iproc-static-adc";
adc-syscon = <&ts_adc_syscon>; adc-syscon = <&ts_adc_syscon>;
......
...@@ -83,7 +83,7 @@ examples: ...@@ -83,7 +83,7 @@ examples:
#size-cells = <0>; #size-cells = <0>;
gyroscope@0 { gyroscope@0 {
compatible = "nxp,fxas2102c"; compatible = "nxp,fxas21002c";
reg = <0x0>; reg = <0x0>;
spi-max-frequency = <2000000>; spi-max-frequency = <2000000>;
......
...@@ -48,7 +48,6 @@ properties: ...@@ -48,7 +48,6 @@ properties:
vdd-supply: true vdd-supply: true
capella,aset-resistance-ohms: capella,aset-resistance-ohms:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [50000, 100000, 300000, 600000] enum: [50000, 100000, 300000, 600000]
description: > description: >
Sensitivity calibration resistance. Note that calibration curves Sensitivity calibration resistance. Note that calibration curves
......
...@@ -11,12 +11,12 @@ maintainers: ...@@ -11,12 +11,12 @@ maintainers:
properties: properties:
compatible: compatible:
const: upisemi,asd5182 const: upisemi,usd5182
reg: reg:
maxItems: 1 maxItems: 1
upsemi,glass-coef: upisemi,glass-coef:
$ref: /schemas/types.yaml#/definitions/uint32 $ref: /schemas/types.yaml#/definitions/uint32
description: | description: |
glass attenuation factor - compensation factor of resolution 1000 glass attenuation factor - compensation factor of resolution 1000
......
.. SPDX-License-Identifier: GPL-2.0 .. SPDX-License-Identifier: GPL-2.0
===========
Device Tree
===========
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
ABI ABI
submitting-patches
writing-bindings writing-bindings
writing-schema
submitting-patches
...@@ -32,6 +32,5 @@ properties: ...@@ -32,6 +32,5 @@ properties:
Duration in seconds which the key should be kept pressed for device to Duration in seconds which the key should be kept pressed for device to
power off automatically. Device with key pressed shutdown feature can power off automatically. Device with key pressed shutdown feature can
specify this property. specify this property.
$ref: /schemas/types.yaml#/definitions/uint32
additionalProperties: true additionalProperties: true
...@@ -47,7 +47,7 @@ examples: ...@@ -47,7 +47,7 @@ examples:
- | - |
#include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/irq.h>
htintc: interrupt-controller@1fb000080 { htintc: interrupt-controller@1fb000080 {
compatible = "loongson,htintc-1.0"; compatible = "loongson,htpic-1.0";
reg = <0xfb000080 0x40>; reg = <0xfb000080 0x40>;
interrupt-controller; interrupt-controller;
#interrupt-cells = <1>; #interrupt-cells = <1>;
......
...@@ -14,6 +14,17 @@ properties: ...@@ -14,6 +14,17 @@ properties:
compatible: compatible:
const: intel,lgm-ssoled const: intel,lgm-ssoled
reg:
maxItems: 1
clocks:
maxItems: 2
clock-names:
items:
- const: sso
- const: fpid
gpio-controller: true gpio-controller: true
'#gpio-cells': '#gpio-cells':
...@@ -36,8 +47,15 @@ properties: ...@@ -36,8 +47,15 @@ properties:
additionalProperties: false additionalProperties: false
properties:
'#address-cells':
const: 1
'#size-cells':
const: 0
patternProperties: patternProperties:
"^led@[0-23]$": "^led@[0-2]$":
type: object type: object
properties: properties:
...@@ -81,7 +99,7 @@ examples: ...@@ -81,7 +99,7 @@ examples:
#include <dt-bindings/leds/common.h> #include <dt-bindings/leds/common.h>
ssogpio: ssogpio@e0d40000 { ssogpio: ssogpio@e0d40000 {
compatible = "intel,sso-led"; compatible = "intel,lgm-ssoled";
reg = <0xE0D40000 0x2E4>; reg = <0xE0D40000 0x2E4>;
gpio-controller; gpio-controller;
#gpio-cells = <2>; #gpio-cells = <2>;
...@@ -103,8 +121,8 @@ examples: ...@@ -103,8 +121,8 @@ examples:
led-gpio = <&ssogpio 0 0>; led-gpio = <&ssogpio 0 0>;
}; };
led@23 { led@2 {
reg = <23>; reg = <2>;
function = LED_FUNCTION_POWER; function = LED_FUNCTION_POWER;
color = <LED_COLOR_ID_GREEN>; color = <LED_COLOR_ID_GREEN>;
led-gpio = <&ssogpio 23 0>; led-gpio = <&ssogpio 23 0>;
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: "http://devicetree.org/schemas/media/qcom,sm8250-venus.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
title: Qualcomm Venus video encode and decode accelerators
maintainers:
- Stanimir Varbanov <stanimir.varbanov@linaro.org>
description: |
The Venus IP is a video encode and decode accelerator present
on Qualcomm platforms
properties:
compatible:
const: qcom,sm8250-venus
reg:
maxItems: 1
interrupts:
maxItems: 1
power-domains:
minItems: 2
maxItems: 3
power-domain-names:
minItems: 2
maxItems: 3
items:
- const: venus
- const: vcodec0
- const: mx
clocks:
maxItems: 3
clock-names:
items:
- const: iface
- const: core
- const: vcodec0_core
iommus:
maxItems: 1
memory-region:
maxItems: 1
interconnects:
maxItems: 2
interconnect-names:
items:
- const: cpu-cfg
- const: video-mem
resets:
maxItems: 2
reset-names:
items:
- const: bus
- const: core
video-decoder:
type: object
properties:
compatible:
const: venus-decoder
required:
- compatible
additionalProperties: false
video-encoder:
type: object
properties:
compatible:
const: venus-encoder
required:
- compatible
additionalProperties: false
video-firmware:
type: object
description: |
Firmware subnode is needed when the platform does not
have TrustZone.
properties:
iommus:
maxItems: 1
required:
- iommus
required:
- compatible
- reg
- interrupts
- power-domains
- power-domain-names
- clocks
- clock-names
- interconnects
- interconnect-names
- iommus
- memory-region
- resets
- reset-names
- video-decoder
- video-encoder
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/qcom,videocc-sm8250.h>
#include <dt-bindings/interconnect/qcom,sm8250.h>
#include <dt-bindings/clock/qcom,gcc-sm8250.h>
#include <dt-bindings/power/qcom-rpmpd.h>
venus: video-codec@aa00000 {
compatible = "qcom,sm8250-venus";
reg = <0x0aa00000 0xff000>;
interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&videocc MVS0C_GDSC>,
<&videocc MVS0_GDSC>,
<&rpmhpd SM8250_MX>;
power-domain-names = "venus", "vcodec0", "mx";
clocks = <&gcc GCC_VIDEO_AXI0_CLK>,
<&videocc VIDEO_CC_MVS0C_CLK>,
<&videocc VIDEO_CC_MVS0_CLK>;
clock-names = "iface", "core", "vcodec0_core";
interconnects = <&gem_noc MASTER_AMPSS_M0 &config_noc SLAVE_VENUS_CFG>,
<&mmss_noc MASTER_VIDEO_P0 &mc_virt SLAVE_EBI_CH0>;
interconnect-names = "cpu-cfg", "video-mem";
iommus = <&apps_smmu 0x2100 0x0400>;
memory-region = <&video_mem>;
resets = <&gcc GCC_VIDEO_AXI0_CLK_ARES>,
<&videocc VIDEO_CC_MVS0C_CLK_ARES>;
reset-names = "bus", "core";
video-decoder {
compatible = "venus-decoder";
};
video-encoder {
compatible = "venus-encoder";
};
};
...@@ -215,130 +215,3 @@ properties: ...@@ -215,130 +215,3 @@ properties:
CCP2, for instance. CCP2, for instance.
additionalProperties: true additionalProperties: true
examples:
# The example snippet below describes two data pipelines. ov772x and imx074
# are camera sensors with a parallel and serial (MIPI CSI-2) video bus
# respectively. Both sensors are on the I2C control bus corresponding to the
# i2c0 controller node. ov772x sensor is linked directly to the ceu0 video
# host interface. imx074 is linked to ceu0 through the MIPI CSI-2 receiver
# (csi2). ceu0 has a (single) DMA engine writing captured data to memory.
# ceu0 node has a single 'port' node which may indicate that at any time
# only one of the following data pipelines can be active:
# ov772x -> ceu0 or imx074 -> csi2 -> ceu0.
- |
ceu@fe910000 {
compatible = "renesas,sh-mobile-ceu";
reg = <0xfe910000 0xa0>;
interrupts = <0x880>;
mclk: master_clock {
compatible = "renesas,ceu-clock";
#clock-cells = <1>;
clock-frequency = <50000000>; /* Max clock frequency */
clock-output-names = "mclk";
};
port {
#address-cells = <1>;
#size-cells = <0>;
/* Parallel bus endpoint */
ceu0_1: endpoint@1 {
reg = <1>; /* Local endpoint # */
remote-endpoint = <&ov772x_1_1>; /* Remote phandle */
bus-width = <8>; /* Used data lines */
data-shift = <2>; /* Lines 9:2 are used */
/* If hsync-active/vsync-active are missing,
embedded BT.656 sync is used */
hsync-active = <0>; /* Active low */
vsync-active = <0>; /* Active low */
data-active = <1>; /* Active high */
pclk-sample = <1>; /* Rising */
};
/* MIPI CSI-2 bus endpoint */
ceu0_0: endpoint@0 {
reg = <0>;
remote-endpoint = <&csi2_2>;
};
};
};
i2c {
#address-cells = <1>;
#size-cells = <0>;
camera@21 {
compatible = "ovti,ov772x";
reg = <0x21>;
vddio-supply = <&regulator1>;
vddcore-supply = <&regulator2>;
clock-frequency = <20000000>;
clocks = <&mclk 0>;
clock-names = "xclk";
port {
/* With 1 endpoint per port no need for addresses. */
ov772x_1_1: endpoint {
bus-width = <8>;
remote-endpoint = <&ceu0_1>;
hsync-active = <1>;
vsync-active = <0>; /* Who came up with an
inverter here ?... */
data-active = <1>;
pclk-sample = <1>;
};
};
};
camera@1a {
compatible = "sony,imx074";
reg = <0x1a>;
vddio-supply = <&regulator1>;
vddcore-supply = <&regulator2>;
clock-frequency = <30000000>; /* Shared clock with ov772x_1 */
clocks = <&mclk 0>;
clock-names = "sysclk"; /* Assuming this is the
name in the datasheet */
port {
imx074_1: endpoint {
clock-lanes = <0>;
data-lanes = <1 2>;
remote-endpoint = <&csi2_1>;
};
};
};
};
csi2: csi2@ffc90000 {
compatible = "renesas,sh-mobile-csi2";
reg = <0xffc90000 0x1000>;
interrupts = <0x17a0>;
#address-cells = <1>;
#size-cells = <0>;
port@1 {
compatible = "renesas,csi2c"; /* One of CSI2I and CSI2C. */
reg = <1>; /* CSI-2 PHY #1 of 2: PHY_S,
PHY_M has port address 0,
is unused. */
csi2_1: endpoint {
clock-lanes = <0>;
data-lanes = <2 1>;
remote-endpoint = <&imx074_1>;
};
};
port@2 {
reg = <2>; /* port 2: link to the CEU */
csi2_2: endpoint {
remote-endpoint = <&ceu0_0>;
};
};
};
...
Video Multiplexer
=================
Video multiplexers allow to select between multiple input ports. Video received
on the active input port is passed through to the output port. Muxes described
by this binding are controlled by a multiplexer controller that is described by
the bindings in Documentation/devicetree/bindings/mux/mux-controller.txt
Required properties:
- compatible : should be "video-mux"
- mux-controls : mux controller node to use for operating the mux
- #address-cells: should be <1>
- #size-cells: should be <0>
- port@*: at least three port nodes containing endpoints connecting to the
source and sink devices according to of_graph bindings. The last port is
the output port, all others are inputs.
Optionally, #address-cells, #size-cells, and port nodes can be grouped under a
ports node as described in Documentation/devicetree/bindings/graph.txt.
Example:
mux: mux-controller {
compatible = "gpio-mux";
#mux-control-cells = <0>;
mux-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
};
video-mux {
compatible = "video-mux";
mux-controls = <&mux>;
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
mux_in0: endpoint {
remote-endpoint = <&video_source0_out>;
};
};
port@1 {
reg = <1>;
mux_in1: endpoint {
remote-endpoint = <&video_source1_out>;
};
};
port@2 {
reg = <2>;
mux_out: endpoint {
remote-endpoint = <&capture_interface_in>;
};
};
};
};
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/media/video-mux.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Video Multiplexer
maintainers:
- Sakari Ailus <sakari.ailus@linux.intel.com>
- Laurent Pinchart <laurent.pinchart@ideasonboard.com>
description:
Video multiplexers allow to select between multiple input ports. Video
received on the active input port is passed through to the output port. Muxes
described by this binding are controlled by a multiplexer controller.
properties:
compatible:
const: video-mux
mux-controls:
maxItems: 1
'#address-cells':
const: 1
'#size-cells':
const: 0
ports:
$ref: /schemas/graph.yaml#/properties/ports
patternProperties:
'^port@':
$ref: /schemas/graph.yaml#/properties/port
required:
- port@0
- port@1
- port@2
patternProperties:
'^port@':
$ref: /schemas/graph.yaml#/properties/port
description:
At least three port nodes containing endpoints connecting to the source
and sink devices according to of_graph bindings. The last port is the
output port, all others are inputs.
required:
- compatible
- mux-controls
oneOf:
- required:
- ports
- required:
- port@0
- port@1
- port@2
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
mux: mux-controller {
compatible = "gpio-mux";
#mux-control-cells = <0>;
mux-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
};
video-mux {
compatible = "video-mux";
mux-controls = <&mux>;
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
mux_in0: endpoint {
remote-endpoint = <&video_source0_out>;
};
};
port@1 {
reg = <1>;
mux_in1: endpoint {
remote-endpoint = <&video_source1_out>;
};
};
port@2 {
reg = <2>;
mux_out: endpoint {
remote-endpoint = <&capture_interface_in>;
};
};
};
...
...@@ -34,7 +34,7 @@ properties: ...@@ -34,7 +34,7 @@ properties:
- description: EMC general interrupt - description: EMC general interrupt
memory-region: memory-region:
$ref: /schemas/types.yaml#/definitions/phandle maxItems: 1
description: description:
phandle to a reserved memory region describing the table of EMC phandle to a reserved memory region describing the table of EMC
frequencies trained by the firmware frequencies trained by the firmware
......
...@@ -57,7 +57,6 @@ properties: ...@@ -57,7 +57,6 @@ properties:
- const: per - const: per
clock-frequency: clock-frequency:
$ref: /schemas/types.yaml#/definitions/uint32
description: | description: |
The oscillator frequency driving the flexcan device, filled in by the The oscillator frequency driving the flexcan device, filled in by the
boot loader. This property should only be used the used operating system boot loader. This property should only be used the used operating system
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/wireless/brcm,bcm4329-fmac.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Broadcom BCM4329 family fullmac wireless SDIO devices
maintainers:
- Arend van Spriel <arend@broadcom.com>
description:
The Broadcom Single chip MAC part for the BCM4329 family and
later Cypress chips in the same family named CYW4373 and similar.
These chips also have a Bluetooth portion described in a separate
binding.
properties:
compatible:
oneOf:
- items:
- enum:
- brcm,bcm43143-fmac
- brcm,bcm4341b0-fmac
- brcm,bcm4341b4-fmac
- brcm,bcm4341b5-fmac
- brcm,bcm4329-fmac
- brcm,bcm4330-fmac
- brcm,bcm4334-fmac
- brcm,bcm43340-fmac
- brcm,bcm4335-fmac
- brcm,bcm43362-fmac
- brcm,bcm4339-fmac
- brcm,bcm43430a0-fmac
- brcm,bcm43430a1-fmac
- brcm,bcm43455-fmac
- brcm,bcm43456-fmac
- brcm,bcm4354-fmac
- brcm,bcm4356-fmac
- brcm,bcm4359-fmac
- cypress,cyw4373-fmac
- cypress,cyw43012-fmac
- const: brcm,bcm4329-fmac
- const: brcm,bcm4329-fmac
reg:
description: SDIO function number for the device, for most cases
this will be 1.
interrupts:
maxItems: 1
description: Out-of-band (OOB) IRQ line for waking up the host
in response to WLAN activity. This corresponds to the HOST_WAKE
line into the chip.
interrupt-names:
description: Name for the OOB IRQ, this must be set to "host-wake".
const: host-wake
brcm,drive-strength:
$ref: /schemas/types.yaml#/definitions/uint32
description: Drive strength used for the SDIO pins on the device in mA.
minimum: 0
maximum: 32
reset-gpios:
maxItems: 1
description: A GPIO line connected to the WL_RST line, if present
this shall be flagged as active low.
brcm,ccode-map:
$ref: /schemas/types.yaml#/definitions/string-array
description: Multiple strings for translating ISO3166 country code to
brcmfmac firmware country code and revision.
items:
pattern: '^[A-Z][A-Z]-[A-Z][0-9A-Z]-[0-9]+$'
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/gpio/gpio.h>
mmc@80118000 {
compatible = "arm,pl18x", "arm,primecell";
reg = <0x80118000 0x1000>;
clocks = <&clk 0>, <&clk 1>;
clock-names = "mclk", "apb_pclk";
interrupts = <0 60 IRQ_TYPE_LEVEL_HIGH>;
bus-width = <4>;
non-removable;
vmmc-supply = <&wl_bt_reg>;
#address-cells = <1>;
#size-cells = <0>;
wifi@1 {
compatible = "brcm,bcm4334-fmac", "brcm,bcm4329-fmac";
reg = <1>;
interrupt-parent = <&gpio>;
interrupts = <24 IRQ_TYPE_EDGE_FALLING>;
interrupt-names = "host-wake";
reset-gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
brcm,ccode-map = "JP-JP-78", "US-Q2-86";
};
};
Broadcom BCM43xx Fullmac wireless SDIO devices
This node provides properties for controlling the Broadcom wireless device. The
node is expected to be specified as a child node to the SDIO controller that
connects the device to the system.
Required properties:
- compatible : Should be "brcm,bcm4329-fmac".
Optional properties:
- brcm,drive-strength : drive strength used for SDIO pins on device in mA
(default = 6).
- interrupts : specifies attributes for the out-of-band interrupt (host-wake).
When not specified the device will use in-band SDIO interrupts.
- interrupt-names : name of the out-of-band interrupt, which must be set
to "host-wake".
Example:
mmc3: mmc@1c12000 {
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&mmc3_pins_a>;
vmmc-supply = <&reg_vmmc3>;
bus-width = <4>;
non-removable;
brcmf: wifi@1 {
reg = <1>;
compatible = "brcm,bcm4329-fmac";
interrupt-parent = <&pio>;
interrupts = <10 8>; /* PH10 / EINT10 */
interrupt-names = "host-wake";
};
};
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
%YAML 1.2 %YAML 1.2
--- ---
$id: http://devicetree.org/schemas/nvmem/nvmem-consumer.yaml# $id: http://devicetree.org/schemas/nvmem/nvmem-consumer.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml# $schema: http://devicetree.org/meta-schemas/base.yaml#
title: NVMEM (Non Volatile Memory) Consumer Device Tree Bindings title: NVMEM (Non Volatile Memory) Consumer Device Tree Bindings
...@@ -23,12 +23,10 @@ properties: ...@@ -23,12 +23,10 @@ properties:
List of phandle to the nvmem data cells. List of phandle to the nvmem data cells.
nvmem-names: nvmem-names:
$ref: /schemas/types.yaml#/definitions/string-array
description: description:
Names for the each nvmem provider. Names for the each nvmem provider.
nvmem-cell-names: nvmem-cell-names:
$ref: /schemas/types.yaml#/definitions/string-array
description: description:
Names for each nvmem-cells specified. Names for each nvmem-cells specified.
......
...@@ -222,7 +222,7 @@ examples: ...@@ -222,7 +222,7 @@ examples:
}; };
serdes@5000000 { serdes@5000000 {
compatible = "cdns,ti,sierra-phy-t0"; compatible = "ti,sierra-phy-t0";
reg-names = "serdes"; reg-names = "serdes";
reg = <0x5000000 0x10000>; reg = <0x5000000 0x10000>;
#address-cells = <1>; #address-cells = <1>;
......
...@@ -39,7 +39,6 @@ properties: ...@@ -39,7 +39,6 @@ properties:
maxItems: 1 maxItems: 1
ti,watchdog-timeout-ms: ti,watchdog-timeout-ms:
$ref: /schemas/types.yaml#/definitions/uint32
default: 0 default: 0
description: | description: |
Watchdog timer in ms. 0 (default) disables the watchdog Watchdog timer in ms. 0 (default) disables the watchdog
......
...@@ -61,7 +61,7 @@ examples: ...@@ -61,7 +61,7 @@ examples:
#size-cells = <0>; #size-cells = <0>;
cw2015@62 { cw2015@62 {
compatible = "cellwise,cw201x"; compatible = "cellwise,cw2015";
reg = <0x62>; reg = <0x62>;
cellwise,battery-profile = /bits/ 8 < cellwise,battery-profile = /bits/ 8 <
0x17 0x67 0x80 0x73 0x6E 0x6C 0x6B 0x63 0x17 0x67 0x80 0x73 0x6E 0x6C 0x6B 0x63
......
...@@ -29,12 +29,10 @@ properties: ...@@ -29,12 +29,10 @@ properties:
description: I2C address of the charger. description: I2C address of the charger.
lltc,rsnsb-micro-ohms: lltc,rsnsb-micro-ohms:
$ref: /schemas/types.yaml#/definitions/uint32
description: Battery sense resistor in microohm. description: Battery sense resistor in microohm.
minimum: 1000 minimum: 1000
lltc,rsnsi-micro-ohms: lltc,rsnsi-micro-ohms:
$ref: /schemas/types.yaml#/definitions/uint32
description: Input current sense resistor in microohm. description: Input current sense resistor in microohm.
minimum: 1000 minimum: 1000
......
...@@ -18,25 +18,3 @@ properties: ...@@ -18,25 +18,3 @@ properties:
additionalProperties: true additionalProperties: true
examples:
- |
power {
#address-cells = <1>;
#size-cells = <0>;
usb_charger:charger@e {
compatible = "some,usb-charger";
reg = <0xe>;
};
ac_charger:charger@c {
compatible = "some,ac-charger";
reg = <0xc>;
};
battery:battery@b {
compatible = "some,battery";
reg = <0xb>;
power-supplies = <&usb_charger>, <&ac_charger>;
};
};
...@@ -23,7 +23,6 @@ properties: ...@@ -23,7 +23,6 @@ properties:
properties: properties:
qcom,soft-start-us: qcom,soft-start-us:
$ref: /schemas/types.yaml#/definitions/uint32
description: Regulator soft start time in microseconds. description: Regulator soft start time in microseconds.
enum: [200, 400, 600, 800] enum: [200, 400, 600, 800]
default: 200 default: 200
......
...@@ -93,7 +93,7 @@ properties: ...@@ -93,7 +93,7 @@ properties:
# The following are the optional properties: # The following are the optional properties:
memory-region: memory-region:
$ref: /schemas/types.yaml#/definitions/phandle maxItems: 1
description: | description: |
phandle to the reserved memory node to be associated phandle to the reserved memory node to be associated
with the remoteproc device. The reserved memory node with the remoteproc device. The reserved memory node
......
...@@ -144,7 +144,7 @@ examples: ...@@ -144,7 +144,7 @@ examples:
interrupts = <1>; interrupts = <1>;
bluetooth { bluetooth {
compatible = "brcm,bcm43341-bt"; compatible = "brcm,bcm4330-bt";
interrupt-parent = <&gpio>; interrupt-parent = <&gpio>;
interrupts = <10>; interrupts = <10>;
}; };
......
...@@ -29,11 +29,9 @@ properties: ...@@ -29,11 +29,9 @@ properties:
clock-frequency: clock-frequency:
description: common clock binding; frequency of MCKO description: common clock binding; frequency of MCKO
$ref: /schemas/types.yaml#/definitions/uint32
clock-output-names: clock-output-names:
description: common clock name description: common clock name
$ref: /schemas/types.yaml#/definitions/string
required: required:
- compatible - compatible
......
...@@ -32,7 +32,7 @@ properties: ...@@ -32,7 +32,7 @@ properties:
The last one integer is the length of the shared memory. The last one integer is the length of the shared memory.
memory-region: memory-region:
$ref: '/schemas/types.yaml#/definitions/phandle' maxItems: 1
description: | description: |
Shared memory region to EC. A "shared-dma-pool". Shared memory region to EC. A "shared-dma-pool".
See ../reserved-memory/reserved-memory.txt for details. See ../reserved-memory/reserved-memory.txt for details.
......
...@@ -78,7 +78,6 @@ properties: ...@@ -78,7 +78,6 @@ properties:
clock-frequency: clock-frequency:
description: for audio_clkout0/1/2/3 description: for audio_clkout0/1/2/3
$ref: /schemas/types.yaml#/definitions/uint32-array
clkout-lr-asynchronous: clkout-lr-asynchronous:
description: audio_clkoutn is asynchronizes with lr-clock. description: audio_clkoutn is asynchronizes with lr-clock.
......
...@@ -90,8 +90,8 @@ examples: ...@@ -90,8 +90,8 @@ examples:
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
ethernet-switch@0 { display@0 {
compatible = "micrel,ks8995m"; compatible = "lg,lg4573";
spi-max-frequency = <1000000>; spi-max-frequency = <1000000>;
reg = <0>; reg = <0>;
}; };
......
...@@ -181,22 +181,23 @@ additionalProperties: true ...@@ -181,22 +181,23 @@ additionalProperties: true
examples: examples:
- | - |
spi@f00 { spi@80010000 {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; compatible = "fsl,imx28-spi";
reg = <0xf00 0x20>; reg = <0x80010000 0x2000>;
interrupts = <2 13 0 2 14 0>; interrupts = <96>;
interrupt-parent = <&mpc5200_pic>; dmas = <&dma_apbh 0>;
dma-names = "rx-tx";
ethernet-switch@0 {
compatible = "micrel,ks8995m"; display@0 {
compatible = "lg,lg4573";
spi-max-frequency = <1000000>; spi-max-frequency = <1000000>;
reg = <0>; reg = <0>;
}; };
codec@1 { sensor@1 {
compatible = "ti,tlv320aic26"; compatible = "bosch,bme680";
spi-max-frequency = <100000>; spi-max-frequency = <100000>;
reg = <1>; reg = <1>;
}; };
......
...@@ -75,16 +75,12 @@ examples: ...@@ -75,16 +75,12 @@ examples:
spi-flash@0 { spi-flash@0 {
compatible = "jedec,spi-nor"; compatible = "jedec,spi-nor";
reg = <0>; reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <40000000>; spi-max-frequency = <40000000>;
}; };
spi-device@1 { sensor@1 {
compatible = "lineartechnology,ltc2488"; compatible = "bosch,bme680";
reg = <1>; reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
spi-max-frequency = <10000000>; spi-max-frequency = <10000000>;
}; };
}; };
......
...@@ -96,12 +96,6 @@ examples: ...@@ -96,12 +96,6 @@ examples:
dma-names = "rx", "tx"; dma-names = "rx", "tx";
cs-gpios = <&gpioa 11 0>; cs-gpios = <&gpioa 11 0>;
aardvark@0 {
compatible = "totalphase,aardvark";
reg = <0>;
spi-max-frequency = <4000000>;
st,spi-midi-ns = <4000>;
};
}; };
... ...
.. SPDX-License-Identifier: GPL-2.0 .. SPDX-License-Identifier: GPL-2.0
========================================== ==========================================
Submitting devicetree (DT) binding patches Submitting Devicetree (DT) binding patches
========================================== ==========================================
I. For patch submitters I. For patch submitters
...@@ -25,7 +25,7 @@ I. For patch submitters ...@@ -25,7 +25,7 @@ I. For patch submitters
make dt_binding_check make dt_binding_check
See Documentation/devicetree/writing-schema.rst for more details about See Documentation/devicetree/bindings/writing-schema.rst for more details about
schema and tools setup. schema and tools setup.
3) DT binding files should be dual licensed. The preferred license tag is 3) DT binding files should be dual licensed. The preferred license tag is
...@@ -84,7 +84,7 @@ II. For kernel maintainers ...@@ -84,7 +84,7 @@ II. For kernel maintainers
III. Notes III. Notes
========== ==========
0) Please see ...bindings/ABI.txt for details regarding devicetree ABI. 0) Please see :doc:`ABI` for details regarding devicetree ABI.
1) This document is intended as a general familiarization with the process as 1) This document is intended as a general familiarization with the process as
decided at the 2013 Kernel Summit. When in doubt, the current word of the decided at the 2013 Kernel Summit. When in doubt, the current word of the
......
...@@ -59,7 +59,6 @@ patternProperties: ...@@ -59,7 +59,6 @@ patternProperties:
properties: properties:
reg: reg:
$ref: /schemas/types.yaml#/definitions/uint32
description: Specify the sensor channel. There are 8 channels in PMIC5's ADC TM description: Specify the sensor channel. There are 8 channels in PMIC5's ADC TM
minimum: 0 minimum: 0
maximum: 7 maximum: 7
...@@ -78,7 +77,6 @@ patternProperties: ...@@ -78,7 +77,6 @@ patternProperties:
also known as absolute calibration. also known as absolute calibration.
qcom,hw-settle-time-us: qcom,hw-settle-time-us:
$ref: /schemas/types.yaml#/definitions/uint32
description: Time between AMUX getting configured and the ADC starting conversion. description: Time between AMUX getting configured and the ADC starting conversion.
enum: [15, 100, 200, 300, 400, 500, 600, 700, 1000, 2000, 4000, 8000, 16000, 32000, 64000, 128000] enum: [15, 100, 200, 300, 400, 500, 600, 700, 1000, 2000, 4000, 8000, 16000, 32000, 64000, 128000]
......
...@@ -23,6 +23,9 @@ properties: ...@@ -23,6 +23,9 @@ properties:
maxItems: 1 maxItems: 1
interrupts: interrupts:
maxItems: 1 maxItems: 1
spi-max-frequency: true
compatible: compatible:
items: items:
- enum: - enum:
......
...@@ -16,7 +16,6 @@ properties: ...@@ -16,7 +16,6 @@ properties:
pattern: "^usb(@.*)?" pattern: "^usb(@.*)?"
phys: phys:
$ref: /schemas/types.yaml#/definitions/phandle-array
description: description:
List of all the USB PHYs on this HCD List of all the USB PHYs on this HCD
......
...@@ -57,6 +57,8 @@ patternProperties: ...@@ -57,6 +57,8 @@ patternProperties:
description: Advantech Corporation description: Advantech Corporation
"^aeroflexgaisler,.*": "^aeroflexgaisler,.*":
description: Aeroflex Gaisler AB description: Aeroflex Gaisler AB
"^aesop,.*":
description: AESOP Embedded Forum
"^al,.*": "^al,.*":
description: Annapurna Labs description: Annapurna Labs
"^alcatel,.*": "^alcatel,.*":
...@@ -1030,6 +1032,8 @@ patternProperties: ...@@ -1030,6 +1032,8 @@ patternProperties:
description: Silergy Corp. description: Silergy Corp.
"^silex-insight,.*": "^silex-insight,.*":
description: Silex Insight description: Silex Insight
"^siliconfile,.*":
description: Siliconfile Technologies lnc.
"^siliconmitus,.*": "^siliconmitus,.*":
description: Silicon Mitus, Inc. description: Silicon Mitus, Inc.
"^siemens,.*": "^siemens,.*":
...@@ -1282,6 +1286,8 @@ patternProperties: ...@@ -1282,6 +1286,8 @@ patternProperties:
description: Yamaha Corporation description: Yamaha Corporation
"^yes-optoelectronics,.*": "^yes-optoelectronics,.*":
description: Yes Optoelectronics Co.,Ltd. description: Yes Optoelectronics Co.,Ltd.
"^yic,.*":
description: YIC System Co., Ltd.
"^ylm,.*": "^ylm,.*":
description: Shenzhen Yangliming Electronic Technology Co., Ltd. description: Shenzhen Yangliming Electronic Technology Co., Ltd.
"^yna,.*": "^yna,.*":
......
.. SPDX-License-Identifier: GPL-2.0 .. SPDX-License-Identifier: GPL-2.0
Writing DeviceTree Bindings in json-schema Writing Devicetree Bindings in json-schema
========================================== ==========================================
Devicetree bindings are written using json-schema vocabulary. Schema files are Devicetree bindings are written using json-schema vocabulary. Schema files are
...@@ -8,6 +8,8 @@ written in a JSON compatible subset of YAML. YAML is used instead of JSON as it ...@@ -8,6 +8,8 @@ written in a JSON compatible subset of YAML. YAML is used instead of JSON as it
is considered more human readable and has some advantages such as allowing is considered more human readable and has some advantages such as allowing
comments (Prefixed with '#'). comments (Prefixed with '#').
Also see :ref:`example-schema`.
Schema Contents Schema Contents
--------------- ---------------
...@@ -46,12 +48,12 @@ select ...@@ -46,12 +48,12 @@ select
schema. By default without 'select', nodes are matched against their possible schema. By default without 'select', nodes are matched against their possible
compatible string values or node name. Most bindings should not need select. compatible string values or node name. Most bindings should not need select.
allOf allOf
Optional. A list of other schemas to include. This is used to 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 include other schemas the binding conforms to. This may be schemas for a
particular class of devices such as I2C or SPI controllers. particular class of devices such as I2C or SPI controllers.
properties properties
A set of sub-schema defining all the DT properties for the A set of sub-schema defining all the DT properties for the
binding. The exact schema syntax depends on whether properties are known, binding. The exact schema syntax depends on whether properties are known,
common properties (e.g. 'interrupts') or are binding/vendor specific properties. common properties (e.g. 'interrupts') or are binding/vendor specific properties.
...@@ -170,3 +172,12 @@ json-schema Resources ...@@ -170,3 +172,12 @@ json-schema Resources
`JSON-Schema Specifications <http://json-schema.org/>`_ `JSON-Schema Specifications <http://json-schema.org/>`_
`Using JSON Schema Book <http://usingjsonschema.com/>`_ `Using JSON Schema Book <http://usingjsonschema.com/>`_
.. _example-schema:
Annotated Example Schema
------------------------
Also available as a separate file: :download:`example-schema.yaml`
.. literalinclude:: example-schema.yaml
.. SPDX-License-Identifier: GPL-2.0 .. SPDX-License-Identifier: GPL-2.0
============= =====================
DT Changesets Devicetree Changesets
============= =====================
A DT changeset is a method which allows one to apply changes A Devicetree changeset is a method which allows one to apply changes
in the live tree in such a way that either the full set of changes in the live tree in such a way that either the full set of changes
will be applied, or none of them will be. If an error occurs partway will be applied, or none of them will be. If an error occurs partway
through applying the changeset, then the tree will be rolled back to the through applying the changeset, then the tree will be rolled back to the
......
.. SPDX-License-Identifier: GPL-2.0 .. SPDX-License-Identifier: GPL-2.0
================================== =================================
Device Tree Dynamic Resolver Notes Devicetree Dynamic Resolver Notes
================================== =================================
This document describes the implementation of the in-kernel This document describes the implementation of the in-kernel
Device Tree resolver, residing in drivers/of/resolver.c DeviceTree resolver, residing in drivers/of/resolver.c
How the resolver works How the resolver works
---------------------- ----------------------
......
.. SPDX-License-Identifier: GPL-2.0 .. SPDX-License-Identifier: GPL-2.0
============================= =============================
Open Firmware and Device Tree Open Firmware and Devicetree
============================= =============================
Kernel Devicetree Usage
=======================
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
usage-model usage-model
writing-schema of_unittest
kernel-api
Devicetree Overlays
===================
.. toctree::
:maxdepth: 1
changesets changesets
dynamic-resolution-notes dynamic-resolution-notes
of_unittest
overlay-notes overlay-notes
Devicetree Bindings
===================
.. toctree::
:maxdepth: 1
bindings/index bindings/index
.. SPDX-License-Identifier: GPL-2.0
.. _devicetree:
======================================
DeviceTree Kernel API
======================================
Core functions
--------------
.. kernel-doc:: drivers/of/base.c
:export:
.. kernel-doc:: include/linux/of.h
:internal:
.. kernel-doc:: drivers/of/property.c
:export:
.. kernel-doc:: include/linux/of_graph.h
:internal:
.. kernel-doc:: drivers/of/address.c
:export:
.. kernel-doc:: drivers/of/irq.c
:export:
.. kernel-doc:: drivers/of/fdt.c
:export:
Driver model functions
----------------------
.. kernel-doc:: include/linux/of_device.h
:internal:
.. kernel-doc:: drivers/of/device.c
:export:
.. kernel-doc:: include/linux/of_platform.h
:internal:
.. kernel-doc:: drivers/of/platform.c
:export:
Overlay and Dynamic DT functions
--------------------------------
.. kernel-doc:: drivers/of/resolver.c
:export:
.. kernel-doc:: drivers/of/dynamic.c
:export:
.. kernel-doc:: drivers/of/overlay.c
:export:
.. SPDX-License-Identifier: GPL-2.0 .. SPDX-License-Identifier: GPL-2.0
================================== =================================
Open Firmware Device Tree Unittest Open Firmware Devicetree Unittest
================================== =================================
Author: Gaurav Minocha <gaurav.minocha.os@gmail.com> Author: Gaurav Minocha <gaurav.minocha.os@gmail.com>
......
.. SPDX-License-Identifier: GPL-2.0 .. SPDX-License-Identifier: GPL-2.0
========================= ========================
Device Tree Overlay Notes Devicetree Overlay Notes
========================= ========================
This document describes the implementation of the in-kernel This document describes the implementation of the in-kernel
device tree overlay functionality residing in drivers/of/overlay.c and is a device tree overlay functionality residing in drivers/of/overlay.c and is a
...@@ -11,7 +11,7 @@ companion document to Documentation/devicetree/dynamic-resolution-notes.rst[1] ...@@ -11,7 +11,7 @@ companion document to Documentation/devicetree/dynamic-resolution-notes.rst[1]
How overlays work How overlays work
----------------- -----------------
A Device Tree's overlay purpose is to modify the kernel's live tree, and A Devicetree's overlay purpose is to modify the kernel's live tree, and
have the modification affecting the state of the kernel in a way that have the modification affecting the state of the kernel in a way that
is reflecting the changes. is reflecting the changes.
Since the kernel mainly deals with devices, any new device node that result Since the kernel mainly deals with devices, any new device node that result
......
.. SPDX-License-Identifier: GPL-2.0 .. SPDX-License-Identifier: GPL-2.0
========================= ========================
Linux and the Device Tree Linux and the Devicetree
========================= ========================
The Linux usage model for device tree data The Linux usage model for device tree data
...@@ -14,7 +14,7 @@ at devicetree.org\ [1]_. ...@@ -14,7 +14,7 @@ at devicetree.org\ [1]_.
.. [1] https://www.devicetree.org/specifications/ .. [1] https://www.devicetree.org/specifications/
The "Open Firmware Device Tree", or simply Device Tree (DT), is a data The "Open Firmware Device Tree", or simply Devicetree (DT), is a data
structure and language for describing hardware. More specifically, it structure and language for describing hardware. More specifically, it
is a description of hardware that is readable by an operating system is a description of hardware that is readable by an operating system
so that the operating system doesn't need to hard code details of the so that the operating system doesn't need to hard code details of the
......
...@@ -1113,6 +1113,7 @@ config KEXEC ...@@ -1113,6 +1113,7 @@ config KEXEC
config KEXEC_FILE config KEXEC_FILE
bool "kexec file based system call" bool "kexec file based system call"
select KEXEC_CORE select KEXEC_CORE
select HAVE_IMA_KEXEC if IMA
help help
This is new version of kexec system call. This system call is This is new version of kexec system call. This system call is
file based and takes file descriptors as system call argument file based and takes file descriptors as system call argument
......
...@@ -96,10 +96,6 @@ struct kimage_arch { ...@@ -96,10 +96,6 @@ struct kimage_arch {
void *dtb; void *dtb;
phys_addr_t dtb_mem; phys_addr_t dtb_mem;
phys_addr_t kern_reloc; phys_addr_t kern_reloc;
/* Core ELF header buffer */
void *elf_headers;
unsigned long elf_headers_mem;
unsigned long elf_headers_sz;
}; };
#ifdef CONFIG_KEXEC_FILE #ifdef CONFIG_KEXEC_FILE
......
...@@ -15,23 +15,12 @@ ...@@ -15,23 +15,12 @@
#include <linux/kexec.h> #include <linux/kexec.h>
#include <linux/libfdt.h> #include <linux/libfdt.h>
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/of.h>
#include <linux/of_fdt.h> #include <linux/of_fdt.h>
#include <linux/random.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <asm/byteorder.h>
/* relevant device tree properties */
#define FDT_PROP_KEXEC_ELFHDR "linux,elfcorehdr"
#define FDT_PROP_MEM_RANGE "linux,usable-memory-range"
#define FDT_PROP_INITRD_START "linux,initrd-start"
#define FDT_PROP_INITRD_END "linux,initrd-end"
#define FDT_PROP_BOOTARGS "bootargs"
#define FDT_PROP_KASLR_SEED "kaslr-seed"
#define FDT_PROP_RNG_SEED "rng-seed"
#define RNG_SEED_SIZE 128
const struct kexec_file_ops * const kexec_file_loaders[] = { const struct kexec_file_ops * const kexec_file_loaders[] = {
&kexec_image_ops, &kexec_image_ops,
...@@ -40,174 +29,16 @@ const struct kexec_file_ops * const kexec_file_loaders[] = { ...@@ -40,174 +29,16 @@ const struct kexec_file_ops * const kexec_file_loaders[] = {
int arch_kimage_file_post_load_cleanup(struct kimage *image) int arch_kimage_file_post_load_cleanup(struct kimage *image)
{ {
vfree(image->arch.dtb); kvfree(image->arch.dtb);
image->arch.dtb = NULL; image->arch.dtb = NULL;
vfree(image->arch.elf_headers); vfree(image->elf_headers);
image->arch.elf_headers = NULL; image->elf_headers = NULL;
image->arch.elf_headers_sz = 0; image->elf_headers_sz = 0;
return kexec_image_post_load_cleanup_default(image); return kexec_image_post_load_cleanup_default(image);
} }
static int setup_dtb(struct kimage *image,
unsigned long initrd_load_addr, unsigned long initrd_len,
char *cmdline, void *dtb)
{
int off, ret;
ret = fdt_path_offset(dtb, "/chosen");
if (ret < 0)
goto out;
off = ret;
ret = fdt_delprop(dtb, off, FDT_PROP_KEXEC_ELFHDR);
if (ret && ret != -FDT_ERR_NOTFOUND)
goto out;
ret = fdt_delprop(dtb, off, FDT_PROP_MEM_RANGE);
if (ret && ret != -FDT_ERR_NOTFOUND)
goto out;
if (image->type == KEXEC_TYPE_CRASH) {
/* add linux,elfcorehdr */
ret = fdt_appendprop_addrrange(dtb, 0, off,
FDT_PROP_KEXEC_ELFHDR,
image->arch.elf_headers_mem,
image->arch.elf_headers_sz);
if (ret)
return (ret == -FDT_ERR_NOSPACE ? -ENOMEM : -EINVAL);
/* add linux,usable-memory-range */
ret = fdt_appendprop_addrrange(dtb, 0, off,
FDT_PROP_MEM_RANGE,
crashk_res.start,
crashk_res.end - crashk_res.start + 1);
if (ret)
return (ret == -FDT_ERR_NOSPACE ? -ENOMEM : -EINVAL);
}
/* add bootargs */
if (cmdline) {
ret = fdt_setprop_string(dtb, off, FDT_PROP_BOOTARGS, cmdline);
if (ret)
goto out;
} else {
ret = fdt_delprop(dtb, off, FDT_PROP_BOOTARGS);
if (ret && (ret != -FDT_ERR_NOTFOUND))
goto out;
}
/* add initrd-* */
if (initrd_load_addr) {
ret = fdt_setprop_u64(dtb, off, FDT_PROP_INITRD_START,
initrd_load_addr);
if (ret)
goto out;
ret = fdt_setprop_u64(dtb, off, FDT_PROP_INITRD_END,
initrd_load_addr + initrd_len);
if (ret)
goto out;
} else {
ret = fdt_delprop(dtb, off, FDT_PROP_INITRD_START);
if (ret && (ret != -FDT_ERR_NOTFOUND))
goto out;
ret = fdt_delprop(dtb, off, FDT_PROP_INITRD_END);
if (ret && (ret != -FDT_ERR_NOTFOUND))
goto out;
}
/* add kaslr-seed */
ret = fdt_delprop(dtb, off, FDT_PROP_KASLR_SEED);
if (ret == -FDT_ERR_NOTFOUND)
ret = 0;
else if (ret)
goto out;
if (rng_is_initialized()) {
u64 seed = get_random_u64();
ret = fdt_setprop_u64(dtb, off, FDT_PROP_KASLR_SEED, seed);
if (ret)
goto out;
} else {
pr_notice("RNG is not initialised: omitting \"%s\" property\n",
FDT_PROP_KASLR_SEED);
}
/* add rng-seed */
if (rng_is_initialized()) {
void *rng_seed;
ret = fdt_setprop_placeholder(dtb, off, FDT_PROP_RNG_SEED,
RNG_SEED_SIZE, &rng_seed);
if (ret)
goto out;
get_random_bytes(rng_seed, RNG_SEED_SIZE);
} else {
pr_notice("RNG is not initialised: omitting \"%s\" property\n",
FDT_PROP_RNG_SEED);
}
out:
if (ret)
return (ret == -FDT_ERR_NOSPACE) ? -ENOMEM : -EINVAL;
return 0;
}
/*
* More space needed so that we can add initrd, bootargs, kaslr-seed,
* rng-seed, userable-memory-range and elfcorehdr.
*/
#define DTB_EXTRA_SPACE 0x1000
static int create_dtb(struct kimage *image,
unsigned long initrd_load_addr, unsigned long initrd_len,
char *cmdline, void **dtb)
{
void *buf;
size_t buf_size;
size_t cmdline_len;
int ret;
cmdline_len = cmdline ? strlen(cmdline) : 0;
buf_size = fdt_totalsize(initial_boot_params)
+ cmdline_len + DTB_EXTRA_SPACE;
for (;;) {
buf = vmalloc(buf_size);
if (!buf)
return -ENOMEM;
/* duplicate a device tree blob */
ret = fdt_open_into(initial_boot_params, buf, buf_size);
if (ret) {
vfree(buf);
return -EINVAL;
}
ret = setup_dtb(image, initrd_load_addr, initrd_len,
cmdline, buf);
if (ret) {
vfree(buf);
if (ret == -ENOMEM) {
/* unlikely, but just in case */
buf_size += DTB_EXTRA_SPACE;
continue;
} else {
return ret;
}
}
/* trim it */
fdt_pack(buf);
*dtb = buf;
return 0;
}
}
static int prepare_elf_headers(void **addr, unsigned long *sz) static int prepare_elf_headers(void **addr, unsigned long *sz)
{ {
struct crash_mem *cmem; struct crash_mem *cmem;
...@@ -284,12 +115,12 @@ int load_other_segments(struct kimage *image, ...@@ -284,12 +115,12 @@ int load_other_segments(struct kimage *image,
vfree(headers); vfree(headers);
goto out_err; goto out_err;
} }
image->arch.elf_headers = headers; image->elf_headers = headers;
image->arch.elf_headers_mem = kbuf.mem; image->elf_load_addr = kbuf.mem;
image->arch.elf_headers_sz = headers_sz; image->elf_headers_sz = headers_sz;
pr_debug("Loaded elf core header at 0x%lx bufsz=0x%lx memsz=0x%lx\n", pr_debug("Loaded elf core header at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
image->arch.elf_headers_mem, kbuf.bufsz, kbuf.memsz); image->elf_load_addr, kbuf.bufsz, kbuf.memsz);
} }
/* load initrd */ /* load initrd */
...@@ -314,12 +145,15 @@ int load_other_segments(struct kimage *image, ...@@ -314,12 +145,15 @@ int load_other_segments(struct kimage *image,
} }
/* load dtb */ /* load dtb */
ret = create_dtb(image, initrd_load_addr, initrd_len, cmdline, &dtb); dtb = of_kexec_alloc_and_setup_fdt(image, initrd_load_addr,
if (ret) { initrd_len, cmdline, 0);
if (!dtb) {
pr_err("Preparing for new dtb failed\n"); pr_err("Preparing for new dtb failed\n");
goto out_err; goto out_err;
} }
/* trim it */
fdt_pack(dtb);
dtb_len = fdt_totalsize(dtb); dtb_len = fdt_totalsize(dtb);
kbuf.buffer = dtb; kbuf.buffer = dtb;
kbuf.bufsz = dtb_len; kbuf.bufsz = dtb_len;
...@@ -343,6 +177,6 @@ int load_other_segments(struct kimage *image, ...@@ -343,6 +177,6 @@ int load_other_segments(struct kimage *image,
out_err: out_err:
image->nr_segments = orig_segments; image->nr_segments = orig_segments;
vfree(dtb); kvfree(dtb);
return ret; return ret;
} }
...@@ -548,7 +548,7 @@ config KEXEC ...@@ -548,7 +548,7 @@ config KEXEC
config KEXEC_FILE config KEXEC_FILE
bool "kexec file based system call" bool "kexec file based system call"
select KEXEC_CORE select KEXEC_CORE
select HAVE_IMA_KEXEC select HAVE_IMA_KEXEC if IMA
select BUILD_BIN2C select BUILD_BIN2C
select KEXEC_ELF select KEXEC_ELF
depends on PPC64 depends on PPC64
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_POWERPC_IMA_H
#define _ASM_POWERPC_IMA_H
struct kimage;
int ima_get_kexec_buffer(void **addr, size_t *size);
int ima_free_kexec_buffer(void);
#ifdef CONFIG_IMA
void remove_ima_buffer(void *fdt, int chosen_node);
#else
static inline void remove_ima_buffer(void *fdt, int chosen_node) {}
#endif
#ifdef CONFIG_IMA_KEXEC
int arch_ima_add_kexec_buffer(struct kimage *image, unsigned long load_addr,
size_t size);
int setup_ima_buffer(const struct kimage *image, void *fdt, int chosen_node);
#else
static inline int setup_ima_buffer(const struct kimage *image, void *fdt,
int chosen_node)
{
remove_ima_buffer(fdt, chosen_node);
return 0;
}
#endif /* CONFIG_IMA_KEXEC */
#endif /* _ASM_POWERPC_IMA_H */
...@@ -107,15 +107,7 @@ struct kimage_arch { ...@@ -107,15 +107,7 @@ struct kimage_arch {
unsigned long backup_start; unsigned long backup_start;
void *backup_buf; void *backup_buf;
void *fdt;
unsigned long elfcorehdr_addr;
unsigned long elf_headers_sz;
void *elf_headers;
#ifdef CONFIG_IMA_KEXEC
phys_addr_t ima_buffer_addr;
size_t ima_buffer_size;
#endif
}; };
char *setup_kdump_cmdline(struct kimage *image, char *cmdline, char *setup_kdump_cmdline(struct kimage *image, char *cmdline,
...@@ -123,10 +115,6 @@ char *setup_kdump_cmdline(struct kimage *image, char *cmdline, ...@@ -123,10 +115,6 @@ char *setup_kdump_cmdline(struct kimage *image, char *cmdline,
int setup_purgatory(struct kimage *image, const void *slave_code, int setup_purgatory(struct kimage *image, const void *slave_code,
const void *fdt, unsigned long kernel_load_addr, const void *fdt, unsigned long kernel_load_addr,
unsigned long fdt_load_addr); unsigned long fdt_load_addr);
int setup_new_fdt(const struct kimage *image, void *fdt,
unsigned long initrd_load_addr, unsigned long initrd_len,
const char *cmdline);
int delete_fdt_mem_rsv(void *fdt, unsigned long start, unsigned long size);
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
struct kexec_buf; struct kexec_buf;
...@@ -136,7 +124,7 @@ int load_crashdump_segments_ppc64(struct kimage *image, ...@@ -136,7 +124,7 @@ int load_crashdump_segments_ppc64(struct kimage *image,
int setup_purgatory_ppc64(struct kimage *image, const void *slave_code, int setup_purgatory_ppc64(struct kimage *image, const void *slave_code,
const void *fdt, unsigned long kernel_load_addr, const void *fdt, unsigned long kernel_load_addr,
unsigned long fdt_load_addr); unsigned long fdt_load_addr);
unsigned int kexec_fdt_totalsize_ppc64(struct kimage *image); unsigned int kexec_extra_fdt_size_ppc64(struct kimage *image);
int setup_new_fdt_ppc64(const struct kimage *image, void *fdt, int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
unsigned long initrd_load_addr, unsigned long initrd_load_addr,
unsigned long initrd_len, const char *cmdline); unsigned long initrd_len, const char *cmdline);
......
...@@ -9,13 +9,6 @@ obj-$(CONFIG_PPC32) += relocate_32.o ...@@ -9,13 +9,6 @@ obj-$(CONFIG_PPC32) += relocate_32.o
obj-$(CONFIG_KEXEC_FILE) += file_load.o ranges.o file_load_$(BITS).o elf_$(BITS).o obj-$(CONFIG_KEXEC_FILE) += file_load.o ranges.o file_load_$(BITS).o elf_$(BITS).o
ifdef CONFIG_HAVE_IMA_KEXEC
ifdef CONFIG_IMA
obj-y += ima.o
endif
endif
# Disable GCOV, KCOV & sanitizers in odd or sensitive code # Disable GCOV, KCOV & sanitizers in odd or sensitive code
GCOV_PROFILE_core_$(BITS).o := n GCOV_PROFILE_core_$(BITS).o := n
KCOV_INSTRUMENT_core_$(BITS).o := n KCOV_INSTRUMENT_core_$(BITS).o := n
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/kexec.h> #include <linux/kexec.h>
#include <linux/libfdt.h> #include <linux/libfdt.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h>
#include <linux/of_fdt.h> #include <linux/of_fdt.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -29,7 +30,6 @@ static void *elf64_load(struct kimage *image, char *kernel_buf, ...@@ -29,7 +30,6 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
unsigned long cmdline_len) unsigned long cmdline_len)
{ {
int ret; int ret;
unsigned int fdt_size;
unsigned long kernel_load_addr; unsigned long kernel_load_addr;
unsigned long initrd_load_addr = 0, fdt_load_addr; unsigned long initrd_load_addr = 0, fdt_load_addr;
void *fdt; void *fdt;
...@@ -45,7 +45,7 @@ static void *elf64_load(struct kimage *image, char *kernel_buf, ...@@ -45,7 +45,7 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
ret = kexec_build_elf_info(kernel_buf, kernel_len, &ehdr, &elf_info); ret = kexec_build_elf_info(kernel_buf, kernel_len, &ehdr, &elf_info);
if (ret) if (ret)
goto out; return ERR_PTR(ret);
if (image->type == KEXEC_TYPE_CRASH) { if (image->type == KEXEC_TYPE_CRASH) {
/* min & max buffer values for kdump case */ /* min & max buffer values for kdump case */
...@@ -102,15 +102,10 @@ static void *elf64_load(struct kimage *image, char *kernel_buf, ...@@ -102,15 +102,10 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
pr_debug("Loaded initrd at 0x%lx\n", initrd_load_addr); pr_debug("Loaded initrd at 0x%lx\n", initrd_load_addr);
} }
fdt_size = kexec_fdt_totalsize_ppc64(image); fdt = of_kexec_alloc_and_setup_fdt(image, initrd_load_addr,
fdt = kmalloc(fdt_size, GFP_KERNEL); initrd_len, cmdline,
kexec_extra_fdt_size_ppc64(image));
if (!fdt) { if (!fdt) {
pr_err("Not enough memory for the device tree.\n");
ret = -ENOMEM;
goto out;
}
ret = fdt_open_into(initial_boot_params, fdt, fdt_size);
if (ret < 0) {
pr_err("Error setting up the new device tree.\n"); pr_err("Error setting up the new device tree.\n");
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
...@@ -119,18 +114,22 @@ static void *elf64_load(struct kimage *image, char *kernel_buf, ...@@ -119,18 +114,22 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
ret = setup_new_fdt_ppc64(image, fdt, initrd_load_addr, ret = setup_new_fdt_ppc64(image, fdt, initrd_load_addr,
initrd_len, cmdline); initrd_len, cmdline);
if (ret) if (ret)
goto out; goto out_free_fdt;
fdt_pack(fdt); fdt_pack(fdt);
kbuf.buffer = fdt; kbuf.buffer = fdt;
kbuf.bufsz = kbuf.memsz = fdt_size; kbuf.bufsz = kbuf.memsz = fdt_totalsize(fdt);
kbuf.buf_align = PAGE_SIZE; kbuf.buf_align = PAGE_SIZE;
kbuf.top_down = true; kbuf.top_down = true;
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN; kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
ret = kexec_add_buffer(&kbuf); ret = kexec_add_buffer(&kbuf);
if (ret) if (ret)
goto out; goto out_free_fdt;
/* FDT will be freed in arch_kimage_file_post_load_cleanup */
image->arch.fdt = fdt;
fdt_load_addr = kbuf.mem; fdt_load_addr = kbuf.mem;
pr_debug("Loaded device tree at 0x%lx\n", fdt_load_addr); pr_debug("Loaded device tree at 0x%lx\n", fdt_load_addr);
...@@ -141,12 +140,15 @@ static void *elf64_load(struct kimage *image, char *kernel_buf, ...@@ -141,12 +140,15 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
if (ret) if (ret)
pr_err("Error setting up the purgatory.\n"); pr_err("Error setting up the purgatory.\n");
goto out;
out_free_fdt:
kvfree(fdt);
out: out:
kfree(modified_cmdline); kfree(modified_cmdline);
kexec_free_elf_info(&elf_info); kexec_free_elf_info(&elf_info);
/* Make kimage_file_post_load_cleanup free the fdt buffer for us. */ return ret ? ERR_PTR(ret) : NULL;
return ret ? ERR_PTR(ret) : fdt;
} }
const struct kexec_file_ops kexec_elf64_ops = { const struct kexec_file_ops kexec_elf64_ops = {
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <linux/of_fdt.h> #include <linux/of_fdt.h>
#include <linux/libfdt.h> #include <linux/libfdt.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/ima.h>
#define SLAVE_CODE_SIZE 256 /* First 0x100 bytes */ #define SLAVE_CODE_SIZE 256 /* First 0x100 bytes */
...@@ -45,7 +44,7 @@ char *setup_kdump_cmdline(struct kimage *image, char *cmdline, ...@@ -45,7 +44,7 @@ char *setup_kdump_cmdline(struct kimage *image, char *cmdline,
return NULL; return NULL;
elfcorehdr_strlen = sprintf(cmdline_ptr, "elfcorehdr=0x%lx ", elfcorehdr_strlen = sprintf(cmdline_ptr, "elfcorehdr=0x%lx ",
image->arch.elfcorehdr_addr); image->elf_load_addr);
if (elfcorehdr_strlen + cmdline_len > COMMAND_LINE_SIZE) { if (elfcorehdr_strlen + cmdline_len > COMMAND_LINE_SIZE) {
pr_err("Appending elfcorehdr=<addr> exceeds cmdline size\n"); pr_err("Appending elfcorehdr=<addr> exceeds cmdline size\n");
...@@ -108,183 +107,3 @@ int setup_purgatory(struct kimage *image, const void *slave_code, ...@@ -108,183 +107,3 @@ int setup_purgatory(struct kimage *image, const void *slave_code,
return 0; return 0;
} }
/**
* delete_fdt_mem_rsv - delete memory reservation with given address and size
*
* Return: 0 on success, or negative errno on error.
*/
int delete_fdt_mem_rsv(void *fdt, unsigned long start, unsigned long size)
{
int i, ret, num_rsvs = fdt_num_mem_rsv(fdt);
for (i = 0; i < num_rsvs; i++) {
uint64_t rsv_start, rsv_size;
ret = fdt_get_mem_rsv(fdt, i, &rsv_start, &rsv_size);
if (ret) {
pr_err("Malformed device tree.\n");
return -EINVAL;
}
if (rsv_start == start && rsv_size == size) {
ret = fdt_del_mem_rsv(fdt, i);
if (ret) {
pr_err("Error deleting device tree reservation.\n");
return -EINVAL;
}
return 0;
}
}
return -ENOENT;
}
/*
* setup_new_fdt - modify /chosen and memory reservation for the next kernel
* @image: kexec image being loaded.
* @fdt: Flattened device tree for the next kernel.
* @initrd_load_addr: Address where the next initrd will be loaded.
* @initrd_len: Size of the next initrd, or 0 if there will be none.
* @cmdline: Command line for the next kernel, or NULL if there will
* be none.
*
* Return: 0 on success, or negative errno on error.
*/
int setup_new_fdt(const struct kimage *image, void *fdt,
unsigned long initrd_load_addr, unsigned long initrd_len,
const char *cmdline)
{
int ret, chosen_node;
const void *prop;
/* Remove memory reservation for the current device tree. */
ret = delete_fdt_mem_rsv(fdt, __pa(initial_boot_params),
fdt_totalsize(initial_boot_params));
if (ret == 0)
pr_debug("Removed old device tree reservation.\n");
else if (ret != -ENOENT)
return ret;
chosen_node = fdt_path_offset(fdt, "/chosen");
if (chosen_node == -FDT_ERR_NOTFOUND) {
chosen_node = fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"),
"chosen");
if (chosen_node < 0) {
pr_err("Error creating /chosen.\n");
return -EINVAL;
}
} else if (chosen_node < 0) {
pr_err("Malformed device tree: error reading /chosen.\n");
return -EINVAL;
}
/* Did we boot using an initrd? */
prop = fdt_getprop(fdt, chosen_node, "linux,initrd-start", NULL);
if (prop) {
uint64_t tmp_start, tmp_end, tmp_size;
tmp_start = fdt64_to_cpu(*((const fdt64_t *) prop));
prop = fdt_getprop(fdt, chosen_node, "linux,initrd-end", NULL);
if (!prop) {
pr_err("Malformed device tree.\n");
return -EINVAL;
}
tmp_end = fdt64_to_cpu(*((const fdt64_t *) prop));
/*
* kexec reserves exact initrd size, while firmware may
* reserve a multiple of PAGE_SIZE, so check for both.
*/
tmp_size = tmp_end - tmp_start;
ret = delete_fdt_mem_rsv(fdt, tmp_start, tmp_size);
if (ret == -ENOENT)
ret = delete_fdt_mem_rsv(fdt, tmp_start,
round_up(tmp_size, PAGE_SIZE));
if (ret == 0)
pr_debug("Removed old initrd reservation.\n");
else if (ret != -ENOENT)
return ret;
/* If there's no new initrd, delete the old initrd's info. */
if (initrd_len == 0) {
ret = fdt_delprop(fdt, chosen_node,
"linux,initrd-start");
if (ret) {
pr_err("Error deleting linux,initrd-start.\n");
return -EINVAL;
}
ret = fdt_delprop(fdt, chosen_node, "linux,initrd-end");
if (ret) {
pr_err("Error deleting linux,initrd-end.\n");
return -EINVAL;
}
}
}
if (initrd_len) {
ret = fdt_setprop_u64(fdt, chosen_node,
"linux,initrd-start",
initrd_load_addr);
if (ret < 0)
goto err;
/* initrd-end is the first address after the initrd image. */
ret = fdt_setprop_u64(fdt, chosen_node, "linux,initrd-end",
initrd_load_addr + initrd_len);
if (ret < 0)
goto err;
ret = fdt_add_mem_rsv(fdt, initrd_load_addr, initrd_len);
if (ret) {
pr_err("Error reserving initrd memory: %s\n",
fdt_strerror(ret));
return -EINVAL;
}
}
if (cmdline != NULL) {
ret = fdt_setprop_string(fdt, chosen_node, "bootargs", cmdline);
if (ret < 0)
goto err;
} else {
ret = fdt_delprop(fdt, chosen_node, "bootargs");
if (ret && ret != -FDT_ERR_NOTFOUND) {
pr_err("Error deleting bootargs.\n");
return -EINVAL;
}
}
if (image->type == KEXEC_TYPE_CRASH) {
/*
* Avoid elfcorehdr from being stomped on in kdump kernel by
* setting up memory reserve map.
*/
ret = fdt_add_mem_rsv(fdt, image->arch.elfcorehdr_addr,
image->arch.elf_headers_sz);
if (ret) {
pr_err("Error reserving elfcorehdr memory: %s\n",
fdt_strerror(ret));
goto err;
}
}
ret = setup_ima_buffer(image, fdt, chosen_node);
if (ret) {
pr_err("Error setting up the new device tree.\n");
return ret;
}
ret = fdt_setprop(fdt, chosen_node, "linux,booted-from-kexec", NULL, 0);
if (ret)
goto err;
return 0;
err:
pr_err("Error setting up the new device tree.\n");
return -EINVAL;
}
...@@ -816,9 +816,9 @@ static int load_elfcorehdr_segment(struct kimage *image, struct kexec_buf *kbuf) ...@@ -816,9 +816,9 @@ static int load_elfcorehdr_segment(struct kimage *image, struct kexec_buf *kbuf)
goto out; goto out;
} }
image->arch.elfcorehdr_addr = kbuf->mem; image->elf_load_addr = kbuf->mem;
image->arch.elf_headers_sz = headers_sz; image->elf_headers_sz = headers_sz;
image->arch.elf_headers = headers; image->elf_headers = headers;
out: out:
kfree(cmem); kfree(cmem);
return ret; return ret;
...@@ -852,7 +852,7 @@ int load_crashdump_segments_ppc64(struct kimage *image, ...@@ -852,7 +852,7 @@ int load_crashdump_segments_ppc64(struct kimage *image,
return ret; return ret;
} }
pr_debug("Loaded elf core header at 0x%lx, bufsz=0x%lx memsz=0x%lx\n", pr_debug("Loaded elf core header at 0x%lx, bufsz=0x%lx memsz=0x%lx\n",
image->arch.elfcorehdr_addr, kbuf->bufsz, kbuf->memsz); image->elf_load_addr, kbuf->bufsz, kbuf->memsz);
return 0; return 0;
} }
...@@ -927,37 +927,27 @@ int setup_purgatory_ppc64(struct kimage *image, const void *slave_code, ...@@ -927,37 +927,27 @@ int setup_purgatory_ppc64(struct kimage *image, const void *slave_code,
} }
/** /**
* kexec_fdt_totalsize_ppc64 - Return the estimated size needed to setup FDT * kexec_extra_fdt_size_ppc64 - Return the estimated additional size needed to
* for kexec/kdump kernel. * setup FDT for kexec/kdump kernel.
* @image: kexec image being loaded. * @image: kexec image being loaded.
* *
* Returns the estimated size needed for kexec/kdump kernel FDT. * Returns the estimated extra size needed for kexec/kdump kernel FDT.
*/ */
unsigned int kexec_fdt_totalsize_ppc64(struct kimage *image) unsigned int kexec_extra_fdt_size_ppc64(struct kimage *image)
{ {
unsigned int fdt_size;
u64 usm_entries; u64 usm_entries;
/*
* The below estimate more than accounts for a typical kexec case where
* the additional space is to accommodate things like kexec cmdline,
* chosen node with properties for initrd start & end addresses and
* a property to indicate kexec boot..
*/
fdt_size = fdt_totalsize(initial_boot_params) + (2 * COMMAND_LINE_SIZE);
if (image->type != KEXEC_TYPE_CRASH) if (image->type != KEXEC_TYPE_CRASH)
return fdt_size; return 0;
/* /*
* For kdump kernel, also account for linux,usable-memory and * For kdump kernel, account for linux,usable-memory and
* linux,drconf-usable-memory properties. Get an approximate on the * linux,drconf-usable-memory properties. Get an approximate on the
* number of usable memory entries and use for FDT size estimation. * number of usable memory entries and use for FDT size estimation.
*/ */
usm_entries = ((memblock_end_of_DRAM() / drmem_lmb_size()) + usm_entries = ((memblock_end_of_DRAM() / drmem_lmb_size()) +
(2 * (resource_size(&crashk_res) / drmem_lmb_size()))); (2 * (resource_size(&crashk_res) / drmem_lmb_size())));
fdt_size += (unsigned int)(usm_entries * sizeof(u64)); return (unsigned int)(usm_entries * sizeof(u64));
return fdt_size;
} }
/** /**
...@@ -979,10 +969,6 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt, ...@@ -979,10 +969,6 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
struct crash_mem *umem = NULL, *rmem = NULL; struct crash_mem *umem = NULL, *rmem = NULL;
int i, nr_ranges, ret; int i, nr_ranges, ret;
ret = setup_new_fdt(image, fdt, initrd_load_addr, initrd_len, cmdline);
if (ret)
goto out;
/* /*
* Restrict memory usage for kdump kernel by setting up * Restrict memory usage for kdump kernel by setting up
* usable memory ranges and memory reserve map. * usable memory ranges and memory reserve map.
...@@ -1142,9 +1128,12 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image) ...@@ -1142,9 +1128,12 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
vfree(image->arch.backup_buf); vfree(image->arch.backup_buf);
image->arch.backup_buf = NULL; image->arch.backup_buf = NULL;
vfree(image->arch.elf_headers); vfree(image->elf_headers);
image->arch.elf_headers = NULL; image->elf_headers = NULL;
image->arch.elf_headers_sz = 0; image->elf_headers_sz = 0;
kvfree(image->arch.fdt);
image->arch.fdt = NULL;
return kexec_image_post_load_cleanup_default(image); return kexec_image_post_load_cleanup_default(image);
} }
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2016 IBM Corporation
*
* Authors:
* Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
*/
#include <linux/slab.h>
#include <linux/kexec.h>
#include <linux/of.h>
#include <linux/memblock.h>
#include <linux/libfdt.h>
static int get_addr_size_cells(int *addr_cells, int *size_cells)
{
struct device_node *root;
root = of_find_node_by_path("/");
if (!root)
return -EINVAL;
*addr_cells = of_n_addr_cells(root);
*size_cells = of_n_size_cells(root);
of_node_put(root);
return 0;
}
static int do_get_kexec_buffer(const void *prop, int len, unsigned long *addr,
size_t *size)
{
int ret, addr_cells, size_cells;
ret = get_addr_size_cells(&addr_cells, &size_cells);
if (ret)
return ret;
if (len < 4 * (addr_cells + size_cells))
return -ENOENT;
*addr = of_read_number(prop, addr_cells);
*size = of_read_number(prop + 4 * addr_cells, size_cells);
return 0;
}
/**
* ima_get_kexec_buffer - get IMA buffer from the previous kernel
* @addr: On successful return, set to point to the buffer contents.
* @size: On successful return, set to the buffer size.
*
* Return: 0 on success, negative errno on error.
*/
int ima_get_kexec_buffer(void **addr, size_t *size)
{
int ret, len;
unsigned long tmp_addr;
size_t tmp_size;
const void *prop;
prop = of_get_property(of_chosen, "linux,ima-kexec-buffer", &len);
if (!prop)
return -ENOENT;
ret = do_get_kexec_buffer(prop, len, &tmp_addr, &tmp_size);
if (ret)
return ret;
*addr = __va(tmp_addr);
*size = tmp_size;
return 0;
}
/**
* ima_free_kexec_buffer - free memory used by the IMA buffer
*/
int ima_free_kexec_buffer(void)
{
int ret;
unsigned long addr;
size_t size;
struct property *prop;
prop = of_find_property(of_chosen, "linux,ima-kexec-buffer", NULL);
if (!prop)
return -ENOENT;
ret = do_get_kexec_buffer(prop->value, prop->length, &addr, &size);
if (ret)
return ret;
ret = of_remove_property(of_chosen, prop);
if (ret)
return ret;
return memblock_free(addr, size);
}
/**
* remove_ima_buffer - remove the IMA buffer property and reservation from @fdt
*
* The IMA measurement buffer is of no use to a subsequent kernel, so we always
* remove it from the device tree.
*/
void remove_ima_buffer(void *fdt, int chosen_node)
{
int ret, len;
unsigned long addr;
size_t size;
const void *prop;
prop = fdt_getprop(fdt, chosen_node, "linux,ima-kexec-buffer", &len);
if (!prop)
return;
ret = do_get_kexec_buffer(prop, len, &addr, &size);
fdt_delprop(fdt, chosen_node, "linux,ima-kexec-buffer");
if (ret)
return;
ret = delete_fdt_mem_rsv(fdt, addr, size);
if (!ret)
pr_debug("Removed old IMA buffer reservation.\n");
}
#ifdef CONFIG_IMA_KEXEC
/**
* arch_ima_add_kexec_buffer - do arch-specific steps to add the IMA buffer
*
* Architectures should use this function to pass on the IMA buffer
* information to the next kernel.
*
* Return: 0 on success, negative errno on error.
*/
int arch_ima_add_kexec_buffer(struct kimage *image, unsigned long load_addr,
size_t size)
{
image->arch.ima_buffer_addr = load_addr;
image->arch.ima_buffer_size = size;
return 0;
}
static int write_number(void *p, u64 value, int cells)
{
if (cells == 1) {
u32 tmp;
if (value > U32_MAX)
return -EINVAL;
tmp = cpu_to_be32(value);
memcpy(p, &tmp, sizeof(tmp));
} else if (cells == 2) {
u64 tmp;
tmp = cpu_to_be64(value);
memcpy(p, &tmp, sizeof(tmp));
} else
return -EINVAL;
return 0;
}
/**
* setup_ima_buffer - add IMA buffer information to the fdt
* @image: kexec image being loaded.
* @fdt: Flattened device tree for the next kernel.
* @chosen_node: Offset to the chosen node.
*
* Return: 0 on success, or negative errno on error.
*/
int setup_ima_buffer(const struct kimage *image, void *fdt, int chosen_node)
{
int ret, addr_cells, size_cells, entry_size;
u8 value[16];
remove_ima_buffer(fdt, chosen_node);
if (!image->arch.ima_buffer_size)
return 0;
ret = get_addr_size_cells(&addr_cells, &size_cells);
if (ret)
return ret;
entry_size = 4 * (addr_cells + size_cells);
if (entry_size > sizeof(value))
return -EINVAL;
ret = write_number(value, image->arch.ima_buffer_addr, addr_cells);
if (ret)
return ret;
ret = write_number(value + 4 * addr_cells, image->arch.ima_buffer_size,
size_cells);
if (ret)
return ret;
ret = fdt_setprop(fdt, chosen_node, "linux,ima-kexec-buffer", value,
entry_size);
if (ret < 0)
return -EINVAL;
ret = fdt_add_mem_rsv(fdt, image->arch.ima_buffer_addr,
image->arch.ima_buffer_size);
if (ret)
return -EINVAL;
pr_debug("IMA buffer at 0x%llx, size = 0x%zx\n",
image->arch.ima_buffer_addr, image->arch.ima_buffer_size);
return 0;
}
#endif /* CONFIG_IMA_KEXEC */
...@@ -150,11 +150,6 @@ struct kimage_arch { ...@@ -150,11 +150,6 @@ struct kimage_arch {
pud_t *pud; pud_t *pud;
pmd_t *pmd; pmd_t *pmd;
pte_t *pte; pte_t *pte;
/* Core ELF header buffer */
void *elf_headers;
unsigned long elf_headers_sz;
unsigned long elf_load_addr;
}; };
#endif /* CONFIG_X86_32 */ #endif /* CONFIG_X86_32 */
......
...@@ -323,8 +323,8 @@ static int memmap_exclude_ranges(struct kimage *image, struct crash_mem *cmem, ...@@ -323,8 +323,8 @@ static int memmap_exclude_ranges(struct kimage *image, struct crash_mem *cmem,
cmem->nr_ranges = 1; cmem->nr_ranges = 1;
/* Exclude elf header region */ /* Exclude elf header region */
start = image->arch.elf_load_addr; start = image->elf_load_addr;
end = start + image->arch.elf_headers_sz - 1; end = start + image->elf_headers_sz - 1;
return crash_exclude_mem_range(cmem, start, end); return crash_exclude_mem_range(cmem, start, end);
} }
...@@ -407,20 +407,20 @@ int crash_load_segments(struct kimage *image) ...@@ -407,20 +407,20 @@ int crash_load_segments(struct kimage *image)
if (ret) if (ret)
return ret; return ret;
image->arch.elf_headers = kbuf.buffer; image->elf_headers = kbuf.buffer;
image->arch.elf_headers_sz = kbuf.bufsz; image->elf_headers_sz = kbuf.bufsz;
kbuf.memsz = kbuf.bufsz; kbuf.memsz = kbuf.bufsz;
kbuf.buf_align = ELF_CORE_HEADER_ALIGN; kbuf.buf_align = ELF_CORE_HEADER_ALIGN;
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN; kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
ret = kexec_add_buffer(&kbuf); ret = kexec_add_buffer(&kbuf);
if (ret) { if (ret) {
vfree((void *)image->arch.elf_headers); vfree((void *)image->elf_headers);
return ret; return ret;
} }
image->arch.elf_load_addr = kbuf.mem; image->elf_load_addr = kbuf.mem;
pr_debug("Loaded ELF headers at 0x%lx bufsz=0x%lx memsz=0x%lx\n", pr_debug("Loaded ELF headers at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
image->arch.elf_load_addr, kbuf.bufsz, kbuf.bufsz); image->elf_load_addr, kbuf.bufsz, kbuf.bufsz);
return ret; return ret;
} }
......
...@@ -75,7 +75,7 @@ static int setup_cmdline(struct kimage *image, struct boot_params *params, ...@@ -75,7 +75,7 @@ static int setup_cmdline(struct kimage *image, struct boot_params *params,
if (image->type == KEXEC_TYPE_CRASH) { if (image->type == KEXEC_TYPE_CRASH) {
len = sprintf(cmdline_ptr, len = sprintf(cmdline_ptr,
"elfcorehdr=0x%lx ", image->arch.elf_load_addr); "elfcorehdr=0x%lx ", image->elf_load_addr);
} }
memcpy(cmdline_ptr + len, cmdline, cmdline_len); memcpy(cmdline_ptr + len, cmdline, cmdline_len);
cmdline_len += len; cmdline_len += len;
......
...@@ -402,8 +402,8 @@ void machine_kexec(struct kimage *image) ...@@ -402,8 +402,8 @@ void machine_kexec(struct kimage *image)
#ifdef CONFIG_KEXEC_FILE #ifdef CONFIG_KEXEC_FILE
void *arch_kexec_kernel_image_load(struct kimage *image) void *arch_kexec_kernel_image_load(struct kimage *image)
{ {
vfree(image->arch.elf_headers); vfree(image->elf_headers);
image->arch.elf_headers = NULL; image->elf_headers = NULL;
if (!image->fops || !image->fops->load) if (!image->fops || !image->fops->load)
return ERR_PTR(-ENOEXEC); return ERR_PTR(-ENOEXEC);
......
...@@ -14,4 +14,10 @@ obj-$(CONFIG_OF_RESOLVE) += resolver.o ...@@ -14,4 +14,10 @@ obj-$(CONFIG_OF_RESOLVE) += resolver.o
obj-$(CONFIG_OF_OVERLAY) += overlay.o obj-$(CONFIG_OF_OVERLAY) += overlay.o
obj-$(CONFIG_OF_NUMA) += of_numa.o obj-$(CONFIG_OF_NUMA) += of_numa.o
ifdef CONFIG_KEXEC_FILE
ifdef CONFIG_OF_FLATTREE
obj-y += kexec.o
endif
endif
obj-$(CONFIG_OF_UNITTEST) += unittest-data/ obj-$(CONFIG_OF_UNITTEST) += unittest-data/
...@@ -117,9 +117,12 @@ static unsigned int of_bus_pci_get_flags(const __be32 *addr) ...@@ -117,9 +117,12 @@ static unsigned int of_bus_pci_get_flags(const __be32 *addr)
flags |= IORESOURCE_IO; flags |= IORESOURCE_IO;
break; break;
case 0x02: /* 32 bits */ case 0x02: /* 32 bits */
case 0x03: /* 64 bits */
flags |= IORESOURCE_MEM; flags |= IORESOURCE_MEM;
break; break;
case 0x03: /* 64 bits */
flags |= IORESOURCE_MEM | IORESOURCE_MEM_64;
break;
} }
if (w & 0x40000000) if (w & 0x40000000)
flags |= IORESOURCE_PREFETCH; flags |= IORESOURCE_PREFETCH;
...@@ -861,6 +864,9 @@ static int __of_address_to_resource(struct device_node *dev, ...@@ -861,6 +864,9 @@ static int __of_address_to_resource(struct device_node *dev,
/** /**
* of_address_to_resource - Translate device tree address and return as resource * of_address_to_resource - Translate device tree address and return as resource
* @dev: Caller's Device Node
* @index: Index into the array
* @r: Pointer to resource array
* *
* Note that if your address is a PIO address, the conversion will fail if * Note that if your address is a PIO address, the conversion will fail if
* the physical address can't be internally converted to an IO token with * the physical address can't be internally converted to an IO token with
......
This diff is collapsed.
...@@ -53,7 +53,7 @@ int of_device_add(struct platform_device *ofdev) ...@@ -53,7 +53,7 @@ int of_device_add(struct platform_device *ofdev)
} }
/** /**
* of_dma_configure - Setup DMA configuration * of_dma_configure_id - Setup DMA configuration
* @dev: Device to apply DMA configuration * @dev: Device to apply DMA configuration
* @np: Pointer to OF node having DMA configuration * @np: Pointer to OF node having DMA configuration
* @force_dma: Whether device is to be set up by of_dma_configure() even if * @force_dma: Whether device is to be set up by of_dma_configure() even if
...@@ -258,6 +258,9 @@ EXPORT_SYMBOL_GPL(of_device_request_module); ...@@ -258,6 +258,9 @@ EXPORT_SYMBOL_GPL(of_device_request_module);
/** /**
* of_device_modalias - Fill buffer with newline terminated modalias string * of_device_modalias - Fill buffer with newline terminated modalias string
* @dev: Calling device
* @str: Modalias string
* @len: Size of @str
*/ */
ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len) ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len)
{ {
...@@ -275,6 +278,8 @@ EXPORT_SYMBOL_GPL(of_device_modalias); ...@@ -275,6 +278,8 @@ EXPORT_SYMBOL_GPL(of_device_modalias);
/** /**
* of_device_uevent - Display OF related uevent information * of_device_uevent - Display OF related uevent information
* @dev: Device to apply DMA configuration
* @env: Kernel object's userspace event reference
*/ */
void of_device_uevent(struct device *dev, struct kobj_uevent_env *env) void of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
{ {
......
...@@ -27,7 +27,7 @@ static struct device_node *kobj_to_device_node(struct kobject *kobj) ...@@ -27,7 +27,7 @@ static struct device_node *kobj_to_device_node(struct kobject *kobj)
* @node: Node to inc refcount, NULL is supported to simplify writing of * @node: Node to inc refcount, NULL is supported to simplify writing of
* callers * callers
* *
* Returns node. * Return: The node with refcount incremented.
*/ */
struct device_node *of_node_get(struct device_node *node) struct device_node *of_node_get(struct device_node *node)
{ {
...@@ -104,7 +104,8 @@ int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p) ...@@ -104,7 +104,8 @@ int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p)
* @arg - argument of the of notifier * @arg - argument of the of notifier
* *
* Returns the new state of a device based on the notifier used. * Returns the new state of a device based on the notifier used.
* Returns 0 on device going from enabled to disabled, 1 on device *
* Return: 0 on device going from enabled to disabled, 1 on device
* going from disabled to enabled and -1 on no change. * going from disabled to enabled and -1 on no change.
*/ */
int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr) int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr)
...@@ -229,6 +230,7 @@ static void __of_attach_node(struct device_node *np) ...@@ -229,6 +230,7 @@ static void __of_attach_node(struct device_node *np)
/** /**
* of_attach_node() - Plug a device node into the tree and global list. * of_attach_node() - Plug a device node into the tree and global list.
* @np: Pointer to the caller's Device Node
*/ */
int of_attach_node(struct device_node *np) int of_attach_node(struct device_node *np)
{ {
...@@ -281,6 +283,7 @@ void __of_detach_node(struct device_node *np) ...@@ -281,6 +283,7 @@ void __of_detach_node(struct device_node *np)
/** /**
* of_detach_node() - "Unplug" a node from the device tree. * of_detach_node() - "Unplug" a node from the device tree.
* @np: Pointer to the caller's Device Node
*/ */
int of_detach_node(struct device_node *np) int of_detach_node(struct device_node *np)
{ {
...@@ -318,7 +321,7 @@ static void property_list_free(struct property *prop_list) ...@@ -318,7 +321,7 @@ static void property_list_free(struct property *prop_list)
/** /**
* of_node_release() - release a dynamically allocated node * of_node_release() - release a dynamically allocated node
* @kref: kref element of the node to be released * @kobj: kernel object of the node to be released
* *
* In of_node_put() this function is passed to kref_put() as the destructor. * In of_node_put() this function is passed to kref_put() as the destructor.
*/ */
...@@ -372,7 +375,8 @@ void of_node_release(struct kobject *kobj) ...@@ -372,7 +375,8 @@ void of_node_release(struct kobject *kobj)
* property structure and the property name & contents. The property's * property structure and the property name & contents. The property's
* flags have the OF_DYNAMIC bit set so that we can differentiate between * flags have the OF_DYNAMIC bit set so that we can differentiate between
* dynamically allocated properties and not. * dynamically allocated properties and not.
* Returns the newly allocated property or NULL on out of memory error. *
* Return: The newly allocated property or NULL on out of memory error.
*/ */
struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags) struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
{ {
...@@ -415,7 +419,7 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags) ...@@ -415,7 +419,7 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
* another node. The node data are dynamically allocated and all the node * another node. The node data are dynamically allocated and all the node
* flags have the OF_DYNAMIC & OF_DETACHED bits set. * flags have the OF_DYNAMIC & OF_DETACHED bits set.
* *
* Returns the newly allocated node or NULL on out of memory error. * Return: The newly allocated node or NULL on out of memory error.
*/ */
struct device_node *__of_node_dup(const struct device_node *np, struct device_node *__of_node_dup(const struct device_node *np,
const char *full_name) const char *full_name)
...@@ -781,7 +785,8 @@ static int __of_changeset_apply(struct of_changeset *ocs) ...@@ -781,7 +785,8 @@ static int __of_changeset_apply(struct of_changeset *ocs)
* Any side-effects of live tree state changes are applied here on * Any side-effects of live tree state changes are applied here on
* success, like creation/destruction of devices and side-effects * success, like creation/destruction of devices and side-effects
* like creation of sysfs properties and directories. * like creation of sysfs properties and directories.
* Returns 0 on success, a negative error value in case of an error. *
* Return: 0 on success, a negative error value in case of an error.
* On error the partially applied effects are reverted. * On error the partially applied effects are reverted.
*/ */
int of_changeset_apply(struct of_changeset *ocs) int of_changeset_apply(struct of_changeset *ocs)
...@@ -875,7 +880,8 @@ static int __of_changeset_revert(struct of_changeset *ocs) ...@@ -875,7 +880,8 @@ static int __of_changeset_revert(struct of_changeset *ocs)
* was before the application. * was before the application.
* Any side-effects like creation/destruction of devices and * Any side-effects like creation/destruction of devices and
* removal of sysfs properties and directories are applied. * removal of sysfs properties and directories are applied.
* Returns 0 on success, a negative error value in case of an error. *
* Return: 0 on success, a negative error value in case of an error.
*/ */
int of_changeset_revert(struct of_changeset *ocs) int of_changeset_revert(struct of_changeset *ocs)
{ {
...@@ -903,7 +909,8 @@ EXPORT_SYMBOL_GPL(of_changeset_revert); ...@@ -903,7 +909,8 @@ EXPORT_SYMBOL_GPL(of_changeset_revert);
* + OF_RECONFIG_ADD_PROPERTY * + OF_RECONFIG_ADD_PROPERTY
* + OF_RECONFIG_REMOVE_PROPERTY, * + OF_RECONFIG_REMOVE_PROPERTY,
* + OF_RECONFIG_UPDATE_PROPERTY * + OF_RECONFIG_UPDATE_PROPERTY
* Returns 0 on success, a negative error value in case of an error. *
* Return: 0 on success, a negative error value in case of an error.
*/ */
int of_changeset_action(struct of_changeset *ocs, unsigned long action, int of_changeset_action(struct of_changeset *ocs, unsigned long action,
struct device_node *np, struct property *prop) struct device_node *np, struct property *prop)
......
...@@ -282,7 +282,7 @@ static void reverse_nodes(struct device_node *parent) ...@@ -282,7 +282,7 @@ static void reverse_nodes(struct device_node *parent)
* @dad: Parent struct device_node * @dad: Parent struct device_node
* @nodepp: The device_node tree created by the call * @nodepp: The device_node tree created by the call
* *
* It returns the size of unflattened device tree or error code * Return: The size of unflattened device tree or error code
*/ */
static int unflatten_dt_nodes(const void *blob, static int unflatten_dt_nodes(const void *blob,
void *mem, void *mem,
...@@ -351,11 +351,6 @@ static int unflatten_dt_nodes(const void *blob, ...@@ -351,11 +351,6 @@ static int unflatten_dt_nodes(const void *blob,
/** /**
* __unflatten_device_tree - create tree of device_nodes from flat blob * __unflatten_device_tree - create tree of device_nodes from flat blob
*
* unflattens a device-tree, creating the
* tree of struct device_node. It also fills the "name" and "type"
* pointers of the nodes so the normal device-tree walking functions
* can be used.
* @blob: The blob to expand * @blob: The blob to expand
* @dad: Parent device node * @dad: Parent device node
* @mynodes: The device_node tree created by the call * @mynodes: The device_node tree created by the call
...@@ -363,7 +358,11 @@ static int unflatten_dt_nodes(const void *blob, ...@@ -363,7 +358,11 @@ static int unflatten_dt_nodes(const void *blob,
* for the resulting tree * for the resulting tree
* @detached: if true set OF_DETACHED on @mynodes * @detached: if true set OF_DETACHED on @mynodes
* *
* Returns NULL on failure or the memory chunk containing the unflattened * unflattens a device-tree, creating the tree of struct device_node. It also
* fills the "name" and "type" pointers of the nodes so the normal device-tree
* walking functions can be used.
*
* Return: NULL on failure or the memory chunk containing the unflattened
* device tree on success. * device tree on success.
*/ */
void *__unflatten_device_tree(const void *blob, void *__unflatten_device_tree(const void *blob,
...@@ -452,7 +451,7 @@ static DEFINE_MUTEX(of_fdt_unflatten_mutex); ...@@ -452,7 +451,7 @@ static DEFINE_MUTEX(of_fdt_unflatten_mutex);
* pointers of the nodes so the normal device-tree walking functions * pointers of the nodes so the normal device-tree walking functions
* can be used. * can be used.
* *
* Returns NULL on failure or the memory chunk containing the unflattened * Return: NULL on failure or the memory chunk containing the unflattened
* device tree on success. * device tree on success.
*/ */
void *of_fdt_unflatten_tree(const unsigned long *blob, void *of_fdt_unflatten_tree(const unsigned long *blob,
...@@ -480,7 +479,7 @@ void *initial_boot_params __ro_after_init; ...@@ -480,7 +479,7 @@ void *initial_boot_params __ro_after_init;
static u32 of_fdt_crc32; static u32 of_fdt_crc32;
/** /*
* __reserved_mem_reserve_reg() - reserve all memory described in 'reg' property * __reserved_mem_reserve_reg() - reserve all memory described in 'reg' property
*/ */
static int __init __reserved_mem_reserve_reg(unsigned long node, static int __init __reserved_mem_reserve_reg(unsigned long node,
...@@ -526,7 +525,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long node, ...@@ -526,7 +525,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
return 0; return 0;
} }
/** /*
* __reserved_mem_check_root() - check if #size-cells, #address-cells provided * __reserved_mem_check_root() - check if #size-cells, #address-cells provided
* in /reserved-memory matches the values supported by the current implementation, * in /reserved-memory matches the values supported by the current implementation,
* also check if ranges property has been provided * also check if ranges property has been provided
...@@ -549,8 +548,8 @@ static int __init __reserved_mem_check_root(unsigned long node) ...@@ -549,8 +548,8 @@ static int __init __reserved_mem_check_root(unsigned long node)
return 0; return 0;
} }
/** /*
* fdt_scan_reserved_mem() - scan a single FDT node for reserved memory * __fdt_scan_reserved_mem() - scan a single FDT node for reserved memory
*/ */
static int __init __fdt_scan_reserved_mem(unsigned long node, const char *uname, static int __init __fdt_scan_reserved_mem(unsigned long node, const char *uname,
int depth, void *data) int depth, void *data)
...@@ -660,6 +659,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node, ...@@ -660,6 +659,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
/** /**
* of_scan_flat_dt_subnodes - scan sub-nodes of a node call callback on each. * of_scan_flat_dt_subnodes - scan sub-nodes of a node call callback on each.
* @parent: parent node
* @it: callback function * @it: callback function
* @data: context data pointer * @data: context data pointer
* *
...@@ -699,7 +699,7 @@ int __init of_get_flat_dt_subnode_by_name(unsigned long node, const char *uname) ...@@ -699,7 +699,7 @@ int __init of_get_flat_dt_subnode_by_name(unsigned long node, const char *uname)
return fdt_subnode_offset(initial_boot_params, node, uname); return fdt_subnode_offset(initial_boot_params, node, uname);
} }
/** /*
* of_get_flat_dt_root - find the root node in the flat blob * of_get_flat_dt_root - find the root node in the flat blob
*/ */
unsigned long __init of_get_flat_dt_root(void) unsigned long __init of_get_flat_dt_root(void)
...@@ -707,7 +707,7 @@ unsigned long __init of_get_flat_dt_root(void) ...@@ -707,7 +707,7 @@ unsigned long __init of_get_flat_dt_root(void)
return 0; return 0;
} }
/** /*
* of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr
* *
* This function can be used within scan_flattened_dt callback to get * This function can be used within scan_flattened_dt callback to get
...@@ -726,7 +726,7 @@ const void *__init of_get_flat_dt_prop(unsigned long node, const char *name, ...@@ -726,7 +726,7 @@ const void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
* @node: node to test * @node: node to test
* @compat: compatible string to compare with compatible list. * @compat: compatible string to compare with compatible list.
* *
* On match, returns a non-zero value with smaller values returned for more * Return: a non-zero value on match with smaller values returned for more
* specific compatible values. * specific compatible values.
*/ */
static int of_fdt_is_compatible(const void *blob, static int of_fdt_is_compatible(const void *blob,
...@@ -761,7 +761,7 @@ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) ...@@ -761,7 +761,7 @@ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
return of_fdt_is_compatible(initial_boot_params, node, compat); return of_fdt_is_compatible(initial_boot_params, node, compat);
} }
/** /*
* of_flat_dt_match - Return true if node matches a list of compatible values * of_flat_dt_match - Return true if node matches a list of compatible values
*/ */
static int __init of_flat_dt_match(unsigned long node, const char *const *compat) static int __init of_flat_dt_match(unsigned long node, const char *const *compat)
...@@ -781,8 +781,8 @@ static int __init of_flat_dt_match(unsigned long node, const char *const *compat ...@@ -781,8 +781,8 @@ static int __init of_flat_dt_match(unsigned long node, const char *const *compat
return score; return score;
} }
/** /*
* of_get_flat_dt_prop - Given a node in the flat blob, return the phandle * of_get_flat_dt_phandle - Given a node in the flat blob, return the phandle
*/ */
uint32_t __init of_get_flat_dt_phandle(unsigned long node) uint32_t __init of_get_flat_dt_phandle(unsigned long node)
{ {
...@@ -957,7 +957,7 @@ int __init early_init_dt_scan_chosen_stdout(void) ...@@ -957,7 +957,7 @@ int __init early_init_dt_scan_chosen_stdout(void)
} }
#endif #endif
/** /*
* early_init_dt_scan_root - fetch the top level address and size cells * early_init_dt_scan_root - fetch the top level address and size cells
*/ */
int __init early_init_dt_scan_root(unsigned long node, const char *uname, int __init early_init_dt_scan_root(unsigned long node, const char *uname,
...@@ -993,7 +993,7 @@ u64 __init dt_mem_next_cell(int s, const __be32 **cellp) ...@@ -993,7 +993,7 @@ u64 __init dt_mem_next_cell(int s, const __be32 **cellp)
return of_read_number(p, s); return of_read_number(p, s);
} }
/** /*
* early_init_dt_scan_memory - Look for and parse memory nodes * early_init_dt_scan_memory - Look for and parse memory nodes
*/ */
int __init early_init_dt_scan_memory(unsigned long node, const char *uname, int __init early_init_dt_scan_memory(unsigned long node, const char *uname,
......
...@@ -48,7 +48,7 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map); ...@@ -48,7 +48,7 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
* of_irq_find_parent - Given a device node, find its interrupt parent node * of_irq_find_parent - Given a device node, find its interrupt parent node
* @child: pointer to device node * @child: pointer to device node
* *
* Returns a pointer to the interrupt parent node, or NULL if the interrupt * Return: A pointer to the interrupt parent node, or NULL if the interrupt
* parent could not be determined. * parent could not be determined.
*/ */
struct device_node *of_irq_find_parent(struct device_node *child) struct device_node *of_irq_find_parent(struct device_node *child)
...@@ -81,14 +81,14 @@ EXPORT_SYMBOL_GPL(of_irq_find_parent); ...@@ -81,14 +81,14 @@ EXPORT_SYMBOL_GPL(of_irq_find_parent);
* @addr: address specifier (start of "reg" property of the device) in be32 format * @addr: address specifier (start of "reg" property of the device) in be32 format
* @out_irq: structure of_phandle_args updated by this function * @out_irq: structure of_phandle_args updated by this function
* *
* Returns 0 on success and a negative number on error
*
* This function is a low-level interrupt tree walking function. It * This function is a low-level interrupt tree walking function. It
* can be used to do a partial walk with synthetized reg and interrupts * can be used to do a partial walk with synthetized reg and interrupts
* properties, for example when resolving PCI interrupts when no device * properties, for example when resolving PCI interrupts when no device
* node exist for the parent. It takes an interrupt specifier structure as * node exist for the parent. It takes an interrupt specifier structure as
* input, walks the tree looking for any interrupt-map properties, translates * input, walks the tree looking for any interrupt-map properties, translates
* the specifier for each map, and then returns the translated map. * the specifier for each map, and then returns the translated map.
*
* Return: 0 on success and a negative number on error
*/ */
int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq)
{ {
...@@ -380,7 +380,7 @@ EXPORT_SYMBOL_GPL(of_irq_to_resource); ...@@ -380,7 +380,7 @@ EXPORT_SYMBOL_GPL(of_irq_to_resource);
* @dev: pointer to device tree node * @dev: pointer to device tree node
* @index: zero-based index of the IRQ * @index: zero-based index of the IRQ
* *
* Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or * Return: Linux IRQ number on success, or 0 on the IRQ mapping failure, or
* -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
* of any other failure. * of any other failure.
*/ */
...@@ -407,7 +407,7 @@ EXPORT_SYMBOL_GPL(of_irq_get); ...@@ -407,7 +407,7 @@ EXPORT_SYMBOL_GPL(of_irq_get);
* @dev: pointer to device tree node * @dev: pointer to device tree node
* @name: IRQ name * @name: IRQ name
* *
* Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or * Return: Linux IRQ number on success, or 0 on the IRQ mapping failure, or
* -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
* of any other failure. * of any other failure.
*/ */
...@@ -447,7 +447,7 @@ int of_irq_count(struct device_node *dev) ...@@ -447,7 +447,7 @@ int of_irq_count(struct device_node *dev)
* @res: array of resources to fill in * @res: array of resources to fill in
* @nr_irqs: the number of IRQs (and upper bound for num of @res elements) * @nr_irqs: the number of IRQs (and upper bound for num of @res elements)
* *
* Returns the size of the filled in table (up to @nr_irqs). * Return: The size of the filled in table (up to @nr_irqs).
*/ */
int of_irq_to_resource_table(struct device_node *dev, struct resource *res, int of_irq_to_resource_table(struct device_node *dev, struct resource *res,
int nr_irqs) int nr_irqs)
...@@ -602,7 +602,7 @@ static u32 __of_msi_map_id(struct device *dev, struct device_node **np, ...@@ -602,7 +602,7 @@ static u32 __of_msi_map_id(struct device *dev, struct device_node **np,
* Walk up the device hierarchy looking for devices with a "msi-map" * Walk up the device hierarchy looking for devices with a "msi-map"
* property. If found, apply the mapping to @id_in. * property. If found, apply the mapping to @id_in.
* *
* Returns the mapped MSI ID. * Return: The mapped MSI ID.
*/ */
u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in) u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in)
{ {
......
This diff is collapsed.
...@@ -79,6 +79,9 @@ static const void *of_get_mac_addr_nvmem(struct device_node *np) ...@@ -79,6 +79,9 @@ static const void *of_get_mac_addr_nvmem(struct device_node *np)
} }
/** /**
* of_get_mac_address()
* @np: Caller's Device Node
*
* Search the device tree for the best MAC address to use. 'mac-address' is * Search the device tree for the best MAC address to use. 'mac-address' is
* checked first, because that is supposed to contain to "most recent" MAC * checked first, because that is supposed to contain to "most recent" MAC
* address. If that isn't set, then 'local-mac-address' is checked next, * address. If that isn't set, then 'local-mac-address' is checked next,
......
...@@ -45,7 +45,7 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size, ...@@ -45,7 +45,7 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
return memblock_reserve(base, size); return memblock_reserve(base, size);
} }
/** /*
* fdt_reserved_mem_save_node() - save fdt node for second pass initialization * fdt_reserved_mem_save_node() - save fdt node for second pass initialization
*/ */
void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname, void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname,
...@@ -67,7 +67,7 @@ void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname, ...@@ -67,7 +67,7 @@ void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname,
return; return;
} }
/** /*
* __reserved_mem_alloc_size() - allocate reserved memory described by * __reserved_mem_alloc_size() - allocate reserved memory described by
* 'size', 'alignment' and 'alloc-ranges' properties. * 'size', 'alignment' and 'alloc-ranges' properties.
*/ */
...@@ -164,7 +164,7 @@ static int __init __reserved_mem_alloc_size(unsigned long node, ...@@ -164,7 +164,7 @@ static int __init __reserved_mem_alloc_size(unsigned long node,
static const struct of_device_id __rmem_of_table_sentinel static const struct of_device_id __rmem_of_table_sentinel
__used __section("__reservedmem_of_table_end"); __used __section("__reservedmem_of_table_end");
/** /*
* __reserved_mem_init_node() - call region specific reserved memory init code * __reserved_mem_init_node() - call region specific reserved memory init code
*/ */
static int __init __reserved_mem_init_node(struct reserved_mem *rmem) static int __init __reserved_mem_init_node(struct reserved_mem *rmem)
......
...@@ -140,7 +140,7 @@ int of_overlay_notifier_register(struct notifier_block *nb) ...@@ -140,7 +140,7 @@ int of_overlay_notifier_register(struct notifier_block *nb)
EXPORT_SYMBOL_GPL(of_overlay_notifier_register); EXPORT_SYMBOL_GPL(of_overlay_notifier_register);
/** /**
* of_overlay_notifier_register() - Unregister notifier for overlay operations * of_overlay_notifier_unregister() - Unregister notifier for overlay operations
* @nb: Notifier block to unregister * @nb: Notifier block to unregister
*/ */
int of_overlay_notifier_unregister(struct notifier_block *nb) int of_overlay_notifier_unregister(struct notifier_block *nb)
...@@ -298,7 +298,7 @@ static struct property *dup_and_fixup_symbol_prop( ...@@ -298,7 +298,7 @@ static struct property *dup_and_fixup_symbol_prop(
* *
* Update of property in symbols node is not allowed. * Update of property in symbols node is not allowed.
* *
* Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if * Return: 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
* invalid @overlay. * invalid @overlay.
*/ */
static int add_changeset_property(struct overlay_changeset *ovcs, static int add_changeset_property(struct overlay_changeset *ovcs,
...@@ -403,7 +403,7 @@ static int add_changeset_property(struct overlay_changeset *ovcs, ...@@ -403,7 +403,7 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
* *
* NOTE_2: Multiple mods of created nodes not supported. * NOTE_2: Multiple mods of created nodes not supported.
* *
* Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if * Return: 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
* invalid @overlay. * invalid @overlay.
*/ */
static int add_changeset_node(struct overlay_changeset *ovcs, static int add_changeset_node(struct overlay_changeset *ovcs,
...@@ -475,7 +475,7 @@ static int add_changeset_node(struct overlay_changeset *ovcs, ...@@ -475,7 +475,7 @@ static int add_changeset_node(struct overlay_changeset *ovcs,
* *
* Do not allow symbols node to have any children. * Do not allow symbols node to have any children.
* *
* Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if * Return: 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
* invalid @overlay_node. * invalid @overlay_node.
*/ */
static int build_changeset_next_level(struct overlay_changeset *ovcs, static int build_changeset_next_level(struct overlay_changeset *ovcs,
...@@ -606,7 +606,7 @@ static int find_dup_cset_prop(struct overlay_changeset *ovcs, ...@@ -606,7 +606,7 @@ static int find_dup_cset_prop(struct overlay_changeset *ovcs,
* the same node or duplicate {add, delete, or update} properties entries * the same node or duplicate {add, delete, or update} properties entries
* for the same property. * for the same property.
* *
* Returns 0 on success, or -EINVAL if duplicate changeset entry found. * Return: 0 on success, or -EINVAL if duplicate changeset entry found.
*/ */
static int changeset_dup_entry_check(struct overlay_changeset *ovcs) static int changeset_dup_entry_check(struct overlay_changeset *ovcs)
{ {
...@@ -630,7 +630,7 @@ static int changeset_dup_entry_check(struct overlay_changeset *ovcs) ...@@ -630,7 +630,7 @@ static int changeset_dup_entry_check(struct overlay_changeset *ovcs)
* any portions of the changeset that were successfully created will remain * any portions of the changeset that were successfully created will remain
* in @ovcs->cset. * in @ovcs->cset.
* *
* Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if * Return: 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if
* invalid overlay in @ovcs->fragments[]. * invalid overlay in @ovcs->fragments[].
*/ */
static int build_changeset(struct overlay_changeset *ovcs) static int build_changeset(struct overlay_changeset *ovcs)
...@@ -726,7 +726,7 @@ static struct device_node *find_target(struct device_node *info_node) ...@@ -726,7 +726,7 @@ static struct device_node *find_target(struct device_node *info_node)
* the top level of @tree. The relevant top level nodes are the fragment * the top level of @tree. The relevant top level nodes are the fragment
* nodes and the __symbols__ node. Any other top level node will be ignored. * nodes and the __symbols__ node. Any other top level node will be ignored.
* *
* Returns 0 on success, -ENOMEM if memory allocation failure, -EINVAL if error * Return: 0 on success, -ENOMEM if memory allocation failure, -EINVAL if error
* detected in @tree, or -ENOSPC if idr_alloc() error. * detected in @tree, or -ENOSPC if idr_alloc() error.
*/ */
static int init_overlay_changeset(struct overlay_changeset *ovcs, static int init_overlay_changeset(struct overlay_changeset *ovcs,
...@@ -796,6 +796,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs, ...@@ -796,6 +796,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs,
if (!fragment->target) { if (!fragment->target) {
of_node_put(fragment->overlay); of_node_put(fragment->overlay);
ret = -EINVAL; ret = -EINVAL;
of_node_put(node);
goto err_free_fragments; goto err_free_fragments;
} }
...@@ -1186,7 +1187,7 @@ static int overlay_removal_is_ok(struct overlay_changeset *remove_ovcs) ...@@ -1186,7 +1187,7 @@ static int overlay_removal_is_ok(struct overlay_changeset *remove_ovcs)
* If an error is returned by an overlay changeset post-remove notifier * If an error is returned by an overlay changeset post-remove notifier
* then no further overlay changeset post-remove notifier will be called. * then no further overlay changeset post-remove notifier will be called.
* *
* Returns 0 on success, or a negative error number. *ovcs_id is set to * Return: 0 on success, or a negative error number. *@ovcs_id is set to
* zero after reverting the changeset, even if a subsequent error occurs. * zero after reverting the changeset, even if a subsequent error occurs.
*/ */
int of_overlay_remove(int *ovcs_id) int of_overlay_remove(int *ovcs_id)
...@@ -1264,7 +1265,7 @@ EXPORT_SYMBOL_GPL(of_overlay_remove); ...@@ -1264,7 +1265,7 @@ EXPORT_SYMBOL_GPL(of_overlay_remove);
* *
* Removes all overlays from the system in the correct order. * Removes all overlays from the system in the correct order.
* *
* Returns 0 on success, or a negative error number * Return: 0 on success, or a negative error number
*/ */
int of_overlay_remove_all(void) int of_overlay_remove_all(void)
{ {
......
...@@ -44,7 +44,7 @@ static const struct of_device_id of_skipped_node_table[] = { ...@@ -44,7 +44,7 @@ static const struct of_device_id of_skipped_node_table[] = {
* Takes a reference to the embedded struct device which needs to be dropped * Takes a reference to the embedded struct device which needs to be dropped
* after use. * after use.
* *
* Returns platform_device pointer, or NULL if not found * Return: platform_device pointer, or NULL if not found
*/ */
struct platform_device *of_find_device_by_node(struct device_node *np) struct platform_device *of_find_device_by_node(struct device_node *np)
{ {
...@@ -160,7 +160,7 @@ EXPORT_SYMBOL(of_device_alloc); ...@@ -160,7 +160,7 @@ EXPORT_SYMBOL(of_device_alloc);
* @platform_data: pointer to populate platform_data pointer with * @platform_data: pointer to populate platform_data pointer with
* @parent: Linux device model parent device. * @parent: Linux device model parent device.
* *
* Returns pointer to created platform device, or NULL if a device was not * Return: Pointer to created platform device, or NULL if a device was not
* registered. Unavailable devices will not get registered. * registered. Unavailable devices will not get registered.
*/ */
static struct platform_device *of_platform_device_create_pdata( static struct platform_device *of_platform_device_create_pdata(
...@@ -204,7 +204,7 @@ static struct platform_device *of_platform_device_create_pdata( ...@@ -204,7 +204,7 @@ static struct platform_device *of_platform_device_create_pdata(
* @bus_id: name to assign device * @bus_id: name to assign device
* @parent: Linux device model parent device. * @parent: Linux device model parent device.
* *
* Returns pointer to created platform device, or NULL if a device was not * Return: Pointer to created platform device, or NULL if a device was not
* registered. Unavailable devices will not get registered. * registered. Unavailable devices will not get registered.
*/ */
struct platform_device *of_platform_device_create(struct device_node *np, struct platform_device *of_platform_device_create(struct device_node *np,
...@@ -290,7 +290,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node, ...@@ -290,7 +290,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
} }
#endif /* CONFIG_ARM_AMBA */ #endif /* CONFIG_ARM_AMBA */
/** /*
* of_dev_lookup() - Given a device node, lookup the preferred Linux name * of_dev_lookup() - Given a device node, lookup the preferred Linux name
*/ */
static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *lookup, static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *lookup,
...@@ -463,7 +463,7 @@ EXPORT_SYMBOL(of_platform_bus_probe); ...@@ -463,7 +463,7 @@ EXPORT_SYMBOL(of_platform_bus_probe);
* New board support should be using this function instead of * New board support should be using this function instead of
* of_platform_bus_probe(). * of_platform_bus_probe().
* *
* Returns 0 on success, < 0 on failure. * Return: 0 on success, < 0 on failure.
*/ */
int of_platform_populate(struct device_node *root, int of_platform_populate(struct device_node *root,
const struct of_device_id *matches, const struct of_device_id *matches,
...@@ -607,7 +607,7 @@ static void devm_of_platform_populate_release(struct device *dev, void *res) ...@@ -607,7 +607,7 @@ static void devm_of_platform_populate_release(struct device *dev, void *res)
* Similar to of_platform_populate(), but will automatically call * Similar to of_platform_populate(), but will automatically call
* of_platform_depopulate() when the device is unbound from the bus. * of_platform_depopulate() when the device is unbound from the bus.
* *
* Returns 0 on success, < 0 on failure. * Return: 0 on success, < 0 on failure.
*/ */
int devm_of_platform_populate(struct device *dev) int devm_of_platform_populate(struct device *dev)
{ {
......
...@@ -61,9 +61,11 @@ EXPORT_SYMBOL(of_graph_is_present); ...@@ -61,9 +61,11 @@ EXPORT_SYMBOL(of_graph_is_present);
* @elem_size: size of the individual element * @elem_size: size of the individual element
* *
* Search for a property in a device node and count the number of elements of * Search for a property in a device node and count the number of elements of
* size elem_size in it. Returns number of elements on sucess, -EINVAL if the * size elem_size in it.
* property does not exist or its length does not match a multiple of elem_size *
* and -ENODATA if the property does not have a value. * Return: The number of elements on sucess, -EINVAL if the property does not
* exist or its length does not match a multiple of elem_size and -ENODATA if
* the property does not have a value.
*/ */
int of_property_count_elems_of_size(const struct device_node *np, int of_property_count_elems_of_size(const struct device_node *np,
const char *propname, int elem_size) const char *propname, int elem_size)
...@@ -95,7 +97,8 @@ EXPORT_SYMBOL_GPL(of_property_count_elems_of_size); ...@@ -95,7 +97,8 @@ EXPORT_SYMBOL_GPL(of_property_count_elems_of_size);
* @len: if !=NULL, actual length is written to here * @len: if !=NULL, actual length is written to here
* *
* Search for a property in a device node and valid the requested size. * Search for a property in a device node and valid the requested size.
* Returns the property value on success, -EINVAL if the property does not *
* Return: The property value on success, -EINVAL if the property does not
* exist, -ENODATA if property does not have a value, and -EOVERFLOW if the * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
* property data is too small or too large. * property data is too small or too large.
* *
...@@ -129,7 +132,9 @@ static void *of_find_property_value_of_size(const struct device_node *np, ...@@ -129,7 +132,9 @@ static void *of_find_property_value_of_size(const struct device_node *np,
* @out_value: pointer to return value, modified only if no error. * @out_value: pointer to return value, modified only if no error.
* *
* Search for a property in a device node and read nth 32-bit value from * Search for a property in a device node and read nth 32-bit value from
* it. Returns 0 on success, -EINVAL if the property does not exist, * it.
*
* Return: 0 on success, -EINVAL if the property does not exist,
* -ENODATA if property does not have a value, and -EOVERFLOW if the * -ENODATA if property does not have a value, and -EOVERFLOW if the
* property data isn't large enough. * property data isn't large enough.
* *
...@@ -161,7 +166,9 @@ EXPORT_SYMBOL_GPL(of_property_read_u32_index); ...@@ -161,7 +166,9 @@ EXPORT_SYMBOL_GPL(of_property_read_u32_index);
* @out_value: pointer to return value, modified only if no error. * @out_value: pointer to return value, modified only if no error.
* *
* Search for a property in a device node and read nth 64-bit value from * Search for a property in a device node and read nth 64-bit value from
* it. Returns 0 on success, -EINVAL if the property does not exist, * it.
*
* Return: 0 on success, -EINVAL if the property does not exist,
* -ENODATA if property does not have a value, and -EOVERFLOW if the * -ENODATA if property does not have a value, and -EOVERFLOW if the
* property data isn't large enough. * property data isn't large enough.
* *
...@@ -196,12 +203,14 @@ EXPORT_SYMBOL_GPL(of_property_read_u64_index); ...@@ -196,12 +203,14 @@ EXPORT_SYMBOL_GPL(of_property_read_u64_index);
* sz_min will be read. * sz_min will be read.
* *
* Search for a property in a device node and read 8-bit value(s) from * Search for a property in a device node and read 8-bit value(s) from
* it. Returns number of elements read on success, -EINVAL if the property * it.
* does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
* if the property data is smaller than sz_min or longer than sz_max.
* *
* dts entry of array should be like: * dts entry of array should be like:
* property = /bits/ 8 <0x50 0x60 0x70>; * ``property = /bits/ 8 <0x50 0x60 0x70>;``
*
* Return: The number of elements read on success, -EINVAL if the property
* does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
* if the property data is smaller than sz_min or longer than sz_max.
* *
* The out_values is modified only if a valid u8 value can be decoded. * The out_values is modified only if a valid u8 value can be decoded.
*/ */
...@@ -244,12 +253,14 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u8_array); ...@@ -244,12 +253,14 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u8_array);
* sz_min will be read. * sz_min will be read.
* *
* Search for a property in a device node and read 16-bit value(s) from * Search for a property in a device node and read 16-bit value(s) from
* it. Returns number of elements read on success, -EINVAL if the property * it.
* does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
* if the property data is smaller than sz_min or longer than sz_max.
* *
* dts entry of array should be like: * dts entry of array should be like:
* property = /bits/ 16 <0x5000 0x6000 0x7000>; * ``property = /bits/ 16 <0x5000 0x6000 0x7000>;``
*
* Return: The number of elements read on success, -EINVAL if the property
* does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
* if the property data is smaller than sz_min or longer than sz_max.
* *
* The out_values is modified only if a valid u16 value can be decoded. * The out_values is modified only if a valid u16 value can be decoded.
*/ */
...@@ -292,7 +303,9 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u16_array); ...@@ -292,7 +303,9 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u16_array);
* sz_min will be read. * sz_min will be read.
* *
* Search for a property in a device node and read 32-bit value(s) from * Search for a property in a device node and read 32-bit value(s) from
* it. Returns number of elements read on success, -EINVAL if the property * it.
*
* Return: The number of elements read on success, -EINVAL if the property
* does not exist, -ENODATA if property does not have a value, and -EOVERFLOW * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
* if the property data is smaller than sz_min or longer than sz_max. * if the property data is smaller than sz_min or longer than sz_max.
* *
...@@ -331,7 +344,9 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u32_array); ...@@ -331,7 +344,9 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u32_array);
* @out_value: pointer to return value, modified only if return value is 0. * @out_value: pointer to return value, modified only if return value is 0.
* *
* Search for a property in a device node and read a 64-bit value from * Search for a property in a device node and read a 64-bit value from
* it. Returns 0 on success, -EINVAL if the property does not exist, * it.
*
* Return: 0 on success, -EINVAL if the property does not exist,
* -ENODATA if property does not have a value, and -EOVERFLOW if the * -ENODATA if property does not have a value, and -EOVERFLOW if the
* property data isn't large enough. * property data isn't large enough.
* *
...@@ -366,7 +381,9 @@ EXPORT_SYMBOL_GPL(of_property_read_u64); ...@@ -366,7 +381,9 @@ EXPORT_SYMBOL_GPL(of_property_read_u64);
* sz_min will be read. * sz_min will be read.
* *
* Search for a property in a device node and read 64-bit value(s) from * Search for a property in a device node and read 64-bit value(s) from
* it. Returns number of elements read on success, -EINVAL if the property * it.
*
* Return: The number of elements read on success, -EINVAL if the property
* does not exist, -ENODATA if property does not have a value, and -EOVERFLOW * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW
* if the property data is smaller than sz_min or longer than sz_max. * if the property data is smaller than sz_min or longer than sz_max.
* *
...@@ -408,10 +425,11 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u64_array); ...@@ -408,10 +425,11 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u64_array);
* return value is 0. * return value is 0.
* *
* Search for a property in a device tree node and retrieve a null * Search for a property in a device tree node and retrieve a null
* terminated string value (pointer to data, not a copy). Returns 0 on * terminated string value (pointer to data, not a copy).
* success, -EINVAL if the property does not exist, -ENODATA if property *
* does not have a value, and -EILSEQ if the string is not null-terminated * Return: 0 on success, -EINVAL if the property does not exist, -ENODATA if
* within the length of the property data. * property does not have a value, and -EILSEQ if the string is not
* null-terminated within the length of the property data.
* *
* The out_string pointer is modified only if a valid string can be decoded. * The out_string pointer is modified only if a valid string can be decoded.
*/ */
...@@ -1230,7 +1248,7 @@ static struct device_node *parse_##fname(struct device_node *np, \ ...@@ -1230,7 +1248,7 @@ static struct device_node *parse_##fname(struct device_node *np, \
* @parse_prop.prop_name: Name of property holding a phandle value * @parse_prop.prop_name: Name of property holding a phandle value
* @parse_prop.index: For properties holding a list of phandles, this is the * @parse_prop.index: For properties holding a list of phandles, this is the
* index into the list * index into the list
* @optional: The property can be an optional dependency. * @optional: Describes whether a supplier is mandatory or not
* @node_not_dev: The consumer node containing the property is never a device. * @node_not_dev: The consumer node containing the property is never a device.
* *
* Returns: * Returns:
...@@ -1363,7 +1381,6 @@ static const struct supplier_bindings of_supplier_bindings[] = { ...@@ -1363,7 +1381,6 @@ static const struct supplier_bindings of_supplier_bindings[] = {
/** /**
* of_link_property - Create device links to suppliers listed in a property * of_link_property - Create device links to suppliers listed in a property
* @dev: Consumer device
* @con_np: The consumer device tree node which contains the property * @con_np: The consumer device tree node which contains the property
* @prop_name: Name of property to be parsed * @prop_name: Name of property to be parsed
* *
...@@ -1387,7 +1404,6 @@ static int of_link_property(struct device_node *con_np, const char *prop_name) ...@@ -1387,7 +1404,6 @@ static int of_link_property(struct device_node *con_np, const char *prop_name)
const struct supplier_bindings *s = of_supplier_bindings; const struct supplier_bindings *s = of_supplier_bindings;
unsigned int i = 0; unsigned int i = 0;
bool matched = false; bool matched = false;
int ret = 0;
/* Do not stop at first failed link, link all available suppliers. */ /* Do not stop at first failed link, link all available suppliers. */
while (!matched && s->parse_prop) { while (!matched && s->parse_prop) {
...@@ -1410,7 +1426,7 @@ static int of_link_property(struct device_node *con_np, const char *prop_name) ...@@ -1410,7 +1426,7 @@ static int of_link_property(struct device_node *con_np, const char *prop_name)
} }
s++; s++;
} }
return ret; return 0;
} }
static int of_fwnode_add_links(struct fwnode_handle *fwnode) static int of_fwnode_add_links(struct fwnode_handle *fwnode)
......
...@@ -38,3 +38,51 @@ DTC_FLAGS_testcases += -@ ...@@ -38,3 +38,51 @@ DTC_FLAGS_testcases += -@
# suppress warnings about intentional errors # suppress warnings about intentional errors
DTC_FLAGS_testcases += -Wno-interrupts_property DTC_FLAGS_testcases += -Wno-interrupts_property
# Apply overlays statically with fdtoverlay. This is a build time test that
# the overlays can be applied successfully by fdtoverlay. This does not
# guarantee that the overlays can be applied successfully at run time by
# unittest, but it provides a bit of build time test coverage for those
# who do not execute unittest.
#
# The overlays are applied on top of static_base_1.dtb and static_base_2.dtb to
# create static_test_1.dtb and static_test_2.dtb. If fdtoverlay detects an
# error than the kernel build will fail. static_test_1.dtb and
# static_test_2.dtb are not consumed by unittest.
#
# Some unittest overlays deliberately contain errors that unittest checks for.
# These overlays will cause fdtoverlay to fail, and are thus not included
# in the static test:
# overlay_bad_add_dup_node.dtbo \
# overlay_bad_add_dup_prop.dtbo \
# overlay_bad_phandle.dtbo \
# overlay_bad_symbol.dtbo \
apply_static_overlay_1 := overlay_0.dtbo \
overlay_1.dtbo \
overlay_2.dtbo \
overlay_3.dtbo \
overlay_4.dtbo \
overlay_5.dtbo \
overlay_6.dtbo \
overlay_7.dtbo \
overlay_8.dtbo \
overlay_9.dtbo \
overlay_10.dtbo \
overlay_11.dtbo \
overlay_12.dtbo \
overlay_13.dtbo \
overlay_15.dtbo \
overlay_gpio_01.dtbo \
overlay_gpio_02a.dtbo \
overlay_gpio_02b.dtbo \
overlay_gpio_03.dtbo \
overlay_gpio_04a.dtbo \
overlay_gpio_04b.dtbo
apply_static_overlay_2 := overlay.dtbo
static_test_1-dtbs := static_base_1.dtb $(apply_static_overlay_1)
static_test_2-dtbs := static_base_2.dtb $(apply_static_overlay_2)
dtb-$(CONFIG_OF_OVERLAY) += static_test_1.dtb static_test_2.dtb
...@@ -2,92 +2,4 @@ ...@@ -2,92 +2,4 @@
/dts-v1/; /dts-v1/;
/plugin/; /plugin/;
/* #include "overlay_common.dtsi"
* Base device tree that overlays will be applied against.
*
* Do not add any properties in node "/".
* Do not add any nodes other than "/testcase-data-2" in node "/".
* Do not add anything that would result in dtc creating node "/__fixups__".
* dtc will create nodes "/__symbols__" and "/__local_fixups__".
*/
/ {
testcase-data-2 {
#address-cells = <1>;
#size-cells = <1>;
electric_1: substation@100 {
compatible = "ot,big-volts-control";
reg = < 0x00000100 0x100 >;
status = "disabled";
hvac_1: hvac-medium-1 {
compatible = "ot,hvac-medium";
heat-range = < 50 75 >;
cool-range = < 60 80 >;
};
spin_ctrl_1: motor-1 {
compatible = "ot,ferris-wheel-motor";
spin = "clockwise";
rpm_avail = < 50 >;
};
spin_ctrl_2: motor-8 {
compatible = "ot,roller-coaster-motor";
};
};
rides_1: fairway-1 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "ot,rides";
status = "disabled";
orientation = < 127 >;
ride@100 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "ot,roller-coaster";
reg = < 0x00000100 0x100 >;
hvac-provider = < &hvac_1 >;
hvac-thermostat = < 29 > ;
hvac-zones = < 14 >;
hvac-zone-names = "operator";
spin-controller = < &spin_ctrl_2 5 &spin_ctrl_2 7 >;
spin-controller-names = "track_1", "track_2";
queues = < 2 >;
track@30 {
reg = < 0x00000030 0x10 >;
};
track@40 {
reg = < 0x00000040 0x10 >;
};
};
};
lights_1: lights@30000 {
compatible = "ot,work-lights";
reg = < 0x00030000 0x1000 >;
status = "disabled";
};
lights_2: lights@40000 {
compatible = "ot,show-lights";
reg = < 0x00040000 0x1000 >;
status = "disabled";
rate = < 13 138 >;
};
retail_1: vending@50000 {
reg = < 0x00050000 0x1000 >;
compatible = "ot,tickets";
status = "disabled";
};
};
};
// SPDX-License-Identifier: GPL-2.0
/*
* Base device tree that overlays will be applied against.
*
* Do not add any properties in node "/".
* Do not add any nodes other than "/testcase-data-2" in node "/".
* Do not add anything that would result in dtc creating node "/__fixups__".
* dtc will create nodes "/__symbols__" and "/__local_fixups__".
*/
/ {
testcase-data-2 {
#address-cells = <1>;
#size-cells = <1>;
electric_1: substation@100 {
compatible = "ot,big-volts-control";
reg = < 0x00000100 0x100 >;
status = "disabled";
hvac_1: hvac-medium-1 {
compatible = "ot,hvac-medium";
heat-range = < 50 75 >;
cool-range = < 60 80 >;
};
spin_ctrl_1: motor-1 {
compatible = "ot,ferris-wheel-motor";
spin = "clockwise";
rpm_avail = < 50 >;
};
spin_ctrl_2: motor-8 {
compatible = "ot,roller-coaster-motor";
};
};
rides_1: fairway-1 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "ot,rides";
status = "disabled";
orientation = < 127 >;
ride@100 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "ot,roller-coaster";
reg = < 0x00000100 0x100 >;
hvac-provider = < &hvac_1 >;
hvac-thermostat = < 29 > ;
hvac-zones = < 14 >;
hvac-zone-names = "operator";
spin-controller = < &spin_ctrl_2 5 &spin_ctrl_2 7 >;
spin-controller-names = "track_1", "track_2";
queues = < 2 >;
track@30 {
reg = < 0x00000030 0x10 >;
};
track@40 {
reg = < 0x00000040 0x10 >;
};
};
};
lights_1: lights@30000 {
compatible = "ot,work-lights";
reg = < 0x00030000 0x1000 >;
status = "disabled";
};
lights_2: lights@40000 {
compatible = "ot,show-lights";
reg = < 0x00040000 0x1000 >;
status = "disabled";
rate = < 13 138 >;
};
retail_1: vending@50000 {
reg = < 0x00050000 0x1000 >;
compatible = "ot,tickets";
status = "disabled";
};
};
};
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
#include "testcases_common.dtsi"
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
#include "overlay_common.dtsi"
...@@ -2,19 +2,20 @@ ...@@ -2,19 +2,20 @@
/dts-v1/; /dts-v1/;
/plugin/; /plugin/;
#include "testcases_common.dtsi"
/ { / {
/*
* testcase data that intentionally results in an error is located here
* instead of in testcases_common.dtsi so that the static overlay apply
* tests will not include the error.
*/
testcase-data { testcase-data {
changeset { testcase-device2 {
prop-update = "hello"; compatible = "testcase-device";
prop-remove = "world"; interrupt-parent = <&test_intc2>;
node-remove { interrupts = <1>; /* invalid specifier - too short */
};
}; };
}; };
}; };
#include "tests-phandle.dtsi"
#include "tests-interrupts.dtsi"
#include "tests-match.dtsi"
#include "tests-address.dtsi"
#include "tests-platform.dtsi"
#include "tests-overlay.dtsi"
// SPDX-License-Identifier: GPL-2.0
/ {
testcase-data {
changeset {
prop-update = "hello";
prop-remove = "world";
node-remove {
};
};
};
};
#include "tests-phandle.dtsi"
#include "tests-interrupts.dtsi"
#include "tests-match.dtsi"
#include "tests-address.dtsi"
#include "tests-platform.dtsi"
#include "tests-overlay.dtsi"
...@@ -62,11 +62,10 @@ testcase-device1 { ...@@ -62,11 +62,10 @@ testcase-device1 {
interrupts = <1>; interrupts = <1>;
}; };
testcase-device2 { /*
compatible = "testcase-device"; * testcase data that intentionally results in an error is
interrupt-parent = <&test_intc2>; * located in testcases.dts instead of in this file so that the
interrupts = <1>; /* invalid specifier - too short */ * static overlay apply tests will not include the error.
}; */
}; };
}; };
...@@ -304,7 +304,15 @@ struct kimage { ...@@ -304,7 +304,15 @@ struct kimage {
#ifdef CONFIG_IMA_KEXEC #ifdef CONFIG_IMA_KEXEC
/* Virtual address of IMA measurement buffer for kexec syscall */ /* Virtual address of IMA measurement buffer for kexec syscall */
void *ima_buffer; void *ima_buffer;
phys_addr_t ima_buffer_addr;
size_t ima_buffer_size;
#endif #endif
/* Core ELF header buffer */
void *elf_headers;
unsigned long elf_headers_sz;
unsigned long elf_load_addr;
}; };
/* kexec interface functions */ /* kexec interface functions */
......
...@@ -424,12 +424,14 @@ extern int of_detach_node(struct device_node *); ...@@ -424,12 +424,14 @@ extern int of_detach_node(struct device_node *);
* @sz: number of array elements to read * @sz: number of array elements to read
* *
* Search for a property in a device node and read 8-bit value(s) from * Search for a property in a device node and read 8-bit value(s) from
* it. Returns 0 on success, -EINVAL if the property does not exist, * it.
* -ENODATA if property does not have a value, and -EOVERFLOW if the
* property data isn't large enough.
* *
* dts entry of array should be like: * dts entry of array should be like:
* property = /bits/ 8 <0x50 0x60 0x70>; * ``property = /bits/ 8 <0x50 0x60 0x70>;``
*
* Return: 0 on success, -EINVAL if the property does not exist,
* -ENODATA if property does not have a value, and -EOVERFLOW if the
* property data isn't large enough.
* *
* The out_values is modified only if a valid u8 value can be decoded. * The out_values is modified only if a valid u8 value can be decoded.
*/ */
...@@ -454,12 +456,14 @@ static inline int of_property_read_u8_array(const struct device_node *np, ...@@ -454,12 +456,14 @@ static inline int of_property_read_u8_array(const struct device_node *np,
* @sz: number of array elements to read * @sz: number of array elements to read
* *
* Search for a property in a device node and read 16-bit value(s) from * Search for a property in a device node and read 16-bit value(s) from
* it. Returns 0 on success, -EINVAL if the property does not exist, * it.
* -ENODATA if property does not have a value, and -EOVERFLOW if the
* property data isn't large enough.
* *
* dts entry of array should be like: * dts entry of array should be like:
* property = /bits/ 16 <0x5000 0x6000 0x7000>; * ``property = /bits/ 16 <0x5000 0x6000 0x7000>;``
*
* Return: 0 on success, -EINVAL if the property does not exist,
* -ENODATA if property does not have a value, and -EOVERFLOW if the
* property data isn't large enough.
* *
* The out_values is modified only if a valid u16 value can be decoded. * The out_values is modified only if a valid u16 value can be decoded.
*/ */
...@@ -485,7 +489,9 @@ static inline int of_property_read_u16_array(const struct device_node *np, ...@@ -485,7 +489,9 @@ static inline int of_property_read_u16_array(const struct device_node *np,
* @sz: number of array elements to read * @sz: number of array elements to read
* *
* Search for a property in a device node and read 32-bit value(s) from * Search for a property in a device node and read 32-bit value(s) from
* it. Returns 0 on success, -EINVAL if the property does not exist, * it.
*
* Return: 0 on success, -EINVAL if the property does not exist,
* -ENODATA if property does not have a value, and -EOVERFLOW if the * -ENODATA if property does not have a value, and -EOVERFLOW if the
* property data isn't large enough. * property data isn't large enough.
* *
...@@ -513,7 +519,9 @@ static inline int of_property_read_u32_array(const struct device_node *np, ...@@ -513,7 +519,9 @@ static inline int of_property_read_u32_array(const struct device_node *np,
* @sz: number of array elements to read * @sz: number of array elements to read
* *
* Search for a property in a device node and read 64-bit value(s) from * Search for a property in a device node and read 64-bit value(s) from
* it. Returns 0 on success, -EINVAL if the property does not exist, * it.
*
* Return: 0 on success, -EINVAL if the property does not exist,
* -ENODATA if property does not have a value, and -EOVERFLOW if the * -ENODATA if property does not have a value, and -EOVERFLOW if the
* property data isn't large enough. * property data isn't large enough.
* *
...@@ -560,6 +568,13 @@ int of_map_id(struct device_node *np, u32 id, ...@@ -560,6 +568,13 @@ int of_map_id(struct device_node *np, u32 id,
phys_addr_t of_dma_get_max_cpu_address(struct device_node *np); phys_addr_t of_dma_get_max_cpu_address(struct device_node *np);
struct kimage;
void *of_kexec_alloc_and_setup_fdt(const struct kimage *image,
unsigned long initrd_load_addr,
unsigned long initrd_len,
const char *cmdline, size_t extra_fdt_size);
int ima_get_kexec_buffer(void **addr, size_t *size);
int ima_free_kexec_buffer(void);
#else /* CONFIG_OF */ #else /* CONFIG_OF */
static inline void of_core_init(void) static inline void of_core_init(void)
...@@ -1063,7 +1078,9 @@ static inline bool of_node_is_type(const struct device_node *np, const char *typ ...@@ -1063,7 +1078,9 @@ static inline bool of_node_is_type(const struct device_node *np, const char *typ
* @propname: name of the property to be searched. * @propname: name of the property to be searched.
* *
* Search for a property in a device node and count the number of u8 elements * Search for a property in a device node and count the number of u8 elements
* in it. Returns number of elements on sucess, -EINVAL if the property does * in it.
*
* Return: The number of elements on sucess, -EINVAL if the property does
* not exist or its length does not match a multiple of u8 and -ENODATA if the * not exist or its length does not match a multiple of u8 and -ENODATA if the
* property does not have a value. * property does not have a value.
*/ */
...@@ -1080,7 +1097,9 @@ static inline int of_property_count_u8_elems(const struct device_node *np, ...@@ -1080,7 +1097,9 @@ static inline int of_property_count_u8_elems(const struct device_node *np,
* @propname: name of the property to be searched. * @propname: name of the property to be searched.
* *
* Search for a property in a device node and count the number of u16 elements * Search for a property in a device node and count the number of u16 elements
* in it. Returns number of elements on sucess, -EINVAL if the property does * in it.
*
* Return: The number of elements on sucess, -EINVAL if the property does
* not exist or its length does not match a multiple of u16 and -ENODATA if the * not exist or its length does not match a multiple of u16 and -ENODATA if the
* property does not have a value. * property does not have a value.
*/ */
...@@ -1097,7 +1116,9 @@ static inline int of_property_count_u16_elems(const struct device_node *np, ...@@ -1097,7 +1116,9 @@ static inline int of_property_count_u16_elems(const struct device_node *np,
* @propname: name of the property to be searched. * @propname: name of the property to be searched.
* *
* Search for a property in a device node and count the number of u32 elements * Search for a property in a device node and count the number of u32 elements
* in it. Returns number of elements on sucess, -EINVAL if the property does * in it.
*
* Return: The number of elements on sucess, -EINVAL if the property does
* not exist or its length does not match a multiple of u32 and -ENODATA if the * not exist or its length does not match a multiple of u32 and -ENODATA if the
* property does not have a value. * property does not have a value.
*/ */
...@@ -1114,7 +1135,9 @@ static inline int of_property_count_u32_elems(const struct device_node *np, ...@@ -1114,7 +1135,9 @@ static inline int of_property_count_u32_elems(const struct device_node *np,
* @propname: name of the property to be searched. * @propname: name of the property to be searched.
* *
* Search for a property in a device node and count the number of u64 elements * Search for a property in a device node and count the number of u64 elements
* in it. Returns number of elements on sucess, -EINVAL if the property does * in it.
*
* Return: The number of elements on sucess, -EINVAL if the property does
* not exist or its length does not match a multiple of u64 and -ENODATA if the * not exist or its length does not match a multiple of u64 and -ENODATA if the
* property does not have a value. * property does not have a value.
*/ */
...@@ -1135,7 +1158,7 @@ static inline int of_property_count_u64_elems(const struct device_node *np, ...@@ -1135,7 +1158,7 @@ static inline int of_property_count_u64_elems(const struct device_node *np,
* Search for a property in a device tree node and retrieve a list of * Search for a property in a device tree node and retrieve a list of
* terminated string values (pointer to data, not a copy) in that property. * terminated string values (pointer to data, not a copy) in that property.
* *
* If @out_strs is NULL, the number of strings in the property is returned. * Return: If @out_strs is NULL, the number of strings in the property is returned.
*/ */
static inline int of_property_read_string_array(const struct device_node *np, static inline int of_property_read_string_array(const struct device_node *np,
const char *propname, const char **out_strs, const char *propname, const char **out_strs,
...@@ -1151,10 +1174,11 @@ static inline int of_property_read_string_array(const struct device_node *np, ...@@ -1151,10 +1174,11 @@ static inline int of_property_read_string_array(const struct device_node *np,
* @propname: name of the property to be searched. * @propname: name of the property to be searched.
* *
* Search for a property in a device tree node and retrieve the number of null * Search for a property in a device tree node and retrieve the number of null
* terminated string contain in it. Returns the number of strings on * terminated string contain in it.
* success, -EINVAL if the property does not exist, -ENODATA if property *
* does not have a value, and -EILSEQ if the string is not null-terminated * Return: The number of strings on success, -EINVAL if the property does not
* within the length of the property data. * exist, -ENODATA if property does not have a value, and -EILSEQ if the string
* is not null-terminated within the length of the property data.
*/ */
static inline int of_property_count_strings(const struct device_node *np, static inline int of_property_count_strings(const struct device_node *np,
const char *propname) const char *propname)
...@@ -1168,13 +1192,14 @@ static inline int of_property_count_strings(const struct device_node *np, ...@@ -1168,13 +1192,14 @@ static inline int of_property_count_strings(const struct device_node *np,
* @np: device node from which the property value is to be read. * @np: device node from which the property value is to be read.
* @propname: name of the property to be searched. * @propname: name of the property to be searched.
* @index: index of the string in the list of strings * @index: index of the string in the list of strings
* @out_string: pointer to null terminated return string, modified only if * @output: pointer to null terminated return string, modified only if
* return value is 0. * return value is 0.
* *
* Search for a property in a device tree node and retrieve a null * Search for a property in a device tree node and retrieve a null
* terminated string value (pointer to data, not a copy) in the list of strings * terminated string value (pointer to data, not a copy) in the list of strings
* contained in that property. * contained in that property.
* Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if *
* Return: 0 on success, -EINVAL if the property does not exist, -ENODATA if
* property does not have a value, and -EILSEQ if the string is not * property does not have a value, and -EILSEQ if the string is not
* null-terminated within the length of the property data. * null-terminated within the length of the property data.
* *
...@@ -1194,7 +1219,8 @@ static inline int of_property_read_string_index(const struct device_node *np, ...@@ -1194,7 +1219,8 @@ static inline int of_property_read_string_index(const struct device_node *np,
* @propname: name of the property to be searched. * @propname: name of the property to be searched.
* *
* Search for a property in a device node. * Search for a property in a device node.
* Returns true if the property exists false otherwise. *
* Return: true if the property exists false otherwise.
*/ */
static inline bool of_property_read_bool(const struct device_node *np, static inline bool of_property_read_bool(const struct device_node *np,
const char *propname) const char *propname)
...@@ -1440,14 +1466,14 @@ static inline int of_reconfig_get_state_change(unsigned long action, ...@@ -1440,14 +1466,14 @@ static inline int of_reconfig_get_state_change(unsigned long action,
* of_device_is_system_power_controller - Tells if system-power-controller is found for device_node * of_device_is_system_power_controller - Tells if system-power-controller is found for device_node
* @np: Pointer to the given device_node * @np: Pointer to the given device_node
* *
* return true if present false otherwise * Return: true if present false otherwise
*/ */
static inline bool of_device_is_system_power_controller(const struct device_node *np) static inline bool of_device_is_system_power_controller(const struct device_node *np)
{ {
return of_property_read_bool(np, "system-power-controller"); return of_property_read_bool(np, "system-power-controller");
} }
/** /*
* Overlay support * Overlay support
*/ */
......
...@@ -73,14 +73,26 @@ always-y += $(userprogs-always-y) $(userprogs-always-m) ...@@ -73,14 +73,26 @@ always-y += $(userprogs-always-y) $(userprogs-always-m)
# DTB # DTB
# If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built # If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built
dtb-$(CONFIG_OF_ALL_DTBS) += $(dtb-)
# List all dtbs to be generated by fdtoverlay
overlay-y := $(foreach m,$(dtb-y), $(if $(strip $($(m:.dtb=-dtbs))),$(m),))
# Generate symbols for the base files so overlays can be applied to them.
$(foreach m,$(overlay-y), $(eval DTC_FLAGS_$(basename $(firstword $($(m:.dtb=-dtbs)))) += -@))
# Add base dtb and overlay dtbo
dtb-y += $(foreach m,$(overlay-y), $($(m:.dtb=-dtbs)))
always-y += $(dtb-y) always-y += $(dtb-y)
always-$(CONFIG_OF_ALL_DTBS) += $(dtb-)
ifneq ($(CHECK_DTBS),) ifneq ($(CHECK_DTBS),)
always-y += $(patsubst %.dtb,%.dt.yaml, $(dtb-y)) # Don't run schema checks for dtbs created by fdtoverlay as they don't
always-y += $(patsubst %.dtbo,%.dt.yaml, $(dtb-y)) # have corresponding dts files.
always-$(CONFIG_OF_ALL_DTBS) += $(patsubst %.dtb,%.dt.yaml, $(dtb-)) dt-yaml-y := $(filter-out $(overlay-y),$(dtb-y))
always-$(CONFIG_OF_ALL_DTBS) += $(patsubst %.dtbo,%.dt.yaml, $(dtb-))
always-y += $(patsubst %.dtb,%.dt.yaml, $(dt-yaml-y))
always-y += $(patsubst %.dtbo,%.dt.yaml, $(dt-yaml-y))
endif endif
# Add subdir path # Add subdir path
...@@ -338,13 +350,23 @@ $(obj)/%.dtb: $(src)/%.dts $(DTC) FORCE ...@@ -338,13 +350,23 @@ $(obj)/%.dtb: $(src)/%.dts $(DTC) FORCE
$(obj)/%.dtbo: $(src)/%.dts $(DTC) FORCE $(obj)/%.dtbo: $(src)/%.dts $(DTC) FORCE
$(call if_changed_dep,dtc) $(call if_changed_dep,dtc)
overlay-y := $(addprefix $(obj)/, $(overlay-y))
quiet_cmd_fdtoverlay = DTOVL $@
cmd_fdtoverlay = $(objtree)/scripts/dtc/fdtoverlay -o $@ -i $(real-prereqs)
$(overlay-y): FORCE
$(call if_changed,fdtoverlay)
$(call multi_depend, $(overlay-y), .dtb, -dtbs)
DT_CHECKER ?= dt-validate DT_CHECKER ?= dt-validate
DT_CHECKER_FLAGS ?= $(if $(DT_SCHEMA_FILES),,-m)
DT_BINDING_DIR := Documentation/devicetree/bindings DT_BINDING_DIR := Documentation/devicetree/bindings
# DT_TMP_SCHEMA may be overridden from Documentation/devicetree/bindings/Makefile # DT_TMP_SCHEMA may be overridden from Documentation/devicetree/bindings/Makefile
DT_TMP_SCHEMA ?= $(objtree)/$(DT_BINDING_DIR)/processed-schema.json DT_TMP_SCHEMA ?= $(objtree)/$(DT_BINDING_DIR)/processed-schema.json
quiet_cmd_dtb_check = CHECK $@ quiet_cmd_dtb_check = CHECK $@
cmd_dtb_check = $(DT_CHECKER) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@ cmd_dtb_check = $(DT_CHECKER) $(DT_CHECKER_FLAGS) -u $(srctree)/$(DT_BINDING_DIR) -p $(DT_TMP_SCHEMA) $@
define rule_dtc define rule_dtc
$(call cmd_and_fixdep,dtc) $(call cmd_and_fixdep,dtc)
......
...@@ -3245,7 +3245,7 @@ sub process { ...@@ -3245,7 +3245,7 @@ sub process {
($line =~ /^new file mode\s*\d+\s*$/) && ($line =~ /^new file mode\s*\d+\s*$/) &&
($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) { ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
WARN("DT_SCHEMA_BINDING_PATCH", WARN("DT_SCHEMA_BINDING_PATCH",
"DT bindings should be in DT schema format. See: Documentation/devicetree/writing-schema.rst\n"); "DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\n");
} }
# Check for wrappage within a valid hunk of the file # Check for wrappage within a valid hunk of the file
......
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