From patchwork Sun Apr 16 20:26:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 97465 Delivered-To: patch@linaro.org Received: by 10.140.109.52 with SMTP id k49csp1086847qgf; Sun, 16 Apr 2017 13:28:26 -0700 (PDT) X-Received: by 10.99.8.67 with SMTP id 64mr8409407pgi.220.1492374506391; Sun, 16 Apr 2017 13:28:26 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m188si8929486pfc.145.2017.04.16.13.28.26; Sun, 16 Apr 2017 13:28:26 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756889AbdDPU2Q (ORCPT + 15 others); Sun, 16 Apr 2017 16:28:16 -0400 Received: from mail-wm0-f47.google.com ([74.125.82.47]:35631 "EHLO mail-wm0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756858AbdDPU2O (ORCPT ); Sun, 16 Apr 2017 16:28:14 -0400 Received: by mail-wm0-f47.google.com with SMTP id w64so23477418wma.0 for ; Sun, 16 Apr 2017 13:28:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=d3tDXTRjyRbqy8vT+/BKjHnsU2XxW2QsvgOgtU08Q+E=; b=N5ciJAHlbzFikOJx4GLr7qiAd5kLz2c7wjsxkA/qkMmxDL+4P1ZFA3AJOry6ObkkSE eqfpe5lN4PIKhPqy4N9tGiiqVZakBddspqma7IxuVo9S+89MASm5crbAFacGvnaMi8UP XXAmfkclNMXQENNu4OiogrJjyus0KGeA22Wf0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=d3tDXTRjyRbqy8vT+/BKjHnsU2XxW2QsvgOgtU08Q+E=; b=ldzGFLnK5EI3yPHLUNTA3jbHYmf5UYmsVk34T9BqmR4htK4LovFggexpoBhI8Y0A7C A+qmovYHlujwNVPLhy5Vtoz0Ow63TgiY9IEkdbTU1i7qcOKgLHvB1PiTPjvl505nb3rY Mnd21CNKTt85QvNc2VURZgWHckV19nUSCOaBsQoxf97R5XWe67J2SiV+EI64gtmsfpnd nT7DMx8ab8FZPUdDFQK4xFb/Nhxymc2NTL2cKKrLxuXQ7SkUro3fqm2KEkGHANEJPe1z w+sQK5jr8D3iwk1yew5YbYR8txTc4pn2aBbJHrkDOaytodh1PHlTq2CFpqCgXtQ+HLHS SNOQ== X-Gm-Message-State: AN3rC/6emb9Xn5TecfZE1i4c6089qt1UfPntIvNIj2LH1y1w/GlTl+fA vfuL2kzMTAKRSR6j X-Received: by 10.28.125.195 with SMTP id y186mr6437411wmc.32.1492374483287; Sun, 16 Apr 2017 13:28:03 -0700 (PDT) Received: from mai.lan ([2001:41d0:fe90:b800:20c0:6248:a385:db35]) by smtp.gmail.com with ESMTPSA id 81sm7732196wmj.9.2017.04.16.13.28.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 16 Apr 2017 13:28:02 -0700 (PDT) From: Daniel Lezcano To: tglx@linutronix.de Cc: linux-kernel@vger.kernel.org, Marc Zyngier , Mark Rutland , Catalin Marinas , Will Deacon , linux-arm-kernel@lists.infradead.org (moderated list:ARM ARCHITECTED TIMER DRIVER) Subject: [PATCH 06/29] arm64: arch_timer: Add infrastructure for multiple erratum detection methods Date: Sun, 16 Apr 2017 22:26:56 +0200 Message-Id: <1492374441-23336-6-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1492374441-23336-1-git-send-email-daniel.lezcano@linaro.org> References: <20170416202542.GV2078@mai> <1492374441-23336-1-git-send-email-daniel.lezcano@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Marc Zyngier We're currently stuck with DT when it comes to handling errata, which is pretty restrictive. In order to make things more flexible, let's introduce an infrastructure that could support alternative discovery methods. No change in functionality. Acked-by: Thomas Gleixner Reviewed-by: Hanjun Guo Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/arch_timer.h | 7 ++- drivers/clocksource/arm_arch_timer.c | 83 +++++++++++++++++++++++++++++++----- 2 files changed, 78 insertions(+), 12 deletions(-) -- 2.7.4 diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index b4b3400..5cd964e 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -37,9 +37,14 @@ extern struct static_key_false arch_timer_read_ool_enabled; #define needs_unstable_timer_counter_workaround() false #endif +enum arch_timer_erratum_match_type { + ate_match_dt, +}; struct arch_timer_erratum_workaround { - const char *id; /* Indicate the Erratum ID */ + enum arch_timer_erratum_match_type match_type; + const void *id; + const char *desc; u32 (*read_cntp_tval_el0)(void); u32 (*read_cntv_tval_el0)(void); u64 (*read_cntvct_el0)(void); diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 7a8a411..5c5c2af 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -182,7 +182,9 @@ EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled); static const struct arch_timer_erratum_workaround ool_workarounds[] = { #ifdef CONFIG_FSL_ERRATUM_A008585 { + .match_type = ate_match_dt, .id = "fsl,erratum-a008585", + .desc = "Freescale erratum a005858", .read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0, .read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0, .read_cntvct_el0 = fsl_a008585_read_cntvct_el0, @@ -190,13 +192,81 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = { #endif #ifdef CONFIG_HISILICON_ERRATUM_161010101 { + .match_type = ate_match_dt, .id = "hisilicon,erratum-161010101", + .desc = "HiSilicon erratum 161010101", .read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0, .read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0, .read_cntvct_el0 = hisi_161010101_read_cntvct_el0, }, #endif }; + +typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround *, + const void *); + +static +bool arch_timer_check_dt_erratum(const struct arch_timer_erratum_workaround *wa, + const void *arg) +{ + const struct device_node *np = arg; + + return of_property_read_bool(np, wa->id); +} + +static const struct arch_timer_erratum_workaround * +arch_timer_iterate_errata(enum arch_timer_erratum_match_type type, + ate_match_fn_t match_fn, + void *arg) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ool_workarounds); i++) { + if (ool_workarounds[i].match_type != type) + continue; + + if (match_fn(&ool_workarounds[i], arg)) + return &ool_workarounds[i]; + } + + return NULL; +} + +static +void arch_timer_enable_workaround(const struct arch_timer_erratum_workaround *wa) +{ + timer_unstable_counter_workaround = wa; + static_branch_enable(&arch_timer_read_ool_enabled); +} + +static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type type, + void *arg) +{ + const struct arch_timer_erratum_workaround *wa; + ate_match_fn_t match_fn = NULL; + + if (static_branch_unlikely(&arch_timer_read_ool_enabled)) + return; + + switch (type) { + case ate_match_dt: + match_fn = arch_timer_check_dt_erratum; + break; + default: + WARN_ON(1); + return; + } + + wa = arch_timer_iterate_errata(type, match_fn, arg); + if (!wa) + return; + + arch_timer_enable_workaround(wa); + pr_info("Enabling global workaround for %s\n", wa->desc); +} + +#else +#define arch_timer_check_ool_workaround(t,a) do { } while(0) #endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */ static __always_inline @@ -960,17 +1030,8 @@ static int __init arch_timer_of_init(struct device_node *np) arch_timer_c3stop = !of_property_read_bool(np, "always-on"); -#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND - for (i = 0; i < ARRAY_SIZE(ool_workarounds); i++) { - if (of_property_read_bool(np, ool_workarounds[i].id)) { - timer_unstable_counter_workaround = &ool_workarounds[i]; - static_branch_enable(&arch_timer_read_ool_enabled); - pr_info("arch_timer: Enabling workaround for %s\n", - timer_unstable_counter_workaround->id); - break; - } - } -#endif + /* Check for globally applicable workarounds */ + arch_timer_check_ool_workaround(ate_match_dt, np); /* * If we cannot rely on firmware initializing the timer registers then