All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dave Gerlach <d-gerlach@ti.com>
To: Rob Herring <robh+dt@kernel.org>,
	Santosh Shilimkar <ssantosh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Tero Kristo <kristo@kernel.org>, Nishanth Menon <nm@ti.com>
Cc: <linux-arm-kernel@lists.infradead.org>,
	<linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>,
	Vignesh Raghavendra <vigneshr@ti.com>,
	Dave Gerlach <d-gerlach@ti.com>
Subject: [PATCH 5/6] firmware: ti_sci: Use dt provided fw name and address to load at suspend time
Date: Thu, 21 Apr 2022 15:36:58 -0500	[thread overview]
Message-ID: <20220421203659.27853-6-d-gerlach@ti.com> (raw)
In-Reply-To: <20220421203659.27853-1-d-gerlach@ti.com>

Use request_firmware_direct to load the fs stub LPM firmware to a
provided lpm memory region. The filename for the firmware is provided in
the device tree as "ti,lpm-firmware-name"

Also, add support for "lazy loading" of this firmware during the suspend
callback for the driver so that it is loaded at first suspend. It is
possible in the future for this firmware to require reload, so add a
check to indicate that the firmware is currently loaded so it is only
loaded once at this time.

Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
---
 drivers/firmware/ti_sci.c | 69 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 68 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 1c2000b40e8f..772643cb940c 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -11,6 +11,7 @@
 #include <linux/bitmap.h>
 #include <linux/debugfs.h>
 #include <linux/export.h>
+#include <linux/firmware.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
 #include <linux/kernel.h>
@@ -90,6 +91,8 @@ struct ti_sci_desc {
  * @debug_region: Memory region where the debug message are available
  * @debug_region_size: Debug region size
  * @debug_buffer: Buffer allocated to copy debug messages.
+ * @lpm_region: Memory region where the FS Stub LPM Firmware will be stored
+ * @lpm_region_size: LPM region size
  * @handle:	Instance of TI SCI handle to send to clients.
  * @cl:		Mailbox Client
  * @chan_tx:	Transmit mailbox channel
@@ -101,6 +104,8 @@ struct ti_sci_desc {
  * @mem_ctx_hi: High word of address used for low power context memory
  * @users:	Number of users of this instance
  * @is_suspending: Flag set to indicate in suspend path.
+ * @lpm_firmware_loaded: Flag to indicate if LPM firmware has been loaded
+ * @lpm_firmware_name: Name of firmware binary to load from fw search path
  */
 struct ti_sci_info {
 	struct device *dev;
@@ -110,6 +115,8 @@ struct ti_sci_info {
 	void __iomem *debug_region;
 	char *debug_buffer;
 	size_t debug_region_size;
+	void __iomem *lpm_region;
+	size_t lpm_region_size;
 	struct ti_sci_handle handle;
 	struct mbox_client cl;
 	struct mbox_chan *chan_tx;
@@ -122,6 +129,8 @@ struct ti_sci_info {
 	/* protected by ti_sci_list_mutex */
 	int users;
 	bool is_suspending;
+	bool lpm_firmware_loaded;
+	const char *lpm_firmware_name;
 };
 
 #define cl_to_ti_sci_info(c)	container_of(c, struct ti_sci_info, cl)
@@ -3350,6 +3359,30 @@ static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode,
 	return NOTIFY_BAD;
 }
 
+static int ti_sci_load_lpm_firmware(struct device *dev, struct ti_sci_info *info)
+{
+	const struct firmware *firmware;
+	int ret = 0;
+
+	/* If no firmware name is set, do not attempt to load. */
+	if (!info->lpm_firmware_name)
+		return 0;
+
+	if (request_firmware_direct(&firmware, info->lpm_firmware_name, dev)) {
+		dev_warn(dev, "Cannot load %s\n", info->lpm_firmware_name);
+		return -ENODEV;
+	}
+
+	if (firmware->size > info->lpm_region_size)
+		return -ENOMEM;
+
+	memcpy_toio(info->lpm_region, firmware->data, firmware->size);
+
+	release_firmware(firmware);
+
+	return ret;
+}
+
 static void ti_sci_set_is_suspending(struct ti_sci_info *info, bool is_suspending)
 {
 	info->is_suspending = is_suspending;
@@ -3358,6 +3391,8 @@ static void ti_sci_set_is_suspending(struct ti_sci_info *info, bool is_suspendin
 static int ti_sci_suspend(struct device *dev)
 {
 	struct ti_sci_info *info = dev_get_drvdata(dev);
+	int ret = 0;
+
 	/*
 	 * We must switch operation to polled mode now as drivers and the genpd
 	 * layer may make late TI SCI calls to change clock and device states
@@ -3365,7 +3400,19 @@ static int ti_sci_suspend(struct device *dev)
 	 */
 	ti_sci_set_is_suspending(info, true);
 
-	return 0;
+	if (!info->lpm_firmware_loaded) {
+		ret = ti_sci_load_lpm_firmware(dev, info);
+		if (ret) {
+			dev_err(dev,
+				"Failed to load low power mode firmware, suspend is non functional (%d)\n",
+				ret);
+			ret = -ENODEV;
+		} else {
+			info->lpm_firmware_loaded = true;
+		}
+	}
+
+	return ret;
 }
 
 static int ti_sci_resume(struct device *dev)
@@ -3384,6 +3431,7 @@ static int ti_sci_init_suspend(struct platform_device *pdev, struct ti_sci_info
 	struct device *dev = &pdev->dev;
 	struct device_node *rmem_np;
 	struct reserved_mem *rmem;
+	struct resource *res;
 
 	rmem_np = of_parse_phandle(dev->of_node, "ti,ctx-memory-region", 0);
 	if (!rmem_np) {
@@ -3399,6 +3447,25 @@ static int ti_sci_init_suspend(struct platform_device *pdev, struct ti_sci_info
 	info->mem_ctx_lo = (rmem->base & 0xFFFFFFFF);
 	info->mem_ctx_hi = (rmem->base >> 32);
 
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpm");
+	if (!res) {
+		dev_warn(dev,
+			 "lpm region is required for suspend but not provided.\n");
+		return -EINVAL;
+	}
+
+	info->lpm_region = devm_ioremap_resource(dev, res);
+	if (IS_ERR(info->lpm_region))
+		return PTR_ERR(info->lpm_region);
+	info->lpm_region_size = resource_size(res);
+
+	if (of_property_read_string(dev->of_node, "ti,lpm-firmware-name",
+				    &info->lpm_firmware_name)) {
+		dev_warn(dev,
+			 "ti,lpm-firmware-name is required for suspend but not provided.\n");
+		return -EINVAL;
+	}
+
 	return 0;
 }
 
-- 
2.35.0


WARNING: multiple messages have this Message-ID (diff)
From: Dave Gerlach <d-gerlach@ti.com>
To: Rob Herring <robh+dt@kernel.org>,
	Santosh Shilimkar <ssantosh@kernel.org>,
	 Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Tero Kristo <kristo@kernel.org>, Nishanth Menon <nm@ti.com>
Cc: <linux-arm-kernel@lists.infradead.org>,
	<linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>,
	Vignesh Raghavendra <vigneshr@ti.com>,
	Dave Gerlach <d-gerlach@ti.com>
Subject: [PATCH 5/6] firmware: ti_sci: Use dt provided fw name and address to load at suspend time
Date: Thu, 21 Apr 2022 15:36:58 -0500	[thread overview]
Message-ID: <20220421203659.27853-6-d-gerlach@ti.com> (raw)
In-Reply-To: <20220421203659.27853-1-d-gerlach@ti.com>

Use request_firmware_direct to load the fs stub LPM firmware to a
provided lpm memory region. The filename for the firmware is provided in
the device tree as "ti,lpm-firmware-name"

Also, add support for "lazy loading" of this firmware during the suspend
callback for the driver so that it is loaded at first suspend. It is
possible in the future for this firmware to require reload, so add a
check to indicate that the firmware is currently loaded so it is only
loaded once at this time.

Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
---
 drivers/firmware/ti_sci.c | 69 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 68 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 1c2000b40e8f..772643cb940c 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -11,6 +11,7 @@
 #include <linux/bitmap.h>
 #include <linux/debugfs.h>
 #include <linux/export.h>
+#include <linux/firmware.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
 #include <linux/kernel.h>
@@ -90,6 +91,8 @@ struct ti_sci_desc {
  * @debug_region: Memory region where the debug message are available
  * @debug_region_size: Debug region size
  * @debug_buffer: Buffer allocated to copy debug messages.
+ * @lpm_region: Memory region where the FS Stub LPM Firmware will be stored
+ * @lpm_region_size: LPM region size
  * @handle:	Instance of TI SCI handle to send to clients.
  * @cl:		Mailbox Client
  * @chan_tx:	Transmit mailbox channel
@@ -101,6 +104,8 @@ struct ti_sci_desc {
  * @mem_ctx_hi: High word of address used for low power context memory
  * @users:	Number of users of this instance
  * @is_suspending: Flag set to indicate in suspend path.
+ * @lpm_firmware_loaded: Flag to indicate if LPM firmware has been loaded
+ * @lpm_firmware_name: Name of firmware binary to load from fw search path
  */
 struct ti_sci_info {
 	struct device *dev;
@@ -110,6 +115,8 @@ struct ti_sci_info {
 	void __iomem *debug_region;
 	char *debug_buffer;
 	size_t debug_region_size;
+	void __iomem *lpm_region;
+	size_t lpm_region_size;
 	struct ti_sci_handle handle;
 	struct mbox_client cl;
 	struct mbox_chan *chan_tx;
@@ -122,6 +129,8 @@ struct ti_sci_info {
 	/* protected by ti_sci_list_mutex */
 	int users;
 	bool is_suspending;
+	bool lpm_firmware_loaded;
+	const char *lpm_firmware_name;
 };
 
 #define cl_to_ti_sci_info(c)	container_of(c, struct ti_sci_info, cl)
@@ -3350,6 +3359,30 @@ static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode,
 	return NOTIFY_BAD;
 }
 
+static int ti_sci_load_lpm_firmware(struct device *dev, struct ti_sci_info *info)
+{
+	const struct firmware *firmware;
+	int ret = 0;
+
+	/* If no firmware name is set, do not attempt to load. */
+	if (!info->lpm_firmware_name)
+		return 0;
+
+	if (request_firmware_direct(&firmware, info->lpm_firmware_name, dev)) {
+		dev_warn(dev, "Cannot load %s\n", info->lpm_firmware_name);
+		return -ENODEV;
+	}
+
+	if (firmware->size > info->lpm_region_size)
+		return -ENOMEM;
+
+	memcpy_toio(info->lpm_region, firmware->data, firmware->size);
+
+	release_firmware(firmware);
+
+	return ret;
+}
+
 static void ti_sci_set_is_suspending(struct ti_sci_info *info, bool is_suspending)
 {
 	info->is_suspending = is_suspending;
@@ -3358,6 +3391,8 @@ static void ti_sci_set_is_suspending(struct ti_sci_info *info, bool is_suspendin
 static int ti_sci_suspend(struct device *dev)
 {
 	struct ti_sci_info *info = dev_get_drvdata(dev);
+	int ret = 0;
+
 	/*
 	 * We must switch operation to polled mode now as drivers and the genpd
 	 * layer may make late TI SCI calls to change clock and device states
@@ -3365,7 +3400,19 @@ static int ti_sci_suspend(struct device *dev)
 	 */
 	ti_sci_set_is_suspending(info, true);
 
-	return 0;
+	if (!info->lpm_firmware_loaded) {
+		ret = ti_sci_load_lpm_firmware(dev, info);
+		if (ret) {
+			dev_err(dev,
+				"Failed to load low power mode firmware, suspend is non functional (%d)\n",
+				ret);
+			ret = -ENODEV;
+		} else {
+			info->lpm_firmware_loaded = true;
+		}
+	}
+
+	return ret;
 }
 
 static int ti_sci_resume(struct device *dev)
@@ -3384,6 +3431,7 @@ static int ti_sci_init_suspend(struct platform_device *pdev, struct ti_sci_info
 	struct device *dev = &pdev->dev;
 	struct device_node *rmem_np;
 	struct reserved_mem *rmem;
+	struct resource *res;
 
 	rmem_np = of_parse_phandle(dev->of_node, "ti,ctx-memory-region", 0);
 	if (!rmem_np) {
@@ -3399,6 +3447,25 @@ static int ti_sci_init_suspend(struct platform_device *pdev, struct ti_sci_info
 	info->mem_ctx_lo = (rmem->base & 0xFFFFFFFF);
 	info->mem_ctx_hi = (rmem->base >> 32);
 
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpm");
+	if (!res) {
+		dev_warn(dev,
+			 "lpm region is required for suspend but not provided.\n");
+		return -EINVAL;
+	}
+
+	info->lpm_region = devm_ioremap_resource(dev, res);
+	if (IS_ERR(info->lpm_region))
+		return PTR_ERR(info->lpm_region);
+	info->lpm_region_size = resource_size(res);
+
+	if (of_property_read_string(dev->of_node, "ti,lpm-firmware-name",
+				    &info->lpm_firmware_name)) {
+		dev_warn(dev,
+			 "ti,lpm-firmware-name is required for suspend but not provided.\n");
+		return -EINVAL;
+	}
+
 	return 0;
 }
 
-- 
2.35.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:[~2022-04-21 20:38 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-21 20:36 [PATCH 0/6] firmware: ti_sci: Introduce system suspend support Dave Gerlach
2022-04-21 20:36 ` Dave Gerlach
2022-04-21 20:36 ` [PATCH 1/6] dt-bindings: ti,sci: Add ti,ctx-memory-region property Dave Gerlach
2022-04-21 20:36   ` Dave Gerlach
2022-04-22 19:02   ` Andrew Davis
2022-04-22 19:02     ` Andrew Davis
2022-04-22 19:02     ` Andrew Davis
2022-04-22 19:10     ` Dave Gerlach
2022-04-22 19:10       ` Dave Gerlach
2022-04-23 13:36       ` Nishanth Menon
2022-04-23 13:36         ` Nishanth Menon
2022-04-25 20:24         ` Dave Gerlach
2022-04-25 20:24           ` Dave Gerlach
2022-04-26  3:28           ` Nishanth Menon
2022-04-26  3:28             ` Nishanth Menon
2022-05-02 20:14   ` Rob Herring
2022-05-02 20:14     ` Rob Herring
2022-04-21 20:36 ` [PATCH 2/6] dt-bindings: ti,sci: Add lpm region and ti,lpm-firmware-name Dave Gerlach
2022-04-21 20:36   ` [PATCH 2/6] dt-bindings: ti, sci: Add lpm region and ti, lpm-firmware-name Dave Gerlach
2022-05-02 20:15   ` [PATCH 2/6] dt-bindings: ti,sci: Add lpm region and ti,lpm-firmware-name Rob Herring
2022-05-02 20:15     ` Rob Herring
2022-04-21 20:36 ` [PATCH 3/6] firmware: ti_sci: Introduce Power Management Ops Dave Gerlach
2022-04-21 20:36   ` Dave Gerlach
2022-04-21 20:36 ` [PATCH 4/6] firmware: ti_sci: Introduce ti,ctx-memory-region for reserved LPM memory Dave Gerlach
2022-04-21 20:36   ` [PATCH 4/6] firmware: ti_sci: Introduce ti, ctx-memory-region " Dave Gerlach
2022-04-21 20:36 ` Dave Gerlach [this message]
2022-04-21 20:36   ` [PATCH 5/6] firmware: ti_sci: Use dt provided fw name and address to load at suspend time Dave Gerlach
2022-04-21 20:36 ` [PATCH 6/6] firmware: ti_sci: Introduce prepare system suspend call Dave Gerlach
2022-04-21 20:36   ` Dave Gerlach

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=20220421203659.27853-6-d-gerlach@ti.com \
    --to=d-gerlach@ti.com \
    --cc=devicetree@vger.kernel.org \
    --cc=kristo@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nm@ti.com \
    --cc=robh+dt@kernel.org \
    --cc=ssantosh@kernel.org \
    --cc=vigneshr@ti.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.