Devicetree updates for v5.13:
- Refactoring 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 -----BEGIN PGP SIGNATURE----- iQJEBAABCgAuFiEEktVUI4SxYhzZyEuo+vtdtY28YcMFAmCIYdgQHHJvYmhAa2Vy bmVsLm9yZwAKCRD6+121jbxhw/PKEACkOCWDnLSY9U7w1uGDHr6UgXIWOY9j8bYy 2pTvDrVa6KZphT6yGU/hxrOk8Mqh5AMd2vUhO2OCoyyl/priTv+Ktqo+bikvJZLa MQm3JnrLpPy/GetdmVD8wq1l+FoeOSTnRIJqRxInsd8UFVpZImtP22ELox6KgGiv keVHIrjsHU/HpafK3w8wHCLikCZk+1Gl6pL/QgFDv2FaaCTKW16Dt64dPqYm49Xk j7YMMQWl+3NJ9ywZV0+PMbl9udi3EjGm5Ap5VfKzpj53Nh07QObg/QtH/1sj0HPo apyW7jAyQFyLytbjxzFL/tljtOeW/5rZos1GWThZ326e+Y0mTKUTDZShvNplfjIf e26FvVi7gndWlRSr30Ia5gdNFAx72IkpJUAuypBXgb+qNPchBJjAXLn9tcIcg/k+ 2R6BIB7SkVLpgTnJ1Bq1+PRqkKM+ggACdJNJIUApj44xoiG01vtGDGRaFuIio+Ch HT4aBbic4kLvagm8VzuiIF/sL7af5pntzArcyOfQTaZ92DyGI2C0j90rK3yPRIYM u9qX/24t1SXiUji74QpoQFzt/+Egy5hYXMJOJJSywUjKf7DBhehqklTjiJRQHKm6 0DJ/n8q4lNru8F0Y4keKSuYTfHBstF7fS3UTH/rUmBAbfEwkvZe6B29KQbs+7aph GTw+jeoR5Q== =rF27 -----END PGP SIGNATURE----- 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 ...
This commit is contained in:
commit
0080665fbd
@ -5,7 +5,7 @@ DT_MK_SCHEMA ?= dt-mk-schema
|
||||
|
||||
DT_SCHEMA_LINT = $(shell which yamllint)
|
||||
|
||||
DT_SCHEMA_MIN_VERSION = 2020.8.1
|
||||
DT_SCHEMA_MIN_VERSION = 2021.2.1
|
||||
|
||||
PHONY += check_dtschema_version
|
||||
check_dtschema_version:
|
||||
@ -55,6 +55,9 @@ override DTC_FLAGS := \
|
||||
-Wno-graph_child_address \
|
||||
-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
|
||||
$(call if_changed_rule,chkdt)
|
||||
|
||||
|
@ -26,10 +26,7 @@ properties:
|
||||
- const: simple-mfd
|
||||
|
||||
mboxes:
|
||||
$ref: '/schemas/types.yaml#/definitions/phandle'
|
||||
description: |
|
||||
Phandle to the firmware device's Mailbox.
|
||||
(See: ../mailbox/mailbox.txt for more information)
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
type: object
|
||||
|
@ -258,13 +258,11 @@ properties:
|
||||
where voltage is in V, frequency is in MHz.
|
||||
|
||||
power-domains:
|
||||
$ref: '/schemas/types.yaml#/definitions/phandle-array'
|
||||
description:
|
||||
List of phandles and PM domain specifiers, as defined by bindings of the
|
||||
PM domain provider (see also ../power_domain.txt).
|
||||
|
||||
power-domain-names:
|
||||
$ref: '/schemas/types.yaml#/definitions/string-array'
|
||||
description:
|
||||
A list of power domain name strings sorted in the same order as the
|
||||
power-domains property.
|
||||
|
@ -44,7 +44,7 @@ examples:
|
||||
- |
|
||||
clk@1c20000 {
|
||||
#clock-cells = <0>;
|
||||
compatible = "allwinner,sun4i-a10-pll1";
|
||||
compatible = "allwinner,sun4i-a10-pll1-clk";
|
||||
reg = <0x01c20000 0x4>;
|
||||
clocks = <&osc24M>;
|
||||
clock-output-names = "osc24M";
|
||||
|
@ -1,6 +1,6 @@
|
||||
* 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.
|
||||
|
||||
The TBG clock consumer should specify the desired clock by having the
|
||||
|
@ -18,10 +18,12 @@ description: |
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- socionext,milbeaut-m10v-ccu
|
||||
enum:
|
||||
- socionext,milbeaut-m10v-ccu
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
description: external clock
|
||||
@ -41,7 +43,7 @@ examples:
|
||||
# Clock controller node:
|
||||
- |
|
||||
m10v-clk-ctrl@1d021000 {
|
||||
compatible = "socionext,milbeaut-m10v-clk-ccu";
|
||||
compatible = "socionext,milbeaut-m10v-ccu";
|
||||
reg = <0x1d021000 0x4000>;
|
||||
#clock-cells = <1>;
|
||||
clocks = <&clki40mhz>;
|
||||
|
@ -12,6 +12,9 @@ Required 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
|
||||
timing parameters of the DDR device in terms of number of clock cycles.
|
||||
These values shall be obtained from the device data-sheet.
|
||||
@ -49,6 +52,8 @@ samsung_K3QF2F20DB: lpddr3 {
|
||||
compatible = "samsung,K3QF2F20DB", "jedec,lpddr3";
|
||||
density = <16384>;
|
||||
io-width = <32>;
|
||||
manufacturer-id = <1>;
|
||||
revision-id = <123 234>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
|
@ -73,7 +73,6 @@ properties:
|
||||
clock-output-names:
|
||||
description:
|
||||
Name of the LCD pixel clock created.
|
||||
$ref: /schemas/types.yaml#/definitions/string-array
|
||||
maxItems: 1
|
||||
|
||||
dmas:
|
||||
|
@ -77,12 +77,6 @@ examples:
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
The DPU display controller is found in SDM845 SoC.
|
||||
|
||||
MDSS:
|
||||
Required properties:
|
||||
- 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:
|
||||
* "mdss"
|
||||
- power-domains: a power domain consumer specifier according to
|
||||
|
@ -40,7 +40,7 @@ additionalProperties: false
|
||||
examples:
|
||||
- |
|
||||
panel {
|
||||
compatible = "osddisplays,osd057T0559-34ts", "panel-dpi";
|
||||
compatible = "startek,startek-kd050c", "panel-dpi";
|
||||
label = "osddisplay";
|
||||
power-supply = <&vcc_supply>;
|
||||
backlight = <&backlight>;
|
||||
|
@ -64,7 +64,7 @@ examples:
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/dma/qcom-gpi.h>
|
||||
gpi_dma0: dma-controller@800000 {
|
||||
compatible = "qcom,gpi-dma";
|
||||
compatible = "qcom,sdm845-gpi-dma";
|
||||
#dma-cells = <3>;
|
||||
reg = <0x00800000 0x60000>;
|
||||
iommus = <&apps_smmu 0x0016 0x0>;
|
||||
|
@ -43,8 +43,7 @@ properties:
|
||||
|
||||
gpio-ranges: true
|
||||
|
||||
gpio-ranges-group-names:
|
||||
$ref: /schemas/types.yaml#/definitions/string-array
|
||||
gpio-ranges-group-names: true
|
||||
|
||||
socionext,interrupt-ranges:
|
||||
description: |
|
||||
|
@ -4,7 +4,7 @@
|
||||
$id: "http://devicetree.org/schemas/i2c/xlnx,xps-iic-2.00.a.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: ilinx IIC controller Device Tree Bindings
|
||||
title: Xilinx IIC controller Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- info@mocean-labs.com
|
||||
|
@ -157,9 +157,10 @@ examples:
|
||||
i2c-scl-hz = <100000>;
|
||||
|
||||
/* I2C device. */
|
||||
nunchuk: nunchuk@52 {
|
||||
compatible = "nintendo,nunchuk";
|
||||
reg = <0x52 0x0 0x10>;
|
||||
eeprom@57 {
|
||||
compatible = "atmel,24c01";
|
||||
reg = <0x57 0x0 0x10>;
|
||||
pagesize = <0x8>;
|
||||
};
|
||||
|
||||
/* I3C device with a static I2C address. */
|
||||
|
@ -53,11 +53,6 @@ examples:
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
ts_adc_syscon: ts_adc_syscon@180a6000 {
|
||||
compatible = "brcm,iproc-ts-adc-syscon","syscon";
|
||||
reg = <0x180a6000 0xc30>;
|
||||
};
|
||||
|
||||
adc {
|
||||
compatible = "brcm,iproc-static-adc";
|
||||
adc-syscon = <&ts_adc_syscon>;
|
||||
|
@ -83,7 +83,7 @@ examples:
|
||||
#size-cells = <0>;
|
||||
|
||||
gyroscope@0 {
|
||||
compatible = "nxp,fxas2102c";
|
||||
compatible = "nxp,fxas21002c";
|
||||
reg = <0x0>;
|
||||
|
||||
spi-max-frequency = <2000000>;
|
||||
|
@ -48,7 +48,6 @@ properties:
|
||||
vdd-supply: true
|
||||
|
||||
capella,aset-resistance-ohms:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [50000, 100000, 300000, 600000]
|
||||
description: >
|
||||
Sensitivity calibration resistance. Note that calibration curves
|
||||
|
@ -11,12 +11,12 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: upisemi,asd5182
|
||||
const: upisemi,usd5182
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
upsemi,glass-coef:
|
||||
upisemi,glass-coef:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
glass attenuation factor - compensation factor of resolution 1000
|
||||
|
@ -1,12 +1,9 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
===========
|
||||
Device Tree
|
||||
===========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
ABI
|
||||
submitting-patches
|
||||
writing-bindings
|
||||
writing-schema
|
||||
submitting-patches
|
||||
|
@ -32,6 +32,5 @@ properties:
|
||||
Duration in seconds which the key should be kept pressed for device to
|
||||
power off automatically. Device with key pressed shutdown feature can
|
||||
specify this property.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
additionalProperties: true
|
||||
|
@ -47,7 +47,7 @@ examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
htintc: interrupt-controller@1fb000080 {
|
||||
compatible = "loongson,htintc-1.0";
|
||||
compatible = "loongson,htpic-1.0";
|
||||
reg = <0xfb000080 0x40>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
@ -14,6 +14,17 @@ properties:
|
||||
compatible:
|
||||
const: intel,lgm-ssoled
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: sso
|
||||
- const: fpid
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
'#gpio-cells':
|
||||
@ -36,8 +47,15 @@ properties:
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
patternProperties:
|
||||
"^led@[0-23]$":
|
||||
"^led@[0-2]$":
|
||||
type: object
|
||||
|
||||
properties:
|
||||
@ -81,7 +99,7 @@ examples:
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
ssogpio: ssogpio@e0d40000 {
|
||||
compatible = "intel,sso-led";
|
||||
compatible = "intel,lgm-ssoled";
|
||||
reg = <0xE0D40000 0x2E4>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
@ -103,8 +121,8 @@ examples:
|
||||
led-gpio = <&ssogpio 0 0>;
|
||||
};
|
||||
|
||||
led@23 {
|
||||
reg = <23>;
|
||||
led@2 {
|
||||
reg = <2>;
|
||||
function = LED_FUNCTION_POWER;
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
led-gpio = <&ssogpio 23 0>;
|
||||
|
167
Documentation/devicetree/bindings/media/qcom,sm8250-venus.yaml
Normal file
167
Documentation/devicetree/bindings/media/qcom,sm8250-venus.yaml
Normal file
@ -0,0 +1,167 @@
|
||||
# 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:
|
||||
CCP2, for instance.
|
||||
|
||||
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 = <®ulator1>;
|
||||
vddcore-supply = <®ulator2>;
|
||||
|
||||
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 = <®ulator1>;
|
||||
vddcore-supply = <®ulator2>;
|
||||
|
||||
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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
|
@ -1,60 +0,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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
106
Documentation/devicetree/bindings/media/video-mux.yaml
Normal file
106
Documentation/devicetree/bindings/media/video-mux.yaml
Normal file
@ -0,0 +1,106 @@
|
||||
# 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:
|
||||
- description: EMC general interrupt
|
||||
|
||||
memory-region:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
maxItems: 1
|
||||
description:
|
||||
phandle to a reserved memory region describing the table of EMC
|
||||
frequencies trained by the firmware
|
||||
|
@ -57,7 +57,6 @@ properties:
|
||||
- const: per
|
||||
|
||||
clock-frequency:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
The oscillator frequency driving the flexcan device, filled in by the
|
||||
boot loader. This property should only be used the used operating system
|
||||
|
@ -0,0 +1,109 @@
|
||||
# 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";
|
||||
};
|
||||
};
|
@ -1,38 +0,0 @@
|
||||
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 = <®_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 @@
|
||||
%YAML 1.2
|
||||
---
|
||||
$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
|
||||
|
||||
@ -23,12 +23,10 @@ properties:
|
||||
List of phandle to the nvmem data cells.
|
||||
|
||||
nvmem-names:
|
||||
$ref: /schemas/types.yaml#/definitions/string-array
|
||||
description:
|
||||
Names for the each nvmem provider.
|
||||
|
||||
nvmem-cell-names:
|
||||
$ref: /schemas/types.yaml#/definitions/string-array
|
||||
description:
|
||||
Names for each nvmem-cells specified.
|
||||
|
||||
|
@ -222,7 +222,7 @@ examples:
|
||||
};
|
||||
|
||||
serdes@5000000 {
|
||||
compatible = "cdns,ti,sierra-phy-t0";
|
||||
compatible = "ti,sierra-phy-t0";
|
||||
reg-names = "serdes";
|
||||
reg = <0x5000000 0x10000>;
|
||||
#address-cells = <1>;
|
||||
|
@ -39,7 +39,6 @@ properties:
|
||||
maxItems: 1
|
||||
|
||||
ti,watchdog-timeout-ms:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
default: 0
|
||||
description: |
|
||||
Watchdog timer in ms. 0 (default) disables the watchdog
|
||||
|
@ -61,7 +61,7 @@ examples:
|
||||
#size-cells = <0>;
|
||||
|
||||
cw2015@62 {
|
||||
compatible = "cellwise,cw201x";
|
||||
compatible = "cellwise,cw2015";
|
||||
reg = <0x62>;
|
||||
cellwise,battery-profile = /bits/ 8 <
|
||||
0x17 0x67 0x80 0x73 0x6E 0x6C 0x6B 0x63
|
||||
|
@ -29,12 +29,10 @@ properties:
|
||||
description: I2C address of the charger.
|
||||
|
||||
lltc,rsnsb-micro-ohms:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Battery sense resistor in microohm.
|
||||
minimum: 1000
|
||||
|
||||
lltc,rsnsi-micro-ohms:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Input current sense resistor in microohm.
|
||||
minimum: 1000
|
||||
|
||||
|
@ -18,25 +18,3 @@ properties:
|
||||
|
||||
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:
|
||||
|
||||
properties:
|
||||
qcom,soft-start-us:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Regulator soft start time in microseconds.
|
||||
enum: [200, 400, 600, 800]
|
||||
default: 200
|
||||
|
@ -93,7 +93,7 @@ properties:
|
||||
# The following are the optional properties:
|
||||
|
||||
memory-region:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
maxItems: 1
|
||||
description: |
|
||||
phandle to the reserved memory node to be associated
|
||||
with the remoteproc device. The reserved memory node
|
||||
|
@ -144,7 +144,7 @@ examples:
|
||||
interrupts = <1>;
|
||||
|
||||
bluetooth {
|
||||
compatible = "brcm,bcm43341-bt";
|
||||
compatible = "brcm,bcm4330-bt";
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <10>;
|
||||
};
|
||||
|
@ -29,11 +29,9 @@ properties:
|
||||
|
||||
clock-frequency:
|
||||
description: common clock binding; frequency of MCKO
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
clock-output-names:
|
||||
description: common clock name
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
@ -32,7 +32,7 @@ properties:
|
||||
The last one integer is the length of the shared memory.
|
||||
|
||||
memory-region:
|
||||
$ref: '/schemas/types.yaml#/definitions/phandle'
|
||||
maxItems: 1
|
||||
description: |
|
||||
Shared memory region to EC. A "shared-dma-pool".
|
||||
See ../reserved-memory/reserved-memory.txt for details.
|
||||
|
@ -78,7 +78,6 @@ properties:
|
||||
|
||||
clock-frequency:
|
||||
description: for audio_clkout0/1/2/3
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
|
||||
clkout-lr-asynchronous:
|
||||
description: audio_clkoutn is asynchronizes with lr-clock.
|
||||
|
@ -90,8 +90,8 @@ examples:
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ethernet-switch@0 {
|
||||
compatible = "micrel,ks8995m";
|
||||
display@0 {
|
||||
compatible = "lg,lg4573";
|
||||
spi-max-frequency = <1000000>;
|
||||
reg = <0>;
|
||||
};
|
||||
|
@ -181,22 +181,23 @@ additionalProperties: true
|
||||
|
||||
examples:
|
||||
- |
|
||||
spi@f00 {
|
||||
spi@80010000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
|
||||
reg = <0xf00 0x20>;
|
||||
interrupts = <2 13 0 2 14 0>;
|
||||
interrupt-parent = <&mpc5200_pic>;
|
||||
compatible = "fsl,imx28-spi";
|
||||
reg = <0x80010000 0x2000>;
|
||||
interrupts = <96>;
|
||||
dmas = <&dma_apbh 0>;
|
||||
dma-names = "rx-tx";
|
||||
|
||||
ethernet-switch@0 {
|
||||
compatible = "micrel,ks8995m";
|
||||
display@0 {
|
||||
compatible = "lg,lg4573";
|
||||
spi-max-frequency = <1000000>;
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
codec@1 {
|
||||
compatible = "ti,tlv320aic26";
|
||||
sensor@1 {
|
||||
compatible = "bosch,bme680";
|
||||
spi-max-frequency = <100000>;
|
||||
reg = <1>;
|
||||
};
|
||||
|
@ -75,16 +75,12 @@ examples:
|
||||
spi-flash@0 {
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
spi-max-frequency = <40000000>;
|
||||
};
|
||||
|
||||
spi-device@1 {
|
||||
compatible = "lineartechnology,ltc2488";
|
||||
sensor@1 {
|
||||
compatible = "bosch,bme680";
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
spi-max-frequency = <10000000>;
|
||||
};
|
||||
};
|
||||
|
@ -96,12 +96,6 @@ examples:
|
||||
dma-names = "rx", "tx";
|
||||
cs-gpios = <&gpioa 11 0>;
|
||||
|
||||
aardvark@0 {
|
||||
compatible = "totalphase,aardvark";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <4000000>;
|
||||
st,spi-midi-ns = <4000>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
|
@ -1,7 +1,7 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
==========================================
|
||||
Submitting devicetree (DT) binding patches
|
||||
Submitting Devicetree (DT) binding patches
|
||||
==========================================
|
||||
|
||||
I. For patch submitters
|
||||
@ -25,7 +25,7 @@ I. For patch submitters
|
||||
|
||||
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.
|
||||
|
||||
3) DT binding files should be dual licensed. The preferred license tag is
|
||||
@ -84,7 +84,7 @@ II. For kernel maintainers
|
||||
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
|
||||
decided at the 2013 Kernel Summit. When in doubt, the current word of the
|
||||
|
@ -59,7 +59,6 @@ patternProperties:
|
||||
|
||||
properties:
|
||||
reg:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Specify the sensor channel. There are 8 channels in PMIC5's ADC TM
|
||||
minimum: 0
|
||||
maximum: 7
|
||||
@ -78,7 +77,6 @@ patternProperties:
|
||||
also known as absolute calibration.
|
||||
|
||||
qcom,hw-settle-time-us:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
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]
|
||||
|
||||
|
@ -23,6 +23,9 @@ properties:
|
||||
maxItems: 1
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
spi-max-frequency: true
|
||||
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
|
@ -16,7 +16,6 @@ properties:
|
||||
pattern: "^usb(@.*)?"
|
||||
|
||||
phys:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
description:
|
||||
List of all the USB PHYs on this HCD
|
||||
|
||||
|
@ -57,6 +57,8 @@ patternProperties:
|
||||
description: Advantech Corporation
|
||||
"^aeroflexgaisler,.*":
|
||||
description: Aeroflex Gaisler AB
|
||||
"^aesop,.*":
|
||||
description: AESOP Embedded Forum
|
||||
"^al,.*":
|
||||
description: Annapurna Labs
|
||||
"^alcatel,.*":
|
||||
@ -1030,6 +1032,8 @@ patternProperties:
|
||||
description: Silergy Corp.
|
||||
"^silex-insight,.*":
|
||||
description: Silex Insight
|
||||
"^siliconfile,.*":
|
||||
description: Siliconfile Technologies lnc.
|
||||
"^siliconmitus,.*":
|
||||
description: Silicon Mitus, Inc.
|
||||
"^siemens,.*":
|
||||
@ -1282,6 +1286,8 @@ patternProperties:
|
||||
description: Yamaha Corporation
|
||||
"^yes-optoelectronics,.*":
|
||||
description: Yes Optoelectronics Co.,Ltd.
|
||||
"^yic,.*":
|
||||
description: YIC System Co., Ltd.
|
||||
"^ylm,.*":
|
||||
description: Shenzhen Yangliming Electronic Technology Co., Ltd.
|
||||
"^yna,.*":
|
||||
|
@ -1,6 +1,6 @@
|
||||
.. 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
|
||||
@ -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
|
||||
comments (Prefixed with '#').
|
||||
|
||||
Also see :ref:`example-schema`.
|
||||
|
||||
Schema Contents
|
||||
---------------
|
||||
|
||||
@ -46,12 +48,12 @@ select
|
||||
schema. By default without 'select', nodes are matched against their possible
|
||||
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
|
||||
include other schemas the binding conforms to. This may be schemas for a
|
||||
particular class of devices such as I2C or SPI controllers.
|
||||
|
||||
properties
|
||||
properties
|
||||
A set of sub-schema defining all the DT properties for the
|
||||
binding. The exact schema syntax depends on whether properties are known,
|
||||
common properties (e.g. 'interrupts') or are binding/vendor specific properties.
|
||||
@ -170,3 +172,12 @@ json-schema Resources
|
||||
`JSON-Schema Specifications <http://json-schema.org/>`_
|
||||
|
||||
`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
|
@ -1,10 +1,10 @@
|
||||
.. 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
|
||||
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
|
||||
|
@ -1,11 +1,11 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
==================================
|
||||
Device Tree Dynamic Resolver Notes
|
||||
==================================
|
||||
=================================
|
||||
Devicetree Dynamic Resolver Notes
|
||||
=================================
|
||||
|
||||
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
|
||||
----------------------
|
||||
|
@ -1,17 +1,30 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=============================
|
||||
Open Firmware and Device Tree
|
||||
Open Firmware and Devicetree
|
||||
=============================
|
||||
|
||||
Kernel Devicetree Usage
|
||||
=======================
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
usage-model
|
||||
writing-schema
|
||||
of_unittest
|
||||
kernel-api
|
||||
|
||||
Devicetree Overlays
|
||||
===================
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
changesets
|
||||
dynamic-resolution-notes
|
||||
of_unittest
|
||||
overlay-notes
|
||||
|
||||
Devicetree Bindings
|
||||
===================
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
bindings/index
|
||||
|
57
Documentation/devicetree/kernel-api.rst
Normal file
57
Documentation/devicetree/kernel-api.rst
Normal file
@ -0,0 +1,57 @@
|
||||
.. 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:
|
@ -1,8 +1,8 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
==================================
|
||||
Open Firmware Device Tree Unittest
|
||||
==================================
|
||||
=================================
|
||||
Open Firmware Devicetree Unittest
|
||||
=================================
|
||||
|
||||
Author: Gaurav Minocha <gaurav.minocha.os@gmail.com>
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=========================
|
||||
Device Tree Overlay Notes
|
||||
=========================
|
||||
========================
|
||||
Devicetree Overlay Notes
|
||||
========================
|
||||
|
||||
This document describes the implementation of the in-kernel
|
||||
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]
|
||||
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
|
||||
is reflecting the changes.
|
||||
Since the kernel mainly deals with devices, any new device node that result
|
||||
|
@ -1,8 +1,8 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=========================
|
||||
Linux and the Device Tree
|
||||
=========================
|
||||
========================
|
||||
Linux and the Devicetree
|
||||
========================
|
||||
|
||||
The Linux usage model for device tree data
|
||||
|
||||
@ -14,7 +14,7 @@ at devicetree.org\ [1]_.
|
||||
|
||||
.. [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
|
||||
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
|
||||
|
@ -1113,6 +1113,7 @@ config KEXEC
|
||||
config KEXEC_FILE
|
||||
bool "kexec file based system call"
|
||||
select KEXEC_CORE
|
||||
select HAVE_IMA_KEXEC if IMA
|
||||
help
|
||||
This is new version of kexec system call. This system call is
|
||||
file based and takes file descriptors as system call argument
|
||||
|
@ -96,10 +96,6 @@ struct kimage_arch {
|
||||
void *dtb;
|
||||
phys_addr_t dtb_mem;
|
||||
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
|
||||
|
@ -15,23 +15,12 @@
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.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[] = {
|
||||
&kexec_image_ops,
|
||||
@ -40,174 +29,16 @@ const struct kexec_file_ops * const kexec_file_loaders[] = {
|
||||
|
||||
int arch_kimage_file_post_load_cleanup(struct kimage *image)
|
||||
{
|
||||
vfree(image->arch.dtb);
|
||||
kvfree(image->arch.dtb);
|
||||
image->arch.dtb = NULL;
|
||||
|
||||
vfree(image->arch.elf_headers);
|
||||
image->arch.elf_headers = NULL;
|
||||
image->arch.elf_headers_sz = 0;
|
||||
vfree(image->elf_headers);
|
||||
image->elf_headers = NULL;
|
||||
image->elf_headers_sz = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
struct crash_mem *cmem;
|
||||
@ -284,12 +115,12 @@ int load_other_segments(struct kimage *image,
|
||||
vfree(headers);
|
||||
goto out_err;
|
||||
}
|
||||
image->arch.elf_headers = headers;
|
||||
image->arch.elf_headers_mem = kbuf.mem;
|
||||
image->arch.elf_headers_sz = headers_sz;
|
||||
image->elf_headers = headers;
|
||||
image->elf_load_addr = kbuf.mem;
|
||||
image->elf_headers_sz = headers_sz;
|
||||
|
||||
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 */
|
||||
@ -314,12 +145,15 @@ int load_other_segments(struct kimage *image,
|
||||
}
|
||||
|
||||
/* load dtb */
|
||||
ret = create_dtb(image, initrd_load_addr, initrd_len, cmdline, &dtb);
|
||||
if (ret) {
|
||||
dtb = of_kexec_alloc_and_setup_fdt(image, initrd_load_addr,
|
||||
initrd_len, cmdline, 0);
|
||||
if (!dtb) {
|
||||
pr_err("Preparing for new dtb failed\n");
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
/* trim it */
|
||||
fdt_pack(dtb);
|
||||
dtb_len = fdt_totalsize(dtb);
|
||||
kbuf.buffer = dtb;
|
||||
kbuf.bufsz = dtb_len;
|
||||
@ -343,6 +177,6 @@ int load_other_segments(struct kimage *image,
|
||||
|
||||
out_err:
|
||||
image->nr_segments = orig_segments;
|
||||
vfree(dtb);
|
||||
kvfree(dtb);
|
||||
return ret;
|
||||
}
|
||||
|
@ -548,7 +548,7 @@ config KEXEC
|
||||
config KEXEC_FILE
|
||||
bool "kexec file based system call"
|
||||
select KEXEC_CORE
|
||||
select HAVE_IMA_KEXEC
|
||||
select HAVE_IMA_KEXEC if IMA
|
||||
select BUILD_BIN2C
|
||||
select KEXEC_ELF
|
||||
depends on PPC64
|
||||
|
@ -1,30 +0,0 @@
|
||||
/* 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 {
|
||||
|
||||
unsigned long backup_start;
|
||||
void *backup_buf;
|
||||
|
||||
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
|
||||
void *fdt;
|
||||
};
|
||||
|
||||
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,
|
||||
const void *fdt, unsigned long kernel_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
|
||||
struct kexec_buf;
|
||||
@ -136,7 +124,7 @@ int load_crashdump_segments_ppc64(struct kimage *image,
|
||||
int setup_purgatory_ppc64(struct kimage *image, const void *slave_code,
|
||||
const void *fdt, unsigned long kernel_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,
|
||||
unsigned long initrd_load_addr,
|
||||
unsigned long initrd_len, const char *cmdline);
|
||||
|
@ -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
|
||||
|
||||
ifdef CONFIG_HAVE_IMA_KEXEC
|
||||
ifdef CONFIG_IMA
|
||||
obj-y += ima.o
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
# Disable GCOV, KCOV & sanitizers in odd or sensitive code
|
||||
GCOV_PROFILE_core_$(BITS).o := n
|
||||
KCOV_INSTRUMENT_core_$(BITS).o := n
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
@ -29,7 +30,6 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
|
||||
unsigned long cmdline_len)
|
||||
{
|
||||
int ret;
|
||||
unsigned int fdt_size;
|
||||
unsigned long kernel_load_addr;
|
||||
unsigned long initrd_load_addr = 0, fdt_load_addr;
|
||||
void *fdt;
|
||||
@ -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);
|
||||
if (ret)
|
||||
goto out;
|
||||
return ERR_PTR(ret);
|
||||
|
||||
if (image->type == KEXEC_TYPE_CRASH) {
|
||||
/* min & max buffer values for kdump case */
|
||||
@ -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);
|
||||
}
|
||||
|
||||
fdt_size = kexec_fdt_totalsize_ppc64(image);
|
||||
fdt = kmalloc(fdt_size, GFP_KERNEL);
|
||||
fdt = of_kexec_alloc_and_setup_fdt(image, initrd_load_addr,
|
||||
initrd_len, cmdline,
|
||||
kexec_extra_fdt_size_ppc64(image));
|
||||
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");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
@ -119,18 +114,22 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
|
||||
ret = setup_new_fdt_ppc64(image, fdt, initrd_load_addr,
|
||||
initrd_len, cmdline);
|
||||
if (ret)
|
||||
goto out;
|
||||
goto out_free_fdt;
|
||||
|
||||
fdt_pack(fdt);
|
||||
|
||||
kbuf.buffer = fdt;
|
||||
kbuf.bufsz = kbuf.memsz = fdt_size;
|
||||
kbuf.bufsz = kbuf.memsz = fdt_totalsize(fdt);
|
||||
kbuf.buf_align = PAGE_SIZE;
|
||||
kbuf.top_down = true;
|
||||
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
|
||||
ret = kexec_add_buffer(&kbuf);
|
||||
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;
|
||||
|
||||
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,
|
||||
if (ret)
|
||||
pr_err("Error setting up the purgatory.\n");
|
||||
|
||||
goto out;
|
||||
|
||||
out_free_fdt:
|
||||
kvfree(fdt);
|
||||
out:
|
||||
kfree(modified_cmdline);
|
||||
kexec_free_elf_info(&elf_info);
|
||||
|
||||
/* Make kimage_file_post_load_cleanup free the fdt buffer for us. */
|
||||
return ret ? ERR_PTR(ret) : fdt;
|
||||
return ret ? ERR_PTR(ret) : NULL;
|
||||
}
|
||||
|
||||
const struct kexec_file_ops kexec_elf64_ops = {
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/ima.h>
|
||||
|
||||
#define SLAVE_CODE_SIZE 256 /* First 0x100 bytes */
|
||||
|
||||
@ -45,7 +44,7 @@ char *setup_kdump_cmdline(struct kimage *image, char *cmdline,
|
||||
return NULL;
|
||||
|
||||
elfcorehdr_strlen = sprintf(cmdline_ptr, "elfcorehdr=0x%lx ",
|
||||
image->arch.elfcorehdr_addr);
|
||||
image->elf_load_addr);
|
||||
|
||||
if (elfcorehdr_strlen + cmdline_len > COMMAND_LINE_SIZE) {
|
||||
pr_err("Appending elfcorehdr=<addr> exceeds cmdline size\n");
|
||||
@ -108,183 +107,3 @@ int setup_purgatory(struct kimage *image, const void *slave_code,
|
||||
|
||||
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)
|
||||
goto out;
|
||||
}
|
||||
|
||||
image->arch.elfcorehdr_addr = kbuf->mem;
|
||||
image->arch.elf_headers_sz = headers_sz;
|
||||
image->arch.elf_headers = headers;
|
||||
image->elf_load_addr = kbuf->mem;
|
||||
image->elf_headers_sz = headers_sz;
|
||||
image->elf_headers = headers;
|
||||
out:
|
||||
kfree(cmem);
|
||||
return ret;
|
||||
@ -852,7 +852,7 @@ int load_crashdump_segments_ppc64(struct kimage *image,
|
||||
return ret;
|
||||
}
|
||||
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;
|
||||
}
|
||||
@ -927,37 +927,27 @@ out:
|
||||
}
|
||||
|
||||
/**
|
||||
* kexec_fdt_totalsize_ppc64 - Return the estimated size needed to setup FDT
|
||||
* for kexec/kdump kernel.
|
||||
* @image: kexec image being loaded.
|
||||
* kexec_extra_fdt_size_ppc64 - Return the estimated additional size needed to
|
||||
* setup FDT for kexec/kdump kernel.
|
||||
* @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;
|
||||
|
||||
/*
|
||||
* 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)
|
||||
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
|
||||
* number of usable memory entries and use for FDT size estimation.
|
||||
*/
|
||||
usm_entries = ((memblock_end_of_DRAM() / drmem_lmb_size()) +
|
||||
(2 * (resource_size(&crashk_res) / drmem_lmb_size())));
|
||||
fdt_size += (unsigned int)(usm_entries * sizeof(u64));
|
||||
|
||||
return fdt_size;
|
||||
return (unsigned int)(usm_entries * sizeof(u64));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -979,10 +969,6 @@ int setup_new_fdt_ppc64(const struct kimage *image, void *fdt,
|
||||
struct crash_mem *umem = NULL, *rmem = NULL;
|
||||
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
|
||||
* usable memory ranges and memory reserve map.
|
||||
@ -1142,9 +1128,12 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
|
||||
vfree(image->arch.backup_buf);
|
||||
image->arch.backup_buf = NULL;
|
||||
|
||||
vfree(image->arch.elf_headers);
|
||||
image->arch.elf_headers = NULL;
|
||||
image->arch.elf_headers_sz = 0;
|
||||
vfree(image->elf_headers);
|
||||
image->elf_headers = NULL;
|
||||
image->elf_headers_sz = 0;
|
||||
|
||||
kvfree(image->arch.fdt);
|
||||
image->arch.fdt = NULL;
|
||||
|
||||
return kexec_image_post_load_cleanup_default(image);
|
||||
}
|
||||
|
@ -1,219 +0,0 @@
|
||||
// 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 {
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
|
||||
/* Core ELF header buffer */
|
||||
void *elf_headers;
|
||||
unsigned long elf_headers_sz;
|
||||
unsigned long elf_load_addr;
|
||||
};
|
||||
#endif /* CONFIG_X86_32 */
|
||||
|
||||
|
@ -323,8 +323,8 @@ static int memmap_exclude_ranges(struct kimage *image, struct crash_mem *cmem,
|
||||
cmem->nr_ranges = 1;
|
||||
|
||||
/* Exclude elf header region */
|
||||
start = image->arch.elf_load_addr;
|
||||
end = start + image->arch.elf_headers_sz - 1;
|
||||
start = image->elf_load_addr;
|
||||
end = start + image->elf_headers_sz - 1;
|
||||
return crash_exclude_mem_range(cmem, start, end);
|
||||
}
|
||||
|
||||
@ -407,20 +407,20 @@ int crash_load_segments(struct kimage *image)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
image->arch.elf_headers = kbuf.buffer;
|
||||
image->arch.elf_headers_sz = kbuf.bufsz;
|
||||
image->elf_headers = kbuf.buffer;
|
||||
image->elf_headers_sz = kbuf.bufsz;
|
||||
|
||||
kbuf.memsz = kbuf.bufsz;
|
||||
kbuf.buf_align = ELF_CORE_HEADER_ALIGN;
|
||||
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
|
||||
ret = kexec_add_buffer(&kbuf);
|
||||
if (ret) {
|
||||
vfree((void *)image->arch.elf_headers);
|
||||
vfree((void *)image->elf_headers);
|
||||
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",
|
||||
image->arch.elf_load_addr, kbuf.bufsz, kbuf.bufsz);
|
||||
image->elf_load_addr, kbuf.bufsz, kbuf.bufsz);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ static int setup_cmdline(struct kimage *image, struct boot_params *params,
|
||||
|
||||
if (image->type == KEXEC_TYPE_CRASH) {
|
||||
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);
|
||||
cmdline_len += len;
|
||||
|
@ -402,8 +402,8 @@ void machine_kexec(struct kimage *image)
|
||||
#ifdef CONFIG_KEXEC_FILE
|
||||
void *arch_kexec_kernel_image_load(struct kimage *image)
|
||||
{
|
||||
vfree(image->arch.elf_headers);
|
||||
image->arch.elf_headers = NULL;
|
||||
vfree(image->elf_headers);
|
||||
image->elf_headers = NULL;
|
||||
|
||||
if (!image->fops || !image->fops->load)
|
||||
return ERR_PTR(-ENOEXEC);
|
||||
|
@ -14,4 +14,10 @@ obj-$(CONFIG_OF_RESOLVE) += resolver.o
|
||||
obj-$(CONFIG_OF_OVERLAY) += overlay.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/
|
||||
|
@ -117,9 +117,12 @@ static unsigned int of_bus_pci_get_flags(const __be32 *addr)
|
||||
flags |= IORESOURCE_IO;
|
||||
break;
|
||||
case 0x02: /* 32 bits */
|
||||
case 0x03: /* 64 bits */
|
||||
flags |= IORESOURCE_MEM;
|
||||
break;
|
||||
|
||||
case 0x03: /* 64 bits */
|
||||
flags |= IORESOURCE_MEM | IORESOURCE_MEM_64;
|
||||
break;
|
||||
}
|
||||
if (w & 0x40000000)
|
||||
flags |= IORESOURCE_PREFETCH;
|
||||
@ -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
|
||||
* @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
|
||||
* the physical address can't be internally converted to an IO token with
|
||||
|
@ -244,7 +244,7 @@ struct device_node *__of_find_all_nodes(struct device_node *prev)
|
||||
* @prev: Previous node or NULL to start iteration
|
||||
* of_node_put() will be called on it
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* Return: A node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_all_nodes(struct device_node *prev)
|
||||
@ -305,7 +305,7 @@ bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
|
||||
return (u32)phys_id == cpu;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Checks if the given "prop_name" property holds the physical id of the
|
||||
* core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not
|
||||
* NULL, local thread number within the core is returned in it.
|
||||
@ -374,7 +374,7 @@ bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun,
|
||||
* before booting secondary cores. This function uses arch_match_cpu_phys_id
|
||||
* which can be overridden by architecture specific implementation.
|
||||
*
|
||||
* Returns a node pointer for the logical cpu with refcount incremented, use
|
||||
* Return: A node pointer for the logical cpu with refcount incremented, use
|
||||
* of_node_put() on it when done. Returns NULL if not found.
|
||||
*/
|
||||
struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
|
||||
@ -394,8 +394,8 @@ EXPORT_SYMBOL(of_get_cpu_node);
|
||||
*
|
||||
* @cpu_node: Pointer to the device_node for CPU.
|
||||
*
|
||||
* Returns the logical CPU number of the given CPU device_node.
|
||||
* Returns -ENODEV if the CPU is not found.
|
||||
* Return: The logical CPU number of the given CPU device_node or -ENODEV if the
|
||||
* CPU is not found.
|
||||
*/
|
||||
int of_cpu_node_to_id(struct device_node *cpu_node)
|
||||
{
|
||||
@ -427,7 +427,7 @@ EXPORT_SYMBOL(of_cpu_node_to_id);
|
||||
* bindings. This function check for both and returns the idle state node for
|
||||
* the requested index.
|
||||
*
|
||||
* In case an idle state node is found at @index, the refcount is incremented
|
||||
* Return: An idle state node if found at @index. The refcount is incremented
|
||||
* for it, so call of_node_put() on it when done. Returns NULL if not found.
|
||||
*/
|
||||
struct device_node *of_get_cpu_state_node(struct device_node *cpu_node,
|
||||
@ -561,7 +561,7 @@ int of_device_compatible_match(struct device_node *device,
|
||||
* of_machine_is_compatible - Test root of device tree for a given compatible value
|
||||
* @compat: compatible string to look for in root node's compatible property.
|
||||
*
|
||||
* Returns a positive integer if the root node has the given value in its
|
||||
* Return: A positive integer if the root node has the given value in its
|
||||
* compatible property.
|
||||
*/
|
||||
int of_machine_is_compatible(const char *compat)
|
||||
@ -583,7 +583,7 @@ EXPORT_SYMBOL(of_machine_is_compatible);
|
||||
*
|
||||
* @device: Node to check for availability, with locks already held
|
||||
*
|
||||
* Returns true if the status property is absent or set to "okay" or "ok",
|
||||
* Return: True if the status property is absent or set to "okay" or "ok",
|
||||
* false otherwise
|
||||
*/
|
||||
static bool __of_device_is_available(const struct device_node *device)
|
||||
@ -611,7 +611,7 @@ static bool __of_device_is_available(const struct device_node *device)
|
||||
*
|
||||
* @device: Node to check for availability
|
||||
*
|
||||
* Returns true if the status property is absent or set to "okay" or "ok",
|
||||
* Return: True if the status property is absent or set to "okay" or "ok",
|
||||
* false otherwise
|
||||
*/
|
||||
bool of_device_is_available(const struct device_node *device)
|
||||
@ -632,7 +632,7 @@ EXPORT_SYMBOL(of_device_is_available);
|
||||
*
|
||||
* @device: Node to check for endianness
|
||||
*
|
||||
* Returns true if the device has a "big-endian" property, or if the kernel
|
||||
* Return: True if the device has a "big-endian" property, or if the kernel
|
||||
* was compiled for BE *and* the device has a "native-endian" property.
|
||||
* Returns false otherwise.
|
||||
*
|
||||
@ -651,11 +651,11 @@ bool of_device_is_big_endian(const struct device_node *device)
|
||||
EXPORT_SYMBOL(of_device_is_big_endian);
|
||||
|
||||
/**
|
||||
* of_get_parent - Get a node's parent if any
|
||||
* @node: Node to get parent
|
||||
* of_get_parent - Get a node's parent if any
|
||||
* @node: Node to get parent
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
* Return: A node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_get_parent(const struct device_node *node)
|
||||
{
|
||||
@ -673,15 +673,15 @@ struct device_node *of_get_parent(const struct device_node *node)
|
||||
EXPORT_SYMBOL(of_get_parent);
|
||||
|
||||
/**
|
||||
* of_get_next_parent - Iterate to a node's parent
|
||||
* @node: Node to get parent of
|
||||
* of_get_next_parent - Iterate to a node's parent
|
||||
* @node: Node to get parent of
|
||||
*
|
||||
* This is like of_get_parent() except that it drops the
|
||||
* refcount on the passed node, making it suitable for iterating
|
||||
* through a node's parents.
|
||||
* This is like of_get_parent() except that it drops the
|
||||
* refcount on the passed node, making it suitable for iterating
|
||||
* through a node's parents.
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
* Return: A node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_get_next_parent(struct device_node *node)
|
||||
{
|
||||
@ -719,13 +719,13 @@ static struct device_node *__of_get_next_child(const struct device_node *node,
|
||||
child = __of_get_next_child(parent, child))
|
||||
|
||||
/**
|
||||
* of_get_next_child - Iterate a node childs
|
||||
* @node: parent node
|
||||
* @prev: previous child of the parent node, or NULL to get first
|
||||
* of_get_next_child - Iterate a node childs
|
||||
* @node: parent node
|
||||
* @prev: previous child of the parent node, or NULL to get first
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use of_node_put() on
|
||||
* it when done. Returns NULL when prev is the last child. Decrements the
|
||||
* refcount of prev.
|
||||
* Return: A node pointer with refcount incremented, use of_node_put() on
|
||||
* it when done. Returns NULL when prev is the last child. Decrements the
|
||||
* refcount of prev.
|
||||
*/
|
||||
struct device_node *of_get_next_child(const struct device_node *node,
|
||||
struct device_node *prev)
|
||||
@ -741,12 +741,12 @@ struct device_node *of_get_next_child(const struct device_node *node,
|
||||
EXPORT_SYMBOL(of_get_next_child);
|
||||
|
||||
/**
|
||||
* of_get_next_available_child - Find the next available child node
|
||||
* @node: parent node
|
||||
* @prev: previous child of the parent node, or NULL to get first
|
||||
* of_get_next_available_child - Find the next available child node
|
||||
* @node: parent node
|
||||
* @prev: previous child of the parent node, or NULL to get first
|
||||
*
|
||||
* This function is like of_get_next_child(), except that it
|
||||
* automatically skips any disabled nodes (i.e. status = "disabled").
|
||||
* This function is like of_get_next_child(), except that it
|
||||
* automatically skips any disabled nodes (i.e. status = "disabled").
|
||||
*/
|
||||
struct device_node *of_get_next_available_child(const struct device_node *node,
|
||||
struct device_node *prev)
|
||||
@ -772,12 +772,12 @@ struct device_node *of_get_next_available_child(const struct device_node *node,
|
||||
EXPORT_SYMBOL(of_get_next_available_child);
|
||||
|
||||
/**
|
||||
* of_get_next_cpu_node - Iterate on cpu nodes
|
||||
* @prev: previous child of the /cpus node, or NULL to get first
|
||||
* of_get_next_cpu_node - Iterate on cpu nodes
|
||||
* @prev: previous child of the /cpus node, or NULL to get first
|
||||
*
|
||||
* Returns a cpu node pointer with refcount incremented, use of_node_put()
|
||||
* on it when done. Returns NULL when prev is the last child. Decrements
|
||||
* the refcount of prev.
|
||||
* Return: A cpu node pointer with refcount incremented, use of_node_put()
|
||||
* on it when done. Returns NULL when prev is the last child. Decrements
|
||||
* the refcount of prev.
|
||||
*/
|
||||
struct device_node *of_get_next_cpu_node(struct device_node *prev)
|
||||
{
|
||||
@ -816,7 +816,7 @@ EXPORT_SYMBOL(of_get_next_cpu_node);
|
||||
* Lookup child node whose compatible property contains the given compatible
|
||||
* string.
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use of_node_put() on it
|
||||
* Return: a node pointer with refcount incremented, use of_node_put() on it
|
||||
* when done; or NULL if not found.
|
||||
*/
|
||||
struct device_node *of_get_compatible_child(const struct device_node *parent,
|
||||
@ -834,15 +834,15 @@ struct device_node *of_get_compatible_child(const struct device_node *parent,
|
||||
EXPORT_SYMBOL(of_get_compatible_child);
|
||||
|
||||
/**
|
||||
* of_get_child_by_name - Find the child node by name for a given parent
|
||||
* @node: parent node
|
||||
* @name: child name to look for.
|
||||
* of_get_child_by_name - Find the child node by name for a given parent
|
||||
* @node: parent node
|
||||
* @name: child name to look for.
|
||||
*
|
||||
* This function looks for child node for given matching name
|
||||
* This function looks for child node for given matching name
|
||||
*
|
||||
* Returns a node pointer if found, with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
* Returns NULL if node is not found.
|
||||
* Return: A node pointer if found, with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
* Returns NULL if node is not found.
|
||||
*/
|
||||
struct device_node *of_get_child_by_name(const struct device_node *node,
|
||||
const char *name)
|
||||
@ -893,22 +893,22 @@ struct device_node *__of_find_node_by_full_path(struct device_node *node,
|
||||
}
|
||||
|
||||
/**
|
||||
* of_find_node_opts_by_path - Find a node matching a full OF path
|
||||
* @path: Either the full path to match, or if the path does not
|
||||
* start with '/', the name of a property of the /aliases
|
||||
* node (an alias). In the case of an alias, the node
|
||||
* matching the alias' value will be returned.
|
||||
* @opts: Address of a pointer into which to store the start of
|
||||
* an options string appended to the end of the path with
|
||||
* a ':' separator.
|
||||
* of_find_node_opts_by_path - Find a node matching a full OF path
|
||||
* @path: Either the full path to match, or if the path does not
|
||||
* start with '/', the name of a property of the /aliases
|
||||
* node (an alias). In the case of an alias, the node
|
||||
* matching the alias' value will be returned.
|
||||
* @opts: Address of a pointer into which to store the start of
|
||||
* an options string appended to the end of the path with
|
||||
* a ':' separator.
|
||||
*
|
||||
* Valid paths:
|
||||
* /foo/bar Full path
|
||||
* foo Valid alias
|
||||
* foo/bar Valid alias + relative path
|
||||
* Valid paths:
|
||||
* * /foo/bar Full path
|
||||
* * foo Valid alias
|
||||
* * foo/bar Valid alias + relative path
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
* Return: A node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_node_opts_by_path(const char *path, const char **opts)
|
||||
{
|
||||
@ -958,15 +958,15 @@ struct device_node *of_find_node_opts_by_path(const char *path, const char **opt
|
||||
EXPORT_SYMBOL(of_find_node_opts_by_path);
|
||||
|
||||
/**
|
||||
* of_find_node_by_name - Find a node by its "name" property
|
||||
* @from: The node to start searching from or NULL; the node
|
||||
* of_find_node_by_name - Find a node by its "name" property
|
||||
* @from: The node to start searching from or NULL; the node
|
||||
* you pass will not be searched, only the next one
|
||||
* will. Typically, you pass what the previous call
|
||||
* returned. of_node_put() will be called on @from.
|
||||
* @name: The name string to match against
|
||||
* @name: The name string to match against
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
* Return: A node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_node_by_name(struct device_node *from,
|
||||
const char *name)
|
||||
@ -985,16 +985,16 @@ struct device_node *of_find_node_by_name(struct device_node *from,
|
||||
EXPORT_SYMBOL(of_find_node_by_name);
|
||||
|
||||
/**
|
||||
* of_find_node_by_type - Find a node by its "device_type" property
|
||||
* @from: The node to start searching from, or NULL to start searching
|
||||
* of_find_node_by_type - Find a node by its "device_type" property
|
||||
* @from: The node to start searching from, or NULL to start searching
|
||||
* the entire device tree. The node you pass will not be
|
||||
* searched, only the next one will; typically, you pass
|
||||
* what the previous call returned. of_node_put() will be
|
||||
* called on from for you.
|
||||
* @type: The type string to match against
|
||||
* @type: The type string to match against
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
* Return: A node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_node_by_type(struct device_node *from,
|
||||
const char *type)
|
||||
@ -1013,18 +1013,18 @@ struct device_node *of_find_node_by_type(struct device_node *from,
|
||||
EXPORT_SYMBOL(of_find_node_by_type);
|
||||
|
||||
/**
|
||||
* of_find_compatible_node - Find a node based on type and one of the
|
||||
* of_find_compatible_node - Find a node based on type and one of the
|
||||
* tokens in its "compatible" property
|
||||
* @from: The node to start searching from or NULL, the node
|
||||
* you pass will not be searched, only the next one
|
||||
* will; typically, you pass what the previous call
|
||||
* returned. of_node_put() will be called on it
|
||||
* @type: The type string to match "device_type" or NULL to ignore
|
||||
* @compatible: The string to match to one of the tokens in the device
|
||||
* "compatible" list.
|
||||
* @from: The node to start searching from or NULL, the node
|
||||
* you pass will not be searched, only the next one
|
||||
* will; typically, you pass what the previous call
|
||||
* returned. of_node_put() will be called on it
|
||||
* @type: The type string to match "device_type" or NULL to ignore
|
||||
* @compatible: The string to match to one of the tokens in the device
|
||||
* "compatible" list.
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
* Return: A node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_compatible_node(struct device_node *from,
|
||||
const char *type, const char *compatible)
|
||||
@ -1044,16 +1044,16 @@ struct device_node *of_find_compatible_node(struct device_node *from,
|
||||
EXPORT_SYMBOL(of_find_compatible_node);
|
||||
|
||||
/**
|
||||
* of_find_node_with_property - Find a node which has a property with
|
||||
* the given name.
|
||||
* @from: The node to start searching from or NULL, the node
|
||||
* you pass will not be searched, only the next one
|
||||
* will; typically, you pass what the previous call
|
||||
* returned. of_node_put() will be called on it
|
||||
* @prop_name: The name of the property to look for.
|
||||
* of_find_node_with_property - Find a node which has a property with
|
||||
* the given name.
|
||||
* @from: The node to start searching from or NULL, the node
|
||||
* you pass will not be searched, only the next one
|
||||
* will; typically, you pass what the previous call
|
||||
* returned. of_node_put() will be called on it
|
||||
* @prop_name: The name of the property to look for.
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
* Return: A node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_node_with_property(struct device_node *from,
|
||||
const char *prop_name)
|
||||
@ -1102,10 +1102,10 @@ const struct of_device_id *__of_match_node(const struct of_device_id *matches,
|
||||
|
||||
/**
|
||||
* of_match_node - Tell if a device_node has a matching of_match structure
|
||||
* @matches: array of of device match structures to search in
|
||||
* @node: the of device structure to match against
|
||||
* @matches: array of of device match structures to search in
|
||||
* @node: the of device structure to match against
|
||||
*
|
||||
* Low level utility function used by device matching.
|
||||
* Low level utility function used by device matching.
|
||||
*/
|
||||
const struct of_device_id *of_match_node(const struct of_device_id *matches,
|
||||
const struct device_node *node)
|
||||
@ -1121,17 +1121,17 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches,
|
||||
EXPORT_SYMBOL(of_match_node);
|
||||
|
||||
/**
|
||||
* of_find_matching_node_and_match - Find a node based on an of_device_id
|
||||
* match table.
|
||||
* @from: The node to start searching from or NULL, the node
|
||||
* you pass will not be searched, only the next one
|
||||
* will; typically, you pass what the previous call
|
||||
* returned. of_node_put() will be called on it
|
||||
* @matches: array of of device match structures to search in
|
||||
* @match Updated to point at the matches entry which matched
|
||||
* of_find_matching_node_and_match - Find a node based on an of_device_id
|
||||
* match table.
|
||||
* @from: The node to start searching from or NULL, the node
|
||||
* you pass will not be searched, only the next one
|
||||
* will; typically, you pass what the previous call
|
||||
* returned. of_node_put() will be called on it
|
||||
* @matches: array of of device match structures to search in
|
||||
* @match: Updated to point at the matches entry which matched
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
* Return: A node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_matching_node_and_match(struct device_node *from,
|
||||
const struct of_device_id *matches,
|
||||
@ -1170,7 +1170,7 @@ EXPORT_SYMBOL(of_find_matching_node_and_match);
|
||||
* It does this by stripping the manufacturer prefix (as delimited by a ',')
|
||||
* from the first entry in the compatible list property.
|
||||
*
|
||||
* This routine returns 0 on success, <0 on failure.
|
||||
* Return: This routine returns 0 on success, <0 on failure.
|
||||
*/
|
||||
int of_modalias_node(struct device_node *node, char *modalias, int len)
|
||||
{
|
||||
@ -1190,7 +1190,7 @@ EXPORT_SYMBOL_GPL(of_modalias_node);
|
||||
* of_find_node_by_phandle - Find a node given a phandle
|
||||
* @handle: phandle of the node to find
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* Return: A node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_node_by_phandle(phandle handle)
|
||||
@ -1426,7 +1426,7 @@ static int __of_parse_phandle_with_args(const struct device_node *np,
|
||||
* @index: For properties holding a table of phandles, this is the index into
|
||||
* the table
|
||||
*
|
||||
* Returns the device_node pointer with refcount incremented. Use
|
||||
* Return: The device_node pointer with refcount incremented. Use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_parse_phandle(const struct device_node *np,
|
||||
@ -1460,21 +1460,21 @@ EXPORT_SYMBOL(of_parse_phandle);
|
||||
* Caller is responsible to call of_node_put() on the returned out_args->np
|
||||
* pointer.
|
||||
*
|
||||
* Example:
|
||||
* Example::
|
||||
*
|
||||
* phandle1: node1 {
|
||||
* phandle1: node1 {
|
||||
* #list-cells = <2>;
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* phandle2: node2 {
|
||||
* phandle2: node2 {
|
||||
* #list-cells = <1>;
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* node3 {
|
||||
* node3 {
|
||||
* list = <&phandle1 1 2 &phandle2 3>;
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* To get a device_node of the `node2' node you may call this:
|
||||
* To get a device_node of the ``node2`` node you may call this:
|
||||
* of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
|
||||
*/
|
||||
int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
|
||||
@ -1512,29 +1512,29 @@ EXPORT_SYMBOL(of_parse_phandle_with_args);
|
||||
* Caller is responsible to call of_node_put() on the returned out_args->np
|
||||
* pointer.
|
||||
*
|
||||
* Example:
|
||||
* Example::
|
||||
*
|
||||
* phandle1: node1 {
|
||||
* #list-cells = <2>;
|
||||
* }
|
||||
* phandle1: node1 {
|
||||
* #list-cells = <2>;
|
||||
* };
|
||||
*
|
||||
* phandle2: node2 {
|
||||
* #list-cells = <1>;
|
||||
* }
|
||||
* phandle2: node2 {
|
||||
* #list-cells = <1>;
|
||||
* };
|
||||
*
|
||||
* phandle3: node3 {
|
||||
* #list-cells = <1>;
|
||||
* list-map = <0 &phandle2 3>,
|
||||
* <1 &phandle2 2>,
|
||||
* <2 &phandle1 5 1>;
|
||||
* list-map-mask = <0x3>;
|
||||
* };
|
||||
* phandle3: node3 {
|
||||
* #list-cells = <1>;
|
||||
* list-map = <0 &phandle2 3>,
|
||||
* <1 &phandle2 2>,
|
||||
* <2 &phandle1 5 1>;
|
||||
* list-map-mask = <0x3>;
|
||||
* };
|
||||
*
|
||||
* node4 {
|
||||
* list = <&phandle1 1 2 &phandle3 0>;
|
||||
* }
|
||||
* node4 {
|
||||
* list = <&phandle1 1 2 &phandle3 0>;
|
||||
* };
|
||||
*
|
||||
* To get a device_node of the `node2' node you may call this:
|
||||
* To get a device_node of the ``node2`` node you may call this:
|
||||
* of_parse_phandle_with_args(node4, "list", "list", 1, &args);
|
||||
*/
|
||||
int of_parse_phandle_with_args_map(const struct device_node *np,
|
||||
@ -1694,19 +1694,19 @@ EXPORT_SYMBOL(of_parse_phandle_with_args_map);
|
||||
* Caller is responsible to call of_node_put() on the returned out_args->np
|
||||
* pointer.
|
||||
*
|
||||
* Example:
|
||||
* Example::
|
||||
*
|
||||
* phandle1: node1 {
|
||||
* }
|
||||
* phandle1: node1 {
|
||||
* };
|
||||
*
|
||||
* phandle2: node2 {
|
||||
* }
|
||||
* phandle2: node2 {
|
||||
* };
|
||||
*
|
||||
* node3 {
|
||||
* list = <&phandle1 0 2 &phandle2 2 3>;
|
||||
* }
|
||||
* node3 {
|
||||
* list = <&phandle1 0 2 &phandle2 2 3>;
|
||||
* };
|
||||
*
|
||||
* To get a device_node of the `node2' node you may call this:
|
||||
* To get a device_node of the ``node2`` node you may call this:
|
||||
* of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args);
|
||||
*/
|
||||
int of_parse_phandle_with_fixed_args(const struct device_node *np,
|
||||
@ -1726,7 +1726,7 @@ EXPORT_SYMBOL(of_parse_phandle_with_fixed_args);
|
||||
* @list_name: property name that contains a list
|
||||
* @cells_name: property name that specifies phandles' arguments count
|
||||
*
|
||||
* Returns the number of phandle + argument tuples within a property. It
|
||||
* Return: The number of phandle + argument tuples within a property. It
|
||||
* is a typical pattern to encode a list of phandle and variable
|
||||
* arguments into a single property. The number of arguments is encoded
|
||||
* by a property in the phandle-target node. For example, a gpios
|
||||
@ -1774,6 +1774,8 @@ EXPORT_SYMBOL(of_count_phandle_with_args);
|
||||
|
||||
/**
|
||||
* __of_add_property - Add a property to a node without lock operations
|
||||
* @np: Caller's Device Node
|
||||
* @prop: Property to add
|
||||
*/
|
||||
int __of_add_property(struct device_node *np, struct property *prop)
|
||||
{
|
||||
@ -1795,6 +1797,8 @@ int __of_add_property(struct device_node *np, struct property *prop)
|
||||
|
||||
/**
|
||||
* of_add_property - Add a property to a node
|
||||
* @np: Caller's Device Node
|
||||
* @prop: Property to add
|
||||
*/
|
||||
int of_add_property(struct device_node *np, struct property *prop)
|
||||
{
|
||||
@ -1839,6 +1843,8 @@ int __of_remove_property(struct device_node *np, struct property *prop)
|
||||
|
||||
/**
|
||||
* of_remove_property - Remove a property from a node.
|
||||
* @np: Caller's Device Node
|
||||
* @prop: Property to remove
|
||||
*
|
||||
* Note that we don't actually remove it, since we have given out
|
||||
* who-knows-how-many pointers to the data using get-property.
|
||||
@ -1946,13 +1952,12 @@ static void of_alias_add(struct alias_prop *ap, struct device_node *np,
|
||||
|
||||
/**
|
||||
* of_alias_scan - Scan all properties of the 'aliases' node
|
||||
* @dt_alloc: An allocator that provides a virtual address to memory
|
||||
* for storing the resulting tree
|
||||
*
|
||||
* The function scans all the properties of the 'aliases' node and populates
|
||||
* the global lookup table with the properties. It returns the
|
||||
* number of alias properties found, or an error code in case of failure.
|
||||
*
|
||||
* @dt_alloc: An allocator that provides a virtual address to memory
|
||||
* for storing the resulting tree
|
||||
*/
|
||||
void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
|
||||
{
|
||||
@ -2021,7 +2026,9 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
|
||||
* @stem: Alias stem of the given device_node
|
||||
*
|
||||
* The function travels the lookup table to get the alias id for the given
|
||||
* device_node and alias stem. It returns the alias id if found.
|
||||
* device_node and alias stem.
|
||||
*
|
||||
* Return: The alias id if found.
|
||||
*/
|
||||
int of_alias_get_id(struct device_node *np, const char *stem)
|
||||
{
|
||||
@ -2125,13 +2132,14 @@ EXPORT_SYMBOL_GPL(of_alias_get_highest_id);
|
||||
|
||||
/**
|
||||
* of_console_check() - Test and setup console for DT setup
|
||||
* @dn - Pointer to device node
|
||||
* @name - Name to use for preferred console without index. ex. "ttyS"
|
||||
* @index - Index to use for preferred console.
|
||||
* @dn: Pointer to device node
|
||||
* @name: Name to use for preferred console without index. ex. "ttyS"
|
||||
* @index: Index to use for preferred console.
|
||||
*
|
||||
* Check if the given device node matches the stdout-path property in the
|
||||
* /chosen node. If it does then register it as the preferred console and return
|
||||
* TRUE. Otherwise return FALSE.
|
||||
* /chosen node. If it does then register it as the preferred console.
|
||||
*
|
||||
* Return: TRUE if console successfully setup. Otherwise return FALSE.
|
||||
*/
|
||||
bool of_console_check(struct device_node *dn, char *name, int index)
|
||||
{
|
||||
@ -2147,12 +2155,12 @@ bool of_console_check(struct device_node *dn, char *name, int index)
|
||||
EXPORT_SYMBOL_GPL(of_console_check);
|
||||
|
||||
/**
|
||||
* of_find_next_cache_node - Find a node's subsidiary cache
|
||||
* @np: node of type "cpu" or "cache"
|
||||
* of_find_next_cache_node - Find a node's subsidiary cache
|
||||
* @np: node of type "cpu" or "cache"
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done. Caller should hold a reference
|
||||
* to np.
|
||||
* Return: A node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done. Caller should hold a reference
|
||||
* to np.
|
||||
*/
|
||||
struct device_node *of_find_next_cache_node(const struct device_node *np)
|
||||
{
|
||||
@ -2182,7 +2190,7 @@ struct device_node *of_find_next_cache_node(const struct device_node *np)
|
||||
*
|
||||
* @cpu: cpu number(logical index) for which the last cache level is needed
|
||||
*
|
||||
* Returns the the level at which the last cache is present. It is exactly
|
||||
* Return: The the level at which the last cache is present. It is exactly
|
||||
* same as the total number of cache levels for the given logical cpu.
|
||||
*/
|
||||
int of_find_last_cache_level(unsigned int cpu)
|
||||
|
@ -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
|
||||
* @np: Pointer to OF node having DMA configuration
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
@ -275,6 +278,8 @@ EXPORT_SYMBOL_GPL(of_device_modalias);
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
|
@ -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
|
||||
* callers
|
||||
*
|
||||
* Returns node.
|
||||
* Return: The node with refcount incremented.
|
||||
*/
|
||||
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)
|
||||
* @arg - argument of the of notifier
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
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)
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
@ -281,6 +283,7 @@ void __of_detach_node(struct device_node *np)
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
@ -318,7 +321,7 @@ static void property_list_free(struct property *prop_list)
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@ -372,7 +375,8 @@ void of_node_release(struct kobject *kobj)
|
||||
* property structure and the property name & contents. The property's
|
||||
* flags have the OF_DYNAMIC bit set so that we can differentiate between
|
||||
* 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)
|
||||
{
|
||||
@ -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
|
||||
* 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,
|
||||
const char *full_name)
|
||||
@ -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
|
||||
* success, like creation/destruction of devices and side-effects
|
||||
* 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.
|
||||
*/
|
||||
int of_changeset_apply(struct of_changeset *ocs)
|
||||
@ -875,7 +880,8 @@ static int __of_changeset_revert(struct of_changeset *ocs)
|
||||
* was before the application.
|
||||
* Any side-effects like creation/destruction of devices and
|
||||
* 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)
|
||||
{
|
||||
@ -903,7 +909,8 @@ EXPORT_SYMBOL_GPL(of_changeset_revert);
|
||||
* + OF_RECONFIG_ADD_PROPERTY
|
||||
* + OF_RECONFIG_REMOVE_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,
|
||||
struct device_node *np, struct property *prop)
|
||||
|
@ -282,7 +282,7 @@ static void reverse_nodes(struct device_node *parent)
|
||||
* @dad: Parent struct device_node
|
||||
* @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,
|
||||
void *mem,
|
||||
@ -351,11 +351,6 @@ static int unflatten_dt_nodes(const void *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
|
||||
* @dad: Parent device node
|
||||
* @mynodes: The device_node tree created by the call
|
||||
@ -363,7 +358,11 @@ static int unflatten_dt_nodes(const void *blob,
|
||||
* for the resulting tree
|
||||
* @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.
|
||||
*/
|
||||
void *__unflatten_device_tree(const void *blob,
|
||||
@ -452,7 +451,7 @@ static DEFINE_MUTEX(of_fdt_unflatten_mutex);
|
||||
* pointers of the nodes so the normal device-tree walking functions
|
||||
* 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.
|
||||
*/
|
||||
void *of_fdt_unflatten_tree(const unsigned long *blob,
|
||||
@ -480,7 +479,7 @@ void *initial_boot_params __ro_after_init;
|
||||
|
||||
static u32 of_fdt_crc32;
|
||||
|
||||
/**
|
||||
/*
|
||||
* __reserved_mem_reserve_reg() - reserve all memory described in 'reg' property
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* __reserved_mem_check_root() - check if #size-cells, #address-cells provided
|
||||
* in /reserved-memory matches the values supported by the current implementation,
|
||||
* also check if ranges property has been provided
|
||||
@ -549,8 +548,8 @@ static int __init __reserved_mem_check_root(unsigned long node)
|
||||
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,
|
||||
int depth, void *data)
|
||||
@ -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.
|
||||
* @parent: parent node
|
||||
* @it: callback function
|
||||
* @data: context data pointer
|
||||
*
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* of_get_flat_dt_root - find the root node in the flat blob
|
||||
*/
|
||||
unsigned long __init of_get_flat_dt_root(void)
|
||||
@ -707,7 +707,7 @@ unsigned long __init of_get_flat_dt_root(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* 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
|
||||
@ -726,7 +726,7 @@ const void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
|
||||
* @node: node to test
|
||||
* @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.
|
||||
*/
|
||||
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)
|
||||
return of_fdt_is_compatible(initial_boot_params, node, compat);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* 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)
|
||||
@ -781,8 +781,8 @@ static int __init of_flat_dt_match(unsigned long node, const char *const *compat
|
||||
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)
|
||||
{
|
||||
@ -957,7 +957,7 @@ int __init early_init_dt_scan_chosen_stdout(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
/*
|
||||
* 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,
|
||||
@ -993,7 +993,7 @@ u64 __init dt_mem_next_cell(int s, const __be32 **cellp)
|
||||
return of_read_number(p, s);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* early_init_dt_scan_memory - Look for and parse memory nodes
|
||||
*/
|
||||
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);
|
||||
* of_irq_find_parent - Given a device node, find its interrupt parent 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.
|
||||
*/
|
||||
struct device_node *of_irq_find_parent(struct device_node *child)
|
||||
@ -81,14 +81,14 @@ EXPORT_SYMBOL_GPL(of_irq_find_parent);
|
||||
* @addr: address specifier (start of "reg" property of the device) in be32 format
|
||||
* @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
|
||||
* can be used to do a partial walk with synthetized reg and interrupts
|
||||
* properties, for example when resolving PCI interrupts when no device
|
||||
* node exist for the parent. It takes an interrupt specifier structure as
|
||||
* input, walks the tree looking for any interrupt-map properties, translates
|
||||
* 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)
|
||||
{
|
||||
@ -380,7 +380,7 @@ EXPORT_SYMBOL_GPL(of_irq_to_resource);
|
||||
* @dev: pointer to device tree node
|
||||
* @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
|
||||
* of any other failure.
|
||||
*/
|
||||
@ -407,7 +407,7 @@ EXPORT_SYMBOL_GPL(of_irq_get);
|
||||
* @dev: pointer to device tree node
|
||||
* @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
|
||||
* of any other failure.
|
||||
*/
|
||||
@ -447,7 +447,7 @@ int of_irq_count(struct device_node *dev)
|
||||
* @res: array of resources to fill in
|
||||
* @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 nr_irqs)
|
||||
@ -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"
|
||||
* 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)
|
||||
{
|
||||
|
458
drivers/of/kexec.c
Normal file
458
drivers/of/kexec.c
Normal file
@ -0,0 +1,458 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2020 Arm Limited
|
||||
*
|
||||
* Based on arch/arm64/kernel/machine_kexec_file.c:
|
||||
* Copyright (C) 2018 Linaro Limited
|
||||
*
|
||||
* And arch/powerpc/kexec/file_load.c:
|
||||
* Copyright (C) 2016 IBM Corporation
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/types.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
|
||||
|
||||
/*
|
||||
* Additional space needed for the FDT buffer so that we can add initrd,
|
||||
* bootargs, kaslr-seed, rng-seed, useable-memory-range and elfcorehdr.
|
||||
*/
|
||||
#define FDT_EXTRA_SPACE 0x1000
|
||||
|
||||
/**
|
||||
* fdt_find_and_del_mem_rsv - delete memory reservation with given address and size
|
||||
*
|
||||
* @fdt: Flattened device tree for the current kernel.
|
||||
* @start: Starting address of the reserved memory.
|
||||
* @size: Size of the reserved memory.
|
||||
*
|
||||
* Return: 0 on success, or negative errno on error.
|
||||
*/
|
||||
static int fdt_find_and_del_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++) {
|
||||
u64 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_addr_size_cells - Get address and size of root node
|
||||
*
|
||||
* @addr_cells: Return address of the root node
|
||||
* @size_cells: Return size of the root node
|
||||
*
|
||||
* Return: 0 on success, or negative errno on error.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* do_get_kexec_buffer - Get address and size of device tree property
|
||||
*
|
||||
* @prop: Device tree property
|
||||
* @len: Size of @prop
|
||||
* @addr: Return address of the node
|
||||
* @size: Return size of the node
|
||||
*
|
||||
* Return: 0 on success, or negative errno on error.
|
||||
*/
|
||||
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;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_HAVE_IMA_KEXEC))
|
||||
return -ENOTSUPP;
|
||||
|
||||
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;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_HAVE_IMA_KEXEC))
|
||||
return -ENOTSUPP;
|
||||
|
||||
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
|
||||
*
|
||||
* @fdt: Flattened Device Tree to update
|
||||
* @chosen_node: Offset to the chosen node in the device tree
|
||||
*
|
||||
* The IMA measurement buffer is of no use to a subsequent kernel, so we always
|
||||
* remove it from the device tree.
|
||||
*/
|
||||
static void remove_ima_buffer(void *fdt, int chosen_node)
|
||||
{
|
||||
int ret, len;
|
||||
unsigned long addr;
|
||||
size_t size;
|
||||
const void *prop;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_HAVE_IMA_KEXEC))
|
||||
return;
|
||||
|
||||
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 = fdt_find_and_del_mem_rsv(fdt, addr, size);
|
||||
if (!ret)
|
||||
pr_debug("Removed old IMA buffer reservation.\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IMA_KEXEC
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
static int setup_ima_buffer(const struct kimage *image, void *fdt,
|
||||
int chosen_node)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!image->ima_buffer_size)
|
||||
return 0;
|
||||
|
||||
ret = fdt_appendprop_addrrange(fdt, 0, chosen_node,
|
||||
"linux,ima-kexec-buffer",
|
||||
image->ima_buffer_addr,
|
||||
image->ima_buffer_size);
|
||||
if (ret < 0)
|
||||
return -EINVAL;
|
||||
|
||||
ret = fdt_add_mem_rsv(fdt, image->ima_buffer_addr,
|
||||
image->ima_buffer_size);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
pr_debug("IMA buffer at 0x%llx, size = 0x%zx\n",
|
||||
image->ima_buffer_addr, image->ima_buffer_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else /* CONFIG_IMA_KEXEC */
|
||||
static inline int setup_ima_buffer(const struct kimage *image, void *fdt,
|
||||
int chosen_node)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_IMA_KEXEC */
|
||||
|
||||
/*
|
||||
* of_kexec_alloc_and_setup_fdt - Alloc and setup a new Flattened Device Tree
|
||||
*
|
||||
* @image: kexec image being loaded.
|
||||
* @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.
|
||||
* @extra_fdt_size: Additional size for the new FDT buffer.
|
||||
*
|
||||
* Return: fdt on success, or NULL errno on error.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
void *fdt;
|
||||
int ret, chosen_node;
|
||||
const void *prop;
|
||||
size_t fdt_size;
|
||||
|
||||
fdt_size = fdt_totalsize(initial_boot_params) +
|
||||
(cmdline ? strlen(cmdline) : 0) +
|
||||
FDT_EXTRA_SPACE +
|
||||
extra_fdt_size;
|
||||
fdt = kvmalloc(fdt_size, GFP_KERNEL);
|
||||
if (!fdt)
|
||||
return NULL;
|
||||
|
||||
ret = fdt_open_into(initial_boot_params, fdt, fdt_size);
|
||||
if (ret < 0) {
|
||||
pr_err("Error %d setting up the new device tree.\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Remove memory reservation for the current device tree. */
|
||||
ret = fdt_find_and_del_mem_rsv(fdt, __pa(initial_boot_params),
|
||||
fdt_totalsize(initial_boot_params));
|
||||
if (ret == -EINVAL) {
|
||||
pr_err("Error removing memory reservation.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
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) {
|
||||
ret = chosen_node;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = fdt_delprop(fdt, chosen_node, FDT_PROP_KEXEC_ELFHDR);
|
||||
if (ret && ret != -FDT_ERR_NOTFOUND)
|
||||
goto out;
|
||||
ret = fdt_delprop(fdt, chosen_node, FDT_PROP_MEM_RANGE);
|
||||
if (ret && ret != -FDT_ERR_NOTFOUND)
|
||||
goto out;
|
||||
|
||||
/* Did we boot using an initrd? */
|
||||
prop = fdt_getprop(fdt, chosen_node, "linux,initrd-start", NULL);
|
||||
if (prop) {
|
||||
u64 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) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
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 = fdt_find_and_del_mem_rsv(fdt, tmp_start, tmp_size);
|
||||
if (ret == -ENOENT)
|
||||
ret = fdt_find_and_del_mem_rsv(fdt, tmp_start,
|
||||
round_up(tmp_size, PAGE_SIZE));
|
||||
if (ret == -EINVAL)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* add initrd-* */
|
||||
if (initrd_load_addr) {
|
||||
ret = fdt_setprop_u64(fdt, chosen_node, FDT_PROP_INITRD_START,
|
||||
initrd_load_addr);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = fdt_setprop_u64(fdt, chosen_node, FDT_PROP_INITRD_END,
|
||||
initrd_load_addr + initrd_len);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = fdt_add_mem_rsv(fdt, initrd_load_addr, initrd_len);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
} else {
|
||||
ret = fdt_delprop(fdt, chosen_node, FDT_PROP_INITRD_START);
|
||||
if (ret && (ret != -FDT_ERR_NOTFOUND))
|
||||
goto out;
|
||||
|
||||
ret = fdt_delprop(fdt, chosen_node, FDT_PROP_INITRD_END);
|
||||
if (ret && (ret != -FDT_ERR_NOTFOUND))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (image->type == KEXEC_TYPE_CRASH) {
|
||||
/* add linux,elfcorehdr */
|
||||
ret = fdt_appendprop_addrrange(fdt, 0, chosen_node,
|
||||
FDT_PROP_KEXEC_ELFHDR,
|
||||
image->elf_load_addr,
|
||||
image->elf_headers_sz);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Avoid elfcorehdr from being stomped on in kdump kernel by
|
||||
* setting up memory reserve map.
|
||||
*/
|
||||
ret = fdt_add_mem_rsv(fdt, image->elf_load_addr,
|
||||
image->elf_headers_sz);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* add linux,usable-memory-range */
|
||||
ret = fdt_appendprop_addrrange(fdt, 0, chosen_node,
|
||||
FDT_PROP_MEM_RANGE,
|
||||
crashk_res.start,
|
||||
crashk_res.end - crashk_res.start + 1);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* add bootargs */
|
||||
if (cmdline) {
|
||||
ret = fdt_setprop_string(fdt, chosen_node, FDT_PROP_BOOTARGS, cmdline);
|
||||
if (ret)
|
||||
goto out;
|
||||
} else {
|
||||
ret = fdt_delprop(fdt, chosen_node, FDT_PROP_BOOTARGS);
|
||||
if (ret && (ret != -FDT_ERR_NOTFOUND))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* add kaslr-seed */
|
||||
ret = fdt_delprop(fdt, chosen_node, 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(fdt, chosen_node, 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(fdt, chosen_node, 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);
|
||||
}
|
||||
|
||||
ret = fdt_setprop(fdt, chosen_node, "linux,booted-from-kexec", NULL, 0);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
remove_ima_buffer(fdt, chosen_node);
|
||||
ret = setup_ima_buffer(image, fdt, fdt_path_offset(fdt, "/chosen"));
|
||||
|
||||
out:
|
||||
if (ret) {
|
||||
kvfree(fdt);
|
||||
fdt = NULL;
|
||||
}
|
||||
|
||||
return fdt;
|
||||
}
|
@ -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
|
||||
* 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,
|
||||
|
@ -45,7 +45,7 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
|
||||
return memblock_reserve(base, size);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* 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,
|
||||
@ -67,7 +67,7 @@ void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname,
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* __reserved_mem_alloc_size() - allocate reserved memory described by
|
||||
* 'size', 'alignment' and 'alloc-ranges' properties.
|
||||
*/
|
||||
@ -164,7 +164,7 @@ static int __init __reserved_mem_alloc_size(unsigned long node,
|
||||
static const struct of_device_id __rmem_of_table_sentinel
|
||||
__used __section("__reservedmem_of_table_end");
|
||||
|
||||
/**
|
||||
/*
|
||||
* __reserved_mem_init_node() - call region specific reserved memory init code
|
||||
*/
|
||||
static int __init __reserved_mem_init_node(struct reserved_mem *rmem)
|
||||
|
@ -140,7 +140,7 @@ int of_overlay_notifier_register(struct notifier_block *nb)
|
||||
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
|
||||
*/
|
||||
int of_overlay_notifier_unregister(struct notifier_block *nb)
|
||||
@ -298,7 +298,7 @@ err_free_target_path:
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
static int build_changeset_next_level(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
|
||||
* 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)
|
||||
{
|
||||
@ -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
|
||||
* 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[].
|
||||
*/
|
||||
static int build_changeset(struct overlay_changeset *ovcs)
|
||||
@ -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
|
||||
* 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.
|
||||
*/
|
||||
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) {
|
||||
of_node_put(fragment->overlay);
|
||||
ret = -EINVAL;
|
||||
of_node_put(node);
|
||||
goto err_free_fragments;
|
||||
}
|
||||
|
||||
@ -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
|
||||
* 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.
|
||||
*/
|
||||
int of_overlay_remove(int *ovcs_id)
|
||||
@ -1264,7 +1265,7 @@ EXPORT_SYMBOL_GPL(of_overlay_remove);
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
|
@ -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
|
||||
* 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)
|
||||
{
|
||||
@ -160,7 +160,7 @@ EXPORT_SYMBOL(of_device_alloc);
|
||||
* @platform_data: pointer to populate platform_data pointer with
|
||||
* @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.
|
||||
*/
|
||||
static struct platform_device *of_platform_device_create_pdata(
|
||||
@ -204,7 +204,7 @@ err_clear_flag:
|
||||
* @bus_id: name to assign 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.
|
||||
*/
|
||||
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,
|
||||
}
|
||||
#endif /* CONFIG_ARM_AMBA */
|
||||
|
||||
/**
|
||||
/*
|
||||
* 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,
|
||||
@ -463,7 +463,7 @@ EXPORT_SYMBOL(of_platform_bus_probe);
|
||||
* New board support should be using this function instead of
|
||||
* 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,
|
||||
const struct of_device_id *matches,
|
||||
@ -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
|
||||
* 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)
|
||||
{
|
||||
|
@ -61,9 +61,11 @@ EXPORT_SYMBOL(of_graph_is_present);
|
||||
* @elem_size: size of the individual element
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* size elem_size 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 elem_size and -ENODATA if
|
||||
* the property does not have a value.
|
||||
*/
|
||||
int of_property_count_elems_of_size(const struct device_node *np,
|
||||
const char *propname, int elem_size)
|
||||
@ -95,8 +97,9 @@ EXPORT_SYMBOL_GPL(of_property_count_elems_of_size);
|
||||
* @len: if !=NULL, actual length is written to here
|
||||
*
|
||||
* 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
|
||||
* exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
|
||||
*
|
||||
* 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
|
||||
* 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,
|
||||
* @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
|
||||
* 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
|
||||
* property data isn't large enough.
|
||||
*
|
||||
@ -161,7 +166,9 @@ EXPORT_SYMBOL_GPL(of_property_read_u32_index);
|
||||
* @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
|
||||
* 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
|
||||
* property data isn't large enough.
|
||||
*
|
||||
@ -196,12 +203,14 @@ EXPORT_SYMBOL_GPL(of_property_read_u64_index);
|
||||
* sz_min will be read.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* it.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
@ -244,12 +253,14 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u8_array);
|
||||
* sz_min will be read.
|
||||
*
|
||||
* 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
|
||||
* 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.
|
||||
* it.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
@ -292,7 +303,9 @@ EXPORT_SYMBOL_GPL(of_property_read_variable_u16_array);
|
||||
* sz_min will be read.
|
||||
*
|
||||
* 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
|
||||
* 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);
|
||||
* @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
|
||||
* 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
|
||||
* property data isn't large enough.
|
||||
*
|
||||
@ -366,7 +381,9 @@ EXPORT_SYMBOL_GPL(of_property_read_u64);
|
||||
* sz_min will be read.
|
||||
*
|
||||
* 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
|
||||
* 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);
|
||||
* return value is 0.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* within the length of the property data.
|
||||
* terminated string value (pointer to data, not a copy).
|
||||
*
|
||||
* 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
|
||||
* null-terminated within the length of the property data.
|
||||
*
|
||||
* The out_string pointer is modified only if a valid string can be decoded.
|
||||
*/
|
||||
@ -775,7 +793,7 @@ EXPORT_SYMBOL(of_graph_get_remote_port_parent);
|
||||
* @node: pointer to a local endpoint device_node
|
||||
*
|
||||
* Return: Remote port node associated with remote endpoint node linked
|
||||
* to @node. Use of_node_put() on it when done.
|
||||
* to @node. Use of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_graph_get_remote_port(const struct device_node *node)
|
||||
{
|
||||
@ -808,7 +826,7 @@ EXPORT_SYMBOL(of_graph_get_endpoint_count);
|
||||
* @endpoint: identifier (value of reg property) of the endpoint node
|
||||
*
|
||||
* Return: Remote device node associated with remote endpoint node linked
|
||||
* to @node. Use of_node_put() on it when done.
|
||||
* to @node. Use of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_graph_get_remote_node(const struct device_node *node,
|
||||
u32 port, u32 endpoint)
|
||||
@ -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.index: For properties holding a list of phandles, this is the
|
||||
* 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.
|
||||
*
|
||||
* Returns:
|
||||
@ -1363,7 +1381,6 @@ static const struct supplier_bindings of_supplier_bindings[] = {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @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)
|
||||
const struct supplier_bindings *s = of_supplier_bindings;
|
||||
unsigned int i = 0;
|
||||
bool matched = false;
|
||||
int ret = 0;
|
||||
|
||||
/* Do not stop at first failed link, link all available suppliers. */
|
||||
while (!matched && s->parse_prop) {
|
||||
@ -1410,7 +1426,7 @@ static int of_link_property(struct device_node *con_np, const char *prop_name)
|
||||
}
|
||||
s++;
|
||||
}
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int of_fwnode_add_links(struct fwnode_handle *fwnode)
|
||||
|
@ -38,3 +38,51 @@ DTC_FLAGS_testcases += -@
|
||||
|
||||
# suppress warnings about intentional errors
|
||||
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 @@
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
/*
|
||||
* 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";
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
#include "overlay_common.dtsi"
|
||||
|
91
drivers/of/unittest-data/overlay_common.dtsi
Normal file
91
drivers/of/unittest-data/overlay_common.dtsi
Normal file
@ -0,0 +1,91 @@
|
||||
// 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";
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
4
drivers/of/unittest-data/static_base_1.dts
Normal file
4
drivers/of/unittest-data/static_base_1.dts
Normal file
@ -0,0 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/dts-v1/;
|
||||
|
||||
#include "testcases_common.dtsi"
|
4
drivers/of/unittest-data/static_base_2.dts
Normal file
4
drivers/of/unittest-data/static_base_2.dts
Normal file
@ -0,0 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/dts-v1/;
|
||||
|
||||
#include "overlay_common.dtsi"
|
@ -2,19 +2,20 @@
|
||||
/dts-v1/;
|
||||
/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 {
|
||||
changeset {
|
||||
prop-update = "hello";
|
||||
prop-remove = "world";
|
||||
node-remove {
|
||||
};
|
||||
testcase-device2 {
|
||||
compatible = "testcase-device";
|
||||
interrupt-parent = <&test_intc2>;
|
||||
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"
|
||||
|
19
drivers/of/unittest-data/testcases_common.dtsi
Normal file
19
drivers/of/unittest-data/testcases_common.dtsi
Normal file
@ -0,0 +1,19 @@
|
||||
// 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 @@
|
||||
interrupts = <1>;
|
||||
};
|
||||
|
||||
testcase-device2 {
|
||||
compatible = "testcase-device";
|
||||
interrupt-parent = <&test_intc2>;
|
||||
interrupts = <1>; /* invalid specifier - too short */
|
||||
};
|
||||
/*
|
||||
* testcase data that intentionally results in an error is
|
||||
* located in testcases.dts instead of in this file so that the
|
||||
* static overlay apply tests will not include the error.
|
||||
*/
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -304,7 +304,15 @@ struct kimage {
|
||||
#ifdef CONFIG_IMA_KEXEC
|
||||
/* Virtual address of IMA measurement buffer for kexec syscall */
|
||||
void *ima_buffer;
|
||||
|
||||
phys_addr_t ima_buffer_addr;
|
||||
size_t ima_buffer_size;
|
||||
#endif
|
||||
|
||||
/* Core ELF header buffer */
|
||||
void *elf_headers;
|
||||
unsigned long elf_headers_sz;
|
||||
unsigned long elf_load_addr;
|
||||
};
|
||||
|
||||
/* kexec interface functions */
|
||||
|
@ -424,12 +424,14 @@ extern int of_detach_node(struct device_node *);
|
||||
* @sz: number of array elements to read
|
||||
*
|
||||
* 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,
|
||||
* -ENODATA if property does not have a value, and -EOVERFLOW if the
|
||||
* property data isn't large enough.
|
||||
* it.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
@ -454,12 +456,14 @@ static inline int of_property_read_u8_array(const struct device_node *np,
|
||||
* @sz: number of array elements to read
|
||||
*
|
||||
* 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,
|
||||
* -ENODATA if property does not have a value, and -EOVERFLOW if the
|
||||
* property data isn't large enough.
|
||||
* it.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
@ -485,7 +489,9 @@ static inline int of_property_read_u16_array(const struct device_node *np,
|
||||
* @sz: number of array elements to read
|
||||
*
|
||||
* 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
|
||||
* property data isn't large enough.
|
||||
*
|
||||
@ -513,7 +519,9 @@ static inline int of_property_read_u32_array(const struct device_node *np,
|
||||
* @sz: number of array elements to read
|
||||
*
|
||||
* 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
|
||||
* property data isn't large enough.
|
||||
*
|
||||
@ -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);
|
||||
|
||||
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 */
|
||||
|
||||
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
|
||||
* @propname: name of the property to be searched.
|
||||
*
|
||||
* 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
|
||||
* property does not have a value.
|
||||
*/
|
||||
@ -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.
|
||||
*
|
||||
* 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
|
||||
* property does not have a value.
|
||||
*/
|
||||
@ -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.
|
||||
*
|
||||
* 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
|
||||
* property does not have a value.
|
||||
*/
|
||||
@ -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.
|
||||
*
|
||||
* 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
|
||||
* property does not have a value.
|
||||
*/
|
||||
@ -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
|
||||
* 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,
|
||||
const char *propname, const char **out_strs,
|
||||
@ -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.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* within the length of the property data.
|
||||
* terminated string contain in it.
|
||||
*
|
||||
* Return: The number of strings on 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 within the length of the property data.
|
||||
*/
|
||||
static inline int of_property_count_strings(const struct device_node *np,
|
||||
const char *propname)
|
||||
@ -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.
|
||||
* @propname: name of the property to be searched.
|
||||
* @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.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* 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,
|
||||
* @propname: name of the property to be searched.
|
||||
*
|
||||
* 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,
|
||||
const char *propname)
|
||||
@ -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
|
||||
* @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)
|
||||
{
|
||||
return of_property_read_bool(np, "system-power-controller");
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Overlay support
|
||||
*/
|
||||
|
||||
|
@ -73,14 +73,26 @@ always-y += $(userprogs-always-y) $(userprogs-always-m)
|
||||
|
||||
# DTB
|
||||
# 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-$(CONFIG_OF_ALL_DTBS) += $(dtb-)
|
||||
|
||||
ifneq ($(CHECK_DTBS),)
|
||||
always-y += $(patsubst %.dtb,%.dt.yaml, $(dtb-y))
|
||||
always-y += $(patsubst %.dtbo,%.dt.yaml, $(dtb-y))
|
||||
always-$(CONFIG_OF_ALL_DTBS) += $(patsubst %.dtb,%.dt.yaml, $(dtb-))
|
||||
always-$(CONFIG_OF_ALL_DTBS) += $(patsubst %.dtbo,%.dt.yaml, $(dtb-))
|
||||
# Don't run schema checks for dtbs created by fdtoverlay as they don't
|
||||
# have corresponding dts files.
|
||||
dt-yaml-y := $(filter-out $(overlay-y),$(dtb-y))
|
||||
|
||||
always-y += $(patsubst %.dtb,%.dt.yaml, $(dt-yaml-y))
|
||||
always-y += $(patsubst %.dtbo,%.dt.yaml, $(dt-yaml-y))
|
||||
endif
|
||||
|
||||
# Add subdir path
|
||||
@ -338,13 +350,23 @@ $(obj)/%.dtb: $(src)/%.dts $(DTC) FORCE
|
||||
$(obj)/%.dtbo: $(src)/%.dts $(DTC) FORCE
|
||||
$(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_FLAGS ?= $(if $(DT_SCHEMA_FILES),,-m)
|
||||
DT_BINDING_DIR := Documentation/devicetree/bindings
|
||||
# DT_TMP_SCHEMA may be overridden from Documentation/devicetree/bindings/Makefile
|
||||
DT_TMP_SCHEMA ?= $(objtree)/$(DT_BINDING_DIR)/processed-schema.json
|
||||
|
||||
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
|
||||
$(call cmd_and_fixdep,dtc)
|
||||
|
@ -3245,7 +3245,7 @@ sub process {
|
||||
($line =~ /^new file mode\s*\d+\s*$/) &&
|
||||
($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
|
||||
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
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user