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: ...@@ -47,7 +47,7 @@ properties:
maxItems: 1 maxItems: 1
firmware-name: firmware-name:
$ref: /schemas/types.yaml#/definitions/string maxItems: 1
description: description:
If present, name (or relative path) of the file within the If present, name (or relative path) of the file within the
firmware search path containing the firmware image used when firmware search path containing the firmware image used when
...@@ -115,7 +115,7 @@ patternProperties: ...@@ -115,7 +115,7 @@ patternProperties:
maxItems: 1 maxItems: 1
firmware-name: firmware-name:
$ref: /schemas/types.yaml#/definitions/string maxItems: 1
description: description:
If present, name (or relative path) of the file within the If present, name (or relative path) of the file within the
firmware search path containing the firmware image used when firmware search path containing the firmware image used when
......
...@@ -18,7 +18,6 @@ properties: ...@@ -18,7 +18,6 @@ properties:
const: qcom,glink-rpm const: qcom,glink-rpm
label: label:
$ref: /schemas/types.yaml#/definitions/string
description: description:
Name of the edge, used for debugging and identification purposes. The Name of the edge, used for debugging and identification purposes. The
node name will be used if this is not present. node name will be used if this is not present.
......
...@@ -46,7 +46,7 @@ properties: ...@@ -46,7 +46,7 @@ properties:
description: Reference to the reserved-memory for the Hexagon core description: Reference to the reserved-memory for the Hexagon core
firmware-name: firmware-name:
$ref: /schemas/types.yaml#/definitions/string maxItems: 1
description: Firmware name for the Hexagon core description: Firmware name for the Hexagon core
required: required:
......
...@@ -45,7 +45,7 @@ properties: ...@@ -45,7 +45,7 @@ properties:
smd-edge: false smd-edge: false
firmware-name: firmware-name:
$ref: /schemas/types.yaml#/definitions/string maxItems: 1
description: Firmware name for the Hexagon core description: Firmware name for the Hexagon core
required: required:
......
...@@ -80,7 +80,7 @@ properties: ...@@ -80,7 +80,7 @@ properties:
description: Reference to the reserved-memory for the Hexagon core description: Reference to the reserved-memory for the Hexagon core
firmware-name: firmware-name:
$ref: /schemas/types.yaml#/definitions/string maxItems: 1
description: description:
The name of the firmware which should be loaded for this remote The name of the firmware which should be loaded for this remote
processor. processor.
......
...@@ -42,7 +42,7 @@ properties: ...@@ -42,7 +42,7 @@ properties:
description: Reference to the reserved-memory for the Hexagon core description: Reference to the reserved-memory for the Hexagon core
firmware-name: firmware-name:
$ref: /schemas/types.yaml#/definitions/string maxItems: 1
description: Firmware name for the Hexagon core description: Firmware name for the Hexagon core
required: required:
......
...@@ -47,7 +47,7 @@ properties: ...@@ -47,7 +47,7 @@ properties:
smd-edge: false smd-edge: false
firmware-name: firmware-name:
$ref: /schemas/types.yaml#/definitions/string maxItems: 1
description: Firmware name for the Hexagon core description: Firmware name for the Hexagon core
required: required:
......
...@@ -42,7 +42,7 @@ properties: ...@@ -42,7 +42,7 @@ properties:
smd-edge: false smd-edge: false
firmware-name: firmware-name:
$ref: /schemas/types.yaml#/definitions/string maxItems: 1
description: Firmware name for the Hexagon core description: Firmware name for the Hexagon core
required: required:
......
...@@ -36,7 +36,7 @@ properties: ...@@ -36,7 +36,7 @@ properties:
description: Reference to the reserved-memory for the Hexagon core description: Reference to the reserved-memory for the Hexagon core
firmware-name: firmware-name:
$ref: /schemas/types.yaml#/definitions/string maxItems: 1
description: Firmware name for the Hexagon core description: Firmware name for the Hexagon core
smd-edge: false smd-edge: false
......
...@@ -46,7 +46,7 @@ properties: ...@@ -46,7 +46,7 @@ properties:
smd-edge: false smd-edge: false
firmware-name: firmware-name:
$ref: /schemas/types.yaml#/definitions/string maxItems: 1
description: Firmware name for the Hexagon core description: Firmware name for the Hexagon core
required: required:
......
...@@ -47,7 +47,7 @@ properties: ...@@ -47,7 +47,7 @@ properties:
description: Reference to the reserved-memory for the Hexagon core description: Reference to the reserved-memory for the Hexagon core
firmware-name: firmware-name:
$ref: /schemas/types.yaml#/definitions/string maxItems: 1
description: Firmware name for the Hexagon core description: Firmware name for the Hexagon core
required: required:
......
...@@ -19,6 +19,11 @@ properties: ...@@ -19,6 +19,11 @@ properties:
- qcom,sm8550-adsp-pas - qcom,sm8550-adsp-pas
- qcom,sm8550-cdsp-pas - qcom,sm8550-cdsp-pas
- qcom,sm8550-mpss-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: reg:
maxItems: 1 maxItems: 1
...@@ -49,6 +54,8 @@ properties: ...@@ -49,6 +54,8 @@ properties:
- description: Memory region for main Firmware authentication - description: Memory region for main Firmware authentication
- description: Memory region for Devicetree Firmware authentication - description: Memory region for Devicetree Firmware authentication
- description: DSM Memory region - description: DSM Memory region
- description: DSM Memory region 2
- description: Memory region for Qlink Logging
required: required:
- compatible - compatible
...@@ -63,6 +70,9 @@ allOf: ...@@ -63,6 +70,9 @@ allOf:
enum: enum:
- qcom,sm8550-adsp-pas - qcom,sm8550-adsp-pas
- qcom,sm8550-cdsp-pas - qcom,sm8550-cdsp-pas
- qcom,sm8650-adsp-pas
- qcom,x1e80100-adsp-pas
- qcom,x1e80100-cdsp-pas
then: then:
properties: properties:
interrupts: interrupts:
...@@ -71,7 +81,26 @@ allOf: ...@@ -71,7 +81,26 @@ allOf:
maxItems: 5 maxItems: 5
memory-region: memory-region:
maxItems: 2 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: properties:
interrupts: interrupts:
minItems: 6 minItems: 6
...@@ -79,12 +108,29 @@ allOf: ...@@ -79,12 +108,29 @@ allOf:
minItems: 6 minItems: 6
memory-region: memory-region:
minItems: 3 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: - if:
properties: properties:
compatible: compatible:
enum: enum:
- qcom,sm8550-adsp-pas - qcom,sm8550-adsp-pas
- qcom,sm8650-adsp-pas
- qcom,x1e80100-adsp-pas
then: then:
properties: properties:
power-domains: power-domains:
...@@ -101,6 +147,7 @@ allOf: ...@@ -101,6 +147,7 @@ allOf:
compatible: compatible:
enum: enum:
- qcom,sm8550-mpss-pas - qcom,sm8550-mpss-pas
- qcom,sm8650-mpss-pas
then: then:
properties: properties:
power-domains: power-domains:
...@@ -116,6 +163,8 @@ allOf: ...@@ -116,6 +163,8 @@ allOf:
compatible: compatible:
enum: enum:
- qcom,sm8550-cdsp-pas - qcom,sm8550-cdsp-pas
- qcom,sm8650-cdsp-pas
- qcom,x1e80100-cdsp-pas
then: then:
properties: properties:
power-domains: power-domains:
......
...@@ -51,7 +51,7 @@ properties: ...@@ -51,7 +51,7 @@ properties:
- const: stop-ack - const: stop-ack
firmware-name: firmware-name:
$ref: /schemas/types.yaml#/definitions/string maxItems: 1
description: description:
Relative firmware image path for the WCNSS core. Defaults to Relative firmware image path for the WCNSS core. Defaults to
"wcnss.mdt". "wcnss.mdt".
......
...@@ -1040,8 +1040,8 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev) ...@@ -1040,8 +1040,8 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev)
return ret; return ret;
} }
rproc = rproc_alloc(dev, "imx-dsp-rproc", &imx_dsp_rproc_ops, fw_name, rproc = devm_rproc_alloc(dev, "imx-dsp-rproc", &imx_dsp_rproc_ops,
sizeof(*priv)); fw_name, sizeof(*priv));
if (!rproc) if (!rproc)
return -ENOMEM; return -ENOMEM;
...@@ -1061,14 +1061,14 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev) ...@@ -1061,14 +1061,14 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev)
ret = imx_dsp_rproc_detect_mode(priv); ret = imx_dsp_rproc_detect_mode(priv);
if (ret) { if (ret) {
dev_err(dev, "failed on imx_dsp_rproc_detect_mode\n"); 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 */ /* There are multiple power domains required by DSP on some platform */
ret = imx_dsp_attach_pm_domains(priv); ret = imx_dsp_attach_pm_domains(priv);
if (ret) { if (ret) {
dev_err(dev, "failed on imx_dsp_attach_pm_domains\n"); dev_err(dev, "failed on imx_dsp_attach_pm_domains\n");
goto err_put_rproc; return ret;
} }
/* Get clocks */ /* Get clocks */
ret = imx_dsp_rproc_clk_get(priv); ret = imx_dsp_rproc_clk_get(priv);
...@@ -1091,8 +1091,6 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev) ...@@ -1091,8 +1091,6 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev)
err_detach_domains: err_detach_domains:
dev_pm_domain_detach_list(priv->pd_list); dev_pm_domain_detach_list(priv->pd_list);
err_put_rproc:
rproc_free(rproc);
return ret; return ret;
} }
...@@ -1105,7 +1103,6 @@ static void imx_dsp_rproc_remove(struct platform_device *pdev) ...@@ -1105,7 +1103,6 @@ static void imx_dsp_rproc_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
rproc_del(rproc); rproc_del(rproc);
dev_pm_domain_detach_list(priv->pd_list); dev_pm_domain_detach_list(priv->pd_list);
rproc_free(rproc);
} }
/* pm runtime functions */ /* pm runtime functions */
......
...@@ -1049,16 +1049,14 @@ static int imx_rproc_probe(struct platform_device *pdev) ...@@ -1049,16 +1049,14 @@ static int imx_rproc_probe(struct platform_device *pdev)
int ret; int ret;
/* set some other name then imx */ /* set some other name then imx */
rproc = rproc_alloc(dev, "imx-rproc", &imx_rproc_ops, rproc = devm_rproc_alloc(dev, "imx-rproc", &imx_rproc_ops,
NULL, sizeof(*priv)); NULL, sizeof(*priv));
if (!rproc) if (!rproc)
return -ENOMEM; return -ENOMEM;
dcfg = of_device_get_match_data(dev); dcfg = of_device_get_match_data(dev);
if (!dcfg) { if (!dcfg)
ret = -EINVAL; return -EINVAL;
goto err_put_rproc;
}
priv = rproc->priv; priv = rproc->priv;
priv->rproc = rproc; priv->rproc = rproc;
...@@ -1069,8 +1067,7 @@ static int imx_rproc_probe(struct platform_device *pdev) ...@@ -1069,8 +1067,7 @@ static int imx_rproc_probe(struct platform_device *pdev)
priv->workqueue = create_workqueue(dev_name(dev)); priv->workqueue = create_workqueue(dev_name(dev));
if (!priv->workqueue) { if (!priv->workqueue) {
dev_err(dev, "cannot create workqueue\n"); dev_err(dev, "cannot create workqueue\n");
ret = -ENOMEM; return -ENOMEM;
goto err_put_rproc;
} }
ret = imx_rproc_xtr_mbox_init(rproc); ret = imx_rproc_xtr_mbox_init(rproc);
...@@ -1112,8 +1109,6 @@ static int imx_rproc_probe(struct platform_device *pdev) ...@@ -1112,8 +1109,6 @@ static int imx_rproc_probe(struct platform_device *pdev)
imx_rproc_free_mbox(rproc); imx_rproc_free_mbox(rproc);
err_put_wkq: err_put_wkq:
destroy_workqueue(priv->workqueue); destroy_workqueue(priv->workqueue);
err_put_rproc:
rproc_free(rproc);
return ret; return ret;
} }
...@@ -1128,7 +1123,6 @@ static void imx_rproc_remove(struct platform_device *pdev) ...@@ -1128,7 +1123,6 @@ static void imx_rproc_remove(struct platform_device *pdev)
imx_rproc_put_scu(rproc); imx_rproc_put_scu(rproc);
imx_rproc_free_mbox(rproc); imx_rproc_free_mbox(rproc);
destroy_workqueue(priv->workqueue); destroy_workqueue(priv->workqueue);
rproc_free(rproc);
} }
static const struct of_device_id imx_rproc_of_match[] = { static const struct of_device_id imx_rproc_of_match[] = {
......
...@@ -674,8 +674,8 @@ static int adsp_probe(struct platform_device *pdev) ...@@ -674,8 +674,8 @@ static int adsp_probe(struct platform_device *pdev)
return ret; return ret;
} }
rproc = rproc_alloc(&pdev->dev, pdev->name, &adsp_ops, rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &adsp_ops,
firmware_name, sizeof(*adsp)); firmware_name, sizeof(*adsp));
if (!rproc) { if (!rproc) {
dev_err(&pdev->dev, "unable to allocate remoteproc\n"); dev_err(&pdev->dev, "unable to allocate remoteproc\n");
return -ENOMEM; return -ENOMEM;
...@@ -700,16 +700,16 @@ static int adsp_probe(struct platform_device *pdev) ...@@ -700,16 +700,16 @@ static int adsp_probe(struct platform_device *pdev)
ret = adsp_alloc_memory_region(adsp); ret = adsp_alloc_memory_region(adsp);
if (ret) if (ret)
goto free_rproc; return ret;
ret = adsp_init_clock(adsp, desc->clk_ids); ret = adsp_init_clock(adsp, desc->clk_ids);
if (ret) if (ret)
goto free_rproc; return ret;
ret = qcom_rproc_pds_attach(adsp, desc->pd_names, desc->num_pds); ret = qcom_rproc_pds_attach(adsp, desc->pd_names, desc->num_pds);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "Failed to attach proxy power domains\n"); dev_err(&pdev->dev, "Failed to attach proxy power domains\n");
goto free_rproc; return ret;
} }
ret = adsp_init_reset(adsp); ret = adsp_init_reset(adsp);
...@@ -744,9 +744,6 @@ static int adsp_probe(struct platform_device *pdev) ...@@ -744,9 +744,6 @@ static int adsp_probe(struct platform_device *pdev)
disable_pm: disable_pm:
qcom_rproc_pds_detach(adsp); qcom_rproc_pds_detach(adsp);
free_rproc:
rproc_free(rproc);
return ret; return ret;
} }
...@@ -761,7 +758,6 @@ static void adsp_remove(struct platform_device *pdev) ...@@ -761,7 +758,6 @@ static void adsp_remove(struct platform_device *pdev)
qcom_remove_sysmon_subdev(adsp->sysmon); qcom_remove_sysmon_subdev(adsp->sysmon);
qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev); qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
qcom_rproc_pds_detach(adsp); qcom_rproc_pds_detach(adsp);
rproc_free(adsp->rproc);
} }
static const struct adsp_pil_data adsp_resource_init = { static const struct adsp_pil_data adsp_resource_init = {
......
...@@ -1990,8 +1990,8 @@ static int q6v5_probe(struct platform_device *pdev) ...@@ -1990,8 +1990,8 @@ static int q6v5_probe(struct platform_device *pdev)
return ret; return ret;
} }
rproc = rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops, rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops,
mba_image, sizeof(*qproc)); mba_image, sizeof(*qproc));
if (!rproc) { if (!rproc) {
dev_err(&pdev->dev, "failed to allocate rproc\n"); dev_err(&pdev->dev, "failed to allocate rproc\n");
return -ENOMEM; return -ENOMEM;
...@@ -2008,7 +2008,7 @@ static int q6v5_probe(struct platform_device *pdev) ...@@ -2008,7 +2008,7 @@ static int q6v5_probe(struct platform_device *pdev)
1, &qproc->hexagon_mdt_image); 1, &qproc->hexagon_mdt_image);
if (ret < 0 && ret != -EINVAL) { if (ret < 0 && ret != -EINVAL) {
dev_err(&pdev->dev, "unable to read mpss firmware-name\n"); dev_err(&pdev->dev, "unable to read mpss firmware-name\n");
goto free_rproc; return ret;
} }
platform_set_drvdata(pdev, qproc); platform_set_drvdata(pdev, qproc);
...@@ -2019,17 +2019,17 @@ static int q6v5_probe(struct platform_device *pdev) ...@@ -2019,17 +2019,17 @@ static int q6v5_probe(struct platform_device *pdev)
qproc->has_spare_reg = desc->has_spare_reg; qproc->has_spare_reg = desc->has_spare_reg;
ret = q6v5_init_mem(qproc, pdev); ret = q6v5_init_mem(qproc, pdev);
if (ret) if (ret)
goto free_rproc; return ret;
ret = q6v5_alloc_memory_region(qproc); ret = q6v5_alloc_memory_region(qproc);
if (ret) if (ret)
goto free_rproc; return ret;
ret = q6v5_init_clocks(&pdev->dev, qproc->proxy_clks, ret = q6v5_init_clocks(&pdev->dev, qproc->proxy_clks,
desc->proxy_clk_names); desc->proxy_clk_names);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "Failed to get proxy clocks.\n"); dev_err(&pdev->dev, "Failed to get proxy clocks.\n");
goto free_rproc; return ret;
} }
qproc->proxy_clk_count = ret; qproc->proxy_clk_count = ret;
...@@ -2037,7 +2037,7 @@ static int q6v5_probe(struct platform_device *pdev) ...@@ -2037,7 +2037,7 @@ static int q6v5_probe(struct platform_device *pdev)
desc->reset_clk_names); desc->reset_clk_names);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "Failed to get reset clocks.\n"); dev_err(&pdev->dev, "Failed to get reset clocks.\n");
goto free_rproc; return ret;
} }
qproc->reset_clk_count = ret; qproc->reset_clk_count = ret;
...@@ -2045,7 +2045,7 @@ static int q6v5_probe(struct platform_device *pdev) ...@@ -2045,7 +2045,7 @@ static int q6v5_probe(struct platform_device *pdev)
desc->active_clk_names); desc->active_clk_names);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "Failed to get active clocks.\n"); dev_err(&pdev->dev, "Failed to get active clocks.\n");
goto free_rproc; return ret;
} }
qproc->active_clk_count = ret; qproc->active_clk_count = ret;
...@@ -2053,7 +2053,7 @@ static int q6v5_probe(struct platform_device *pdev) ...@@ -2053,7 +2053,7 @@ static int q6v5_probe(struct platform_device *pdev)
desc->proxy_supply); desc->proxy_supply);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "Failed to get proxy regulators.\n"); dev_err(&pdev->dev, "Failed to get proxy regulators.\n");
goto free_rproc; return ret;
} }
qproc->proxy_reg_count = ret; qproc->proxy_reg_count = ret;
...@@ -2061,7 +2061,7 @@ static int q6v5_probe(struct platform_device *pdev) ...@@ -2061,7 +2061,7 @@ static int q6v5_probe(struct platform_device *pdev)
desc->active_supply); desc->active_supply);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "Failed to get active regulators.\n"); dev_err(&pdev->dev, "Failed to get active regulators.\n");
goto free_rproc; return ret;
} }
qproc->active_reg_count = ret; qproc->active_reg_count = ret;
...@@ -2074,12 +2074,12 @@ static int q6v5_probe(struct platform_device *pdev) ...@@ -2074,12 +2074,12 @@ static int q6v5_probe(struct platform_device *pdev)
desc->fallback_proxy_supply); desc->fallback_proxy_supply);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "Failed to get fallback proxy regulators.\n"); dev_err(&pdev->dev, "Failed to get fallback proxy regulators.\n");
goto free_rproc; return ret;
} }
qproc->fallback_proxy_reg_count = ret; qproc->fallback_proxy_reg_count = ret;
} else if (ret < 0) { } else if (ret < 0) {
dev_err(&pdev->dev, "Failed to init power domains\n"); dev_err(&pdev->dev, "Failed to init power domains\n");
goto free_rproc; return ret;
} else { } else {
qproc->proxy_pd_count = ret; qproc->proxy_pd_count = ret;
} }
...@@ -2127,8 +2127,6 @@ static int q6v5_probe(struct platform_device *pdev) ...@@ -2127,8 +2127,6 @@ static int q6v5_probe(struct platform_device *pdev)
qcom_remove_glink_subdev(rproc, &qproc->glink_subdev); qcom_remove_glink_subdev(rproc, &qproc->glink_subdev);
detach_proxy_pds: detach_proxy_pds:
q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count); q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
free_rproc:
rproc_free(rproc);
return ret; return ret;
} }
...@@ -2149,8 +2147,6 @@ static void q6v5_remove(struct platform_device *pdev) ...@@ -2149,8 +2147,6 @@ static void q6v5_remove(struct platform_device *pdev)
qcom_remove_glink_subdev(rproc, &qproc->glink_subdev); qcom_remove_glink_subdev(rproc, &qproc->glink_subdev);
q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count); q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
rproc_free(rproc);
} }
static const struct rproc_hexagon_res sc7180_mss = { static const struct rproc_hexagon_res sc7180_mss = {
......
...@@ -33,12 +33,15 @@ ...@@ -33,12 +33,15 @@
#define ADSP_DECRYPT_SHUTDOWN_DELAY_MS 100 #define ADSP_DECRYPT_SHUTDOWN_DELAY_MS 100
#define MAX_ASSIGN_COUNT 3
struct adsp_data { struct adsp_data {
int crash_reason_smem; int crash_reason_smem;
const char *firmware_name; const char *firmware_name;
const char *dtb_firmware_name; const char *dtb_firmware_name;
int pas_id; int pas_id;
int dtb_pas_id; int dtb_pas_id;
int lite_pas_id;
unsigned int minidump_id; unsigned int minidump_id;
bool auto_boot; bool auto_boot;
bool decrypt_shutdown; bool decrypt_shutdown;
...@@ -51,6 +54,9 @@ struct adsp_data { ...@@ -51,6 +54,9 @@ struct adsp_data {
int ssctl_id; int ssctl_id;
int region_assign_idx; int region_assign_idx;
int region_assign_count;
bool region_assign_shared;
int region_assign_vmid;
}; };
struct qcom_adsp { struct qcom_adsp {
...@@ -72,6 +78,7 @@ struct qcom_adsp { ...@@ -72,6 +78,7 @@ struct qcom_adsp {
const char *dtb_firmware_name; const char *dtb_firmware_name;
int pas_id; int pas_id;
int dtb_pas_id; int dtb_pas_id;
int lite_pas_id;
unsigned int minidump_id; unsigned int minidump_id;
int crash_reason_smem; int crash_reason_smem;
bool decrypt_shutdown; bool decrypt_shutdown;
...@@ -87,15 +94,18 @@ struct qcom_adsp { ...@@ -87,15 +94,18 @@ struct qcom_adsp {
phys_addr_t dtb_mem_phys; phys_addr_t dtb_mem_phys;
phys_addr_t mem_reloc; phys_addr_t mem_reloc;
phys_addr_t dtb_mem_reloc; phys_addr_t dtb_mem_reloc;
phys_addr_t region_assign_phys; phys_addr_t region_assign_phys[MAX_ASSIGN_COUNT];
void *mem_region; void *mem_region;
void *dtb_mem_region; void *dtb_mem_region;
size_t mem_size; size_t mem_size;
size_t dtb_mem_size; size_t dtb_mem_size;
size_t region_assign_size; size_t region_assign_size[MAX_ASSIGN_COUNT];
int region_assign_idx; int region_assign_idx;
u64 region_assign_perms; int region_assign_count;
bool region_assign_shared;
int region_assign_vmid;
u64 region_assign_owners[MAX_ASSIGN_COUNT];
struct qcom_rproc_glink glink_subdev; struct qcom_rproc_glink glink_subdev;
struct qcom_rproc_subdev smd_subdev; struct qcom_rproc_subdev smd_subdev;
...@@ -210,6 +220,9 @@ static int adsp_load(struct rproc *rproc, const struct firmware *fw) ...@@ -210,6 +220,9 @@ static int adsp_load(struct rproc *rproc, const struct firmware *fw)
/* Store firmware handle to be used in adsp_start() */ /* Store firmware handle to be used in adsp_start() */
adsp->firmware = fw; adsp->firmware = fw;
if (adsp->lite_pas_id)
ret = qcom_scm_pas_shutdown(adsp->lite_pas_id);
if (adsp->dtb_pas_id) { if (adsp->dtb_pas_id) {
ret = request_firmware(&adsp->dtb_firmware, adsp->dtb_firmware_name, adsp->dev); ret = request_firmware(&adsp->dtb_firmware, adsp->dtb_firmware_name, adsp->dev);
if (ret) { if (ret) {
...@@ -590,37 +603,53 @@ static int adsp_alloc_memory_region(struct qcom_adsp *adsp) ...@@ -590,37 +603,53 @@ static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
static int adsp_assign_memory_region(struct qcom_adsp *adsp) static int adsp_assign_memory_region(struct qcom_adsp *adsp)
{ {
struct reserved_mem *rmem = NULL; struct qcom_scm_vmperm perm[MAX_ASSIGN_COUNT];
struct qcom_scm_vmperm perm;
struct device_node *node; struct device_node *node;
unsigned int perm_size;
int offset;
int ret; int ret;
if (!adsp->region_assign_idx) if (!adsp->region_assign_idx)
return 0; return 0;
node = of_parse_phandle(adsp->dev->of_node, "memory-region", adsp->region_assign_idx); for (offset = 0; offset < adsp->region_assign_count; ++offset) {
if (node) struct reserved_mem *rmem = NULL;
rmem = of_reserved_mem_lookup(node);
of_node_put(node); node = of_parse_phandle(adsp->dev->of_node, "memory-region",
if (!rmem) { adsp->region_assign_idx + offset);
dev_err(adsp->dev, "unable to resolve shareable memory-region\n"); if (node)
return -EINVAL; rmem = of_reserved_mem_lookup(node);
} of_node_put(node);
if (!rmem) {
dev_err(adsp->dev, "unable to resolve shareable memory-region index %d\n",
offset);
return -EINVAL;
}
perm.vmid = QCOM_SCM_VMID_MSS_MSA; if (adsp->region_assign_shared) {
perm.perm = QCOM_SCM_PERM_RW; perm[0].vmid = QCOM_SCM_VMID_HLOS;
perm[0].perm = QCOM_SCM_PERM_RW;
perm[1].vmid = adsp->region_assign_vmid;
perm[1].perm = QCOM_SCM_PERM_RW;
perm_size = 2;
} else {
perm[0].vmid = adsp->region_assign_vmid;
perm[0].perm = QCOM_SCM_PERM_RW;
perm_size = 1;
}
adsp->region_assign_phys = rmem->base; adsp->region_assign_phys[offset] = rmem->base;
adsp->region_assign_size = rmem->size; adsp->region_assign_size[offset] = rmem->size;
adsp->region_assign_perms = BIT(QCOM_SCM_VMID_HLOS); adsp->region_assign_owners[offset] = BIT(QCOM_SCM_VMID_HLOS);
ret = qcom_scm_assign_mem(adsp->region_assign_phys, ret = qcom_scm_assign_mem(adsp->region_assign_phys[offset],
adsp->region_assign_size, adsp->region_assign_size[offset],
&adsp->region_assign_perms, &adsp->region_assign_owners[offset],
&perm, 1); perm, perm_size);
if (ret < 0) { if (ret < 0) {
dev_err(adsp->dev, "assign memory failed\n"); dev_err(adsp->dev, "assign memory %d failed\n", offset);
return ret; return ret;
}
} }
return 0; return 0;
...@@ -629,20 +658,23 @@ static int adsp_assign_memory_region(struct qcom_adsp *adsp) ...@@ -629,20 +658,23 @@ static int adsp_assign_memory_region(struct qcom_adsp *adsp)
static void adsp_unassign_memory_region(struct qcom_adsp *adsp) static void adsp_unassign_memory_region(struct qcom_adsp *adsp)
{ {
struct qcom_scm_vmperm perm; struct qcom_scm_vmperm perm;
int offset;
int ret; int ret;
if (!adsp->region_assign_idx) if (!adsp->region_assign_idx || adsp->region_assign_shared)
return; return;
perm.vmid = QCOM_SCM_VMID_HLOS; for (offset = 0; offset < adsp->region_assign_count; ++offset) {
perm.perm = QCOM_SCM_PERM_RW; perm.vmid = QCOM_SCM_VMID_HLOS;
perm.perm = QCOM_SCM_PERM_RW;
ret = qcom_scm_assign_mem(adsp->region_assign_phys, ret = qcom_scm_assign_mem(adsp->region_assign_phys[offset],
adsp->region_assign_size, adsp->region_assign_size[offset],
&adsp->region_assign_perms, &adsp->region_assign_owners[offset],
&perm, 1); &perm, 1);
if (ret < 0) if (ret < 0)
dev_err(adsp->dev, "unassign memory failed\n"); dev_err(adsp->dev, "unassign memory %d failed\n", offset);
}
} }
static int adsp_probe(struct platform_device *pdev) static int adsp_probe(struct platform_device *pdev)
...@@ -678,7 +710,7 @@ static int adsp_probe(struct platform_device *pdev) ...@@ -678,7 +710,7 @@ static int adsp_probe(struct platform_device *pdev)
if (desc->minidump_id) if (desc->minidump_id)
ops = &adsp_minidump_ops; ops = &adsp_minidump_ops;
rproc = rproc_alloc(&pdev->dev, pdev->name, ops, fw_name, sizeof(*adsp)); rproc = devm_rproc_alloc(&pdev->dev, pdev->name, ops, fw_name, sizeof(*adsp));
if (!rproc) { if (!rproc) {
dev_err(&pdev->dev, "unable to allocate remoteproc\n"); dev_err(&pdev->dev, "unable to allocate remoteproc\n");
...@@ -693,9 +725,13 @@ static int adsp_probe(struct platform_device *pdev) ...@@ -693,9 +725,13 @@ static int adsp_probe(struct platform_device *pdev)
adsp->rproc = rproc; adsp->rproc = rproc;
adsp->minidump_id = desc->minidump_id; adsp->minidump_id = desc->minidump_id;
adsp->pas_id = desc->pas_id; adsp->pas_id = desc->pas_id;
adsp->lite_pas_id = desc->lite_pas_id;
adsp->info_name = desc->sysmon_name; adsp->info_name = desc->sysmon_name;
adsp->decrypt_shutdown = desc->decrypt_shutdown; adsp->decrypt_shutdown = desc->decrypt_shutdown;
adsp->region_assign_idx = desc->region_assign_idx; adsp->region_assign_idx = desc->region_assign_idx;
adsp->region_assign_count = min_t(int, MAX_ASSIGN_COUNT, desc->region_assign_count);
adsp->region_assign_vmid = desc->region_assign_vmid;
adsp->region_assign_shared = desc->region_assign_shared;
if (dtb_fw_name) { if (dtb_fw_name) {
adsp->dtb_firmware_name = dtb_fw_name; adsp->dtb_firmware_name = dtb_fw_name;
adsp->dtb_pas_id = desc->dtb_pas_id; adsp->dtb_pas_id = desc->dtb_pas_id;
...@@ -754,7 +790,6 @@ static int adsp_probe(struct platform_device *pdev) ...@@ -754,7 +790,6 @@ static int adsp_probe(struct platform_device *pdev)
adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count); adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
free_rproc: free_rproc:
device_init_wakeup(adsp->dev, false); device_init_wakeup(adsp->dev, false);
rproc_free(rproc);
return ret; return ret;
} }
...@@ -773,28 +808,27 @@ static void adsp_remove(struct platform_device *pdev) ...@@ -773,28 +808,27 @@ static void adsp_remove(struct platform_device *pdev)
qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev); qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count); adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
device_init_wakeup(adsp->dev, false); device_init_wakeup(adsp->dev, false);
rproc_free(adsp->rproc);
} }
static const struct adsp_data adsp_resource_init = { static const struct adsp_data adsp_resource_init = {
.crash_reason_smem = 423, .crash_reason_smem = 423,
.firmware_name = "adsp.mdt", .firmware_name = "adsp.mdt",
.pas_id = 1, .pas_id = 1,
.auto_boot = true, .auto_boot = true,
.ssr_name = "lpass", .ssr_name = "lpass",
.sysmon_name = "adsp", .sysmon_name = "adsp",
.ssctl_id = 0x14, .ssctl_id = 0x14,
}; };
static const struct adsp_data sdm845_adsp_resource_init = { static const struct adsp_data sdm845_adsp_resource_init = {
.crash_reason_smem = 423, .crash_reason_smem = 423,
.firmware_name = "adsp.mdt", .firmware_name = "adsp.mdt",
.pas_id = 1, .pas_id = 1,
.auto_boot = true, .auto_boot = true,
.load_state = "adsp", .load_state = "adsp",
.ssr_name = "lpass", .ssr_name = "lpass",
.sysmon_name = "adsp", .sysmon_name = "adsp",
.ssctl_id = 0x14, .ssctl_id = 0x14,
}; };
static const struct adsp_data sm6350_adsp_resource = { static const struct adsp_data sm6350_adsp_resource = {
...@@ -829,18 +863,18 @@ static const struct adsp_data sm6375_mpss_resource = { ...@@ -829,18 +863,18 @@ static const struct adsp_data sm6375_mpss_resource = {
}; };
static const struct adsp_data sm8150_adsp_resource = { static const struct adsp_data sm8150_adsp_resource = {
.crash_reason_smem = 423, .crash_reason_smem = 423,
.firmware_name = "adsp.mdt", .firmware_name = "adsp.mdt",
.pas_id = 1, .pas_id = 1,
.auto_boot = true, .auto_boot = true,
.proxy_pd_names = (char*[]){ .proxy_pd_names = (char*[]){
"cx", "cx",
NULL NULL
}, },
.load_state = "adsp", .load_state = "adsp",
.ssr_name = "lpass", .ssr_name = "lpass",
.sysmon_name = "adsp", .sysmon_name = "adsp",
.ssctl_id = 0x14, .ssctl_id = 0x14,
}; };
static const struct adsp_data sm8250_adsp_resource = { static const struct adsp_data sm8250_adsp_resource = {
...@@ -876,17 +910,17 @@ static const struct adsp_data sm8350_adsp_resource = { ...@@ -876,17 +910,17 @@ static const struct adsp_data sm8350_adsp_resource = {
}; };
static const struct adsp_data msm8996_adsp_resource = { static const struct adsp_data msm8996_adsp_resource = {
.crash_reason_smem = 423, .crash_reason_smem = 423,
.firmware_name = "adsp.mdt", .firmware_name = "adsp.mdt",
.pas_id = 1, .pas_id = 1,
.auto_boot = true, .auto_boot = true,
.proxy_pd_names = (char*[]){ .proxy_pd_names = (char*[]){
"cx", "cx",
NULL NULL
}, },
.ssr_name = "lpass", .ssr_name = "lpass",
.sysmon_name = "adsp", .sysmon_name = "adsp",
.ssctl_id = 0x14, .ssctl_id = 0x14,
}; };
static const struct adsp_data cdsp_resource_init = { static const struct adsp_data cdsp_resource_init = {
...@@ -984,6 +1018,46 @@ static const struct adsp_data sc8280xp_nsp1_resource = { ...@@ -984,6 +1018,46 @@ static const struct adsp_data sc8280xp_nsp1_resource = {
.ssctl_id = 0x20, .ssctl_id = 0x20,
}; };
static const struct adsp_data x1e80100_adsp_resource = {
.crash_reason_smem = 423,
.firmware_name = "adsp.mdt",
.dtb_firmware_name = "adsp_dtb.mdt",
.pas_id = 1,
.dtb_pas_id = 0x24,
.lite_pas_id = 0x1f,
.minidump_id = 5,
.auto_boot = true,
.proxy_pd_names = (char*[]){
"lcx",
"lmx",
NULL
},
.load_state = "adsp",
.ssr_name = "lpass",
.sysmon_name = "adsp",
.ssctl_id = 0x14,
};
static const struct adsp_data x1e80100_cdsp_resource = {
.crash_reason_smem = 601,
.firmware_name = "cdsp.mdt",
.dtb_firmware_name = "cdsp_dtb.mdt",
.pas_id = 18,
.dtb_pas_id = 0x25,
.minidump_id = 7,
.auto_boot = true,
.proxy_pd_names = (char*[]){
"cx",
"mxc",
"nsp",
NULL
},
.load_state = "cdsp",
.ssr_name = "cdsp",
.sysmon_name = "cdsp",
.ssctl_id = 0x17,
};
static const struct adsp_data sm8350_cdsp_resource = { static const struct adsp_data sm8350_cdsp_resource = {
.crash_reason_smem = 601, .crash_reason_smem = 601,
.firmware_name = "cdsp.mdt", .firmware_name = "cdsp.mdt",
...@@ -1033,33 +1107,33 @@ static const struct adsp_data sc8180x_mpss_resource = { ...@@ -1033,33 +1107,33 @@ static const struct adsp_data sc8180x_mpss_resource = {
}; };
static const struct adsp_data msm8996_slpi_resource_init = { static const struct adsp_data msm8996_slpi_resource_init = {
.crash_reason_smem = 424, .crash_reason_smem = 424,
.firmware_name = "slpi.mdt", .firmware_name = "slpi.mdt",
.pas_id = 12, .pas_id = 12,
.auto_boot = true, .auto_boot = true,
.proxy_pd_names = (char*[]){ .proxy_pd_names = (char*[]){
"ssc_cx", "ssc_cx",
NULL NULL
}, },
.ssr_name = "dsps", .ssr_name = "dsps",
.sysmon_name = "slpi", .sysmon_name = "slpi",
.ssctl_id = 0x16, .ssctl_id = 0x16,
}; };
static const struct adsp_data sdm845_slpi_resource_init = { static const struct adsp_data sdm845_slpi_resource_init = {
.crash_reason_smem = 424, .crash_reason_smem = 424,
.firmware_name = "slpi.mdt", .firmware_name = "slpi.mdt",
.pas_id = 12, .pas_id = 12,
.auto_boot = true, .auto_boot = true,
.proxy_pd_names = (char*[]){ .proxy_pd_names = (char*[]){
"lcx", "lcx",
"lmx", "lmx",
NULL NULL
}, },
.load_state = "slpi", .load_state = "slpi",
.ssr_name = "dsps", .ssr_name = "dsps",
.sysmon_name = "slpi", .sysmon_name = "slpi",
.ssctl_id = 0x16, .ssctl_id = 0x16,
}; };
static const struct adsp_data wcss_resource_init = { static const struct adsp_data wcss_resource_init = {
...@@ -1163,6 +1237,8 @@ static const struct adsp_data sm8550_mpss_resource = { ...@@ -1163,6 +1237,8 @@ static const struct adsp_data sm8550_mpss_resource = {
.sysmon_name = "modem", .sysmon_name = "modem",
.ssctl_id = 0x12, .ssctl_id = 0x12,
.region_assign_idx = 2, .region_assign_idx = 2,
.region_assign_count = 1,
.region_assign_vmid = QCOM_SCM_VMID_MSS_MSA,
}; };
static const struct adsp_data sc7280_wpss_resource = { static const struct adsp_data sc7280_wpss_resource = {
...@@ -1181,6 +1257,53 @@ static const struct adsp_data sc7280_wpss_resource = { ...@@ -1181,6 +1257,53 @@ static const struct adsp_data sc7280_wpss_resource = {
.ssctl_id = 0x19, .ssctl_id = 0x19,
}; };
static const struct adsp_data sm8650_cdsp_resource = {
.crash_reason_smem = 601,
.firmware_name = "cdsp.mdt",
.dtb_firmware_name = "cdsp_dtb.mdt",
.pas_id = 18,
.dtb_pas_id = 0x25,
.minidump_id = 7,
.auto_boot = true,
.proxy_pd_names = (char*[]){
"cx",
"mxc",
"nsp",
NULL
},
.load_state = "cdsp",
.ssr_name = "cdsp",
.sysmon_name = "cdsp",
.ssctl_id = 0x17,
.region_assign_idx = 2,
.region_assign_count = 1,
.region_assign_shared = true,
.region_assign_vmid = QCOM_SCM_VMID_CDSP,
};
static const struct adsp_data sm8650_mpss_resource = {
.crash_reason_smem = 421,
.firmware_name = "modem.mdt",
.dtb_firmware_name = "modem_dtb.mdt",
.pas_id = 4,
.dtb_pas_id = 0x26,
.minidump_id = 3,
.auto_boot = false,
.decrypt_shutdown = true,
.proxy_pd_names = (char*[]){
"cx",
"mss",
NULL
},
.load_state = "modem",
.ssr_name = "mpss",
.sysmon_name = "modem",
.ssctl_id = 0x12,
.region_assign_idx = 2,
.region_assign_count = 3,
.region_assign_vmid = QCOM_SCM_VMID_MSS_MSA,
};
static const struct of_device_id adsp_of_match[] = { static const struct of_device_id adsp_of_match[] = {
{ .compatible = "qcom,msm8226-adsp-pil", .data = &adsp_resource_init}, { .compatible = "qcom,msm8226-adsp-pil", .data = &adsp_resource_init},
{ .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource}, { .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource},
...@@ -1236,6 +1359,11 @@ static const struct of_device_id adsp_of_match[] = { ...@@ -1236,6 +1359,11 @@ static const struct of_device_id adsp_of_match[] = {
{ .compatible = "qcom,sm8550-adsp-pas", .data = &sm8550_adsp_resource}, { .compatible = "qcom,sm8550-adsp-pas", .data = &sm8550_adsp_resource},
{ .compatible = "qcom,sm8550-cdsp-pas", .data = &sm8550_cdsp_resource}, { .compatible = "qcom,sm8550-cdsp-pas", .data = &sm8550_cdsp_resource},
{ .compatible = "qcom,sm8550-mpss-pas", .data = &sm8550_mpss_resource}, { .compatible = "qcom,sm8550-mpss-pas", .data = &sm8550_mpss_resource},
{ .compatible = "qcom,sm8650-adsp-pas", .data = &sm8550_adsp_resource},
{ .compatible = "qcom,sm8650-cdsp-pas", .data = &sm8650_cdsp_resource},
{ .compatible = "qcom,sm8650-mpss-pas", .data = &sm8650_mpss_resource},
{ .compatible = "qcom,x1e80100-adsp-pas", .data = &x1e80100_adsp_resource},
{ .compatible = "qcom,x1e80100-cdsp-pas", .data = &x1e80100_cdsp_resource},
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, adsp_of_match); MODULE_DEVICE_TABLE(of, adsp_of_match);
......
...@@ -1011,8 +1011,8 @@ static int q6v5_wcss_probe(struct platform_device *pdev) ...@@ -1011,8 +1011,8 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
if (!desc) if (!desc)
return -EINVAL; return -EINVAL;
rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops, rproc = devm_rproc_alloc(&pdev->dev, pdev->name, desc->ops,
desc->firmware_name, sizeof(*wcss)); desc->firmware_name, sizeof(*wcss));
if (!rproc) { if (!rproc) {
dev_err(&pdev->dev, "failed to allocate rproc\n"); dev_err(&pdev->dev, "failed to allocate rproc\n");
return -ENOMEM; return -ENOMEM;
...@@ -1027,29 +1027,29 @@ static int q6v5_wcss_probe(struct platform_device *pdev) ...@@ -1027,29 +1027,29 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
ret = q6v5_wcss_init_mmio(wcss, pdev); ret = q6v5_wcss_init_mmio(wcss, pdev);
if (ret) if (ret)
goto free_rproc; return ret;
ret = q6v5_alloc_memory_region(wcss); ret = q6v5_alloc_memory_region(wcss);
if (ret) if (ret)
goto free_rproc; return ret;
if (wcss->version == WCSS_QCS404) { if (wcss->version == WCSS_QCS404) {
ret = q6v5_wcss_init_clock(wcss); ret = q6v5_wcss_init_clock(wcss);
if (ret) if (ret)
goto free_rproc; return ret;
ret = q6v5_wcss_init_regulator(wcss); ret = q6v5_wcss_init_regulator(wcss);
if (ret) if (ret)
goto free_rproc; return ret;
} }
ret = q6v5_wcss_init_reset(wcss, desc); ret = q6v5_wcss_init_reset(wcss, desc);
if (ret) if (ret)
goto free_rproc; return ret;
ret = qcom_q6v5_init(&wcss->q6v5, pdev, rproc, desc->crash_reason_smem, NULL, NULL); ret = qcom_q6v5_init(&wcss->q6v5, pdev, rproc, desc->crash_reason_smem, NULL, NULL);
if (ret) if (ret)
goto free_rproc; return ret;
qcom_add_glink_subdev(rproc, &wcss->glink_subdev, "q6wcss"); qcom_add_glink_subdev(rproc, &wcss->glink_subdev, "q6wcss");
qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, "q6wcss"); qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, "q6wcss");
...@@ -1061,16 +1061,11 @@ static int q6v5_wcss_probe(struct platform_device *pdev) ...@@ -1061,16 +1061,11 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
ret = rproc_add(rproc); ret = rproc_add(rproc);
if (ret) if (ret)
goto free_rproc; return ret;
platform_set_drvdata(pdev, rproc); platform_set_drvdata(pdev, rproc);
return 0; return 0;
free_rproc:
rproc_free(rproc);
return ret;
} }
static void q6v5_wcss_remove(struct platform_device *pdev) static void q6v5_wcss_remove(struct platform_device *pdev)
...@@ -1080,7 +1075,6 @@ 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); qcom_q6v5_deinit(&wcss->q6v5);
rproc_del(rproc); rproc_del(rproc);
rproc_free(rproc);
} }
static const struct wcss_data wcss_ipq8074_res_init = { static const struct wcss_data wcss_ipq8074_res_init = {
......
...@@ -555,8 +555,8 @@ static int wcnss_probe(struct platform_device *pdev) ...@@ -555,8 +555,8 @@ static int wcnss_probe(struct platform_device *pdev)
if (ret < 0 && ret != -EINVAL) if (ret < 0 && ret != -EINVAL)
return ret; return ret;
rproc = rproc_alloc(&pdev->dev, pdev->name, &wcnss_ops, rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &wcnss_ops,
fw_name, sizeof(*wcnss)); fw_name, sizeof(*wcnss));
if (!rproc) { if (!rproc) {
dev_err(&pdev->dev, "unable to allocate remoteproc\n"); dev_err(&pdev->dev, "unable to allocate remoteproc\n");
return -ENOMEM; return -ENOMEM;
...@@ -574,14 +574,12 @@ static int wcnss_probe(struct platform_device *pdev) ...@@ -574,14 +574,12 @@ static int wcnss_probe(struct platform_device *pdev)
mutex_init(&wcnss->iris_lock); mutex_init(&wcnss->iris_lock);
mmio = devm_platform_ioremap_resource_byname(pdev, "pmu"); mmio = devm_platform_ioremap_resource_byname(pdev, "pmu");
if (IS_ERR(mmio)) { if (IS_ERR(mmio))
ret = PTR_ERR(mmio); return PTR_ERR(mmio);
goto free_rproc;
}
ret = wcnss_alloc_memory_region(wcnss); ret = wcnss_alloc_memory_region(wcnss);
if (ret) if (ret)
goto free_rproc; return ret;
wcnss->pmu_cfg = mmio + data->pmu_offset; wcnss->pmu_cfg = mmio + data->pmu_offset;
wcnss->spare_out = mmio + data->spare_offset; wcnss->spare_out = mmio + data->spare_offset;
...@@ -592,7 +590,7 @@ static int wcnss_probe(struct platform_device *pdev) ...@@ -592,7 +590,7 @@ static int wcnss_probe(struct platform_device *pdev)
*/ */
ret = wcnss_init_pds(wcnss, data->pd_names); ret = wcnss_init_pds(wcnss, data->pd_names);
if (ret && (ret != -ENODATA || !data->num_pd_vregs)) if (ret && (ret != -ENODATA || !data->num_pd_vregs))
goto free_rproc; return ret;
ret = wcnss_init_regulators(wcnss, data->vregs, data->num_vregs, ret = wcnss_init_regulators(wcnss, data->vregs, data->num_vregs,
data->num_pd_vregs); data->num_pd_vregs);
...@@ -656,8 +654,6 @@ static int wcnss_probe(struct platform_device *pdev) ...@@ -656,8 +654,6 @@ static int wcnss_probe(struct platform_device *pdev)
qcom_iris_remove(wcnss->iris); qcom_iris_remove(wcnss->iris);
detach_pds: detach_pds:
wcnss_release_pds(wcnss); wcnss_release_pds(wcnss);
free_rproc:
rproc_free(rproc);
return ret; return ret;
} }
...@@ -673,7 +669,6 @@ static void wcnss_remove(struct platform_device *pdev) ...@@ -673,7 +669,6 @@ static void wcnss_remove(struct platform_device *pdev)
qcom_remove_sysmon_subdev(wcnss->sysmon); qcom_remove_sysmon_subdev(wcnss->sysmon);
qcom_remove_smd_subdev(wcnss->rproc, &wcnss->smd_subdev); qcom_remove_smd_subdev(wcnss->rproc, &wcnss->smd_subdev);
wcnss_release_pds(wcnss); wcnss_release_pds(wcnss);
rproc_free(wcnss->rproc);
} }
static const struct of_device_id wcnss_of_match[] = { static const struct of_device_id wcnss_of_match[] = {
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/idr.h> #include <linux/idr.h>
#include <linux/elf.h> #include <linux/elf.h>
#include <linux/crc32.h> #include <linux/crc32.h>
#include <linux/of_platform.h>
#include <linux/of_reserved_mem.h> #include <linux/of_reserved_mem.h>
#include <linux/virtio_ids.h> #include <linux/virtio_ids.h>
#include <linux/virtio_ring.h> #include <linux/virtio_ring.h>
...@@ -2112,6 +2113,7 @@ EXPORT_SYMBOL(rproc_detach); ...@@ -2112,6 +2113,7 @@ EXPORT_SYMBOL(rproc_detach);
struct rproc *rproc_get_by_phandle(phandle phandle) struct rproc *rproc_get_by_phandle(phandle phandle)
{ {
struct rproc *rproc = NULL, *r; struct rproc *rproc = NULL, *r;
struct device_driver *driver;
struct device_node *np; struct device_node *np;
np = of_find_node_by_phandle(phandle); np = of_find_node_by_phandle(phandle);
...@@ -2122,7 +2124,26 @@ struct rproc *rproc_get_by_phandle(phandle phandle) ...@@ -2122,7 +2124,26 @@ struct rproc *rproc_get_by_phandle(phandle phandle)
list_for_each_entry_rcu(r, &rproc_list, node) { list_for_each_entry_rcu(r, &rproc_list, node) {
if (r->dev.parent && device_match_of_node(r->dev.parent, np)) { if (r->dev.parent && device_match_of_node(r->dev.parent, np)) {
/* prevent underlying implementation from being removed */ /* 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"); dev_err(&r->dev, "can't get owner\n");
break; break;
} }
...@@ -2533,7 +2554,11 @@ EXPORT_SYMBOL(rproc_free); ...@@ -2533,7 +2554,11 @@ EXPORT_SYMBOL(rproc_free);
*/ */
void rproc_put(struct rproc *rproc) 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); put_device(&rproc->dev);
} }
EXPORT_SYMBOL(rproc_put); EXPORT_SYMBOL(rproc_put);
......
...@@ -351,6 +351,9 @@ static void rproc_virtio_dev_release(struct device *dev) ...@@ -351,6 +351,9 @@ static void rproc_virtio_dev_release(struct device *dev)
kfree(vdev); kfree(vdev);
of_reserved_mem_device_release(&rvdev->pdev->dev);
dma_release_coherent_memory(&rvdev->pdev->dev);
put_device(&rvdev->pdev->dev); put_device(&rvdev->pdev->dev);
} }
...@@ -584,9 +587,6 @@ static void rproc_virtio_remove(struct platform_device *pdev) ...@@ -584,9 +587,6 @@ static void rproc_virtio_remove(struct platform_device *pdev)
rproc_remove_subdev(rproc, &rvdev->subdev); rproc_remove_subdev(rproc, &rvdev->subdev);
rproc_remove_rvdev(rvdev); rproc_remove_rvdev(rvdev);
of_reserved_mem_device_release(&pdev->dev);
dma_release_coherent_memory(&pdev->dev);
put_device(&rproc->dev); put_device(&rproc->dev);
} }
......
...@@ -347,23 +347,21 @@ static int st_rproc_probe(struct platform_device *pdev) ...@@ -347,23 +347,21 @@ static int st_rproc_probe(struct platform_device *pdev)
int enabled; int enabled;
int ret, i; 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) if (!rproc)
return -ENOMEM; return -ENOMEM;
rproc->has_iommu = false; rproc->has_iommu = false;
ddata = rproc->priv; ddata = rproc->priv;
ddata->config = (struct st_rproc_config *)device_get_match_data(dev); ddata->config = (struct st_rproc_config *)device_get_match_data(dev);
if (!ddata->config) { if (!ddata->config)
ret = -ENODEV; return -ENODEV;
goto free_rproc;
}
platform_set_drvdata(pdev, rproc); platform_set_drvdata(pdev, rproc);
ret = st_rproc_parse_dt(pdev); ret = st_rproc_parse_dt(pdev);
if (ret) if (ret)
goto free_rproc; return ret;
enabled = st_rproc_state(pdev); enabled = st_rproc_state(pdev);
if (enabled < 0) { if (enabled < 0) {
...@@ -439,8 +437,7 @@ static int st_rproc_probe(struct platform_device *pdev) ...@@ -439,8 +437,7 @@ static int st_rproc_probe(struct platform_device *pdev)
mbox_free_channel(ddata->mbox_chan[i]); mbox_free_channel(ddata->mbox_chan[i]);
free_clk: free_clk:
clk_unprepare(ddata->clk); clk_unprepare(ddata->clk);
free_rproc:
rproc_free(rproc);
return ret; return ret;
} }
...@@ -456,8 +453,6 @@ static void st_rproc_remove(struct platform_device *pdev) ...@@ -456,8 +453,6 @@ static void st_rproc_remove(struct platform_device *pdev)
for (i = 0; i < ST_RPROC_MAX_VRING * MBOX_MAX; i++) for (i = 0; i < ST_RPROC_MAX_VRING * MBOX_MAX; i++)
mbox_free_channel(ddata->mbox_chan[i]); mbox_free_channel(ddata->mbox_chan[i]);
rproc_free(rproc);
} }
static struct platform_driver st_rproc_driver = { static struct platform_driver st_rproc_driver = {
......
...@@ -120,7 +120,7 @@ static int stm32_rproc_mem_alloc(struct rproc *rproc, ...@@ -120,7 +120,7 @@ static int stm32_rproc_mem_alloc(struct rproc *rproc,
void *va; void *va;
dev_dbg(dev, "map memory: %pad+%zx\n", &mem->dma, mem->len); 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)) { if (IS_ERR_OR_NULL(va)) {
dev_err(dev, "Unable to map memory region: %pad+0x%zx\n", dev_err(dev, "Unable to map memory region: %pad+0x%zx\n",
&mem->dma, mem->len); &mem->dma, mem->len);
...@@ -137,7 +137,7 @@ static int stm32_rproc_mem_release(struct rproc *rproc, ...@@ -137,7 +137,7 @@ static int stm32_rproc_mem_release(struct rproc *rproc,
struct rproc_mem_entry *mem) struct rproc_mem_entry *mem)
{ {
dev_dbg(rproc->dev.parent, "unmap memory: %pa\n", &mem->dma); dev_dbg(rproc->dev.parent, "unmap memory: %pa\n", &mem->dma);
iounmap(mem->va); iounmap((__force __iomem void *)mem->va);
return 0; return 0;
} }
...@@ -657,7 +657,7 @@ stm32_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz) ...@@ -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. * entire area by overwriting it with the initial values stored in rproc->clean_table.
*/ */
*table_sz = RSC_TBL_SIZE; *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 = { static const struct rproc_ops st_rproc_ops = {
...@@ -843,7 +843,7 @@ static int stm32_rproc_probe(struct platform_device *pdev) ...@@ -843,7 +843,7 @@ static int stm32_rproc_probe(struct platform_device *pdev)
if (ret) if (ret)
return 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) if (!rproc)
return -ENOMEM; return -ENOMEM;
...@@ -897,7 +897,6 @@ static int stm32_rproc_probe(struct platform_device *pdev) ...@@ -897,7 +897,6 @@ static int stm32_rproc_probe(struct platform_device *pdev)
dev_pm_clear_wake_irq(dev); dev_pm_clear_wake_irq(dev);
device_init_wakeup(dev, false); device_init_wakeup(dev, false);
} }
rproc_free(rproc);
return ret; return ret;
} }
...@@ -918,7 +917,6 @@ static void stm32_rproc_remove(struct platform_device *pdev) ...@@ -918,7 +917,6 @@ static void stm32_rproc_remove(struct platform_device *pdev)
dev_pm_clear_wake_irq(dev); dev_pm_clear_wake_irq(dev);
device_init_wakeup(dev, false); device_init_wakeup(dev, false);
} }
rproc_free(rproc);
} }
static int stm32_rproc_suspend(struct device *dev) static int stm32_rproc_suspend(struct device *dev)
......
...@@ -550,6 +550,13 @@ static int k3_dsp_rproc_of_get_memories(struct platform_device *pdev, ...@@ -550,6 +550,13 @@ static int k3_dsp_rproc_of_get_memories(struct platform_device *pdev,
return 0; 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) static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc)
{ {
struct device *dev = kproc->dev; struct device *dev = kproc->dev;
...@@ -579,27 +586,25 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc) ...@@ -579,27 +586,25 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc)
ERR_PTR(ret)); ERR_PTR(ret));
return ret; return ret;
} }
ret = devm_add_action_or_reset(dev, k3_dsp_mem_release, dev);
if (ret)
return ret;
num_rmems--; num_rmems--;
kproc->rmem = kcalloc(num_rmems, sizeof(*kproc->rmem), GFP_KERNEL); kproc->rmem = devm_kcalloc(dev, num_rmems, sizeof(*kproc->rmem), GFP_KERNEL);
if (!kproc->rmem) { if (!kproc->rmem)
ret = -ENOMEM; return -ENOMEM;
goto release_rmem;
}
/* use remaining reserved memory regions for static carveouts */ /* use remaining reserved memory regions for static carveouts */
for (i = 0; i < num_rmems; i++) { for (i = 0; i < num_rmems; i++) {
rmem_np = of_parse_phandle(np, "memory-region", i + 1); rmem_np = of_parse_phandle(np, "memory-region", i + 1);
if (!rmem_np) { if (!rmem_np)
ret = -EINVAL; return -EINVAL;
goto unmap_rmem;
}
rmem = of_reserved_mem_lookup(rmem_np); rmem = of_reserved_mem_lookup(rmem_np);
if (!rmem) { if (!rmem) {
of_node_put(rmem_np); of_node_put(rmem_np);
ret = -EINVAL; return -EINVAL;
goto unmap_rmem;
} }
of_node_put(rmem_np); of_node_put(rmem_np);
...@@ -607,12 +612,11 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc) ...@@ -607,12 +612,11 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc)
/* 64-bit address regions currently not supported */ /* 64-bit address regions currently not supported */
kproc->rmem[i].dev_addr = (u32)rmem->base; kproc->rmem[i].dev_addr = (u32)rmem->base;
kproc->rmem[i].size = rmem->size; 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) { if (!kproc->rmem[i].cpu_addr) {
dev_err(dev, "failed to map reserved memory#%d at %pa of size %pa\n", dev_err(dev, "failed to map reserved memory#%d at %pa of size %pa\n",
i + 1, &rmem->base, &rmem->size); i + 1, &rmem->base, &rmem->size);
ret = -ENOMEM; return -ENOMEM;
goto unmap_rmem;
} }
dev_dbg(dev, "reserved memory%d: bus addr %pa size 0x%zx va %pK da 0x%x\n", 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) ...@@ -623,25 +627,13 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc)
kproc->num_rmems = num_rmems; kproc->num_rmems = num_rmems;
return 0; 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++) ti_sci_proc_release(tsp);
iounmap(kproc->rmem[i].cpu_addr);
kfree(kproc->rmem);
of_reserved_mem_device_release(kproc->dev);
} }
static static
...@@ -657,7 +649,7 @@ struct ti_sci_proc *k3_dsp_rproc_of_get_tsp(struct device *dev, ...@@ -657,7 +649,7 @@ struct ti_sci_proc *k3_dsp_rproc_of_get_tsp(struct device *dev,
if (ret < 0) if (ret < 0)
return ERR_PTR(ret); return ERR_PTR(ret);
tsp = kzalloc(sizeof(*tsp), GFP_KERNEL); tsp = devm_kzalloc(dev, sizeof(*tsp), GFP_KERNEL);
if (!tsp) if (!tsp)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
...@@ -680,7 +672,6 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev) ...@@ -680,7 +672,6 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
const char *fw_name; const char *fw_name;
bool p_state = false; bool p_state = false;
int ret = 0; int ret = 0;
int ret1;
data = of_device_get_match_data(dev); data = of_device_get_match_data(dev);
if (!data) if (!data)
...@@ -690,8 +681,8 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev) ...@@ -690,8 +681,8 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
if (ret) if (ret)
return dev_err_probe(dev, ret, "failed to parse firmware-name property\n"); 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, rproc = devm_rproc_alloc(dev, dev_name(dev), &k3_dsp_rproc_ops,
sizeof(*kproc)); fw_name, sizeof(*kproc));
if (!rproc) if (!rproc)
return -ENOMEM; return -ENOMEM;
...@@ -706,56 +697,46 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev) ...@@ -706,56 +697,46 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
kproc->dev = dev; kproc->dev = dev;
kproc->data = data; kproc->data = data;
kproc->ti_sci = ti_sci_get_by_phandle(np, "ti,sci"); kproc->ti_sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
if (IS_ERR(kproc->ti_sci)) { if (IS_ERR(kproc->ti_sci))
ret = dev_err_probe(dev, PTR_ERR(kproc->ti_sci), return dev_err_probe(dev, PTR_ERR(kproc->ti_sci),
"failed to get ti-sci handle\n"); "failed to get ti-sci handle\n");
kproc->ti_sci = NULL;
goto free_rproc;
}
ret = of_property_read_u32(np, "ti,sci-dev-id", &kproc->ti_sci_id); ret = of_property_read_u32(np, "ti,sci-dev-id", &kproc->ti_sci_id);
if (ret) { if (ret)
dev_err_probe(dev, ret, "missing 'ti,sci-dev-id' property\n"); return dev_err_probe(dev, ret, "missing 'ti,sci-dev-id' property\n");
goto put_sci;
}
kproc->reset = devm_reset_control_get_exclusive(dev, NULL); kproc->reset = devm_reset_control_get_exclusive(dev, NULL);
if (IS_ERR(kproc->reset)) { if (IS_ERR(kproc->reset))
ret = dev_err_probe(dev, PTR_ERR(kproc->reset), return dev_err_probe(dev, PTR_ERR(kproc->reset),
"failed to get reset\n"); "failed to get reset\n");
goto put_sci;
}
kproc->tsp = k3_dsp_rproc_of_get_tsp(dev, kproc->ti_sci); kproc->tsp = k3_dsp_rproc_of_get_tsp(dev, kproc->ti_sci);
if (IS_ERR(kproc->tsp)) { if (IS_ERR(kproc->tsp))
ret = dev_err_probe(dev, PTR_ERR(kproc->tsp), return dev_err_probe(dev, PTR_ERR(kproc->tsp),
"failed to construct ti-sci proc control\n"); "failed to construct ti-sci proc control\n");
goto put_sci;
}
ret = ti_sci_proc_request(kproc->tsp); ret = ti_sci_proc_request(kproc->tsp);
if (ret < 0) { if (ret < 0) {
dev_err_probe(dev, ret, "ti_sci_proc_request failed\n"); 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); ret = k3_dsp_rproc_of_get_memories(pdev, kproc);
if (ret) if (ret)
goto release_tsp; return ret;
ret = k3_dsp_reserved_mem_init(kproc); ret = k3_dsp_reserved_mem_init(kproc);
if (ret) { if (ret)
dev_err_probe(dev, ret, "reserved memory init failed\n"); return dev_err_probe(dev, ret, "reserved memory init failed\n");
goto release_tsp;
}
ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id, ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id,
NULL, &p_state); NULL, &p_state);
if (ret) { if (ret)
dev_err_probe(dev, ret, "failed to get initial state, mode cannot be determined\n"); return dev_err_probe(dev, ret, "failed to get initial state, mode cannot be determined\n");
goto release_mem;
}
/* configure J721E devices for either remoteproc or IPC-only mode */ /* configure J721E devices for either remoteproc or IPC-only mode */
if (p_state) { if (p_state) {
...@@ -779,8 +760,7 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev) ...@@ -779,8 +760,7 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
if (data->uses_lreset) { if (data->uses_lreset) {
ret = reset_control_status(kproc->reset); ret = reset_control_status(kproc->reset);
if (ret < 0) { if (ret < 0) {
dev_err_probe(dev, ret, "failed to get reset status\n"); return dev_err_probe(dev, ret, "failed to get reset status\n");
goto release_mem;
} else if (ret == 0) { } else if (ret == 0) {
dev_warn(dev, "local reset is deasserted for device\n"); dev_warn(dev, "local reset is deasserted for device\n");
k3_dsp_rproc_reset(kproc); k3_dsp_rproc_reset(kproc);
...@@ -788,31 +768,13 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev) ...@@ -788,31 +768,13 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
} }
} }
ret = rproc_add(rproc); ret = devm_rproc_add(dev, rproc);
if (ret) { if (ret)
dev_err_probe(dev, ret, "failed to add register device with remoteproc core\n"); return dev_err_probe(dev, ret, "failed to add register device with remoteproc core\n");
goto release_mem;
}
platform_set_drvdata(pdev, kproc); platform_set_drvdata(pdev, kproc);
return 0; 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) static void k3_dsp_rproc_remove(struct platform_device *pdev)
...@@ -824,27 +786,9 @@ 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) { if (rproc->state == RPROC_ATTACHED) {
ret = rproc_detach(rproc); ret = rproc_detach(rproc);
if (ret) { if (ret)
/* Note this error path leaks resources */
dev_err(dev, "failed to detach proc (%pe)\n", ERR_PTR(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[] = { 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