Re: [PATCH 01/12] soc: qcom: add firmware name helper

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 21/05/2024 11:45, Dmitry Baryshkov wrote:
Qualcomm platforms have different sets of the firmware files, which
differ from platform to platform (and from board to board, due to the
embedded signatures). Rather than listing all the firmware files,
including full paths, in the DT, provide a way to determine firmware
path based on the root DT node compatible.

Ok this looks quite over-engineered but necessary to handle the legacy,
but I really think we should add a way to look for a board-specific path
first and fallback to those SoC specific paths.

Neil


Suggested-by: Arnd Bergmann <arnd@xxxxxxxx>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxx>
---
  drivers/soc/qcom/Kconfig           |  5 +++
  drivers/soc/qcom/Makefile          |  1 +
  drivers/soc/qcom/qcom_fw_helper.c  | 86 ++++++++++++++++++++++++++++++++++++++
  include/linux/soc/qcom/fw_helper.h | 10 +++++
  4 files changed, 102 insertions(+)

diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 5af33b0e3470..b663774d65f8 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -62,6 +62,11 @@ config QCOM_MDT_LOADER
  	tristate
  	select QCOM_SCM
+config QCOM_FW_HELPER
+	tristate "NONE FW HELPER"
+	help
+	  Helpers to return platform-specific location for the firmware files.
+
  config QCOM_OCMEM
  	tristate "Qualcomm On Chip Memory (OCMEM) driver"
  	depends on ARCH_QCOM
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index ca0bece0dfff..e612bee5b955 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_QCOM_GENI_SE) +=	qcom-geni-se.o
  obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o
  obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
  obj-$(CONFIG_QCOM_MDT_LOADER)	+= mdt_loader.o
+obj-$(CONFIG_QCOM_FW_HELPER)	+= qcom_fw_helper.o
  obj-$(CONFIG_QCOM_OCMEM)	+= ocmem.o
  obj-$(CONFIG_QCOM_PDR_HELPERS)	+= pdr_interface.o
  obj-$(CONFIG_QCOM_PMIC_GLINK)	+= pmic_glink.o
diff --git a/drivers/soc/qcom/qcom_fw_helper.c b/drivers/soc/qcom/qcom_fw_helper.c
new file mode 100644
index 000000000000..13123c2514b8
--- /dev/null
+++ b/drivers/soc/qcom/qcom_fw_helper.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Qualcomm Firmware loading data
+ *
+ * Copyright (C) 2024 Linaro Ltd
+ */
+
+#include <linux/cleanup.h>
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/soc/qcom/fw_helper.h>
+
+static DEFINE_MUTEX(qcom_fw_mutex);
+static const char *fw_path;
+
+static const struct of_device_id qcom_fw_paths[] = {
+	/* device-specific entries */
+	{ .compatible = "thundercomm,db845c", .data = "qcom/sdm845/Thundercomm/db845c", },
+	{ .compatible = "qcom,qrb5165-rb5", .data = "qcom/sm8250/Thundercomm/RB5", },
+	/* SoC default entries */
+	{ .compatible = "qcom,apq8016", .data = "qcom/apq8016", },
+	{ .compatible = "qcom,apq8096", .data = "qcom/apq8096", },
+	{ .compatible = "qcom,sdm845", .data = "qcom/sdm845", },
+	{ .compatible = "qcom,sm8250", .data = "qcom/sm8250", },
+	{ .compatible = "qcom,sm8350", .data = "qcom/sm8350", },
+	{ .compatible = "qcom,sm8450", .data = "qcom/sm8450", },
+	{ .compatible = "qcom,sm8550", .data = "qcom/sm8550", },
+	{ .compatible = "qcom,sm8650", .data = "qcom/sm8650", },
+	{},
+};
+
+static int qcom_fw_ensure_init(void)
+{
+	const struct of_device_id *match;
+	struct device_node *root;
+
+	if (fw_path)
+		return 0;
+
+	root = of_find_node_by_path("/");
+	if (!root)
+		return -ENODEV;
+
+	match = of_match_node(qcom_fw_paths, root);
+	of_node_put(root);
+	if (!match || !match->data) {
+		pr_notice("Platform not supported by qcom_fw_helper\n");
+		return -ENODEV;
+	}
+
+	fw_path = match->data;
+
+	return 0;
+}
+
+const char *qcom_get_board_fw(const char *firmware)
+{
+	if (strchr(firmware, '/'))
+		return kstrdup(firmware, GFP_KERNEL);
+
+	scoped_guard(mutex, &qcom_fw_mutex) {
+		if (!qcom_fw_ensure_init())
+			return kasprintf(GFP_KERNEL, "%s/%s", fw_path, firmware);
+	}
+
+	return kstrdup(firmware, GFP_KERNEL);
+}
+EXPORT_SYMBOL_GPL(qcom_get_board_fw);
+
+const char *devm_qcom_get_board_fw(struct device *dev, const char *firmware)
+{
+	if (strchr(firmware, '/'))
+		return devm_kstrdup(dev, firmware, GFP_KERNEL);
+
+	scoped_guard(mutex, &qcom_fw_mutex) {
+		if (!qcom_fw_ensure_init())
+			return devm_kasprintf(dev, GFP_KERNEL, "%s/%s", fw_path, firmware);
+	}
+
+	return devm_kstrdup(dev, firmware, GFP_KERNEL);
+}
+EXPORT_SYMBOL_GPL(devm_qcom_get_board_fw);
+
+MODULE_DESCRIPTION("Firmware helpers for Qualcomm devices");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/soc/qcom/fw_helper.h b/include/linux/soc/qcom/fw_helper.h
new file mode 100644
index 000000000000..755645386bba
--- /dev/null
+++ b/include/linux/soc/qcom/fw_helper.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __QCOM_FW_HELPER_H__
+#define __QCOM_FW_HELPER_H__
+
+struct device;
+
+const char *qcom_get_board_fw(const char *firmware);
+const char *devm_qcom_get_board_fw(struct device *dev, const char *firmware);
+
+#endif






[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux