diff options
author | Pantelis Antoniou <pantelis.antoniou@konsulko.com> | 2014-07-04 19:58:49 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-02-20 23:41:12 +0900 |
commit | 33ef56d1b95d9b628f9ed78c34d40b746668855e (patch) | |
tree | 3315e525a45650f9a9bd8eca44a31711f7ea9ceb /include | |
parent | a39492cbb90cebc0c1cb55d95e913848f6d68109 (diff) |
of: Transactional DT support.
Introducing DT transactional support.
A DT transaction is a method which allows one to apply changes
in the live tree, in such a way that either the full set of changes
take effect, or the state of the tree can be rolled-back to the
state it was before it was attempted. An applied transaction
can be rolled-back at any time.
Documentation is in
Documentation/devicetree/changesets.txt
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
[glikely: Removed device notifiers and reworked to be more consistent]
Signed-off-by: Grant Likely <grant.likely@linaro.org>
(cherry picked from commit 201c910bd6898d81d4ac6685d0f421b7e10f3c5d)
Signed-off-by: Mark Brown <broonie@kernel.org>
Conflicts:
include/linux/of.h
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/of.h | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/include/linux/of.h b/include/linux/of.h index 689e26274cf0..ae091484bf74 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -751,4 +751,102 @@ static inline int of_get_available_child_count(const struct device_node *np) return num; } +#ifdef CONFIG_OF +#define _OF_DECLARE(table, name, compat, fn, fn_type) \ + static const struct of_device_id __of_table_##name \ + __used __section(__##table##_of_table) \ + = { .compatible = compat, \ + .data = (fn == (fn_type)NULL) ? fn : fn } +#else +#define _OF_DECLARE(table, name, compat, fn, fn_type) \ + static const struct of_device_id __of_table_##name \ + __attribute__((unused)) \ + = { .compatible = compat, \ + .data = (fn == (fn_type)NULL) ? fn : fn } +#endif + +typedef int (*of_init_fn_2)(struct device_node *, struct device_node *); +typedef void (*of_init_fn_1)(struct device_node *); + +#define OF_DECLARE_1(table, name, compat, fn) \ + _OF_DECLARE(table, name, compat, fn, of_init_fn_1) +#define OF_DECLARE_2(table, name, compat, fn) \ + _OF_DECLARE(table, name, compat, fn, of_init_fn_2) + +/** + * 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; + unsigned long 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; +}; + +#ifdef CONFIG_OF_DYNAMIC +extern void of_changeset_init(struct of_changeset *ocs); +extern void of_changeset_destroy(struct of_changeset *ocs); +extern int of_changeset_apply(struct of_changeset *ocs); +extern int of_changeset_revert(struct of_changeset *ocs); +extern int of_changeset_action(struct of_changeset *ocs, + unsigned long action, struct device_node *np, + struct property *prop); + +static inline int of_changeset_attach_node(struct of_changeset *ocs, + struct device_node *np) +{ + return of_changeset_action(ocs, OF_RECONFIG_ATTACH_NODE, np, NULL); +} + +static inline int of_changeset_detach_node(struct of_changeset *ocs, + struct device_node *np) +{ + return of_changeset_action(ocs, OF_RECONFIG_DETACH_NODE, np, NULL); +} + +static inline int of_changeset_add_property(struct of_changeset *ocs, + struct device_node *np, struct property *prop) +{ + return of_changeset_action(ocs, OF_RECONFIG_ADD_PROPERTY, np, prop); +} + +static inline int of_changeset_remove_property(struct of_changeset *ocs, + struct device_node *np, struct property *prop) +{ + return of_changeset_action(ocs, OF_RECONFIG_REMOVE_PROPERTY, np, prop); +} + +static inline int of_changeset_update_property(struct of_changeset *ocs, + struct device_node *np, struct property *prop) +{ + return of_changeset_action(ocs, OF_RECONFIG_UPDATE_PROPERTY, np, prop); +} +#endif + #endif /* _LINUX_OF_H */ |