remoteproc updates for v6.9
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. It 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. -----BEGIN PGP SIGNATURE----- iQJJBAABCAAzFiEEBd4DzF816k8JZtUlCx85Pw2ZrcUFAmX3oxcVHGFuZGVyc3Nv bkBrZXJuZWwub3JnAAoJEAsfOT8Nma3FargP/1kVpsEZbzaqc3v0OJBShG45gpQR O9wIfP0T9KrZGDSayAGX7/c80cvLl3y/ukkwY6ehGLrV2iOQ2+7fhV9vLDe09a95 mMkcE3d3WFrlDPGPjquTRlCFjkBcK/WloQWBQZZ+ZtCxjfUjwKxtPutB7XPCQC4r Ky3qUUhkxhXSD2R8Vr8PSDtdMxwj991A7Ejo+wRYEzv40atiJ0M3v9/hjNeIinVz zui6EOB0p9s4geDfD7uAbbDfwi7CxvlprC3AcAYz4KWV1q5Dh8NhYI0KqcF03G8q pCpJHuHYBBiarAvflKe99KLSiVz7+GOtcz2a4d4YBSbePliW+HafPXugUqBG/RtC TzH1H4NuS+07JyYlklz/lC3Do284LimSrGlGMR+uypY8sLWRVSHBazTJypGHOUZd ei/E3Nf7hbEkBh31o4lTMVrVT/zTXKe2gdzAM7dgom6euav8OiUEgpVdc2ye3oHf 0Xmeb8UXAVTCZEfHqgKr3QO3v3wAbarbJ/UZiPHeN/5kFUxbTxpRAmpTeI4ViKk3 KDbqibnx6YI8UHkAPgQalf1x37z2f1b/DEfi3nulzwLsZ0UgvoZy5Zim7RSS/R5K JFqMNKPj0m2J6LF+2YTjZL6Af989mWmLOLPTM6szpWvEil/ndRTqWaAKOilWeGJu wqVp6JrREfPhHsWY =na/C -----END PGP SIGNATURE----- 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 ...
This commit is contained in:
commit
0e875ee5e8
|
@ -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,
|
||||
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 @@ err_put_mbox:
|
|||
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,7 +674,7 @@ static int adsp_probe(struct platform_device *pdev)
|
|||
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));
|
||||
if (!rproc) {
|
||||
dev_err(&pdev->dev, "unable to allocate remoteproc\n");
|
||||
|
@ -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,7 +1990,7 @@ static int q6v5_probe(struct platform_device *pdev)
|
|||
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));
|
||||
if (!rproc) {
|
||||
dev_err(&pdev->dev, "failed to allocate rproc\n");
|
||||
|
@ -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 @@ remove_subdevs:
|
|||
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 = {
|
||||
|
|
|
@ -33,12 +33,15 @@
|
|||
|
||||
#define ADSP_DECRYPT_SHUTDOWN_DELAY_MS 100
|
||||
|
||||
#define MAX_ASSIGN_COUNT 3
|
||||
|
||||
struct adsp_data {
|
||||
int crash_reason_smem;
|
||||
const char *firmware_name;
|
||||
const char *dtb_firmware_name;
|
||||
int pas_id;
|
||||
int dtb_pas_id;
|
||||
int lite_pas_id;
|
||||
unsigned int minidump_id;
|
||||
bool auto_boot;
|
||||
bool decrypt_shutdown;
|
||||
|
@ -51,6 +54,9 @@ struct adsp_data {
|
|||
int ssctl_id;
|
||||
|
||||
int region_assign_idx;
|
||||
int region_assign_count;
|
||||
bool region_assign_shared;
|
||||
int region_assign_vmid;
|
||||
};
|
||||
|
||||
struct qcom_adsp {
|
||||
|
@ -72,6 +78,7 @@ struct qcom_adsp {
|
|||
const char *dtb_firmware_name;
|
||||
int pas_id;
|
||||
int dtb_pas_id;
|
||||
int lite_pas_id;
|
||||
unsigned int minidump_id;
|
||||
int crash_reason_smem;
|
||||
bool decrypt_shutdown;
|
||||
|
@ -87,15 +94,18 @@ struct qcom_adsp {
|
|||
phys_addr_t dtb_mem_phys;
|
||||
phys_addr_t 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 *dtb_mem_region;
|
||||
size_t mem_size;
|
||||
size_t dtb_mem_size;
|
||||
size_t region_assign_size;
|
||||
size_t region_assign_size[MAX_ASSIGN_COUNT];
|
||||
|
||||
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_subdev smd_subdev;
|
||||
|
@ -210,6 +220,9 @@ static int adsp_load(struct rproc *rproc, const struct firmware *fw)
|
|||
/* Store firmware handle to be used in adsp_start() */
|
||||
adsp->firmware = fw;
|
||||
|
||||
if (adsp->lite_pas_id)
|
||||
ret = qcom_scm_pas_shutdown(adsp->lite_pas_id);
|
||||
|
||||
if (adsp->dtb_pas_id) {
|
||||
ret = request_firmware(&adsp->dtb_firmware, adsp->dtb_firmware_name, adsp->dev);
|
||||
if (ret) {
|
||||
|
@ -590,38 +603,54 @@ static int adsp_alloc_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;
|
||||
struct qcom_scm_vmperm perm[MAX_ASSIGN_COUNT];
|
||||
struct device_node *node;
|
||||
unsigned int perm_size;
|
||||
int offset;
|
||||
int ret;
|
||||
|
||||
if (!adsp->region_assign_idx)
|
||||
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) {
|
||||
struct reserved_mem *rmem = NULL;
|
||||
|
||||
node = of_parse_phandle(adsp->dev->of_node, "memory-region",
|
||||
adsp->region_assign_idx + offset);
|
||||
if (node)
|
||||
rmem = of_reserved_mem_lookup(node);
|
||||
of_node_put(node);
|
||||
if (!rmem) {
|
||||
dev_err(adsp->dev, "unable to resolve shareable memory-region\n");
|
||||
dev_err(adsp->dev, "unable to resolve shareable memory-region index %d\n",
|
||||
offset);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
perm.vmid = QCOM_SCM_VMID_MSS_MSA;
|
||||
perm.perm = QCOM_SCM_PERM_RW;
|
||||
if (adsp->region_assign_shared) {
|
||||
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_size = rmem->size;
|
||||
adsp->region_assign_perms = BIT(QCOM_SCM_VMID_HLOS);
|
||||
adsp->region_assign_phys[offset] = rmem->base;
|
||||
adsp->region_assign_size[offset] = rmem->size;
|
||||
adsp->region_assign_owners[offset] = BIT(QCOM_SCM_VMID_HLOS);
|
||||
|
||||
ret = qcom_scm_assign_mem(adsp->region_assign_phys,
|
||||
adsp->region_assign_size,
|
||||
&adsp->region_assign_perms,
|
||||
&perm, 1);
|
||||
ret = qcom_scm_assign_mem(adsp->region_assign_phys[offset],
|
||||
adsp->region_assign_size[offset],
|
||||
&adsp->region_assign_owners[offset],
|
||||
perm, perm_size);
|
||||
if (ret < 0) {
|
||||
dev_err(adsp->dev, "assign memory failed\n");
|
||||
dev_err(adsp->dev, "assign memory %d failed\n", offset);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -629,20 +658,23 @@ static int adsp_assign_memory_region(struct qcom_adsp *adsp)
|
|||
static void adsp_unassign_memory_region(struct qcom_adsp *adsp)
|
||||
{
|
||||
struct qcom_scm_vmperm perm;
|
||||
int offset;
|
||||
int ret;
|
||||
|
||||
if (!adsp->region_assign_idx)
|
||||
if (!adsp->region_assign_idx || adsp->region_assign_shared)
|
||||
return;
|
||||
|
||||
for (offset = 0; offset < adsp->region_assign_count; ++offset) {
|
||||
perm.vmid = QCOM_SCM_VMID_HLOS;
|
||||
perm.perm = QCOM_SCM_PERM_RW;
|
||||
|
||||
ret = qcom_scm_assign_mem(adsp->region_assign_phys,
|
||||
adsp->region_assign_size,
|
||||
&adsp->region_assign_perms,
|
||||
ret = qcom_scm_assign_mem(adsp->region_assign_phys[offset],
|
||||
adsp->region_assign_size[offset],
|
||||
&adsp->region_assign_owners[offset],
|
||||
&perm, 1);
|
||||
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)
|
||||
|
@ -678,7 +710,7 @@ static int adsp_probe(struct platform_device *pdev)
|
|||
if (desc->minidump_id)
|
||||
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) {
|
||||
dev_err(&pdev->dev, "unable to allocate remoteproc\n");
|
||||
|
@ -693,9 +725,13 @@ static int adsp_probe(struct platform_device *pdev)
|
|||
adsp->rproc = rproc;
|
||||
adsp->minidump_id = desc->minidump_id;
|
||||
adsp->pas_id = desc->pas_id;
|
||||
adsp->lite_pas_id = desc->lite_pas_id;
|
||||
adsp->info_name = desc->sysmon_name;
|
||||
adsp->decrypt_shutdown = desc->decrypt_shutdown;
|
||||
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) {
|
||||
adsp->dtb_firmware_name = dtb_fw_name;
|
||||
adsp->dtb_pas_id = desc->dtb_pas_id;
|
||||
|
@ -754,7 +790,6 @@ detach_proxy_pds:
|
|||
adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
|
||||
free_rproc:
|
||||
device_init_wakeup(adsp->dev, false);
|
||||
rproc_free(rproc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -773,7 +808,6 @@ static void adsp_remove(struct platform_device *pdev)
|
|||
qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
|
||||
adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
|
||||
device_init_wakeup(adsp->dev, false);
|
||||
rproc_free(adsp->rproc);
|
||||
}
|
||||
|
||||
static const struct adsp_data adsp_resource_init = {
|
||||
|
@ -984,6 +1018,46 @@ static const struct adsp_data sc8280xp_nsp1_resource = {
|
|||
.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 = {
|
||||
.crash_reason_smem = 601,
|
||||
.firmware_name = "cdsp.mdt",
|
||||
|
@ -1163,6 +1237,8 @@ static const struct adsp_data sm8550_mpss_resource = {
|
|||
.sysmon_name = "modem",
|
||||
.ssctl_id = 0x12,
|
||||
.region_assign_idx = 2,
|
||||
.region_assign_count = 1,
|
||||
.region_assign_vmid = QCOM_SCM_VMID_MSS_MSA,
|
||||
};
|
||||
|
||||
static const struct adsp_data sc7280_wpss_resource = {
|
||||
|
@ -1181,6 +1257,53 @@ static const struct adsp_data sc7280_wpss_resource = {
|
|||
.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[] = {
|
||||
{ .compatible = "qcom,msm8226-adsp-pil", .data = &adsp_resource_init},
|
||||
{ .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource},
|
||||
|
@ -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-cdsp-pas", .data = &sm8550_cdsp_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);
|
||||
|
|
|
@ -1011,7 +1011,7 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
|
|||
if (!desc)
|
||||
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));
|
||||
if (!rproc) {
|
||||
dev_err(&pdev->dev, "failed to allocate rproc\n");
|
||||
|
@ -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,7 +555,7 @@ static int wcnss_probe(struct platform_device *pdev)
|
|||
if (ret < 0 && ret != -EINVAL)
|
||||
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));
|
||||
if (!rproc) {
|
||||
dev_err(&pdev->dev, "unable to allocate remoteproc\n");
|
||||
|
@ -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 @@ remove_iris:
|
|||
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)
|
||||
{
|
||||
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 @@ free_mbox:
|
|||
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 @@ done:
|
|||
* 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 @@ free_rproc:
|
|||
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),
|
||||
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");
|
||||
kproc->ti_sci = NULL;
|
||||
goto free_rproc;
|
||||
}
|
||||
|
||||
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),
|
||||
if (IS_ERR(kproc->reset))
|
||||
return dev_err_probe(dev, PTR_ERR(kproc->reset),
|
||||
"failed to get reset\n");
|
||||
goto put_sci;
|
||||
}
|
||||
|
||||
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),
|
||||
if (IS_ERR(kproc->tsp))
|
||||
return dev_err_probe(dev, PTR_ERR(kproc->tsp),
|
||||
"failed to construct ti-sci proc control\n");
|
||||
goto put_sci;
|
||||
}
|
||||
|
||||
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,29 +786,11 @@ 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[] = {
|
||||
{ .name = "l2sram", .dev_addr = 0x800000 },
|
||||
{ .name = "l1pram", .dev_addr = 0xe00000 },
|
||||
|
|
Loading…
Reference in New Issue