Devicetree updates for v6.13:

Bindings:
 
 - Enable dtc "interrupt_provider" warnings for binding examples.
   Fix the warnings in fsl,mu-msi and ti,sci-inta due to this.
 
 - Convert zii,rave-sp-wdt, zii,rave-sp-pwrbutton,  and
   altr,fpga-passive-serial to DT schema format
 
 - Add some documentation on the different forms of YAML text blocks
   which are a constant source of review comments
 
 - Fix some schema errors in constraints for arrays
 
 - Add compatibles for qcom,sar2130p-pdc and onnn,adt7462
 
 DT core:
 
 - Allow overlay kunit tests to run CONFIG_OF_OVERLAY=n
 
 - Add some warnings on deprecated address handling
 
 - Rework early_init_dt_scan() so the arch can pass in the phys address
   of the DTB as __pa() is not always valid to use. This fixes a warning
   for arm64 with kexec.
 
 - Add and use some new DT graph iterators for iterating over ports and
   endpoints
 
 - Rework reserved-memory handling to be sized dynamically for fixed
   regions
 
 - Optimize of_modalias() to avoid a strlen() call
 
 - Constify struct device_node and property pointers where ever possible
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEktVUI4SxYhzZyEuo+vtdtY28YcMFAmc7qaoACgkQ+vtdtY28
 YcN54g/+Ifz4hQTSWV+VBhihovMMPiQUdxZ+MfJfPnPcZ7NJzaTf+zqhZyS4wQou
 v0pdtyR0B1fCM/EvKaYD+1aTTAQFEIT5Dqac+9ePwqaYqSk+yCTxyzW9m+P3rTPV
 THo8SGRss7T+Rs+2WaUGxphTJItMGIRdbBvoqK+82EdKFXXKw2BSD8tlJTWwbTam
 9xkrpUzw7f4FvVY8vVhRyOd5i8/v+FH8D65DMIT6ME9zRn4MzKVzCg6udgYeCBld
 C2XbV+wnyewtjrN2IX+2uQ2mheb7yJu3AEI3iFR5x/sRrsSLpisxrUl38xOOpxrM
 XxYtHgE3omjagQ+y+L2PMthlKvhFrXVXIvhUH8xxje5z1Vyq3VMfiABkHlMpAnys
 5LY4xEhvqDkPNo65UmjMiHxGW/xtcKsmAZBOp+HLerZfCJIFvl380fi8mNg/Sjvz
 7ExCSpzCPsHASZg7QCTplU3BUtg+067Ch/k8Hsn/Og73Pqm3xH4IezQZKwweN9ZT
 LC6OQBI7C3Yt1hom9qgUcA4H4/aaPxTVV7i0DGuAKh8Lon6SaoX2yFpweUBgbsL/
 c9DIW4vbYBIGASxxUbHlNMKvPCKACKmpFXhsnH5Waj+VWSOwsJ8bjGpH8PfMKdFW
 dyJB/r94GqCGpCW7+FC1qGmXiQJGkCo89pKBVjSf4Kj45ht/76o=
 =NCYS
 -----END PGP SIGNATURE-----

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

Pull devicetree updates from Rob Herring:
 "Bindings:

   - Enable dtc "interrupt_provider" warnings for binding examples. Fix
     the warnings in fsl,mu-msi and ti,sci-inta due to this.

   - Convert zii,rave-sp-wdt, zii,rave-sp-pwrbutton, and
     altr,fpga-passive-serial to DT schema format

   - Add some documentation on the different forms of YAML text blocks
     which are a constant source of review comments

   - Fix some schema errors in constraints for arrays

   - Add compatibles for qcom,sar2130p-pdc and onnn,adt7462

  DT core:

   - Allow overlay kunit tests to run CONFIG_OF_OVERLAY=n

   - Add some warnings on deprecated address handling

   - Rework early_init_dt_scan() so the arch can pass in the phys
     address of the DTB as __pa() is not always valid to use. This fixes
     a warning for arm64 with kexec.

   - Add and use some new DT graph iterators for iterating over ports
     and endpoints

   - Rework reserved-memory handling to be sized dynamically for fixed
     regions

   - Optimize of_modalias() to avoid a strlen() call

   - Constify struct device_node and property pointers where ever
     possible"

* tag 'devicetree-for-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (36 commits)
  of: Allow overlay kunit tests to run CONFIG_OF_OVERLAY=n
  dt-bindings: interrupt-controller: qcom,pdc: Add SAR2130P compatible
  of/address: Rework bus matching to avoid warnings
  of: WARN on deprecated #address-cells/#size-cells handling
  of/fdt: Don't use default address cell sizes for address translation
  dt-bindings: Enable dtc "interrupt_provider" warnings
  of/fdt: add dt_phys arg to early_init_dt_scan and early_init_dt_verify
  dt-bindings: cache: qcom,llcc: Fix X1E80100 reg entries
  dt-bindings: watchdog: convert zii,rave-sp-wdt.txt to yaml format
  dt-bindings: input: convert zii,rave-sp-pwrbutton.txt to yaml
  media: xilinx-tpg: use new of_graph functions
  fbdev: omapfb: use new of_graph functions
  gpu: drm: omapdrm: use new of_graph functions
  ASoC: audio-graph-card2: use new of_graph functions
  ASoC: audio-graph-card: use new of_graph functions
  ASoC: test-component: use new of_graph functions
  of: property: use new of_graph functions
  of: property: add of_graph_get_next_port_endpoint()
  of: property: add of_graph_get_next_port()
  of: module: remove strlen() call in of_modalias()
  ...
This commit is contained in:
Linus Torvalds 2024-11-20 13:19:25 -08:00
commit e6de688e93
78 changed files with 790 additions and 487 deletions

View File

@ -56,7 +56,6 @@ DT_DOCS = $(patsubst $(srctree)/%,%,$(shell $(find_all_cmd)))
override DTC_FLAGS := \
-Wno-avoid_unnecessary_addr_size \
-Wno-graph_child_address \
-Wno-interrupt_provider \
-Wno-unique_unit_address \
-Wunique_unit_address_if_enabled

View File

@ -100,9 +100,8 @@ properties:
filter. Addresses in the filter window are directed to the M1 port. Other
addresses will go to the M0 port.
$ref: /schemas/types.yaml#/definitions/uint32-array
items:
minItems: 2
maxItems: 2
minItems: 2
maxItems: 2
arm,io-coherent:
description: indicates that the system is operating in an hardware

View File

@ -39,11 +39,11 @@ properties:
reg:
minItems: 2
maxItems: 9
maxItems: 10
reg-names:
minItems: 2
maxItems: 9
maxItems: 10
interrupts:
maxItems: 1
@ -134,7 +134,6 @@ allOf:
- qcom,qdu1000-llcc
- qcom,sc8180x-llcc
- qcom,sc8280xp-llcc
- qcom,x1e80100-llcc
then:
properties:
reg:
@ -160,6 +159,39 @@ allOf:
- const: llcc7_base
- const: llcc_broadcast_base
- if:
properties:
compatible:
contains:
enum:
- qcom,x1e80100-llcc
then:
properties:
reg:
items:
- description: LLCC0 base register region
- description: LLCC1 base register region
- description: LLCC2 base register region
- description: LLCC3 base register region
- description: LLCC4 base register region
- description: LLCC5 base register region
- description: LLCC6 base register region
- description: LLCC7 base register region
- description: LLCC broadcast base register region
- description: LLCC broadcast AND register region
reg-names:
items:
- const: llcc0_base
- const: llcc1_base
- const: llcc2_base
- const: llcc3_base
- const: llcc4_base
- const: llcc5_base
- const: llcc6_base
- const: llcc7_base
- const: llcc_broadcast_base
- const: llcc_broadcast_and_base
- if:
properties:
compatible:

View File

@ -32,10 +32,9 @@ properties:
The first item in the array is for channels 0-31, the second is for
channels 32-63, etc.
$ref: /schemas/types.yaml#/definitions/uint32-array
items:
minItems: 1
# Should be enough
maxItems: 255
minItems: 1
# Should be enough
maxItems: 255
dma-channels:
$ref: /schemas/types.yaml#/definitions/uint32

View File

@ -262,4 +262,5 @@ examples:
reg-names = "core", "aux";
interrupts = <10>;
interrupt-controller;
#interrupt-cells = <2>;
};

View File

@ -1,29 +0,0 @@
Altera Passive Serial SPI FPGA Manager
Altera FPGAs support a method of loading the bitstream over what is
referred to as "passive serial".
The passive serial link is not technically SPI, and might require extra
circuits in order to play nicely with other SPI slaves on the same bus.
See https://www.altera.com/literature/hb/cyc/cyc_c51013.pdf
Required properties:
- compatible: Must be one of the following:
"altr,fpga-passive-serial",
"altr,fpga-arria10-passive-serial"
- reg: SPI chip select of the FPGA
- nconfig-gpios: config pin (referred to as nCONFIG in the manual)
- nstat-gpios: status pin (referred to as nSTATUS in the manual)
Optional properties:
- confd-gpios: confd pin (referred to as CONF_DONE in the manual)
Example:
fpga: fpga@0 {
compatible = "altr,fpga-passive-serial";
spi-max-frequency = <20000000>;
reg = <0>;
nconfig-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>;
nstat-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>;
confd-gpios = <&gpio4 12 GPIO_ACTIVE_LOW>;
};

View File

@ -0,0 +1,74 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/fpga/altr,fpga-passive-serial.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Altera Passive Serial SPI FPGA Manager
maintainers:
- Fabio Estevam <festevam@denx.de>
description: |
Altera FPGAs support a method of loading the bitstream over what is
referred to as "passive serial".
The passive serial link is not technically SPI, and might require extra
circuits in order to play nicely with other SPI slaves on the same bus.
See https://www.altera.com/literature/hb/cyc/cyc_c51013.pdf
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
properties:
compatible:
enum:
- altr,fpga-passive-serial
- altr,fpga-arria10-passive-serial
spi-max-frequency:
maximum: 20000000
reg:
maxItems: 1
nconfig-gpios:
description:
Config pin (referred to as nCONFIG in the manual).
maxItems: 1
nstat-gpios:
description:
Status pin (referred to as nSTATUS in the manual).
maxItems: 1
confd-gpios:
description:
confd pin (referred to as CONF_DONE in the manual)
maxItems: 1
required:
- compatible
- reg
- nconfig-gpios
- nstat-gpios
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
fpga@0 {
compatible = "altr,fpga-passive-serial";
reg = <0>;
nconfig-gpios = <&gpio4 18 GPIO_ACTIVE_LOW>;
nstat-gpios = <&gpio4 19 GPIO_ACTIVE_LOW>;
confd-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
};
};
...

View File

@ -1,22 +0,0 @@
Zodiac Inflight Innovations RAVE Supervisory Processor Power Button Bindings
RAVE SP input device is a "MFD cell" device corresponding to power
button functionality of RAVE Supervisory Processor. It is expected
that its Device Tree node is specified as a child of the node
corresponding to the parent RAVE SP device (as documented in
Documentation/devicetree/bindings/mfd/zii,rave-sp.txt)
Required properties:
- compatible: Should be "zii,rave-sp-pwrbutton"
Example:
rave-sp {
compatible = "zii,rave-sp-rdu1";
current-speed = <38400>;
pwrbutton {
compatible = "zii,rave-sp-pwrbutton";
};
}

View File

@ -0,0 +1,36 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/input/zii,rave-sp-pwrbutton.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Zodiac Inflight Innovations RAVE Supervisory Processor Power Button
maintainers:
- Frank Li <Frank.li@nxp.com>
description:
RAVE SP input device is a "MFD cell" device corresponding to power
button functionality of RAVE Supervisory Processor. It is expected
that its Device Tree node is specified as a child of the node
corresponding to the parent RAVE SP device (as documented in
Documentation/devicetree/bindings/mfd/zii,rave-sp.yaml)
properties:
compatible:
const: zii,rave-sp-pwrbutton
required:
- compatible
allOf:
- $ref: input.yaml
unevaluatedProperties: false
examples:
- |
pwrbutton {
compatible = "zii,rave-sp-pwrbutton";
};

View File

@ -132,10 +132,9 @@ properties:
Address property. Base address of an alias of the GICD region containing
only the {SET,CLR}SPI registers to be used if isolation is required,
and if supported by the HW.
$ref: /schemas/types.yaml#/definitions/uint32-array
items:
minItems: 1
maxItems: 2
oneOf:
- $ref: /schemas/types.yaml#/definitions/uint32
- $ref: /schemas/types.yaml#/definitions/uint64
ppi-partitions:
type: object
@ -223,9 +222,8 @@ patternProperties:
(u32, u32) tuple describing the untranslated
address and size of the pre-ITS window.
$ref: /schemas/types.yaml#/definitions/uint32-array
items:
minItems: 2
maxItems: 2
minItems: 2
maxItems: 2
required:
- compatible

View File

@ -62,8 +62,6 @@ properties:
- const: processor-a-side
- const: processor-b-side
interrupt-controller: true
msi-controller: true
"#msi-cells":
@ -73,7 +71,6 @@ required:
- compatible
- reg
- interrupts
- interrupt-controller
- msi-controller
- "#msi-cells"
@ -88,7 +85,6 @@ examples:
compatible = "fsl,imx6sx-mu-msi";
msi-controller;
#msi-cells = <0>;
interrupt-controller;
reg = <0x5d270000 0x10000>, /* A side */
<0x5d300000 0x10000>; /* B side */
reg-names = "processor-a-side", "processor-b-side";

View File

@ -29,6 +29,7 @@ properties:
- qcom,qdu1000-pdc
- qcom,sa8255p-pdc
- qcom,sa8775p-pdc
- qcom,sar2130p-pdc
- qcom,sc7180-pdc
- qcom,sc7280-pdc
- qcom,sc8180x-pdc

View File

@ -109,6 +109,7 @@ examples:
compatible = "ti,sci-inta";
reg = <0x0 0x33d00000 0x0 0x100000>;
interrupt-controller;
#interrupt-cells = <0>;
msi-controller;
interrupt-parent = <&main_navss_intr>;
ti,sci = <&dmsc>;

View File

@ -135,8 +135,7 @@ properties:
data-lanes:
$ref: /schemas/media/video-interfaces.yaml#/properties/data-lanes
items:
maxItems: 4
maxItems: 4
description:
This property is for lane reordering between the THP7312 and the imaging
sensor that it is connected to.

View File

@ -66,9 +66,8 @@ patternProperties:
samsung,srom-timing:
$ref: /schemas/types.yaml#/definitions/uint32-array
items:
minItems: 6
maxItems: 6
minItems: 6
maxItems: 6
description: |
Array of 6 integers, specifying bank timings in the following order:
Tacp, Tcah, Tcoh, Tacc, Tcos, Tacs.

View File

@ -92,9 +92,8 @@ properties:
may have two component regions -- base and extended -- so
this information cannot be deduced from the dma-ranges.
$ref: /schemas/types.yaml#/definitions/uint64-array
items:
minItems: 1
maxItems: 3
minItems: 1
maxItems: 3
resets:
minItems: 1

View File

@ -55,8 +55,7 @@ properties:
qcom,smem:
$ref: /schemas/types.yaml#/definitions/uint32-array
items:
maxItems: 2
maxItems: 2
description:
Two identifiers of the inbound and outbound smem items used for this edge.

View File

@ -297,6 +297,8 @@ properties:
- nuvoton,w83773g
# OKI ML86V7667 video decoder
- oki,ml86v7667
# ON Semiconductor ADT7462 Temperature, Voltage Monitor and Fan Controller
- onnn,adt7462
# 48-Lane, 12-Port PCI Express Gen 2 (5.0 GT/s) Switch
- plx,pex8648
# Pulsedlight LIDAR range-finding sensor

View File

@ -1,39 +0,0 @@
Zodiac Inflight Innovations RAVE Supervisory Processor Watchdog Bindings
RAVE SP watchdog device is a "MFD cell" device corresponding to
watchdog functionality of RAVE Supervisory Processor. It is expected
that its Device Tree node is specified as a child of the node
corresponding to the parent RAVE SP device (as documented in
Documentation/devicetree/bindings/mfd/zii,rave-sp.txt)
Required properties:
- compatible: Depending on wire protocol implemented by RAVE SP
firmware, should be one of:
- "zii,rave-sp-watchdog"
- "zii,rave-sp-watchdog-legacy"
Optional properties:
- wdt-timeout: Two byte nvmem cell specified as per
Documentation/devicetree/bindings/nvmem/nvmem.txt
Example:
rave-sp {
compatible = "zii,rave-sp-rdu1";
current-speed = <38400>;
eeprom {
wdt_timeout: wdt-timeout@8E {
reg = <0x8E 2>;
};
};
watchdog {
compatible = "zii,rave-sp-watchdog";
nvmem-cells = <&wdt_timeout>;
nvmem-cell-names = "wdt-timeout";
};
}

View File

@ -0,0 +1,47 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/watchdog/zii,rave-sp-wdt.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Zodiac Inflight Innovations RAVE Supervisory Processor Watchdog
maintainers:
- Frank Li <Frank.Li@nxp.com>
description:
RAVE SP watchdog device is a "MFD cell" device corresponding to
watchdog functionality of RAVE Supervisory Processor. It is expected
that its Device Tree node is specified as a child of the node
corresponding to the parent RAVE SP device (as documented in
Documentation/devicetree/bindings/mfd/zii,rave-sp.yaml)
properties:
compatible:
enum:
- zii,rave-sp-watchdog
- zii,rave-sp-watchdog-legacy
nvmem-cell-names:
items:
- const: wdt_timeout
nvmem-cells:
maxItems: 1
required:
- compatible
allOf:
- $ref: watchdog.yaml#
unevaluatedProperties: false
examples:
- |
watchdog {
compatible = "zii,rave-sp-watchdog";
nvmem-cells = <&wdt_timeout>;
nvmem-cell-names = "wdt_timeout";
};

View File

@ -43,6 +43,36 @@ description
or device does, standards the device conforms to, and links to datasheets for
more information.
The YAML format has several options for defining the formatting of the text
block. The options are controlled with indicator characters following the key
(e.g. "description: \|"). The minimum formatting needed for a block should be
used. The formatting controls can not only affect whether the YAML can be
parsed correctly, but are important when the text blocks are rendered to
another form. The options are as follows.
The default without any indicators is flowed, plain scalar style where single
line breaks and leading whitespace are stripped. Paragraphs are delimited by
blank lines (i.e. double line break). This style cannot contain ": " in it as
it will be interpretted as a key. Any " #" sequence will be interpretted as
a comment. There's other restrictions on characters as well. Most
restrictions are on what the first character can be.
The second style is folded which is indicated by ">" character. In addition
to maintaining line breaks on double line breaks, the folded style also
maintains leading whitespace beyond indentation of the first line. The line
breaks on indented lines are also maintained.
The third style is literal which is indicated by "\|" character. The literal
style maintains all line breaks and whitespace (beyond indentation of the
first line).
The above is not a complete description of YAML text blocks. More details on
multi-line YAML text blocks can be found online:
https://yaml-multiline.info/
https://www.yaml.info/learn/quote.html
select
Optional. A json-schema used to match nodes for applying the
schema. By default, without 'select', nodes are matched against their possible

View File

@ -62,7 +62,7 @@ const struct machine_desc * __init setup_machine_fdt(void *dt)
const struct machine_desc *mdesc;
unsigned long dt_root;
if (!early_init_dt_scan(dt))
if (!early_init_dt_scan(dt, __pa(dt)))
return NULL;
mdesc = of_flat_dt_match_machine(NULL, arch_get_next_mach);

View File

@ -200,7 +200,7 @@ const struct machine_desc * __init setup_machine_fdt(void *dt_virt)
mdesc_best = &__mach_desc_GENERIC_DT;
if (!dt_virt || !early_init_dt_verify(dt_virt))
if (!dt_virt || !early_init_dt_verify(dt_virt, __pa(dt_virt)))
return NULL;
mdesc = of_flat_dt_match_machine(mdesc_best, arch_get_next_mach);

View File

@ -176,7 +176,11 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
if (dt_virt)
memblock_reserve(dt_phys, size);
if (!dt_virt || !early_init_dt_scan(dt_virt)) {
/*
* dt_virt is a fixmap address, hence __pa(dt_virt) can't be used.
* Pass dt_phys directly.
*/
if (!early_init_dt_scan(dt_virt, dt_phys)) {
pr_crit("\n"
"Error: invalid device tree blob at physical address %pa (virtual address 0x%px)\n"
"The dtb must be 8-byte aligned and must not exceed 2 MB in size\n"

View File

@ -112,9 +112,9 @@ asmlinkage __visible void __init csky_start(unsigned int unused,
pre_trap_init();
if (dtb_start == NULL)
early_init_dt_scan(__dtb_start);
early_init_dt_scan(__dtb_start, __pa(dtb_start));
else
early_init_dt_scan(dtb_start);
early_init_dt_scan(dtb_start, __pa(dtb_start));
start_kernel();

View File

@ -291,7 +291,7 @@ static void __init fdt_setup(void)
if (!fdt_pointer || fdt_check_header(fdt_pointer))
return;
early_init_dt_scan(fdt_pointer);
early_init_dt_scan(fdt_pointer, __pa(fdt_pointer));
early_init_fdt_reserve_self();
max_low_pfn = PFN_PHYS(memblock_end_of_DRAM());

View File

@ -18,7 +18,7 @@ void __init early_init_devtree(void *params)
{
pr_debug(" -> early_init_devtree(%p)\n", params);
early_init_dt_scan(params);
early_init_dt_scan(params, __pa(params));
if (!strlen(boot_command_line))
strscpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);

View File

@ -41,7 +41,7 @@ char *mips_get_machine_name(void)
void __init __dt_setup_arch(void *bph)
{
if (!early_init_dt_scan(bph))
if (!early_init_dt_scan(bph, __pa(bph)))
return;
mips_set_machine_name(of_flat_dt_get_machine_name());

View File

@ -337,7 +337,7 @@ void *__init relocate_kernel(void)
#if defined(CONFIG_USE_OF)
/* Deal with the device tree */
fdt = plat_get_fdt();
early_init_dt_scan(fdt);
early_init_dt_scan(fdt, __pa(fdt));
if (boot_command_line[0]) {
/* Boot command line was passed in device tree */
strscpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);

View File

@ -27,7 +27,7 @@ void __init early_init_devtree(void *params)
if (be32_to_cpup((__be32 *)CONFIG_NIOS2_DTB_PHYS_ADDR) ==
OF_DT_HEADER) {
params = (void *)CONFIG_NIOS2_DTB_PHYS_ADDR;
early_init_dt_scan(params);
early_init_dt_scan(params, __pa(params));
return;
}
#endif
@ -37,5 +37,5 @@ void __init early_init_devtree(void *params)
params = (void *)__dtb_start;
#endif
early_init_dt_scan(params);
early_init_dt_scan(params, __pa(params));
}

View File

@ -22,6 +22,6 @@
void __init early_init_devtree(void *params)
{
early_init_dt_scan(params);
early_init_dt_scan(params, __pa(params));
memblock_allow_resize();
}

View File

@ -867,7 +867,7 @@ bool __init dt_cpu_ftrs_init(void *fdt)
using_dt_cpu_ftrs = false;
/* Setup and verify the FDT, if it fails we just bail */
if (!early_init_dt_verify(fdt))
if (!early_init_dt_verify(fdt, __pa(fdt)))
return false;
if (!of_scan_flat_dt(fdt_find_cpu_features, NULL))

View File

@ -791,7 +791,7 @@ void __init early_init_devtree(void *params)
DBG(" -> early_init_devtree(%px)\n", params);
/* Too early to BUG_ON(), do it by hand */
if (!early_init_dt_verify(params))
if (!early_init_dt_verify(params, __pa(params)))
panic("BUG: Failed verifying flat device tree, bad version?");
of_scan_flat_dt(early_init_dt_scan_model, NULL);

View File

@ -683,7 +683,7 @@ void __init plpks_early_init_devtree(void)
out:
fdt_nop_property(fdt, chosen_node, "ibm,plpks-pw");
// Since we've cleared the password, we must update the FDT checksum
early_init_dt_verify(fdt);
early_init_dt_verify(fdt, __pa(fdt));
}
static __init int pseries_plpks_init(void)

View File

@ -227,7 +227,7 @@ static void __init init_resources(void)
static void __init parse_dtb(void)
{
/* Early scan of device tree from init memory */
if (early_init_dt_scan(dtb_early_va)) {
if (early_init_dt_scan(dtb_early_va, __pa(dtb_early_va))) {
const char *name = of_flat_dt_get_machine_name();
if (name) {

View File

@ -255,7 +255,7 @@ void __ref sh_fdt_init(phys_addr_t dt_phys)
dt_virt = phys_to_virt(dt_phys);
#endif
if (!dt_virt || !early_init_dt_scan(dt_virt)) {
if (!dt_virt || !early_init_dt_scan(dt_virt, __pa(dt_virt))) {
pr_crit("Error: invalid device tree blob"
" at physical address %p\n", (void *)dt_phys);

View File

@ -17,7 +17,7 @@ void uml_dtb_init(void)
area = uml_load_file(dtb, &size);
if (area) {
if (!early_init_dt_scan(area)) {
if (!early_init_dt_scan(area, __pa(area))) {
pr_err("invalid DTB %s\n", dtb);
memblock_free(area, size);
return;

View File

@ -305,7 +305,7 @@ void __init x86_flattree_get_config(void)
map_len = size;
}
early_init_dt_verify(dt);
early_init_dt_verify(dt, __pa(dt));
}
unflatten_and_copy_device_tree();

View File

@ -216,7 +216,7 @@ static int __init xtensa_dt_io_area(unsigned long node, const char *uname,
void __init early_init_devtree(void *params)
{
early_init_dt_scan(params);
early_init_dt_scan(params, __pa(params));
of_scan_flat_dt(xtensa_dt_io_area, NULL);
if (!command_line[0])

View File

@ -16,6 +16,7 @@
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/string.h>
@ -709,7 +710,7 @@ int dpi_init_port(struct dss_device *dss, struct platform_device *pdev,
if (!dpi)
return -ENOMEM;
ep = of_get_next_child(port, NULL);
ep = of_graph_get_next_port_endpoint(port, NULL);
if (!ep)
return 0;

View File

@ -11,6 +11,7 @@
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/string.h>
@ -346,7 +347,7 @@ int sdi_init_port(struct dss_device *dss, struct platform_device *pdev,
if (!sdi)
return -ENOMEM;
ep = of_get_next_child(port, NULL);
ep = of_graph_get_next_port_endpoint(port, NULL);
if (!ep) {
r = 0;
goto err_free;

View File

@ -13,6 +13,7 @@
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/xilinx-v4l2-controls.h>
@ -711,22 +712,13 @@ static int xtpg_parse_of(struct xtpg_device *xtpg)
{
struct device *dev = xtpg->xvip.dev;
struct device_node *node = xtpg->xvip.dev->of_node;
struct device_node *ports;
struct device_node *port;
unsigned int nports = 0;
bool has_endpoint = false;
ports = of_get_child_by_name(node, "ports");
if (ports == NULL)
ports = node;
for_each_child_of_node(ports, port) {
for_each_of_graph_port(node, port) {
const struct xvip_video_format *format;
struct device_node *endpoint;
if (!of_node_name_eq(port, "port"))
continue;
format = xvip_of_get_format(port);
if (IS_ERR(format)) {
dev_err(dev, "invalid format in DT");
@ -744,7 +736,7 @@ static int xtpg_parse_of(struct xtpg_device *xtpg)
}
if (nports == 0) {
endpoint = of_get_next_child(port, NULL);
endpoint = of_graph_get_next_port_endpoint(port, NULL);
if (endpoint)
has_endpoint = true;
of_node_put(endpoint);

View File

@ -1,4 +1,5 @@
CONFIG_KUNIT=y
CONFIG_OF=y
CONFIG_OF_KUNIT_TEST=y
CONFIG_OF_OVERLAY=y
CONFIG_OF_OVERLAY_KUNIT_TEST=y

View File

@ -111,7 +111,7 @@ config OF_OVERLAY_KUNIT_TEST
tristate "Device Tree overlay KUnit tests" if !KUNIT_ALL_TESTS
depends on KUNIT
default KUNIT_ALL_TESTS
select OF_OVERLAY
select DTC
help
This option builds KUnit unit tests for the device tree overlay code.

View File

@ -147,7 +147,7 @@ static unsigned int of_bus_pci_get_flags(const __be32 *addr)
* PCI bus specific translator
*/
static bool of_node_is_pcie(struct device_node *np)
static bool of_node_is_pcie(const struct device_node *np)
{
bool is_pcie = of_node_name_eq(np, "pcie");
@ -230,8 +230,8 @@ static int __of_address_resource_bounds(struct resource *r, u64 start, u64 size)
* To guard against that we try to register the IO range first.
* If that fails we know that pci_address_to_pio() will do too.
*/
int of_pci_range_to_resource(struct of_pci_range *range,
struct device_node *np, struct resource *res)
int of_pci_range_to_resource(const struct of_pci_range *range,
const struct device_node *np, struct resource *res)
{
u64 start;
int err;
@ -333,14 +333,18 @@ static unsigned int of_bus_isa_get_flags(const __be32 *addr)
static int of_bus_default_flags_match(struct device_node *np)
{
return of_bus_n_addr_cells(np) == 3;
/*
* Check for presence first since of_bus_n_addr_cells() will warn when
* walking parent nodes.
*/
return of_property_present(np, "#address-cells") && (of_bus_n_addr_cells(np) == 3);
}
/*
* Array of bus specific translators
*/
static struct of_bus of_busses[] = {
static const struct of_bus of_busses[] = {
#ifdef CONFIG_PCI
/* PCI */
{
@ -388,7 +392,7 @@ static struct of_bus of_busses[] = {
},
};
static struct of_bus *of_match_bus(struct device_node *np)
static const struct of_bus *of_match_bus(struct device_node *np)
{
int i;
@ -399,7 +403,7 @@ static struct of_bus *of_match_bus(struct device_node *np)
return NULL;
}
static int of_empty_ranges_quirk(struct device_node *np)
static int of_empty_ranges_quirk(const struct device_node *np)
{
if (IS_ENABLED(CONFIG_PPC)) {
/* To save cycles, we cache the result for global "Mac" setting */
@ -419,8 +423,8 @@ static int of_empty_ranges_quirk(struct device_node *np)
return false;
}
static int of_translate_one(struct device_node *parent, struct of_bus *bus,
struct of_bus *pbus, __be32 *addr,
static int of_translate_one(const struct device_node *parent, const struct of_bus *bus,
const struct of_bus *pbus, __be32 *addr,
int na, int ns, int pna, const char *rprop)
{
const __be32 *ranges;
@ -505,7 +509,7 @@ static u64 __of_translate_address(struct device_node *node,
{
struct device_node *dev __free(device_node) = of_node_get(node);
struct device_node *parent __free(device_node) = get_parent(dev);
struct of_bus *bus, *pbus;
const struct of_bus *bus, *pbus;
__be32 addr[OF_MAX_ADDR_CELLS];
int na, ns, pna, pns;
@ -690,7 +694,7 @@ const __be32 *__of_get_address(struct device_node *dev, int index, int bar_no,
const __be32 *prop;
unsigned int psize;
struct device_node *parent __free(device_node) = of_get_parent(dev);
struct of_bus *bus;
const struct of_bus *bus;
int onesize, i, na, ns;
if (parent == NULL)
@ -701,16 +705,16 @@ const __be32 *__of_get_address(struct device_node *dev, int index, int bar_no,
if (strcmp(bus->name, "pci") && (bar_no >= 0))
return NULL;
bus->count_cells(dev, &na, &ns);
if (!OF_CHECK_ADDR_COUNT(na))
return NULL;
/* Get "reg" or "assigned-addresses" property */
prop = of_get_property(dev, bus->addresses, &psize);
if (prop == NULL)
return NULL;
psize /= 4;
bus->count_cells(dev, &na, &ns);
if (!OF_CHECK_ADDR_COUNT(na))
return NULL;
onesize = na + ns;
for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) {
u32 val = be32_to_cpu(prop[0]);
@ -1030,7 +1034,7 @@ EXPORT_SYMBOL_GPL(of_dma_is_coherent);
* This is currently only enabled on builds that support Apple ARM devices, as
* an optimization.
*/
static bool of_mmio_is_nonposted(struct device_node *np)
static bool of_mmio_is_nonposted(const struct device_node *np)
{
if (!IS_ENABLED(CONFIG_ARCH_APPLE))
return false;

View File

@ -87,15 +87,25 @@ static bool __of_node_is_type(const struct device_node *np, const char *type)
return np && match && type && !strcmp(match, type);
}
#define EXCLUDED_DEFAULT_CELLS_PLATFORMS ( \
IS_ENABLED(CONFIG_SPARC) \
)
int of_bus_n_addr_cells(struct device_node *np)
{
u32 cells;
for (; np; np = np->parent)
for (; np; np = np->parent) {
if (!of_property_read_u32(np, "#address-cells", &cells))
return cells;
/* No #address-cells property for the root node */
/*
* Default root value and walking parent nodes for "#address-cells"
* is deprecated. Any platforms which hit this warning should
* be added to the excluded list.
*/
WARN_ONCE(!EXCLUDED_DEFAULT_CELLS_PLATFORMS,
"Missing '#address-cells' in %pOF\n", np);
}
return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
}
@ -112,11 +122,17 @@ int of_bus_n_size_cells(struct device_node *np)
{
u32 cells;
for (; np; np = np->parent)
for (; np; np = np->parent) {
if (!of_property_read_u32(np, "#size-cells", &cells))
return cells;
/* No #size-cells property for the root node */
/*
* Default root value and walking parent nodes for "#size-cells"
* is deprecated. Any platforms which hit this warning should
* be added to the excluded list.
*/
WARN_ONCE(!EXCLUDED_DEFAULT_CELLS_PLATFORMS,
"Missing '#size-cells' in %pOF\n", np);
}
return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
}
@ -270,7 +286,7 @@ EXPORT_SYMBOL(of_find_all_nodes);
const void *__of_get_property(const struct device_node *np,
const char *name, int *lenp)
{
struct property *pp = __of_find_property(np, name, lenp);
const struct property *pp = __of_find_property(np, name, lenp);
return pp ? pp->value : NULL;
}
@ -282,7 +298,7 @@ const void *__of_get_property(const struct device_node *np,
const void *of_get_property(const struct device_node *np, const char *name,
int *lenp)
{
struct property *pp = of_find_property(np, name, lenp);
const struct property *pp = of_find_property(np, name, lenp);
return pp ? pp->value : NULL;
}
@ -321,7 +337,7 @@ EXPORT_SYMBOL(of_get_property);
static int __of_device_is_compatible(const struct device_node *device,
const char *compat, const char *type, const char *name)
{
struct property *prop;
const struct property *prop;
const char *cp;
int index = 0, score = 0;
@ -771,7 +787,7 @@ struct device_node *of_get_child_by_name(const struct device_node *node,
}
EXPORT_SYMBOL(of_get_child_by_name);
struct device_node *__of_find_node_by_path(struct device_node *parent,
struct device_node *__of_find_node_by_path(const struct device_node *parent,
const char *path)
{
struct device_node *child;
@ -828,7 +844,7 @@ struct device_node *__of_find_node_by_full_path(struct device_node *node,
struct device_node *of_find_node_opts_by_path(const char *path, const char **opts)
{
struct device_node *np = NULL;
struct property *pp;
const struct property *pp;
unsigned long flags;
const char *separator = strchr(path, ':');
@ -974,7 +990,7 @@ struct device_node *of_find_node_with_property(struct device_node *from,
const char *prop_name)
{
struct device_node *np;
struct property *pp;
const struct property *pp;
unsigned long flags;
raw_spin_lock_irqsave(&devtree_lock, flags);
@ -1769,7 +1785,7 @@ static void of_alias_add(struct alias_prop *ap, struct device_node *np,
*/
void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
{
struct property *pp;
const struct property *pp;
of_aliases = of_find_node_by_path("/aliases");
of_chosen = of_find_node_by_path("/chosen");
@ -1840,7 +1856,7 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
*
* Return: The alias id if found.
*/
int of_alias_get_id(struct device_node *np, const char *stem)
int of_alias_get_id(const struct device_node *np, const char *stem)
{
struct alias_prop *app;
int id = -ENODEV;
@ -1898,7 +1914,7 @@ EXPORT_SYMBOL_GPL(of_alias_get_highest_id);
*
* Return: TRUE if console successfully setup. Otherwise return FALSE.
*/
bool of_console_check(struct device_node *dn, char *name, int index)
bool of_console_check(const struct device_node *dn, char *name, int index)
{
if (!dn || dn != of_stdout || console_set_on_cmdline)
return false;
@ -1986,7 +2002,7 @@ int of_find_last_cache_level(unsigned int cpu)
*
* Return: 0 on success or a standard error code on failure.
*/
int of_map_id(struct device_node *np, u32 id,
int of_map_id(const struct device_node *np, u32 id,
const char *map_name, const char *map_mask_name,
struct device_node **target, u32 *id_out)
{

View File

@ -188,7 +188,7 @@ EXPORT_SYMBOL(of_cpu_node_to_id);
* 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,
struct device_node *of_get_cpu_state_node(const struct device_node *cpu_node,
int index)
{
struct of_phandle_args args;

View File

@ -536,7 +536,7 @@ static void __of_changeset_entry_destroy(struct of_changeset_entry *ce)
kfree(ce);
}
static void __of_changeset_entry_invert(struct of_changeset_entry *ce,
static void __of_changeset_entry_invert(const struct of_changeset_entry *ce,
struct of_changeset_entry *rce)
{
memcpy(rce, ce, sizeof(*rce));
@ -636,7 +636,7 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce)
return 0;
}
static inline int __of_changeset_entry_revert(struct of_changeset_entry *ce)
static inline int __of_changeset_entry_revert(const struct of_changeset_entry *ce)
{
struct of_changeset_entry ce_inverted;

View File

@ -457,6 +457,7 @@ int __initdata dt_root_addr_cells;
int __initdata dt_root_size_cells;
void *initial_boot_params __ro_after_init;
phys_addr_t initial_boot_params_pa __ro_after_init;
#ifdef CONFIG_OF_EARLY_FLATTREE
@ -511,8 +512,6 @@ void __init early_init_fdt_scan_reserved_mem(void)
break;
memblock_reserve(base, size);
}
fdt_init_reserved_mem();
}
/**
@ -938,12 +937,12 @@ int __init early_init_dt_scan_root(void)
dt_root_addr_cells = OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
if (prop)
if (!WARN(!prop, "No '#size-cells' in root node\n"))
dt_root_size_cells = be32_to_cpup(prop);
pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells);
prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
if (prop)
if (!WARN(!prop, "No '#address-cells' in root node\n"))
dt_root_addr_cells = be32_to_cpup(prop);
pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells);
@ -1136,17 +1135,18 @@ static void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
return ptr;
}
bool __init early_init_dt_verify(void *params)
bool __init early_init_dt_verify(void *dt_virt, phys_addr_t dt_phys)
{
if (!params)
if (!dt_virt)
return false;
/* check device tree validity */
if (fdt_check_header(params))
if (fdt_check_header(dt_virt))
return false;
/* Setup flat device-tree pointer */
initial_boot_params = params;
initial_boot_params = dt_virt;
initial_boot_params_pa = dt_phys;
of_fdt_crc32 = crc32_be(~0, initial_boot_params,
fdt_totalsize(initial_boot_params));
@ -1173,11 +1173,11 @@ void __init early_init_dt_scan_nodes(void)
early_init_dt_check_for_usable_mem_range();
}
bool __init early_init_dt_scan(void *params)
bool __init early_init_dt_scan(void *dt_virt, phys_addr_t dt_phys)
{
bool status;
status = early_init_dt_verify(params);
status = early_init_dt_verify(dt_virt, dt_phys);
if (!status)
return false;
@ -1212,6 +1212,9 @@ void __init unflatten_device_tree(void)
{
void *fdt = initial_boot_params;
/* Save the statically-placed regions in the reserved_mem array */
fdt_scan_reserved_mem_reg_nodes();
/* Don't use the bootloader provided DTB if ACPI is enabled */
if (!acpi_disabled)
fdt = NULL;

View File

@ -55,7 +55,7 @@ static void __init fdt_bus_default_count_cells(const void *blob, int parentoffse
if (prop)
*addrc = be32_to_cpup(prop);
else
*addrc = dt_root_addr_cells;
*addrc = -1;
}
if (sizec) {
@ -63,7 +63,7 @@ static void __init fdt_bus_default_count_cells(const void *blob, int parentoffse
if (prop)
*sizec = be32_to_cpup(prop);
else
*sizec = dt_root_size_cells;
*sizec = -1;
}
}

View File

@ -720,7 +720,7 @@ struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 id,
* Returns: the MSI domain for this device (or NULL on failure).
*/
struct irq_domain *of_msi_get_domain(struct device *dev,
struct device_node *np,
const struct device_node *np,
enum irq_domain_bus_token token)
{
struct of_phandle_iterator it;
@ -742,7 +742,7 @@ EXPORT_SYMBOL_GPL(of_msi_get_domain);
* @dev: device structure to associate with an MSI irq domain
* @np: device node for that device
*/
void of_msi_configure(struct device *dev, struct device_node *np)
void of_msi_configure(struct device *dev, const struct device_node *np)
{
dev_set_msi_domain(dev,
of_msi_get_domain(dev, np, DOMAIN_BUS_PLATFORM_MSI));

View File

@ -301,7 +301,7 @@ void *of_kexec_alloc_and_setup_fdt(const struct kimage *image,
}
/* Remove memory reservation for the current device tree. */
ret = fdt_find_and_del_mem_rsv(fdt, __pa(initial_boot_params),
ret = fdt_find_and_del_mem_rsv(fdt, initial_boot_params_pa,
fdt_totalsize(initial_boot_params));
if (ret == -EINVAL) {
pr_err("Error removing memory reservation.\n");

View File

@ -37,7 +37,7 @@ static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj,
}
/* always return newly allocated name, caller must free after use */
static const char *safe_name(struct kobject *kobj, const char *orig_name)
static const char *safe_name(const struct kobject *kobj, const char *orig_name)
{
const char *name = orig_name;
struct kernfs_node *kn;
@ -84,7 +84,7 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp)
return rc;
}
void __of_sysfs_remove_bin_file(struct device_node *np, struct property *prop)
void __of_sysfs_remove_bin_file(struct device_node *np, const struct property *prop)
{
if (!IS_ENABLED(CONFIG_SYSFS))
return;
@ -93,7 +93,7 @@ void __of_sysfs_remove_bin_file(struct device_node *np, struct property *prop)
kfree(prop->attr.attr.name);
}
void __of_remove_property_sysfs(struct device_node *np, struct property *prop)
void __of_remove_property_sysfs(struct device_node *np, const struct property *prop)
{
/* at early boot, bail here and defer setup to of_init() */
if (of_kset && of_node_is_attached(np))
@ -101,7 +101,7 @@ void __of_remove_property_sysfs(struct device_node *np, struct property *prop)
}
void __of_update_property_sysfs(struct device_node *np, struct property *newprop,
struct property *oldprop)
const struct property *oldprop)
{
/* At early boot, bail out and defer setup to of_init() */
if (!of_kset)

View File

@ -35,12 +35,10 @@ ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len)
str += csize;
of_property_for_each_string(np, "compatible", p, compat) {
csize = strlen(compat) + 1;
csize = snprintf(str, len, "C%s", compat);
tsize += csize;
if (csize >= len)
continue;
csize = snprintf(str, len, "C%s", compat);
for (c = str; c; ) {
c = strchr(c, ' ');
if (c)

View File

@ -14,9 +14,6 @@
#include <asm/numa.h>
/* define default numa node to 0 */
#define DEFAULT_NODE 0
/*
* Even though we connect cpus to numa domains later in SMP
* init, we need to know the node ids now for all cpus.

View File

@ -9,6 +9,7 @@
*/
#define FDT_ALIGN_SIZE 8
#define MAX_RESERVED_REGIONS 64
/**
* struct alias_prop - Alias property in 'aliases' node
@ -72,9 +73,9 @@ static inline void of_platform_register_reconfig_notifier(void) { }
#if defined(CONFIG_OF_KOBJ)
int of_node_is_attached(const struct device_node *node);
int __of_add_property_sysfs(struct device_node *np, struct property *pp);
void __of_remove_property_sysfs(struct device_node *np, struct property *prop);
void __of_remove_property_sysfs(struct device_node *np, const struct property *prop);
void __of_update_property_sysfs(struct device_node *np, struct property *newprop,
struct property *oldprop);
const struct property *oldprop);
int __of_attach_node_sysfs(struct device_node *np);
void __of_detach_node_sysfs(struct device_node *np);
#else
@ -82,9 +83,9 @@ static inline int __of_add_property_sysfs(struct device_node *np, struct propert
{
return 0;
}
static inline void __of_remove_property_sysfs(struct device_node *np, struct property *prop) {}
static inline void __of_remove_property_sysfs(struct device_node *np, const struct property *prop) {}
static inline void __of_update_property_sysfs(struct device_node *np,
struct property *newprop, struct property *oldprop) {}
struct property *newprop, const struct property *oldprop) {}
static inline int __of_attach_node_sysfs(struct device_node *np)
{
return 0;
@ -130,7 +131,7 @@ void __of_prop_free(struct property *prop);
struct device_node *__of_node_dup(const struct device_node *np,
const char *full_name);
struct device_node *__of_find_node_by_path(struct device_node *parent,
struct device_node *__of_find_node_by_path(const struct device_node *parent,
const char *path);
struct device_node *__of_find_node_by_full_path(struct device_node *node,
const char *path);
@ -145,7 +146,7 @@ extern int __of_update_property(struct device_node *np,
extern void __of_detach_node(struct device_node *np);
extern void __of_sysfs_remove_bin_file(struct device_node *np,
struct property *prop);
const struct property *prop);
/* illegal phandle value (set when unresolved) */
#define OF_PHANDLE_ILLEGAL 0xdeadbeef
@ -183,7 +184,7 @@ static inline struct device_node *__of_get_dma_parent(const struct device_node *
#endif
int fdt_scan_reserved_mem(void);
void fdt_init_reserved_mem(void);
void __init fdt_scan_reserved_mem_reg_nodes(void);
bool of_fdt_device_is_available(const void *blob, unsigned long node);

View File

@ -27,8 +27,9 @@
#include "of_private.h"
#define MAX_RESERVED_REGIONS 64
static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
static struct reserved_mem reserved_mem_array[MAX_RESERVED_REGIONS] __initdata;
static struct reserved_mem *reserved_mem __refdata = reserved_mem_array;
static int total_reserved_mem_cnt = MAX_RESERVED_REGIONS;
static int reserved_mem_count;
static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
@ -56,6 +57,51 @@ static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
return err;
}
/*
* alloc_reserved_mem_array() - allocate memory for the reserved_mem
* array using memblock
*
* This function is used to allocate memory for the reserved_mem
* array according to the total number of reserved memory regions
* defined in the DT.
* After the new array is allocated, the information stored in
* the initial static array is copied over to this new array and
* the new array is used from this point on.
*/
static void __init alloc_reserved_mem_array(void)
{
struct reserved_mem *new_array;
size_t alloc_size, copy_size, memset_size;
alloc_size = array_size(total_reserved_mem_cnt, sizeof(*new_array));
if (alloc_size == SIZE_MAX) {
pr_err("Failed to allocate memory for reserved_mem array with err: %d", -EOVERFLOW);
return;
}
new_array = memblock_alloc(alloc_size, SMP_CACHE_BYTES);
if (!new_array) {
pr_err("Failed to allocate memory for reserved_mem array with err: %d", -ENOMEM);
return;
}
copy_size = array_size(reserved_mem_count, sizeof(*new_array));
if (copy_size == SIZE_MAX) {
memblock_free(new_array, alloc_size);
total_reserved_mem_cnt = MAX_RESERVED_REGIONS;
pr_err("Failed to allocate memory for reserved_mem array with err: %d", -EOVERFLOW);
return;
}
memset_size = alloc_size - copy_size;
memcpy(new_array, reserved_mem, copy_size);
memset(new_array + reserved_mem_count, 0, memset_size);
reserved_mem = new_array;
}
static void __init fdt_init_reserved_mem_node(struct reserved_mem *rmem);
/*
* fdt_reserved_mem_save_node() - save fdt node for second pass initialization
*/
@ -64,7 +110,7 @@ static void __init fdt_reserved_mem_save_node(unsigned long node, const char *un
{
struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
if (reserved_mem_count == ARRAY_SIZE(reserved_mem)) {
if (reserved_mem_count == total_reserved_mem_cnt) {
pr_err("not enough space for all defined regions.\n");
return;
}
@ -74,6 +120,9 @@ static void __init fdt_reserved_mem_save_node(unsigned long node, const char *un
rmem->base = base;
rmem->size = size;
/* Call the region specific initialization function */
fdt_init_reserved_mem_node(rmem);
reserved_mem_count++;
return;
}
@ -106,7 +155,6 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
phys_addr_t base, size;
int len;
const __be32 *prop;
int first = 1;
bool nomap;
prop = of_get_flat_dt_prop(node, "reg", &len);
@ -134,10 +182,6 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
uname, &base, (unsigned long)(size / SZ_1M));
len -= t_len;
if (first) {
fdt_reserved_mem_save_node(node, uname, base, size);
first = 0;
}
}
return 0;
}
@ -165,12 +209,80 @@ static int __init __reserved_mem_check_root(unsigned long node)
return 0;
}
static void __init __rmem_check_for_overlap(void);
/**
* fdt_scan_reserved_mem_reg_nodes() - Store info for the "reg" defined
* reserved memory regions.
*
* This function is used to scan through the DT and store the
* information for the reserved memory regions that are defined using
* the "reg" property. The region node number, name, base address, and
* size are all stored in the reserved_mem array by calling the
* fdt_reserved_mem_save_node() function.
*/
void __init fdt_scan_reserved_mem_reg_nodes(void)
{
int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
const void *fdt = initial_boot_params;
phys_addr_t base, size;
const __be32 *prop;
int node, child;
int len;
if (!fdt)
return;
node = fdt_path_offset(fdt, "/reserved-memory");
if (node < 0) {
pr_info("Reserved memory: No reserved-memory node in the DT\n");
return;
}
/* Attempt dynamic allocation of a new reserved_mem array */
alloc_reserved_mem_array();
if (__reserved_mem_check_root(node)) {
pr_err("Reserved memory: unsupported node format, ignoring\n");
return;
}
fdt_for_each_subnode(child, fdt, node) {
const char *uname;
prop = of_get_flat_dt_prop(child, "reg", &len);
if (!prop)
continue;
if (!of_fdt_device_is_available(fdt, child))
continue;
uname = fdt_get_name(fdt, child, NULL);
if (len && len % t_len != 0) {
pr_err("Reserved memory: invalid reg property in '%s', skipping node.\n",
uname);
continue;
}
base = dt_mem_next_cell(dt_root_addr_cells, &prop);
size = dt_mem_next_cell(dt_root_size_cells, &prop);
if (size)
fdt_reserved_mem_save_node(child, uname, base, size);
}
/* check for overlapping reserved regions */
__rmem_check_for_overlap();
}
static int __init __reserved_mem_alloc_size(unsigned long node, const char *uname);
/*
* fdt_scan_reserved_mem() - scan a single FDT node for reserved memory
*/
int __init fdt_scan_reserved_mem(void)
{
int node, child;
int dynamic_nodes_cnt = 0, count = 0;
int dynamic_nodes[MAX_RESERVED_REGIONS];
const void *fdt = initial_boot_params;
node = fdt_path_offset(fdt, "/reserved-memory");
@ -192,9 +304,31 @@ int __init fdt_scan_reserved_mem(void)
uname = fdt_get_name(fdt, child, NULL);
err = __reserved_mem_reserve_reg(child, uname);
if (err == -ENOENT && of_get_flat_dt_prop(child, "size", NULL))
fdt_reserved_mem_save_node(child, uname, 0, 0);
if (!err)
count++;
/*
* Save the nodes for the dynamically-placed regions
* into an array which will be used for allocation right
* after all the statically-placed regions are reserved
* or marked as no-map. This is done to avoid dynamically
* allocating from one of the statically-placed regions.
*/
if (err == -ENOENT && of_get_flat_dt_prop(child, "size", NULL)) {
dynamic_nodes[dynamic_nodes_cnt] = child;
dynamic_nodes_cnt++;
}
}
for (int i = 0; i < dynamic_nodes_cnt; i++) {
const char *uname;
int err;
child = dynamic_nodes[i];
uname = fdt_get_name(fdt, child, NULL);
err = __reserved_mem_alloc_size(child, uname);
if (!err)
count++;
}
total_reserved_mem_cnt = count;
return 0;
}
@ -253,8 +387,7 @@ static int __init __reserved_mem_alloc_in_range(phys_addr_t size,
* __reserved_mem_alloc_size() - allocate reserved memory described by
* 'size', 'alignment' and 'alloc-ranges' properties.
*/
static int __init __reserved_mem_alloc_size(unsigned long node,
const char *uname, phys_addr_t *res_base, phys_addr_t *res_size)
static int __init __reserved_mem_alloc_size(unsigned long node, const char *uname)
{
int t_len = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32);
phys_addr_t start = 0, end = 0;
@ -334,9 +467,8 @@ static int __init __reserved_mem_alloc_size(unsigned long node,
return -ENOMEM;
}
*res_base = base;
*res_size = size;
/* Save region in the reserved_mem array */
fdt_reserved_mem_save_node(node, uname, base, size);
return 0;
}
@ -425,48 +557,37 @@ static void __init __rmem_check_for_overlap(void)
}
/**
* fdt_init_reserved_mem() - allocate and init all saved reserved memory regions
* fdt_init_reserved_mem_node() - Initialize a reserved memory region
* @rmem: reserved_mem struct of the memory region to be initialized.
*
* This function is used to call the region specific initialization
* function for a reserved memory region.
*/
void __init fdt_init_reserved_mem(void)
static void __init fdt_init_reserved_mem_node(struct reserved_mem *rmem)
{
int i;
unsigned long node = rmem->fdt_node;
int err = 0;
bool nomap;
/* check for overlapping reserved regions */
__rmem_check_for_overlap();
nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
for (i = 0; i < reserved_mem_count; i++) {
struct reserved_mem *rmem = &reserved_mem[i];
unsigned long node = rmem->fdt_node;
int err = 0;
bool nomap;
err = __reserved_mem_init_node(rmem);
if (err != 0 && err != -ENOENT) {
pr_info("node %s compatible matching fail\n", rmem->name);
if (nomap)
memblock_clear_nomap(rmem->base, rmem->size);
else
memblock_phys_free(rmem->base, rmem->size);
} else {
phys_addr_t end = rmem->base + rmem->size - 1;
bool reusable =
(of_get_flat_dt_prop(node, "reusable", NULL)) != NULL;
nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
if (rmem->size == 0)
err = __reserved_mem_alloc_size(node, rmem->name,
&rmem->base, &rmem->size);
if (err == 0) {
err = __reserved_mem_init_node(rmem);
if (err != 0 && err != -ENOENT) {
pr_info("node %s compatible matching fail\n",
rmem->name);
if (nomap)
memblock_clear_nomap(rmem->base, rmem->size);
else
memblock_phys_free(rmem->base,
rmem->size);
} else {
phys_addr_t end = rmem->base + rmem->size - 1;
bool reusable =
(of_get_flat_dt_prop(node, "reusable", NULL)) != NULL;
pr_info("%pa..%pa (%lu KiB) %s %s %s\n",
&rmem->base, &end, (unsigned long)(rmem->size / SZ_1K),
nomap ? "nomap" : "map",
reusable ? "reusable" : "non-reusable",
rmem->name ? rmem->name : "unknown");
}
}
pr_info("%pa..%pa (%lu KiB) %s %s %s\n",
&rmem->base, &end, (unsigned long)(rmem->size / SZ_1K),
nomap ? "nomap" : "map",
reusable ? "reusable" : "non-reusable",
rmem->name ? rmem->name : "unknown");
}
}

View File

@ -296,10 +296,11 @@ err_free_target_path:
* invalid @overlay.
*/
static int add_changeset_property(struct overlay_changeset *ovcs,
struct target *target, struct property *overlay_prop,
struct target *target, const struct property *overlay_prop,
bool is_symbols_prop)
{
struct property *new_prop = NULL, *prop;
struct property *new_prop = NULL;
const struct property *prop;
int ret = 0;
if (target->in_livetree)
@ -398,7 +399,7 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
* invalid @overlay.
*/
static int add_changeset_node(struct overlay_changeset *ovcs,
struct target *target, struct device_node *node)
struct target *target, const struct device_node *node)
{
const char *node_kbasename;
const __be32 *phandle;
@ -675,8 +676,8 @@ static int build_changeset(struct overlay_changeset *ovcs)
* 1) "target" property containing the phandle of the target
* 2) "target-path" property containing the path of the target
*/
static struct device_node *find_target(struct device_node *info_node,
struct device_node *target_base)
static struct device_node *find_target(const struct device_node *info_node,
const struct device_node *target_base)
{
struct device_node *node;
char *target_path;
@ -735,7 +736,7 @@ static struct device_node *find_target(struct device_node *info_node,
* init_overlay_changeset() must call free_overlay_changeset().
*/
static int init_overlay_changeset(struct overlay_changeset *ovcs,
struct device_node *target_base)
const struct device_node *target_base)
{
struct device_node *node, *overlay_node;
struct fragment *fragment;
@ -910,7 +911,7 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs)
*/
static int of_overlay_apply(struct overlay_changeset *ovcs,
struct device_node *base)
const struct device_node *base)
{
int ret = 0, ret_revert, ret_tmp;
@ -978,7 +979,7 @@ out:
*/
int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size,
int *ret_ovcs_id, struct device_node *base)
int *ret_ovcs_id, const struct device_node *base)
{
void *new_fdt;
void *new_fdt_align;
@ -1074,7 +1075,7 @@ EXPORT_SYMBOL_GPL(of_overlay_fdt_apply);
*
* Returns 1 if @np is @tree or is contained in @tree, else 0
*/
static int find_node(struct device_node *tree, struct device_node *np)
static int find_node(const struct device_node *tree, struct device_node *np)
{
if (tree == np)
return 1;

View File

@ -65,6 +65,8 @@ static void of_overlay_apply_kunit_cleanup(struct kunit *test)
struct device_node *np;
of_root_kunit_skip(test);
if (!IS_ENABLED(CONFIG_OF_OVERLAY))
kunit_skip(test, "requires CONFIG_OF_OVERLAY to apply overlay");
if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE))
kunit_skip(test, "requires CONFIG_OF_EARLY_FLATTREE for root node");

View File

@ -68,7 +68,7 @@ EXPORT_SYMBOL(of_graph_is_present);
int of_property_count_elems_of_size(const struct device_node *np,
const char *propname, int elem_size)
{
struct property *prop = of_find_property(np, propname, NULL);
const struct property *prop = of_find_property(np, propname, NULL);
if (!prop)
return -EINVAL;
@ -104,7 +104,7 @@ EXPORT_SYMBOL_GPL(of_property_count_elems_of_size);
static void *of_find_property_value_of_size(const struct device_node *np,
const char *propname, u32 min, u32 max, size_t *len)
{
struct property *prop = of_find_property(np, propname, NULL);
const struct property *prop = of_find_property(np, propname, NULL);
if (!prop)
return ERR_PTR(-EINVAL);
@ -530,7 +530,7 @@ int of_property_read_string_helper(const struct device_node *np,
}
EXPORT_SYMBOL_GPL(of_property_read_string_helper);
const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
const __be32 *of_prop_next_u32(const struct property *prop, const __be32 *cur,
u32 *pu)
{
const void *curv = cur;
@ -553,7 +553,7 @@ out_val:
}
EXPORT_SYMBOL_GPL(of_prop_next_u32);
const char *of_prop_next_string(struct property *prop, const char *cur)
const char *of_prop_next_string(const struct property *prop, const char *cur)
{
const void *curv = cur;
@ -630,6 +630,70 @@ struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id)
}
EXPORT_SYMBOL(of_graph_get_port_by_id);
/**
* of_graph_get_next_port() - get next port node.
* @parent: pointer to the parent device node, or parent ports node
* @prev: previous port node, or NULL to get first
*
* Parent device node can be used as @parent whether device node has ports node
* or not. It will work same as ports@0 node.
*
* Return: A 'port' node pointer with refcount incremented. Refcount
* of the passed @prev node is decremented.
*/
struct device_node *of_graph_get_next_port(const struct device_node *parent,
struct device_node *prev)
{
if (!parent)
return NULL;
if (!prev) {
struct device_node *node __free(device_node) =
of_get_child_by_name(parent, "ports");
if (node)
parent = node;
return of_get_child_by_name(parent, "port");
}
do {
prev = of_get_next_child(parent, prev);
if (!prev)
break;
} while (!of_node_name_eq(prev, "port"));
return prev;
}
EXPORT_SYMBOL(of_graph_get_next_port);
/**
* of_graph_get_next_port_endpoint() - get next endpoint node in port.
* If it reached to end of the port, it will return NULL.
* @port: pointer to the target port node
* @prev: previous endpoint node, or NULL to get first
*
* Return: An 'endpoint' node pointer with refcount incremented. Refcount
* of the passed @prev node is decremented.
*/
struct device_node *of_graph_get_next_port_endpoint(const struct device_node *port,
struct device_node *prev)
{
while (1) {
prev = of_get_next_child(port, prev);
if (!prev)
break;
if (WARN(!of_node_name_eq(prev, "endpoint"),
"non endpoint node is used (%pOF)", prev))
continue;
break;
}
return prev;
}
EXPORT_SYMBOL(of_graph_get_next_port_endpoint);
/**
* of_graph_get_next_endpoint() - get next endpoint node
* @parent: pointer to the parent device node
@ -653,13 +717,7 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
* parent port node.
*/
if (!prev) {
struct device_node *node __free(device_node) =
of_get_child_by_name(parent, "ports");
if (node)
parent = node;
port = of_get_child_by_name(parent, "port");
port = of_graph_get_next_port(parent, NULL);
if (!port) {
pr_debug("graph: no port node found in %pOF\n", parent);
return NULL;
@ -677,7 +735,7 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
* getting the next child. If the previous endpoint is NULL this
* will return the first child.
*/
endpoint = of_get_next_child(port, prev);
endpoint = of_graph_get_next_port_endpoint(port, prev);
if (endpoint) {
of_node_put(port);
return endpoint;
@ -686,11 +744,9 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
/* No more endpoints under this port, try the next one. */
prev = NULL;
do {
port = of_get_next_child(parent, port);
if (!port)
return NULL;
} while (!of_node_name_eq(port, "port"));
port = of_graph_get_next_port(parent, port);
if (!port)
return NULL;
}
}
EXPORT_SYMBOL(of_graph_get_next_endpoint);
@ -823,6 +879,23 @@ unsigned int of_graph_get_endpoint_count(const struct device_node *np)
}
EXPORT_SYMBOL(of_graph_get_endpoint_count);
/**
* of_graph_get_port_count() - get the number of port in a device or ports node
* @np: pointer to the device or ports node
*
* Return: count of port of this device or ports node
*/
unsigned int of_graph_get_port_count(struct device_node *np)
{
unsigned int num = 0;
for_each_of_graph_port(np, port)
num++;
return num;
}
EXPORT_SYMBOL(of_graph_get_port_count);
/**
* of_graph_get_remote_node() - get remote parent device_node for given port/endpoint
* @node: pointer to parent device_node containing graph port/endpoint
@ -1466,7 +1539,7 @@ static int of_fwnode_irq_get(const struct fwnode_handle *fwnode,
static int of_fwnode_add_links(struct fwnode_handle *fwnode)
{
struct property *p;
const struct property *p;
struct device_node *con_np = to_of_node(fwnode);
if (IS_ENABLED(CONFIG_X86))

View File

@ -42,7 +42,7 @@ static void adjust_overlay_phandles(struct device_node *overlay,
int phandle_delta)
{
struct device_node *child;
struct property *prop;
const struct property *prop;
phandle phandle;
/* adjust node's phandle in node */
@ -71,10 +71,10 @@ static void adjust_overlay_phandles(struct device_node *overlay,
}
static int update_usages_of_a_phandle_reference(struct device_node *overlay,
struct property *prop_fixup, phandle phandle)
const struct property *prop_fixup, phandle phandle)
{
struct device_node *refnode;
struct property *prop;
const struct property *prop;
char *value __free(kfree) = kmemdup(prop_fixup->value, prop_fixup->length, GFP_KERNEL);
char *cur, *end, *node_path, *prop_name, *s;
int offset, len;
@ -147,11 +147,11 @@ static int node_name_cmp(const struct device_node *dn1,
* of offsets of the phandle reference(s) within the respective property
* value(s). The values at these offsets will be fixed up.
*/
static int adjust_local_phandle_references(struct device_node *local_fixups,
struct device_node *overlay, int phandle_delta)
static int adjust_local_phandle_references(const struct device_node *local_fixups,
const struct device_node *overlay, int phandle_delta)
{
struct device_node *overlay_child;
struct property *prop_fix, *prop;
const struct property *prop_fix, *prop;
int err, i, count;
unsigned int off;

View File

@ -4167,7 +4167,7 @@ EXPORT_SYMBOL(pci_request_regions_exclusive);
* Record the PCI IO range (expressed as CPU physical address + size).
* Return a negative value if an error has occurred, zero otherwise
*/
int pci_register_io_range(struct fwnode_handle *fwnode, phys_addr_t addr,
int pci_register_io_range(const struct fwnode_handle *fwnode, phys_addr_t addr,
resource_size_t size)
{
int ret = 0;

View File

@ -20,6 +20,7 @@
#include <linux/regulator/consumer.h>
#include <linux/string.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/clk.h>
#include <linux/component.h>
@ -845,7 +846,7 @@ int dpi_init_port(struct platform_device *pdev, struct device_node *port)
if (!dpi)
return -ENOMEM;
ep = omapdss_of_get_next_endpoint(port, NULL);
ep = of_graph_get_next_port_endpoint(port, NULL);
if (!ep)
return 0;

View File

@ -15,72 +15,6 @@
#include "dss.h"
struct device_node *
omapdss_of_get_next_port(const struct device_node *parent,
struct device_node *prev)
{
struct device_node *port = NULL;
if (!parent)
return NULL;
if (!prev) {
struct device_node *ports;
/*
* It's the first call, we have to find a port subnode
* within this node or within an optional 'ports' node.
*/
ports = of_get_child_by_name(parent, "ports");
if (ports)
parent = ports;
port = of_get_child_by_name(parent, "port");
/* release the 'ports' node */
of_node_put(ports);
} else {
struct device_node *ports;
ports = of_get_parent(prev);
if (!ports)
return NULL;
do {
port = of_get_next_child(ports, prev);
if (!port) {
of_node_put(ports);
return NULL;
}
prev = port;
} while (!of_node_name_eq(port, "port"));
of_node_put(ports);
}
return port;
}
EXPORT_SYMBOL_GPL(omapdss_of_get_next_port);
struct device_node *
omapdss_of_get_next_endpoint(const struct device_node *parent,
struct device_node *prev)
{
struct device_node *ep = NULL;
if (!parent)
return NULL;
do {
ep = of_get_next_child(parent, prev);
if (!ep)
return NULL;
prev = ep;
} while (!of_node_name_eq(ep, "endpoint"));
return ep;
}
EXPORT_SYMBOL_GPL(omapdss_of_get_next_endpoint);
struct device_node *dss_of_port_get_parent_device(struct device_node *port)
{
struct device_node *np;

View File

@ -26,6 +26,7 @@
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/regulator/consumer.h>
#include <linux/suspend.h>
#include <linux/component.h>
@ -919,10 +920,7 @@ static int dss_init_ports(struct platform_device *pdev)
struct device_node *port;
int r, ret = 0;
if (parent == NULL)
return 0;
port = omapdss_of_get_next_port(parent, NULL);
port = of_graph_get_next_port(parent, NULL);
if (!port)
return 0;
@ -952,8 +950,9 @@ static int dss_init_ports(struct platform_device *pdev)
default:
break;
}
} while (!ret &&
(port = omapdss_of_get_next_port(parent, port)) != NULL);
port = of_graph_get_next_port(parent, port);
} while (!ret && port);
if (ret)
dss_uninit_ports(pdev);
@ -966,10 +965,7 @@ static void dss_uninit_ports(struct platform_device *pdev)
struct device_node *parent = pdev->dev.of_node;
struct device_node *port;
if (parent == NULL)
return;
port = omapdss_of_get_next_port(parent, NULL);
port = of_graph_get_next_port(parent, NULL);
if (!port)
return;
@ -1000,7 +996,9 @@ static void dss_uninit_ports(struct platform_device *pdev)
default:
break;
}
} while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
port = of_graph_get_next_port(parent, port);
} while (port);
}
static int dss_video_pll_probe(struct platform_device *pdev)

View File

@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/string.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/component.h>
#include <video/omapfb_dss.h>
@ -405,7 +406,7 @@ int sdi_init_port(struct platform_device *pdev, struct device_node *port)
u32 datapairs;
int r;
ep = omapdss_of_get_next_endpoint(port, NULL);
ep = of_graph_get_next_port_endpoint(port, NULL);
if (!ep)
return 0;

View File

@ -17,7 +17,7 @@ enum {
struct logic_pio_hwaddr {
struct list_head list;
struct fwnode_handle *fwnode;
const struct fwnode_handle *fwnode;
resource_size_t hw_start;
resource_size_t io_start;
resource_size_t size; /* range size populated */
@ -110,8 +110,8 @@ void logic_outsl(unsigned long addr, const void *buffer, unsigned int count);
#endif /* CONFIG_INDIRECT_PIO */
#define MMIO_UPPER_LIMIT (IO_SPACE_LIMIT - PIO_INDIRECT_SIZE)
struct logic_pio_hwaddr *find_io_range_by_fwnode(struct fwnode_handle *fwnode);
unsigned long logic_pio_trans_hwaddr(struct fwnode_handle *fwnode,
struct logic_pio_hwaddr *find_io_range_by_fwnode(const struct fwnode_handle *fwnode);
unsigned long logic_pio_trans_hwaddr(const struct fwnode_handle *fwnode,
resource_size_t hw_addr, resource_size_t size);
int logic_pio_register_range(struct logic_pio_hwaddr *newrange);
void logic_pio_unregister_range(struct logic_pio_hwaddr *range);

View File

@ -357,7 +357,7 @@ extern struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
extern struct device_node *of_cpu_device_node_get(int cpu);
extern int of_cpu_node_to_id(struct device_node *np);
extern struct device_node *of_get_next_cpu_node(struct device_node *prev);
extern struct device_node *of_get_cpu_state_node(struct device_node *cpu_node,
extern struct device_node *of_get_cpu_state_node(const struct device_node *cpu_node,
int index);
extern u64 of_get_cpu_hwid(struct device_node *cpun, unsigned int thread);
@ -395,7 +395,7 @@ extern int of_phandle_iterator_args(struct of_phandle_iterator *it,
int size);
extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align));
extern int of_alias_get_id(struct device_node *np, const char *stem);
extern int of_alias_get_id(const struct device_node *np, const char *stem);
extern int of_alias_get_highest_id(const char *stem);
bool of_machine_compatible_match(const char *const *compats);
@ -435,7 +435,7 @@ extern int of_detach_node(struct device_node *);
* of_property_for_each_u32(np, "propname", u)
* printk("U32 value: %x\n", u);
*/
const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
const __be32 *of_prop_next_u32(const struct property *prop, const __be32 *cur,
u32 *pu);
/*
* struct property *prop;
@ -444,11 +444,11 @@ const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
* of_property_for_each_string(np, "propname", prop, s)
* printk("String value: %s\n", s);
*/
const char *of_prop_next_string(struct property *prop, const char *cur);
const char *of_prop_next_string(const struct property *prop, const char *cur);
bool of_console_check(struct device_node *dn, char *name, int index);
bool of_console_check(const struct device_node *dn, char *name, int index);
int of_map_id(struct device_node *np, u32 id,
int of_map_id(const struct device_node *np, u32 id,
const char *map_name, const char *map_mask_name,
struct device_node **target, u32 *id_out);
@ -826,13 +826,13 @@ static inline bool of_console_check(const struct device_node *dn, const char *na
return false;
}
static inline const __be32 *of_prop_next_u32(struct property *prop,
static inline const __be32 *of_prop_next_u32(const struct property *prop,
const __be32 *cur, u32 *pu)
{
return NULL;
}
static inline const char *of_prop_next_string(struct property *prop,
static inline const char *of_prop_next_string(const struct property *prop,
const char *cur)
{
return NULL;
@ -871,7 +871,7 @@ static inline void of_property_clear_flag(struct property *p, unsigned long flag
{
}
static inline int of_map_id(struct device_node *np, u32 id,
static inline int of_map_id(const struct device_node *np, u32 id,
const char *map_name, const char *map_mask_name,
struct device_node **target, u32 *id_out)
{
@ -899,7 +899,7 @@ static inline const void *of_device_get_match_data(const struct device *dev)
#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
#endif
static inline int of_prop_val_eq(struct property *p1, struct property *p2)
static inline int of_prop_val_eq(const struct property *p1, const struct property *p2)
{
return p1->length == p2->length &&
!memcmp(p1->value, p2->value, (size_t)p1->length);
@ -1252,7 +1252,7 @@ static inline int of_property_read_string_index(const struct device_node *np,
static inline bool of_property_read_bool(const struct device_node *np,
const char *propname)
{
struct property *prop = of_find_property(np, propname, NULL);
const struct property *prop = of_find_property(np, propname, NULL);
return prop ? true : false;
}
@ -1430,7 +1430,7 @@ static inline int of_property_read_s32(const struct device_node *np,
err = of_phandle_iterator_next(it))
#define of_property_for_each_u32(np, propname, u) \
for (struct {struct property *prop; const __be32 *item; } _it = \
for (struct {const struct property *prop; const __be32 *item; } _it = \
{of_find_property(np, propname, NULL), \
of_prop_next_u32(_it.prop, NULL, &u)}; \
_it.item; \
@ -1734,7 +1734,7 @@ struct of_overlay_notify_data {
#ifdef CONFIG_OF_OVERLAY
int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size,
int *ovcs_id, struct device_node *target_base);
int *ovcs_id, const struct device_node *target_base);
int of_overlay_remove(int *ovcs_id);
int of_overlay_remove_all(void);
@ -1744,7 +1744,7 @@ int of_overlay_notifier_unregister(struct notifier_block *nb);
#else
static inline int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size,
int *ovcs_id, struct device_node *target_base)
int *ovcs_id, const struct device_node *target_base)
{
return -ENOTSUPP;
}

View File

@ -10,7 +10,7 @@ struct of_bus;
struct of_pci_range_parser {
struct device_node *node;
struct of_bus *bus;
const struct of_bus *bus;
const __be32 *range;
const __be32 *end;
int na;
@ -83,8 +83,8 @@ extern struct of_pci_range *of_pci_range_parser_one(
struct of_pci_range *range);
extern int of_pci_address_to_resource(struct device_node *dev, int bar,
struct resource *r);
extern int of_pci_range_to_resource(struct of_pci_range *range,
struct device_node *np,
extern int of_pci_range_to_resource(const struct of_pci_range *range,
const struct device_node *np,
struct resource *res);
extern int of_range_to_resource(struct device_node *np, int index,
struct resource *res);

View File

@ -31,6 +31,7 @@ extern void *of_fdt_unflatten_tree(const unsigned long *blob,
extern int __initdata dt_root_addr_cells;
extern int __initdata dt_root_size_cells;
extern void *initial_boot_params;
extern phys_addr_t initial_boot_params_pa;
extern char __dtb_start[];
extern char __dtb_end[];
@ -70,8 +71,8 @@ extern u64 dt_mem_next_cell(int s, const __be32 **cellp);
/* Early flat tree scan hooks */
extern int early_init_dt_scan_root(void);
extern bool early_init_dt_scan(void *params);
extern bool early_init_dt_verify(void *params);
extern bool early_init_dt_scan(void *dt_virt, phys_addr_t dt_phys);
extern bool early_init_dt_verify(void *dt_virt, phys_addr_t dt_phys);
extern void early_init_dt_scan_nodes(void);
extern const char *of_flat_dt_get_machine_name(void);

View File

@ -11,6 +11,7 @@
#ifndef __LINUX_OF_GRAPH_H
#define __LINUX_OF_GRAPH_H
#include <linux/cleanup.h>
#include <linux/types.h>
#include <linux/errno.h>
@ -37,14 +38,43 @@ struct of_endpoint {
for (child = of_graph_get_next_endpoint(parent, NULL); child != NULL; \
child = of_graph_get_next_endpoint(parent, child))
/**
* for_each_of_graph_port - iterate over every port in a device or ports node
* @parent: parent device or ports node containing port
* @child: loop variable pointing to the current port node
*
* When breaking out of the loop, and continue to use the @child, you need to
* use return_ptr(@child) or no_free_ptr(@child) not to call __free() for it.
*/
#define for_each_of_graph_port(parent, child) \
for (struct device_node *child __free(device_node) = of_graph_get_next_port(parent, NULL);\
child != NULL; child = of_graph_get_next_port(parent, child))
/**
* for_each_of_graph_port_endpoint - iterate over every endpoint in a port node
* @parent: parent port node
* @child: loop variable pointing to the current endpoint node
*
* When breaking out of the loop, and continue to use the @child, you need to
* use return_ptr(@child) or no_free_ptr(@child) not to call __free() for it.
*/
#define for_each_of_graph_port_endpoint(parent, child) \
for (struct device_node *child __free(device_node) = of_graph_get_next_port_endpoint(parent, NULL);\
child != NULL; child = of_graph_get_next_port_endpoint(parent, child))
#ifdef CONFIG_OF
bool of_graph_is_present(const struct device_node *node);
int of_graph_parse_endpoint(const struct device_node *node,
struct of_endpoint *endpoint);
unsigned int of_graph_get_endpoint_count(const struct device_node *np);
unsigned int of_graph_get_port_count(struct device_node *np);
struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id);
struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
struct device_node *previous);
struct device_node *of_graph_get_next_port(const struct device_node *parent,
struct device_node *port);
struct device_node *of_graph_get_next_port_endpoint(const struct device_node *port,
struct device_node *prev);
struct device_node *of_graph_get_endpoint_by_regs(
const struct device_node *parent, int port_reg, int reg);
struct device_node *of_graph_get_remote_endpoint(
@ -73,6 +103,11 @@ static inline unsigned int of_graph_get_endpoint_count(const struct device_node
return 0;
}
static inline unsigned int of_graph_get_port_count(struct device_node *np)
{
return 0;
}
static inline struct device_node *of_graph_get_port_by_id(
struct device_node *node, u32 id)
{
@ -86,6 +121,20 @@ static inline struct device_node *of_graph_get_next_endpoint(
return NULL;
}
static inline struct device_node *of_graph_get_next_port(
const struct device_node *parent,
struct device_node *previous)
{
return NULL;
}
static inline struct device_node *of_graph_get_next_port_endpoint(
const struct device_node *parent,
struct device_node *previous)
{
return NULL;
}
static inline struct device_node *of_graph_get_endpoint_by_regs(
const struct device_node *parent, int port_reg, int reg)
{

View File

@ -48,12 +48,12 @@ extern int of_irq_to_resource_table(struct device_node *dev,
struct resource *res, int nr_irqs);
extern struct device_node *of_irq_find_parent(struct device_node *child);
extern struct irq_domain *of_msi_get_domain(struct device *dev,
struct device_node *np,
const struct device_node *np,
enum irq_domain_bus_token token);
extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev,
u32 id,
u32 bus_token);
extern void of_msi_configure(struct device *dev, struct device_node *np);
extern void of_msi_configure(struct device *dev, const struct device_node *np);
u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in);
#else
static inline void of_irq_init(const struct of_device_id *matches)

View File

@ -1556,7 +1556,7 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
void *alignf_data);
int pci_register_io_range(struct fwnode_handle *fwnode, phys_addr_t addr,
int pci_register_io_range(const struct fwnode_handle *fwnode, phys_addr_t addr,
resource_size_t size);
unsigned long pci_address_to_pio(phys_addr_t addr);
phys_addr_t pci_pio_to_address(unsigned long pio);
@ -2019,7 +2019,7 @@ static inline int pci_request_regions(struct pci_dev *dev, const char *res_name)
{ return -EIO; }
static inline void pci_release_regions(struct pci_dev *dev) { }
static inline int pci_register_io_range(struct fwnode_handle *fwnode,
static inline int pci_register_io_range(const struct fwnode_handle *fwnode,
phys_addr_t addr, resource_size_t size)
{ return -EINVAL; }

View File

@ -811,14 +811,6 @@ static inline bool omapdss_device_is_enabled(struct omap_dss_device *dssdev)
return dssdev->state == OMAP_DSS_DISPLAY_ACTIVE;
}
struct device_node *
omapdss_of_get_next_port(const struct device_node *parent,
struct device_node *prev);
struct device_node *
omapdss_of_get_next_endpoint(const struct device_node *parent,
struct device_node *prev);
struct omap_dss_device *
omapdss_of_find_source_for_first_ep(struct device_node *node);
#else

View File

@ -122,7 +122,7 @@ void logic_pio_unregister_range(struct logic_pio_hwaddr *range)
*
* Traverse the io_range_list to find the registered node for @fwnode.
*/
struct logic_pio_hwaddr *find_io_range_by_fwnode(struct fwnode_handle *fwnode)
struct logic_pio_hwaddr *find_io_range_by_fwnode(const struct fwnode_handle *fwnode)
{
struct logic_pio_hwaddr *range, *found_range = NULL;
@ -186,7 +186,7 @@ resource_size_t logic_pio_to_hwaddr(unsigned long pio)
*
* Returns Logical PIO value if successful, ~0UL otherwise
*/
unsigned long logic_pio_trans_hwaddr(struct fwnode_handle *fwnode,
unsigned long logic_pio_trans_hwaddr(const struct fwnode_handle *fwnode,
resource_size_t addr, resource_size_t size)
{
struct logic_pio_hwaddr *range;

View File

@ -372,7 +372,7 @@ static int __graph_for_each_link(struct simple_util_priv *priv,
cpu_port = it.node;
/* loop for all CPU endpoint */
for_each_child_of_node_scoped(cpu_port, cpu_ep) {
for_each_of_graph_port_endpoint(cpu_port, cpu_ep) {
/* get codec */
codec_ep = of_graph_get_remote_endpoint(cpu_ep);
codec_port = ep_to_port(codec_ep);

View File

@ -234,8 +234,6 @@ enum graph_type {
#define GRAPH_NODENAME_DPCM "dpcm"
#define GRAPH_NODENAME_C2C "codec2codec"
#define port_to_endpoint(port) of_get_child_by_name(port, "endpoint")
#define ep_to_port(ep) of_get_parent(ep)
static struct device_node *port_to_ports(struct device_node *port)
{
@ -354,14 +352,9 @@ static struct device_node *graph_get_next_multi_ep(struct device_node **port)
* port@1 { rep1 };
* };
*/
do {
*port = of_get_next_child(ports, *port);
if (!*port)
break;
} while (!of_node_name_eq(*port, "port"));
*port = of_graph_get_next_port(ports, *port);
if (*port) {
ep = port_to_endpoint(*port);
ep = of_graph_get_next_port_endpoint(*port, NULL);
rep = of_graph_get_remote_endpoint(ep);
}
@ -533,67 +526,66 @@ static int graph_parse_node_multi_nm(struct snd_soc_dai_link *dai_link,
* };
* };
*/
struct device_node *mcpu_ep = port_to_endpoint(mcpu_port);
struct device_node *mcpu_ep_n = mcpu_ep;
struct device_node *mcpu_port_top = of_get_next_child(port_to_ports(mcpu_port), NULL);
struct device_node *mcpu_ep_top = port_to_endpoint(mcpu_port_top);
struct device_node *mcpu_ep = of_graph_get_next_port_endpoint(mcpu_port, NULL);
struct device_node *mcpu_ports = port_to_ports(mcpu_port);
struct device_node *mcpu_port_top = of_graph_get_next_port(mcpu_ports, NULL);
struct device_node *mcpu_ep_top = of_graph_get_next_port_endpoint(mcpu_port_top, NULL);
struct device_node *mcodec_ep_top = of_graph_get_remote_endpoint(mcpu_ep_top);
struct device_node *mcodec_port_top = ep_to_port(mcodec_ep_top);
struct device_node *mcodec_ports = port_to_ports(mcodec_port_top);
int nm_max = max(dai_link->num_cpus, dai_link->num_codecs);
int ret = -EINVAL;
int ret = 0;
if (cpu_idx > dai_link->num_cpus)
if (cpu_idx > dai_link->num_cpus) {
ret = -EINVAL;
goto mcpu_err;
}
while (1) {
for_each_of_graph_port_endpoint(mcpu_port, mcpu_ep_n) {
struct device_node *mcodec_ep_n;
struct device_node *mcodec_port_i;
struct device_node *mcodec_port;
int codec_idx;
/* ignore 1st ep which is for element */
if (mcpu_ep_n == mcpu_ep)
continue;
if (*nm_idx > nm_max)
break;
mcpu_ep_n = of_get_next_child(mcpu_port, mcpu_ep_n);
if (!mcpu_ep_n) {
ret = 0;
break;
}
mcodec_ep_n = of_graph_get_remote_endpoint(mcpu_ep_n);
mcodec_port = ep_to_port(mcodec_ep_n);
if (mcodec_ports != port_to_ports(mcodec_port))
if (mcodec_ports != port_to_ports(mcodec_port)) {
ret = -EINVAL;
goto mcpu_err;
codec_idx = 0;
mcodec_port_i = of_get_next_child(mcodec_ports, NULL);
while (1) {
if (codec_idx > dai_link->num_codecs)
goto mcodec_err;
mcodec_port_i = of_get_next_child(mcodec_ports, mcodec_port_i);
if (!mcodec_port_i)
goto mcodec_err;
if (mcodec_port_i == mcodec_port)
break;
codec_idx++;
}
dai_link->ch_maps[*nm_idx].cpu = cpu_idx;
dai_link->ch_maps[*nm_idx].codec = codec_idx;
codec_idx = 0;
ret = -EINVAL;
for_each_of_graph_port(mcodec_ports, mcodec_port_i) {
(*nm_idx)++;
/* ignore 1st port which is for pair connection */
if (mcodec_port_top == mcodec_port_i)
continue;
of_node_put(mcodec_port_i);
mcodec_err:
if (codec_idx > dai_link->num_codecs)
break;
if (mcodec_port_i == mcodec_port) {
dai_link->ch_maps[*nm_idx].cpu = cpu_idx;
dai_link->ch_maps[*nm_idx].codec = codec_idx;
(*nm_idx)++;
ret = 0;
break;
}
codec_idx++;
}
of_node_put(mcodec_port);
of_node_put(mcpu_ep_n);
of_node_put(mcodec_ep_n);
if (ret < 0)
break;
}
mcpu_err:
of_node_put(mcpu_ep);
@ -677,7 +669,7 @@ static int graph_parse_node_single(struct simple_util_priv *priv,
struct device_node *port,
struct link_info *li, int is_cpu)
{
struct device_node *ep = port_to_endpoint(port);
struct device_node *ep = of_graph_get_next_port_endpoint(port, NULL);
int ret = __graph_parse_node(priv, gtype, ep, li, is_cpu, 0);
of_node_put(ep);
@ -772,7 +764,7 @@ static void graph_link_init(struct simple_util_priv *priv,
of_node_put(port_cpu);
port_cpu = ep_to_port(ep_cpu);
} else {
ep_cpu = port_to_endpoint(port_cpu);
ep_cpu = of_graph_get_next_port_endpoint(port_cpu, NULL);
}
ports_cpu = port_to_ports(port_cpu);
@ -782,7 +774,7 @@ static void graph_link_init(struct simple_util_priv *priv,
of_node_put(port_cpu);
port_codec = ep_to_port(ep_codec);
} else {
ep_codec = port_to_endpoint(port_codec);
ep_codec = of_graph_get_next_port_endpoint(port_codec, NULL);
}
ports_codec = port_to_ports(port_codec);
@ -853,7 +845,7 @@ int audio_graph2_link_normal(struct simple_util_priv *priv,
struct link_info *li)
{
struct device_node *cpu_port = lnk;
struct device_node *cpu_ep = port_to_endpoint(cpu_port);
struct device_node *cpu_ep = of_graph_get_next_port_endpoint(cpu_port, NULL);
struct device_node *codec_port = of_graph_get_remote_port(cpu_ep);
int ret;
@ -886,7 +878,7 @@ int audio_graph2_link_dpcm(struct simple_util_priv *priv,
struct device_node *lnk,
struct link_info *li)
{
struct device_node *ep = port_to_endpoint(lnk);
struct device_node *ep = of_graph_get_next_port_endpoint(lnk, NULL);
struct device_node *rep = of_graph_get_remote_endpoint(ep);
struct device_node *cpu_port = NULL;
struct device_node *codec_port = NULL;
@ -1010,7 +1002,7 @@ int audio_graph2_link_c2c(struct simple_util_priv *priv,
of_node_get(lnk);
port0 = lnk;
ports = port_to_ports(port0);
port1 = of_get_next_child(ports, lnk);
port1 = of_graph_get_next_port(ports, port0);
/*
* Card2 can use original Codec2Codec settings if DT has.
@ -1040,8 +1032,8 @@ int audio_graph2_link_c2c(struct simple_util_priv *priv,
dai_link->num_c2c_params = 1;
}
ep0 = port_to_endpoint(port0);
ep1 = port_to_endpoint(port1);
ep0 = of_graph_get_next_port_endpoint(port0, NULL);
ep1 = of_graph_get_next_port_endpoint(port1, NULL);
codec0_port = of_graph_get_remote_port(ep0);
codec1_port = of_graph_get_remote_port(ep1);
@ -1147,7 +1139,7 @@ static int graph_counter(struct device_node *lnk)
* CPU/Codec = N:M case has many endpoints.
* We can't use of_graph_get_endpoint_count() here
*/
return of_get_child_count(ports) - 1;
return of_graph_get_port_count(ports) - 1;
}
/*
* Single CPU / Codec
@ -1161,7 +1153,7 @@ static int graph_count_normal(struct simple_util_priv *priv,
struct link_info *li)
{
struct device_node *cpu_port = lnk;
struct device_node *cpu_ep = port_to_endpoint(cpu_port);
struct device_node *cpu_ep = of_graph_get_next_port_endpoint(cpu_port, NULL);
struct device_node *codec_port = of_graph_get_remote_port(cpu_ep);
/*
@ -1189,7 +1181,7 @@ static int graph_count_dpcm(struct simple_util_priv *priv,
struct device_node *lnk,
struct link_info *li)
{
struct device_node *ep = port_to_endpoint(lnk);
struct device_node *ep = of_graph_get_next_port_endpoint(lnk, NULL);
struct device_node *rport = of_graph_get_remote_port(ep);
/*
@ -1231,9 +1223,9 @@ static int graph_count_c2c(struct simple_util_priv *priv,
{
struct device_node *ports = port_to_ports(lnk);
struct device_node *port0 = lnk;
struct device_node *port1 = of_get_next_child(ports, of_node_get(lnk));
struct device_node *ep0 = port_to_endpoint(port0);
struct device_node *ep1 = port_to_endpoint(port1);
struct device_node *port1 = of_graph_get_next_port(ports, of_node_get(port0));
struct device_node *ep0 = of_graph_get_next_port_endpoint(port0, NULL);
struct device_node *ep1 = of_graph_get_next_port_endpoint(port1, NULL);
struct device_node *codec0 = of_graph_get_remote_port(ep0);
struct device_node *codec1 = of_graph_get_remote_port(ep1);

View File

@ -521,7 +521,6 @@ static int test_driver_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
struct device_node *ep;
const struct test_adata *adata = of_device_get_match_data(&pdev->dev);
struct snd_soc_component_driver *cdriv;
struct snd_soc_dai_driver *ddriv;
@ -591,7 +590,7 @@ static int test_driver_probe(struct platform_device *pdev)
}
i = 0;
for_each_endpoint_of_node(node, ep) {
for_each_of_graph_port(node, port) {
snprintf(dname[i].name, TEST_NAME_LEN, "%s.%d", node->name, i);
ddriv[i].name = dname[i].name;