* Re: [PATCH 0/3] arm-smmu-v3: Add PMCG child support and update PMU MMIO mapping
From: Robin Murphy @ 2026-04-14 9:32 UTC (permalink / raw)
To: Peng Fan
Cc: Will Deacon, Joerg Roedel, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Mark Rutland, linux-arm-kernel, iommu, devicetree,
linux-kernel, linux-perf-users, Peng Fan
In-Reply-To: <ad3w/P1vA2uKsV/o@shlinux89>
On 2026-04-14 8:47 am, Peng Fan wrote:
> Hi Robin,
>
> On Fri, Apr 10, 2026 at 01:07:29PM +0100, Robin Murphy wrote:
>> On 08/04/2026 2:47 pm, Peng Fan wrote:
>>> On Wed, Apr 08, 2026 at 12:15:31PM +0100, Robin Murphy wrote:
>>>> On 2026-04-08 8:51 am, Peng Fan (OSS) wrote:
>>>>> This patch series adds proper support for describing and probing the
>>>>> Arm SMMU v3 PMCG (Performance Monitor Control Group) as a child node of
>>>>> the SMMU in Devicetree, and updates the relevant drivers accordingly.
>>>>>
>>>>> The SMMU v3 architecture allows an optional PMCG block, typically
>>>>> associated with TCUs, to be implemented within the SMMU register
>>>>> address space. For example, mmu700 PMCG is at the offset 0x2000 of the
>>>>> TCU page 0.
>>>>
>>>> But what's wrong with the existing binding? Especially given that it even has
>>>> an upstream user already:
>>>>
>>>> https://git.kernel.org/torvalds/c/aef9703dcbf8
>>>>
>>>>> Patch 1 updates the SMMU v3 Devicetree binding to allow PMCG child nodes,
>>>>> referencing the existing arm,smmu-v3-pmcg binding.
>>>>>
>>>>> Patch 2 updates the arm-smmu-v3 driver to populate platform devices for
>>>>> child nodes described in DT once the SMMU probe succeeds.
>>>>>
>>>>> Patch 3 updates the SMMUv3 PMU driver to correctly handle MMIO mapping when
>>>>> PMCG is described as a child node. The PMCG registers occupy a sub-region
>>>>> of the parent SMMU MMIO window, which is already requested by the SMMU
>>>>
>>>> That has not been the case since 52f3fab0067d ("iommu/arm-smmu-v3: Don't
>>>> reserve implementation defined register space") nearly 6 years ago, where the
>>>> whole purpose was to support Arm's PMCG implementation properly. What kernel
>>>> is this based on?
>>>
>>> Seems I am wrong. I thought PMCG is in page 0, so there were resource
>>> conflicts. I just retest without this patchset, all goes well.
>>>
>>> But from dt perspective, should the TCU PMCG node be child node of
>>> SMMU node?
>>
>> No. PMCGs can be used entirely independently of the SMMU itself, and while
>> most of the events do relate to SMMU translation and thus aren't necessarily
>> meaningful if it's not in use, there are still some which can be useful for
>> basic traffic counting, monitoring GPT/translation activity from _other_
>> security states (if observation is delegated to Non-Secure) and possibly
>> other things, even if the "main" Non-Secure SMMU interface isn't advertised
>> at all. It would be unreasonable to require the SMMU node to be present and
>> enabled *and* have a driver to populate PMCGs, to monitor events which are
>> outside the scope of that driver.
>
> Thanks for explaining this in detail.
>
> Just have one more question, we are using mmu-700, but MMU-700 implementation
> defined TCU and TBU events are not supported.
>
> Should we introduce a compatible string saying "arm,mmu700-tcu-pmcg" or
> "arm,mmu700-tbu-pmcg"? TBH, I have not checked MMU600(AE) or else.
MMU-700 and all other Arm implementations are still fully compatible
with "arm,mmu-600-pmcg" in terms of what that means. That lets the
driver correctly construct the "identifier" attribute, which then allows
userspace to know what exact PMU implementation it is.
We don't maintain ever-growing lists of aliases for imp-def events in
the kernel driver, same as we don't for CPU PMUs either. Generally,
anyone who has reason to go near those is likely to already have the TRM
to hand and thus have the encodings anyway, but I suppose you could add
jevents with the proper meaningful descriptions if you really wanted to.
Thanks,
Robin.
^ permalink raw reply
* Re: [PATCH bpf-next v2 1/2] bpf, arm64: Remove redundant bpf_flush_icache() after pack allocator finalize
From: Puranjay Mohan @ 2026-04-14 9:38 UTC (permalink / raw)
To: Xu Kuohai
Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Song Liu, Yonghong Song, Jiri Olsa, Catalin Marinas, Will Deacon,
Luke Nelson, Xi Wang, Björn Töpel, Pu Lehui,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
linux-arm-kernel, linux-riscv, linux-kernel
In-Reply-To: <dd645fcf-76dc-4c68-8b6f-1a168cafd44f@huaweicloud.com>
On Tue, Apr 14, 2026 at 2:56 AM Xu Kuohai <xukuohai@huaweicloud.com> wrote:
>
> On 4/14/2026 3:11 AM, Puranjay Mohan wrote:
> > bpf_flush_icache() calls flush_icache_range() to clean the data cache
> > and invalidate the instruction cache for the JITed code region. However,
> > since commit 1dad391daef1 ("bpf, arm64: use bpf_prog_pack for memory
> > management"), this flush is redundant.
> >
> > bpf_jit_binary_pack_finalize() copies the JITed instructions to the ROX
> > region via bpf_arch_text_copy() -> aarch64_insn_copy() -> __text_poke(),
> > and __text_poke() already calls flush_icache_range() on the written
> > range. The subsequent bpf_flush_icache() repeats the same cache
> > maintenance on an overlapping range, including an unnecessary second
> > synchronous IPI to all CPUs via kick_all_cpus_sync().
> >
>
> So icache is flushed twice: once per instruction and again after all
> instructions are copied. I think it's better to remove the per-instruction
> flush and retain the single final flush to avoid repeating flush overhead
> for each instruction.
No, bpf_jit_binary_pack_finalize() is called at the end after the
whole program is jited, and it calls: bpf_arch_text_copy(ro_header,
rw_header, rw_header->size); which does aarch64_insn_copy(dst, src,
len), this calls __text_poke() which copies the whole program and then
does flush_icache_range((uintptr_t)addr, (uintptr_t)addr + len); once.
This is correct, after this we don't need to call flush_icache_range()
on the same range again.
If we had been calling flush_icache_range() for each instruction, the
system would hang due to the storm of IPIs.
^ permalink raw reply
* [PATCH v6 0/3] pinctrl: aspeed: Add AST2700 SoC0 support
From: Billy Tsai @ 2026-04-14 9:38 UTC (permalink / raw)
To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Joel Stanley, Andrew Jeffery, Linus Walleij, Billy Tsai,
Bartosz Golaszewski, Ryan Chen
Cc: Andrew Jeffery, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, openbmc, linux-gpio, linux-clk
AST2700 is composed of two interconnected SoC instances, each providing
its own pin control hardware. This series introduces bindings describing
the AST2700 pinctrl architecture and adds pinctrl driver support for the
SoC0 instance.
The bindings document the AST2700 dual-SoC design and follow common
pinctrl conventions, while the SoC0 driver implementation builds upon
the existing ASPEED pinctrl infrastructure.
---
Changes in v6:
- Restrict AST2700 SoC0 pinctrl pin configuration properties
(`drive-strength` and `bias-*`) to `pins`-based state nodes in the
binding schema.
- Move `memory-region` and `memory-region-names` in the AST2x00 SCU
binding to top-level descriptions, and keep the conditional schema
only to disallow them for non-AST2700 SCU0 compatibles.
- Add bias pull-up, pull-down, and disable support for AST2700 SoC0
GPIO18A/GPIO18B pins in the pinctrl driver.
- Fix the USB2 Port B XH/XHP mux selector definitions to use the
correct `PORTB_U2_XH_DESC` setting.
- Link to v5: https://lore.kernel.org/r/20260331-upstream_pinctrl-v5-0-8994f59ff367@aspeedtech.com
Changes in v5:
- Complete the AST2700 SCU0 binding and disallow child nodes that are
not relevant for the hardware (p2a-control and smp-memram).
- Add examples for both the AST2700 SCU0 binding and the pinctrl binding,
ensuring they are valid against the schema.
- Rework the pinctrl binding example to be self-contained and independent
of the SCU binding.
- Reorder the binding patches so the pinctrl binding is introduced before
the SCU binding update, allowing the SCU example to be added cleanly.
- Adjust the binding accordingly to restrict drive-strength to the
supported values.
- Update the drive-strength table to match hardware-defined values.
- Link to v4: https://lore.kernel.org/r/20260306-upstream_pinctrl-v4-0-ad4e8ab8b489@aspeedtech.com
Changes in v4:
- Rename series title to "pinctrl: aspeed: Add AST2700 SoC0 support"
to make it specific to SoC0.
- Remove unnecessary SCU example from bindings.
- Fix Makefile newline to avoid patch warning.
- Make pinctrl data structures const and align with existing Aspeed drivers.
- Sort the arrays and enums alphabetically.
- Minor cleanups for consistency, no functional changes.
- Link to v3: https://lore.kernel.org/r/20260120-upstream_pinctrl-v3-0-868fbf8413b5@aspeedtech.com
Changes in v3:
dt-bindings: pinctrl: aspeed: AST2700 pinctrl improvements
- Improved binding descriptions for SoC0 and SoC1 to better explain the
AST2700 dual-SoC architecture with independent pin control blocks
- Switched from additionalProperties to patternProperties using the
'-state$' suffix to restrict child node naming
- Removed per-binding examples based on review feedback
- Added additionalProperties: false at the top level for stricter schema
validation
- Dropped the aspeed,ast2700-soc1-pinctrl binding, as the SoC1 pinctrl
registers follow a regular layout and can be described using an
existing generic pinctrl binding
- Updated the function and group enum lists to match the definitions
used by the AST2700 pinctrl driver
dt-bindings: mfd: aspeed: Add AST2700 SCU example with pinctrl
- Added a complete AST2700 SCU0 example demonstrating pinctrl integration
- Example covers both pin function/group configuration and pin
drive-strength settings
- Updated child node naming to use the '-state' suffix, following common
pinctrl conventions
pinctrl: aspeed: AST2700 SoC0 driver improvements
- Refactored pin and signal declarations to use common ASPEED pinmux
macros (SIG_EXPR_LIST_DECL_SEMG, SIG_EXPR_LIST_DECL_SESG, PIN_DECL_*)
- Added SCU010 register definition for hardware strap control
- Reworked code structure to better align with existing ASPEED pinctrl
drivers
- Link to v2: https://lore.kernel.org/r/20250904103401.88287-1-billy_tsai@aspeedtech.com
Changes in v2:
- Update pinctrl aspeed binding files.
- Update the commit message for pinctrl binding patch.
- Link to v1: https://lore.kernel.org/r/20250829073030.2749482-1-billy_tsai@aspeedtech.com
---
Billy Tsai (3):
dt-bindings: pinctrl: Add aspeed,ast2700-soc0-pinctrl
dt-bindings: mfd: aspeed,ast2x00-scu: Describe AST2700 SCU0
pinctrl: aspeed: Add AST2700 SoC0 support
.../bindings/mfd/aspeed,ast2x00-scu.yaml | 112 +++
.../pinctrl/aspeed,ast2700-soc0-pinctrl.yaml | 170 +++++
drivers/pinctrl/aspeed/Kconfig | 9 +
drivers/pinctrl/aspeed/Makefile | 1 +
drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc0.c | 749 +++++++++++++++++++++
5 files changed, 1041 insertions(+)
---
base-commit: af4e9ef3d78420feb8fe58cd9a1ab80c501b3c08
change-id: 20251215-upstream_pinctrl-8f195df0a975
Best regards,
--
Billy Tsai <billy_tsai@aspeedtech.com>
^ permalink raw reply
* [PATCH v6 1/3] dt-bindings: pinctrl: Add aspeed,ast2700-soc0-pinctrl
From: Billy Tsai @ 2026-04-14 9:38 UTC (permalink / raw)
To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Joel Stanley, Andrew Jeffery, Linus Walleij, Billy Tsai,
Bartosz Golaszewski, Ryan Chen
Cc: Andrew Jeffery, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, openbmc, linux-gpio, linux-clk
In-Reply-To: <20260414-upstream_pinctrl-v6-0-709f2127da33@aspeedtech.com>
Add a device tree binding for the pin controller found in the
ASPEED AST2700 SoC0.
The controller manages various peripheral functions such as eMMC, USB,
VGA DDC, JTAG, and PCIe root complex signals.
Describe the AST2700 SoC0 pin controller using standard pin multiplexing
and configuration properties.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
.../pinctrl/aspeed,ast2700-soc0-pinctrl.yaml | 170 +++++++++++++++++++++
1 file changed, 170 insertions(+)
diff --git a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc0-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc0-pinctrl.yaml
new file mode 100644
index 000000000000..ca008cf9dc7c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc0-pinctrl.yaml
@@ -0,0 +1,170 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/aspeed,ast2700-soc0-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ASPEED AST2700 SoC0 Pin Controller
+
+maintainers:
+ - Billy Tsai <billy_tsai@aspeedtech.com>
+
+description:
+ The AST2700 features a dual-SoC architecture with two interconnected SoCs,
+ each having its own System Control Unit (SCU) for independent pin control.
+ This pin controller manages the pin multiplexing for SoC0.
+
+ The SoC0 pin controller manages pin functions including eMMC, VGA DDC,
+ dual USB3/USB2 ports (A and B), JTAG, and PCIe root complex interfaces.
+
+properties:
+ compatible:
+ const: aspeed,ast2700-soc0-pinctrl
+ reg:
+ maxItems: 1
+
+patternProperties:
+ '-state$':
+ type: object
+ allOf:
+ - $ref: pinmux-node.yaml#
+ - $ref: pincfg-node.yaml#
+ - if:
+ required:
+ - pins
+ else:
+ properties:
+ drive-strength: false
+ bias-disable: false
+ bias-pull-up: false
+ bias-pull-down: false
+ additionalProperties: false
+
+ properties:
+ function:
+ enum:
+ - EMMC
+ - JTAGDDR
+ - JTAGM0
+ - JTAGPCIEA
+ - JTAGPCIEB
+ - JTAGPSP
+ - JTAGSSP
+ - JTAGTSP
+ - JTAGUSB3A
+ - JTAGUSB3B
+ - PCIERC0PERST
+ - PCIERC1PERST
+ - TSPRSTN
+ - UFSCLKI
+ - USB2AD0
+ - USB2AD1
+ - USB2AH
+ - USB2AHP
+ - USB2AHPD0
+ - USB2AXH
+ - USB2AXH2B
+ - USB2AXHD1
+ - USB2AXHP
+ - USB2AXHP2B
+ - USB2AXHPD1
+ - USB2BD0
+ - USB2BD1
+ - USB2BH
+ - USB2BHP
+ - USB2BHPD0
+ - USB2BXH
+ - USB2BXH2A
+ - USB2BXHD1
+ - USB2BXHP
+ - USB2BXHP2A
+ - USB2BXHPD1
+ - USB3AXH
+ - USB3AXH2B
+ - USB3AXHD
+ - USB3AXHP
+ - USB3AXHP2B
+ - USB3AXHPD
+ - USB3BXH
+ - USB3BXH2A
+ - USB3BXHD
+ - USB3BXHP
+ - USB3BXHP2A
+ - USB3BXHPD
+ - VB
+ - VGADDC
+
+ groups:
+ enum:
+ - EMMCCDN
+ - EMMCG1
+ - EMMCG4
+ - EMMCG8
+ - EMMCWPN
+ - JTAG0
+ - PCIERC0PERST
+ - PCIERC1PERST
+ - TSPRSTN
+ - UFSCLKI
+ - USB2A
+ - USB2AAP
+ - USB2ABP
+ - USB2ADAP
+ - USB2AH
+ - USB2AHAP
+ - USB2B
+ - USB2BAP
+ - USB2BBP
+ - USB2BDBP
+ - USB2BH
+ - USB2BHBP
+ - USB3A
+ - USB3AAP
+ - USB3ABP
+ - USB3B
+ - USB3BAP
+ - USB3BBP
+ - VB0
+ - VB1
+ - VGADDC
+ pins:
+ enum:
+ - AB13
+ - AB14
+ - AC13
+ - AC14
+ - AD13
+ - AD14
+ - AE13
+ - AE14
+ - AE15
+ - AF13
+ - AF14
+ - AF15
+
+ drive-strength:
+ enum: [3, 6, 8, 11, 16, 18, 20, 23, 30, 32, 33, 35, 37, 38, 39, 41]
+
+ bias-disable: true
+ bias-pull-up: true
+ bias-pull-down: true
+
+required:
+ - compatible
+ - reg
+
+allOf:
+ - $ref: pinctrl.yaml#
+
+additionalProperties: false
+
+examples:
+ - |
+ pinctrl@400 {
+ compatible = "aspeed,ast2700-soc0-pinctrl";
+ reg = <0x400 0x318>;
+ emmc-state {
+ function = "EMMC";
+ groups = "EMMCG1";
+ };
+ };
--
2.34.1
^ permalink raw reply related
* [PATCH v6 2/3] dt-bindings: mfd: aspeed,ast2x00-scu: Describe AST2700 SCU0
From: Billy Tsai @ 2026-04-14 9:39 UTC (permalink / raw)
To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Joel Stanley, Andrew Jeffery, Linus Walleij, Billy Tsai,
Bartosz Golaszewski, Ryan Chen
Cc: Andrew Jeffery, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, openbmc, linux-gpio, linux-clk
In-Reply-To: <20260414-upstream_pinctrl-v6-0-709f2127da33@aspeedtech.com>
AST2700 consists of two interconnected SoC instances, each with its own
System Control Unit (SCU). The SCU0 provides pin control, interrupt
controllers, clocks, resets, and address-space mappings for the
Secondary and Tertiary Service Processors (SSP and TSP).
Describe the SSP/TSP address mappings using the standard
memory-region and memory-region-names properties.
Disallow legacy child nodes that are not present on AST2700, including
p2a-control and smp-memram. The latter is unnecessary as software can
access the scratch registers via the SCU syscon.
Also allow the AST2700 SoC0 pin controller to be described as a child
node of the SCU0, and add an example illustrating the SCU0 layout,
including reserved-memory, interrupt controllers, and pinctrl.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
.../bindings/mfd/aspeed,ast2x00-scu.yaml | 112 +++++++++++++++++++++
1 file changed, 112 insertions(+)
diff --git a/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml b/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml
index a87f31fce019..d65897576a40 100644
--- a/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml
+++ b/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml
@@ -46,6 +46,17 @@ properties:
'#reset-cells':
const: 1
+ memory-region:
+ items:
+ - description: Region mapped through the first SSP address window.
+ - description: Region mapped through the second SSP address window.
+ - description: Region mapped through the TSP address window.
+ memory-region-names:
+ items:
+ - const: ssp-0
+ - const: ssp-1
+ - const: tsp
+
patternProperties:
'^p2a-control@[0-9a-f]+$':
description: >
@@ -87,6 +98,7 @@ patternProperties:
- aspeed,ast2400-pinctrl
- aspeed,ast2500-pinctrl
- aspeed,ast2600-pinctrl
+ - aspeed,ast2700-soc0-pinctrl
required:
- compatible
@@ -156,6 +168,29 @@ required:
- '#clock-cells'
- '#reset-cells'
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ anyOf:
+ - const: aspeed,ast2700-scu0
+ - const: aspeed,ast2700-scu1
+ then:
+ patternProperties:
+ '^p2a-control@[0-9a-f]+$': false
+ '^smp-memram@[0-9a-f]+$': false
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: aspeed,ast2700-scu0
+ else:
+ properties:
+ memory-region: false
+ memory-region-names: false
+
additionalProperties: false
examples:
@@ -180,4 +215,81 @@ examples:
reg = <0x7c 0x4>, <0x150 0x8>;
};
};
+
+ - |
+ / {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ ssp_region_0: memory@400000000 {
+ reg = <0x4 0x00000000 0x0 0x01000000>;
+ no-map;
+ };
+
+ ssp_region_1: memory@401000000 {
+ reg = <0x4 0x01000000 0x0 0x01000000>;
+ no-map;
+ };
+
+ tsp_region: memory@402000000 {
+ reg = <0x4 0x02000000 0x0 0x01000000>;
+ no-map;
+ };
+ };
+
+ bus {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ syscon@12c02000 {
+ compatible = "aspeed,ast2700-scu0", "syscon", "simple-mfd";
+ reg = <0 0x12c02000 0 0x1000>;
+ ranges = <0x0 0x0 0x12c02000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+
+ memory-region = <&ssp_region_0>, <&ssp_region_1>,
+ <&tsp_region>;
+ memory-region-names = "ssp-0", "ssp-1", "tsp";
+
+ silicon-id@0 {
+ compatible = "aspeed,ast2700-silicon-id", "aspeed,silicon-id";
+ reg = <0x0 0x4>;
+ };
+
+ interrupt-controller@1b0 {
+ compatible = "aspeed,ast2700-scu-ic0";
+ reg = <0x1b0 0x4>;
+ #interrupt-cells = <1>;
+ interrupts-extended = <&intc0 97>;
+ interrupt-controller;
+ };
+
+ interrupt-controller@1e0 {
+ compatible = "aspeed,ast2700-scu-ic1";
+ reg = <0x1e0 0x4>;
+ #interrupt-cells = <1>;
+ interrupts-extended = <&intc0 98>;
+ interrupt-controller;
+ };
+
+ pinctrl@400 {
+ compatible = "aspeed,ast2700-soc0-pinctrl";
+ reg = <0x400 0x318>;
+ emmc-state {
+ function = "EMMC";
+ groups = "EMMCG1";
+ };
+ };
+ };
+ };
+ };
+
...
--
2.34.1
^ permalink raw reply related
* [PATCH v6 3/3] pinctrl: aspeed: Add AST2700 SoC0 support
From: Billy Tsai @ 2026-04-14 9:39 UTC (permalink / raw)
To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Joel Stanley, Andrew Jeffery, Linus Walleij, Billy Tsai,
Bartosz Golaszewski, Ryan Chen
Cc: Andrew Jeffery, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, openbmc, linux-gpio, linux-clk
In-Reply-To: <20260414-upstream_pinctrl-v6-0-709f2127da33@aspeedtech.com>
Add pinctrl support for the SoC0 instance of the ASPEED AST2700.
AST2700 consists of two interconnected SoC instances, each with its own
pinctrl register block.
The SoC0 pinctrl hardware closely follows the design found in previous
ASPEED BMC generations, allowing the driver to build upon the common
ASPEED pinctrl infrastructure.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/pinctrl/aspeed/Kconfig | 9 +
drivers/pinctrl/aspeed/Makefile | 1 +
drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc0.c | 749 ++++++++++++++++++++++++
3 files changed, 759 insertions(+)
diff --git a/drivers/pinctrl/aspeed/Kconfig b/drivers/pinctrl/aspeed/Kconfig
index 1a4e5b9ed471..f9672cca891e 100644
--- a/drivers/pinctrl/aspeed/Kconfig
+++ b/drivers/pinctrl/aspeed/Kconfig
@@ -31,3 +31,12 @@ config PINCTRL_ASPEED_G6
help
Say Y here to enable pin controller support for Aspeed's 6th
generation SoCs. GPIO is provided by a separate GPIO driver.
+
+config PINCTRL_ASPEED_G7_SOC0
+ bool "Aspeed G7 SoC pin control"
+ depends on (ARCH_ASPEED || COMPILE_TEST) && OF
+ select PINCTRL_ASPEED
+ help
+ 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.
diff --git a/drivers/pinctrl/aspeed/Makefile b/drivers/pinctrl/aspeed/Makefile
index db2a7600ae2b..0de524ca2c72 100644
--- a/drivers/pinctrl/aspeed/Makefile
+++ b/drivers/pinctrl/aspeed/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_PINCTRL_ASPEED) += pinctrl-aspeed.o pinmux-aspeed.o
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
diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc0.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc0.c
new file mode 100644
index 000000000000..35a28b677318
--- /dev/null
+++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc0.c
@@ -0,0 +1,749 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/bitops.h>
+#include <linux/bits.h>
+#include <linux/mfd/syscon.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 "pinctrl-aspeed.h"
+#include "pinmux-aspeed.h"
+#include "../pinctrl-utils.h"
+
+#define SCU200 0x200 /* System Reset Control #1 */
+
+#define SCU010 0x010 /* Hardware Strap Register */
+#define SCU400 0x400 /* Multi-function Pin Control #1 */
+#define SCU404 0x404 /* Multi-function Pin Control #2 */
+#define SCU408 0x408 /* Multi-function Pin Control #3 */
+#define SCU40C 0x40C /* Multi-function Pin Control #3 */
+#define SCU410 0x410 /* USB Multi-function Control Register */
+#define SCU414 0x414 /* VGA Function Control Register */
+
+#define SCU480 0x480 /* GPIO18A0 IO Control Register */
+#define SCU484 0x484 /* GPIO18A1 IO Control Register */
+#define SCU488 0x488 /* GPIO18A2 IO Control Register */
+#define SCU48C 0x48c /* GPIO18A3 IO Control Register */
+#define SCU490 0x490 /* GPIO18A4 IO Control Register */
+#define SCU494 0x494 /* GPIO18A5 IO Control Register */
+#define SCU498 0x498 /* GPIO18A6 IO Control Register */
+#define SCU49C 0x49c /* GPIO18A7 IO Control Register */
+#define SCU4A0 0x4A0 /* GPIO18B0 IO Control Register */
+#define SCU4A4 0x4A4 /* GPIO18B1 IO Control Register */
+#define SCU4A8 0x4A8 /* GPIO18B2 IO Control Register */
+#define SCU4AC 0x4AC /* GPIO18B3 IO Control Register */
+
+enum {
+ AC14,
+ AE15,
+ AD14,
+ AE14,
+ AF14,
+ AB13,
+ AB14,
+ AF15,
+ AF13,
+ AC13,
+ AD13,
+ AE13,
+ JTAG_PORT,
+ PCIERC0_PERST,
+ PCIERC1_PERST,
+ PORTA_MODE,
+ PORTA_U2,
+ PORTB_MODE,
+ PORTB_U2,
+ PORTA_U2_PHY,
+ PORTB_U2_PHY,
+ PORTA_U3,
+ PORTB_U3,
+ PORTA_U3_PHY,
+ PORTB_U3_PHY,
+};
+
+SIG_EXPR_LIST_DECL_SEMG(AC14, EMMCCLK, EMMCG1, EMMC, SIG_DESC_SET(SCU400, 0));
+SIG_EXPR_LIST_DECL_SESG(AC14, VB1CS, VB1, SIG_DESC_SET(SCU404, 0));
+PIN_DECL_2(AC14, GPIO18A0, EMMCCLK, VB1CS);
+
+SIG_EXPR_LIST_DECL_SEMG(AE15, EMMCCMD, EMMCG1, EMMC, SIG_DESC_SET(SCU400, 1));
+SIG_EXPR_LIST_DECL_SESG(AE15, VB1CK, VB1, SIG_DESC_SET(SCU404, 1));
+PIN_DECL_2(AE15, GPIO18A1, EMMCCMD, VB1CK);
+
+SIG_EXPR_LIST_DECL_SEMG(AD14, EMMCDAT0, EMMCG1, EMMC, SIG_DESC_SET(SCU400, 2));
+SIG_EXPR_LIST_DECL_SESG(AD14, VB1MOSI, VB1, SIG_DESC_SET(SCU404, 2));
+PIN_DECL_2(AD14, GPIO18A2, EMMCDAT0, VB1MOSI);
+
+SIG_EXPR_LIST_DECL_SEMG(AE14, EMMCDAT1, EMMCG4, EMMC, SIG_DESC_SET(SCU400, 3));
+SIG_EXPR_LIST_DECL_SESG(AE14, VB1MISO, VB1, SIG_DESC_SET(SCU404, 3));
+PIN_DECL_2(AE14, GPIO18A3, EMMCDAT1, VB1MISO);
+
+SIG_EXPR_LIST_DECL_SEMG(AF14, EMMCDAT2, EMMCG4, EMMC, SIG_DESC_SET(SCU400, 4));
+PIN_DECL_1(AF14, GPIO18A4, EMMCDAT2);
+
+SIG_EXPR_LIST_DECL_SEMG(AB13, EMMCDAT3, EMMCG4, EMMC, SIG_DESC_SET(SCU400, 5));
+PIN_DECL_1(AB13, GPIO18A5, EMMCDAT3);
+
+SIG_EXPR_LIST_DECL_SEMG(AB14, EMMCCDN, EMMCG1, EMMC, SIG_DESC_SET(SCU400, 6));
+SIG_EXPR_LIST_DECL_SESG(AB14, VB0CS, VB0, SIG_DESC_SET(SCU010, 17));
+PIN_DECL_2(AB14, GPIO18A6, EMMCCDN, VB0CS);
+
+SIG_EXPR_LIST_DECL_SEMG(AF15, EMMCWPN, EMMCG1, EMMC, SIG_DESC_SET(SCU400, 7));
+SIG_EXPR_LIST_DECL_SESG(AF15, VB0CK, VB0, SIG_DESC_SET(SCU010, 17));
+PIN_DECL_2(AF15, GPIO18A7, EMMCWPN, VB0CK);
+
+SIG_EXPR_LIST_DECL_SESG(AF13, TSPRSTN, TSPRSTN, SIG_DESC_SET(SCU010, 9));
+SIG_EXPR_LIST_DECL_SEMG(AF13, EMMCDAT4, EMMCG8, EMMC, SIG_DESC_SET(SCU400, 8));
+SIG_EXPR_LIST_DECL_SESG(AF13, VB0MOSI, VB0, SIG_DESC_SET(SCU010, 17));
+PIN_DECL_3(AF13, GPIO18B0, TSPRSTN, EMMCDAT4, VB0MOSI);
+
+SIG_EXPR_LIST_DECL_SESG(AC13, UFSCLKI, UFSCLKI, SIG_DESC_SET(SCU010, 19));
+SIG_EXPR_LIST_DECL_SEMG(AC13, EMMCDAT5, EMMCG8, EMMC, SIG_DESC_SET(SCU400, 9));
+SIG_EXPR_LIST_DECL_SESG(AC13, VB0MISO, VB0, SIG_DESC_SET(SCU010, 17));
+PIN_DECL_3(AC13, GPIO18B1, UFSCLKI, EMMCDAT5, VB0MISO);
+
+SIG_EXPR_LIST_DECL_SEMG(AD13, EMMCDAT6, EMMCG8, EMMC, SIG_DESC_SET(SCU400, 10));
+SIG_EXPR_LIST_DECL_SESG(AD13, DDCCLK, VGADDC, SIG_DESC_SET(SCU404, 10));
+PIN_DECL_2(AD13, GPIO18B2, EMMCDAT6, DDCCLK);
+
+SIG_EXPR_LIST_DECL_SEMG(AE13, EMMCDAT7, EMMCG8, EMMC, SIG_DESC_SET(SCU400, 11));
+SIG_EXPR_LIST_DECL_SESG(AE13, DDCDAT, VGADDC, SIG_DESC_SET(SCU404, 11));
+PIN_DECL_2(AE13, GPIO18B3, EMMCDAT7, DDCDAT);
+
+GROUP_DECL(EMMCG1, AC14, AE15, AD14);
+GROUP_DECL(EMMCG4, AC14, AE15, AD14, AE14, AF14, AB13);
+GROUP_DECL(EMMCG8, AC14, AE15, AD14, AE14, AF14, AB13, AF13, AC13, AD13, AE13);
+GROUP_DECL(EMMCWPN, AF15);
+GROUP_DECL(EMMCCDN, AB14);
+FUNC_DECL_(EMMC, "EMMCG1", "EMMCG4", "EMMCG8", "EMMCWPN", "EMMCCDN");
+
+GROUP_DECL(VB1, AC14, AE15, AD14, AE14);
+GROUP_DECL(VB0, AF15, AB14, AF13, AC13);
+FUNC_DECL_2(VB, VB1, VB0);
+
+FUNC_GROUP_DECL(TSPRSTN, AF13);
+
+FUNC_GROUP_DECL(UFSCLKI, AC13);
+
+FUNC_GROUP_DECL(VGADDC, AD13, AE13);
+
+/* JTAG Port Selection */
+#define JTAG_PORT_PSP_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x0, 0 }
+#define JTAG_PORT_SSP_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x41, 0 }
+#define JTAG_PORT_TSP_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x42, 0 }
+#define JTAG_PORT_DDR_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x43, 0 }
+#define JTAG_PORT_USB3A_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x44, 0 }
+#define JTAG_PORT_USB3B_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x45, 0 }
+#define JTAG_PORT_PCIEA_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x46, 0 }
+#define JTAG_PORT_PCIEB_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x47, 0 }
+#define JTAG_PORT_JTAGM0_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x8, 0 }
+
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGPSP, JTAG0, JTAGPSP, JTAG_PORT_PSP_DESC);
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGSSP, JTAG0, JTAGSSP, JTAG_PORT_SSP_DESC);
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGTSP, JTAG0, JTAGTSP, JTAG_PORT_TSP_DESC);
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGDDR, JTAG0, JTAGDDR, JTAG_PORT_DDR_DESC);
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGUSB3A, JTAG0, JTAGUSB3A, JTAG_PORT_USB3A_DESC);
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGUSB3B, JTAG0, JTAGUSB3B, JTAG_PORT_USB3B_DESC);
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGPCIEA, JTAG0, JTAGPCIEA, JTAG_PORT_PCIEA_DESC);
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGPCIEB, JTAG0, JTAGPCIEB, JTAG_PORT_PCIEB_DESC);
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGM0, JTAG0, JTAGM0, JTAG_PORT_JTAGM0_DESC);
+PIN_DECL_(JTAG_PORT, SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGPSP), SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGSSP),
+ SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGTSP), SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGDDR),
+ SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGUSB3A), SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGUSB3B),
+ SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGPCIEA), SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGPCIEB),
+ SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGM0));
+
+GROUP_DECL(JTAG0, JTAG_PORT);
+
+FUNC_DECL_1(JTAGPSP, JTAG0);
+FUNC_DECL_1(JTAGSSP, JTAG0);
+FUNC_DECL_1(JTAGTSP, JTAG0);
+FUNC_DECL_1(JTAGDDR, JTAG0);
+FUNC_DECL_1(JTAGUSB3A, JTAG0);
+FUNC_DECL_1(JTAGUSB3B, JTAG0);
+FUNC_DECL_1(JTAGPCIEA, JTAG0);
+FUNC_DECL_1(JTAGPCIEB, JTAG0);
+FUNC_DECL_1(JTAGM0, JTAG0);
+
+/* PCIe Reset Control */
+SIG_EXPR_LIST_DECL_SESG(PCIERC0_PERST, PCIERC0PERST, PCIERC0PERST, SIG_DESC_SET(SCU200, 21));
+PIN_DECL_(PCIERC0_PERST, SIG_EXPR_LIST_PTR(PCIERC0_PERST, PCIERC0PERST));
+FUNC_GROUP_DECL(PCIERC0PERST, PCIERC0_PERST);
+
+SIG_EXPR_LIST_DECL_SESG(PCIERC1_PERST, PCIERC1PERST, PCIERC1PERST, SIG_DESC_SET(SCU200, 19));
+PIN_DECL_(PCIERC1_PERST, SIG_EXPR_LIST_PTR(PCIERC1_PERST, PCIERC1PERST));
+FUNC_GROUP_DECL(PCIERC1PERST, PCIERC1_PERST);
+
+#define PORTA_MODE_HPD0_DESC { ASPEED_IP_SCU, SCU410, GENMASK(25, 24), 0, 0 }
+#define PORTA_MODE_D0_DESC { ASPEED_IP_SCU, SCU410, GENMASK(25, 24), 1, 0 }
+#define PORTA_MODE_H_DESC { ASPEED_IP_SCU, SCU410, GENMASK(25, 24), 2, 0 }
+#define PORTA_MODE_HP_DESC { ASPEED_IP_SCU, SCU410, GENMASK(25, 24), 3, 0 }
+
+SIG_EXPR_LIST_DECL_SEMG(PORTA_MODE, USB2AHPD0, USB2AH, USB2AHPD0, PORTA_MODE_HPD0_DESC);
+SIG_EXPR_LIST_DECL_SEMG(PORTA_MODE, USB2AH, USB2AHAP, USB2AH, PORTA_MODE_H_DESC);
+SIG_EXPR_LIST_DECL_SEMG(PORTA_MODE, USB2AHP, USB2AHAP, USB2AHP, PORTA_MODE_HP_DESC);
+SIG_EXPR_LIST_DECL_SEMG(PORTA_MODE, USB2AD0, USB2AHAP, USB2AD0, PORTA_MODE_D0_DESC);
+PIN_DECL_(PORTA_MODE, SIG_EXPR_LIST_PTR(PORTA_MODE, USB2AHPD0),
+ SIG_EXPR_LIST_PTR(PORTA_MODE, USB2AH), SIG_EXPR_LIST_PTR(PORTA_MODE, USB2AHP),
+ SIG_EXPR_LIST_PTR(PORTA_MODE, USB2AD0));
+
+#define PORTA_U2_XHD_DESC { ASPEED_IP_SCU, SCU410, GENMASK(3, 2), 0, 0 }
+#define PORTA_U2_D1_DESC { ASPEED_IP_SCU, SCU410, GENMASK(3, 2), 1, 0 }
+#define PORTA_U2_XH_DESC { ASPEED_IP_SCU, SCU410, GENMASK(3, 2), 2, 0 }
+#define PORTA_U2_XH2E_DESC { ASPEED_IP_SCU, SCU410, GENMASK(3, 2), 3, 0 }
+
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U2, USB2AXHD1, USB2A, USB2AXHD1, PORTA_U2_XHD_DESC,
+ SIG_DESC_SET(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U2, USB2AXHPD1, USB2A, USB2AXHPD1, PORTA_U2_XHD_DESC,
+ SIG_DESC_CLEAR(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U2, USB2AXH, USB2AAP, USB2AXH, PORTA_U2_XH_DESC,
+ SIG_DESC_SET(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U2, USB2AXHP, USB2AAP, USB2AXHP, PORTA_U2_XH_DESC,
+ SIG_DESC_CLEAR(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U2, USB2AXH2B, USB2ABP, USB2AXH2B, PORTA_U2_XH2E_DESC,
+ SIG_DESC_SET(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U2, USB2AXHP2B, USB2ABP, USB2AXHP2B, PORTA_U2_XH2E_DESC,
+ SIG_DESC_CLEAR(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U2, USB2AD1, USB2ADAP, USB2AD1, PORTA_U2_D1_DESC);
+PIN_DECL_(PORTA_U2, SIG_EXPR_LIST_PTR(PORTA_U2, USB2AXHD1), SIG_EXPR_LIST_PTR(PORTA_U2, USB2AXHPD1),
+ SIG_EXPR_LIST_PTR(PORTA_U2, USB2AXH), SIG_EXPR_LIST_PTR(PORTA_U2, USB2AXHP),
+ SIG_EXPR_LIST_PTR(PORTA_U2, USB2AXH2B), SIG_EXPR_LIST_PTR(PORTA_U2, USB2AXHP2B),
+ SIG_EXPR_LIST_PTR(PORTA_U2, USB2AD1));
+
+#define PORTB_MODE_HPD0_DESC { ASPEED_IP_SCU, SCU410, GENMASK(29, 28), 0, 0 }
+#define PORTB_MODE_D0_DESC { ASPEED_IP_SCU, SCU410, GENMASK(29, 28), 1, 0 }
+#define PORTB_MODE_H_DESC { ASPEED_IP_SCU, SCU410, GENMASK(29, 28), 2, 0 }
+#define PORTB_MODE_HP_DESC { ASPEED_IP_SCU, SCU410, GENMASK(29, 28), 3, 0 }
+
+SIG_EXPR_LIST_DECL_SEMG(PORTB_MODE, USB2BHPD0, USB2BH, USB2BHPD0, PORTB_MODE_HPD0_DESC);
+SIG_EXPR_LIST_DECL_SEMG(PORTB_MODE, USB2BH, USB2BHBP, USB2BH, PORTB_MODE_H_DESC);
+SIG_EXPR_LIST_DECL_SEMG(PORTB_MODE, USB2BHP, USB2BHBP, USB2BHP, PORTB_MODE_HP_DESC);
+SIG_EXPR_LIST_DECL_SEMG(PORTB_MODE, USB2BD0, USB2BHBP, USB2BD0, PORTB_MODE_D0_DESC);
+PIN_DECL_(PORTB_MODE, SIG_EXPR_LIST_PTR(PORTB_MODE, USB2BHPD0),
+ SIG_EXPR_LIST_PTR(PORTB_MODE, USB2BH), SIG_EXPR_LIST_PTR(PORTB_MODE, USB2BHP),
+ SIG_EXPR_LIST_PTR(PORTB_MODE, USB2BD0));
+
+#define PORTB_U2_XHD_DESC { ASPEED_IP_SCU, SCU410, GENMASK(7, 6), 0, 0 }
+#define PORTB_U2_D1_DESC { ASPEED_IP_SCU, SCU410, GENMASK(7, 6), 1, 0 }
+#define PORTB_U2_XH_DESC { ASPEED_IP_SCU, SCU410, GENMASK(7, 6), 2, 0 }
+#define PORTB_U2_XH2E_DESC { ASPEED_IP_SCU, SCU410, GENMASK(7, 6), 3, 0 }
+
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U2, USB2BXHD1, USB2B, USB2BXHD1, PORTB_U2_XHD_DESC,
+ SIG_DESC_SET(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U2, USB2BXHPD1, USB2B, USB2BXHPD1, PORTB_U2_XHD_DESC,
+ SIG_DESC_CLEAR(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U2, USB2BXH, USB2BBP, USB2BXH, PORTB_U2_XH_DESC,
+ SIG_DESC_SET(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U2, USB2BXHP, USB2BBP, USB2BXHP, PORTB_U2_XH_DESC,
+ SIG_DESC_CLEAR(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U2, USB2BXH2A, USB2BAP, USB2BXH2A, PORTB_U2_XH2E_DESC,
+ SIG_DESC_SET(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U2, USB2BXHP2A, USB2BAP, USB2BXHP2A, PORTB_U2_XH2E_DESC,
+ SIG_DESC_CLEAR(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U2, USB2BD1, USB2BDBP, USB2BD1, PORTB_U2_D1_DESC);
+PIN_DECL_(PORTB_U2, SIG_EXPR_LIST_PTR(PORTB_U2, USB2BXHD1), SIG_EXPR_LIST_PTR(PORTB_U2, USB2BXHPD1),
+ SIG_EXPR_LIST_PTR(PORTB_U2, USB2BXH), SIG_EXPR_LIST_PTR(PORTB_U2, USB2BXHP),
+ SIG_EXPR_LIST_PTR(PORTB_U2, USB2BXH2A), SIG_EXPR_LIST_PTR(PORTB_U2, USB2BXHP2A),
+ SIG_EXPR_LIST_PTR(PORTB_U2, USB2BD1));
+/*
+ * USB2 virtual PHY pins.
+ *
+ * PORTA_U2_PHY and PORTB_U2_PHY are logical endpoints, not package pins.
+ * They alias existing USB2 expressions so pin groups can model direct and
+ * cross-coupled routing for host and mode paths.
+ *
+ * - USB2AAP/USB2ADAP/USB2AHAP: use PORTA_U2_PHY
+ * - USB2ABP : use PORTB_U2_PHY
+ * - USB2BBP/USB2BDBP/USB2BHBP: use PORTB_U2_PHY
+ * - USB2BAP : use PORTA_U2_PHY
+ *
+ * They do not have any registers to configure this behaviour; the goal is
+ * simply for the driver to prevent conflicting selections. For example,
+ * selecting group USB2ABP and USB2BBP at the same time should not be
+ * allowed.
+ */
+SIG_EXPR_LIST_ALIAS(PORTA_U2_PHY, USB2AXH, USB2AAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U2_PHY, USB2AXHP, USB2AAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U2_PHY, USB2BXH2A, USB2BAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U2_PHY, USB2BXHP2A, USB2BAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U2_PHY, USB2AD1, USB2ADAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U2_PHY, USB2AH, USB2AHAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U2_PHY, USB2AHP, USB2AHAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U2_PHY, USB2AD0, USB2AHAP);
+PIN_DECL_(PORTA_U2_PHY, SIG_EXPR_LIST_PTR(PORTA_U2_PHY, USB2AXH),
+ SIG_EXPR_LIST_PTR(PORTA_U2_PHY, USB2AXHP), SIG_EXPR_LIST_PTR(PORTA_U2_PHY, USB2BXH2A),
+ SIG_EXPR_LIST_PTR(PORTA_U2_PHY, USB2BXHP2A), SIG_EXPR_LIST_PTR(PORTA_U2_PHY, USB2AD1),
+ SIG_EXPR_LIST_PTR(PORTA_U2_PHY, USB2AH), SIG_EXPR_LIST_PTR(PORTA_U2_PHY, USB2AHP),
+ SIG_EXPR_LIST_PTR(PORTA_U2_PHY, USB2AD0));
+
+SIG_EXPR_LIST_ALIAS(PORTB_U2_PHY, USB2AXH2B, USB2ABP);
+SIG_EXPR_LIST_ALIAS(PORTB_U2_PHY, USB2AXHP2B, USB2ABP);
+SIG_EXPR_LIST_ALIAS(PORTB_U2_PHY, USB2BXH, USB2BBP);
+SIG_EXPR_LIST_ALIAS(PORTB_U2_PHY, USB2BXHP, USB2BBP);
+SIG_EXPR_LIST_ALIAS(PORTB_U2_PHY, USB2BD1, USB2BDBP);
+SIG_EXPR_LIST_ALIAS(PORTB_U2_PHY, USB2BH, USB2BHBP);
+SIG_EXPR_LIST_ALIAS(PORTB_U2_PHY, USB2BHP, USB2BHBP);
+SIG_EXPR_LIST_ALIAS(PORTB_U2_PHY, USB2BD0, USB2BHBP);
+PIN_DECL_(PORTB_U2_PHY, SIG_EXPR_LIST_PTR(PORTB_U2_PHY, USB2AXH2B),
+ SIG_EXPR_LIST_PTR(PORTB_U2_PHY, USB2AXHP2B), SIG_EXPR_LIST_PTR(PORTB_U2_PHY, USB2BXH),
+ SIG_EXPR_LIST_PTR(PORTB_U2_PHY, USB2BXHP), SIG_EXPR_LIST_PTR(PORTB_U2_PHY, USB2BD1),
+ SIG_EXPR_LIST_PTR(PORTB_U2_PHY, USB2BH), SIG_EXPR_LIST_PTR(PORTB_U2_PHY, USB2BHP),
+ SIG_EXPR_LIST_PTR(PORTB_U2_PHY, USB2BD0));
+
+GROUP_DECL(USB2A, PORTA_U2);
+GROUP_DECL(USB2AAP, PORTA_U2, PORTA_U2_PHY);
+GROUP_DECL(USB2ABP, PORTA_U2, PORTB_U2_PHY);
+GROUP_DECL(USB2ADAP, PORTA_U2, PORTA_U2_PHY);
+GROUP_DECL(USB2AH, PORTA_MODE);
+GROUP_DECL(USB2AHAP, PORTA_MODE, PORTA_U2_PHY);
+
+FUNC_DECL_1(USB2AXHD1, USB2A);
+FUNC_DECL_1(USB2AXHPD1, USB2A);
+FUNC_DECL_1(USB2AXH, USB2AAP);
+FUNC_DECL_1(USB2AXHP, USB2AAP);
+FUNC_DECL_1(USB2AXH2B, USB2ABP);
+FUNC_DECL_1(USB2AXHP2B, USB2ABP);
+FUNC_DECL_1(USB2AD1, USB2ADAP);
+FUNC_DECL_1(USB2AHPD0, USB2AH);
+FUNC_DECL_1(USB2AH, USB2AHAP);
+FUNC_DECL_1(USB2AHP, USB2AHAP);
+FUNC_DECL_1(USB2AD0, USB2AHAP);
+
+GROUP_DECL(USB2B, PORTB_U2);
+GROUP_DECL(USB2BBP, PORTB_U2, PORTB_U2_PHY);
+GROUP_DECL(USB2BAP, PORTB_U2, PORTA_U2_PHY);
+GROUP_DECL(USB2BDBP, PORTB_U2, PORTB_U2_PHY);
+GROUP_DECL(USB2BH, PORTB_MODE);
+GROUP_DECL(USB2BHBP, PORTB_MODE, PORTB_U2_PHY);
+
+FUNC_DECL_1(USB2BXHD1, USB2B);
+FUNC_DECL_1(USB2BXHPD1, USB2B);
+FUNC_DECL_1(USB2BXH, USB2BBP);
+FUNC_DECL_1(USB2BXHP, USB2BBP);
+FUNC_DECL_1(USB2BXH2A, USB2BAP);
+FUNC_DECL_1(USB2BXHP2A, USB2BAP);
+FUNC_DECL_1(USB2BD1, USB2BDBP);
+FUNC_DECL_1(USB2BHPD0, USB2BH);
+FUNC_DECL_1(USB2BH, USB2BHBP);
+FUNC_DECL_1(USB2BHP, USB2BHBP);
+FUNC_DECL_1(USB2BD0, USB2BHBP);
+
+#define PORTA_U3_XHD_DESC { ASPEED_IP_SCU, SCU410, GENMASK(1, 0), 0, 0 }
+#define PORTA_U3_XH_DESC { ASPEED_IP_SCU, SCU410, GENMASK(1, 0), 2, 0 }
+#define PORTA_U3_XH2E_DESC { ASPEED_IP_SCU, SCU410, GENMASK(1, 0), 3, 0 }
+
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U3, USB3AXHD, USB3A, USB3AXHD, PORTA_U3_XHD_DESC,
+ SIG_DESC_SET(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U3, USB3AXHPD, USB3A, USB3AXHPD, PORTA_U3_XHD_DESC,
+ SIG_DESC_CLEAR(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U3, USB3AXH, USB3AAP, USB3AXH, PORTA_U3_XH_DESC,
+ SIG_DESC_SET(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U3, USB3AXHP, USB3AAP, USB3AXHP, PORTA_U3_XH_DESC,
+ SIG_DESC_CLEAR(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U3, USB3AXH2B, USB3ABP, USB3AXH2B, PORTA_U3_XH2E_DESC,
+ SIG_DESC_SET(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U3, USB3AXHP2B, USB3ABP, USB3AXHP2B, PORTA_U3_XH2E_DESC,
+ SIG_DESC_CLEAR(SCU410, 9));
+PIN_DECL_(PORTA_U3, SIG_EXPR_LIST_PTR(PORTA_U3, USB3AXHD), SIG_EXPR_LIST_PTR(PORTA_U3, USB3AXHPD),
+ SIG_EXPR_LIST_PTR(PORTA_U3, USB3AXH), SIG_EXPR_LIST_PTR(PORTA_U3, USB3AXHP),
+ SIG_EXPR_LIST_PTR(PORTA_U3, USB3AXH2B), SIG_EXPR_LIST_PTR(PORTA_U3, USB3AXHP2B));
+
+#define PORTB_U3_XHD_DESC { ASPEED_IP_SCU, SCU410, GENMASK(5, 4), 0, 0 }
+#define PORTB_U3_XH_DESC { ASPEED_IP_SCU, SCU410, GENMASK(5, 4), 2, 0 }
+#define PORTB_U3_XH2E_DESC { ASPEED_IP_SCU, SCU410, GENMASK(5, 4), 3, 0 }
+
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U3, USB3BXHD, USB3B, USB3BXHD, PORTB_U3_XHD_DESC,
+ SIG_DESC_SET(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U3, USB3BXHPD, USB3B, USB3BXHPD, PORTB_U3_XHD_DESC,
+ SIG_DESC_CLEAR(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U3, USB3BXH, USB3BBP, USB3BXH, PORTB_U3_XH_DESC,
+ SIG_DESC_SET(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U3, USB3BXHP, USB3BBP, USB3BXHP, PORTB_U3_XH_DESC,
+ SIG_DESC_CLEAR(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U3, USB3BXH2A, USB3BAP, USB3BXH2A, PORTB_U3_XH2E_DESC,
+ SIG_DESC_SET(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U3, USB3BXHP2A, USB3BAP, USB3BXHP2A, PORTB_U3_XH2E_DESC,
+ SIG_DESC_CLEAR(SCU410, 10));
+PIN_DECL_(PORTB_U3, SIG_EXPR_LIST_PTR(PORTB_U3, USB3BXHD), SIG_EXPR_LIST_PTR(PORTB_U3, USB3BXHPD),
+ SIG_EXPR_LIST_PTR(PORTB_U3, USB3BXH), SIG_EXPR_LIST_PTR(PORTB_U3, USB3BXHP),
+ SIG_EXPR_LIST_PTR(PORTB_U3, USB3BXH2A), SIG_EXPR_LIST_PTR(PORTB_U3, USB3BXHP2A));
+
+/*
+ * USB3 virtual PHY pins.
+ *
+ * PORTA_U3_PHY and PORTB_U3_PHY are logical endpoints, not package pins.
+ * They alias existing USB3 expressions so pin groups can model both direct and
+ * cross-coupled routing to PHY A/B.
+ *
+ * - USB3AAP: PORTA_U3 + PORTA_U3_PHY (A -> PHY A)
+ * - USB3ABP: PORTA_U3 + PORTB_U3_PHY (A -> PHY B)
+ * - USB3BBP: PORTB_U3 + PORTB_U3_PHY (B -> PHY B)
+ * - USB3BAP: PORTB_U3 + PORTA_U3_PHY (B -> PHY A)
+ *
+ * They do not have any registers to configure this behavior; the goal is
+ * simply for the driver to prevent conflicting selections. For example,
+ * selecting group USB3ABP and USB3BBP at the same time should not be
+ * allowed.
+ */
+SIG_EXPR_LIST_ALIAS(PORTA_U3_PHY, USB3AXH, USB3AAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U3_PHY, USB3AXHP, USB3AAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U3_PHY, USB3BXH2A, USB3BAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U3_PHY, USB3BXHP2A, USB3BAP);
+PIN_DECL_(PORTA_U3_PHY, SIG_EXPR_LIST_PTR(PORTA_U3_PHY, USB3AXH),
+ SIG_EXPR_LIST_PTR(PORTA_U3_PHY, USB3AXHP), SIG_EXPR_LIST_PTR(PORTA_U3_PHY, USB3BXH2A),
+ SIG_EXPR_LIST_PTR(PORTA_U3_PHY, USB3BXHP2A));
+
+SIG_EXPR_LIST_ALIAS(PORTB_U3_PHY, USB3AXH2B, USB3ABP);
+SIG_EXPR_LIST_ALIAS(PORTB_U3_PHY, USB3AXHP2B, USB3ABP);
+SIG_EXPR_LIST_ALIAS(PORTB_U3_PHY, USB3BXH, USB3BBP);
+SIG_EXPR_LIST_ALIAS(PORTB_U3_PHY, USB3BXHP, USB3BBP);
+PIN_DECL_(PORTB_U3_PHY, SIG_EXPR_LIST_PTR(PORTB_U3_PHY, USB3AXH2B),
+ SIG_EXPR_LIST_PTR(PORTB_U3_PHY, USB3AXHP2B), SIG_EXPR_LIST_PTR(PORTB_U3_PHY, USB3BXH),
+ SIG_EXPR_LIST_PTR(PORTB_U3_PHY, USB3BXHP));
+
+/* USB3A xHCI to vHUB */
+GROUP_DECL(USB3A, PORTA_U3);
+/* USB3A xHCI to USB3A PHY */
+GROUP_DECL(USB3AAP, PORTA_U3, PORTA_U3_PHY);
+/* USB3A xHCI to USB3B PHY */
+GROUP_DECL(USB3ABP, PORTA_U3, PORTB_U3_PHY);
+
+FUNC_DECL_1(USB3AXHD, USB3A);
+FUNC_DECL_1(USB3AXHPD, USB3A);
+FUNC_DECL_1(USB3AXH, USB3AAP);
+FUNC_DECL_1(USB3AXHP, USB3AAP);
+FUNC_DECL_1(USB3AXH2B, USB3ABP);
+FUNC_DECL_1(USB3AXHP2B, USB3ABP);
+
+/* USB3B xHCI to vHUB */
+GROUP_DECL(USB3B, PORTB_U3);
+/* USB3B xHCI to USB3A PHY */
+GROUP_DECL(USB3BAP, PORTB_U3, PORTA_U3_PHY);
+/* USB3B xHCI to USB3B PHY */
+GROUP_DECL(USB3BBP, PORTB_U3, PORTB_U3_PHY);
+
+FUNC_DECL_1(USB3BXHD, USB3B);
+FUNC_DECL_1(USB3BXHPD, USB3B);
+FUNC_DECL_1(USB3BXH, USB3BBP);
+FUNC_DECL_1(USB3BXHP, USB3BBP);
+FUNC_DECL_1(USB3BXH2A, USB3BAP);
+FUNC_DECL_1(USB3BXHP2A, USB3BAP);
+
+static const struct pinctrl_pin_desc aspeed_g7_soc0_pins[] = {
+ ASPEED_PINCTRL_PIN(AC14),
+ ASPEED_PINCTRL_PIN(AE15),
+ ASPEED_PINCTRL_PIN(AD14),
+ ASPEED_PINCTRL_PIN(AE14),
+ ASPEED_PINCTRL_PIN(AF14),
+ ASPEED_PINCTRL_PIN(AB13),
+ ASPEED_PINCTRL_PIN(AB14),
+ ASPEED_PINCTRL_PIN(AF15),
+ ASPEED_PINCTRL_PIN(AF13),
+ ASPEED_PINCTRL_PIN(AC13),
+ ASPEED_PINCTRL_PIN(AD13),
+ ASPEED_PINCTRL_PIN(AE13),
+ ASPEED_PINCTRL_PIN(JTAG_PORT),
+ ASPEED_PINCTRL_PIN(PCIERC0_PERST),
+ ASPEED_PINCTRL_PIN(PCIERC1_PERST),
+ ASPEED_PINCTRL_PIN(PORTA_MODE),
+ ASPEED_PINCTRL_PIN(PORTA_U2),
+ ASPEED_PINCTRL_PIN(PORTA_U3),
+ ASPEED_PINCTRL_PIN(PORTA_U2_PHY),
+ ASPEED_PINCTRL_PIN(PORTA_U3_PHY),
+ ASPEED_PINCTRL_PIN(PORTB_MODE),
+ ASPEED_PINCTRL_PIN(PORTB_U2),
+ ASPEED_PINCTRL_PIN(PORTB_U3),
+ ASPEED_PINCTRL_PIN(PORTB_U2_PHY),
+ ASPEED_PINCTRL_PIN(PORTB_U3_PHY),
+};
+
+static const struct aspeed_pin_group aspeed_g7_soc0_groups[] = {
+ ASPEED_PINCTRL_GROUP(EMMCCDN),
+ ASPEED_PINCTRL_GROUP(EMMCG1),
+ ASPEED_PINCTRL_GROUP(EMMCG4),
+ ASPEED_PINCTRL_GROUP(EMMCG8),
+ ASPEED_PINCTRL_GROUP(EMMCWPN),
+ ASPEED_PINCTRL_GROUP(TSPRSTN),
+ ASPEED_PINCTRL_GROUP(UFSCLKI),
+ ASPEED_PINCTRL_GROUP(VB0),
+ ASPEED_PINCTRL_GROUP(VB1),
+ ASPEED_PINCTRL_GROUP(VGADDC),
+ /* JTAG groups */
+ ASPEED_PINCTRL_GROUP(JTAG0),
+ /* PCIE RC groups */
+ ASPEED_PINCTRL_GROUP(PCIERC0PERST),
+ ASPEED_PINCTRL_GROUP(PCIERC1PERST),
+ /* USB3A groups */
+ ASPEED_PINCTRL_GROUP(USB3A),
+ ASPEED_PINCTRL_GROUP(USB3AAP),
+ ASPEED_PINCTRL_GROUP(USB3ABP),
+ /* USB3B groups */
+ ASPEED_PINCTRL_GROUP(USB3B),
+ ASPEED_PINCTRL_GROUP(USB3BAP),
+ ASPEED_PINCTRL_GROUP(USB3BBP),
+ /* USB2A groups */
+ ASPEED_PINCTRL_GROUP(USB2A),
+ ASPEED_PINCTRL_GROUP(USB2AAP),
+ ASPEED_PINCTRL_GROUP(USB2ABP),
+ ASPEED_PINCTRL_GROUP(USB2ADAP),
+ ASPEED_PINCTRL_GROUP(USB2AH),
+ ASPEED_PINCTRL_GROUP(USB2AHAP),
+ /* USB2B groups */
+ ASPEED_PINCTRL_GROUP(USB2B),
+ ASPEED_PINCTRL_GROUP(USB2BAP),
+ ASPEED_PINCTRL_GROUP(USB2BBP),
+ ASPEED_PINCTRL_GROUP(USB2BDBP),
+ ASPEED_PINCTRL_GROUP(USB2BH),
+ ASPEED_PINCTRL_GROUP(USB2BHBP),
+};
+
+static const struct aspeed_pin_function aspeed_g7_soc0_functions[] = {
+ ASPEED_PINCTRL_FUNC(EMMC),
+ ASPEED_PINCTRL_FUNC(TSPRSTN),
+ ASPEED_PINCTRL_FUNC(UFSCLKI),
+ ASPEED_PINCTRL_FUNC(VB),
+ ASPEED_PINCTRL_FUNC(VGADDC),
+ /* JTAG functions */
+ ASPEED_PINCTRL_FUNC(JTAGDDR),
+ ASPEED_PINCTRL_FUNC(JTAGM0),
+ ASPEED_PINCTRL_FUNC(JTAGPCIEA),
+ ASPEED_PINCTRL_FUNC(JTAGPCIEB),
+ ASPEED_PINCTRL_FUNC(JTAGPSP),
+ ASPEED_PINCTRL_FUNC(JTAGSSP),
+ ASPEED_PINCTRL_FUNC(JTAGTSP),
+ ASPEED_PINCTRL_FUNC(JTAGUSB3A),
+ ASPEED_PINCTRL_FUNC(JTAGUSB3B),
+ /* PCIE RC functions */
+ ASPEED_PINCTRL_FUNC(PCIERC0PERST),
+ ASPEED_PINCTRL_FUNC(PCIERC1PERST),
+ /* USB3A functions */
+ ASPEED_PINCTRL_FUNC(USB3AXH),
+ ASPEED_PINCTRL_FUNC(USB3AXH2B),
+ ASPEED_PINCTRL_FUNC(USB3AXHD),
+ ASPEED_PINCTRL_FUNC(USB3AXHP),
+ ASPEED_PINCTRL_FUNC(USB3AXHP2B),
+ ASPEED_PINCTRL_FUNC(USB3AXHPD),
+ /* USB3B functions */
+ ASPEED_PINCTRL_FUNC(USB3BXH),
+ ASPEED_PINCTRL_FUNC(USB3BXH2A),
+ ASPEED_PINCTRL_FUNC(USB3BXHD),
+ ASPEED_PINCTRL_FUNC(USB3BXHP),
+ ASPEED_PINCTRL_FUNC(USB3BXHP2A),
+ ASPEED_PINCTRL_FUNC(USB3BXHPD),
+ /* USB2A functions */
+ ASPEED_PINCTRL_FUNC(USB2AD0),
+ ASPEED_PINCTRL_FUNC(USB2AD1),
+ ASPEED_PINCTRL_FUNC(USB2AH),
+ ASPEED_PINCTRL_FUNC(USB2AHP),
+ ASPEED_PINCTRL_FUNC(USB2AHPD0),
+ ASPEED_PINCTRL_FUNC(USB2AXH),
+ ASPEED_PINCTRL_FUNC(USB2AXH2B),
+ ASPEED_PINCTRL_FUNC(USB2AXHD1),
+ ASPEED_PINCTRL_FUNC(USB2AXHP),
+ ASPEED_PINCTRL_FUNC(USB2AXHP2B),
+ ASPEED_PINCTRL_FUNC(USB2AXHPD1),
+ /* USB2B functions */
+ ASPEED_PINCTRL_FUNC(USB2BD0),
+ ASPEED_PINCTRL_FUNC(USB2BD1),
+ ASPEED_PINCTRL_FUNC(USB2BH),
+ ASPEED_PINCTRL_FUNC(USB2BHP),
+ ASPEED_PINCTRL_FUNC(USB2BHPD0),
+ ASPEED_PINCTRL_FUNC(USB2BXH),
+ ASPEED_PINCTRL_FUNC(USB2BXH2A),
+ ASPEED_PINCTRL_FUNC(USB2BXHD1),
+ ASPEED_PINCTRL_FUNC(USB2BXHP),
+ ASPEED_PINCTRL_FUNC(USB2BXHP2A),
+ ASPEED_PINCTRL_FUNC(USB2BXHPD1),
+};
+
+static const struct pinmux_ops aspeed_g7_soc0_pinmux_ops = {
+ .get_functions_count = aspeed_pinmux_get_fn_count,
+ .get_function_name = aspeed_pinmux_get_fn_name,
+ .get_function_groups = aspeed_pinmux_get_fn_groups,
+ .set_mux = aspeed_pinmux_set_mux,
+ .gpio_request_enable = aspeed_gpio_request_enable,
+ .strict = true,
+};
+
+static const struct pinctrl_ops aspeed_g7_soc0_pinctrl_ops = {
+ .get_groups_count = aspeed_pinctrl_get_groups_count,
+ .get_group_name = aspeed_pinctrl_get_group_name,
+ .get_group_pins = aspeed_pinctrl_get_group_pins,
+ .pin_dbg_show = aspeed_pinctrl_pin_dbg_show,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+ .dt_free_map = pinctrl_utils_free_map,
+};
+
+static const struct pinconf_ops aspeed_g7_soc0_pinconf_ops = {
+ .is_generic = true,
+ .pin_config_get = aspeed_pin_config_get,
+ .pin_config_set = aspeed_pin_config_set,
+ .pin_config_group_get = aspeed_pin_config_group_get,
+ .pin_config_group_set = aspeed_pin_config_group_set,
+};
+
+/* pinctrl_desc */
+static const struct pinctrl_desc aspeed_g7_soc0_pinctrl_desc = {
+ .name = "aspeed-g7-soc0-pinctrl",
+ .pins = aspeed_g7_soc0_pins,
+ .npins = ARRAY_SIZE(aspeed_g7_soc0_pins),
+ .pctlops = &aspeed_g7_soc0_pinctrl_ops,
+ .pmxops = &aspeed_g7_soc0_pinmux_ops,
+ .confops = &aspeed_g7_soc0_pinconf_ops,
+};
+
+static const struct aspeed_pin_config aspeed_g7_soc0_configs[] = {
+ /* GPIO18A */
+ { PIN_CONFIG_DRIVE_STRENGTH, { AC14, AC14 }, SCU480, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AC14, AC14 }, SCU480, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AC14, AC14 }, SCU480, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AC14, AC14 }, SCU480, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AE15, AE15 }, SCU484, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AE15, AE15 }, SCU484, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AE15, AE15 }, SCU484, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AE15, AE15 }, SCU484, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AD14, AD14 }, SCU488, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AD14, AD14 }, SCU488, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AD14, AD14 }, SCU488, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AD14, AD14 }, SCU488, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AE14, AE14 }, SCU48C, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AE14, AE14 }, SCU48C, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AE14, AE14 }, SCU48C, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AE14, AE14 }, SCU48C, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AF14, AF14 }, SCU490, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AF14, AF14 }, SCU490, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AF14, AF14 }, SCU490, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AF14, AF14 }, SCU490, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AB13, AB13 }, SCU494, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AB13, AB13 }, SCU494, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AB13, AB13 }, SCU494, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AB13, AB13 }, SCU494, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AB14, AB14 }, SCU498, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AB14, AB14 }, SCU498, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AB14, AB14 }, SCU498, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AB14, AB14 }, SCU498, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AF15, AF15 }, SCU49C, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AF15, AF15 }, SCU49C, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AF15, AF15 }, SCU49C, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AF15, AF15 }, SCU49C, BIT(5) },
+ /* GPIO18B */
+ { PIN_CONFIG_DRIVE_STRENGTH, { AF13, AF13 }, SCU4A0, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AF13, AF13 }, SCU4A0, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AF13, AF13 }, SCU4A0, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AF13, AF13 }, SCU4A0, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AC13, AC13 }, SCU4A4, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AC13, AC13 }, SCU4A4, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AC13, AC13 }, SCU4A4, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AC13, AC13 }, SCU4A4, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AD13, AD13 }, SCU4A8, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AD13, AD13 }, SCU4A8, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AD13, AD13 }, SCU4A8, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AD13, AD13 }, SCU4A8, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AE13, AE13 }, SCU4AC, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AE13, AE13 }, SCU4AC, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AE13, AE13 }, SCU4AC, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AE13, AE13 }, SCU4AC, BIT(5) },
+};
+
+static const struct aspeed_pin_config_map aspeed_g7_soc0_pin_config_map[] = {
+ { PIN_CONFIG_BIAS_PULL_DOWN, -1, 2, GENMASK(1, 0) },
+ { PIN_CONFIG_BIAS_PULL_UP, -1, 3, GENMASK(1, 0) },
+ { PIN_CONFIG_BIAS_DISABLE, -1, 0, BIT_MASK(0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 3, 0, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 6, 1, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 8, 2, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 11, 3, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 16, 4, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 18, 5, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 20, 6, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 23, 7, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 30, 8, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 32, 9, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 33, 10, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 35, 11, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 37, 12, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 38, 13, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 39, 14, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 41, 15, GENMASK(3, 0) },
+
+};
+
+static int aspeed_g7_soc0_sig_expr_set(struct aspeed_pinmux_data *ctx,
+ const struct aspeed_sig_expr *expr, bool enable)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i < expr->ndescs; i++) {
+ const struct aspeed_sig_desc *desc = &expr->descs[i];
+ u32 pattern = enable ? desc->enable : desc->disable;
+ u32 val = (pattern << __ffs(desc->mask));
+
+ if (!ctx->maps[desc->ip])
+ return -ENODEV;
+
+ WARN_ON_ONCE(desc->ip != ASPEED_IP_SCU);
+
+ ret = regmap_update_bits(ctx->maps[desc->ip], desc->reg,
+ desc->mask, val);
+ if (ret)
+ return ret;
+ }
+
+ ret = aspeed_sig_expr_eval(ctx, expr, enable);
+ if (ret < 0)
+ return ret;
+
+ return ret ? 0 : -EPERM;
+}
+
+static const struct aspeed_pinmux_ops aspeed_g7_soc0_ops = {
+ .set = aspeed_g7_soc0_sig_expr_set,
+};
+
+static struct aspeed_pinctrl_data aspeed_g7_soc0_pinctrl_data = {
+ .pins = aspeed_g7_soc0_pins,
+ .npins = ARRAY_SIZE(aspeed_g7_soc0_pins),
+ .pinmux = {
+ .ops = &aspeed_g7_soc0_ops,
+ .groups = aspeed_g7_soc0_groups,
+ .ngroups = ARRAY_SIZE(aspeed_g7_soc0_groups),
+ .functions = aspeed_g7_soc0_functions,
+ .nfunctions = ARRAY_SIZE(aspeed_g7_soc0_functions),
+ },
+ .configs = aspeed_g7_soc0_configs,
+ .nconfigs = ARRAY_SIZE(aspeed_g7_soc0_configs),
+ .confmaps = aspeed_g7_soc0_pin_config_map,
+ .nconfmaps = ARRAY_SIZE(aspeed_g7_soc0_pin_config_map),
+};
+
+static int aspeed_g7_soc0_pinctrl_probe(struct platform_device *pdev)
+{
+ return aspeed_pinctrl_probe(pdev, &aspeed_g7_soc0_pinctrl_desc,
+ &aspeed_g7_soc0_pinctrl_data);
+}
+
+static const struct of_device_id aspeed_g7_soc0_pinctrl_match[] = {
+ { .compatible = "aspeed,ast2700-soc0-pinctrl" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, aspeed_g7_soc0_pinctrl_match);
+
+static struct platform_driver aspeed_g7_soc0_pinctrl_driver = {
+ .probe = aspeed_g7_soc0_pinctrl_probe,
+ .driver = {
+ .name = "aspeed-g7-soc0-pinctrl",
+ .of_match_table = aspeed_g7_soc0_pinctrl_match,
+ .suppress_bind_attrs = true,
+ },
+};
+
+static int __init aspeed_g7_soc0_pinctrl_init(void)
+{
+ return platform_driver_register(&aspeed_g7_soc0_pinctrl_driver);
+}
+arch_initcall(aspeed_g7_soc0_pinctrl_init);
--
2.34.1
^ permalink raw reply related
* Re: [PATCH RFC] ACPI: processor: idle: Do not propagate acpi_processor_ffh_lpi_probe() -ENODEV
From: lihuisong (C) @ 2026-04-14 9:43 UTC (permalink / raw)
To: Breno Leitao, Rafael J. Wysocki, Len Brown, lpieralisi,
catalin.marinas, will
Cc: Rafael J. Wysocki, linux-acpi, linux-kernel, pjaroszynski,
guohanjun, sudeep.holla, linux-arm-kernel, rmikey, kernel-team,
lihuisong
In-Reply-To: <20260413-ffh-v1-1-301704f69e2f@debian.org>
On 4/14/2026 12:54 AM, Breno Leitao wrote:
> Commit cac173bea57d ("ACPI: processor: idle: Rework the handling of
> acpi_processor_ffh_lpi_probe()") moved the acpi_processor_ffh_lpi_probe()
> call from acpi_processor_setup_cpuidle_dev(), where its return value was
> ignored, to acpi_processor_get_power_info(), where it is treated as a
> hard failure. This causes cpuidle setup to fail entirely for all CPUs on
> platforms where the FFH LPI probe returns an error.
>
> On NVIDIA Grace (aarch64) systems with PSCIv1.1, the probe fails for all
> 72 CPUs with -ENODEV because psci_acpi_cpu_init_idle() finds
> power.count - 1 <= 0 (power.count=1). This results in no cpuidle states
> registered for any CPU, forcing them to busy-poll when idle instead of
> entering low-power states.
>
>
Sorry for bring you cpuidle issues on your platform.
IIUC, your platfom just has one LPI states on failure, it should be WFI,
right?
This failure will only cause the cpuidle directory for each CPU not to
be created, but will not affect the CPU entering the WFI state which
done by cpuidle core.
But it is a real issue. Thanks for your report.
I think the best way to fix your issue is that remove this verification
in psci_acpi_cpu_init_idle().
Because it is legal for platform to report one LPI state.
This function just needs to verify the LPI states which are FFH.
/Huisong
>
>
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: reset: imx8mq: Add _N suffix to IMX8MQ_RESET_MIPI_CSI*_RESET
From: Robby Cai @ 2026-04-14 9:55 UTC (permalink / raw)
To: Philipp Zabel
Cc: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, festevam, devicetree,
kernel, imx, linux-arm-kernel, linux-kernel, aisheng.dong
In-Reply-To: <d6cdea5f1a4f2eb3f7b73e6136c77020f444d8f0.camel@pengutronix.de>
On Tue, Mar 31, 2026 at 02:45:07PM +0200, Philipp Zabel wrote:
> On Di, 2026-03-31 at 18:13 +0800, Robby Cai wrote:
> > The assert logic of the MIPI CSI reset signals is active-low on i.MX8MQ,
> > but the existing names do not indicate this explicitly. To improve
> > consistency and clarity, append the _N suffix to all
> > IMX8MQ_RESET_MIPI_CSI*_RESET definitions. The deprecated
> > IMX8MQ_RESET_MIPI_CSI*_RESET versions remain temporarily for DT ABI
> > compatibility and will be removed at an appropriate time in the future.
>
> The register description in the latest reference manual I can download,
> IMX8MDQLQRM Rev. 3.1 (06/2021), still call these bits
> MIPI_CSI1_CORE_RESET and so on (without _N). There is no mention of
> polarity in the bitfield description. Is a documentation update
> planned?
Yes. A documentation update is already planned to clarify the reset polarity
(active-low) and naming. The current RM description is incomplete and will be
corrected in a future revision.
>
> Right now I'd say this improves clarity, but reduces consistency with
> existing documentation.
>
> Are these bits self-clearing, or can the reset be asserted by writing
> 0? As it stands, the CSI driver using these resets, imx8mq-mipi-csi2.c,
> only calls reset_control_assert() in imx8mq_mipi_csi_sw_reset():
>
> /*
> * these are most likely self-clearing reset bits. to make it
> * more clear, the reset-imx7 driver should implement the
> * .reset() operation.
> */
> ret = reset_control_assert(state->rst);
>
> This will probably have to be turned into a deassert together with the
> reset driver change.
No, these reset bits are not self-clearing.
According to the design team, the MIPI CSI reset logic on i.MX8MQ is identical
to MIPI DSI: the reset is active-low and must be explicitly deasserted.
Writing ��0�� asserts reset and it will remain asserted until cleared by software.
The current assumption in the CSI driver that these bits are self-clearing is
therefore incorrect. This was exposed by the landing patch [1].
To fix this properly, the reset-imx7 driver needs to reflect the correct polarity,
and the CSI driver should use deassert instead of only calling
reset_control_assert(). The RM will also be updated to clarify this behavior.
[1] https://git.linuxtv.org/media.git/commit/?id=6d79bb8fd2aa25afccbd6aeec2821722fa0b5db5
Regards,
Robby
^ permalink raw reply
* Re: [PATCH 1/3] iio: adc: xilinx-ams: fix out-of-bounds channel lookup in event handling
From: Andy Shevchenko @ 2026-04-14 9:58 UTC (permalink / raw)
To: Guilherme Ivo Bozi
Cc: Salih Erim, Conall O'Griofa, Jonathan Cameron, Michal Simek,
David Lechner, Nuno Sá, Andy Shevchenko, linux-iio,
linux-arm-kernel, linux-kernel
In-Reply-To: <20260414093018.7153-2-guilherme.bozi@usp.br>
On Tue, Apr 14, 2026 at 06:29:28AM -0300, Guilherme Ivo Bozi wrote:
> ams_event_to_channel() may return a pointer past the end of
> dev->channels when no matching scan_index is found. This can lead
> to invalid memory access in ams_handle_event().
>
> Add a bounds check in ams_event_to_channel() and return NULL when
> no channel is found. Also guard the caller to safely handle this
> case.
> Fixes: <d5c70627a79455154f5f636096abe6fe57510605>
Incorrect format of the Fixes tag. Please, consult with Submitting Patches
documentation on that matter.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH 2/3] iio: adc: xilinx-ams: use guard(mutex) for automatic locking
From: Andy Shevchenko @ 2026-04-14 9:59 UTC (permalink / raw)
To: Guilherme Ivo Bozi
Cc: Salih Erim, Conall O'Griofa, Jonathan Cameron, Michal Simek,
David Lechner, Nuno Sá, Andy Shevchenko, linux-iio,
linux-arm-kernel, linux-kernel
In-Reply-To: <20260414093018.7153-3-guilherme.bozi@usp.br>
On Tue, Apr 14, 2026 at 06:29:29AM -0300, Guilherme Ivo Bozi wrote:
> Replace open-coded mutex_lock()/mutex_unlock() pairs with
> guard(mutex) to simplify locking and ensure proper unlock on
> all control flow paths.
>
> This removes explicit unlock handling, reduces boilerplate,
> and avoids potential mistakes in error paths while keeping
> the behavior unchanged.
OK.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* [PATCH] KVM: arm64: Re-allow hyp tracing HVCs for [nh]VHE
From: Vincent Donnefort @ 2026-04-14 10:02 UTC (permalink / raw)
To: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will
Cc: linux-arm-kernel, kvmarm, kernel-team, Vincent Donnefort
The introduction of __KVM_HOST_SMCCC_FUNC_MAX_NO_PKVM excluded hyp
tracing HVCs from the common [nh]VHE/pKVM list. Re-allow them.
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 37414440cee7..11dcdf434971 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -72,6 +72,14 @@ enum __kvm_host_smccc_func {
__KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid_range,
__KVM_HOST_SMCCC_FUNC___kvm_flush_cpu_context,
__KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff,
+ __KVM_HOST_SMCCC_FUNC___tracing_load,
+ __KVM_HOST_SMCCC_FUNC___tracing_unload,
+ __KVM_HOST_SMCCC_FUNC___tracing_enable,
+ __KVM_HOST_SMCCC_FUNC___tracing_swap_reader,
+ __KVM_HOST_SMCCC_FUNC___tracing_update_clock,
+ __KVM_HOST_SMCCC_FUNC___tracing_reset,
+ __KVM_HOST_SMCCC_FUNC___tracing_enable_event,
+ __KVM_HOST_SMCCC_FUNC___tracing_write_event,
__KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs,
__KVM_HOST_SMCCC_FUNC___vgic_v3_restore_vmcr_aprs,
__KVM_HOST_SMCCC_FUNC___vgic_v5_save_apr,
@@ -100,14 +108,6 @@ enum __kvm_host_smccc_func {
__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load,
__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put,
__KVM_HOST_SMCCC_FUNC___pkvm_tlb_flush_vmid,
- __KVM_HOST_SMCCC_FUNC___tracing_load,
- __KVM_HOST_SMCCC_FUNC___tracing_unload,
- __KVM_HOST_SMCCC_FUNC___tracing_enable,
- __KVM_HOST_SMCCC_FUNC___tracing_swap_reader,
- __KVM_HOST_SMCCC_FUNC___tracing_update_clock,
- __KVM_HOST_SMCCC_FUNC___tracing_reset,
- __KVM_HOST_SMCCC_FUNC___tracing_enable_event,
- __KVM_HOST_SMCCC_FUNC___tracing_write_event,
};
#define DECLARE_KVM_VHE_SYM(sym) extern char sym[]
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 73f2e0221e70..8f7582d57ab5 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -709,6 +709,14 @@ static const hcall_t host_hcall[] = {
HANDLE_FUNC(__kvm_tlb_flush_vmid_range),
HANDLE_FUNC(__kvm_flush_cpu_context),
HANDLE_FUNC(__kvm_timer_set_cntvoff),
+ HANDLE_FUNC(__tracing_load),
+ HANDLE_FUNC(__tracing_unload),
+ HANDLE_FUNC(__tracing_enable),
+ HANDLE_FUNC(__tracing_swap_reader),
+ HANDLE_FUNC(__tracing_update_clock),
+ HANDLE_FUNC(__tracing_reset),
+ HANDLE_FUNC(__tracing_enable_event),
+ HANDLE_FUNC(__tracing_write_event),
HANDLE_FUNC(__vgic_v3_save_aprs),
HANDLE_FUNC(__vgic_v3_restore_vmcr_aprs),
HANDLE_FUNC(__vgic_v5_save_apr),
@@ -735,14 +743,6 @@ static const hcall_t host_hcall[] = {
HANDLE_FUNC(__pkvm_vcpu_load),
HANDLE_FUNC(__pkvm_vcpu_put),
HANDLE_FUNC(__pkvm_tlb_flush_vmid),
- HANDLE_FUNC(__tracing_load),
- HANDLE_FUNC(__tracing_unload),
- HANDLE_FUNC(__tracing_enable),
- HANDLE_FUNC(__tracing_swap_reader),
- HANDLE_FUNC(__tracing_update_clock),
- HANDLE_FUNC(__tracing_reset),
- HANDLE_FUNC(__tracing_enable_event),
- HANDLE_FUNC(__tracing_write_event),
};
static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
base-commit: 94b4ae79ebb42a8a6f2124b4d4b033b15a98e4f9
--
2.54.0.rc0.605.g598a273b03-goog
^ permalink raw reply related
* Re: [PATCH 3/3] iio: adc: xilinx-ams: refactor alarm mapping to table-driven approach
From: Andy Shevchenko @ 2026-04-14 10:04 UTC (permalink / raw)
To: Guilherme Ivo Bozi
Cc: Salih Erim, Conall O'Griofa, Jonathan Cameron, Michal Simek,
David Lechner, Nuno Sá, Andy Shevchenko, linux-iio,
linux-arm-kernel, linux-kernel
In-Reply-To: <20260414093018.7153-4-guilherme.bozi@usp.br>
On Tue, Apr 14, 2026 at 06:29:30AM -0300, Guilherme Ivo Bozi wrote:
> Replace multiple open-coded switch statements that map between
> scan_index, alarm bits, and register offsets with a centralized
> table-driven approach.
>
> Introduce a struct-based alarm_map to describe the relationship
> between scan indices and alarm offsets, and add a helper to
> translate scan_index to event IDs. This removes duplicated logic
> across ams_get_alarm_offset(), ams_event_to_channel(), and
> ams_get_alarm_mask().
>
> The new approach improves maintainability, reduces code size,
> and makes it easier to extend or modify alarm mappings in the
> future, while preserving existing behavior.
...
> +#define AMS_ALARM_INVALID -1
This value sounds like out of the range, also signed.
Can't 0x000 be used instead?
#define AMS_ALARM_NONE 0x000 /* not a real offset */
> #define AMS_ALARM_TEMP 0x140
> #define AMS_ALARM_SUPPLY1 0x144
> #define AMS_ALARM_SUPPLY2 0x148
...
> +struct ams_alarm_map {
> + enum ams_ps_pl_seq scan_index;
> + int base_offset;
With the above we put this as u32 (or whatever is used for offsets).
> +};
...
> +static int ams_scan_index_to_event(int scan_index)
> +{
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(alarm_map); i++) {
for (unsigned int i = 0; i < ARRAY_SIZE(alarm_map); i++) {
> + if (alarm_map[i].base_offset == AMS_ALARM_INVALID)
> + continue;
> +
> + if (alarm_map[i].scan_index == scan_index)
> + return i;
> + }
> +
> + return -EINVAL;
> +}
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH 0/3] arm64/virt: Add Arm CCA measurement register support
From: Suzuki K Poulose @ 2026-04-14 10:10 UTC (permalink / raw)
To: Jason Gunthorpe, Sami Mujawar, Dan Williams
Cc: linux-arm-kernel, linux-kernel, catalin.marinas, will, thuth,
steven.price, gshan, YeoReum.Yun, cedric.xing, Dan Williams,
Dionna Glaze, Aneesh Kumar K . V, Alexey Kardashevskiy,
linux-coco@lists.linux.dev
In-Reply-To: <20260413125925.GK3694781@ziepe.ca>
Cc: Dan, Cedric, Dionna, Aneesh, Alexey. linux-coco
Hi Jason,
On 13/04/2026 13:59, Jason Gunthorpe wrote:
> On Mon, Apr 13, 2026 at 09:49:54AM +0100, Sami Mujawar wrote:
>> This series adds support for Arm Confidential Compute Architecture (CCA)
>> measurement registers in the Linux kernel, enabling guest Realms to
>> access, extend, and expose measurement values for attestation and runtime
>> integrity tracking.
>>
>> The Realm Management Monitor (RMM) defines a set of measurement registers
>> consisting of a Realm Initial Measurement (RIM) and a number of Realm
>> Extensible Measurements (REMs). This series introduces the necessary
>> infrastructure to interact with these registers via the RSI interface
>> and exposes them to userspace through the TSM measurement framework.
>>
>> At a high level, the series includes:
>> - Helper interfaces for reading and extending measurement
>> registers via RSI
>> - Definitions for Realm hash algorithms as defined by the
>> RMM specification
>> - Integration with the TSM measurement subsystem and sysfs
>> exposure for userspace visibility and interaction
>>
>> After applying this series, measurement registers are exposed under:
>> /sys/devices/virtual/misc/arm_cca_guest/measurements/
>
> I'm surprised we get some random sysfs files? How does some more
> generic userspace figure out to use this vs a TPM or some other
> platform's version of it?
That is true. This is the infrastructure for exposing Runtime
Measurement registers (R/W) for use by the OS, complementing the
TSM_REPORTS (Read Only Platform measurements+Attestation Reports, e.g.
on CCA Attestation Report from RMM). Unlike the TSM reports,
this doesn't have a generic interface for userspace.
> I also think exposing PCRs as was done for TPM in sysfs was something
> of a mistake.. Allowing extension without logging is too low level and
> is very hard to build an entire attestation system around.
>
> I really think we are missing a subsystem here, TPM has sort of been
> filling this role in a non-generic way, but we should have a
> common uAPI for platform measurement & attestation:
Agreed, such a subsystem would solve the below.
> - Discover available measurements
> - Report signed measurements, with ingesting a nonce
> - Report measurement logs
> - Extend measurements and udpate logs
> - Report certificates used in signing
> - General reporting of various kinds of attestation evidence
>
> And it would be nice for the PCI devices and others to plug into the
> general framework as well instead of building a parallel TSM framework
> for handling evidence.
That makes sense and AFAIU, there are efforts in progress to expose
the Device measurements+Certificates in a different form. May be a good
idea to intervene early enough to see if we can find a common ground.
>
> Isn't this also sort of incomplete? Doesn't anything serious need
> signed measurements? Isnt't there alot more data that comes out of RMM
> than just a few measurement registers?
As mentioned above, this series adds the support for Runtime Extendible
Measurements (REM in CCA, RTMR on TDX). The RIM+Platform Attestation is
already provided via the TSM_REPORT
Kind regards
Suzuki
>
> Jason
^ permalink raw reply
* Re: [PATCH v2] arm64: panic from init_IRQ if IRQ handler stacks cannot be allocated
From: Osama Abdelkader @ 2026-04-14 10:14 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Ard Biesheuvel, Ryo Takakura,
Breno Leitao, Mark Rutland, linux-arm-kernel, linux-kernel
In-Reply-To: <20260326225755.50297-1-osama.abdelkader@gmail.com>
On Thu, Mar 26, 2026 at 11:57:52PM +0100, Osama Abdelkader wrote:
> init_irq_stacks() and init_irq_scs() may fail when arch_alloc_vmap_stack
> or scs_alloc return NULL. Return -ENOMEM from both and call panic() once
> from init_IRQ(), covering per-CPU IRQ stacks and shadow IRQ stacks
> consistently.
>
> Signed-off-by: Osama Abdelkader <osama.abdelkader@gmail.com>
> ---
> v2:
> - Add return -ENOMEM from both init_irq_stacks() and init_irq_scs()
> - Call panic() once from init_IRQ() if either init_irq_stacks() or
> init_irq_scs() returns -ENOMEM
> ---
> arch/arm64/kernel/irq.c | 29 ++++++++++++++++++++---------
> 1 file changed, 20 insertions(+), 9 deletions(-)
>
> diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c
> index 15dedb385b9e..9fafd826002b 100644
> --- a/arch/arm64/kernel/irq.c
> +++ b/arch/arm64/kernel/irq.c
> @@ -10,6 +10,7 @@
> * Copyright (C) 2012 ARM Ltd.
> */
>
> +#include <linux/errno.h>
> #include <linux/hardirq.h>
> #include <linux/init.h>
> #include <linux/irq.h>
> @@ -32,34 +33,43 @@ DEFINE_PER_CPU(struct nmi_ctx, nmi_contexts);
>
> DEFINE_PER_CPU(unsigned long *, irq_stack_ptr);
>
> -
> DECLARE_PER_CPU(unsigned long *, irq_shadow_call_stack_ptr);
>
> #ifdef CONFIG_SHADOW_CALL_STACK
> DEFINE_PER_CPU(unsigned long *, irq_shadow_call_stack_ptr);
> #endif
>
> -static void init_irq_scs(void)
> +static int __init init_irq_scs(void)
> {
> int cpu;
> + void *s;
>
> if (!scs_is_enabled())
> - return;
> + return 0;
> +
> + for_each_possible_cpu(cpu) {
> + s = scs_alloc(early_cpu_to_node(cpu));
> + if (!s)
> + return -ENOMEM;
> + per_cpu(irq_shadow_call_stack_ptr, cpu) = s;
> + }
>
> - for_each_possible_cpu(cpu)
> - per_cpu(irq_shadow_call_stack_ptr, cpu) =
> - scs_alloc(early_cpu_to_node(cpu));
> + return 0;
> }
>
> -static void __init init_irq_stacks(void)
> +static int __init init_irq_stacks(void)
> {
> int cpu;
> unsigned long *p;
>
> for_each_possible_cpu(cpu) {
> p = arch_alloc_vmap_stack(IRQ_STACK_SIZE, early_cpu_to_node(cpu));
> + if (!p)
> + return -ENOMEM;
> per_cpu(irq_stack_ptr, cpu) = p;
> }
> +
> + return 0;
> }
>
> #ifdef CONFIG_SOFTIRQ_ON_OWN_STACK
> @@ -109,8 +119,9 @@ int __init set_handle_fiq(void (*handle_fiq)(struct pt_regs *))
>
> void __init init_IRQ(void)
> {
> - init_irq_stacks();
> - init_irq_scs();
> + if (init_irq_stacks() || init_irq_scs())
> + panic("Failed to allocate IRQ stack resources\n");
> +
> irqchip_init();
>
> if (system_uses_irq_prio_masking()) {
> --
> 2.43.0
>
Hi All,
Can you please review?
Best regards,
Osama
^ permalink raw reply
* Re: [PATCH 1/7] x86/vdso: Respect COMPAT_32BIT_TIME
From: Thomas Weißschuh @ 2026-04-14 10:16 UTC (permalink / raw)
To: Arnd Bergmann
Cc: H. Peter Anvin, Andy Lutomirski, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, Russell King, Catalin Marinas,
Will Deacon, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Thomas Bogendoerfer,
Vincenzo Frascino, linux-kernel, linux-arm-kernel, linuxppc-dev,
linux-mips
In-Reply-To: <e9487ebe-3730-438a-9c23-e45f75986ecc@app.fastmail.com>
On Mon, Apr 13, 2026 at 06:57:57PM +0200, Arnd Bergmann wrote:
> On Mon, Apr 13, 2026, at 18:13, Thomas Weißschuh wrote:
(...)
> > if (tv && !IS_ENABLED(CONFIG_COMPAT_32BIT_TIME) && sizeof(tv->tv_sec) < 8) {
> > pr_warn_once(...);
> > return -EINVAL;
> > }
> >
> > Or maybe drop the EINVAL but still emit a warning. That warning would be
> > useful for gettimeofday(), too.
>
> We discussed this during the original y2038 work and decided
> at the time to not have those warnings for syscalls. We could
> bring that back, but I think I would want one level of abstraction
> there and control this using a global Kconfig switch for all
> syscalls as well as ioctl commands that could use such a check.
I'd like to avoid another kconfig option. Linus doesn't sound too
excited about those [0].
Thomas
[0] https://lore.kernel.org/lkml/CAHk-=whigg3hvOy7c1j1MXFy6o6CHp0g4Tc3Y-MAk+XDssHU0A@mail.gmail.com/
^ permalink raw reply
* Re: [PATCH v2 3/4] KVM: arm64: sefltests: Add basic NV selftest
From: Wei-Lin Chang @ 2026-04-14 10:16 UTC (permalink / raw)
To: Itaru Kitayama
Cc: linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel,
Marc Zyngier, Oliver Upton, Joey Gouly, Suzuki K Poulose,
Zenghui Yu, Catalin Marinas, Will Deacon, Paolo Bonzini,
Shuah Khan
In-Reply-To: <ad1gqsqqOXyYmJoG@sm-arm-grace07>
On Tue, Apr 14, 2026 at 06:31:22AM +0900, Itaru Kitayama wrote:
> On Mon, Apr 13, 2026 at 10:18:42AM +0100, Wei-Lin Chang wrote:
> > Hi Itaru,
> >
> > On Mon, Apr 13, 2026 at 08:19:25AM +0900, Itaru Kitayama wrote:
> > > On Sun, Apr 12, 2026 at 03:22:15PM +0100, Wei-Lin Chang wrote:
> > > > This selftest simply starts an L1, which starts its own guest (L2). L2
> > > > runs without stage-1 and 2 translations, it calls an HVC to jump back
> > > > to L1.
> > >
> > > How do you disable both the nested guest (L2)'s MMU and stage 2
> > > translations?
> >
> > Guest stage-2 is disabled by not setting HCR_EL2.VM in prepare_hyp(),
> > and stage-1 is disabled by not writing to SCTLR_EL12 in init_vcpu(),
> > effectively using the default value set by L0. However since SCTLR_EL1
> > has many architecturally UNKNOWN bits (including SCTLR_EL1.M), it should
> > be better to write a value before running L2 I suppose...
>
> Thanks. What do you think of using copy_el2_to_el1() macro in at.c, so we
> can prepare in guest_code() to manipulate the SCTLR_EL12 System register
> with the sensible programmed values?
Yes, using copy_el2_to_el1() can give us an L2 stage-1 that is identical
to the L1's stage-1. But what I was considering was if guest stage-2 is
enabled (which we plan to implement), then those stage-1 page tables
will have to be mapped for L2, and its base address translated to L2IPA.
It's doable but seems like extra complexity when stage-1 is not so
interesting for KVM (except for AT?), it lets the guest do whatever it
likes and let the hardware do the translation.
Let me know if you have reasons to want stage-1 for L2, there could be
something I should consider but did not.
Thanks,
Wei-Lin Chang
>
> Itaru.
>
> >
> > Thanks,
> > Wei-Lin Chang
> >
> > >
> > > Itaru.
> > >
> > > >
> > > > Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com>
> > > > ---
> > > > tools/testing/selftests/kvm/Makefile.kvm | 1 +
> > > > .../selftests/kvm/arm64/hello_nested.c | 103 ++++++++++++++++++
> > > > 2 files changed, 104 insertions(+)
> > > > create mode 100644 tools/testing/selftests/kvm/arm64/hello_nested.c
> > > >
> > > > diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
> > > > index 3dc3e39f7025..e8c108e0c487 100644
> > > > --- a/tools/testing/selftests/kvm/Makefile.kvm
> > > > +++ b/tools/testing/selftests/kvm/Makefile.kvm
> > > > @@ -168,6 +168,7 @@ TEST_GEN_PROGS_arm64 += arm64/arch_timer_edge_cases
> > > > TEST_GEN_PROGS_arm64 += arm64/at
> > > > TEST_GEN_PROGS_arm64 += arm64/debug-exceptions
> > > > TEST_GEN_PROGS_arm64 += arm64/hello_el2
> > > > +TEST_GEN_PROGS_arm64 += arm64/hello_nested
> > > > TEST_GEN_PROGS_arm64 += arm64/host_sve
> > > > TEST_GEN_PROGS_arm64 += arm64/hypercalls
> > > > TEST_GEN_PROGS_arm64 += arm64/external_aborts
> > > > diff --git a/tools/testing/selftests/kvm/arm64/hello_nested.c b/tools/testing/selftests/kvm/arm64/hello_nested.c
> > > > new file mode 100644
> > > > index 000000000000..97387e4697b3
> > > > --- /dev/null
> > > > +++ b/tools/testing/selftests/kvm/arm64/hello_nested.c
> > > > @@ -0,0 +1,103 @@
> > > > +// SPDX-License-Identifier: GPL-2.0-only
> > > > +/*
> > > > + * hello_nested - Go from vEL2 to EL1 then back
> > > > + */
> > > > +
> > > > +#include "nested.h"
> > > > +#include "processor.h"
> > > > +#include "test_util.h"
> > > > +#include "ucall.h"
> > > > +
> > > > +#define XLATE2GPA (0xABCD)
> > > > +#define L2STACKSZ (0x100)
> > > > +
> > > > +/*
> > > > + * TPIDR_EL2 is used to store vcpu id, so save and restore it.
> > > > + */
> > > > +static vm_paddr_t ucall_translate_to_gpa(void *gva)
> > > > +{
> > > > + vm_paddr_t gpa;
> > > > + u64 vcpu_id = read_sysreg(tpidr_el2);
> > > > +
> > > > + GUEST_SYNC2(XLATE2GPA, gva);
> > > > +
> > > > + /* get the result from userspace */
> > > > + gpa = read_sysreg(tpidr_el2);
> > > > +
> > > > + write_sysreg(vcpu_id, tpidr_el2);
> > > > +
> > > > + return gpa;
> > > > +}
> > > > +
> > > > +static void l2_guest_code(void)
> > > > +{
> > > > + do_hvc();
> > > > +}
> > > > +
> > > > +static void guest_code(void)
> > > > +{
> > > > + struct vcpu vcpu;
> > > > + struct hyp_data hyp_data;
> > > > + int ret;
> > > > + vm_paddr_t l2_pc, l2_stack_top;
> > > > + /* force 16-byte alignment for the stack pointer */
> > > > + u8 l2_stack[L2STACKSZ] __attribute__((aligned(16)));
> > > > +
> > > > + GUEST_ASSERT_EQ(get_current_el(), 2);
> > > > + GUEST_PRINTF("vEL2 entry\n");
> > > > +
> > > > + l2_pc = ucall_translate_to_gpa(l2_guest_code);
> > > > + l2_stack_top = ucall_translate_to_gpa(&l2_stack[L2STACKSZ]);
> > > > +
> > > > + init_vcpu(&vcpu, l2_pc, l2_stack_top);
> > > > + prepare_hyp();
> > > > +
> > > > + ret = run_l2(&vcpu, &hyp_data);
> > > > + GUEST_ASSERT_EQ(ret, ARM_EXCEPTION_TRAP);
> > > > + GUEST_DONE();
> > > > +}
> > > > +
> > > > +int main(void)
> > > > +{
> > > > + struct kvm_vcpu_init init;
> > > > + struct kvm_vcpu *vcpu;
> > > > + struct kvm_vm *vm;
> > > > + struct ucall uc;
> > > > + vm_paddr_t gpa;
> > > > +
> > > > + TEST_REQUIRE(kvm_check_cap(KVM_CAP_ARM_EL2));
> > > > + vm = vm_create(1);
> > > > +
> > > > + kvm_get_default_vcpu_target(vm, &init);
> > > > + init.features[0] |= BIT(KVM_ARM_VCPU_HAS_EL2);
> > > > + vcpu = aarch64_vcpu_add(vm, 0, &init, guest_code);
> > > > + kvm_arch_vm_finalize_vcpus(vm);
> > > > +
> > > > + while (true) {
> > > > + vcpu_run(vcpu);
> > > > +
> > > > + switch (get_ucall(vcpu, &uc)) {
> > > > + case UCALL_SYNC:
> > > > + if (uc.args[0] == XLATE2GPA) {
> > > > + gpa = addr_gva2gpa(vm, (vm_vaddr_t)uc.args[1]);
> > > > + vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TPIDR_EL2), gpa);
> > > > + }
> > > > + break;
> > > > + case UCALL_PRINTF:
> > > > + pr_info("%s", uc.buffer);
> > > > + break;
> > > > + case UCALL_DONE:
> > > > + pr_info("DONE!\n");
> > > > + goto end;
> > > > + case UCALL_ABORT:
> > > > + REPORT_GUEST_ASSERT(uc);
> > > > + fallthrough;
> > > > + default:
> > > > + TEST_FAIL("Unhandled ucall: %ld\n", uc.cmd);
> > > > + }
> > > > + }
> > > > +
> > > > +end:
> > > > + kvm_vm_free(vm);
> > > > + return 0;
> > > > +}
> > > > --
> > > > 2.43.0
> > > >
^ permalink raw reply
* Re: [PATCH] arm64: dts: exynos850: Add SRAM node
From: Tudor Ambarus @ 2026-04-14 10:20 UTC (permalink / raw)
To: Krzysztof Kozlowski, Alexey Klimov, Sam Protsenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Alim Akhtar
Cc: linux-samsung-soc, linux-arm-kernel, devicetree, linux-kernel,
Juan Yescas, Peter Griffin, André Draszik
In-Reply-To: <4c6a92e0-15a1-4f82-afc9-542f5ad9d2df@kernel.org>
Hi!
On 4/14/26 12:08 PM, Krzysztof Kozlowski wrote:
> On 14/04/2026 11:00, Alexey Klimov wrote:
>> On Mon Apr 13, 2026 at 4:23 PM BST, Krzysztof Kozlowski wrote:
>>> On 13/04/2026 16:52, Alexey Klimov wrote:
>>>> SRAM is used by the ACPM protocol to retrieve the ACPM channels
>>>> information and configuration data. Add the SRAM node.
>>>>
>>>> Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
>>>> ---
>>>> arch/arm64/boot/dts/exynos/exynos850.dtsi | 8 ++++++++
>>>> 1 file changed, 8 insertions(+)
>>>>
>>>> diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
>>>> index cb55015c8dce..cf4a6168846c 100644
>>>> --- a/arch/arm64/boot/dts/exynos/exynos850.dtsi
>>>> +++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
>>>> @@ -910,6 +910,14 @@ spi_2: spi@11d20000 {
>>>> };
>>>> };
>>>> };
>>>> +
>>>> + apm_sram: sram@2039000 {
>>>> + compatible = "mmio-sram";
>>>> + reg = <0x0 0x2039000 0x40000>;
>>>> + #address-cells = <1>;
>>>> + #size-cells = <1>;
>>>> + ranges = <0x0 0x0 0x2039000 0x40000>;
>>>
>>> You miss here children.
>>
>> Thank you! I guess I should convert it to smth like this:
>>
>> apm_sram: sram@2039000 {
>> compatible = "mmio-sram";
>> reg = <0x0 0x2039000 0x40000>;
>> ranges = <0x0 0x0 0x2039000 0x40000>;
>> #address-cells = <1>;
>> #size-cells = <1>;
>>
>> acpm_sram_region: sram-section@0 {
>> reg = <0x0 0x40000>;
>
> This covers entire block, so feels pointless. Maybe requirement of
> children should be dropped. What's the point of having children? Why
> does the driver need them?
>
>> };
>> };
>>
>> And then later reference shmem = &acpm_sram_region from acpm node.
>>
>>> Also, 'ranges' should be after 'reg'.
>>
>> Thanks, will fix this.
>>
>> FWIW this commit is a copy of commit 48e7821b26904
>> https://lore.kernel.org/r/20250207-gs101-acpm-dt-v4-1-230ba8663a2d@linaro.org
>
>
> Huh, we should fix that one as well.
>
On gs101, likely on e850 too, ACPM parses the SRAM and discovers at runtime where
the TX/RX queue offsets are in SRAM. So we can't define static partitions in DT.
I remember that I thought about extending the SRAM driver to add dynamic
partitions (clients to request the mmio-sram driver to create partitions at
runtime), but it was just ACPM that's using SRAM, so I didn't need it.
Cheers,
ta
^ permalink raw reply
* Re: [PATCH RFC] ACPI: processor: idle: Do not propagate acpi_processor_ffh_lpi_probe() -ENODEV
From: Breno Leitao @ 2026-04-14 10:21 UTC (permalink / raw)
To: lihuisong (C)
Cc: Rafael J. Wysocki, Len Brown, lpieralisi, catalin.marinas, will,
Rafael J. Wysocki, linux-acpi, linux-kernel, pjaroszynski,
guohanjun, sudeep.holla, linux-arm-kernel, rmikey, kernel-team
In-Reply-To: <af9c679d-899c-4832-b902-e621b5987f12@huawei.com>
Hello Huisong,
On Tue, Apr 14, 2026 at 05:43:51PM +0800, lihuisong (C) wrote:
> But it is a real issue. Thanks for your report.
> I think the best way to fix your issue is that remove this verification in
> psci_acpi_cpu_init_idle().
> Because it is legal for platform to report one LPI state.
> This function just needs to verify the LPI states which are FFH.
Thank you for the prompt feedback.
Would this approach work?
commit 6c9d52840a4f778cc989838ba76ee51416e85de3
Author: Breno Leitao <leitao@debian.org>
Date: Tue Apr 14 03:16:08 2026 -0700
ACPI: processor: idle: Allow platforms with only one LPI state
psci_acpi_cpu_init_idle() rejects platforms where power.count - 1 <= 0
by returning -ENODEV. However, having a single LPI state (WFI) is a
valid configuration. The function's purpose is to verify FFH idle states,
and when count is zero, there are simply no FFH states to validate —
this is not an error.
On NVIDIA Grace (aarch64) systems with PSCIv1.1, power.count is 1 for
all 72 CPUs, so the probe fails with -ENODEV. After commit cac173bea57d
("ACPI: processor: idle: Rework the handling of
acpi_processor_ffh_lpi_probe()"), this failure propagates up and prevents
cpuidle registration entirely.
Change the check from (count <= 0) to (count < 0) so that platforms
with only WFI are accepted. The for loop naturally handles count == 0
by not iterating.
Fixes: cac173bea57d ("ACPI: processor: idle: Rework the handling of acpi_processor_ffh_lpi_probe()")
Signed-off-by: Breno Leitao <leitao@debian.org>
diff --git a/drivers/acpi/arm64/cpuidle.c b/drivers/acpi/arm64/cpuidle.c
index 801f9c4501425..7791b751042ce 100644
--- a/drivers/acpi/arm64/cpuidle.c
+++ b/drivers/acpi/arm64/cpuidle.c
@@ -31,7 +31,7 @@ static int psci_acpi_cpu_init_idle(unsigned int cpu)
return -EOPNOTSUPP;
count = pr->power.count - 1;
- if (count <= 0)
+ if (count < 0)
return -ENODEV;
for (i = 0; i < count; i++) {
^ permalink raw reply related
* [PATCH v2 0/3] iio: adc: xilinx-ams: refactor alarm handling to table-driven design
From: Guilherme Ivo Bozi @ 2026-04-14 10:29 UTC (permalink / raw)
To: Salih Erim, Conall O'Griofa, Jonathan Cameron, Michal Simek
Cc: David Lechner, Nuno Sá, Andy Shevchenko, linux-iio,
linux-arm-kernel, linux-kernel, Guilherme Ivo Bozi
In-Reply-To: <20260414093018.7153-1-guilherme.bozi@usp.br>
This series addresses significant code duplication in alarm handling
logic across the Xilinx AMS IIO driver.
To address this, the series introduces a centralized table-driven
mapping (alarm_map) that replaces multiple switch statements spread
across the driver.
This improves:
- maintainability (single source of truth for mappings)
- readability (removes repeated switch logic)
- extensibility (new alarms require only table updates)
No functional changes are intended.
Series overview:
- Patch 1: fix out-of-bounds channel lookup
- Patch 2: convert mutex handling to guard(mutex)
- Patch 3: introduce table-driven alarm mapping
v1 -> v2:
- Fixed Fixes tag format
- Replaced AMS_ALARM_INVALID with AMS_ALARM_NONE
- Changed alarm_map base_offset type
Guilherme Ivo Bozi (3):
iio: adc: xilinx-ams: fix out-of-bounds channel lookup in event
handling
iio: adc: xilinx-ams: use guard(mutex) for automatic locking
iio: adc: xilinx-ams: refactor alarm mapping to table-driven approach
drivers/iio/adc/xilinx-ams.c | 190 +++++++++++++----------------------
1 file changed, 71 insertions(+), 119 deletions(-)
--
2.47.3
^ permalink raw reply
* [PATCH v2 1/3] iio: adc: xilinx-ams: fix out-of-bounds channel lookup in event handling
From: Guilherme Ivo Bozi @ 2026-04-14 10:29 UTC (permalink / raw)
To: Salih Erim, Conall O'Griofa, Jonathan Cameron, Michal Simek
Cc: David Lechner, Nuno Sá, Andy Shevchenko, linux-iio,
linux-arm-kernel, linux-kernel, Guilherme Ivo Bozi
In-Reply-To: <20260414103316.18455-1-guilherme.bozi@usp.br>
ams_event_to_channel() may return a pointer past the end of
dev->channels when no matching scan_index is found. This can lead
to invalid memory access in ams_handle_event().
Add a bounds check in ams_event_to_channel() and return NULL when
no channel is found. Also guard the caller to safely handle this
case.
Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
Signed-off-by: Guilherme Ivo Bozi <guilherme.bozi@usp.br>
---
drivers/iio/adc/xilinx-ams.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
index 124470c92529..f364e69a5a0d 100644
--- a/drivers/iio/adc/xilinx-ams.c
+++ b/drivers/iio/adc/xilinx-ams.c
@@ -871,6 +871,9 @@ static const struct iio_chan_spec *ams_event_to_channel(struct iio_dev *dev,
if (dev->channels[i].scan_index == scan_index)
break;
+ if (i >= dev->num_channels)
+ return NULL;
+
return &dev->channels[i];
}
@@ -1012,6 +1015,8 @@ static void ams_handle_event(struct iio_dev *indio_dev, u32 event)
const struct iio_chan_spec *chan;
chan = ams_event_to_channel(indio_dev, event);
+ if (!chan)
+ return;
if (chan->type == IIO_TEMP) {
/*
--
2.47.3
^ permalink raw reply related
* [PATCH 0/3] Mediatek Genio 510/700-EVK: add CPU power supplies
From: Louis-Alexis Eyraud @ 2026-04-14 10:33 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Louis-Alexis Eyraud
This series adds for the Mediatek Genio 510-EVK (MT8370) and 700-EVK
(MT8390) boards the CPU power supply definitions in their devicetree
that are missing for all their CPU cores.
On the boards, the big core power is supplied by a MT6319 (sub PMIC)
and little core power by a MT6365 (main PMIC).
Patch 1 adds the MT6319 PMIC support that was not yet enabled for these
boards.
Patch 2 adds the CPU power supplies definitions that are common to both
Genio 510 and 700 EVK boards, and patch 3 adds the Genio 700-EVK
specific ones.
The series has been tested on Genio 510-EVK board with a kernel based
on linux-next (tag: next-20260410).
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
Louis-Alexis Eyraud (3):
arm64: dts: mediatek: mt8390-genio-common: add MT6319 PMIC support
arm64: dts: mediatek: mt8390-genio-common: add CPU power supplies
arm64: dts: mediatek: mt8390-genio-700-evk: add specific CPU power supplies
.../boot/dts/mediatek/mt8390-genio-700-evk.dts | 7 +++
.../boot/dts/mediatek/mt8390-genio-common.dtsi | 68 ++++++++++++++++++++++
2 files changed, 75 insertions(+)
---
base-commit: f244905cd8cff7a7249cd3dac8a366e02d61ad4f
change-id: 20260413-mtk-g510-700-cpu-supplies-41a78a6bf175
Best regards,
--
Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
^ permalink raw reply
* [PATCH 1/3] arm64: dts: mediatek: mt8390-genio-common: add MT6319 PMIC support
From: Louis-Alexis Eyraud @ 2026-04-14 10:33 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Louis-Alexis Eyraud
In-Reply-To: <20260414-mtk-g510-700-cpu-supplies-v1-0-3b8313e5ca8d@collabora.com>
Mediatek Genio 510 and 700-EVK boards integrate a MT6319 PMIC, powered
by the board system power rail (VSYS) and connected to the SPMI
interface. It provides buck regulators for CPU core power supplies in
particular.
Add the needed nodes in the board common dtsi to enable its support.
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
.../boot/dts/mediatek/mt8390-genio-common.dtsi | 44 ++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi b/arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi
index 2062506f6cc5..aab474d6c5f8 100644
--- a/arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi
@@ -1364,6 +1364,50 @@ &spi2 {
status = "okay";
};
+&spmi {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ pmic@6 {
+ compatible = "mediatek,mt6319-regulator", "mediatek,mt6315-regulator";
+ reg = <0x6 SPMI_USID>;
+
+ pvdd1-supply = <®_vsys>;
+ pvdd2-supply = <®_vsys>;
+ pvdd3-supply = <®_vsys>;
+ pvdd4-supply = <®_vsys>;
+
+ regulators {
+ mt6319_vbuck1: vbuck1 {
+ regulator-name = "dvdd_proc_b";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1193750>;
+ regulator-enable-ramp-delay = <256>;
+ regulator-allowed-modes = <0 1 2>;
+ regulator-always-on;
+ };
+
+ vbuck3 {
+ regulator-name = "avdd2_emi";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1193750>;
+ regulator-enable-ramp-delay = <256>;
+ regulator-allowed-modes = <0 1 2>;
+ regulator-always-on;
+ };
+
+ vbuck4 {
+ regulator-name = "avddq_emi";
+ regulator-min-microvolt = <300000>;
+ regulator-max-microvolt = <1193750>;
+ regulator-enable-ramp-delay = <256>;
+ regulator-allowed-modes = <0 1 2>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
&uart0 {
pinctrl-0 = <&uart0_pins>;
pinctrl-names = "default";
--
2.53.0
^ permalink raw reply related
* [PATCH 2/3] arm64: dts: mediatek: mt8390-genio-common: add CPU power supplies
From: Louis-Alexis Eyraud @ 2026-04-14 10:33 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Louis-Alexis Eyraud
In-Reply-To: <20260414-mtk-g510-700-cpu-supplies-v1-0-3b8313e5ca8d@collabora.com>
Mediatek Genio 510-EVK (MT8370) and 700-EVK (MT8390) devicetrees are
missing power supply definitions for all their CPU cores.
On the boards, the big core power is supplied by a MT6319 (sub PMIC),
and little core power by a MT6365 (main PMIC).
MT8370 and MT8390 SoC have the same core type (little cores are ARM
Cortex A55, big ones are A72), the same big core number (2) but MT8390
SoC has more little cores (6) than MT8370 SoC (only 4).
To handle the little core number difference, add in the board common
dtsi the power supply definitions for the common CPU core nodes (0-3,
6 and 7).
The power supplies for the additional MT8390 CPU core nodes (4 and 5)
will be added for the Genio 700 in a separate commit.
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
.../boot/dts/mediatek/mt8390-genio-common.dtsi | 24 ++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi b/arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi
index aab474d6c5f8..9ebb222a877f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8390-genio-common.dtsi
@@ -285,6 +285,30 @@ &afe {
status = "okay";
};
+&cpu0 {
+ cpu-supply = <&mt6359_vcore_buck_reg>;
+};
+
+&cpu1 {
+ cpu-supply = <&mt6359_vcore_buck_reg>;
+};
+
+&cpu2 {
+ cpu-supply = <&mt6359_vcore_buck_reg>;
+};
+
+&cpu3 {
+ cpu-supply = <&mt6359_vcore_buck_reg>;
+};
+
+&cpu6 {
+ cpu-supply = <&mt6319_vbuck1>;
+};
+
+&cpu7 {
+ cpu-supply = <&mt6319_vbuck1>;
+};
+
&disp_dsi0 {
#address-cells = <1>;
#size-cells = <0>;
--
2.53.0
^ permalink raw reply related
* [PATCH 3/3] arm64: dts: mediatek: mt8390-genio-700-evk: add specific CPU power supplies
From: Louis-Alexis Eyraud @ 2026-04-14 10:33 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Louis-Alexis Eyraud
In-Reply-To: <20260414-mtk-g510-700-cpu-supplies-v1-0-3b8313e5ca8d@collabora.com>
Add power supply definitions for the additional little CPU core nodes,
that cannot be factorized in the board common dtsi due to little core
number difference between MT8390 SoC (used by this board) and MT8370
SoC (used by Genio 510-EVK).
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts b/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts
index 612336713a64..0d5a75efb2ee 100644
--- a/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8390-genio-700-evk.dts
@@ -21,3 +21,10 @@ memory@40000000 {
};
};
+&cpu4 {
+ cpu-supply = <&mt6359_vcore_buck_reg>;
+};
+
+&cpu5 {
+ cpu-supply = <&mt6359_vcore_buck_reg>;
+};
--
2.53.0
^ permalink raw reply related
* [PATCH v2 2/3] iio: adc: xilinx-ams: use guard(mutex) for automatic locking
From: Guilherme Ivo Bozi @ 2026-04-14 10:29 UTC (permalink / raw)
To: Salih Erim, Conall O'Griofa, Jonathan Cameron, Michal Simek
Cc: David Lechner, Nuno Sá, Andy Shevchenko, linux-iio,
linux-arm-kernel, linux-kernel, Guilherme Ivo Bozi,
Andy Shevchenko
In-Reply-To: <20260414103316.18455-1-guilherme.bozi@usp.br>
Replace open-coded mutex_lock()/mutex_unlock() pairs with
guard(mutex) to simplify locking and ensure proper unlock on
all control flow paths.
This removes explicit unlock handling, reduces boilerplate,
and avoids potential mistakes in error paths while keeping
the behavior unchanged.
Signed-off-by: Guilherme Ivo Bozi <guilherme.bozi@usp.br>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
---
drivers/iio/adc/xilinx-ams.c | 24 ++++++++----------------
1 file changed, 8 insertions(+), 16 deletions(-)
diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
index f364e69a5a0d..1d84310b61a9 100644
--- a/drivers/iio/adc/xilinx-ams.c
+++ b/drivers/iio/adc/xilinx-ams.c
@@ -720,22 +720,20 @@ static int ams_read_raw(struct iio_dev *indio_dev,
int ret;
switch (mask) {
- case IIO_CHAN_INFO_RAW:
- mutex_lock(&ams->lock);
+ case IIO_CHAN_INFO_RAW: {
+ guard(mutex)(&ams->lock);
if (chan->scan_index >= AMS_CTRL_SEQ_BASE) {
ret = ams_read_vcc_reg(ams, chan->address, val);
if (ret)
- goto unlock_mutex;
+ return ret;
ams_enable_channel_sequence(indio_dev);
} else if (chan->scan_index >= AMS_PS_SEQ_MAX)
*val = readl(ams->pl_base + chan->address);
else
*val = readl(ams->ps_base + chan->address);
- ret = IIO_VAL_INT;
-unlock_mutex:
- mutex_unlock(&ams->lock);
- return ret;
+ return IIO_VAL_INT;
+ }
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_VOLTAGE:
@@ -939,7 +937,7 @@ static int ams_write_event_config(struct iio_dev *indio_dev,
alarm = ams_get_alarm_mask(chan->scan_index);
- mutex_lock(&ams->lock);
+ guard(mutex)(&ams->lock);
if (state)
ams->alarm_mask |= alarm;
@@ -948,8 +946,6 @@ static int ams_write_event_config(struct iio_dev *indio_dev,
ams_update_alarm(ams, ams->alarm_mask);
- mutex_unlock(&ams->lock);
-
return 0;
}
@@ -962,15 +958,13 @@ static int ams_read_event_value(struct iio_dev *indio_dev,
struct ams *ams = iio_priv(indio_dev);
unsigned int offset = ams_get_alarm_offset(chan->scan_index, dir);
- mutex_lock(&ams->lock);
+ guard(mutex)(&ams->lock);
if (chan->scan_index >= AMS_PS_SEQ_MAX)
*val = readl(ams->pl_base + offset);
else
*val = readl(ams->ps_base + offset);
- mutex_unlock(&ams->lock);
-
return IIO_VAL_INT;
}
@@ -983,7 +977,7 @@ static int ams_write_event_value(struct iio_dev *indio_dev,
struct ams *ams = iio_priv(indio_dev);
unsigned int offset;
- mutex_lock(&ams->lock);
+ guard(mutex)(&ams->lock);
/* Set temperature channel threshold to direct threshold */
if (chan->type == IIO_TEMP) {
@@ -1005,8 +999,6 @@ static int ams_write_event_value(struct iio_dev *indio_dev,
else
writel(val, ams->ps_base + offset);
- mutex_unlock(&ams->lock);
-
return 0;
}
--
2.47.3
^ permalink raw reply related
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