Devicetree fixes for v5.12, take 2:
- Fix fw_devlink failure with ".*,nr-gpios" properties - Doc link reference fixes from Mauro - Fixes for unaligned FDT handling found on OpenRisc. First, avoid crash with better error handling when unflattening an unaligned FDT. Second, fix memory allocations for FDTs to ensure alignment. -----BEGIN PGP SIGNATURE----- iQJEBAABCgAuFiEEktVUI4SxYhzZyEuo+vtdtY28YcMFAmBwq7UQHHJvYmhAa2Vy bmVsLm9yZwAKCRD6+121jbxhw1IMD/4mnveo0vrzSBnB8Gj9MQ1NIPumUIpc/VN6 NtfwZgemupEQM66TMQiHzeHSmQ7tY6SPRJnIlqZvWTvmeHYDOtrTtByR4BQHQb+E Foz6a+4aFQjo2Wc4LJG7Y+25sg+/outLuC8dBARpbi7uCEKlCOaVCpyMhR+61uvS JIqpNCbwKgos9aSTsNDpiturKlw9qMRq3jIITF/YS8R1QXuVgrDj6X7HDpm0iVxM IUZZz6Qe6lSsJodVNV+8sMIIF4I2pCfNlUo46W5q80VzerHTlp7aArFQdSpvCyHF StVS1a3ksYqycIsW90zgo+v3DrnKI6OSe9LqLsYOHwHCuu1G5t02RqoZ2/oYRZJX Ho1t+12AZpkcQ1DSm+nrawLGr7VJ9eFToGFhMeSIRiQebdKDWYbIJe21NSaEBYtO FTj5cigBopJOE7WrfIPuCZwfHokYqZeti/vaCYc5VkgVB25gVRsOowosE+Z7S2Rm xJvMDnKSCQprUbX6Q1w+9CZ79Ru/t/K/Xq0wakbhnFI+jiGhBbjfEyBfzCVUZcQq Jhl42KQPLCYeLpkuwFZBcRLZzOQU6xZHxWU8FfRulpMefIvDHFOvyNntElXrHSgg niMwCUY042eHXj/Ptg2cUYsYugiAik6+eEMtqX0tb61a1+n7UVztDGfjeWlbaIzP ol+Ba+6wCg== =7rNZ -----END PGP SIGNATURE----- Merge tag 'devicetree-fixes-for-5.12-2' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux Pull devicetree fixes from Rob Herring: - Fix fw_devlink failure with ".*,nr-gpios" properties - Doc link reference fixes from Mauro - Fixes for unaligned FDT handling found on OpenRisc. First, avoid crash with better error handling when unflattening an unaligned FDT. Second, fix memory allocations for FDTs to ensure alignment. * tag 'devicetree-fixes-for-5.12-2' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: of: property: fw_devlink: do not link ".*,nr-gpios" dt-bindings:iio:adc: update motorola,cpcap-adc.yaml reference dt-bindings: fix references for iio-bindings.txt dt-bindings: don't use ../dir for doc references of: unittest: overlay: ensure proper alignment of copied FDT of: properly check for error returned by fdt_get_name()
This commit is contained in:
commit
a2521822bd
@ -32,7 +32,7 @@ Optional node properties:
|
||||
- "#thermal-sensor-cells" Used to expose itself to thermal fw.
|
||||
|
||||
Read more about iio bindings at
|
||||
Documentation/devicetree/bindings/iio/iio-bindings.txt
|
||||
https://github.com/devicetree-org/dt-schema/blob/master/schemas/iio/
|
||||
|
||||
Example:
|
||||
ncp15wb473@0 {
|
||||
|
@ -14,8 +14,9 @@ description: >
|
||||
Industrial I/O subsystem bindings for ADC controller found in
|
||||
Ingenic JZ47xx SoCs.
|
||||
|
||||
ADC clients must use the format described in iio-bindings.txt, giving
|
||||
a phandle and IIO specifier pair ("io-channels") to the ADC controller.
|
||||
ADC clients must use the format described in
|
||||
https://github.com/devicetree-org/dt-schema/blob/master/schemas/iio/iio-consumer.yaml,
|
||||
giving a phandle and IIO specifier pair ("io-channels") to the ADC controller.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
|
@ -24,7 +24,9 @@ properties:
|
||||
description: >
|
||||
List of phandle and IIO specifier pairs.
|
||||
Each pair defines one ADC channel to which a joystick axis is connected.
|
||||
See Documentation/devicetree/bindings/iio/iio-bindings.txt for details.
|
||||
See
|
||||
https://github.com/devicetree-org/dt-schema/blob/master/schemas/iio/iio-consumer.yaml
|
||||
for details.
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
@ -5,7 +5,10 @@ Required properties:
|
||||
- compatible: must be "resistive-adc-touch"
|
||||
The device must be connected to an ADC device that provides channels for
|
||||
position measurement and optional pressure.
|
||||
Refer to ../iio/iio-bindings.txt for details
|
||||
Refer to
|
||||
https://github.com/devicetree-org/dt-schema/blob/master/schemas/iio/iio-consumer.yaml
|
||||
for details
|
||||
|
||||
- iio-channels: must have at least two channels connected to an ADC device.
|
||||
These should correspond to the channels exposed by the ADC device and should
|
||||
have the right index as the ADC device registers them. These channels
|
||||
|
@ -72,7 +72,9 @@ Required child device properties:
|
||||
pwm|regulator|rtc|sysctrl|usb]";
|
||||
|
||||
A few child devices require ADC channels from the GPADC node. Those follow the
|
||||
standard bindings from iio/iio-bindings.txt and iio/adc/adc.txt
|
||||
standard bindings from
|
||||
https://github.com/devicetree-org/dt-schema/blob/master/schemas/iio/iio-consumer.yaml
|
||||
and Documentation/devicetree/bindings/iio/adc/adc.yaml
|
||||
|
||||
abx500-temp : io-channels "aux1" and "aux2" for measuring external
|
||||
temperatures.
|
||||
|
@ -16,14 +16,14 @@ Optional subnodes:
|
||||
The sub-functions of CPCAP get their own node with their own compatible values,
|
||||
which are described in the following files:
|
||||
|
||||
- ../power/supply/cpcap-battery.txt
|
||||
- ../power/supply/cpcap-charger.txt
|
||||
- ../regulator/cpcap-regulator.txt
|
||||
- ../phy/phy-cpcap-usb.txt
|
||||
- ../input/cpcap-pwrbutton.txt
|
||||
- ../rtc/cpcap-rtc.txt
|
||||
- ../leds/leds-cpcap.txt
|
||||
- ../iio/adc/cpcap-adc.txt
|
||||
- Documentation/devicetree/bindings/power/supply/cpcap-battery.txt
|
||||
- Documentation/devicetree/bindings/power/supply/cpcap-charger.txt
|
||||
- Documentation/devicetree/bindings/regulator/cpcap-regulator.txt
|
||||
- Documentation/devicetree/bindings/phy/phy-cpcap-usb.txt
|
||||
- Documentation/devicetree/bindings/input/cpcap-pwrbutton.txt
|
||||
- Documentation/devicetree/bindings/rtc/cpcap-rtc.txt
|
||||
- Documentation/devicetree/bindings/leds/leds-cpcap.txt
|
||||
- Documentation/devicetree/bindings/iio/adc/motorola,cpcap-adc.yaml
|
||||
|
||||
The only exception is the audio codec. Instead of a compatible value its
|
||||
node must be named "audio-codec".
|
||||
|
@ -205,7 +205,7 @@ static void populate_properties(const void *blob,
|
||||
*pprev = NULL;
|
||||
}
|
||||
|
||||
static bool populate_node(const void *blob,
|
||||
static int populate_node(const void *blob,
|
||||
int offset,
|
||||
void **mem,
|
||||
struct device_node *dad,
|
||||
@ -214,24 +214,24 @@ static bool populate_node(const void *blob,
|
||||
{
|
||||
struct device_node *np;
|
||||
const char *pathp;
|
||||
unsigned int l, allocl;
|
||||
int len;
|
||||
|
||||
pathp = fdt_get_name(blob, offset, &l);
|
||||
pathp = fdt_get_name(blob, offset, &len);
|
||||
if (!pathp) {
|
||||
*pnp = NULL;
|
||||
return false;
|
||||
return len;
|
||||
}
|
||||
|
||||
allocl = ++l;
|
||||
len++;
|
||||
|
||||
np = unflatten_dt_alloc(mem, sizeof(struct device_node) + allocl,
|
||||
np = unflatten_dt_alloc(mem, sizeof(struct device_node) + len,
|
||||
__alignof__(struct device_node));
|
||||
if (!dryrun) {
|
||||
char *fn;
|
||||
of_node_init(np);
|
||||
np->full_name = fn = ((char *)np) + sizeof(*np);
|
||||
|
||||
memcpy(fn, pathp, l);
|
||||
memcpy(fn, pathp, len);
|
||||
|
||||
if (dad != NULL) {
|
||||
np->parent = dad;
|
||||
@ -295,6 +295,7 @@ static int unflatten_dt_nodes(const void *blob,
|
||||
struct device_node *nps[FDT_MAX_DEPTH];
|
||||
void *base = mem;
|
||||
bool dryrun = !base;
|
||||
int ret;
|
||||
|
||||
if (nodepp)
|
||||
*nodepp = NULL;
|
||||
@ -322,9 +323,10 @@ static int unflatten_dt_nodes(const void *blob,
|
||||
!of_fdt_device_is_available(blob, offset))
|
||||
continue;
|
||||
|
||||
if (!populate_node(blob, offset, &mem, nps[depth],
|
||||
&nps[depth+1], dryrun))
|
||||
return mem - base;
|
||||
ret = populate_node(blob, offset, &mem, nps[depth],
|
||||
&nps[depth+1], dryrun);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!dryrun && nodepp && !*nodepp)
|
||||
*nodepp = nps[depth+1];
|
||||
@ -372,6 +374,10 @@ void *__unflatten_device_tree(const void *blob,
|
||||
{
|
||||
int size;
|
||||
void *mem;
|
||||
int ret;
|
||||
|
||||
if (mynodes)
|
||||
*mynodes = NULL;
|
||||
|
||||
pr_debug(" -> unflatten_device_tree()\n");
|
||||
|
||||
@ -392,7 +398,7 @@ void *__unflatten_device_tree(const void *blob,
|
||||
|
||||
/* First pass, scan for size */
|
||||
size = unflatten_dt_nodes(blob, NULL, dad, NULL);
|
||||
if (size < 0)
|
||||
if (size <= 0)
|
||||
return NULL;
|
||||
|
||||
size = ALIGN(size, 4);
|
||||
@ -410,12 +416,16 @@ void *__unflatten_device_tree(const void *blob,
|
||||
pr_debug(" unflattening %p...\n", mem);
|
||||
|
||||
/* Second pass, do actual unflattening */
|
||||
unflatten_dt_nodes(blob, mem, dad, mynodes);
|
||||
ret = unflatten_dt_nodes(blob, mem, dad, mynodes);
|
||||
|
||||
if (be32_to_cpup(mem + size) != 0xdeadbeef)
|
||||
pr_warn("End of tree marker overwritten: %08x\n",
|
||||
be32_to_cpup(mem + size));
|
||||
|
||||
if (detached && mynodes) {
|
||||
if (ret <= 0)
|
||||
return NULL;
|
||||
|
||||
if (detached && mynodes && *mynodes) {
|
||||
of_node_set_flag(*mynodes, OF_DETACHED);
|
||||
pr_debug("unflattened tree is detached\n");
|
||||
}
|
||||
|
@ -8,6 +8,8 @@
|
||||
* Copyright (C) 1996-2005 Paul Mackerras.
|
||||
*/
|
||||
|
||||
#define FDT_ALIGN_SIZE 8
|
||||
|
||||
/**
|
||||
* struct alias_prop - Alias property in 'aliases' node
|
||||
* @link: List node to link the structure in aliases_lookup list
|
||||
|
@ -57,7 +57,7 @@ struct fragment {
|
||||
* struct overlay_changeset
|
||||
* @id: changeset identifier
|
||||
* @ovcs_list: list on which we are located
|
||||
* @fdt: FDT that was unflattened to create @overlay_tree
|
||||
* @fdt: base of memory allocated to hold aligned FDT that was unflattened to create @overlay_tree
|
||||
* @overlay_tree: expanded device tree that contains the fragment nodes
|
||||
* @count: count of fragment structures
|
||||
* @fragments: fragment nodes in the overlay expanded device tree
|
||||
@ -719,8 +719,8 @@ static struct device_node *find_target(struct device_node *info_node)
|
||||
/**
|
||||
* init_overlay_changeset() - initialize overlay changeset from overlay tree
|
||||
* @ovcs: Overlay changeset to build
|
||||
* @fdt: the FDT that was unflattened to create @tree
|
||||
* @tree: Contains all the overlay fragments and overlay fixup nodes
|
||||
* @fdt: base of memory allocated to hold aligned FDT that was unflattened to create @tree
|
||||
* @tree: Contains the overlay fragments and overlay fixup nodes
|
||||
*
|
||||
* Initialize @ovcs. Populate @ovcs->fragments with node information from
|
||||
* the top level of @tree. The relevant top level nodes are the fragment
|
||||
@ -873,7 +873,7 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs)
|
||||
* internal documentation
|
||||
*
|
||||
* of_overlay_apply() - Create and apply an overlay changeset
|
||||
* @fdt: the FDT that was unflattened to create @tree
|
||||
* @fdt: base of memory allocated to hold the aligned FDT
|
||||
* @tree: Expanded overlay device tree
|
||||
* @ovcs_id: Pointer to overlay changeset id
|
||||
*
|
||||
@ -953,7 +953,9 @@ static int of_overlay_apply(const void *fdt, struct device_node *tree,
|
||||
/*
|
||||
* after overlay_notify(), ovcs->overlay_tree related pointers may have
|
||||
* leaked to drivers, so can not kfree() tree, aka ovcs->overlay_tree;
|
||||
* and can not free fdt, aka ovcs->fdt
|
||||
* and can not free memory containing aligned fdt. The aligned fdt
|
||||
* is contained within the memory at ovcs->fdt, possibly at an offset
|
||||
* from ovcs->fdt.
|
||||
*/
|
||||
ret = overlay_notify(ovcs, OF_OVERLAY_PRE_APPLY);
|
||||
if (ret) {
|
||||
@ -1014,10 +1016,11 @@ out:
|
||||
int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size,
|
||||
int *ovcs_id)
|
||||
{
|
||||
const void *new_fdt;
|
||||
void *new_fdt;
|
||||
void *new_fdt_align;
|
||||
int ret;
|
||||
u32 size;
|
||||
struct device_node *overlay_root;
|
||||
struct device_node *overlay_root = NULL;
|
||||
|
||||
*ovcs_id = 0;
|
||||
ret = 0;
|
||||
@ -1036,11 +1039,14 @@ int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size,
|
||||
* Must create permanent copy of FDT because of_fdt_unflatten_tree()
|
||||
* will create pointers to the passed in FDT in the unflattened tree.
|
||||
*/
|
||||
new_fdt = kmemdup(overlay_fdt, size, GFP_KERNEL);
|
||||
new_fdt = kmalloc(size + FDT_ALIGN_SIZE, GFP_KERNEL);
|
||||
if (!new_fdt)
|
||||
return -ENOMEM;
|
||||
|
||||
of_fdt_unflatten_tree(new_fdt, NULL, &overlay_root);
|
||||
new_fdt_align = PTR_ALIGN(new_fdt, FDT_ALIGN_SIZE);
|
||||
memcpy(new_fdt_align, overlay_fdt, size);
|
||||
|
||||
of_fdt_unflatten_tree(new_fdt_align, NULL, &overlay_root);
|
||||
if (!overlay_root) {
|
||||
pr_err("unable to unflatten overlay_fdt\n");
|
||||
ret = -EINVAL;
|
||||
|
@ -1262,7 +1262,16 @@ DEFINE_SIMPLE_PROP(pinctrl7, "pinctrl-7", NULL)
|
||||
DEFINE_SIMPLE_PROP(pinctrl8, "pinctrl-8", NULL)
|
||||
DEFINE_SUFFIX_PROP(regulators, "-supply", NULL)
|
||||
DEFINE_SUFFIX_PROP(gpio, "-gpio", "#gpio-cells")
|
||||
DEFINE_SUFFIX_PROP(gpios, "-gpios", "#gpio-cells")
|
||||
|
||||
static struct device_node *parse_gpios(struct device_node *np,
|
||||
const char *prop_name, int index)
|
||||
{
|
||||
if (!strcmp_suffix(prop_name, ",nr-gpios"))
|
||||
return NULL;
|
||||
|
||||
return parse_suffix_prop_cells(np, prop_name, index, "-gpios",
|
||||
"#gpio-cells");
|
||||
}
|
||||
|
||||
static struct device_node *parse_iommu_maps(struct device_node *np,
|
||||
const char *prop_name, int index)
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-mux.h>
|
||||
@ -1408,7 +1409,8 @@ static void attach_node_and_children(struct device_node *np)
|
||||
static int __init unittest_data_add(void)
|
||||
{
|
||||
void *unittest_data;
|
||||
struct device_node *unittest_data_node, *np;
|
||||
void *unittest_data_align;
|
||||
struct device_node *unittest_data_node = NULL, *np;
|
||||
/*
|
||||
* __dtb_testcases_begin[] and __dtb_testcases_end[] are magically
|
||||
* created by cmd_dt_S_dtb in scripts/Makefile.lib
|
||||
@ -1417,21 +1419,29 @@ static int __init unittest_data_add(void)
|
||||
extern uint8_t __dtb_testcases_end[];
|
||||
const int size = __dtb_testcases_end - __dtb_testcases_begin;
|
||||
int rc;
|
||||
void *ret;
|
||||
|
||||
if (!size) {
|
||||
pr_warn("%s: No testcase data to attach; not running tests\n",
|
||||
__func__);
|
||||
pr_warn("%s: testcases is empty\n", __func__);
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
/* creating copy */
|
||||
unittest_data = kmemdup(__dtb_testcases_begin, size, GFP_KERNEL);
|
||||
unittest_data = kmalloc(size + FDT_ALIGN_SIZE, GFP_KERNEL);
|
||||
if (!unittest_data)
|
||||
return -ENOMEM;
|
||||
|
||||
of_fdt_unflatten_tree(unittest_data, NULL, &unittest_data_node);
|
||||
unittest_data_align = PTR_ALIGN(unittest_data, FDT_ALIGN_SIZE);
|
||||
memcpy(unittest_data_align, __dtb_testcases_begin, size);
|
||||
|
||||
ret = of_fdt_unflatten_tree(unittest_data_align, NULL, &unittest_data_node);
|
||||
if (!ret) {
|
||||
pr_warn("%s: unflatten testcases tree failed\n", __func__);
|
||||
kfree(unittest_data);
|
||||
return -ENODATA;
|
||||
}
|
||||
if (!unittest_data_node) {
|
||||
pr_warn("%s: No tree to attach; not running tests\n", __func__);
|
||||
pr_warn("%s: testcases tree is empty\n", __func__);
|
||||
kfree(unittest_data);
|
||||
return -ENODATA;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user