summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 18f60ed)
raw | patch | inline | side by side (parent: 18f60ed)
author | Suman Anna <s-anna@ti.com> | |
Tue, 4 Aug 2020 20:05:00 +0000 (15:05 -0500) | ||
committer | Suman Anna <s-anna@ti.com> | |
Tue, 4 Aug 2020 22:08:47 +0000 (17:08 -0500) |
The K3 R5F remoteproc driver currently uses a mixture of devres and
regular functions, and unwinds all the previously acquired resources
manually upon any failures in cleanup paths, some even using the
devres cleanup functions themselves. Simplify these failure path
code cleanups by updating the driver to use more devres functions.
A lot of the code has been cleaned up courtesy of using
devm_add_action_or_reset() in the driver probe function for the
cluster-level cleanup, and devres_open_group() & devres_release_group()
functions for the core-level cleanups, and using any available
equivalent devres functions for regular functions.
Signed-off-by: Suman Anna <s-anna@ti.com>
regular functions, and unwinds all the previously acquired resources
manually upon any failures in cleanup paths, some even using the
devres cleanup functions themselves. Simplify these failure path
code cleanups by updating the driver to use more devres functions.
A lot of the code has been cleaned up courtesy of using
devm_add_action_or_reset() in the driver probe function for the
cluster-level cleanup, and devres_open_group() & devres_release_group()
functions for the core-level cleanups, and using any available
equivalent devres functions for regular functions.
Signed-off-by: Suman Anna <s-anna@ti.com>
drivers/remoteproc/ti_k3_r5_remoteproc.c | patch | blob | history |
index 47de3643acbfd6f699b95b796072713102bf5c01..ed1769f8617c336b41e114218f8f76bcc84fc9e8 100644 (file)
struct device *dev = &pdev->dev;
struct resource *res;
int num_mems;
- int i, ret;
+ int i;
num_mems = ARRAY_SIZE(mem_names);
core->mem = devm_kcalloc(dev, num_mems, sizeof(*core->mem), GFP_KERNEL);
@@ -1117,16 +1117,14 @@ static int k3_r5_core_of_get_internal_memories(struct platform_device *pdev,
if (!res) {
dev_err(dev, "found no memory resource for %s\n",
mem_names[i]);
- ret = -EINVAL;
- goto fail;
+ return -EINVAL;
}
if (!devm_request_mem_region(dev, res->start,
resource_size(res),
dev_name(dev))) {
dev_err(dev, "could not request %s region for resource\n",
mem_names[i]);
- ret = -EBUSY;
- goto fail;
+ return -EBUSY;
}
/*
resource_size(res));
if (IS_ERR(core->mem[i].cpu_addr)) {
dev_err(dev, "failed to map %s memory\n", mem_names[i]);
- ret = PTR_ERR(core->mem[i].cpu_addr);
- devm_release_mem_region(dev, res->start,
- resource_size(res));
- goto fail;
+ return PTR_ERR(core->mem[i].cpu_addr);
}
core->mem[i].bus_addr = res->start;
core->num_mems = num_mems;
return 0;
-
-fail:
- for (i--; i >= 0; i--) {
- devm_iounmap(dev, core->mem[i].cpu_addr);
- devm_release_mem_region(dev, core->mem[i].bus_addr,
- core->mem[i].size);
- }
- if (core->mem)
- devm_kfree(dev, core->mem);
- return ret;
}
static int k3_r5_core_of_get_sram_memories(struct platform_device *pdev,
return 0;
}
- core->sram = kcalloc(num_sram, sizeof(*core->sram), GFP_KERNEL);
+ core->sram = devm_kcalloc(dev, num_sram, sizeof(*core->sram),
+ GFP_KERNEL);
if (!core->sram)
return -ENOMEM;
for (i = 0; i < num_sram; i++) {
sram_np = of_parse_phandle(np, "sram", i);
- if (!sram_np) {
- ret = -EINVAL;
- goto fail;
- }
+ if (!sram_np)
+ return -EINVAL;
if (!of_device_is_available(sram_np)) {
of_node_put(sram_np);
- ret = -EINVAL;
- goto fail;
+ return -EINVAL;
}
ret = of_address_to_resource(sram_np, 0, &res);
of_node_put(sram_np);
- if (ret) {
- ret = -EINVAL;
- goto fail;
- }
+ if (ret)
+ return -EINVAL;
+
core->sram[i].bus_addr = res.start;
core->sram[i].dev_addr = res.start;
core->sram[i].size = resource_size(&res);
- core->sram[i].cpu_addr = ioremap_wc(res.start,
- resource_size(&res));
+ core->sram[i].cpu_addr = devm_ioremap_wc(dev, res.start,
+ resource_size(&res));
if (!core->sram[i].cpu_addr) {
dev_err(dev, "failed to parse and map sram%d memory at %pad\n",
i, &res.start);
- ret = -ENOMEM;
- goto fail;
+ return -ENOMEM;
}
dev_dbg(dev, "memory sram%d: bus addr %pa size 0x%zx va %pK da 0x%x\n",
core->num_sram = num_sram;
return 0;
-
-fail:
- for (i--; i >= 0; i--) {
- if (core->sram[i].cpu_addr)
- iounmap(core->sram[i].cpu_addr);
- }
- kfree(core->sram);
-
- return ret;
}
static
if (ret < 0)
return ERR_PTR(ret);
- tsp = kzalloc(sizeof(*tsp), GFP_KERNEL);
+ tsp = devm_kzalloc(dev, sizeof(*tsp), GFP_KERNEL);
if (!tsp)
return ERR_PTR(-ENOMEM);
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct k3_r5_core *core;
- int ret, ret1, i;
+ int ret;
- core = devm_kzalloc(dev, sizeof(*core), GFP_KERNEL);
- if (!core)
+ if (!devres_open_group(dev, k3_r5_core_of_init, GFP_KERNEL))
return -ENOMEM;
+ core = devm_kzalloc(dev, sizeof(*core), GFP_KERNEL);
+ if (!core) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
core->dev = dev;
core->atcm_enable = 0;
core->btcm_enable = 1;
ret = of_property_read_u32(np, "atcm-enable", &core->atcm_enable);
if (ret < 0 && ret != -EINVAL) {
dev_err(dev, "invalid format for atcm-enable, ret = %d\n", ret);
- goto err_of;
+ goto err;
}
ret = of_property_read_u32(np, "btcm-enable", &core->btcm_enable);
if (ret < 0 && ret != -EINVAL) {
dev_err(dev, "invalid format for btcm-enable, ret = %d\n", ret);
- goto err_of;
+ goto err;
}
ret = of_property_read_u32(np, "loczrama", &core->loczrama);
if (ret < 0 && ret != -EINVAL) {
dev_err(dev, "invalid format for loczrama, ret = %d\n", ret);
- goto err_of;
+ goto err;
}
- core->ti_sci = ti_sci_get_by_phandle(np, "ti,sci");
+ core->ti_sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
if (IS_ERR(core->ti_sci)) {
ret = PTR_ERR(core->ti_sci);
if (ret != -EPROBE_DEFER) {
ret);
}
core->ti_sci = NULL;
- goto err_of;
+ goto err;
}
ret = of_property_read_u32(np, "ti,sci-dev-id", &core->ti_sci_id);
if (ret) {
dev_err(dev, "missing 'ti,sci-dev-id' property\n");
- goto err_sci_id;
+ goto err;
}
- core->reset = reset_control_get_exclusive(dev, NULL);
- if (IS_ERR(core->reset)) {
- ret = PTR_ERR(core->reset);
+ core->reset = devm_reset_control_get_exclusive(dev, NULL);
+ if (IS_ERR_OR_NULL(core->reset)) {
+ ret = PTR_ERR_OR_ZERO(core->reset);
+ if (!ret)
+ ret = -ENODEV;
if (ret != -EPROBE_DEFER) {
dev_err(dev, "failed to get reset handle, ret = %d\n",
ret);
}
- goto err_sci_id;
+ goto err;
}
core->tsp = k3_r5_core_of_get_tsp(dev, core->ti_sci);
dev_err(dev, "failed to construct ti-sci proc control, ret = %d\n",
ret);
ret = PTR_ERR(core->tsp);
- goto err_sci_proc;
- }
-
- ret = ti_sci_proc_request(core->tsp);
- if (ret < 0) {
- dev_err(dev, "ti_sci_proc_request failed, ret = %d\n", ret);
- goto err_proc;
+ goto err;
}
ret = k3_r5_core_of_get_internal_memories(pdev, core);
if (ret) {
dev_err(dev, "failed to get internal memories, ret = %d\n",
ret);
- goto err_intmem;
+ goto err;
}
ret = k3_r5_core_of_get_sram_memories(pdev, core);
if (ret) {
dev_err(dev, "failed to get sram memories, ret = %d\n", ret);
- goto err_sram;
+ goto err;
+ }
+
+ ret = ti_sci_proc_request(core->tsp);
+ if (ret < 0) {
+ dev_err(dev, "ti_sci_proc_request failed, ret = %d\n", ret);
+ goto err;
}
platform_set_drvdata(pdev, core);
+ devres_close_group(dev, k3_r5_core_of_init);
return 0;
-err_sram:
- for (i = 0; i < core->num_mems; i++) {
- devm_iounmap(dev, core->mem[i].cpu_addr);
- devm_release_mem_region(dev, core->mem[i].bus_addr,
- core->mem[i].size);
- }
- devm_kfree(dev, core->mem);
-err_intmem:
- ret1 = ti_sci_proc_release(core->tsp);
- if (ret1)
- dev_err(dev, "failed to release proc, ret1 = %d\n", ret1);
-err_proc:
- kfree(core->tsp);
-err_sci_proc:
- reset_control_put(core->reset);
-err_sci_id:
- ret1 = ti_sci_put_handle(core->ti_sci);
- if (ret1)
- dev_err(dev, "failed to put ti_sci handle, ret = %d\n", ret1);
-err_of:
- devm_kfree(dev, core);
+err:
+ devres_release_group(dev, k3_r5_core_of_init);
return ret;
}
* free the resources explicitly since driver model is not being used
* for the child R5F devices
*/
-static int k3_r5_core_of_exit(struct platform_device *pdev)
+static void k3_r5_core_of_exit(struct platform_device *pdev)
{
struct k3_r5_core *core = platform_get_drvdata(pdev);
struct device *dev = &pdev->dev;
- int i, ret;
-
- for (i = 0; i < core->num_sram; i++)
- iounmap(core->sram[i].cpu_addr);
- kfree(core->sram);
-
- for (i = 0; i < core->num_mems; i++) {
- devm_release_mem_region(dev, core->mem[i].bus_addr,
- core->mem[i].size);
- devm_iounmap(dev, core->mem[i].cpu_addr);
- }
- if (core->mem)
- devm_kfree(dev, core->mem);
+ int ret;
ret = ti_sci_proc_release(core->tsp);
if (ret)
dev_err(dev, "failed to release proc, ret = %d\n", ret);
- kfree(core->tsp);
- reset_control_put(core->reset);
-
- ret = ti_sci_put_handle(core->ti_sci);
- if (ret)
- dev_err(dev, "failed to put ti_sci handle, ret = %d\n", ret);
-
platform_set_drvdata(pdev, NULL);
- devm_kfree(dev, core);
+ devres_release_group(dev, k3_r5_core_of_init);
+}
- return ret;
+static void k3_r5_cluster_of_exit(struct platform_device *pdev)
+{
+ struct k3_r5_cluster *cluster = platform_get_drvdata(pdev);
+ struct platform_device *cpdev;
+ struct k3_r5_core *core, *temp;
+
+ list_for_each_entry_safe_reverse(core, temp, &cluster->cores, elem) {
+ list_del(&core->elem);
+ cpdev = to_platform_device(core->dev);
+ k3_r5_core_of_exit(cpdev);
+ }
}
static int k3_r5_cluster_of_init(struct platform_device *pdev)
struct device_node *np = dev->of_node;
struct platform_device *cpdev;
struct device_node *child;
- struct k3_r5_core *core, *temp;
+ struct k3_r5_core *core;
int ret;
for_each_available_child_of_node(np, child) {
return 0;
fail:
- list_for_each_entry_safe_reverse(core, temp, &cluster->cores, elem) {
- list_del(&core->elem);
- cpdev = to_platform_device(core->dev);
- if (k3_r5_core_of_exit(cpdev))
- dev_err(dev, "k3_r5_core_of_exit cleanup failed\n");
- }
- return ret;
-}
-
-static int k3_r5_cluster_of_exit(struct platform_device *pdev)
-{
- struct k3_r5_cluster *cluster = platform_get_drvdata(pdev);
- struct device *dev = &pdev->dev;
- struct platform_device *cpdev;
- struct k3_r5_core *core, *temp;
- int ret;
-
- list_for_each_entry_safe_reverse(core, temp, &cluster->cores, elem) {
- list_del(&core->elem);
- cpdev = to_platform_device(core->dev);
- ret = k3_r5_core_of_exit(cpdev);
- if (ret) {
- dev_err(dev, "k3_r5_core_of_exit failed, ret = %d\n",
- ret);
- break;
- }
- }
-
+ k3_r5_cluster_of_exit(pdev);
return ret;
}
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct k3_r5_cluster *cluster;
- int ret, ret1;
+ int ret;
int num_cores;
cluster = devm_kzalloc(dev, sizeof(*cluster), GFP_KERNEL);
platform_set_drvdata(pdev, cluster);
dev_dbg(dev, "creating child devices for R5F cores\n");
- ret = of_platform_populate(np, NULL, NULL, dev);
+ ret = devm_of_platform_populate(dev);
if (ret) {
- dev_err(dev, "of_platform_populate failed, ret = %d\n", ret);
+ dev_err(dev, "devm_of_platform_populate failed, ret = %d\n",
+ ret);
return ret;
}
ret = k3_r5_cluster_of_init(pdev);
if (ret) {
dev_err(dev, "k3_r5_cluster_of_init failed, ret = %d\n", ret);
- goto fail_of;
+ return ret;
}
+ ret = devm_add_action_or_reset(dev,
+ (void(*)(void *))k3_r5_cluster_of_exit,
+ pdev);
+ if (ret)
+ return ret;
+
ret = k3_r5_cluster_rproc_init(pdev);
if (ret) {
dev_err(dev, "k3_r5_cluster_rproc_init failed, ret = %d\n",
ret);
- goto fail_rproc;
- }
-
- return 0;
-
-fail_rproc:
- ret1 = k3_r5_cluster_of_exit(pdev);
- if (ret1)
- dev_err(dev, "k3_r5_cluster_of_exit failed, ret = %d\n", ret1);
-fail_of:
- of_platform_depopulate(dev);
- return ret;
-}
-
-static int k3_r5_remove(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- int ret;
-
- ret = k3_r5_cluster_rproc_exit(pdev);
- if (ret) {
- dev_err(dev, "k3_r5_cluster_rproc_exit failed, ret = %d\n",
- ret);
- goto fail;
- }
-
- ret = k3_r5_cluster_of_exit(pdev);
- if (ret) {
- dev_err(dev, "k3_r5_cluster_of_exit failed, ret = %d\n", ret);
- goto fail;
+ return ret;
}
- dev_dbg(dev, "removing child devices for R5F cores\n");
- of_platform_depopulate(dev);
+ ret = devm_add_action_or_reset(dev,
+ (void(*)(void *))k3_r5_cluster_rproc_exit,
+ pdev);
+ if (ret)
+ return ret;
-fail:
- return ret;
+ return 0;
}
static const struct of_device_id k3_r5_of_match[] = {
static struct platform_driver k3_r5_rproc_driver = {
.probe = k3_r5_probe,
- .remove = k3_r5_remove,
.driver = {
.name = "k3_r5_rproc",
.of_match_table = k3_r5_of_match,