* [PATCH v3 2/3] nvmem: lan9662-otp: add support for LAN969x
From: Robert Marko @ 2026-05-15 11:59 UTC (permalink / raw)
To: srini, robh, krzk+dt, conor+dt, nicolas.ferre, claudiu.beznea,
horatiu.vultur, daniel.machon, devicetree, linux-kernel,
linux-arm-kernel
Cc: luka.perkov, Robert Marko
In-Reply-To: <20260515115954.701155-1-robimarko@gmail.com>
From: Horatiu Vultur <horatiu.vultur@microchip.com>
Microchip LAN969x provides OTP with the same control logic, only the size
differs as LAN969x has 16KB of OTP instead of 8KB like on LAN966x.
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
---
Changes in v3:
* Rebase onto current next-20260508
drivers/nvmem/Kconfig | 2 +-
drivers/nvmem/lan9662-otpc.c | 12 +++++++++---
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 74ddbd0f79b0..78b648e14727 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -138,7 +138,7 @@ config NVMEM_JZ4780_EFUSE
config NVMEM_LAN9662_OTPC
tristate "Microchip LAN9662 OTP controller support"
- depends on SOC_LAN966 || COMPILE_TEST
+ depends on SOC_LAN966 || ARCH_LAN969X || COMPILE_TEST
depends on HAS_IOMEM
help
This driver enables the OTP controller available on Microchip LAN9662
diff --git a/drivers/nvmem/lan9662-otpc.c b/drivers/nvmem/lan9662-otpc.c
index 56fc19f092a7..62d1d6381bf8 100644
--- a/drivers/nvmem/lan9662-otpc.c
+++ b/drivers/nvmem/lan9662-otpc.c
@@ -27,7 +27,6 @@
#define OTP_OTP_STATUS_OTP_CPUMPEN BIT(1)
#define OTP_OTP_STATUS_OTP_BUSY BIT(0)
-#define OTP_MEM_SIZE 8192
#define OTP_SLEEP_US 10
#define OTP_TIMEOUT_US 500000
@@ -176,7 +175,6 @@ static struct nvmem_config otp_config = {
.word_size = 1,
.reg_read = lan9662_otp_read,
.reg_write = lan9662_otp_write,
- .size = OTP_MEM_SIZE,
};
static int lan9662_otp_probe(struct platform_device *pdev)
@@ -196,6 +194,7 @@ static int lan9662_otp_probe(struct platform_device *pdev)
otp_config.priv = otp;
otp_config.dev = dev;
+ otp_config.size = (uintptr_t) device_get_match_data(dev);
nvmem = devm_nvmem_register(dev, &otp_config);
@@ -203,7 +202,14 @@ static int lan9662_otp_probe(struct platform_device *pdev)
}
static const struct of_device_id lan9662_otp_match[] = {
- { .compatible = "microchip,lan9662-otpc", },
+ {
+ .compatible = "microchip,lan9662-otpc",
+ .data = (const void *) SZ_8K,
+ },
+ {
+ .compatible = "microchip,lan9691-otpc",
+ .data = (const void *) SZ_16K,
+ },
{ },
};
MODULE_DEVICE_TABLE(of, lan9662_otp_match);
--
2.54.0
^ permalink raw reply related
* [PATCH v3 1/3] dt-bindings: nvmem: lan9662-otpc: Add LAN969x series
From: Robert Marko @ 2026-05-15 11:59 UTC (permalink / raw)
To: srini, robh, krzk+dt, conor+dt, nicolas.ferre, claudiu.beznea,
horatiu.vultur, daniel.machon, devicetree, linux-kernel,
linux-arm-kernel
Cc: luka.perkov, Robert Marko, Conor Dooley
From: Robert Marko <robert.marko@sartura.hr>
Unlike LAN966x series which has 8K of OTP space, LAN969x series has 16K of
OTP space, so document the compatible.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
---
Changes in v3:
* Pick Acked-by from Conor
.../devicetree/bindings/nvmem/microchip,lan9662-otpc.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/nvmem/microchip,lan9662-otpc.yaml b/Documentation/devicetree/bindings/nvmem/microchip,lan9662-otpc.yaml
index f97c6beb4766..c03e96afe564 100644
--- a/Documentation/devicetree/bindings/nvmem/microchip,lan9662-otpc.yaml
+++ b/Documentation/devicetree/bindings/nvmem/microchip,lan9662-otpc.yaml
@@ -25,6 +25,7 @@ properties:
- const: microchip,lan9662-otpc
- enum:
- microchip,lan9662-otpc
+ - microchip,lan9691-otpc
reg:
maxItems: 1
--
2.54.0
^ permalink raw reply related
* Re: [PATCH] net: stmmac: fix fatal bus error on resume by reinitializing RX buffers
From: Andrew Lunn @ 2026-05-15 11:58 UTC (permalink / raw)
To: Ding Hui
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Maxime Coquelin, Alexandre Torgue,
Russell King (Oracle), Maxime Chevallier,
open list:STMMAC ETHERNET DRIVER,
moderated list:ARM/STM32 ARCHITECTURE,
moderated list:ARM/STM32 ARCHITECTURE, open list, dinghui,
xiasanbo, yangchen11, liuxuanjun
In-Reply-To: <20260515053856.2310369-1-dinghui1111@163.com>
> Fix this by treating the RX ring the same way as on close/open around
> a PM transition:
>
> - In stmmac_suspend(), after stmmac_stop_all_dma(), walk every RX
> queue and free its buffers via dma_free_rx_xskbufs() when an XSK
> pool is attached or dma_free_rx_skbufs() otherwise, then reset
> rx_q->buf_alloc_num and clear rx_q->xsk_pool so the queue state
> matches a freshly closed queue.
>
> - In stmmac_resume(), call init_dma_rx_desc_rings() before
> stmmac_reset_queues_param() so RX buffers are re-allocated and
> the descriptor buffer-address fields are properly repopulated
> before the DMA is restarted.
The problem with this is, if the system is under memory pressure, it
might not be able to allocate the new RX buffers. So on resume, your
network interface dies.
For configuration changes which require buffers to be change, like
ethtool --set-ring, sometimes changing the MTU, you first allocate the
new buffers, and only if successful do you free the old buffers, so
that you can gracefully fail.
That free and then release idea does not work for resume.
So, can you live with the buffers you have, and just reset the
descriptors?
Andrew
^ permalink raw reply
* Re: [PATCH] firmware: arm_scmi: Fix OOB in scmi_power_name_get()
From: Cristian Marussi @ 2026-05-15 11:46 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Dan Carpenter, Sudeep Holla, Cristian Marussi, arm-scmi,
linux-arm-kernel, linux-kernel
In-Reply-To: <CAMuHMdXreO-6xQ+e88AKQ_vSiwMPMnx=t8h5JChBAtuV4UDMEw@mail.gmail.com>
On Fri, May 15, 2026 at 01:29:27PM +0200, Geert Uytterhoeven wrote:
> Hi Dan,
>
Hi all,
> On Fri, 15 May 2026 at 12:28, Dan Carpenter <error27@gmail.com> wrote:
> > On Fri, May 15, 2026 at 11:59:15AM +0200, Geert Uytterhoeven wrote:
> > > scmi_power_name_get() does not validate the domain number passed by the
> > > external caller, which may lead to an out-of-bounds access.
> >
> > Is an external caller an out of tree caller? So far as I can see this
>
> I meant a caller outside drivers/firmware/arm_scmi/.
>
> > is only called by scmi_pm_domain_probe().
> >
> > scmi_pd->name = power_ops->name_get(ph, i);
> >
> > where i < num_domains.
>
> You are right. But this seems to be only API implementation in
> drivers/firmware/arm_scmi/ that does not validate the passed domain
> number.
>
Yes we tend to validate protocol operations calls even if apparently
safe from teh caller perspective...indeed I have this fixed locally
since ages in an horrible patch, that does a lot more, and that I
never posted :P
Usually, if it is worth, we also build an internal domain get helper to
reuse across the protocol unit...but here really there are only 2 call-sites.
What I am not sure is what to return: "unknown" is safer as of now than NULL
for sure, but really, what happened is NOT that the name was "unknown" (which
by itself would be out-of-spec behaviour) it is more that the whole domain that
was referred to that was invalid and NOT existent...
....mmm I suppose we are opening another can of worms here :P
Thanks,
Cristian
^ permalink raw reply
* Re: [PATCH v2 0/6] firmware: samsung: acpm: TMU support and cleanups
From: Tudor Ambarus @ 2026-05-15 11:46 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Alim Akhtar, Sylwester Nawrocki, Chanwoo Choi, André Draszik,
linux-kernel, linux-samsung-soc, linux-arm-kernel, linux-clk,
peter.griffin, jyescas, kernel-team, Krzysztof Kozlowski,
Michael Turquette, Stephen Boyd, Lee Jones
In-Reply-To: <a4c287df-0300-4fae-8a2b-23e2358fb740@linaro.org>
On 5/15/26 2:44 PM, Tudor Ambarus wrote:
> Hi, Krzysztof,
>
> On 5/15/26 12:32 PM, Tudor Ambarus wrote:
>> Changes in v2:
>> - collect tags
>> - resend as sashiko couldn't apply previous version. We want
>> sashiko's review feedback
>
> That didn't work, sashiko still can't apply:
> https://sashiko.dev/#/patchset/20260506-acpm-tmu-helpers-v1-0-a9cd5daf8355%40linaro.org
the correct link is
https://sashiko.dev/#/patchset/20260515-acpm-tmu-helpers-v2-0-8ca011d5a965%40linaro.org
the description bellow still applies.
>
> cut
>
>> ---
>> base-commit: 5e9b7d093f3f77cb0af4409559e3d139babfb443
> above is v7.1-rc1 (signed tag)
>
>> change-id: 20260505-acpm-tmu-helpers-4c5af0e2f07c
>> prerequisite-change-id: 20260423-acpm-fixes-sashiko-reports-ae28b6ed5581:v5
>> prerequisite-patch-id: 18d89d0e2bc0efe2cb366746ac4db36f4682f061
>> prerequisite-patch-id: e877f865862ee94f5750b877b5fad863d8acd7c8
>> prerequisite-patch-id: b5da16b5c6d6731ea519ed68302fd52ce57c7ffa
>> prerequisite-patch-id: df5b1d9df4c8894afaff645c9eb84aa4e3daeeee
>> prerequisite-patch-id: be74a55583acb36dedca3e118f49633172979617
>> prerequisite-patch-id: 31ebc7bd806d4d466c256049f32e3270e2caeeb6
>> prerequisite-patch-id: 7ea0832fcf76e4f40e18b74083904e7e37e1addf
>
> While I see I forgot to update the dependencies, I don't think they
> matter to sashiko. If sashiko used v7.1-rc1 and the prerequisite
> patches it would correctly apply the set.
>
> If one goes in the Sashiko link above and expand the `Baseline`
> (show details), will see:
>
> 5e9b7d093f3f77cb0af4409559e3d139babfb443 (5e9b7d093f3f77cb0af4409559e3d139babfb443) Failed View Log
> ^ this is v7.1-rc1 (signed tag)
>
> krzk/HEAD (254f49634ee16a731174d2ae34bc50bd5f45e731) Failed View Log
> ^ this is krzk/HEAD -> krzk/master -> v7.1-rc1
>
> Shall your HEAD point to the krzk/for-next branch? Happy to resubmit
> the set.
>
> Thanks,
> ta
^ permalink raw reply
* Re: [PATCH v2 0/6] firmware: samsung: acpm: TMU support and cleanups
From: Tudor Ambarus @ 2026-05-15 11:44 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Alim Akhtar, Sylwester Nawrocki, Chanwoo Choi, André Draszik,
linux-kernel, linux-samsung-soc, linux-arm-kernel, linux-clk,
peter.griffin, jyescas, kernel-team, Krzysztof Kozlowski,
Michael Turquette, Stephen Boyd, Lee Jones
In-Reply-To: <20260515-acpm-tmu-helpers-v2-0-8ca011d5a965@linaro.org>
Hi, Krzysztof,
On 5/15/26 12:32 PM, Tudor Ambarus wrote:
> Changes in v2:
> - collect tags
> - resend as sashiko couldn't apply previous version. We want
> sashiko's review feedback
That didn't work, sashiko still can't apply:
https://sashiko.dev/#/patchset/20260506-acpm-tmu-helpers-v1-0-a9cd5daf8355%40linaro.org
cut
> ---
> base-commit: 5e9b7d093f3f77cb0af4409559e3d139babfb443
above is v7.1-rc1 (signed tag)
> change-id: 20260505-acpm-tmu-helpers-4c5af0e2f07c
> prerequisite-change-id: 20260423-acpm-fixes-sashiko-reports-ae28b6ed5581:v5
> prerequisite-patch-id: 18d89d0e2bc0efe2cb366746ac4db36f4682f061
> prerequisite-patch-id: e877f865862ee94f5750b877b5fad863d8acd7c8
> prerequisite-patch-id: b5da16b5c6d6731ea519ed68302fd52ce57c7ffa
> prerequisite-patch-id: df5b1d9df4c8894afaff645c9eb84aa4e3daeeee
> prerequisite-patch-id: be74a55583acb36dedca3e118f49633172979617
> prerequisite-patch-id: 31ebc7bd806d4d466c256049f32e3270e2caeeb6
> prerequisite-patch-id: 7ea0832fcf76e4f40e18b74083904e7e37e1addf
While I see I forgot to update the dependencies, I don't think they
matter to sashiko. If sashiko used v7.1-rc1 and the prerequisite
patches it would correctly apply the set.
If one goes in the Sashiko link above and expand the `Baseline`
(show details), will see:
5e9b7d093f3f77cb0af4409559e3d139babfb443 (5e9b7d093f3f77cb0af4409559e3d139babfb443) Failed View Log
^ this is v7.1-rc1 (signed tag)
krzk/HEAD (254f49634ee16a731174d2ae34bc50bd5f45e731) Failed View Log
^ this is krzk/HEAD -> krzk/master -> v7.1-rc1
Shall your HEAD point to the krzk/for-next branch? Happy to resubmit
the set.
Thanks,
ta
^ permalink raw reply
* Re: [PATCH v3] EDAC/altera: Guard SDRAM irq2 retrieval for Arria10 only
From: Dinh Nguyen @ 2026-05-15 11:41 UTC (permalink / raw)
To: muhammad.nazim.amirul.nazle.asmade, bp, tony.luck
Cc: linux-edac, linux-arm-kernel, linux-kernel
In-Reply-To: <20260515050444.10380-1-muhammad.nazim.amirul.nazle.asmade@altera.com>
On 5/15/26 00:04, muhammad.nazim.amirul.nazle.asmade@altera.com wrote:
> From: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
>
> Guard the irq2 retrieval with an of_machine_is_compatible() check so
> that platform_get_irq(pdev, 1) is only called on Arria10 platforms.
>
> Signed-off-by: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
> ---
> v3: Fix commit header formatting to follow EDAC/altera: prefix
> convention as per maintainer feedback.
> v2: Move irq2 = platform_get_irq(pdev, 1) inside the existing
> of_machine_is_compatible("altr,socfpga-arria10") block instead of
> adding a separate duplicate guard around it.
> ---
> drivers/edac/altera_edac.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
> index 4edd2088c2db..ee6ced033f2c 100644
> --- a/drivers/edac/altera_edac.c
> +++ b/drivers/edac/altera_edac.c
> @@ -347,9 +347,6 @@ static int altr_sdram_probe(struct platform_device *pdev)
> return irq;
> }
>
> - /* Arria10 has a 2nd IRQ */
> - irq2 = platform_get_irq(pdev, 1);
> -
> layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
> layers[0].size = 1;
> layers[0].is_virt_csrow = true;
> @@ -395,6 +392,9 @@ static int altr_sdram_probe(struct platform_device *pdev)
>
> /* Only the Arria10 has separate IRQs */
> if (of_machine_is_compatible("altr,socfpga-arria10")) {
> + /* Arria10 has a 2nd IRQ */
> + irq2 = platform_get_irq(pdev, 1);
> +
> /* Arria10 specific initialization */
> res = a10_init(mc_vbase);
> if (res < 0)
Acked-by: Dinh Nguyen <dinguyen@kernel.org>
^ permalink raw reply
* Re: [PATCH 3/4] soc: qcom: Make important drivers default
From: Konrad Dybcio @ 2026-05-15 11:36 UTC (permalink / raw)
To: Krzysztof Kozlowski, Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-kernel, linux-arm-kernel
In-Reply-To: <bf37cdd6-b863-4e59-9459-3247080955a9@oss.qualcomm.com>
On 4/29/26 6:10 PM, Krzysztof Kozlowski wrote:
> On 29/04/2026 11:06, Konrad Dybcio wrote:
>> On 4/29/26 10:56 AM, Krzysztof Kozlowski wrote:
>>> The drivers for Qualcomm SoC components are covering a basic or
>>> fundamental SoC blocks. Usually they are required for booting or to
>>> achieve basic expected functionality when running Linux. These drivers
>>> do not represent any sort of buses visible to the board
>>> designers/configurators, thus they should be always enabled, regardless
>>> how SoC is used in the final board.
>>>
>>> Kernel configuration should not ask users choice of drivers when that
>>> choice is obvious and known to the developers that answer should be
>>> 'yes' or 'module'.
>>>
>>> Switch most of the Qualcomm SoC drivers to a default 'yes' or
>>> 'module' for ARCH_QCOM, to match existing defconfig usage.
>>>
>>> This has no impact on arm64 defconfig, arm qcom_defconfig and arm
>>> multi_v7_defconfig.
>>>
>>> The change will however enable by default all drivers for arm or arm64
>>> COMPILE_TEST builds, whenever ARCH_QCOM is selected, which feels
>>> logical: if one selects ARCH_QCOM then probably by default wants to
>>> build test it entirely. Kernels with COMPILE_TEST are not supposed to
>>> be used for booting.
>>>
>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
>>> ---
>>
>> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>>
>> Please also add:
>>
>> QCOM_RMTFS_MEM (required for modem)
>
> It's in the patch.
>
>> QCOM_SPM (cpufreq-adjacent on some platforms)
>
> I assume only for arm, because none of arm64 compatibles are present in
> upstream DTS.
There will be a couple arm64 ones too, but due to their age they're on the
back burner.. Whenever Dmitry can get some time for the museum pieces
Konrad
^ permalink raw reply
* Re: [PATCH] firmware: arm_scmi: Fix OOB in scmi_power_name_get()
From: Dan Carpenter @ 2026-05-15 11:36 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Sudeep Holla, Cristian Marussi, arm-scmi, linux-arm-kernel,
linux-kernel
In-Reply-To: <CAMuHMdXreO-6xQ+e88AKQ_vSiwMPMnx=t8h5JChBAtuV4UDMEw@mail.gmail.com>
On Fri, May 15, 2026 at 01:29:27PM +0200, Geert Uytterhoeven wrote:
> Hi Dan,
>
> On Fri, 15 May 2026 at 12:28, Dan Carpenter <error27@gmail.com> wrote:
> > On Fri, May 15, 2026 at 11:59:15AM +0200, Geert Uytterhoeven wrote:
> > > scmi_power_name_get() does not validate the domain number passed by the
> > > external caller, which may lead to an out-of-bounds access.
> >
> > Is an external caller an out of tree caller? So far as I can see this
>
> I meant a caller outside drivers/firmware/arm_scmi/.
>
> > is only called by scmi_pm_domain_probe().
> >
> > scmi_pd->name = power_ops->name_get(ph, i);
> >
> > where i < num_domains.
>
> You are right. But this seems to be only API implementation in
> drivers/firmware/arm_scmi/ that does not validate the passed domain
> number.
I don't have a problem with the patch but I don't think it should have
a Fixes tag.
regards,
dan carpenter
^ permalink raw reply
* Re: [PATCH 1/4] soc: qcom: Hide all drivers behind selectable menu
From: Konrad Dybcio @ 2026-05-15 11:35 UTC (permalink / raw)
To: Krzysztof Kozlowski, Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-kernel, linux-arm-kernel
In-Reply-To: <daaf1ad5-5ba7-4978-9758-18caf829def7@oss.qualcomm.com>
On 4/29/26 5:30 PM, Krzysztof Kozlowski wrote:
> On 29/04/2026 11:28, Konrad Dybcio wrote:
>>> +config QCOM_PDR_HELPERS
>>> + tristate
>>> + select QCOM_QMI_HELPERS
>>> + select QCOM_PDR_MSG
>>> + depends on NET
>>> +
>>> +config QCOM_QMI_HELPERS
>>> + tristate
>>> + depends on NET
>>
>> also:
>>
>> QCOM_KRYO_L2_ACCESSORS -> drivers/perf/Kconfig
>
> Ack
>
>> QCOM_SPM -> drivers/cpuidle/Kconfig.arm
>
> Heh, that's user-selectable driver, so I think we should change the
> select into dependency. It will make choice a bit more complex for arm32
> - the SPM cpuidle driver will be hidden if this is not selected. But
> alternative is that this driver will be outside of entire menuconfig.
>
> Does changing to "depends" feel right?
Yeah
Konrad
^ permalink raw reply
* Re: [PATCH v5 0/8] unwind, arm64: add sframe unwinder for kernel
From: Mostafa Saleh @ 2026-05-15 11:32 UTC (permalink / raw)
To: Dylan Hatch
Cc: Roman Gushchin, Weinan Liu, Will Deacon, Josh Poimboeuf,
Indu Bhagat, Peter Zijlstra, Steven Rostedt, Catalin Marinas,
Jiri Kosina, Jens Remus, Mark Rutland, Prasanna Kumar T S M,
Puranjay Mohan, Song Liu, joe.lawrence, linux-toolchains,
linux-kernel, live-patching, linux-arm-kernel, Randy Dunlap
In-Reply-To: <20260428183643.3796063-1-dylanbhatch@google.com>
On Tue, Apr 28, 2026 at 06:36:35PM +0000, Dylan Hatch wrote:
> Implement a generic kernel sframe-based [1] unwinder. The main goal is
> to improve reliable stacktrace on arm64 by unwinding across exception
> boundaries.
>
> On x86, the ORC unwinder provides reliable stacktrace through similar
> methodology, but arm64 lacks the necessary support from objtool to
> create ORC unwind tables.
>
> Currently, there's already a sframe unwinder proposed for userspace: [2].
> To maintain common definitions and algorithms for sframe lookup, a
> substantial portion of this patch series aims to refactor the sframe
> lookup code to support both kernel and userspace sframe sections.
>
> Currently, only GNU Binutils support sframe. This series relies on the
> Sframe V3 format, which is supported in binutils 2.46.
>
> These patches are based on Steven Rostedt's sframe/core branch [3],
> which is and aggregation of existing work done for x86 sframe userspace
> unwind, and contains [2]. This branch is, in turn, based on Linux
> v7.0-rc3. This full series (applied to the sframe/core branch) is
> available on github: [4].
>
Not sure if related, but after updating my toolchain
(aarch64-linux-gnu-gcc (Debian 15.2.0-4) 15.2.0), I hit link errors:
ld.lld: error: arch/arm64/kernel/vdso/vgettimeofday.o:(.sframe) is being placed in '.sframe'
ld.lld: error: arch/arm64/kernel/vdso/vgetrandom.o:(.sframe) is being placed in '.sframe`
I applied this series hoping that fix it, but it doesn't, so far I
have this hack :
diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vdso.lds.S
index 52314be29191..53bdf757ee44 100644
--- a/arch/arm64/kernel/vdso/vdso.lds.S
+++ b/arch/arm64/kernel/vdso/vdso.lds.S
@@ -77,7 +77,7 @@ SECTIONS
/DISCARD/ : {
*(.data .data.* .gnu.linkonce.d.* .sdata*)
*(.bss .sbss .dynbss .dynsbss)
- *(.eh_frame .eh_frame_hdr)
+ *(.eh_frame .eh_frame_hdr .sframe)
}
}
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 60c8c22fd3e4..759903acd6fc 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -1064,6 +1064,7 @@
/* ld.bfd warns about .gnu.version* even when not emitted */ \
*(.gnu.version*) \
*(__tracepoint_check) \
+ *(.sframe) \
#define DISCARDS \
/DISCARD/ : { \
Thanks,
Mostafa
^ permalink raw reply related
* Re: [PATCH] firmware: arm_scmi: Fix OOB in scmi_power_name_get()
From: Geert Uytterhoeven @ 2026-05-15 11:29 UTC (permalink / raw)
To: Dan Carpenter
Cc: Sudeep Holla, Cristian Marussi, arm-scmi, linux-arm-kernel,
linux-kernel
In-Reply-To: <agb1Q6mrGyDwFdmO@stanley.mountain>
Hi Dan,
On Fri, 15 May 2026 at 12:28, Dan Carpenter <error27@gmail.com> wrote:
> On Fri, May 15, 2026 at 11:59:15AM +0200, Geert Uytterhoeven wrote:
> > scmi_power_name_get() does not validate the domain number passed by the
> > external caller, which may lead to an out-of-bounds access.
>
> Is an external caller an out of tree caller? So far as I can see this
I meant a caller outside drivers/firmware/arm_scmi/.
> is only called by scmi_pm_domain_probe().
>
> scmi_pd->name = power_ops->name_get(ph, i);
>
> where i < num_domains.
You are right. But this seems to be only API implementation in
drivers/firmware/arm_scmi/ that does not validate the passed domain
number.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH v5 1/7] perf unwind: Refactor get_entries to allow dynamic libdw/libunwind selection
From: Arnaldo Carvalho de Melo @ 2026-05-15 11:27 UTC (permalink / raw)
To: Ian Rogers
Cc: adrian.hunter, dapeng1.mi, james.clark, namhyung,
Florian Fainelli, Li Guan, 9erthalion6, alex, alexander.shishkin,
andrew.jones, aou, atrajeev, howardchu95, john.g.garry, jolsa,
leo.yan, libunwind-devel, linux-arm-kernel, linux-kernel,
linux-perf-users, linux-riscv, mingo, palmer, peterz, pjw,
shimin.guo, tglozar, tmricht, will
In-Reply-To: <agZk-CCrLUMTyWE4@x1>
On Thu, May 14, 2026 at 09:12:40PM -0300, Arnaldo Carvalho de Melo wrote:
> On Wed, May 13, 2026 at 04:31:45PM -0700, Ian Rogers wrote:
<SNIP>
> > +++ b/tools/perf/util/unwind.h
<SNIP>
> > +static inline int libdw__get_entries(unwind_entry_cb_t cb __maybe_unused, void *arg __maybe_unused,
> > + struct thread *thread __maybe_unused,
> > + struct perf_sample *data __maybe_unused,
> > + int max_stack __maybe_unused,
> > + bool best_effort __maybe_unused)
> > +{
> > + pr_err("Error: libdw dwarf unwinding not built into perf\n");
> > + return 0;
> > +}
> > +#endif
I also addressed this local sashiko review comment:
-------------------------------------------------------------------------
Since unwinding is performed per-sample in the hot path, will using pr_err()
here cause console flooding if the user explicitly configures an unsupported
unwind style?
Should this use pr_warning_once() instead, similar to the UNWIND_STYLE_UNKNOWN
fallback behavior in unwind.c?
-------------------------------------------------------------------------
And in one other place, please ack,
- Arnaldo
diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h
index 28db3e3b9b513401..69ba08afda792d17 100644
--- a/tools/perf/util/unwind.h
+++ b/tools/perf/util/unwind.h
@@ -53,7 +53,7 @@ static inline int libdw__get_entries(unwind_entry_cb_t cb __maybe_unused, void *
int max_stack __maybe_unused,
bool best_effort __maybe_unused)
{
- pr_err("Error: libdw dwarf unwinding not built into perf\n");
+ pr_warning_once("Error: libdw dwarf unwinding not built into perf\n");
return 0;
}
#endif
@@ -81,7 +81,7 @@ static inline int libunwind__get_entries(unwind_entry_cb_t cb __maybe_unused,
int max_stack __maybe_unused,
bool best_effort __maybe_unused)
{
- pr_err("Error: libunwind dwarf unwinding not built into perf\n");
+ pr_warning_once("Error: libunwind dwarf unwinding not built into perf\n");
return 0;
}
^ permalink raw reply related
* [PATCH v2 4/4] ASoC: stm: stm32_spdifrx: Use guard() for spin locks
From: phucduc.bui @ 2026-05-15 11:24 UTC (permalink / raw)
To: olivier.moysan, arnaud.pouliquen, broonie
Cc: lgirdwood, perex, tiwai, mcoquelin.stm32, alexandre.torgue,
linux-sound, linux-stm32, linux-arm-kernel, linux-kernel,
bui duc phuc
In-Reply-To: <20260515112458.34378-1-phucduc.bui@gmail.com>
From: bui duc phuc <phucduc.bui@gmail.com>
Clean up the code using guard() for spin locks.
Merely code refactoring, and no behavior change.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
sound/soc/stm/stm32_spdifrx.c | 44 +++++++++++++----------------------
1 file changed, 16 insertions(+), 28 deletions(-)
diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c
index 57b711c44278..2f83ca989e68 100644
--- a/sound/soc/stm/stm32_spdifrx.c
+++ b/sound/soc/stm/stm32_spdifrx.c
@@ -322,7 +322,6 @@ static void stm32_spdifrx_dma_ctrl_stop(struct stm32_spdifrx_data *spdifrx)
static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)
{
int cr, cr_mask, imr, ret;
- unsigned long flags;
/* Enable IRQs */
imr = SPDIFRX_IMR_IFEIE | SPDIFRX_IMR_SYNCDIE | SPDIFRX_IMR_PERRIE;
@@ -330,7 +329,7 @@ static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)
if (ret)
return ret;
- spin_lock_irqsave(&spdifrx->lock, flags);
+ guard(spinlock_irqsave)(&spdifrx->lock);
spdifrx->refcount++;
@@ -365,22 +364,17 @@ static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx)
"Failed to start synchronization\n");
}
- spin_unlock_irqrestore(&spdifrx->lock, flags);
-
return ret;
}
static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx)
{
int cr, cr_mask, reg;
- unsigned long flags;
- spin_lock_irqsave(&spdifrx->lock, flags);
+ guard(spinlock_irqsave)(&spdifrx->lock);
- if (--spdifrx->refcount) {
- spin_unlock_irqrestore(&spdifrx->lock, flags);
+ if (--spdifrx->refcount)
return;
- }
cr = SPDIFRX_CR_SPDIFENSET(SPDIFRX_SPDIFEN_DISABLE);
cr_mask = SPDIFRX_CR_SPDIFEN_MASK | SPDIFRX_CR_RXDMAEN;
@@ -396,8 +390,6 @@ static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx)
/* dummy read to clear CSRNE and RXNE in status register */
regmap_read(spdifrx->regmap, STM32_SPDIFRX_DR, ®);
regmap_read(spdifrx->regmap, STM32_SPDIFRX_CSR, ®);
-
- spin_unlock_irqrestore(&spdifrx->lock, flags);
}
static int stm32_spdifrx_dma_ctrl_register(struct device *dev,
@@ -744,19 +736,19 @@ static irqreturn_t stm32_spdifrx_isr(int irq, void *devid)
return IRQ_HANDLED;
}
- spin_lock(&spdifrx->irq_lock);
- if (spdifrx->substream)
- snd_pcm_stop(spdifrx->substream,
- SNDRV_PCM_STATE_DISCONNECTED);
- spin_unlock(&spdifrx->irq_lock);
+ scoped_guard(spinlock, &spdifrx->irq_lock) {
+ if (spdifrx->substream)
+ snd_pcm_stop(spdifrx->substream,
+ SNDRV_PCM_STATE_DISCONNECTED);
+ }
return IRQ_HANDLED;
}
- spin_lock(&spdifrx->irq_lock);
- if (err_xrun && spdifrx->substream)
- snd_pcm_stop_xrun(spdifrx->substream);
- spin_unlock(&spdifrx->irq_lock);
+ scoped_guard(spinlock, &spdifrx->irq_lock) {
+ if (err_xrun && spdifrx->substream)
+ snd_pcm_stop_xrun(spdifrx->substream);
+ }
return IRQ_HANDLED;
}
@@ -765,12 +757,10 @@ static int stm32_spdifrx_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned long flags;
int ret;
- spin_lock_irqsave(&spdifrx->irq_lock, flags);
- spdifrx->substream = substream;
- spin_unlock_irqrestore(&spdifrx->irq_lock, flags);
+ scoped_guard(spinlock_irqsave, &spdifrx->irq_lock)
+ spdifrx->substream = substream;
ret = clk_prepare_enable(spdifrx->kclk);
if (ret)
@@ -846,11 +836,9 @@ static void stm32_spdifrx_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned long flags;
- spin_lock_irqsave(&spdifrx->irq_lock, flags);
- spdifrx->substream = NULL;
- spin_unlock_irqrestore(&spdifrx->irq_lock, flags);
+ scoped_guard(spinlock_irqsave, &spdifrx->irq_lock)
+ spdifrx->substream = NULL;
clk_disable_unprepare(spdifrx->kclk);
}
--
2.43.0
^ permalink raw reply related
* [PATCH v2 3/4] ASoC: stm: stm32_sai_sub: Use guard() for mutex & spin locks
From: phucduc.bui @ 2026-05-15 11:24 UTC (permalink / raw)
To: olivier.moysan, arnaud.pouliquen, broonie
Cc: lgirdwood, perex, tiwai, mcoquelin.stm32, alexandre.torgue,
linux-sound, linux-stm32, linux-arm-kernel, linux-kernel,
bui duc phuc
In-Reply-To: <20260515112458.34378-1-phucduc.bui@gmail.com>
From: bui duc phuc <phucduc.bui@gmail.com>
Clean up the code using guard() for mutex & spin locks.
Merely code refactoring, and no behavior change.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
sound/soc/stm/stm32_sai_sub.c | 29 +++++++++++------------------
1 file changed, 11 insertions(+), 18 deletions(-)
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
index 3e82fa90e719..ea9e8bddd63f 100644
--- a/sound/soc/stm/stm32_sai_sub.c
+++ b/sound/soc/stm/stm32_sai_sub.c
@@ -280,9 +280,8 @@ static int snd_pcm_iec958_get(struct snd_kcontrol *kcontrol,
{
struct stm32_sai_sub_data *sai = snd_kcontrol_chip(kcontrol);
- mutex_lock(&sai->ctrl_lock);
+ guard(mutex)(&sai->ctrl_lock);
memcpy(uctl->value.iec958.status, sai->iec958.status, 4);
- mutex_unlock(&sai->ctrl_lock);
return 0;
}
@@ -292,9 +291,8 @@ static int snd_pcm_iec958_put(struct snd_kcontrol *kcontrol,
{
struct stm32_sai_sub_data *sai = snd_kcontrol_chip(kcontrol);
- mutex_lock(&sai->ctrl_lock);
+ guard(mutex)(&sai->ctrl_lock);
memcpy(sai->iec958.status, uctl->value.iec958.status, 4);
- mutex_unlock(&sai->ctrl_lock);
return 0;
}
@@ -658,10 +656,10 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid)
status = SNDRV_PCM_STATE_XRUN;
}
- spin_lock(&sai->irq_lock);
- if (status != SNDRV_PCM_STATE_RUNNING && sai->substream)
- snd_pcm_stop_xrun(sai->substream);
- spin_unlock(&sai->irq_lock);
+ scoped_guard(spinlock, &sai->irq_lock) {
+ if (status != SNDRV_PCM_STATE_RUNNING && sai->substream)
+ snd_pcm_stop_xrun(sai->substream);
+ }
return IRQ_HANDLED;
}
@@ -894,11 +892,9 @@ static int stm32_sai_startup(struct snd_pcm_substream *substream,
{
struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
int imr, cr2, ret;
- unsigned long flags;
- spin_lock_irqsave(&sai->irq_lock, flags);
- sai->substream = substream;
- spin_unlock_irqrestore(&sai->irq_lock, flags);
+ scoped_guard(spinlock_irqsave, &sai->irq_lock)
+ sai->substream = substream;
if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
snd_pcm_hw_constraint_mask64(substream->runtime,
@@ -1083,7 +1079,7 @@ static void stm32_sai_set_iec958_status(struct stm32_sai_sub_data *sai,
return;
/* Force the sample rate according to runtime rate */
- mutex_lock(&sai->ctrl_lock);
+ guard(mutex)(&sai->ctrl_lock);
switch (runtime->rate) {
case 22050:
sai->iec958.status[3] = IEC958_AES3_CON_FS_22050;
@@ -1116,7 +1112,6 @@ static void stm32_sai_set_iec958_status(struct stm32_sai_sub_data *sai,
sai->iec958.status[3] = IEC958_AES3_CON_FS_NOTID;
break;
}
- mutex_unlock(&sai->ctrl_lock);
}
static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai,
@@ -1284,7 +1279,6 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned long flags;
stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0);
@@ -1298,9 +1292,8 @@ static void stm32_sai_shutdown(struct snd_pcm_substream *substream,
if (!sai->sai_mclk && sai->put_sai_ck_rate)
sai->put_sai_ck_rate(sai);
- spin_lock_irqsave(&sai->irq_lock, flags);
- sai->substream = NULL;
- spin_unlock_irqrestore(&sai->irq_lock, flags);
+ scoped_guard(spinlock_irqsave, &sai->irq_lock)
+ sai->substream = NULL;
}
static int stm32_sai_pcm_new(struct snd_soc_pcm_runtime *rtd,
--
2.43.0
^ permalink raw reply related
* [PATCH v2 2/4] ASoC: stm: stm32_i2s: Use guard() for spin locks
From: phucduc.bui @ 2026-05-15 11:24 UTC (permalink / raw)
To: olivier.moysan, arnaud.pouliquen, broonie
Cc: lgirdwood, perex, tiwai, mcoquelin.stm32, alexandre.torgue,
linux-sound, linux-stm32, linux-arm-kernel, linux-kernel,
bui duc phuc
In-Reply-To: <20260515112458.34378-1-phucduc.bui@gmail.com>
From: bui duc phuc <phucduc.bui@gmail.com>
Clean up the code using guard() for spin locks.
Merely code refactoring, and no behavior change.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
Changes in v2:
Replace break statements inside scoped_guard() blocks with return 0
in stm32_i2s trigger handling, since break only exits the implicit
scoped_guard loop rather than the function switch block.
sound/soc/stm/stm32_i2s.c | 67 ++++++++++++++++++---------------------
1 file changed, 30 insertions(+), 37 deletions(-)
diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c
index 6ca21780f21d..ae9e25657f3f 100644
--- a/sound/soc/stm/stm32_i2s.c
+++ b/sound/soc/stm/stm32_i2s.c
@@ -615,10 +615,10 @@ static irqreturn_t stm32_i2s_isr(int irq, void *devid)
if (flags & I2S_SR_TIFRE)
dev_dbg(&pdev->dev, "Frame error\n");
- spin_lock(&i2s->irq_lock);
- if (err && i2s->substream)
- snd_pcm_stop_xrun(i2s->substream);
- spin_unlock(&i2s->irq_lock);
+ scoped_guard(spinlock, &i2s->irq_lock) {
+ if (err && i2s->substream)
+ snd_pcm_stop_xrun(i2s->substream);
+ }
return IRQ_HANDLED;
}
@@ -905,12 +905,10 @@ static int stm32_i2s_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned long flags;
int ret;
- spin_lock_irqsave(&i2s->irq_lock, flags);
- i2s->substream = substream;
- spin_unlock_irqrestore(&i2s->irq_lock, flags);
+ scoped_guard(spinlock_irqsave, &i2s->irq_lock)
+ i2s->substream = substream;
if ((i2s->fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_DSP_A)
snd_pcm_hw_constraint_single(substream->runtime,
@@ -982,19 +980,19 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
regmap_write_bits(i2s->regmap, STM32_I2S_IFCR_REG,
I2S_IFCR_MASK, I2S_IFCR_MASK);
- spin_lock(&i2s->lock_fd);
- i2s->refcount++;
- if (playback_flg) {
- ier = I2S_IER_UDRIE;
- } else {
- ier = I2S_IER_OVRIE;
-
- if (STM32_I2S_IS_MASTER(i2s) && i2s->refcount == 1)
- /* dummy write to gate bus clocks */
- regmap_write(i2s->regmap,
- STM32_I2S_TXDR_REG, 0);
+ scoped_guard(spinlock, &i2s->lock_fd) {
+ i2s->refcount++;
+ if (playback_flg) {
+ ier = I2S_IER_UDRIE;
+ } else {
+ ier = I2S_IER_OVRIE;
+
+ if (STM32_I2S_IS_MASTER(i2s) && i2s->refcount == 1)
+ /* dummy write to gate bus clocks */
+ regmap_write(i2s->regmap,
+ STM32_I2S_TXDR_REG, 0);
+ }
}
- spin_unlock(&i2s->lock_fd);
if (STM32_I2S_IS_SLAVE(i2s))
ier |= I2S_IER_TIFREIE;
@@ -1016,21 +1014,18 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
I2S_IER_OVRIE,
(unsigned int)~I2S_IER_OVRIE);
- spin_lock(&i2s->lock_fd);
- i2s->refcount--;
- if (i2s->refcount) {
- spin_unlock(&i2s->lock_fd);
- break;
- }
+ scoped_guard(spinlock, &i2s->lock_fd) {
+ i2s->refcount--;
+ if (i2s->refcount)
+ return 0;
- ret = regmap_update_bits(i2s->regmap, STM32_I2S_CR1_REG,
- I2S_CR1_SPE, 0);
- if (ret < 0) {
- dev_err(cpu_dai->dev, "Error %d disabling I2S\n", ret);
- spin_unlock(&i2s->lock_fd);
- return ret;
+ ret = regmap_update_bits(i2s->regmap, STM32_I2S_CR1_REG,
+ I2S_CR1_SPE, 0);
+ if (ret < 0) {
+ dev_err(cpu_dai->dev, "Error %d disabling I2S\n", ret);
+ return ret;
+ }
}
- spin_unlock(&i2s->lock_fd);
cfg1_mask = I2S_CFG1_RXDMAEN | I2S_CFG1_TXDMAEN;
regmap_update_bits(i2s->regmap, STM32_I2S_CFG1_REG,
@@ -1047,7 +1042,6 @@ static void stm32_i2s_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai);
- unsigned long flags;
clk_disable_unprepare(i2s->i2sclk);
@@ -1059,9 +1053,8 @@ static void stm32_i2s_shutdown(struct snd_pcm_substream *substream,
if (!i2s->i2smclk && i2s->put_i2s_clk_rate)
i2s->put_i2s_clk_rate(i2s);
- spin_lock_irqsave(&i2s->irq_lock, flags);
- i2s->substream = NULL;
- spin_unlock_irqrestore(&i2s->irq_lock, flags);
+ scoped_guard(spinlock_irqsave, &i2s->irq_lock)
+ i2s->substream = NULL;
}
static int stm32_i2s_dai_probe(struct snd_soc_dai *cpu_dai)
--
2.43.0
^ permalink raw reply related
* [PATCH v2 1/4] ASoC: stm: stm32_adfsdm: Use guard() for mutex locks
From: phucduc.bui @ 2026-05-15 11:24 UTC (permalink / raw)
To: olivier.moysan, arnaud.pouliquen, broonie
Cc: lgirdwood, perex, tiwai, mcoquelin.stm32, alexandre.torgue,
linux-sound, linux-stm32, linux-arm-kernel, linux-kernel,
bui duc phuc
In-Reply-To: <20260515112458.34378-1-phucduc.bui@gmail.com>
From: bui duc phuc <phucduc.bui@gmail.com>
Clean up the code using guard() for mutex locks.
Merely code refactoring, and no behavior change.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
sound/soc/stm/stm32_adfsdm.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c
index 0f6d32814c22..a585cb9fc011 100644
--- a/sound/soc/stm/stm32_adfsdm.c
+++ b/sound/soc/stm/stm32_adfsdm.c
@@ -62,12 +62,11 @@ static void stm32_adfsdm_shutdown(struct snd_pcm_substream *substream,
{
struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
- mutex_lock(&priv->lock);
+ guard(mutex)(&priv->lock);
if (priv->iio_active) {
iio_channel_stop_all_cb(priv->iio_cb);
priv->iio_active = false;
}
- mutex_unlock(&priv->lock);
}
static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
@@ -76,7 +75,7 @@ static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
int ret;
- mutex_lock(&priv->lock);
+ guard(mutex)(&priv->lock);
if (priv->iio_active) {
iio_channel_stop_all_cb(priv->iio_cb);
priv->iio_active = false;
@@ -88,7 +87,7 @@ static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
if (ret < 0) {
dev_err(dai->dev, "%s: Failed to set %d sampling rate\n",
__func__, substream->runtime->rate);
- goto out;
+ return ret;
}
if (!priv->iio_active) {
@@ -100,9 +99,6 @@ static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
__func__, ret);
}
-out:
- mutex_unlock(&priv->lock);
-
return ret;
}
--
2.43.0
^ permalink raw reply related
* [PATCH v2 0/4] ASoC: stm: Use guard() for mutex & spin locks
From: phucduc.bui @ 2026-05-15 11:24 UTC (permalink / raw)
To: olivier.moysan, arnaud.pouliquen, broonie
Cc: lgirdwood, perex, tiwai, mcoquelin.stm32, alexandre.torgue,
linux-sound, linux-stm32, linux-arm-kernel, linux-kernel,
bui duc phuc
From: bui duc phuc <phucduc.bui@gmail.com>
Hi all,
This series converts mutex and spinlock handling in the STM drivers
to use guard() helpers.
The changes are code cleanup only and should have no functional impact.
Best regards,
Phuc
Changes in v2:
Replace break statements inside scoped_guard() blocks with return 0
in stm32_i2s trigger handling, since break only exits the implicit
scoped_guard loop rather than the function switch block.
bui duc phuc (4):
ASoC: stm: stm32_adfsdm: Use guard() for mutex locks
ASoC: stm: stm32_i2s: Use guard() for spin locks
ASoC: stm: stm32_sai_sub: Use guard() for mutex & spin locks
ASoC: stm: stm32_spdifrx: Use guard() for spin locks
sound/soc/stm/stm32_adfsdm.c | 10 ++----
sound/soc/stm/stm32_i2s.c | 67 ++++++++++++++++-------------------
sound/soc/stm/stm32_sai_sub.c | 29 ++++++---------
sound/soc/stm/stm32_spdifrx.c | 44 +++++++++--------------
4 files changed, 60 insertions(+), 90 deletions(-)
--
2.43.0
^ permalink raw reply
* Re: [PATCH v2 01/17] ACPI: GTDT: Account for GTDTv3 size when walking the platform timer descriptors
From: Marc Zyngier @ 2026-05-15 11:23 UTC (permalink / raw)
To: Sudeep Holla
Cc: linux-arm-kernel, linux-acpi, linux-kernel, devicetree,
Lorenzo Pieralisi, Hanjun Guo, Catalin Marinas, Will Deacon,
Rafael J. Wysocki, Mark Rutland, Daniel Lezcano, Thomas Gleixner,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Neil Armstrong, Kevin Hilman,
Jerome Brunet, Martin Blumenstingl, Ge Gordon,
BST Linux Kernel Upstream Group, Jesper Nilsson, Lars Persson,
Alim Akhtar, Ivaylo Ivanov, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Dinh Nguyen,
Matthias Brugger, AngeloGioacchino Del Regno, Thierry Reding,
Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
Andreas Färber, Heiko Stuebner, Shawn Lin, Orson Zhai,
Baolin Wang, Michal Simek
In-Reply-To: <20260515-prudent-vagabond-beetle-cad34b@sudeepholla>
On Fri, 15 May 2026 10:51:52 +0100,
Sudeep Holla <sudeep.holla@kernel.org> wrote:
>
> On Thu, May 14, 2026 at 04:09:29PM +0100, Marc Zyngier wrote:
> > Since ARMv8.1, the architecture has grown an EL2-private virtual
> > timer. This has been described in ACPI since ACPI v6.3 and revision
> > 3 of the GTDT table.
> >
> > An aditional structure was added in ACPICA, though in a rather
> > bizarre way, and merged in v5.1 as 8f5a14d053100 ("ACPICA: ACPI 6.3:
> > add GTDT Revision 3 support").
> >
> > Finally plug the table parsing in GTDT, and correct the parsing of
> > the platform timer subtables to account for the expanded size of
> > the base table.
> >
> > Suggested-by: Sudeep Holla <sudeep.holla@kernel.org>
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > ---
> > drivers/acpi/arm64/gtdt.c | 15 ++++++++++++++-
> > 1 file changed, 14 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
> > index ffc867bac2d60..b9d9b8edf2df7 100644
> > --- a/drivers/acpi/arm64/gtdt.c
> > +++ b/drivers/acpi/arm64/gtdt.c
> > @@ -32,6 +32,12 @@ struct acpi_gtdt_descriptor {
> > struct acpi_table_gtdt *gtdt;
> > void *gtdt_end;
> > void *platform_timer;
> > + bool v3;
> > +};
> > +
> > +struct gtdt_v3 {
> > + struct acpi_table_gtdt gtdt_v2;
> > + struct acpi_gtdt_el2 el2_vtimer;
> > };
> >
> > static struct acpi_gtdt_descriptor acpi_gtdt_desc __initdata;
> > @@ -39,8 +45,14 @@ static struct acpi_gtdt_descriptor acpi_gtdt_desc __initdata;
> > static __init bool platform_timer_valid(void *platform_timer)
> > {
> > struct acpi_gtdt_header *gh = platform_timer;
> > + void *platform_timer_begin;
> > +
> > + if (acpi_gtdt_desc.v3)
> > + platform_timer_begin = container_of(acpi_gtdt_desc.gtdt, struct gtdt_v3, gtdt_v2) + 1;
> > + else
> > + platform_timer_begin = acpi_gtdt_desc.gtdt + 1;
> >
> > - return (platform_timer >= (void *)(acpi_gtdt_desc.gtdt + 1) &&
> > + return (platform_timer >= platform_timer_begin &&
> > platform_timer < acpi_gtdt_desc.gtdt_end &&
> > gh->length != 0 &&
> > platform_timer + gh->length <= acpi_gtdt_desc.gtdt_end);
> > @@ -169,6 +181,7 @@ int __init acpi_gtdt_init(struct acpi_table_header *table,
> > acpi_gtdt_desc.gtdt = gtdt;
> > acpi_gtdt_desc.gtdt_end = (void *)table + table->length;
> > acpi_gtdt_desc.platform_timer = NULL;
> > + acpi_gtdt_desc.v3 = gtdt->header.revision >= 3 && gtdt->header.length >= sizeof(struct gtdt_v3);
>
> Regarding Sashiko’s comment about the missing length validation for GTDT v2, I
> realised that the current check could cause a malformed v3 table to be
> interpreted as v2 if its length does not match the expected v3
> length.
Yeah, that's overall dodgy. As much as I hate having to write a
validating parser for ACPI, we need to be prepared for the worst.
> It would be better to fail early and return an error rather than allow
> processing to continue with the table incorrectly interpreted as v2.
How about something like the hack below?
Thanks,
M.
diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c
index 12bc8875e95e2..ceec69609f038 100644
--- a/drivers/acpi/arm64/gtdt.c
+++ b/drivers/acpi/arm64/gtdt.c
@@ -202,7 +202,15 @@ int __init acpi_gtdt_init(struct acpi_table_header *table,
acpi_gtdt_desc.gtdt = gtdt;
acpi_gtdt_desc.gtdt_end = (void *)table + table->length;
acpi_gtdt_desc.platform_timer = NULL;
- acpi_gtdt_desc.v3 = gtdt->header.revision >= 3 && gtdt->header.length >= sizeof(struct gtdt_v3);
+
+ if ((gtdt->header.revision >= 3 && gtdt->header.length < sizeof(struct gtdt_v3)) ||
+ (gtdt->header.revision == 2 && gtdt->header.length < sizeof(*gtdt))) {
+ pr_err(FW_BUG "GTDT with invalid size %d\n", gtdt->header.length);
+ return -EINVAL;
+ }
+
+ acpi_gtdt_desc.v3 = gtdt->header.revision >= 3;
+
if (platform_timer_count)
*platform_timer_count = 0;
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply related
* [PATCH v3 3/3] pinctrl: aspeed: Add AST2700 SoC1 support
From: Billy Tsai @ 2026-05-15 9:37 UTC (permalink / raw)
To: Linus Walleij, Tony Lindgren, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Joel Stanley, Andrew Jeffery, Bartosz Golaszewski,
Lee Jones, Ryan Chen
Cc: patrickw3, linux-gpio, devicetree, linux-kernel, linux-arm-kernel,
linux-aspeed, BMC-SW, openbmc, Andrew Jeffery, linux-clk,
Billy Tsai
In-Reply-To: <20260515-pinctrl-single-bit-v3-0-e97da4312104@aspeedtech.com>
Implement pin multiplexing (and pin configuration where applicable)
for the AST2700 SoC1 SCU pinctrl block using static SoC data tables.
Unlike legacy ASPEED pin controllers, the SoC1 pin function control
fields are highly regular, which makes it practical to describe the
packed-field register layout directly in driver data rather than reuse
the existing Aspeed pinctrl macro infrastructure.
The driver uses the generic pinctrl, pinmux and pinconf frameworks.
The controller registers are accessed via regmap from the parent
syscon, allowing shared ownership of the SCU register block.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/pinctrl/aspeed/Kconfig | 14 +
drivers/pinctrl/aspeed/Makefile | 1 +
drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c | 1732 +++++++++++++++++++++++
3 files changed, 1747 insertions(+)
diff --git a/drivers/pinctrl/aspeed/Kconfig b/drivers/pinctrl/aspeed/Kconfig
index f9672cca891e..8e1d4da0891d 100644
--- a/drivers/pinctrl/aspeed/Kconfig
+++ b/drivers/pinctrl/aspeed/Kconfig
@@ -40,3 +40,17 @@ config PINCTRL_ASPEED_G7_SOC0
Say Y here to enable pin controller support for the SoC0 instance
of Aspeed's 7th generation SoCs. GPIO is provided by a separate
GPIO driver.
+
+config PINCTRL_ASPEED_G7_SOC1
+ bool "Aspeed G7 SoC1 pin control"
+ depends on (ARCH_ASPEED || COMPILE_TEST) && OF
+ select MFD_SYSCON
+ select PINMUX
+ select GENERIC_PINCTRL_GROUPS
+ select GENERIC_PINMUX_FUNCTIONS
+ select GENERIC_PINCONF
+ select REGMAP_MMIO
+ help
+ Say Y here to enable pin controller support for the SoC1 instance
+ of Aspeed's 7th generation SoCs. GPIO is provided by a separate
+ GPIO driver.
diff --git a/drivers/pinctrl/aspeed/Makefile b/drivers/pinctrl/aspeed/Makefile
index 0de524ca2c72..7a41ca45c6ba 100644
--- a/drivers/pinctrl/aspeed/Makefile
+++ b/drivers/pinctrl/aspeed/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_PINCTRL_ASPEED_G4) += pinctrl-aspeed-g4.o
obj-$(CONFIG_PINCTRL_ASPEED_G5) += pinctrl-aspeed-g5.o
obj-$(CONFIG_PINCTRL_ASPEED_G6) += pinctrl-aspeed-g6.o
obj-$(CONFIG_PINCTRL_ASPEED_G7_SOC0) += pinctrl-aspeed-g7-soc0.o
+obj-$(CONFIG_PINCTRL_ASPEED_G7_SOC1) += pinctrl-aspeed-g7-soc1.o
diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c
new file mode 100644
index 000000000000..09d41ad4e52d
--- /dev/null
+++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc1.c
@@ -0,0 +1,1732 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Pinctrl driver for Aspeed G7 SoC1
+ *
+ * Copyright (C) 2026 Aspeed Technology Inc.
+ */
+
+#include <linux/errno.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#include "../core.h"
+#include "../pinconf.h"
+#include "../pinctrl-utils.h"
+#include "../pinmux.h"
+
+#define ASPEED_G7_SOC1_NR_PINS 220
+#define ASPEED_G7_SOC1_REG_WIDTH 32
+#define ASPEED_G7_SOC1_REG_STRIDE 4
+
+#define ASPEED_G7_SOC1_MUX_BASE 0x400
+#define ASPEED_G7_SOC1_BIAS_BASE 0x480
+#define ASPEED_G7_SOC1_DRV_BASE 0x4C0
+#define ASPEED_G7_SOC1_PCIE_REG 0x908
+#define ASPEED_G7_SOC1_USB_MODE_REG 0x3B0
+
+#define ASPEED_G7_SOC1_MUX_FUNC_MASK 0x7
+#define ASPEED_G7_SOC1_MUX_BITS_PER_PIN 4
+#define ASPEED_G7_SOC1_MUX_PINS_PER_REG \
+ (ASPEED_G7_SOC1_REG_WIDTH / ASPEED_G7_SOC1_MUX_BITS_PER_PIN)
+
+#define ASPEED_G7_SOC1_BIAS_FUNC_MASK 0x1
+#define ASPEED_G7_SOC1_BIAS_BITS_PER_PIN 1
+#define ASPEED_G7_SOC1_BIAS_PINS_PER_REG \
+ (ASPEED_G7_SOC1_REG_WIDTH / ASPEED_G7_SOC1_BIAS_BITS_PER_PIN)
+
+#define ASPEED_G7_SOC1_DRV_FUNC_MASK 0x3
+#define ASPEED_G7_SOC1_DRV_BITS_PER_PIN 2
+#define ASPEED_G7_SOC1_DRV_PINS_PER_REG \
+ (ASPEED_G7_SOC1_REG_WIDTH / ASPEED_G7_SOC1_DRV_BITS_PER_PIN)
+
+#define ASPEED_G7_SOC1_DRV_STRENGTH_STEP_MA 4
+#define ASPEED_G7_SOC1_DRV_STRENGTH_HW_BASE 1
+#define ASPEED_G7_SOC1_DRV_STRENGTH_MIN_MA \
+ (ASPEED_G7_SOC1_DRV_STRENGTH_HW_BASE * ASPEED_G7_SOC1_DRV_STRENGTH_STEP_MA)
+#define ASPEED_G7_SOC1_DRV_STRENGTH_MAX_MA \
+ ((ASPEED_G7_SOC1_DRV_FUNC_MASK + ASPEED_G7_SOC1_DRV_STRENGTH_HW_BASE) * \
+ ASPEED_G7_SOC1_DRV_STRENGTH_STEP_MA)
+
+/*
+ * NOTE: The numeric values of these enum entries are significant.
+ * They must match the SoC GPIO numbering / ball-to-GPIO ID mapping.
+ * Do not reorder alphabetically.
+ */
+enum {
+ C16,
+ C14,
+ C11,
+ D9,
+ F14,
+ D10,
+ C12,
+ C13,
+ AC26,
+ AA25,
+ AB23,
+ U22,
+ V21,
+ N26,
+ P25,
+ N25,
+ V23,
+ W22,
+ AB26,
+ AD26,
+ P26,
+ AE26,
+ AF26,
+ AF25,
+ AE25,
+ AD25,
+ AF23,
+ AF20,
+ AF21,
+ AE21,
+ AE23,
+ AD22,
+ AF17,
+ AA16,
+ Y16,
+ V17,
+ J13,
+ AB16,
+ AC16,
+ AF16,
+ AA15,
+ AB15,
+ AC15,
+ AD15,
+ Y15,
+ AA14,
+ W16,
+ V16,
+ AB18,
+ AC18,
+ K13,
+ AA17,
+ AB17,
+ AD16,
+ AC17,
+ AD17,
+ AE16,
+ AE17,
+ AB24,
+ W26,
+ HOLE0,
+ HOLE1,
+ HOLE2,
+ HOLE3,
+ W25,
+ Y23,
+ Y24,
+ W21,
+ AA23,
+ AC22,
+ AB22,
+ Y21,
+ AE20,
+ AF19,
+ Y22,
+ AA20,
+ AA22,
+ AB20,
+ AF18,
+ AE19,
+ AD20,
+ AC20,
+ AA21,
+ AB21,
+ AC19,
+ AE18,
+ AD19,
+ AD18,
+ U25,
+ U26,
+ Y26,
+ AA24,
+ R25,
+ AA26,
+ R26,
+ Y25,
+ B16,
+ D14,
+ B15,
+ B14,
+ C17,
+ B13,
+ E14,
+ C15,
+ D24,
+ B23,
+ B22,
+ C23,
+ B18,
+ B21,
+ M15,
+ B19,
+ B26,
+ A25,
+ A24,
+ B24,
+ E26,
+ A21,
+ A19,
+ A18,
+ D26,
+ C26,
+ A23,
+ A22,
+ B25,
+ F26,
+ A26,
+ A14,
+ E10,
+ E13,
+ D12,
+ F10,
+ E11,
+ F11,
+ F13,
+ N15,
+ C20,
+ C19,
+ A8,
+ R14,
+ A7,
+ P14,
+ D20,
+ A6,
+ B6,
+ N14,
+ B7,
+ B8,
+ B9,
+ M14,
+ J11,
+ E7,
+ D19,
+ B11,
+ D15,
+ B12,
+ B10,
+ P13,
+ C18,
+ C6,
+ C7,
+ D7,
+ N13,
+ C8,
+ C9,
+ C10,
+ M16,
+ A15,
+ G11,
+ H7,
+ H8,
+ H9,
+ H10,
+ H11,
+ J9,
+ J10,
+ E9,
+ F9,
+ F8,
+ M13,
+ F7,
+ D8,
+ E8,
+ L12,
+ F12,
+ E12,
+ J12,
+ G7,
+ G8,
+ G9,
+ G10,
+ K12,
+ W17,
+ V18,
+ W18,
+ Y17,
+ AA18,
+ AA13,
+ Y18,
+ AA12,
+ W20,
+ V20,
+ Y11,
+ V14,
+ V19,
+ W14,
+ Y20,
+ AB19,
+ U21,
+ T24,
+ V24,
+ V22,
+ T23,
+ AC25,
+ AB25,
+ AC24,
+ PCIERC2_PERST,
+ PORTC_MODE,
+ PORTD_MODE,
+ SGMII0,
+};
+
+struct aspeed_g7_soc1_pinctrl {
+ struct device *dev;
+ struct regmap *regmap;
+ struct pinctrl_dev *pctl;
+};
+
+struct aspeed_g7_field {
+ unsigned int reg;
+ unsigned int shift;
+ unsigned int mask;
+};
+
+static struct aspeed_g7_field
+aspeed_g7_soc1_pinmux_field_from_pin(unsigned int pin)
+{
+ return (struct aspeed_g7_field){
+ .reg = ASPEED_G7_SOC1_MUX_BASE +
+ (pin / ASPEED_G7_SOC1_MUX_PINS_PER_REG) *
+ ASPEED_G7_SOC1_REG_STRIDE,
+ .shift = (pin % ASPEED_G7_SOC1_MUX_PINS_PER_REG) *
+ ASPEED_G7_SOC1_MUX_BITS_PER_PIN,
+ .mask = ASPEED_G7_SOC1_MUX_FUNC_MASK,
+ };
+}
+
+static struct aspeed_g7_field
+aspeed_g7_soc1_bias_field_from_pin(unsigned int pin)
+{
+ return (struct aspeed_g7_field){
+ .reg = ASPEED_G7_SOC1_BIAS_BASE +
+ (pin / ASPEED_G7_SOC1_BIAS_PINS_PER_REG) *
+ ASPEED_G7_SOC1_REG_STRIDE,
+ .shift = pin % ASPEED_G7_SOC1_BIAS_PINS_PER_REG,
+ .mask = ASPEED_G7_SOC1_BIAS_FUNC_MASK,
+ };
+}
+
+static struct aspeed_g7_field
+aspeed_g7_soc1_drv_field_from_idx(unsigned int idx)
+{
+ return (struct aspeed_g7_field){
+ .reg = ASPEED_G7_SOC1_DRV_BASE +
+ (idx / ASPEED_G7_SOC1_DRV_PINS_PER_REG) *
+ ASPEED_G7_SOC1_REG_STRIDE,
+ .shift = (idx % ASPEED_G7_SOC1_DRV_PINS_PER_REG) *
+ ASPEED_G7_SOC1_DRV_BITS_PER_PIN,
+ .mask = ASPEED_G7_SOC1_DRV_FUNC_MASK,
+ };
+}
+
+#define PIN(n) PINCTRL_PIN(n, #n)
+
+static const struct pinctrl_pin_desc aspeed_g7_soc1_pins[] = {
+ PIN(C16),
+ PIN(C14),
+ PIN(C11),
+ PIN(D9),
+ PIN(F14),
+ PIN(D10),
+ PIN(C12),
+ PIN(C13),
+ PIN(AC26),
+ PIN(AA25),
+ PIN(AB23),
+ PIN(U22),
+ PIN(V21),
+ PIN(N26),
+ PIN(P25),
+ PIN(N25),
+ PIN(V23),
+ PIN(W22),
+ PIN(AB26),
+ PIN(AD26),
+ PIN(P26),
+ PIN(AE26),
+ PIN(AF26),
+ PIN(AF25),
+ PIN(AE25),
+ PIN(AD25),
+ PIN(AF23),
+ PIN(AF20),
+ PIN(AF21),
+ PIN(AE21),
+ PIN(AE23),
+ PIN(AD22),
+ PIN(AF17),
+ PIN(AA16),
+ PIN(Y16),
+ PIN(V17),
+ PIN(J13),
+ PIN(AB16),
+ PIN(AC16),
+ PIN(AF16),
+ PIN(AA15),
+ PIN(AB15),
+ PIN(AC15),
+ PIN(AD15),
+ PIN(Y15),
+ PIN(AA14),
+ PIN(W16),
+ PIN(V16),
+ PIN(AB18),
+ PIN(AC18),
+ PIN(K13),
+ PIN(AA17),
+ PIN(AB17),
+ PIN(AD16),
+ PIN(AC17),
+ PIN(AD17),
+ PIN(AE16),
+ PIN(AE17),
+ PIN(AB24),
+ PIN(W26),
+ PIN(HOLE0),
+ PIN(HOLE1),
+ PIN(HOLE2),
+ PIN(HOLE3),
+ PIN(W25),
+ PIN(Y23),
+ PIN(Y24),
+ PIN(W21),
+ PIN(AA23),
+ PIN(AC22),
+ PIN(AB22),
+ PIN(Y21),
+ PIN(AE20),
+ PIN(AF19),
+ PIN(Y22),
+ PIN(AA20),
+ PIN(AA22),
+ PIN(AB20),
+ PIN(AF18),
+ PIN(AE19),
+ PIN(AD20),
+ PIN(AC20),
+ PIN(AA21),
+ PIN(AB21),
+ PIN(AC19),
+ PIN(AE18),
+ PIN(AD19),
+ PIN(AD18),
+ PIN(U25),
+ PIN(U26),
+ PIN(Y26),
+ PIN(AA24),
+ PIN(R25),
+ PIN(AA26),
+ PIN(R26),
+ PIN(Y25),
+ PIN(B16),
+ PIN(D14),
+ PIN(B15),
+ PIN(B14),
+ PIN(C17),
+ PIN(B13),
+ PIN(E14),
+ PIN(C15),
+ PIN(D24),
+ PIN(B23),
+ PIN(B22),
+ PIN(C23),
+ PIN(B18),
+ PIN(B21),
+ PIN(M15),
+ PIN(B19),
+ PIN(B26),
+ PIN(A25),
+ PIN(A24),
+ PIN(B24),
+ PIN(E26),
+ PIN(A21),
+ PIN(A19),
+ PIN(A18),
+ PIN(D26),
+ PIN(C26),
+ PIN(A23),
+ PIN(A22),
+ PIN(B25),
+ PIN(F26),
+ PIN(A26),
+ PIN(A14),
+ PIN(E10),
+ PIN(E13),
+ PIN(D12),
+ PIN(F10),
+ PIN(E11),
+ PIN(F11),
+ PIN(F13),
+ PIN(N15),
+ PIN(C20),
+ PIN(C19),
+ PIN(A8),
+ PIN(R14),
+ PIN(A7),
+ PIN(P14),
+ PIN(D20),
+ PIN(A6),
+ PIN(B6),
+ PIN(N14),
+ PIN(B7),
+ PIN(B8),
+ PIN(B9),
+ PIN(M14),
+ PIN(J11),
+ PIN(E7),
+ PIN(D19),
+ PIN(B11),
+ PIN(D15),
+ PIN(B12),
+ PIN(B10),
+ PIN(P13),
+ PIN(C18),
+ PIN(C6),
+ PIN(C7),
+ PIN(D7),
+ PIN(N13),
+ PIN(C8),
+ PIN(C9),
+ PIN(C10),
+ PIN(M16),
+ PIN(A15),
+ PIN(G11),
+ PIN(H7),
+ PIN(H8),
+ PIN(H9),
+ PIN(H10),
+ PIN(H11),
+ PIN(J9),
+ PIN(J10),
+ PIN(E9),
+ PIN(F9),
+ PIN(F8),
+ PIN(M13),
+ PIN(F7),
+ PIN(D8),
+ PIN(E8),
+ PIN(L12),
+ PIN(F12),
+ PIN(E12),
+ PIN(J12),
+ PIN(G7),
+ PIN(G8),
+ PIN(G9),
+ PIN(G10),
+ PIN(K12),
+ PIN(W17),
+ PIN(V18),
+ PIN(W18),
+ PIN(Y17),
+ PIN(AA18),
+ PIN(AA13),
+ PIN(Y18),
+ PIN(AA12),
+ PIN(W20),
+ PIN(V20),
+ PIN(Y11),
+ PIN(V14),
+ PIN(V19),
+ PIN(W14),
+ PIN(Y20),
+ PIN(AB19),
+ PIN(U21),
+ PIN(T24),
+ PIN(V24),
+ PIN(V22),
+ PIN(T23),
+ PIN(AC25),
+ PIN(AB25),
+ PIN(AC24),
+ PIN(PCIERC2_PERST),
+ PIN(PORTC_MODE),
+ PIN(PORTD_MODE),
+ PIN(SGMII0),
+};
+
+static const struct pinctrl_ops aspeed_g7_soc1_pctl_ops = {
+ .get_groups_count = pinctrl_generic_get_group_count,
+ .get_group_name = pinctrl_generic_get_group_name,
+ .get_group_pins = pinctrl_generic_get_group_pins,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+ .dt_free_map = pinctrl_utils_free_map,
+};
+
+struct aspeed_g7_soc1_function {
+ struct pinfunction pinfunction;
+ const u8 *muxvals;
+};
+
+static int aspeed_g7_soc1_drive_strength_to_hw(u32 strength,
+ unsigned int *val)
+{
+ if (strength < ASPEED_G7_SOC1_DRV_STRENGTH_MIN_MA ||
+ strength > ASPEED_G7_SOC1_DRV_STRENGTH_MAX_MA ||
+ strength % ASPEED_G7_SOC1_DRV_STRENGTH_STEP_MA)
+ return -EINVAL;
+
+ *val = (strength / ASPEED_G7_SOC1_DRV_STRENGTH_STEP_MA) -
+ ASPEED_G7_SOC1_DRV_STRENGTH_HW_BASE;
+
+ return 0;
+}
+
+static int aspeed_g7_soc1_set_mux(struct pinctrl_dev *pctldev,
+ unsigned int fselector, unsigned int group)
+{
+ struct aspeed_g7_soc1_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ const struct aspeed_g7_soc1_function *soc1_func;
+ const struct function_desc *fd;
+ const struct pinfunction *func;
+ const struct pingroup *grp;
+ struct group_desc *gd;
+ const char *gname;
+ int i, g_idx = -1, ret;
+
+ gd = pinctrl_generic_get_group(pctldev, group);
+ if (!gd)
+ return -EINVAL;
+
+ grp = &gd->grp;
+
+ fd = pinmux_generic_get_function(pctldev, fselector);
+ if (!fd)
+ return -EINVAL;
+
+ soc1_func = fd->data;
+ if (!soc1_func)
+ return -EINVAL;
+
+ func = &soc1_func->pinfunction;
+ gname = grp->name;
+
+ for (i = 0; i < func->ngroups; i++) {
+ if (!strcmp(gname, func->groups[i])) {
+ g_idx = i;
+ break;
+ }
+ }
+
+ if (g_idx < 0)
+ return -EINVAL;
+
+ for (i = 0; i < grp->npins; i++) {
+ unsigned int val = soc1_func->muxvals[g_idx];
+ unsigned int pin = grp->pins[i];
+ struct aspeed_g7_field field;
+
+ if (pin == PCIERC2_PERST) {
+ /*
+ * PCIERC2_PERST is a special case: it is managed by a
+ * dedicated control register (0x908) instead of the
+ * standard 4-bit multi-function field.
+ */
+ field.reg = ASPEED_G7_SOC1_PCIE_REG;
+ field.shift = 0;
+ field.mask = 0x1;
+ val = 1;
+ } else if (pin == PORTC_MODE || pin == PORTD_MODE) {
+ /*
+ * PORTC_MODE and PORTD_MODE are virtual "pins" that
+ * control the USB 2.0 controller mode settings.
+ * These reside in a specific control register (0x3B0)
+ * with non-standard bit widths.
+ */
+ field.reg = ASPEED_G7_SOC1_USB_MODE_REG;
+ field.mask = 0x3;
+ field.shift = pin == PORTC_MODE ? 0 : 2;
+ } else {
+ /* Standard 4-bit-per-pin multi-function configuration */
+ field = aspeed_g7_soc1_pinmux_field_from_pin(pin);
+ }
+
+ dev_dbg(pctl->dev,
+ "Setting pin %u reg 0x%x shift %u to function %s (muxval=0x%x)\n",
+ pin, field.reg, field.shift, func->name, val);
+
+ ret = regmap_update_bits(pctl->regmap, field.reg,
+ field.mask << field.shift,
+ val << field.shift);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int aspeed_g7_soc1_gpio_request_enable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned int pin)
+{
+ struct aspeed_g7_soc1_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ struct aspeed_g7_field field;
+ int ret = -ENOTSUPP;
+
+ if (pin <= AC24) {
+ field = aspeed_g7_soc1_pinmux_field_from_pin(pin);
+ ret = regmap_update_bits(pctl->regmap, field.reg,
+ field.mask << field.shift, 0);
+ }
+
+ return ret;
+}
+
+static const struct pinmux_ops aspeed_g7_soc1_pmx_ops = {
+ .get_functions_count = pinmux_generic_get_function_count,
+ .get_function_name = pinmux_generic_get_function_name,
+ .get_function_groups = pinmux_generic_get_function_groups,
+ .set_mux = aspeed_g7_soc1_set_mux,
+ .gpio_request_enable = aspeed_g7_soc1_gpio_request_enable,
+ .strict = true,
+};
+
+/*
+ * aspeed_g7_soc1_drv_map - Mapping table for pin drive strength control.
+ *
+ * In AST2700 SOC1, drive strength configuration is architecturally decoupled
+ * from the main pin mux registers (0x400 range). It is managed by a separate
+ * set of registers starting at 0x4C0.
+ *
+ * This table is required because:
+ * 1. The mapping between physical pin IDs and drive strength control slots
+ * is non-linear and sparse.
+ * For example, W25 maps to field index 8 (stored as 9),
+ * meaning it occupies bits [17:16] of the first 0x4C0 register.
+ * 2. Only a subset of physical pins supports drive strength configuration.
+ *
+ * The table stores (drive strength field index + 1).
+ * The field index refers to the 2-bit drive strength field position within the
+ * 0x4C0 register range. A value of 0 indicates that the pin does not support
+ * drive strength configuration (returning -ENOTSUPP).
+ * This +1 offset allows us to rely on C's default zero-initialization for
+ * unsupported pins while avoiding compiler warnings regarding overridden
+ * initializers.
+ */
+static const int aspeed_g7_soc1_drv_map[ASPEED_G7_SOC1_NR_PINS] = {
+ [C16] = 1, [C14] = 2, [C11] = 3, [D9] = 4, [F14] = 5, [D10] = 6, [C12] = 7,
+ [C13] = 8, [W25] = 9, [Y23] = 10, [Y24] = 11, [W21] = 12, [AA23] = 13, [AC22] = 14,
+ [AB22] = 15, [Y21] = 16, [AE20] = 17, [AF19] = 18, [Y22] = 19, [AA20] = 20, [AA22] = 21,
+ [AB20] = 22, [AF18] = 23, [AE19] = 24, [AD20] = 25, [AC20] = 26, [AA21] = 27, [AB21] = 28,
+ [AC19] = 29, [AE18] = 30, [AD19] = 31, [AD18] = 32, [U25] = 33, [U26] = 34, [Y26] = 35,
+ [AA24] = 36, [R25] = 37, [AA26] = 38, [R26] = 39, [Y25] = 40, [B16] = 41, [D14] = 42,
+ [B15] = 43, [B14] = 44, [C17] = 45, [B13] = 46, [E14] = 47, [C15] = 48, [D24] = 49,
+ [B23] = 50, [B22] = 51, [C23] = 52, [B18] = 53, [B21] = 54, [M15] = 55, [B19] = 56,
+ [B26] = 57, [A25] = 58, [A24] = 59, [B24] = 60, [E26] = 61, [A21] = 62, [A19] = 63,
+ [A18] = 64, [D26] = 65, [C26] = 66, [A23] = 67, [A22] = 68, [B25] = 69, [F26] = 70,
+ [A26] = 71, [A14] = 72, [E10] = 73, [E13] = 74, [D12] = 75, [F10] = 76, [E11] = 77,
+ [F11] = 78, [F13] = 79, [N15] = 80, [C20] = 81, [C19] = 82, [A8] = 83, [R14] = 84,
+ [A7] = 85, [P14] = 86, [D20] = 87, [A6] = 88, [B6] = 89, [N14] = 90, [B7] = 91,
+ [B8] = 92, [B9] = 93, [M14] = 94, [J11] = 95, [E7] = 96, [D19] = 97, [B11] = 98,
+ [D15] = 99, [B12] = 100, [B10] = 101, [P13] = 102, [C18] = 103, [C6] = 104, [C7] = 105,
+ [D7] = 106, [N13] = 107, [C8] = 108, [C9] = 109, [C10] = 110, [M16] = 111, [A15] = 112,
+ [E9] = 113, [F9] = 114, [F8] = 115, [M13] = 116, [F7] = 117, [D8] = 118, [E8] = 119,
+ [L12] = 120,
+};
+
+static int aspeed_g7_soc1_pin_config_get(struct pinctrl_dev *pctldev,
+ unsigned int pin,
+ unsigned long *config)
+{
+ struct aspeed_g7_soc1_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ enum pin_config_param param = pinconf_to_config_param(*config);
+ struct aspeed_g7_field field;
+ unsigned int val, val_raw;
+ int ret, ds_idx;
+
+ if (pin > AC24)
+ return -EINVAL;
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_BIAS_DISABLE:
+ field = aspeed_g7_soc1_bias_field_from_pin(pin);
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ ds_idx = aspeed_g7_soc1_drv_map[pin];
+ if (!ds_idx)
+ return -ENOTSUPP;
+ ds_idx--; /* Adjust back to 0-based hardware index */
+ field = aspeed_g7_soc1_drv_field_from_idx(ds_idx);
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ ret = regmap_read(pctl->regmap, field.reg, &val_raw);
+ if (ret)
+ return ret;
+
+ val = (val_raw & (field.mask << field.shift)) >> field.shift;
+ if (param == PIN_CONFIG_DRIVE_STRENGTH)
+ val = (val + ASPEED_G7_SOC1_DRV_STRENGTH_HW_BASE) *
+ ASPEED_G7_SOC1_DRV_STRENGTH_STEP_MA;
+ else if (param != PIN_CONFIG_BIAS_DISABLE)
+ val = !val;
+
+ *config = pinconf_to_config_packed(param, val);
+
+ return 0;
+}
+
+static int aspeed_g7_soc1_pin_config_set(struct pinctrl_dev *pctldev,
+ unsigned int pin,
+ unsigned long *configs,
+ unsigned int num_configs)
+{
+ struct aspeed_g7_soc1_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
+ struct aspeed_g7_field field;
+ enum pin_config_param param;
+ int i, ret, ds_idx;
+ unsigned int val;
+ u32 arg;
+
+ if (pin > AC24)
+ return -EINVAL;
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_BIAS_DISABLE:
+ field = aspeed_g7_soc1_bias_field_from_pin(pin);
+ val = (param == PIN_CONFIG_BIAS_DISABLE) ? 1 : 0;
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ ds_idx = aspeed_g7_soc1_drv_map[pin];
+ if (!ds_idx)
+ return -ENOTSUPP;
+ ds_idx--; /* Adjust back to 0-based hardware index */
+ field = aspeed_g7_soc1_drv_field_from_idx(ds_idx);
+ ret = aspeed_g7_soc1_drive_strength_to_hw(arg, &val);
+ if (ret)
+ return ret;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ dev_dbg(pctl->dev,
+ "Configuring pin %u reg 0x%x shift %u param %d arg %u val 0x%x\n",
+ pin, field.reg, field.shift, param, arg, val);
+
+ ret = regmap_update_bits(pctl->regmap, field.reg,
+ field.mask << field.shift,
+ val << field.shift);
+
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int aspeed_g7_soc1_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ const unsigned int **pins,
+ unsigned int *npins)
+{
+ struct group_desc *group;
+
+ group = pinctrl_generic_get_group(pctldev, selector);
+ if (!group)
+ return -EINVAL;
+
+ if (!group->grp.npins)
+ return -ENODEV;
+
+ *pins = group->grp.pins;
+ *npins = group->grp.npins;
+
+ return 0;
+}
+
+static int aspeed_g7_soc1_pin_config_group_get(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ unsigned long *config)
+{
+ const unsigned int *pins;
+ unsigned int npins;
+ int ret;
+
+ ret = aspeed_g7_soc1_get_group_pins(pctldev, selector, &pins, &npins);
+ if (ret)
+ return ret;
+
+ return aspeed_g7_soc1_pin_config_get(pctldev, pins[0], config);
+}
+
+static int aspeed_g7_soc1_pin_config_group_set(struct pinctrl_dev *pctldev,
+ unsigned int selector,
+ unsigned long *configs,
+ unsigned int num_configs)
+{
+ const unsigned int *pins;
+ unsigned int npins;
+ int ret;
+ int i;
+
+ ret = aspeed_g7_soc1_get_group_pins(pctldev, selector, &pins, &npins);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < npins; i++) {
+ ret = aspeed_g7_soc1_pin_config_set(pctldev, pins[i], configs,
+ num_configs);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct pinconf_ops aspeed_g7_soc1_conf_ops = {
+ .is_generic = true,
+ .pin_config_get = aspeed_g7_soc1_pin_config_get,
+ .pin_config_set = aspeed_g7_soc1_pin_config_set,
+ .pin_config_group_get = aspeed_g7_soc1_pin_config_group_get,
+ .pin_config_group_set = aspeed_g7_soc1_pin_config_group_set,
+ .pin_config_config_dbg_show = pinconf_generic_dump_config,
+};
+
+static const struct pinctrl_desc aspeed_g7_soc1_desc = {
+ .name = "aspeed-g7-soc1-pinctrl",
+ .pins = aspeed_g7_soc1_pins,
+ .npins = ARRAY_SIZE(aspeed_g7_soc1_pins),
+ .pctlops = &aspeed_g7_soc1_pctl_ops,
+ .pmxops = &aspeed_g7_soc1_pmx_ops,
+ .confops = &aspeed_g7_soc1_conf_ops,
+ .owner = THIS_MODULE,
+};
+
+ #define PIN_GROUP(name, ...) static const unsigned int name ## _pins[] = { __VA_ARGS__ }
+
+/* Pin Groups and Functions */
+PIN_GROUP(ADC0, W17);
+PIN_GROUP(ADC1, V18);
+PIN_GROUP(ADC10, Y11);
+PIN_GROUP(ADC11, V14);
+PIN_GROUP(ADC12, V19);
+PIN_GROUP(ADC13, W14);
+PIN_GROUP(ADC14, Y20);
+PIN_GROUP(ADC15, AB19);
+PIN_GROUP(ADC2, W18);
+PIN_GROUP(ADC3, Y17);
+PIN_GROUP(ADC4, AA18);
+PIN_GROUP(ADC5, AA13);
+PIN_GROUP(ADC6, Y18);
+PIN_GROUP(ADC7, AA12);
+PIN_GROUP(ADC8, W20);
+PIN_GROUP(ADC9, V20);
+PIN_GROUP(AUXPWRGOOD0, W14);
+PIN_GROUP(AUXPWRGOOD1, Y20);
+PIN_GROUP(CANBUS, G7, G8, G9);
+PIN_GROUP(DI2C0, C16, D9);
+PIN_GROUP(DI2C1, C14, F14);
+PIN_GROUP(DI2C10, R25, AA26);
+PIN_GROUP(DI2C11, R26, Y25);
+PIN_GROUP(DI2C12, W25, Y23);
+PIN_GROUP(DI2C13, Y24, W21);
+PIN_GROUP(DI2C14, AA23, AC22);
+PIN_GROUP(DI2C15, AB22, Y21);
+PIN_GROUP(DI2C2, D10, C12);
+PIN_GROUP(DI2C3, C11, C13);
+PIN_GROUP(DI2C8, U25, U26);
+PIN_GROUP(DI2C9, Y26, AA24);
+PIN_GROUP(DSGPM0, D19, B10, C7, D7);
+PIN_GROUP(ESPI0, B16, D14, B15, B14, C17, B13, E14, C15);
+PIN_GROUP(ESPI1, C16, C14, C11, D9, F14, D10, C12, C13);
+PIN_GROUP(FSI0, AD20, AC20);
+PIN_GROUP(FSI1, AA21, AB21);
+PIN_GROUP(FSI2, AC19, AE18);
+PIN_GROUP(FSI3, AD19, AD18);
+PIN_GROUP(FWQSPI, M16, A15);
+PIN_GROUP(FWSPIABR, A14);
+PIN_GROUP(FWWPN, N15);
+PIN_GROUP(HBLED, V24);
+PIN_GROUP(HVI3C0, U25, U26);
+PIN_GROUP(HVI3C1, Y26, AA24);
+PIN_GROUP(HVI3C12, W25, Y23);
+PIN_GROUP(HVI3C13, Y24, W21);
+PIN_GROUP(HVI3C14, AA23, AC22);
+PIN_GROUP(HVI3C15, AB22, Y21);
+PIN_GROUP(HVI3C2, R25, AA26);
+PIN_GROUP(HVI3C3, R26, Y25);
+PIN_GROUP(I2C0, G11, H7);
+PIN_GROUP(I2C1, H8, H9);
+PIN_GROUP(I2C10, G8, G9);
+PIN_GROUP(I2C11, G10, K12);
+PIN_GROUP(I2C12, AC18, AA17);
+PIN_GROUP(I2C13, AB17, AD16);
+PIN_GROUP(I2C14, AC17, AD17);
+PIN_GROUP(I2C15, AE16, AE17);
+PIN_GROUP(I2C2, H10, H11);
+PIN_GROUP(I2C3, J9, J10);
+PIN_GROUP(I2C4, E9, F9);
+PIN_GROUP(I2C5, F8, M13);
+PIN_GROUP(I2C6, F7, D8);
+PIN_GROUP(I2C7, E8, L12);
+PIN_GROUP(I2C8, F12, E12);
+PIN_GROUP(I2C9, J12, G7);
+PIN_GROUP(I2CF0, F12, E12, J12, G7);
+PIN_GROUP(I2CF1, E9, F9, F8, M13);
+PIN_GROUP(I2CF2, F7, D8, E8, L12);
+PIN_GROUP(I3C10, AC19, AE18);
+PIN_GROUP(I3C11, AD19, AD18);
+PIN_GROUP(I3C4, AE20, AF19);
+PIN_GROUP(I3C5, Y22, AA20);
+PIN_GROUP(I3C6, AA22, AB20);
+PIN_GROUP(I3C7, AF18, AE19);
+PIN_GROUP(I3C8, AD20, AC20);
+PIN_GROUP(I3C9, AA21, AB21);
+PIN_GROUP(JTAGM1, D12, F10, E11, F11, F13);
+PIN_GROUP(LPC0, AF26, AF25, B16, D14, B15, B14, C17, B13, E14, C15);
+PIN_GROUP(LPC1, C16, C14, C11, D9, F14, D10, C12, C13, AE16, AE17);
+PIN_GROUP(LTPI, U25, U26, Y26, AA24);
+PIN_GROUP(LTPI_PS_I2C0, G11, H7);
+PIN_GROUP(LTPI_PS_I2C1, H8, H9);
+PIN_GROUP(LTPI_PS_I2C2, H10, H11);
+PIN_GROUP(LTPI_PS_I2C3, J9, J10);
+PIN_GROUP(MACLINK0, U21);
+PIN_GROUP(MACLINK1, AC24);
+PIN_GROUP(MACLINK2, T24);
+PIN_GROUP(MDIO0, B9, M14);
+PIN_GROUP(MDIO1, C9, C10);
+PIN_GROUP(MDIO2, E10, E13);
+PIN_GROUP(NCTS0, AF17);
+PIN_GROUP(NCTS1, AA15);
+PIN_GROUP(NCTS5, V21);
+PIN_GROUP(NCTS6, AB26);
+PIN_GROUP(NDCD0, AA16);
+PIN_GROUP(NDCD1, AB15);
+PIN_GROUP(NDCD5, N26);
+PIN_GROUP(NDCD6, AD26);
+PIN_GROUP(NDSR0, Y16);
+PIN_GROUP(NDSR1, AC15);
+PIN_GROUP(NDSR5, P25);
+PIN_GROUP(NDSR6, P26);
+PIN_GROUP(NDTR0, J13);
+PIN_GROUP(NDTR1, Y15);
+PIN_GROUP(NDTR5, V23);
+PIN_GROUP(NDTR6, AF26);
+PIN_GROUP(NRI0, V17);
+PIN_GROUP(NRI1, AD15);
+PIN_GROUP(NRI5, N25);
+PIN_GROUP(NRI6, AE26);
+PIN_GROUP(NRTS0, AB16);
+PIN_GROUP(NRTS1, AA14);
+PIN_GROUP(NRTS5, W22);
+PIN_GROUP(NRTS6, AF25);
+PIN_GROUP(OSCCLK, C17);
+PIN_GROUP(PE2SGRSTN, E10, PCIERC2_PERST);
+PIN_GROUP(PWM0, AE25);
+PIN_GROUP(PWM1, AD25);
+PIN_GROUP(PWM10, AB17);
+PIN_GROUP(PWM11, AD16);
+PIN_GROUP(PWM12, AC17);
+PIN_GROUP(PWM13, AD17);
+PIN_GROUP(PWM14, AE16);
+PIN_GROUP(PWM15, AE17);
+PIN_GROUP(PWM2, AF23);
+PIN_GROUP(PWM3, AF20);
+PIN_GROUP(PWM4, AF21);
+PIN_GROUP(PWM5, AE21);
+PIN_GROUP(PWM6, AE23);
+PIN_GROUP(PWM7, AD22);
+PIN_GROUP(PWM8, K13);
+PIN_GROUP(PWM9, AA17);
+PIN_GROUP(QSPI0, C23, B18);
+PIN_GROUP(QSPI1, B24, E26);
+PIN_GROUP(QSPI2, B25, F26);
+PIN_GROUP(RGMII0, C20, C19, A8, R14, A7, P14, D20, A6, B6, N14, B7, B8);
+PIN_GROUP(RGMII1, D19, B11, D15, B12, B10, P13, C18, C6, C7, D7, N13, C8);
+PIN_GROUP(RMII0, C20, A8, R14, A7, P14, A6, B6, N14);
+PIN_GROUP(RMII0RCLKO, D20);
+PIN_GROUP(RMII1, D19, D15, B12, B10, P13, C6, C7, D7);
+PIN_GROUP(RMII1RCLKO, C18);
+PIN_GROUP(SALT0, AC17);
+PIN_GROUP(SALT1, AD17);
+PIN_GROUP(SALT10, Y18);
+PIN_GROUP(SALT11, AA12);
+PIN_GROUP(SALT12, AB26);
+PIN_GROUP(SALT13, AD26);
+PIN_GROUP(SALT14, P26);
+PIN_GROUP(SALT15, AE26);
+PIN_GROUP(SALT2, AC15);
+PIN_GROUP(SALT3, AD15);
+PIN_GROUP(SALT4, W17);
+PIN_GROUP(SALT5, V18);
+PIN_GROUP(SALT6, W18);
+PIN_GROUP(SALT7, Y17);
+PIN_GROUP(SALT8, AA18);
+PIN_GROUP(SALT9, AA13);
+PIN_GROUP(SD, C16, C14, C11, D9, F14, D10, C12, C13);
+PIN_GROUP(SGMII, SGMII0);
+PIN_GROUP(SGPM0, U21, T24, V22, T23);
+PIN_GROUP(SGPM1, AC25, AB25, AB24, W26);
+PIN_GROUP(SGPS, B11, C18, N13, C8);
+PIN_GROUP(SIOONCTRLN0, AE23);
+PIN_GROUP(SIOONCTRLN1, AA15);
+PIN_GROUP(SIOPBIN0, AD25);
+PIN_GROUP(SIOPBIN1, AA16);
+PIN_GROUP(SIOPBON0, AE25);
+PIN_GROUP(SIOPBON1, AF17);
+PIN_GROUP(SIOPWREQN0, AE21);
+PIN_GROUP(SIOPWREQN1, AB16);
+PIN_GROUP(SIOPWRGD1, AB15);
+PIN_GROUP(SIOS3N0, AF20);
+PIN_GROUP(SIOS3N1, V17);
+PIN_GROUP(SIOS5N0, AF21);
+PIN_GROUP(SIOS5N1, J13);
+PIN_GROUP(SIOSCIN0, AF23);
+PIN_GROUP(SIOSCIN1, Y16);
+PIN_GROUP(SMON0, U21, T24, V22, T23);
+PIN_GROUP(SMON1, W26, AC25, AB25);
+PIN_GROUP(SPI0, D24, B23, B22);
+PIN_GROUP(SPI0ABR, M15);
+PIN_GROUP(SPI0CS1, B21);
+PIN_GROUP(SPI0WPN, B19);
+PIN_GROUP(SPI1, B26, A25, A24);
+PIN_GROUP(SPI1ABR, A19);
+PIN_GROUP(SPI1CS1, A21);
+PIN_GROUP(SPI1WPN, A18);
+PIN_GROUP(SPI2, D26, C26, A23, A22);
+PIN_GROUP(SPI2CS1, A26);
+PIN_GROUP(TACH0, AC26);
+PIN_GROUP(TACH1, AA25);
+PIN_GROUP(TACH10, AB26);
+PIN_GROUP(TACH11, AD26);
+PIN_GROUP(TACH12, P26);
+PIN_GROUP(TACH13, AE26);
+PIN_GROUP(TACH14, AF26);
+PIN_GROUP(TACH15, AF25);
+PIN_GROUP(TACH2, AB23);
+PIN_GROUP(TACH3, U22);
+PIN_GROUP(TACH4, V21);
+PIN_GROUP(TACH5, N26);
+PIN_GROUP(TACH6, P25);
+PIN_GROUP(TACH7, N25);
+PIN_GROUP(TACH8, V23);
+PIN_GROUP(TACH9, W22);
+PIN_GROUP(THRU0, AC26, AA25);
+PIN_GROUP(THRU1, AB23, U22);
+PIN_GROUP(THRU2, A19, A18);
+PIN_GROUP(THRU3, B25, F26);
+PIN_GROUP(UART0, AC16, AF16);
+PIN_GROUP(UART1, W16, V16);
+PIN_GROUP(UART2, AB18, AC18);
+PIN_GROUP(UART3, K13, AA17);
+PIN_GROUP(UART5, AB17, AD16);
+PIN_GROUP(UART6, AC17, AD17);
+PIN_GROUP(UART7, AE16, AE17);
+PIN_GROUP(UART8, M15, B19);
+PIN_GROUP(UART9, B26, A25);
+PIN_GROUP(UART10, A24, B24);
+PIN_GROUP(UART11, E26, A21);
+PIN_GROUP(USB2CD, PORTC_MODE);
+PIN_GROUP(USB2CH, PORTC_MODE);
+PIN_GROUP(USB2CU, PORTC_MODE);
+PIN_GROUP(USB2CUD, PORTC_MODE);
+PIN_GROUP(USB2DD, PORTD_MODE);
+PIN_GROUP(USB2DH, PORTD_MODE);
+PIN_GROUP(USBUART, G10, K12);
+PIN_GROUP(VGA, J11, E7);
+PIN_GROUP(VPI, C16, C14, C11, D9, F14, D10, AC26, AA25, AB23, U22, V21, N26,
+ P25, N25, V23, W22, AB26, AD26, P26, AE26, AF26, AF25, AE25, AD25,
+ AF23, AF20, AF21, AE21);
+PIN_GROUP(WDTRST0N, K13);
+PIN_GROUP(WDTRST1N, AA17);
+PIN_GROUP(WDTRST2N, AB17);
+PIN_GROUP(WDTRST3N, AD16);
+PIN_GROUP(WDTRST4N, AC25);
+PIN_GROUP(WDTRST5N, AB25);
+PIN_GROUP(WDTRST6N, AC24);
+PIN_GROUP(WDTRST7N, AB24);
+
+#define GROUP(n) PINCTRL_PINGROUP(#n, n##_pins, ARRAY_SIZE(n##_pins))
+
+static const struct pingroup aspeed_g7_soc1_groups[] = {
+ GROUP(ADC0),
+ GROUP(ADC1),
+ GROUP(ADC10),
+ GROUP(ADC11),
+ GROUP(ADC12),
+ GROUP(ADC13),
+ GROUP(ADC14),
+ GROUP(ADC15),
+ GROUP(ADC2),
+ GROUP(ADC3),
+ GROUP(ADC4),
+ GROUP(ADC5),
+ GROUP(ADC6),
+ GROUP(ADC7),
+ GROUP(ADC8),
+ GROUP(ADC9),
+ GROUP(AUXPWRGOOD0),
+ GROUP(AUXPWRGOOD1),
+ GROUP(CANBUS),
+ GROUP(DI2C0),
+ GROUP(DI2C1),
+ GROUP(DI2C10),
+ GROUP(DI2C11),
+ GROUP(DI2C12),
+ GROUP(DI2C13),
+ GROUP(DI2C14),
+ GROUP(DI2C15),
+ GROUP(DI2C2),
+ GROUP(DI2C3),
+ GROUP(DI2C8),
+ GROUP(DI2C9),
+ GROUP(DSGPM0),
+ GROUP(ESPI0),
+ GROUP(ESPI1),
+ GROUP(FSI0),
+ GROUP(FSI1),
+ GROUP(FSI2),
+ GROUP(FSI3),
+ GROUP(FWQSPI),
+ GROUP(FWSPIABR),
+ GROUP(FWWPN),
+ GROUP(HBLED),
+ GROUP(HVI3C0),
+ GROUP(HVI3C1),
+ GROUP(HVI3C12),
+ GROUP(HVI3C13),
+ GROUP(HVI3C14),
+ GROUP(HVI3C15),
+ GROUP(HVI3C2),
+ GROUP(HVI3C3),
+ GROUP(I2C0),
+ GROUP(I2C1),
+ GROUP(I2C10),
+ GROUP(I2C11),
+ GROUP(I2C12),
+ GROUP(I2C13),
+ GROUP(I2C14),
+ GROUP(I2C15),
+ GROUP(I2C2),
+ GROUP(I2C3),
+ GROUP(I2C4),
+ GROUP(I2C5),
+ GROUP(I2C6),
+ GROUP(I2C7),
+ GROUP(I2C8),
+ GROUP(I2C9),
+ GROUP(I2CF0),
+ GROUP(I2CF1),
+ GROUP(I2CF2),
+ GROUP(I3C10),
+ GROUP(I3C11),
+ GROUP(I3C4),
+ GROUP(I3C5),
+ GROUP(I3C6),
+ GROUP(I3C7),
+ GROUP(I3C8),
+ GROUP(I3C9),
+ GROUP(JTAGM1),
+ GROUP(LPC0),
+ GROUP(LPC1),
+ GROUP(LTPI),
+ GROUP(LTPI_PS_I2C0),
+ GROUP(LTPI_PS_I2C1),
+ GROUP(LTPI_PS_I2C2),
+ GROUP(LTPI_PS_I2C3),
+ GROUP(MACLINK0),
+ GROUP(MACLINK1),
+ GROUP(MACLINK2),
+ GROUP(MDIO0),
+ GROUP(MDIO1),
+ GROUP(MDIO2),
+ GROUP(NCTS0),
+ GROUP(NCTS1),
+ GROUP(NCTS5),
+ GROUP(NCTS6),
+ GROUP(NDCD0),
+ GROUP(NDCD1),
+ GROUP(NDCD5),
+ GROUP(NDCD6),
+ GROUP(NDSR0),
+ GROUP(NDSR1),
+ GROUP(NDSR5),
+ GROUP(NDSR6),
+ GROUP(NDTR0),
+ GROUP(NDTR1),
+ GROUP(NDTR5),
+ GROUP(NDTR6),
+ GROUP(NRI0),
+ GROUP(NRI1),
+ GROUP(NRI5),
+ GROUP(NRI6),
+ GROUP(NRTS0),
+ GROUP(NRTS1),
+ GROUP(NRTS5),
+ GROUP(NRTS6),
+ GROUP(OSCCLK),
+ GROUP(PE2SGRSTN),
+ GROUP(PWM0),
+ GROUP(PWM1),
+ GROUP(PWM10),
+ GROUP(PWM11),
+ GROUP(PWM12),
+ GROUP(PWM13),
+ GROUP(PWM14),
+ GROUP(PWM15),
+ GROUP(PWM2),
+ GROUP(PWM3),
+ GROUP(PWM4),
+ GROUP(PWM5),
+ GROUP(PWM6),
+ GROUP(PWM7),
+ GROUP(PWM8),
+ GROUP(PWM9),
+ GROUP(QSPI0),
+ GROUP(QSPI1),
+ GROUP(QSPI2),
+ GROUP(RGMII0),
+ GROUP(RGMII1),
+ GROUP(RMII0),
+ GROUP(RMII0RCLKO),
+ GROUP(RMII1),
+ GROUP(RMII1RCLKO),
+ GROUP(SALT0),
+ GROUP(SALT1),
+ GROUP(SALT10),
+ GROUP(SALT11),
+ GROUP(SALT12),
+ GROUP(SALT13),
+ GROUP(SALT14),
+ GROUP(SALT15),
+ GROUP(SALT2),
+ GROUP(SALT3),
+ GROUP(SALT4),
+ GROUP(SALT5),
+ GROUP(SALT6),
+ GROUP(SALT7),
+ GROUP(SALT8),
+ GROUP(SALT9),
+ GROUP(SD),
+ GROUP(SGMII),
+ GROUP(SGPM0),
+ GROUP(SGPM1),
+ GROUP(SGPS),
+ GROUP(SIOONCTRLN0),
+ GROUP(SIOONCTRLN1),
+ GROUP(SIOPBIN0),
+ GROUP(SIOPBIN1),
+ GROUP(SIOPBON0),
+ GROUP(SIOPBON1),
+ GROUP(SIOPWREQN0),
+ GROUP(SIOPWREQN1),
+ GROUP(SIOPWRGD1),
+ GROUP(SIOS3N0),
+ GROUP(SIOS3N1),
+ GROUP(SIOS5N0),
+ GROUP(SIOS5N1),
+ GROUP(SIOSCIN0),
+ GROUP(SIOSCIN1),
+ GROUP(SMON0),
+ GROUP(SMON1),
+ GROUP(SPI0),
+ GROUP(SPI0ABR),
+ GROUP(SPI0CS1),
+ GROUP(SPI0WPN),
+ GROUP(SPI1),
+ GROUP(SPI1ABR),
+ GROUP(SPI1CS1),
+ GROUP(SPI1WPN),
+ GROUP(SPI2),
+ GROUP(SPI2CS1),
+ GROUP(TACH0),
+ GROUP(TACH1),
+ GROUP(TACH10),
+ GROUP(TACH11),
+ GROUP(TACH12),
+ GROUP(TACH13),
+ GROUP(TACH14),
+ GROUP(TACH15),
+ GROUP(TACH2),
+ GROUP(TACH3),
+ GROUP(TACH4),
+ GROUP(TACH5),
+ GROUP(TACH6),
+ GROUP(TACH7),
+ GROUP(TACH8),
+ GROUP(TACH9),
+ GROUP(THRU0),
+ GROUP(THRU1),
+ GROUP(THRU2),
+ GROUP(THRU3),
+ GROUP(UART0),
+ GROUP(UART1),
+ GROUP(UART10),
+ GROUP(UART11),
+ GROUP(UART2),
+ GROUP(UART3),
+ GROUP(UART5),
+ GROUP(UART6),
+ GROUP(UART7),
+ GROUP(UART8),
+ GROUP(UART9),
+ GROUP(USB2CD),
+ GROUP(USB2CH),
+ GROUP(USB2CU),
+ GROUP(USB2CUD),
+ GROUP(USB2DD),
+ GROUP(USB2DH),
+ GROUP(USBUART),
+ GROUP(VGA),
+ GROUP(VPI),
+ GROUP(WDTRST0N),
+ GROUP(WDTRST1N),
+ GROUP(WDTRST2N),
+ GROUP(WDTRST3N),
+ GROUP(WDTRST4N),
+ GROUP(WDTRST5N),
+ GROUP(WDTRST6N),
+ GROUP(WDTRST7N),
+};
+
+/**
+ * VM() - Helper macro to unwrap a parenthesized list of arguments.
+ * @...: The parenthesized list to be unwrapped.
+ *
+ * Since the C preprocessor treats commas inside braces {} as argument
+ * separators for macros, we wrap lists (like mux values) in parentheses ()
+ * to protect them during macro expansion. This macro strips those
+ * parentheses when the values are needed for array initialization.
+ */
+#define VM(...) __VA_ARGS__
+
+/**
+ * FUNC() - Macro to initialize an aspeed_g7_soc1_function entry.
+ * @n: Name of the pin function.
+ * @m: Parenthesized list of mux values, mapped 1:1 to the groups list.
+ * @...: Variable list of pin group names associated with this function.
+ *
+ * This macro solves complex static initialization by:
+ * 1. Creating anonymous arrays for both group names and mux values
+ * using C99 Compound Literals.
+ * 2. Using VM(m) to unwrap mux values into the array initializer.
+ * 3. Calculating the number of groups via sizeof() division, which
+ * bypasses the __must_be_array() check performed by ARRAY_SIZE()
+ * that often fails on compound literals in the kernel environment.
+ *
+ * Example: FUNC(i2c0, (1, 4), "i2c0", "di2c0")
+ * Maps "i2c0" group to mux value 1 and "di2c0" group to mux value 4.
+ */
+#define FUNC(n, m, ...) \
+ { \
+ .pinfunction = { \
+ .name = #n, \
+ .groups = (const char *const[]){ __VA_ARGS__ }, \
+ .ngroups = sizeof((const char *const[]){ __VA_ARGS__ }) / sizeof(char *), \
+ }, \
+ .muxvals = (const u8[]){ VM m } \
+ }
+
+static const struct aspeed_g7_soc1_function aspeed_g7_soc1_functions[] = {
+ FUNC(ADC0, (0), "ADC0"),
+ FUNC(ADC1, (0), "ADC1"),
+ FUNC(ADC10, (0), "ADC10"),
+ FUNC(ADC11, (0), "ADC11"),
+ FUNC(ADC12, (0), "ADC12"),
+ FUNC(ADC13, (0), "ADC13"),
+ FUNC(ADC14, (0), "ADC14"),
+ FUNC(ADC15, (0), "ADC15"),
+ FUNC(ADC2, (0), "ADC2"),
+ FUNC(ADC3, (0), "ADC3"),
+ FUNC(ADC4, (0), "ADC4"),
+ FUNC(ADC5, (0), "ADC5"),
+ FUNC(ADC6, (0), "ADC6"),
+ FUNC(ADC7, (0), "ADC7"),
+ FUNC(ADC8, (0), "ADC8"),
+ FUNC(ADC9, (0), "ADC9"),
+ FUNC(AUXPWRGOOD0, (2), "AUXPWRGOOD0"),
+ FUNC(AUXPWRGOOD1, (2), "AUXPWRGOOD1"),
+ FUNC(CANBUS, (2), "CANBUS"),
+ FUNC(ESPI0, (1), "ESPI0"),
+ FUNC(ESPI1, (1), "ESPI1"),
+ FUNC(FSI0, (2), "FSI0"),
+ FUNC(FSI1, (2), "FSI1"),
+ FUNC(FSI2, (2), "FSI2"),
+ FUNC(FSI3, (2), "FSI3"),
+ FUNC(FWQSPI, (1), "FWQSPI"),
+ FUNC(FWSPIABR, (1), "FWSPIABR"),
+ FUNC(FWWPN, (1), "FWWPN"),
+ FUNC(HBLED, (2), "HBLED"),
+ FUNC(I2C0, (1, 2, 4), "I2C0", "LTPI_PS_I2C0", "DI2C0"),
+ FUNC(I2C1, (1, 2, 4), "I2C1", "LTPI_PS_I2C1", "DI2C1"),
+ FUNC(I2C10, (1, 2), "I2C10", "DI2C10"),
+ FUNC(I2C11, (1, 2), "I2C11", "DI2C11"),
+ FUNC(I2C12, (4, 2), "I2C12", "DI2C12"),
+ FUNC(I2C13, (4, 2), "I2C13", "DI2C13"),
+ FUNC(I2C14, (4, 2), "I2C14", "DI2C14"),
+ FUNC(I2C15, (2, 2), "I2C15", "DI2C15"),
+ FUNC(I2C2, (1, 2, 4), "I2C2", "LTPI_PS_I2C2", "DI2C2"),
+ FUNC(I2C3, (1, 2, 4), "I2C3", "LTPI_PS_I2C3", "DI2C3"),
+ FUNC(I2C4, (1), "I2C4"),
+ FUNC(I2C5, (1), "I2C5"),
+ FUNC(I2C6, (1), "I2C6"),
+ FUNC(I2C7, (1), "I2C7"),
+ FUNC(I2C8, (1, 2), "I2C8", "DI2C8"),
+ FUNC(I2C9, (1, 2), "I2C9", "DI2C9"),
+ FUNC(I2CF0, (5), "I2CF0"),
+ FUNC(I2CF1, (5), "I2CF1"),
+ FUNC(I2CF2, (5), "I2CF2"),
+ FUNC(I3C0, (1), "HVI3C0"),
+ FUNC(I3C1, (1), "HVI3C1"),
+ FUNC(I3C10, (1), "I3C10"),
+ FUNC(I3C11, (1), "I3C11"),
+ FUNC(I3C12, (1), "HVI3C12"),
+ FUNC(I3C13, (1), "HVI3C13"),
+ FUNC(I3C14, (1), "HVI3C14"),
+ FUNC(I3C15, (1), "HVI3C15"),
+ FUNC(I3C2, (1), "HVI3C2"),
+ FUNC(I3C3, (1), "HVI3C3"),
+ FUNC(I3C4, (1), "I3C4"),
+ FUNC(I3C5, (1), "I3C5"),
+ FUNC(I3C6, (1), "I3C6"),
+ FUNC(I3C7, (1), "I3C7"),
+ FUNC(I3C8, (1), "I3C8"),
+ FUNC(I3C9, (1), "I3C9"),
+ FUNC(JTAGM1, (1), "JTAGM1"),
+ FUNC(LPC0, (2), "LPC0"),
+ FUNC(LPC1, (2), "LPC1"),
+ FUNC(LTPI, (2), "LTPI"),
+ FUNC(MACLINK0, (4), "MACLINK0"),
+ FUNC(MACLINK1, (3), "MACLINK1"),
+ FUNC(MACLINK2, (4), "MACLINK2"),
+ FUNC(MDIO0, (1), "MDIO0"),
+ FUNC(MDIO1, (1), "MDIO1"),
+ FUNC(MDIO2, (1), "MDIO2"),
+ FUNC(NCTS0, (1), "NCTS0"),
+ FUNC(NCTS1, (1), "NCTS1"),
+ FUNC(NCTS5, (4), "NCTS5"),
+ FUNC(NCTS6, (4), "NCTS6"),
+ FUNC(NDCD0, (1), "NDCD0"),
+ FUNC(NDCD1, (1), "NDCD1"),
+ FUNC(NDCD5, (4), "NDCD5"),
+ FUNC(NDCD6, (4), "NDCD6"),
+ FUNC(NDSR0, (1), "NDSR0"),
+ FUNC(NDSR1, (1), "NDSR1"),
+ FUNC(NDSR5, (4), "NDSR5"),
+ FUNC(NDSR6, (4), "NDSR6"),
+ FUNC(NDTR0, (1), "NDTR0"),
+ FUNC(NDTR1, (1), "NDTR1"),
+ FUNC(NDTR5, (4), "NDTR5"),
+ FUNC(NDTR6, (4), "NDTR6"),
+ FUNC(NRI0, (1), "NRI0"),
+ FUNC(NRI1, (1), "NRI1"),
+ FUNC(NRI5, (4), "NRI5"),
+ FUNC(NRI6, (4), "NRI6"),
+ FUNC(NRTS0, (1), "NRTS0"),
+ FUNC(NRTS1, (1), "NRTS1"),
+ FUNC(NRTS5, (4), "NRTS5"),
+ FUNC(NRTS6, (4), "NRTS6"),
+ FUNC(OSCCLK, (3), "OSCCLK"),
+ FUNC(PCIERC, (2), "PE2SGRSTN"),
+ FUNC(PWM0, (1), "PWM0"),
+ FUNC(PWM1, (1), "PWM1"),
+ FUNC(PWM10, (3), "PWM10"),
+ FUNC(PWM11, (3), "PWM11"),
+ FUNC(PWM12, (3), "PWM12"),
+ FUNC(PWM13, (3), "PWM13"),
+ FUNC(PWM14, (3), "PWM14"),
+ FUNC(PWM15, (3), "PWM15"),
+ FUNC(PWM2, (1), "PWM2"),
+ FUNC(PWM3, (1), "PWM3"),
+ FUNC(PWM4, (1), "PWM4"),
+ FUNC(PWM5, (1), "PWM5"),
+ FUNC(PWM6, (1), "PWM6"),
+ FUNC(PWM7, (1), "PWM7"),
+ FUNC(PWM8, (3), "PWM8"),
+ FUNC(PWM9, (3), "PWM9"),
+ FUNC(QSPI0, (1), "QSPI0"),
+ FUNC(QSPI1, (1), "QSPI1"),
+ FUNC(QSPI2, (1), "QSPI2"),
+ FUNC(RGMII0, (1), "RGMII0"),
+ FUNC(RGMII1, (1), "RGMII1"),
+ FUNC(RMII0, (2), "RMII0"),
+ FUNC(RMII0RCLKO, (2), "RMII0RCLKO"),
+ FUNC(RMII1, (2), "RMII1"),
+ FUNC(RMII1RCLKO, (2), "RMII1RCLKO"),
+ FUNC(SALT0, (2), "SALT0"),
+ FUNC(SALT1, (2), "SALT1"),
+ FUNC(SALT10, (2), "SALT10"),
+ FUNC(SALT11, (2), "SALT11"),
+ FUNC(SALT12, (2), "SALT12"),
+ FUNC(SALT13, (2), "SALT13"),
+ FUNC(SALT14, (2), "SALT14"),
+ FUNC(SALT15, (2), "SALT15"),
+ FUNC(SALT2, (2), "SALT2"),
+ FUNC(SALT3, (2), "SALT3"),
+ FUNC(SALT4, (2), "SALT4"),
+ FUNC(SALT5, (2), "SALT5"),
+ FUNC(SALT6, (2), "SALT6"),
+ FUNC(SALT7, (2), "SALT7"),
+ FUNC(SALT8, (2), "SALT8"),
+ FUNC(SALT9, (2), "SALT9"),
+ FUNC(SD, (3), "SD"),
+ FUNC(SGMII, (1), "SGMII"),
+ FUNC(SGPM0, (1, 4), "SGPM0", "DSGPM0"),
+ FUNC(SGPM1, (1), "SGPM1"),
+ FUNC(SGPS, (5), "SGPS"),
+ FUNC(SIOONCTRLN0, (2), "SIOONCTRLN0"),
+ FUNC(SIOONCTRLN1, (2), "SIOONCTRLN1"),
+ FUNC(SIOPBIN0, (2), "SIOPBIN0"),
+ FUNC(SIOPBIN1, (2), "SIOPBIN1"),
+ FUNC(SIOPBON0, (2), "SIOPBON0"),
+ FUNC(SIOPBON1, (2), "SIOPBON1"),
+ FUNC(SIOPWREQN0, (2), "SIOPWREQN0"),
+ FUNC(SIOPWREQN1, (2), "SIOPWREQN1"),
+ FUNC(SIOPWRGD1, (2), "SIOPWRGD1"),
+ FUNC(SIOS3N0, (2), "SIOS3N0"),
+ FUNC(SIOS3N1, (2), "SIOS3N1"),
+ FUNC(SIOS5N0, (2), "SIOS5N0"),
+ FUNC(SIOS5N1, (2), "SIOS5N1"),
+ FUNC(SIOSCIN0, (2), "SIOSCIN0"),
+ FUNC(SIOSCIN1, (2), "SIOSCIN1"),
+ FUNC(SMON0, (2), "SMON0"),
+ FUNC(SMON1, (4), "SMON1"),
+ FUNC(SPI0, (1), "SPI0"),
+ FUNC(SPI0ABR, (1), "SPI0ABR"),
+ FUNC(SPI0CS1, (1), "SPI0CS1"),
+ FUNC(SPI0WPN, (1), "SPI0WPN"),
+ FUNC(SPI1, (1), "SPI1"),
+ FUNC(SPI1ABR, (1), "SPI1ABR"),
+ FUNC(SPI1CS1, (1), "SPI1CS1"),
+ FUNC(SPI1WPN, (1), "SPI1WPN"),
+ FUNC(SPI2, (1), "SPI2"),
+ FUNC(SPI2CS1, (1), "SPI2CS1"),
+ FUNC(TACH0, (1), "TACH0"),
+ FUNC(TACH1, (1), "TACH1"),
+ FUNC(TACH10, (1), "TACH10"),
+ FUNC(TACH11, (1), "TACH11"),
+ FUNC(TACH12, (1), "TACH12"),
+ FUNC(TACH13, (1), "TACH13"),
+ FUNC(TACH14, (1), "TACH14"),
+ FUNC(TACH15, (1), "TACH15"),
+ FUNC(TACH2, (1), "TACH2"),
+ FUNC(TACH3, (1), "TACH3"),
+ FUNC(TACH4, (1), "TACH4"),
+ FUNC(TACH5, (1), "TACH5"),
+ FUNC(TACH6, (1), "TACH6"),
+ FUNC(TACH7, (1), "TACH7"),
+ FUNC(TACH8, (1), "TACH8"),
+ FUNC(TACH9, (1), "TACH9"),
+ FUNC(THRU0, (2), "THRU0"),
+ FUNC(THRU1, (2), "THRU1"),
+ FUNC(THRU2, (4), "THRU2"),
+ FUNC(THRU3, (4), "THRU3"),
+ FUNC(UART0, (1), "UART0"),
+ FUNC(UART1, (1), "UART1"),
+ FUNC(UART10, (3), "UART10"),
+ FUNC(UART11, (3), "UART11"),
+ FUNC(UART2, (1), "UART2"),
+ FUNC(UART3, (1), "UART3"),
+ FUNC(UART5, (4), "UART5"),
+ FUNC(UART6, (4), "UART6"),
+ FUNC(UART7, (1), "UART7"),
+ FUNC(UART8, (3), "UART8"),
+ FUNC(UART9, (3), "UART9"),
+ FUNC(USB2C, (0, 1, 2, 3), "USB2CUD", "USB2CD", "USB2CH", "USB2CU"),
+ FUNC(USB2D, (1, 2), "USB2DD", "USB2DH"),
+ FUNC(USBUART, (2), "USBUART"),
+ FUNC(VGA, (1), "VGA"),
+ FUNC(VPI, (5), "VPI"),
+ FUNC(WDTRST0N, (2), "WDTRST0N"),
+ FUNC(WDTRST1N, (2), "WDTRST1N"),
+ FUNC(WDTRST2N, (2), "WDTRST2N"),
+ FUNC(WDTRST3N, (2), "WDTRST3N"),
+ FUNC(WDTRST4N, (2), "WDTRST4N"),
+ FUNC(WDTRST5N, (2), "WDTRST5N"),
+ FUNC(WDTRST6N, (2), "WDTRST6N"),
+ FUNC(WDTRST7N, (2), "WDTRST7N"),
+};
+
+static int aspeed_g7_soc1_pinctrl_probe(struct platform_device *pdev)
+{
+ struct aspeed_g7_soc1_pinctrl *pctl;
+ struct device *dev = &pdev->dev;
+ int i, ret;
+
+ pctl = devm_kzalloc(dev, sizeof(*pctl), GFP_KERNEL);
+ if (!pctl)
+ return -ENOMEM;
+
+ pctl->dev = dev;
+ pctl->regmap = syscon_node_to_regmap(dev->parent->of_node);
+ if (IS_ERR(pctl->regmap)) {
+ dev_err(dev, "Failed to get regmap from parent\n");
+ return PTR_ERR(pctl->regmap);
+ }
+
+ pctl->pctl = devm_pinctrl_register(dev, &aspeed_g7_soc1_desc, pctl);
+ if (IS_ERR(pctl->pctl)) {
+ dev_err(dev, "Failed to register pinctrl\n");
+ return PTR_ERR(pctl->pctl);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(aspeed_g7_soc1_groups); i++) {
+ const struct pingroup *grp = &aspeed_g7_soc1_groups[i];
+
+ ret = pinctrl_generic_add_group(pctl->pctl, grp->name, (unsigned int *)grp->pins,
+ grp->npins, pctl);
+ if (ret < 0) {
+ dev_err(dev, "Failed to add group %s\n", grp->name);
+ return ret;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(aspeed_g7_soc1_functions); i++) {
+ const struct aspeed_g7_soc1_function *func = &aspeed_g7_soc1_functions[i];
+
+ ret = pinmux_generic_add_function(pctl->pctl, func->pinfunction.name,
+ func->pinfunction.groups,
+ func->pinfunction.ngroups, (void *)func);
+ if (ret < 0) {
+ dev_err(dev, "Failed to add function %s\n", func->pinfunction.name);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static const struct of_device_id aspeed_g7_soc1_pinctrl_match[] = {
+ { .compatible = "aspeed,ast2700-soc1-pinctrl" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, aspeed_g7_soc1_pinctrl_match);
+
+static struct platform_driver aspeed_g7_soc1_pinctrl_driver = {
+ .probe = aspeed_g7_soc1_pinctrl_probe,
+ .driver = {
+ .name = "aspeed-g7-soc1-pinctrl",
+ .of_match_table = aspeed_g7_soc1_pinctrl_match,
+ .suppress_bind_attrs = true,
+ },
+};
+
+static int __init aspeed_g7_soc1_pinctrl_init(void)
+{
+ return platform_driver_register(&aspeed_g7_soc1_pinctrl_driver);
+}
+arch_initcall(aspeed_g7_soc1_pinctrl_init);
--
2.34.1
^ permalink raw reply related
* Re: [PATCH 3/4] dt-bindings: usb: add CIX Sky1 Cadence USB3 controller
From: Krzysztof Kozlowski @ 2026-05-15 11:18 UTC (permalink / raw)
To: Peter Chen
Cc: robh, krzk+dt, conor+dt, gregkh, pawell, rogerq, devicetree,
linux-kernel, linux-usb, cix-kernel-upstream, linux-arm-kernel,
arnd
In-Reply-To: <agb0he7vvbqSIym5@nchen-desktop>
On 15/05/2026 12:25, Peter Chen wrote:
> On 26-05-15 09:54:10, Krzysztof Kozlowski wrote:
>> EXTERNAL EMAIL
>>
>> On Mon, May 11, 2026 at 10:42:43AM +0800, Peter Chen wrote:
>>> Add a binding for the CIX Sky1 integration of the Cadence USBSSP DRD
>>> controller. The schema documents the glue register window, clocks,
>>> resets, interrupts and S5 system controller phandle.
>>>
>>> Signed-off-by: Peter Chen <peter.chen@cixtech.com>
>>> ---
>>> .../bindings/usb/cix,sky1-cdns3.yaml | 151 ++++++++++++++++++
>>
>> Why are you mixing USB patches with DTS in one patchset? Don't.
>
> In this series, the 1st patch is the IP core driver changes (export APIs for glue layer
> use), and the second glue layer patch is the user for new adding APIs.
Not really answer to my question. Why is DTS here? It has nothing to do
with 1st patch, second patch or this one.
> Normally, we combine dt-binding, driver (glue layer) and DTS changes at one patch series.
>
> It is much like below submission:
>
> https://lore.kernel.org/all/20250318-dwc3-refactor-v5-0-90ea6e5b3ba4@oss.qualcomm.com/
Which is also wrong. Why do people pick bad examples as arguments
instead of finding one of my many emails telling why is that incorrect?
Or maybe all the folks who dig through the archives and found my emails
did not continued discussion...
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v12 19/28] coresight: Save active path for system tracers
From: Leo Yan @ 2026-05-15 11:18 UTC (permalink / raw)
To: Suzuki K Poulose
Cc: Mike Leach, James Clark, Yeoreum Yun, Mark Rutland, Will Deacon,
Yabin Cui, Keita Morisaki, Jie Gan, Yuanfang Zhang,
Greg Kroah-Hartman, Alexander Shishkin, Tamas Petz,
Thomas Gleixner, Peter Zijlstra, coresight, linux-arm-kernel
In-Reply-To: <a40b0d0f-bbf8-4ba4-9370-2b5be71bdc44@arm.com>
On Fri, May 15, 2026 at 11:54:22AM +0100, Suzuki K Poulose wrote:
[...]
> > + /*
> > + * Update the path pointer until after the source is enabled to avoid
> > + * races where multiple paths attempt to enable the same source.
> > + *
> > + * Do not set the path pointer here for per-CPU sources; set it locally
> > + * on the CPU instead. Otherwise, there is a window where the path is
> > + * enabled but the pointer is not yet set, causing CPU PM notifiers to
> > + * miss PM operations due to reading a NULL pointer.
> > + */
> > + if (!coresight_is_percpu_source(csdev))
> > + csdev->path = path;
>
> Do we need to specail case this for non-percpu sources ? We could always let
> the driver save/clear the path leaving the core out of it. We can fix it
> separately from this series in a follow up patch.
This patch has a big reason is for patch 22. After saving csdev->path,
then patch 22 can totally remove IDR cache related things.
Otherwise, we can drop this patch and patch 22, this wouldn't impact
CPU PM stuffs.
Thanks,
Leo
^ permalink raw reply
* Re: [net-next v8 2/3] net: ethernet: mtk_eth_soc: Add RSS support
From: Frank Wunderlich @ 2026-05-15 11:13 UTC (permalink / raw)
To: Jakub Kicinski, Mason Chang
Cc: AngeloGioacchino Del Regno, netdev, Russell King, linux-kernel,
Andrew Lunn, Eric Dumazet, linux-mediatek, Daniel Golle,
Matthias Brugger, Paolo Abeni, Lorenzo Bianconi, David S. Miller,
linux-arm-kernel, Felix Fietkau, Frank Wunderlich
In-Reply-To: <20260513185625.48e69837@kernel.org>
Hi Jakub,
thanks for your review, i have to discuss the previous parts (AI-review)
with MTK on how to make it better. The changes there seem not trivial for
me and this will take some time.
Am 14. Mai 2026 um 03:56 schrieb "Jakub Kicinski" <kuba@kernel.org>:
>
> On Sat, 9 May 2026 21:09:31 +0200 Frank Wunderlich wrote:
>
> >
> > From: Mason Chang <mason-cw.chang@mediatek.com>
> >
> > Add support for Receive Side Scaling.
> >
> > We can adjust SMP affinity with the following command:
> > echo [CPU bitmap num] > /proc/irq/[virtual IRQ ID]/smp_affinity,
> > with interrupts evenly assigned to 4 CPUs, we were able to measure
> > an RX throughput of 7.3Gbps using iperf3 on the MT7988. Further
> > optimizations will be carried out in the future.
> >
> Would be great to split this up a little more for ease of review.
you mean splitting the code into more separate patches or the commit description?
> >
> > +static int mtk_rss_init(struct mtk_eth *eth)
> > +{
> > + const struct mtk_soc_data *soc = eth->soc;
> > + const struct mtk_reg_map *reg_map = eth->soc->reg_map;
> > + struct mtk_rss_params *rss_params = ð->rss_params;
> >
> reverse xmas tree should be followed, please fix everywhere in this
> submission
will check again when we have the fixed flow (AI-review).
> >
> > +/* struct mtk_rss_params - This is the structure holding parameters
> > + * for the RSS ring
> > + * @hash_key The element is used to record the
> > + * secret key for the RSS ring
> > + * indirection_table The element is used to record the
> > + * indirection table for the RSS ring
> > + */
> >
> Quite odd looking comment. Having the right side aligned like that
> makes it header to correlate where doc for fields start.
> And there's @ missing for indirection_table.
dito
@Mason: have you found some time for looking into the AI suggestions?
Maybe it is better discussing changes here if they match upstream
requirements as i did only up-port the SDK-patches with some small
changes and made tests :)
As a note: i have not activated RSS/LRO on other mt798x because it was
not clear, if RSS or LRO is better for them and only mt7988 can do both
simultanously. AI also complained about it. And this decision causes
changes in code too.
It would be great if you can use the actual state here as base for
changes so that i do not miss anything when upporting the SDK state again.
regards Frank
^ permalink raw reply
* Re: [PATCH v2] soc: ti: knav_qmss_queue: Implement resource cleanup in remove()
From: Nishanth Menon @ 2026-05-15 11:12 UTC (permalink / raw)
To: Md Shofiqul Islam; +Cc: ssantosh, linux-arm-kernel, linux-kernel
In-Reply-To: <177878513972.16124.2519778203402988912@gmail.com>
On 21:58-20260514, Md Shofiqul Islam wrote:
> Hi Nishanth,
>
> Gentle ping on this patch. You suggested this fix — the patch
> implements exactly what was discussed: stopping PDSPs and freeing
> queue regions and queue ranges before disabling runtime PM,
> mirroring the cleanup already done in the probe error path, and
> setting device_ready to false before teardown.
>
> Could you take a look and provide an Acked-by if it looks correct?
>
> The patch has been waiting since November 2025 across several
> versions with no reviewer feedback.
>
> Link: https://lore.kernel.org/linux-arm-kernel/20260506154114.2288-1-shofiqtest@gmail.com/
Usually the latest version of the patch does need a few days of
soaking in mailing list before being picked up. I was going to do that
later today.
--
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3 1A34 DDB5 849D 1736 249D
https://ti.com/opensource
^ permalink raw reply
* Re: [PATCH 3/3] interconnect: qcom: Make important drivers default
From: Konrad Dybcio @ 2026-05-15 11:12 UTC (permalink / raw)
To: Krzysztof Kozlowski, Georgi Djakov, Bjorn Andersson,
Konrad Dybcio
Cc: linux-arm-msm, linux-pm, linux-kernel, linux-arm-kernel
In-Reply-To: <720715a0-eb4f-4083-a67f-aa380e130d6c@oss.qualcomm.com>
On 5/15/26 1:11 PM, Krzysztof Kozlowski wrote:
> On 15/05/2026 12:54, Konrad Dybcio wrote:
>> On 4/29/26 5:09 PM, Krzysztof Kozlowski wrote:
>>> On 29/04/2026 11:23, Konrad Dybcio wrote:
>>>> On 4/28/26 7:32 PM, Krzysztof Kozlowski wrote:
>>>>> The interconnect drivers for Qualcomm SoC Network-on-Chip are covering a
>>>>> basic or fundamental SoC feature: bandwidth management between internal
>>>>> SoC blocks. SoC can boot without these, but power management or
>>>>> performance will be affected. These drivers do not represent any sort
>>>>> of buses visible to the board designers/configurators, thus they should
>>>>> be always enabled, regardless how SoC is used in the final board.
>>>>>
>>>>> Kernel configuration should not ask users choice of drivers when that
>>>>> choice is obvious and known to the developers that answer should be
>>>>> 'yes' or 'module'.
>>>>
>>>> I'd say let's make them all `default ARCH_QCOM` - all of these drivers
>>>> are required to boot (minus the OSM_L3 driver which is "only" highly
>>>> desired, so that your CPU's bus isn't heavily bottlenecked)
>>>
>>> So the few of them should not be a module? That's what you want to say?
>>
>> I'm saying that if you only want to shoot yourself in the foot and not
>> in the face, you can make them modules
>>
>> But the L3 driver is required to make the caches run at a reasonable
>> speed, so that they don't bottleneck the rest of the system's mem
>> bandwidth
>
> okidoki, so I will mark all as default built-in as you said, including
> the OSM_L3, based on your explanation.
Thanks!
Konrad
^ 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