From nobody Thu Sep 24 23:32:47 2026 Received: from mail.cjdns.fr (mail.cjdns.fr [5.135.140.105]) (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 BDBF15038F0; Fri, 18 Sep 2026 15:36:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.135.140.105 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789745782; cv=none; b=IHkKQeJxlBPJGya/HKIFQnS1yJU209sJSzn3mB0+8hqI08tgQy+RY3gQ+XcCBNINZc2APRah0Ao1gG3fptYOWs20Pn/AR/tBF5ubfNEz4q/ov5d94wJ8rKOCdcxWGfBbMbyYoRTxjyL1y0ggvznTuPKZhZWzqkbtQQQtEbzQaXw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789745782; c=relaxed/simple; bh=9cxKqRSzDI1k9DZMBIppT7I1D0ocQhPQ6p2OsQkLhW4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=frBr9EUp5NBT0qeYeTk/oTG2jkQOIECO5ewy/7guJwEPw96DB5xh4L6KP8I1m3MM3p3bWoWBFL2hi7pxEXQLQa7kjt43/zAsIsbs3jcfUMd54xHZmh21D/UZoZFjMtfvelM7gH802TYOszlkFYaFyCeqJ2ZfL19aEnbRKPCdJNw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cjdns.fr; spf=pass smtp.mailfrom=cjdns.fr; dkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr header.b=M9Vv1oBk; arc=none smtp.client-ip=5.135.140.105 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cjdns.fr Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=cjdns.fr Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr header.b="M9Vv1oBk" Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 36A674DE073; Fri, 18 Sep 2026 17:36:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cjdns.fr; s=dkim; t=1789745778; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=Q6cAAX9tCyXcIpCsb2E2vZSxmNLsA1iEdhH9bQm/us8=; b=M9Vv1oBkeXW97PMRh4KKgbEAEuM/2AvVrgE1NS+mpyVpA01HZSDWH7Ddek62pTlW1vVx4+ ljKacrKXvTxmdaGe+A3Ug5r7q4wvY9hffz/gddMzDczHRXbilYRi9aGq34YjiHYfa1iG5g ijKEbV+VxX1ATf1gdyeZDDFo4al2IFRqEEoC2AmLV2vYTePR82RrFadCUl5u44OetBlgHh u/ny1zeraHU14DDnxokhSMsVoEAcLXkLbqcnmkWmNxao+KO8n/6SFjYy9/LUSPmf+2VNYf l/Vy1nI56hYoYFtsMAN8oFWSmfRdU1ks8Yrp6Bad6tQCcw0Q5bKiWiBKjr+w5w== From: Caleb James DeLisle To: linux-mips@vger.kernel.org Cc: conor+dt@kernel.org, daniel.lezcano@kernel.org, devicetree@vger.kernel.org, krzk+dt@kernel.org, linux-kernel@vger.kernel.org, naseefkm@gmail.com, robh@kernel.org, tglx@kernel.org, grandmaster@al2klimov.de, Caleb James DeLisle Subject: [PATCH v9 1/5] clocksource/timer-econet-en751221: fix refcount leak Date: Fri, 18 Sep 2026 15:36:02 +0000 Message-Id: <20260918153606.344143-2-cjd@cjdns.fr> In-Reply-To: <20260918153606.344143-1-cjd@cjdns.fr> References: <20260918153606.344143-1-cjd@cjdns.fr> 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 X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" From: "Alexander A. Klimov" Every value returned from of_clk_get() is supposed to be cleaned up via clk_put() once not needed anymore. Fixes: 3b4c33ac87d0 ("clocksource/drivers: Add EcoNet Timer HPT driver") Signed-off-by: Alexander A. Klimov Signed-off-by: Caleb James DeLisle --- drivers/clocksource/timer-econet-en751221.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clocksource/timer-econet-en751221.c b/drivers/clocksou= rce/timer-econet-en751221.c index 4008076b1a21..1859335345b5 100644 --- a/drivers/clocksource/timer-econet-en751221.c +++ b/drivers/clocksource/timer-econet-en751221.c @@ -181,6 +181,7 @@ static int __init timer_init(struct device_node *np) } =20 econet_timer.freq_hz =3D clk_get_rate(clk); + clk_put(clk); =20 for (int i =3D 0; i < num_blocks; i++) { econet_timer.membase[i] =3D of_iomap(np, i); --=20 2.39.5 From nobody Thu Sep 24 23:32:47 2026 Received: from mail.cjdns.fr (mail.cjdns.fr [5.135.140.105]) (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 49A5B5038F0; Fri, 18 Sep 2026 15:36:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.135.140.105 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789745788; cv=none; b=uZA/8COCI83Pw/QZ4/L95L29Ew6W9LhPlEUQx9K118bVtqoDUrFcZf1hwvBjvXqN/EmBRrdvZqw2y3uNZCtETILJOz1g1ePPkRig8Mf2pSB+CeSqw1fwDZ+rbOqkbpvf0n80ZuuL9qSx1LM8sJroMjKak9tYv7uPWLJ5xgb3XRU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789745788; c=relaxed/simple; bh=Ze4Nv8y680E6FSf/un9hYJUthpJ2COzdxd+LB34Yb2I=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=MaLmmPrT18F94Aj8RjyiaNrxD/VV5oBlq6U2wXrAoV1VP5IzOHxjcQG6R5MvTYQOzf87KknDKg+KjSlkY4eWNrJNCkuA7DmvMJW8lMkhiRTPx6ZQSqpAPNRpwovxTJxdZHniM1nIRoCNfp3Yj3CsN3VrhMjxaShrUvhNExzPMcA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cjdns.fr; spf=none smtp.mailfrom=cjdns.fr; dkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr header.b=pGEklKOJ; arc=none smtp.client-ip=5.135.140.105 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cjdns.fr Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=cjdns.fr Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr header.b="pGEklKOJ" Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 9D5BE4E0F01; Fri, 18 Sep 2026 17:36:18 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cjdns.fr; s=dkim; t=1789745781; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=X5WYmjC+W1XLRGqsI2xwQZ9HsjRo/iUHSgzYnXKRgcw=; b=pGEklKOJjFFjCenfw4uJOEJagK7bdT2PTqiIO3JDlqfiEQ5jlrnx8HkwvXKNl4Tp2KgqkS bkJdcX4SiUe9Kr1re63kvMuErutLQWejTyXoD8ZodwIdNbbQ7C0xI63K2tMtUnvlhaTqyA 3QzF403qez2b7rZl1sLa+yED+oZPZ2o9CF/pMsmr9RYCu4Rph6+B6Dr5gizwp0wtslh7r7 OuqdybsM/ox0ZdrJXOjULkCBfDY1Nmg0HI2FfL0+uuJ/1SeXU6PF3zDJLS57bR17ZWVLFW 9Rf1Nk70Y8CauIN7kJimfP2icYeJnR0XgK7TbSxNInQPY9E6ype5jnIEDxUeZQ== From: Caleb James DeLisle To: linux-mips@vger.kernel.org Cc: conor+dt@kernel.org, daniel.lezcano@kernel.org, devicetree@vger.kernel.org, krzk+dt@kernel.org, linux-kernel@vger.kernel.org, naseefkm@gmail.com, robh@kernel.org, tglx@kernel.org, grandmaster@al2klimov.de, Caleb James DeLisle , Conor Dooley Subject: [PATCH v9 2/5] dt-bindings: timer: econet: Update EN751627 for multi-IRQ Date: Fri, 18 Sep 2026 15:36:03 +0000 Message-Id: <20260918153606.344143-3-cjd@cjdns.fr> In-Reply-To: <20260918153606.344143-1-cjd@cjdns.fr> References: <20260918153606.344143-1-cjd@cjdns.fr> 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 X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" This hardware is found in the EN751221 SoC family as well as the EN751627. The former uses a percpu IRQ for all timers while the latter uses an individual IRQ number per timer. Signed-off-by: Caleb James DeLisle Acked-by: Conor Dooley --- .../bindings/timer/econet,en751221-timer.yaml | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/Documentation/devicetree/bindings/timer/econet,en751221-timer.= yaml b/Documentation/devicetree/bindings/timer/econet,en751221-timer.yaml index c1e7c2b6afde..ac25785ecfdf 100644 --- a/Documentation/devicetree/bindings/timer/econet,en751221-timer.yaml +++ b/Documentation/devicetree/bindings/timer/econet,en751221-timer.yaml @@ -12,24 +12,23 @@ maintainers: description: The EcoNet High Precision Timer (HPT) is a timer peripheral found in var= ious EcoNet SoCs, including the EN751221 and EN751627 families. It provides p= er-VPE - count/compare registers and a per-CPU control register, with a single in= terrupt - line using a percpu-devid interrupt mechanism. + count/compare registers and a per-CPU control register. On EN751221 it u= ses a + single interrupt line using a percpu-devid interrupt mechanism, and on + EN751627 it uses an interrupt per VPE. =20 properties: compatible: - oneOf: - - const: econet,en751221-timer - - items: - - const: econet,en751627-timer - - const: econet,en751221-timer + enum: + - econet,en751221-timer + - econet,en751627-timer =20 reg: minItems: 1 maxItems: 2 =20 interrupts: - maxItems: 1 - description: A percpu-devid timer interrupt shared across CPUs. + minItems: 1 + maxItems: 4 =20 clocks: maxItems: 1 @@ -52,21 +51,31 @@ allOf: items: - description: VPE timers 0 and 1 - description: VPE timers 2 and 3 + interrupts: + description: An interrupt for each timer (one per VPE) + minItems: 4 else: properties: reg: items: - description: VPE timers 0 and 1 + interrupts: + description: A percpu-devid timer interrupt shared across timers + maxItems: 1 =20 additionalProperties: false =20 examples: - | + #include timer@1fbf0400 { - compatible =3D "econet,en751627-timer", "econet,en751221-timer"; + compatible =3D "econet,en751627-timer"; reg =3D <0x1fbf0400 0x100>, <0x1fbe0000 0x100>; interrupt-parent =3D <&intc>; - interrupts =3D <30>; + interrupts =3D , + , + , + ; clocks =3D <&hpt_clock>; }; - | --=20 2.39.5 From nobody Thu Sep 24 23:32:47 2026 Received: from mail.cjdns.fr (mail.cjdns.fr [5.135.140.105]) (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 9916E509EE7; Fri, 18 Sep 2026 15:36:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.135.140.105 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789745789; cv=none; b=o5zW91KkzqHRxyBSEBRkjhKLP+/awc8ZLzQRF+4Sjt6EdfPVvtWhb34snKao85nxSmNzRMBDNM3imfO8EUFYttJ6EcYTw8p4Ua9E6Fi1c3JKbbkAaPunFSgwskM71h8Jzj4jK3xAtU8PMKYhV8CnMbDo+XJQKfaIEgPfKHblIuM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789745789; c=relaxed/simple; bh=xkU7FTh2Qx1l444kXVxCZ72X6BDvMmnbijkDMtD0tYY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=EphCXa2YoW3a1R8j0gpCjGNtFN16srkCtKo/HS3RD1xLyJvFXGpjwlW9j3vJ8zBI5S3P/CVYZ9E3Pid1KzfWY9Ofa+aUp3aJEh+PWbbaBs7o8crmj1BpgZBumG1JLXB3s98LT2sTCP7E58UHFNQ4CzO4VZ9sQbxaRUKbnoLUGg0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cjdns.fr; spf=pass smtp.mailfrom=cjdns.fr; dkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr header.b=GRSz8Ncz; arc=none smtp.client-ip=5.135.140.105 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cjdns.fr Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=cjdns.fr Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr header.b="GRSz8Ncz" Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 501784E0F8F; Fri, 18 Sep 2026 17:36:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cjdns.fr; s=dkim; t=1789745784; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=B1OV7lBJrmDaac8ePy8dHk2DEYoP6HJXQm0PFK+z8S0=; b=GRSz8Nczj8PSth2MjRMyLrh/0ZwPpRcGdNOvftdlLycQY5tzXAnUVy9fK+VZK7RMpib6KR FBdaGqaMW8t9mGNDLyGA6trpRW6SOuGHaxXNfnIWFwhxHOWi/dVgYFmK72+Ec1xVdhJMuw ab/+SX7Cka1iBecJqVjWVSBRJcsDkKqUB1J0ZVgjY9k+JsjeZmCbUSaQIBfxpaAPwmIaNl RSnUbhv/2CfRCGdr6KUH/Rqj3BnBfr7WhLHkDKnRkNUhZgNlJ6956zDm4PZADQBxR/8xVw CY0CmQDjD8h7Zx+4jAcUb4jK0hvvMCWrn+r7cukO3mZ60ifpjr7Qt6dMB1fCfg== From: Caleb James DeLisle To: linux-mips@vger.kernel.org Cc: conor+dt@kernel.org, daniel.lezcano@kernel.org, devicetree@vger.kernel.org, krzk+dt@kernel.org, linux-kernel@vger.kernel.org, naseefkm@gmail.com, robh@kernel.org, tglx@kernel.org, grandmaster@al2klimov.de, Caleb James DeLisle Subject: [PATCH v9 3/5] clocksource/timer-econet-en751221: Init teardown on error if possible Date: Fri, 18 Sep 2026 15:36:04 +0000 Message-Id: <20260918153606.344143-4-cjd@cjdns.fr> In-Reply-To: <20260918153606.344143-1-cjd@cjdns.fr> References: <20260918153606.344143-1-cjd@cjdns.fr> 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 X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" As a clocksource, much of the initialization process is irreversible and the impact of a failure to initialize is a failure to boot. That said, good practice is to attempt a clean exit if probing fails, and supporting this pattern will reduce the likelihood that future contributions introduce a bug by trying to teardown after it is no longer possible to do so. Convert the init process into two clearly delineated phases, one which is reverted in case of error, and the other which can't be. Move all IRQ and address resource mapping before that point, and add teardown logic in case of error before the point of no return. Signed-off-by: Caleb James DeLisle --- drivers/clocksource/timer-econet-en751221.c | 84 ++++++++++++--------- 1 file changed, 50 insertions(+), 34 deletions(-) diff --git a/drivers/clocksource/timer-econet-en751221.c b/drivers/clocksou= rce/timer-econet-en751221.c index 1859335345b5..714702b9ef12 100644 --- a/drivers/clocksource/timer-econet-en751221.c +++ b/drivers/clocksource/timer-econet-en751221.c @@ -24,6 +24,7 @@ =20 static struct { void __iomem *membase[ECONET_NUM_BLOCKS]; + int irq; u32 freq_hz; } econet_timer __ro_after_init; =20 @@ -126,22 +127,9 @@ static void __init cevt_dev_init(uint cpu) iowrite32(U32_MAX, reg_compare(cpu)); } =20 -static int __init cevt_init(struct device_node *np) +static void __init cevt_init(struct device_node *np) { - int i, irq, ret; - - irq =3D irq_of_parse_and_map(np, 0); - if (irq <=3D 0) { - pr_err("%pOFn: irq_of_parse_and_map failed", np); - return -EINVAL; - } - - ret =3D request_percpu_irq(irq, cevt_interrupt, np->name, &econet_timer_p= cpu); - - if (ret < 0) { - pr_err("%pOFn: IRQ %d setup failed (%d)\n", np, irq, ret); - goto err_unmap_irq; - } + int i; =20 for_each_possible_cpu(i) { struct clock_event_device *cd =3D &per_cpu(econet_timer_pcpu, i); @@ -151,21 +139,12 @@ static int __init cevt_init(struct device_node *np) CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_PERCPU; cd->set_next_event =3D cevt_set_next_event; - cd->irq =3D irq; + cd->irq =3D econet_timer.irq; cd->cpumask =3D cpumask_of(i); cd->name =3D np->name; =20 cevt_dev_init(i); } - - cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, - "clockevents/econet/timer:starting", - cevt_init_cpu, NULL); - return 0; - -err_unmap_irq: - irq_dispose_mapping(irq); - return ret; } =20 static int __init timer_init(struct device_node *np) @@ -187,22 +166,45 @@ static int __init timer_init(struct device_node *np) econet_timer.membase[i] =3D of_iomap(np, i); if (!econet_timer.membase[i]) { pr_err("%pOFn: failed to map register [%d]\n", np, i); - return -ENXIO; + ret =3D -ENXIO; + goto out_membase; } } =20 + econet_timer.irq =3D irq_of_parse_and_map(np, 0); + if (econet_timer.irq <=3D 0) { + pr_err("%pOFn: irq_of_parse_and_map failed\n", np); + ret =3D -EINVAL; + goto out_membase; + } + + ret =3D request_percpu_irq(econet_timer.irq, cevt_interrupt, np->name, + &econet_timer_pcpu); + + if (ret < 0) { + pr_err("%pOFn: IRQ %d setup failed (%d)\n", np, + econet_timer.irq, ret); + goto out_irq_mapping; + } + + cevt_init(np); + + ret =3D cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, + "clockevents/econet/timer:starting", + cevt_init_cpu, NULL); + if (ret < 0) { + pr_err("%pOFn: cpuhp setup failed (%d)\n", np, ret); + goto out_irq_free; + } + + /* Point of no return, do not attempt to tear down after this. */ + /* For clocksource purposes always read clock zero, whatever the CPU */ ret =3D clocksource_mmio_init(reg_count(0), np->name, econet_timer.freq_hz, 301, ECONET_BITS, clocksource_mmio_readl_up); - if (ret) { - pr_err("%pOFn: clocksource_mmio_init failed: %d", np, ret); - return ret; - } - - ret =3D cevt_init(np); - if (ret < 0) - return ret; + if (ret) + pr_err("%pOFn: clocksource_mmio_init failed: %d\n", np, ret); =20 sched_clock_register(sched_clock_read, ECONET_BITS, econet_timer.freq_hz); @@ -212,6 +214,20 @@ static int __init timer_init(struct device_node *np) (econet_timer.freq_hz / 1000) % 1000); =20 return 0; + +out_irq_free: + free_percpu_irq(econet_timer.irq, &econet_timer_pcpu); +out_irq_mapping: + irq_dispose_mapping(econet_timer.irq); +out_membase: + for (int i =3D 0; i < ARRAY_SIZE(econet_timer.membase); i++) { + if (econet_timer.membase[i]) { + iounmap(econet_timer.membase[i]); + econet_timer.membase[i] =3D NULL; + } + } + + return ret; } =20 TIMER_OF_DECLARE(econet_timer_hpt, "econet,en751221-timer", timer_init); --=20 2.39.5 From nobody Thu Sep 24 23:32:47 2026 Received: from mail.cjdns.fr (mail.cjdns.fr [5.135.140.105]) (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 213F850B403; Fri, 18 Sep 2026 15:36:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.135.140.105 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789745791; cv=none; b=piZUGp+Hmwp3tr42ReJUfFfEaQGvysWJR8JsF5aF4JDECJr/lQyKL4t6lJDaJYPPSlTD6jnrdZ18u5IpP4wy2Q6lLQ2+0kcN15UZyw1TAWDoAq6ZJJJX9xAicDq0nuu81XzeEbP2r/KhXJmJyBNatpPyX0cFJHIQPnmtvnOwT04= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789745791; c=relaxed/simple; bh=x0XMny1qGGl4AJoowktjLCWIaQ/7L5RzSu5rS1V5VRE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=QTj1+bhJVp0vQaFbHQpYC9AWW67MiFZbNaE9ySIm1kG9NrQaNSg8zThtt43DCRM22SEXjCIAGHID7W4+ZOIH2eZcGh095EU74w2+aax4mdw2l98Nv7lWNs0wWBK5Be7hbENU7xXJ6DqjiQwqqvrKNjpdinS/bkI1b0veyA02GLE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cjdns.fr; spf=none smtp.mailfrom=cjdns.fr; dkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr header.b=vw7SD2oJ; arc=none smtp.client-ip=5.135.140.105 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cjdns.fr Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=cjdns.fr Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr header.b="vw7SD2oJ" Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 409574E0025; Fri, 18 Sep 2026 17:36:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cjdns.fr; s=dkim; t=1789745787; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=lRhqM7LAgl/X+6g5+JRRCWTiassQyFmX1v5QtTJrszQ=; b=vw7SD2oJG1EOTBIe4kPOT7F3IJvmTXNbwU7ID0V4Z4BwLupmlW/F800kAy409GWzTqbz39 axcB1MES6KkVcgYL/aHzFQ4UH6fXFM2BIBuHtbFdC9LEez9Zc0E4wC4hgFkkINUSy8wike kBwxq1WU1fvTKH7X++zXgjMKNztL8+8mTeF+Q9Id16VSXNYStbL3U3lokeTqukeCdm3qre Qd6+dcPGXYk7D9rKuE/Xsnd2SSOh90Ohf8MO0KAUdUS6tsSDtxSBnIes+3GsC+8mB7WwIl h7y7UG9tFEdqqbekPJkXzqJuAMRDZsN7yECJqXpC5hG0upqT4X+RPlDHVob2Zg== From: Caleb James DeLisle To: linux-mips@vger.kernel.org Cc: conor+dt@kernel.org, daniel.lezcano@kernel.org, devicetree@vger.kernel.org, krzk+dt@kernel.org, linux-kernel@vger.kernel.org, naseefkm@gmail.com, robh@kernel.org, tglx@kernel.org, grandmaster@al2klimov.de, Caleb James DeLisle Subject: [PATCH v9 4/5] clocksource/timer-econet-en751221: Disable IRQ until cevt registered Date: Fri, 18 Sep 2026 15:36:05 +0000 Message-Id: <20260918153606.344143-5-cjd@cjdns.fr> In-Reply-To: <20260918153606.344143-1-cjd@cjdns.fr> References: <20260918153606.344143-1-cjd@cjdns.fr> 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 X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" Eliminate a race condition where cevt_interrupt may trigger before clockevents_config_and_register has been called, and dev->event_handler is at that point NULL. Additionally, NULL check dev->event_handler in interrupt callback just in case clockevents_config_and_register failed. Signed-off-by: Caleb James DeLisle --- drivers/clocksource/timer-econet-en751221.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/clocksource/timer-econet-en751221.c b/drivers/clocksou= rce/timer-econet-en751221.c index 714702b9ef12..f2c4c1ee0a56 100644 --- a/drivers/clocksource/timer-econet-en751221.c +++ b/drivers/clocksource/timer-econet-en751221.c @@ -75,7 +75,10 @@ static irqreturn_t cevt_interrupt(int irq, void *dev_id) return IRQ_NONE; =20 iowrite32(ioread32(reg_count(cpu)), reg_compare(cpu)); - dev->event_handler(dev); + + if (dev->event_handler) + dev->event_handler(dev); + return IRQ_HANDLED; } =20 @@ -104,12 +107,11 @@ static int cevt_init_cpu(uint cpu) reg =3D ioread32(reg_ctl(cpu)) | ctl_bit_enabled(cpu); iowrite32(reg, reg_ctl(cpu)); =20 - enable_percpu_irq(cd->irq, IRQ_TYPE_NONE); - - /* Do this last because it synchronously configures the timer */ clockevents_config_and_register(cd, econet_timer.freq_hz, ECONET_MIN_DELTA, ECONET_MAX_DELTA); =20 + enable_percpu_irq(cd->irq, IRQ_TYPE_NONE); + return 0; } =20 @@ -178,6 +180,8 @@ static int __init timer_init(struct device_node *np) goto out_membase; } =20 + irq_set_status_flags(econet_timer.irq, IRQ_NOAUTOEN); + ret =3D request_percpu_irq(econet_timer.irq, cevt_interrupt, np->name, &econet_timer_pcpu); =20 --=20 2.39.5 From nobody Thu Sep 24 23:32:47 2026 Received: from mail.cjdns.fr (mail.cjdns.fr [5.135.140.105]) (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 E0FDA50B41D; Fri, 18 Sep 2026 15:36:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=5.135.140.105 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789745793; cv=none; b=qZ5s4QPqZt3XK2PfvZKsupJGDDxJ46DUAwuXjHQvKct5Lxas9ELsDt/Yv4DBX8hqm1Dj0W7ufxNut8czBp2QdNJq8lBEcfhy9XIolR3VLMuW1sYEJBOk/LVS+RtLACiFjotnJrWIxj7Doq9fQKo3pxqLtWD54/kAVMN4AyygwNg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789745793; c=relaxed/simple; bh=taGDNe4YWDW+c3AHiAuplVTuWLbeZ7es1eM7b/Y6LN4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ZdPjSY5/i4sVfKSBLt88XV1Dno2znQWeuMkT3M25aIG202FoNFu7/FLiMQX0FgKBer+s+uY5uS47YZm32jQtcDHjd9Fk+JnXf+Kv08pLaJlBKgvvtwfYv3VuGYqEoEm0APm9ugHm4hGntBuTwtrihxWDNGA5kwMfOEbBO49CHkk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cjdns.fr; spf=none smtp.mailfrom=cjdns.fr; dkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr header.b=sxZaItgz; arc=none smtp.client-ip=5.135.140.105 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=cjdns.fr Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=cjdns.fr Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cjdns.fr header.i=@cjdns.fr header.b="sxZaItgz" Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 3ABE64E1002; Fri, 18 Sep 2026 17:36:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cjdns.fr; s=dkim; t=1789745789; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=uZfN8xD8XsMIRA/4gH4WfsuC1DI/C5678otyU+/S8xg=; b=sxZaItgzoJgLL25Sq3KdXNdM64rJeJOwqWmHtF3oTHevc7usVi+quUed1+fBGmybmX3m/p Hx+u6u4deE/9G2DXbfD0EVD2dq6tWcH6KZ+fOap5vRxWzkZnEIMfMEauSWoZ/yBkcRCMN5 mYR/uNaqC+OJCSPkG0Rt7DlxHbWsRK9RbINdgqf2KAu7j7s1imY1GMcD0DslulRrG9SzR1 vTf0Po3VyFThNf7MynT1aluElfML1rfNcCCd/gUv8ORURxXyFR+qhFV2kxbSNDw1U/v7PB vj0iWMkSw5Vd4+ctrWmH+d4rbn59kLbeid78pfeVifCK9lp75ngvUVhG2ZUGtg== From: Caleb James DeLisle To: linux-mips@vger.kernel.org Cc: conor+dt@kernel.org, daniel.lezcano@kernel.org, devicetree@vger.kernel.org, krzk+dt@kernel.org, linux-kernel@vger.kernel.org, naseefkm@gmail.com, robh@kernel.org, tglx@kernel.org, grandmaster@al2klimov.de, Caleb James DeLisle Subject: [PATCH v9 5/5] clocksource/timer-econet-en751221: Support EN751627 without percpu IRQ Date: Fri, 18 Sep 2026 15:36:06 +0000 Message-Id: <20260918153606.344143-6-cjd@cjdns.fr> In-Reply-To: <20260918153606.344143-1-cjd@cjdns.fr> References: <20260918153606.344143-1-cjd@cjdns.fr> 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 X-Last-TLS-Session-Version: TLSv1.3 Content-Type: text/plain; charset="utf-8" EN751627 is based on the 1004Kc which uses a different interrupt number for each CPU timer. Support both this and the EN751221 which uses a single percpu interrupt. Signed-off-by: Caleb James DeLisle --- drivers/clocksource/timer-econet-en751221.c | 122 ++++++++++++++++---- 1 file changed, 99 insertions(+), 23 deletions(-) diff --git a/drivers/clocksource/timer-econet-en751221.c b/drivers/clocksou= rce/timer-econet-en751221.c index f2c4c1ee0a56..ff86a7edd31d 100644 --- a/drivers/clocksource/timer-econet-en751221.c +++ b/drivers/clocksource/timer-econet-en751221.c @@ -21,10 +21,12 @@ #define ECONET_MAX_DELTA GENMASK(ECONET_BITS - 2, 0) /* 34Kc hardware has 1 block and 1004Kc has 2. */ #define ECONET_NUM_BLOCKS DIV_ROUND_UP(NR_CPUS, 2) +#define ECONET_NUM_IRQS NR_CPUS =20 static struct { void __iomem *membase[ECONET_NUM_BLOCKS]; - int irq; + int irqs[ECONET_NUM_IRQS]; + bool is_percpu; u32 freq_hz; } econet_timer __ro_after_init; =20 @@ -102,6 +104,25 @@ static int cevt_init_cpu(uint cpu) struct clock_event_device *cd =3D &per_cpu(econet_timer_pcpu, cpu); u32 reg; =20 + if (!reg_ctl(cpu)) { + pr_err("%s: missing address resource for CPU %d\n", cd->name, + cpu); + return -EINVAL; + } + if (cd->irq <=3D 0) { + pr_err("%s: missing IRQ for CPU %d\n", cd->name, cpu); + return -EINVAL; + } + if (!econet_timer.is_percpu) { + int ret =3D irq_force_affinity(cd->irq, cpumask_of(cpu)); + + if (ret) { + pr_err("%s: failed to set IRQ affinity to CPU %d: %pe\n", + cd->name, cpu, ERR_PTR(ret)); + return ret; + } + } + pr_debug("%s: Setting up clockevent for CPU %d\n", cd->name, cpu); =20 reg =3D ioread32(reg_ctl(cpu)) | ctl_bit_enabled(cpu); @@ -110,7 +131,10 @@ static int cevt_init_cpu(uint cpu) clockevents_config_and_register(cd, econet_timer.freq_hz, ECONET_MIN_DELTA, ECONET_MAX_DELTA); =20 - enable_percpu_irq(cd->irq, IRQ_TYPE_NONE); + if (econet_timer.is_percpu) + enable_percpu_irq(cd->irq, IRQ_TYPE_NONE); + else + enable_irq(cd->irq); =20 return 0; } @@ -141,19 +165,52 @@ static void __init cevt_init(struct device_node *np) CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_PERCPU; cd->set_next_event =3D cevt_set_next_event; - cd->irq =3D econet_timer.irq; + + if (econet_timer.is_percpu) + cd->irq =3D econet_timer.irqs[0]; + else + cd->irq =3D econet_timer.irqs[i]; + cd->cpumask =3D cpumask_of(i); cd->name =3D np->name; =20 - cevt_dev_init(i); + /* + * Tolerate CPUs that could exist but don't. + * Fail in cevt_init_cpu when they try to start. + */ + if (reg_ctl(i)) + cevt_dev_init(i); } } =20 static int __init timer_init(struct device_node *np) { - int num_blocks =3D DIV_ROUND_UP(num_possible_cpus(), 2); + int num_blocks =3D of_address_count(np); + int num_irqs =3D of_irq_count(np); struct clk *clk; - int ret; + int ret, i; + + econet_timer.is_percpu =3D of_device_is_compatible(np, "econet,en751221-t= imer"); + + if (econet_timer.is_percpu && num_irqs !=3D 1) { + pr_err("%pOFn: EN751221 clock must have 1 IRQ not %d\n", np, + num_irqs); + return -EINVAL; + } + if (num_irqs > ARRAY_SIZE(econet_timer.irqs)) { + pr_err("%pOFn: Too many IRQs max %zd got %d\n", np, + ARRAY_SIZE(econet_timer.irqs), num_irqs); + return -EINVAL; + } + if (num_blocks > ARRAY_SIZE(econet_timer.membase)) { + pr_err("%pOFn: Too many regs: max %zd got %d\n", np, + ARRAY_SIZE(econet_timer.membase), num_blocks); + return -EINVAL; + } + if (num_blocks =3D=3D 0) { + pr_err("%pOFn: At least one reg block must be provided\n", np); + return -EINVAL; + } =20 clk =3D of_clk_get(np, 0); if (IS_ERR(clk)) { @@ -164,7 +221,7 @@ static int __init timer_init(struct device_node *np) econet_timer.freq_hz =3D clk_get_rate(clk); clk_put(clk); =20 - for (int i =3D 0; i < num_blocks; i++) { + for (i =3D 0; i < num_blocks; i++) { econet_timer.membase[i] =3D of_iomap(np, i); if (!econet_timer.membase[i]) { pr_err("%pOFn: failed to map register [%d]\n", np, i); @@ -173,22 +230,32 @@ static int __init timer_init(struct device_node *np) } } =20 - econet_timer.irq =3D irq_of_parse_and_map(np, 0); - if (econet_timer.irq <=3D 0) { - pr_err("%pOFn: irq_of_parse_and_map failed\n", np); - ret =3D -EINVAL; - goto out_membase; + for (i =3D 0; i < num_irqs; i++) { + econet_timer.irqs[i] =3D irq_of_parse_and_map(np, i); + if (econet_timer.irqs[i] <=3D 0) { + pr_err("%pOFn: failed mapping irq %d\n", np, i); + ret =3D -EINVAL; + goto out_irq_mapping; + } } =20 - irq_set_status_flags(econet_timer.irq, IRQ_NOAUTOEN); - - ret =3D request_percpu_irq(econet_timer.irq, cevt_interrupt, np->name, - &econet_timer_pcpu); - - if (ret < 0) { - pr_err("%pOFn: IRQ %d setup failed (%d)\n", np, - econet_timer.irq, ret); - goto out_irq_mapping; + for (i =3D 0; i < num_irqs; i++) { + irq_set_status_flags(econet_timer.irqs[i], IRQ_NOAUTOEN); + + if (econet_timer.is_percpu) + ret =3D request_percpu_irq(econet_timer.irqs[i], + cevt_interrupt, np->name, + &econet_timer_pcpu); + else + ret =3D request_irq(econet_timer.irqs[i], cevt_interrupt, + IRQF_TIMER | IRQF_NOBALANCING, + np->name, NULL); + + if (ret < 0) { + pr_err("%pOFn: IRQ %d setup failed: %pe\n", np, + i, ERR_PTR(ret)); + goto out_irq_free; + } } =20 cevt_init(np); @@ -220,9 +287,17 @@ static int __init timer_init(struct device_node *np) return 0; =20 out_irq_free: - free_percpu_irq(econet_timer.irq, &econet_timer_pcpu); + while (--i >=3D 0) { + if (econet_timer.is_percpu) + free_percpu_irq(econet_timer.irqs[i], &econet_timer_pcpu); + else + free_irq(econet_timer.irqs[i], NULL); + } out_irq_mapping: - irq_dispose_mapping(econet_timer.irq); + for (i =3D 0; i < num_irqs; i++) { + if (econet_timer.irqs[i] > 0) + irq_dispose_mapping(econet_timer.irqs[i]); + } out_membase: for (int i =3D 0; i < ARRAY_SIZE(econet_timer.membase); i++) { if (econet_timer.membase[i]) { @@ -235,3 +310,4 @@ static int __init timer_init(struct device_node *np) } =20 TIMER_OF_DECLARE(econet_timer_hpt, "econet,en751221-timer", timer_init); +TIMER_OF_DECLARE(econet_timer_en751627, "econet,en751627-timer", timer_ini= t); --=20 2.39.5