Commit 0e875ee5 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'rproc-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux

Pull remoteproc updates from Bjorn Andersson:
 "Qualcomm SM8650 audio, compute and modem remoteproc are added.
  Qualcomm X1 Elite audio and compute remoteprocs are added, after
  support for shutting down the bootloader-loaded firmware loaded into
  the audio DSP..

  A dozen drivers in the subsystem are transitioned to use devres
  helpers for remoteproc and memory allocations - this makes it possible
  to acquire in-kernel handle to individual remoteproc instances in a
  cluster.

  The release of DMA memory for remoteproc virtio is corrected to ensure
  that restarting due to a watchdog bite doesn't attempt to allocate the
  memory again without first freeing it.

  Last, but not least, a couple of DeviceTree binding cleanups"

* tag 'rproc-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux: (30 commits)
  remoteproc: qcom_q6v5_pas: Unload lite firmware on ADSP
  remoteproc: qcom_q6v5_pas: Add support for X1E80100 ADSP/CDSP
  dt-bindings: remoteproc: qcom,sm8550-pas: document the X1E80100 aDSP & cDSP
  remoteproc: qcom_wcnss: Use devm_rproc_alloc() helper
  remoteproc: qcom_q6v5_wcss: Use devm_rproc_alloc() helper
  remoteproc: qcom_q6v5_pas: Use devm_rproc_alloc() helper
  remoteproc: qcom_q6v5_mss: Use devm_rproc_alloc() helper
  remoteproc: qcom_q6v5_adsp: Use devm_rproc_alloc() helper
  dt-bindings: remoteproc: do not override firmware-name $ref
  dt-bindings: remoteproc: qcom,glink-rpm-edge: drop redundant type from label
  remoteproc: qcom: pas: correct data indentation
  remoteproc: Make rproc_get_by_phandle() work for clusters
  remoteproc: qcom: pas: Add SM8650 remoteproc support
  remoteproc: qcom: pas: make region assign more generic
  dt-bindings: remoteproc: qcom,sm8550-pas: document the SM8650 PAS
  remoteproc: k3-dsp: Use devm_rproc_add() helper
  remoteproc: k3-dsp: Use devm_ioremap_wc() helper
  remoteproc: k3-dsp: Add devm action to release tsp
  remoteproc: k3-dsp: Use devm_kzalloc() helper
  remoteproc: k3-dsp: Use devm_ti_sci_get_by_phandle() helper
  ...
parents ebc9bee8 62210f75
......@@ -47,7 +47,7 @@ properties:
maxItems: 1
firmware-name:
$ref: /schemas/types.yaml#/definitions/string
maxItems: 1
description:
If present, name (or relative path) of the file within the
firmware search path containing the firmware image used when
......@@ -115,7 +115,7 @@ patternProperties:
maxItems: 1
firmware-name:
$ref: /schemas/types.yaml#/definitions/string
maxItems: 1
description:
If present, name (or relative path) of the file within the
firmware search path containing the firmware image used when
......
......@@ -18,7 +18,6 @@ properties:
const: qcom,glink-rpm
label:
$ref: /schemas/types.yaml#/definitions/string
description:
Name of the edge, used for debugging and identification purposes. The
node name will be used if this is not present.
......
......@@ -46,7 +46,7 @@ properties:
description: Reference to the reserved-memory for the Hexagon core
firmware-name:
$ref: /schemas/types.yaml#/definitions/string
maxItems: 1
description: Firmware name for the Hexagon core
required:
......
......@@ -45,7 +45,7 @@ properties:
smd-edge: false
firmware-name:
$ref: /schemas/types.yaml#/definitions/string
maxItems: 1
description: Firmware name for the Hexagon core
required:
......
......@@ -80,7 +80,7 @@ properties:
description: Reference to the reserved-memory for the Hexagon core
firmware-name:
$ref: /schemas/types.yaml#/definitions/string
maxItems: 1
description:
The name of the firmware which should be loaded for this remote
processor.
......
......@@ -42,7 +42,7 @@ properties:
description: Reference to the reserved-memory for the Hexagon core
firmware-name:
$ref: /schemas/types.yaml#/definitions/string
maxItems: 1
description: Firmware name for the Hexagon core
required:
......
......@@ -47,7 +47,7 @@ properties:
smd-edge: false
firmware-name:
$ref: /schemas/types.yaml#/definitions/string
maxItems: 1
description: Firmware name for the Hexagon core
required:
......
......@@ -42,7 +42,7 @@ properties:
smd-edge: false
firmware-name:
$ref: /schemas/types.yaml#/definitions/string
maxItems: 1
description: Firmware name for the Hexagon core
required:
......
......@@ -36,7 +36,7 @@ properties:
description: Reference to the reserved-memory for the Hexagon core
firmware-name:
$ref: /schemas/types.yaml#/definitions/string
maxItems: 1
description: Firmware name for the Hexagon core
smd-edge: false
......
......@@ -46,7 +46,7 @@ properties:
smd-edge: false
firmware-name:
$ref: /schemas/types.yaml#/definitions/string
maxItems: 1
description: Firmware name for the Hexagon core
required:
......
......@@ -47,7 +47,7 @@ properties:
description: Reference to the reserved-memory for the Hexagon core
firmware-name:
$ref: /schemas/types.yaml#/definitions/string
maxItems: 1
description: Firmware name for the Hexagon core
required:
......
......@@ -19,6 +19,11 @@ properties:
- qcom,sm8550-adsp-pas
- qcom,sm8550-cdsp-pas
- qcom,sm8550-mpss-pas
- qcom,sm8650-adsp-pas
- qcom,sm8650-cdsp-pas
- qcom,sm8650-mpss-pas
- qcom,x1e80100-adsp-pas
- qcom,x1e80100-cdsp-pas
reg:
maxItems: 1
......@@ -49,6 +54,8 @@ properties:
- description: Memory region for main Firmware authentication
- description: Memory region for Devicetree Firmware authentication
- description: DSM Memory region
- description: DSM Memory region 2
- description: Memory region for Qlink Logging
required:
- compatible
......@@ -63,6 +70,9 @@ allOf:
enum:
- qcom,sm8550-adsp-pas
- qcom,sm8550-cdsp-pas
- qcom,sm8650-adsp-pas
- qcom,x1e80100-adsp-pas
- qcom,x1e80100-cdsp-pas
then:
properties:
interrupts:
......@@ -71,7 +81,26 @@ allOf:
maxItems: 5
memory-region:
maxItems: 2
else:
- if:
properties:
compatible:
enum:
- qcom,sm8650-cdsp-pas
then:
properties:
interrupts:
maxItems: 5
interrupt-names:
maxItems: 5
memory-region:
minItems: 3
maxItems: 3
- if:
properties:
compatible:
enum:
- qcom,sm8550-mpss-pas
then:
properties:
interrupts:
minItems: 6
......@@ -79,12 +108,29 @@ allOf:
minItems: 6
memory-region:
minItems: 3
maxItems: 3
- if:
properties:
compatible:
enum:
- qcom,sm8650-mpss-pas
then:
properties:
interrupts:
minItems: 6
interrupt-names:
minItems: 6
memory-region:
minItems: 5
maxItems: 5
- if:
properties:
compatible:
enum:
- qcom,sm8550-adsp-pas
- qcom,sm8650-adsp-pas
- qcom,x1e80100-adsp-pas
then:
properties:
power-domains:
......@@ -101,6 +147,7 @@ allOf:
compatible:
enum:
- qcom,sm8550-mpss-pas
- qcom,sm8650-mpss-pas
then:
properties:
power-domains:
......@@ -116,6 +163,8 @@ allOf:
compatible:
enum:
- qcom,sm8550-cdsp-pas
- qcom,sm8650-cdsp-pas
- qcom,x1e80100-cdsp-pas
then:
properties:
power-domains:
......
......@@ -51,7 +51,7 @@ properties:
- const: stop-ack
firmware-name:
$ref: /schemas/types.yaml#/definitions/string
maxItems: 1
description:
Relative firmware image path for the WCNSS core. Defaults to
"wcnss.mdt".
......
......@@ -1040,8 +1040,8 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev)
return ret;
}
rproc = rproc_alloc(dev, "imx-dsp-rproc", &imx_dsp_rproc_ops, fw_name,
sizeof(*priv));
rproc = devm_rproc_alloc(dev, "imx-dsp-rproc", &imx_dsp_rproc_ops,
fw_name, sizeof(*priv));
if (!rproc)
return -ENOMEM;
......@@ -1061,14 +1061,14 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev)
ret = imx_dsp_rproc_detect_mode(priv);
if (ret) {
dev_err(dev, "failed on imx_dsp_rproc_detect_mode\n");
goto err_put_rproc;
return ret;
}
/* There are multiple power domains required by DSP on some platform */
ret = imx_dsp_attach_pm_domains(priv);
if (ret) {
dev_err(dev, "failed on imx_dsp_attach_pm_domains\n");
goto err_put_rproc;
return ret;
}
/* Get clocks */
ret = imx_dsp_rproc_clk_get(priv);
......@@ -1091,8 +1091,6 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev)
err_detach_domains:
dev_pm_domain_detach_list(priv->pd_list);
err_put_rproc:
rproc_free(rproc);
return ret;
}
......@@ -1105,7 +1103,6 @@ static void imx_dsp_rproc_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
rproc_del(rproc);
dev_pm_domain_detach_list(priv->pd_list);
rproc_free(rproc);
}
/* pm runtime functions */
......
......@@ -1049,16 +1049,14 @@ static int imx_rproc_probe(struct platform_device *pdev)
int ret;
/* set some other name then imx */
rproc = rproc_alloc(dev, "imx-rproc", &imx_rproc_ops,
NULL, sizeof(*priv));
rproc = devm_rproc_alloc(dev, "imx-rproc", &imx_rproc_ops,
NULL, sizeof(*priv));
if (!rproc)
return -ENOMEM;
dcfg = of_device_get_match_data(dev);
if (!dcfg) {
ret = -EINVAL;
goto err_put_rproc;
}
if (!dcfg)
return -EINVAL;
priv = rproc->priv;
priv->rproc = rproc;
......@@ -1069,8 +1067,7 @@ static int imx_rproc_probe(struct platform_device *pdev)
priv->workqueue = create_workqueue(dev_name(dev));
if (!priv->workqueue) {
dev_err(dev, "cannot create workqueue\n");
ret = -ENOMEM;
goto err_put_rproc;
return -ENOMEM;
}
ret = imx_rproc_xtr_mbox_init(rproc);
......@@ -1112,8 +1109,6 @@ static int imx_rproc_probe(struct platform_device *pdev)
imx_rproc_free_mbox(rproc);
err_put_wkq:
destroy_workqueue(priv->workqueue);
err_put_rproc:
rproc_free(rproc);
return ret;
}
......@@ -1128,7 +1123,6 @@ static void imx_rproc_remove(struct platform_device *pdev)
imx_rproc_put_scu(rproc);
imx_rproc_free_mbox(rproc);
destroy_workqueue(priv->workqueue);
rproc_free(rproc);
}
static const struct of_device_id imx_rproc_of_match[] = {
......
......@@ -674,8 +674,8 @@ static int adsp_probe(struct platform_device *pdev)
return ret;
}
rproc = rproc_alloc(&pdev->dev, pdev->name, &adsp_ops,
firmware_name, sizeof(*adsp));
rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &adsp_ops,
firmware_name, sizeof(*adsp));
if (!rproc) {
dev_err(&pdev->dev, "unable to allocate remoteproc\n");
return -ENOMEM;
......@@ -700,16 +700,16 @@ static int adsp_probe(struct platform_device *pdev)
ret = adsp_alloc_memory_region(adsp);
if (ret)
goto free_rproc;
return ret;
ret = adsp_init_clock(adsp, desc->clk_ids);
if (ret)
goto free_rproc;
return ret;
ret = qcom_rproc_pds_attach(adsp, desc->pd_names, desc->num_pds);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to attach proxy power domains\n");
goto free_rproc;
return ret;
}
ret = adsp_init_reset(adsp);
......@@ -744,9 +744,6 @@ static int adsp_probe(struct platform_device *pdev)
disable_pm:
qcom_rproc_pds_detach(adsp);
free_rproc:
rproc_free(rproc);
return ret;
}
......@@ -761,7 +758,6 @@ static void adsp_remove(struct platform_device *pdev)
qcom_remove_sysmon_subdev(adsp->sysmon);
qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
qcom_rproc_pds_detach(adsp);
rproc_free(adsp->rproc);
}
static const struct adsp_pil_data adsp_resource_init = {
......
......@@ -1990,8 +1990,8 @@ static int q6v5_probe(struct platform_device *pdev)
return ret;
}
rproc = rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops,
mba_image, sizeof(*qproc));
rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops,
mba_image, sizeof(*qproc));
if (!rproc) {
dev_err(&pdev->dev, "failed to allocate rproc\n");
return -ENOMEM;
......@@ -2008,7 +2008,7 @@ static int q6v5_probe(struct platform_device *pdev)
1, &qproc->hexagon_mdt_image);
if (ret < 0 && ret != -EINVAL) {
dev_err(&pdev->dev, "unable to read mpss firmware-name\n");
goto free_rproc;
return ret;
}
platform_set_drvdata(pdev, qproc);
......@@ -2019,17 +2019,17 @@ static int q6v5_probe(struct platform_device *pdev)
qproc->has_spare_reg = desc->has_spare_reg;
ret = q6v5_init_mem(qproc, pdev);
if (ret)
goto free_rproc;
return ret;
ret = q6v5_alloc_memory_region(qproc);
if (ret)
goto free_rproc;
return ret;
ret = q6v5_init_clocks(&pdev->dev, qproc->proxy_clks,
desc->proxy_clk_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get proxy clocks.\n");
goto free_rproc;
return ret;
}
qproc->proxy_clk_count = ret;
......@@ -2037,7 +2037,7 @@ static int q6v5_probe(struct platform_device *pdev)
desc->reset_clk_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get reset clocks.\n");
goto free_rproc;
return ret;
}
qproc->reset_clk_count = ret;
......@@ -2045,7 +2045,7 @@ static int q6v5_probe(struct platform_device *pdev)
desc->active_clk_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get active clocks.\n");
goto free_rproc;
return ret;
}
qproc->active_clk_count = ret;
......@@ -2053,7 +2053,7 @@ static int q6v5_probe(struct platform_device *pdev)
desc->proxy_supply);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get proxy regulators.\n");
goto free_rproc;
return ret;
}
qproc->proxy_reg_count = ret;
......@@ -2061,7 +2061,7 @@ static int q6v5_probe(struct platform_device *pdev)
desc->active_supply);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get active regulators.\n");
goto free_rproc;
return ret;
}
qproc->active_reg_count = ret;
......@@ -2074,12 +2074,12 @@ static int q6v5_probe(struct platform_device *pdev)
desc->fallback_proxy_supply);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get fallback proxy regulators.\n");
goto free_rproc;
return ret;
}
qproc->fallback_proxy_reg_count = ret;
} else if (ret < 0) {
dev_err(&pdev->dev, "Failed to init power domains\n");
goto free_rproc;
return ret;
} else {
qproc->proxy_pd_count = ret;
}
......@@ -2127,8 +2127,6 @@ static int q6v5_probe(struct platform_device *pdev)
qcom_remove_glink_subdev(rproc, &qproc->glink_subdev);
detach_proxy_pds:
q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
free_rproc:
rproc_free(rproc);
return ret;
}
......@@ -2149,8 +2147,6 @@ static void q6v5_remove(struct platform_device *pdev)
qcom_remove_glink_subdev(rproc, &qproc->glink_subdev);
q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
rproc_free(rproc);
}
static const struct rproc_hexagon_res sc7180_mss = {
......
This diff is collapsed.
......@@ -1011,8 +1011,8 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
if (!desc)
return -EINVAL;
rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops,
desc->firmware_name, sizeof(*wcss));
rproc = devm_rproc_alloc(&pdev->dev, pdev->name, desc->ops,
desc->firmware_name, sizeof(*wcss));
if (!rproc) {
dev_err(&pdev->dev, "failed to allocate rproc\n");
return -ENOMEM;
......@@ -1027,29 +1027,29 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
ret = q6v5_wcss_init_mmio(wcss, pdev);
if (ret)
goto free_rproc;
return ret;
ret = q6v5_alloc_memory_region(wcss);
if (ret)
goto free_rproc;
return ret;
if (wcss->version == WCSS_QCS404) {
ret = q6v5_wcss_init_clock(wcss);
if (ret)
goto free_rproc;
return ret;
ret = q6v5_wcss_init_regulator(wcss);
if (ret)
goto free_rproc;
return ret;
}
ret = q6v5_wcss_init_reset(wcss, desc);
if (ret)
goto free_rproc;
return ret;
ret = qcom_q6v5_init(&wcss->q6v5, pdev, rproc, desc->crash_reason_smem, NULL, NULL);
if (ret)
goto free_rproc;
return ret;
qcom_add_glink_subdev(rproc, &wcss->glink_subdev, "q6wcss");
qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, "q6wcss");
......@@ -1061,16 +1061,11 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
ret = rproc_add(rproc);
if (ret)
goto free_rproc;
return ret;
platform_set_drvdata(pdev, rproc);
return 0;
free_rproc:
rproc_free(rproc);
return ret;
}
static void q6v5_wcss_remove(struct platform_device *pdev)
......@@ -1080,7 +1075,6 @@ static void q6v5_wcss_remove(struct platform_device *pdev)
qcom_q6v5_deinit(&wcss->q6v5);
rproc_del(rproc);
rproc_free(rproc);
}
static const struct wcss_data wcss_ipq8074_res_init = {
......
......@@ -555,8 +555,8 @@ static int wcnss_probe(struct platform_device *pdev)
if (ret < 0 && ret != -EINVAL)
return ret;
rproc = rproc_alloc(&pdev->dev, pdev->name, &wcnss_ops,
fw_name, sizeof(*wcnss));
rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &wcnss_ops,
fw_name, sizeof(*wcnss));
if (!rproc) {
dev_err(&pdev->dev, "unable to allocate remoteproc\n");
return -ENOMEM;
......@@ -574,14 +574,12 @@ static int wcnss_probe(struct platform_device *pdev)
mutex_init(&wcnss->iris_lock);
mmio = devm_platform_ioremap_resource_byname(pdev, "pmu");
if (IS_ERR(mmio)) {
ret = PTR_ERR(mmio);
goto free_rproc;
}
if (IS_ERR(mmio))
return PTR_ERR(mmio);
ret = wcnss_alloc_memory_region(wcnss);
if (ret)
goto free_rproc;
return ret;
wcnss->pmu_cfg = mmio + data->pmu_offset;
wcnss->spare_out = mmio + data->spare_offset;
......@@ -592,7 +590,7 @@ static int wcnss_probe(struct platform_device *pdev)
*/
ret = wcnss_init_pds(wcnss, data->pd_names);
if (ret && (ret != -ENODATA || !data->num_pd_vregs))
goto free_rproc;
return ret;
ret = wcnss_init_regulators(wcnss, data->vregs, data->num_vregs,
data->num_pd_vregs);
......@@ -656,8 +654,6 @@ static int wcnss_probe(struct platform_device *pdev)
qcom_iris_remove(wcnss->iris);
detach_pds:
wcnss_release_pds(wcnss);
free_rproc:
rproc_free(rproc);
return ret;
}
......@@ -673,7 +669,6 @@ static void wcnss_remove(struct platform_device *pdev)
qcom_remove_sysmon_subdev(wcnss->sysmon);
qcom_remove_smd_subdev(wcnss->rproc, &wcnss->smd_subdev);
wcnss_release_pds(wcnss);
rproc_free(wcnss->rproc);
}
static const struct of_device_id wcnss_of_match[] = {
......
......@@ -33,6 +33,7 @@
#include <linux/idr.h>
#include <linux/elf.h>
#include <linux/crc32.h>
#include <linux/of_platform.h>
#include <linux/of_reserved_mem.h>
#include <linux/virtio_ids.h>
#include <linux/virtio_ring.h>
......@@ -2112,6 +2113,7 @@ EXPORT_SYMBOL(rproc_detach);
struct rproc *rproc_get_by_phandle(phandle phandle)
{
struct rproc *rproc = NULL, *r;
struct device_driver *driver;
struct device_node *np;
np = of_find_node_by_phandle(phandle);
......@@ -2122,7 +2124,26 @@ struct rproc *rproc_get_by_phandle(phandle phandle)
list_for_each_entry_rcu(r, &rproc_list, node) {
if (r->dev.parent && device_match_of_node(r->dev.parent, np)) {
/* prevent underlying implementation from being removed */
if (!try_module_get(r->dev.parent->driver->owner)) {
/*
* If the remoteproc's parent has a driver, the
* remoteproc is not part of a cluster and we can use
* that driver.
*/
driver = r->dev.parent->driver;
/*
* If the remoteproc's parent does not have a driver,
* look for the driver associated with the cluster.
*/
if (!driver) {
if (r->dev.parent->parent)
driver = r->dev.parent->parent->driver;
if (!driver)
break;
}
if (!try_module_get(driver->owner)) {
dev_err(&r->dev, "can't get owner\n");
break;
}
......@@ -2533,7 +2554,11 @@ EXPORT_SYMBOL(rproc_free);
*/
void rproc_put(struct rproc *rproc)
{
module_put(rproc->dev.parent->driver->owner);
if (rproc->dev.parent->driver)
module_put(rproc->dev.parent->driver->owner);
else
module_put(rproc->dev.parent->parent->driver->owner);
put_device(&rproc->dev);
}
EXPORT_SYMBOL(rproc_put);
......
......@@ -351,6 +351,9 @@ static void rproc_virtio_dev_release(struct device *dev)
kfree(vdev);
of_reserved_mem_device_release(&rvdev->pdev->dev);
dma_release_coherent_memory(&rvdev->pdev->dev);
put_device(&rvdev->pdev->dev);
}
......@@ -584,9 +587,6 @@ static void rproc_virtio_remove(struct platform_device *pdev)
rproc_remove_subdev(rproc, &rvdev->subdev);
rproc_remove_rvdev(rvdev);
of_reserved_mem_device_release(&pdev->dev);
dma_release_coherent_memory(&pdev->dev);
put_device(&rproc->dev);
}
......
......@@ -347,23 +347,21 @@ static int st_rproc_probe(struct platform_device *pdev)
int enabled;
int ret, i;
rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
rproc = devm_rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
if (!rproc)
return -ENOMEM;
rproc->has_iommu = false;
ddata = rproc->priv;
ddata->config = (struct st_rproc_config *)device_get_match_data(dev);
if (!ddata->config) {
ret = -ENODEV;
goto free_rproc;
}
if (!ddata->config)
return -ENODEV;
platform_set_drvdata(pdev, rproc);
ret = st_rproc_parse_dt(pdev);
if (ret)
goto free_rproc;
return ret;
enabled = st_rproc_state(pdev);
if (enabled < 0) {
......@@ -439,8 +437,7 @@ static int st_rproc_probe(struct platform_device *pdev)
mbox_free_channel(ddata->mbox_chan[i]);
free_clk:
clk_unprepare(ddata->clk);
free_rproc:
rproc_free(rproc);
return ret;
}
......@@ -456,8 +453,6 @@ static void st_rproc_remove(struct platform_device *pdev)
for (i = 0; i < ST_RPROC_MAX_VRING * MBOX_MAX; i++)
mbox_free_channel(ddata->mbox_chan[i]);
rproc_free(rproc);
}
static struct platform_driver st_rproc_driver = {
......
......@@ -120,7 +120,7 @@ static int stm32_rproc_mem_alloc(struct rproc *rproc,
void *va;
dev_dbg(dev, "map memory: %pad+%zx\n", &mem->dma, mem->len);
va = ioremap_wc(mem->dma, mem->len);
va = (__force void *)ioremap_wc(mem->dma, mem->len);
if (IS_ERR_OR_NULL(va)) {
dev_err(dev, "Unable to map memory region: %pad+0x%zx\n",
&mem->dma, mem->len);
......@@ -137,7 +137,7 @@ static int stm32_rproc_mem_release(struct rproc *rproc,
struct rproc_mem_entry *mem)
{
dev_dbg(rproc->dev.parent, "unmap memory: %pa\n", &mem->dma);
iounmap(mem->va);
iounmap((__force __iomem void *)mem->va);
return 0;
}
......@@ -657,7 +657,7 @@ stm32_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
* entire area by overwriting it with the initial values stored in rproc->clean_table.
*/
*table_sz = RSC_TBL_SIZE;
return (struct resource_table *)ddata->rsc_va;
return (__force struct resource_table *)ddata->rsc_va;
}
static const struct rproc_ops st_rproc_ops = {
......@@ -843,7 +843,7 @@ static int stm32_rproc_probe(struct platform_device *pdev)
if (ret)
return ret;
rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
rproc = devm_rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
if (!rproc)
return -ENOMEM;
......@@ -897,7 +897,6 @@ static int stm32_rproc_probe(struct platform_device *pdev)
dev_pm_clear_wake_irq(dev);
device_init_wakeup(dev, false);
}
rproc_free(rproc);
return ret;
}
......@@ -918,7 +917,6 @@ static void stm32_rproc_remove(struct platform_device *pdev)
dev_pm_clear_wake_irq(dev);
device_init_wakeup(dev, false);
}
rproc_free(rproc);
}
static int stm32_rproc_suspend(struct device *dev)
......
......@@ -550,6 +550,13 @@ static int k3_dsp_rproc_of_get_memories(struct platform_device *pdev,
return 0;
}
static void k3_dsp_mem_release(void *data)
{
struct device *dev = data;
of_reserved_mem_device_release(dev);
}
static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc)
{
struct device *dev = kproc->dev;
......@@ -579,27 +586,25 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc)
ERR_PTR(ret));
return ret;
}
ret = devm_add_action_or_reset(dev, k3_dsp_mem_release, dev);
if (ret)
return ret;
num_rmems--;
kproc->rmem = kcalloc(num_rmems, sizeof(*kproc->rmem), GFP_KERNEL);
if (!kproc->rmem) {
ret = -ENOMEM;
goto release_rmem;
}
kproc->rmem = devm_kcalloc(dev, num_rmems, sizeof(*kproc->rmem), GFP_KERNEL);
if (!kproc->rmem)
return -ENOMEM;
/* use remaining reserved memory regions for static carveouts */
for (i = 0; i < num_rmems; i++) {
rmem_np = of_parse_phandle(np, "memory-region", i + 1);
if (!rmem_np) {
ret = -EINVAL;
goto unmap_rmem;
}
if (!rmem_np)
return -EINVAL;
rmem = of_reserved_mem_lookup(rmem_np);
if (!rmem) {
of_node_put(rmem_np);
ret = -EINVAL;
goto unmap_rmem;
return -EINVAL;
}
of_node_put(rmem_np);
......@@ -607,12 +612,11 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc)
/* 64-bit address regions currently not supported */
kproc->rmem[i].dev_addr = (u32)rmem->base;
kproc->rmem[i].size = rmem->size;
kproc->rmem[i].cpu_addr = ioremap_wc(rmem->base, rmem->size);
kproc->rmem[i].cpu_addr = devm_ioremap_wc(dev, rmem->base, rmem->size);
if (!kproc->rmem[i].cpu_addr) {
dev_err(dev, "failed to map reserved memory#%d at %pa of size %pa\n",
i + 1, &rmem->base, &rmem->size);
ret = -ENOMEM;
goto unmap_rmem;
return -ENOMEM;
}
dev_dbg(dev, "reserved memory%d: bus addr %pa size 0x%zx va %pK da 0x%x\n",
......@@ -623,25 +627,13 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc)
kproc->num_rmems = num_rmems;
return 0;
unmap_rmem:
for (i--; i >= 0; i--)
iounmap(kproc->rmem[i].cpu_addr);
kfree(kproc->rmem);
release_rmem:
of_reserved_mem_device_release(kproc->dev);
return ret;
}
static void k3_dsp_reserved_mem_exit(struct k3_dsp_rproc *kproc)
static void k3_dsp_release_tsp(void *data)
{
int i;
struct ti_sci_proc *tsp = data;
for (i = 0; i < kproc->num_rmems; i++)
iounmap(kproc->rmem[i].cpu_addr);
kfree(kproc->rmem);
of_reserved_mem_device_release(kproc->dev);
ti_sci_proc_release(tsp);
}
static
......@@ -657,7 +649,7 @@ struct ti_sci_proc *k3_dsp_rproc_of_get_tsp(struct device *dev,
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);
......@@ -680,7 +672,6 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
const char *fw_name;
bool p_state = false;
int ret = 0;
int ret1;
data = of_device_get_match_data(dev);
if (!data)
......@@ -690,8 +681,8 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
if (ret)
return dev_err_probe(dev, ret, "failed to parse firmware-name property\n");
rproc = rproc_alloc(dev, dev_name(dev), &k3_dsp_rproc_ops, fw_name,
sizeof(*kproc));
rproc = devm_rproc_alloc(dev, dev_name(dev), &k3_dsp_rproc_ops,
fw_name, sizeof(*kproc));
if (!rproc)
return -ENOMEM;
......@@ -706,56 +697,46 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
kproc->dev = dev;
kproc->data = data;
kproc->ti_sci = ti_sci_get_by_phandle(np, "ti,sci");
if (IS_ERR(kproc->ti_sci)) {
ret = dev_err_probe(dev, PTR_ERR(kproc->ti_sci),
"failed to get ti-sci handle\n");
kproc->ti_sci = NULL;
goto free_rproc;
}
kproc->ti_sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
if (IS_ERR(kproc->ti_sci))
return dev_err_probe(dev, PTR_ERR(kproc->ti_sci),
"failed to get ti-sci handle\n");
ret = of_property_read_u32(np, "ti,sci-dev-id", &kproc->ti_sci_id);
if (ret) {
dev_err_probe(dev, ret, "missing 'ti,sci-dev-id' property\n");
goto put_sci;
}
if (ret)
return dev_err_probe(dev, ret, "missing 'ti,sci-dev-id' property\n");
kproc->reset = devm_reset_control_get_exclusive(dev, NULL);
if (IS_ERR(kproc->reset)) {
ret = dev_err_probe(dev, PTR_ERR(kproc->reset),
"failed to get reset\n");
goto put_sci;
}
if (IS_ERR(kproc->reset))
return dev_err_probe(dev, PTR_ERR(kproc->reset),
"failed to get reset\n");
kproc->tsp = k3_dsp_rproc_of_get_tsp(dev, kproc->ti_sci);
if (IS_ERR(kproc->tsp)) {
ret = dev_err_probe(dev, PTR_ERR(kproc->tsp),
"failed to construct ti-sci proc control\n");
goto put_sci;
}
if (IS_ERR(kproc->tsp))
return dev_err_probe(dev, PTR_ERR(kproc->tsp),
"failed to construct ti-sci proc control\n");
ret = ti_sci_proc_request(kproc->tsp);
if (ret < 0) {
dev_err_probe(dev, ret, "ti_sci_proc_request failed\n");
goto free_tsp;
return ret;
}
ret = devm_add_action_or_reset(dev, k3_dsp_release_tsp, kproc->tsp);
if (ret)
return ret;
ret = k3_dsp_rproc_of_get_memories(pdev, kproc);
if (ret)
goto release_tsp;
return ret;
ret = k3_dsp_reserved_mem_init(kproc);
if (ret) {
dev_err_probe(dev, ret, "reserved memory init failed\n");
goto release_tsp;
}
if (ret)
return dev_err_probe(dev, ret, "reserved memory init failed\n");
ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id,
NULL, &p_state);
if (ret) {
dev_err_probe(dev, ret, "failed to get initial state, mode cannot be determined\n");
goto release_mem;
}
if (ret)
return dev_err_probe(dev, ret, "failed to get initial state, mode cannot be determined\n");
/* configure J721E devices for either remoteproc or IPC-only mode */
if (p_state) {
......@@ -779,8 +760,7 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
if (data->uses_lreset) {
ret = reset_control_status(kproc->reset);
if (ret < 0) {
dev_err_probe(dev, ret, "failed to get reset status\n");
goto release_mem;
return dev_err_probe(dev, ret, "failed to get reset status\n");
} else if (ret == 0) {
dev_warn(dev, "local reset is deasserted for device\n");
k3_dsp_rproc_reset(kproc);
......@@ -788,31 +768,13 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
}
}
ret = rproc_add(rproc);
if (ret) {
dev_err_probe(dev, ret, "failed to add register device with remoteproc core\n");
goto release_mem;
}
ret = devm_rproc_add(dev, rproc);
if (ret)
return dev_err_probe(dev, ret, "failed to add register device with remoteproc core\n");
platform_set_drvdata(pdev, kproc);
return 0;
release_mem:
k3_dsp_reserved_mem_exit(kproc);
release_tsp:
ret1 = ti_sci_proc_release(kproc->tsp);
if (ret1)
dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret1));
free_tsp:
kfree(kproc->tsp);
put_sci:
ret1 = ti_sci_put_handle(kproc->ti_sci);
if (ret1)
dev_err(dev, "failed to put ti_sci handle (%pe)\n", ERR_PTR(ret1));
free_rproc:
rproc_free(rproc);
return ret;
}
static void k3_dsp_rproc_remove(struct platform_device *pdev)
......@@ -824,27 +786,9 @@ static void k3_dsp_rproc_remove(struct platform_device *pdev)
if (rproc->state == RPROC_ATTACHED) {
ret = rproc_detach(rproc);
if (ret) {
/* Note this error path leaks resources */
if (ret)
dev_err(dev, "failed to detach proc (%pe)\n", ERR_PTR(ret));
return;
}
}
rproc_del(kproc->rproc);
ret = ti_sci_proc_release(kproc->tsp);
if (ret)
dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret));
kfree(kproc->tsp);
ret = ti_sci_put_handle(kproc->ti_sci);
if (ret)
dev_err(dev, "failed to put ti_sci handle (%pe)\n", ERR_PTR(ret));
k3_dsp_reserved_mem_exit(kproc);
rproc_free(kproc->rproc);
}
static const struct k3_dsp_mem_data c66_mems[] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment