From nobody Tue Feb 10 23:13:44 2026 Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 262E54ADDA2 for ; Wed, 21 Jan 2026 15:01:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769007721; cv=none; b=in0oCQS0n7gbjiVeH5xiTneHN8C7nbckAdNX00XOjv37HhyrqUweYvRBCSjWqM3cckZ85jymscZslEcgjWyN8A/Fi0xI4GADsYRoRHMZy5KZ//WkCqMww7/+adbBCRyNvjZ5mq1Sn6W80tWOw+SAXBsppq1nXU7mGUtYflxIv+w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769007721; c=relaxed/simple; bh=ZHgJbN8Xpa/1C1FZZKvYY2GnxRx8RIG+qmp7yJymjys=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FD02kMFxxKBg15QCI5rQWYM6VrFtg9leYyLgntk45hYf1sph96nBVme3JlqogfYzFZM1K463gPiwjSrTlb45PDkQhbPPRSVSV9wIiNu6K31qCbvOhwbZf7VbxVANYzjkJJqKk2JvU2EkV3sFcNP1Eht/L2CJKwHzeOOyrGsol6A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Kd1Cj9+J; arc=none smtp.client-ip=209.85.128.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Kd1Cj9+J" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-48039fdc8aeso15370825e9.3 for ; Wed, 21 Jan 2026 07:01:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1769007717; x=1769612517; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=K5DmHDY3DPc4B0A5rMMRb7kro45hNcXliNwW1gu8UJU=; b=Kd1Cj9+JKpECLnNm+pvyHrwYWUA+jaRlXHfGG4231NpWn4bgVgmR8VbdWb9R2G6+nz mEOYEiWLme8wcnkue7n0JLQHs5DhOFQuyOPp1gjlbs14C1r9jPGbOp30NXDo7J43q95i pgv3GPSG349qCW60fQkWlaJRh1lbt8kmuyvZgqLX952T+c9Z6wWXIr8GGDLioDsmtbMe 1a5wAsMffvRJjpUfWAo6VNfkiNvYiz2tOaUNzJZKc3M89+QLvfu3CYoIWlHo3DevazUE UB0HYqP71N7tsYRrTsMPQZs0EtAP6JMiUwCDNfqcqriVmEkE0tl2myyo7C42pWllVYdU ajPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769007717; x=1769612517; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=K5DmHDY3DPc4B0A5rMMRb7kro45hNcXliNwW1gu8UJU=; b=KwNVJFK4A1ht+xN1XUqgpJKdSQ/fO+PO9u5X6ntJz9JoK/AgjUcASACEAf1nJZmieE sRRVpjjNz0I5S+moD5IrMhL6Hjp46j526OIWyOxE8TVHs3EJ96hHTSoZYkeeWLA6NvpI KPsuv8NwgSjw4rGKO4N9RdnMv9Sgjz1j3MzY/s815RC83g+kW0nD9gqBe3ki4BuCg3gJ uUgLfCp42W4rz4V5EpoplCgaXoKEChnP7TpSErI4CDMDXG2lYdJMQImEFsvRUUGN5LDK I1N568Tl+Eow0l1ENZnf+C+kLYiDGAeXNMl2QNtPm75J1LzYJmEvanc5fXOkGvvM16vg 3j8g== X-Gm-Message-State: AOJu0YzgrGMPse41ZcVljVB2+052eX78VT0zX22GfZQmNru6rri+HIr6 b+bMzr7S51I9k0gsHsKeTseJp+ZDdTJWMMYrp7FIuohhA/UeGWjqNPF7 X-Gm-Gg: AZuq6aIpOOT52OiKOty8lT8yFdU4wkxrEDqyIGuu6Kgz4yiL+4gFTeCm3F+5BbCQeAe 3zuKZ6h4KC7f3sB/ocKIy93lQZcpgxILNFYq5fzpBryAB1mCPdxICzmGBOr21drcFn7Qzwub/MF HKToqD4SntqHmUaR/tRQsmjyy4BwJ+FjW21BJw7brujxn9k49UhIpJJ6ElO9ONM02keTpLk1TfO BFJ+O4AP7yMcCgBmQXDnZUu0U2884j0OVFEBfDACrsp9GuQbWsMwYVXhQ0sV8Z1yPDapUYoZbyI WsReG1k/pYu9i4gXbyk4C5EdTk/xFpxv5YokwolHqjjgbaFgFeVIbvC8D6V6UCHVdtrirJ+IHjY egB607LFTeAixWT77Pbq0DyXLrtSFRZMADmLEbtLPOFsJFpIUetTdIAPVDPpea4vEnmHIYiF1cA I4tRdb8nNInE8YaZvetlYnQKERwK0r716ZFF+sF+PsE7eWkOhq0HnSw+MkiZ7u5cP5uw6M85Ecm 9Oqz1dt4ydJWza36MZnFakpJ1dHvtoJ X-Received: by 2002:a05:600c:528c:b0:47e:e61d:b8d2 with SMTP id 5b1f17b1804b1-4803e7f18d4mr75543255e9.27.1769007716605; Wed, 21 Jan 2026 07:01:56 -0800 (PST) Received: from iku.example.org ([2a06:5906:61b:2d00:3190:c653:bb13:4ca]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48042b6a3e2sm24787585e9.1.2026.01.21.07.01.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Jan 2026 07:01:55 -0800 (PST) From: Prabhakar X-Google-Original-From: Prabhakar To: Thomas Gleixner , Philipp Zabel , Geert Uytterhoeven , Magnus Damm Cc: linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Prabhakar , Biju Das , Fabrizio Castro , Lad Prabhakar Subject: [PATCH 5/6] irqchip/renesas-rzv2h: Handle ICU error IRQ and add SWPE trigger Date: Wed, 21 Jan 2026 15:01:36 +0000 Message-ID: <20260121150137.3364865-6-prabhakar.mahadev-lad.rj@bp.renesas.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260121150137.3364865-1-prabhakar.mahadev-lad.rj@bp.renesas.com> References: <20260121150137.3364865-1-prabhakar.mahadev-lad.rj@bp.renesas.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Lad Prabhakar Handle the RZ/V2H ICU error interrupt to help diagnose latched bus, ECC RAM, and CA55/IP error conditions during bring-up and debugging. When debug support is enabled, register the error IRQ handler and provide a debugfs write interface to trigger pseudo error generation via ICU_SWPE for validation. Account for SoC differences in ECC RAM error register coverage so the handler only iterates over valid ECC status/clear banks, and route the RZ/V2N compatible to a probe path with the correct ECC range while keeping the existing RZ/V2H and RZ/G3E handling. Signed-off-by: Lad Prabhakar --- drivers/irqchip/irq-renesas-rzv2h.c | 141 +++++++++++++++++++++++++++- 1 file changed, 140 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-rene= sas-rzv2h.c index 7d3ce1d762f0..6dc297220f05 100644 --- a/drivers/irqchip/irq-renesas-rzv2h.c +++ b/drivers/irqchip/irq-renesas-rzv2h.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -47,7 +48,15 @@ #define ICU_TSCLR 0x24 #define ICU_TITSR(k) (0x28 + (k) * 4) #define ICU_TSSR(k) (0x30 + (k) * 4) +#define ICU_BEISR(k) (0x70 + (k) * 4) +#define ICU_BECLR(k) (0x80 + (k) * 4) +#define ICU_EREISR(k) (0x90 + (k) * 4) +#define ICU_ERCLR(k) (0xE0 + (k) * 4) #define ICU_SWINT 0x130 +#define ICU_ERINTA55CTL(k) (0x338 + (k) * 4) +#define ICU_ERINTA55CRL(k) (0x348 + (k) * 4) +#define ICU_ERINTA55MSK(k) (0x358 + (k) * 4) +#define ICU_SWPE 0x370 #define ICU_DMkSELy(k, y) (0x420 + (k) * 0x20 + (y) * 4) #define ICU_DMACKSELk(k) (0x500 + (k) * 4) =20 @@ -99,6 +108,9 @@ #define ICU_RZV2H_TSSEL_MAX_VAL 0x55 =20 #define ICU_SWINT_NUM 4 +#define ICU_SWPE_NUM 16 +#define ICU_NUM_BE 4 +#define ICU_NUM_A55ERR 4 =20 static bool enable_icu_debug; module_param_named(debug, enable_icu_debug, bool, 0644); @@ -123,12 +135,16 @@ struct rzv2h_irqc_reg_cache { * @t_offs: TINT offset * @max_tssel: TSSEL max value * @field_width: TSSR field width + * @ecc_start: Start index of ECC RAM interrupts + * @ecc_end: End index of ECC RAM interrupts */ struct rzv2h_hw_info { const u8 *tssel_lut; u16 t_offs; u8 max_tssel; u8 field_width; + u8 ecc_start; + u8 ecc_end; }; =20 /* DMAC */ @@ -565,6 +581,48 @@ static int rzv2h_icu_parse_interrupts(struct rzv2h_icu= _priv *priv, struct device return 0; } =20 +static irqreturn_t rzv2h_icu_error_irq(int irq, void *data) +{ + struct rzv2h_icu_priv *priv =3D data; + const struct rzv2h_hw_info *hw_info =3D priv->info; + void __iomem *base =3D priv->base; + unsigned int k; + u32 st; + + /* 1) Bus errors (BEISR0..3) */ + for (k =3D 0; k < ICU_NUM_BE; k++) { + st =3D readl(base + ICU_BEISR(k)); + if (!st) + continue; + + writel(st, base + ICU_BECLR(k)); + pr_debug("rzv2h-icu: BUS error k=3D%u status=3D0x%08x\n", k, st); + } + + /* 2) ECC RAM errors (EREISR0..X) */ + for (k =3D hw_info->ecc_start; k <=3D hw_info->ecc_end; k++) { + st =3D readl(base + ICU_EREISR(k)); + if (!st) + continue; + + writel(st, base + ICU_ERCLR(k)); + pr_debug("rzv2h-icu: ECC error k=3D%u status=3D0x%08x\n", k, st); + } + + /* 3) IP/CA55 error interrupt status (ERINTA55CTL0..3) */ + for (k =3D 0; k < ICU_NUM_A55ERR; k++) { + st =3D readl(base + ICU_ERINTA55CTL(k)); + if (!st) + continue; + + /* there is no relation with status bits so clear all the interrupts */ + writel(0xffffffff, base + ICU_ERINTA55CRL(k)); + pr_debug("rzv2h-icu: IP/CA55 error k=3D%u status=3D0x%08x\n", k, st); + } + + return IRQ_HANDLED; +} + static irqreturn_t rzv2h_icu_swint_irq(int irq, void *data) { u8 cpu =3D *(u8 *)data; @@ -611,13 +669,47 @@ static const struct file_operations rzv2h_icu_swint_f= ops =3D { .llseek =3D noop_llseek, }; =20 +static ssize_t rzv2h_icu_swpe_write(struct file *file, + const char __user *ubuf, + size_t len, loff_t *ppos) +{ + struct rzv2h_icu_priv *priv =3D file->private_data; + unsigned long swpe; + char buf[32]; + int ret; + + len =3D min(len, sizeof(buf) - 1); + if (copy_from_user(buf, ubuf, len)) + return -EFAULT; + buf[len] =3D '\0'; + + ret =3D kstrtoul(strim(buf), 0, &swpe); + if (ret) + return ret; + + if (swpe >=3D ICU_SWPE_NUM) + return -EINVAL; + + writel(BIT(swpe), priv->base + ICU_SWPE); + return len; +} + +static const struct file_operations rzv2h_icu_swpe_fops =3D { + .open =3D simple_open, + .write =3D rzv2h_icu_swpe_write, + .llseek =3D noop_llseek, +}; + static int rzv2h_icu_setup_debug_irqs(struct platform_device *pdev) { + const struct rzv2h_hw_info *hw_info =3D rzv2h_icu_data->info; static const u8 swint_idx[ICU_SWINT_NUM] =3D { 0, 1, 2, 3 }; static const char * const rzv2h_swint_names[] =3D { "int-ca55-0", "int-ca55-1", "int-ca55-2", "int-ca55-3", }; + static const char *icu_err =3D "icu-error-ca55"; + void __iomem *base =3D rzv2h_icu_data->base; struct device *dev =3D &pdev->dev; struct dentry *dentry; struct dentry *dir; @@ -654,6 +746,36 @@ static int rzv2h_icu_setup_debug_irqs(struct platform_= device *pdev) if (IS_ERR(dentry)) return PTR_ERR(dentry); =20 + ret =3D devm_add_action_or_reset(dev, rzv2h_icu_remove_debugfs, dentry); + if (ret) + return ret; + + icu_irq =3D platform_get_irq_byname(pdev, icu_err); + if (icu_irq < 0) + return dev_err_probe(dev, icu_irq, "Failed to get %s IRQ\n", icu_err); + + /* Unmask and clear all IP/CA55 error interrupts */ + for (i =3D 0; i < ICU_NUM_A55ERR; i++) { + writel(0xffffff, base + ICU_ERINTA55CRL(i)); + writel(0x0, base + ICU_ERINTA55MSK(i)); + } + + /* Clear all Bus errors */ + for (i =3D 0; i < ICU_NUM_BE; i++) + writel(0xffffffff, base + ICU_BECLR(i)); + + /* Clear all ECCRAM errors */ + for (i =3D hw_info->ecc_start; i <=3D hw_info->ecc_end; i++) + writel(0xffffffff, base + ICU_ERCLR(i)); + + ret =3D devm_request_irq(dev, icu_irq, rzv2h_icu_error_irq, 0, dev_name(d= ev), rzv2h_icu_data); + if (ret) + return dev_err_probe(dev, ret, "Failed to request %s IRQ\n", icu_err); + + dentry =3D debugfs_create_file("swpe", 0200, dir, rzv2h_icu_data, &rzv2h_= icu_swpe_fops); + if (IS_ERR(dentry)) + return PTR_ERR(dentry); + return devm_add_action_or_reset(dev, rzv2h_icu_remove_debugfs, dentry); } =20 @@ -759,12 +881,24 @@ static const struct rzv2h_hw_info rzg3e_hw_params =3D= { .t_offs =3D ICU_RZG3E_TINT_OFFSET, .max_tssel =3D ICU_RZG3E_TSSEL_MAX_VAL, .field_width =3D 16, + .ecc_start =3D 1, + .ecc_end =3D 4, +}; + +static const struct rzv2h_hw_info rzv2n_hw_params =3D { + .t_offs =3D 0, + .max_tssel =3D ICU_RZV2H_TSSEL_MAX_VAL, + .field_width =3D 8, + .ecc_start =3D 0, + .ecc_end =3D 2, }; =20 static const struct rzv2h_hw_info rzv2h_hw_params =3D { .t_offs =3D 0, .max_tssel =3D ICU_RZV2H_TSSEL_MAX_VAL, .field_width =3D 8, + .ecc_start =3D 0, + .ecc_end =3D 11, }; =20 static int rzg3e_icu_probe(struct platform_device *pdev, struct device_nod= e *parent) @@ -772,6 +906,11 @@ static int rzg3e_icu_probe(struct platform_device *pde= v, struct device_node *par return rzv2h_icu_probe_common(pdev, parent, &rzg3e_hw_params); } =20 +static int rzv2n_icu_probe(struct platform_device *pdev, struct device_nod= e *parent) +{ + return rzv2h_icu_probe_common(pdev, parent, &rzv2n_hw_params); +} + static int rzv2h_icu_probe(struct platform_device *pdev, struct device_nod= e *parent) { return rzv2h_icu_probe_common(pdev, parent, &rzv2h_hw_params); @@ -779,7 +918,7 @@ static int rzv2h_icu_probe(struct platform_device *pdev= , struct device_node *par =20 IRQCHIP_PLATFORM_DRIVER_BEGIN(rzv2h_icu) IRQCHIP_MATCH("renesas,r9a09g047-icu", rzg3e_icu_probe) -IRQCHIP_MATCH("renesas,r9a09g056-icu", rzv2h_icu_probe) +IRQCHIP_MATCH("renesas,r9a09g056-icu", rzv2n_icu_probe) IRQCHIP_MATCH("renesas,r9a09g057-icu", rzv2h_icu_probe) IRQCHIP_PLATFORM_DRIVER_END(rzv2h_icu) MODULE_AUTHOR("Fabrizio Castro "); --=20 2.52.0