/* SPDX-License-Identifier: GPL-2.0+ */ #ifndef _LINUX_OF_H #define _LINUX_OF_H /* * Definitions for talking to the Open Firmware PROM on * Power Macintosh and other computers. * * Copyright (C) 1996-2005 Paul Mackerras. * * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp. * Updates for SPARC64 by David S. Miller * Derived from PowerPC and Sparc prom.h files by Stephen Rothwell, IBM Corp.
*/ #include <linux/types.h> #include <linux/bitops.h> #include <linux/cleanup.h> #include <linux/errno.h> #include <linux/kobject.h> #include <linux/mod_devicetable.h> #include <linux/property.h> #include <linux/list.h>
/** * of_node_init - initialize a devicetree node * @node: Pointer to device node that has been created by kzalloc() * * On return the device_node refcount is set to one. Use of_node_put() * on @node when done to free the memory allocated for it. If the node * is NOT a dynamic node the memory will not be freed. The decision of * whether to free the memory will be done by node->release(), which is * of_node_release().
*/ staticinlinevoid of_node_init(struct device_node *node)
{ #ifdefined(CONFIG_OF_KOBJ)
kobject_init(&node->kobj, &of_node_ktype); #endif
fwnode_init(&node->fwnode, &of_fwnode_ops);
}
/* Pointer for first entry in chain of all nodes. */ externstruct device_node *of_root; externstruct device_node *of_chosen; externstruct device_node *of_aliases; externstruct device_node *of_stdout;
/* * struct device_node flag descriptions * (need to be visible even when !CONFIG_OF)
*/ #define OF_DYNAMIC 1 /* (and properties) allocated via kmalloc */ #define OF_DETACHED 2 /* detached from the device tree */ #define OF_POPULATED 3 /* device already created */ #define OF_POPULATED_BUS 4 /* platform bus created for children */ #define OF_OVERLAY 5 /* allocated for an overlay */ #define OF_OVERLAY_FREE_CSET 6 /* in overlay cset being freed */
/* Helper to read a big number; size is in cells (not bytes) */ staticinline u64 of_read_number(const __be32 *cell, int size)
{
u64 r = 0; for (; size--; cell++)
r = (r << 32) | be32_to_cpu(*cell); return r;
}
/* Like of_read_number, but we want an unsigned long result */ staticinlineunsignedlong of_read_ulong(const __be32 *cell, int size)
{ /* toss away upper bits if unsigned long is smaller than u64 */ return of_read_number(cell, size);
}
/** * of_machine_is_compatible - Test root of device tree for a given compatible value * @compat: compatible string to look for in root node's compatible property. * * Return: true if the root node has the given value in its compatible property.
*/ staticinlinebool of_machine_is_compatible(constchar *compat)
{ constchar *compats[] = { compat, NULL };
return np && match && type && !strcmp(match, type);
}
/** * of_parse_phandle - Resolve a phandle property to a device_node pointer * @np: Pointer to device node holding phandle property * @phandle_name: Name of property holding a phandle value * @index: For properties holding a table of phandles, this is the index into * the table * * Return: The device_node pointer with refcount incremented. Use * of_node_put() on it when done.
*/ staticinlinestruct device_node *of_parse_phandle(conststruct device_node *np, constchar *phandle_name, int index)
{ struct of_phandle_args args;
if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0,
index, &args)) return NULL;
return args.np;
}
/** * of_parse_phandle_with_args() - Find a node pointed by phandle in a list * @np: pointer to a device tree node containing a list * @list_name: property name that contains a list * @cells_name: property name that specifies phandles' arguments count * @index: index of a phandle to parse out * @out_args: optional pointer to output arguments structure (will be filled) * * This function is useful to parse lists of phandles and their arguments. * Returns 0 on success and fills out_args, on error returns appropriate * errno value. * * Caller is responsible to call of_node_put() on the returned out_args->np * pointer. * * Example:: * * phandle1: node1 { * #list-cells = <2>; * }; * * phandle2: node2 { * #list-cells = <1>; * }; * * node3 { * list = <&phandle1 1 2 &phandle2 3>; * }; * * To get a device_node of the ``node2`` node you may call this: * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args);
*/ staticinlineint of_parse_phandle_with_args(conststruct device_node *np, constchar *list_name, constchar *cells_name, int index, struct of_phandle_args *out_args)
{ int cell_count = -1;
/* If cells_name is NULL we assume a cell count of 0 */ if (!cells_name)
cell_count = 0;
/** * of_parse_phandle_with_fixed_args() - Find a node pointed by phandle in a list * @np: pointer to a device tree node containing a list * @list_name: property name that contains a list * @cell_count: number of argument cells following the phandle * @index: index of a phandle to parse out * @out_args: optional pointer to output arguments structure (will be filled) * * This function is useful to parse lists of phandles and their arguments. * Returns 0 on success and fills out_args, on error returns appropriate * errno value. * * Caller is responsible to call of_node_put() on the returned out_args->np * pointer. * * Example:: * * phandle1: node1 { * }; * * phandle2: node2 { * }; * * node3 { * list = <&phandle1 0 2 &phandle2 2 3>; * }; * * To get a device_node of the ``node2`` node you may call this: * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args);
*/ staticinlineint of_parse_phandle_with_fixed_args(conststruct device_node *np, constchar *list_name, int cell_count, int index, struct of_phandle_args *out_args)
{ return __of_parse_phandle_with_args(np, list_name, NULL, cell_count,
index, out_args);
}
/** * of_parse_phandle_with_optional_args() - Find a node pointed by phandle in a list * @np: pointer to a device tree node containing a list * @list_name: property name that contains a list * @cells_name: property name that specifies phandles' arguments count * @index: index of a phandle to parse out * @out_args: optional pointer to output arguments structure (will be filled) * * Same as of_parse_phandle_with_args() except that if the cells_name property * is not found, cell_count of 0 is assumed. * * This is used to useful, if you have a phandle which didn't have arguments * before and thus doesn't have a '#*-cells' property but is now migrated to * having arguments while retaining backwards compatibility.
*/ staticinlineint of_parse_phandle_with_optional_args(conststruct device_node *np, constchar *list_name, constchar *cells_name, int index, struct of_phandle_args *out_args)
{ return __of_parse_phandle_with_args(np, list_name, cells_name,
0, index, out_args);
}
/** * of_phandle_args_equal() - Compare two of_phandle_args * @a1: First of_phandle_args to compare * @a2: Second of_phandle_args to compare * * Return: True if a1 and a2 are the same (same node pointer, same phandle * args), false otherwise.
*/ staticinlinebool of_phandle_args_equal(conststruct of_phandle_args *a1, conststruct of_phandle_args *a2)
{ return a1->np == a2->np &&
a1->args_count == a2->args_count &&
!memcmp(a1->args, a2->args, sizeof(a1->args[0]) * a1->args_count);
}
/** * of_property_count_u8_elems - Count the number of u8 elements in a property * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * * Search for a property in a device node and count the number of u8 elements * in it. * * Return: The number of elements on sucess, -EINVAL if the property does * not exist or its length does not match a multiple of u8 and -ENODATA if the * property does not have a value.
*/ staticinlineint of_property_count_u8_elems(conststruct device_node *np, constchar *propname)
{ return of_property_count_elems_of_size(np, propname, sizeof(u8));
}
/** * of_property_count_u16_elems - Count the number of u16 elements in a property * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * * Search for a property in a device node and count the number of u16 elements * in it. * * Return: The number of elements on sucess, -EINVAL if the property does * not exist or its length does not match a multiple of u16 and -ENODATA if the * property does not have a value.
*/ staticinlineint of_property_count_u16_elems(conststruct device_node *np, constchar *propname)
{ return of_property_count_elems_of_size(np, propname, sizeof(u16));
}
/** * of_property_count_u32_elems - Count the number of u32 elements in a property * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * * Search for a property in a device node and count the number of u32 elements * in it. * * Return: The number of elements on sucess, -EINVAL if the property does * not exist or its length does not match a multiple of u32 and -ENODATA if the * property does not have a value.
*/ staticinlineint of_property_count_u32_elems(conststruct device_node *np, constchar *propname)
{ return of_property_count_elems_of_size(np, propname, sizeof(u32));
}
/** * of_property_count_u64_elems - Count the number of u64 elements in a property * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * * Search for a property in a device node and count the number of u64 elements * in it. * * Return: The number of elements on sucess, -EINVAL if the property does * not exist or its length does not match a multiple of u64 and -ENODATA if the * property does not have a value.
*/ staticinlineint of_property_count_u64_elems(conststruct device_node *np, constchar *propname)
{ return of_property_count_elems_of_size(np, propname, sizeof(u64));
}
/** * of_property_read_string_array() - Read an array of strings from a multiple * strings property. * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @out_strs: output array of string pointers. * @sz: number of array elements to read. * * Search for a property in a device tree node and retrieve a list of * terminated string values (pointer to data, not a copy) in that property. * * Return: If @out_strs is NULL, the number of strings in the property is returned.
*/ staticinlineint of_property_read_string_array(conststruct device_node *np, constchar *propname, constchar **out_strs,
size_t sz)
{ return of_property_read_string_helper(np, propname, out_strs, sz, 0);
}
/** * of_property_count_strings() - Find and return the number of strings from a * multiple strings property. * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * * Search for a property in a device tree node and retrieve the number of null * terminated string contain in it. * * Return: The number of strings on success, -EINVAL if the property does not * exist, -ENODATA if property does not have a value, and -EILSEQ if the string * is not null-terminated within the length of the property data.
*/ staticinlineint of_property_count_strings(conststruct device_node *np, constchar *propname)
{ return of_property_read_string_helper(np, propname, NULL, 0, 0);
}
/** * of_property_read_string_index() - Find and read a string from a multiple * strings property. * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @index: index of the string in the list of strings * @output: pointer to null terminated return string, modified only if * return value is 0. * * Search for a property in a device tree node and retrieve a null * terminated string value (pointer to data, not a copy) in the list of strings * contained in that property. * * Return: 0 on success, -EINVAL if the property does not exist, -ENODATA if * property does not have a value, and -EILSEQ if the string is not * null-terminated within the length of the property data. * * The out_string pointer is modified only if a valid string can be decoded.
*/ staticinlineint of_property_read_string_index(conststruct device_node *np, constchar *propname, int index, constchar **output)
{ int rc = of_property_read_string_helper(np, propname, output, 1, index); return rc < 0 ? rc : 0;
}
/** * of_property_present - Test if a property is present in a node * @np: device node to search for the property. * @propname: name of the property to be searched. * * Test for a property present in a device node. * * Return: true if the property exists false otherwise.
*/ staticinlinebool of_property_present(conststruct device_node *np, constchar *propname)
{ struct property *prop = of_find_property(np, propname, NULL);
return prop ? true : false;
}
/** * of_property_read_u8_array - Find and read an array of u8 from a property. * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @out_values: pointer to return value, modified only if return value is 0. * @sz: number of array elements to read * * Search for a property in a device node and read 8-bit value(s) from * it. * * dts entry of array should be like: * ``property = /bits/ 8 <0x50 0x60 0x70>;`` * * Return: 0 on success, -EINVAL if the property does not exist, * -ENODATA if property does not have a value, and -EOVERFLOW if the * property data isn't large enough. * * The out_values is modified only if a valid u8 value can be decoded.
*/ staticinlineint of_property_read_u8_array(conststruct device_node *np, constchar *propname,
u8 *out_values, size_t sz)
{ int ret = of_property_read_variable_u8_array(np, propname, out_values,
sz, 0); if (ret >= 0) return 0; else return ret;
}
/** * of_property_read_u16_array - Find and read an array of u16 from a property. * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @out_values: pointer to return value, modified only if return value is 0. * @sz: number of array elements to read * * Search for a property in a device node and read 16-bit value(s) from * it. * * dts entry of array should be like: * ``property = /bits/ 16 <0x5000 0x6000 0x7000>;`` * * Return: 0 on success, -EINVAL if the property does not exist, * -ENODATA if property does not have a value, and -EOVERFLOW if the * property data isn't large enough. * * The out_values is modified only if a valid u16 value can be decoded.
*/ staticinlineint of_property_read_u16_array(conststruct device_node *np, constchar *propname,
u16 *out_values, size_t sz)
{ int ret = of_property_read_variable_u16_array(np, propname, out_values,
sz, 0); if (ret >= 0) return 0; else return ret;
}
/** * of_property_read_u32_array - Find and read an array of 32 bit integers * from a property. * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @out_values: pointer to return value, modified only if return value is 0. * @sz: number of array elements to read * * Search for a property in a device node and read 32-bit value(s) from * it. * * Return: 0 on success, -EINVAL if the property does not exist, * -ENODATA if property does not have a value, and -EOVERFLOW if the * property data isn't large enough. * * The out_values is modified only if a valid u32 value can be decoded.
*/ staticinlineint of_property_read_u32_array(conststruct device_node *np, constchar *propname,
u32 *out_values, size_t sz)
{ int ret = of_property_read_variable_u32_array(np, propname, out_values,
sz, 0); if (ret >= 0) return 0; else return ret;
}
/** * of_property_read_u64_array - Find and read an array of 64 bit integers * from a property. * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @out_values: pointer to return value, modified only if return value is 0. * @sz: number of array elements to read * * Search for a property in a device node and read 64-bit value(s) from * it. * * Return: 0 on success, -EINVAL if the property does not exist, * -ENODATA if property does not have a value, and -EOVERFLOW if the * property data isn't large enough. * * The out_values is modified only if a valid u64 value can be decoded.
*/ staticinlineint of_property_read_u64_array(conststruct device_node *np, constchar *propname,
u64 *out_values, size_t sz)
{ int ret = of_property_read_variable_u64_array(np, propname, out_values,
sz, 0); if (ret >= 0) return 0; else return ret;
}
/** * struct of_changeset_entry - Holds a changeset entry * * @node: list_head for the log list * @action: notifier action * @np: pointer to the device node affected * @prop: pointer to the property affected * @old_prop: hold a pointer to the original property * * Every modification of the device tree during a changeset * is held in a list of of_changeset_entry structures. * That way we can recover from a partial application, or we can * revert the changeset
*/ struct of_changeset_entry { struct list_head node; unsignedlong action; struct device_node *np; struct property *prop; struct property *old_prop;
};
/** * struct of_changeset - changeset tracker structure * * @entries: list_head for the changeset entries * * changesets are a convenient way to apply bulk changes to the * live tree. In case of an error, changes are rolled-back. * changesets live on after initial application, and if not * destroyed after use, they can be reverted in one single call.
*/ struct of_changeset { struct list_head entries;
};
/** * of_device_is_system_power_controller - Tells if system-power-controller is found for device_node * @np: Pointer to the given device_node * * Return: true if present false otherwise
*/ staticinlinebool of_device_is_system_power_controller(conststruct device_node *np)
{ return of_property_read_bool(np, "system-power-controller");
}
/** * of_have_populated_dt() - Has DT been populated by bootloader * * Return: True if a DTB has been populated by the bootloader and it isn't the * empty builtin one. False otherwise.
*/ staticinlinebool of_have_populated_dt(void)
{ #ifdef CONFIG_OF return of_property_present(of_root, "compatible"); #else returnfalse; #endif
}
/* * Overlay support
*/
enum of_overlay_notify_action {
OF_OVERLAY_INIT = 0, /* kzalloc() of ovcs sets this value */
OF_OVERLAY_PRE_APPLY,
OF_OVERLAY_POST_APPLY,
OF_OVERLAY_PRE_REMOVE,
OF_OVERLAY_POST_REMOVE,
};
int of_overlay_fdt_apply(constvoid *overlay_fdt, u32 overlay_fdt_size, int *ovcs_id, conststruct device_node *target_base); int of_overlay_remove(int *ovcs_id); int of_overlay_remove_all(void);
int of_overlay_notifier_register(struct notifier_block *nb); int of_overlay_notifier_unregister(struct notifier_block *nb);
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.75Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.