From nobody Fri Oct 3 21:35:25 2025 Received: from pegase2.c-s.fr (pegase2.c-s.fr [93.17.235.10]) by smtp.subspace.kernel.org (Postfix) with ESMTP id DE6EB288C2F; Mon, 25 Aug 2025 07:20:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=93.17.235.10 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756106441; cv=none; b=vANxhwBVCCFbn6AhgcHek3xirLBzmAdH2c+jDPlqgCh23XpsS4dTC9GTsuNHC0iuadIdXlJ76Tx0tdVGBkVbXr5FVM0kre7mROLZxaGYwGMidFOAaciPzgojwlRiruxl5SUjRjJsZN3vhSRe79qTXPp++gTvRtiJbivF8Ug6kMY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756106441; c=relaxed/simple; bh=G7scsgL+yrYA4D+2n/22/LhhZgPYYRLFCIoU4FAox1M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jLtpiP308XsWAa6GziE8021+s9gbv2tQaZPDhtbVuXzT2pV6jjbJzT7EYTvfmRPooCI3VYbc16qO/8hHNXhoblGklK/7DWGYi/3Tu7cFVShHA6Bw1N3IXCKfnvz3HJZfhElT+M2oXzEOx9Zvjyo9zfDh3jbk9hXlLPS2nnzSSRA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=csgroup.eu; spf=pass smtp.mailfrom=csgroup.eu; arc=none smtp.client-ip=93.17.235.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=csgroup.eu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=csgroup.eu Received: from localhost (mailhub4.si.c-s.fr [172.26.127.67]) by localhost (Postfix) with ESMTP id 4c9M290qdHz9sSS; Mon, 25 Aug 2025 08:53:21 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase2.c-s.fr ([172.26.127.65]) by localhost (pegase2.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id WS6yEEqteSXJ; Mon, 25 Aug 2025 08:53:21 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase2.c-s.fr (Postfix) with ESMTP id 4c9M286kZpz9sSH; Mon, 25 Aug 2025 08:53:20 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id D3E398B769; Mon, 25 Aug 2025 08:53:20 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id 94toZ_4Vro2v; Mon, 25 Aug 2025 08:53:20 +0200 (CEST) Received: from PO20335.idsi0.si.c-s.fr (unknown [10.25.207.160]) by messagerie.si.c-s.fr (Postfix) with ESMTP id A2F5F8B768; Mon, 25 Aug 2025 08:53:20 +0200 (CEST) From: Christophe Leroy To: Qiang Zhao , Linus Walleij , Bartosz Golaszewski , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Christophe Leroy , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, devicetree@vger.kernel.org Subject: [PATCH v3 1/6] soc: fsl: qe: Add an interrupt controller for QUICC Engine Ports Date: Mon, 25 Aug 2025 08:53:16 +0200 Message-ID: <6e6561f55c4cd51774e1b28268493ed2cd53ffc7.1756104334.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1756104796; l=5183; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=G7scsgL+yrYA4D+2n/22/LhhZgPYYRLFCIoU4FAox1M=; b=rdnea9DJY931Mv7VrEienQIjii0Xa12hnBl6Oo7Zx6SspCHJZXdBw5v2VY3Eu8BgzuQdlvdwt gacNAYu6GcRAbuHasgYXldbT95MuGZFpYsCEfMqUOkqiot8KEGMD33J X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The QUICC Engine provides interrupts for a few I/O ports. This is handled via a separate interrupt ID and managed via a triplet of dedicated registers hosted by the SoC. Implement an interrupt driver for it for that those IRQs can then be linked to the related GPIOs. The number of ports for which interrupts are supported depends on the microcontroller: - mpc8323 has 10 interrupts - mpc8360 has 28 interrupts - mpc8568 has 18 interrupts So add this information as data of the compatible. Signed-off-by: Christophe Leroy --- drivers/soc/fsl/qe/Makefile | 2 +- drivers/soc/fsl/qe/qe_ports_ic.c | 156 +++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 drivers/soc/fsl/qe/qe_ports_ic.c diff --git a/drivers/soc/fsl/qe/Makefile b/drivers/soc/fsl/qe/Makefile index ec8506e13113..901a9c40d5eb 100644 --- a/drivers/soc/fsl/qe/Makefile +++ b/drivers/soc/fsl/qe/Makefile @@ -11,4 +11,4 @@ obj-$(CONFIG_UCC_SLOW) +=3D ucc_slow.o obj-$(CONFIG_UCC_FAST) +=3D ucc_fast.o obj-$(CONFIG_QE_TDM) +=3D qe_tdm.o obj-$(CONFIG_QE_USB) +=3D usb.o -obj-$(CONFIG_QE_GPIO) +=3D gpio.o +obj-$(CONFIG_QE_GPIO) +=3D gpio.o qe_ports_ic.o diff --git a/drivers/soc/fsl/qe/qe_ports_ic.c b/drivers/soc/fsl/qe/qe_ports= _ic.c new file mode 100644 index 000000000000..9715643d36a6 --- /dev/null +++ b/drivers/soc/fsl/qe/qe_ports_ic.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * QUICC ENGINE I/O Ports Interrupt Controller + * + * Copyright (c) 2025 Christophe Leroy CS GROUP France (christophe.leroy@c= sgroup.eu) + */ + +#include +#include +#include + +/* QE IC registers offset */ +#define CEPIER 0x0c +#define CEPIMR 0x10 +#define CEPICR 0x14 + +struct qepic_data { + void __iomem *reg; + struct irq_domain *host; +}; + +static void qepic_mask(struct irq_data *d) +{ + struct qepic_data *data =3D irq_data_get_irq_chip_data(d); + + clrbits32(data->reg + CEPIMR, 1 << (31 - irqd_to_hwirq(d))); +} + +static void qepic_unmask(struct irq_data *d) +{ + struct qepic_data *data =3D irq_data_get_irq_chip_data(d); + + setbits32(data->reg + CEPIMR, 1 << (31 - irqd_to_hwirq(d))); +} + +static void qepic_end(struct irq_data *d) +{ + struct qepic_data *data =3D irq_data_get_irq_chip_data(d); + + out_be32(data->reg + CEPIER, 1 << (31 - irqd_to_hwirq(d))); +} + +static int qepic_set_type(struct irq_data *d, unsigned int flow_type) +{ + struct qepic_data *data =3D irq_data_get_irq_chip_data(d); + unsigned int vec =3D (unsigned int)irqd_to_hwirq(d); + + switch (flow_type & IRQ_TYPE_SENSE_MASK) { + case IRQ_TYPE_EDGE_FALLING: + setbits32(data->reg + CEPICR, 1 << (31 - vec)); + return 0; + case IRQ_TYPE_EDGE_BOTH: + case IRQ_TYPE_NONE: + clrbits32(data->reg + CEPICR, 1 << (31 - vec)); + return 0; + } + return -EINVAL; +} + +static struct irq_chip qepic =3D { + .name =3D "QEPIC", + .irq_mask =3D qepic_mask, + .irq_unmask =3D qepic_unmask, + .irq_eoi =3D qepic_end, + .irq_set_type =3D qepic_set_type, +}; + +static int qepic_get_irq(struct irq_desc *desc) +{ + struct qepic_data *data =3D irq_desc_get_handler_data(desc); + u32 event =3D in_be32(data->reg + CEPIER); + + if (!event) + return -1; + + return irq_find_mapping(data->host, 32 - ffs(event)); +} + +static void qepic_cascade(struct irq_desc *desc) +{ + generic_handle_irq(qepic_get_irq(desc)); +} + +static int qepic_host_map(struct irq_domain *h, unsigned int virq, irq_hw_= number_t hw) +{ + irq_set_chip_data(virq, h->host_data); + irq_set_chip_and_handler(virq, &qepic, handle_fasteoi_irq); + return 0; +} + +static const struct irq_domain_ops qepic_host_ops =3D { + .map =3D qepic_host_map, +}; + +static int qepic_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct qepic_data *data; + unsigned long nb; + int irq; + + nb =3D (unsigned long)of_device_get_match_data(dev); + if (nb < 1 || nb > 32) + return -EINVAL; + + data =3D devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->reg =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(data->reg)) + return PTR_ERR(data->reg); + + irq =3D platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + data->host =3D irq_domain_add_linear(dev->of_node, nb, &qepic_host_ops, d= ata); + if (!data->host) + return -ENODEV; + + irq_set_handler_data(irq, data); + irq_set_chained_handler(irq, qepic_cascade); + + return 0; +} + +static const struct of_device_id qepic_match[] =3D { + { + .compatible =3D "fsl,mpc8323-qe-ports-ic", + .data =3D (void *)10, + }, + { + .compatible =3D "fsl,mpc8360-qe-ports-ic", + .data =3D (void *)28, + }, + { + .compatible =3D "fsl,mpc8568-qe-ports-ic", + .data =3D (void *)18, + }, + {}, +}; + +static struct platform_driver qepic_driver =3D { + .driver =3D { + .name =3D "qe_ports_ic", + .of_match_table =3D qepic_match, + }, + .probe =3D qepic_probe, +}; + +static int __init qepic_init(void) +{ + return platform_driver_register(&qepic_driver); +} +arch_initcall(qepic_init); --=20 2.49.0