diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-07-18 04:07:31 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-07-18 04:07:31 +0300 |
commit | 0ffb8a4c96e55ecf0e572aec1a0220af3da84e22 (patch) | |
tree | ea497c6728d2b93b31f1f4535a1413a436a59683 /drivers/of | |
parent | 5b9ac6c2a735f5b1721e0bc7331f8707190f9ef6 (diff) | |
parent | 76be2f9823b10c07daf814cb6c732eb1456a0b9e (diff) | |
download | linux-0ffb8a4c96e55ecf0e572aec1a0220af3da84e22.tar.xz |
Merge tag 'devicetree-for-6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux
Pull devicetree updates from Rob Herring:
"DT Bindings:
- Convert and add a bunch of IBM FSI related bindings
- Add a new schema listing legacy compatibles which will (probably)
never be documented. This will silence various checks warning about
them.
- Add bindings for Sierra Wireless mangOH Green SPI IoT interface,
new Arm 2024 Cortex and Neoverse CPUs, QCom sc8180x PDC, QCom SDX75
GPI DMA, imx8mp/imx8qxp fsl,irqsteer, and Renesas RZ/G2UL CRU and
CSI-2 blocks
- Convert Spreadtrum sprd-timer, FSL cpm_qe, FSL fsl,ls-scfg-msi, FSL
q(b)man-*, FSL qoriq-mc, and img,pdc-wdt bindings to DT schema
- Drop obsolete stericsson,abx500.txt
DT core:
- Update dtc to upstream version v1.7.0-93-g1df7b047fe43
- Add support to run DT validation on DTs with applied overlays
- Add helper for creating boolean properties in dynamic nodes and use
that for dynamic PCI nodes
- Clean-up early parsing of '#{address,size}-cells'"
* tag 'devicetree-for-6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (39 commits)
dt-bindings: timer: sprd-timer: convert to YAML
dt-bindings: incomplete-devices: document devices without bindings
dt-bindings: trivial-devices: document the Sierra Wireless mangOH Green SPI IoT interface
scripts/dtc: Update to upstream version v1.7.0-93-g1df7b047fe43
dt-bindings: soc: fsl: Add fsl,ls1028a-reset for reset syscon node
dt-bindings: soc: fsl: cpm_qe: convert to yaml format
dt-bindings: i2c: i2c-fsi: Convert to json-schema
dt-bindings: fsi: Document the FSI Hub Controller
dt-bindings: fsi: Document the AST2700 FSI controller
dt-bindings: fsi: ast2600-fsi-master: Convert to json-schema
dt-bindings: fsi: ibm,i2cr-fsi-master: Reference common FSI controller
dt-bindings: fsi: Document the FSI controller common properties
dt-bindings: fsi: Document the IBM SBEFIFO engine
dt-bindings: fsi: p9-occ: Convert to json-schema
dt-bindings: fsi: Document the IBM SCOM engine
dt-bindings: fsi: fsi2spi: Document SPI controller child nodes
dt-bindings: interrupt-controller: convert fsl,ls-scfg-msi to yaml
dt-bindings: soc: fsl: Convert q(b)man-* to yaml format
dt-bindings: misc: fsl,qoriq-mc: convert to yaml format
dt-bindings: drop stale Anson Huang from maintainers
...
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/dynamic.c | 27 | ||||
-rw-r--r-- | drivers/of/fdt.c | 30 | ||||
-rw-r--r-- | drivers/of/unittest.c | 166 |
3 files changed, 197 insertions, 26 deletions
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index dda6092e6d3a..110104a936d9 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -984,7 +984,7 @@ EXPORT_SYMBOL_GPL(of_changeset_add_prop_string); int of_changeset_add_prop_string_array(struct of_changeset *ocs, struct device_node *np, const char *prop_name, - const char **str_array, size_t sz) + const char * const *str_array, size_t sz) { struct property prop; int i, ret; @@ -1047,3 +1047,28 @@ int of_changeset_add_prop_u32_array(struct of_changeset *ocs, return of_changeset_add_prop_helper(ocs, np, &prop); } EXPORT_SYMBOL_GPL(of_changeset_add_prop_u32_array); + +/** + * of_changeset_add_prop_bool - Add a boolean property (i.e. a property without + * any values) to a changeset. + * + * @ocs: changeset pointer + * @np: device node pointer + * @prop_name: name of the property to be added + * + * Create a boolean property and add it to a changeset. + * + * Return: 0 on success, a negative error value in case of an error. + */ +int of_changeset_add_prop_bool(struct of_changeset *ocs, struct device_node *np, + const char *prop_name) +{ + struct property prop; + + prop.name = (char *)prop_name; + prop.length = 0; + prop.value = NULL; + + return of_changeset_add_prop_helper(ocs, np, &prop); +} +EXPORT_SYMBOL_GPL(of_changeset_add_prop_bool); diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index a8a04f27915b..68103ad230ee 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -52,28 +52,7 @@ void __init of_fdt_limit_memory(int limit) int memory; int len; const void *val; - int nr_address_cells = OF_ROOT_NODE_ADDR_CELLS_DEFAULT; - int nr_size_cells = OF_ROOT_NODE_SIZE_CELLS_DEFAULT; - const __be32 *addr_prop; - const __be32 *size_prop; - int root_offset; - int cell_size; - - root_offset = fdt_path_offset(initial_boot_params, "/"); - if (root_offset < 0) - return; - - addr_prop = fdt_getprop(initial_boot_params, root_offset, - "#address-cells", NULL); - if (addr_prop) - nr_address_cells = fdt32_to_cpu(*addr_prop); - - size_prop = fdt_getprop(initial_boot_params, root_offset, - "#size-cells", NULL); - if (size_prop) - nr_size_cells = fdt32_to_cpu(*size_prop); - - cell_size = sizeof(uint32_t)*(nr_address_cells + nr_size_cells); + int cell_size = sizeof(uint32_t)*(dt_root_addr_cells + dt_root_size_cells); memory = fdt_path_offset(initial_boot_params, "/memory"); if (memory > 0) { @@ -1170,6 +1149,10 @@ bool __init early_init_dt_verify(void *params) initial_boot_params = params; of_fdt_crc32 = crc32_be(~0, initial_boot_params, fdt_totalsize(initial_boot_params)); + + /* Initialize {size,address}-cells info */ + early_init_dt_scan_root(); + return true; } @@ -1178,9 +1161,6 @@ void __init early_init_dt_scan_nodes(void) { int rc; - /* Initialize {size,address}-cells info */ - early_init_dt_scan_root(); - /* Retrieve various information from the /chosen node */ rc = early_init_dt_scan_chosen(boot_command_line); if (rc) diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 445ad13dab98..c830f346df45 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -917,6 +917,171 @@ static void __init of_unittest_changeset(void) #endif } +static void __init __maybe_unused changeset_check_string(struct device_node *np, + const char *prop_name, + const char *expected_str) +{ + const char *str; + int ret; + + ret = of_property_read_string(np, prop_name, &str); + if (unittest(ret == 0, "failed to read %s\n", prop_name)) + return; + + unittest(strcmp(str, expected_str) == 0, + "%s value mismatch (read '%s', exp '%s')\n", + prop_name, str, expected_str); +} + +static void __init __maybe_unused changeset_check_string_array(struct device_node *np, + const char *prop_name, + const char * const *expected_array, + unsigned int count) +{ + const char *str; + unsigned int i; + int ret; + int cnt; + + cnt = of_property_count_strings(np, prop_name); + if (unittest(cnt >= 0, "failed to get %s count\n", prop_name)) + return; + + if (unittest(cnt == count, + "%s count mismatch (read %d, exp %u)\n", + prop_name, cnt, count)) + return; + + for (i = 0; i < count; i++) { + ret = of_property_read_string_index(np, prop_name, i, &str); + if (unittest(ret == 0, "failed to read %s[%d]\n", prop_name, i)) + continue; + + unittest(strcmp(str, expected_array[i]) == 0, + "%s[%d] value mismatch (read '%s', exp '%s')\n", + prop_name, i, str, expected_array[i]); + } +} + +static void __init __maybe_unused changeset_check_u32(struct device_node *np, + const char *prop_name, + u32 expected_u32) +{ + u32 val32; + int ret; + + ret = of_property_read_u32(np, prop_name, &val32); + if (unittest(ret == 0, "failed to read %s\n", prop_name)) + return; + + unittest(val32 == expected_u32, + "%s value mismatch (read '%u', exp '%u')\n", + prop_name, val32, expected_u32); +} + +static void __init __maybe_unused changeset_check_u32_array(struct device_node *np, + const char *prop_name, + const u32 *expected_array, + unsigned int count) +{ + unsigned int i; + u32 val32; + int ret; + int cnt; + + cnt = of_property_count_u32_elems(np, prop_name); + if (unittest(cnt >= 0, "failed to get %s count\n", prop_name)) + return; + + if (unittest(cnt == count, + "%s count mismatch (read %d, exp %u)\n", + prop_name, cnt, count)) + return; + + for (i = 0; i < count; i++) { + ret = of_property_read_u32_index(np, prop_name, i, &val32); + if (unittest(ret == 0, "failed to read %s[%d]\n", prop_name, i)) + continue; + + unittest(val32 == expected_array[i], + "%s[%d] value mismatch (read '%u', exp '%u')\n", + prop_name, i, val32, expected_array[i]); + } +} + +static void __init __maybe_unused changeset_check_bool(struct device_node *np, + const char *prop_name) +{ + unittest(of_property_read_bool(np, prop_name), + "%s value mismatch (read 'false', exp 'true')\n", prop_name); +} + +static void __init of_unittest_changeset_prop(void) +{ +#ifdef CONFIG_OF_DYNAMIC + static const char * const str_array[] = { "abc", "defg", "hij" }; + static const u32 u32_array[] = { 123, 4567, 89, 10, 11 }; + struct device_node *nchangeset, *np; + struct of_changeset chgset; + int ret; + + nchangeset = of_find_node_by_path("/testcase-data/changeset"); + if (!nchangeset) { + pr_err("missing testcase data\n"); + return; + } + + of_changeset_init(&chgset); + + np = of_changeset_create_node(&chgset, nchangeset, "test-prop"); + if (unittest(np, "failed to create test-prop node\n")) + goto end_changeset_destroy; + + ret = of_changeset_add_prop_string(&chgset, np, "prop-string", "abcde"); + unittest(ret == 0, "failed to add prop-string\n"); + + ret = of_changeset_add_prop_string_array(&chgset, np, "prop-string-array", + str_array, ARRAY_SIZE(str_array)); + unittest(ret == 0, "failed to add prop-string-array\n"); + + ret = of_changeset_add_prop_u32(&chgset, np, "prop-u32", 1234); + unittest(ret == 0, "failed to add prop-u32\n"); + + ret = of_changeset_add_prop_u32_array(&chgset, np, "prop-u32-array", + u32_array, ARRAY_SIZE(u32_array)); + unittest(ret == 0, "failed to add prop-u32-array\n"); + + ret = of_changeset_add_prop_bool(&chgset, np, "prop-bool"); + unittest(ret == 0, "failed to add prop-bool\n"); + + of_node_put(np); + + ret = of_changeset_apply(&chgset); + if (unittest(ret == 0, "failed to apply changeset\n")) + goto end_changeset_destroy; + + np = of_find_node_by_path("/testcase-data/changeset/test-prop"); + if (unittest(np, "failed to find test-prop node\n")) + goto end_revert_changeset; + + changeset_check_string(np, "prop-string", "abcde"); + changeset_check_string_array(np, "prop-string-array", str_array, ARRAY_SIZE(str_array)); + changeset_check_u32(np, "prop-u32", 1234); + changeset_check_u32_array(np, "prop-u32-array", u32_array, ARRAY_SIZE(u32_array)); + changeset_check_bool(np, "prop-bool"); + + of_node_put(np); + +end_revert_changeset: + ret = of_changeset_revert(&chgset); + unittest(ret == 0, "failed to revert changeset\n"); + +end_changeset_destroy: + of_changeset_destroy(&chgset); + of_node_put(nchangeset); +#endif +} + static void __init of_unittest_dma_get_max_cpu_address(void) { struct device_node *np; @@ -4101,6 +4266,7 @@ static int __init of_unittest(void) of_unittest_property_string(); of_unittest_property_copy(); of_unittest_changeset(); + of_unittest_changeset_prop(); of_unittest_parse_interrupts(); of_unittest_parse_interrupts_extended(); of_unittest_dma_get_max_cpu_address(); |