public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
From: Markus Mayer <mmayer@broadcom.com>
To: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>,
	Florian Fainelli <florian.fainelli@broadcom.com>,
	Rob Herring <robh+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>
Cc: Markus Mayer <mmayer@broadcom.com>,
	Linux ARM Kernel List <linux-arm-kernel@lists.infradead.org>,
	Device Tree Mailing List <devicetree@vger.kernel.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: [PATCH 4/4] memory: brcmstb_dpfe: introduce best-effort API detection
Date: Tue,  5 Dec 2023 10:47:37 -0800	[thread overview]
Message-ID: <20231205184741.3092376-5-mmayer@broadcom.com> (raw)
In-Reply-To: <20231205184741.3092376-1-mmayer@broadcom.com>

Add a best-effort probe function that tries all known DPFE versions to
see if one might actually work. This helps in cases where device tree
doesn't provide the proper version information for whatever reason. In
that case, the driver may still be able to register if one of the known
API versions ends up working.

Caveat: we have to skip "v1" during our best effort attempts. This is
due to the fact that attempting a firmware download as required by v1
will result in a memory access violation on anything but v1 hardware.
This would crash the kernel. Since we don't know the HW version, we need
to play it safe and skip v1.

Signed-off-by: Markus Mayer <mmayer@broadcom.com>
---
 drivers/memory/brcmstb_dpfe.c | 58 ++++++++++++++++++++++++++++++++++-
 1 file changed, 57 insertions(+), 1 deletion(-)

diff --git a/drivers/memory/brcmstb_dpfe.c b/drivers/memory/brcmstb_dpfe.c
index 0b0a9b85b605..15f4ee3b8535 100644
--- a/drivers/memory/brcmstb_dpfe.c
+++ b/drivers/memory/brcmstb_dpfe.c
@@ -879,6 +879,50 @@ static int brcmstb_dpfe_resume(struct platform_device *pdev)
 	return brcmstb_dpfe_download_firmware(priv);
 }
 
+static int brcmstb_dpfe_probe_best_effort(struct platform_device *pdev)
+{
+	const char versioned_compat[] = "brcm,dpfe-cpu-v";
+	const char v1_str[] = "-v1";
+	const struct of_device_id *matches;
+	const struct dpfe_api *orig_dpfe_api;
+	struct device *dev = &pdev->dev;
+	struct brcmstb_dpfe_priv *priv;
+	int ret = -ENODEV;
+
+	priv = dev_get_drvdata(dev);
+	orig_dpfe_api = priv->dpfe_api;
+	matches = dev->driver->of_match_table;
+
+	/* Loop over all compatible strings */
+	for (; matches->compatible[0]; matches++) {
+		const char *compat = matches->compatible;
+		/* Find the ones that start with "brcm,dpfe-cpu-v" */
+		if (strstr(compat, versioned_compat) == compat) {
+			char *v1_ptr = strstr(compat, v1_str);
+			/*
+			 * We must skip v1, since we don't know the hardware
+			 * version and attempting a firmware download on v2 and
+			 * newer would crash the kernel due to a memory access
+			 * violation.
+			 * We make sure to match "-v1" at the end of the string
+			 * only.
+			 */
+			if (v1_ptr && v1_ptr[sizeof(v1_str)] == '\0')
+				continue;
+			priv->dpfe_api = matches->data;
+			/* Fingers crossed... */
+			ret = brcmstb_dpfe_download_firmware(priv);
+			if (!ret)
+				return 0;
+		}
+	}
+
+	/* It didn't work, so let's clean up. */
+	priv->dpfe_api = orig_dpfe_api;
+
+	return ret;
+}
+
 static int brcmstb_dpfe_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -923,8 +967,20 @@ static int brcmstb_dpfe_probe(struct platform_device *pdev)
 	}
 
 	ret = brcmstb_dpfe_download_firmware(priv);
+	if (ret && ret != -EPROBE_DEFER) {
+		/*
+		 * If the information provided by Device Tree didn't work, let's
+		 * try all known version. Maybe one will work.
+		 */
+		dev_warn(dev,
+			"DPFE v%d didn't work, reverting to best-effort\n",
+			priv->dpfe_api->version);
+		dev_warn(dev,
+			"Device Tree and / or the driver should be updated\n");
+		ret = brcmstb_dpfe_probe_best_effort(pdev);
+	}
 	if (ret)
-		return dev_err_probe(dev, ret, "Couldn't download firmware\n");
+		return dev_err_probe(dev, ret, "Unable to talk to DCPU\n");
 
 	ret = sysfs_create_groups(&pdev->dev.kobj, priv->dpfe_api->sysfs_attrs);
 	if (!ret)
-- 
2.43.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2023-12-05 18:49 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-05 18:47 [PATCH 0/4] memory: brcmstb_dpfe: support DPFE API v4 Markus Mayer
2023-12-05 18:47 ` [PATCH 1/4] dt-bindings: memory: additional compatible strings for Broadcom DPFE Markus Mayer
2023-12-06 11:09   ` Krzysztof Kozlowski
2023-12-06 16:32     ` Florian Fainelli
2023-12-06 17:29       ` Krzysztof Kozlowski
2023-12-06 17:36         ` Florian Fainelli
2023-12-06 17:42           ` Krzysztof Kozlowski
2023-12-05 18:47 ` [PATCH 2/4] memory: brcmstb_dpfe: introduce version-specific compatible strings Markus Mayer
2023-12-05 19:05   ` Florian Fainelli
2023-12-06 11:09   ` Krzysztof Kozlowski
2023-12-06 16:19     ` Florian Fainelli
2023-12-06 17:33       ` Krzysztof Kozlowski
2023-12-05 18:47 ` [PATCH 3/4] memory: brcmstb_dpfe: support DPFE API v4 Markus Mayer
2023-12-05 19:05   ` Florian Fainelli
2023-12-06 11:10   ` Krzysztof Kozlowski
2023-12-06 16:18     ` Florian Fainelli
2023-12-06 17:31       ` Krzysztof Kozlowski
2023-12-06 18:48         ` Markus Mayer
2023-12-05 18:47 ` Markus Mayer [this message]
2023-12-05 19:06   ` [PATCH 4/4] memory: brcmstb_dpfe: introduce best-effort API detection Florian Fainelli
2023-12-06 11:13   ` Krzysztof Kozlowski
2023-12-06 16:24     ` Florian Fainelli
2023-12-06 11:14 ` [PATCH 0/4] memory: brcmstb_dpfe: support DPFE API v4 Krzysztof Kozlowski

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=20231205184741.3092376-5-mmayer@broadcom.com \
    --to=mmayer@broadcom.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=florian.fainelli@broadcom.com \
    --cc=krzysztof.kozlowski@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=robh+dt@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