The state backend format was changed from a phandle based description to
a string based description. This was done because of the missing support
to store the state within a on-disk partition like MBR/GPT. By this sync
we import the code required to manipulate the state which is stored on a
on-disk partition.

Furthermore the sync did a few minor style fixes.

Signed-off-by: Marco Felsch <m.fel...@pengutronix.de>
---
 src/barebox-state/state.c | 168 ++++++++++++++++++++++++++++----------
 src/barebox-state/state.h |   6 +-
 src/dt/common.h           |  17 ++++
 3 files changed, 145 insertions(+), 46 deletions(-)

diff --git a/src/barebox-state/state.c b/src/barebox-state/state.c
index 4779574..e8c08d6 100644
--- a/src/barebox-state/state.c
+++ b/src/barebox-state/state.c
@@ -40,11 +40,11 @@ static LIST_HEAD(state_list);
  */
 int state_save(struct state *state)
 {
-       void *buf;
-       ssize_t len;
-       int ret;
        struct state_backend_storage_bucket *bucket;
        struct state_backend_storage *storage;
+       ssize_t len;
+       void *buf;
+       int ret;
 
        if (!state->dirty)
                return 0;
@@ -211,13 +211,13 @@ static int state_convert_node_variable(struct state 
*state,
                                       const char *parent_name,
                                       enum state_convert conv)
 {
+       struct device_node *new_node = NULL;
        const struct variable_type *vtype;
+       char *short_name, *name, *indexs;
+       unsigned int start_size[2];
        struct device_node *child;
-       struct device_node *new_node = NULL;
        struct state_variable *sv;
        const char *type_name;
-       char *short_name, *name, *indexs;
-       unsigned int start_size[2];
        int ret;
 
        /* strip trailing @<ADDRESS> */
@@ -341,8 +341,8 @@ struct device_node *state_to_node(struct state *state,
                                  struct device_node *parent,
                                  enum state_convert conv)
 {
-       struct device_node *child;
        struct device_node *root, *state_root;
+       struct device_node *child;
        int ret;
 
        state_root = of_find_node_by_path(state->of_path);
@@ -369,8 +369,8 @@ int state_from_node(struct state *state, struct device_node 
*node, bool create)
 {
        struct device_node *child;
        enum state_convert conv;
-       int ret;
        uint32_t magic;
+       int ret;
 
        ret = of_property_read_u32(node, "magic", &magic);
        if (ret)
@@ -428,12 +428,11 @@ int state_from_node(struct state *state, struct 
device_node *node, bool create)
 
 static int of_state_fixup(struct device_node *root, void *ctx)
 {
-       struct state *state = ctx;
-       const char *compatible = "barebox,state";
        struct device_node *new_node, *node, *parent, *backend_node, *aliases;
+       const char *compatible = "barebox,state";
+       struct state *state = ctx;
        struct property *p;
        int ret;
-       phandle phandle;
 
        node = of_find_node_by_path_from(root, state->of_path);
        if (node) {
@@ -493,16 +492,26 @@ static int of_state_fixup(struct device_node *root, void 
*ctx)
 
        /* backend phandle */
        backend_node = of_find_node_by_reproducible_name(root,
-                                               
state->backend_reproducible_name);
+                                               state->backend_dts_dev_or_part);
        if (!backend_node) {
                ret = -ENODEV;
                goto out;
        }
 
-       phandle = of_node_create_phandle(backend_node);
-       ret = of_property_write_u32(new_node, "backend", phandle);
-       if (ret)
-               goto out;
+       if (state->backend_is_new_format) {
+               ret = of_property_write_strings(new_node, "backend",
+                                               backend_node->full_name,
+                                               state->backend_dts_partition, 
NULL);
+               if (ret)
+                       goto out;
+       } else {
+               phandle phandle;
+
+               phandle = of_node_create_phandle(backend_node);
+               ret = of_property_write_u32(new_node, "backend", phandle);
+               if (ret)
+                       goto out;
+       }
 
        if (!strcmp("raw", state->format->name)) {
                struct digest *digest =
@@ -572,12 +581,86 @@ void state_release(struct state *state)
        unregister_device(&state->dev);
        state_storage_free(&state->storage);
        state_format_free(state->format);
-       free(state->backend_path);
-       free(state->backend_reproducible_name);
+       free(state->backend_dev_path);
+       free(state->backend_dts_dev_or_part);
+       free(state->backend_dts_partition);
        free(state->of_path);
        free(state);
 }
 
+#ifdef __BAREBOX__
+
+#define state_of_find_path_by_node(node, path, flags, offset, size) \
+       of_find_path_by_node(node, path, flags)
+#define state_of_find_path(node, propname, outpath, flags, offset, size) \
+       of_find_path(node, propname, outpath, flags)
+
+#else
+
+#define state_of_find_path_by_node(node, path, flags, offset, size) \
+       of_get_devicepath(node, path, offset, size)
+#define state_of_find_path(node, propname, outpath, flags, offset, size) \
+       of_find_path(node, propname, outpath, offset, size)
+
+#endif /* __BAREBOX__ */
+
+static int
+state_parse_old_backend_format(struct device_node *backend_node,
+                              struct state *state, off_t *offset, size_t *size)
+{
+       int ret;
+
+       ret = of_partition_ensure_probed(backend_node);
+       if (ret)
+               return ret;
+
+       ret = state_of_find_path_by_node(backend_node, &state->backend_dev_path,
+                                        0, offset, size);
+       if (ret) {
+               if (ret != -EPROBE_DEFER)
+                       dev_err(&state->dev, "state failed to parse path to 
backend: %s\n",
+                              strerror(-ret));
+               return ret;
+       }
+
+       state->backend_dts_dev_or_part = of_get_reproducible_name(backend_node);
+
+       return 0;
+}
+
+static int
+state_parse_new_backend_format(struct device_node *state_node,
+                              struct state *state, off_t *offset, size_t *size)
+{
+       struct device_node *backend_node;
+       const char *backend_dev_or_part;
+       const char *part = NULL;
+       int ret;
+
+       backend_dev_or_part = of_get_property(state_node, "backend", NULL);
+       if (!backend_dev_or_part)
+               return -EINVAL;
+
+       backend_node = of_find_node_by_path(backend_dev_or_part);
+       if (!backend_node)
+               return -ENODEV;
+
+       if (is_of_partition(backend_node))
+               ret = of_partition_ensure_probed(backend_node);
+       else
+               ret = of_device_ensure_probed(backend_node);
+       if (ret)
+               return ret;
+
+       of_property_read_string_index(state_node, "backend", 1, &part);
+       state->backend_dts_dev_or_part = of_get_reproducible_name(backend_node);
+       state->backend_dts_partition = xstrdup(part);
+       state->backend_is_new_format = true;
+
+       return state_of_find_path(state_node, "backend",
+                                 &state->backend_dev_path, 0, offset, size);
+}
+
 /*
  * state_new_from_node - create a new state instance from a device_node
  *
@@ -587,15 +670,15 @@ void state_release(struct state *state)
  */
 struct state *state_new_from_node(struct device_node *node, bool readonly)
 {
-       struct state *state;
-       int ret = 0;
-       const char *backend_type;
+       struct device_node *backend_node;
        const char *storage_type = NULL;
-       const char *alias;
+       const char *backend_type;
+       struct state *state;
        uint32_t stridesize;
-       struct device_node *partition_node;
+       const char *alias;
        off_t offset = 0;
        size_t size = 0;
+       int ret;
 
        alias = of_alias_get(node);
        if (!alias) {
@@ -607,26 +690,23 @@ struct state *state_new_from_node(struct device_node 
*node, bool readonly)
        if (IS_ERR(state))
                return state;
 
-       partition_node = of_parse_phandle(node, "backend", 0);
-       if (!partition_node) {
-               dev_err(&state->dev, "Cannot resolve \"backend\" phandle\n");
-               ret = -EINVAL;
-               goto out_release_state;
-       }
-
-#ifdef __BAREBOX__
-       ret = of_find_path_by_node(partition_node, &state->backend_path, 0);
-#else
-       ret = of_get_devicepath(partition_node, &state->backend_path, &offset, 
&size);
-#endif
-       if (ret) {
-               if (ret != -EPROBE_DEFER)
-                       dev_err(&state->dev, "state failed to parse path to 
backend: %s\n",
-                              strerror(-ret));
+       /*
+        * backend can be in three formats:
+        *  old) backend = <&state_part>;
+        *  new) backend = &state_part;
+        *       backend = &state_part_dev, "partname:0";
+        *
+        * Start with the old format for compatibility reasons.
+        */
+       backend_node = of_parse_phandle(node, "backend", 0);
+       if (backend_node)
+               ret = state_parse_old_backend_format(backend_node, state,
+                                                    &offset, &size);
+       else
+               ret = state_parse_new_backend_format(node, state,
+                                                    &offset, &size);
+       if (ret)
                goto out_release_state;
-       }
-
-       state->backend_reproducible_name = 
of_get_reproducible_name(partition_node);
 
        ret = of_property_read_string(node, "backend-type", &backend_type);
        if (ret) {
@@ -649,7 +729,7 @@ struct state *state_new_from_node(struct device_node *node, 
bool readonly)
        if (ret)
                goto out_release_state;
 
-       ret = state_storage_init(state, state->backend_path, offset,
+       ret = state_storage_init(state, state->backend_dev_path, offset,
                                 size, stridesize, storage_type);
        if (ret)
                goto out_release_state;
@@ -744,7 +824,7 @@ void state_info(void)
                if (state->format)
                        printf("(backend: %s, path: %s)\n",
                               state->format->name,
-                              state->backend_path);
+                              state->backend_dev_path);
                else
                        printf("(no backend)\n");
        }
diff --git a/src/barebox-state/state.h b/src/barebox-state/state.h
index 719f7e4..2d3ec41 100644
--- a/src/barebox-state/state.h
+++ b/src/barebox-state/state.h
@@ -118,8 +118,10 @@ struct state {
 
        struct state_backend_format *format;
        struct state_backend_storage storage;
-       char *backend_path;
-       char *backend_reproducible_name;
+       char *backend_dev_path;
+       char *backend_dts_dev_or_part;
+       char *backend_dts_partition;
+       bool backend_is_new_format;
 };
 
 enum state_convert {
diff --git a/src/dt/common.h b/src/dt/common.h
index 9b1c169..4cb0dc2 100644
--- a/src/dt/common.h
+++ b/src/dt/common.h
@@ -360,6 +360,23 @@ static inline int is_zero_ether_addr(const u8 *addr)
        return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
 }
 
+struct device_node;
+
+static inline int of_partition_ensure_probed(struct device_node *np)
+{
+       return 0;
+}
+
+static inline int of_device_ensure_probed(struct device_node *np)
+{
+       return 0;
+}
+
+static inline int is_of_partition(struct device_node *np)
+{
+       return 0;
+}
+
 #define MAX_DRIVER_NAME                32
 #define DEVICE_ID_SINGLE       -1
 
-- 
2.30.2


Reply via email to