* Re: [PATCH v4 5/6] mm/vmalloc: map contiguous pages in batches for vmap() if possible
From: Uladzislau Rezki @ 2026-06-30 13:54 UTC (permalink / raw)
To: Wen Jiang
Cc: linux-mm, linux-arm-kernel, catalin.marinas, will, akpm, urezki,
baohua, Xueyuan.chen21, dev.jain, rppt, david, ryan.roberts,
anshuman.khandual, ajd, linux-kernel, jiangwen6, shanghaoqiang
In-Reply-To: <20260618084726.1070022-6-jiangwen6@xiaomi.com>
On Thu, Jun 18, 2026 at 04:47:25PM +0800, Wen Jiang wrote:
> From: "Barry Song (Xiaomi)" <baohua@kernel.org>
>
> In many cases, the pages passed to vmap() may include high-order
> pages. For example, the systemheap often allocates pages in descending
> order: order 8, then 4, then 0. Currently, vmap() iterates over every
> page individually—even pages inside a high-order block are handled
> one by one.
>
> This patch detects physically contiguous pages (regardless of whether
> they are compound or non-compound) by scanning with
> num_pages_contiguous(), and maps them as a single contiguous block
> whenever possible. The mapping order is determined by taking the
> minimum of the contiguous page count and the pfn alignment, allowing
> graceful degradation when pfn alignment is less than the contiguous
> range.
>
> Pages with the same page_shift are coalesced and mapped via
> vmap_pages_range_noflush_walk() to avoid page table rewalk.
>
> As users typically allocate memory in descending orders (e.g.
> 8 → 4 → 0), once an order-0 page is encountered, we stop scanning
> for contiguous pages since subsequent pages are likely order-0 as well.
>
> Signed-off-by: Barry Song (Xiaomi) <baohua@kernel.org>
> Co-developed-by: Dev Jain <dev.jain@arm.com>
> Signed-off-by: Dev Jain <dev.jain@arm.com>
> Signed-off-by: Wen Jiang <jiangwen6@xiaomi.com>
> Tested-by: Xueyuan Chen <xueyuan.chen21@gmail.com>
> ---
> mm/vmalloc.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 85 insertions(+), 2 deletions(-)
>
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index 253e017130e09..fffb885cb2158 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -3545,6 +3545,89 @@ void vunmap(const void *addr)
> }
> EXPORT_SYMBOL(vunmap);
>
> +static inline unsigned int vm_shift(pgprot_t prot, unsigned long size)
> +{
> + if (arch_vmap_pmd_supported(prot) && size >= PMD_SIZE)
> + return PMD_SHIFT;
> +
> + return arch_vmap_pte_supported_shift(size);
> +}
> +
> +static inline int get_vmap_batch_order(struct page **pages,
> + pgprot_t prot, unsigned int max_steps, unsigned int idx)
> +{
> + unsigned int nr_contig;
> + int order;
> +
> + if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP))
> + return 0;
> +
> + nr_contig = num_pages_contiguous(&pages[idx], max_steps);
> + if (nr_contig < 2)
> + return 0;
> +
> + order = ilog2(nr_contig);
> +
> + /* Limit order by pfn alignment */
> + order = min_t(int, order, __ffs(page_to_pfn(pages[idx])));
> +
> + if (vm_shift(prot, PAGE_SIZE << order) == PAGE_SHIFT)
> + return 0;
> +
> + return order;
> +}
> +
> +static int vmap_batched(unsigned long addr, unsigned long end,
> + pgprot_t prot, struct page **pages)
> +{
> + unsigned int count = (end - addr) >> PAGE_SHIFT;
> + unsigned int prev_shift = 0, idx = 0;
> + unsigned long start = addr, map_addr = addr;
> + int err;
> +
> + err = kmsan_vmap_pages_range_noflush(addr, end, prot, pages,
> + PAGE_SHIFT, GFP_KERNEL);
> + if (err)
> + goto out;
> +
> + for (unsigned int i = 0; i < count; ) {
> + unsigned int shift = PAGE_SHIFT +
> + get_vmap_batch_order(pages, prot, count - i, i);
> +
> + if (!i)
> + prev_shift = shift;
> +
> + if (shift != prev_shift) {
> + err = vmap_pages_range_noflush_walk(map_addr, addr,
> + prot, pages + idx, prev_shift);
> + if (err)
> + goto out;
> + prev_shift = shift;
> + map_addr = addr;
> + idx = i;
> + }
> +
> + /*
> + * Once small pages are encountered, the remaining pages
> + * are likely small as well.
> + */
> + if (shift == PAGE_SHIFT)
> + break;
> +
> + addr += 1UL << shift;
> + i += 1U << (shift - PAGE_SHIFT);
> + }
> +
> + /* Remaining */
> + if (map_addr < end)
> + err = vmap_pages_range_noflush_walk(map_addr, end,
> + prot, pages + idx, prev_shift);
> +
> +out:
> + flush_cache_vmap(start, end);
> + return err;
> +}
> +
> /**
> * vmap - map an array of pages into virtually contiguous space
> * @pages: array of page pointers
> @@ -3588,8 +3671,8 @@ void *vmap(struct page **pages, unsigned int count,
> return NULL;
>
> addr = (unsigned long)area->addr;
> - if (vmap_pages_range(addr, addr + size, pgprot_nx(prot),
> - pages, PAGE_SHIFT) < 0) {
> + if (vmap_batched(addr, addr + size, pgprot_nx(prot),
> + pages) < 0) {
>
Better naming? vmap_pages_range_batched()?
--
Uladzislau Rezki
^ permalink raw reply
* Re: [PATCH v7 1/4] dt-bindings: pci: Strictly distinguish C0 from C1-C5
From: Rob Herring (Arm) @ 2026-06-30 13:54 UTC (permalink / raw)
To: Thierry Reding
Cc: Krzysztof Wilczyński, linux-arm-kernel, Jonathan Hunter,
Thomas Petazzoni, linux-tegra, Pali Rohár, devicetree,
Karthikeyan Mitran, linux-kernel, linux-pci, Thierry Reding,
Manivannan Sadhasivam, Conor Dooley, Michal Simek, Bjorn Helgaas,
Aksh Garg, Krzysztof Kozlowski, Kevin Xie, Lorenzo Pieralisi,
Thierry Reding, Hou Zhiqiang
In-Reply-To: <20260617-tegra264-pcie-v7-1-eae7ae964629@nvidia.com>
On Wed, 17 Jun 2026 18:01:28 +0200, Thierry Reding wrote:
> From: Thierry Reding <treding@nvidia.com>
>
> Instead of using the ECAM registers as the first entry, strictly make a
> distinction between C0 and C1-C5. This is needed because otherwise the
> unit address doesn't match the first "reg" entry. We also cannot change
> the ordering of these nodes to follow the ECAM addresses because that
> would put them outside of their "control bus" hierarchy since the ECAM
> address space is a global one outside of any of the control busses.
>
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
> Changes in v7:
> - undo changes suggested by Sashiko, should've trust the dedicated tool
> rather than the AI
>
> Changes in v6:
> - add maxItems as suggested by Sashiko
>
> Changes in v5:
> - rebase on top of v7.1-rc1, make it into a fix
>
> Changes in v4:
> - ECAM is outside of the controller's region, so it cannot be the first
> reg entry, otherwise we get warnings because it doesn't match the
> unit-address, so revert back to oneOf construct
>
> Changes in v2:
> - move ECAM region first and unify C0 vs. C1-C5
> - move unevaluatedProperties to right before the examples
> - add description to clarify the two types of controllers
> - add examples for C0 and C1-C5
> ---
> .../bindings/pci/nvidia,tegra264-pcie.yaml | 75 ++++++++++++++--------
> 1 file changed, 50 insertions(+), 25 deletions(-)
>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply
* Re: [PATCH v4 0/2] arm64: errata: NVIDIA Olympus device store/load ordering
From: Will Deacon @ 2026-06-30 13:53 UTC (permalink / raw)
To: Shanker Donthineni
Cc: Vladimir Murzin, Catalin Marinas, Jason Gunthorpe,
linux-arm-kernel, Mark Rutland, linux-kernel, linux-doc,
Vikram Sethi, Jason Sequeira
In-Reply-To: <ba15e106-9066-4e55-be2f-6767a32e123d@nvidia.com>
On Mon, Jun 29, 2026 at 06:08:37PM -0500, Shanker Donthineni wrote:
> On 6/29/2026 5:45 AM, Vladimir Murzin wrote:
> > That's interesting. With the way the patch set is structured, it
> > now looks like:
> >
> > 1. Fix the erratum, but cause a performance regression.
> > 2. Restore the performance regression and (re)apply the erratum
> > workaround.
> >
> > Would it make sense to avoid introducing the performance
> > regression in the first place by structuring the patch set
> > slightly differently?
> >
> > 1. (Re)introduce arm64 memset_io()/memcpy_toio().
> > 2. Fix the erratum once for all
> >
> > What do you reckon?
>
> Yes, that ordering makes sense.
>
> I can restructure v5 so that patch 1 introduces the arm64 memset_{to}io()
> implementations while preserving the existing behavior. Patch 2 will
> then add the complete erratum workaround, including the conditional
> trailing DMB for those block-write helpers. This avoids introducing
> the intermediate performance regression and keeps each commit
> independently usable.
>
> Will and Catalin, could you please share your thoughts on this approach?
tbh, I think I'm ok with the current ordering. The second patch is purely
a performance thing for affected CPUs, so doesn't strictly need to be
applied or backported for functional correctness afaict.
Will
^ permalink raw reply
* Re: [PATCH 0/3] arm64: dts/net: stmmac: Add Agilex5 SoCDK TSN Config2 board support
From: Maxime Chevallier @ 2026-06-30 13:53 UTC (permalink / raw)
To: muhammad.nazim.amirul.nazle.asmade, dinguyen
Cc: rmk+kernel, krzk+dt, conor+dt, robh, davem, edumazet, kuba,
pabeni, andrew+netdev, devicetree, linux-arm-kernel, netdev,
linux-kernel
In-Reply-To: <20260630133108.27244-1-muhammad.nazim.amirul.nazle.asmade@altera.com>
Hi,
On 6/30/26 15:31, muhammad.nazim.amirul.nazle.asmade@altera.com wrote:
> From: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
>
> The Intel SoCFPGA Agilex5 SoCDK TSN Config2 board uses a dual-port
> Ethernet setup where gmac1 (TSN port) operates with different MAC-side
> and PHY-side interface modes: GMII internally in the MAC, and RGMII
> towards the PHY.
There's the same behaviour on Gen5, e.g. CycloneV where we have the
"EMAC splitter". Based on wether or not we have that splitter in DT,
we override the INTF_SEL bits to set GMII as the MAC output, the splitter
converting that to RGMII/SGMII.
Is there something similar on this AgileX5 version by any chance, for
which we could reuse the logic ?
I know that on CycloneV you also need to adjust that GMII -> RGMII/SGMII
splitter whenever the speed changes, is that different on agileX5 ? have
you tested 10/100Mbps ?
Thanks,
Maxime
^ permalink raw reply
* [PATCH 00/10] Add support for Apple Silicon DockChannel internal keyboards
From: Michael Reeves via B4 Relay @ 2026-06-30 12:54 UTC (permalink / raw)
To: Sven Peter, Janne Grunau, Neal Gompa, Jassi Brar, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Hector Martin,
Joerg Roedel (AMD), Will Deacon, Robin Murphy, Dmitry Torokhov,
Jiri Kosina, Benjamin Tissoires
Cc: asahi, linux-arm-kernel, linux-kernel, devicetree, iommu,
linux-input, Michael Reeves, Sasha Finkelstein
This series introduces support for the internal keyboards on Apple
Silicon M2 and M3 MacBook models.
On these platforms, built-in input devices are managed by a dedicated
coprocessor running an RTKit-based operating system. Communication
between this coprocessor and the main processor is carried out over a
low-latency hardware byte FIFO interface called DockChannel.
To support this input path, the series introduces a few new components:
- An apple-dockchannel mailbox driver to handle the low-level
byte-stream FIFO.
- A DockChannel HID transport driver (apple-hid) that boots the
coprocessor using the RTKit framework and encapsulates the HID
protocol over the mailbox.
- Minor additions to the apple-rtkit and hid-apple drivers to support
the TraceKit endpoint and integrate the keyboards into the existing
input-quirks framework.
- Devicetree bindings and DTS updates to describe the nodes on M2 and
M3 laptops.
The transport driver is based on an original out-of-tree implementation
by Hector Martin, but it has been significantly rewritten for upstream
inclusion to use the standard Linux mailbox framework and align better
with upstream HID design patterns and reduce reliance on hacks.
While the coprocessor manages both the keyboard and the trackpad, this
series only enables keyboard support. The keyboard can be initialised
without loading external firmware, whereas the trackpad requires
firmware. Trackpad support will be submitted in a subsequent series
once these base transport layers are established.
Tested on: MacBook Air M3 (J613).
Signed-off-by: Michael Reeves <michael.reeves077@gmail.com>
---
Michael Reeves (9):
dt-bindings: mailbox: Add Apple t8122 ASC mailbox
dt-bindings: mailbox: apple: Add DockChannel mailbox
dt-bindings: iommu: apple,dart: Add t8122 compatible
dt-bindings: input: apple: Add DockChannel HID transport
mailbox: apple: Add DockChannel FIFO controller
HID: apple: Add support for DockChannel HID keyboards
HID: apple: Add DockChannel HID transport driver
arm64: dts: apple: Add MTP DockChannel HID nodes
arm64: dts: apple: Enable DockChannel HID on M2 and M3 laptops
Sasha Finkelstein (1):
soc: apple: rtkit: Add tracekit endpoint
.../bindings/input/apple,dockchannel-hid.yaml | 91 ++
.../devicetree/bindings/iommu/apple,dart.yaml | 4 +-
.../bindings/mailbox/apple,dockchannel.yaml | 75 ++
.../devicetree/bindings/mailbox/apple,mailbox.yaml | 1 +
MAINTAINERS | 5 +
arch/arm64/boot/dts/apple/t602x-die0.dtsi | 46 +
arch/arm64/boot/dts/apple/t602x-j414-j416.dtsi | 25 +
arch/arm64/boot/dts/apple/t8112-j413.dts | 20 +
arch/arm64/boot/dts/apple/t8112-j415.dts | 20 +
arch/arm64/boot/dts/apple/t8112-j493.dts | 22 +-
arch/arm64/boot/dts/apple/t8112.dtsi | 46 +
arch/arm64/boot/dts/apple/t8122-j504.dts | 22 +
arch/arm64/boot/dts/apple/t8122-j613.dts | 23 +
arch/arm64/boot/dts/apple/t8122-j615.dts | 23 +
arch/arm64/boot/dts/apple/t8122.dtsi | 47 +
drivers/hid/Kconfig | 2 +
drivers/hid/Makefile | 2 +
drivers/hid/dockchannel/Kconfig | 15 +
drivers/hid/dockchannel/Makefile | 3 +
drivers/hid/dockchannel/apple-hid.c | 1130 ++++++++++++++++++++
drivers/hid/hid-apple.c | 139 ++-
drivers/mailbox/Kconfig | 12 +
drivers/mailbox/Makefile | 2 +
drivers/mailbox/apple-dockchannel.c | 380 +++++++
drivers/soc/apple/rtkit.c | 2 +
include/linux/hid.h | 1 +
include/linux/mailbox/apple-dockchannel.h | 29 +
27 files changed, 2139 insertions(+), 48 deletions(-)
---
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
change-id: 20260629-apple-mtp-keyboard-final-91cb5a6ff4fc
Best regards,
--
Michael Reeves <michael.reeves077@gmail.com>
^ permalink raw reply
* Re: [PATCH 09/27] ASoC: codecs: idt821034: Use guard() for mutex locks
From: Bui Duc Phuc @ 2026-06-30 13:50 UTC (permalink / raw)
To: Mark Brown
Cc: Herve Codina, Takashi Iwai, Nick Li, Support Opensource,
Liam Girdwood, Jaroslav Kysela, Srinivas Kandagatla,
Charles Keepax, Richard Fitzgerald, Matthias Brugger,
AngeloGioacchino Del Regno, Shenghao Ding, Kevin Lu, Baojun Xu,
Sen Wang, Oder Chiou, Linus Walleij, Kuninori Morimoto,
u.kleine-koenig, Zhang Yi, Marco Crivellari, Kees Cook,
HyeongJun An, Arnd Bergmann, Qianfeng Rong, linux-sound,
linux-kernel, patches, linux-mediatek, linux-arm-msm,
linux-arm-kernel
In-Reply-To: <f5ab965a-9640-4df0-8108-7877f34b6950@sirena.org.uk>
On Tue, Jun 30, 2026 at 8:29 PM Mark Brown <broonie@kernel.org> wrote:
> Please delete unneeded context from mails when replying. Doing this
> makes it much easier to find your reply in the message, helping ensure
> it won't be missed by people scrolling through the irrelevant quoted
> material.
Got it. I'll make sure to trim the unneeded context in my future replies.
Thanks for the reminder!
Best regards,
Phuc
^ permalink raw reply
* Re: [PATCH net-next v11 1/7] dt-bindings: phy: document the serdes PHY on sa8255p
From: Bartosz Golaszewski @ 2026-06-30 13:44 UTC (permalink / raw)
To: Vinod Koul
Cc: Geert Uytterhoeven, Bartosz Golaszewski, Bjorn Andersson,
Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Maxime Coquelin, Alexandre Torgue,
Giuseppe Cavallaro, Chen-Yu Tsai, Jernej Skrabec, Neil Armstrong,
Kevin Hilman, Jerome Brunet, Shawn Guo, Fabio Estevam,
Jan Petrous, s32, Mohd Ayaan Anwar, Romain Gantois, Magnus Damm,
Maxime Ripard, Christophe Roullier, Radu Rendec, linux-arm-msm,
devicetree, linux-kernel, netdev, linux-stm32, linux-arm-kernel,
Drew Fustini, linux-sunxi, linux-amlogic, linux-mips, imx,
linux-renesas-soc, linux-rockchip, sophgo, linux-riscv,
Bartosz Golaszewski, Bartosz Golaszewski
In-Reply-To: <akOZFIowVvprnAMf@vaman>
On Tue, 30 Jun 2026 12:23:16 +0200, Vinod Koul <vkoul@kernel.org> said:
> On 29-06-26, 16:51, Geert Uytterhoeven wrote:
>> > Russell King asked me to put the PHY logic for SCMI pm domains into the PHY
>> > driver instead of the MAC driver where it was previously. Instead of cramming
>> > both HLOS and firmware handling into the same driver, I figured it makes more
>> > sense to have a dedicated, cleaner driver as the two share very little code (if
>> > any).
>>
>> I think you are mixing up DT bindings and driver implementation?
>
> Should the bindings change if we have different driver and firmware
> implementations? Isn't binding supposed to be agnostic of
> implementations..?
>
The way sa8255p implements SCMI is with SMC exclusively but - since even base
support is not yet upstream - maybe it would be possible to expose SCMI clocks
like some platforms do and reuse the same binding.
Would it make sense?
Bart
^ permalink raw reply
* Re: [PATCH v3 3/5] arm64: dts: qcom: kaanapali: fix traceNoC probe issue
From: Jie Gan @ 2026-06-30 13:44 UTC (permalink / raw)
To: Konrad Dybcio, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Tingwei Zhang, Jingyi Wang,
Abel Vesa, Suzuki K Poulose, Mike Leach, James Clark, Leo Yan,
Yuanfang Zhang, Abel Vesa, Alexander Shishkin
Cc: linux-arm-msm, devicetree, linux-kernel, coresight,
linux-arm-kernel
In-Reply-To: <a88201a7-0a00-48d8-97cd-300d6aa5fc88@oss.qualcomm.com>
On 6/30/2026 8:53 PM, Konrad Dybcio wrote:
> On 6/30/26 12:36 PM, Jie Gan wrote:
>> The traceNoC node used the "qcom,coresight-tnoc", "arm,primecell"
>> compatible, which places the device on the AMBA bus. The AMBA peripheral
>> ID probing fails on this platform, so the device never probes.
>
> An interested reader would immediately expect an answer to why that's
> the case
>
>> Switch the node to the standalone "qcom,coresight-agtnoc" compatible.
>> Dropping "arm,primecell" makes the device probe through the platform
>> driver instead of the AMBA bus, which resolves the probe failure while
>> keeping it an Aggregator TNOC that retains ATID functionality.
>
> This describes OS behavior. Move your message towards the other
> compatible not depending on reading that ID register.
Thanks for the suggestion, will rephrase the description.
Thanks,
Jie
>
> Konrad
^ permalink raw reply
* [PATCH v3 net-next 2/2] dt-bindings: phy: cadence-torrent: Update property values to support 3 clocks
From: Gokul Praveen @ 2026-06-30 13:43 UTC (permalink / raw)
To: conor+dt, devicetree, krzk+dt, linux-arm-kernel, linux-kernel,
linux-phy, neil.armstrong, nm, robh, sjakhade, kristo, vigneshr,
vkoul, yamonkar
In-Reply-To: <20260630134324.61085-1-g-praveen@ti.com>
Update maxItems value of "clocks" property to 3 as description of
this parameter already indicates 3 clocks(refclk,pll1_refclk(optional)
and phy_en_refclk(optional))
Update the "clock-names" property as well with the 3 clocks.
Signed-off-by: Gokul Praveen <g-praveen@ti.com>
---
.../devicetree/bindings/phy/phy-cadence-torrent.yaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
index 9af39b33646a..54fe78da297a 100644
--- a/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
+++ b/Documentation/devicetree/bindings/phy/phy-cadence-torrent.yaml
@@ -34,7 +34,7 @@ properties:
clocks:
minItems: 1
- maxItems: 2
+ maxItems: 3
description:
PHY input reference clocks - refclk (for PLL0) & pll1_refclk (for PLL1).
pll1_refclk is optional and used for multi-protocol configurations requiring
@@ -47,7 +47,7 @@ properties:
minItems: 1
items:
- const: refclk
- - enum: [ pll1_refclk, phy_en_refclk ]
+ - enum: [refclk, pll1_refclk, phy_en_refclk ]
reg:
minItems: 1
--
2.34.1
^ permalink raw reply related
* [PATCH v3 net-next 0/2] Add support for dual port USXGMII+SGMII
From: Gokul Praveen @ 2026-06-30 13:43 UTC (permalink / raw)
To: conor+dt, devicetree, krzk+dt, linux-arm-kernel, linux-kernel,
linux-phy, neil.armstrong, nm, robh, sjakhade, kristo, vigneshr,
vkoul, yamonkar
This patch series enables dual port USXGMII and SGMII Ethernet mode
support on the TI J784S4 EVM platform using the CPSW9G Ethernet switch.
The CPSW9G instance supports both SGMII and USXGMII modes simultaneously
on MAC Ports 1 and 2, which connect to ENET Expansion 1 and ENET
Expansion 2 slots through the SERDES2 instance. The series includes:
Multilink SERDES configuration support added to the SERDES2 node by adding
the PLL1 refclk.
v2 <==> v1
===========
* Added modifications to the device tree bindings documentation.
v3 <=> v2
==========
* Added net-next suffix in the patch subject.
* Added a separate bindings patch and added appropriate subject
format expected for Bindings patches.
* Updated the cover letter description
Gokul Praveen (2):
arm64: dts: ti: Add PLL1 refclk to J784S4 SoC SERDES node
dt-bindings: phy: cadence-torrent: Update property values to support 3
clocks
.../devicetree/bindings/phy/phy-cadence-torrent.yaml | 4 ++--
arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 3 ++-
2 files changed, 4 insertions(+), 3 deletions(-)
--
2.34.1
^ permalink raw reply
* [PATCH v3 net-next 1/2] arm64: dts: ti: Add PLL1 refclk to J784S4 SoC SERDES node
From: Gokul Praveen @ 2026-06-30 13:43 UTC (permalink / raw)
To: conor+dt, devicetree, krzk+dt, linux-arm-kernel, linux-kernel,
linux-phy, neil.armstrong, nm, robh, sjakhade, kristo, vigneshr,
vkoul, yamonkar
In-Reply-To: <20260630134324.61085-1-g-praveen@ti.com>
Add PLL1 refclk to "clocks" and "clock-names" parameter of SERDES2 node
as "assigned clocks" parameter has PLL1 and serdes multilink configuration
fails without PLL1.
Signed-off-by: Gokul Praveen <g-praveen@ti.com>
---
arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
index 78fcd0c40abc..da8d582574d0 100644
--- a/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
@@ -122,8 +122,9 @@ serdes2: serdes@5020000 {
resets = <&serdes_wiz2 0>;
reset-names = "torrent_reset";
clocks = <&serdes_wiz2 TI_WIZ_PLL0_REFCLK>,
+ <&serdes_wiz2 TI_WIZ_PLL1_REFCLK>,
<&serdes_wiz2 TI_WIZ_PHY_EN_REFCLK>;
- clock-names = "refclk", "phy_en_refclk";
+ clock-names = "refclk","pll1_refclk", "phy_en_refclk";
assigned-clocks = <&serdes_wiz2 TI_WIZ_PLL0_REFCLK>,
<&serdes_wiz2 TI_WIZ_PLL1_REFCLK>,
<&serdes_wiz2 TI_WIZ_REFCLK_DIG>;
--
2.34.1
^ permalink raw reply related
* Re: [PATCH 07/10] HID: apple: Add support for DockChannel HID keyboards
From: Sasha Finkelstein @ 2026-06-30 13:41 UTC (permalink / raw)
To: michael.reeves077
Cc: Sven Peter, Janne Grunau, Neal Gompa, Jassi Brar, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Hector Martin,
Joerg Roedel (AMD), Will Deacon, Robin Murphy, Dmitry Torokhov,
Jiri Kosina, Benjamin Tissoires, asahi, linux-arm-kernel,
linux-kernel, devicetree, iommu, linux-input
In-Reply-To: <20260630-apple-mtp-keyboard-final-v1-7-506d936a1707@gmail.com>
> On Jun 30, 2026, at 14:54, Michael Reeves via B4 Relay <devnull+michael.reeves077.gmail.com@kernel.org> wrote:
>
> @@ -659,6 +669,7 @@ static void apple_battery_timer_tick(struct timer_list *t)
> /*
> * MacBook JIS keyboard has wrong logical maximum
> * Magic Keyboard JIS has wrong logical maximum
> + * Internal DockChannel keyboards can advertise oversized report sizes
> */
> static const __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
> unsigned int *rsize)
> @@ -699,6 +710,27 @@ static const __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
> rdesc[3] = 0x06;
> }
>
> + if (apple_is_dockchannel_keyboard(hdev) && *rsize >= 5) {
> + int i;
> +
> + for (i = 0; i <= *rsize - 5; i++) {
> + if (rdesc[i] == 0x76 && rdesc[i + 1] == 0x00 &&
> + rdesc[i + 2] == 0x40 && rdesc[i + 3] == 0x95) {
> + u8 count = rdesc[i + 4];
> +
> + if (count > 0 && count < 32) {
> + hid_info(hdev,
> + "fixing up DockChannel report size\n");
> + rdesc[i] = 0x75;
> + rdesc[i + 1] = 0x08;
> + rdesc[i + 2] = 0x96;
> + rdesc[i + 3] = 0x00;
> + rdesc[i + 4] = count * 8;
> + }
> + }
> + }
> + }
> +
> return rdesc;
> }
>
It looks like this section is duplicated in the following commit (8).
Is that correct?
^ permalink raw reply
* Re: [PATCH v3] ARM: entry: expand comment in __switch_to
From: Mark Rutland @ 2026-06-30 13:38 UTC (permalink / raw)
To: Linus Walleij; +Cc: Russell King, Ard Biesheuvel, linux-arm-kernel
In-Reply-To: <20260630-comments-in-switch-to-v3-1-87a946a3fddd@kernel.org>
On Tue, Jun 30, 2026 at 11:38:55AM +0200, Linus Walleij wrote:
> From: Linus Walleij <linus.walleij@linaro.org>
>
> As per discussion between the developers in the mail thread
> linked, expand the comment in __switch_to so that readers
> of the code understand what is going on.
>
> Link: https://lore.kernel.org/linux-arm-kernel/ZxDh9biUbf9W8gNN@J2N7QTR9R3/
> Suggested-by: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> Acked-by: Mark Rutland <mark.rutland@arm.com>
> ---
> Changes in v3:
> - EDITME: describe what is new in this series revision.
> - EDITME: use bulletpoints and terse descriptions.
> - Link to v2: https://lore.kernel.org/r/20251216-comments-in-switch-to-v2-1-190d8741db14@kernel.org
Looks like you might have forgotten something here. ;)
This looks good to me, so I reckon you should drop it into Russell's
patch tracker:
https://www.armlinux.org.uk/developer/patches/
Mark.
>
> Changes in v2:
> - Rebased on v6.19-rc1
> - Link to v1: https://lore.kernel.org/r/20241028-comments-in-switch-to-v1-0-7280d09671a8@linaro.org
> ---
> arch/arm/kernel/entry-armv.S | 13 ++++++++++---
> 1 file changed, 10 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
> index a3d050ce9b79..2d2ea3ca880c 100644
> --- a/arch/arm/kernel/entry-armv.S
> +++ b/arch/arm/kernel/entry-armv.S
> @@ -557,9 +557,16 @@ ENTRY(__switch_to)
> ldmia r4, {r4 - sl, fp, ip, lr} @ Load all regs saved previously
> #ifdef CONFIG_VMAP_STACK
> @
> - @ Do a dummy read from the new stack while running from the old one so
> - @ that we can rely on do_translation_fault() to fix up any stale PMD
> - @ entries covering the vmalloc region.
> + @ For a non-lazy mm switch, check_vmalloc_seq() has ensured that
> + @ that the active mm's page tables have mappings for the prev
> + @ task's stack and the next task's stack.
> + @
> + @ For a lazy mm switch the active mm's page tables have mappings
> + @ for the prev task's stack but might not have mappings for the
> + @ new task's stack. Do a dummy read from the new stack while
> + @ running from the old stack so that we can rely on
> + @ do_translation_fault() to populate missing PMD entries covering the
> + @ new task's stack in the old task's page tables.
> @
> ldr r2, [ip]
> #ifdef CONFIG_KASAN_VMALLOC
>
> ---
> base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
> change-id: 20241028-comments-in-switch-to-0e24480e8495
>
> Best regards,
> --
> Linus Walleij <linusw@kernel.org>
>
^ permalink raw reply
* [PATCH 2/3] arm64: dts: socfpga: agilex5: Add SoCDK TSN Config2 board
From: muhammad.nazim.amirul.nazle.asmade @ 2026-06-30 13:31 UTC (permalink / raw)
To: dinguyen, maxime.chevallier
Cc: rmk+kernel, krzk+dt, conor+dt, robh, davem, edumazet, kuba,
pabeni, andrew+netdev, devicetree, linux-arm-kernel, netdev,
linux-kernel
In-Reply-To: <20260630133108.27244-1-muhammad.nazim.amirul.nazle.asmade@altera.com>
From: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
Add device tree for the Intel SoCFPGA Agilex5 SoCDK TSN Config2 board
variant. This configuration enables gmac1 as a TSN port alongside
the standard gmac2 Ethernet port.
The TSN port (gmac1) uses GMII internally in the MAC but connects to an
RGMII PHY. The mac-mode property is set to "gmii" to reflect the
MAC-side interface, while phy-mode is set to "rgmii" for the PHY-side
interface.
Signed-off-by: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
---
arch/arm64/boot/dts/intel/Makefile | 3 +-
.../intel/socfpga_agilex5_socdk_tsn_cfg2.dts | 133 ++++++++++++++++++
2 files changed, 135 insertions(+), 1 deletion(-)
create mode 100644 arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_tsn_cfg2.dts
diff --git a/arch/arm64/boot/dts/intel/Makefile b/arch/arm64/boot/dts/intel/Makefile
index 270c70fdf084..fc7ba2c6384b 100644
--- a/arch/arm64/boot/dts/intel/Makefile
+++ b/arch/arm64/boot/dts/intel/Makefile
@@ -4,10 +4,11 @@ dtb-$(CONFIG_ARCH_INTEL_SOCFPGA) += socfpga_agilex_n6000.dtb \
socfpga_agilex_socdk_emmc.dtb \
socfpga_agilex_socdk_nand.dtb \
socfpga_agilex3_socdk.dtb \
- socfpga_agilex5_socdk.dtb \
+ socfpga_agilex5_socdk.dtb \
socfpga_agilex5_socdk_013b.dtb \
socfpga_agilex5_socdk_modular.dtb \
socfpga_agilex5_socdk_nand.dtb \
+ socfpga_agilex5_socdk_tsn_cfg2.dtb \
socfpga_agilex72_socdk.dtb \
socfpga_agilex7m_socdk.dtb \
socfpga_n5x_socdk.dtb
diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_tsn_cfg2.dts b/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_tsn_cfg2.dts
new file mode 100644
index 000000000000..f84f41a647ae
--- /dev/null
+++ b/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_tsn_cfg2.dts
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2026, Altera Corporation
+ */
+#include "socfpga_agilex5.dtsi"
+
+/ {
+ model = "SoCFPGA Agilex5 SoCDK TSN Config2";
+ compatible = "intel,socfpga-agilex5-socdk-tsn-cfg2", "intel,socfpga-agilex5";
+
+ aliases {
+ serial0 = &uart0;
+ ethernet1 = &gmac1;
+ ethernet2 = &gmac2;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ label = "hps_led0";
+ gpios = <&porta 11 GPIO_ACTIVE_HIGH>;
+ };
+
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ /* We expect the bootloader to fill in the reg */
+ reg = <0x0 0x80000000 0x0 0x0>;
+ };
+};
+
+&gpio0 {
+ status = "okay";
+};
+
+&gpio1 {
+ status = "okay";
+};
+
+/*
+ * gmac1 is the TSN port. The MAC operates in GMII mode internally
+ * while the PHY-side interface is RGMII, so mac-mode and phy-mode differ.
+ */
+&gmac1 {
+ status = "okay";
+ phy-mode = "rgmii"; /* TX/RX clock delays provided by Agilex5 I/O hardware */
+ mac-mode = "gmii";
+ phy-handle = <&emac1_phy0>;
+ max-frame-size = <9000>;
+
+ mdio0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+
+ emac1_phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+};
+
+&gmac2 {
+ status = "okay";
+ phy-mode = "rgmii"; /* TX/RX clock delays provided by Agilex5 I/O hardware */
+ phy-handle = <&emac2_phy0>;
+ max-frame-size = <9000>;
+
+ mdio0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+
+ emac2_phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+};
+
+&osc1 {
+ clock-frequency = <25000000>;
+};
+
+&qspi {
+ status = "okay";
+ flash@0 {
+ compatible = "micron,mt25qu02g", "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <100000000>;
+ m25p,fast-read;
+ cdns,read-delay = <2>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ qspi_boot: partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x04200000>;
+ };
+
+ root: partition@4200000 {
+ label = "root";
+ reg = <0x04200000 0x0be00000>;
+ };
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+ disable-over-current;
+};
+
+&watchdog0 {
+ status = "okay";
+};
--
2.43.7
^ permalink raw reply related
* [PATCH 3/3] net: stmmac: dwmac-socfpga: Add mac-mode DT property support
From: muhammad.nazim.amirul.nazle.asmade @ 2026-06-30 13:31 UTC (permalink / raw)
To: dinguyen, maxime.chevallier
Cc: rmk+kernel, krzk+dt, conor+dt, robh, davem, edumazet, kuba,
pabeni, andrew+netdev, devicetree, linux-arm-kernel, netdev,
linux-kernel
In-Reply-To: <20260630133108.27244-1-muhammad.nazim.amirul.nazle.asmade@altera.com>
From: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
Russell King's commit de696c63c1dc ("net: stmmac: socfpga: convert to
use phy_interface") replaced mac_interface with phy_interface in
socfpga_get_plat_phymode(), noting that no upstream DTS files set the
"mac-mode" property, making the two values identical.
The Agilex5 SoCDK TSN Config2 board is an exception: its gmac1 TSN
port uses GMII internally in the MAC while the PHY-side interface is
RGMII, so mac-mode and phy-mode differ. Without restoring mac_interface
support, the MAC is configured with RGMII instead of GMII, causing
connectivity failures on this board.
Add socfpga_of_get_mac_mode() to read the optional "mac-mode" DT
property and store it in a new mac_interface field. When the property
is absent, mac_interface falls back to phy_interface, preserving
the existing behaviour for all other boards.
Fixes: de696c63c1dc ("net: stmmac: socfpga: convert to use phy_interface")
Signed-off-by: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
---
.../ethernet/stmicro/stmmac/dwmac-socfpga.c | 23 ++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 1d7f0a57d288..6a6837c4a414 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -69,12 +69,30 @@ struct socfpga_dwmac {
void __iomem *tse_pcs_base;
void __iomem *sgmii_adapter_base;
bool f2h_ptp_ref_clk;
+ phy_interface_t mac_interface;
const struct socfpga_dwmac_ops *ops;
};
+static int socfpga_of_get_mac_mode(struct device_node *np)
+{
+ const char *pm;
+ int err, i;
+
+ err = of_property_read_string(np, "mac-mode", &pm);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++) {
+ if (!strcasecmp(pm, phy_modes(i)))
+ return i;
+ }
+
+ return -ENODEV;
+}
+
static phy_interface_t socfpga_get_plat_phymode(struct socfpga_dwmac *dwmac)
{
- return dwmac->plat_dat->phy_interface;
+ return dwmac->mac_interface;
}
static void socfpga_sgmii_config(struct socfpga_dwmac *dwmac, bool enable)
@@ -650,6 +668,9 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
plat_dat->pcs_exit = socfpga_dwmac_pcs_exit;
plat_dat->select_pcs = socfpga_dwmac_select_pcs;
+ ret = socfpga_of_get_mac_mode(pdev->dev.of_node);
+ dwmac->mac_interface = ret < 0 ? plat_dat->phy_interface : ret;
+
ops->setup_plat_dat(dwmac);
return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
--
2.43.7
^ permalink raw reply related
* [PATCH 1/3] dt-bindings: arm: altera: Add Agilex5 SoCDK TSN Config2 board board
From: muhammad.nazim.amirul.nazle.asmade @ 2026-06-30 13:31 UTC (permalink / raw)
To: dinguyen, maxime.chevallier
Cc: rmk+kernel, krzk+dt, conor+dt, robh, davem, edumazet, kuba,
pabeni, andrew+netdev, devicetree, linux-arm-kernel, netdev,
linux-kernel
In-Reply-To: <20260630133108.27244-1-muhammad.nazim.amirul.nazle.asmade@altera.com>
From: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
Add compatible string for the Intel SoCFPGA Agilex5 SoCDK TSN Config2
board variant, which uses a dual-port TSN configuration where gmac1
operates with different MAC-side (GMII) and PHY-side (RGMII) interface
modes.
Signed-off-by: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
---
Documentation/devicetree/bindings/arm/altera.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/arm/altera.yaml b/Documentation/devicetree/bindings/arm/altera.yaml
index 3030cf46fe74..e431469a7175 100644
--- a/Documentation/devicetree/bindings/arm/altera.yaml
+++ b/Documentation/devicetree/bindings/arm/altera.yaml
@@ -114,6 +114,7 @@ properties:
- intel,socfpga-agilex5-socdk-debug
- intel,socfpga-agilex5-socdk-modular
- intel,socfpga-agilex5-socdk-nand
+ - intel,socfpga-agilex5-socdk-tsn-cfg2
- const: intel,socfpga-agilex5
- description: Agilex72 boards
--
2.43.7
^ permalink raw reply related
* [PATCH 0/3] arm64: dts/net: stmmac: Add Agilex5 SoCDK TSN Config2 board support
From: muhammad.nazim.amirul.nazle.asmade @ 2026-06-30 13:31 UTC (permalink / raw)
To: dinguyen, maxime.chevallier
Cc: rmk+kernel, krzk+dt, conor+dt, robh, davem, edumazet, kuba,
pabeni, andrew+netdev, devicetree, linux-arm-kernel, netdev,
linux-kernel
From: Nazim Amirul <muhammad.nazim.amirul.nazle.asmade@altera.com>
The Intel SoCFPGA Agilex5 SoCDK TSN Config2 board uses a dual-port
Ethernet setup where gmac1 (TSN port) operates with different MAC-side
and PHY-side interface modes: GMII internally in the MAC, and RGMII
towards the PHY.
Russell King's commit de696c63c1dc ("net: stmmac: socfpga: convert to
use phy_interface") replaced mac_interface with phy_interface in
socfpga_get_plat_phymode(), correctly noting that no upstream DTS files
set the "mac-mode" property at the time. However, the Agilex5 SoCDK
TSN Config2 board requires mac-mode and phy-mode to differ, causing
ping failures when the MAC is configured with RGMII instead of GMII.
This series fixes the issue in three steps:
Patch 1 (dt-bindings): Add the compatible string for the new board
variant to Documentation/devicetree/bindings/arm/altera.yaml.
Patch 2 (dts): Add the device tree source for the Agilex5 SoCDK
TSN Config2 board, enabling gmac1 with mac-mode = "gmii" alongside
the standard gmac2 port.
Patch 3 (driver): Restore mac_interface support in dwmac-socfpga by
reading the optional "mac-mode" DT property. When absent, it falls
back to phy_interface, preserving existing behaviour for all other
boards.
Note: Patches 1 and 2 target Dinh Nguyen's SoCFPGA tree
(git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux.git).
Patch 3 targets net-next.
Nazim Amirul (3):
dt-bindings: arm: altera: Add Agilex5 SoCDK TSN Config2 board
arm64: dts: socfpga: agilex5: Add SoCDK TSN Config2 board
net: stmmac: dwmac-socfpga: Add mac-mode DT property support
Documentation/devicetree/bindings/arm/altera.yaml | 1 +
arch/arm64/boot/dts/intel/Makefile | 9 +-
arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_tsn_cfg2.dts | 133 ++++++++++++++++++
drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 23 ++-
4 files changed, 162 insertions(+), 4 deletions(-)
create mode 100644 arch/arm64/boot/dts/intel/socfpga_agilex5_socdk_tsn_cfg2.dts
--
2.43.7
^ permalink raw reply
* Re: [PATCH 09/27] ASoC: codecs: idt821034: Use guard() for mutex locks
From: Mark Brown @ 2026-06-30 13:28 UTC (permalink / raw)
To: Bui Duc Phuc
Cc: Herve Codina, Takashi Iwai, Nick Li, Support Opensource,
Liam Girdwood, Jaroslav Kysela, Srinivas Kandagatla,
Charles Keepax, Richard Fitzgerald, Matthias Brugger,
AngeloGioacchino Del Regno, Shenghao Ding, Kevin Lu, Baojun Xu,
Sen Wang, Oder Chiou, Linus Walleij, Kuninori Morimoto,
u.kleine-koenig, Zhang Yi, Marco Crivellari, Kees Cook,
HyeongJun An, Arnd Bergmann, Qianfeng Rong, linux-sound,
linux-kernel, patches, linux-mediatek, linux-arm-msm,
linux-arm-kernel
In-Reply-To: <CAABR9nG5Wo1Wb+2_T6dR+6XTw8Vs9awSpQrSZ+k6=jp_ogoGCw@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 386 bytes --]
On Tue, Jun 30, 2026 at 04:14:33PM +0700, Bui Duc Phuc wrote:
> On Tue, Jun 30, 2026 at 2:28 PM Herve Codina <herve.codina@bootlin.com> wrote:
> >
> > Hi,
Please delete unneeded context from mails when replying. Doing this
makes it much easier to find your reply in the message, helping ensure
it won't be missed by people scrolling through the irrelevant quoted
material.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH net-next v11 1/7] dt-bindings: phy: document the serdes PHY on sa8255p
From: Krzysztof Kozlowski @ 2026-06-30 13:24 UTC (permalink / raw)
To: Vinod Koul, Geert Uytterhoeven
Cc: Bartosz Golaszewski, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Coquelin,
Alexandre Torgue, Giuseppe Cavallaro, Chen-Yu Tsai,
Jernej Skrabec, Neil Armstrong, Kevin Hilman, Jerome Brunet,
Shawn Guo, Fabio Estevam, Jan Petrous, s32, Mohd Ayaan Anwar,
Romain Gantois, Magnus Damm, Maxime Ripard, Christophe Roullier,
Radu Rendec, linux-arm-msm, devicetree, linux-kernel, netdev,
linux-stm32, linux-arm-kernel, Drew Fustini, linux-sunxi,
linux-amlogic, linux-mips, imx, linux-renesas-soc, linux-rockchip,
sophgo, linux-riscv, Bartosz Golaszewski, Bartosz Golaszewski
In-Reply-To: <akOZFIowVvprnAMf@vaman>
On 30/06/2026 12:23, Vinod Koul wrote:
> On 29-06-26, 16:51, Geert Uytterhoeven wrote:
>>> Russell King asked me to put the PHY logic for SCMI pm domains into the PHY
>>> driver instead of the MAC driver where it was previously. Instead of cramming
>>> both HLOS and firmware handling into the same driver, I figured it makes more
>>> sense to have a dedicated, cleaner driver as the two share very little code (if
>>> any).
>>
>> I think you are mixing up DT bindings and driver implementation?
>
> Should the bindings change if we have different driver and firmware
> implementations? Isn't binding supposed to be agnostic of
> implementations..?
I did not follow earlier discussions, so I do not know Russell
arguments, but in general it's true that driver choices should not
influence binding decisions. IOW, you need to figure out which real
device is part of power domain and add the power-domains to that device
node (that device).
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v5 0/5] Add support for AAEON SRG-IMX8P MCU
From: Thomas Perrot @ 2026-06-30 13:24 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: thomas.perrot, devicetree, linux-kernel, linux-gpio, imx,
linux-arm-kernel, linux-watchdog, Thomas Petazzoni, Miquel Raynal,
Krzysztof Kozlowski, Conor Dooley, Bartosz Golaszewski,
Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Linus Walleij, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Jérémie Dautheribes, Wim Van Sebroeck,
Lee Jones
In-Reply-To: <CAMRc=MdJJnRTOSEecqpX-EddJRAzWc_1a-cg3wrW8m0jR2Fihw@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 884 bytes --]
Hello Bartosz,
On Tue, 2026-06-30 at 00:47 -0700, Bartosz Golaszewski wrote:
> On Mon, 29 Jun 2026 18:04:59 +0200, Thomas Perrot
> <thomas.perrot@bootlin.com> said:
> > Hello Guenter,
> >
> > On Sat, 2026-04-11 at 17:12 -0700, Guenter Roeck wrote:
> > > snip
> > >
> > > Sashiko has some interesting feedback that might be worth looking
> > > into.
> > >
> > > https://sashiko.dev/#/patchset/20260408-dev-b4-aaeon-mcu-driver-v5-0-ad98bd481668%40bootlin.com
> > >
> >
> > Thanks for the pointer. I went through all findings and addressed
> > the
> > valid ones in v6:
> >
>
> Did I miss anything? I don't see the v6 neither in my inbox nor on
> lore.
I just submitted it. I was waiting for the tests to finish.
Kind regards,
Thomas Perrot
>
> Bart
--
Thomas Perrot, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 659 bytes --]
^ permalink raw reply
* Re: [PATCH 08/10] HID: apple: Add DockChannel HID transport driver
From: Yureka Lilian @ 2026-06-30 13:21 UTC (permalink / raw)
To: michael.reeves077, Sven Peter, Janne Grunau, Neal Gompa,
Jassi Brar, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Hector Martin, Joerg Roedel (AMD), Will Deacon, Robin Murphy,
Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires
Cc: asahi, linux-arm-kernel, linux-kernel, devicetree, iommu,
linux-input
In-Reply-To: <20260630-apple-mtp-keyboard-final-v1-8-506d936a1707@gmail.com>
On 6/30/26 14:54, Michael Reeves via B4 Relay wrote:
> From: Michael Reeves <michael.reeves077@gmail.com>
>
> Apple MTP exposes internal keyboard and trackpad interfaces over a HID
> transport carried by DockChannel.
>
> Add a transport driver that boots the MTP RTKit coprocessor, exchanges
> HID packets through the DockChannel mailbox, and registers child HID
> interfaces from devicetree.
>
> Co-developed-by: Hector Martin <marcan@marcan.st>
> Signed-off-by: Hector Martin <marcan@marcan.st>
> Signed-off-by: Michael Reeves <michael.reeves077@gmail.com>
> ---
> MAINTAINERS | 1 +
> drivers/hid/Kconfig | 2 +
> drivers/hid/Makefile | 2 +
> drivers/hid/dockchannel/Kconfig | 15 +
> drivers/hid/dockchannel/Makefile | 3 +
> drivers/hid/dockchannel/apple-hid.c | 1130 +++++++++++++++++++++++++++++++++++
> 6 files changed, 1153 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index ed68452c0ad6..0063276f0349 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2620,6 +2620,7 @@ F: drivers/clk/clk-apple-nco.c
> F: drivers/cpufreq/apple-soc-cpufreq.c
> F: drivers/dma/apple-admac.c
> F: drivers/gpio/gpio-macsmc.c
> +F: drivers/hid/dockchannel/
> F: drivers/hwmon/macsmc-hwmon.c
> F: drivers/pmdomain/apple/
> F: drivers/i2c/busses/i2c-pasemi-core.c
> diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
> index f9bcaeb66385..f27cda601ede 100644
> --- a/drivers/hid/Kconfig
> +++ b/drivers/hid/Kconfig
> @@ -1488,6 +1488,8 @@ source "drivers/hid/surface-hid/Kconfig"
>
> source "drivers/hid/intel-thc-hid/Kconfig"
>
> +source "drivers/hid/dockchannel/Kconfig"
> +
> endif # HID
>
> # USB support may be used with HID disabled
> diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
> index 23e6e3dd0c56..c9b4b1aff247 100644
> --- a/drivers/hid/Makefile
> +++ b/drivers/hid/Makefile
> @@ -182,3 +182,5 @@ obj-$(CONFIG_AMD_SFH_HID) += amd-sfh-hid/
> obj-$(CONFIG_SURFACE_HID_CORE) += surface-hid/
>
> obj-$(CONFIG_INTEL_THC_HID) += intel-thc-hid/
> +
> +obj-$(CONFIG_APPLE_DOCKCHANNEL_HID) += dockchannel/
> diff --git a/drivers/hid/dockchannel/Kconfig b/drivers/hid/dockchannel/Kconfig
> new file mode 100644
> index 000000000000..fca09ef74403
> --- /dev/null
> +++ b/drivers/hid/dockchannel/Kconfig
> @@ -0,0 +1,15 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR MIT
> +
> +config APPLE_DOCKCHANNEL_HID
> + tristate "HID over Apple DockChannel"
> + depends on APPLE_DOCKCHANNEL
> + depends on APPLE_RTKIT
> + depends on HID
> + depends on INPUT
> + depends on OF
> + help
> + This provides a HID transport layer over the Apple DockChannel
> + mailbox interface. It is required to support the internal keyboard
> + and trackpad on M2 and later MacBook models.
> +
> + Say Y here if you have an M2 or later Apple MacBook.
> diff --git a/drivers/hid/dockchannel/Makefile b/drivers/hid/dockchannel/Makefile
> new file mode 100644
> index 000000000000..d1a82aa57a69
> --- /dev/null
> +++ b/drivers/hid/dockchannel/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR MIT
> +
> +obj-$(CONFIG_APPLE_DOCKCHANNEL_HID) += apple-hid.o
> diff --git a/drivers/hid/dockchannel/apple-hid.c b/drivers/hid/dockchannel/apple-hid.c
> new file mode 100644
> index 000000000000..162fcfb5ab1c
> --- /dev/null
> +++ b/drivers/hid/dockchannel/apple-hid.c
> @@ -0,0 +1,1130 @@
> +// SPDX-License-Identifier: GPL-2.0-only OR MIT
> +/*
> + * Apple DockChannel HID transport driver
> + *
> + * Copyright The Asahi Linux Contributors
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/completion.h>
> +#include <linux/ctype.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/hid.h>
> +#include <linux/mailbox/apple-dockchannel.h>
> +#include <linux/mailbox_client.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/property.h>
> +#include <linux/slab.h>
> +#include <linux/soc/apple/rtkit.h>
> +#include <linux/spinlock.h>
> +#include <linux/string.h>
> +#include <linux/unaligned.h>
> +#include <linux/workqueue.h>
> +
> +#define APPLE_ASC_CPU_CONTROL 0x44
> +#define APPLE_ASC_CPU_CONTROL_RUN BIT(4)
> +
> +#define COMMAND_TIMEOUT_MS 1000
> +#define START_TIMEOUT_MS 2000
> +
> +#define MAX_INTERFACES 16
> +
> +#define DCHID_MAX_PAYLOAD 0xffff
> +#define DCHID_CHECKSUM_LEN 4
> +#define DCHID_RX_BUF_SIZE (sizeof(struct dchid_hdr) + DCHID_MAX_PAYLOAD + \
> + DCHID_CHECKSUM_LEN)
> +
> +#define DCHID_CHANNEL_CMD 0x11
> +#define DCHID_CHANNEL_REPORT 0x12
> +#define DCHID_CHECKSUM_SEED 0xffffffff
> +
> +struct dchid_hdr {
> + u8 hdr_len;
> + u8 channel;
> + __le16 length;
> + u8 seq;
> + u8 iface;
> + __le16 pad;
> +} __packed;
> +
> +#define IFACE_COMM 0
> +
> +#define FLAGS_GROUP GENMASK(7, 6)
> +#define FLAGS_REQ GENMASK(5, 0)
> +
> +#define REQ_SET_REPORT 0
> +#define REQ_GET_REPORT 1
> +
> +struct dchid_subhdr {
> + u8 flags;
> + u8 unk;
> + __le16 length;
> + __le32 retcode;
> +} __packed;
> +
> +#define EVENT_INIT 0xf0
> +#define EVENT_READY 0xf1
> +
> +struct dchid_init_hdr {
> + u8 type;
> + u8 unk1;
> + u8 unk2;
> + u8 iface;
> + char name[16];
> + u8 more_packets;
> + u8 unkpad;
> +} __packed;
> +
> +#define INIT_HID_DESCRIPTOR 0
> +#define INIT_TERMINATOR 2
> +#define INIT_PRODUCT_NAME 7
> +
> +#define CMD_RESET_INTERFACE 0x40
> +#define CMD_RESET_INTERFACE_SUB 1
> +#define CMD_ENABLE_INTERFACE 0xb4
> +
> +struct dchid_init_block_hdr {
> + __le16 type;
> + __le16 length;
> +} __packed;
> +
> +#define STM_REPORT_ID 0x10
> +#define STM_REPORT_SERIAL 0x11
> +
> +struct dchid_stm_id {
> + u8 unk;
> + __le16 vendor_id;
> + __le16 product_id;
> + __le16 version_number;
> + u8 unk2;
> + u8 unk3;
> + u8 keyboard_type;
> + u8 serial_length;
> + /* Serial follows, but we grab it with a different report. */
> +} __packed;
> +
> +struct dchid_work {
> + struct work_struct work;
> + struct dchid_iface *iface;
> +
> + struct dchid_hdr hdr;
> + u8 data[];
> +};
> +
> +struct dchid_iface {
> + struct dchid_dev *dchid;
> + struct hid_device *hid;
> + struct workqueue_struct *wq;
> +
> + bool creating;
> + struct work_struct create_work;
> +
> + int index;
> + const char *name;
> + struct fwnode_handle *fwnode;
> +
> + u8 tx_seq;
> + bool deferred;
> + bool starting;
> + bool open;
> + struct completion ready;
> +
> + void *hid_desc;
> + size_t hid_desc_len;
> +
> + /* Lock for command submission state below */
> + spinlock_t out_lock;
> + u32 out_flags;
> + int out_report;
> + u32 retcode;
> + void *resp_buf;
> + size_t resp_size;
> + struct completion out_complete;
> +};
> +
> +struct dchid_dev {
> + struct device *dev;
> + struct mbox_client dc_mbox_client;
> + struct mbox_chan *dc_mbox;
> +
> + struct apple_rtkit *rtk;
> + void __iomem *asc_base;
> + void __iomem *sram_base;
> + struct resource sram_res;
> +
> + bool id_ready;
> + struct dchid_stm_id device_id;
> + char serial[64];
> +
> + u8 *rx_buf;
> + size_t rx_len;
> +
> + struct dchid_iface *comm;
> + struct mutex ifaces_lock; /* protects ifaces array */
> + struct dchid_iface *ifaces[MAX_INTERFACES];
> +
> + /* Workqueue to asynchronously create HID devices */
> + struct workqueue_struct *new_iface_wq;
> +};
> +
> +static void dchid_destroy_wq(void *data)
> +{
> + struct workqueue_struct *wq = data;
> +
> + destroy_workqueue(wq);
> +}
> +
> +static void dchid_fwnode_release(void *data)
> +{
> + fwnode_handle_put(data);
> +}
> +
> +static void dchid_free_mbox(void *data)
> +{
> + mbox_free_channel(data);
> +}
> +
> +static u32 dchid_checksum(const void *data, size_t len)
> +{
> + const u8 *p = data;
> + u32 sum = 0;
> + int i;
> +
> + while (len >= sizeof(u32)) {
> + sum += get_unaligned_le32(p);
> + p += sizeof(u32);
> + len -= sizeof(u32);
> + }
> +
> + if (len) {
> + u32 tmp = 0;
> +
> + for (i = 0; i < len; i++)
> + tmp |= p[i] << (i * 8);
> + sum += tmp;
> + }
> +
> + return sum;
> +}
> +
> +static struct dchid_iface *
> +dchid_get_interface(struct dchid_dev *dchid, int index, const char *name)
> +{
> + struct dchid_iface *iface;
> + struct fwnode_handle *fwnode;
> + int ret;
> +
> + if (index >= MAX_INTERFACES) {
> + dev_err(dchid->dev, "interface index %d out of range\n", index);
> + return NULL;
> + }
> +
> + mutex_lock(&dchid->ifaces_lock);
> + if (dchid->ifaces[index]) {
> + iface = dchid->ifaces[index];
> + mutex_unlock(&dchid->ifaces_lock);
> + return iface;
> + }
> +
> + iface = devm_kzalloc(dchid->dev, sizeof(*iface), GFP_KERNEL);
> + if (!iface) {
> + mutex_unlock(&dchid->ifaces_lock);
> + return NULL;
> + }
> +
> + iface->index = index;
> + iface->name = devm_kstrdup(dchid->dev, name, GFP_KERNEL);
> + if (!iface->name) {
> + mutex_unlock(&dchid->ifaces_lock);
> + return NULL;
> + }
> +
> + iface->dchid = dchid;
> + iface->out_report = -1;
> + init_completion(&iface->out_complete);
> + init_completion(&iface->ready);
> + spin_lock_init(&iface->out_lock);
> +
> + iface->wq = alloc_ordered_workqueue("dchid-%s", 0, iface->name);
> + if (!iface->wq) {
> + mutex_unlock(&dchid->ifaces_lock);
> + return NULL;
> + }
> +
> + ret = devm_add_action_or_reset(dchid->dev, dchid_destroy_wq, iface->wq);
> + if (ret) {
> + mutex_unlock(&dchid->ifaces_lock);
> + return NULL;
> + }
> +
> + if (!strcmp(name, "comm")) {
> + /* Comm is not a HID subdevice */
> + dchid->ifaces[index] = iface;
> + mutex_unlock(&dchid->ifaces_lock);
> + return iface;
> + }
> +
> + fwnode = device_get_named_child_node(dchid->dev, name);
> + if (fwnode) {
> + iface->fwnode = fwnode;
> + ret = devm_add_action_or_reset(dchid->dev, dchid_fwnode_release,
> + iface->fwnode);
> + if (ret) {
> + mutex_unlock(&dchid->ifaces_lock);
> + return NULL;
> + }
> + } else {
> + iface->fwnode = dev_fwnode(dchid->dev);
> + }
> +
> + dchid->ifaces[index] = iface;
> + mutex_unlock(&dchid->ifaces_lock);
> + return iface;
> +}
> +
> +static int dchid_send(struct dchid_iface *iface, u32 flags, const void *msg,
> + size_t size)
> +{
> + struct dchid_dev *dchid = iface->dchid;
> + size_t payload_padded = round_up(size, sizeof(u32));
> + size_t total_len = sizeof(struct dchid_hdr) + sizeof(struct dchid_subhdr) +
> + payload_padded + DCHID_CHECKSUM_LEN;
> + struct apple_dockchannel_msg dc_msg;
> + struct dchid_hdr *hdr;
> + struct dchid_subhdr *sub;
> + u32 *checksum_ptr;
> + u8 *buf;
> + int ret;
> +
> + if (total_len > DCHID_RX_BUF_SIZE)
> + return -EINVAL;
> +
> + buf = kzalloc(total_len, GFP_KERNEL);
> + if (!buf)
> + return -ENOMEM;
> +
> + hdr = (struct dchid_hdr *)buf;
> + sub = (struct dchid_subhdr *)(buf + sizeof(*hdr));
> + checksum_ptr = (u32 *)(buf + total_len - DCHID_CHECKSUM_LEN);
> +
> + hdr->hdr_len = sizeof(*hdr);
> + hdr->channel = DCHID_CHANNEL_CMD;
> + hdr->length = cpu_to_le16(payload_padded + sizeof(*sub));
> + hdr->seq = iface->tx_seq;
> + hdr->iface = iface->index;
> +
> + sub->flags = (u8)flags;
> + sub->length = cpu_to_le16(size);
> +
> + memcpy(buf + sizeof(*hdr) + sizeof(*sub), msg, size);
> +
> + *checksum_ptr = 0xffffffff - dchid_checksum(buf, total_len - DCHID_CHECKSUM_LEN);
> +
> + dc_msg.data = buf;
> + dc_msg.len = total_len;
> + ret = mbox_send_message(dchid->dc_mbox, &dc_msg);
> + kfree(buf);
> +
> + return ret < 0 ? ret : 0;
> +}
> +
> +static int dchid_cmd(struct dchid_iface *iface, u32 type, u32 req,
> + void *data, size_t size, void *resp_buf, size_t resp_size)
> +{
> + unsigned long flags;
> + int ret;
> + int report_id;
> + bool timed_out = false;
> + u32 out_flags;
> +
> + if (size < 1)
> + return -EINVAL;
> +
> + report_id = *(u8 *)data;
> + out_flags = FIELD_PREP(FLAGS_GROUP, type) | FIELD_PREP(FLAGS_REQ, req);
> +
> + spin_lock_irqsave(&iface->out_lock, flags);
> +
> + /* Only one command can be in flight per interface */
> + if (WARN_ON(iface->out_report != -1)) {
> + spin_unlock_irqrestore(&iface->out_lock, flags);
> + return -EBUSY;
> + }
> +
> + iface->out_report = report_id;
> + iface->out_flags = out_flags;
> + iface->retcode = 0;
> + iface->resp_buf = resp_buf;
> + iface->resp_size = resp_size;
> + reinit_completion(&iface->out_complete);
> +
> + spin_unlock_irqrestore(&iface->out_lock, flags);
> +
> + ret = dchid_send(iface, out_flags, data, size);
> + if (ret < 0) {
> + spin_lock_irqsave(&iface->out_lock, flags);
> + iface->out_report = -1;
> + iface->resp_buf = NULL;
> + iface->resp_size = 0;
> + spin_unlock_irqrestore(&iface->out_lock, flags);
> + return ret;
> + }
> +
> + if (!wait_for_completion_timeout(&iface->out_complete,
> + msecs_to_jiffies(COMMAND_TIMEOUT_MS))) {
> + dev_err(iface->dchid->dev, "command 0x%x to iface %d (%s) timed out\n",
> + report_id, iface->index, iface->name);
> + timed_out = true;
> + }
> +
> + spin_lock_irqsave(&iface->out_lock, flags);
> +
> + if (timed_out && iface->out_report == report_id) {
> + ret = -ETIMEDOUT;
> + } else if (iface->retcode) {
> + dev_err(iface->dchid->dev,
> + "command 0x%x to iface %d (%s) failed with err 0x%x\n",
> + report_id, iface->index, iface->name, iface->retcode);
> + ret = -EIO;
> + } else {
> + ret = iface->resp_size;
> + }
> +
> + iface->tx_seq++;
> + iface->out_report = -1;
> + iface->resp_buf = NULL;
> + iface->resp_size = 0;
> + spin_unlock_irqrestore(&iface->out_lock, flags);
> +
> + return ret;
> +}
> +
> +static int dchid_comm_cmd(struct dchid_dev *dchid, void *cmd, size_t size)
> +{
> + return dchid_cmd(dchid->comm, HID_FEATURE_REPORT, REQ_SET_REPORT,
> + cmd, size, NULL, 0);
> +}
> +
> +static int dchid_enable_interface(struct dchid_iface *iface)
> +{
> + u8 cmd[] = { CMD_ENABLE_INTERFACE, iface->index };
> +
> + return dchid_comm_cmd(iface->dchid, cmd, sizeof(cmd));
> +}
> +
> +static int dchid_reset_interface(struct dchid_iface *iface, int state)
> +{
> + u8 cmd[] = { CMD_RESET_INTERFACE, CMD_RESET_INTERFACE_SUB, iface->index,
> + (u8)state };
> +
> + return dchid_comm_cmd(iface->dchid, cmd, sizeof(cmd));
> +}
> +
> +static int dchid_start_interface(struct dchid_iface *iface)
> +{
> + if (iface->starting)
> + return -EINPROGRESS;
> +
> + dev_dbg(iface->dchid->dev, "starting interface %s\n", iface->name);
> +
> + iface->starting = true;
> + dchid_reset_interface(iface, 0);
> + dchid_reset_interface(iface, 2);
> +
> + return 0;
> +}
> +
> +static int dchid_start(struct hid_device *hdev)
> +{
> + return 0;
> +}
> +
> +static int dchid_open(struct hid_device *hdev)
> +{
> + struct dchid_iface *iface = hdev->driver_data;
> + int ret;
> +
> + if (!completion_done(&iface->ready)) {
> + ret = dchid_start_interface(iface);
> + if (ret < 0)
> + return ret;
> +
> + if (!wait_for_completion_timeout(&iface->ready,
> + msecs_to_jiffies(START_TIMEOUT_MS))) {
> + dev_err(iface->dchid->dev, "iface %s start timed out\n",
> + iface->name);
> + return -ETIMEDOUT;
> + }
> + }
> +
> + iface->open = true;
> + return 0;
> +}
> +
> +static void dchid_close(struct hid_device *hdev)
> +{
> + struct dchid_iface *iface = hdev->driver_data;
> +
> + iface->open = false;
> +}
> +
> +static int dchid_parse(struct hid_device *hdev)
> +{
> + struct dchid_iface *iface = hdev->driver_data;
> +
> + return hid_parse_report(hdev, iface->hid_desc, iface->hid_desc_len);
> +}
> +
> +/* Note: buf excludes report number. */
> +static int dchid_get_report_cmd(struct dchid_iface *iface, u8 reportnum,
> + void *buf, size_t len)
> +{
> + int ret;
> +
> + ret = dchid_cmd(iface, HID_FEATURE_REPORT, REQ_GET_REPORT, &reportnum, 1,
> + buf, len);
> +
> + return ret <= 0 ? ret : ret - 1;
> +}
> +
> +/* Note: buf includes report number. */
> +static int dchid_set_report(struct dchid_iface *iface, void *buf, size_t len)
> +{
> + return dchid_cmd(iface, HID_OUTPUT_REPORT, REQ_SET_REPORT, buf, len,
> + NULL, 0);
> +}
> +
> +static int dchid_raw_request(struct hid_device *hdev, unsigned char reportnum,
> + __u8 *buf, size_t len, unsigned char rtype,
> + int reqtype)
> +{
> + struct dchid_iface *iface = hdev->driver_data;
> +
> + switch (reqtype) {
> + case HID_REQ_GET_REPORT:
> + if (len < 1)
> + return -EINVAL;
> +
> + buf[0] = reportnum;
> + return dchid_cmd(iface, rtype, REQ_GET_REPORT, &reportnum, 1,
> + buf + 1, len - 1);
> + case HID_REQ_SET_REPORT:
> + return dchid_set_report(iface, buf, len);
> + default:
> + return -EIO;
> + }
> +}
> +
> +static const struct hid_ll_driver dchid_ll = {
> + .start = dchid_start,
> + .open = dchid_open,
> + .close = dchid_close,
> + .parse = dchid_parse,
> + .raw_request = dchid_raw_request,
> +};
> +
> +static void dchid_create_interface_work(struct work_struct *ws)
> +{
> + struct dchid_iface *iface = container_of(ws, struct dchid_iface, create_work);
> + struct dchid_dev *dchid = iface->dchid;
> + struct hid_device *hid;
> + char cap_name[16];
> + int ret;
> +
> + if (iface->hid) {
> + dev_warn(dchid->dev, "interface %s already created\n", iface->name);
> + goto done;
> + }
> +
> + ret = dchid_enable_interface(iface);
> + if (ret < 0) {
> + dev_warn(dchid->dev, "failed to enable %s: %d\n", iface->name, ret);
> + goto done;
> + }
> +
> + iface->deferred = false;
> +
> + hid = hid_allocate_device();
> + if (IS_ERR(hid))
> + goto done;
> +
> + strscpy(cap_name, iface->name, sizeof(cap_name));
> + if (cap_name[0])
> + cap_name[0] = toupper(cap_name[0]);
> + snprintf(hid->name, sizeof(hid->name), "Apple DockChannel %s", cap_name);
> +
> + snprintf(hid->phys, sizeof(hid->phys), "%s.%d", dev_name(dchid->dev),
> + iface->index);
> + strscpy(hid->uniq, dchid->serial, sizeof(hid->uniq));
If the keyboard appeared before stm, dchip->serial might be uninitialized.
> +
> + hid->ll_driver = &dchid_ll;
> + hid->bus = BUS_HOST;
> + hid->vendor = le16_to_cpu(dchid->device_id.vendor_id);
> + hid->product = le16_to_cpu(dchid->device_id.product_id);
> + hid->version = le16_to_cpu(dchid->device_id.version_number);
> + hid->type = HID_TYPE_OTHER;
> + if (!strcmp(iface->name, "keyboard")) {
> + u32 country_code;
> +
> + hid->group = HID_GROUP_APPLE_DOCKCHANNEL;
> +
> + /*
> + * The device provides no reliable way to get the keyboard
> + * country code, so board devicetrees provide it instead,
> + * filled by the bootloader.
> + */
> + if (!fwnode_property_read_u32(iface->fwnode, "hid-country-code",
> + &country_code))
> + hid->country = country_code;
> + }
> +
> + hid->dev.parent = iface->dchid->dev;
> + hid->driver_data = iface;
> + iface->hid = hid;
> +
> + ret = hid_add_device(hid);
> + if (ret < 0) {
> + iface->hid = NULL;
> + hid_destroy_device(hid);
> + dev_warn(iface->dchid->dev, "failed to register HID device %s\n",
> + iface->name);
> + }
> +
> +done:
> + iface->creating = false;
> +}
> +
> +static int dchid_create_interface(struct dchid_iface *iface)
> +{
> + if (iface->creating)
> + return -EBUSY;
> +
> + iface->creating = true;
> + INIT_WORK(&iface->create_work, dchid_create_interface_work);
> + return queue_work(iface->dchid->new_iface_wq, &iface->create_work);
> +}
> +
> +static void dchid_handle_descriptor(struct dchid_iface *iface, void *hid_desc,
> + size_t desc_len)
> +{
> + u8 *rdesc;
> + int i;
> +
> + if (iface->hid)
> + return;
> +
> + rdesc = devm_kmemdup(iface->dchid->dev, hid_desc, desc_len,
> + GFP_KERNEL);
> + if (!rdesc)
> + return;
> +
> + /* Fix up oversized report sizes in DockChannel report descriptors */
> + if (desc_len >= 5) {
> + for (i = 0; i <= (int)desc_len - 5; i++) {
> + if (rdesc[i] == 0x76 && rdesc[i + 1] == 0x00 &&
> + rdesc[i + 2] == 0x40 && rdesc[i + 3] == 0x95) {
> + u8 count = rdesc[i + 4];
> +
> + if (count > 0 && count < 32) {
> + dev_info(iface->dchid->dev,
> + "fixing up interface %s (%d) report size\n",
> + iface->name, iface->index);
> + rdesc[i] = 0x75;
> + rdesc[i + 1] = 0x08;
> + rdesc[i + 2] = 0x96;
> + rdesc[i + 3] = 0x00;
> + rdesc[i + 4] = count * 8;
> + }
> + }
> + }
> + }
> +
> + iface->hid_desc = rdesc;
> + iface->hid_desc_len = desc_len;
> +}
> +
> +static void dchid_handle_ready(struct dchid_dev *dchid, void *data, size_t length)
> +{
> + struct dchid_iface *iface;
> + u8 *pkt = data;
> + u8 index;
> + int i;
> + int ret;
> +
> + if (length < 2)
> + return;
> +
> + index = pkt[1];
> + if (index >= MAX_INTERFACES)
> + return;
> +
> + iface = dchid->ifaces[index];
> + if (!iface)
> + return;
> +
> + dev_dbg(dchid->dev, "interface %s is now ready\n", iface->name);
> + complete_all(&iface->ready);
> +
> + /* When STM is ready, grab global device info */
> + if (!strcmp(iface->name, "stm")) {
> + ret = dchid_get_report_cmd(iface, STM_REPORT_ID, &dchid->device_id,
> + sizeof(dchid->device_id));
> + if (ret < (int)sizeof(dchid->device_id)) {
> + dev_warn(iface->dchid->dev, "failed to get device ID from STM\n");
> + /* Fake it and keep going. Things might still work. */
> + memset(&dchid->device_id, 0, sizeof(dchid->device_id));
> + }
> +
> + ret = dchid_get_report_cmd(iface, STM_REPORT_SERIAL, dchid->serial,
> + sizeof(dchid->serial) - 1);
> + if (ret < 0) {
> + dev_warn(iface->dchid->dev, "failed to get serial from STM\n");
> + dchid->serial[0] = 0;
> + }
> +
> + dchid->id_ready = true;
> + for (i = 0; i < MAX_INTERFACES; i++) {
> + if (!dchid->ifaces[i] || !dchid->ifaces[i]->deferred)
> + continue;
> + dchid_create_interface(dchid->ifaces[i]);
> + }
> + }
> +}
> +
> +static void dchid_handle_init(struct dchid_dev *dchid, void *data, size_t length)
> +{
> + struct dchid_init_hdr *hdr = data;
> + struct dchid_init_block_hdr *blk;
> + struct dchid_iface *iface;
> + u8 *p = data;
> +
> + if (length < sizeof(*hdr))
> + return;
> +
> + iface = dchid_get_interface(dchid, hdr->iface, hdr->name);
> + if (!iface)
> + return;
> +
> + p += sizeof(*hdr);
> + length -= sizeof(*hdr);
> +
> + while (length >= sizeof(*blk)) {
> + u16 blk_len;
> +
> + blk = (struct dchid_init_block_hdr *)p;
> + p += sizeof(*blk);
> + length -= sizeof(*blk);
> +
> + blk_len = le16_to_cpu(blk->length);
> + if (blk_len > length)
> + break;
> +
> + switch (le16_to_cpu(blk->type)) {
> + case INIT_HID_DESCRIPTOR:
> + dchid_handle_descriptor(iface, p, blk_len);
> + break;
> + case INIT_PRODUCT_NAME:
> + if (blk_len > 0 && p[blk_len - 1] != 0)
> + dev_warn(dchid->dev, "unterminated product name for %s\n",
> + iface->name);
> + break;
> + }
> +
> + p += blk_len;
> + length -= blk_len;
> +
> + if (le16_to_cpu(blk->type) == INIT_TERMINATOR)
> + break;
> + }
> +
> + if (hdr->more_packets)
> + return;
> +
> + /*
> + * Prefer to enable STM first, since it provides device IDs. Some
> + * firmware versions do not expose STM, so let the keyboard start
> + * without it.
> + */
> + if (iface->dchid->id_ready || !strcmp(iface->name, "stm") ||
> + !strcmp(iface->name, "keyboard"))
I specifically asked for a mechanism to let the keyboard probe even on
devices which do not expose/have stm. Thanks for adding that!
However, I think this might need some more sophisticated mechanism to
decide whether the stm is still going to appear after the keyboard, or
not at all. I'm not sure if there is a way to tell this at this point,
or we need to add a timeout for the stm to appearing, which needs to
expire before we create the other interfaces with fake serials.
> + dchid_create_interface(iface);
> + else
> + iface->deferred = true;
> +}
> +
> +static void dchid_handle_event(struct dchid_dev *dchid, void *data, size_t length)
> +{
> + u8 *p = data;
> +
> + if (!length)
> + return;
> +
> + switch (*p) {
> + case EVENT_INIT:
> + dchid_handle_init(dchid, data, length);
> + break;
> + case EVENT_READY:
> + dchid_handle_ready(dchid, data, length);
> + break;
> + }
> +}
> +
> +static void dchid_handle_report(struct dchid_iface *iface, void *data, size_t length)
> +{
> + if (!iface->hid || !iface->open)
> + return;
> +
> + hid_input_report(iface->hid, HID_INPUT_REPORT, data, length, 1);
> +}
> +
> +static void dchid_packet_work(struct work_struct *ws)
> +{
> + struct dchid_work *work = container_of(ws, struct dchid_work, work);
> + struct dchid_subhdr *shdr = (void *)work->data;
> + struct dchid_dev *dchid = work->iface->dchid;
> + u16 hdr_len = le16_to_cpu(work->hdr.length);
> + u16 sub_len;
> + int type;
> + u8 *payload;
> +
> + if (hdr_len < sizeof(*shdr)) {
> + dev_err(dchid->dev, "bad subheader length\n");
> + goto done;
> + }
> +
> + sub_len = le16_to_cpu(shdr->length);
> + if (sub_len > hdr_len - sizeof(*shdr)) {
> + dev_err(dchid->dev, "bad subheader length\n");
> + goto done;
> + }
> +
> + type = FIELD_GET(FLAGS_GROUP, shdr->flags);
> + payload = work->data + sizeof(*shdr);
> +
> + switch (type) {
> + case HID_INPUT_REPORT:
> + if (work->hdr.iface == IFACE_COMM)
> + dchid_handle_event(dchid, payload, sub_len);
> + else
> + dchid_handle_report(work->iface, payload, sub_len);
> + break;
> + }
> +
> +done:
> + kfree(work);
> +}
> +
> +static void dchid_handle_ack(struct dchid_iface *iface, struct dchid_hdr *hdr,
> + void *data)
> +{
> + struct dchid_subhdr *shdr = data;
> + u8 *payload = data + sizeof(*shdr);
> + u16 hdr_len = le16_to_cpu(hdr->length);
> + u16 sub_len = le16_to_cpu(shdr->length);
> + unsigned long flags;
> + bool complete_cmd = false;
> +
> + if (hdr_len < sizeof(*shdr) || sub_len > hdr_len - sizeof(*shdr) ||
> + sub_len < 1)
> + return;
> +
> + spin_lock_irqsave(&iface->out_lock, flags);
> +
> + if (shdr->flags == iface->out_flags && iface->tx_seq == hdr->seq &&
> + iface->out_report == payload[0]) {
> + if (iface->resp_buf && iface->resp_size)
> + memcpy(iface->resp_buf, payload + 1,
> + min_t(size_t, sub_len - 1, iface->resp_size));
> +
> + iface->resp_size = sub_len;
> + iface->out_report = -1;
> + iface->retcode = le32_to_cpu(shdr->retcode);
> + complete_cmd = true;
> + }
> +
> + spin_unlock_irqrestore(&iface->out_lock, flags);
> +
> + if (complete_cmd)
> + complete(&iface->out_complete);
> +}
> +
> +static void dchid_process_packet(struct dchid_dev *dchid, struct dchid_hdr *hdr,
> + u8 *payload, size_t payload_len, u8 *packet,
> + size_t packet_len)
> +{
> + struct dchid_work *work;
> +
> + if (dchid_checksum(packet, packet_len) != DCHID_CHECKSUM_SEED) {
> + dev_err_ratelimited(dchid->dev, "checksum error\n");
> + return;
> + }
> +
> + if (payload_len < sizeof(struct dchid_subhdr))
> + return;
> +
> + if (hdr->iface >= MAX_INTERFACES || !dchid->ifaces[hdr->iface])
> + return;
> +
> + if (hdr->channel == DCHID_CHANNEL_CMD) {
> + dchid_handle_ack(dchid->ifaces[hdr->iface], hdr, payload);
> + return;
> + }
> +
> + if (hdr->channel != DCHID_CHANNEL_REPORT)
> + return;
> +
> + work = kzalloc(sizeof(*work) + payload_len, GFP_ATOMIC);
> + if (!work)
> + return;
> +
> + work->hdr = *hdr;
> + work->iface = dchid->ifaces[hdr->iface];
> + memcpy(work->data, payload, payload_len);
> + INIT_WORK(&work->work, dchid_packet_work);
> +
> + queue_work(work->iface->wq, &work->work);
> +}
> +
> +static void dchid_consume_rx(struct dchid_dev *dchid)
> +{
> + while (dchid->rx_len >= sizeof(struct dchid_hdr)) {
> + struct dchid_hdr *hdr = (struct dchid_hdr *)dchid->rx_buf;
> + size_t payload_len;
> + size_t packet_len;
> +
> + if (hdr->hdr_len != sizeof(*hdr)) {
> + dev_err_ratelimited(dchid->dev, "bad header length %u\n",
> + hdr->hdr_len);
> + dchid->rx_len = 0;
> + return;
> + }
> +
> + payload_len = le16_to_cpu(hdr->length);
> + packet_len = sizeof(*hdr) + payload_len + DCHID_CHECKSUM_LEN;
> + if (packet_len > DCHID_RX_BUF_SIZE) {
> + dev_err_ratelimited(dchid->dev, "oversized packet %zu\n",
> + packet_len);
> + dchid->rx_len = 0;
> + return;
> + }
> +
> + if (dchid->rx_len < packet_len)
> + return;
> +
> + dchid_process_packet(dchid, hdr, dchid->rx_buf + sizeof(*hdr),
> + payload_len, dchid->rx_buf, packet_len);
> +
> + dchid->rx_len -= packet_len;
> + memmove(dchid->rx_buf, dchid->rx_buf + packet_len, dchid->rx_len);
> + }
> +}
> +
> +static void dchid_rx_callback(struct mbox_client *cl, void *mssg)
> +{
> + struct dchid_dev *dchid = container_of(cl, struct dchid_dev, dc_mbox_client);
> + struct apple_dockchannel_msg *msg = mssg;
> +
> + if (!msg || !msg->data || !msg->len)
> + return;
> +
> + if (msg->len > DCHID_RX_BUF_SIZE - dchid->rx_len) {
> + dev_err_ratelimited(dchid->dev, "RX buffer overflow\n");
> + dchid->rx_len = 0;
> + return;
> + }
> +
> + memcpy(dchid->rx_buf + dchid->rx_len, msg->data, msg->len);
> + dchid->rx_len += msg->len;
> +
> + dchid_consume_rx(dchid);
> +}
> +
> +static int dchid_rtkit_shmem_setup(void *cookie, struct apple_rtkit_shmem *bfr)
> +{
> + struct dchid_dev *dchid = cookie;
> + struct resource res = {
> + .start = bfr->iova,
> + .end = bfr->iova + bfr->size - 1,
> + .name = "rtkit_map",
> + };
> +
> + if (!bfr->iova) {
> + bfr->buffer = dma_alloc_coherent(dchid->dev, bfr->size,
> + &bfr->iova, GFP_KERNEL);
> + if (!bfr->buffer)
> + return -ENOMEM;
> + return 0;
> + }
> +
> + if (!dchid->sram_res.start)
> + return -EFAULT;
> +
> + res.flags = dchid->sram_res.flags;
> + if (res.end < res.start || !resource_contains(&dchid->sram_res, &res))
> + return -EFAULT;
> +
> + bfr->iomem = dchid->sram_base + (res.start - dchid->sram_res.start);
> + bfr->is_mapped = true;
> +
> + return 0;
> +}
> +
> +static void dchid_rtkit_shmem_destroy(void *cookie, struct apple_rtkit_shmem *bfr)
> +{
> + struct dchid_dev *dchid = cookie;
> +
> + if (bfr->buffer)
> + dma_free_coherent(dchid->dev, bfr->size, bfr->buffer, bfr->iova);
> +}
> +
> +static const struct apple_rtkit_ops dchid_rtkit_ops = {
> + .shmem_setup = dchid_rtkit_shmem_setup,
> + .shmem_destroy = dchid_rtkit_shmem_destroy,
> +};
> +
> +static int dchid_map_helper_cpu(struct platform_device *pdev, struct dchid_dev *dchid)
> +{
> + struct resource *res;
> +
> + dchid->asc_base = devm_platform_ioremap_resource_byname(pdev, "coproc-asc");
> + if (IS_ERR(dchid->asc_base))
> + return PTR_ERR(dchid->asc_base);
> +
> + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "coproc-sram");
> + if (!res)
> + return -EINVAL;
> +
> + dchid->sram_res = *res;
> +
> + dchid->sram_base = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(dchid->sram_base))
> + return PTR_ERR(dchid->sram_base);
> +
> + return 0;
> +}
> +
> +static int dchid_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct dchid_dev *dchid;
> + int ret;
> +
> + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(44));
> + if (ret)
> + return dev_err_probe(dev, ret, "failed to set DMA mask\n");
> +
> + dchid = devm_kzalloc(dev, sizeof(*dchid), GFP_KERNEL);
> + if (!dchid)
> + return -ENOMEM;
> +
> + dchid->rx_buf = devm_kmalloc(dev, DCHID_RX_BUF_SIZE, GFP_KERNEL);
> + if (!dchid->rx_buf)
> + return -ENOMEM;
> +
> + dchid->dev = dev;
> + mutex_init(&dchid->ifaces_lock);
> + platform_set_drvdata(pdev, dchid);
> +
> + ret = dchid_map_helper_cpu(pdev, dchid);
> + if (ret)
> + return dev_err_probe(dev, ret, "failed to map helper CPU\n");
> +
> + dchid->dc_mbox_client.dev = dev;
> + dchid->dc_mbox_client.tx_block = true;
> + dchid->dc_mbox_client.rx_callback = dchid_rx_callback;
> +
> + dchid->dc_mbox = mbox_request_channel_byname(&dchid->dc_mbox_client,
> + "dockchannel");
> + if (IS_ERR(dchid->dc_mbox))
> + return dev_err_probe(dev, PTR_ERR(dchid->dc_mbox),
> + "failed to request DockChannel mailbox\n");
> +
> + ret = devm_add_action_or_reset(dev, dchid_free_mbox, dchid->dc_mbox);
> + if (ret)
> + return ret;
> +
> + dchid->rtk = devm_apple_rtkit_init(dev, dchid, "asc", 0, &dchid_rtkit_ops);
> + if (IS_ERR(dchid->rtk))
> + return dev_err_probe(dev, PTR_ERR(dchid->rtk), "failed to init RTKit\n");
> +
> + writel_relaxed(APPLE_ASC_CPU_CONTROL_RUN,
> + dchid->asc_base + APPLE_ASC_CPU_CONTROL);
> +
> + ret = apple_rtkit_wake(dchid->rtk);
> + if (ret)
> + return dev_err_probe(dev, ret, "failed to wake coprocessor\n");
> +
> + dchid->new_iface_wq = alloc_ordered_workqueue("dchid-new", 0);
> + if (!dchid->new_iface_wq)
> + return dev_err_probe(dev, -ENOMEM, "failed to allocate workqueue\n");
> +
> + ret = devm_add_action_or_reset(dev, dchid_destroy_wq, dchid->new_iface_wq);
> + if (ret)
> + return ret;
> +
> + dchid->comm = dchid_get_interface(dchid, IFACE_COMM, "comm");
> + if (!dchid->comm)
> + return dev_err_probe(dev, -EIO, "failed to init comm interface\n");
> +
> + return 0;
> +}
> +
> +static void dchid_remove(struct platform_device *pdev)
> +{
> + struct dchid_dev *dchid = platform_get_drvdata(pdev);
> + int i;
> +
> + if (dchid->dc_mbox) {
> + devm_release_action(&pdev->dev, dchid_free_mbox, dchid->dc_mbox);
> + dchid->dc_mbox = NULL;
> + }
> +
> + if (dchid->rtk && apple_rtkit_is_running(dchid->rtk))
> + apple_rtkit_quiesce(dchid->rtk);
> +
> + if (dchid->asc_base)
> + writel_relaxed(0, dchid->asc_base + APPLE_ASC_CPU_CONTROL);
> +
> + for (i = 0; i < MAX_INTERFACES; i++) {
> + struct dchid_iface *iface = dchid->ifaces[i];
> +
> + if (!iface)
> + continue;
> +
> + cancel_work_sync(&iface->create_work);
> + flush_workqueue(iface->wq);
> +
> + if (iface->hid)
> + hid_destroy_device(iface->hid);
> + }
> +
> + if (dchid->new_iface_wq)
> + flush_workqueue(dchid->new_iface_wq);
> +}
> +
> +static const struct of_device_id dchid_of_match[] = {
> + { .compatible = "apple,t8122-dockchannel-hid" },
> + { .compatible = "apple,t8112-dockchannel-hid" },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, dchid_of_match);
> +
> +static struct platform_driver dchid_platform_driver = {
> + .driver = {
> + .name = "dockchannel-hid",
> + .of_match_table = dchid_of_match,
> + },
> + .probe = dchid_probe,
> + .remove = dchid_remove,
> +};
> +module_platform_driver(dchid_platform_driver);
> +
> +MODULE_DESCRIPTION("Apple DockChannel HID transport driver");
> +MODULE_AUTHOR("Hector Martin <marcan@marcan.st>");
> +MODULE_AUTHOR("Michael Reeves <michael.reeves077@gmail.com>");
> +MODULE_LICENSE("Dual MIT/GPL");
>
^ permalink raw reply
* Re: [PATCH v3 2/7] gpio: regmap: add gpio_regmap_get_gpiochip() accessor
From: Linus Walleij @ 2026-06-30 13:21 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Michael Walle, Bartosz Golaszewski, robh@kernel.org,
krzk+dt@kernel.org, conor+dt@kernel.org, afaerber@suse.com,
wbg@kernel.org, mathieu.dubois-briand@bootlin.com,
lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org,
nuno.sa@analog.com, andy@kernel.org, dlechner@baylibre.com,
TY_Chang[張子逸], linux-gpio@vger.kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-realtek-soc@lists.infradead.org, linux-iio@vger.kernel.org,
CY_Huang[黃鉦晏],
Stanley Chang[昌育德],
James Tai [戴志峰],
Yu-Chun Lin [林祐君]
In-Reply-To: <ajkP4DHN4JPjr6yb@ashevche-desk.local>
On Mon, Jun 22, 2026 at 11:35 AM Andy Shevchenko
<andriy.shevchenko@intel.com> wrote:
> So, when we instantiate our own domain in regmap GPIO, we should have those
> callbacks be defined somewhere?
Domains are just translators, but if you create an irq chip it should
ideally have these callbacks.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH rc v7 0/7] iommu/arm-smmu-v3: Fix device crash on kdump kernel
From: Mostafa Saleh @ 2026-06-30 13:17 UTC (permalink / raw)
To: Nicolin Chen
Cc: will, robin.murphy, jgg, joro, praan, kees, baolu.lu, kevin.tian,
miko.lenczewski, linux-arm-kernel, iommu, linux-kernel, stable,
jamien
In-Reply-To: <cover.1782799827.git.nicolinc@nvidia.com>
On Mon, Jun 29, 2026 at 11:15:33PM -0700, Nicolin Chen wrote:
> When transitioning to a kdump kernel, the primary kernel might have crashed
> while endpoint devices were actively bus-mastering DMA. Currently, the SMMU
> driver aggressively resets the hardware during probe by clearing CR0_SMMUEN
> and setting the Global Bypass Attribute (GBPA) to ABORT.
>
> In a kdump scenario, this aggressive reset is highly destructive:
> a) If GBPA is set to ABORT, in-flight DMA will be aborted, generating fatal
> PCIe AER or SErrors that may panic the kdump kernel
Can you please clarify more on those errors, what conditions will
trigger that?
For example, patch 4 disables the EVTQ to avoid events as there might
be a lot, why are they not fatal also?
> b) If GBPA is set to BYPASS, in-flight DMA targeting some IOVAs will bypass
> the SMMU and corrupt the physical memory at those 1:1 mapped IOVAs.
>
> To safely absorb in-flight DMA, the kdump kernel must leave SMMUEN=1 intact
> and avoid modifying STRTAB_BASE. This allows HW to continue translating in-
> flight DMA using the crashed kernel's page tables until the endpoint device
> drivers probe and quiesce their respective hardware.
>
> However, the ARM SMMUv3 architecture specification states that updating the
> SMMU_STRTAB_BASE register while SMMUEN == 1 is UNPREDICTABLE or ignored.
>
> This leaves a kdump kernel no choice but to adopt the stream table from the
> crashed kernel.
In many cases the patches assume that the CDs/STE might be corrupted,
but still attempt to retrieve them with some validation
(log2size/split...)
However, the base address might be broken, TLBs state is unknown...
IMO, although that might improve the status quo, there are still
heuristics, in addition to noticeable complexity to transition the
stream tables. I wonder if FW can deal with AER in that case before
booting the kdump kernel.
Thanks,
Mostafa
>
> In this series:
> - Introduce an ARM_SMMU_OPT_KDUMP_ADOPT
> - Skip SMMUEN and STRTAB_BASE resets in arm_smmu_device_reset()
> - Skip EVENTQ/PRIQ setup including interrupts and their handlers
> - Memremap the crashed kernel's stream tables into the kdump kernel [*]
> - Defer any default domain attachment to retain STEs until device drivers
> explicitly request it.
>
> [*] For verification reasons, this series only fixes coherent SMMUs.
>
> For non-ARM_SMMU_OPT_KDUMP_ADOPT cases, keep a status quo since the commit
> 3f54c447df34f ("iommu/arm-smmu-v3: Don't disable SMMU in kdump kernel"):
> full reset followed by driver-initiated reattach, potentially rejecting any
> in-flight DMA.
>
> Note that the series requires Jason's work that was merged in v6.12: commit
> 85196f54743d ("iommu/arm-smmu-v3: Reorganize struct arm_smmu_strtab_cfg").
> I have a backported version that is verified with a v6.8 kernel. I can send
> if we see a strong need after this version is accepted.
>
> This is on Github:
> https://github.com/nicolinc/iommufd/commits/smmuv3_kdump-v7
>
> Changelog
> v7
> * Rebase v7.2-rc1
> * Add Reviewed-by from Pranjal
> * Reword the linear stream table adoption comment
> * Use dev_dbg for the stream table adoption message
> * Document why the lazy L2 adoption uses devm_memremap()
> * Drop redundant FEAT_COHERENCY checks in the adopt functions
> * Use feature bit instead of STRTAB_BASE_CFG in adopt cleanup
> * Skip CR0_ATSCHK update in adopt mode to retain the crashed policy
> * Restore FEAT_2_LVL_STRTAB if the cleanup action fails to register
> v6
> https://lore.kernel.org/all/cover.1779265413.git.nicolinc@nvidia.com/
> * Rebase v7.1-rc3
> * Add Reviewed-by from Jason
> * Replace dma_addr_t with phys_addr_t
> * Drop arm_smmu_kdump_phys_is_corrupted()
> * Skip threaded IRQ handlers for EVTQ and PRIQ
> * Bypass arm_smmu_rmr_install_bypass_ste() in kdump case
> * Drop devm_ for adopt-time allocations; set up cleanup function via
> devm_add_action_or_reset()
> v5
> https://lore.kernel.org/all/cover.1778416609.git.nicolinc@nvidia.com/
> * Add Reviewed-by from Kevin
> * Drop READ_ONCE on lazy-attach L1 read
> * Split "Skip EVTQ/PRIQ setup" into two patches
> * Tighten kdump probe comment and dev_warn message
> * Use MEM + BUSY in arm_smmu_kdump_phys_is_corrupted
> v4
> https://lore.kernel.org/all/cover.1777446969.git.nicolinc@nvidia.com/
> * Rebase v7.1-rc1
> * s/arm_smmu_adopt/arm_smmu_kdump_adopt
> * Revert alloc/memremap/fmt on fallback
> * Reorder patches to avoid bisect regression
> * Use IRQ_NONE for spurious evtq/priq entries
> * Cap linear log2size by kdump's allocation bound
> * Defer clearing FEAT_2_LVL_STRTAB on linear adopt
> * Add arm_smmu_kdump_phys_is_corrupted() validation
> * Defer l2 stream table memremap till master inserts
> * Re-validate L1 desc on master insert with READ_ONCE
> v3
> https://lore.kernel.org/all/cover.1777150307.git.nicolinc@nvidia.com/
> * s/OPT_KDUMP/OPT_KDUMP_ADOPT
> * Do not adopt if GERROR_SFM_ERR
> * Retain CR0_ATSCHK beside CR0_SMMUEN
> * Clear latched GERROR bits (e.g. CMDQ_ERR)
> * Assert ARM_SMMU_FEAT_COHERENCY in adopt functions
> * Add STE.Cfg check in arm_smmu_is_attach_deferred()
> * Fix validations on return codes from devm_memremap()
> * Sanitize crashed kernel register values in adopt functions
> * Drop unnecessary l2ptrs guard in arm_smmu_is_attach_deferred()
> * Don't enable PRIQ/EVTQ irqs and guard the irq functions for combined
> irq cases
> v2
> https://lore.kernel.org/all/cover.1776286352.git.nicolinc@nvidia.com/
> * Add warning in non-coherent SMMU cases
> * Keep eventq/priq disabled vs. enabling-and-disabling-later
> * Check KDUMP option in the beginning of arm_smmu_device_reset()
> * Validate STRTAB format matches HW capability instead of forcing flags
> v1:
> https://lore.kernel.org/all/cover.1775763475.git.nicolinc@nvidia.com/
>
> Nicolin Chen (7):
> iommu/arm-smmu-v3: Add arm_smmu_kdump_adopt_strtab() for kdump
> iommu/arm-smmu-v3: Implement is_attach_deferred() for kdump
> iommu/arm-smmu-v3: Do not enable EVTQ/PRIQ interrupts in kdump kernel
> iommu/arm-smmu-v3: Skip EVTQ/PRIQ setup in kdump kernel
> iommu/arm-smmu-v3: Retain CR0_SMMUEN during kdump device reset
> iommu/arm-smmu-v3: Skip RMR bypass for kdump adoption
> iommu/arm-smmu-v3: Detect ARM_SMMU_OPT_KDUMP_ADOPT in probe()
>
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 1 +
> drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 467 ++++++++++++++++++--
> 2 files changed, 422 insertions(+), 46 deletions(-)
>
> --
> 2.43.0
>
^ permalink raw reply
* Re: [PATCH v4 1/4] dt-bindings: gpio: realtek: Add realtek,rtd1625-gpio
From: Linus Walleij @ 2026-06-30 13:17 UTC (permalink / raw)
To: Yu-Chun Lin
Cc: brgl, robh, krzk+dt, conor+dt, afaerber, mwalle,
andriy.shevchenko, tychang, linux-gpio, devicetree, linux-kernel,
linux-arm-kernel, linux-realtek-soc, cy.huang, stanley_chang,
james.tai, Krzysztof Kozlowski
In-Reply-To: <20260622092335.1166876-2-eleanor.lin@realtek.com>
Hi Yu-Chun,
thanks for your patch!
On Mon, Jun 22, 2026 at 10:33 AM Yu-Chun Lin <eleanor.lin@realtek.com> wrote:
> From: Tzuyi Chang <tychang@realtek.com>
>
> Add the device tree bindings for the Realtek DHC (Digital Home Center)
> RTD1625 GPIO controllers.
>
> The RTD1625 GPIO controller features a per-pin register architecture
> that differs significantly from previous generations. It utilizes
> separate register blocks for GPIO configuration and interrupt control.
>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
> Signed-off-by: Tzuyi Chang <tychang@realtek.com>
> Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
(...)
> + interrupt-controller: true
> +
> + "#interrupt-cells":
> + const: 2
> +
> + gpio-ranges: true
> +
> + gpio-controller: true
> +
> + "#gpio-cells":
> + const: 2
After looking at the driver I must challenge this binding.
Your driver is full of (offset % 32) and even (offset % 32) *4 to just
work around the fact that the hardware inherently has 32-pin banks.
Instead of using twocell GPIO and irqs, just use threecell, interrupt-cells
and gpio-cells 3.
First cell is bank, second cell is offset inside each bank.
For Linux specifically there are helpers for dealing with this in gpiolib,
and further you will be able to use the GPIO_GENERIC library,
while this is beside the point for the binding itself.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v2 0/9] vDSO: Respect COMPAT_32BIT_TIME
From: Arnd Bergmann @ 2026-06-30 13:16 UTC (permalink / raw)
To: Thomas Weißschuh, Andy Lutomirski, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Russell King, Catalin Marinas, Will Deacon, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Christophe Leroy,
Thomas Bogendoerfer, Vincenzo Frascino, John Stultz, Stephen Boyd,
David S . Miller, Andreas Larsson
Cc: linux-kernel, linux-arm-kernel, linuxppc-dev, linux-mips,
linux-api, sparclinux
In-Reply-To: <20260630-vdso-compat_32bit_time-v2-0-520d194640dd@linutronix.de>
On Tue, Jun 30, 2026, at 09:38, Thomas Weißschuh wrote:
> If CONFIG_COMPAT_32BIT_TIME is disabled then the vDSO should not
> provide any 32-bit time related functionality. This is the intended
> effect of the kconfig option and also the fallback system calls would
> also not be implemented.
>
> Currently the kconfig option does not affect the gettimeofday() syscall,
> so also keep that in the vDSO.
>
> I also tried to introduce some helpers to avoid much of the ifdeffery,
> but due to the high variance in the architecture-specific glue code
> these would need to handle they ended up being worse than the current
> proposal.
>
> As a side-effect this will make the self-tests more reliable,
> as there is now always a matching syscall available for each vDSO function.
>
> clock_gettime_time64() was only introduced in v6.19, so libc implementations
^ clock_getres_time64()
> Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> ---
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
once we have consensus on my patch 1/9 comment. Thanks for
continuing this work!
Arnd
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox