svn commit: r292156 - head/sys/dev/ofw
Michal Meloun
mmel at FreeBSD.org
Sun Dec 13 08:17:51 UTC 2015
Author: mmel
Date: Sun Dec 13 08:17:49 2015
New Revision: 292156
URL: https://svnweb.freebsd.org/changeset/base/292156
Log:
OFW: Add helper functions for parsing xref based lists.
By using this functions, we can parse a list of tuples, each of them holds
xref and variable number of values.
This kind of list is used in DT for clocks, gpios, resets ...
Discussed with: ian, nwhitehorn
Approved by: kib (mentor)
Differential Revision: https://reviews.freebsd.org/D4316
Modified:
head/sys/dev/ofw/ofw_bus_subr.c
head/sys/dev/ofw/ofw_bus_subr.h
Modified: head/sys/dev/ofw/ofw_bus_subr.c
==============================================================================
--- head/sys/dev/ofw/ofw_bus_subr.c Sun Dec 13 07:39:49 2015 (r292155)
+++ head/sys/dev/ofw/ofw_bus_subr.c Sun Dec 13 08:17:49 2015 (r292156)
@@ -607,3 +607,134 @@ ofw_bus_find_child_device_by_phandle(dev
return (retval);
}
+
+/*
+ * Parse property that contain list of xrefs and values
+ * (like standard "clocks" and "resets" properties)
+ * Input arguments:
+ * node - consumers device node
+ * list_name - name of parsed list - "clocks"
+ * cells_name - name of size property - "#clock-cells"
+ * Output arguments:
+ * producer - handle of producer
+ * ncells - number of cells in result
+ * cells - array of decoded cells
+ */
+int
+ofw_bus_parse_xref_list_alloc(phandle_t node, const char *list_name,
+ const char *cells_name, int idx, phandle_t *producer, int *ncells,
+ pcell_t **cells)
+{
+ phandle_t pnode;
+ phandle_t *elems;
+ uint32_t pcells;
+ int rv, i, j, nelems, cnt;
+
+ elems = NULL;
+ nelems = OF_getencprop_alloc(node, list_name, sizeof(*elems),
+ (void **)&elems);
+ if (nelems <= 0)
+ return (ENOENT);
+ rv = ENOENT;
+ for (i = 0, cnt = 0; i < nelems; i += pcells, cnt++) {
+ pnode = elems[i++];
+ if (OF_getencprop(OF_node_from_xref(pnode),
+ cells_name, &pcells, sizeof(pcells)) == -1) {
+ printf("Missing %s property\n", cells_name);
+ rv = ENOENT;
+ break;
+ }
+
+ if ((i + pcells) > nelems) {
+ printf("Invalid %s property value <%d>\n", cells_name,
+ pcells);
+ rv = ERANGE;
+ break;
+ }
+ if (cnt == idx) {
+ *cells= malloc(pcells * sizeof(**cells), M_OFWPROP,
+ M_WAITOK);
+ *producer = pnode;
+ *ncells = pcells;
+ for (j = 0; j < pcells; j++)
+ (*cells)[j] = elems[i + j];
+ rv = 0;
+ break;
+ }
+ }
+ if (elems != NULL)
+ free(elems, M_OFWPROP);
+ return (rv);
+}
+
+/*
+ * Find index of string in string list property (case sensitive).
+ */
+int
+ofw_bus_find_string_index(phandle_t node, const char *list_name,
+ const char *name, int *idx)
+{
+ char *elems;
+ int rv, i, cnt, nelems;
+
+ elems = NULL;
+ nelems = OF_getprop_alloc(node, list_name, 1, (void **)&elems);
+ if (nelems <= 0)
+ return (ENOENT);
+
+ rv = ENOENT;
+ for (i = 0, cnt = 0; i < nelems; cnt++) {
+ if (strcmp(elems + i, name) == 0) {
+ *idx = cnt;
+ rv = 0;
+ break;
+ }
+ i += strlen(elems + i) + 1;
+ }
+
+ if (elems != NULL)
+ free(elems, M_OFWPROP);
+ return (rv);
+}
+
+/*
+ * Create zero terminated array of strings from string list property.
+ */
+int
+ofw_bus_string_list_to_array(phandle_t node, const char *list_name,
+ const char ***array)
+{
+ char *elems, *tptr;
+ int i, cnt, nelems, len;
+
+ elems = NULL;
+ nelems = OF_getprop_alloc(node, list_name, 1, (void **)&elems);
+ if (nelems <= 0)
+ return (nelems);
+
+ /* Count number of strings. */
+ for (i = 0, cnt = 0; i < nelems; cnt++)
+ i += strlen(elems + i) + 1;
+
+ /* Allocate space for arrays and all strings. */
+ *array = malloc((cnt + 1) * sizeof(char *) + nelems, M_OFWPROP,
+ M_WAITOK);
+
+ /* Get address of first string. */
+ tptr = (char *)(*array + cnt);
+
+ /* Copy strings. */
+ memcpy(tptr, elems, nelems);
+ free(elems, M_OFWPROP);
+
+ /* Fill string pointers. */
+ for (i = 0, cnt = 0; i < nelems; cnt++) {
+ len = strlen(tptr + i) + 1;
+ *array[cnt] = tptr;
+ i += len;
+ tptr += len;
+ }
+ *array[cnt] = 0;
+
+ return (cnt);
+}
Modified: head/sys/dev/ofw/ofw_bus_subr.h
==============================================================================
--- head/sys/dev/ofw/ofw_bus_subr.h Sun Dec 13 07:39:49 2015 (r292155)
+++ head/sys/dev/ofw/ofw_bus_subr.h Sun Dec 13 08:17:49 2015 (r292156)
@@ -110,4 +110,13 @@ phandle_t ofw_bus_find_child(phandle_t,
/* Helper routine to find a device_t child matchig a given phandle_t */
device_t ofw_bus_find_child_device_by_phandle(device_t bus, phandle_t node);
+/* Helper routines for parsing lists */
+int ofw_bus_parse_xref_list_alloc(phandle_t node, const char *list_name,
+ const char *cells_name, int idx, phandle_t *producer, int *ncells,
+ pcell_t **cells);
+int ofw_bus_find_string_index(phandle_t node, const char *list_name,
+ const char *name, int *idx);
+int ofw_bus_string_list_to_array(phandle_t node, const char *list_name,
+ const char ***array);
+
#endif /* !_DEV_OFW_OFW_BUS_SUBR_H_ */
More information about the svn-src-head
mailing list