Received: by 2002:a05:7412:a9a2:b0:e2:908c:2ebd with SMTP id o34csp537606rdh; Thu, 26 Oct 2023 08:50:31 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFJLvCoZaa7crNCnGXDIDv4gexCLFqcUu+5ADP5ZiBxOh8Kw4JYHPHrsAxZTz6nSPWcuaIk X-Received: by 2002:a05:6358:8a9:b0:168:e841:5450 with SMTP id m41-20020a05635808a900b00168e8415450mr84865rwj.0.1698335430688; Thu, 26 Oct 2023 08:50:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698335430; cv=none; d=google.com; s=arc-20160816; b=ka4hNaY/WLI6KFV6P9AjpVMujlAaRHUOsPhV5GbYxYfSWNK1Ig1aNiiZUjX0eyas0H vw2TV32/V+uaRalFSbqIz7ZWuprLIcE6s3FQzJOhv1/7945/5nX/h4rNZno4m/UF1Q2B yGZbEVMGq+nQT8WzVixQ0sIKGItwDU8CVyCFLf2gtnRjjgH8J4EhrcLvfLZLULPcaJFw v1oOUz4GdOkAYFTmVYAougzCcKur9hnM0pSUKrCJJqC9+wIrFIkOyWD3iKQR//aUu1vH 1XYulVWYTLcKxKIDQ5gKEVDB/xdLlN/hiI/kc76yaUuqz5ia4Wyj0keoxusqEUk9Kno/ NFQw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:message-id:content-transfer-encoding :mime-version:subject:date:from:dkim-signature; bh=EMSq5iJqZKkaPhtGiAuNlCyNMf68u8IKBdumZ9/wExQ=; fh=4kKBV5MJ0T7Pe+Df8v7Z2X/m2fdepSZ73LzcarLNSx8=; b=jRcLarJlsKsXLexQr+OCfcTO0bQ82x/HKkd4FM6cJtNHc2+gmOFn03bBBTY6QVhuk5 zJWceOhWvXYpHOXwL/gc8zq12lND0JyWYZDUz6ZB8FP86ghaQI2I+FKpDE9tHw9FFi78 mGwxVaG9S5Jhv/SplfuyTNO72FO1xFVpNOEzjFJYpgZ40dBZ8/LAa0bqIvVAEFEVklI+ un5NRF6eQXR6wjHak7IygcnNNaBXzASbDyINflBG0IPQg7nR3zyHBreBrqv9z1Pv9Ixn gFyOLHH5W7SARnxgLeaNrh9k0X+2/gazVw/2TRDduPhgcPTjO5q49CTzFmNW9qMW4yy3 WXpw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=a0vlJmCm; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.34 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from howler.vger.email (howler.vger.email. [23.128.96.34]) by mx.google.com with ESMTPS id v4-20020a818504000000b00579e8b962adsi15126562ywf.175.2023.10.26.08.50.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Oct 2023 08:50:30 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.34 as permitted sender) client-ip=23.128.96.34; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=a0vlJmCm; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.34 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by howler.vger.email (Postfix) with ESMTP id AEF7280ECF9C; Thu, 26 Oct 2023 08:50:27 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at howler.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345476AbjJZPuT (ORCPT + 99 others); Thu, 26 Oct 2023 11:50:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44780 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345479AbjJZPuS (ORCPT ); Thu, 26 Oct 2023 11:50:18 -0400 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3F487196; Thu, 26 Oct 2023 08:50:16 -0700 (PDT) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CD90FC433C7; Thu, 26 Oct 2023 15:50:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1698335415; bh=2TNYOlAWXSo2s3s0MUtNW5qeHxKzDFx3ObC+ajuBzvo=; h=From:Date:Subject:To:Cc:From; b=a0vlJmCmYlf9/apd7la5cvFEuusbJYvfjIz1qcz9wjIsLkiYuC3Fi5GS2TvFET3pc QRlxZT2qT7qYb2+CQLS69YUWI72lGqjUU3IFKXprabDIfKRSGPHyIgeaDdgwXpb7uh 67FDiwdUgbN7P87+gvKiRiD8SIwzynvnAnLEYJmcpXIKGE90omnbjsIyAvYojUX53A f7u5dJdG0HcutOtn5gGHO1vXdCRqccsV+83iV5g8u+dvdWfAQ7K1lY+yZeYBZCuinQ uhEzbR2xAsDowfVGDeBAzd/ksfmyCC8lnpV+46CH/eY9HYrcKm8vdYzJClCw9IM8bh AvR90wL0K8rSA== From: Mark Brown Date: Thu, 26 Oct 2023 16:49:19 +0100 Subject: [PATCH] regmap: Ensure range selector registers are updated after cache sync MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20231026-regmap-fix-selector-sync-v1-1-633ded82770d@kernel.org> X-B4-Tracking: v=1; b=H4sIAH+KOmUC/x2MQQqDMBBFryKz7kASbRe9SnERkokOtFFmpCjBu zu4efDg/d9ASZgU3l0DoT8rL9XEPzpIc6wTIWdzCC703oUXCk2/uGLhHZW+lLZFUI+aMGb/9EM x5gI2X4Usuq8/43letFvR32oAAAA= To: Hector Martin , linux-kernel@vger.kernel.org Cc: Mark Brown , stable@vger.kernel.org X-Mailer: b4 0.13-dev-0438c X-Developer-Signature: v=1; a=openpgp-sha256; l=3008; i=broonie@kernel.org; h=from:subject:message-id; bh=2TNYOlAWXSo2s3s0MUtNW5qeHxKzDFx3ObC+ajuBzvo=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBlOoq13XfJMKLkO/6LHKkYMytONA8JC1UZg/ZKY9M1 tXGBwOGJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZTqKtQAKCRAk1otyXVSH0PujB/ 4i0FN10uwbwubidM8dysJf5BXaMoQCcR85HUy6JMnSSjFuukqe+zc/WONlibNM6Bbtvc1xiKCOAxsx 98wmL1SCF9wSKLcsib5kHU5f9ZZpl0Zsfg/UgdQdse8hbcVksU3t3sF5I40pJgT6W2p+f7VY9VLyIR d0Bzt2wze2KQZM6SOiM9ljkQh5PgAxaQZdN3E92LS+QirepKHDC11UZatT/m0QXeYS6isIlKwc2QLm Y6jprBJGG1NTPPs8kuXFF3C8qlXzdnipWPHcWjXQTjetRFX7x5RwHoPCRD82xtiCa6mnadeY2l2Qnd /mMAD/DkgMz/+rnRCjGiZQKifuH/eY X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB X-Spam-Status: No, score=-1.2 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on howler.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (howler.vger.email [0.0.0.0]); Thu, 26 Oct 2023 08:50:27 -0700 (PDT) When we sync the register cache we do so with the cache bypassed in order to avoid overhead from writing the synced values back into the cache. If the regmap has ranges and the selector register for those ranges is in a register which is cached this has the unfortunate side effect of meaning that the physical and cached copies of the selector register can be out of sync after a cache sync. The cache will have whatever the selector was when the sync started and the hardware will have the selector for the register that was synced last. Fix this by rewriting all cached selector registers after every sync, ensuring that the hardware and cache have the same content. This will result in extra writes that wouldn't otherwise be needed but is simple so hopefully robust. We don't read from the hardware since not all devices have physical read support. Given that nobody noticed this until now it is likely that we are rarely if ever hitting this case. Reported-by: Hector Martin Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/base/regmap/regcache.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index c5d151e9c481..92592f944a3d 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -334,6 +334,11 @@ static int regcache_default_sync(struct regmap *map, unsigned int min, return 0; } +static int rbtree_all(const void *key, const struct rb_node *node) +{ + return 0; +} + /** * regcache_sync - Sync the register cache with the hardware. * @@ -351,6 +356,7 @@ int regcache_sync(struct regmap *map) unsigned int i; const char *name; bool bypass; + struct rb_node *node; if (WARN_ON(map->cache_type == REGCACHE_NONE)) return -EINVAL; @@ -392,6 +398,30 @@ int regcache_sync(struct regmap *map) /* Restore the bypass state */ map->cache_bypass = bypass; map->no_sync_defaults = false; + + /* + * If we did any paging with cache bypassed and a cached + * paging register then the register and cache state might + * have gone out of sync, force writes of all the paging + * registers. + */ + rb_for_each(node, 0, &map->range_tree, rbtree_all) { + struct regmap_range_node *this = + rb_entry(node, struct regmap_range_node, node); + + /* If there's nothing in the cache there's nothing to sync */ + ret = regcache_read(map, this->selector_reg, &i); + if (ret != 0) + continue; + + ret = _regmap_write(map, this->selector_reg, i); + if (ret != 0) { + dev_err(map->dev, "Failed to write %x = %x: %d\n", + this->selector_reg, i, ret); + break; + } + } + map->unlock(map->lock_arg); regmap_async_complete(map); --- base-commit: 611da07b89fdd53f140d7b33013f255bf0ed8f34 change-id: 20231026-regmap-fix-selector-sync-ad1514fd15df Best regards, -- Mark Brown