public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 0/2] Read _SUB from ACPI to be able to identify firmware
@ 2022-07-07 15:10 Stefan Binding
  2022-07-07 15:10 ` [PATCH v6 1/2] ACPI: utils: Add api to read _SUB from ACPI Stefan Binding
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Stefan Binding @ 2022-07-07 15:10 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Mark Brown, Liam Girdwood
  Cc: linux-acpi, alsa-devel, linux-kernel, patches, Stefan Binding

CS35L41 has a DSP which is able to run firmware, as well as a tuning file.
Different systems may want to use different firmwares and tuning files, and
some firmwares/tunings may not be compatible with other systems.
To allow a system to select the correct fimware/tuning, we can read an _SUB
from the ACPI. This _SUB can then be used to uniquely identify the system
in the firmware/tuning file name.

Add a helper function which reads the _SUB, so this can be used by other
parts in the future.
Add support inside the CS35L41 ASoC driver to read this _SUB, and save it
appropriately.

Changes since v5:
- Clean up return codes
- Refactor length calculation
- Allow fallback to existing behaviour when bad ACPI is detected

Changes since v4:
- Rename function

Changes since v3:
- Fix 32 bit format string warning

Changes since v2:
- Fix error in function prototype

Changes since v1:
- Add length validation for SSID String
- Rename API
- Allocate memory inside API
- Use ACPI_HANDLE macro instead of ACPI_COMPANION
- Improve error handling

Stefan Binding (2):
  ACPI: utils: Add api to read _SUB from ACPI
  ASoC: cs35l41: Read System Name from ACPI _SUB to identify firmware

 drivers/acpi/utils.c       | 38 ++++++++++++++++++++++++++++++++++++++
 include/linux/acpi.h       |  6 ++++++
 sound/soc/codecs/cs35l41.c | 30 ++++++++++++++++++++++++++++++
 3 files changed, 74 insertions(+)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v6 1/2] ACPI: utils: Add api to read _SUB from ACPI
  2022-07-07 15:10 [PATCH v6 0/2] Read _SUB from ACPI to be able to identify firmware Stefan Binding
@ 2022-07-07 15:10 ` Stefan Binding
  2022-07-14 18:24   ` Rafael J. Wysocki
  2022-07-07 15:10 ` [PATCH v6 2/2] ASoC: cs35l41: Read System Name from ACPI _SUB to identify firmware Stefan Binding
  2022-07-15 17:22 ` [PATCH v6 0/2] Read _SUB from ACPI to be able " Mark Brown
  2 siblings, 1 reply; 5+ messages in thread
From: Stefan Binding @ 2022-07-07 15:10 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Mark Brown, Liam Girdwood
  Cc: linux-acpi, alsa-devel, linux-kernel, patches, Stefan Binding

Add a wrapper function to read the _SUB string from ACPI.

Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>
---
 drivers/acpi/utils.c | 38 ++++++++++++++++++++++++++++++++++++++
 include/linux/acpi.h |  6 ++++++
 2 files changed, 44 insertions(+)

diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index 3a9773a09e19..5a7b8065e77f 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -291,6 +291,44 @@ int acpi_get_local_address(acpi_handle handle, u32 *addr)
 }
 EXPORT_SYMBOL(acpi_get_local_address);
 
+#define ACPI_MAX_SUB_BUF_SIZE	9
+
+const char *acpi_get_subsystem_id(acpi_handle handle)
+{
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *obj;
+	acpi_status status;
+	const char *sub;
+	size_t len;
+
+	status = acpi_evaluate_object(handle, METHOD_NAME__SUB, NULL, &buffer);
+	if (ACPI_FAILURE(status)) {
+		acpi_handle_debug(handle, "Reading ACPI _SUB failed: %#x\n", status);
+		return ERR_PTR(-ENODATA);
+	}
+
+	obj = buffer.pointer;
+	if (obj->type == ACPI_TYPE_STRING) {
+		len = strlen(obj->string.pointer);
+		if (len < ACPI_MAX_SUB_BUF_SIZE && len > 0) {
+			sub = kstrdup(obj->string.pointer, GFP_KERNEL);
+			if (!sub)
+				sub = ERR_PTR(-ENOMEM);
+		} else {
+			acpi_handle_err(handle, "ACPI _SUB Length %zu is Invalid\n", len);
+			sub = ERR_PTR(-ENODATA);
+		}
+	} else {
+		acpi_handle_warn(handle, "Warning ACPI _SUB did not return a string\n");
+		sub = ERR_PTR(-ENODATA);
+	}
+
+	acpi_os_free(buffer.pointer);
+
+	return sub;
+}
+EXPORT_SYMBOL_GPL(acpi_get_subsystem_id);
+
 acpi_status
 acpi_evaluate_reference(acpi_handle handle,
 			acpi_string pathname,
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 2a0e95336094..447898685e09 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -762,6 +762,7 @@ static inline u64 acpi_arch_get_root_pointer(void)
 #endif
 
 int acpi_get_local_address(acpi_handle handle, u32 *addr);
+const char *acpi_get_subsystem_id(acpi_handle handle);
 
 #else	/* !CONFIG_ACPI */
 
@@ -1023,6 +1024,11 @@ static inline int acpi_get_local_address(acpi_handle handle, u32 *addr)
 	return -ENODEV;
 }
 
+static inline const char *acpi_get_subsystem_id(acpi_handle handle)
+{
+	return ERR_PTR(-ENODEV);
+}
+
 static inline int acpi_register_wakeup_handler(int wake_irq,
 	bool (*wakeup)(void *context), void *context)
 {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v6 2/2] ASoC: cs35l41: Read System Name from ACPI _SUB to identify firmware
  2022-07-07 15:10 [PATCH v6 0/2] Read _SUB from ACPI to be able to identify firmware Stefan Binding
  2022-07-07 15:10 ` [PATCH v6 1/2] ACPI: utils: Add api to read _SUB from ACPI Stefan Binding
@ 2022-07-07 15:10 ` Stefan Binding
  2022-07-15 17:22 ` [PATCH v6 0/2] Read _SUB from ACPI to be able " Mark Brown
  2 siblings, 0 replies; 5+ messages in thread
From: Stefan Binding @ 2022-07-07 15:10 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Mark Brown, Liam Girdwood
  Cc: linux-acpi, alsa-devel, linux-kernel, patches, Stefan Binding

When loading firmware, wm_adsp uses a number of parameters to
determine the path of the firmware and tuning files to load.
One of these parameters is system_name.
Add support in cs35l41 to read this system name from the ACPI
_SUB ID in order to uniquely identify the firmware and tuning
mapped to a particular system.

Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>
---
 sound/soc/codecs/cs35l41.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c
index 8766e19d85f1..c223d83e02cf 100644
--- a/sound/soc/codecs/cs35l41.c
+++ b/sound/soc/codecs/cs35l41.c
@@ -6,6 +6,7 @@
 //
 // Author: David Rhodes <david.rhodes@cirrus.com>
 
+#include <linux/acpi.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/init.h>
@@ -1142,6 +1143,30 @@ static int cs35l41_dsp_init(struct cs35l41_private *cs35l41)
 	return ret;
 }
 
+static int cs35l41_acpi_get_name(struct cs35l41_private *cs35l41)
+{
+	acpi_handle handle = ACPI_HANDLE(cs35l41->dev);
+	const char *sub;
+
+	/* If there is no ACPI_HANDLE, there is no ACPI for this system, return 0 */
+	if (!handle)
+		return 0;
+
+	sub = acpi_get_subsystem_id(handle);
+	if (IS_ERR(sub)) {
+		/* If bad ACPI, return 0 and fallback to legacy firmware path, otherwise fail */
+		if (PTR_ERR(sub) == -ENODATA)
+			return 0;
+		else
+			return PTR_ERR(sub);
+	}
+
+	cs35l41->dsp.system_name = sub;
+	dev_dbg(cs35l41->dev, "Subsystem ID: %s\n", cs35l41->dsp.system_name);
+
+	return 0;
+}
+
 int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *hw_cfg)
 {
 	u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match;
@@ -1270,6 +1295,10 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *
 		goto err;
 	}
 
+	ret = cs35l41_acpi_get_name(cs35l41);
+	if (ret < 0)
+		goto err;
+
 	ret = cs35l41_dsp_init(cs35l41);
 	if (ret < 0)
 		goto err;
@@ -1316,6 +1345,7 @@ void cs35l41_remove(struct cs35l41_private *cs35l41)
 	pm_runtime_disable(cs35l41->dev);
 
 	regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF);
+	kfree(cs35l41->dsp.system_name);
 	wm_adsp2_remove(&cs35l41->dsp);
 	cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type);
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v6 1/2] ACPI: utils: Add api to read _SUB from ACPI
  2022-07-07 15:10 ` [PATCH v6 1/2] ACPI: utils: Add api to read _SUB from ACPI Stefan Binding
@ 2022-07-14 18:24   ` Rafael J. Wysocki
  0 siblings, 0 replies; 5+ messages in thread
From: Rafael J. Wysocki @ 2022-07-14 18:24 UTC (permalink / raw)
  To: Stefan Binding
  Cc: Rafael J . Wysocki, Len Brown, Mark Brown, Liam Girdwood,
	ACPI Devel Maling List,
	moderated list:SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEM...,
	Linux Kernel Mailing List, patches

On Thu, Jul 7, 2022 at 5:11 PM Stefan Binding
<sbinding@opensource.cirrus.com> wrote:
>
> Add a wrapper function to read the _SUB string from ACPI.
>
> Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>

In case you want to push this through ASoC

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Otherwise, I need a maintainer's ACK to apply the second patch.

> ---
>  drivers/acpi/utils.c | 38 ++++++++++++++++++++++++++++++++++++++
>  include/linux/acpi.h |  6 ++++++
>  2 files changed, 44 insertions(+)
>
> diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
> index 3a9773a09e19..5a7b8065e77f 100644
> --- a/drivers/acpi/utils.c
> +++ b/drivers/acpi/utils.c
> @@ -291,6 +291,44 @@ int acpi_get_local_address(acpi_handle handle, u32 *addr)
>  }
>  EXPORT_SYMBOL(acpi_get_local_address);
>
> +#define ACPI_MAX_SUB_BUF_SIZE  9
> +
> +const char *acpi_get_subsystem_id(acpi_handle handle)
> +{
> +       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
> +       union acpi_object *obj;
> +       acpi_status status;
> +       const char *sub;
> +       size_t len;
> +
> +       status = acpi_evaluate_object(handle, METHOD_NAME__SUB, NULL, &buffer);
> +       if (ACPI_FAILURE(status)) {
> +               acpi_handle_debug(handle, "Reading ACPI _SUB failed: %#x\n", status);
> +               return ERR_PTR(-ENODATA);
> +       }
> +
> +       obj = buffer.pointer;
> +       if (obj->type == ACPI_TYPE_STRING) {
> +               len = strlen(obj->string.pointer);
> +               if (len < ACPI_MAX_SUB_BUF_SIZE && len > 0) {
> +                       sub = kstrdup(obj->string.pointer, GFP_KERNEL);
> +                       if (!sub)
> +                               sub = ERR_PTR(-ENOMEM);
> +               } else {
> +                       acpi_handle_err(handle, "ACPI _SUB Length %zu is Invalid\n", len);
> +                       sub = ERR_PTR(-ENODATA);
> +               }
> +       } else {
> +               acpi_handle_warn(handle, "Warning ACPI _SUB did not return a string\n");
> +               sub = ERR_PTR(-ENODATA);
> +       }
> +
> +       acpi_os_free(buffer.pointer);
> +
> +       return sub;
> +}
> +EXPORT_SYMBOL_GPL(acpi_get_subsystem_id);
> +
>  acpi_status
>  acpi_evaluate_reference(acpi_handle handle,
>                         acpi_string pathname,
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 2a0e95336094..447898685e09 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -762,6 +762,7 @@ static inline u64 acpi_arch_get_root_pointer(void)
>  #endif
>
>  int acpi_get_local_address(acpi_handle handle, u32 *addr);
> +const char *acpi_get_subsystem_id(acpi_handle handle);
>
>  #else  /* !CONFIG_ACPI */
>
> @@ -1023,6 +1024,11 @@ static inline int acpi_get_local_address(acpi_handle handle, u32 *addr)
>         return -ENODEV;
>  }
>
> +static inline const char *acpi_get_subsystem_id(acpi_handle handle)
> +{
> +       return ERR_PTR(-ENODEV);
> +}
> +
>  static inline int acpi_register_wakeup_handler(int wake_irq,
>         bool (*wakeup)(void *context), void *context)
>  {
> --
> 2.25.1
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v6 0/2] Read _SUB from ACPI to be able to identify firmware
  2022-07-07 15:10 [PATCH v6 0/2] Read _SUB from ACPI to be able to identify firmware Stefan Binding
  2022-07-07 15:10 ` [PATCH v6 1/2] ACPI: utils: Add api to read _SUB from ACPI Stefan Binding
  2022-07-07 15:10 ` [PATCH v6 2/2] ASoC: cs35l41: Read System Name from ACPI _SUB to identify firmware Stefan Binding
@ 2022-07-15 17:22 ` Mark Brown
  2 siblings, 0 replies; 5+ messages in thread
From: Mark Brown @ 2022-07-15 17:22 UTC (permalink / raw)
  To: sbinding, lenb, lgirdwood, rafael
  Cc: linux-acpi, patches, alsa-devel, linux-kernel

On Thu, 7 Jul 2022 16:10:35 +0100, Stefan Binding wrote:
> CS35L41 has a DSP which is able to run firmware, as well as a tuning file.
> Different systems may want to use different firmwares and tuning files, and
> some firmwares/tunings may not be compatible with other systems.
> To allow a system to select the correct fimware/tuning, we can read an _SUB
> from the ACPI. This _SUB can then be used to uniquely identify the system
> in the firmware/tuning file name.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/2] ACPI: utils: Add api to read _SUB from ACPI
      commit: 93064e15c8a3a8394319a11b8037666e4b7d653d
[2/2] ASoC: cs35l41: Read System Name from ACPI _SUB to identify firmware
      commit: c1ad138822a1be95a7a7b122521c2415583a0c26

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-07-15 17:22 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-07-07 15:10 [PATCH v6 0/2] Read _SUB from ACPI to be able to identify firmware Stefan Binding
2022-07-07 15:10 ` [PATCH v6 1/2] ACPI: utils: Add api to read _SUB from ACPI Stefan Binding
2022-07-14 18:24   ` Rafael J. Wysocki
2022-07-07 15:10 ` [PATCH v6 2/2] ASoC: cs35l41: Read System Name from ACPI _SUB to identify firmware Stefan Binding
2022-07-15 17:22 ` [PATCH v6 0/2] Read _SUB from ACPI to be able " Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox