Merge pull request #58 from TsaiGaggery/add-linux-ptl-audio
Add linux-ptl-audio kernel package for Panther Lake SDCA audio
This commit is contained in:
+160
@@ -0,0 +1,160 @@
|
||||
From 917d5770485e4ccd73f1123e2032a220c021bb56 Mon Sep 17 00:00:00 2001
|
||||
From: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
|
||||
Date: Wed, 3 Dec 2025 17:12:40 +0100
|
||||
Subject: [PATCH 01/17] ASoC: SDCA: functions: Fix confusing cleanup.h syntax
|
||||
|
||||
Initializing automatic __free variables to NULL without need (e.g.
|
||||
branches with different allocations), followed by actual allocation is
|
||||
in contrary to explicit coding rules guiding cleanup.h:
|
||||
|
||||
"Given that the "__free(...) = NULL" pattern for variables defined at
|
||||
the top of the function poses this potential interdependency problem the
|
||||
recommendation is to always define and assign variables in one statement
|
||||
and not group variable definitions at the top of the function when
|
||||
__free() is used."
|
||||
|
||||
Code does not have a bug, but is less readable and uses discouraged
|
||||
coding practice, so fix that by moving declaration to the place of
|
||||
assignment.
|
||||
|
||||
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
|
||||
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Link: https://patch.msgid.link/20251203-asoc-wrong-cleanup-h-continued-v1-3-5142be4874fb@oss.qualcomm.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sdca/sdca_functions.c | 28 ++++++++++++++--------------
|
||||
1 file changed, 14 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c
|
||||
index e86004c9dea0..b26884fc2a98 100644
|
||||
--- a/sound/soc/sdca/sdca_functions.c
|
||||
+++ b/sound/soc/sdca/sdca_functions.c
|
||||
@@ -1180,7 +1180,6 @@ static int find_sdca_entity_pde(struct device *dev,
|
||||
{
|
||||
static const int mult_delay = 3;
|
||||
struct sdca_entity_pde *power = &entity->pde;
|
||||
- u32 *delay_list __free(kfree) = NULL;
|
||||
struct sdca_pde_delay *delays;
|
||||
int num_delays;
|
||||
int i, j;
|
||||
@@ -1201,7 +1200,8 @@ static int find_sdca_entity_pde(struct device *dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- delay_list = kcalloc(num_delays, sizeof(*delay_list), GFP_KERNEL);
|
||||
+ u32 *delay_list __free(kfree) = kcalloc(num_delays, sizeof(*delay_list),
|
||||
+ GFP_KERNEL);
|
||||
if (!delay_list)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1246,7 +1246,6 @@ static int find_sdca_entity_ge(struct device *dev,
|
||||
struct sdca_entity *entity)
|
||||
{
|
||||
struct sdca_entity_ge *group = &entity->ge;
|
||||
- u8 *affected_list __free(kfree) = NULL;
|
||||
u8 *affected_iter;
|
||||
int num_affected;
|
||||
int i, j;
|
||||
@@ -1265,7 +1264,8 @@ static int find_sdca_entity_ge(struct device *dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- affected_list = kcalloc(num_affected, sizeof(*affected_list), GFP_KERNEL);
|
||||
+ u8 *affected_list __free(kfree) = kcalloc(num_affected, sizeof(*affected_list),
|
||||
+ GFP_KERNEL);
|
||||
if (!affected_list)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1491,7 +1491,6 @@ static int find_sdca_entities(struct device *dev, struct sdw_slave *sdw,
|
||||
struct fwnode_handle *function_node,
|
||||
struct sdca_function_data *function)
|
||||
{
|
||||
- u32 *entity_list __free(kfree) = NULL;
|
||||
struct sdca_entity *entities;
|
||||
int num_entities;
|
||||
int i, ret;
|
||||
@@ -1513,7 +1512,8 @@ static int find_sdca_entities(struct device *dev, struct sdw_slave *sdw,
|
||||
if (!entities)
|
||||
return -ENOMEM;
|
||||
|
||||
- entity_list = kcalloc(num_entities, sizeof(*entity_list), GFP_KERNEL);
|
||||
+ u32 *entity_list __free(kfree) = kcalloc(num_entities, sizeof(*entity_list),
|
||||
+ GFP_KERNEL);
|
||||
if (!entity_list)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1638,7 +1638,6 @@ static int find_sdca_entity_connection_pde(struct device *dev,
|
||||
struct sdca_entity *entity)
|
||||
{
|
||||
struct sdca_entity_pde *power = &entity->pde;
|
||||
- u32 *managed_list __free(kfree) = NULL;
|
||||
struct sdca_entity **managed;
|
||||
int num_managed;
|
||||
int i;
|
||||
@@ -1660,7 +1659,8 @@ static int find_sdca_entity_connection_pde(struct device *dev,
|
||||
if (!managed)
|
||||
return -ENOMEM;
|
||||
|
||||
- managed_list = kcalloc(num_managed, sizeof(*managed_list), GFP_KERNEL);
|
||||
+ u32 *managed_list __free(kfree) = kcalloc(num_managed, sizeof(*managed_list),
|
||||
+ GFP_KERNEL);
|
||||
if (!managed_list)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1957,7 +1957,6 @@ static int find_sdca_clusters(struct device *dev,
|
||||
struct fwnode_handle *function_node,
|
||||
struct sdca_function_data *function)
|
||||
{
|
||||
- u32 *cluster_list __free(kfree) = NULL;
|
||||
struct sdca_cluster *clusters;
|
||||
int num_clusters;
|
||||
int i, ret;
|
||||
@@ -1978,7 +1977,8 @@ static int find_sdca_clusters(struct device *dev,
|
||||
if (!clusters)
|
||||
return -ENOMEM;
|
||||
|
||||
- cluster_list = kcalloc(num_clusters, sizeof(*cluster_list), GFP_KERNEL);
|
||||
+ u32 *cluster_list __free(kfree) = kcalloc(num_clusters, sizeof(*cluster_list),
|
||||
+ GFP_KERNEL);
|
||||
if (!cluster_list)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -2022,7 +2022,6 @@ static int find_sdca_filesets(struct device *dev, struct sdw_slave *sdw,
|
||||
{
|
||||
static const int mult_fileset = 3;
|
||||
char fileset_name[SDCA_PROPERTY_LENGTH];
|
||||
- u32 *filesets_list __free(kfree) = NULL;
|
||||
struct sdca_fdl_set *sets;
|
||||
int num_sets;
|
||||
int i, j;
|
||||
@@ -2037,7 +2036,8 @@ static int find_sdca_filesets(struct device *dev, struct sdw_slave *sdw,
|
||||
return num_sets;
|
||||
}
|
||||
|
||||
- filesets_list = kcalloc(num_sets, sizeof(u32), GFP_KERNEL);
|
||||
+ u32 *filesets_list __free(kfree) = kcalloc(num_sets, sizeof(u32),
|
||||
+ GFP_KERNEL);
|
||||
if (!filesets_list)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -2049,7 +2049,6 @@ static int find_sdca_filesets(struct device *dev, struct sdw_slave *sdw,
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < num_sets; i++) {
|
||||
- u32 *fileset_entries __free(kfree) = NULL;
|
||||
struct sdca_fdl_set *set = &sets[i];
|
||||
struct sdca_fdl_file *files;
|
||||
int num_files, num_entries;
|
||||
@@ -2075,7 +2074,8 @@ static int find_sdca_filesets(struct device *dev, struct sdw_slave *sdw,
|
||||
if (!files)
|
||||
return -ENOMEM;
|
||||
|
||||
- fileset_entries = kcalloc(num_entries, sizeof(u32), GFP_KERNEL);
|
||||
+ u32 *fileset_entries __free(kfree) = kcalloc(num_entries, sizeof(u32),
|
||||
+ GFP_KERNEL);
|
||||
if (!fileset_entries)
|
||||
return -ENOMEM;
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
From 09b0835977b5fa955e35147513ed770e6bf0229d Mon Sep 17 00:00:00 2001
|
||||
From: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Date: Mon, 15 Dec 2025 15:36:49 +0000
|
||||
Subject: [PATCH 02/17] ASoC: SDCA: Add ASoC jack hookup in class driver
|
||||
|
||||
Add the necessary calls to the class driver to connect the ASoC jack
|
||||
from the machine driver.
|
||||
|
||||
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Link: https://patch.msgid.link/20251215153650.3913117-4-ckeepax@opensource.cirrus.com
|
||||
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sdca/sdca_class_function.c | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
diff --git a/sound/soc/sdca/sdca_class_function.c b/sound/soc/sdca/sdca_class_function.c
|
||||
index 0028482a1e75..416948cfb5cb 100644
|
||||
--- a/sound/soc/sdca/sdca_class_function.c
|
||||
+++ b/sound/soc/sdca/sdca_class_function.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <sound/sdca_fdl.h>
|
||||
#include <sound/sdca_function.h>
|
||||
#include <sound/sdca_interrupts.h>
|
||||
+#include <sound/sdca_jack.h>
|
||||
#include <sound/sdca_regmap.h>
|
||||
#include <sound/sdw.h>
|
||||
#include <sound/soc-component.h>
|
||||
@@ -195,6 +196,15 @@ static int class_function_component_probe(struct snd_soc_component *component)
|
||||
return sdca_irq_populate(drv->function, component, core->irq_info);
|
||||
}
|
||||
|
||||
+static int class_function_set_jack(struct snd_soc_component *component,
|
||||
+ struct snd_soc_jack *jack, void *d)
|
||||
+{
|
||||
+ struct class_function_drv *drv = snd_soc_component_get_drvdata(component);
|
||||
+ struct sdca_class_drv *core = drv->core;
|
||||
+
|
||||
+ return sdca_jack_set_jack(core->irq_info, jack);
|
||||
+}
|
||||
+
|
||||
static const struct snd_soc_component_driver class_function_component_drv = {
|
||||
.probe = class_function_component_probe,
|
||||
.endianness = 1,
|
||||
@@ -351,6 +361,9 @@ static int class_function_probe(struct auxiliary_device *auxdev,
|
||||
return dev_err_probe(dev, PTR_ERR(drv->regmap),
|
||||
"failed to create regmap");
|
||||
|
||||
+ if (desc->type == SDCA_FUNCTION_TYPE_UAJ)
|
||||
+ cmp_drv->set_jack = class_function_set_jack;
|
||||
+
|
||||
ret = sdca_asoc_populate_component(dev, drv->function, cmp_drv,
|
||||
&dais, &num_dais,
|
||||
&class_function_sdw_ops);
|
||||
--
|
||||
2.43.0
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
From 04d5b8676de028c8dded6d174620f69656b6ddd2 Mon Sep 17 00:00:00 2001
|
||||
From: Marco Crivellari <marco.crivellari@suse.com>
|
||||
Date: Tue, 30 Dec 2025 15:34:29 +0100
|
||||
Subject: [PATCH 03/17] ASoC: SDCA: Replace use of system_wq with system_dfl_wq
|
||||
|
||||
This patch continues the effort to refactor workqueue APIs, which has begun
|
||||
with the changes introducing new workqueues and a new alloc_workqueue flag:
|
||||
|
||||
commit 128ea9f6ccfb ("workqueue: Add system_percpu_wq and system_dfl_wq")
|
||||
commit 930c2ea566af ("workqueue: Add new WQ_PERCPU flag")
|
||||
|
||||
The point of the refactoring is to eventually alter the default behavior of
|
||||
workqueues to become unbound by default so that their workload placement is
|
||||
optimized by the scheduler.
|
||||
|
||||
Before that to happen after a careful review and conversion of each individual
|
||||
case, workqueue users must be converted to the better named new workqueues with
|
||||
no intended behaviour changes:
|
||||
|
||||
system_wq -> system_percpu_wq
|
||||
system_unbound_wq -> system_dfl_wq
|
||||
|
||||
This specific workload has no benefits being per-cpu, so system_wq
|
||||
has been replaced with system_dfl_wq (the unbound workqueue).
|
||||
|
||||
This way the old obsolete workqueues (system_wq, system_unbound_wq) can be
|
||||
removed in the future.
|
||||
|
||||
Suggested-by: Tejun Heo <tj@kernel.org>
|
||||
Signed-off-by: Marco Crivellari <marco.crivellari@suse.com>
|
||||
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Link: https://patch.msgid.link/20251230143429.179643-1-marco.crivellari@suse.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sdca/sdca_ump.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sound/soc/sdca/sdca_ump.c b/sound/soc/sdca/sdca_ump.c
|
||||
index 8aba3ff16872..a86bb28c6d0a 100644
|
||||
--- a/sound/soc/sdca/sdca_ump.c
|
||||
+++ b/sound/soc/sdca/sdca_ump.c
|
||||
@@ -257,6 +257,6 @@ void sdca_ump_schedule_timeout(struct delayed_work *work, unsigned int timeout_u
|
||||
if (!timeout_us)
|
||||
return;
|
||||
|
||||
- queue_delayed_work(system_wq, work, usecs_to_jiffies(timeout_us));
|
||||
+ queue_delayed_work(system_dfl_wq, work, usecs_to_jiffies(timeout_us));
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(sdca_ump_schedule_timeout, "SND_SOC_SDCA");
|
||||
--
|
||||
2.43.0
|
||||
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
From 4b55c8cdab4fbbf35fdb22e711a473c7c19b8c39 Mon Sep 17 00:00:00 2001
|
||||
From: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Date: Fri, 9 Jan 2026 14:52:03 +0000
|
||||
Subject: [PATCH 04/17] ASoC: SDCA: Add SDCA IRQ enable/disable helpers
|
||||
|
||||
Add helpers to enable and disable the SDCA IRQs by Function. These are
|
||||
useful to sequence the powering down and up around system suspend.
|
||||
|
||||
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
|
||||
Link: https://patch.msgid.link/20260109145206.3456151-2-ckeepax@opensource.cirrus.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
include/sound/sdca_interrupts.h | 7 +++
|
||||
sound/soc/sdca/sdca_interrupts.c | 76 ++++++++++++++++++++++++++++++++
|
||||
2 files changed, 83 insertions(+)
|
||||
|
||||
diff --git a/include/sound/sdca_interrupts.h b/include/sound/sdca_interrupts.h
|
||||
index 8f13417d129a..9bcb5d8fd592 100644
|
||||
--- a/include/sound/sdca_interrupts.h
|
||||
+++ b/include/sound/sdca_interrupts.h
|
||||
@@ -84,4 +84,11 @@ int sdca_irq_populate(struct sdca_function_data *function,
|
||||
struct sdca_interrupt_info *sdca_irq_allocate(struct device *dev,
|
||||
struct regmap *regmap, int irq);
|
||||
|
||||
+void sdca_irq_enable_early(struct sdca_function_data *function,
|
||||
+ struct sdca_interrupt_info *info);
|
||||
+void sdca_irq_enable(struct sdca_function_data *function,
|
||||
+ struct sdca_interrupt_info *info);
|
||||
+void sdca_irq_disable(struct sdca_function_data *function,
|
||||
+ struct sdca_interrupt_info *info);
|
||||
+
|
||||
#endif
|
||||
diff --git a/sound/soc/sdca/sdca_interrupts.c b/sound/soc/sdca/sdca_interrupts.c
|
||||
index ff3a7e405fdc..afef7bbf613c 100644
|
||||
--- a/sound/soc/sdca/sdca_interrupts.c
|
||||
+++ b/sound/soc/sdca/sdca_interrupts.c
|
||||
@@ -541,3 +541,79 @@ struct sdca_interrupt_info *sdca_irq_allocate(struct device *sdev,
|
||||
return info;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(sdca_irq_allocate, "SND_SOC_SDCA");
|
||||
+
|
||||
+static void irq_enable_flags(struct sdca_function_data *function,
|
||||
+ struct sdca_interrupt_info *info, bool early)
|
||||
+{
|
||||
+ struct sdca_interrupt *interrupt;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < SDCA_MAX_INTERRUPTS; i++) {
|
||||
+ interrupt = &info->irqs[i];
|
||||
+
|
||||
+ if (!interrupt || interrupt->function != function)
|
||||
+ continue;
|
||||
+
|
||||
+ switch (SDCA_CTL_TYPE(interrupt->entity->type,
|
||||
+ interrupt->control->sel)) {
|
||||
+ case SDCA_CTL_TYPE_S(XU, FDL_CURRENTOWNER):
|
||||
+ if (early)
|
||||
+ enable_irq(interrupt->irq);
|
||||
+ break;
|
||||
+ default:
|
||||
+ if (!early)
|
||||
+ enable_irq(interrupt->irq);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * sdca_irq_enable_early - Re-enable early SDCA IRQs for a given function
|
||||
+ * @function: Pointer to the SDCA Function.
|
||||
+ * @info: Pointer to the SDCA interrupt info for this device.
|
||||
+ *
|
||||
+ * The early version of the IRQ enable allows enabling IRQs which may be
|
||||
+ * necessary to bootstrap functionality for other IRQs, such as the FDL
|
||||
+ * process.
|
||||
+ */
|
||||
+void sdca_irq_enable_early(struct sdca_function_data *function,
|
||||
+ struct sdca_interrupt_info *info)
|
||||
+{
|
||||
+ irq_enable_flags(function, info, true);
|
||||
+}
|
||||
+EXPORT_SYMBOL_NS_GPL(sdca_irq_enable_early, "SND_SOC_SDCA");
|
||||
+
|
||||
+/**
|
||||
+ * sdca_irq_enable - Re-enable SDCA IRQs for a given function
|
||||
+ * @function: Pointer to the SDCA Function.
|
||||
+ * @info: Pointer to the SDCA interrupt info for this device.
|
||||
+ */
|
||||
+void sdca_irq_enable(struct sdca_function_data *function,
|
||||
+ struct sdca_interrupt_info *info)
|
||||
+{
|
||||
+ irq_enable_flags(function, info, false);
|
||||
+}
|
||||
+EXPORT_SYMBOL_NS_GPL(sdca_irq_enable, "SND_SOC_SDCA");
|
||||
+
|
||||
+/**
|
||||
+ * sdca_irq_disable - Disable SDCA IRQs for a given function
|
||||
+ * @function: Pointer to the SDCA Function.
|
||||
+ * @info: Pointer to the SDCA interrupt info for this device.
|
||||
+ */
|
||||
+void sdca_irq_disable(struct sdca_function_data *function,
|
||||
+ struct sdca_interrupt_info *info)
|
||||
+{
|
||||
+ struct sdca_interrupt *interrupt;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < SDCA_MAX_INTERRUPTS; i++) {
|
||||
+ interrupt = &info->irqs[i];
|
||||
+
|
||||
+ if (!interrupt || interrupt->function != function)
|
||||
+ continue;
|
||||
+
|
||||
+ disable_irq(interrupt->irq);
|
||||
+ }
|
||||
+}
|
||||
+EXPORT_SYMBOL_NS_GPL(sdca_irq_disable, "SND_SOC_SDCA");
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
From 10bf875e22235547b28f5143566d154c665206cc Mon Sep 17 00:00:00 2001
|
||||
From: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Date: Fri, 9 Jan 2026 14:52:04 +0000
|
||||
Subject: [PATCH 05/17] ASoC: SDCA: Add basic system suspend support
|
||||
|
||||
Add basic system suspend support. Disable the IRQs and force runtime
|
||||
suspend, during system suspend, because the device will likely fully
|
||||
power down during suspend.
|
||||
|
||||
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
|
||||
Link: https://patch.msgid.link/20260109145206.3456151-3-ckeepax@opensource.cirrus.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sdca/sdca_class.c | 33 ++++++++++++++++++
|
||||
sound/soc/sdca/sdca_class_function.c | 51 ++++++++++++++++++++++++++++
|
||||
2 files changed, 84 insertions(+)
|
||||
|
||||
diff --git a/sound/soc/sdca/sdca_class.c b/sound/soc/sdca/sdca_class.c
|
||||
index 349d32933ba8..6d19a183683e 100644
|
||||
--- a/sound/soc/sdca/sdca_class.c
|
||||
+++ b/sound/soc/sdca/sdca_class.c
|
||||
@@ -238,6 +238,38 @@ static int class_sdw_probe(struct sdw_slave *sdw, const struct sdw_device_id *id
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int class_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct sdca_class_drv *drv = dev_get_drvdata(dev);
|
||||
+ int ret;
|
||||
+
|
||||
+ disable_irq(drv->sdw->irq);
|
||||
+
|
||||
+ ret = pm_runtime_force_suspend(dev);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to force suspend: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int class_resume(struct device *dev)
|
||||
+{
|
||||
+ struct sdca_class_drv *drv = dev_get_drvdata(dev);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = pm_runtime_force_resume(dev);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to force resume: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ enable_irq(drv->sdw->irq);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int class_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct sdca_class_drv *drv = dev_get_drvdata(dev);
|
||||
@@ -278,6 +310,7 @@ static int class_runtime_resume(struct device *dev)
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops class_pm_ops = {
|
||||
+ SYSTEM_SLEEP_PM_OPS(class_suspend, class_resume)
|
||||
RUNTIME_PM_OPS(class_runtime_suspend, class_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
diff --git a/sound/soc/sdca/sdca_class_function.c b/sound/soc/sdca/sdca_class_function.c
|
||||
index 416948cfb5cb..7d0a6c0adbfb 100644
|
||||
--- a/sound/soc/sdca/sdca_class_function.c
|
||||
+++ b/sound/soc/sdca/sdca_class_function.c
|
||||
@@ -33,6 +33,7 @@ struct class_function_drv {
|
||||
struct sdca_class_drv *core;
|
||||
|
||||
struct sdca_function_data *function;
|
||||
+ bool suspended;
|
||||
};
|
||||
|
||||
static void class_function_regmap_lock(void *data)
|
||||
@@ -417,6 +418,14 @@ static int class_function_runtime_resume(struct device *dev)
|
||||
regcache_mark_dirty(drv->regmap);
|
||||
regcache_cache_only(drv->regmap, false);
|
||||
|
||||
+ if (drv->suspended) {
|
||||
+ sdca_irq_enable_early(drv->function, drv->core->irq_info);
|
||||
+ /* TODO: Add FDL process between early and late IRQs */
|
||||
+ sdca_irq_enable(drv->function, drv->core->irq_info);
|
||||
+
|
||||
+ drv->suspended = false;
|
||||
+ }
|
||||
+
|
||||
ret = regcache_sync(drv->regmap);
|
||||
if (ret) {
|
||||
dev_err(drv->dev, "failed to restore register cache: %d\n", ret);
|
||||
@@ -431,7 +440,49 @@ static int class_function_runtime_resume(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int class_function_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
|
||||
+ struct class_function_drv *drv = auxiliary_get_drvdata(auxdev);
|
||||
+ int ret;
|
||||
+
|
||||
+ drv->suspended = true;
|
||||
+
|
||||
+ /* Ensure runtime resume runs on resume */
|
||||
+ ret = pm_runtime_resume_and_get(dev);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to resume for suspend: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ sdca_irq_disable(drv->function, drv->core->irq_info);
|
||||
+
|
||||
+ ret = pm_runtime_force_suspend(dev);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to force suspend: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ pm_runtime_put_noidle(dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int class_function_resume(struct device *dev)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = pm_runtime_force_resume(dev);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to force resume: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static const struct dev_pm_ops class_function_pm_ops = {
|
||||
+ SYSTEM_SLEEP_PM_OPS(class_function_suspend, class_function_resume)
|
||||
RUNTIME_PM_OPS(class_function_runtime_suspend,
|
||||
class_function_runtime_resume, NULL)
|
||||
};
|
||||
--
|
||||
2.43.0
|
||||
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
From 914bb3e2ba56354fd66cbb130eb536513ae3e1ca Mon Sep 17 00:00:00 2001
|
||||
From: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Date: Fri, 9 Jan 2026 14:52:06 +0000
|
||||
Subject: [PATCH 07/17] ASoC: SDCA: Add lock to serialise the Function
|
||||
initialisation
|
||||
|
||||
To avoid issues on some devices serialise the boot of each SDCA Function
|
||||
from the others.
|
||||
|
||||
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
|
||||
Link: https://patch.msgid.link/20260109145206.3456151-5-ckeepax@opensource.cirrus.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sdca/sdca_class.c | 1 +
|
||||
sound/soc/sdca/sdca_class.h | 2 ++
|
||||
sound/soc/sdca/sdca_class_function.c | 5 +++++
|
||||
3 files changed, 8 insertions(+)
|
||||
|
||||
diff --git a/sound/soc/sdca/sdca_class.c b/sound/soc/sdca/sdca_class.c
|
||||
index 6d19a183683e..918b638acb57 100644
|
||||
--- a/sound/soc/sdca/sdca_class.c
|
||||
+++ b/sound/soc/sdca/sdca_class.c
|
||||
@@ -205,6 +205,7 @@ static int class_sdw_probe(struct sdw_slave *sdw, const struct sdw_device_id *id
|
||||
drv->dev = dev;
|
||||
drv->sdw = sdw;
|
||||
mutex_init(&drv->regmap_lock);
|
||||
+ mutex_init(&drv->init_lock);
|
||||
|
||||
dev_set_drvdata(drv->dev, drv);
|
||||
|
||||
diff --git a/sound/soc/sdca/sdca_class.h b/sound/soc/sdca/sdca_class.h
|
||||
index bb4c9dd12429..6f24ea2bbd38 100644
|
||||
--- a/sound/soc/sdca/sdca_class.h
|
||||
+++ b/sound/soc/sdca/sdca_class.h
|
||||
@@ -28,6 +28,8 @@ struct sdca_class_drv {
|
||||
struct sdca_interrupt_info *irq_info;
|
||||
|
||||
struct mutex regmap_lock;
|
||||
+ /* Serialise function initialisations */
|
||||
+ struct mutex init_lock;
|
||||
struct work_struct boot_work;
|
||||
struct completion device_attach;
|
||||
|
||||
diff --git a/sound/soc/sdca/sdca_class_function.c b/sound/soc/sdca/sdca_class_function.c
|
||||
index bbf486d9a3d0..0afa41c1ee93 100644
|
||||
--- a/sound/soc/sdca/sdca_class_function.c
|
||||
+++ b/sound/soc/sdca/sdca_class_function.c
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/auxiliary_bus.h>
|
||||
+#include <linux/cleanup.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm.h>
|
||||
@@ -244,6 +245,8 @@ static int class_function_boot(struct class_function_drv *drv)
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
+ guard(mutex)(&drv->core->init_lock);
|
||||
+
|
||||
ret = regmap_read(drv->regmap, reg, &val);
|
||||
if (ret < 0) {
|
||||
dev_err(drv->dev, "failed to read function status: %d\n", ret);
|
||||
@@ -418,6 +421,8 @@ static int class_function_runtime_resume(struct device *dev)
|
||||
struct class_function_drv *drv = auxiliary_get_drvdata(auxdev);
|
||||
int ret;
|
||||
|
||||
+ guard(mutex)(&drv->core->init_lock);
|
||||
+
|
||||
regcache_mark_dirty(drv->regmap);
|
||||
regcache_cache_only(drv->regmap, false);
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
From 657e4d51de49864710a8b804c50e94e0e14ac63b Mon Sep 17 00:00:00 2001
|
||||
From: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Date: Thu, 15 Jan 2026 11:46:07 +0000
|
||||
Subject: [PATCH 08/17] ASoC: SDCA: Tidy up some memory allocations
|
||||
|
||||
It is slightly better to deference the type being allocate for a sizeof
|
||||
rather than manually using the type. Saves effort if types change in the
|
||||
future. This results in no functional changes, just tidies up the style
|
||||
of the code a little.
|
||||
|
||||
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Link: https://patch.msgid.link/20260115114607.271990-1-ckeepax@opensource.cirrus.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sdca/sdca_fdl.c | 2 +-
|
||||
sound/soc/sdca/sdca_functions.c | 6 +++---
|
||||
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/sdca/sdca_fdl.c b/sound/soc/sdca/sdca_fdl.c
|
||||
index 3180ebd07c40..8bee9f23c473 100644
|
||||
--- a/sound/soc/sdca/sdca_fdl.c
|
||||
+++ b/sound/soc/sdca/sdca_fdl.c
|
||||
@@ -487,7 +487,7 @@ int sdca_fdl_alloc_state(struct sdca_interrupt *interrupt)
|
||||
struct device *dev = interrupt->dev;
|
||||
struct fdl_state *fdl_state;
|
||||
|
||||
- fdl_state = devm_kzalloc(dev, sizeof(struct fdl_state), GFP_KERNEL);
|
||||
+ fdl_state = devm_kzalloc(dev, sizeof(*fdl_state), GFP_KERNEL);
|
||||
if (!fdl_state)
|
||||
return -ENOMEM;
|
||||
|
||||
diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c
|
||||
index b26884fc2a98..f97dde912d59 100644
|
||||
--- a/sound/soc/sdca/sdca_functions.c
|
||||
+++ b/sound/soc/sdca/sdca_functions.c
|
||||
@@ -948,7 +948,7 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti
|
||||
}
|
||||
|
||||
control->values = devm_kcalloc(dev, hweight64(control->cn_list),
|
||||
- sizeof(int), GFP_KERNEL);
|
||||
+ sizeof(*control->values), GFP_KERNEL);
|
||||
if (!control->values)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -2044,7 +2044,7 @@ static int find_sdca_filesets(struct device *dev, struct sdw_slave *sdw,
|
||||
fwnode_property_read_u32_array(function_node, "mipi-sdca-file-set-id-list",
|
||||
filesets_list, num_sets);
|
||||
|
||||
- sets = devm_kcalloc(dev, num_sets, sizeof(struct sdca_fdl_set), GFP_KERNEL);
|
||||
+ sets = devm_kcalloc(dev, num_sets, sizeof(*sets), GFP_KERNEL);
|
||||
if (!sets)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -2070,7 +2070,7 @@ static int find_sdca_filesets(struct device *dev, struct sdw_slave *sdw,
|
||||
dev_dbg(dev, "fileset: %#x\n", filesets_list[i]);
|
||||
|
||||
files = devm_kcalloc(dev, num_entries / mult_fileset,
|
||||
- sizeof(struct sdca_fdl_file), GFP_KERNEL);
|
||||
+ sizeof(*files), GFP_KERNEL);
|
||||
if (!files)
|
||||
return -ENOMEM;
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
From b92178f5dd8fa8f70e26d4e2b055327842e58a74 Mon Sep 17 00:00:00 2001
|
||||
From: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Date: Thu, 15 Jan 2026 13:17:26 +0000
|
||||
Subject: [PATCH 10/17] ASoC: SDCA: Add NO_DIRECT_COMPLETE flag to class driver
|
||||
|
||||
The SDCA class driver currently expects the device will be fully powered
|
||||
down on system suspend but not on runtime suspend. This is typically
|
||||
required as when audio is not active (ie. runtime suspend) jack detect
|
||||
is expected to still function, but when the whole system is hibernated
|
||||
there is no need to recognise audio jack events. This means the class
|
||||
driver needs to always be informed of a system suspend, so the direct
|
||||
complete optimisation (where PM will skip calling system suspend if the
|
||||
device is runtime suspended) is not appropriate for the SDCA class
|
||||
driver.
|
||||
|
||||
Add the NO_DIRECT_COMPLETE flag to prevent this optimisation from
|
||||
running against this driver.
|
||||
|
||||
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
|
||||
link: https://github.com/thesofproject/linux/blob/ec0e6c69113f4b342ee8eabec286dea33d98a7cc/drivers/soundwire/intel_auxdevice.c#L568
|
||||
Link: https://patch.msgid.link/20260115131727.373738-1-ckeepax@opensource.cirrus.com
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sdca/sdca_class_function.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/sound/soc/sdca/sdca_class_function.c b/sound/soc/sdca/sdca_class_function.c
|
||||
index 0afa41c1ee93..98fd3fd1052b 100644
|
||||
--- a/sound/soc/sdca/sdca_class_function.c
|
||||
+++ b/sound/soc/sdca/sdca_class_function.c
|
||||
@@ -377,6 +377,8 @@ static int class_function_probe(struct auxiliary_device *auxdev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ dev_pm_set_driver_flags(dev, DPM_FLAG_NO_DIRECT_COMPLETE);
|
||||
+
|
||||
pm_runtime_set_autosuspend_delay(dev, 200);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
pm_runtime_set_active(dev);
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
From c7da79578f653d5503f5faadcb887e4f8997c2b9 Mon Sep 17 00:00:00 2001
|
||||
From: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Date: Wed, 4 Feb 2026 12:59:41 +0000
|
||||
Subject: [PATCH 12/17] ASoC: SDCA: Rearrange FDL file messages
|
||||
|
||||
It is helpful to have something in the log showing which firmware file
|
||||
was loaded by the driver. Update the existing FDL disk file debug
|
||||
statement to just note that a disk file rather than ACPI file was used,
|
||||
and add a new info printk that prints out the details of the loaded file
|
||||
regardless of where that file came from. Likewise, sometimes it is
|
||||
useful to get a message if the file-sets list is missing, although this
|
||||
isn't technically an error so make it a debug.
|
||||
|
||||
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Link: https://patch.msgid.link/20260204125944.1134011-5-ckeepax@opensource.cirrus.com
|
||||
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sdca/sdca_fdl.c | 6 ++++--
|
||||
sound/soc/sdca/sdca_functions.c | 1 +
|
||||
2 files changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/sdca/sdca_fdl.c b/sound/soc/sdca/sdca_fdl.c
|
||||
index 8bee9f23c473..07892bc3a44e 100644
|
||||
--- a/sound/soc/sdca/sdca_fdl.c
|
||||
+++ b/sound/soc/sdca/sdca_fdl.c
|
||||
@@ -256,8 +256,7 @@ static int fdl_load_file(struct sdca_interrupt *interrupt,
|
||||
tmp->file_length != firmware->size) {
|
||||
dev_err(dev, "bad disk SWF size\n");
|
||||
} else if (!swf || swf->file_version <= tmp->file_version) {
|
||||
- dev_dbg(dev, "using SWF from disk: %x-%x-%x\n",
|
||||
- tmp->vendor_id, tmp->file_id, tmp->file_version);
|
||||
+ dev_dbg(dev, "using SWF from disk\n");
|
||||
swf = tmp;
|
||||
}
|
||||
}
|
||||
@@ -267,6 +266,9 @@ static int fdl_load_file(struct sdca_interrupt *interrupt,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
+ dev_info(dev, "loading SWF: %x-%x-%x\n",
|
||||
+ swf->vendor_id, swf->file_id, swf->file_version);
|
||||
+
|
||||
ret = sdca_ump_write_message(dev, interrupt->device_regmap,
|
||||
interrupt->function_regmap,
|
||||
interrupt->function, interrupt->entity,
|
||||
diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c
|
||||
index f97dde912d59..f38791eab4f1 100644
|
||||
--- a/sound/soc/sdca/sdca_functions.c
|
||||
+++ b/sound/soc/sdca/sdca_functions.c
|
||||
@@ -2029,6 +2029,7 @@ static int find_sdca_filesets(struct device *dev, struct sdw_slave *sdw,
|
||||
num_sets = fwnode_property_count_u32(function_node,
|
||||
"mipi-sdca-file-set-id-list");
|
||||
if (num_sets == 0 || num_sets == -EINVAL) {
|
||||
+ dev_dbg(dev, "%pfwP: file set id list missing\n", function_node);
|
||||
return 0;
|
||||
} else if (num_sets < 0) {
|
||||
dev_err(dev, "%pfwP: failed to read file set list: %d\n",
|
||||
--
|
||||
2.43.0
|
||||
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
From a80d5cd47c6d2eb3890235a527ad41a73b28009e Mon Sep 17 00:00:00 2001
|
||||
From: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Date: Wed, 4 Feb 2026 12:59:42 +0000
|
||||
Subject: [PATCH 13/17] ASoC: SDCA: Add regmap defaults for specification
|
||||
defined values
|
||||
|
||||
Some of the SDCA Controls have a defined reset value in the
|
||||
specification. Update the parsing to add these specification defined
|
||||
values into the regmap defaults array. This will reduce the number of
|
||||
registers that are synchronised on a cache sync.
|
||||
|
||||
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Link: https://patch.msgid.link/20260204125944.1134011-6-ckeepax@opensource.cirrus.com
|
||||
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
include/sound/sdca_function.h | 4 ++++
|
||||
sound/soc/sdca/sdca_functions.c | 36 +++++++++++++++++++++++++++++++++
|
||||
sound/soc/sdca/sdca_regmap.c | 14 ++++++++++---
|
||||
3 files changed, 51 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/include/sound/sdca_function.h b/include/sound/sdca_function.h
|
||||
index 6e9391b3816c..79bd5a7a0f88 100644
|
||||
--- a/include/sound/sdca_function.h
|
||||
+++ b/include/sound/sdca_function.h
|
||||
@@ -798,6 +798,7 @@ struct sdca_control_range {
|
||||
* @sel: Identifier used for addressing.
|
||||
* @nbits: Number of bits used in the Control.
|
||||
* @values: Holds the Control value for constants and defaults.
|
||||
+ * @reset: Defined reset value for the Control.
|
||||
* @cn_list: A bitmask showing the valid Control Numbers within this Control,
|
||||
* Control Numbers typically represent channels.
|
||||
* @interrupt_position: SCDA interrupt line that will alert to changes on this
|
||||
@@ -808,6 +809,7 @@ struct sdca_control_range {
|
||||
* @layers: Bitmask of access layers of the Control.
|
||||
* @deferrable: Indicates if the access to the Control can be deferred.
|
||||
* @has_default: Indicates the Control has a default value to be written.
|
||||
+ * @has_reset: Indicates the Control has a defined reset value.
|
||||
* @has_fixed: Indicates the Control only supports a single value.
|
||||
*/
|
||||
struct sdca_control {
|
||||
@@ -816,6 +818,7 @@ struct sdca_control {
|
||||
|
||||
int nbits;
|
||||
int *values;
|
||||
+ int reset;
|
||||
u64 cn_list;
|
||||
int interrupt_position;
|
||||
|
||||
@@ -827,6 +830,7 @@ struct sdca_control {
|
||||
bool deferrable;
|
||||
bool is_volatile;
|
||||
bool has_default;
|
||||
+ bool has_reset;
|
||||
bool has_fixed;
|
||||
};
|
||||
|
||||
diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c
|
||||
index f38791eab4f1..95b67bb904c3 100644
|
||||
--- a/sound/soc/sdca/sdca_functions.c
|
||||
+++ b/sound/soc/sdca/sdca_functions.c
|
||||
@@ -911,6 +911,38 @@ static int find_sdca_control_value(struct device *dev, struct sdca_entity *entit
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int find_sdca_control_reset(const struct sdca_entity *entity,
|
||||
+ struct sdca_control *control)
|
||||
+{
|
||||
+ switch (SDCA_CTL_TYPE(entity->type, control->sel)) {
|
||||
+ case SDCA_CTL_TYPE_S(FU, AGC):
|
||||
+ case SDCA_CTL_TYPE_S(FU, BASS_BOOST):
|
||||
+ case SDCA_CTL_TYPE_S(FU, LOUDNESS):
|
||||
+ case SDCA_CTL_TYPE_S(SMPU, TRIGGER_ENABLE):
|
||||
+ case SDCA_CTL_TYPE_S(GE, SELECTED_MODE):
|
||||
+ case SDCA_CTL_TYPE_S(TG, TONE_DIVIDER):
|
||||
+ case SDCA_CTL_TYPE_S(ENTITY_0, COMMIT_GROUP_MASK):
|
||||
+ control->has_reset = true;
|
||||
+ control->reset = 0;
|
||||
+ break;
|
||||
+ case SDCA_CTL_TYPE_S(XU, BYPASS):
|
||||
+ case SDCA_CTL_TYPE_S(MFPU, BYPASS):
|
||||
+ case SDCA_CTL_TYPE_S(FU, MUTE):
|
||||
+ case SDCA_CTL_TYPE_S(CX, CLOCK_SELECT):
|
||||
+ control->has_reset = true;
|
||||
+ control->reset = 1;
|
||||
+ break;
|
||||
+ case SDCA_CTL_TYPE_S(PDE, REQUESTED_PS):
|
||||
+ control->has_reset = true;
|
||||
+ control->reset = 3;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int find_sdca_entity_control(struct device *dev, struct sdca_entity *entity,
|
||||
struct fwnode_handle *control_node,
|
||||
struct sdca_control *control)
|
||||
@@ -986,6 +1018,10 @@ static int find_sdca_entity_control(struct device *dev, struct sdca_entity *enti
|
||||
|
||||
control->is_volatile = find_sdca_control_volatile(entity, control);
|
||||
|
||||
+ ret = find_sdca_control_reset(entity, control);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
ret = find_sdca_control_range(dev, control_node, &control->range);
|
||||
if (ret) {
|
||||
dev_err(dev, "%s: control %#x: range missing: %d\n",
|
||||
diff --git a/sound/soc/sdca/sdca_regmap.c b/sound/soc/sdca/sdca_regmap.c
|
||||
index 2cca9a9c71ea..4f8a685dc43d 100644
|
||||
--- a/sound/soc/sdca/sdca_regmap.c
|
||||
+++ b/sound/soc/sdca/sdca_regmap.c
|
||||
@@ -218,7 +218,8 @@ int sdca_regmap_count_constants(struct device *dev,
|
||||
struct sdca_entity *entity = &function->entities[i];
|
||||
|
||||
for (j = 0; j < entity->num_controls; j++) {
|
||||
- if (entity->controls[j].mode == SDCA_ACCESS_MODE_DC)
|
||||
+ if (entity->controls[j].mode == SDCA_ACCESS_MODE_DC ||
|
||||
+ entity->controls[j].has_reset)
|
||||
nconsts += hweight64(entity->controls[j].cn_list);
|
||||
}
|
||||
}
|
||||
@@ -255,7 +256,8 @@ int sdca_regmap_populate_constants(struct device *dev,
|
||||
struct sdca_control *control = &entity->controls[j];
|
||||
int cn;
|
||||
|
||||
- if (control->mode != SDCA_ACCESS_MODE_DC)
|
||||
+ if (control->mode != SDCA_ACCESS_MODE_DC &&
|
||||
+ !control->has_reset)
|
||||
continue;
|
||||
|
||||
l = 0;
|
||||
@@ -264,7 +266,10 @@ int sdca_regmap_populate_constants(struct device *dev,
|
||||
consts[k].reg = SDW_SDCA_CTL(function->desc->adr,
|
||||
entity->id,
|
||||
control->sel, cn);
|
||||
- consts[k].def = control->values[l];
|
||||
+ if (control->mode == SDCA_ACCESS_MODE_DC)
|
||||
+ consts[k].def = control->values[l];
|
||||
+ else
|
||||
+ consts[k].def = control->reset;
|
||||
k++;
|
||||
l++;
|
||||
}
|
||||
@@ -306,6 +311,9 @@ static int populate_control_defaults(struct device *dev, struct regmap *regmap,
|
||||
|
||||
i++;
|
||||
} else if (!control->is_volatile) {
|
||||
+ if (control->has_reset)
|
||||
+ regcache_drop_region(regmap, reg, reg);
|
||||
+
|
||||
ret = regmap_read(regmap, reg, &val);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to read initial %#x: %d\n",
|
||||
--
|
||||
2.43.0
|
||||
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
From 29408c08047402839d40cb03bf870efcf476c361 Mon Sep 17 00:00:00 2001
|
||||
From: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Date: Wed, 4 Feb 2026 12:59:43 +0000
|
||||
Subject: [PATCH 14/17] ASoC: SDCA: Limit values user can write to Selected
|
||||
Mode
|
||||
|
||||
Prevent the user from both updating the Selected Mode control
|
||||
whilst the jack is not present, and from writing values that don't
|
||||
correspond to a valid jack type (Unknown, in progress, etc.).
|
||||
|
||||
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
|
||||
Link: https://patch.msgid.link/20260204125944.1134011-7-ckeepax@opensource.cirrus.com
|
||||
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
|
||||
Signed-off-by: Mark Brown <broonie@kernel.org>
|
||||
---
|
||||
sound/soc/sdca/sdca_asoc.c | 37 ++++++++++++++++++++++++++++++++++++-
|
||||
sound/soc/sdca/sdca_jack.c | 2 +-
|
||||
2 files changed, 37 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/sdca/sdca_asoc.c b/sound/soc/sdca/sdca_asoc.c
|
||||
index 9685281529e9..bb6e74e80a3e 100644
|
||||
--- a/sound/soc/sdca/sdca_asoc.c
|
||||
+++ b/sound/soc/sdca/sdca_asoc.c
|
||||
@@ -116,6 +116,41 @@ int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *fun
|
||||
}
|
||||
EXPORT_SYMBOL_NS(sdca_asoc_count_component, "SND_SOC_SDCA");
|
||||
|
||||
+static int ge_put_enum_double(struct snd_kcontrol *kcontrol,
|
||||
+ struct snd_ctl_elem_value *ucontrol)
|
||||
+{
|
||||
+ struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol);
|
||||
+ struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
|
||||
+ struct device *dev = component->dev;
|
||||
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
|
||||
+ unsigned int *item = ucontrol->value.enumerated.item;
|
||||
+ unsigned int reg = e->reg;
|
||||
+ int ret;
|
||||
+
|
||||
+ reg &= ~SDW_SDCA_CTL_CSEL(0x3F);
|
||||
+ reg |= SDW_SDCA_CTL_CSEL(SDCA_CTL_GE_DETECTED_MODE);
|
||||
+
|
||||
+ ret = pm_runtime_resume_and_get(dev);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(dev, "failed to resume writing %s: %d\n",
|
||||
+ kcontrol->id.name, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = snd_soc_component_read(component, reg);
|
||||
+ pm_runtime_put(dev);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+ else if (ret <= SDCA_DETECTED_MODE_DETECTION_IN_PROGRESS)
|
||||
+ return -EBUSY;
|
||||
+
|
||||
+ ret = snd_soc_enum_item_to_val(e, item[0]);
|
||||
+ if (ret <= SDCA_DETECTED_MODE_DETECTION_IN_PROGRESS)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
|
||||
+}
|
||||
+
|
||||
static int entity_early_parse_ge(struct device *dev,
|
||||
struct sdca_function_data *function,
|
||||
struct sdca_entity *entity)
|
||||
@@ -192,7 +227,7 @@ static int entity_early_parse_ge(struct device *dev,
|
||||
kctl->name = control_name;
|
||||
kctl->info = snd_soc_info_enum_double;
|
||||
kctl->get = snd_soc_dapm_get_enum_double;
|
||||
- kctl->put = snd_soc_dapm_put_enum_double;
|
||||
+ kctl->put = ge_put_enum_double;
|
||||
kctl->private_value = (unsigned long)soc_enum;
|
||||
|
||||
entity->ge.kctl = kctl;
|
||||
diff --git a/sound/soc/sdca/sdca_jack.c b/sound/soc/sdca/sdca_jack.c
|
||||
index bfa621b744e1..605514f02045 100644
|
||||
--- a/sound/soc/sdca/sdca_jack.c
|
||||
+++ b/sound/soc/sdca/sdca_jack.c
|
||||
@@ -105,7 +105,7 @@ int sdca_jack_process(struct sdca_interrupt *interrupt)
|
||||
|
||||
ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(soc_enum, val);
|
||||
|
||||
- ret = kctl->put(kctl, ucontrol);
|
||||
+ ret = snd_soc_dapm_put_enum_double(kctl, ucontrol);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to update selected mode: %d\n", ret);
|
||||
return ret;
|
||||
--
|
||||
2.43.0
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
From 849489b94fe35172a4fea6e09acabacd273d8993 Mon Sep 17 00:00:00 2001
|
||||
From: TsaiGaggery <gaggery.tsai@intel.com>
|
||||
Date: Wed, 11 Mar 2026 14:21:39 -0700
|
||||
Subject: [PATCH 17/17] ASoC: SDCA: Fix NULL pointer dereference in
|
||||
sdca_jack_process()
|
||||
|
||||
Add NULL guard for card and card->snd_card before dereferencing.
|
||||
During card teardown, component->card can be NULL when an IRQ fires.
|
||||
---
|
||||
sound/soc/sdca/sdca_jack.c | 12 ++++++++++--
|
||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/sdca/sdca_jack.c b/sound/soc/sdca/sdca_jack.c
|
||||
index 605514f02045..04ff391aa7bc 100644
|
||||
--- a/sound/soc/sdca/sdca_jack.c
|
||||
+++ b/sound/soc/sdca/sdca_jack.c
|
||||
@@ -37,13 +37,21 @@ int sdca_jack_process(struct sdca_interrupt *interrupt)
|
||||
struct device *dev = interrupt->dev;
|
||||
struct snd_soc_component *component = interrupt->component;
|
||||
struct snd_soc_card *card = component->card;
|
||||
- struct rw_semaphore *rwsem = &card->snd_card->controls_rwsem;
|
||||
+ struct rw_semaphore *rwsem;
|
||||
struct jack_state *state = interrupt->priv;
|
||||
- struct snd_kcontrol *kctl = state->kctl;
|
||||
+ struct snd_kcontrol *kctl;
|
||||
struct snd_ctl_elem_value *ucontrol __free(kfree) = NULL;
|
||||
unsigned int reg, val;
|
||||
int ret;
|
||||
|
||||
+ if (!card || !card->snd_card) {
|
||||
+ dev_dbg(dev, "card not yet bound, deferring jack event\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
+ rwsem = &card->snd_card->controls_rwsem;
|
||||
+ kctl = state->kctl;
|
||||
+
|
||||
guard(rwsem_write)(rwsem);
|
||||
|
||||
if (!kctl) {
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
# Maintainer: Intel PTL Audio Enablement
|
||||
# Based on Arch Linux linux package by Jan Alexander Steffens (heftig)
|
||||
|
||||
pkgbase=linux-ptl-audio
|
||||
pkgver=6.19.9.arch1
|
||||
pkgrel=1
|
||||
pkgdesc='Linux with Panther Lake SDCA audio backports'
|
||||
url='https://github.com/archlinux/linux'
|
||||
arch=(
|
||||
x86_64
|
||||
)
|
||||
license=(GPL-2.0-only)
|
||||
makedepends=(
|
||||
bc
|
||||
cpio
|
||||
gettext
|
||||
libelf
|
||||
pahole
|
||||
perl
|
||||
python
|
||||
tar
|
||||
xz
|
||||
)
|
||||
options=(
|
||||
!debug
|
||||
!strip
|
||||
)
|
||||
_srcname=linux-${pkgver%.*}
|
||||
_srctag=v${pkgver%.*}-${pkgver##*.}
|
||||
source=(
|
||||
https://cdn.kernel.org/pub/linux/kernel/v${pkgver%%.*}.x/${_srcname}.tar.{xz,sign}
|
||||
$url/releases/download/$_srctag/linux-$_srctag.patch.zst{,.sig}
|
||||
0001-ASoC-SDCA-functions-Fix-confusing-cleanup.h-syntax.patch
|
||||
0002-ASoC-SDCA-Add-ASoC-jack-hookup-in-class-driver.patch
|
||||
0003-ASoC-SDCA-Replace-use-of-system_wq-with-system_dfl_w.patch
|
||||
0004-ASoC-SDCA-Add-SDCA-IRQ-enable-disable-helpers.patch
|
||||
0005-ASoC-SDCA-Add-basic-system-suspend-support.patch
|
||||
0007-ASoC-SDCA-Add-lock-to-serialise-the-Function-initial.patch
|
||||
0008-ASoC-SDCA-Tidy-up-some-memory-allocations.patch
|
||||
0010-ASoC-SDCA-Add-NO_DIRECT_COMPLETE-flag-to-class-drive.patch
|
||||
0012-ASoC-SDCA-Rearrange-FDL-file-messages.patch
|
||||
0013-ASoC-SDCA-Add-regmap-defaults-for-specification-defi.patch
|
||||
0014-ASoC-SDCA-Limit-values-user-can-write-to-Selected-Mo.patch
|
||||
0017-ASoC-SDCA-Fix-NULL-pointer-dereference-in-sdca_jack_.patch
|
||||
)
|
||||
source_x86_64=(config.x86_64)
|
||||
validpgpkeys=(
|
||||
ABAF11C65A2970B130ABE3C479BE3E4300411886 # Linus Torvalds
|
||||
647F28654894E3BD457199BE38DBBDC86092693E # Greg Kroah-Hartman
|
||||
83BC8889351B5DEBBB68416EB8AC08600F108CDF # Jan Alexander Steffens (heftig)
|
||||
)
|
||||
b2sums=('6be41037c5b18e9a8d1c58fdd613e37bb5c841b7f43baf95516f3dda461adc6eb20da03e6a8892bd5b8410125ad42dae8ef4634a0eb95b84aaf3882a6ed00074'
|
||||
'SKIP'
|
||||
'edc6d11f32f16a53e520b53b52be690d192c0a64153419cbba65e4a2c0f426ce76ab2c10dbddd7f82f2c407c071039b05018796cf2b8ba501d46e3a259146ced'
|
||||
'SKIP'
|
||||
'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP'
|
||||
'SKIP' 'SKIP' 'SKIP' 'SKIP')
|
||||
b2sums_x86_64=('cab93bd983d92e2fc6047bfaa3fc3b52fbd23272aef4aaa10500ac0ac26847c1bbdfdb13a6f64ad7689166109b99a078580bf43a02aaf9f2be0ae8885a87ffc8')
|
||||
|
||||
# https://www.kernel.org/pub/linux/kernel/v6.x/sha256sums.asc
|
||||
sha256sums=('c16068a3af12e3943dee3b1eef57ca70229c069128bfa1184fb3f48b219d55bf'
|
||||
'SKIP'
|
||||
'dacb94dc3be57fc442995a3d3d1519775d3f6877a4e2fec437223d95e318f04b'
|
||||
'SKIP'
|
||||
'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP'
|
||||
'SKIP' 'SKIP' 'SKIP' 'SKIP')
|
||||
|
||||
export KBUILD_BUILD_HOST=archlinux
|
||||
export KBUILD_BUILD_USER=$pkgbase
|
||||
export KBUILD_BUILD_TIMESTAMP="$(date -Ru${SOURCE_DATE_EPOCH:+d @$SOURCE_DATE_EPOCH})"
|
||||
|
||||
prepare() {
|
||||
cd $_srcname
|
||||
|
||||
echo "Setting version..."
|
||||
echo "-$pkgrel" > localversion.10-pkgrel
|
||||
echo "${pkgbase#linux}" > localversion.20-pkgname
|
||||
|
||||
local src
|
||||
for src in "${source[@]}"; do
|
||||
src="${src%%::*}"
|
||||
src="${src##*/}"
|
||||
src="${src%.zst}"
|
||||
[[ $src = *.patch ]] || continue
|
||||
echo "Applying patch $src..."
|
||||
patch -Np1 < "../$src"
|
||||
done
|
||||
|
||||
echo "Setting config..."
|
||||
cp ../config.$CARCH .config
|
||||
make olddefconfig
|
||||
diff -u ../config.$CARCH .config || :
|
||||
|
||||
make -s kernelrelease > version
|
||||
echo "Prepared $pkgbase version $(<version)"
|
||||
}
|
||||
|
||||
build() {
|
||||
cd $_srcname
|
||||
make all
|
||||
make -C tools/bpf/bpftool vmlinux.h feature-clang-bpf-co-re=1
|
||||
}
|
||||
|
||||
_package() {
|
||||
pkgdesc="The $pkgdesc kernel and modules"
|
||||
depends=(
|
||||
coreutils
|
||||
initramfs
|
||||
kmod
|
||||
)
|
||||
optdepends=(
|
||||
"$pkgbase-headers: headers and scripts for building modules"
|
||||
'linux-firmware: firmware images needed for some devices'
|
||||
'scx-scheds: to use sched-ext schedulers'
|
||||
'wireless-regdb: to set the correct wireless channels of your country'
|
||||
)
|
||||
provides=(
|
||||
KSMBD-MODULE
|
||||
NTSYNC-MODULE
|
||||
VIRTUALBOX-GUEST-MODULES
|
||||
WIREGUARD-MODULE
|
||||
)
|
||||
replaces=(
|
||||
virtualbox-guest-modules-arch
|
||||
wireguard-arch
|
||||
)
|
||||
|
||||
cd $_srcname
|
||||
local modulesdir="$pkgdir/usr/lib/modules/$(<version)"
|
||||
|
||||
echo "Installing boot image..."
|
||||
# systemd expects to find the kernel here to allow hibernation
|
||||
# https://github.com/systemd/systemd/commit/edda44605f06a41fb86b7ab8128dcf99161d2344
|
||||
install -Dm644 "$(make -s image_name)" "$modulesdir/vmlinuz"
|
||||
|
||||
# Used by mkinitcpio to name the kernel
|
||||
echo "$pkgbase" | install -Dm644 /dev/stdin "$modulesdir/pkgbase"
|
||||
|
||||
echo "Installing modules..."
|
||||
ZSTD_CLEVEL=19 make INSTALL_MOD_PATH="$pkgdir/usr" INSTALL_MOD_STRIP=1 \
|
||||
DEPMOD=/doesnt/exist modules_install # Suppress depmod
|
||||
|
||||
# remove build link
|
||||
rm "$modulesdir"/build
|
||||
}
|
||||
|
||||
_package-headers() {
|
||||
pkgdesc="Headers and scripts for building modules for the $pkgdesc kernel"
|
||||
depends=(pahole)
|
||||
provides=(LINUX-HEADERS)
|
||||
|
||||
cd $_srcname
|
||||
local builddir="$pkgdir/usr/lib/modules/$(<version)/build"
|
||||
|
||||
local karch
|
||||
case $CARCH in
|
||||
x86_64) karch=x86 ;;
|
||||
*) echo "Unknown CARCH $CARCH"; exit 1 ;;
|
||||
esac
|
||||
|
||||
echo "Installing build files..."
|
||||
install -Dt "$builddir" -m644 .config Makefile Module.symvers System.map \
|
||||
localversion.* version vmlinux tools/bpf/bpftool/vmlinux.h
|
||||
install -Dt "$builddir/kernel" -m644 kernel/Makefile
|
||||
install -Dt "$builddir/arch/$karch" -m644 arch/$karch/Makefile
|
||||
cp -t "$builddir" -a scripts
|
||||
ln -srt "$builddir" "$builddir/scripts/gdb/vmlinux-gdb.py"
|
||||
|
||||
if [[ $(scripts/config -s CONFIG_HAVE_STACK_VALIDATION) = y ]]; then
|
||||
install -Dt "$builddir/tools/objtool" tools/objtool/objtool
|
||||
fi
|
||||
|
||||
if [[ $(scripts/config -s CONFIG_DEBUG_INFO_BTF_MODULES) = y ]]; then
|
||||
install -Dt "$builddir/tools/bpf/resolve_btfids" tools/bpf/resolve_btfids/resolve_btfids
|
||||
fi
|
||||
|
||||
echo "Installing headers..."
|
||||
cp -t "$builddir" -a include
|
||||
cp -t "$builddir/arch/$karch" -a arch/$karch/include
|
||||
install -Dt "$builddir/arch/$karch/kernel" -m644 arch/$karch/kernel/asm-offsets.s
|
||||
|
||||
install -Dt "$builddir/drivers/md" -m644 drivers/md/*.h
|
||||
install -Dt "$builddir/net/mac80211" -m644 net/mac80211/*.h
|
||||
|
||||
# https://bugs.archlinux.org/task/13146
|
||||
install -Dt "$builddir/drivers/media/i2c" -m644 drivers/media/i2c/msp3400-driver.h
|
||||
|
||||
# https://bugs.archlinux.org/task/20402
|
||||
install -Dt "$builddir/drivers/media/usb/dvb-usb" -m644 drivers/media/usb/dvb-usb/*.h
|
||||
install -Dt "$builddir/drivers/media/dvb-frontends" -m644 drivers/media/dvb-frontends/*.h
|
||||
install -Dt "$builddir/drivers/media/tuners" -m644 drivers/media/tuners/*.h
|
||||
|
||||
# https://bugs.archlinux.org/task/71392
|
||||
install -Dt "$builddir/drivers/iio/common/hid-sensors" -m644 drivers/iio/common/hid-sensors/*.h
|
||||
|
||||
echo "Installing KConfig files..."
|
||||
find . -name 'Kconfig*' -exec install -Dm644 {} "$builddir/{}" \;
|
||||
|
||||
echo "Installing Rust files..."
|
||||
if [[ $(scripts/config -s CONFIG_RUST) = y ]]; then
|
||||
install -Dt "$builddir/rust" -m644 rust/*.rmeta
|
||||
install -Dt "$builddir/rust" rust/*.so
|
||||
fi
|
||||
|
||||
echo "Installing unstripped VDSO..."
|
||||
make INSTALL_MOD_PATH="$pkgdir/usr" vdso_install \
|
||||
link= # Suppress build-id symlinks
|
||||
|
||||
echo "Removing unneeded architectures..."
|
||||
local arch
|
||||
for arch in "$builddir"/arch/*/; do
|
||||
[[ $arch = */$karch/ ]] && continue
|
||||
echo "Removing $(basename "$arch")"
|
||||
rm -r "$arch"
|
||||
done
|
||||
|
||||
echo "Removing documentation..."
|
||||
rm -r "$builddir/Documentation"
|
||||
|
||||
echo "Removing broken symlinks..."
|
||||
find -L "$builddir" -type l -printf 'Removing %P\n' -delete
|
||||
|
||||
echo "Removing loose objects..."
|
||||
find "$builddir" -type f -name '*.o' -printf 'Removing %P\n' -delete
|
||||
|
||||
echo "Stripping build tools..."
|
||||
local file
|
||||
while read -rd '' file; do
|
||||
case "$(file -Sib "$file")" in
|
||||
application/x-sharedlib\;*) # Libraries (.so)
|
||||
strip -v $STRIP_SHARED "$file" ;;
|
||||
application/x-archive\;*) # Libraries (.a)
|
||||
strip -v $STRIP_STATIC "$file" ;;
|
||||
application/x-executable\;*) # Binaries
|
||||
strip -v $STRIP_BINARIES "$file" ;;
|
||||
application/x-pie-executable\;*) # Relocatable binaries
|
||||
strip -v $STRIP_SHARED "$file" ;;
|
||||
esac
|
||||
done < <(find "$builddir" -type f -perm -u+x ! -name vmlinux -print0)
|
||||
|
||||
echo "Stripping vmlinux..."
|
||||
strip -v $STRIP_STATIC "$builddir/vmlinux"
|
||||
|
||||
echo "Adding symlink..."
|
||||
mkdir -p "$pkgdir/usr/src"
|
||||
ln -sr "$builddir" "$pkgdir/usr/src/$pkgbase"
|
||||
}
|
||||
|
||||
_package-docs() {
|
||||
pkgdesc="Documentation for the $pkgdesc kernel"
|
||||
|
||||
cd $_srcname
|
||||
local builddir="$pkgdir/usr/lib/modules/$(<version)/build"
|
||||
|
||||
echo "Installing documentation..."
|
||||
local src dst
|
||||
while read -rd '' src; do
|
||||
dst="${src#Documentation/}"
|
||||
dst="$builddir/Documentation/${dst#output/}"
|
||||
install -Dm644 "$src" "$dst"
|
||||
done < <(find Documentation -name '.*' -prune -o ! -type d -print0)
|
||||
|
||||
echo "Adding symlink..."
|
||||
mkdir -p "$pkgdir/usr/share/doc"
|
||||
ln -sr "$builddir/Documentation" "$pkgdir/usr/share/doc/$pkgbase"
|
||||
}
|
||||
|
||||
pkgname=(
|
||||
"$pkgbase"
|
||||
"$pkgbase-headers"
|
||||
)
|
||||
for _p in "${pkgname[@]}"; do
|
||||
eval "package_$_p() {
|
||||
$(declare -f "_package${_p#$pkgbase}")
|
||||
_package${_p#$pkgbase}
|
||||
}"
|
||||
done
|
||||
|
||||
# vim:set ts=8 sts=2 sw=2 et:
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user