Message ID | pnd1qifa7sj.fsf@axis.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp507240vqr; Tue, 13 Jun 2023 05:32:22 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7Y9I0Z6CqC5hII5jkn5mwSn9TQYjET5d1yOBaWoUajmD4gzQ6a0gJkxBVJSWBZSAG6gCw9 X-Received: by 2002:a2e:869a:0:b0:2b1:b727:7a7e with SMTP id l26-20020a2e869a000000b002b1b7277a7emr5081580lji.18.1686659542334; Tue, 13 Jun 2023 05:32:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686659542; cv=none; d=google.com; s=arc-20160816; b=yFcudKa9pVmTVWWpBeaknT/xEtiHrB9P6OqPKwuHwad9xntU9BBGbhEnKBdIdXXvQr 71r5SZi9ewNDSHN8to+ua7SuJdsV+j4LdpPWovT65xSTicaAmC9TbU31jdkpoJQ7k2Da ow6RDjfxNJOCG8EWv8Gi5xTD0yI9oc7qeUbJmLpCyQkVG7CDah3YB2w3Kf+DIwN57XBK 4pEyqd8VvUuKfmQDF683vBYJ6In5PkMm9dz6VFZsed5oO2sgVFGZyX0xc7c9O/eB5udZ 9vSyz0eDmrX7I0XEd9Vl1lO1tmEaTTch7YiiUQX8l067MchGJBZs01ZitKJWuwjZp9iq pSKw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:message-id:date:subject:cc:to:from :user-agent:dkim-signature; bh=0M3Bw0Wvlmg09M9Otqtr7gQiKvBD/9rNZgj0Z8luQVA=; b=Up8IvWB6xsfHHLVw6kmBXgksBSgJxnOEzLn8HGbQzchGRDTyVJZi/JTO3tVyRwe6CB gCVFAS1Engc273cqzXk+BPRLlC3Oj7jEUhWQjCz3PZDB6kRyCQf8WEWtEiVNtQ7MlYbj kTuO8Fb6DeHngC+7XMyJbwrCRmuispEoNUAr1BUoPSv9MqxOWTq5dtd2NLpn/knog5l0 qUkGw126RrmcJuZikhMMd4QlVuBi8WUQBaQb4XJKiITYjxZLA3RhwWTKUfmKgVmX9+YR Vif0Yv5aZDackiYk2CebKjHxzgnHhGeBS1dZXYT3SpHohW5n7wQ7udertO2HzSuBrS+i 3VFg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass (test mode) header.i=@axis.com header.s=axis-central1 header.b=B1pggX0K; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=axis.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id u17-20020aa7d0d1000000b005187a3f512csi455755edo.635.2023.06.13.05.31.57; Tue, 13 Jun 2023 05:32:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass (test mode) header.i=@axis.com header.s=axis-central1 header.b=B1pggX0K; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=axis.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242268AbjFMMDc (ORCPT <rfc822;rust.linux@gmail.com> + 99 others); Tue, 13 Jun 2023 08:03:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51244 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235323AbjFMMD3 (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Tue, 13 Jun 2023 08:03:29 -0400 Received: from smtp1.axis.com (smtp1.axis.com [195.60.68.17]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C59D91AC for <linux-kernel@vger.kernel.org>; Tue, 13 Jun 2023 05:03:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axis.com; q=dns/txt; s=axis-central1; t=1686657808; x=1718193808; h=from:to:cc:subject:date:message-id:mime-version; bh=0M3Bw0Wvlmg09M9Otqtr7gQiKvBD/9rNZgj0Z8luQVA=; b=B1pggX0KfEPzMjBeAa5P3gRPVvmWxjYmsFxCvdyOTDRL6aavEywxlkr+ I/X9LWD/1pziIF5jNnH6EUCkIIrID0DJemAt+rT3iI48cDsn0LTOnK+u3 03CqcIY2jSOjEbrJI6tU1Af+5/ae3rxYTA9cgcbyokBn1BjNKbVVSPnIv dVMWl/wu5y//pMsddgMILytIWxsZRbkrQk12nOix8E/Ia8XZDpYC17ope Y7GbiOd7GXkPtTUVgXa0UJeisXMMQUCHBXcVgUJo27nvxqtKR6rHxUp4/ zFHkEiTzmzfRKJCKmStD0e4mAXcFSh1FOJApfj5TWXx90F76nXgx9WSOC A==; User-agent: a.out From: Waqar Hameed <waqar.hameed@axis.com> To: Mark Brown <broonie@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, "Rafael J. Wysocki" <rafael@kernel.org> CC: <kernel@axis.com>, <linux-kernel@vger.kernel.org> Subject: [PATCH v2] regmap: Add debugfs file for forcing field writes Date: Tue, 13 Jun 2023 13:42:27 +0200 Message-ID: <pnd1qifa7sj.fsf@axis.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.0.5.60] X-ClientProxiedBy: se-mail02w.axis.com (10.20.40.8) To se-mail01w.axis.com (10.20.40.7) X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_PASS, SPF_PASS,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham 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: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1768590716077932698?= X-GMAIL-MSGID: =?utf-8?q?1768590716077932698?= |
Series |
[v2] regmap: Add debugfs file for forcing field writes
|
|
Commit Message
Waqar Hameed
June 13, 2023, 11:42 a.m. UTC
`_regmap_update_bits()` checks if the current register value differs
from the new value, and only writes to the register if they differ. When
testing hardware drivers, it might be desirable to always force a
register write, for example when writing to a `regmap_field`. This
enables and simplifies testing and verification of the hardware
interaction. For example, when using a hardware mock/simulation model,
one can then more easily verify that the driver makes the correct
expected register writes during certain events.
Add a bool variable `force_write_field` and a corresponding debugfs
entry to enable this. Since this feature could interfere with driver
operation, guard it with a macro.
Signed-off-by: Waqar Hameed <waqar.hameed@axis.com>
---
Changes in v2:
* Add macro to guard the debugfs entry.
* Fix `Signed-off-by` in commit message to match actual email address.
* Link to v1: https://lore.kernel.org/all/pndttvcu3ut.fsf@axis.com/
drivers/base/regmap/internal.h | 3 +++
drivers/base/regmap/regmap-debugfs.c | 11 +++++++++++
drivers/base/regmap/regmap.c | 2 +-
3 files changed, 15 insertions(+), 1 deletion(-)
base-commit: 858fd168a95c5b9669aac8db6c14a9aeab446375
Comments
On Tue, Jun 13, 2023 at 01:42:27PM +0200, Waqar Hameed wrote: > `_regmap_update_bits()` checks if the current register value differs > from the new value, and only writes to the register if they differ. When > testing hardware drivers, it might be desirable to always force a > register write, for example when writing to a `regmap_field`. This > enables and simplifies testing and verification of the hardware > interaction. For example, when using a hardware mock/simulation model, > one can then more easily verify that the driver makes the correct > expected register writes during certain events. > > Add a bool variable `force_write_field` and a corresponding debugfs > entry to enable this. Since this feature could interfere with driver > operation, guard it with a macro. > > Signed-off-by: Waqar Hameed <waqar.hameed@axis.com> > --- > Changes in v2: > * Add macro to guard the debugfs entry. > * Fix `Signed-off-by` in commit message to match actual email address. > * Link to v1: https://lore.kernel.org/all/pndttvcu3ut.fsf@axis.com/ > > drivers/base/regmap/internal.h | 3 +++ > drivers/base/regmap/regmap-debugfs.c | 11 +++++++++++ > drivers/base/regmap/regmap.c | 2 +- > 3 files changed, 15 insertions(+), 1 deletion(-) > > diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h > index 9bd0dfd1e259..6472b3222b82 100644 > --- a/drivers/base/regmap/internal.h > +++ b/drivers/base/regmap/internal.h > @@ -125,6 +125,9 @@ struct regmap { > int reg_stride; > int reg_stride_order; > > + /* If set, will always write field to HW. */ > + bool force_write_field; > + > /* regcache specific members */ > const struct regcache_ops *cache_ops; > enum regcache_type cache_type; > diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c > index c491fabe3617..f36027591e1a 100644 > --- a/drivers/base/regmap/regmap-debugfs.c > +++ b/drivers/base/regmap/regmap-debugfs.c > @@ -636,6 +636,17 @@ void regmap_debugfs_init(struct regmap *map) > ®map_cache_bypass_fops); > } > > + /* > + * This could interfere with driver operation. Therefore, don't provide > + * any real compile time configuration option for this feature. One will > + * have to modify the source code directly in order to use it. > + */ > +#undef REGMAP_ALLOW_FORCE_WRITE_FIELD_DEBUGFS > +#ifdef REGMAP_ALLOW_FORCE_WRITE_FIELD_DEBUGFS > + debugfs_create_bool("force_write_field", 0600, map->debugfs, > + &map->force_write_field); > +#endif Please no, that means this will never ever ever get used, and if it happens to break the build or runtime, no one will ever notice it. If you need this for your device/tree/distro, great, just keep it as an out-of-tree patch with the huge header "NEVER ENABLE THIS IN A REAL SYSTEM" or something like that. But as-is, we can't take this, sorry. greg k-h
On Tue, 13 Jun 2023, Greg Kroah-Hartman wrote: > On Tue, Jun 13, 2023 at 01:42:27PM +0200, Waqar Hameed wrote: > > `_regmap_update_bits()` checks if the current register value differs > > from the new value, and only writes to the register if they differ. When > > > > + /* > > + * This could interfere with driver operation. Therefore, don't provide > > + * any real compile time configuration option for this feature. One will > > + * have to modify the source code directly in order to use it. > > + */ > > +#undef REGMAP_ALLOW_FORCE_WRITE_FIELD_DEBUGFS > > +#ifdef REGMAP_ALLOW_FORCE_WRITE_FIELD_DEBUGFS > > + debugfs_create_bool("force_write_field", 0600, map->debugfs, > > + &map->force_write_field); > > +#endif > > Please no, that means this will never ever ever get used, and if it > happens to break the build or runtime, no one will ever notice it. > > If you need this for your device/tree/distro, great, just keep it as an > out-of-tree patch with the huge header "NEVER ENABLE THIS IN A REAL > SYSTEM" or something like that. The ordinary only-write-if-bits-have-changed behavior of _regmap_update_bits would seem to be mostly an optimization to minimize the number of writes to a device. The way it is normally used in the code, it's not easy to predict when it in fact will result in a write, because the whole idea of a function like this is that a driver doesn't have to keep track of which bits are actually set or not, or else the function would not be useful in the first place. I can understand that enabling a write-always behavior results in a different behavior on the associated bus (e.g. I2C), but in the end it shouldn't affect the functionality of the peripheral device any more than rearranging driver code to perform regmap writes in a different order, which might also lead to fewer or more bus writes. It seems I'm clearly in the wrong here, so there must be some scenario I've missed. It just doesn't seem that dangerous; it's a debug functionality after all. /Ricard
On Tue, Jun 13, 2023 at 05:02:27PM +0200, Greg Kroah-Hartman wrote: > On Tue, Jun 13, 2023 at 01:42:27PM +0200, Waqar Hameed wrote: > > +#undef REGMAP_ALLOW_FORCE_WRITE_FIELD_DEBUGFS > > +#ifdef REGMAP_ALLOW_FORCE_WRITE_FIELD_DEBUGFS > > + debugfs_create_bool("force_write_field", 0600, map->debugfs, > > + &map->force_write_field); > > +#endif > Please no, that means this will never ever ever get used, and if it > happens to break the build or runtime, no one will ever notice it. > If you need this for your device/tree/distro, great, just keep it as an > out-of-tree patch with the huge header "NEVER ENABLE THIS IN A REAL > SYSTEM" or something like that. We have an existing setting that parallels this which enables writes via debugfs - there *is* demand for this sort of thing in development where this is a viable configuration mechanism, having something in tree in a way that requires an out of tree patch like you're suggesting to enable it documents why the feature isn't something you can enable without code changes whereas just not having anything means people send patches adding the feature. This one is very much safer than the general write thing, we probably *could* have a Kconfig option but changing the guarantees underneath drivers feels like it's going to explode if we just let it happen.
On Tue, Jun 13, 2023 at 05:15:10PM +0200, Ricard Wanderlof wrote: > I can understand that enabling a write-always behavior results in a > different behavior on the associated bus (e.g. I2C), but in the end it > shouldn't affect the functionality of the peripheral device any more than > rearranging driver code to perform regmap writes in a different order, > which might also lead to fewer or more bus writes. > It seems I'm clearly in the wrong here, so there must be some scenario > I've missed. It just doesn't seem that dangerous; it's a debug > functionality after all. There are devices where the act of writing to a register can have side effects even if the values in the register are the same (for example triggering some kind of recalibration based on the "new" value). It's rare, and it's probably more likely to be annoying or disruptive than actually dangerous, but it is something drivers might be relying on.
On Tue, 13 Jun 2023 13:42:27 +0200, Waqar Hameed wrote: > `_regmap_update_bits()` checks if the current register value differs > from the new value, and only writes to the register if they differ. When > testing hardware drivers, it might be desirable to always force a > register write, for example when writing to a `regmap_field`. This > enables and simplifies testing and verification of the hardware > interaction. For example, when using a hardware mock/simulation model, > one can then more easily verify that the driver makes the correct > expected register writes during certain events. > > [...] Applied to https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git for-next Thanks! [1/1] regmap: Add debugfs file for forcing field writes commit: b629c698eae745eb51b6d92395e2eee44bbf5f49 All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 9bd0dfd1e259..6472b3222b82 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -125,6 +125,9 @@ struct regmap { int reg_stride; int reg_stride_order; + /* If set, will always write field to HW. */ + bool force_write_field; + /* regcache specific members */ const struct regcache_ops *cache_ops; enum regcache_type cache_type; diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index c491fabe3617..f36027591e1a 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c @@ -636,6 +636,17 @@ void regmap_debugfs_init(struct regmap *map) ®map_cache_bypass_fops); } + /* + * This could interfere with driver operation. Therefore, don't provide + * any real compile time configuration option for this feature. One will + * have to modify the source code directly in order to use it. + */ +#undef REGMAP_ALLOW_FORCE_WRITE_FIELD_DEBUGFS +#ifdef REGMAP_ALLOW_FORCE_WRITE_FIELD_DEBUGFS + debugfs_create_bool("force_write_field", 0600, map->debugfs, + &map->force_write_field); +#endif + next = rb_first(&map->range_tree); while (next) { range_node = rb_entry(next, struct regmap_range_node, node); diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index fa2d3fba6ac9..89b701ceb43f 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -3273,7 +3273,7 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg, tmp = orig & ~mask; tmp |= val & mask; - if (force_write || (tmp != orig)) { + if (force_write || (tmp != orig) || map->force_write_field) { ret = _regmap_write(map, reg, tmp); if (ret == 0 && change) *change = true;