mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Daniel Lezcano <daniel.lezcano@linaro.org>
To: tglx@linutronix.de, daniel.lezcano@linaro.org
Cc: linux-kernel@vger.kernel.org,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Marc Zyngier <marc.zyngier@arm.com>,
	linux-arm-kernel@lists.infradead.org (moderated list:ARM
	ARCHITECTED TIMER DRIVER)
Subject: [PATCH 13/17] clocksource/drivers/arm_arch_timer: Validate CNTFRQ after enabling frame
Date: Sun, 29 Oct 2017 22:20:30 +0100	[thread overview]
Message-ID: <1509312035-17368-13-git-send-email-daniel.lezcano@linaro.org> (raw)
In-Reply-To: <1509312035-17368-1-git-send-email-daniel.lezcano@linaro.org>

From: Ard Biesheuvel <ard.biesheuvel@linaro.org>

The ACPI GTDT code validates the CNTFRQ field of each MMIO timer
frame against the CNTFRQ system register of the current CPU, to
ensure that they are equal, which is mandated by the architecture.

However, reading the CNTFRQ field of a frame is not possible until
the RFRQ bit in the frame's CNTACRn register is set, and doing so
before that willl produce the following error:

  arch_timer: [Firmware Bug]: CNTFRQ mismatch: frame @ 0x00000000e0be0000: (0x00000000), CPU: (0x0ee6b280)
  arch_timer: Disabling MMIO timers due to CNTFRQ mismatch
  arch_timer: Failed to initialize memory-mapped timer.

The reason is that the CNTFRQ field is RES0 if access is not enabled.

So move the validation of CNTFRQ into the loop that iterates over the
timers to find the best frame, but defer it until after we have selected
the best frame, which should also have enabled the RFRQ bit.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/arm_arch_timer.c | 38 ++++++++++++++++++++----------------
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index fd4b7f6..14e2419 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -1268,10 +1268,6 @@ arch_timer_mem_find_best_frame(struct arch_timer_mem *timer_mem)
 
 	iounmap(cntctlbase);
 
-	if (!best_frame)
-		pr_err("Unable to find a suitable frame in timer @ %pa\n",
-			&timer_mem->cntctlbase);
-
 	return best_frame;
 }
 
@@ -1372,6 +1368,8 @@ static int __init arch_timer_mem_of_init(struct device_node *np)
 
 	frame = arch_timer_mem_find_best_frame(timer_mem);
 	if (!frame) {
+		pr_err("Unable to find a suitable frame in timer @ %pa\n",
+			&timer_mem->cntctlbase);
 		ret = -EINVAL;
 		goto out;
 	}
@@ -1420,7 +1418,7 @@ arch_timer_mem_verify_cntfrq(struct arch_timer_mem *timer_mem)
 static int __init arch_timer_mem_acpi_init(int platform_timer_count)
 {
 	struct arch_timer_mem *timers, *timer;
-	struct arch_timer_mem_frame *frame;
+	struct arch_timer_mem_frame *frame, *best_frame = NULL;
 	int timer_count, i, ret = 0;
 
 	timers = kcalloc(platform_timer_count, sizeof(*timers),
@@ -1432,14 +1430,6 @@ static int __init arch_timer_mem_acpi_init(int platform_timer_count)
 	if (ret || !timer_count)
 		goto out;
 
-	for (i = 0; i < timer_count; i++) {
-		ret = arch_timer_mem_verify_cntfrq(&timers[i]);
-		if (ret) {
-			pr_err("Disabling MMIO timers due to CNTFRQ mismatch\n");
-			goto out;
-		}
-	}
-
 	/*
 	 * While unlikely, it's theoretically possible that none of the frames
 	 * in a timer expose the combination of feature we want.
@@ -1448,12 +1438,26 @@ static int __init arch_timer_mem_acpi_init(int platform_timer_count)
 		timer = &timers[i];
 
 		frame = arch_timer_mem_find_best_frame(timer);
-		if (frame)
-			break;
+		if (!best_frame)
+			best_frame = frame;
+
+		ret = arch_timer_mem_verify_cntfrq(timer);
+		if (ret) {
+			pr_err("Disabling MMIO timers due to CNTFRQ mismatch\n");
+			goto out;
+		}
+
+		if (!best_frame) /* implies !frame */
+			/*
+			 * Only complain about missing suitable frames if we
+			 * haven't already found one in a previous iteration.
+			 */
+			pr_err("Unable to find a suitable frame in timer @ %pa\n",
+				&timer->cntctlbase);
 	}
 
-	if (frame)
-		ret = arch_timer_mem_frame_register(frame);
+	if (best_frame)
+		ret = arch_timer_mem_frame_register(best_frame);
 out:
 	kfree(timers);
 	return ret;
-- 
2.7.4

  parent reply	other threads:[~2017-10-29 21:24 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-29 21:20 [GIT PULL] clockevents / clocksources for 4.15 Daniel Lezcano
2017-10-29 21:20 ` [PATCH 01/17] dt-bindings: timer: renesas, cmt: Fix SoC-specific compatible values Daniel Lezcano
2017-10-29 21:20   ` [PATCH 02/17] clocksource/drivers/sh_cmt: Use 0x3f mask for SH_CMT_48BIT case Daniel Lezcano
2017-10-29 21:20   ` [PATCH 03/17] clocksource/drivers/sh_cmt: Support separate R-Car Gen2 CMT0/1 Daniel Lezcano
2017-10-29 21:20   ` [PATCH 04/17] clocksource/drivers/sh_cmt: Remove support for "renesas,cmt-32*" Daniel Lezcano
2017-10-29 21:20   ` [PATCH 05/17] clocksource/drivers/sh_cmt: Mark "renesas,cmt-48-gen2" deprecated Daniel Lezcano
2017-10-29 21:20   ` [PATCH 06/17] clocksource/drivers/sh_cmt: Remove unused "renesas, channels-mask" handling Daniel Lezcano
2017-10-29 21:20   ` [PATCH 07/17] clocksource/drivers/sh_cmt: Use of_device_get_match_data() helper Daniel Lezcano
2017-10-29 21:20   ` [PATCH 08/17] clocksource/drivers/fttmr010: pr_err() strings should end with newlines Daniel Lezcano
2017-10-29 21:20   ` [PATCH 09/17] clocksource/drivers/owl: " Daniel Lezcano
2017-10-29 21:20   ` [PATCH 10/17] clocksource/drivers/rockchip: " Daniel Lezcano
2017-10-29 21:20   ` [PATCH 11/17] clocksource: Improve GENERIC_CLOCKEVENTS dependency Daniel Lezcano
2017-10-29 21:20   ` [PATCH 12/17] MAINTAINERS: Fix path and add bindings to timers Daniel Lezcano
2017-10-29 21:20   ` Daniel Lezcano [this message]
2017-10-29 21:20   ` [PATCH 14/17] clocksource/drivers/arm_arch_timer: Fix DEFINE_PER_CPU expansion Daniel Lezcano
2017-10-29 21:20   ` [PATCH 15/17] clocksource/drivers/mips-gic-timer: Remove pointless irq_save,restore Daniel Lezcano
2017-10-29 21:20   ` [PATCH 16/17] clocksource/drivers/mips-gic-timer: Add fastpath for local timer updates Daniel Lezcano
2017-10-29 21:20   ` [PATCH 17/17] clocksource/drivers/timer-of: Add timer_of_exit function Daniel Lezcano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1509312035-17368-13-git-send-email-daniel.lezcano@linaro.org \
    --to=daniel.lezcano@linaro.org \
    --cc=ard.biesheuvel@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marc.zyngier@arm.com \
    --cc=mark.rutland@arm.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®