Received: by 2002:ad5:4acb:0:0:0:0:0 with SMTP id n11csp4449147imw; Tue, 19 Jul 2022 06:52:10 -0700 (PDT) X-Google-Smtp-Source: AGRyM1v54NmXObr3sgU7Sj8V2l2eF+52/r5mMJhRImrGVFpYrLvKgL8ojwyzCOO7gtYKIfmcbude X-Received: by 2002:a05:6402:400a:b0:43a:40e4:af89 with SMTP id d10-20020a056402400a00b0043a40e4af89mr44914628eda.383.1658238730479; Tue, 19 Jul 2022 06:52:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658238730; cv=none; d=google.com; s=arc-20160816; b=w8jXAMyBJ/oy4ivQuq7GsJqdKb7QW6YoUTrJyK4ylmDrG3ojWrdOvGwbdTdj/TGvDo txxx/fl2Hrx+uoZG6tusOXTFLovzaYlzdQ45GPI/evubKV4WOoFVolOZkkzfDSeQvAau sQ+KPefaI0p2C4Ggoxz4W0kGfZPbFr9eAMs7Bn35BIEBEYi05v92j4WvcoxRSQsD/GBP zUo12yhteGMZBc7XfnBSG+JUvLhlTBvJt/ddPo+oI3IKAvKpuq2EpwaAzeIwENtBdjC0 MijiOYUPKp8oGeamaLLXdr1HLhvftP4GQq+U6DJW9JxZJyRsYsGug8EqQQxr2r8uKcH1 bK0A== 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 :message-id:date:subject:cc:to:from:dkim-signature; bh=34WEw9awHu7gIj88S8fD4edkfHyl6opCxCuZk5MV1WY=; b=cubZeasSuu5KPRPGccUfFEH6PgJp/dAHlB9vGz1sIwI14jgINgfkw+swhnCV3KJgPY R15nFX7EvCBzE1N1hAQPNQ49z94C7kU0/cedXAU4O6tHCTZ2FUnircdQiaNXlN9IOrcO FXmgu0ZjYqAJmzPa6C/t36vnn0gLhe4J0SkJ82uRZp30t/UGNKo4fVwLxVrgWBT0C1D5 D2f9Efe3V8ZpeBJr7RQlM/z8ub4u44IcG0nspw61XoYlZRukWjzInHqMDAfeJ382Q3qg SDz5OMiXZGSaGHA51g9gJkTC6F8QTxgz+BLAyUmXh5c1e5Ccj5+xD4YBXl9Yuz3OktQJ SOuw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="AsAWj/Ao"; 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=linaro.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ji17-20020a170907981100b0072ae7302377si25730538ejc.527.2022.07.19.06.51.46; Tue, 19 Jul 2022 06:52:10 -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 header.i=@linaro.org header.s=google header.b="AsAWj/Ao"; 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=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241169AbiGSMjL (ORCPT + 99 others); Tue, 19 Jul 2022 08:39:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49830 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240996AbiGSMiY (ORCPT ); Tue, 19 Jul 2022 08:38:24 -0400 Received: from mail-lf1-x12f.google.com (mail-lf1-x12f.google.com [IPv6:2a00:1450:4864:20::12f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C319A52E66 for ; Tue, 19 Jul 2022 05:15:00 -0700 (PDT) Received: by mail-lf1-x12f.google.com with SMTP id bf9so24384231lfb.13 for ; Tue, 19 Jul 2022 05:15:00 -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:mime-version :content-transfer-encoding; bh=34WEw9awHu7gIj88S8fD4edkfHyl6opCxCuZk5MV1WY=; b=AsAWj/AoIqTCw/y/vRqi6d8PBRZR41f9vcEoK7NedJ6XFDli5M0KyZDzdKjJWDJoWG LDjCB7vRB7MYilrC0pCactxmsHmQkI6bUavPH+Lv7JtztyqDLzwlbI5Q8FEZAn9I1QkZ WdrxeJjZ+YZ3BrKlgAxyiCtVQHLCRIDPd27xFEANiIu/7EQlkYZq3Faxfw4xJiCE1aKQ +Rcnxihrxu/rYwRLNsH0R7EJUTM/W1i78x/z2r7Bo8ePRTSjYonHaZOdZMglfR7jvGEJ xmaBVkCPXGLEXflU1IEFmQdYpwpeEa7ftbgXZCQpGS494JPwzLt0W5gg0d1S8PxgHBF7 pW0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=34WEw9awHu7gIj88S8fD4edkfHyl6opCxCuZk5MV1WY=; b=swBuj9unujzmwfjvRHg+3OfF3a1LMtkmynN9tk8nmtsqlDc71mnJ+J4J/x59K2ejaA 24E4/GoTyBBSlEJcBNNHljqWcMkgMbzdoCgjNZk45w/kGNV8ZDVUR7PIt9VdApkSMEjR 4vTGWdU5Wrnyqrf2wZPcgY3SFtgPtUYG3i+xpjsxp/6b2pH/Jmes7WXkpbHOgJkWPUSm 4zowCjW2opK8IpBioTOfZhKndWKqoPoAfc0YDiR6B5RdIT2+oEKIFXkly8wYyVFWAfVQ eBdoFiR6NJ7BsPVS2VuIELQaZd05RQ57Czza2aaS+hbWQir+fkzwEdPwHiyd/dtYCJpU HYDQ== X-Gm-Message-State: AJIora+QIxYek6KB6kGLC17i2zuevTp4+YDwf13QOTUvQFOS1BncToh5 0ukbEyjFDW4OLylanjKj6Oy+Thzsk+NgyPNc X-Received: by 2002:a05:6512:344e:b0:489:f4ad:88d8 with SMTP id j14-20020a056512344e00b00489f4ad88d8mr19034026lfr.297.1658232899046; Tue, 19 Jul 2022 05:14:59 -0700 (PDT) Received: from krzk-bin.. (89-162-31-138.fiber.signal.no. [89.162.31.138]) by smtp.gmail.com with ESMTPSA id p4-20020a2ea4c4000000b0025d6c8cfafcsm2645676ljm.93.2022.07.19.05.14.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Jul 2022 05:14:58 -0700 (PDT) From: Krzysztof Kozlowski To: Mark Brown , Greg Kroah-Hartman , "Rafael J. Wysocki" , linux-kernel@vger.kernel.org Cc: Krzysztof Kozlowski , Srinivas Kandagatla , Charles Keepax , Kuninori Morimoto , Bjorn Andersson Subject: [PATCH] regmap: support regmap_field_write() on non-readable fields Date: Tue, 19 Jul 2022 14:14:46 +0200 Message-Id: <20220719121446.375095-1-krzysztof.kozlowski@linaro.org> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS 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: X-Mailing-List: linux-kernel@vger.kernel.org Current implementation of regmap_field_write() performs an update of register (read+write), therefore it ignores regmap read-restrictions and is not suitable for write-only registers (e.g. interrupt clearing). Extend regmap_field_write() and regmap_field_force_write() to check if register is readable and only then perform an update. In the other case, it is expected that mask of field covers entire register thus a full write is allowed. Signed-off-by: Krzysztof Kozlowski --- Cc: Srinivas Kandagatla Cc: Charles Keepax Cc: Kuninori Morimoto Cc: Bjorn Andersson --- drivers/base/regmap/regmap.c | 50 ++++++++++++++++++++++++++++++++++++ include/linux/regmap.h | 15 ++--------- 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 0caa5690c560..4d18a34f7b2c 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -2192,6 +2192,56 @@ int regmap_noinc_write(struct regmap *map, unsigned int reg, } EXPORT_SYMBOL_GPL(regmap_noinc_write); +static int _regmap_field_write_or_update(struct regmap_field *field, + unsigned int val, bool *change, + bool async, bool force) +{ + unsigned int mask = (~0 << field->shift) & field->mask; + unsigned int map_val_mask, map_val_mask_h; + int ret; + + if (regmap_readable(field->regmap, field->reg)) + return regmap_update_bits_base(field->regmap, field->reg, + mask, val << field->shift, + change, async, force); + + map_val_mask_h = field->regmap->format.val_bytes * 8 - 1; + map_val_mask = GENMASK(map_val_mask_h, 0); + + /* Writes of parts of register are not allowed for sanity */ + if (field->shift) + return -EINVAL; + + /* Mask of field must cover entire register */ + if (field->mask != map_val_mask) + return -EINVAL; + + if (change) + *change = false; + + if (async) + ret = regmap_write(field->regmap, field->reg, val); + else + ret = regmap_write_async(field->regmap, field->reg, val); + + if (ret == 0 && change) + *change = true; + + return ret; +} + +int regmap_field_write(struct regmap_field *field, unsigned int val) +{ + return _regmap_field_write_or_update(field, val, NULL, false, false); +} +EXPORT_SYMBOL_GPL(regmap_field_write); + +int regmap_field_force_write(struct regmap_field *field, unsigned int val) +{ + return _regmap_field_write_or_update(field, val, NULL, false, true); +} +EXPORT_SYMBOL_GPL(regmap_field_force_write); + /** * regmap_field_update_bits_base() - Perform a read/modify/write cycle a * register field. diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 7cf2157134ac..08507e764dfa 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -1307,6 +1307,8 @@ void devm_regmap_field_bulk_free(struct device *dev, struct regmap_field *field); int regmap_field_read(struct regmap_field *field, unsigned int *val); +int regmap_field_write(struct regmap_field *field, unsigned int val); +int regmap_field_force_write(struct regmap_field *field, unsigned int val); int regmap_field_update_bits_base(struct regmap_field *field, unsigned int mask, unsigned int val, bool *change, bool async, bool force); @@ -1316,19 +1318,6 @@ int regmap_fields_update_bits_base(struct regmap_field *field, unsigned int id, unsigned int mask, unsigned int val, bool *change, bool async, bool force); -static inline int regmap_field_write(struct regmap_field *field, - unsigned int val) -{ - return regmap_field_update_bits_base(field, ~0, val, - NULL, false, false); -} - -static inline int regmap_field_force_write(struct regmap_field *field, - unsigned int val) -{ - return regmap_field_update_bits_base(field, ~0, val, NULL, false, true); -} - static inline int regmap_field_update_bits(struct regmap_field *field, unsigned int mask, unsigned int val) { -- 2.34.1