summaryrefslogtreecommitdiff
path: root/drivers/of
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-07-18 04:07:31 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2024-07-18 04:07:31 +0300
commit0ffb8a4c96e55ecf0e572aec1a0220af3da84e22 (patch)
treeea497c6728d2b93b31f1f4535a1413a436a59683 /drivers/of
parent5b9ac6c2a735f5b1721e0bc7331f8707190f9ef6 (diff)
parent76be2f9823b10c07daf814cb6c732eb1456a0b9e (diff)
downloadlinux-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.c27
-rw-r--r--drivers/of/fdt.c30
-rw-r--r--drivers/of/unittest.c166
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();