linux Linux ptl 7.0.2 patch rebase (#83)

* linux-ptl: rebase patches for 7.0.2

* fix patch placement for 27
This commit is contained in:
Spencer Bull
2026-04-30 16:45:39 +02:00
committed by GitHub
parent 7fd3bd88ad
commit 830d684130
18 changed files with 249 additions and 1154 deletions
@@ -1,160 +0,0 @@
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
@@ -1,52 +0,0 @@
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
@@ -1,120 +0,0 @@
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
@@ -1,149 +0,0 @@
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
@@ -1,77 +0,0 @@
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
@@ -1,65 +0,0 @@
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
@@ -1,43 +0,0 @@
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
@@ -1,61 +0,0 @@
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
@@ -1,160 +0,0 @@
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
@@ -1,90 +0,0 @@
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
@@ -1,7 +1,7 @@
diff -ruN a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
--- a/drivers/gpu/drm/i915/display/intel_psr.c 2026-04-06 23:05:21.088563236 -0700
+++ b/drivers/gpu/drm/i915/display/intel_psr.c 2026-04-06 23:05:32.080081783 -0700
@@ -716,8 +716,14 @@
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -700,8 +700,14 @@
* To support PSR version 02h and PSR version 03h without
* Y-coordinate requirement panels we would need to enable
* GTC first.
@@ -10,10 +10,10 @@ diff -ruN a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/disp
+ * support. Accept it without explicit Y-coordinate
+ * requirement bit.
*/
- intel_dp->psr.sink_psr2_support = y_req &&
+ intel_dp->psr.sink_psr2_support =
+ (y_req || intel_dp->psr_dpcd[0] ==
- connector->dp.psr_caps.su_support = y_req &&
+ connector->dp.psr_caps.su_support =
+ (y_req || connector->dp.psr_caps.dpcd[0] ==
+ DP_PSR2_WITH_Y_COORD_ET_SUPPORTED) &&
intel_alpm_aux_wake_supported(intel_dp);
drm_dbg_kms(display->drm, "PSR2 %ssupported\n",
intel_dp->psr.sink_psr2_support ? "" : "not ");
connector->dp.psr_caps.su_support ? "" : "not ");
@@ -0,0 +1,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Gaggery Tsai <gaggery.tsai@intel.com>
Date: Tue, 28 Apr 2026 15:00:00 -0500
Subject: [PATCH] drm/i915/alpm: limit Panel Replay ALPM programming to PR
Linux 7 already carries the Panel Replay/PSR selective-update
granularity fixes from the old linux-ptl 0020 patch. Keep only the
remaining ALPM fix: avoid programming PR-specific ALPM controls when
Panel Replay is not active, and use the common helper for aux-less ALPM
selection.
Signed-off-by: Gaggery Tsai <gaggery.tsai@intel.com>
---
drivers/gpu/drm/i915/display/intel_alpm.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c
--- a/drivers/gpu/drm/i915/display/intel_alpm.c
+++ b/drivers/gpu/drm/i915/display/intel_alpm.c
@@ -317,7 +317,7 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp,
ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_50_SYMBOLS |
ALPM_CTL_AUX_LESS_WAKE_TIME(crtc_state->alpm_state.aux_less_wake_lines);
- if (intel_dp->as_sdp_supported) {
+ if (intel_dp->as_sdp_supported && crtc_state->has_panel_replay) {
u32 pr_alpm_ctl = PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T1;
if (crtc_state->link_off_after_as_sdp_when_pr_active)
@@ -432,8 +432,8 @@ void intel_alpm_enable_sink(struct intel_dp *intel_dp,
val = DP_ALPM_ENABLE | DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE;
- if (crtc_state->has_panel_replay || (crtc_state->has_lobf &&
- intel_alpm_aux_less_wake_supported(intel_dp)))
+ if (intel_psr_needs_alpm_aux_less(intel_dp, crtc_state) ||
+ (crtc_state->has_lobf && intel_alpm_aux_less_wake_supported(intel_dp)))
val |= DP_ALPM_MODE_AUX_LESS;
drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, val);
@@ -1,56 +0,0 @@
diff -ruN a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c
--- a/drivers/gpu/drm/i915/display/intel_alpm.c 2026-04-06 22:15:28.734440462 -0700
+++ b/drivers/gpu/drm/i915/display/intel_alpm.c 2026-04-06 22:16:30.831931436 -0700
@@ -317,7 +317,7 @@
ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_50_SYMBOLS |
ALPM_CTL_AUX_LESS_WAKE_TIME(crtc_state->alpm_state.aux_less_wake_lines);
- if (intel_dp->as_sdp_supported) {
+ if (intel_dp->as_sdp_supported && crtc_state->has_panel_replay) {
u32 pr_alpm_ctl = PR_ALPM_CTL_ADAPTIVE_SYNC_SDP_POSITION_T1;
if (intel_dp->pr_dpcd[INTEL_PR_DPCD_INDEX(DP_PANEL_REPLAY_CAP_CAPABILITY)] &
@@ -432,8 +432,8 @@
val = DP_ALPM_ENABLE | DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE;
- if (crtc_state->has_panel_replay || (crtc_state->has_lobf &&
- intel_alpm_aux_less_wake_supported(intel_dp)))
+ if (intel_psr_needs_alpm_aux_less(intel_dp, crtc_state) ||
+ (crtc_state->has_lobf && intel_alpm_aux_less_wake_supported(intel_dp)))
val |= DP_ALPM_MODE_AUX_LESS;
drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, val);
diff -ruN a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
--- a/drivers/gpu/drm/i915/display/intel_psr.c 2026-04-06 22:15:28.733325868 -0700
+++ b/drivers/gpu/drm/i915/display/intel_psr.c 2026-04-06 23:05:46.639364241 -0700
@@ -498,7 +498,8 @@
{
u8 su_capability = 0;
- if (intel_dp->psr.sink_panel_replay_su_support) {
+ if (intel_dp->psr.sink_panel_replay_su_support &&
+ panel_replay_global_enabled(intel_dp)) {
if (drm_dp_dpcd_read_byte(&intel_dp->aux,
DP_PANEL_REPLAY_CAP_CAPABILITY,
&su_capability) < 0)
@@ -513,7 +514,8 @@
static unsigned int
intel_dp_get_su_x_granularity_offset(struct intel_dp *intel_dp)
{
- return intel_dp->psr.sink_panel_replay_su_support ?
+ return (intel_dp->psr.sink_panel_replay_su_support &&
+ panel_replay_global_enabled(intel_dp)) ?
DP_PANEL_REPLAY_CAP_X_GRANULARITY :
DP_PSR2_SU_X_GRANULARITY;
}
@@ -521,7 +523,8 @@
static unsigned int
intel_dp_get_su_y_granularity_offset(struct intel_dp *intel_dp)
{
- return intel_dp->psr.sink_panel_replay_su_support ?
+ return (intel_dp->psr.sink_panel_replay_su_support &&
+ panel_replay_global_enabled(intel_dp)) ?
DP_PANEL_REPLAY_CAP_Y_GRANULARITY :
DP_PSR2_SU_Y_GRANULARITY;
}
@@ -21,7 +21,7 @@ Signed-off-by: Gaggery Tsai <gaggery.tsai@intel.com>
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1712,12 +1712,6 @@ static bool _psr_compute_config(struct intel_dp *intel_dp,
@@ -1708,13 +1708,7 @@ static bool _psr_compute_config(struct intel_dp *intel_dp,
if (!CAN_PSR(intel_dp) || !display->params.enable_psr)
return false;
@@ -31,6 +31,7 @@ diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/dis
- if (crtc_state->vrr.enable)
- return false;
-
entry_setup_frames = intel_psr_entry_setup_frames(intel_dp, adjusted_mode);
entry_setup_frames = intel_psr_entry_setup_frames(intel_dp, conn_state, adjusted_mode);
if (entry_setup_frames >= 0) {
intel_dp->psr.entry_setup_frames = entry_setup_frames;
crtc_state->entry_setup_frames = entry_setup_frames;
@@ -1,35 +0,0 @@
From: Gaggery Tsai <gaggery.tsai@intel.com>
Date: Thu, 10 Apr 2026 00:00:00 -0700
Subject: [PATCH] drm/i915/psr: handle Panel Replay full-line SU granularity
Panel Replay SU reports X granularity = 0xFFFF meaning full-line.
Without this, psr2_granularity_check() rejects PR SU because
2880 % 65535 != 0.
Signed-off-by: Gaggery Tsai <gaggery.tsai@intel.com>
---
drivers/gpu/drm/i915/display/intel_psr.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1326,9 +1326,17 @@
const int crtc_hdisplay = crtc_state->hw.adjusted_mode.crtc_hdisplay;
const int crtc_vdisplay = crtc_state->hw.adjusted_mode.crtc_vdisplay;
u16 y_granularity = 0;
+ u16 w_granularity = intel_dp->psr.su_w_granularity;
+
+ /*
+ * Panel Replay SU can report 0xFFFF meaning full-line granularity.
+ * Substitute crtc_hdisplay so the modulo check passes.
+ */
+ if (w_granularity == 0xFFFF)
+ w_granularity = crtc_hdisplay;
/* PSR2 HW only send full lines so we only need to validate the width */
- if (crtc_hdisplay % intel_dp->psr.su_w_granularity)
+ if (crtc_hdisplay % w_granularity)
return false;
if (crtc_vdisplay % intel_dp->psr.su_y_granularity)
@@ -1,21 +1,194 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Gaggery Tsai <gaggery.tsai@intel.com>
Date: Thu, 10 Apr 2026 10:00:00 -0700
Subject: [PATCH] drm/i915: send TRANS_PUSH Frame Change for Panel Replay cursor updates
Date: Tue, 28 Apr 2026 16:10:00 -0500
Subject: [PATCH] drm/i915: use TRANS_PUSH frame changes for PSR/Panel Replay
Panel Replay Selective Update requires a software-triggered Frame
Change event via TRANS_PUSH to send dirty regions to the panel.
Cursor updates (legacy_cursor_update) skip TRANS_PUSH_SEND, so the
panel never receives cursor position changes under Panel Replay SU.
Panel Replay Selective Update requires a software-triggered Frame Change
event via TRANS_PUSH to send dirty regions to the panel. Cursor updates
can skip the normal VRR push path, so the panel may not receive cursor
position changes under Panel Replay SU.
Fix by sending TRANS_PUSH with LNL_TRANS_PUSH_PSR_PR_EN for cursor
updates when Panel Replay is active.
Backport the upstream TRANS_PUSH frame-change flow for display 20+:
program the PSR/PR frame-change bit when PSR is enabled, skip the old
CURSURFLIVE frame-change path on platforms using TRANS_PUSH, and send a
push for legacy cursor updates when PSR/Panel Replay uses TRANS_PUSH.
Signed-off-by: Gaggery Tsai <gaggery.tsai@intel.com>
---
drivers/gpu/drm/i915/display/intel_crtc.c | 4 +++-
drivers/gpu/drm/i915/display/intel_display_device.h | 1 +
drivers/gpu/drm/i915/display/intel_psr.c | 20 +++++++++++++++++---
drivers/gpu/drm/i915/display/intel_psr.h | 1 +
drivers/gpu/drm/i915/display/intel_vrr.c | 35 +++++++++++++++++++++++++++++------
drivers/gpu/drm/i915/display/intel_vrr.h | 1 +
drivers/gpu/drm/i915/display/intel_vrr_regs.h | 1 +
7 files changed, 53 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -747,7 +747,9 @@ void intel_pipe_update_end(struct intel_atomic_state *state,
* push to affect the next frame instead of the current frame,
* which would cause the next frame to terminate already at vmin
* vblank start instead of vmax vblank start.
*/
- if (!state->base.legacy_cursor_update)
+ if (!state->base.legacy_cursor_update ||
+ (intel_psr_use_trans_push(new_crtc_state) &&
+ !new_crtc_state->vrr.enable))
intel_vrr_send_push(NULL, new_crtc_state);
local_irq_enable();
diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h
--- a/drivers/gpu/drm/i915/display/intel_display_device.h
+++ b/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -186,6 +186,7 @@ struct intel_display_platforms {
#define HAS_PSR(__display) (DISPLAY_INFO(__display)->has_psr)
#define HAS_PSR_HW_TRACKING(__display) (DISPLAY_INFO(__display)->has_psr_hw_tracking)
#define HAS_PSR2_SEL_FETCH(__display) (DISPLAY_VER(__display) >= 12)
+#define HAS_PSR_TRANS_PUSH_FRAME_CHANGE(__display) (DISPLAY_VER(__display) >= 20)
#define HAS_SAGV(__display) (DISPLAY_VER(__display) >= 9 && \
!(__display)->platform.broxton && !(__display)->platform.geminilake)
#define HAS_TRANSCODER(__display, trans) ((DISPLAY_RUNTIME_INFO(__display)->cpu_transcoder_mask & \
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2130,5 +2130,8 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
intel_alpm_configure(intel_dp, crtc_state);
+
+ if (HAS_PSR_TRANS_PUSH_FRAME_CHANGE(display))
+ intel_vrr_psr_frame_change_enable(crtc_state);
}
static bool psr_interrupt_error_check(struct intel_dp *intel_dp)
@@ -2522,10 +2525,12 @@ void intel_psr_trigger_frame_change_event(struct intel_dsb *dsb,
const struct intel_crtc_state *crtc_state =
intel_pre_commit_crtc_state(state, crtc);
struct intel_display *display = to_intel_display(crtc);
- if (crtc_state->has_psr)
- intel_de_write_dsb(display, dsb,
- CURSURFLIVE(display, crtc->pipe), 0);
+ if (!crtc_state->has_psr || intel_psr_use_trans_push(crtc_state))
+ return;
+
+ intel_de_write_dsb(display, dsb,
+ CURSURFLIVE(display, crtc->pipe), 0);
}
/**
@@ -4615,3 +4620,10 @@ int intel_psr_min_guardband(struct intel_crtc_state *crtc_state)
return psr_min_guardband;
}
+
+bool intel_psr_use_trans_push(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_display *display = to_intel_display(crtc_state);
+
+ return HAS_PSR_TRANS_PUSH_FRAME_CHANGE(display) && crtc_state->has_psr;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
--- a/drivers/gpu/drm/i915/display/intel_psr.h
+++ b/drivers/gpu/drm/i915/display/intel_psr.h
@@ -80,5 +80,6 @@ bool intel_psr_needs_alpm_aux_less(struct intel_dp *intel_dp,
void intel_psr_compute_config_late(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state);
int intel_psr_min_guardband(struct intel_crtc_state *crtc_state);
+bool intel_psr_use_trans_push(const struct intel_crtc_state *crtc_state);
#endif /* __INTEL_PSR_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -688,21 +688,40 @@ intel_vrr_dcb_reset(const struct intel_crtc_state *old_crtc_state,
intel_de_write(display, PIPEDMC_DCB_BALANCE_RESET(pipe), 0);
}
+static u32 trans_vrr_push(const struct intel_crtc_state *crtc_state,
+ bool send_push)
+{
+ struct intel_display *display = to_intel_display(crtc_state);
+ u32 trans_vrr_push = 0;
+
+ if (intel_vrr_always_use_vrr_tg(display) ||
+ crtc_state->vrr.enable)
+ trans_vrr_push |= TRANS_PUSH_EN;
+
+ if (send_push)
+ trans_vrr_push |= TRANS_PUSH_SEND;
+
+ if (HAS_PSR_TRANS_PUSH_FRAME_CHANGE(display))
+ trans_vrr_push |= LNL_TRANS_PUSH_PSR_PR_EN;
+
+ return trans_vrr_push;
+}
+
void intel_vrr_send_push(struct intel_dsb *dsb,
const struct intel_crtc_state *crtc_state)
{
struct intel_display *display = to_intel_display(crtc_state);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
- if (!crtc_state->vrr.enable)
+ if (!crtc_state->vrr.enable && !intel_psr_use_trans_push(crtc_state))
return;
if (dsb)
intel_dsb_nonpost_start(dsb);
intel_de_write_dsb(display, dsb,
TRANS_PUSH(display, cpu_transcoder),
- TRANS_PUSH_EN | TRANS_PUSH_SEND);
+ trans_vrr_push(crtc_state, true));
if (dsb)
intel_dsb_nonpost_end(dsb);
@@ -888,7 +907,8 @@ static void intel_vrr_tg_enable(const struct intel_crtc_state *crtc_state,
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
u32 vrr_ctl;
- intel_de_write(display, TRANS_PUSH(display, cpu_transcoder), TRANS_PUSH_EN);
+ intel_de_write(display, TRANS_PUSH(display, cpu_transcoder),
+ trans_vrr_push(crtc_state, false));
vrr_ctl = VRR_CTL_VRR_ENABLE | trans_vrr_ctl(crtc_state);
@@ -919,1 +939,2 @@ static void intel_vrr_tg_disable(const struct intel_crtc_state *old_crtc_state)
- intel_de_write(display, TRANS_PUSH(display, cpu_transcoder), 0);
+ intel_de_rmw(display, TRANS_PUSH(display, cpu_transcoder),
+ TRANS_PUSH_EN, 0);
@@ -970,6 +991,15 @@ void intel_vrr_transcoder_disable(const struct intel_crtc_state *old_crtc_state)
intel_vrr_tg_disable(old_crtc_state);
}
+void intel_vrr_psr_frame_change_enable(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_display *display = to_intel_display(crtc_state);
+ enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
+
+ intel_de_write(display, TRANS_PUSH(display, cpu_transcoder),
+ trans_vrr_push(crtc_state, false));
+}
+
bool intel_vrr_is_fixed_rr(const struct intel_crtc_state *crtc_state)
{
return crtc_state->vrr.flipline &&
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/drm/i915/display/intel_vrr.h
--- a/drivers/gpu/drm/i915/display/intel_vrr.h
+++ b/drivers/gpu/drm/i915/display/intel_vrr.h
@@ -30,5 +30,6 @@ void intel_vrr_dcb_increment_flip_count(struct intel_crtc_state *crtc_state,
bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state);
void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state);
+void intel_vrr_psr_frame_change_enable(const struct intel_crtc_state *crtc_state);
void intel_vrr_get_config(struct intel_crtc_state *crtc_state);
int intel_vrr_vmax_vtotal(const struct intel_crtc_state *crtc_state);
int intel_vrr_vmin_vtotal(const struct intel_crtc_state *crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_vrr_regs.h b/drivers/gpu/drm/i915/display/intel_vrr_regs.h
--- a/drivers/gpu/drm/i915/display/intel_vrr_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_vrr_regs.h
@@ -97,6 +97,7 @@
@@ -163,6 +163,7 @@
#define TRANS_PUSH(display, trans) _MMIO_TRANS2((display), (trans), _TRANS_PUSH_A)
#define TRANS_PUSH_EN REG_BIT(31)
#define TRANS_PUSH_SEND REG_BIT(30)
@@ -23,38 +196,3 @@ diff --git a/drivers/gpu/drm/i915/display/intel_vrr_regs.h b/drivers/gpu/drm/i91
#define _TRANS_VRR_VSYNC_A 0x60078
#define TRANS_VRR_VSYNC(display, trans) _MMIO_TRANS2((display), (trans), _TRANS_VRR_VSYNC_A)
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -732,7 +732,8 @@
* which would cause the next frame to terminate already at vmin
* vblank start instead of vmax vblank start.
*/
- if (!state->base.legacy_cursor_update)
+ if (!state->base.legacy_cursor_update ||
+ new_crtc_state->has_panel_replay)
intel_vrr_send_push(NULL, new_crtc_state);
local_irq_enable();
diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -597,7 +597,7 @@
struct intel_display *display = to_intel_display(crtc_state);
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
- if (!crtc_state->vrr.enable)
+ if (!crtc_state->vrr.enable && !crtc_state->has_panel_replay)
return;
if (dsb)
@@ -605,7 +605,8 @@
intel_de_write_dsb(display, dsb,
TRANS_PUSH(display, cpu_transcoder),
- TRANS_PUSH_EN | TRANS_PUSH_SEND);
+ TRANS_PUSH_EN | TRANS_PUSH_SEND |
+ (crtc_state->has_panel_replay ? LNL_TRANS_PUSH_PSR_PR_EN : 0));
if (dsb)
intel_dsb_nonpost_end(dsb);
@@ -61,19 +61,19 @@ Signed-off-by: Gaggery Tsai <gaggery.tsai@intel.com>
enum fb_op_origin origin);
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1217,6 +1217,8 @@ static void tgl_psr2_enable_dc3co(struct intel_dp *intel_dp)
@@ -1189,6 +1189,8 @@ static void tgl_psr2_disable_dc3co(struct intel_dp *intel_dp)
intel_display_power_set_target_dc_state(display, DC_STATE_EN_UPTO_DC6);
psr2_program_idle_frames(intel_dp, psr_compute_idle_frames(intel_dp));
}
+static void intel_psr_activate(struct intel_dp *intel_dp);
+
+static void intel_psr_activate(struct intel_dp *intel_dp);
static void tgl_dc3co_disable_work(struct work_struct *work)
{
struct intel_dp *intel_dp =
@@ -1227,6 +1229,13 @@ static void tgl_dc3co_disable_work(struct work_struct *work)
@@ -1203,6 +1205,13 @@ static void tgl_dc3co_disable_work(struct work_struct *work)
if (delayed_work_pending(&intel_dp->psr.dc3co_work))
goto unlock;
+ /* Panel Replay ALPM cursor-lag workaround re-activation path. */
+ if (intel_dp->psr.panel_replay_enabled &&
+ intel_dp->psr.enabled && !intel_dp->psr.active) {
@@ -84,7 +84,7 @@ Signed-off-by: Gaggery Tsai <gaggery.tsai@intel.com>
tgl_psr2_disable_dc3co(intel_dp);
unlock:
mutex_unlock(&intel_dp->psr.lock);
@@ -4593,2 +4593,29 @@ u8 intel_psr_needed_vblank_count_for_frontbuffer_flush(struct intel_display *dis
@@ -4615,2 +4624,29 @@ int intel_psr_min_guardband(struct intel_crtc_state *crtc_state)
return psr_min_guardband;
}
+
+10 -25
View File
@@ -2,9 +2,9 @@
# Based on Arch Linux linux package by Jan Alexander Steffens (heftig)
pkgbase=linux-ptl
pkgver=6.19.14.arch1
pkgver=7.0.2.arch1
pkgrel=1
pkgdesc='Linux with Panther Lake hardware backports (SDCA audio, WiFi 7, PSR2, Panel Replay SU)'
pkgdesc='Linux with Panther Lake hardware backports (SDCA audio, PSR2, Panel Replay SU)'
url='https://github.com/archlinux/linux'
arch=(
x86_64
@@ -30,21 +30,10 @@ _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
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
0019-drm-i915-psr-accept-early-transport-for-psr2.patch
0020-drm-i915-psr-fix-su-granularity-source-for-psr2.patch
0020-drm-i915-alpm-limit-pr-alpm-to-panel-replay.patch
0022-drm-i915-psr-allow-psr-with-vrr-on-ptl.patch
0026-drm-i915-psr-handle-Panel-Replay-full-line-SU-granul.patch
0027-drm-i915-trans-push-frame-change-for-panel-replay.patch
0028-drm-i915-psr-exit-Panel-Replay-for-ALPM-lag.patch
0029-drm-edid-populate-monitor-range-from-displayid-adaptive-sync.patch
@@ -55,23 +44,19 @@ validpgpkeys=(
647F28654894E3BD457199BE38DBBDC86092693E # Greg Kroah-Hartman
83BC8889351B5DEBBB68416EB8AC08600F108CDF # Jan Alexander Steffens (heftig)
)
b2sums=('64c2a0003d8080f268772d36923ff6ef8b2d55320ea08b77ad39384c98c9a5c1a8e71425470619aa3aa4dda8941f46aa9da364748cfa8fd9f8507a5ddd7ac03a'
b2sums=('SKIP'
'SKIP'
'6536f9ccb408f89b0a6dc86fdbb09f4229e9e4ea5ed210d118484a18ca8a82a1e1060114877ce7286b721d59587a8a70b5ed4616c4ec4925b0bdf5b25227e6fe'
'SKIP'
'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP'
'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP'
'SKIP' 'SKIP')
'SKIP'
'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP')
b2sums_x86_64=('9742088ab0381d8196046e42e8acb4ce01ea77461fada77dc90d197e859631e73b06ead4d512f15ab619b33ebad7bca58a10d4506d66916a99c40f9f52708a53')
# https://www.kernel.org/pub/linux/kernel/v6.x/sha256sums.asc
sha256sums=('cde8bf6739be4a0777fedbbba5330b8188c55680c45a922a4dfa289cbec6f185'
# https://www.kernel.org/pub/linux/kernel/v7.x/sha256sums.asc
sha256sums=('53591a03294527a48ccb0b9e559e922df8a38554745a1206827ca751d2ca7662'
'SKIP'
'2ae741a9e5009d21e1bbbb7a9abeebcc39ec5cdb7cf4cdf52d616a57d262de96'
'SKIP'
'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP'
'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP'
'SKIP' 'SKIP')
'SKIP'
'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP')
export KBUILD_BUILD_HOST=archlinux
export KBUILD_BUILD_USER=$pkgbase