From nobody Fri Sep 25 00:02:32 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 668D53E8C4C; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738120; cv=none; b=DmtKbtLNG6l4wqh8FH9Mp+hfVmZMJLSmPCpfPh+3K9fBLSAZy7qX+jw/W9bobZP/w0cekLYwDFAZygR+jvqCwsPD45muvD0fOpG9omDAiXhNUKzQKYZfvKgpq1fPBhwTsh+lIuSnd76hwzQ/nGzr+PuroVQOz/xckx0ql+XPun8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738120; c=relaxed/simple; bh=SxIZzWCnD27F3bETzw8GzrIINZnH9G/TAzwOYgMlEyQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XIzxBliFwOojcyUU0CSxR/s8Abr8V2okUmP26MWPj51FqQPWN8zokkXciX2NRF0nzXrqHdE8CFkpVnGQX8yuC7bWPF5CxcqLtEoc65I4VEiO2y9IN07xvjkx5aLPVhw3OmoTqI5vSlXDA4EfZeDQ36dUXbqvPuNQoup22lZiv+M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PPhxwElJ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PPhxwElJ" Received: by smtp.kernel.org (Postfix) with ESMTPS id 052B5C2BCF6; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789738120; bh=SxIZzWCnD27F3bETzw8GzrIINZnH9G/TAzwOYgMlEyQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=PPhxwElJDmWds9qb+1aJB3nANMP20ueAteYvomAU6dgMPKaKwWAQ9pJWoY+p7AOXu dPDWYiCeo0IOESfwQnyArsclOP9mNnz3J9qh19vUrm2ZSUdkIvCgVFd/22UYmByc1P BRhQif6c9dXLlMWfJyLl8A66z96/kBRKSYYU5qrFGU6sQXS4hpNYbOxODOgSPLayvD pb064X4Ng/OkdMwR0ek1RvCEmY7tC1MlPD46xFCBNxqgeTg36TwH55qqBsOyT/kbDc 9p0YJYxo3/6t0HcJmBtjkTbYRFZIBZw/+AWCd0p9xItzFm/4/Fj0kYyKCbNBEsPv4u wVWgp9I0hR5sg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id D6427C982D8; Fri, 18 Sep 2026 13:28:39 +0000 (UTC) From: Michael Reeves via B4 Relay Date: Fri, 18 Sep 2026 23:28:31 +1000 Subject: [PATCH v3 01/10] dt-bindings: mailbox: apple: Add M3 ASC mailbox compatibles Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260918-apple-mtp-keyboard-final-v3-1-e356464e454b@gmail.com> References: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> In-Reply-To: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> To: Sven Peter , Janne Grunau , Neal Gompa , Jassi Brar , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Hector Martin , Michael Reeves , "Joerg Roedel (AMD)" , Will Deacon , Robin Murphy , Dmitry Torokhov , Jiri Kosina , Benjamin Tissoires Cc: asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, iommu@lists.linux.dev, linux-input@vger.kernel.org, Yureka Lilian , Julian Braha , Sasha Finkelstein , Conor Dooley X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1789738118; l=1133; i=michael.reeves077@gmail.com; s=fedora-20260918; h=from:subject:message-id; bh=jWZaHgDdQBahv3cP0BkPbF81okNWtgFAdgZ27z/Vurk=; b=A5yWgABN5ixdoi+/6yhNozlTx8zVWdg9kL3kOjBC64ywumlXwBigB/u6lc1FxBPOcZCYYlIFC Ovu2lAvNgNLBWd8KOq7jAKJb5fYfhymPAjI2djCTJgcsC79ioUheCxT X-Developer-Key: i=michael.reeves077@gmail.com; a=ed25519; pk=VJ0TvyQ9TvfzYZa908YSE9kpkjFLLD5luv0bERu+boc= X-Endpoint-Received: by B4 Relay for michael.reeves077@gmail.com/fedora-20260918 with auth_id=1035 X-Original-From: Michael Reeves Reply-To: michael.reeves077@gmail.com From: Michael Reeves Add the t8122, t6030 and t6031 ASC mailbox compatibles used by the MTP coprocessor on M3, M3 Pro and M3 Max SoCs. They share the existing ASC v4 mailbox interface. Signed-off-by: Michael Reeves Acked-by: Conor Dooley --- Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml b= /Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml index 28985cc62..9a6dfb0b2 100644 --- a/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml +++ b/Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml @@ -30,8 +30,11 @@ properties: - enum: - apple,t8103-asc-mailbox - apple,t8112-asc-mailbox + - apple,t8122-asc-mailbox - apple,t6000-asc-mailbox - apple,t6020-asc-mailbox + - apple,t6030-asc-mailbox + - apple,t6031-asc-mailbox - const: apple,asc-mailbox-v4 =20 - description: --=20 2.55.0 From nobody Fri Sep 25 00:02:32 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 66AB34E780B; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738120; cv=none; b=NPdyj5CaF9H6Quf4qXE0xLt5b21dNqqRcSM6qK4g7CMShtvDCizRxBJsGVyyZSBitntqVK/tZr3hJ/V6cN/7Y/d+POQGNZmXvSbWrg15G0KCg4KpqNHTBnayyhLSY2/YUrmhQmgyVkqruFHoZ4NMH04X81zjU29febj14HgOB2E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738120; c=relaxed/simple; bh=x45dY1rVj1cZoRbZ3WbYKT3XvBNlieNhr6jNH5/qAa4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=I6YHcfu8J5iXAoRFH2clyeX3/9u1su1kZ+o/tMb4Wmg0s8Hfk2d3DxPJYNy60WcwLqBkeJaAN1mNEzyLm1/biKAb0MBEExwkKQz9P3DJifoNNmmzYO0CKokYS7BbyyMTWFtg4ee4XwQ1TXccuM6/pizTMHqDfUcg5pPNIe6tyjI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tsyYiuZB; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tsyYiuZB" Received: by smtp.kernel.org (Postfix) with ESMTPS id 14DADC2BCFA; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789738120; bh=x45dY1rVj1cZoRbZ3WbYKT3XvBNlieNhr6jNH5/qAa4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=tsyYiuZBOU+bEkuqo4ZjDAKV8J7xnCOUz8SkGHouora6lG8V/TtvOY4HOwQWPf5YR 0ROJCsPh8g1ln9WbyGbZuRi4xhcwU7eDoFdPlYrEm6v9ElfZB6NDubw6GjVNrcYFx3 UZ7AH+Wf0vYKFEzBFbO6Bk9/islBbGx/5PzAI+06k9B1pm68ZkrcZ7KXCcawUqCBVp VYvYxsmFkIoNodOQyRX341h/Cl5FgAjoeaIUHTeHOdiItXhYckEcygUz+gfzR+gqYm fiEU1yH+7csDpkFUDBTsHtD3kpm5nA2TCRLVwU95LBL8Ob5wS/HM+JRLgzgynEbQHQ In/1rklXVr1eA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E4D77C982DF; Fri, 18 Sep 2026 13:28:39 +0000 (UTC) From: Michael Reeves via B4 Relay Date: Fri, 18 Sep 2026 23:28:32 +1000 Subject: [PATCH v3 02/10] dt-bindings: mailbox: apple: Add DockChannel mailbox Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260918-apple-mtp-keyboard-final-v3-2-e356464e454b@gmail.com> References: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> In-Reply-To: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> To: Sven Peter , Janne Grunau , Neal Gompa , Jassi Brar , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Hector Martin , Michael Reeves , "Joerg Roedel (AMD)" , Will Deacon , Robin Murphy , Dmitry Torokhov , Jiri Kosina , Benjamin Tissoires Cc: asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, iommu@lists.linux.dev, linux-input@vger.kernel.org, Yureka Lilian , Julian Braha , Sasha Finkelstein , Conor Dooley X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1789738118; l=3526; i=michael.reeves077@gmail.com; s=fedora-20260918; h=from:subject:message-id; bh=2Ignuv/vmTwVuxidQ+JOxc1KREH4iq4mptqg1ItCXik=; b=zexFWV4jjmQo3mEpaYt1sQ05EVD45DsvxBS2ceeZvD/0EXb3kM4RGUhcd+CHSAtg1qtiiZ8uc ovMB1mD0MAVBf0C3+el8cSfdABIQMVseUIgtGIO6U5oz9NsU93tnLXy X-Developer-Key: i=michael.reeves077@gmail.com; a=ed25519; pk=VJ0TvyQ9TvfzYZa908YSE9kpkjFLLD5luv0bERu+boc= X-Endpoint-Received: by B4 Relay for michael.reeves077@gmail.com/fedora-20260918 with auth_id=1035 X-Original-From: Michael Reeves Reply-To: michael.reeves077@gmail.com From: Michael Reeves DockChannel is a FIFO and interrupt block used by Apple coprocessors to exchange byte-stream traffic with the AP. Describe it as a mailbox provider so HID and future serial clients can use the common mailbox API. Signed-off-by: Michael Reeves Reviewed-by: Conor Dooley --- .../bindings/mailbox/apple,t8112-dockchannel.yaml | 77 ++++++++++++++++++= ++++ MAINTAINERS | 1 + 2 files changed, 78 insertions(+) diff --git a/Documentation/devicetree/bindings/mailbox/apple,t8112-dockchan= nel.yaml b/Documentation/devicetree/bindings/mailbox/apple,t8112-dockchanne= l.yaml new file mode 100644 index 000000000..dd2fdfa01 --- /dev/null +++ b/Documentation/devicetree/bindings/mailbox/apple,t8112-dockchannel.yaml @@ -0,0 +1,77 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mailbox/apple,t8112-dockchannel.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple DockChannel FIFO Mailbox + +maintainers: + - Michael Reeves + +description: + DockChannel is a hardware FIFO and interrupt block used on Apple SoCs for + low-latency byte stream communication with co-processors. + +properties: + compatible: + oneOf: + - items: + - const: apple,t8112-dockchannel + - items: + - enum: + - apple,t6020-dockchannel + - apple,t6030-dockchannel + - apple,t6031-dockchannel + - apple,t8122-dockchannel + - const: apple,t8112-dockchannel + + reg: + items: + - description: Interrupt control registers + - description: FIFO configuration registers + - description: FIFO data registers + + reg-names: + items: + - const: irq + - const: config + - const: data + + interrupts: + maxItems: 1 + + "#mbox-cells": + const: 0 + + nonposted-mmio: true + +required: + - compatible + - reg + - reg-names + - interrupts + - "#mbox-cells" + +additionalProperties: false + +examples: + - | + #include + #include + + soc { + #address-cells =3D <2>; + #size-cells =3D <2>; + + mailbox@24eb14000 { + compatible =3D "apple,t8112-dockchannel"; + reg =3D <0x2 0x4eb14000 0x0 0x4000>, + <0x2 0x4eb30000 0x0 0x4000>, + <0x2 0x4eb34000 0x0 0x4000>; + reg-names =3D "irq", "config", "data"; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #mbox-cells =3D <0>; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 3b2eb2a7a..0183c3e1c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2643,6 +2643,7 @@ F: Documentation/devicetree/bindings/iommu/apple,dart= .yaml F: Documentation/devicetree/bindings/iommu/apple,sart.yaml F: Documentation/devicetree/bindings/leds/backlight/apple,dwi-bl.yaml F: Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml +F: Documentation/devicetree/bindings/mailbox/apple,t8112-dockchannel.yaml F: Documentation/devicetree/bindings/mfd/apple,smc.yaml F: Documentation/devicetree/bindings/net/bluetooth/brcm,bcm4377-bluetooth.= yaml F: Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml --=20 2.55.0 From nobody Fri Sep 25 00:02:32 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 66A074CDA37; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738120; cv=none; b=D3+bFuZwOAm/Vfk6fw50tQu6MZVIoUJScTHfBIkbgeZI/63n3Gs6x5vckJDXOv1BoRsz8H9AEgEXzEVh/Quesomxg0xblj16mnAFd8SQvomILA1vWErV1et42xHOAhNqfEzUWk6dkAVN5mIJr10TZKgQCsObyiT9B/J875tRe1g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738120; c=relaxed/simple; bh=t5iAp3fMjkIZ0RzU4Fip5Mdwa1CzjHXcMHU8zfCTkBQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZA6ML1eGR/2sagzMJHHOXsuOqi/4mIq+lCOXLE6B1bil8AiWMl/uNj75keVMGB11EnSGG/URFT9n0HY/7bdM3oE3xACKGoSjvvsGP1H10369cdmbNlawstCSVOF8qDi3c0eFylvYjQjsQCqY1jCsCE3r8ynL8yYsr4fZbri39TM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WV/u7hzX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="WV/u7hzX" Received: by smtp.kernel.org (Postfix) with ESMTPS id 28587C2BCFB; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789738120; bh=t5iAp3fMjkIZ0RzU4Fip5Mdwa1CzjHXcMHU8zfCTkBQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=WV/u7hzXY8tFgRYMo28Hbd6UBtIKz8rPEq0zFQ/9h/yGj6XZvMxGmI1qekt/QHHb8 ERrnqaogjNUIW1W5lJPgZ6wSi8aiZ5U+7zYgrOBs9NW+C7NvhPA1JeOyn07f2gPoif 5SjZq2F3pZp9oWW96+GgGlziFRCCnbDLXmKlBPBwcye2Xho6HklIsbgnqj7IUwu0ET eZRZEmDpzkj+rM+2GfJ6X5BODU4yaYx4/ozZAirgJqiYWd8wnW125FXsjxpOtvZmBY 7evItqXcj48DbYDMc82+FoFYrkXMu6yJilr7bunVRttR/eNRUG9a0cs3JObgyWFrNF mYr3zNypM6R6Q== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 009B4C982E1; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) From: Michael Reeves via B4 Relay Date: Fri, 18 Sep 2026 23:28:33 +1000 Subject: [PATCH v3 03/10] dt-bindings: iommu: apple,dart: Add M3 compatibles Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260918-apple-mtp-keyboard-final-v3-3-e356464e454b@gmail.com> References: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> In-Reply-To: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> To: Sven Peter , Janne Grunau , Neal Gompa , Jassi Brar , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Hector Martin , Michael Reeves , "Joerg Roedel (AMD)" , Will Deacon , Robin Murphy , Dmitry Torokhov , Jiri Kosina , Benjamin Tissoires Cc: asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, iommu@lists.linux.dev, linux-input@vger.kernel.org, Yureka Lilian , Julian Braha , Sasha Finkelstein , Conor Dooley X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1789738118; l=1038; i=michael.reeves077@gmail.com; s=fedora-20260918; h=from:subject:message-id; bh=eobqpYoOQsgGWNW9L5TA1i/2YQsYWCHpu2/7P/SVNyI=; b=cRF61PRL2G+SfagQ1oXcz8kpbAZ8xF2kQKKkg+MtyTC0clgoPRyxzfNn3Lzpvqt2uZRr711Rv BGNC7tMinrLAqeFuTAyrJV6ZFejr+jKYgCu/8arw0BpRKWezdJLb64G X-Developer-Key: i=michael.reeves077@gmail.com; a=ed25519; pk=VJ0TvyQ9TvfzYZa908YSE9kpkjFLLD5luv0bERu+boc= X-Endpoint-Received: by B4 Relay for michael.reeves077@gmail.com/fedora-20260918 with auth_id=1035 X-Original-From: Michael Reeves Reply-To: michael.reeves077@gmail.com From: Michael Reeves Add the t8122, t6030 and t6031 DART compatibles used by the MTP coprocessor on M3, M3 Pro and M3 Max SoCs, with the t8110 fallback. Signed-off-by: Michael Reeves Acked-by: Conor Dooley --- Documentation/devicetree/bindings/iommu/apple,dart.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/iommu/apple,dart.yaml b/Docu= mentation/devicetree/bindings/iommu/apple,dart.yaml index 47ec7fa52..efadec786 100644 --- a/Documentation/devicetree/bindings/iommu/apple,dart.yaml +++ b/Documentation/devicetree/bindings/iommu/apple,dart.yaml @@ -29,7 +29,11 @@ properties: - apple,t8110-dart - apple,t6000-dart - items: - - const: apple,t6020-dart + - enum: + - apple,t6020-dart + - apple,t6030-dart + - apple,t6031-dart + - apple,t8122-dart - const: apple,t8110-dart =20 reg: --=20 2.55.0 From nobody Fri Sep 25 00:02:32 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B8E364F68A4; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738120; cv=none; b=Cd8OY6k8O6xVeqw/HnlKjNQeNHMYLdi99IlbNGqRnpSvYtblmP7rJ8x9b/fzH20sLmn1AEEJeQux5TdFph7OVVOQsQfHNQNtF5jMxbzwef5HLey741ptnrGH98P2i5sgQs+PYiW3oJ3WGAmpRwV8iTLTSSt6ZP/NONND+Xx17mw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738120; c=relaxed/simple; bh=RauQ/I1IkRSuYgsTU1p3RctiiX1Uc5/3p9HxZZgiji0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CJqwr0Zt0SZtxLhFP0b/tLJAl6R2UKcfzKZwmnisnP1tCgDwZQS3C6sE3FRfXIk715tS0n+vQUDZxC5MkduMXE8rvs5v3O5q1c7gZ/C0ZFZC6OkglYTgoIwnxNGh+dKxQqHm1R3OwEiFKqRc43Rh68hdwFXzs68/GMtwdmBalr0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rxf+Ewoj; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rxf+Ewoj" Received: by smtp.kernel.org (Postfix) with ESMTPS id 333E8C2BCFF; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789738120; bh=RauQ/I1IkRSuYgsTU1p3RctiiX1Uc5/3p9HxZZgiji0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=rxf+EwojSjBLDHhU2hKEd6r+z/7cUu6VWPAmkzPebkpc+jibiNJ60D2EEpCks3pXx A6KBxGCf7DYSZj96w9EZTDooOo1BFl7NiDjjbXcclZlAjWpN+CxcQxJgPiNsR8aG+P jbuyLrYFm7r12QWIzeK6oGvWr7T8P98IlMpfpOaFwnwlpEsR7vgKk0OoTNI4f0pyse 5I3GlpHbcactEmkCiQP4ijOIBqg7zJ8XqfpraBY1VM2XBy+eJVtzNh7wnCGlY3ismc jO0SFgT8SJUjT91nVcIloODYgaBK1owKAWfFWt+77KOyBIOxbM57EB9lgUeMwkiilJ /BbmG8j2J7XWA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0F55FC982E2; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) From: Michael Reeves via B4 Relay Date: Fri, 18 Sep 2026 23:28:34 +1000 Subject: [PATCH v3 04/10] dt-bindings: input: apple: Add DockChannel HID transport Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260918-apple-mtp-keyboard-final-v3-4-e356464e454b@gmail.com> References: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> In-Reply-To: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> To: Sven Peter , Janne Grunau , Neal Gompa , Jassi Brar , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Hector Martin , Michael Reeves , "Joerg Roedel (AMD)" , Will Deacon , Robin Murphy , Dmitry Torokhov , Jiri Kosina , Benjamin Tissoires Cc: asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, iommu@lists.linux.dev, linux-input@vger.kernel.org, Yureka Lilian , Julian Braha , Sasha Finkelstein X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1789738118; l=4567; i=michael.reeves077@gmail.com; s=fedora-20260918; h=from:subject:message-id; bh=V1jYsSN5PQjfbShoIWh4p5vyghr3NpPiAnZkrcqg0fY=; b=0zS63V5NrTNPXHkAjHPkgrEaDH6iEBlSkRmsMJymKwO/AIY8JlkLjCYD6tjqmbnLqbjgbkPqn elmMGbGRrJtA0q7eO1pM3D0fdOvYna0n/XWiRXxsUu3z+0KzZZzPfRY X-Developer-Key: i=michael.reeves077@gmail.com; a=ed25519; pk=VJ0TvyQ9TvfzYZa908YSE9kpkjFLLD5luv0bERu+boc= X-Endpoint-Received: by B4 Relay for michael.reeves077@gmail.com/fedora-20260918 with auth_id=1035 X-Original-From: Michael Reeves Reply-To: michael.reeves077@gmail.com From: Michael Reeves Apple internal keyboards and trackpads behind MTP are exposed through a DockChannel HID transport. Add the client binding tying together the RTKit ASC mailbox, DockChannel mailbox, and MTP DART. The keyboard child can provide the HID country code used by hid-apple to distinguish layout variants. Describe the optional STM child, which supplies the device identifiers and serial number shared by the HID interfaces. Signed-off-by: Michael Reeves --- Conor's v1 Reviewed-by is not carried forward because v2 adds the STM bindi= ng. --- .../input/apple,t8112-dockchannel-hid.yaml | 104 +++++++++++++++++= ++++ MAINTAINERS | 1 + 2 files changed, 105 insertions(+) diff --git a/Documentation/devicetree/bindings/input/apple,t8112-dockchanne= l-hid.yaml b/Documentation/devicetree/bindings/input/apple,t8112-dockchanne= l-hid.yaml new file mode 100644 index 000000000..c25e072b6 --- /dev/null +++ b/Documentation/devicetree/bindings/input/apple,t8112-dockchannel-hid.y= aml @@ -0,0 +1,104 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/apple,t8112-dockchannel-hid.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple DockChannel HID Transport + +maintainers: + - Michael Reeves + +description: + HID transport for keyboard and trackpad devices connected via the + DockChannel FIFO mailbox on Apple Silicon SoCs. The endpoint includes a + small RTKit coprocessor called MTP which must be booted before the HID + transport becomes available. + +properties: + compatible: + oneOf: + - items: + - const: apple,t8112-dockchannel-hid + - items: + - enum: + - apple,t6020-dockchannel-hid + - apple,t6030-dockchannel-hid + - apple,t6031-dockchannel-hid + - apple,t8122-dockchannel-hid + - const: apple,t8112-dockchannel-hid + + reg: + items: + - description: Coprocessor ASC registers + - description: Coprocessor SRAM/mailbox registers + + reg-names: + items: + - const: coproc-asc + - const: coproc-sram + + mboxes: + items: + - description: ASC mailbox used for RTKit control + - description: DockChannel FIFO mailbox used for HID packets + + mbox-names: + items: + - const: asc + - const: dockchannel + + iommus: + maxItems: 1 + + stm: + type: object + description: + STM interface providing the vendor, product and version identifiers + and serial number shared by the HID devices. When present, the host + must query this interface before registering the keyboard. + additionalProperties: false + + keyboard: + type: object + properties: + hid-country-code: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + HID country code for the keyboard layout variant. + + additionalProperties: false + +required: + - compatible + - reg + - reg-names + - mboxes + - mbox-names + - iommus + +additionalProperties: false + +examples: + - | + soc { + #address-cells =3D <2>; + #size-cells =3D <2>; + + hid@24e400000 { + compatible =3D "apple,t8112-dockchannel-hid"; + reg =3D <0x2 0x4e400000 0x0 0x4000>, + <0x2 0x4ec00000 0x0 0x100000>; + reg-names =3D "coproc-asc", "coproc-sram"; + mboxes =3D <&mtp_mbox>, <&mtp_dockchannel>; + mbox-names =3D "asc", "dockchannel"; + iommus =3D <&mtp_dart 1>; + + stm { + }; + + keyboard { + hid-country-code =3D <0>; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 0183c3e1c..7fe2ebb5e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2637,6 +2637,7 @@ F: Documentation/devicetree/bindings/gpio/apple,smc-g= pio.yaml F: Documentation/devicetree/bindings/gpu/apple,agx.yaml F: Documentation/devicetree/bindings/hwmon/apple,smc-hwmon.yaml F: Documentation/devicetree/bindings/i2c/apple,i2c.yaml +F: Documentation/devicetree/bindings/input/apple,t8112-dockchannel-hid.yaml F: Documentation/devicetree/bindings/input/touchscreen/apple,z2-multitouch= .yaml F: Documentation/devicetree/bindings/interrupt-controller/apple,* F: Documentation/devicetree/bindings/iommu/apple,dart.yaml --=20 2.55.0 From nobody Fri Sep 25 00:02:32 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6D3834EDCB1; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738120; cv=none; b=XPncfXzL7oMdR/2b25jL+4Xomu+gx3o2NGi8ZTyGuGLTovNlqTel5esZ9Qcol6xlgg0hr074xR3/Wn++/vFKm4hlfYKNV7oFS7m9MPDydOn4q6xFgOZB+jB3gJUjC4SQyZ1j8hK5aF3U555Q7S9C9uvEHU/guXgme9qLAARPRsI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738120; c=relaxed/simple; bh=Cm58DSIrb/G+4Sg0ytpzkm65yOH/0amB8MFdhlzrJbk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=fBGlzEZTVGFJspSguUHxJuaz+AuqiQgRquHtqb/+JqVxqaF6CsMB/odkJcj+HT0qA+ghLbBIu/ZTzFsV5dD/8FcnYqTNjpqwCSyPQh2FsVzPJUcxBQ0F3buLxDTcuFDDAHk5z90iKlY4OY3Gih/iFEpWgnoACQk8C151GsigxeM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nsABvMcP; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="nsABvMcP" Received: by smtp.kernel.org (Postfix) with ESMTPS id 3B871C2BD01; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789738120; bh=Cm58DSIrb/G+4Sg0ytpzkm65yOH/0amB8MFdhlzrJbk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=nsABvMcPFj6U9cBh9wnUasQiXopb2YYD3exd+sBPmTuIOoaI03j5qK3qSSh/zrSkR yrtJ9jr9uuXBxdVK4DW3cjpeWAQf5ZlDAk7k3yX38mE+t5QaYgi+7i6wqOFKt0qbfE BXcrPO7G6QHgNlQpQ61bPDp1xE8adS7sneEVW7A5skOuhZA44shds+0G+BZptRJdfs HvR+za2giQVoFyykBkxiAmZA7Puyx5VHXbwvfA/AbnRjLgOCUeDsRbLZQLcAj3MUEI ah0TmglUZl+YkuHD3UDpd0xXJuPIuft4glHtHckZoAabP0lsDMJj0+ladfiuKsuRgn xmSnR6/8ASA0w== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1EBA2C982E0; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) From: Michael Reeves via B4 Relay Date: Fri, 18 Sep 2026 23:28:35 +1000 Subject: [PATCH v3 05/10] mailbox: apple: Add DockChannel FIFO controller Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260918-apple-mtp-keyboard-final-v3-5-e356464e454b@gmail.com> References: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> In-Reply-To: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> To: Sven Peter , Janne Grunau , Neal Gompa , Jassi Brar , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Hector Martin , Michael Reeves , "Joerg Roedel (AMD)" , Will Deacon , Robin Murphy , Dmitry Torokhov , Jiri Kosina , Benjamin Tissoires Cc: asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, iommu@lists.linux.dev, linux-input@vger.kernel.org, Yureka Lilian , Julian Braha , Sasha Finkelstein X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1789738118; l=14201; i=michael.reeves077@gmail.com; s=fedora-20260918; h=from:subject:message-id; bh=JfOc3mv53wX6q509C07iXDBxLQ9JoLzRgZnNsuIBQZs=; b=BShfkNGSEfn1l6Db3eJPY3AakwUDT8qB4h7LCcuRNij4b/i8BskHOCjGw/JMh8Kn2NWDl+fni b0NQ3n6IBSrDKGTMDW6Fxb0+0rDw4hNKhIx/M0Ir1t6LbUEQZ2uf8C5 X-Developer-Key: i=michael.reeves077@gmail.com; a=ed25519; pk=VJ0TvyQ9TvfzYZa908YSE9kpkjFLLD5luv0bERu+boc= X-Endpoint-Received: by B4 Relay for michael.reeves077@gmail.com/fedora-20260918 with auth_id=1035 X-Original-From: Michael Reeves Reply-To: michael.reeves077@gmail.com From: Michael Reeves DockChannel is a hardware FIFO used by Apple coprocessors for low-latency byte-stream communication with the AP. Add a mailbox controller that preallocates RX storage, tracks IRQ enable state in software, and reports TX completion from the TX-empty interrupt. Reject messages larger than the FIFO and return -EBUSY while the previous message is still pending. This keeps the provider usable for future small-message clients such as serial transports without a TX worker. Handle RX and TX interrupts in a thread so mailbox callbacks and locking run outside hard-IRQ context. Co-developed-by: Hector Martin Signed-off-by: Hector Martin Signed-off-by: Michael Reeves --- MAINTAINERS | 2 + drivers/mailbox/Kconfig | 12 + drivers/mailbox/Makefile | 2 + drivers/mailbox/apple-dockchannel.c | 372 ++++++++++++++++++++++++++= ++++ include/linux/mailbox/apple-dockchannel.h | 29 +++ 5 files changed, 417 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 7fe2ebb5e..e5be5934c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2677,6 +2677,7 @@ F: drivers/input/touchscreen/apple_z2.c F: drivers/iommu/apple-dart.c F: drivers/iommu/io-pgtable-dart.c F: drivers/irqchip/irq-apple-aic.c +F: drivers/mailbox/apple-dockchannel.c F: drivers/mfd/macsmc.c F: drivers/nvme/host/apple.c F: drivers/nvmem/apple-efuses.c @@ -2695,6 +2696,7 @@ F: drivers/video/backlight/apple_dwi_bl.c F: drivers/watchdog/apple_wdt.c F: include/dt-bindings/interrupt-controller/apple-aic.h F: include/dt-bindings/pinctrl/apple.h +F: include/linux/mailbox/apple-dockchannel.h F: include/linux/mfd/macsmc.h F: include/linux/soc/apple/* F: include/uapi/drm/asahi_drm.h diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index ab869769e..503d3286f 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig @@ -36,6 +36,18 @@ config ARM_MHU_V3 that provides different means of transports: supported extensions will be discovered and possibly managed at probe-time. =20 +config APPLE_DOCKCHANNEL + tristate "Apple DockChannel FIFO mailbox" + depends on ARCH_APPLE || COMPILE_TEST + depends on HAS_IOMEM + depends on OF + help + DockChannel is a hardware FIFO used on Apple Silicon SoCs for + communication between the application processor and co-processors. + This driver exposes DockChannel FIFOs through the mailbox framework. + + Say Y here if you have an M2 or later Apple MacBook. + config AST2700_MBOX tristate "ASPEED AST2700 IPC driver" depends on ARCH_ASPEED || COMPILE_TEST diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile index 45dc59bb3..61b15fe45 100644 --- a/drivers/mailbox/Makefile +++ b/drivers/mailbox/Makefile @@ -11,6 +11,8 @@ obj-$(CONFIG_ARM_MHU_V2) +=3D arm_mhuv2.o =20 obj-$(CONFIG_ARM_MHU_V3) +=3D arm_mhuv3.o =20 +obj-$(CONFIG_APPLE_DOCKCHANNEL) +=3D apple-dockchannel.o + obj-$(CONFIG_AST2700_MBOX) +=3D ast2700-mailbox.o =20 obj-$(CONFIG_CV1800_MBOX) +=3D cv1800-mailbox.o diff --git a/drivers/mailbox/apple-dockchannel.c b/drivers/mailbox/apple-do= ckchannel.c new file mode 100644 index 000000000..a99b8dad0 --- /dev/null +++ b/drivers/mailbox/apple-dockchannel.c @@ -0,0 +1,372 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Apple DockChannel mailbox controller + * + * Copyright The Asahi Linux Contributors + * + * DockChannel is a byte FIFO used by Apple co-processors. This driver exp= oses a + * single FIFO pair as a Linux mailbox channel and moves payload bytes wit= h PIO. + * There is no DMA involved, so relaxed MMIO accessors are sufficient for = the + * FIFO accesses themselves. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define APPLE_DOCKCHANNEL_FIFO_SIZE 0x800 + +#define IRQ_MASK 0x0 +#define IRQ_FLAG 0x4 + +#define IRQ_TX BIT(2) +#define IRQ_RX BIT(3) + +#define CONFIG_TX_THRESH 0x0 +#define CONFIG_RX_THRESH 0x4 + +#define DATA_TX8 0x4 +#define DATA_TX32 0x10 +#define DATA_TX_FREE 0x14 +#define DATA_RX8 0x1c +#define DATA_RX32 0x28 +#define DATA_RX_COUNT 0x2c + +struct apple_dockchannel { + struct device *dev; + struct mbox_controller controller; + struct mbox_chan chan; + + void __iomem *irq_base; + void __iomem *config_base; + void __iomem *data_base; + int irq; + + spinlock_t lock; /* protects IRQ mask and TX state */ + u32 irq_mask; + + const u8 *tx_buf; + size_t tx_len; + size_t tx_pos; + bool tx_active; + + u8 rx_buf[APPLE_DOCKCHANNEL_FIFO_SIZE]; +}; + +static void apple_dockchannel_irq_update(struct apple_dockchannel *dc, + u32 bits, bool enable) +{ + if (enable) + dc->irq_mask |=3D bits; + else + dc->irq_mask &=3D ~bits; + writel_relaxed(dc->irq_mask, dc->irq_base + IRQ_MASK); +} + +static void apple_dockchannel_irq_enable(struct apple_dockchannel *dc, u32= bits) +{ + /* + * IRQ_FLAG is write-to-clear. Clear stale latched flags before + * unmasking so the next interrupt reflects current FIFO state. + */ + writel_relaxed(bits, dc->irq_base + IRQ_FLAG); + apple_dockchannel_irq_update(dc, bits, true); +} + +static void apple_dockchannel_irq_disable(struct apple_dockchannel *dc, u3= 2 bits) +{ + apple_dockchannel_irq_update(dc, bits, false); +} + +static bool apple_dockchannel_tx_empty(struct apple_dockchannel *dc) +{ + return readl_relaxed(dc->data_base + DATA_TX_FREE) =3D=3D + APPLE_DOCKCHANNEL_FIFO_SIZE; +} + +static void apple_dockchannel_write_pending(struct apple_dockchannel *dc) +{ + size_t left =3D dc->tx_len - dc->tx_pos; + const u8 *p =3D dc->tx_buf + dc->tx_pos; + + while (left) { + size_t avail; + size_t block; + + avail =3D readl_relaxed(dc->data_base + DATA_TX_FREE); + if (!avail) + break; + + block =3D min(left, avail); + + while (block >=3D sizeof(u32)) { + writel_relaxed(get_unaligned_le32(p), + dc->data_base + DATA_TX32); + p +=3D sizeof(u32); + left -=3D sizeof(u32); + block -=3D sizeof(u32); + } + + /* TX data is in bits [7:0]; RX uses those bits for the count. */ + while (block) { + writel_relaxed(*p++, dc->data_base + DATA_TX8); + left--; + block--; + } + } + + dc->tx_pos =3D dc->tx_len - left; +} + +static void apple_dockchannel_read(struct apple_dockchannel *dc, void *buf, + size_t count) +{ + u8 *p =3D buf; + size_t left =3D count; + + while (left >=3D sizeof(u32)) { + put_unaligned_le32(readl_relaxed(dc->data_base + DATA_RX32), p); + p +=3D sizeof(u32); + left -=3D sizeof(u32); + } + + while (left) { + /* + * The byte FIFO register returns the byte in bits [15:8] on + * these instances. + */ + *p++ =3D readl_relaxed(dc->data_base + DATA_RX8) >> 8; + left--; + } +} + +static int apple_dockchannel_send_data(struct mbox_chan *chan, void *data) +{ + struct apple_dockchannel *dc =3D chan->con_priv; + struct apple_dockchannel_msg *msg =3D data; + unsigned long flags; + + if (!msg || !msg->data || !msg->len) + return -EINVAL; + + if (msg->len > APPLE_DOCKCHANNEL_FIFO_SIZE) + return -EMSGSIZE; + + spin_lock_irqsave(&dc->lock, flags); + + if (dc->tx_active || !apple_dockchannel_tx_empty(dc)) { + spin_unlock_irqrestore(&dc->lock, flags); + return -EBUSY; + } + + dc->tx_buf =3D msg->data; + dc->tx_len =3D msg->len; + dc->tx_pos =3D 0; + dc->tx_active =3D true; + + apple_dockchannel_write_pending(dc); + writel_relaxed(APPLE_DOCKCHANNEL_FIFO_SIZE, + dc->config_base + CONFIG_TX_THRESH); + apple_dockchannel_irq_enable(dc, IRQ_TX); + + spin_unlock_irqrestore(&dc->lock, flags); + + return 0; +} + +static int apple_dockchannel_startup(struct mbox_chan *chan) +{ + struct apple_dockchannel *dc =3D chan->con_priv; + unsigned long flags; + + spin_lock_irqsave(&dc->lock, flags); + /* + * The mailbox framework has no per-client RX threshold. Use byte + * granularity because UART-style DockChannel clients require it. + */ + writel_relaxed(1, dc->config_base + CONFIG_RX_THRESH); + apple_dockchannel_irq_enable(dc, IRQ_RX); + spin_unlock_irqrestore(&dc->lock, flags); + + enable_irq(dc->irq); + + return 0; +} + +static void apple_dockchannel_shutdown(struct mbox_chan *chan) +{ + struct apple_dockchannel *dc =3D chan->con_priv; + unsigned long flags; + + disable_irq(dc->irq); + + spin_lock_irqsave(&dc->lock, flags); + apple_dockchannel_irq_disable(dc, IRQ_TX | IRQ_RX); + dc->tx_active =3D false; + spin_unlock_irqrestore(&dc->lock, flags); +} + +static const struct mbox_chan_ops apple_dockchannel_mbox_ops =3D { + .send_data =3D apple_dockchannel_send_data, + .startup =3D apple_dockchannel_startup, + .shutdown =3D apple_dockchannel_shutdown, +}; + +static irqreturn_t apple_dockchannel_irq_thread(int irq, void *data) +{ + struct apple_dockchannel *dc =3D data; + unsigned long irqflags; + u32 flags; + u32 pending; + bool tx_done =3D false; + + flags =3D readl_relaxed(dc->irq_base + IRQ_FLAG); + + spin_lock_irqsave(&dc->lock, irqflags); + + pending =3D flags & dc->irq_mask & (IRQ_TX | IRQ_RX); + if (!pending) + goto out_unlock_none; + + if (pending & IRQ_TX) { + if (apple_dockchannel_tx_empty(dc)) { + apple_dockchannel_irq_disable(dc, IRQ_TX); + tx_done =3D dc->tx_active; + dc->tx_active =3D false; + } else { + pending &=3D ~IRQ_TX; + } + } + + writel_relaxed(pending, dc->irq_base + IRQ_FLAG); + + spin_unlock_irqrestore(&dc->lock, irqflags); + + if (tx_done) + mbox_chan_txdone(&dc->chan, 0); + + if (!(pending & IRQ_RX)) + return pending ? IRQ_HANDLED : IRQ_NONE; + + for (;;) { + struct apple_dockchannel_msg msg; + size_t avail; + + avail =3D readl_relaxed(dc->data_base + DATA_RX_COUNT); + if (!avail) + break; + + avail =3D min_t(size_t, avail, APPLE_DOCKCHANNEL_FIFO_SIZE); + + apple_dockchannel_read(dc, dc->rx_buf, avail); + + msg.data =3D dc->rx_buf; + msg.len =3D avail; + mbox_chan_received_data(&dc->chan, &msg); + } + + return IRQ_HANDLED; + +out_unlock_none: + spin_unlock_irqrestore(&dc->lock, irqflags); + + if (flags & (IRQ_TX | IRQ_RX)) + writel_relaxed(flags & (IRQ_TX | IRQ_RX), + dc->irq_base + IRQ_FLAG); + + return IRQ_NONE; +} + +static struct mbox_chan * +apple_dockchannel_of_xlate(struct mbox_controller *mbox, + const struct of_phandle_args *spec) +{ + if (spec->args_count !=3D 0) + return ERR_PTR(-EINVAL); + + return &mbox->chans[0]; +} + +static int apple_dockchannel_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct apple_dockchannel *dc; + int ret; + + dc =3D devm_kzalloc(dev, sizeof(*dc), GFP_KERNEL); + if (!dc) + return -ENOMEM; + + dc->dev =3D dev; + spin_lock_init(&dc->lock); + platform_set_drvdata(pdev, dc); + + dc->irq_base =3D devm_platform_ioremap_resource_byname(pdev, "irq"); + if (IS_ERR(dc->irq_base)) + return PTR_ERR(dc->irq_base); + + dc->config_base =3D devm_platform_ioremap_resource_byname(pdev, "config"); + if (IS_ERR(dc->config_base)) + return PTR_ERR(dc->config_base); + + dc->data_base =3D devm_platform_ioremap_resource_byname(pdev, "data"); + if (IS_ERR(dc->data_base)) + return PTR_ERR(dc->data_base); + + writel_relaxed(0, dc->irq_base + IRQ_MASK); + writel_relaxed(~0, dc->irq_base + IRQ_FLAG); + + dc->irq =3D platform_get_irq(pdev, 0); + if (dc->irq < 0) + return dc->irq; + + ret =3D devm_request_threaded_irq(dev, dc->irq, NULL, + apple_dockchannel_irq_thread, IRQF_ONESHOT, + dev_name(dev), dc); + if (ret) + return dev_err_probe(dev, ret, "failed to request IRQ\n"); + + disable_irq(dc->irq); + + dc->chan.con_priv =3D dc; + dc->controller.dev =3D dev; + dc->controller.ops =3D &apple_dockchannel_mbox_ops; + dc->controller.chans =3D &dc->chan; + dc->controller.num_chans =3D 1; + dc->controller.txdone_irq =3D true; + dc->controller.of_xlate =3D apple_dockchannel_of_xlate; + + ret =3D devm_mbox_controller_register(dev, &dc->controller); + if (ret) + return dev_err_probe(dev, ret, "failed to register mailbox\n"); + + return 0; +} + +static const struct of_device_id apple_dockchannel_of_match[] =3D { + { .compatible =3D "apple,t8122-dockchannel" }, + { .compatible =3D "apple,t8112-dockchannel" }, + {}, +}; +MODULE_DEVICE_TABLE(of, apple_dockchannel_of_match); + +static struct platform_driver apple_dockchannel_driver =3D { + .driver =3D { + .name =3D "apple-dockchannel", + .of_match_table =3D apple_dockchannel_of_match, + }, + .probe =3D apple_dockchannel_probe, +}; +module_platform_driver(apple_dockchannel_driver); + +MODULE_DESCRIPTION("Apple DockChannel mailbox controller"); +MODULE_AUTHOR("Hector Martin "); +MODULE_AUTHOR("Michael Reeves "); +MODULE_LICENSE("Dual MIT/GPL"); diff --git a/include/linux/mailbox/apple-dockchannel.h b/include/linux/mail= box/apple-dockchannel.h new file mode 100644 index 000000000..04d2fc44f --- /dev/null +++ b/include/linux/mailbox/apple-dockchannel.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ +/* + * Apple DockChannel mailbox message format. + * + * Copyright The Asahi Linux Contributors + */ + +#ifndef _LINUX_MAILBOX_APPLE_DOCKCHANNEL_H_ +#define _LINUX_MAILBOX_APPLE_DOCKCHANNEL_H_ + +#include + +/** + * struct apple_dockchannel_msg - DockChannel mailbox payload + * @data: Pointer to the byte stream payload + * @len: Number of payload bytes + * + * For TX, @data must remain valid until mbox_send_message() completes or = the + * client receives tx_done in non-blocking mode. + * + * For RX, @data is owned by the controller and is valid only for the dura= tion + * of the rx_callback. + */ +struct apple_dockchannel_msg { + void *data; + size_t len; +}; + +#endif /* _LINUX_MAILBOX_APPLE_DOCKCHANNEL_H_ */ --=20 2.55.0 From nobody Fri Sep 25 00:02:32 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B94E64F68A8; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738120; cv=none; b=uAisfcBeh8a+JUL1lMDfNaJO1KJlO90HkrVlQhT4MIQqjUX+eoHrfh1oLM9U/jW9Lnuo3mzqjl5brfT9SJL0RA4dERhglVD2LDHpbbLWjIeP+yl5ytDmo3TyFwU6sXlvcOH9OA/iRezXAoXK/Pbf40Zp2f7/Wbh4oeZImvniNLk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738120; c=relaxed/simple; bh=fRDe89N3HJeAFyCusP4aAHWCcvsF/BWXyWYiiFspEec=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=d7xGXsJ7T5K5OUYugKrBWryoqNmeZBQ4IyXDLODVk3EA/7VSKDQGKOkJ2ptZwpEyhCLNvnoDI+XQFlvUmQF53AnHewI8l9dY8E1SqKhikwxGLfmicJYEwQlcBDhgrAouDJU3pDAEj6ezvo7PyC6DuyWRBZjtiNBkmw/uhfWgelc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QIK66MGU; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QIK66MGU" Received: by smtp.kernel.org (Postfix) with ESMTPS id 43C04C4AF16; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789738120; bh=fRDe89N3HJeAFyCusP4aAHWCcvsF/BWXyWYiiFspEec=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=QIK66MGUf0GL5zbVhOw4a9e4cI+crtSY9/8eauBk5FXPLq8Eliy8kVcw1gAKQyePy Onzkfejemh6vbUdcpxQqc8/Mpg/D0CLaj2hk0DdlxqWc/iMBdLKi1gOkTN/69XhePo RrOIcRyToPb/Q0ZiLW5O/DGY3cCIn+1Q4wuzCGPhrS/ZmQOr32OM8RxQbfQhe2wVU7 7c6YDHOnKbKW0WQNMmq4ecrrrbUAuyCSXsdc9Ur0TUetnOYXtdkmrL3tqQI3T7N1NB qUwKAAEo1ji/8B+8SswdiYyCeLVmwDzkt6aBckTAnAMrqXQGRHy6baAnNkCKEjDLAP 2lUXajt9K4fsA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2DD6BC982E4; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) From: Michael Reeves via B4 Relay Date: Fri, 18 Sep 2026 23:28:36 +1000 Subject: [PATCH v3 06/10] soc: apple: rtkit: Add tracekit endpoint Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260918-apple-mtp-keyboard-final-v3-6-e356464e454b@gmail.com> References: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> In-Reply-To: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> To: Sven Peter , Janne Grunau , Neal Gompa , Jassi Brar , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Hector Martin , Michael Reeves , "Joerg Roedel (AMD)" , Will Deacon , Robin Murphy , Dmitry Torokhov , Jiri Kosina , Benjamin Tissoires Cc: asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, iommu@lists.linux.dev, linux-input@vger.kernel.org, Yureka Lilian , Julian Braha , Sasha Finkelstein X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1789738118; l=1194; i=michael.reeves077@gmail.com; s=fedora-20260918; h=from:subject:message-id; bh=kS9uTA8Dh/vtajiZu3Qfpn0cuQfrngimukMbAAW4igI=; b=DExpakc9/XQpplMDm/FnTW5uTsaQfRwti4xjWJAqpr7jeOK6+0PheO+oRZaesvE8rowSg8kde HowMzYLms81CutLvHqlJVtEQdA6FmGa2dI5vnowMk2jgxFD9hM5/vsF X-Developer-Key: i=michael.reeves077@gmail.com; a=ed25519; pk=VJ0TvyQ9TvfzYZa908YSE9kpkjFLLD5luv0bERu+boc= X-Endpoint-Received: by B4 Relay for michael.reeves077@gmail.com/fedora-20260918 with auth_id=1035 X-Original-From: Michael Reeves Reply-To: michael.reeves077@gmail.com From: Sasha Finkelstein The TraceKit endpoint is a system endpoint used by MTP, AOP, and potentially other Apple RTKit coprocessors. Start it automatically when it appears in the endpoint map, like the other known system endpoints, to avoid warnings about an unknown endpoint. Signed-off-by: Sasha Finkelstein Signed-off-by: Michael Reeves --- drivers/soc/apple/rtkit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/soc/apple/rtkit.c b/drivers/soc/apple/rtkit.c index a3fdac8f6..1059b4bd8 100644 --- a/drivers/soc/apple/rtkit.c +++ b/drivers/soc/apple/rtkit.c @@ -22,6 +22,7 @@ enum { APPLE_RTKIT_EP_DEBUG =3D 3, APPLE_RTKIT_EP_IOREPORT =3D 4, APPLE_RTKIT_EP_OSLOG =3D 8, + APPLE_RTKIT_EP_TRACEKIT =3D 0xa, }; =20 #define APPLE_RTKIT_MGMT_TYPE GENMASK_ULL(59, 52) @@ -191,6 +192,7 @@ static void apple_rtkit_management_rx_epmap(struct appl= e_rtkit *rtk, u64 msg) case APPLE_RTKIT_EP_DEBUG: case APPLE_RTKIT_EP_IOREPORT: case APPLE_RTKIT_EP_OSLOG: + case APPLE_RTKIT_EP_TRACEKIT: dev_dbg(rtk->dev, "RTKit: Starting system endpoint 0x%02x\n", ep); apple_rtkit_start_ep(rtk, ep); --=20 2.55.0 From nobody Fri Sep 25 00:02:32 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CC8044F68D7; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738120; cv=none; b=BMepowVKewGy+0Hvw1vXevtT6PMCjvxh5JRuxz1qNxxF0Z/s7wTlJyldrRO+zt6rMvc1pce8/ShN3p5rHyi0yStT4NsrCkVoCfbIHWidkAHuzFzWIphHquKOKVemcgDcKLzVQQtK7V6gefVc65LxgaeC0R9YxgrHmadlkC2VWHQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738120; c=relaxed/simple; bh=kshdd0UgoZdMmGyTQdR78b5BxL4LZLWUeh+/eMSqKDQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SUqA2rqC39ckKMcF0W5xWOBzGcejY7aZ0YyaLoxAHzIfIqdkrAz9mf+cKvOFCM/ziiLYm9PXUs+coZcGSmh75s8HYQs3lpS0VLU5glYKJkjRo+nb4h956CDF7tQxiYqyv15//jgj2Sd2+HV8YoKk72LmlcGQlhq51ds2sY5tqT8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dgg69dyq; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dgg69dyq" Received: by smtp.kernel.org (Postfix) with ESMTPS id 5168DC4AF15; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789738120; bh=kshdd0UgoZdMmGyTQdR78b5BxL4LZLWUeh+/eMSqKDQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=dgg69dyqPjDbJkCHJy86/caNLZe3SQEm0XwzcNvJhEwUB1xjAQkZU6TSApJVQhzbM G4TpSZt4nDaIhgSQ0weihgl/k980sm+zCDKubw6Nji5HDWLZVnhYvmwt0zqJ4JpxXr /8Mpj9RdVzQamQZdFxWWPQ1NWl/iW85zfswOQPujEeBoPMPHHT0r65l/Cd/lIkcUXx s3p3xICge71MtwyxhQvbRZbm2FJrJCpCscrsAUJfd4yprVYAgZHI2WK+DNROraN+No 4H38MVp3oBMi/6JhwoXjQlfoCYpuJ427Z4rKShiGLAn1uLprka+e8yS9bV3TBDimcK 6vbnL01pvtyVw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3CDBFC982D8; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) From: Michael Reeves via B4 Relay Date: Fri, 18 Sep 2026 23:28:37 +1000 Subject: [PATCH v3 07/10] HID: apple: Add support for DockChannel HID keyboards Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260918-apple-mtp-keyboard-final-v3-7-e356464e454b@gmail.com> References: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> In-Reply-To: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> To: Sven Peter , Janne Grunau , Neal Gompa , Jassi Brar , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Hector Martin , Michael Reeves , "Joerg Roedel (AMD)" , Will Deacon , Robin Murphy , Dmitry Torokhov , Jiri Kosina , Benjamin Tissoires Cc: asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, iommu@lists.linux.dev, linux-input@vger.kernel.org, Yureka Lilian , Julian Braha , Sasha Finkelstein X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1789738118; l=7532; i=michael.reeves077@gmail.com; s=fedora-20260918; h=from:subject:message-id; bh=Jn8V1WltiVnkawdzC5bVKS+cIf6Ev+2/cLas2bYpiBs=; b=CCaAE3SKILaat8IshUCCrbFZQu9WJgizsWYZDIJbVD8PTc6Cc1dh/F3s9FFcyCmmn9/ysQgB+ CZQe16TorGVCjkpNzvMDacYVQqhti4SCS+kgkcspXLT/MVO4lsLb2uP X-Developer-Key: i=michael.reeves077@gmail.com; a=ed25519; pk=VJ0TvyQ9TvfzYZa908YSE9kpkjFLLD5luv0bERu+boc= X-Endpoint-Received: by B4 Relay for michael.reeves077@gmail.com/fedora-20260918 with auth_id=1035 X-Original-From: Michael Reeves Reply-To: michael.reeves077@gmail.com From: Michael Reeves DockChannel keyboards are registered as host-bus Apple HID devices instead of USB or Bluetooth devices. Match them in hid-apple and use the modern Magic Keyboard function-key table. Honor the per-device special-driver quirk when matching. Signed-off-by: Michael Reeves --- drivers/hid/hid-apple.c | 118 +++++++++++++++++++++++++++++---------------= ---- include/linux/hid.h | 1 + 2 files changed, 73 insertions(+), 46 deletions(-) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index f6134c582..524ac80cb 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -395,6 +395,12 @@ static bool apple_is_omoton_kb066(struct hid_device *h= dev) strcmp(hdev->name, "Bluetooth Keyboard") =3D=3D 0; } =20 +static bool apple_is_dockchannel_keyboard(struct hid_device *hdev) +{ + return hdev->bus =3D=3D BUS_HOST && + hdev->group =3D=3D HID_GROUP_APPLE_DOCKCHANNEL; +} + static inline void apple_setup_key_translation(struct input_dev *input, const struct apple_key_translation *table) { @@ -482,53 +488,57 @@ static int hidinput_apple_event(struct hid_device *hi= d, struct input_dev *input, asc->fn_on =3D !!value; =20 if (real_fnmode) { - switch (hid->product) { - case USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI: - case USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO: - case USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS: - case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI: - case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO: - case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS: - case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI: - case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO: - case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS: - table =3D magic_keyboard_alu_fn_keys; - break; - case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015: - case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015: - table =3D magic_keyboard_2015_fn_keys; - break; - case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021: - case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021: - case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021: - case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024: - case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2024: - case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2024: + if (apple_is_dockchannel_keyboard(hid)) { table =3D magic_keyboard_2021_and_2024_fn_keys; - break; - case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: - case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213: - case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680: - case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT: - table =3D macbookpro_no_esc_fn_keys; - break; - case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F: - case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K: - case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223: - table =3D macbookpro_dedicated_esc_fn_keys; - break; - case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K: - case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K: - table =3D apple_fn_keys; - break; - default: - if (hid->product >=3D USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && - hid->product <=3D USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) - table =3D macbookair_fn_keys; - else if (hid->product < 0x21d || hid->product >=3D 0x300) - table =3D powerbook_fn_keys; - else + } else { + switch (hid->product) { + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI: + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO: + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS: + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI: + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO: + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS: + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI: + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO: + case USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS: + table =3D magic_keyboard_alu_fn_keys; + break; + case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015: + case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015: + table =3D magic_keyboard_2015_fn_keys; + break; + case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021: + case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021: + case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021: + case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2024: + case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2024: + case USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2024: + table =3D magic_keyboard_2021_and_2024_fn_keys; + break; + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT: + table =3D macbookpro_no_esc_fn_keys; + break; + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223: + table =3D macbookpro_dedicated_esc_fn_keys; + break; + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K: + case USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K: table =3D apple_fn_keys; + break; + default: + if (hid->product >=3D USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && + hid->product <=3D USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) + table =3D macbookair_fn_keys; + else if (hid->product < 0x21d || hid->product >=3D 0x300) + table =3D powerbook_fn_keys; + else + table =3D apple_fn_keys; + } } =20 trans =3D apple_find_translation(table, code); @@ -768,7 +778,7 @@ static int apple_input_configured(struct hid_device *hd= ev, struct apple_sc *asc =3D hid_get_drvdata(hdev); =20 if (((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) || apple_is_omoton_k= b066(hdev)) { - hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disab= ling Fn key handling\n"); + hid_info(hdev, "Disabling function quirk for device without function key= \n"); asc->quirks &=3D ~APPLE_HAS_FN; } =20 @@ -1019,6 +1029,18 @@ static void apple_remove(struct hid_device *hdev) hid_hw_stop(hdev); } =20 +static bool apple_match(struct hid_device *hdev, bool ignore_special_drive= r) +{ + if (ignore_special_driver || + (hdev->quirks & HID_QUIRK_IGNORE_SPECIAL_DRIVER)) + return false; + + if (hdev->group =3D=3D HID_GROUP_APPLE_DOCKCHANNEL) + return apple_is_dockchannel_keyboard(hdev); + + return true; +} + static const struct hid_device_id apple_devices[] =3D { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE), .driver_data =3D APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL }, @@ -1240,6 +1262,9 @@ static const struct hid_device_id apple_devices[] =3D= { .driver_data =3D APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_TOUCHBAR_BACKLI= GHT), .driver_data =3D APPLE_MAGIC_BACKLIGHT }, + { HID_DEVICE(BUS_HOST, HID_GROUP_APPLE_DOCKCHANNEL, + HID_ANY_ID, HID_ANY_ID), + .driver_data =3D APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, =20 { } }; @@ -1248,6 +1273,7 @@ MODULE_DEVICE_TABLE(hid, apple_devices); static struct hid_driver apple_driver =3D { .name =3D "apple", .id_table =3D apple_devices, + .match =3D apple_match, .report_fixup =3D apple_report_fixup, .probe =3D apple_probe, .remove =3D apple_remove, diff --git a/include/linux/hid.h b/include/linux/hid.h index 8d17b7416..40be5eabf 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -441,6 +441,7 @@ struct hid_item { #define HID_GROUP_STEAM 0x0103 #define HID_GROUP_LOGITECH_27MHZ_DEVICE 0x0104 #define HID_GROUP_VIVALDI 0x0105 +#define HID_GROUP_APPLE_DOCKCHANNEL 0x0106 =20 /* * HID protocol status --=20 2.55.0 From nobody Fri Sep 25 00:02:32 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DB8114F7CA0; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738120; cv=none; b=j1XhdMJpQsaNAD3IP6Kz6nUelEJaaUKtrMrs+KFKZZLQWp+auWutf8RmVpEHej7mVDPaM/6Eq9d7/JmT1lBU3n9Fsn43j9if93DMFu7B7oUxfmK60qa1hdZ7Mw0M6VuBvVDrAdRnSzJ/s492cx/3+YKLpQ+KPGaTy/hokKRbTIo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738120; c=relaxed/simple; bh=VA0ltfojBdjXumfyMImupo7JuNTSs8tr9hpz2tUAHuU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=JoKbddJuggts4wXDGTvnwBT6RD0y3PXAQjatfZoIIqeHdUgljXiCWuG6Kqlwsg0MQwqAULwf0sfS9fd56gBxF5XJjvJ2bNxFnb02aS4P8OjoF1Lwph8gj7c3xw2XEDrthOCstWVsOBGeNWofiJdrCSJpKhlmNBOLNY5CBrx/lRo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NjRGxQSc; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="NjRGxQSc" Received: by smtp.kernel.org (Postfix) with ESMTPS id 63DBCC4DDE3; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789738120; bh=VA0ltfojBdjXumfyMImupo7JuNTSs8tr9hpz2tUAHuU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=NjRGxQSctnL20Zo1PVgjSM0sCrkFob2xc82ZPDlGMEOzMTI+oectcHhZuJxRepcMA iw6zW0Qaxb6JoE1etl39rpVFgPOyYghaj5wZHFsJ2cQmVYnmSkX8QGS1sJQfw2RZ/2 5OxHN/zPc2mAJqSRWyj8nw4ldVQA0AHd1mrRGnRkY5A9HWQ5SoQiDRLk8OJCP8nZcG cWa+oHw3J+oIta9TK5oAUkjOdGpInsbn5pdxyLL/AQdGzlJavaT8/Jv6KXitebAusf yK7QroxFMO9ItBTVBnJ7jaYCrhF4qL/AjODnRiqIHn8bizDyimYf/9+hOYwPN5drxN 4OpQtgUL8IebA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4DD6BC982E3; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) From: Michael Reeves via B4 Relay Date: Fri, 18 Sep 2026 23:28:38 +1000 Subject: [PATCH v3 08/10] HID: apple: Add DockChannel HID transport driver Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260918-apple-mtp-keyboard-final-v3-8-e356464e454b@gmail.com> References: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> In-Reply-To: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> To: Sven Peter , Janne Grunau , Neal Gompa , Jassi Brar , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Hector Martin , Michael Reeves , "Joerg Roedel (AMD)" , Will Deacon , Robin Murphy , Dmitry Torokhov , Jiri Kosina , Benjamin Tissoires Cc: asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, iommu@lists.linux.dev, linux-input@vger.kernel.org, Yureka Lilian , Julian Braha , Sasha Finkelstein X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1789738118; l=34354; i=michael.reeves077@gmail.com; s=fedora-20260918; h=from:subject:message-id; bh=dfUipdGyjaZRYd9gva4/Kltd9TKrR4yYkqOCkYENvdw=; b=EUuSnPtSBP3jcJvKLcyoeif/2fSf4MNrFqWITzN3DJU9i6m8QRqjcHckhBcvfjg1BehGgBNHT 5CKsVID2H28AZIeAXnkG7+4Uwd82siszhtLgEPlU06EQYtU53pZy3x3 X-Developer-Key: i=michael.reeves077@gmail.com; a=ed25519; pk=VJ0TvyQ9TvfzYZa908YSE9kpkjFLLD5luv0bERu+boc= X-Endpoint-Received: by B4 Relay for michael.reeves077@gmail.com/fedora-20260918 with auth_id=1035 X-Original-From: Michael Reeves Reply-To: michael.reeves077@gmail.com From: Michael Reeves 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. Use the presence of an STM child node to decide whether to wait for shared device identifiers. Machines without STM can register their keyboard without waiting for an interface that never appears. Only interfaces described by available child nodes are instantiated. On removal or failed probe, stop queueing reports, drain packet and device-creation work, and destroy HID devices. Keep command acknowledgements flowing until outstanding users have finished, then stop the coprocessor before releasing the mailbox. Publish initialized interfaces with release/acquire ordering and keep the first accepted descriptor stable. Bound report replies to the bytes copied and preserve the requested report type and transfer length. Co-developed-by: Hector Martin Signed-off-by: Hector Martin Signed-off-by: Michael Reeves --- MAINTAINERS | 1 + drivers/hid/Kconfig | 2 + drivers/hid/Makefile | 2 + drivers/hid/dockchannel/Kconfig | 14 + drivers/hid/dockchannel/Makefile | 3 + drivers/hid/dockchannel/apple-hid.c | 1177 +++++++++++++++++++++++++++++++= ++++ 6 files changed, 1199 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index e5be5934c..fc20a2781 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2669,6 +2669,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 a81bf51cb..fb8def311 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -1534,6 +1534,8 @@ source "drivers/hid/surface-hid/Kconfig" =20 source "drivers/hid/intel-thc-hid/Kconfig" =20 +source "drivers/hid/dockchannel/Kconfig" + endif # HID =20 # USB support may be used with HID disabled diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 48a863b24..e889bd37b 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -184,3 +184,5 @@ obj-$(CONFIG_AMD_SFH_HID) +=3D amd-sfh-hid/ obj-$(CONFIG_SURFACE_HID_CORE) +=3D surface-hid/ =20 obj-$(CONFIG_INTEL_THC_HID) +=3D intel-thc-hid/ + +obj-$(CONFIG_APPLE_DOCKCHANNEL_HID) +=3D dockchannel/ diff --git a/drivers/hid/dockchannel/Kconfig b/drivers/hid/dockchannel/Kcon= fig new file mode 100644 index 000000000..aeb4e4edf --- /dev/null +++ b/drivers/hid/dockchannel/Kconfig @@ -0,0 +1,14 @@ +# 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 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/Mak= efile new file mode 100644 index 000000000..d1a82aa57 --- /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) +=3D apple-hid.o diff --git a/drivers/hid/dockchannel/apple-hid.c b/drivers/hid/dockchannel/= apple-hid.c new file mode 100644 index 000000000..1966dc6aa --- /dev/null +++ b/drivers/hid/dockchannel/apple-hid.c @@ -0,0 +1,1177 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Apple DockChannel HID transport driver + * + * Copyright The Asahi Linux Contributors + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; + spinlock_t rx_lock; /* serializes report queueing with teardown */ + bool stopping; + + 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 =3D data; + + destroy_workqueue(wq); +} + +static void dchid_fwnode_release(void *data) +{ + fwnode_handle_put(data); +} + +static u32 dchid_checksum(const void *data, size_t len) +{ + const u8 *p =3D data; + u32 sum =3D 0; + int i; + + while (len >=3D sizeof(u32)) { + sum +=3D get_unaligned_le32(p); + p +=3D sizeof(u32); + len -=3D sizeof(u32); + } + + if (len) { + u32 tmp =3D 0; + + for (i =3D 0; i < len; i++) + tmp |=3D p[i] << (i * 8); + sum +=3D tmp; + } + + return sum; +} + +static void dchid_create_interface_work(struct work_struct *ws); + +static struct dchid_iface * +dchid_get_interface(struct dchid_dev *dchid, int index, const char *name) +{ + struct dchid_iface *iface; + struct fwnode_handle *fwnode =3D NULL; + int ret; + + if (index >=3D 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 =3D dchid->ifaces[index]; + mutex_unlock(&dchid->ifaces_lock); + return iface; + } + + if (strcmp(name, "comm")) { + fwnode =3D device_get_named_child_node(dchid->dev, name); + if (!fwnode || !fwnode_device_is_available(fwnode)) + goto err_put_fwnode; + } + + iface =3D devm_kzalloc(dchid->dev, sizeof(*iface), GFP_KERNEL); + if (!iface) + goto err_put_fwnode; + + iface->index =3D index; + iface->name =3D devm_kstrdup(dchid->dev, name, GFP_KERNEL); + if (!iface->name) + goto err_put_fwnode; + + iface->dchid =3D dchid; + iface->out_report =3D -1; + init_completion(&iface->out_complete); + init_completion(&iface->ready); + INIT_WORK(&iface->create_work, dchid_create_interface_work); + spin_lock_init(&iface->out_lock); + + iface->wq =3D alloc_ordered_workqueue("dchid-%s", 0, iface->name); + if (!iface->wq) + goto err_put_fwnode; + + ret =3D devm_add_action_or_reset(dchid->dev, dchid_destroy_wq, iface->wq); + if (ret) + goto err_put_fwnode; + + /* Comm is not a HID subdevice. */ + if (!strcmp(name, "comm")) + goto publish; + + iface->fwnode =3D fwnode; + ret =3D devm_add_action_or_reset(dchid->dev, dchid_fwnode_release, + iface->fwnode); + if (ret) + goto err_unlock; + +publish: + /* Publish initialization to the lockless RX reader. */ + smp_store_release(&dchid->ifaces[index], iface); + mutex_unlock(&dchid->ifaces_lock); + return iface; + +err_put_fwnode: + fwnode_handle_put(fwnode); +err_unlock: + mutex_unlock(&dchid->ifaces_lock); + return NULL; +} + +static int dchid_send(struct dchid_iface *iface, u32 flags, const void *ms= g, + size_t size) +{ + struct dchid_dev *dchid =3D iface->dchid; + size_t payload_padded =3D round_up(size, sizeof(u32)); + size_t total_len =3D sizeof(struct dchid_hdr) + sizeof(struct dchid_subhd= r) + + payload_padded + DCHID_CHECKSUM_LEN; + struct apple_dockchannel_msg dc_msg; + struct dchid_hdr *hdr; + struct dchid_subhdr *sub; + __le32 *checksum_ptr; + u8 *buf; + int ret; + + if (total_len > DCHID_RX_BUF_SIZE) + return -EINVAL; + + buf =3D kzalloc(total_len, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + hdr =3D (struct dchid_hdr *)buf; + sub =3D (struct dchid_subhdr *)(buf + sizeof(*hdr)); + checksum_ptr =3D (__le32 *)(buf + total_len - DCHID_CHECKSUM_LEN); + + hdr->hdr_len =3D sizeof(*hdr); + hdr->channel =3D DCHID_CHANNEL_CMD; + hdr->length =3D cpu_to_le16(payload_padded + sizeof(*sub)); + hdr->seq =3D iface->tx_seq; + hdr->iface =3D iface->index; + + sub->flags =3D (u8)flags; + sub->length =3D cpu_to_le16(size); + + memcpy(buf + sizeof(*hdr) + sizeof(*sub), msg, size); + + *checksum_ptr =3D cpu_to_le32(DCHID_CHECKSUM_SEED - + dchid_checksum(buf, total_len - DCHID_CHECKSUM_LEN)); + + dc_msg.data =3D buf; + dc_msg.len =3D total_len; + ret =3D 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 =3D false; + u32 out_flags; + + if (size < 1) + return -EINVAL; + + report_id =3D *(u8 *)data; + out_flags =3D 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 !=3D -1)) { + spin_unlock_irqrestore(&iface->out_lock, flags); + return -EBUSY; + } + + iface->out_report =3D report_id; + iface->out_flags =3D out_flags; + iface->retcode =3D 0; + iface->resp_buf =3D resp_buf; + iface->resp_size =3D resp_size; + reinit_completion(&iface->out_complete); + + spin_unlock_irqrestore(&iface->out_lock, flags); + + ret =3D dchid_send(iface, out_flags, data, size); + if (ret < 0) { + spin_lock_irqsave(&iface->out_lock, flags); + iface->out_report =3D -1; + iface->resp_buf =3D NULL; + iface->resp_size =3D 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 =3D true; + } + + spin_lock_irqsave(&iface->out_lock, flags); + + if (timed_out && iface->out_report =3D=3D report_id) { + ret =3D -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 =3D -EIO; + } else { + ret =3D iface->resp_size; + } + + iface->tx_seq++; + iface->out_report =3D -1; + iface->resp_buf =3D NULL; + iface->resp_size =3D 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[] =3D { 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[] =3D { 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 =3D true; + dchid_reset_interface(iface, 0); + dchid_reset_interface(iface, 2); + + return 0; +} + +static int dchid_start(struct hid_device *hdev) +{ + return 0; +} + +static void dchid_stop(struct hid_device *hdev) +{ +} + +static int dchid_open(struct hid_device *hdev) +{ + struct dchid_iface *iface =3D hdev->driver_data; + int ret; + + if (!completion_done(&iface->ready)) { + ret =3D 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 =3D true; + return 0; +} + +static void dchid_close(struct hid_device *hdev) +{ + struct dchid_iface *iface =3D hdev->driver_data; + + iface->open =3D false; +} + +static int dchid_parse(struct hid_device *hdev) +{ + struct dchid_iface *iface =3D 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 =3D dchid_cmd(iface, HID_FEATURE_REPORT, REQ_GET_REPORT, &reportnum, = 1, + buf, len); + + return ret <=3D 0 ? ret : ret - 1; +} + +/* Note: buf includes report number. */ +static int dchid_set_report(struct dchid_iface *iface, void *buf, size_t l= en, + unsigned char rtype) +{ + int ret; + + ret =3D dchid_cmd(iface, rtype, REQ_SET_REPORT, buf, len, NULL, 0); + if (ret < 0) + return ret; + + return len; +} + +static int dchid_raw_request(struct hid_device *hdev, unsigned char report= num, + __u8 *buf, size_t len, unsigned char rtype, + int reqtype) +{ + struct dchid_iface *iface =3D hdev->driver_data; + + switch (reqtype) { + case HID_REQ_GET_REPORT: + if (len < 1) + return -EINVAL; + + buf[0] =3D 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, rtype); + default: + return -EIO; + } +} + +static const struct hid_ll_driver dchid_ll =3D { + .start =3D dchid_start, + .stop =3D dchid_stop, + .open =3D dchid_open, + .close =3D dchid_close, + .parse =3D dchid_parse, + .raw_request =3D dchid_raw_request, +}; + +static void dchid_create_interface_work(struct work_struct *ws) +{ + struct dchid_iface *iface =3D container_of(ws, struct dchid_iface, create= _work); + struct dchid_dev *dchid =3D iface->dchid; + struct hid_device *hid; + char cap_name[16]; + int ret; + + if (READ_ONCE(dchid->stopping)) + goto done; + + if (iface->hid) { + dev_warn(dchid->dev, "interface %s already created\n", iface->name); + goto done; + } + + ret =3D dchid_enable_interface(iface); + if (ret < 0) { + dev_warn(dchid->dev, "failed to enable %s: %d\n", iface->name, ret); + goto done; + } + + iface->deferred =3D false; + + hid =3D hid_allocate_device(); + if (IS_ERR(hid)) + goto done; + + strscpy(cap_name, iface->name, sizeof(cap_name)); + if (cap_name[0]) + cap_name[0] =3D 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)); + + hid->ll_driver =3D &dchid_ll; + hid->bus =3D BUS_HOST; + hid->vendor =3D le16_to_cpu(dchid->device_id.vendor_id); + hid->product =3D le16_to_cpu(dchid->device_id.product_id); + hid->version =3D le16_to_cpu(dchid->device_id.version_number); + hid->type =3D HID_TYPE_OTHER; + if (!strcmp(iface->name, "keyboard")) { + u32 country_code; + + hid->group =3D 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 =3D country_code; + } + + hid->dev.parent =3D iface->dchid->dev; + hid->driver_data =3D iface; + iface->hid =3D hid; + + ret =3D hid_add_device(hid); + if (ret < 0) { + iface->hid =3D NULL; + hid_destroy_device(hid); + dev_warn(iface->dchid->dev, "failed to register HID device %s\n", + iface->name); + } + +done: + iface->creating =3D false; +} + +static int dchid_create_interface(struct dchid_iface *iface) +{ + if (iface->creating) + return -EBUSY; + + iface->creating =3D true; + return queue_work(iface->dchid->new_iface_wq, &iface->create_work); +} + +static void dchid_handle_descriptor(struct dchid_iface *iface, void *hid_d= esc, + size_t desc_len) +{ + u8 *rdesc; + int i; + + /* Keep the descriptor stable while creation and HID parsing run. */ + if (iface->hid_desc) + return; + + rdesc =3D 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 >=3D 5) { + for (i =3D 0; i <=3D (int)desc_len - 5; i++) { + if (rdesc[i] =3D=3D 0x76 && rdesc[i + 1] =3D=3D 0x00 && + rdesc[i + 2] =3D=3D 0x40 && rdesc[i + 3] =3D=3D 0x95) { + u8 count =3D 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] =3D 0x75; + rdesc[i + 1] =3D 0x08; + rdesc[i + 2] =3D 0x96; + rdesc[i + 3] =3D 0x00; + rdesc[i + 4] =3D count * 8; + } + } + } + } + + iface->hid_desc =3D rdesc; + iface->hid_desc_len =3D desc_len; +} + +static void dchid_handle_ready(struct dchid_dev *dchid, void *data, size_t= length) +{ + struct dchid_iface *iface; + u8 *pkt =3D data; + u8 index; + int i; + int ret; + + if (length < 2) + return; + + index =3D pkt[1]; + if (index >=3D MAX_INTERFACES) + return; + + iface =3D 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 =3D 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 =3D 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] =3D 0; + } else { + dchid->serial[ret] =3D 0; + } + + dchid->id_ready =3D true; + for (i =3D 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 =3D data; + struct dchid_init_block_hdr *blk; + struct dchid_iface *iface; + u8 *p =3D data; + + if (length < sizeof(*hdr)) + return; + + if (!memchr(hdr->name, 0, sizeof(hdr->name))) + return; + + iface =3D dchid_get_interface(dchid, hdr->iface, hdr->name); + if (!iface) + return; + + p +=3D sizeof(*hdr); + length -=3D sizeof(*hdr); + + while (length >=3D sizeof(*blk)) { + u16 blk_len; + + blk =3D (struct dchid_init_block_hdr *)p; + p +=3D sizeof(*blk); + length -=3D sizeof(*blk); + + blk_len =3D 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] !=3D 0) + dev_warn(dchid->dev, "unterminated product name for %s\n", + iface->name); + break; + } + + p +=3D blk_len; + length -=3D blk_len; + + if (le16_to_cpu(blk->type) =3D=3D INIT_TERMINATOR) + break; + } + + if (hdr->more_packets) + return; + + /* Wait for the shared device IDs only on machines with an STM. */ + if (dchid->id_ready || !strcmp(iface->name, "stm")) + dchid_create_interface(iface); + else + iface->deferred =3D true; +} + +static void dchid_handle_event(struct dchid_dev *dchid, void *data, size_t= length) +{ + u8 *p =3D 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, siz= e_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 =3D container_of(ws, struct dchid_work, work); + struct dchid_subhdr *shdr =3D (void *)work->data; + struct dchid_dev *dchid =3D work->iface->dchid; + u16 hdr_len =3D le16_to_cpu(work->hdr.length); + u16 sub_len; + int type; + u8 *payload; + + if (READ_ONCE(dchid->stopping)) + goto done; + + if (hdr_len < sizeof(*shdr)) { + dev_err(dchid->dev, "bad subheader length\n"); + goto done; + } + + sub_len =3D le16_to_cpu(shdr->length); + if (sub_len > hdr_len - sizeof(*shdr)) { + dev_err(dchid->dev, "bad subheader length\n"); + goto done; + } + + type =3D FIELD_GET(FLAGS_GROUP, shdr->flags); + payload =3D work->data + sizeof(*shdr); + + switch (type) { + case HID_INPUT_REPORT: + if (work->hdr.iface =3D=3D 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 =3D data; + u8 *payload =3D data + sizeof(*shdr); + u16 hdr_len =3D le16_to_cpu(hdr->length); + u16 sub_len =3D le16_to_cpu(shdr->length); + unsigned long flags; + bool complete_cmd =3D 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 =3D=3D iface->out_flags && iface->tx_seq =3D=3D hdr->seq = && + iface->out_report =3D=3D payload[0]) { + iface->resp_size =3D min_t(size_t, sub_len - 1, iface->resp_size); + if (iface->resp_buf && iface->resp_size) + memcpy(iface->resp_buf, payload + 1, iface->resp_size); + + /* Command replies include the report ID, which the caller supplies. */ + iface->resp_size++; + iface->out_report =3D -1; + iface->retcode =3D le32_to_cpu(shdr->retcode); + complete_cmd =3D 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; + struct dchid_iface *iface; + unsigned long flags; + + if (dchid_checksum(packet, packet_len) !=3D DCHID_CHECKSUM_SEED) { + dev_err_ratelimited(dchid->dev, "checksum error\n"); + return; + } + + if (payload_len < sizeof(struct dchid_subhdr)) + return; + + if (hdr->iface >=3D MAX_INTERFACES) + return; + + /* Pair with publication after interface initialization. */ + iface =3D smp_load_acquire(&dchid->ifaces[hdr->iface]); + if (!iface) + return; + + if (hdr->channel =3D=3D DCHID_CHANNEL_CMD) { + dchid_handle_ack(iface, hdr, payload); + return; + } + + if (hdr->channel !=3D DCHID_CHANNEL_REPORT) + return; + + work =3D kzalloc(sizeof(*work) + payload_len, GFP_ATOMIC); + if (!work) + return; + + work->hdr =3D *hdr; + work->iface =3D iface; + memcpy(work->data, payload, payload_len); + INIT_WORK(&work->work, dchid_packet_work); + + spin_lock_irqsave(&dchid->rx_lock, flags); + if (dchid->stopping) + kfree(work); + else + queue_work(work->iface->wq, &work->work); + spin_unlock_irqrestore(&dchid->rx_lock, flags); +} + +static void dchid_consume_rx(struct dchid_dev *dchid) +{ + while (dchid->rx_len >=3D sizeof(struct dchid_hdr)) { + struct dchid_hdr *hdr =3D (struct dchid_hdr *)dchid->rx_buf; + size_t payload_len; + size_t packet_len; + + if (hdr->hdr_len !=3D sizeof(*hdr)) { + dev_err_ratelimited(dchid->dev, "bad header length %u\n", + hdr->hdr_len); + dchid->rx_len =3D 0; + return; + } + + payload_len =3D le16_to_cpu(hdr->length); + packet_len =3D 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 =3D 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 -=3D 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 =3D container_of(cl, struct dchid_dev, dc_mbox_cl= ient); + struct apple_dockchannel_msg *msg =3D 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 =3D 0; + return; + } + + memcpy(dchid->rx_buf + dchid->rx_len, msg->data, msg->len); + dchid->rx_len +=3D msg->len; + + dchid_consume_rx(dchid); +} + +static int dchid_rtkit_shmem_setup(void *cookie, struct apple_rtkit_shmem = *bfr) +{ + struct dchid_dev *dchid =3D cookie; + struct resource res =3D { + .start =3D bfr->iova, + .end =3D bfr->iova + bfr->size - 1, + .name =3D "rtkit_map", + }; + + if (!bfr->iova) { + bfr->buffer =3D 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 =3D dchid->sram_res.flags; + if (res.end < res.start || !resource_contains(&dchid->sram_res, &res)) + return -EFAULT; + + bfr->iomem =3D dchid->sram_base + (res.start - dchid->sram_res.start); + bfr->is_mapped =3D true; + + return 0; +} + +static void dchid_rtkit_shmem_destroy(void *cookie, struct apple_rtkit_shm= em *bfr) +{ + struct dchid_dev *dchid =3D cookie; + + if (bfr->buffer) + dma_free_coherent(dchid->dev, bfr->size, bfr->buffer, bfr->iova); +} + +static const struct apple_rtkit_ops dchid_rtkit_ops =3D { + .shmem_setup =3D dchid_rtkit_shmem_setup, + .shmem_destroy =3D dchid_rtkit_shmem_destroy, +}; + +static int dchid_map_helper_cpu(struct platform_device *pdev, struct dchid= _dev *dchid) +{ + struct resource *res; + + dchid->asc_base =3D devm_platform_ioremap_resource_byname(pdev, "coproc-a= sc"); + if (IS_ERR(dchid->asc_base)) + return PTR_ERR(dchid->asc_base); + + res =3D platform_get_resource_byname(pdev, IORESOURCE_MEM, "coproc-sram"); + if (!res) + return -EINVAL; + + dchid->sram_res =3D *res; + + dchid->sram_base =3D devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(dchid->sram_base)) + return PTR_ERR(dchid->sram_base); + + return 0; +} + +static void dchid_shutdown(struct dchid_dev *dchid) +{ + unsigned long flags; + int i; + + /* Stop queueing reports, but keep receiving command acknowledgements. */ + spin_lock_irqsave(&dchid->rx_lock, flags); + WRITE_ONCE(dchid->stopping, true); + spin_unlock_irqrestore(&dchid->rx_lock, flags); + + /* Comm work can create interfaces, so drain it before walking ifaces. */ + flush_workqueue(dchid->comm->wq); + + /* Packet work can queue creation work; drain the queues in that order. */ + for (i =3D 0; i < MAX_INTERFACES; i++) { + struct dchid_iface *iface =3D dchid->ifaces[i]; + + if (iface) + flush_workqueue(iface->wq); + } + flush_workqueue(dchid->new_iface_wq); + + for (i =3D 0; i < MAX_INTERFACES; i++) { + struct dchid_iface *iface =3D dchid->ifaces[i]; + + if (iface && iface->hid) + hid_destroy_device(iface->hid); + } + + if (!IS_ERR_OR_NULL(dchid->rtk) && apple_rtkit_is_running(dchid->rtk)) + apple_rtkit_quiesce(dchid->rtk); + + writel(0, dchid->asc_base + APPLE_ASC_CPU_CONTROL); + readl(dchid->asc_base + APPLE_ASC_CPU_CONTROL); + mbox_free_channel(dchid->dc_mbox); + dchid->dc_mbox =3D NULL; +} + +static int dchid_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct dchid_dev *dchid; + struct fwnode_handle *stm; + int ret; + + ret =3D 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 =3D devm_kzalloc(dev, sizeof(*dchid), GFP_KERNEL); + if (!dchid) + return -ENOMEM; + + dchid->rx_buf =3D devm_kmalloc(dev, DCHID_RX_BUF_SIZE, GFP_KERNEL); + if (!dchid->rx_buf) + return -ENOMEM; + + dchid->dev =3D dev; + stm =3D device_get_named_child_node(dev, "stm"); + dchid->id_ready =3D !stm || !fwnode_device_is_available(stm); + fwnode_handle_put(stm); + mutex_init(&dchid->ifaces_lock); + spin_lock_init(&dchid->rx_lock); + platform_set_drvdata(pdev, dchid); + + ret =3D dchid_map_helper_cpu(pdev, dchid); + if (ret) + return dev_err_probe(dev, ret, "failed to map helper CPU\n"); + + dchid->new_iface_wq =3D alloc_ordered_workqueue("dchid-new", 0); + if (!dchid->new_iface_wq) + return dev_err_probe(dev, -ENOMEM, "failed to allocate workqueue\n"); + + ret =3D devm_add_action_or_reset(dev, dchid_destroy_wq, dchid->new_iface_= wq); + if (ret) + return ret; + + dchid->comm =3D dchid_get_interface(dchid, IFACE_COMM, "comm"); + if (!dchid->comm) + return dev_err_probe(dev, -EIO, "failed to init comm interface\n"); + + dchid->dc_mbox_client.dev =3D dev; + dchid->dc_mbox_client.tx_block =3D true; + dchid->dc_mbox_client.rx_callback =3D dchid_rx_callback; + + dchid->dc_mbox =3D 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"); + + dchid->rtk =3D devm_apple_rtkit_init(dev, dchid, "asc", 0, &dchid_rtkit_o= ps); + if (IS_ERR(dchid->rtk)) { + ret =3D dev_err_probe(dev, PTR_ERR(dchid->rtk), "failed to init RTKit\n"= ); + goto err_shutdown; + } + + writel_relaxed(APPLE_ASC_CPU_CONTROL_RUN, + dchid->asc_base + APPLE_ASC_CPU_CONTROL); + + ret =3D apple_rtkit_wake(dchid->rtk); + if (ret) { + dev_err_probe(dev, ret, "failed to wake coprocessor\n"); + goto err_shutdown; + } + + return 0; + +err_shutdown: + dchid_shutdown(dchid); + return ret; +} + +static void dchid_remove(struct platform_device *pdev) +{ + dchid_shutdown(platform_get_drvdata(pdev)); +} + +static const struct of_device_id dchid_of_match[] =3D { + { .compatible =3D "apple,t8122-dockchannel-hid" }, + { .compatible =3D "apple,t8112-dockchannel-hid" }, + {}, +}; +MODULE_DEVICE_TABLE(of, dchid_of_match); + +static struct platform_driver dchid_platform_driver =3D { + .driver =3D { + .name =3D "dockchannel-hid", + .of_match_table =3D dchid_of_match, + }, + .probe =3D dchid_probe, + .remove =3D dchid_remove, +}; +module_platform_driver(dchid_platform_driver); + +MODULE_DESCRIPTION("Apple DockChannel HID transport driver"); +MODULE_AUTHOR("Hector Martin "); +MODULE_AUTHOR("Michael Reeves "); +MODULE_LICENSE("Dual MIT/GPL"); --=20 2.55.0 From nobody Fri Sep 25 00:02:32 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E86C64F7CD5; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738121; cv=none; b=DvVdhNPaN5ZP4l5pkoSUDZXP7NStk3I+eUr8+OW4t5E0m4++fgDxQ+dzyPlNE9asb78B5MYMpgZSZhtQzNKL9dCk4I63GvW7LHU2OutkLZQYk31utVqV2Zs/nPk1qm2yXEpixI/kI/ysnpTKO6k9c98L5qrCNR56Cw2mvfnj+g4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738121; c=relaxed/simple; bh=qHsL6nJsyo40SQoF4f2zG/1G7Q2hFBVFDBcl86L3XT0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=R9iGOrbKJWKzBzXSZt5tkxSh9ioX6ZAVBzfGTY+723NwuJndwnyUtd9kHYFx/3C/6LQrPyCoY3vVjQ6vjbfOzklS+ZvxoJoQ/xzc3Ym1zku5KcyfeVWgn0QHhVTFMutHtDjQlpdHHjK2t+0beom3x+hWdiZYKpJbeMcH37YPpq8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=r3nuxftf; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="r3nuxftf" Received: by smtp.kernel.org (Postfix) with ESMTPS id 6FF6BC4DDEC; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789738120; bh=qHsL6nJsyo40SQoF4f2zG/1G7Q2hFBVFDBcl86L3XT0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=r3nuxftfhg4iCY+bzGUkpMDj/QcDc7MixdoKCJUubBXz7V9W2cLsV9sQ0Chbkl6j5 RfZucaYShH74XMva8TNKVDF9f9PPddkhUw5QIvcMVw7bIAKKk11lxELI0hwcWds7YD TS+FPWiY6penytS/8KysyrnnY2zFDPP900QdxWKlF5p6wgoxew8/xhyZWP3AiHumgV 4wHemCgBCbMKLM21e8QGsyvcOEV/9CMhFFmVWWQoYtndEPYb9xZoFQTKLTkEDRhQ+K U38qubyHmemXang2/YhWIRFtZDGVJjBvxYUcIjUX2tLYIZZsFNriqi7wcQAdi006nt BOxh3GqiAXFaQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5DC26C982DF; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) From: Michael Reeves via B4 Relay Date: Fri, 18 Sep 2026 23:28:39 +1000 Subject: [PATCH v3 09/10] arm64: dts: apple: Add MTP DockChannel HID nodes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260918-apple-mtp-keyboard-final-v3-9-e356464e454b@gmail.com> References: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> In-Reply-To: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> To: Sven Peter , Janne Grunau , Neal Gompa , Jassi Brar , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Hector Martin , Michael Reeves , "Joerg Roedel (AMD)" , Will Deacon , Robin Murphy , Dmitry Torokhov , Jiri Kosina , Benjamin Tissoires Cc: asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, iommu@lists.linux.dev, linux-input@vger.kernel.org, Yureka Lilian , Julian Braha , Sasha Finkelstein X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1789738118; l=10900; i=michael.reeves077@gmail.com; s=fedora-20260918; h=from:subject:message-id; bh=zxJFH8v87kXfldcYDDUIbUkkqOIeTECoXrgC66NUKAo=; b=+6+MW8GDrjkVjh/SAwayTj8/7EKgZFImA3sw7qmR2S8xJjLscSivctuWHM4Vuu3U6QdjHiqiO Y5a1K5l+DwCBaUYK8kBvslUV0AXT55TMEconNvYXYG1vBM2RRCjZXO7 X-Developer-Key: i=michael.reeves077@gmail.com; a=ed25519; pk=VJ0TvyQ9TvfzYZa908YSE9kpkjFLLD5luv0bERu+boc= X-Endpoint-Received: by B4 Relay for michael.reeves077@gmail.com/fedora-20260918 with auth_id=1035 X-Original-From: Michael Reeves Reply-To: michael.reeves077@gmail.com From: Michael Reeves Add disabled MTP nodes for the Apple SoCs used by M2 and M3 systems. Each instance describes the RTKit ASC mailbox, MTP DART, DockChannel mailbox, and DockChannel HID client. Board files can enable them on machines that route internal input through MTP. Co-developed-by: Hector Martin Signed-off-by: Hector Martin Signed-off-by: Michael Reeves --- arch/arm64/boot/dts/apple/t602x-die0.dtsi | 46 +++++++++++++++++++++++++++= +++ arch/arm64/boot/dts/apple/t6030.dtsi | 46 +++++++++++++++++++++++++++= +++ arch/arm64/boot/dts/apple/t6031-die0.dtsi | 46 +++++++++++++++++++++++++++= +++ arch/arm64/boot/dts/apple/t8112.dtsi | 46 +++++++++++++++++++++++++++= +++ arch/arm64/boot/dts/apple/t8122.dtsi | 47 +++++++++++++++++++++++++++= ++++ 5 files changed, 231 insertions(+) diff --git a/arch/arm64/boot/dts/apple/t602x-die0.dtsi b/arch/arm64/boot/dt= s/apple/t602x-die0.dtsi index c33623f0e..5f62d0a9c 100644 --- a/arch/arm64/boot/dts/apple/t602x-die0.dtsi +++ b/arch/arm64/boot/dts/apple/t602x-die0.dtsi @@ -161,6 +161,52 @@ pinctrl_smc: pinctrl@2a2820000 { ; }; =20 + mtp_mbox: mbox@2a9408000 { + compatible =3D "apple,t6020-asc-mailbox", "apple,asc-mailbox-v4"; + reg =3D <0x2 0xa9408000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + ; + interrupt-names =3D "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells =3D <0>; + status =3D "disabled"; + }; + + mtp_dart: iommu@2a9808000 { + compatible =3D "apple,t6020-dart", "apple,t8110-dart"; + reg =3D <0x2 0xa9808000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #iommu-cells =3D <1>; + status =3D "disabled"; + }; + + mtp_dockchannel: mailbox@2a9b14000 { + compatible =3D "apple,t6020-dockchannel", "apple,t8112-dockchannel"; + reg =3D <0x2 0xa9b14000 0x0 0x4000>, + <0x2 0xa9b30000 0x0 0x4000>, + <0x2 0xa9b34000 0x0 0x4000>; + reg-names =3D "irq", "config", "data"; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #mbox-cells =3D <0>; + status =3D "disabled"; + }; + + mtp_hid: hid@2a9400000 { + compatible =3D "apple,t6020-dockchannel-hid", "apple,t8112-dockchannel-h= id"; + reg =3D <0x2 0xa9400000 0x0 0x4000>, + <0x2 0xa9c00000 0x0 0x100000>; + reg-names =3D "coproc-asc", "coproc-sram"; + mboxes =3D <&mtp_mbox>, <&mtp_dockchannel>; + mbox-names =3D "asc", "dockchannel"; + iommus =3D <&mtp_dart 1>; + status =3D "disabled"; + }; + sio_dart: iommu@39b008000 { compatible =3D "apple,t6020-dart", "apple,t8110-dart"; reg =3D <0x3 0x9b008000 0x0 0x8000>; diff --git a/arch/arm64/boot/dts/apple/t6030.dtsi b/arch/arm64/boot/dts/app= le/t6030.dtsi index dda9568af..e460e547e 100644 --- a/arch/arm64/boot/dts/apple/t6030.dtsi +++ b/arch/arm64/boot/dts/apple/t6030.dtsi @@ -474,6 +474,52 @@ wdt: watchdog@3642b0000 { interrupts =3D ; }; =20 + mtp_mbox: mbox@37a408000 { + compatible =3D "apple,t6030-asc-mailbox", "apple,asc-mailbox-v4"; + reg =3D <0x3 0x7a408000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + ; + interrupt-names =3D "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells =3D <0>; + status =3D "disabled"; + }; + + mtp_dart: iommu@37a808000 { + compatible =3D "apple,t6030-dart", "apple,t8110-dart"; + reg =3D <0x3 0x7a808000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #iommu-cells =3D <1>; + status =3D "disabled"; + }; + + mtp_dockchannel: mailbox@37ab14000 { + compatible =3D "apple,t6030-dockchannel", "apple,t8112-dockchannel"; + reg =3D <0x3 0x7ab14000 0x0 0x4000>, + <0x3 0x7ab30000 0x0 0x4000>, + <0x3 0x7ab34000 0x0 0x4000>; + reg-names =3D "irq", "config", "data"; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #mbox-cells =3D <0>; + status =3D "disabled"; + }; + + mtp_hid: hid@37a400000 { + compatible =3D "apple,t6030-dockchannel-hid", "apple,t8112-dockchannel-= hid"; + reg =3D <0x3 0x7a400000 0x0 0x4000>, + <0x3 0x7ac00000 0x0 0x100000>; + reg-names =3D "coproc-asc", "coproc-sram"; + mboxes =3D <&mtp_mbox>, <&mtp_dockchannel>; + mbox-names =3D "asc", "dockchannel"; + iommus =3D <&mtp_dart 1>; + status =3D "disabled"; + }; + pinctrl_smc: pinctrl@36c820000 { compatible =3D "apple,t6030-pinctrl", "apple,t8103-pinctrl"; reg =3D <0x3 0x6c820000 0x0 0x4000>; diff --git a/arch/arm64/boot/dts/apple/t6031-die0.dtsi b/arch/arm64/boot/dt= s/apple/t6031-die0.dtsi index 47d08672a..d7a6d72b3 100644 --- a/arch/arm64/boot/dts/apple/t6031-die0.dtsi +++ b/arch/arm64/boot/dts/apple/t6031-die0.dtsi @@ -195,3 +195,49 @@ serial0: serial@391200000 { power-domains =3D <&ps_uart0>; status =3D "disabled"; }; + + mtp_mbox: mbox@2ac408000 { + compatible =3D "apple,t6031-asc-mailbox", "apple,asc-mailbox-v4"; + reg =3D <0x2 0xac408000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + ; + interrupt-names =3D "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells =3D <0>; + status =3D "disabled"; + }; + + mtp_dart: iommu@2ac808000 { + compatible =3D "apple,t6031-dart", "apple,t8110-dart"; + reg =3D <0x2 0xac808000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #iommu-cells =3D <1>; + status =3D "disabled"; + }; + + mtp_dockchannel: mailbox@2acb14000 { + compatible =3D "apple,t6031-dockchannel", "apple,t8112-dockchannel"; + reg =3D <0x2 0xacb14000 0x0 0x4000>, + <0x2 0xacb30000 0x0 0x4000>, + <0x2 0xacb34000 0x0 0x4000>; + reg-names =3D "irq", "config", "data"; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #mbox-cells =3D <0>; + status =3D "disabled"; + }; + + mtp_hid: hid@2ac400000 { + compatible =3D "apple,t6031-dockchannel-hid", "apple,t8112-dockchannel-h= id"; + reg =3D <0x2 0xac400000 0x0 0x4000>, + <0x2 0xacc00000 0x0 0x100000>; + reg-names =3D "coproc-asc", "coproc-sram"; + mboxes =3D <&mtp_mbox>, <&mtp_dockchannel>; + mbox-names =3D "asc", "dockchannel"; + iommus =3D <&mtp_dart 1>; + status =3D "disabled"; + }; diff --git a/arch/arm64/boot/dts/apple/t8112.dtsi b/arch/arm64/boot/dts/app= le/t8112.dtsi index ec248ca05..d5c2f35ef 100644 --- a/arch/arm64/boot/dts/apple/t8112.dtsi +++ b/arch/arm64/boot/dts/apple/t8112.dtsi @@ -987,6 +987,52 @@ pinctrl_aop: pinctrl@24a820000 { ; }; =20 + mtp_mbox: mbox@24e408000 { + compatible =3D "apple,t8112-asc-mailbox", "apple,asc-mailbox-v4"; + reg =3D <0x2 0x4e408000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + ; + interrupt-names =3D "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells =3D <0>; + status =3D "disabled"; + }; + + mtp_dart: iommu@24e808000 { + compatible =3D "apple,t8110-dart"; + reg =3D <0x2 0x4e808000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #iommu-cells =3D <1>; + status =3D "disabled"; + }; + + mtp_dockchannel: mailbox@24eb14000 { + compatible =3D "apple,t8112-dockchannel"; + reg =3D <0x2 0x4eb14000 0x0 0x4000>, + <0x2 0x4eb30000 0x0 0x4000>, + <0x2 0x4eb34000 0x0 0x4000>; + reg-names =3D "irq", "config", "data"; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #mbox-cells =3D <0>; + status =3D "disabled"; + }; + + mtp_hid: hid@24e400000 { + compatible =3D "apple,t8112-dockchannel-hid"; + reg =3D <0x2 0x4e400000 0x0 0x4000>, + <0x2 0x4ec00000 0x0 0x100000>; + reg-names =3D "coproc-asc", "coproc-sram"; + mboxes =3D <&mtp_mbox>, <&mtp_dockchannel>; + mbox-names =3D "asc", "dockchannel"; + iommus =3D <&mtp_dart 1>; + status =3D "disabled"; + }; + ans_mbox: mbox@277408000 { compatible =3D "apple,t8112-asc-mailbox", "apple,asc-mailbox-v4"; reg =3D <0x2 0x77408000 0x0 0x4000>; diff --git a/arch/arm64/boot/dts/apple/t8122.dtsi b/arch/arm64/boot/dts/app= le/t8122.dtsi index 1ee61c5b3..47102f431 100644 --- a/arch/arm64/boot/dts/apple/t8122.dtsi +++ b/arch/arm64/boot/dts/apple/t8122.dtsi @@ -438,6 +438,53 @@ pinctrl_aop: pinctrl@2f4824000 { , ; }; + + mtp_mbox: mbox@2fa408000 { + compatible =3D "apple,t8122-asc-mailbox", "apple,asc-mailbox-v4"; + reg =3D <0x2 0xfa408000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D , + , + , + ; + interrupt-names =3D "send-empty", "send-not-empty", + "recv-empty", "recv-not-empty"; + #mbox-cells =3D <0>; + status =3D "disabled"; + }; + + mtp_dart: iommu@2fa808000 { + compatible =3D "apple,t8122-dart", "apple,t8110-dart"; + reg =3D <0x2 0xfa808000 0x0 0x4000>; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #iommu-cells =3D <1>; + status =3D "disabled"; + }; + + mtp_dockchannel: mailbox@2fab14000 { + compatible =3D "apple,t8122-dockchannel", "apple,t8112-dockchannel"; + reg =3D <0x2 0xfab14000 0x0 0x4000>, + <0x2 0xfab30000 0x0 0x4000>, + <0x2 0xfab34000 0x0 0x4000>; + reg-names =3D "irq", "config", "data"; + interrupt-parent =3D <&aic>; + interrupts =3D ; + #mbox-cells =3D <0>; + status =3D "disabled"; + }; + + mtp_hid: hid@2fa400000 { + compatible =3D "apple,t8122-dockchannel-hid", + "apple,t8112-dockchannel-hid"; + reg =3D <0x2 0xfa400000 0x0 0x4000>, + <0x2 0xfac00000 0x0 0x100000>; + reg-names =3D "coproc-asc", "coproc-sram"; + mboxes =3D <&mtp_mbox>, <&mtp_dockchannel>; + mbox-names =3D "asc", "dockchannel"; + iommus =3D <&mtp_dart 1>; + status =3D "disabled"; + }; }; }; =20 --=20 2.55.0 From nobody Fri Sep 25 00:02:32 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E236A4F7CAB; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738121; cv=none; b=X6tJFmEMq/i9dnxG8fH05242NmsnL0SkIf5Y4piT/3w4ZNGKHhre5abp9h6MnQ+0d4W1UW1R3cs3DQkkvAs+JZCpFn9DP2/yhRmHzBwNlVD7rliJnyv0iEp5KPW/hoHbf0fyeJFILl8eRu+OE26jEjzxuOUbxPY4kqabNfNGt6E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789738121; c=relaxed/simple; bh=XsLeQwB1fLUCtAKmgPFpm557IbbzSOp56z8va3WVDH8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sadcsgI8ZtMTWhMG6Y+sV02jalgQ+SIXAzRhlL55iHEsUzvqDNFI4ZQLb2/o8ZBRvJ/Nc0smUy+A6K2gh33d10PmgzEWMZhseWL4SFxFap7JYAjkEN8FHaMRcBeT1eY+kLajUI/l/l8I2VI2M6HACyUuBrh9XI3tufsi8kztVKY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MNaYGErW; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MNaYGErW" Received: by smtp.kernel.org (Postfix) with ESMTPS id 7FC28C4DDF1; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1789738120; bh=XsLeQwB1fLUCtAKmgPFpm557IbbzSOp56z8va3WVDH8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=MNaYGErWQCvV3M5+lpKWBXF1p0O7L6sf3Ac5JXJz1ZP2Jn59oLJA+F49bPtsvxEZc uu2ZQAcT51KDiinj+K0h98OLZMOvEDEd3HqZahvy+eaA6+JM+p1/34/ZkBsZUF1mP3 bn6wzVnbZUryaq6KgvcUoW8lpmeHDyA/sRd4e81dObIfYYKoa2rZzbRAt+AuRw5BBQ J0QiST1dz6IR4lN8TG9GxbDcXZUCKkpBpsDmgKP98BhnYQlCFRtvES0kaf7PAP5DPN hAaBVmE3bqYsauL/qsToBL5WCCbDIGfq2ir59M0fSO9WcjUfn8Eqi3bS1tV6P3dMSb OsYA/rjY8Mj6A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6D6C9C982D8; Fri, 18 Sep 2026 13:28:40 +0000 (UTC) From: Michael Reeves via B4 Relay Date: Fri, 18 Sep 2026 23:28:40 +1000 Subject: [PATCH v3 10/10] arm64: dts: apple: Enable DockChannel HID on M2 and M3 laptops Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260918-apple-mtp-keyboard-final-v3-10-e356464e454b@gmail.com> References: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> In-Reply-To: <20260918-apple-mtp-keyboard-final-v3-0-e356464e454b@gmail.com> To: Sven Peter , Janne Grunau , Neal Gompa , Jassi Brar , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Hector Martin , Michael Reeves , "Joerg Roedel (AMD)" , Will Deacon , Robin Murphy , Dmitry Torokhov , Jiri Kosina , Benjamin Tissoires Cc: asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, iommu@lists.linux.dev, linux-input@vger.kernel.org, Yureka Lilian , Julian Braha , Sasha Finkelstein X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1789738118; l=7273; i=michael.reeves077@gmail.com; s=fedora-20260918; h=from:subject:message-id; bh=78kUfdeWKUeiEf4dX7SZ0qB0VILZ/K/tdCVxq/uYAb0=; b=TGgCftyINjFjNL0uGFbBppvjrdM3U4Yf9IkDp1GwSU4ezULdUcx5vSDeaD3sAx+dqNhgzbUt7 /tfScv6XQBVDgjGX/wg1xPhPJryLHGdVDcva/wqv68UFTNfSsupAvZ5 X-Developer-Key: i=michael.reeves077@gmail.com; a=ed25519; pk=VJ0TvyQ9TvfzYZa908YSE9kpkjFLLD5luv0bERu+boc= X-Endpoint-Received: by B4 Relay for michael.reeves077@gmail.com/fedora-20260918 with auth_id=1035 X-Original-From: Michael Reeves Reply-To: michael.reeves077@gmail.com From: Michael Reeves Enable the MTP mailbox, DART, DockChannel mailbox, and HID transport on the M2 and M3 laptop device trees using this internal input path. Add a keyboard alias and keyboard child node for each machine so the transport can expose the internal keyboard. Co-developed-by: Hector Martin Signed-off-by: Hector Martin Signed-off-by: Michael Reeves --- arch/arm64/boot/dts/apple/t602x-j414-j416.dtsi | 29 ++++++++++++++++++++++= ++++ arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi | 24 +++++++++++++++++++++ arch/arm64/boot/dts/apple/t8112-j413.dts | 24 +++++++++++++++++++++ arch/arm64/boot/dts/apple/t8112-j415.dts | 24 +++++++++++++++++++++ arch/arm64/boot/dts/apple/t8112-j493.dts | 26 ++++++++++++++++++++++- arch/arm64/boot/dts/apple/t8122-j504.dts | 26 +++++++++++++++++++++++ arch/arm64/boot/dts/apple/t8122-j613.dts | 27 ++++++++++++++++++++++= ++ arch/arm64/boot/dts/apple/t8122-j615.dts | 27 ++++++++++++++++++++++= ++ 8 files changed, 206 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/apple/t602x-j414-j416.dtsi b/arch/arm64/bo= ot/dts/apple/t602x-j414-j416.dtsi index 0e806d8dd..91fda44d9 100644 --- a/arch/arm64/boot/dts/apple/t602x-j414-j416.dtsi +++ b/arch/arm64/boot/dts/apple/t602x-j414-j416.dtsi @@ -16,6 +16,12 @@ =20 #include "t600x-j314-j316.dtsi" =20 +/ { + aliases { + keyboard =3D &keyboard; + }; +}; + &framebuffer0 { power-domains =3D <&ps_disp0_cpu0>, <&ps_dptx_phy_ps>; }; @@ -43,3 +49,26 @@ &wifi0 { &bluetooth0 { compatible =3D "pci14e4,5f72"; }; + +&mtp_mbox { + status =3D "okay"; +}; + +&mtp_dart { + status =3D "okay"; +}; + +&mtp_dockchannel { + status =3D "okay"; +}; + +&mtp_hid { + status =3D "okay"; + + keyboard: keyboard { + hid-country-code =3D <0>; + }; + + stm { + }; +}; diff --git a/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi b/arch/arm64/bo= ot/dts/apple/t603x-j514-j516.dtsi index 517b84c18..f6fe382de 100644 --- a/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi +++ b/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi @@ -21,6 +21,7 @@ / { chassis-type =3D "laptop"; =20 aliases { + keyboard =3D &keyboard; serial0 =3D &serial0; }; =20 @@ -64,3 +65,26 @@ &serial0 { &fpwm0 { status =3D "okay"; }; + +&mtp_mbox { + status =3D "okay"; +}; + +&mtp_dart { + status =3D "okay"; +}; + +&mtp_dockchannel { + status =3D "okay"; +}; + +&mtp_hid { + status =3D "okay"; + + keyboard: keyboard { + hid-country-code =3D <0>; + }; + + stm { + }; +}; diff --git a/arch/arm64/boot/dts/apple/t8112-j413.dts b/arch/arm64/boot/dts= /apple/t8112-j413.dts index 7ccfceb08..5b9bdad3d 100644 --- a/arch/arm64/boot/dts/apple/t8112-j413.dts +++ b/arch/arm64/boot/dts/apple/t8112-j413.dts @@ -20,6 +20,7 @@ / { =20 aliases { bluetooth0 =3D &bluetooth0; + keyboard =3D &keyboard; wifi0 =3D &wifi0; }; =20 @@ -93,3 +94,26 @@ &fpwm1 { }; =20 #include "hwmon-laptop.dtsi" + +&mtp_mbox { + status =3D "okay"; +}; + +&mtp_dart { + status =3D "okay"; +}; + +&mtp_dockchannel { + status =3D "okay"; +}; + +&mtp_hid { + status =3D "okay"; + + keyboard: keyboard { + hid-country-code =3D <0>; + }; + + stm { + }; +}; diff --git a/arch/arm64/boot/dts/apple/t8112-j415.dts b/arch/arm64/boot/dts= /apple/t8112-j415.dts index fdc3409d2..3da132eeb 100644 --- a/arch/arm64/boot/dts/apple/t8112-j415.dts +++ b/arch/arm64/boot/dts/apple/t8112-j415.dts @@ -20,6 +20,7 @@ / { =20 aliases { bluetooth0 =3D &bluetooth0; + keyboard =3D &keyboard; wifi0 =3D &wifi0; }; =20 @@ -93,3 +94,26 @@ &fpwm1 { }; =20 #include "hwmon-laptop.dtsi" + +&mtp_mbox { + status =3D "okay"; +}; + +&mtp_dart { + status =3D "okay"; +}; + +&mtp_dockchannel { + status =3D "okay"; +}; + +&mtp_hid { + status =3D "okay"; + + keyboard: keyboard { + hid-country-code =3D <0>; + }; + + stm { + }; +}; diff --git a/arch/arm64/boot/dts/apple/t8112-j493.dts b/arch/arm64/boot/dts= /apple/t8112-j493.dts index 7cea5c594..ecc057929 100644 --- a/arch/arm64/boot/dts/apple/t8112-j493.dts +++ b/arch/arm64/boot/dts/apple/t8112-j493.dts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Apple MacBook Pro (13-inch, M1, 2022) + * Apple MacBook Pro (13-inch, M2, 2022) * * target-type: J493 * @@ -24,6 +24,7 @@ / { */ aliases { bluetooth0 =3D &bluetooth0; + keyboard =3D &keyboard; touchbar0 =3D &touchbar0; wifi0 =3D &wifi0; }; @@ -149,3 +150,26 @@ touchbar0: touchbar@0 { =20 #include "hwmon-laptop.dtsi" #include "hwmon-fan.dtsi" + +&mtp_mbox { + status =3D "okay"; +}; + +&mtp_dart { + status =3D "okay"; +}; + +&mtp_dockchannel { + status =3D "okay"; +}; + +&mtp_hid { + status =3D "okay"; + + keyboard: keyboard { + hid-country-code =3D <0>; + }; + + stm { + }; +}; diff --git a/arch/arm64/boot/dts/apple/t8122-j504.dts b/arch/arm64/boot/dts= /apple/t8122-j504.dts index 464491b55..a08a130be 100644 --- a/arch/arm64/boot/dts/apple/t8122-j504.dts +++ b/arch/arm64/boot/dts/apple/t8122-j504.dts @@ -18,6 +18,10 @@ / { compatible =3D "apple,j504", "apple,t8122", "apple,arm-platform"; model =3D "Apple MacBook Pro (14-inch, M3, 2023)"; =20 + aliases { + keyboard =3D &keyboard; + }; + led-controller { compatible =3D "pwm-leds"; led-0 { @@ -35,3 +39,25 @@ &fpwm1 { status =3D "okay"; }; =20 +&mtp_mbox { + status =3D "okay"; +}; + +&mtp_dart { + status =3D "okay"; +}; + +&mtp_dockchannel { + status =3D "okay"; +}; + +&mtp_hid { + status =3D "okay"; + + keyboard: keyboard { + hid-country-code =3D <0>; + }; + + stm { + }; +}; diff --git a/arch/arm64/boot/dts/apple/t8122-j613.dts b/arch/arm64/boot/dts= /apple/t8122-j613.dts index 51894ea70..a81326cd5 100644 --- a/arch/arm64/boot/dts/apple/t8122-j613.dts +++ b/arch/arm64/boot/dts/apple/t8122-j613.dts @@ -17,6 +17,10 @@ / { compatible =3D "apple,j613", "apple,t8122", "apple,arm-platform"; model =3D "Apple MacBook Air (13-inch, M3, 2024)"; =20 + aliases { + keyboard =3D &keyboard; + }; + led-controller { compatible =3D "pwm-leds"; led-0 { @@ -33,3 +37,26 @@ led-0 { &fpwm1 { status =3D "okay"; }; + +&mtp_mbox { + status =3D "okay"; +}; + +&mtp_dart { + status =3D "okay"; +}; + +&mtp_dockchannel { + status =3D "okay"; +}; + +&mtp_hid { + status =3D "okay"; + + keyboard: keyboard { + hid-country-code =3D <0>; + }; + + stm { + }; +}; diff --git a/arch/arm64/boot/dts/apple/t8122-j615.dts b/arch/arm64/boot/dts= /apple/t8122-j615.dts index 2a1970c1b..21bcacb6f 100644 --- a/arch/arm64/boot/dts/apple/t8122-j615.dts +++ b/arch/arm64/boot/dts/apple/t8122-j615.dts @@ -17,6 +17,10 @@ / { compatible =3D "apple,j615", "apple,t8122", "apple,arm-platform"; model =3D "Apple MacBook Air (15-inch, M3, 2024)"; =20 + aliases { + keyboard =3D &keyboard; + }; + led-controller { compatible =3D "pwm-leds"; led-0 { @@ -33,3 +37,26 @@ led-0 { &fpwm1 { status =3D "okay"; }; + +&mtp_mbox { + status =3D "okay"; +}; + +&mtp_dart { + status =3D "okay"; +}; + +&mtp_dockchannel { + status =3D "okay"; +}; + +&mtp_hid { + status =3D "okay"; + + keyboard: keyboard { + hid-country-code =3D <0>; + }; + + stm { + }; +}; --=20 2.55.0