From 65a8f2f8f1066b589560b1f09f3ae1da485335eb Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 13 May 2015 12:12:30 +0200 Subject: 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 Signed-off-by: Sascha Hauer --- drivers/misc/state.c | 72 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 14 deletions(-) (limited to 'drivers/misc') 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[] = { -- cgit v1.2.3