devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
To: Manikanta Mylavarapu <quic_mmanikan@quicinc.com>,
	agross@kernel.org, andersson@kernel.org,
	konrad.dybcio@linaro.org, mathieu.poirier@linaro.org,
	robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org,
	conor+dt@kernel.org, mturquette@baylibre.com, sboyd@kernel.org,
	quic_eberman@quicinc.com, kvalo@kernel.org,
	loic.poulain@linaro.org, linux-arm-msm@vger.kernel.org,
	linux-remoteproc@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org
Cc: quic_srichara@quicinc.com, quic_sjaganat@quicinc.com,
	quic_kathirav@quicinc.com, quic_anusha@quicinc.com
Subject: Re: [V3,09/11] remoteproc: qcom: Add Hexagon based multipd rproc driver
Date: Wed, 19 Jul 2023 09:26:53 +0200	[thread overview]
Message-ID: <fedea75a-a5f1-fbe4-7f12-75bfdf9bfcf2@linaro.org> (raw)
In-Reply-To: <20230718120501.3205661-10-quic_mmanikan@quicinc.com>

On 18/07/2023 14:04, Manikanta Mylavarapu wrote:
> It adds support to bring up remoteproc's on multipd model.
> Pd means protection domain. It's similar to process in Linux.
> Here QDSP6 processor runs each wifi radio functionality on a
> separate process. One process can't access other process
> resources, so this is termed as PD i.e protection domain.
> 
> Here we have two pd's called root and user pd. We can correlate
> Root pd as root and user pd as user in linux. Root pd has more
> privileges than user pd. Root will provide services to user pd.
> 


> +static int q6_get_inbound_irq(struct qcom_q6v5 *q6,
> +			      struct platform_device *pdev,
> +			      const char *int_name,
> +			      int index, int *pirq,
> +			      irqreturn_t (*handler)(int irq, void *data))
> +{
> +	int ret, irq;
> +	char *interrupt, *tmp = (char *)int_name;
> +	struct q6_wcss *wcss = q6->rproc->priv;
> +
> +	irq = platform_get_irq(pdev, index);
> +	if (irq < 0) {
> +		if (irq != -EPROBE_DEFER)
> +			dev_err_probe(&pdev->dev, irq,
> +				      "failed to retrieve %s IRQ: %d\n",
> +				      int_name, irq);

Wait, what? This does not make any sense. dev_err_probe is to replace
all this dance. return dev_err_probe which I explicitly asked last time:

https://lore.kernel.org/all/2061a641-4b97-1aa6-27cd-99f01a785033@linaro.org/

> +		return irq;
> +	}
> +
> +	*pirq = irq;
> +
> +	interrupt = devm_kzalloc(&pdev->dev, BUF_SIZE, GFP_KERNEL);
> +	if (!interrupt)
> +		return -ENOMEM;
> +
> +	snprintf(interrupt, BUF_SIZE, "q6v5_wcss_userpd%d_%s", wcss->pd_asid, tmp);
> +
> +	ret = devm_request_threaded_irq(&pdev->dev, *pirq,
> +					NULL, handler,
> +					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> +					interrupt, q6);
> +	if (ret) {
> +		dev_err_probe(&pdev->dev, ret,
> +			      "failed to acquire %s irq\n", interrupt);
> +		return ret;
> +	}
> +	return 0;
> +}
> +
> +static int q6_get_outbound_irq(struct qcom_q6v5 *q6,
> +			       struct platform_device *pdev,
> +			       const char *int_name)
> +{
> +	struct qcom_smem_state *tmp_state;
> +	unsigned  bit;
> +
> +	tmp_state = qcom_smem_state_get(&pdev->dev, int_name, &bit);
> +	if (IS_ERR(tmp_state)) {
> +		dev_err_probe(&pdev->dev, IS_ERR(tmp_state),
> +			      "failed to acquire %s state\n", int_name);
> +		return PTR_ERR(tmp_state);

So it is everywhere...


> +	}
> +
> +	if (!strcmp(int_name, "stop")) {
> +		q6->state = tmp_state;
> +		q6->stop_bit = bit;
> +	} else if (!strcmp(int_name, "spawn")) {
> +		q6->spawn_state = tmp_state;
> +		q6->spawn_bit = bit;
> +	}
> +
> +	return 0;
> +}
> +
> +static int init_irq(struct qcom_q6v5 *q6,
> +		    struct platform_device *pdev, struct rproc *rproc,
> +		    int crash_reason, const char *load_state,
> +		    void (*handover)(struct qcom_q6v5 *q6))
> +{
> +	int ret;
> +	struct q6_wcss *wcss = rproc->priv;
> +
> +	q6->rproc = rproc;
> +	q6->dev = &pdev->dev;
> +	q6->crash_reason = crash_reason;
> +	q6->handover = handover;
> +
> +	init_completion(&q6->start_done);
> +	init_completion(&q6->stop_done);
> +	init_completion(&q6->spawn_done);
> +
> +	ret = q6_get_outbound_irq(q6, pdev, "stop");
> +	if (ret)
> +		return ret;
> +
> +	ret = q6_get_outbound_irq(q6, pdev, "spawn");
> +	if (ret)
> +		return ret;
> +
> +	/* Get pd_asid to prepare interrupt names */
> +	wcss->pd_asid = qcom_get_pd_asid(rproc);
> +
> +	ret = q6_get_inbound_irq(q6, pdev, "fatal", 0, &q6->fatal_irq,
> +				 q6v5_fatal_interrupt);
> +	if (ret)
> +		return ret;
> +
> +	ret = q6_get_inbound_irq(q6, pdev, "ready", 1, &q6->ready_irq,
> +				 q6v5_ready_interrupt);
> +	if (ret)
> +		return ret;
> +
> +	ret = q6_get_inbound_irq(q6, pdev, "stop-ack", 3, &q6->stop_irq,
> +				 q6v5_stop_interrupt);
> +	if (ret)
> +		return ret;
> +
> +	ret = q6_get_inbound_irq(q6, pdev, "spawn-ack", 2, &q6->spawn_irq,
> +				 q6v5_spawn_interrupt);
> +	if (ret)
> +		return ret;
> +	return 0;
> +}
> +
> +static void q6_release_resources(struct platform_device *pdev)
> +{
> +	struct rproc *upd_rproc;
> +	struct device_node *upd_np;
> +	struct platform_device *upd_pdev;
> +
> +	/* Release userpd resources */
> +	for_each_available_child_of_node(pdev->dev.of_node, upd_np) {

You should not iterate over OF to get devices to unregister. What if you
have more nodes than before because of overlay?


> +		upd_pdev = of_find_device_by_node(upd_np);
> +		if (!upd_pdev)
> +			continue;
> +
> +		upd_rproc = platform_get_drvdata(upd_pdev);
> +		if (!upd_rproc) {
> +			platform_device_unregister(upd_pdev);
> +			continue;
> +		}
> +
> +		rproc_del(upd_rproc);
> +		rproc_free(upd_rproc);
> +	}
> +}
> +
> +static int q6_register_userpd(struct platform_device *pdev)
> +{
> +	struct q6_wcss *wcss;
> +	struct rproc *rproc = NULL;
> +	int ret;
> +	struct device_node *userpd_np;
> +	struct platform_device *userpd_pdev;
> +	const char *firmware_name = NULL;
> +
> +	for_each_available_child_of_node(pdev->dev.of_node, userpd_np) {
> +		ret = of_property_read_string(userpd_np, "firmware-name",
> +					      &firmware_name);
> +		if (ret < 0)
> +			continue;
> +
> +		dev_info(&pdev->dev, "%s node found\n", userpd_np->name);
> +
> +		userpd_pdev = of_platform_device_create(userpd_np,
> +							userpd_np->name,
> +							&pdev->dev);
> +		if (!userpd_pdev) {
> +			ret = -ENODEV;
> +			dev_err_probe(&pdev->dev, ret,
> +				      "failed to create %s platform device\n",
> +				      userpd_np->name);
> +			goto release_resource;
> +		}
> +		userpd_pdev->dev.driver = pdev->dev.driver;
> +		rproc = rproc_alloc(&userpd_pdev->dev, userpd_pdev->name,
> +				    &wcss_ops, firmware_name,
> +				    sizeof(*wcss));
> +		if (!rproc) {
> +			ret = -ENOMEM;
> +			goto release_resource;
> +		}
> +
> +		wcss = rproc->priv;
> +		wcss->dev = &userpd_pdev->dev;
> +
> +		ret = q6_alloc_memory_region(wcss);
> +		if (ret)

How do you release the resource allocated in rproc_alloc() for this
node? drvdata is not set, so your cleanup function will skip it.

> +			goto release_resource;
> +
> +		ret = init_irq(&wcss->q6, userpd_pdev, rproc,
> +			       WCSS_CRASH_REASON, NULL, NULL);
> +		if (ret)
> +			goto release_resource;
> +
> +		rproc->auto_boot = false;
> +		ret = rproc_add(rproc);
> +		if (ret)
> +			goto release_resource;
> +
> +		platform_set_drvdata(userpd_pdev, rproc);
> +		qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, userpd_pdev->name);
> +	}
> +	return 0;
> +
> +release_resource:
> +	q6_release_resources(pdev);
> +	return ret;
> +}
> +
> +static int q6_wcss_probe(struct platform_device *pdev)
> +{
> +	const struct wcss_data *desc;
> +	struct q6_wcss *wcss;
> +	struct rproc *rproc;
> +	int ret;
> +	char *subdev_name;
> +	const char **firmware;
> +
> +	desc = of_device_get_match_data(&pdev->dev);
> +	if (!desc)
> +		return -EINVAL;
> +
> +	firmware = devm_kcalloc(&pdev->dev, MAX_FIRMWARE,
> +				sizeof(*firmware), GFP_KERNEL);
> +	if (!firmware)
> +		return -ENOMEM;
> +
> +	ret = of_property_read_string_array(pdev->dev.of_node, "firmware-name",
> +					    firmware, MAX_FIRMWARE);
> +	if (ret < 0)
> +		return ret;
> +
> +	rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops,
> +			    firmware[0], sizeof(*wcss));
> +	if (!rproc)
> +		return -ENOMEM;
> +
> +	wcss = rproc->priv;
> +	wcss->dev = &pdev->dev;
> +	wcss->desc = desc;
> +	wcss->firmware = firmware;
> +
> +	ret = q6_alloc_memory_region(wcss);
> +	if (ret)
> +		goto free_rproc;
> +
> +	ret = desc->init_irq(&wcss->q6, pdev, rproc,
> +			     desc->crash_reason_smem, NULL, NULL);
> +	if (ret)
> +		goto free_rproc;
> +
> +	if (desc->glink_subdev_required)
> +		qcom_add_glink_subdev(rproc, &wcss->glink_subdev, desc->ssr_name);
> +
> +	subdev_name = (char *)(desc->ssr_name ? desc->ssr_name : pdev->name);

Wrong cast. Why are you dropping const? That's a bug.

> +	qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, subdev_name);
> +
> +	rproc->auto_boot = false;
> +	ret = rproc_add(rproc);
> +	if (ret)
> +		goto free_rproc;
> +
> +	platform_set_drvdata(pdev, rproc);
> +
> +	ret = q6_register_userpd(pdev);
> +	if (ret) {
> +		dev_err_probe(&pdev->dev, ret, "Failed to register userpd\n");
> +		return ret;

return dev_err_probe

> +	}
> +
> +	return 0;
> +
> +free_rproc:
> +	rproc_free(rproc);
> +
> +	return ret;

Best regards,
Krzysztof


  reply	other threads:[~2023-07-19  7:27 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-18 12:04 [V3,00/11] Add multipd remoteproc support Manikanta Mylavarapu
2023-07-18 12:04 ` [V3,01/11] dt-bindings: remoteproc: qcom: Add support for multipd model Manikanta Mylavarapu
2023-07-19  7:11   ` Krzysztof Kozlowski
2023-07-18 12:04 ` [V3,02/11] dt-bindings: clock: qcom: gcc-ipq9574: remove q6 bring up clock macros Manikanta Mylavarapu
2023-07-19  7:14   ` Krzysztof Kozlowski
2023-07-19  7:15     ` Krzysztof Kozlowski
2023-07-19 15:11       ` Manikanta Mylavarapu
2023-07-19 15:21         ` Krzysztof Kozlowski
2023-07-18 12:04 ` [V3,03/11] dt-bindings: clock: qcom: gcc-ipq5332: " Manikanta Mylavarapu
2023-07-19  7:15   ` Krzysztof Kozlowski
2023-07-18 12:04 ` [V3,04/11] clk: qcom: ipq9574: remove q6 bring up clocks Manikanta Mylavarapu
2023-07-18 12:04 ` [V3,05/11] clk: qcom: ipq5332: " Manikanta Mylavarapu
2023-07-18 12:04 ` [V3,06/11] firmware: qcom_scm: ipq5332: add support to pass metadata size Manikanta Mylavarapu
2023-07-18 12:04 ` [V3,07/11] firmware: qcom_scm: ipq5332: add msa lock/unlock support Manikanta Mylavarapu
2023-07-18 12:04 ` [V3,08/11] remoteproc: qcom: q6v5: Add multipd interrupts support Manikanta Mylavarapu
2023-07-18 12:04 ` [V3,09/11] remoteproc: qcom: Add Hexagon based multipd rproc driver Manikanta Mylavarapu
2023-07-19  7:26   ` Krzysztof Kozlowski [this message]
2023-07-19 15:32     ` Manikanta Mylavarapu
2023-07-21  7:14     ` Manikanta Mylavarapu
2023-07-19 11:04   ` kernel test robot
2023-07-20 13:13   ` Krzysztof Kozlowski
2023-07-21  6:33     ` Manikanta Mylavarapu
2023-07-18 12:05 ` [V3,10/11] arm64: dts: qcom: ipq5332: Add nodes to bringup multipd Manikanta Mylavarapu
2023-07-18 12:05 ` [V3,11/11] arm64: dts: qcom: ipq9574: Add nodes to bring up multipd Manikanta Mylavarapu
2023-07-19  7:01 ` [V3,00/11] Add multipd remoteproc support Krzysztof Kozlowski
2023-07-19  7:09   ` Manikanta Mylavarapu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fedea75a-a5f1-fbe4-7f12-75bfdf9bfcf2@linaro.org \
    --to=krzysztof.kozlowski@linaro.org \
    --cc=agross@kernel.org \
    --cc=andersson@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=konrad.dybcio@linaro.org \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=kvalo@kernel.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-remoteproc@vger.kernel.org \
    --cc=loic.poulain@linaro.org \
    --cc=mathieu.poirier@linaro.org \
    --cc=mturquette@baylibre.com \
    --cc=quic_anusha@quicinc.com \
    --cc=quic_eberman@quicinc.com \
    --cc=quic_kathirav@quicinc.com \
    --cc=quic_mmanikan@quicinc.com \
    --cc=quic_sjaganat@quicinc.com \
    --cc=quic_srichara@quicinc.com \
    --cc=robh+dt@kernel.org \
    --cc=sboyd@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).