* [PATCH v2 2/3] iio: adc: xilinx-ams: use guard(mutex) for automatic locking
From: Guilherme Ivo Bozi @ 2026-04-14 10:29 UTC (permalink / raw)
To: Salih Erim, Conall O'Griofa, Jonathan Cameron, Michal Simek
Cc: David Lechner, Nuno Sá, Andy Shevchenko, linux-iio,
linux-arm-kernel, linux-kernel, Guilherme Ivo Bozi,
Andy Shevchenko
In-Reply-To: <20260414103316.18455-1-guilherme.bozi@usp.br>
Replace open-coded mutex_lock()/mutex_unlock() pairs with
guard(mutex) to simplify locking and ensure proper unlock on
all control flow paths.
This removes explicit unlock handling, reduces boilerplate,
and avoids potential mistakes in error paths while keeping
the behavior unchanged.
Signed-off-by: Guilherme Ivo Bozi <guilherme.bozi@usp.br>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
---
drivers/iio/adc/xilinx-ams.c | 24 ++++++++----------------
1 file changed, 8 insertions(+), 16 deletions(-)
diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
index f364e69a5a0d..1d84310b61a9 100644
--- a/drivers/iio/adc/xilinx-ams.c
+++ b/drivers/iio/adc/xilinx-ams.c
@@ -720,22 +720,20 @@ static int ams_read_raw(struct iio_dev *indio_dev,
int ret;
switch (mask) {
- case IIO_CHAN_INFO_RAW:
- mutex_lock(&ams->lock);
+ case IIO_CHAN_INFO_RAW: {
+ guard(mutex)(&ams->lock);
if (chan->scan_index >= AMS_CTRL_SEQ_BASE) {
ret = ams_read_vcc_reg(ams, chan->address, val);
if (ret)
- goto unlock_mutex;
+ return ret;
ams_enable_channel_sequence(indio_dev);
} else if (chan->scan_index >= AMS_PS_SEQ_MAX)
*val = readl(ams->pl_base + chan->address);
else
*val = readl(ams->ps_base + chan->address);
- ret = IIO_VAL_INT;
-unlock_mutex:
- mutex_unlock(&ams->lock);
- return ret;
+ return IIO_VAL_INT;
+ }
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_VOLTAGE:
@@ -939,7 +937,7 @@ static int ams_write_event_config(struct iio_dev *indio_dev,
alarm = ams_get_alarm_mask(chan->scan_index);
- mutex_lock(&ams->lock);
+ guard(mutex)(&ams->lock);
if (state)
ams->alarm_mask |= alarm;
@@ -948,8 +946,6 @@ static int ams_write_event_config(struct iio_dev *indio_dev,
ams_update_alarm(ams, ams->alarm_mask);
- mutex_unlock(&ams->lock);
-
return 0;
}
@@ -962,15 +958,13 @@ static int ams_read_event_value(struct iio_dev *indio_dev,
struct ams *ams = iio_priv(indio_dev);
unsigned int offset = ams_get_alarm_offset(chan->scan_index, dir);
- mutex_lock(&ams->lock);
+ guard(mutex)(&ams->lock);
if (chan->scan_index >= AMS_PS_SEQ_MAX)
*val = readl(ams->pl_base + offset);
else
*val = readl(ams->ps_base + offset);
- mutex_unlock(&ams->lock);
-
return IIO_VAL_INT;
}
@@ -983,7 +977,7 @@ static int ams_write_event_value(struct iio_dev *indio_dev,
struct ams *ams = iio_priv(indio_dev);
unsigned int offset;
- mutex_lock(&ams->lock);
+ guard(mutex)(&ams->lock);
/* Set temperature channel threshold to direct threshold */
if (chan->type == IIO_TEMP) {
@@ -1005,8 +999,6 @@ static int ams_write_event_value(struct iio_dev *indio_dev,
else
writel(val, ams->ps_base + offset);
- mutex_unlock(&ams->lock);
-
return 0;
}
--
2.47.3
^ permalink raw reply related
* [PATCH v2 3/3] iio: adc: xilinx-ams: refactor alarm mapping to table-driven approach
From: Guilherme Ivo Bozi @ 2026-04-14 10:29 UTC (permalink / raw)
To: Salih Erim, Conall O'Griofa, Jonathan Cameron, Michal Simek
Cc: David Lechner, Nuno Sá, Andy Shevchenko, linux-iio,
linux-arm-kernel, linux-kernel, Guilherme Ivo Bozi
In-Reply-To: <20260414103316.18455-1-guilherme.bozi@usp.br>
Replace multiple open-coded switch statements that map between
scan_index, alarm bits, and register offsets with a centralized
table-driven approach.
Introduce a struct-based alarm_map to describe the relationship
between scan indices and alarm offsets, and add a helper to
translate scan_index to event IDs. This removes duplicated logic
across ams_get_alarm_offset(), ams_event_to_channel(), and
ams_get_alarm_mask().
The new approach improves maintainability, reduces code size,
and makes it easier to extend or modify alarm mappings in the
future, while preserving existing behavior.
Signed-off-by: Guilherme Ivo Bozi <guilherme.bozi@usp.br>
---
drivers/iio/adc/xilinx-ams.c | 161 +++++++++++++----------------------
1 file changed, 58 insertions(+), 103 deletions(-)
diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
index 1d84310b61a9..90343d94cf95 100644
--- a/drivers/iio/adc/xilinx-ams.c
+++ b/drivers/iio/adc/xilinx-ams.c
@@ -102,6 +102,7 @@
#define AMS_PS_SEQ_MASK GENMASK(21, 0)
#define AMS_PL_SEQ_MASK GENMASK_ULL(59, 22)
+#define AMS_ALARM_NONE 0x000 /* not a real offset */
#define AMS_ALARM_TEMP 0x140
#define AMS_ALARM_SUPPLY1 0x144
#define AMS_ALARM_SUPPLY2 0x148
@@ -763,9 +764,49 @@ static int ams_read_raw(struct iio_dev *indio_dev,
}
}
+struct ams_alarm_map {
+ enum ams_ps_pl_seq scan_index;
+ unsigned int base_offset;
+};
+
+/*
+ * Array index matches enum ams_alarm_bit.
+ * Entries with base_offset == AMS_ALARM_NONE are unused/invalid
+ * (e.g. RESERVED) and must be skipped.
+ */
+static const struct ams_alarm_map alarm_map[] = {
+ [AMS_ALARM_BIT_TEMP] = { AMS_SEQ_TEMP, AMS_ALARM_TEMP },
+ [AMS_ALARM_BIT_SUPPLY1] = { AMS_SEQ_SUPPLY1, AMS_ALARM_SUPPLY1 },
+ [AMS_ALARM_BIT_SUPPLY2] = { AMS_SEQ_SUPPLY2, AMS_ALARM_SUPPLY2 },
+ [AMS_ALARM_BIT_SUPPLY3] = { AMS_SEQ_SUPPLY3, AMS_ALARM_SUPPLY3 },
+ [AMS_ALARM_BIT_SUPPLY4] = { AMS_SEQ_SUPPLY4, AMS_ALARM_SUPPLY4 },
+ [AMS_ALARM_BIT_SUPPLY5] = { AMS_SEQ_SUPPLY5, AMS_ALARM_SUPPLY5 },
+ [AMS_ALARM_BIT_SUPPLY6] = { AMS_SEQ_SUPPLY6, AMS_ALARM_SUPPLY6 },
+ [AMS_ALARM_BIT_RESERVED] = { 0, AMS_ALARM_NONE },
+ [AMS_ALARM_BIT_SUPPLY7] = { AMS_SEQ_SUPPLY7, AMS_ALARM_SUPPLY7 },
+ [AMS_ALARM_BIT_SUPPLY8] = { AMS_SEQ_SUPPLY8, AMS_ALARM_SUPPLY8 },
+ [AMS_ALARM_BIT_SUPPLY9] = { AMS_SEQ_SUPPLY9, AMS_ALARM_SUPPLY9 },
+ [AMS_ALARM_BIT_SUPPLY10] = { AMS_SEQ_SUPPLY10, AMS_ALARM_SUPPLY10 },
+ [AMS_ALARM_BIT_VCCAMS] = { AMS_SEQ_VCCAMS, AMS_ALARM_VCCAMS },
+ [AMS_ALARM_BIT_TEMP_REMOTE] = { AMS_SEQ_TEMP_REMOTE, AMS_ALARM_TEMP_REMOTE }
+};
+
+static int ams_scan_index_to_event(int scan_index)
+{
+ for (unsigned int i = 0; i < ARRAY_SIZE(alarm_map); i++) {
+ if (alarm_map[i].base_offset == AMS_ALARM_NONE)
+ continue;
+
+ if (alarm_map[i].scan_index == scan_index)
+ return i;
+ }
+
+ return -EINVAL;
+}
+
static int ams_get_alarm_offset(int scan_index, enum iio_event_direction dir)
{
- int offset;
+ int offset, event;
if (scan_index >= AMS_PS_SEQ_MAX)
scan_index -= AMS_PS_SEQ_MAX;
@@ -779,36 +820,11 @@ static int ams_get_alarm_offset(int scan_index, enum iio_event_direction dir)
offset = 0;
}
- switch (scan_index) {
- case AMS_SEQ_TEMP:
- return AMS_ALARM_TEMP + offset;
- case AMS_SEQ_SUPPLY1:
- return AMS_ALARM_SUPPLY1 + offset;
- case AMS_SEQ_SUPPLY2:
- return AMS_ALARM_SUPPLY2 + offset;
- case AMS_SEQ_SUPPLY3:
- return AMS_ALARM_SUPPLY3 + offset;
- case AMS_SEQ_SUPPLY4:
- return AMS_ALARM_SUPPLY4 + offset;
- case AMS_SEQ_SUPPLY5:
- return AMS_ALARM_SUPPLY5 + offset;
- case AMS_SEQ_SUPPLY6:
- return AMS_ALARM_SUPPLY6 + offset;
- case AMS_SEQ_SUPPLY7:
- return AMS_ALARM_SUPPLY7 + offset;
- case AMS_SEQ_SUPPLY8:
- return AMS_ALARM_SUPPLY8 + offset;
- case AMS_SEQ_SUPPLY9:
- return AMS_ALARM_SUPPLY9 + offset;
- case AMS_SEQ_SUPPLY10:
- return AMS_ALARM_SUPPLY10 + offset;
- case AMS_SEQ_VCCAMS:
- return AMS_ALARM_VCCAMS + offset;
- case AMS_SEQ_TEMP_REMOTE:
- return AMS_ALARM_TEMP_REMOTE + offset;
- default:
+ event = ams_scan_index_to_event(scan_index);
+ if (event < 0 || alarm_map[event].base_offset == AMS_ALARM_NONE)
return 0;
- }
+
+ return alarm_map[event].base_offset + offset;
}
static const struct iio_chan_spec *ams_event_to_channel(struct iio_dev *dev,
@@ -821,49 +837,13 @@ static const struct iio_chan_spec *ams_event_to_channel(struct iio_dev *dev,
scan_index = AMS_PS_SEQ_MAX;
}
- switch (event) {
- case AMS_ALARM_BIT_TEMP:
- scan_index += AMS_SEQ_TEMP;
- break;
- case AMS_ALARM_BIT_SUPPLY1:
- scan_index += AMS_SEQ_SUPPLY1;
- break;
- case AMS_ALARM_BIT_SUPPLY2:
- scan_index += AMS_SEQ_SUPPLY2;
- break;
- case AMS_ALARM_BIT_SUPPLY3:
- scan_index += AMS_SEQ_SUPPLY3;
- break;
- case AMS_ALARM_BIT_SUPPLY4:
- scan_index += AMS_SEQ_SUPPLY4;
- break;
- case AMS_ALARM_BIT_SUPPLY5:
- scan_index += AMS_SEQ_SUPPLY5;
- break;
- case AMS_ALARM_BIT_SUPPLY6:
- scan_index += AMS_SEQ_SUPPLY6;
- break;
- case AMS_ALARM_BIT_SUPPLY7:
- scan_index += AMS_SEQ_SUPPLY7;
- break;
- case AMS_ALARM_BIT_SUPPLY8:
- scan_index += AMS_SEQ_SUPPLY8;
- break;
- case AMS_ALARM_BIT_SUPPLY9:
- scan_index += AMS_SEQ_SUPPLY9;
- break;
- case AMS_ALARM_BIT_SUPPLY10:
- scan_index += AMS_SEQ_SUPPLY10;
- break;
- case AMS_ALARM_BIT_VCCAMS:
- scan_index += AMS_SEQ_VCCAMS;
- break;
- case AMS_ALARM_BIT_TEMP_REMOTE:
- scan_index += AMS_SEQ_TEMP_REMOTE;
- break;
- default:
- break;
- }
+ if (event < 0 || event >= ARRAY_SIZE(alarm_map))
+ return NULL;
+
+ if (alarm_map[event].base_offset == AMS_ALARM_NONE)
+ return NULL;
+
+ scan_index += alarm_map[event].scan_index;
for (i = 0; i < dev->num_channels; i++)
if (dev->channels[i].scan_index == scan_index)
@@ -877,43 +857,18 @@ static const struct iio_chan_spec *ams_event_to_channel(struct iio_dev *dev,
static int ams_get_alarm_mask(int scan_index)
{
- int bit = 0;
+ int bit = 0, event;
if (scan_index >= AMS_PS_SEQ_MAX) {
bit = AMS_PL_ALARM_START;
scan_index -= AMS_PS_SEQ_MAX;
}
- switch (scan_index) {
- case AMS_SEQ_TEMP:
- return BIT(AMS_ALARM_BIT_TEMP + bit);
- case AMS_SEQ_SUPPLY1:
- return BIT(AMS_ALARM_BIT_SUPPLY1 + bit);
- case AMS_SEQ_SUPPLY2:
- return BIT(AMS_ALARM_BIT_SUPPLY2 + bit);
- case AMS_SEQ_SUPPLY3:
- return BIT(AMS_ALARM_BIT_SUPPLY3 + bit);
- case AMS_SEQ_SUPPLY4:
- return BIT(AMS_ALARM_BIT_SUPPLY4 + bit);
- case AMS_SEQ_SUPPLY5:
- return BIT(AMS_ALARM_BIT_SUPPLY5 + bit);
- case AMS_SEQ_SUPPLY6:
- return BIT(AMS_ALARM_BIT_SUPPLY6 + bit);
- case AMS_SEQ_SUPPLY7:
- return BIT(AMS_ALARM_BIT_SUPPLY7 + bit);
- case AMS_SEQ_SUPPLY8:
- return BIT(AMS_ALARM_BIT_SUPPLY8 + bit);
- case AMS_SEQ_SUPPLY9:
- return BIT(AMS_ALARM_BIT_SUPPLY9 + bit);
- case AMS_SEQ_SUPPLY10:
- return BIT(AMS_ALARM_BIT_SUPPLY10 + bit);
- case AMS_SEQ_VCCAMS:
- return BIT(AMS_ALARM_BIT_VCCAMS + bit);
- case AMS_SEQ_TEMP_REMOTE:
- return BIT(AMS_ALARM_BIT_TEMP_REMOTE + bit);
- default:
+ event = ams_scan_index_to_event(scan_index);
+ if (event < 0)
return 0;
- }
+
+ return BIT(event + bit);
}
static int ams_read_event_config(struct iio_dev *indio_dev,
--
2.47.3
^ permalink raw reply related
* [GIT PULL] pmdomain updates for v7.1
From: Ulf Hansson @ 2026-04-14 10:38 UTC (permalink / raw)
To: Linus, linux-pm, linux-kernel; +Cc: Ulf Hansson, linux-arm-kernel
Hi Linus,
Here's the pull-request with pmdomain updates for v7.1. Details about the
highlights are as usual found in the signed tag.
Please pull this in!
Kind regards
Ulf Hansson
The following changes since commit e91d5f94acf68618ea3ad9c92ac28614e791ae7d:
pmdomain: imx8mp-blk-ctrl: Keep the NOC_HDCP clock enabled (2026-04-01 13:03:07 +0200)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm.git tags/pmdomain-v7.1
for you to fetch changes up to 596ca99cf04f339db2ed18a5bb230ee11a47b699:
pmdomain: qcom: rpmhpd: Add power domains for Hawi SoC (2026-04-08 12:01:37 +0200)
----------------------------------------------------------------
pmdomain core:
- Extend statistics for domain idle states with s2idle data
- Show latency/residency for domain idle states in debugfs
pmdomain providers:
- imx: Add support for optional subnodes for imx93-blk-ctrl
- marvell: Add audio power island for Marvell PXA1908
- mediatek: Add legacy support for the MT7622 audio power domain
- mediatek: Add nvmem provider functionality to the mtk-mfg-pmdomain
- mediatek: Add support for the MT8189 power domains
- qcom: Add support for the Eliza and Hawi power domains
- sunxi: Add support for the Allwinner A733 power domains
- ti: Handle wakeup constraints for out-of-band wakeups for ti_sci
----------------------------------------------------------------
Abel Vesa (2):
dt-bindings: power: qcom,rpmpd: document the Eliza RPMh Power Domains
pmdomain: qcom: rpmhpd: Add Eliza RPMh Power Domains
AngeloGioacchino Del Regno (2):
dt-bindings: power: mt7622-power: Add MT7622_POWER_DOMAIN_AUDIO
pmdomain: mediatek: scpsys: Add MT7622 Audio power domain to legacy driver
Chris Morgan (1):
pmdomain: rockchip: quiet regulator error on -EPROBE_DEFER
Dmitry Baryshkov (1):
PM: domains: De-constify fields in struct dev_pm_domain_attach_data
Felix Gu (2):
pmdomain: ti: omap_prm: Fix a reference leak on device node
pmdomain: imx: scu-pd: Fix device_node reference leak during ->probe()
Fenglin Wu (2):
dt-bindings: power: qcom,rpmhpd: Add RPMh power domain for Hawi SoC
pmdomain: qcom: rpmhpd: Add power domains for Hawi SoC
Gabor Juhos (1):
pmdomain: qcom: rpmpd: drop stray semicolon
Irving-CH Lin (3):
dt-bindings: power: Add MediaTek MT8189 power domain
pmdomain: mediatek: Add bus protect control flow for MT8189
pmdomain: mediatek: Add power domain driver for MT8189 SoC
Karel Balej (2):
dt-bindings: power: define ID for Marvell PXA1908 audio domain
pmdomain: add audio power island for Marvell PXA1908 SoC
Kendall Willis (1):
pmdomain: ti_sci: handle wakeup constraint for out-of-band wakeup
Krzysztof Kozlowski (1):
pmdomain: mediatek: Simplify with scoped for each OF child loop
Marco Felsch (3):
pmdomain: imx93-blk-ctrl: cleanup error path
pmdomain: imx93-blk-ctrl: convert to devm_* only
pmdomain: imx93-blk-ctrl: add support for optional subnodes
Maíra Canal (1):
pmdomain: bcm: bcm2835-power: Replace open-coded polling with readl_poll_timeout_atomic()
Nicolas Frattaroli (2):
dt-bindings: power: mt8196-gpufreq: Describe nvmem provider ability
pmdomain: mediatek: mtk-mfg: Expose shader_present as nvmem cell
Rosen Penev (2):
pmdomain: qcom: cpr: simplify main allocation
pmdomain: qcom: cpr: add COMPILE_TEST support
Ulf Hansson (8):
pmdomain: Merge branch dt into next
pmdomain: core: Restructure domain idle states data for genpd in debugfs
pmdomain: core: Show latency/residency for domain idle states in debugfs
pmdomain: core: Extend statistics for domain idle states with s2idle data
pmdomain: arm: Add print after a successful probe for SCMI power domains
pmdomain: Merge branch pmdomain into next
pmdomain: Merge branch fixes into next
pmdomain: Merge branch dt into next
Yuanshen Cao (2):
dt-bindings: power: Add Support for Allwinner A733 PCK600 Power Domain Controller
pmdomain: sunxi: Add support for A733 to Allwinner PCK600 driver
.../bindings/power/allwinner,sun20i-d1-ppu.yaml | 17 +-
.../bindings/power/mediatek,mt8196-gpufreq.yaml | 13 +
.../bindings/power/mediatek,power-controller.yaml | 1 +
.../devicetree/bindings/power/qcom,rpmpd.yaml | 2 +
drivers/pmdomain/arm/scmi_pm_domain.c | 1 +
drivers/pmdomain/bcm/bcm2835-power.c | 25 +-
drivers/pmdomain/core.c | 59 ++-
drivers/pmdomain/imx/imx93-blk-ctrl.c | 77 ++--
drivers/pmdomain/imx/scu-pd.c | 1 +
.../pmdomain/marvell/pxa1908-power-controller.c | 39 +-
drivers/pmdomain/mediatek/mt8189-pm-domains.h | 485 +++++++++++++++++++++
drivers/pmdomain/mediatek/mtk-mfg-pmdomain.c | 59 +++
drivers/pmdomain/mediatek/mtk-pm-domains.c | 44 +-
drivers/pmdomain/mediatek/mtk-pm-domains.h | 5 +
drivers/pmdomain/mediatek/mtk-scpsys.c | 10 +
drivers/pmdomain/qcom/Kconfig | 2 +-
drivers/pmdomain/qcom/cpr.c | 13 +-
drivers/pmdomain/qcom/rpmhpd.c | 58 +++
drivers/pmdomain/qcom/rpmpd.c | 2 +-
drivers/pmdomain/rockchip/pm-domains.c | 7 +-
drivers/pmdomain/sunxi/sun55i-pck600.c | 35 +-
drivers/pmdomain/ti/omap_prm.c | 1 +
drivers/pmdomain/ti/ti_sci_pm_domains.c | 5 +-
.../power/allwinner,sun60i-a733-pck-600.h | 18 +
include/dt-bindings/power/marvell,pxa1908-power.h | 1 +
include/dt-bindings/power/mediatek,mt8189-power.h | 38 ++
include/dt-bindings/power/mt7622-power.h | 1 +
include/dt-bindings/power/qcom,rpmhpd.h | 12 +
include/linux/pm_domain.h | 5 +-
29 files changed, 932 insertions(+), 104 deletions(-)
create mode 100644 drivers/pmdomain/mediatek/mt8189-pm-domains.h
create mode 100644 include/dt-bindings/power/allwinner,sun60i-a733-pck-600.h
create mode 100644 include/dt-bindings/power/mediatek,mt8189-power.h
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: reset: imx8mq: Add _N suffix to IMX8MQ_RESET_MIPI_CSI*_RESET
From: Robby Cai @ 2026-04-14 10:46 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: p.zabel, robh, krzk+dt, conor+dt, Frank.Li, s.hauer, festevam,
devicetree, kernel, imx, linux-arm-kernel, linux-kernel,
aisheng.dong
In-Reply-To: <20260401-simple-dragonfly-of-will-fedc8c@quoll>
On Wed, Apr 01, 2026 at 09:41:48AM +0200, Krzysztof Kozlowski wrote:
> On Tue, Mar 31, 2026 at 06:13:30PM +0800, Robby Cai wrote:
> > The assert logic of the MIPI CSI reset signals is active-low on i.MX8MQ,
> > but the existing names do not indicate this explicitly. To improve
> > consistency and clarity, append the _N suffix to all
> > IMX8MQ_RESET_MIPI_CSI*_RESET definitions. The deprecated
> > IMX8MQ_RESET_MIPI_CSI*_RESET versions remain temporarily for DT ABI
> > compatibility and will be removed at an appropriate time in the future.
> >
> > Signed-off-by: Robby Cai <robby.cai@nxp.com>
> > ---
> > include/dt-bindings/reset/imx8mq-reset.h | 18 ++++++++++++------
> > 1 file changed, 12 insertions(+), 6 deletions(-)
> >
> > diff --git a/include/dt-bindings/reset/imx8mq-reset.h b/include/dt-bindings/reset/imx8mq-reset.h
> > index 705870693ec2..83a155dbbd4a 100644
> > --- a/include/dt-bindings/reset/imx8mq-reset.h
> > +++ b/include/dt-bindings/reset/imx8mq-reset.h
> > @@ -46,12 +46,18 @@
> > #define IMX8MQ_RESET_PCIEPHY2_PERST 35 /* i.MX8MM/i.MX8MN does NOT support */
> > #define IMX8MQ_RESET_PCIE2_CTRL_APPS_EN 36 /* i.MX8MM/i.MX8MN does NOT support */
> > #define IMX8MQ_RESET_PCIE2_CTRL_APPS_TURNOFF 37 /* i.MX8MM/i.MX8MN does NOT support */
> > -#define IMX8MQ_RESET_MIPI_CSI1_CORE_RESET 38 /* i.MX8MM/i.MX8MN does NOT support */
> > -#define IMX8MQ_RESET_MIPI_CSI1_PHY_REF_RESET 39 /* i.MX8MM/i.MX8MN does NOT support */
> > -#define IMX8MQ_RESET_MIPI_CSI1_ESC_RESET 40 /* i.MX8MM/i.MX8MN does NOT support */
> > -#define IMX8MQ_RESET_MIPI_CSI2_CORE_RESET 41 /* i.MX8MM/i.MX8MN does NOT support */
> > -#define IMX8MQ_RESET_MIPI_CSI2_PHY_REF_RESET 42 /* i.MX8MM/i.MX8MN does NOT support */
> > -#define IMX8MQ_RESET_MIPI_CSI2_ESC_RESET 43 /* i.MX8MM/i.MX8MN does NOT support */
> > +#define IMX8MQ_RESET_MIPI_CSI1_CORE_RESET 38 /* Deprecated. Use *_RESET_N instead */
> > +#define IMX8MQ_RESET_MIPI_CSI1_CORE_RESET_N 38 /* i.MX8MM/i.MX8MN does NOT support */
>
> That's quite a churn for no need. The entire point of these values being
> the binding is that it describes the ABI for SW and DTS, not your
> hardware registers.
>
> Whether signal is active low or high is kind of irrelevant. Linux uses
> it exactly the same way.
>
The original naming was taken from the reference manual at the time.
The upcoming RM revision will clarify that these resets are active-low and
use the _N suffix, consistent with MIPI DSI.
However, I agree that the DT binding and naming need not be changed.
I'll keep the existing binding and naming, and address this in v2 by fixing the
reset logic in the driver only.
Regards,
Robby
^ permalink raw reply
* Re: [PATCH v2 1/2] mmc: dw_mmc: implement option for configuring DMA threshold
From: Kaustabh Chakraborty @ 2026-04-14 10:49 UTC (permalink / raw)
To: Shawn Lin, Kaustabh Chakraborty, Ulf Hansson, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jaehoon Chung,
Krzysztof Kozlowski, Alim Akhtar
Cc: linux-mmc, devicetree, linux-kernel, linux-arm-kernel,
linux-samsung-soc
In-Reply-To: <cec99f99-5ac4-7f0d-8e2a-947edfef8930@rock-chips.com>
On 2026-04-14 16:50 +08:00, Shawn Lin wrote:
> 在 2026/04/14 星期二 16:36, Kaustabh Chakraborty 写道:
>> Some controllers, such as certain Exynos SDIO ones, are unable to
>> perform DMA transfers of small amount of bytes properly. Following the
>> device tree schema, implement the property to define the DMA transfer
>> threshold (from a hard coded value of 16 bytes) so that lesser number of
>> bytes can be transferred safely skipping DMA in such controllers. The
>> value of 16 bytes stays as the default for controllers which do not
>> define it. This value can be overridden by implementation-specific init
>> sequences.
>>
>> Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
>> ---
>> drivers/mmc/host/dw_mmc.c | 5 +++--
>> drivers/mmc/host/dw_mmc.h | 2 ++
>> 2 files changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>> index 20193ee7b73eb..9dd9fed4ccf49 100644
>> --- a/drivers/mmc/host/dw_mmc.c
>> +++ b/drivers/mmc/host/dw_mmc.c
>> @@ -40,7 +40,6 @@
>> SDMMC_INT_RESP_ERR | SDMMC_INT_HLE)
>> #define DW_MCI_ERROR_FLAGS (DW_MCI_DATA_ERROR_FLAGS | \
>> DW_MCI_CMD_ERROR_FLAGS)
>> -#define DW_MCI_DMA_THRESHOLD 16
>>
>> #define DW_MCI_FREQ_MAX 200000000 /* unit: HZ */
>> #define DW_MCI_FREQ_MIN 100000 /* unit: HZ */
>> @@ -821,7 +820,7 @@ static int dw_mci_pre_dma_transfer(struct dw_mci *host,
>> * non-word-aligned buffers or lengths. Also, we don't bother
>> * with all the DMA setup overhead for short transfers.
>> */
>> - if (data->blocks * data->blksz < DW_MCI_DMA_THRESHOLD)
>> + if (data->blocks * data->blksz < host->dma_threshold)
>> return -EINVAL;
>>
>> if (data->blksz & 3)
>> @@ -3245,6 +3244,8 @@ int dw_mci_probe(struct dw_mci *host)
>> goto err_clk_ciu;
>> }
>>
>> + host->dma_threshold = 16;
>
> I'd prefer to set it in dw_mci_alloc_host() instead of picking up
> a random place to put it, for better code management.
Okay, that function is in -next I see.
>
>> +
>> if (host->rstc) {
>> reset_control_assert(host->rstc);
>> usleep_range(10, 50);
>> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
>> index 42e58be74ce09..fc7601fba849f 100644
>> --- a/drivers/mmc/host/dw_mmc.h
>> +++ b/drivers/mmc/host/dw_mmc.h
>> @@ -164,6 +164,8 @@ struct dw_mci {
>> void __iomem *fifo_reg;
>> u32 data_addr_override;
>> bool wm_aligned;
>> + /* Configurable data byte threshold value for DMA transfer. */
>
> No here, there is a long section of comment before struct dw_mci{ } that
> describes each member of it, please add it there.
Ah, you mean the documenting comment. Shouldn't have missed in either
way.
>
>> + u32 dma_threshold;
>>
>> struct scatterlist *sg;
>> struct sg_mapping_iter sg_miter;
>>
^ permalink raw reply
* [PATCH v3 0/6] perf arm_spe: Dump IMPDEF events
From: James Clark @ 2026-04-14 11:04 UTC (permalink / raw)
To: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter
Cc: linux-arm-kernel, linux-perf-users, linux-kernel, James Clark,
Leo Yan, Al Grant
In the Arm SPE raw data dump, IMPDEF events aren't printed. Add the
ability to add names for some known events or print the raw event number
for unknown events.
For example:
$ perf report -D
... ARM SPE data: size 0xd000 bytes
00000000: b0 18 c6 32 80 00 80 ff a0 PC 0xff80008032c618 el1 ns=1
00000009: 64 e7 42 00 00 CONTEXT 0x42e7 el1
0000000e: 00 00 00 00 00 PAD
00000013: 49 00 LD GP-REG
00000015: 52 16 10 EV RETIRED L1D-ACCESS TLB-ACCESS
On N1 the event line becomes:
00000015: 52 16 10 EV RETIRED L1D-ACCESS TLB-ACCESS LATE-PREFETCH
Or on other cores it becomes:
00000015: 52 16 10 EV RETIRED L1D-ACCESS TLB-ACCESS IMPDEF:12
Signed-off-by: James Clark <james.clark@linaro.org>
---
Changes in v3:
- Revert for_each_set_bit() back to a loop with BIT_ULL to fix both 32
bit builds and decoding on big endian machines.
- Link to v2: https://lore.kernel.org/r/20260407-james-spe-impdef-decode-v2-0-55d3ef997c48@linaro.org
Changes in v2:
- Put MIDR in arm_spe_pkt (Leo)
- Use for_each_set_bit() (Leo)
- Use BIT_ULL() to fix 32bit builds (Ian)
- Don't call strtol() with NULL (Ian)
- Link to v1: https://lore.kernel.org/r/20260401-james-spe-impdef-decode-v1-0-ad0d372c220c@linaro.org
---
James Clark (6):
perf arm_spe: Make a function to get the MIDR
perf arm_spe: Handle missing CPU IDs
perf arm_spe: Store MIDR in arm_spe_pkt
perf arm_spe: Turn event name mappings into an array
perf arm_spe: Decode Arm N1 IMPDEF events
perf arm_spe: Print remaining IMPDEF event numbers
tools/perf/util/arm-spe-decoder/Build | 2 +
tools/perf/util/arm-spe-decoder/arm-spe-decoder.c | 17 ++-
tools/perf/util/arm-spe-decoder/arm-spe-decoder.h | 3 +-
.../util/arm-spe-decoder/arm-spe-pkt-decoder.c | 144 ++++++++++++++-------
.../util/arm-spe-decoder/arm-spe-pkt-decoder.h | 5 +-
tools/perf/util/arm-spe.c | 62 ++++++---
6 files changed, 158 insertions(+), 75 deletions(-)
---
base-commit: 4e03d6494f9504f8af46ba68a2a8b6877c196789
change-id: 20260331-james-spe-impdef-decode-d944f4fdcff7
Best regards,
--
James Clark <james.clark@linaro.org>
^ permalink raw reply
* [PATCH v3 1/6] perf arm_spe: Make a function to get the MIDR
From: James Clark @ 2026-04-14 11:04 UTC (permalink / raw)
To: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter
Cc: linux-arm-kernel, linux-perf-users, linux-kernel, James Clark,
Leo Yan
In-Reply-To: <20260414-james-spe-impdef-decode-v3-0-63baf9c893b1@linaro.org>
We'll need the MIDR to dump IMPDEF events in the next commits so extract
a function for it.
No functional changes intended.
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/util/arm-spe.c | 36 ++++++++++++++++++++++--------------
1 file changed, 22 insertions(+), 14 deletions(-)
diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
index e5835042acdf7685f95e19665cd45f97ed868275..39046033e1433cff82ef0668074867aba4a462a4 100644
--- a/tools/perf/util/arm-spe.c
+++ b/tools/perf/util/arm-spe.c
@@ -972,14 +972,9 @@ static void arm_spe__synth_memory_level(struct arm_spe_queue *speq,
}
}
-static void arm_spe__synth_ds(struct arm_spe_queue *speq,
- const struct arm_spe_record *record,
- union perf_mem_data_src *data_src)
+static int arm_spe__get_midr(struct arm_spe *spe, int cpu, u64 *midr)
{
- struct arm_spe *spe = speq->spe;
- u64 *metadata = NULL;
- u64 midr;
- unsigned int i;
+ u64 *metadata;
/* Metadata version 1 assumes all CPUs are the same (old behavior) */
if (spe->metadata_ver == 1) {
@@ -987,15 +982,28 @@ static void arm_spe__synth_ds(struct arm_spe_queue *speq,
pr_warning_once("Old SPE metadata, re-record to improve decode accuracy\n");
cpuid = perf_env__cpuid(perf_session__env(spe->session));
- midr = strtol(cpuid, NULL, 16);
- } else {
- metadata = arm_spe__get_metadata_by_cpu(spe, speq->cpu);
- if (!metadata)
- return;
-
- midr = metadata[ARM_SPE_CPU_MIDR];
+ *midr = strtol(cpuid, NULL, 16);
+ return 0;
}
+ metadata = arm_spe__get_metadata_by_cpu(spe, cpu);
+ if (!metadata)
+ return -EINVAL;
+
+ *midr = metadata[ARM_SPE_CPU_MIDR];
+ return 0;
+}
+
+static void arm_spe__synth_ds(struct arm_spe_queue *speq,
+ const struct arm_spe_record *record,
+ union perf_mem_data_src *data_src)
+{
+ u64 midr;
+ unsigned int i;
+
+ if (arm_spe__get_midr(speq->spe, speq->cpu, &midr))
+ return;
+
for (i = 0; i < ARRAY_SIZE(data_source_handles); i++) {
if (is_midr_in_range_list(midr, data_source_handles[i].midr_ranges)) {
return data_source_handles[i].ds_synth(record, data_src);
--
2.34.1
^ permalink raw reply related
* [PATCH v3 2/6] perf arm_spe: Handle missing CPU IDs
From: James Clark @ 2026-04-14 11:04 UTC (permalink / raw)
To: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter
Cc: linux-arm-kernel, linux-perf-users, linux-kernel, James Clark,
Leo Yan
In-Reply-To: <20260414-james-spe-impdef-decode-v3-0-63baf9c893b1@linaro.org>
Don't call strtol() with a null pointer to avoid undefined behavior.
I'm not sure of the exact scenario for missing CPU IDs but I don't think
it happens in practice. SPE decoding can continue without them with
reduced functionality, but print an error message anyway.
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/util/arm-spe.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
index 39046033e1433cff82ef0668074867aba4a462a4..f9188fdb8e786fccff94cd8a92f367d90efc5cfe 100644
--- a/tools/perf/util/arm-spe.c
+++ b/tools/perf/util/arm-spe.c
@@ -982,16 +982,23 @@ static int arm_spe__get_midr(struct arm_spe *spe, int cpu, u64 *midr)
pr_warning_once("Old SPE metadata, re-record to improve decode accuracy\n");
cpuid = perf_env__cpuid(perf_session__env(spe->session));
+ if (!cpuid)
+ goto err;
+
*midr = strtol(cpuid, NULL, 16);
return 0;
}
metadata = arm_spe__get_metadata_by_cpu(spe, cpu);
if (!metadata)
- return -EINVAL;
+ goto err;
*midr = metadata[ARM_SPE_CPU_MIDR];
return 0;
+
+err:
+ pr_err("Failed to get MIDR for CPU %d\n", cpu);
+ return -EINVAL;
}
static void arm_spe__synth_ds(struct arm_spe_queue *speq,
--
2.34.1
^ permalink raw reply related
* [PATCH v3 3/6] perf arm_spe: Store MIDR in arm_spe_pkt
From: James Clark @ 2026-04-14 11:04 UTC (permalink / raw)
To: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter
Cc: linux-arm-kernel, linux-perf-users, linux-kernel, James Clark,
Leo Yan
In-Reply-To: <20260414-james-spe-impdef-decode-v3-0-63baf9c893b1@linaro.org>
The MIDR will affect printing of arm_spe_pkts, so store a copy of it
there. Technically it's constant for each decoder, but there is no
decoder when doing a raw dump, so it has to be stored in every packet.
It will only be used in raw dump mode and not in normal decoding for
now, but to avoid any surprises, set MIDR properly on the decoder too.
Having both the MIDR and the arm_spe_pkt (which has a copy of it) in the
decoder seemed a bit weird, so remove arm_spe_pkt from the decoder. The
packet is only short lived anyway so probably shouldn't have been there
in the first place.
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/util/arm-spe-decoder/arm-spe-decoder.c | 17 ++++++++++-------
tools/perf/util/arm-spe-decoder/arm-spe-decoder.h | 3 +--
.../perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c | 3 ++-
.../perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h | 3 ++-
tools/perf/util/arm-spe.c | 21 +++++++++++++++------
5 files changed, 30 insertions(+), 17 deletions(-)
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
index 9e02b2bdd1177193996d071dd88f969e25b1ad86..7a3a4815fd37b7f57687189c09c618aaf7ac9801 100644
--- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
@@ -120,7 +120,8 @@ static int arm_spe_get_data(struct arm_spe_decoder *decoder)
return decoder->len;
}
-static int arm_spe_get_next_packet(struct arm_spe_decoder *decoder)
+static int arm_spe_get_next_packet(struct arm_spe_decoder *decoder,
+ struct arm_spe_pkt *packet)
{
int ret;
@@ -134,7 +135,8 @@ static int arm_spe_get_next_packet(struct arm_spe_decoder *decoder)
}
ret = arm_spe_get_packet(decoder->buf, decoder->len,
- &decoder->packet);
+ packet, decoder->midr);
+
if (ret <= 0) {
/* Move forward for 1 byte */
decoder->buf += 1;
@@ -144,7 +146,7 @@ static int arm_spe_get_next_packet(struct arm_spe_decoder *decoder)
decoder->buf += ret;
decoder->len -= ret;
- } while (decoder->packet.type == ARM_SPE_PAD);
+ } while (packet->type == ARM_SPE_PAD);
return 1;
}
@@ -154,19 +156,20 @@ static int arm_spe_read_record(struct arm_spe_decoder *decoder)
int err;
int idx;
u64 payload, ip;
+ struct arm_spe_pkt packet;
memset(&decoder->record, 0x0, sizeof(decoder->record));
decoder->record.context_id = (u64)-1;
while (1) {
- err = arm_spe_get_next_packet(decoder);
+ err = arm_spe_get_next_packet(decoder, &packet);
if (err <= 0)
return err;
- idx = decoder->packet.index;
- payload = decoder->packet.payload;
+ idx = packet.index;
+ payload = packet.payload;
- switch (decoder->packet.type) {
+ switch (packet.type) {
case ARM_SPE_TIMESTAMP:
decoder->record.timestamp = payload;
return 1;
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
index 3310e05122f02e8ef32f79f8ed3c6932cc43eecc..0cbcb501edc9965d34cfd3ede79cab3fd9b318f8 100644
--- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
@@ -147,8 +147,7 @@ struct arm_spe_decoder {
const unsigned char *buf;
size_t len;
-
- struct arm_spe_pkt packet;
+ u64 midr;
};
struct arm_spe_decoder *arm_spe_decoder_new(struct arm_spe_params *params);
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
index 5769ba2f414049161f271fd8b8f40c440d15a75a..718022aecec30bf30a51ba3d2bca9cf6465259a7 100644
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
@@ -222,11 +222,12 @@ static int arm_spe_do_get_packet(const unsigned char *buf, size_t len,
}
int arm_spe_get_packet(const unsigned char *buf, size_t len,
- struct arm_spe_pkt *packet)
+ struct arm_spe_pkt *packet, u64 midr)
{
int ret;
ret = arm_spe_do_get_packet(buf, len, packet);
+ packet->midr = midr;
/* put multiple consecutive PADs on the same line, up to
* the fixed-width output format of 16 bytes per line.
*/
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
index adf4cde320aad01265b5232b0d6ff6b1f752f35f..a457821f3bccb67691cfd530de2f1c5bf9d8d50c 100644
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
@@ -35,6 +35,7 @@ struct arm_spe_pkt {
enum arm_spe_pkt_type type;
unsigned char index;
uint64_t payload;
+ uint64_t midr;
};
/* Short header (HEADER0) and extended header (HEADER1) */
@@ -184,7 +185,7 @@ enum arm_spe_events {
const char *arm_spe_pkt_name(enum arm_spe_pkt_type);
int arm_spe_get_packet(const unsigned char *buf, size_t len,
- struct arm_spe_pkt *packet);
+ struct arm_spe_pkt *packet, u64 midr);
int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf, size_t len);
#endif
diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
index f9188fdb8e786fccff94cd8a92f367d90efc5cfe..ed4515fef2de3dded17befc358c87c2461d397d4 100644
--- a/tools/perf/util/arm-spe.c
+++ b/tools/perf/util/arm-spe.c
@@ -134,8 +134,10 @@ struct data_source_handle {
.ds_synth = arm_spe__synth_##func, \
}
+static int arm_spe__get_midr(struct arm_spe *spe, int cpu, u64 *midr);
+
static void arm_spe_dump(struct arm_spe *spe __maybe_unused,
- unsigned char *buf, size_t len)
+ unsigned char *buf, size_t len, u64 midr)
{
struct arm_spe_pkt packet;
size_t pos = 0;
@@ -148,7 +150,8 @@ static void arm_spe_dump(struct arm_spe *spe __maybe_unused,
len);
while (len) {
- ret = arm_spe_get_packet(buf, len, &packet);
+ ret = arm_spe_get_packet(buf, len, &packet, midr);
+
if (ret > 0)
pkt_len = ret;
else
@@ -174,10 +177,10 @@ static void arm_spe_dump(struct arm_spe *spe __maybe_unused,
}
static void arm_spe_dump_event(struct arm_spe *spe, unsigned char *buf,
- size_t len)
+ size_t len, u64 midr)
{
printf(".\n");
- arm_spe_dump(spe, buf, len);
+ arm_spe_dump(spe, buf, len, midr);
}
static int arm_spe_get_trace(struct arm_spe_buffer *b, void *data)
@@ -302,8 +305,10 @@ static void arm_spe_set_pid_tid_cpu(struct arm_spe *spe,
if (speq->thread) {
speq->pid = thread__pid(speq->thread);
- if (queue->cpu == -1)
+ if (queue->cpu == -1) {
speq->cpu = thread__cpu(speq->thread);
+ arm_spe__get_midr(spe, speq->cpu, &speq->decoder->midr);
+ }
}
}
@@ -1248,6 +1253,7 @@ static int arm_spe__setup_queue(struct arm_spe *spe,
if (queue->cpu != -1)
speq->cpu = queue->cpu;
+ arm_spe__get_midr(spe, queue->cpu, &speq->decoder->midr);
if (!speq->on_heap) {
int ret;
@@ -1490,8 +1496,11 @@ static int arm_spe_process_auxtrace_event(struct perf_session *session,
/* Dump here now we have copied a piped trace out of the pipe */
if (dump_trace) {
if (auxtrace_buffer__get_data(buffer, fd)) {
+ u64 midr = 0;
+
+ arm_spe__get_midr(spe, buffer->cpu.cpu, &midr);
arm_spe_dump_event(spe, buffer->data,
- buffer->size);
+ buffer->size, midr);
auxtrace_buffer__put_data(buffer);
}
}
--
2.34.1
^ permalink raw reply related
* [PATCH v3 4/6] perf arm_spe: Turn event name mappings into an array
From: James Clark @ 2026-04-14 11:04 UTC (permalink / raw)
To: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter
Cc: linux-arm-kernel, linux-perf-users, linux-kernel, James Clark,
Leo Yan
In-Reply-To: <20260414-james-spe-impdef-decode-v3-0-63baf9c893b1@linaro.org>
This is so we can have a single function that prints events and can be
used with multiple mappings from different CPUs. Remove any bit that was
printed so that later we can print out the remaining unknown impdef
bits.
No functional changes intended.
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
.../util/arm-spe-decoder/arm-spe-pkt-decoder.c | 88 +++++++++++-----------
1 file changed, 43 insertions(+), 45 deletions(-)
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
index 718022aecec30bf30a51ba3d2bca9cf6465259a7..67ca356100e53aaf6d47489717537ba27aa2b98e 100644
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
@@ -277,6 +277,48 @@ static int arm_spe_pkt_out_string(int *err, char **buf_p, size_t *blen,
return ret;
}
+struct ev_string {
+ u8 event;
+ const char *desc;
+};
+
+static const struct ev_string common_ev_strings[] = {
+ { .event = EV_EXCEPTION_GEN, .desc = "EXCEPTION-GEN" },
+ { .event = EV_RETIRED, .desc = "RETIRED" },
+ { .event = EV_L1D_ACCESS, .desc = "L1D-ACCESS" },
+ { .event = EV_L1D_REFILL, .desc = "L1D-REFILL" },
+ { .event = EV_TLB_ACCESS, .desc = "TLB-ACCESS" },
+ { .event = EV_TLB_WALK, .desc = "TLB-REFILL" },
+ { .event = EV_NOT_TAKEN, .desc = "NOT-TAKEN" },
+ { .event = EV_MISPRED, .desc = "MISPRED" },
+ { .event = EV_LLC_ACCESS, .desc = "LLC-ACCESS" },
+ { .event = EV_LLC_MISS, .desc = "LLC-REFILL" },
+ { .event = EV_REMOTE_ACCESS, .desc = "REMOTE-ACCESS" },
+ { .event = EV_ALIGNMENT, .desc = "ALIGNMENT" },
+ { .event = EV_TRANSACTIONAL, .desc = "TXN" },
+ { .event = EV_PARTIAL_PREDICATE, .desc = "SVE-PARTIAL-PRED" },
+ { .event = EV_EMPTY_PREDICATE, .desc = "SVE-EMPTY-PRED" },
+ { .event = EV_L2D_ACCESS, .desc = "L2D-ACCESS" },
+ { .event = EV_L2D_MISS, .desc = "L2D-MISS" },
+ { .event = EV_CACHE_DATA_MODIFIED, .desc = "HITM" },
+ { .event = EV_RECENTLY_FETCHED, .desc = "LFB" },
+ { .event = EV_DATA_SNOOPED, .desc = "SNOOPED" },
+ { .event = EV_STREAMING_SVE_MODE, .desc = "STREAMING-SVE" },
+ { .event = EV_SMCU, .desc = "SMCU" },
+ { .event = 0, .desc = NULL },
+};
+
+static u64 print_event_list(int *err, char **buf, size_t *buf_len,
+ const struct ev_string *ev_strings, u64 payload)
+{
+ for (const struct ev_string *ev = ev_strings; ev->desc != NULL; ev++) {
+ if (payload & BIT_ULL(ev->event))
+ arm_spe_pkt_out_string(err, buf, buf_len, " %s", ev->desc);
+ payload &= ~BIT_ULL(ev->event);
+ }
+ return payload;
+}
+
static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
char *buf, size_t buf_len)
{
@@ -284,51 +326,7 @@ static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
int err = 0;
arm_spe_pkt_out_string(&err, &buf, &buf_len, "EV");
-
- if (payload & BIT(EV_EXCEPTION_GEN))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " EXCEPTION-GEN");
- if (payload & BIT(EV_RETIRED))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " RETIRED");
- if (payload & BIT(EV_L1D_ACCESS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-ACCESS");
- if (payload & BIT(EV_L1D_REFILL))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-REFILL");
- if (payload & BIT(EV_TLB_ACCESS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-ACCESS");
- if (payload & BIT(EV_TLB_WALK))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-REFILL");
- if (payload & BIT(EV_NOT_TAKEN))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " NOT-TAKEN");
- if (payload & BIT(EV_MISPRED))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " MISPRED");
- if (payload & BIT(EV_LLC_ACCESS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-ACCESS");
- if (payload & BIT(EV_LLC_MISS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-REFILL");
- if (payload & BIT(EV_REMOTE_ACCESS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " REMOTE-ACCESS");
- if (payload & BIT(EV_ALIGNMENT))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " ALIGNMENT");
- if (payload & BIT(EV_TRANSACTIONAL))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " TXN");
- if (payload & BIT(EV_PARTIAL_PREDICATE))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-PARTIAL-PRED");
- if (payload & BIT(EV_EMPTY_PREDICATE))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-EMPTY-PRED");
- if (payload & BIT(EV_L2D_ACCESS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " L2D-ACCESS");
- if (payload & BIT(EV_L2D_MISS))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " L2D-MISS");
- if (payload & BIT(EV_CACHE_DATA_MODIFIED))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " HITM");
- if (payload & BIT(EV_RECENTLY_FETCHED))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " LFB");
- if (payload & BIT(EV_DATA_SNOOPED))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " SNOOPED");
- if (payload & BIT(EV_STREAMING_SVE_MODE))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " STREAMING-SVE");
- if (payload & BIT(EV_SMCU))
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " SMCU");
+ print_event_list(&err, &buf, &buf_len, common_ev_strings, payload);
return err;
}
--
2.34.1
^ permalink raw reply related
* [PATCH v3 5/6] perf arm_spe: Decode Arm N1 IMPDEF events
From: James Clark @ 2026-04-14 11:04 UTC (permalink / raw)
To: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter
Cc: linux-arm-kernel, linux-perf-users, linux-kernel, James Clark,
Al Grant, Leo Yan
In-Reply-To: <20260414-james-spe-impdef-decode-v3-0-63baf9c893b1@linaro.org>
>From the TRM [1], N1 has one IMPDEF event which isn't covered by the
common list. Add a framework so that more cores can be added in the
future and that the N1 IMPDEF event can be decoded. Also increase the
size of the buffer because we're adding more strings and if it gets
truncated it falls back to a hex dump only.
[1]: https://developer.arm.com/documentation/100616/0401/Statistical-Profiling-Extension/implementation-defined-features-of-SPE
Suggested-by: Al Grant <al.grant@arm.com>
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/util/arm-spe-decoder/Build | 2 ++
.../util/arm-spe-decoder/arm-spe-pkt-decoder.c | 39 +++++++++++++++++++++-
.../util/arm-spe-decoder/arm-spe-pkt-decoder.h | 2 +-
3 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/tools/perf/util/arm-spe-decoder/Build b/tools/perf/util/arm-spe-decoder/Build
index ab500e0efe2449fa2535d6efae2a30bc2690cb9e..97a298d1e2791bb9556cf893bd170ef938bfe631 100644
--- a/tools/perf/util/arm-spe-decoder/Build
+++ b/tools/perf/util/arm-spe-decoder/Build
@@ -1 +1,3 @@
perf-util-y += arm-spe-pkt-decoder.o arm-spe-decoder.o
+
+CFLAGS_arm-spe-pkt-decoder.o += -I$(srctree)/tools/arch/arm64/include/ -I$(OUTPUT)arch/arm64/include/generated/
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
index 67ca356100e53aaf6d47489717537ba27aa2b98e..b74f887a48f2a13b1be165947b4e3293f9987bd4 100644
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
@@ -15,6 +15,8 @@
#include "arm-spe-pkt-decoder.h"
+#include "../../arm64/include/asm/cputype.h"
+
static const char * const arm_spe_packet_name[] = {
[ARM_SPE_PAD] = "PAD",
[ARM_SPE_END] = "END",
@@ -308,6 +310,11 @@ static const struct ev_string common_ev_strings[] = {
{ .event = 0, .desc = NULL },
};
+static const struct ev_string n1_event_strings[] = {
+ { .event = 12, .desc = "LATE-PREFETCH" },
+ { .event = 0, .desc = NULL },
+};
+
static u64 print_event_list(int *err, char **buf, size_t *buf_len,
const struct ev_string *ev_strings, u64 payload)
{
@@ -319,6 +326,26 @@ static u64 print_event_list(int *err, char **buf, size_t *buf_len,
return payload;
}
+struct event_print_handle {
+ const struct midr_range *midr_ranges;
+ const struct ev_string *ev_strings;
+};
+
+#define EV_PRINT(range, strings) \
+ { \
+ .midr_ranges = range, \
+ .ev_strings = strings, \
+ }
+
+static const struct midr_range n1_event_encoding_cpus[] = {
+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
+ {},
+};
+
+static const struct event_print_handle event_print_handles[] = {
+ EV_PRINT(n1_event_encoding_cpus, n1_event_strings),
+};
+
static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
char *buf, size_t buf_len)
{
@@ -326,7 +353,17 @@ static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
int err = 0;
arm_spe_pkt_out_string(&err, &buf, &buf_len, "EV");
- print_event_list(&err, &buf, &buf_len, common_ev_strings, payload);
+ payload = print_event_list(&err, &buf, &buf_len, common_ev_strings,
+ payload);
+
+ /* Try to decode IMPDEF bits for known CPUs */
+ for (unsigned int i = 0; i < ARRAY_SIZE(event_print_handles); i++) {
+ if (is_midr_in_range_list(packet->midr,
+ event_print_handles[i].midr_ranges))
+ payload = print_event_list(&err, &buf, &buf_len,
+ event_print_handles[i].ev_strings,
+ payload);
+ }
return err;
}
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
index a457821f3bccb67691cfd530de2f1c5bf9d8d50c..a3300bec4990a76608d23e34368d6146c9f4a5b5 100644
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
@@ -11,7 +11,7 @@
#include <stddef.h>
#include <stdint.h>
-#define ARM_SPE_PKT_DESC_MAX 256
+#define ARM_SPE_PKT_DESC_MAX 512
#define ARM_SPE_NEED_MORE_BYTES -1
#define ARM_SPE_BAD_PACKET -2
--
2.34.1
^ permalink raw reply related
* [PATCH v3 6/6] perf arm_spe: Print remaining IMPDEF event numbers
From: James Clark @ 2026-04-14 11:04 UTC (permalink / raw)
To: John Garry, Will Deacon, Mike Leach, Leo Yan, Peter Zijlstra,
Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter
Cc: linux-arm-kernel, linux-perf-users, linux-kernel, James Clark,
Al Grant, Leo Yan
In-Reply-To: <20260414-james-spe-impdef-decode-v3-0-63baf9c893b1@linaro.org>
Any IMPDEF events not printed out from a known core's IMPDEF list or for
a completely unknown core will still not be shown to the user. Fix this
by printing the remaining bits as comma separated raw numbers, e.g.
"IMPDEF:1,2,3,4".
Suggested-by: Al Grant <al.grant@arm.com>
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: James Clark <james.clark@linaro.org>
---
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
index b74f887a48f2a13b1be165947b4e3293f9987bd4..600677318f84c06970e4e618280c39cc83ac5b1e 100644
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
@@ -8,6 +8,7 @@
#include <string.h>
#include <endian.h>
#include <byteswap.h>
+#include <linux/bitmap.h>
#include <linux/bitops.h>
#include <stdarg.h>
#include <linux/kernel.h>
@@ -365,6 +366,23 @@ static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
payload);
}
+ /*
+ * Print remaining IMPDEF bits that weren't printed above as raw
+ * "IMPDEF:1,2,3,4" etc.
+ */
+ if (payload) {
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " IMPDEF:");
+ for (int i = 0; i < 64; i++) {
+ const char *sep = payload & (payload - 1) ? "," : "";
+
+ if (payload & BIT_ULL(i)) {
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, "%d%s", i,
+ sep);
+ payload &= ~BIT_ULL(i);
+ }
+ }
+ }
+
return err;
}
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] mm/arm: pgtable: remove young bit check for pte_valid_user
From: Will Deacon @ 2026-04-14 11:08 UTC (permalink / raw)
To: Brian Ruley
Cc: Russell King (Oracle), Steve Capper, linux-arm-kernel,
linux-kernel, catalin.marinas
In-Reply-To: <ad3wRQt7K-QLX8Jw@zoo11.fihel.lab.ge-healthcare.net>
On Tue, Apr 14, 2026 at 10:44:05AM +0300, Brian Ruley wrote:
> On Apr 13, Brian Ruley wrote:
> >
> > In the meanwhile, I'll see if I can add some instrumentation to
> > verify this is the bug we're seeing.
>
> The instrumentation worked (used the same ring buffer approach to track
> dcache flushes). Here's the output:
>
> ```
> kernel: [48629.557043] SIGILL at b6b80ac0 cpu 1 pid 32663 linux_pte=8eff659f hw_pte=8eff6e7e young=1 exec=1
> kernel: [48629.557157] dcache flush START cpu0 pfn=8eff6 ts=48629557020154
> kernel: [48629.557207] dcache flush FINISH cpu0 pfn=8eff6 ts=48629557036154
> kernel: [48629.557230] dcache flush SKIPPED cpu1 pfn=8eff6 ts=48629557020154
> audisp-syslog: type=ANOM_ABEND msg=audit(1776154637.460:15): auid=4294967295 uid=0 gid=0 ses=4294967295 pid=32663 comm="journalctl" exe="/usr/bin/journalctl" sig=4 res=1 AUID="unset" UID="root" GID="root"
> ```
Red-handed!
Please send a patch for review (perhaps you can include that snippet in
the commit message).
Cheers,
Will
^ permalink raw reply
* Re: [PATCH bpf-next v2 1/2] bpf, arm64: Remove redundant bpf_flush_icache() after pack allocator finalize
From: Xu Kuohai @ 2026-04-14 11:16 UTC (permalink / raw)
To: Puranjay Mohan
Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Song Liu, Yonghong Song, Jiri Olsa, Catalin Marinas, Will Deacon,
Luke Nelson, Xi Wang, Björn Töpel, Pu Lehui,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
linux-arm-kernel, linux-riscv, linux-kernel
In-Reply-To: <CANk7y0js0YxPFX1HqpYumN-ji6-OkKi4YO5=CRz8nx8aTzYxPw@mail.gmail.com>
On 4/14/2026 5:38 PM, Puranjay Mohan wrote:
> On Tue, Apr 14, 2026 at 2:56 AM Xu Kuohai <xukuohai@huaweicloud.com> wrote:
>>
>> On 4/14/2026 3:11 AM, Puranjay Mohan wrote:
>>> bpf_flush_icache() calls flush_icache_range() to clean the data cache
>>> and invalidate the instruction cache for the JITed code region. However,
>>> since commit 1dad391daef1 ("bpf, arm64: use bpf_prog_pack for memory
>>> management"), this flush is redundant.
>>>
>>> bpf_jit_binary_pack_finalize() copies the JITed instructions to the ROX
>>> region via bpf_arch_text_copy() -> aarch64_insn_copy() -> __text_poke(),
>>> and __text_poke() already calls flush_icache_range() on the written
>>> range. The subsequent bpf_flush_icache() repeats the same cache
>>> maintenance on an overlapping range, including an unnecessary second
>>> synchronous IPI to all CPUs via kick_all_cpus_sync().
>>>
>>
>> So icache is flushed twice: once per instruction and again after all
>> instructions are copied. I think it's better to remove the per-instruction
>> flush and retain the single final flush to avoid repeating flush overhead
>> for each instruction.
>
> No, bpf_jit_binary_pack_finalize() is called at the end after the
> whole program is jited, and it calls: bpf_arch_text_copy(ro_header,
> rw_header, rw_header->size); which does aarch64_insn_copy(dst, src,
> len), this calls __text_poke() which copies the whole program and then
> does flush_icache_range((uintptr_t)addr, (uintptr_t)addr + len); once.
> This is correct, after this we don't need to call flush_icache_range()
> on the same range again.
>
> If we had been calling flush_icache_range() for each instruction, the
> system would hang due to the storm of IPIs.
Right, thanks for the explanation!
LGTM.
^ permalink raw reply
* [PATCH AUTOSEL 6.19-5.10] ASoC: stm32_sai: fix incorrect BCLK polarity for DSP_A/B, LEFT_J
From: Sasha Levin @ 2026-04-14 11:25 UTC (permalink / raw)
To: patches, stable
Cc: Tomasz Merta, Tomasz Merta, Mark Brown, Sasha Levin,
olivier.moysan, arnaud.pouliquen, lgirdwood, perex, tiwai,
mcoquelin.stm32, alexandre.torgue, linux-sound, linux-stm32,
linux-arm-kernel, linux-kernel
In-Reply-To: <20260414112509.410217-1-sashal@kernel.org>
From: Tomasz Merta <tomasz.merta@arrow.com>
[ Upstream commit 0669631dbccd41cf3ca7aa70213fcd8bb41c4b38 ]
The STM32 SAI driver do not set the clock strobing bit (CKSTR) for DSP_A,
DSP_B and LEFT_J formats, causing data to be sampled on the wrong BCLK
edge when SND_SOC_DAIFMT_NB_NF is used.
Per ALSA convention, NB_NF requires sampling on the rising BCLK edge.
The STM32MP25 SAI reference manual states that CKSTR=1 is required for
signals received by the SAI to be sampled on the SCK rising edge.
Without setting CKSTR=1, the SAI samples on the falling edge, violating
the NB_NF convention. For comparison, the NXP FSL SAI driver correctly
sets FSL_SAI_CR2_BCP for DSP_A, DSP_B and LEFT_J, consistent with its
I2S handling.
This patch adds SAI_XCR1_CKSTR for DSP_A, DSP_B and LEFT_J in
stm32_sai_set_dai_fmt which was verified empirically with a cs47l35 codec.
RIGHT_J (LSB) is not investigated and addressed by this patch.
Note: the STM32 I2S driver (stm32_i2s_set_dai_fmt) may have the same issue
for DSP_A mode, as I2S_CGFR_CKPOL is not set. This has not been verified
and is left for a separate investigation.
Signed-off-by: Tomasz Merta <tommerta@gmail.com>
Link: https://patch.msgid.link/20260408084056.20588-1-tommerta@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Now I have comprehensive data. Let me compile the full analysis.
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Parse the Subject Line
- **Subsystem:** ASoC: stm32_sai (STM32 Serial Audio Interface driver)
- **Action verb:** "fix" — explicitly a bug fix
- **Summary:** Fixes incorrect BCLK (bit clock) polarity for DSP_A,
DSP_B, and LEFT_J audio formats
Record: [ASoC: stm32_sai] [fix] [incorrect BCLK polarity for DSP_A/B,
LEFT_J formats]
### Step 1.2: Parse All Commit Message Tags
- **Signed-off-by:** Tomasz Merta <tommerta@gmail.com> — patch author
- **Link:**
https://patch.msgid.link/20260408084056.20588-1-tommerta@gmail.com —
patch submission link
- **Signed-off-by:** Mark Brown <broonie@kernel.org> — ASoC subsystem
maintainer applied it
- **No Fixes: tag** — expected for commits under review
- **No Cc: stable** — expected for commits under review
- **No Reported-by** — author discovered this themselves
Record: Applied by Mark Brown (ASoC maintainer). No Fixes: or Cc:stable
tags. Single-patch submission, no series.
### Step 1.3: Analyze the Commit Body Text
The commit explains:
- **Bug:** The CKSTR (Clock STRobing) bit is not set for DSP_A, DSP_B,
and LEFT_J formats
- **Symptom:** Data sampled on the wrong BCLK edge when
SND_SOC_DAIFMT_NB_NF is used
- **Root cause:** Per ALSA convention, NB_NF (Normal Bit clock, Normal
Frame) requires sampling on the rising BCLK edge. The STM32MP25
reference manual confirms CKSTR=1 is needed for rising edge sampling.
Without it, data is sampled on the falling edge.
- **Verification:** Empirically verified with a cs47l35 codec
- **Reference:** NXP FSL SAI driver correctly sets the equivalent bit
for these formats
Record: Real hardware bug — audio data sampled on wrong clock edge for
DSP_A, DSP_B, LEFT_J formats. Causes incorrect audio behavior.
### Step 1.4: Detect Hidden Bug Fixes
This is an explicit bug fix — not hidden. The subject says "fix" and the
commit describes the exact hardware behavior violation.
Record: Explicit bug fix, no hidden nature.
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory the Changes
- **File:** sound/soc/stm/stm32_sai_sub.c
- **Lines added:** 3
- **Lines removed:** 0
- **Functions modified:** `stm32_sai_set_dai_fmt()`
- **Scope:** Single-file, single-function, surgical fix
Record: 1 file, +3 lines, 0 removed. Only stm32_sai_set_dai_fmt()
modified. Extremely small and surgical.
### Step 2.2: Understand the Code Flow Change
Three hunks, each adding `cr1 |= SAI_XCR1_CKSTR;`:
1. **SND_SOC_DAIFMT_MSB (LEFT_J):** Before: only set FSPOL and FSDEF.
After: also sets CKSTR for rising-edge sampling.
2. **SND_SOC_DAIFMT_DSP_A:** Before: only set FSPOL and FSOFF. After:
also sets CKSTR.
3. **SND_SOC_DAIFMT_DSP_B:** Before: only set FSPOL. After: also sets
CKSTR.
The I2S case already had `cr1 |= SAI_XCR1_CKSTR;` — the fix makes the
other formats consistent.
Note the later code at line 828-832: the SND_SOC_DAIFMT_INV_MASK switch
uses XOR (`cr1 ^= SAI_XCR1_CKSTR`) to invert the polarity. Without CKSTR
being initially set, the XOR for IB_NF would SET it instead of clearing
it — the inversion logic only works correctly when CKSTR starts at the
right default value.
Record: Each hunk adds the missing CKSTR bit to a format case. Fix makes
DSP_A, DSP_B, LEFT_J consistent with I2S (which already had CKSTR). Also
fixes the inversion logic interaction.
### Step 2.3: Identify the Bug Mechanism
Category: **Logic/correctness fix** — missing hardware register bit
configuration.
The STM32 SAI hardware defaults to sampling on the falling edge
(CKSTR=0). ALSA convention says NB_NF means rising edge. Without setting
CKSTR=1 for these formats, audio data is sampled on the wrong clock
edge, leading to corrupted or incorrect audio output.
Record: Logic/correctness bug. Missing register bit causes wrong clock
edge for audio sampling.
### Step 2.4: Assess the Fix Quality
- **Obviously correct:** Yes. The I2S case already sets CKSTR, and the
FSL SAI driver (a well-established reference implementation) sets the
equivalent bit for all these formats. The hardware reference manual
confirms CKSTR=1 is needed.
- **Minimal/surgical:** Extremely — 3 identical one-line additions
- **Regression risk:** Very low. Only affects users of STM32 SAI with
DSP_A, DSP_B, or LEFT_J formats. Cannot affect other formats or other
hardware.
- **Red flags:** None
Record: Obviously correct (confirmed by reference manual, FSL SAI
comparison, empirical testing). Zero regression risk for unaffected
configurations.
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame the Changed Lines
The buggy code was introduced by commit `3e086edfe0c73d` ("ASoC: stm32:
add SAI driver") from 2017-04-10, by Olivier Moysan. This was the
**initial driver commit** creating the entire stm32_sai_sub.c file.
First appeared in **v4.12**.
Record: Bug present since the initial driver addition in v4.12 (2017).
Present in ALL stable trees that have this driver.
### Step 3.2: Follow the Fixes: Tag
No Fixes: tag present. The implicit fixes target is `3e086edfe0c73d`
(the initial driver commit).
Record: Bug is original to the driver (v4.12). Present in all stable
trees.
### Step 3.3: Check File History for Related Changes
Recent changes to stm32_sai_sub.c are mostly cleanup, probe error path
fixes, and stm32mp25 support additions. None touch the
`stm32_sai_set_dai_fmt()` function's format handling.
Record: No recent changes to the same code region. Patch applies cleanly
to any stable tree containing this driver.
### Step 3.4: Check the Author's Other Commits
Tomasz Merta has no other commits in the kernel tree. This is a first-
time contributor. However, the fix was accepted by Mark Brown (ASoC
subsystem maintainer) which validates it.
Record: First-time contributor, but fix accepted by subsystem maintainer
Mark Brown.
### Step 3.5: Check for Dependent/Prerequisite Commits
None. The fix adds 3 identical lines (`cr1 |= SAI_XCR1_CKSTR;`) in
switch cases that have been unchanged since v4.12. No dependencies.
Record: Fully standalone. No prerequisites needed.
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: Find the Original Patch Discussion
From the agent research: The patch was submitted on April 8, 2026, and
applied by Mark Brown the same day to his `for-7.0` branch. Only two
messages in the thread — submission and Mark Brown's automated "Applied
to" message. No substantive review discussion.
Record: Lore URL:
https://patch.msgid.link/20260408084056.20588-1-tommerta@gmail.com.
Applied same day by maintainer. No concerns raised.
### Step 4.2: Check Who Reviewed the Patch
Mark Brown (ASoC maintainer) applied the patch. Olivier Moysan (original
STM32 SAI driver author) was CC'd but did not comment.
Record: Applied by subsystem maintainer. No objections.
### Step 4.3: Search for Bug Report
No formal Reported-by tag. Author discovered this empirically while
working with a cs47l35 codec on STM32 hardware.
Record: Author-discovered bug during empirical testing.
### Step 4.4: Check for Related Patches and Series
Single patch, not part of a series. The commit message notes the STM32
I2S driver may have a similar issue but that is a separate
investigation.
Record: Standalone fix.
### Step 4.5: Check Stable Mailing List History
No prior stable discussion found for this specific issue.
Record: No prior stable discussion.
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Identify Key Functions in the Diff
Only `stm32_sai_set_dai_fmt()` is modified.
### Step 5.2: Trace Callers
`stm32_sai_set_dai_fmt` is registered as `.set_fmt` in two
`snd_soc_dai_ops` structs (lines 1368 and 1380). It is called by the
ASoC framework during DAI configuration — a standard, commonly exercised
path whenever audio playback/capture begins with this hardware.
Record: Called by ASoC framework during DAI setup. Common path for any
audio operation on STM32 SAI hardware.
### Step 5.3-5.4: Trace Callees and Call Chain
The function configures hardware registers via `regmap_update_bits`.
Standard ASoC driver pattern with no unusual side effects.
Record: Standard register configuration function.
### Step 5.5: Search for Similar Patterns
Confirmed by FSL SAI driver comparison: `fsl_sai.c` lines 325, 333, 342,
351 all set `FSL_SAI_CR2_BCP` (the equivalent bit) for I2S, LEFT_J,
DSP_A, and DSP_B formats. The STM32 SAI driver was missing it for 3 of 4
formats.
Record: FSL SAI driver confirms the correct pattern — BCP/CKSTR must be
set for all these formats.
---
## PHASE 6: CROSS-REFERENCING AND STABLE TREE ANALYSIS
### Step 6.1: Does the Buggy Code Exist in Stable Trees?
The buggy code was introduced in v4.12. The function
`stm32_sai_set_dai_fmt()` and the specific switch cases have been
unchanged since then. The bug exists in **all active stable trees**
(5.10, 5.15, 6.1, 6.6, 6.12+).
Record: Bug present in all active stable trees.
### Step 6.2: Check for Backport Complications
None of the recent commits touch the format switch in
`stm32_sai_set_dai_fmt()`. The patch adds simple one-line additions to
existing switch cases. Expected to apply cleanly to all stable trees.
Record: Clean apply expected for all stable trees.
### Step 6.3: Check if Related Fixes Are Already in Stable
No related clock polarity fixes have been applied to this driver.
Record: No existing fixes for this issue.
---
## PHASE 7: SUBSYSTEM AND MAINTAINER CONTEXT
### Step 7.1: Identify the Subsystem and Its Criticality
- **Subsystem:** ASoC (ALSA System on Chip) / STM32 SAI driver
- **Criticality:** PERIPHERAL — affects STM32 (ARM embedded) platform
users
- **User base:** STM32MP1, STM32MP2 series users running Linux (embedded
systems, IoT, industrial)
Record: PERIPHERAL. Affects STM32 ARM SoC users.
### Step 7.2: Assess Subsystem Activity
The stm32_sai_sub.c file has had 65 changes since v4.19. Moderate
activity, mostly maintenance and cleanup. The core format handling code
has been stable since v4.12.
Record: Moderate activity. Format handling code very stable.
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Determine Who Is Affected
Users of STM32 SAI hardware using DSP_A, DSP_B, or LEFT_J audio formats
with codecs. This is specific to STM32 embedded platform users.
Record: STM32 SAI users with DSP_A/DSP_B/LEFT_J formats. Niche but real
user population.
### Step 8.2: Determine the Trigger Conditions
The bug triggers whenever:
1. STM32 SAI driver is used (common on STM32MP platforms)
2. Audio format is DSP_A, DSP_B, or LEFT_J (common for certain codecs)
3. NB_NF clock polarity convention is used (the default/normal case)
This is deterministic — it always triggers for these configurations, not
a race or timing issue.
Record: Deterministic trigger for affected configurations. Always
broken, not intermittent.
### Step 8.3: Determine the Failure Mode Severity
- Audio data sampled on wrong clock edge
- Results in **incorrect audio output** — corrupted, distorted, or
silent audio
- This is a **functional correctness** issue, not a crash or security
issue
- Severity: **MEDIUM** — incorrect hardware behavior, but no
crash/corruption/security impact
Record: Incorrect audio output. MEDIUM severity. No crash or data
corruption.
### Step 8.4: Calculate Risk-Benefit Ratio
- **BENEFIT:** Medium. Fixes broken audio for STM32 SAI users with
DSP_A/DSP_B/LEFT_J formats. Deterministic bug.
- **RISK:** Very low. 3 one-line additions. Identical pattern to
existing I2S case. Cannot affect other formats or other hardware.
Confirmed correct by hardware reference manual and NXP FSL SAI
reference implementation.
- **Ratio:** Favorable. Very low risk, meaningful benefit for affected
users.
Record: Benefit=MEDIUM, Risk=VERY LOW. Favorable ratio.
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Compile the Evidence
**Evidence FOR backporting:**
- Fixes a real hardware bug: audio data sampled on wrong clock edge
- Bug present since v4.12 (initial driver addition) — affects all stable
trees
- Extremely small and surgical: 3 identical one-line additions
- Obviously correct: confirmed by hardware reference manual, FSL SAI
reference driver, and empirical testing
- No dependencies or prerequisites
- Will apply cleanly to all stable trees
- Accepted by subsystem maintainer Mark Brown
- Deterministic bug (always triggers for affected configs)
**Evidence AGAINST backporting:**
- Driver-specific, affecting only STM32 SAI users
- No crash, data corruption, or security impact — functional audio
correctness only
- No Reported-by tags — unclear how many users are affected in practice
- No formal bug reports from users
**Unresolved:**
- Exact number of users affected is unknown (STM32 embedded is a niche
but real market)
### Step 9.2: Apply the Stable Rules Checklist
1. **Obviously correct and tested?** YES — empirically verified with
cs47l35 codec, confirmed by hardware manual and FSL SAI reference
2. **Fixes a real bug?** YES — wrong clock edge for audio sampling
3. **Important issue?** MEDIUM — incorrect audio output, not
crash/security
4. **Small and contained?** YES — 3 lines in 1 file, 1 function
5. **No new features or APIs?** Correct — pure bug fix
6. **Can apply to stable trees?** YES — clean apply expected
### Step 9.3: Check for Exception Categories
This falls under a **hardware workaround/correctness fix** — fixing
incorrect hardware register configuration for an existing driver.
### Step 9.4: Decision
This is a well-understood, minimal, obviously correct fix for a real
hardware bug that has existed since the driver was first added. While it
only affects STM32 SAI users with specific audio formats (not a crash or
security issue), the fix is so small and risk-free that the benefit
clearly outweighs the negligible risk. It meets all stable kernel
criteria and is the kind of small driver fix that routinely goes to
stable.
---
## Verification
- [Phase 1] Parsed tags: Signed-off-by from author (Tomasz Merta) and
maintainer (Mark Brown). Link to patch.msgid.link. No Fixes: or Cc:
stable (expected).
- [Phase 2] Diff analysis: 3 identical one-line additions of `cr1 |=
SAI_XCR1_CKSTR;` in MSB, DSP_A, DSP_B cases of
stm32_sai_set_dai_fmt().
- [Phase 2] FSL SAI comparison verified: fsl_sai.c:325,333,342,351 all
set FSL_SAI_CR2_BCP for I2S, LEFT_J, DSP_A, DSP_B — confirms the STM32
fix is correct.
- [Phase 2] SAI_XCR1_CKSTR definition verified: stm32_sai.h:63 defines
it as BIT(9).
- [Phase 3] git blame: all affected lines trace to 3e086edfe0c73d
(2017-04-10, "ASoC: stm32: add SAI driver"), first in v4.12.
- [Phase 3] git tag --contains 3e086edfe0c73d: confirms first release
was v4.12-rc1.
- [Phase 3] No other commits touch the format switch in
stm32_sai_set_dai_fmt — clean apply expected.
- [Phase 3] Author (Tomasz Merta) has no other kernel commits — first-
time contributor.
- [Phase 4] Mailing list: 2-message thread. Applied by Mark Brown same
day. No objections, no stable nomination.
- [Phase 5] stm32_sai_set_dai_fmt registered in .set_fmt ops (lines
1368, 1380) — called by ASoC framework during standard DAI setup.
- [Phase 6] File exists unchanged in all stable trees (v5.10+, v6.1+,
v6.6+). No conflicting changes to the format switch.
- [Phase 7] Subsystem: ASoC STM32 SAI. PERIPHERAL criticality.
- [Phase 8] Failure mode: incorrect audio sampling (wrong clock edge).
MEDIUM severity. VERY LOW regression risk.
**YES**
sound/soc/stm/stm32_sai_sub.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
index 450e1585edeee..3e82fa90e719a 100644
--- a/sound/soc/stm/stm32_sai_sub.c
+++ b/sound/soc/stm/stm32_sai_sub.c
@@ -802,6 +802,7 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
break;
/* Left justified */
case SND_SOC_DAIFMT_MSB:
+ cr1 |= SAI_XCR1_CKSTR;
frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSDEF;
break;
/* Right justified */
@@ -809,9 +810,11 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSDEF;
break;
case SND_SOC_DAIFMT_DSP_A:
+ cr1 |= SAI_XCR1_CKSTR;
frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSOFF;
break;
case SND_SOC_DAIFMT_DSP_B:
+ cr1 |= SAI_XCR1_CKSTR;
frcr |= SAI_XFRCR_FSPOL;
break;
default:
--
2.53.0
^ permalink raw reply related
* Re: [PATCH RFC] ACPI: processor: idle: Do not propagate acpi_processor_ffh_lpi_probe() -ENODEV
From: lihuisong (C) @ 2026-04-14 11:31 UTC (permalink / raw)
To: Breno Leitao
Cc: Rafael J. Wysocki, Len Brown, lpieralisi, catalin.marinas, will,
Rafael J. Wysocki, linux-acpi, linux-kernel, pjaroszynski,
guohanjun, sudeep.holla, linux-arm-kernel, rmikey, kernel-team
In-Reply-To: <ad4UWJ__dnDQtrj8@gmail.com>
On 4/14/2026 6:21 PM, Breno Leitao wrote:
> Hello Huisong,
>
> On Tue, Apr 14, 2026 at 05:43:51PM +0800, lihuisong (C) wrote:
>> But it is a real issue. Thanks for your report.
>> I think the best way to fix your issue is that remove this verification in
>> psci_acpi_cpu_init_idle().
>> Because it is legal for platform to report one LPI state.
>> This function just needs to verify the LPI states which are FFH.
> Thank you for the prompt feedback.
>
> Would this approach work?
>
> commit 6c9d52840a4f778cc989838ba76ee51416e85de3
> Author: Breno Leitao <leitao@debian.org>
> Date: Tue Apr 14 03:16:08 2026 -0700
>
> ACPI: processor: idle: Allow platforms with only one LPI state
>
> psci_acpi_cpu_init_idle() rejects platforms where power.count - 1 <= 0
> by returning -ENODEV. However, having a single LPI state (WFI) is a
> valid configuration. The function's purpose is to verify FFH idle states,
> and when count is zero, there are simply no FFH states to validate —
> this is not an error.
>
> On NVIDIA Grace (aarch64) systems with PSCIv1.1, power.count is 1 for
> all 72 CPUs, so the probe fails with -ENODEV. After commit cac173bea57d
> ("ACPI: processor: idle: Rework the handling of
> acpi_processor_ffh_lpi_probe()"), this failure propagates up and prevents
> cpuidle registration entirely.
>
> Change the check from (count <= 0) to (count < 0) so that platforms
> with only WFI are accepted. The for loop naturally handles count == 0
> by not iterating.
>
> Fixes: cac173bea57d ("ACPI: processor: idle: Rework the handling of acpi_processor_ffh_lpi_probe()")
> Signed-off-by: Breno Leitao <leitao@debian.org>
>
> diff --git a/drivers/acpi/arm64/cpuidle.c b/drivers/acpi/arm64/cpuidle.c
> index 801f9c4501425..7791b751042ce 100644
> --- a/drivers/acpi/arm64/cpuidle.c
> +++ b/drivers/acpi/arm64/cpuidle.c
> @@ -31,7 +31,7 @@ static int psci_acpi_cpu_init_idle(unsigned int cpu)
> return -EOPNOTSUPP;
>
> count = pr->power.count - 1;
> - if (count <= 0)
> + if (count < 0)
> return -ENODEV;
>
> for (i = 0; i < count; i++) {
This count already verified in acpi_processor_get_lpi_info.
I suggest modifing it as below:
-->
git diff
diff --git a/drivers/acpi/arm64/cpuidle.c b/drivers/acpi/arm64/cpuidle.c
index 801f9c450142..c68a5db8ebba 100644
--- a/drivers/acpi/arm64/cpuidle.c
+++ b/drivers/acpi/arm64/cpuidle.c
@@ -16,7 +16,7 @@
static int psci_acpi_cpu_init_idle(unsigned int cpu)
{
- int i, count;
+ int i;
struct acpi_lpi_state *lpi;
struct acpi_processor *pr = per_cpu(processors, cpu);
@@ -30,14 +30,10 @@ static int psci_acpi_cpu_init_idle(unsigned int cpu)
if (!psci_ops.cpu_suspend)
return -EOPNOTSUPP;
- count = pr->power.count - 1;
- if (count <= 0)
- return -ENODEV;
-
- for (i = 0; i < count; i++) {
+ for (i = 1; i < pr->power.count; i++) {
u32 state;
- lpi = &pr->power.lpi_states[i + 1];
+ lpi = &pr->power.lpi_states[i];
/*
* Only bits[31:0] represent a PSCI power_state while
* bits[63:32] must be 0x0 as per ARM ACPI FFH
Specification
^ permalink raw reply related
* Re: [PATCH v2 0/3] iio: adc: xilinx-ams: refactor alarm handling to table-driven design
From: Andy Shevchenko @ 2026-04-14 11:33 UTC (permalink / raw)
To: Guilherme Ivo Bozi
Cc: Salih Erim, Conall O'Griofa, Jonathan Cameron, Michal Simek,
David Lechner, Nuno Sá, Andy Shevchenko, linux-iio,
linux-arm-kernel, linux-kernel
In-Reply-To: <20260414103316.18455-1-guilherme.bozi@usp.br>
On Tue, Apr 14, 2026 at 07:29:16AM -0300, Guilherme Ivo Bozi wrote:
> This series addresses significant code duplication in alarm handling
> logic across the Xilinx AMS IIO driver.
>
> To address this, the series introduces a centralized table-driven
> mapping (alarm_map) that replaces multiple switch statements spread
> across the driver.
>
> This improves:
> - maintainability (single source of truth for mappings)
> - readability (removes repeated switch logic)
> - extensibility (new alarms require only table updates)
>
> No functional changes are intended.
Please, do not send a new version in the same email thread!
> Series overview:
> - Patch 1: fix out-of-bounds channel lookup
> - Patch 2: convert mutex handling to guard(mutex)
> - Patch 3: introduce table-driven alarm mapping
I will look into them later on.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* [PATCH] arm: fix race condition on PG_dcache_clean in __sync_icache_dcache()
From: Brian Ruley @ 2026-04-14 11:39 UTC (permalink / raw)
To: Russell King
Cc: will, catalin.marinas, Brian Ruley, linux-arm-kernel,
linux-kernel
This bug was already discovered and fixed for arm64 in
commit 588a513d3425 ("arm64: Fix race condition on PG_dcache_clean in
__sync_icache_dcache()").
Verified with added instrumentation to track dcache flushes in a ring
buffer, as shown by the (distilled) output:
kernel: SIGILL at b6b80ac0 cpu 1 pid 32663 linux_pte=8eff659f
hw_pte=8eff6e7e young=1 exec=1
kernel: dcache flush START cpu0 pfn=8eff6 ts=48629557020154
kernel: dcache flush SKIPPED cpu1 pfn=8eff6 ts=48629557020154
kernel: dcache flush FINISH cpu0 pfn=8eff6 ts=48629557036154
audisp-syslog: comm="journalctl" exe="/usr/bin/journalctl" sig=4 [...]
Discussions in the mailing list mentioned that arch/arm is also affected
but the fix was never applied to it [1][2]. Apply the change now, since
the race condition can cause sporadic SIGILL's and SEGV's especially
while under high memory pressure.
Link: https://lore.kernel.org/all/adzMOdySgMIePcue@willie-the-truck [1]
Link: https://lore.kernel.org/all/20210514095001.13236-1-catalin.marinas@arm.com [2]
Signed-off-by: Brian Ruley <brian.ruley@gehealthcare.com>
---
arch/arm/mm/flush.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 19470d938b23..4d7ef5cc36b6 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -304,8 +304,10 @@ void __sync_icache_dcache(pte_t pteval)
else
mapping = NULL;
- if (!test_and_set_bit(PG_dcache_clean, &folio->flags.f))
+ if (!test_bit(PG_dcache_clean, &folio->flags.f)) {
__flush_dcache_folio(mapping, folio);
+ set_bit(PG_dcache_clean, &folio->flags.f);
+ }
if (pte_exec(pteval))
__flush_icache_all();
--
2.47.3
^ permalink raw reply related
* Re: [PATCH net] net: airoha: Fix VIP configuration for AN7583 SoC
From: patchwork-bot+netdevbpf @ 2026-04-14 11:40 UTC (permalink / raw)
To: Lorenzo Bianconi
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms,
linux-arm-kernel, linux-mediatek, netdev
In-Reply-To: <20260412-airoha-7583-vip-fix-v1-1-c35e02b054bb@kernel.org>
Hello:
This patch was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Sun, 12 Apr 2026 09:57:29 +0200 you wrote:
> EN7581 and AN7583 SoCs have different VIP definitions. Introduce
> get_vip_port callback in airoha_eth_soc_data struct in order to take
> into account EN7581 and AN7583 VIP register layout and definition
> differences.
> Introduce nbq parameter in airoha_gdm_port struct. At the moment nbq
> is set statically to value previously used in airhoha_set_gdm2_loopback
> routine and it will be read from device tree in subsequent patches.
>
> [...]
Here is the summary with links:
- [net] net: airoha: Fix VIP configuration for AN7583 SoC
https://git.kernel.org/netdev/net/c/1acdfbdb516b
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* [PATCH 1/3] regulator: dt-bindings: mt6360: add buck regulator supplies
From: Louis-Alexis Eyraud @ 2026-04-14 11:44 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Liam Girdwood, Mark Brown, Gene Chen
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Louis-Alexis Eyraud
In-Reply-To: <20260414-mtk-g1200-pmic-cleanup-v1-0-2a7193ed4e93@collabora.com>
MT6360 PMIC provides 2 buck and 6 ldo regulators, that have each one a
separate supply.
Currently, the supplies for the ldo regulators are described in the
dt-bindings but the ones for the buck regulators are not.
Add the descriptions for these missing supplies.
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
Documentation/devicetree/bindings/regulator/mt6360-regulator.yaml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/regulator/mt6360-regulator.yaml b/Documentation/devicetree/bindings/regulator/mt6360-regulator.yaml
index 9c879bc3c360..cbb74e8e875d 100644
--- a/Documentation/devicetree/bindings/regulator/mt6360-regulator.yaml
+++ b/Documentation/devicetree/bindings/regulator/mt6360-regulator.yaml
@@ -17,6 +17,10 @@ properties:
compatible:
const: mediatek,mt6360-regulator
+ BUCK1_VIN-supply:
+ description: Input supply phandle(s) for BUCK1
+ BUCK2_VIN-supply:
+ description: Input supply phandle(s) for BUCK2
LDO_VIN1-supply:
description: Input supply phandle(s) for LDO1/2/3
LDO_VIN2-supply:
--
2.53.0
^ permalink raw reply related
* [PATCH 0/3] Mediatek Genio 1200-EVK: MT6315/MT6360 PMIC regulator supply cleanup
From: Louis-Alexis Eyraud @ 2026-04-14 11:44 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Liam Girdwood, Mark Brown, Gene Chen
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Louis-Alexis Eyraud
This series goal is to cleanup the power supplies of MT6315 and MT6360
PMIC regulators, that are either missing or incorrect in the Mediatek
Genio 1200-EVK board devicetree.
Patch 1 completes the MT6360 dt-bindings by adding the missing power
supply descriptions for its buck regulators, that already handled by
the mt6360 regulator driver.
Patch 2 adds for the board the MT6315 regulator supply properties, that
were added in the dt-bindings by [1].
Patch 3 adds for the board the MT6360 regulator supply properties and
fixes the existing one.
The series has been tested on Genio 1200-EVK board with a kernel based
on linux-next (tag: next-20260410).
[1]: https://lore.kernel.org/linux-mediatek/20260326081050.1115201-1-wenst@chromium.org/
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
Louis-Alexis Eyraud (3):
regulator: dt-bindings: mt6360: add buck regulator supplies
arm64: dts: mediatek: mt8395-genio-common: add MT6315 PMIC supplies
arm64: dts: mediatek: mt8395-genio-common: add MT6360 PMIC supplies
.../bindings/regulator/mt6360-regulator.yaml | 4 +++
.../boot/dts/mediatek/mt8395-genio-common.dtsi | 32 +++++++++++++++++++++-
2 files changed, 35 insertions(+), 1 deletion(-)
---
base-commit: f244905cd8cff7a7249cd3dac8a366e02d61ad4f
change-id: 20260413-mtk-g1200-pmic-cleanup-666643b85b52
Best regards,
--
Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
^ permalink raw reply
* [PATCH 2/3] arm64: dts: mediatek: mt8395-genio-common: add MT6315 PMIC supplies
From: Louis-Alexis Eyraud @ 2026-04-14 11:44 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Liam Girdwood, Mark Brown, Gene Chen
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Louis-Alexis Eyraud
In-Reply-To: <20260414-mtk-g1200-pmic-cleanup-v1-0-2a7193ed4e93@collabora.com>
Mediatek Genio 1200-EVK board has two MT6315 PMICs, powered by the
board system power rail (VSYS) and connected to the SPMI interface.
Add VSYS regulator node for system power rail and the supply inputs of
these two PMICs.
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi b/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi
index 62c336e21500..01e153137a6f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi
@@ -201,6 +201,14 @@ wifi_fixed_3v3: regulator-2 {
enable-active-high;
regulator-always-on;
};
+
+ /* system wide 4.2V power rail */
+ reg_vsys: regulator-vsys {
+ compatible = "regulator-fixed";
+ regulator-name = "vsys";
+ regulator-always-on;
+ regulator-boot-on;
+ };
};
&adsp {
@@ -1238,6 +1246,11 @@ mt6315_6: pmic@6 {
compatible = "mediatek,mt6315-regulator";
reg = <0x6 SPMI_USID>;
+ pvdd1-supply = <®_vsys>;
+ pvdd2-supply = <®_vsys>;
+ pvdd3-supply = <®_vsys>;
+ pvdd4-supply = <®_vsys>;
+
regulators {
mt6315_6_vbuck1: vbuck1 {
regulator-name = "Vbcpu";
@@ -1254,6 +1267,11 @@ mt6315_7: pmic@7 {
compatible = "mediatek,mt6315-regulator";
reg = <0x7 SPMI_USID>;
+ pvdd1-supply = <®_vsys>;
+ pvdd2-supply = <®_vsys>;
+ pvdd3-supply = <®_vsys>;
+ pvdd4-supply = <®_vsys>;
+
regulators {
mt6315_7_vbuck1: vbuck1 {
regulator-name = "Vgpu";
--
2.53.0
^ permalink raw reply related
* [PATCH 3/3] arm64: dts: mediatek: mt8395-genio-common: add MT6360 PMIC supplies
From: Louis-Alexis Eyraud @ 2026-04-14 11:44 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Liam Girdwood, Mark Brown, Gene Chen
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Louis-Alexis Eyraud
In-Reply-To: <20260414-mtk-g1200-pmic-cleanup-v1-0-2a7193ed4e93@collabora.com>
The Mediatek Genio 1200-EVK board has a MT6360 PMIC, powered by the
board system power rail (VSYS) and an additional system power rail
(VSYS_BUCK).
In the board devicetree, the power supply inputs for its buck and ldo
regulators are either incorrect (LDO_VIN3) or missing (LDO_VIN1/2,
BUCK_VIN1/2).
So, add VSYS_BUCK regulator node and the proper supply inputs for this
PMIC.
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi b/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi
index 01e153137a6f..21dbcabe5e72 100644
--- a/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8395-genio-common.dtsi
@@ -209,6 +209,14 @@ reg_vsys: regulator-vsys {
regulator-always-on;
regulator-boot-on;
};
+
+ reg_vsys_buck: regulator-vsys-buck {
+ compatible = "regulator-fixed";
+ regulator-name = "vsys_buck";
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <®_vsys>;
+ };
};
&adsp {
@@ -486,7 +494,11 @@ otg_vbus_regulator: usb-otg-vbus-regulator {
regulator {
compatible = "mediatek,mt6360-regulator";
- LDO_VIN3-supply = <&mt6360_buck2>;
+ BUCK1_VIN-supply = <®_vsys>;
+ BUCK2_VIN-supply = <®_vsys>;
+ LDO_VIN1-supply = <®_vsys_buck>;
+ LDO_VIN2-supply = <®_vsys_buck>;
+ LDO_VIN3-supply = <®_vsys>;
mt6360_buck1: buck1 {
regulator-name = "emi_vdd2";
--
2.53.0
^ permalink raw reply related
* Re: [PATCH] mm/arm: pgtable: remove young bit check for pte_valid_user
From: Brian Ruley @ 2026-04-14 11:43 UTC (permalink / raw)
To: Will Deacon
Cc: Russell King (Oracle), Steve Capper, linux-arm-kernel,
linux-kernel, catalin.marinas
In-Reply-To: <ad4gOu83zY-SKijx@willie-the-truck>
On Apr 14, Will Deacon wrote:
>
> Red-handed!
>
> Please send a patch for review (perhaps you can include that snippet in
> the commit message).
>
> Cheers,
>
> Will
I sent it as separate patch with a link to this thread, since it's a
different fix.
Thank you for the help in this matter!
BR,
Brian
^ permalink raw reply
* Re: [PATCH RFC] ACPI: processor: idle: Do not propagate acpi_processor_ffh_lpi_probe() -ENODEV
From: Breno Leitao @ 2026-04-14 12:05 UTC (permalink / raw)
To: lihuisong (C)
Cc: Rafael J. Wysocki, Len Brown, lpieralisi, catalin.marinas, will,
Rafael J. Wysocki, linux-acpi, linux-kernel, pjaroszynski,
guohanjun, sudeep.holla, linux-arm-kernel, rmikey, kernel-team
In-Reply-To: <6694ca7c-13bf-4e7d-9621-bc992cbf96a7@huawei.com>
On Tue, Apr 14, 2026 at 07:31:29PM +0800, lihuisong (C) wrote:
>
> On 4/14/2026 6:21 PM, Breno Leitao wrote:
> > Hello Huisong,
> >
> > On Tue, Apr 14, 2026 at 05:43:51PM +0800, lihuisong (C) wrote:
> > > But it is a real issue. Thanks for your report.
> > > I think the best way to fix your issue is that remove this verification in
> > > psci_acpi_cpu_init_idle().
> > > Because it is legal for platform to report one LPI state.
> > > This function just needs to verify the LPI states which are FFH.
> > Thank you for the prompt feedback.
> >
> > Would this approach work?
> >
> > commit 6c9d52840a4f778cc989838ba76ee51416e85de3
> > Author: Breno Leitao <leitao@debian.org>
> > Date: Tue Apr 14 03:16:08 2026 -0700
> >
> > ACPI: processor: idle: Allow platforms with only one LPI state
> > psci_acpi_cpu_init_idle() rejects platforms where power.count - 1 <= 0
> > by returning -ENODEV. However, having a single LPI state (WFI) is a
> > valid configuration. The function's purpose is to verify FFH idle states,
> > and when count is zero, there are simply no FFH states to validate —
> > this is not an error.
> > On NVIDIA Grace (aarch64) systems with PSCIv1.1, power.count is 1 for
> > all 72 CPUs, so the probe fails with -ENODEV. After commit cac173bea57d
> > ("ACPI: processor: idle: Rework the handling of
> > acpi_processor_ffh_lpi_probe()"), this failure propagates up and prevents
> > cpuidle registration entirely.
> > Change the check from (count <= 0) to (count < 0) so that platforms
> > with only WFI are accepted. The for loop naturally handles count == 0
> > by not iterating.
> > Fixes: cac173bea57d ("ACPI: processor: idle: Rework the handling of acpi_processor_ffh_lpi_probe()")
> > Signed-off-by: Breno Leitao <leitao@debian.org>
> >
> > diff --git a/drivers/acpi/arm64/cpuidle.c b/drivers/acpi/arm64/cpuidle.c
> > index 801f9c4501425..7791b751042ce 100644
> > --- a/drivers/acpi/arm64/cpuidle.c
> > +++ b/drivers/acpi/arm64/cpuidle.c
> > @@ -31,7 +31,7 @@ static int psci_acpi_cpu_init_idle(unsigned int cpu)
> > return -EOPNOTSUPP;
> > count = pr->power.count - 1;
> > - if (count <= 0)
> > + if (count < 0)
> > return -ENODEV;
> > for (i = 0; i < count; i++) {
>
> This count already verified in acpi_processor_get_lpi_info.
>
> I suggest modifing it as below:
>
> -->
>
> git diff
> diff --git a/drivers/acpi/arm64/cpuidle.c b/drivers/acpi/arm64/cpuidle.c
> index 801f9c450142..c68a5db8ebba 100644
> --- a/drivers/acpi/arm64/cpuidle.c
> +++ b/drivers/acpi/arm64/cpuidle.c
> @@ -16,7 +16,7 @@
>
> static int psci_acpi_cpu_init_idle(unsigned int cpu)
> {
> - int i, count;
> + int i;
> struct acpi_lpi_state *lpi;
> struct acpi_processor *pr = per_cpu(processors, cpu);
>
> @@ -30,14 +30,10 @@ static int psci_acpi_cpu_init_idle(unsigned int cpu)
> if (!psci_ops.cpu_suspend)
> return -EOPNOTSUPP;
>
> - count = pr->power.count - 1;
> - if (count <= 0)
> - return -ENODEV;
> -
> - for (i = 0; i < count; i++) {
> + for (i = 1; i < pr->power.count; i++) {
> u32 state;
>
> - lpi = &pr->power.lpi_states[i + 1];
> + lpi = &pr->power.lpi_states[i];
> /*
> * Only bits[31:0] represent a PSCI power_state while
> * bits[63:32] must be 0x0 as per ARM ACPI FFH Specification
Ack, I will respin.
Thanks for your help,
--breno
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox