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:
Linus Torvalds 2024-03-21 10:37:39 -07:00
commit 0e875ee5e8
25 changed files with 419 additions and 309 deletions

View File

@ -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

View File

@ -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.

View File

@ -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:

View File

@ -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:

View File

@ -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.

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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".

View File

@ -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 */

View File

@ -1049,16 +1049,14 @@ static int imx_rproc_probe(struct platform_device *pdev)
int ret;
/* set some other name then imx */
rproc = rproc_alloc(dev, "imx-rproc", &imx_rproc_ops,
NULL, sizeof(*priv));
rproc = devm_rproc_alloc(dev, "imx-rproc", &imx_rproc_ops,
NULL, sizeof(*priv));
if (!rproc)
return -ENOMEM;
dcfg = of_device_get_match_data(dev);
if (!dcfg) {
ret = -EINVAL;
goto err_put_rproc;
}
if (!dcfg)
return -EINVAL;
priv = rproc->priv;
priv->rproc = rproc;
@ -1069,8 +1067,7 @@ static int imx_rproc_probe(struct platform_device *pdev)
priv->workqueue = create_workqueue(dev_name(dev));
if (!priv->workqueue) {
dev_err(dev, "cannot create workqueue\n");
ret = -ENOMEM;
goto err_put_rproc;
return -ENOMEM;
}
ret = imx_rproc_xtr_mbox_init(rproc);
@ -1112,8 +1109,6 @@ 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[] = {

View File

@ -674,8 +674,8 @@ static int adsp_probe(struct platform_device *pdev)
return ret;
}
rproc = rproc_alloc(&pdev->dev, pdev->name, &adsp_ops,
firmware_name, sizeof(*adsp));
rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &adsp_ops,
firmware_name, sizeof(*adsp));
if (!rproc) {
dev_err(&pdev->dev, "unable to allocate remoteproc\n");
return -ENOMEM;
@ -700,16 +700,16 @@ static int adsp_probe(struct platform_device *pdev)
ret = adsp_alloc_memory_region(adsp);
if (ret)
goto free_rproc;
return ret;
ret = adsp_init_clock(adsp, desc->clk_ids);
if (ret)
goto free_rproc;
return ret;
ret = qcom_rproc_pds_attach(adsp, desc->pd_names, desc->num_pds);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to attach proxy power domains\n");
goto free_rproc;
return ret;
}
ret = adsp_init_reset(adsp);
@ -744,9 +744,6 @@ static int adsp_probe(struct platform_device *pdev)
disable_pm:
qcom_rproc_pds_detach(adsp);
free_rproc:
rproc_free(rproc);
return ret;
}
@ -761,7 +758,6 @@ static void adsp_remove(struct platform_device *pdev)
qcom_remove_sysmon_subdev(adsp->sysmon);
qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
qcom_rproc_pds_detach(adsp);
rproc_free(adsp->rproc);
}
static const struct adsp_pil_data adsp_resource_init = {

View File

@ -1990,8 +1990,8 @@ static int q6v5_probe(struct platform_device *pdev)
return ret;
}
rproc = rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops,
mba_image, sizeof(*qproc));
rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops,
mba_image, sizeof(*qproc));
if (!rproc) {
dev_err(&pdev->dev, "failed to allocate rproc\n");
return -ENOMEM;
@ -2008,7 +2008,7 @@ static int q6v5_probe(struct platform_device *pdev)
1, &qproc->hexagon_mdt_image);
if (ret < 0 && ret != -EINVAL) {
dev_err(&pdev->dev, "unable to read mpss firmware-name\n");
goto free_rproc;
return ret;
}
platform_set_drvdata(pdev, qproc);
@ -2019,17 +2019,17 @@ static int q6v5_probe(struct platform_device *pdev)
qproc->has_spare_reg = desc->has_spare_reg;
ret = q6v5_init_mem(qproc, pdev);
if (ret)
goto free_rproc;
return ret;
ret = q6v5_alloc_memory_region(qproc);
if (ret)
goto free_rproc;
return ret;
ret = q6v5_init_clocks(&pdev->dev, qproc->proxy_clks,
desc->proxy_clk_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get proxy clocks.\n");
goto free_rproc;
return ret;
}
qproc->proxy_clk_count = ret;
@ -2037,7 +2037,7 @@ static int q6v5_probe(struct platform_device *pdev)
desc->reset_clk_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get reset clocks.\n");
goto free_rproc;
return ret;
}
qproc->reset_clk_count = ret;
@ -2045,7 +2045,7 @@ static int q6v5_probe(struct platform_device *pdev)
desc->active_clk_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get active clocks.\n");
goto free_rproc;
return ret;
}
qproc->active_clk_count = ret;
@ -2053,7 +2053,7 @@ static int q6v5_probe(struct platform_device *pdev)
desc->proxy_supply);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get proxy regulators.\n");
goto free_rproc;
return ret;
}
qproc->proxy_reg_count = ret;
@ -2061,7 +2061,7 @@ static int q6v5_probe(struct platform_device *pdev)
desc->active_supply);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get active regulators.\n");
goto free_rproc;
return ret;
}
qproc->active_reg_count = ret;
@ -2074,12 +2074,12 @@ static int q6v5_probe(struct platform_device *pdev)
desc->fallback_proxy_supply);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get fallback proxy regulators.\n");
goto free_rproc;
return ret;
}
qproc->fallback_proxy_reg_count = ret;
} else if (ret < 0) {
dev_err(&pdev->dev, "Failed to init power domains\n");
goto free_rproc;
return ret;
} else {
qproc->proxy_pd_count = ret;
}
@ -2127,8 +2127,6 @@ 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 = {

View File

@ -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,37 +603,53 @@ 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);
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");
return -EINVAL;
}
for (offset = 0; offset < adsp->region_assign_count; ++offset) {
struct reserved_mem *rmem = NULL;
perm.vmid = QCOM_SCM_VMID_MSS_MSA;
perm.perm = QCOM_SCM_PERM_RW;
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 index %d\n",
offset);
return -EINVAL;
}
adsp->region_assign_phys = rmem->base;
adsp->region_assign_size = rmem->size;
adsp->region_assign_perms = BIT(QCOM_SCM_VMID_HLOS);
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;
}
ret = qcom_scm_assign_mem(adsp->region_assign_phys,
adsp->region_assign_size,
&adsp->region_assign_perms,
&perm, 1);
if (ret < 0) {
dev_err(adsp->dev, "assign memory failed\n");
return ret;
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[offset],
adsp->region_assign_size[offset],
&adsp->region_assign_owners[offset],
perm, perm_size);
if (ret < 0) {
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;
perm.vmid = QCOM_SCM_VMID_HLOS;
perm.perm = QCOM_SCM_PERM_RW;
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,
&perm, 1);
if (ret < 0)
dev_err(adsp->dev, "unassign memory failed\n");
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 %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,28 +808,27 @@ 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 = {
.crash_reason_smem = 423,
.firmware_name = "adsp.mdt",
.pas_id = 1,
.auto_boot = true,
.ssr_name = "lpass",
.sysmon_name = "adsp",
.ssctl_id = 0x14,
.crash_reason_smem = 423,
.firmware_name = "adsp.mdt",
.pas_id = 1,
.auto_boot = true,
.ssr_name = "lpass",
.sysmon_name = "adsp",
.ssctl_id = 0x14,
};
static const struct adsp_data sdm845_adsp_resource_init = {
.crash_reason_smem = 423,
.firmware_name = "adsp.mdt",
.pas_id = 1,
.auto_boot = true,
.load_state = "adsp",
.ssr_name = "lpass",
.sysmon_name = "adsp",
.ssctl_id = 0x14,
.crash_reason_smem = 423,
.firmware_name = "adsp.mdt",
.pas_id = 1,
.auto_boot = true,
.load_state = "adsp",
.ssr_name = "lpass",
.sysmon_name = "adsp",
.ssctl_id = 0x14,
};
static const struct adsp_data sm6350_adsp_resource = {
@ -829,18 +863,18 @@ static const struct adsp_data sm6375_mpss_resource = {
};
static const struct adsp_data sm8150_adsp_resource = {
.crash_reason_smem = 423,
.firmware_name = "adsp.mdt",
.pas_id = 1,
.auto_boot = true,
.proxy_pd_names = (char*[]){
"cx",
NULL
},
.load_state = "adsp",
.ssr_name = "lpass",
.sysmon_name = "adsp",
.ssctl_id = 0x14,
.crash_reason_smem = 423,
.firmware_name = "adsp.mdt",
.pas_id = 1,
.auto_boot = true,
.proxy_pd_names = (char*[]){
"cx",
NULL
},
.load_state = "adsp",
.ssr_name = "lpass",
.sysmon_name = "adsp",
.ssctl_id = 0x14,
};
static const struct adsp_data sm8250_adsp_resource = {
@ -876,17 +910,17 @@ static const struct adsp_data sm8350_adsp_resource = {
};
static const struct adsp_data msm8996_adsp_resource = {
.crash_reason_smem = 423,
.firmware_name = "adsp.mdt",
.pas_id = 1,
.auto_boot = true,
.proxy_pd_names = (char*[]){
"cx",
NULL
},
.ssr_name = "lpass",
.sysmon_name = "adsp",
.ssctl_id = 0x14,
.crash_reason_smem = 423,
.firmware_name = "adsp.mdt",
.pas_id = 1,
.auto_boot = true,
.proxy_pd_names = (char*[]){
"cx",
NULL
},
.ssr_name = "lpass",
.sysmon_name = "adsp",
.ssctl_id = 0x14,
};
static const struct adsp_data cdsp_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",
@ -1033,33 +1107,33 @@ static const struct adsp_data sc8180x_mpss_resource = {
};
static const struct adsp_data msm8996_slpi_resource_init = {
.crash_reason_smem = 424,
.firmware_name = "slpi.mdt",
.pas_id = 12,
.auto_boot = true,
.proxy_pd_names = (char*[]){
"ssc_cx",
NULL
},
.ssr_name = "dsps",
.sysmon_name = "slpi",
.ssctl_id = 0x16,
.crash_reason_smem = 424,
.firmware_name = "slpi.mdt",
.pas_id = 12,
.auto_boot = true,
.proxy_pd_names = (char*[]){
"ssc_cx",
NULL
},
.ssr_name = "dsps",
.sysmon_name = "slpi",
.ssctl_id = 0x16,
};
static const struct adsp_data sdm845_slpi_resource_init = {
.crash_reason_smem = 424,
.firmware_name = "slpi.mdt",
.pas_id = 12,
.auto_boot = true,
.proxy_pd_names = (char*[]){
"lcx",
"lmx",
NULL
},
.load_state = "slpi",
.ssr_name = "dsps",
.sysmon_name = "slpi",
.ssctl_id = 0x16,
.crash_reason_smem = 424,
.firmware_name = "slpi.mdt",
.pas_id = 12,
.auto_boot = true,
.proxy_pd_names = (char*[]){
"lcx",
"lmx",
NULL
},
.load_state = "slpi",
.ssr_name = "dsps",
.sysmon_name = "slpi",
.ssctl_id = 0x16,
};
static const struct adsp_data wcss_resource_init = {
@ -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);

View File

@ -1011,8 +1011,8 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
if (!desc)
return -EINVAL;
rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops,
desc->firmware_name, sizeof(*wcss));
rproc = devm_rproc_alloc(&pdev->dev, pdev->name, desc->ops,
desc->firmware_name, sizeof(*wcss));
if (!rproc) {
dev_err(&pdev->dev, "failed to allocate rproc\n");
return -ENOMEM;
@ -1027,29 +1027,29 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
ret = q6v5_wcss_init_mmio(wcss, pdev);
if (ret)
goto free_rproc;
return ret;
ret = q6v5_alloc_memory_region(wcss);
if (ret)
goto free_rproc;
return ret;
if (wcss->version == WCSS_QCS404) {
ret = q6v5_wcss_init_clock(wcss);
if (ret)
goto free_rproc;
return ret;
ret = q6v5_wcss_init_regulator(wcss);
if (ret)
goto free_rproc;
return ret;
}
ret = q6v5_wcss_init_reset(wcss, desc);
if (ret)
goto free_rproc;
return ret;
ret = qcom_q6v5_init(&wcss->q6v5, pdev, rproc, desc->crash_reason_smem, NULL, NULL);
if (ret)
goto free_rproc;
return ret;
qcom_add_glink_subdev(rproc, &wcss->glink_subdev, "q6wcss");
qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, "q6wcss");
@ -1061,16 +1061,11 @@ static int q6v5_wcss_probe(struct platform_device *pdev)
ret = rproc_add(rproc);
if (ret)
goto free_rproc;
return ret;
platform_set_drvdata(pdev, rproc);
return 0;
free_rproc:
rproc_free(rproc);
return ret;
}
static void q6v5_wcss_remove(struct platform_device *pdev)
@ -1080,7 +1075,6 @@ static void q6v5_wcss_remove(struct platform_device *pdev)
qcom_q6v5_deinit(&wcss->q6v5);
rproc_del(rproc);
rproc_free(rproc);
}
static const struct wcss_data wcss_ipq8074_res_init = {

View File

@ -555,8 +555,8 @@ static int wcnss_probe(struct platform_device *pdev)
if (ret < 0 && ret != -EINVAL)
return ret;
rproc = rproc_alloc(&pdev->dev, pdev->name, &wcnss_ops,
fw_name, sizeof(*wcnss));
rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &wcnss_ops,
fw_name, sizeof(*wcnss));
if (!rproc) {
dev_err(&pdev->dev, "unable to allocate remoteproc\n");
return -ENOMEM;
@ -574,14 +574,12 @@ static int wcnss_probe(struct platform_device *pdev)
mutex_init(&wcnss->iris_lock);
mmio = devm_platform_ioremap_resource_byname(pdev, "pmu");
if (IS_ERR(mmio)) {
ret = PTR_ERR(mmio);
goto free_rproc;
}
if (IS_ERR(mmio))
return PTR_ERR(mmio);
ret = wcnss_alloc_memory_region(wcnss);
if (ret)
goto free_rproc;
return ret;
wcnss->pmu_cfg = mmio + data->pmu_offset;
wcnss->spare_out = mmio + data->spare_offset;
@ -592,7 +590,7 @@ static int wcnss_probe(struct platform_device *pdev)
*/
ret = wcnss_init_pds(wcnss, data->pd_names);
if (ret && (ret != -ENODATA || !data->num_pd_vregs))
goto free_rproc;
return ret;
ret = wcnss_init_regulators(wcnss, data->vregs, data->num_vregs,
data->num_pd_vregs);
@ -656,8 +654,6 @@ 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[] = {

View File

@ -33,6 +33,7 @@
#include <linux/idr.h>
#include <linux/elf.h>
#include <linux/crc32.h>
#include <linux/of_platform.h>
#include <linux/of_reserved_mem.h>
#include <linux/virtio_ids.h>
#include <linux/virtio_ring.h>
@ -2112,6 +2113,7 @@ EXPORT_SYMBOL(rproc_detach);
struct rproc *rproc_get_by_phandle(phandle phandle)
{
struct rproc *rproc = NULL, *r;
struct device_driver *driver;
struct device_node *np;
np = of_find_node_by_phandle(phandle);
@ -2122,7 +2124,26 @@ struct rproc *rproc_get_by_phandle(phandle phandle)
list_for_each_entry_rcu(r, &rproc_list, node) {
if (r->dev.parent && device_match_of_node(r->dev.parent, np)) {
/* prevent underlying implementation from being removed */
if (!try_module_get(r->dev.parent->driver->owner)) {
/*
* If the remoteproc's parent has a driver, the
* remoteproc is not part of a cluster and we can use
* that driver.
*/
driver = r->dev.parent->driver;
/*
* If the remoteproc's parent does not have a driver,
* look for the driver associated with the cluster.
*/
if (!driver) {
if (r->dev.parent->parent)
driver = r->dev.parent->parent->driver;
if (!driver)
break;
}
if (!try_module_get(driver->owner)) {
dev_err(&r->dev, "can't get owner\n");
break;
}
@ -2533,7 +2554,11 @@ EXPORT_SYMBOL(rproc_free);
*/
void rproc_put(struct rproc *rproc)
{
module_put(rproc->dev.parent->driver->owner);
if (rproc->dev.parent->driver)
module_put(rproc->dev.parent->driver->owner);
else
module_put(rproc->dev.parent->parent->driver->owner);
put_device(&rproc->dev);
}
EXPORT_SYMBOL(rproc_put);

View File

@ -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);
}

View File

@ -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 = {

View File

@ -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)

View File

@ -550,6 +550,13 @@ static int k3_dsp_rproc_of_get_memories(struct platform_device *pdev,
return 0;
}
static void k3_dsp_mem_release(void *data)
{
struct device *dev = data;
of_reserved_mem_device_release(dev);
}
static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc)
{
struct device *dev = kproc->dev;
@ -579,27 +586,25 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc)
ERR_PTR(ret));
return ret;
}
ret = devm_add_action_or_reset(dev, k3_dsp_mem_release, dev);
if (ret)
return ret;
num_rmems--;
kproc->rmem = kcalloc(num_rmems, sizeof(*kproc->rmem), GFP_KERNEL);
if (!kproc->rmem) {
ret = -ENOMEM;
goto release_rmem;
}
kproc->rmem = devm_kcalloc(dev, num_rmems, sizeof(*kproc->rmem), GFP_KERNEL);
if (!kproc->rmem)
return -ENOMEM;
/* use remaining reserved memory regions for static carveouts */
for (i = 0; i < num_rmems; i++) {
rmem_np = of_parse_phandle(np, "memory-region", i + 1);
if (!rmem_np) {
ret = -EINVAL;
goto unmap_rmem;
}
if (!rmem_np)
return -EINVAL;
rmem = of_reserved_mem_lookup(rmem_np);
if (!rmem) {
of_node_put(rmem_np);
ret = -EINVAL;
goto unmap_rmem;
return -EINVAL;
}
of_node_put(rmem_np);
@ -607,12 +612,11 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc)
/* 64-bit address regions currently not supported */
kproc->rmem[i].dev_addr = (u32)rmem->base;
kproc->rmem[i].size = rmem->size;
kproc->rmem[i].cpu_addr = ioremap_wc(rmem->base, rmem->size);
kproc->rmem[i].cpu_addr = devm_ioremap_wc(dev, rmem->base, rmem->size);
if (!kproc->rmem[i].cpu_addr) {
dev_err(dev, "failed to map reserved memory#%d at %pa of size %pa\n",
i + 1, &rmem->base, &rmem->size);
ret = -ENOMEM;
goto unmap_rmem;
return -ENOMEM;
}
dev_dbg(dev, "reserved memory%d: bus addr %pa size 0x%zx va %pK da 0x%x\n",
@ -623,25 +627,13 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc)
kproc->num_rmems = num_rmems;
return 0;
unmap_rmem:
for (i--; i >= 0; i--)
iounmap(kproc->rmem[i].cpu_addr);
kfree(kproc->rmem);
release_rmem:
of_reserved_mem_device_release(kproc->dev);
return ret;
}
static void k3_dsp_reserved_mem_exit(struct k3_dsp_rproc *kproc)
static void k3_dsp_release_tsp(void *data)
{
int i;
struct ti_sci_proc *tsp = data;
for (i = 0; i < kproc->num_rmems; i++)
iounmap(kproc->rmem[i].cpu_addr);
kfree(kproc->rmem);
of_reserved_mem_device_release(kproc->dev);
ti_sci_proc_release(tsp);
}
static
@ -657,7 +649,7 @@ struct ti_sci_proc *k3_dsp_rproc_of_get_tsp(struct device *dev,
if (ret < 0)
return ERR_PTR(ret);
tsp = kzalloc(sizeof(*tsp), GFP_KERNEL);
tsp = devm_kzalloc(dev, sizeof(*tsp), GFP_KERNEL);
if (!tsp)
return ERR_PTR(-ENOMEM);
@ -680,7 +672,6 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
const char *fw_name;
bool p_state = false;
int ret = 0;
int ret1;
data = of_device_get_match_data(dev);
if (!data)
@ -690,8 +681,8 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
if (ret)
return dev_err_probe(dev, ret, "failed to parse firmware-name property\n");
rproc = rproc_alloc(dev, dev_name(dev), &k3_dsp_rproc_ops, fw_name,
sizeof(*kproc));
rproc = devm_rproc_alloc(dev, dev_name(dev), &k3_dsp_rproc_ops,
fw_name, sizeof(*kproc));
if (!rproc)
return -ENOMEM;
@ -706,56 +697,46 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
kproc->dev = dev;
kproc->data = data;
kproc->ti_sci = ti_sci_get_by_phandle(np, "ti,sci");
if (IS_ERR(kproc->ti_sci)) {
ret = dev_err_probe(dev, PTR_ERR(kproc->ti_sci),
"failed to get ti-sci handle\n");
kproc->ti_sci = NULL;
goto free_rproc;
}
kproc->ti_sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
if (IS_ERR(kproc->ti_sci))
return dev_err_probe(dev, PTR_ERR(kproc->ti_sci),
"failed to get ti-sci handle\n");
ret = of_property_read_u32(np, "ti,sci-dev-id", &kproc->ti_sci_id);
if (ret) {
dev_err_probe(dev, ret, "missing 'ti,sci-dev-id' property\n");
goto put_sci;
}
if (ret)
return dev_err_probe(dev, ret, "missing 'ti,sci-dev-id' property\n");
kproc->reset = devm_reset_control_get_exclusive(dev, NULL);
if (IS_ERR(kproc->reset)) {
ret = dev_err_probe(dev, PTR_ERR(kproc->reset),
"failed to get reset\n");
goto put_sci;
}
if (IS_ERR(kproc->reset))
return dev_err_probe(dev, PTR_ERR(kproc->reset),
"failed to get reset\n");
kproc->tsp = k3_dsp_rproc_of_get_tsp(dev, kproc->ti_sci);
if (IS_ERR(kproc->tsp)) {
ret = dev_err_probe(dev, PTR_ERR(kproc->tsp),
"failed to construct ti-sci proc control\n");
goto put_sci;
}
if (IS_ERR(kproc->tsp))
return dev_err_probe(dev, PTR_ERR(kproc->tsp),
"failed to construct ti-sci proc control\n");
ret = ti_sci_proc_request(kproc->tsp);
if (ret < 0) {
dev_err_probe(dev, ret, "ti_sci_proc_request failed\n");
goto free_tsp;
return ret;
}
ret = devm_add_action_or_reset(dev, k3_dsp_release_tsp, kproc->tsp);
if (ret)
return ret;
ret = k3_dsp_rproc_of_get_memories(pdev, kproc);
if (ret)
goto release_tsp;
return ret;
ret = k3_dsp_reserved_mem_init(kproc);
if (ret) {
dev_err_probe(dev, ret, "reserved memory init failed\n");
goto release_tsp;
}
if (ret)
return dev_err_probe(dev, ret, "reserved memory init failed\n");
ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id,
NULL, &p_state);
if (ret) {
dev_err_probe(dev, ret, "failed to get initial state, mode cannot be determined\n");
goto release_mem;
}
if (ret)
return dev_err_probe(dev, ret, "failed to get initial state, mode cannot be determined\n");
/* configure J721E devices for either remoteproc or IPC-only mode */
if (p_state) {
@ -779,8 +760,7 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
if (data->uses_lreset) {
ret = reset_control_status(kproc->reset);
if (ret < 0) {
dev_err_probe(dev, ret, "failed to get reset status\n");
goto release_mem;
return dev_err_probe(dev, ret, "failed to get reset status\n");
} else if (ret == 0) {
dev_warn(dev, "local reset is deasserted for device\n");
k3_dsp_rproc_reset(kproc);
@ -788,31 +768,13 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev)
}
}
ret = rproc_add(rproc);
if (ret) {
dev_err_probe(dev, ret, "failed to add register device with remoteproc core\n");
goto release_mem;
}
ret = devm_rproc_add(dev, rproc);
if (ret)
return dev_err_probe(dev, ret, "failed to add register device with remoteproc core\n");
platform_set_drvdata(pdev, kproc);
return 0;
release_mem:
k3_dsp_reserved_mem_exit(kproc);
release_tsp:
ret1 = ti_sci_proc_release(kproc->tsp);
if (ret1)
dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret1));
free_tsp:
kfree(kproc->tsp);
put_sci:
ret1 = ti_sci_put_handle(kproc->ti_sci);
if (ret1)
dev_err(dev, "failed to put ti_sci handle (%pe)\n", ERR_PTR(ret1));
free_rproc:
rproc_free(rproc);
return ret;
}
static void k3_dsp_rproc_remove(struct platform_device *pdev)
@ -824,27 +786,9 @@ static void k3_dsp_rproc_remove(struct platform_device *pdev)
if (rproc->state == RPROC_ATTACHED) {
ret = rproc_detach(rproc);
if (ret) {
/* Note this error path leaks resources */
if (ret)
dev_err(dev, "failed to detach proc (%pe)\n", ERR_PTR(ret));
return;
}
}
rproc_del(kproc->rproc);
ret = ti_sci_proc_release(kproc->tsp);
if (ret)
dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret));
kfree(kproc->tsp);
ret = ti_sci_put_handle(kproc->ti_sci);
if (ret)
dev_err(dev, "failed to put ti_sci handle (%pe)\n", ERR_PTR(ret));
k3_dsp_reserved_mem_exit(kproc);
rproc_free(kproc->rproc);
}
static const struct k3_dsp_mem_data c66_mems[] = {