diff options
author | Marc Kleine-Budde <mkl@pengutronix.de> | 2015-05-13 12:12:30 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2015-05-15 07:03:49 +0200 |
commit | 65a8f2f8f1066b589560b1f09f3ae1da485335eb (patch) | |
tree | 8d5e3dc5d28357478ff895436e393923c9e88bae /drivers/misc | |
parent | 74840ebe98f81ad839f4808ea5daf3cd27ac42f5 (diff) | |
download | barebox-65a8f2f8f1066b589560b1f09f3ae1da485335eb.tar.gz barebox-65a8f2f8f1066b589560b1f09f3ae1da485335eb.tar.xz |
state: backend: support phandle and of_path references
This patch improves the backend property, it can be either a phandle or a
of_path. During probe() of the state driver the backend property is
dereferenced and the resulting of_path is saved in the state context. In a
later patch it will be used to generate a phandle reference to the backend
during DT fixup.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/state.c | 72 |
1 files changed, 58 insertions, 14 deletions
diff --git a/drivers/misc/state.c b/drivers/misc/state.c index 3b07bb93d7..f3e366480f 100644 --- a/drivers/misc/state.c +++ b/drivers/misc/state.c @@ -24,10 +24,12 @@ static int state_probe(struct device_d *dev) { struct device_node *np = dev->device_node; + struct device_node *partition_node; struct state *state; const char *alias; const char *backend_type = NULL; - int ret; + int len, ret; + const char *of_path; char *path; if (!np) @@ -41,28 +43,70 @@ static int state_probe(struct device_d *dev) if (IS_ERR(state)) return PTR_ERR(state); - ret = of_find_path(np, "backend", &path, 0); - if (ret) - return ret; + of_path = of_get_property(np, "backend", &len); + if (!of_path) { + ret = -ENODEV; + goto out_release; + } + + /* guess if of_path is a path, not a phandle */ + if (of_path[0] == '/' && len > 1) { + ret = of_find_path(np, "backend", &path, 0); + if (ret) + goto out_release; + } else { + struct device_d *dev; + struct cdev *cdev; + + partition_node = of_parse_phandle(np, "backend", 0); + if (!partition_node) { + ret = -ENODEV; + goto out_release; + } + + dev = of_find_device_by_node(partition_node); + if (!list_is_singular(&dev->cdevs)) { + ret = -ENODEV; + goto out_release; + } + + cdev = list_first_entry(&dev->cdevs, struct cdev, devices_list); + if (!cdev) { + ret = -ENODEV; + goto out_release; + } - dev_info(dev, "outpath: %s\n", path); + path = asprintf("/dev/%s", cdev->name); + of_path = partition_node->full_name; + } ret = of_property_read_string(np, "backend-type", &backend_type); - if (ret) - return ret; - else if (!strcmp(backend_type, "raw")) - ret = state_backend_raw_file(state, path, 0, 0); - else if (!strcmp(backend_type, "dtb")) - ret = state_backend_dtb_file(state, path); - else + if (ret) { + goto out_free; + } else if (!strcmp(backend_type, "raw")) { + ret = state_backend_raw_file(state, of_path, path, 0, 0); + } else if (!strcmp(backend_type, "dtb")) { + ret = state_backend_dtb_file(state, of_path, path); + } else { dev_warn(dev, "invalid backend type: %s\n", backend_type); + ret = -ENODEV; + goto out_free; + } if (ret) - return ret; + goto out_free; - state_load(state); + dev_info(dev, "backend: %s, path: %s, of_path: %s\n", backend_type, path, of_path); + free(path); + state_load(state); return 0; + + out_free: + free(path); + out_release: + state_release(state); + return ret; } static __maybe_unused struct of_device_id state_ids[] = { |