From nobody Sat Jul 25 20:04:11 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 0A4D03DA7C4; Tue, 14 Jul 2026 08:08:26 +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=1784016507; cv=none; b=aSfOvUwQT6WqzgITXVYLEmz7+LZaBMgU81CO0AGfotI2NQpFLnYqSAuLcKfTl057sMizEvMC9ZErbMXjqNiGc0F5AYA4zCPapw+B9v9LWhPx3IXpchnciAHdOxfnAMR2OD9exs4zM5pBROoIfibwDNjJSnB8eihqxaHe4LEiEuw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784016507; c=relaxed/simple; bh=1JoqAKvb1v+9+8D6Z6hKQDixrMHBsj2+KAE8y7K+VgE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SgINwG2/U44vGHAgPVeBUGMM53iXjJpE/ZMYIdtELvkH3Ky16pjitr1XMqXYPIEJnMEXMlCSnQhQ91xDDouKMfGNptFEirKoVyEhfMp/f7UqOwSn/Fya3NyTyIy8s9yhyyML4O1oaQdDCebyjOyushpKO2IuT72m9O6oMblFL9Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rUpjOmZt; 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="rUpjOmZt" Received: by smtp.kernel.org (Postfix) with ESMTPS id 91B1DC2BCF4; Tue, 14 Jul 2026 08:08:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1784016506; bh=1JoqAKvb1v+9+8D6Z6hKQDixrMHBsj2+KAE8y7K+VgE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=rUpjOmZtT75xj83ZbwU9ymmX5LepMtytDbzi4/8PqHGS22JqWifzAs6lHWc2SSIok vtF/jbpcj5Uh464PiADd7Qex2cDmLnu6LVnjtAszlyePRwGso5PWTM2rkj1bB4MPBI IpdctoBTq+pBSAr/QghTqI4CvabmGAqX4jBHf+bAEMCtdoYTk67Tty40ar+l/PGkeg XmFRiUcXIdX4hyhenNObQNctUMQiJ5v35b7n+Z+WTEg5tsUQzAIToQ5z0J5A7UcZgf /Gpvhh5OrTo0nmikDT7TqaOyss0PMZPzkBBWq8tyhCveWUvNivJ2aSeN+qn6y9hwr0 HwssCC0d/d+pw== 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 719C8C44507; Tue, 14 Jul 2026 08:08:26 +0000 (UTC) From: Xianwei Zhao via B4 Relay Date: Tue, 14 Jul 2026 08:08:22 +0000 Subject: [PATCH v11 1/3] dt-bindings: dma: Add Amlogic A9 SoC DMA 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: <20260714-amlogic-dma-v11-1-de79c2394282@amlogic.com> References: <20260714-amlogic-dma-v11-0-de79c2394282@amlogic.com> In-Reply-To: <20260714-amlogic-dma-v11-0-de79c2394282@amlogic.com> To: Vinod Koul , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Kees Cook , "Gustavo A. R. Silva" , Frank Li Cc: linux-amlogic@lists.infradead.org, dmaengine@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, Xianwei Zhao , Krzysztof Kozlowski X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784016504; l=2916; i=xianwei.zhao@amlogic.com; s=20251216; h=from:subject:message-id; bh=o/Qp8oCw+N9EVwbF9aeiSMMFq+aTHa2sv+r3V4aaRw0=; b=6Ol2T8VYPwXMhxCqvfoGG4CJmGSmph6kYYxU+hYx5OG61IblfX88kRxiSJBeSVhKP3AXVN8n0 s0i8bRRnMYdCSAA8X04Q2x8pbO1+f9zwmphm/ccgkQujLrg+eUWTiy8 X-Developer-Key: i=xianwei.zhao@amlogic.com; a=ed25519; pk=dWwxtWCxC6FHRurOmxEtr34SuBYU+WJowV/ZmRJ7H+k= X-Endpoint-Received: by B4 Relay for xianwei.zhao@amlogic.com/20251216 with auth_id=578 X-Original-From: Xianwei Zhao Reply-To: xianwei.zhao@amlogic.com From: Xianwei Zhao Add documentation describing the Amlogic A9 SoC DMA. And add the properties specific values defines into a new include file. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Xianwei Zhao --- .../devicetree/bindings/dma/amlogic,a9-dma.yaml | 68 ++++++++++++++++++= ++++ include/dt-bindings/dma/amlogic,a9-dma.h | 8 +++ 2 files changed, 76 insertions(+) diff --git a/Documentation/devicetree/bindings/dma/amlogic,a9-dma.yaml b/Do= cumentation/devicetree/bindings/dma/amlogic,a9-dma.yaml new file mode 100644 index 000000000000..6cedd5fdfefd --- /dev/null +++ b/Documentation/devicetree/bindings/dma/amlogic,a9-dma.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/dma/amlogic,a9-dma.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Amlogic general DMA controller + +description: + This is a general-purpose peripheral DMA controller. It currently suppor= ts + major peripherals including I2C, I3C, PIO, and CAN-BUS. Transmit and rec= eive + for the same peripheral use two separate channels, controlled by differe= nt + register sets. I2C and I3C transfer data in 1-byte units, while PIO and + CAN-BUS transfer data in 4-byte units. From the controller=E2=80=99s per= spective, + there is no significant difference. + +maintainers: + - Xianwei Zhao + +properties: + compatible: + const: amlogic,a9-dma + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + const: sys + + '#dma-cells': + const: 2 + description: + The first cell is the DMA channel type(DMA_TX or DMA_RX). + The second cell is the DMA channel index. + + dma-channels: + maximum: 64 + +required: + - compatible + - reg + - interrupts + - clocks + - '#dma-cells' + - dma-channels + +allOf: + - $ref: dma-controller.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + dma-controller@fe400000 { + compatible =3D "amlogic,a9-dma"; + reg =3D <0xfe400000 0x4000>; + interrupts =3D ; + clocks =3D <&clkc 45>; + #dma-cells =3D <2>; + dma-channels =3D <28>; + }; diff --git a/include/dt-bindings/dma/amlogic,a9-dma.h b/include/dt-bindings= /dma/amlogic,a9-dma.h new file mode 100644 index 000000000000..c59c2fd4b956 --- /dev/null +++ b/include/dt-bindings/dma/amlogic,a9-dma.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ + +#ifndef __DT_BINDINGS_DMA_AMLOGIC_DMA_H__ +#define __DT_BINDINGS_DMA_AMLOGIC_DMA_H__ + +#define DMA_TX 0 +#define DMA_RX 1 +#endif /* __DT_BINDINGS_DMA_AMLOGIC_DMA_H__ */ --=20 2.52.0 From nobody Sat Jul 25 20:04:11 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 0A6A93F4822; Tue, 14 Jul 2026 08:08:26 +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=1784016507; cv=none; b=C31Uo18M+9vtFLHsA+gwdhtnIvozC6OuG14tBvGCZ03i/ftM2MRZGydkmFJjfMB+Y3j+8fwQds4zyd85GBxJH2SpDu48EfaC2ZA2xyXYKQ53NP9+kDfpiKFia1ZQVrn4vBxqeaSVVq0/1HF8qmWr7PuA8/iXeOfcgYIEqEzhnlU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784016507; c=relaxed/simple; bh=mAo/mBJ1cTHwc4LaukIjK7CkedJHOy8DtAG9B37QKVc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=o8w/ZsgNFqZDVpyo6mkNpmog2mUINoaaPFN+9zRwv50//ITbcmZ6uW9Tro+bkPP9frM3dpXiak9o9/IQuwfUUEuHIVsMau8LxrJkuqoMMwGiZy1jPmTtZFXICgF3sRlQ63egHADZB5ceys1sEkiZV7kB2A8ImBym7jGjZwPnBr4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nwDSoMVh; 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="nwDSoMVh" Received: by smtp.kernel.org (Postfix) with ESMTPS id A20C5C2BCC9; Tue, 14 Jul 2026 08:08:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1784016506; bh=mAo/mBJ1cTHwc4LaukIjK7CkedJHOy8DtAG9B37QKVc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=nwDSoMVheCfa/26S6ltjWDoJVQ3timWgRheLXM0u4xIFjbIbEV2LQR5j5Z8bvq9Rt E/lMjNW/8q13TidRbrIlUVufeVXLuNaAnLfm2gAkfsGmK9uiv8X0a+E6xXiGRXnOI6 TM3innmJdcA0Y9V2Ne4tCJQAfWUrn4sSfRjr3CDHlB1/+FOdM+m9yVgMVSi+hxNFP9 dR2pc0ag787e2Uiozw7OK3nyVpmH8t9Jhvxhdl1Uh6Ji9W8+03fy4AmFsB053NYrgC e1ymmSS/MP+R/l5E3TaIXZfC3jqo2dVUTFtNCrohwbbn6Vv+FkKUmFycvMmhq+so7M yov6HS+Uv8hdA== 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 843B4C44501; Tue, 14 Jul 2026 08:08:26 +0000 (UTC) From: Xianwei Zhao via B4 Relay Date: Tue, 14 Jul 2026 08:08:23 +0000 Subject: [PATCH v11 2/3] dmaengine: amlogic: Add general DMA driver for A9 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: <20260714-amlogic-dma-v11-2-de79c2394282@amlogic.com> References: <20260714-amlogic-dma-v11-0-de79c2394282@amlogic.com> In-Reply-To: <20260714-amlogic-dma-v11-0-de79c2394282@amlogic.com> To: Vinod Koul , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Kees Cook , "Gustavo A. R. Silva" , Frank Li Cc: linux-amlogic@lists.infradead.org, dmaengine@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, Xianwei Zhao , Frank Li X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784016504; l=24938; i=xianwei.zhao@amlogic.com; s=20251216; h=from:subject:message-id; bh=gyzTthftWqL/oquDJI3xZV4UDfYRO+WohE3CsdIfEWo=; b=KJsACqojf7x43MGHEJ4jVvz3tggYKX5EcKj8kFblVgjLTcEWswKZHF3F0o8FZvwd17yM2rhmN IOHSDU5rDKbA6dGxf4/P9K02ohkn9dSLSJlzmHXJwF2t0iQyIBzBsAu X-Developer-Key: i=xianwei.zhao@amlogic.com; a=ed25519; pk=dWwxtWCxC6FHRurOmxEtr34SuBYU+WJowV/ZmRJ7H+k= X-Endpoint-Received: by B4 Relay for xianwei.zhao@amlogic.com/20251216 with auth_id=578 X-Original-From: Xianwei Zhao Reply-To: xianwei.zhao@amlogic.com From: Xianwei Zhao Amlogic A9 SoCs include a general-purpose DMA controller that can be used by multiple peripherals, such as I2C PIO and I3C. Each peripheral group is associated with a dedicated DMA channel in hardware. Reviewed-by: Frank Li Signed-off-by: Xianwei Zhao --- drivers/dma/Kconfig | 10 + drivers/dma/Makefile | 1 + drivers/dma/amlogic-dma.c | 726 ++++++++++++++++++++++++++++++++++++++++++= ++++ 3 files changed, 737 insertions(+) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index ae6a682c9f76..01f96a8257e5 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -85,6 +85,16 @@ config AMCC_PPC440SPE_ADMA help Enable support for the AMCC PPC440SPe RAID engines. =20 +config AMLOGIC_DMA + tristate "Amlogic general DMA support" + depends on ARCH_MESON || COMPILE_TEST + select DMA_ENGINE + select DMA_VIRTUAL_CHANNELS + select REGMAP_MMIO + help + Enable support for the Amlogic general DMA engines. THis DMA + controller is used some Amlogic SoCs, such as A9. + config APPLE_ADMAC tristate "Apple ADMAC support" depends on ARCH_APPLE || COMPILE_TEST diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 14aa086629d5..f62d12b08e15 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_DMATEST) +=3D dmatest.o obj-$(CONFIG_ALTERA_MSGDMA) +=3D altera-msgdma.o obj-$(CONFIG_AMBA_PL08X) +=3D amba-pl08x.o obj-$(CONFIG_AMCC_PPC440SPE_ADMA) +=3D ppc4xx/ +obj-$(CONFIG_AMLOGIC_DMA) +=3D amlogic-dma.o obj-$(CONFIG_APPLE_ADMAC) +=3D apple-admac.o obj-$(CONFIG_ARM_DMA350) +=3D arm-dma350.o obj-$(CONFIG_AT_HDMAC) +=3D at_hdmac.o diff --git a/drivers/dma/amlogic-dma.c b/drivers/dma/amlogic-dma.c new file mode 100644 index 000000000000..9de650a79aba --- /dev/null +++ b/drivers/dma/amlogic-dma.c @@ -0,0 +1,726 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) +/* + * Copyright (C) 2025 Amlogic, Inc. All rights reserved + * Author: Xianwei Zhao + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "virt-dma.h" + +#define RCH_REG_BASE 0x0 +#define WCH_REG_BASE 0x2000 +/* + * Each rch (read from memory) REG offset Rch_offset 0x0 each channel tot= al 0x40 + * rch addr =3D DMA_base + Rch_offset+ chan_id * 0x40 + reg_offset + */ +#define RCH_READY 0x0 +#define RCH_STATUS 0x4 +#define RCH_CFG 0x8 +#define CFG_CLEAR BIT(25) +#define CFG_PAUSE BIT(26) +#define CFG_ENABLE BIT(27) +#define CFG_DONE BIT(28) +#define RCH_ADDR 0xc +#define RCH_LEN 0x10 +#define RCH_RD_LEN 0x14 +#define RCH_PRT 0x18 +#define RCH_SYCN_STAT 0x1c +#define RCH_ADDR_LOW 0x20 +#define RCH_ADDR_HIGH 0x24 +/* if work on 64, it work with RCH_PRT */ +#define RCH_PTR_HIGH 0x28 + +/* + * Each wch (write to memory) REG offset Wch_offset 0x2000 each channel t= otal 0x40 + * wch addr =3D DMA_base + Wch_offset+ chan_id * 0x40 + reg_offset + */ +#define WCH_READY 0x0 +#define WCH_TOTAL_LEN 0x4 +#define WCH_CFG 0x8 +#define WCH_ADDR 0xc +#define WCH_LEN 0x10 +#define WCH_RD_LEN 0x14 +#define WCH_PRT 0x18 +#define WCH_CMD_CNT 0x1c +#define WCH_ADDR_LOW 0x20 +#define WCH_ADDR_HIGH 0x24 +/* if work on 64, it work with RCH_PRT */ +#define WCH_PTR_HIGH 0x28 + +/* DMA controller reg */ +#define RCH_INT_MASK 0x1000 +#define WCH_INT_MASK 0x1004 +#define CLEAR_W_BATCH 0x1014 +#define CLEAR_RCH 0x1024 +#define CLEAR_WCH 0x1028 +#define RCH_ACTIVE 0x1038 +#define WCH_ACTIVE 0x103c +#define RCH_DONE 0x104c +#define WCH_DONE 0x1050 +#define RCH_ERR 0x1060 +#define RCH_LEN_ERR 0x1064 +#define WCH_ERR 0x1068 +#define DMA_BATCH_END 0x1078 +#define WCH_EOC_DONE 0x1088 +#define WDMA_RESP_ERR 0x1098 +#define UPT_PKT_SYNC 0x10a8 +#define RCHN_CFG 0x10ac +#define WCHN_CFG 0x10b0 +#define MEM_PD_CFG 0x10b4 +#define MEM_BUS_CFG 0x10b8 +#define DMA_GMV_CFG 0x10bc +#define DMA_GMR_CFG 0x10c0 + +#define MAX_CHAN_ID 32 +#define SG_MAX_LEN (GENMASK(26, 0) & ~0x3) + +struct aml_dma_sg_link { +#define LINK_LEN GENMASK(26, 0) +#define LINK_IRQ BIT(27) +#define LINK_EOC BIT(28) +#define LINK_LOOP BIT(29) +#define LINK_ERR BIT(30) +#define LINK_OWNER BIT(31) + u32 ctl; + u32 addr_low; + u32 addr_high; + u32 revered; +} __packed; + +/* 1 page for link 256*16 */ +#define DMA_MAX_LINK 256 +/* sizeof(struct aml_dma_sg_link) */ +#define DMA_LINK_SIZE 16 +#define DMA_LINK_MAX_SIZE (DMA_LINK_SIZE * DMA_MAX_LINK) + +struct aml_dma_desc { + struct virt_dma_desc vd; + struct aml_dma_sg_link *sg_link; + struct dma_device *dma_device; + dma_addr_t sg_link_phys; + size_t sg_link_size; + u32 data_len; + struct work_struct free_work; +}; + +struct aml_dma_chan { + struct virt_dma_chan vchan; + struct aml_dma_dev *aml_dma; + struct aml_dma_desc *cur_desc; + enum dma_status pre_status; + enum dma_status status; + enum dma_transfer_direction direction; + int chan_id; + /* reg_base (direction + chan_id) */ + int reg_offs; + /* When there are multiple consecutive transmission errors, this chanel h= alt */ + int err_num; +}; + +struct aml_dma_dev { + struct dma_device dma_device; + void __iomem *base; + struct regmap *regmap; + struct clk *clk; + int irq; + struct platform_device *pdev; + struct aml_dma_chan *aml_rch[MAX_CHAN_ID]; + struct aml_dma_chan *aml_wch[MAX_CHAN_ID]; + unsigned int chan_nr; + unsigned int chan_used; + struct aml_dma_chan aml_chans[]__counted_by(chan_nr); +}; + +static inline struct aml_dma_chan *to_aml_dma_chan(struct dma_chan *chan) +{ + return container_of(chan, struct aml_dma_chan, vchan.chan); +} + +static inline struct aml_dma_desc *to_aml_dma_desc(struct virt_dma_desc *v= d) +{ + return container_of(vd, struct aml_dma_desc, vd); +} + +static void aml_dma_free_desc_work(struct work_struct *work) +{ + struct aml_dma_desc *aml_desc =3D + container_of(work, struct aml_dma_desc, free_work); + + dma_free_coherent(aml_desc->dma_device->dev, + aml_desc->sg_link_size, + aml_desc->sg_link, + aml_desc->sg_link_phys); + kfree(aml_desc); +} + +static void aml_dma_free_desc(struct virt_dma_desc *vd) +{ + struct aml_dma_desc *aml_desc =3D to_aml_dma_desc(vd); + + schedule_work(&aml_desc->free_work); +} + +static int aml_dma_alloc_chan_resources(struct dma_chan *chan) +{ + struct aml_dma_chan *aml_chan =3D to_aml_dma_chan(chan); + struct aml_dma_dev *aml_dma =3D aml_chan->aml_dma; + + /* offset is the same RCH_CFG and WCH_CFG */ + regmap_set_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_CLEAR); + regmap_clear_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_PAUS= E); + regmap_clear_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_CLEA= R); + + aml_chan->status =3D DMA_COMPLETE; + aml_chan->cur_desc =3D NULL; + aml_chan->err_num =3D 0; + + return 0; +} + +static void aml_dma_free_chan_resources(struct dma_chan *chan) +{ + struct aml_dma_chan *aml_chan =3D to_aml_dma_chan(chan); + struct aml_dma_dev *aml_dma =3D aml_chan->aml_dma; + struct virt_dma_desc *cur_vd =3D NULL; + unsigned long flags; + + spin_lock_irqsave(&aml_chan->vchan.lock, flags); + regmap_set_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_PAUSE); + regmap_set_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_CLEAR); + if (aml_chan->cur_desc) + cur_vd =3D &aml_chan->cur_desc->vd; + aml_chan->cur_desc =3D NULL; + spin_unlock_irqrestore(&aml_chan->vchan.lock, flags); + if (cur_vd) + aml_dma_free_desc(cur_vd); + + vchan_free_chan_resources(&aml_chan->vchan); +} + +/* DMA transfer state update how many data reside it */ +static enum dma_status aml_dma_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, + struct dma_tx_state *txstate) +{ + struct aml_dma_chan *aml_chan =3D to_aml_dma_chan(chan); + struct aml_dma_dev *aml_dma =3D aml_chan->aml_dma; + struct aml_dma_desc *aml_desc =3D NULL; + struct virt_dma_desc *vd; + u32 residue =3D 0, done; + unsigned long flags; + enum dma_status ret; + + ret =3D dma_cookie_status(chan, cookie, txstate); + if (ret =3D=3D DMA_COMPLETE) + return ret; + + ret =3D aml_chan->status; + if (!txstate) + return ret; + + spin_lock_irqsave(&aml_chan->vchan.lock, flags); + vd =3D vchan_find_desc(&aml_chan->vchan, cookie); + spin_unlock_irqrestore(&aml_chan->vchan.lock, flags); + if (vd) { + aml_desc =3D to_aml_dma_desc(vd); + residue =3D aml_desc->data_len; + } else if (aml_chan->cur_desc && aml_chan->cur_desc->vd.tx.cookie =3D=3D = cookie) { + aml_desc =3D aml_chan->cur_desc; + regmap_read(aml_dma->regmap, aml_chan->reg_offs + RCH_RD_LEN, &done); + residue =3D aml_desc->data_len - done; + } else { + dev_err(aml_dma->dma_device.dev, "cookie error\n"); + } + dma_set_residue(txstate, residue); + + return ret; +} + +static struct dma_async_tx_descriptor *aml_dma_prep_slave_sg + (struct dma_chan *chan, struct scatterlist *sgl, + unsigned int sg_len, enum dma_transfer_direction direction, + unsigned long flags, void *context) +{ + struct aml_dma_chan *aml_chan =3D to_aml_dma_chan(chan); + struct aml_dma_dev *aml_dma =3D aml_chan->aml_dma; + struct aml_dma_desc *aml_desc =3D NULL; + struct aml_dma_sg_link *sg_link =3D NULL; + struct scatterlist *sg =3D NULL; + u64 paddr; + u32 link_count, avail; + u32 i; + + if (aml_chan->direction !=3D direction) { + dev_err(aml_dma->dma_device.dev, "direction not support\n"); + return NULL; + } + + link_count =3D sg_nents_for_dma(sgl, sg_len, SG_MAX_LEN); + if (link_count =3D=3D 0) + return NULL; + + aml_desc =3D kzalloc_obj(*aml_desc, GFP_NOWAIT); + if (!aml_desc) + return NULL; + + INIT_WORK(&aml_desc->free_work, aml_dma_free_desc_work); + aml_desc->sg_link_size =3D link_count * sizeof(*sg_link); + aml_desc->sg_link =3D dma_alloc_coherent(aml_dma->dma_device.dev, aml_des= c->sg_link_size, + &aml_desc->sg_link_phys, GFP_NOWAIT); + if (!aml_desc->sg_link) { + kfree(aml_desc); + return NULL; + } + aml_desc->dma_device =3D &aml_dma->dma_device; + + sg_link =3D aml_desc->sg_link; + for_each_sg(sgl, sg, sg_len, i) { + avail =3D sg_dma_len(sg); + if (avail =3D=3D 0) + continue; + paddr =3D sg->dma_address; + while (avail > SG_MAX_LEN) { + /* set dma address and len to sglink*/ + sg_link->addr_low =3D lower_32_bits(paddr); + sg_link->addr_high =3D upper_32_bits(paddr); + sg_link->ctl =3D FIELD_PREP(LINK_LEN, SG_MAX_LEN); + paddr =3D paddr + SG_MAX_LEN; + avail =3D avail - SG_MAX_LEN; + sg_link++; + } + /* set dma address and len to sglink*/ + sg_link->addr_low =3D lower_32_bits(paddr); + sg_link->addr_high =3D upper_32_bits(paddr); + sg_link->ctl =3D FIELD_PREP(LINK_LEN, avail); + + aml_desc->data_len +=3D sg_dma_len(sg); + sg_link++; + } + + /* the last sg set eoc flag */ + sg_link--; + sg_link->ctl |=3D LINK_EOC; + + return vchan_tx_prep(&aml_chan->vchan, &aml_desc->vd, flags); +} + +static int aml_dma_chan_pause(struct dma_chan *chan) +{ + struct aml_dma_chan *aml_chan =3D to_aml_dma_chan(chan); + struct aml_dma_dev *aml_dma =3D aml_chan->aml_dma; + unsigned long flags; + + spin_lock_irqsave(&aml_chan->vchan.lock, flags); + regmap_set_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_PAUSE); + aml_chan->pre_status =3D aml_chan->status; + aml_chan->status =3D DMA_PAUSED; + spin_unlock_irqrestore(&aml_chan->vchan.lock, flags); + + return 0; +} + +static int aml_dma_chan_resume(struct dma_chan *chan) +{ + struct aml_dma_chan *aml_chan =3D to_aml_dma_chan(chan); + struct aml_dma_dev *aml_dma =3D aml_chan->aml_dma; + unsigned long flags; + + spin_lock_irqsave(&aml_chan->vchan.lock, flags); + regmap_clear_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_PAUS= E); + aml_chan->status =3D aml_chan->pre_status; + spin_unlock_irqrestore(&aml_chan->vchan.lock, flags); + + return 0; +} + +static int aml_dma_terminate_all(struct dma_chan *chan) +{ + struct aml_dma_chan *aml_chan =3D to_aml_dma_chan(chan); + struct aml_dma_dev *aml_dma =3D aml_chan->aml_dma; + int chan_id =3D aml_chan->chan_id; + struct virt_dma_desc *cur_vd; + unsigned long flags; + LIST_HEAD(head); + + spin_lock_irqsave(&aml_chan->vchan.lock, flags); + regmap_set_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_PAUSE); + regmap_set_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_CLEAR); + + if (aml_chan->direction =3D=3D DMA_MEM_TO_DEV) + regmap_set_bits(aml_dma->regmap, RCH_INT_MASK, BIT(chan_id)); + else if (aml_chan->direction =3D=3D DMA_DEV_TO_MEM) + regmap_set_bits(aml_dma->regmap, WCH_INT_MASK, BIT(chan_id)); + + vchan_get_all_descriptors(&aml_chan->vchan, &head); + cur_vd =3D &aml_chan->cur_desc->vd; + aml_chan->cur_desc =3D NULL; + spin_unlock_irqrestore(&aml_chan->vchan.lock, flags); + if (cur_vd) + aml_dma_free_desc(cur_vd); + + vchan_dma_desc_free_list(&aml_chan->vchan, &head); + + regmap_clear_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_PAUS= E); + regmap_clear_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_CLEA= R); + aml_chan->status =3D DMA_COMPLETE; + aml_chan->err_num =3D 0; + + return 0; +} + +static void aml_dma_start(struct aml_dma_chan *aml_chan) +{ + struct virt_dma_desc *vd =3D vchan_next_desc(&aml_chan->vchan); + struct aml_dma_dev *aml_dma =3D aml_chan->aml_dma; + struct aml_dma_desc *aml_desc =3D NULL; + int chan_id =3D aml_chan->chan_id; + + if (aml_chan->status =3D=3D DMA_ERROR) { + if (aml_chan->err_num > 5) { + dev_err(aml_dma->dma_device.dev, "hw error\n"); + return; + } + regmap_set_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_PAUSE= ); + regmap_set_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_CLEAR= ); + aml_chan->err_num++; + regmap_clear_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_PAU= SE); + regmap_clear_bits(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, CFG_CLE= AR); + aml_chan->status =3D DMA_COMPLETE; + } else { + aml_chan->err_num =3D 0; + } + + if (!vd) + return; + + if (aml_chan->status !=3D DMA_COMPLETE) + return; + + list_del(&vd->node); + aml_desc =3D to_aml_dma_desc(vd); + aml_chan->cur_desc =3D aml_desc; + + if (aml_chan->direction =3D=3D DMA_MEM_TO_DEV) { + regmap_write(aml_dma->regmap, aml_chan->reg_offs + RCH_ADDR, + lower_32_bits(aml_desc->sg_link_phys)); + regmap_write(aml_dma->regmap, aml_chan->reg_offs + RCH_ADDR_HIGH, + upper_32_bits(aml_desc->sg_link_phys)); + regmap_write(aml_dma->regmap, aml_chan->reg_offs + RCH_LEN, aml_desc->da= ta_len); + regmap_clear_bits(aml_dma->regmap, RCH_INT_MASK, BIT(chan_id)); + /* for rch (tx) need set cfg 0 to trigger start */ + regmap_write(aml_dma->regmap, aml_chan->reg_offs + RCH_CFG, 0); + } else if (aml_chan->direction =3D=3D DMA_DEV_TO_MEM) { + regmap_write(aml_dma->regmap, aml_chan->reg_offs + WCH_ADDR, + lower_32_bits(aml_desc->sg_link_phys)); + regmap_write(aml_dma->regmap, aml_chan->reg_offs + WCH_ADDR_HIGH, + upper_32_bits(aml_desc->sg_link_phys)); + regmap_write(aml_dma->regmap, aml_chan->reg_offs + WCH_LEN, aml_desc->da= ta_len); + regmap_clear_bits(aml_dma->regmap, WCH_INT_MASK, BIT(chan_id)); + } +} + +static void aml_dma_issue_pending(struct dma_chan *chan) +{ + struct aml_dma_chan *aml_chan =3D to_aml_dma_chan(chan); + unsigned long flags; + + spin_lock_irqsave(&aml_chan->vchan.lock, flags); + if (vchan_issue_pending(&aml_chan->vchan) && !aml_chan->cur_desc) + aml_dma_start(aml_chan); + spin_unlock_irqrestore(&aml_chan->vchan.lock, flags); +} + +static irqreturn_t aml_dma_interrupt_handler(int irq, void *dev_id) +{ + struct aml_dma_dev *aml_dma =3D dev_id; + struct aml_dma_chan *aml_chan; + struct aml_dma_desc *aml_desc; + u32 done, eoc_done, err, err_l, end; + u32 cpl_data; + int i =3D 0; + + /* deal with rch normal complete and error */ + regmap_read(aml_dma->regmap, RCH_DONE, &done); + regmap_read(aml_dma->regmap, RCH_ERR, &err); + regmap_read(aml_dma->regmap, RCH_LEN_ERR, &err_l); + err =3D err | err_l; + + done =3D done | err; + + while (done) { + i =3D ffs(done) - 1; + regmap_write(aml_dma->regmap, CLEAR_RCH, BIT(i)); + done &=3D ~BIT(i); + aml_chan =3D aml_dma->aml_rch[i]; + if (!aml_chan) { + dev_err(aml_dma->dma_device.dev, "idx %d rch not initialized\n", i); + continue; + } + spin_lock(&aml_chan->vchan.lock); + aml_chan->status =3D (err & BIT(i)) ? DMA_ERROR : DMA_COMPLETE; + aml_desc =3D aml_chan->cur_desc; + if (!aml_desc) { + spin_unlock(&aml_chan->vchan.lock); + continue; + } + if (aml_chan->status =3D=3D DMA_ERROR) { + aml_desc->vd.tx_result.result =3D DMA_TRANS_READ_FAILED; + regmap_read(aml_dma->regmap, aml_chan->reg_offs + RCH_RD_LEN, &cpl_data= ); + aml_desc->vd.tx_result.residue =3D aml_desc->data_len - cpl_data; + } + vchan_cookie_complete(&aml_desc->vd); + aml_chan->cur_desc =3D NULL; + aml_dma_start(aml_chan); + spin_unlock(&aml_chan->vchan.lock); + } + + /* deal with wch normal complete and error */ + regmap_read(aml_dma->regmap, DMA_BATCH_END, &end); + if (end) + regmap_write(aml_dma->regmap, CLEAR_W_BATCH, end); + + regmap_read(aml_dma->regmap, WCH_DONE, &done); + regmap_read(aml_dma->regmap, WCH_EOC_DONE, &eoc_done); + done =3D done | eoc_done; + + regmap_read(aml_dma->regmap, WCH_ERR, &err); + regmap_read(aml_dma->regmap, WDMA_RESP_ERR, &err_l); + err =3D err | err_l; + + done =3D done | err; + i =3D 0; + while (done) { + i =3D ffs(done) - 1; + done &=3D ~BIT(i); + regmap_write(aml_dma->regmap, CLEAR_WCH, BIT(i)); + aml_chan =3D aml_dma->aml_wch[i]; + if (!aml_chan) { + dev_err(aml_dma->dma_device.dev, "idx %d wch not initialized\n", i); + continue; + } + spin_lock(&aml_chan->vchan.lock); + aml_chan->status =3D (err & BIT(i)) ? DMA_ERROR : DMA_COMPLETE; + aml_desc =3D aml_chan->cur_desc; + if (!aml_desc) { + spin_unlock(&aml_chan->vchan.lock); + continue; + } + if (aml_chan->status =3D=3D DMA_ERROR) { + aml_desc->vd.tx_result.result =3D DMA_TRANS_WRITE_FAILED; + regmap_read(aml_dma->regmap, aml_chan->reg_offs + RCH_RD_LEN, &cpl_data= ); + aml_desc->vd.tx_result.residue =3D aml_desc->data_len - cpl_data; + } + vchan_cookie_complete(&aml_desc->vd); + aml_chan->cur_desc =3D NULL; + aml_dma_start(aml_chan); + spin_unlock(&aml_chan->vchan.lock); + } + + return IRQ_HANDLED; +} + +static struct dma_chan *aml_of_dma_xlate(struct of_phandle_args *dma_spec,= struct of_dma *ofdma) +{ + struct aml_dma_dev *aml_dma =3D (struct aml_dma_dev *)ofdma->of_dma_data; + struct aml_dma_chan *aml_chan =3D NULL; + u32 type; + u32 phy_chan_id; + + if (dma_spec->args_count !=3D 2) + return NULL; + + type =3D dma_spec->args[0]; + phy_chan_id =3D dma_spec->args[1]; + + if (phy_chan_id >=3D MAX_CHAN_ID) + return NULL; + + if (type =3D=3D DMA_TX) { + aml_chan =3D aml_dma->aml_rch[phy_chan_id]; + if (!aml_chan) { + if (aml_dma->chan_used >=3D aml_dma->chan_nr) { + dev_err(aml_dma->dma_device.dev, "some dma clients err used\n"); + return NULL; + } + aml_chan =3D &aml_dma->aml_chans[aml_dma->chan_used]; + aml_dma->chan_used++; + aml_chan->direction =3D DMA_MEM_TO_DEV; + aml_chan->chan_id =3D phy_chan_id; + aml_chan->reg_offs =3D RCH_REG_BASE + 0x40 * aml_chan->chan_id; + aml_dma->aml_rch[phy_chan_id] =3D aml_chan; + } + } else if (type =3D=3D DMA_RX) { + aml_chan =3D aml_dma->aml_wch[phy_chan_id]; + if (!aml_chan) { + if (aml_dma->chan_used >=3D aml_dma->chan_nr) { + dev_err(aml_dma->dma_device.dev, "some dma clients err used\n"); + return NULL; + } + aml_chan =3D &aml_dma->aml_chans[aml_dma->chan_used]; + aml_dma->chan_used++; + aml_chan->direction =3D DMA_DEV_TO_MEM; + aml_chan->chan_id =3D phy_chan_id; + aml_chan->reg_offs =3D WCH_REG_BASE + 0x40 * aml_chan->chan_id; + aml_dma->aml_wch[phy_chan_id] =3D aml_chan; + } + } else { + dev_err(aml_dma->dma_device.dev, "type %d not supported\n", type); + return NULL; + } + + return dma_get_slave_channel(&aml_chan->vchan.chan); +} + +static int aml_dma_probe(struct platform_device *pdev) +{ + struct device_node *np =3D pdev->dev.of_node; + struct dma_device *dma_dev; + struct aml_dma_dev *aml_dma; + int ret, i, len; + u32 chan_nr; + + const struct regmap_config aml_regmap_config =3D { + .reg_bits =3D 32, + .val_bits =3D 32, + .reg_stride =3D 4, + .max_register =3D 0x3000, + }; + + ret =3D of_property_read_u32(np, "dma-channels", &chan_nr); + if (ret) + return dev_err_probe(&pdev->dev, ret, "failed to read dma-channels\n"); + if (chan_nr > (MAX_CHAN_ID * 2)) + return dev_err_probe(&pdev->dev, -EINVAL, "dma-channels unusual\n"); + + len =3D sizeof(struct aml_dma_dev) + sizeof(struct aml_dma_chan) * chan_n= r; + aml_dma =3D devm_kzalloc(&pdev->dev, len, GFP_KERNEL); + if (!aml_dma) + return -ENOMEM; + + aml_dma->chan_nr =3D chan_nr; + + aml_dma->base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(aml_dma->base)) + return PTR_ERR(aml_dma->base); + + aml_dma->regmap =3D devm_regmap_init_mmio(&pdev->dev, aml_dma->base, + &aml_regmap_config); + if (IS_ERR_OR_NULL(aml_dma->regmap)) + return PTR_ERR(aml_dma->regmap); + + aml_dma->clk =3D devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(aml_dma->clk)) + return PTR_ERR(aml_dma->clk); + + aml_dma->irq =3D platform_get_irq(pdev, 0); + + aml_dma->pdev =3D pdev; + aml_dma->dma_device.dev =3D &pdev->dev; + + dma_dev =3D &aml_dma->dma_device; + INIT_LIST_HEAD(&dma_dev->channels); + + /* Initialize channel parameters */ + for (i =3D 0; i < chan_nr; i++) { + struct aml_dma_chan *aml_chan =3D &aml_dma->aml_chans[i]; + + aml_chan->aml_dma =3D aml_dma; + aml_chan->vchan.desc_free =3D aml_dma_free_desc; + vchan_init(&aml_chan->vchan, &aml_dma->dma_device); + } + aml_dma->chan_used =3D 0; + + dma_set_max_seg_size(dma_dev->dev, SG_MAX_LEN); + dma_cap_set(DMA_SLAVE, dma_dev->cap_mask); + dma_dev->device_alloc_chan_resources =3D aml_dma_alloc_chan_resources; + dma_dev->device_free_chan_resources =3D aml_dma_free_chan_resources; + dma_dev->device_tx_status =3D aml_dma_tx_status; + dma_dev->device_prep_slave_sg =3D aml_dma_prep_slave_sg; + dma_dev->device_pause =3D aml_dma_chan_pause; + dma_dev->device_resume =3D aml_dma_chan_resume; + dma_dev->device_terminate_all =3D aml_dma_terminate_all; + dma_dev->device_issue_pending =3D aml_dma_issue_pending; + /* PIO 4 bytes and I2C 1 byte */ + dma_dev->dst_addr_widths =3D BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | BIT(DMA_SL= AVE_BUSWIDTH_1_BYTE); + dma_dev->directions =3D BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); + dma_dev->residue_granularity =3D DMA_RESIDUE_GRANULARITY_BURST; + + regmap_write(aml_dma->regmap, RCH_INT_MASK, 0xffffffff); + regmap_write(aml_dma->regmap, WCH_INT_MASK, 0xffffffff); + + ret =3D devm_request_irq(&pdev->dev, aml_dma->irq, aml_dma_interrupt_hand= ler, + 0, dev_name(&pdev->dev), aml_dma); + if (ret) + return dev_err_probe(&pdev->dev, ret, "failed to register irq\n"); + + ret =3D dmaenginem_async_device_register(dma_dev); + if (ret) + return dev_err_probe(&pdev->dev, ret, "failed to register dmaenginem\n"); + + ret =3D of_dma_controller_register(np, aml_of_dma_xlate, aml_dma); + if (ret) + return dev_err_probe(&pdev->dev, ret, "failed to register xlate\n"); + + platform_set_drvdata(pdev, aml_dma); + + return 0; +} + +static void aml_dma_remove(struct platform_device *pdev) +{ + struct aml_dma_dev *aml_dma =3D platform_get_drvdata(pdev); + struct aml_dma_chan *aml_chan =3D NULL; + int i; + + of_dma_controller_free((&pdev->dev)->of_node); + + regmap_write(aml_dma->regmap, RCH_INT_MASK, 0xffffffff); + regmap_write(aml_dma->regmap, WCH_INT_MASK, 0xffffffff); + + for (i =3D 0; i < MAX_CHAN_ID; i++) { + aml_chan =3D aml_dma->aml_rch[i]; + if (aml_chan) + tasklet_kill(&aml_chan->vchan.task); + aml_chan =3D aml_dma->aml_wch[i]; + if (aml_chan) + tasklet_kill(&aml_chan->vchan.task); + } +} + +static const struct of_device_id aml_dma_ids[] =3D { + { .compatible =3D "amlogic,a9-dma", }, + { } +}; +MODULE_DEVICE_TABLE(of, aml_dma_ids); + +static struct platform_driver aml_dma_driver =3D { + .probe =3D aml_dma_probe, + .remove =3D aml_dma_remove, + .driver =3D { + .name =3D "aml-dma", + .of_match_table =3D aml_dma_ids, + }, +}; + +module_platform_driver(aml_dma_driver); + +MODULE_DESCRIPTION("GENERAL DMA driver for Amlogic"); +MODULE_AUTHOR("Xianwei Zhao "); +MODULE_LICENSE("GPL"); --=20 2.52.0 From nobody Sat Jul 25 20:04:11 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 0A61B3F411A; Tue, 14 Jul 2026 08:08:26 +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=1784016507; cv=none; b=SR2VyGBwijPtFweTt3AgSxZVP2DlFMNIbbJzDRnhWXXaH0XdblXlQuoOJwiQsAjIY5Qes6Igof1MylM1advojx3i5AfIZa83dZ/bvnPRlRkYt1elyiRiSq+kiMTHCPV3S0pkpqtbliyJFNeiagq3Rqi5UsQVw87BYqpvTXFxTxs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784016507; c=relaxed/simple; bh=NcdLhXrPcWFclpxrmSESajR2JcjuoXQBKnYxQjejsnA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CHPteuny6swf6TVJmSfseWMqt2QsPP8n8ujnghnyK98gpTvFhFizL6OVsV9mGEfdpsH9IdqWxQB5GlCoxI1wGyUxVkdmNBr61umSI0WxdxYrPDCdMX8uvFIVB5HS5okmP7TvWAdgTBfXrp2SZmIxcL+QmZNvyJPUN3wt8il7YX0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nnC1ZLES; 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="nnC1ZLES" Received: by smtp.kernel.org (Postfix) with ESMTPS id B12A6C2BCFC; Tue, 14 Jul 2026 08:08:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1784016506; bh=NcdLhXrPcWFclpxrmSESajR2JcjuoXQBKnYxQjejsnA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=nnC1ZLESWNi63lydbDRZQ1+5qfzZfhKDf2ksDGlimDIKrZiWdCdyJaJhtZf/BwIUq ptj/KW1Ms42Lgu8g7oeiXwYORYe6xWPAmsPivBQtre+1aLVlPiKI6Uja+oUJXyrxWr CCKpkEjiCR78XHjlZUMPTTZJ1mqFnaiEP5AQi/8nMJ1JmXZp0Qj/bC27lHZI6PIW2f jz+dMW5hdGWqvKWA32yG0ipXT2oKgl3SG82+hZPljMqZBE8Rc+u1yirYl/E6QbJHbZ CWCjFdLT70dfnD91Z/Q25cYJCxh3BEDbjZT93CA/fMyNh9tJWspN8m30JeJf6v3+o5 m29MPK5kqAsvA== 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 95C5BC44509; Tue, 14 Jul 2026 08:08:26 +0000 (UTC) From: Xianwei Zhao via B4 Relay Date: Tue, 14 Jul 2026 08:08:24 +0000 Subject: [PATCH v11 3/3] MAINTAINERS: Add an entry for Amlogic DMA 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: <20260714-amlogic-dma-v11-3-de79c2394282@amlogic.com> References: <20260714-amlogic-dma-v11-0-de79c2394282@amlogic.com> In-Reply-To: <20260714-amlogic-dma-v11-0-de79c2394282@amlogic.com> To: Vinod Koul , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Kees Cook , "Gustavo A. R. Silva" , Frank Li Cc: linux-amlogic@lists.infradead.org, dmaengine@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org, Xianwei Zhao X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1784016504; l=791; i=xianwei.zhao@amlogic.com; s=20251216; h=from:subject:message-id; bh=9xq7fFe8x3ZtUEb/et7K+dc4J+CzRRN9hABeSR7Mhcs=; b=GQGbDVtN0DJ3QCFuGL8tehM4hRIkFg3vDtt3FA82rPj/nWqzFSNgaqc0Sf5bexu8ulxhVlVmx MgmXhIUAcaiAVSiySyfyU0na9KSRSnmZiHh1QdZLxhrj4ZqphETw9DW X-Developer-Key: i=xianwei.zhao@amlogic.com; a=ed25519; pk=dWwxtWCxC6FHRurOmxEtr34SuBYU+WJowV/ZmRJ7H+k= X-Endpoint-Received: by B4 Relay for xianwei.zhao@amlogic.com/20251216 with auth_id=578 X-Original-From: Xianwei Zhao Reply-To: xianwei.zhao@amlogic.com From: Xianwei Zhao Add Amlogic DMA controller entry to MAINTAINERS to clarify the maintainers. Signed-off-by: Xianwei Zhao --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 3e7b2d9e9c24..b4ef8d3f52cb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1307,6 +1307,13 @@ F: Documentation/devicetree/bindings/perf/amlogic,g1= 2-ddr-pmu.yaml F: drivers/perf/amlogic/ F: include/soc/amlogic/ =20 +AMLOGIC DMA DRIVER +M: Xianwei Zhao +L: linux-amlogic@lists.infradead.org +S: Maintained +F: Documentation/devicetree/bindings/dma/amlogic,a9-dma.yaml +F: drivers/dma/amlogic-dma.c + AMLOGIC ISP DRIVER M: Keke Li L: linux-media@vger.kernel.org --=20 2.52.0