Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp1210488pxb; Wed, 6 Apr 2022 11:24:39 -0700 (PDT) X-Google-Smtp-Source: ABdhPJylCSS7cd0izXpRJsxXMaj7r/BfXrnJ+N2VpeOZtlBUhlyhyn0Zhk7/DLRe6wff3YTpGXvd X-Received: by 2002:a17:902:7c0a:b0:156:87e0:846 with SMTP id x10-20020a1709027c0a00b0015687e00846mr9926839pll.8.1649269479242; Wed, 06 Apr 2022 11:24:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1649269479; cv=none; d=google.com; s=arc-20160816; b=ewXb9Nm90Q+SRj5+g+KaRNLBW0mEXpJ6yD6dDiknINc1pTXGJn2t23w2b6yZaIamJ3 XnuHHhLHTdRjqeuJG3WW2AwcofGY98Yt3nRTzkt7hGAoA4Jao053w/Koo2YLbRXPqarM jwI+VQZJRssY7GIyIt2wdn6wu15hA/wS0FaO1gcZtw7d2sz/ZGkLgAj8WS4akO8bQD7/ FVMSn6e3G65bKMweJzm3Gb/gVrL5S0ONJSCOZKAyu4Qqq6xSqXWbh/qIFxdjwIIT1uHv hflROC9xx6gjOVP1+mf0Snd7p6e6p4QMGHYyiJfeqgPxXt4VNIHVDckjKzP2JrZkrlOy ZYvA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=1Myc8GbNGuIukMdWeAOf11Y8MsmWBDf+MLVS2qCPhiM=; b=jZvS32QwAlX6jPbaoN3tF6lJx/pAVXDjBq2u+v2MJGZuzFob8zf+ELTFZc9ayTOs9m tLaFMxeRLg+XxoI7V3b24de5lHK+UpIL0PL1YZ/53tBNv9jo0DniM13p3GGQoVyobRlr StslWOn8Cwh2yYlCLXOR0x3UHrN9d8bRoqSfWETcHgI3NfN3By1GhkhgwzSWqO4RiDmR tmyIDxpYXamktR/RmIpttLC+k5dsGqD7GCXWzgofY4uARjitXEIuQVxQ0/17EzMYDkA/ blB//9810F7VW9b0EE2KJQJSU9k+qJpBlrf9P8XOqb5ubk3kEuCa61UfFBpSbhSMDUDu eXjw== ARC-Authentication-Results: i=1; mx.google.com; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id y5-20020a17090322c500b00153b2d16460si17714691plg.104.2022.04.06.11.24.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Apr 2022 11:24:39 -0700 (PDT) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 082511905B9; Wed, 6 Apr 2022 11:07:47 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240214AbiDFSJO (ORCPT + 99 others); Wed, 6 Apr 2022 14:09:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54336 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240428AbiDFSHx (ORCPT ); Wed, 6 Apr 2022 14:07:53 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 136A718B7A0; Wed, 6 Apr 2022 09:46:15 -0700 (PDT) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id EA27023A; Wed, 6 Apr 2022 09:46:14 -0700 (PDT) Received: from eglon.cambridge.arm.com (eglon.cambridge.arm.com [10.1.196.218]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4184F3F73B; Wed, 6 Apr 2022 09:46:14 -0700 (PDT) From: James Morse To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: James Morse , Catalin Marinas Subject: [stable:PATCH v4.9.309 14/43] arm64: arch_timer: Add infrastructure for multiple erratum detection methods Date: Wed, 6 Apr 2022 17:45:17 +0100 Message-Id: <20220406164546.1888528-14-james.morse@arm.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220406164546.1888528-1-james.morse@arm.com> References: <0220406164217.1888053-1-james.morse@arm.com> <20220406164546.1888528-1-james.morse@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RDNS_NONE, SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Marc Zyngier commit 651bb2e9dca6e6dbad3fba5f6e6086a23575b8b5 upstream. 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 [ morse: Removed the changes to HiSilicon erratum 161010101, which isn't present in v4.9 ] Signed-off-by: James Morse --- arch/arm64/include/asm/arch_timer.h | 7 ++- drivers/clocksource/arm_arch_timer.c | 81 ++++++++++++++++++++++++---- 2 files changed, 76 insertions(+), 12 deletions(-) diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index b4b34004a21e..5cd964e90d11 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 4b268ef9cc78..015b28e7f1f2 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -140,13 +140,81 @@ 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, }, #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 @@ -919,17 +987,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 -- 2.30.2