From patchwork Wed Oct 24 02:36:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolin Chen X-Patchwork-Id: 10654083 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5E7AA13BF for ; Wed, 24 Oct 2018 02:59:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3F0B42A1C0 for ; Wed, 24 Oct 2018 02:59:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 331E12A1EF; Wed, 24 Oct 2018 02:59:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C95222A1C0 for ; Wed, 24 Oct 2018 02:59:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726111AbeJXLZZ (ORCPT ); Wed, 24 Oct 2018 07:25:25 -0400 Received: from mail-pg1-f194.google.com ([209.85.215.194]:46991 "EHLO mail-pg1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725979AbeJXLZZ (ORCPT ); Wed, 24 Oct 2018 07:25:25 -0400 Received: by mail-pg1-f194.google.com with SMTP id a5-v6so712990pgt.13; Tue, 23 Oct 2018 19:59:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ejb7TUjIq2sUg/ciurEdUX72ayrKyRTFAOORT5hlWw8=; b=WbpCg7eHUxUsoCj9OAAOsxwFDHIpecSwdTg0vB053v5hSR+RIIHbptf0qFxTKeLj+4 1BF2q26/31/hSDeTv3HHzmdzAa9F36ou/MXMb2GhXmR/oNO/iynR9YODhMb+EcejjQ21 PVklSp6TRQ7U3dwI3B3GtGCeuun4uZ162YBwGbyyP15x32Uh/PTnlf12MvjWh/VAWjHV mEVleqPO3RO5zkVVEvEFY/HPk+qzexwLDdFWpPdGLNo/ABIOSFV+8bWi1LmCwBzCDo4T rTieXtwkzH+UgJw0m9OD5jlNCwgMd2AWkrklV76anOHT0I8Fpb3KyuUcWWjcjaNOf2kL 2dvA== 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=ejb7TUjIq2sUg/ciurEdUX72ayrKyRTFAOORT5hlWw8=; b=tGDncyAiVmClIIq369E9Q808zQWL7g96BwV/QdsT5rvV9sTN1LzutdteaN9XfGrxfs UslUF9qPIwTE5wjogd0QXnLvyf4xhv6l8W+7urFY64tCJLt/ZRSfKBkGnl8MANm2VIys bb75aECIEMPXqfU0lUTw9wguUS92KP68GP0Sei5x1LZhLIfjV6hLFM3UVYW9fu6agjPR x9ucZgL8seu2h9J55KWfxMI77uq2vJndGKsgfBJWW1nRaMduFc2Yo+KzwA1142aK5hk0 TCSTHgYOrSPdrUR8YKOaKrDK3oraEEz+enYO/uAspv3BmomSdxaycJ8KQ+xy+ZMmFO7N HQ1Q== X-Gm-Message-State: AGRZ1gKH72U8/SszOlLemj0P009Q15RhONd70zRt/kdJ/TqTZinPIwQx 9zqbgJp1VvGun7o4MI3nOWc= X-Google-Smtp-Source: AJdET5fK+mDCC5NgVl+hcrOHCOsng+xXJiS1S6tKhSm9bXjKtLkRj5aIAhB7ogM/1+lmXU7jUCzBxQ== X-Received: by 2002:a63:64c:: with SMTP id 73mr762574pgg.373.1540348589988; Tue, 23 Oct 2018 19:36:29 -0700 (PDT) Received: from Asurada-Nvidia.nvidia.com (thunderhill.nvidia.com. [216.228.112.22]) by smtp.gmail.com with ESMTPSA id n17-v6sm3606625pfj.84.2018.10.23.19.36.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 23 Oct 2018 19:36:29 -0700 (PDT) From: Nicolin Chen To: jdelvare@suse.com, linux@roeck-us.net Cc: linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/5] hwmon: (core) Inherit power properties to hdev Date: Tue, 23 Oct 2018 19:36:19 -0700 Message-Id: <20181024023623.4231-2-nicoleotsuka@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181024023623.4231-1-nicoleotsuka@gmail.com> References: <20181024023623.4231-1-nicoleotsuka@gmail.com> Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The new hdev is a child device related to the original parent hwmon driver and its device. However, it doesn't support the power features, typically being defined in the parent driver. So this patch inherits three necessary power properties from the parent dev to hdev: power, pm_domain and driver pointers. Note that the dev->driver pointer is the place that contains a dev_pm_ops pointer defined in the parent device driver and the pm runtime core also checks this pointer: if (!cb && dev->driver && dev->driver->pm) Signed-off-by: Nicolin Chen --- Changelog v1->v2: * Added device pointer check drivers/hwmon/hwmon.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index 975c95169884..14cfab64649f 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c @@ -625,7 +625,12 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata, hwdev->name = name; hdev->class = &hwmon_class; hdev->parent = dev; - hdev->of_node = dev ? dev->of_node : NULL; + if (dev) { + hdev->driver = dev->driver; + hdev->power = dev->power; + hdev->pm_domain = dev->pm_domain; + hdev->of_node = dev->of_node; + } hwdev->chip = chip; dev_set_drvdata(hdev, drvdata); dev_set_name(hdev, HWMON_ID_FORMAT, id); From patchwork Wed Oct 24 02:36:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolin Chen X-Patchwork-Id: 10654099 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 19A0613B5 for ; Wed, 24 Oct 2018 03:08:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EFC052A2D9 for ; Wed, 24 Oct 2018 03:08:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E10782A2E3; Wed, 24 Oct 2018 03:08:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8E6172A2D9 for ; Wed, 24 Oct 2018 03:08:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725896AbeJXLeT (ORCPT ); Wed, 24 Oct 2018 07:34:19 -0400 Received: from mail-pg1-f195.google.com ([209.85.215.195]:36042 "EHLO mail-pg1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725826AbeJXLeT (ORCPT ); Wed, 24 Oct 2018 07:34:19 -0400 Received: by mail-pg1-f195.google.com with SMTP id l6-v6so1625578pgp.3; Tue, 23 Oct 2018 20:08:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nsuYjcR1EiPlDCJ6JViUW3dlgy89BBd7N5H87xE87CE=; b=ubkKuQU2ptxlXeSTDT848h8n7RDmXT9J0x8RR9wqe7y571qSuE/IrY6xfBi1ybOTGt syDTlQNrvioVDWgJvJbUFFvUhn/4iYxyB+X07ZVK5rFdlv4Dpnu95nSQUXOzJIDSe+h8 zyy4EsSJzhYPX+veKAOnQ+UmQaxAzAXTVF84pk1tP5VBri9zORekoj5SKQtYf0GQpvcI eEEDcjVTVSdj3iaEgEKhuwB1P/E4CJrWEjTew89zxZa70R/gsPoP+l330fuIuOXAx2+j R84QnEMG/Ko50qNOPIEWRaSiO2E/NKe6AZSbHMrziZpA+rBfYGBgqc6nxVEwOUhgmE6q 4aVw== 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=nsuYjcR1EiPlDCJ6JViUW3dlgy89BBd7N5H87xE87CE=; b=S0u2SZOzgnrAvXb1fReMptKeaKAvH9bEbMNHoM9+mjnfjWVf8GCrOz9xVLA371C+sy uU/As1UvwpU8BwNcm+hTGxyBc1DRN5xSkd+763uyfpPkYoucDMK2UcETd5/aRYcpRozT iqSMOPPOQg/5okamZzGtAcwUuBwLBp5hnGr/2a6SHIpHJVKXoHpE7bDath09vPmX0QmC o6hdIuaundhQmZ/T8tjtGKz/LoU3cGetcrnvG8BykY0S3ql6/D+Mp4XN/f28J4exxs/V hRpni2W0vTErvq2al0+xNeiWNRygS8vYziA/upXqdyXxN4MSY9sOhlTkrkmvxHGlDSRZ L7sw== X-Gm-Message-State: AGRZ1gJhRZxZFSkYeePw4NC2V2i7li/4Y0cZqGwl5gaBLA/ybaK/G9Io pMuTQauj0LNdPT2Jv6Pf9g/c5opf X-Google-Smtp-Source: AJdET5cc0i8uCrPezrM5rd+Nk5MIEcEXua+GqjevguZVp7wx+xPrnyGvuIm7JgiMv+2A8Cl0djEUnQ== X-Received: by 2002:a65:4981:: with SMTP id r1-v6mr771496pgs.153.1540348590701; Tue, 23 Oct 2018 19:36:30 -0700 (PDT) Received: from Asurada-Nvidia.nvidia.com (thunderhill.nvidia.com. [216.228.112.22]) by smtp.gmail.com with ESMTPSA id n17-v6sm3606625pfj.84.2018.10.23.19.36.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 23 Oct 2018 19:36:30 -0700 (PDT) From: Nicolin Chen To: jdelvare@suse.com, linux@roeck-us.net Cc: linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/5] hwmon: (ina3221) Check channel status for alarms attribute read Date: Tue, 23 Oct 2018 19:36:20 -0700 Message-Id: <20181024023623.4231-3-nicoleotsuka@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181024023623.4231-1-nicoleotsuka@gmail.com> References: <20181024023623.4231-1-nicoleotsuka@gmail.com> Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP There is nothing critically wrong to read these two attributes without having a is_enabled() check at this point. But reading the MASK_ENABLE register would clear the CVRF bit according to the datasheet. So it'd be safer to fence for disabled channels in order to add pm runtime feature. Signed-off-by: Nicolin Chen --- Changelog v1->v2: * Returned 0 for alert flags instead of -ENODATA drivers/hwmon/ina3221.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/hwmon/ina3221.c b/drivers/hwmon/ina3221.c index d61688f04594..26cdf3342d80 100644 --- a/drivers/hwmon/ina3221.c +++ b/drivers/hwmon/ina3221.c @@ -200,6 +200,12 @@ static int ina3221_read_curr(struct device *dev, u32 attr, return 0; case hwmon_curr_crit_alarm: case hwmon_curr_max_alarm: + /* No actual register read if channel is disabled */ + if (!ina3221_is_enabled(ina, channel)) { + /* Return 0 for alert flags */ + *val = 0; + return 0; + } ret = regmap_field_read(ina->fields[reg], ®val); if (ret) return ret; From patchwork Wed Oct 24 02:36:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolin Chen X-Patchwork-Id: 10654095 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C6B2413A4 for ; Wed, 24 Oct 2018 03:05:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A93C52A209 for ; Wed, 24 Oct 2018 03:05:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9DB272A2E0; Wed, 24 Oct 2018 03:05:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 27BC02A209 for ; Wed, 24 Oct 2018 03:05:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725952AbeJXLbo (ORCPT ); Wed, 24 Oct 2018 07:31:44 -0400 Received: from mail-pg1-f195.google.com ([209.85.215.195]:42640 "EHLO mail-pg1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725826AbeJXLbo (ORCPT ); Wed, 24 Oct 2018 07:31:44 -0400 Received: by mail-pg1-f195.google.com with SMTP id i4-v6so1608313pgq.9; Tue, 23 Oct 2018 20:05:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=a5VCWP1jvBGTVRlOXHM630rkywHqtK6S6KhPyPHlEck=; b=UM4L/fsNfl52iBUTqQrnNlYc0SvU96IYRp2htFW/JEC8hNwBNC9Q4SUWP8/xPvDJxo hycsB/sDK2YcksE4CezBcK8RImrYzrT9S3wg67V6jOpn03dYxf2ped5CJ361iYN1qcv6 2J+t9+bnVtMT5xq4hTyd9tGVzDfozkmCb9X7PJg8lvu/Uh5hXzVFYft3NCXJbnm3Tg97 EQWRZinHuSPI9CVpHkBgxSss8yYYK8WrPEmWNElNnQM93D8JsI4iTRtFmC9rCAc7kAb2 VvQhKoKTaHLOsArkwj0XBbcMhMCHJXtEcXzmIoqNljlV3B5vT3O0ClfKtq+UNtPmyMdA DZCw== 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=a5VCWP1jvBGTVRlOXHM630rkywHqtK6S6KhPyPHlEck=; b=a+/Kk89I8HLTBiG7M1J3oqwitoA1qEV3SKzxkEt8GDyNtoirUxsGBf/3PPNI9KF/PB VvTvK9c7zFhlA3uVxdz/u94cNG5lX/6OL9pOR9az/ImThvCnH6fHrUT9+YAvDC+pzvGa Rz6fp8/jpxuH/Rv6bntm5ijkeEd8XE00RaNdr2/elkvdQgRZFcPk4WRMWj0cFK2Ov3RT 6UTI7eGIUlcFx9IqB1Id2iv7qU87gN51KKGLxgLamgTRAZmCgUYQaPwjKDFzvErxx5UC OPpHTgU6sCy5gg4QhenTWT8Lmfdnp1teTbSs91pK62Lyz/NrtZvRLP7MglXrTW1+2iZp TySw== X-Gm-Message-State: AGRZ1gJurYzt25qOsFVx8vKqjtiJbNWmr6z69H+IqrJrAQ5Bfb8UEpxt 4BWuGXuoCFKb4JdKafsMaelyItgT X-Google-Smtp-Source: AJdET5fv217Bs7DKw59s4YDhDn46i1Imb1FTHLoPNX9xObMsI2s7ozEZ3mH85tjqMfool4WCWZrt0g== X-Received: by 2002:a63:1f58:: with SMTP id q24-v6mr781948pgm.88.1540348591440; Tue, 23 Oct 2018 19:36:31 -0700 (PDT) Received: from Asurada-Nvidia.nvidia.com (thunderhill.nvidia.com. [216.228.112.22]) by smtp.gmail.com with ESMTPSA id n17-v6sm3606625pfj.84.2018.10.23.19.36.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 23 Oct 2018 19:36:30 -0700 (PDT) From: Nicolin Chen To: jdelvare@suse.com, linux@roeck-us.net Cc: linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/5] hwmon: (ina3221) Serialize sysfs ABI accesses Date: Tue, 23 Oct 2018 19:36:21 -0700 Message-Id: <20181024023623.4231-4-nicoleotsuka@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181024023623.4231-1-nicoleotsuka@gmail.com> References: <20181024023623.4231-1-nicoleotsuka@gmail.com> Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This change adds a mutex to serialize accesses of sysfs attributes. This is required when polling CVRF bit of the MASK/ENABLE register because this bit is cleared on a read of this MASK/ENABLE register or a write to CONFIG register, which means that this bit might be accidentally cleared by reading other fields like alert flags. So this patch adds a mutex lock to protect the write() and read() callbacks. The read_string() callback won't need the lock since it just returns the label without touching any hardware register. Signed-off-by: Nicolin Chen --- drivers/hwmon/ina3221.c | 51 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/drivers/hwmon/ina3221.c b/drivers/hwmon/ina3221.c index 26cdf3342d80..10e8347a3c80 100644 --- a/drivers/hwmon/ina3221.c +++ b/drivers/hwmon/ina3221.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -94,12 +95,14 @@ struct ina3221_input { * @regmap: Register map of the device * @fields: Register fields of the device * @inputs: Array of channel input source specific structures + * @lock: mutex lock to serialize sysfs attribute accesses * @reg_config: Register value of INA3221_CONFIG */ struct ina3221_data { struct regmap *regmap; struct regmap_field *fields[F_MAX_FIELDS]; struct ina3221_input inputs[INA3221_NUM_CHANNELS]; + struct mutex lock; u32 reg_config; }; @@ -265,29 +268,53 @@ static int ina3221_write_enable(struct device *dev, int channel, bool enable) static int ina3221_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long *val) { + struct ina3221_data *ina = dev_get_drvdata(dev); + int ret; + + mutex_lock(&ina->lock); + switch (type) { case hwmon_in: /* 0-align channel ID */ - return ina3221_read_in(dev, attr, channel - 1, val); + ret = ina3221_read_in(dev, attr, channel - 1, val); + break; case hwmon_curr: - return ina3221_read_curr(dev, attr, channel, val); + ret = ina3221_read_curr(dev, attr, channel, val); + break; default: - return -EOPNOTSUPP; + ret = -EOPNOTSUPP; + break; } + + mutex_unlock(&ina->lock); + + return ret; } static int ina3221_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long val) { + struct ina3221_data *ina = dev_get_drvdata(dev); + int ret; + + mutex_lock(&ina->lock); + switch (type) { case hwmon_in: /* 0-align channel ID */ - return ina3221_write_enable(dev, channel - 1, val); + ret = ina3221_write_enable(dev, channel - 1, val); + break; case hwmon_curr: - return ina3221_write_curr(dev, attr, channel, val); + ret = ina3221_write_curr(dev, attr, channel, val); + break; default: - return -EOPNOTSUPP; + ret = -EOPNOTSUPP; + break; } + + mutex_unlock(&ina->lock); + + return ret; } static int ina3221_read_string(struct device *dev, enum hwmon_sensor_types type, @@ -582,6 +609,7 @@ static int ina3221_probe(struct i2c_client *client, if (ret) return ret; + mutex_init(&ina->lock); dev_set_drvdata(dev, ina); hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, ina, @@ -589,12 +617,22 @@ static int ina3221_probe(struct i2c_client *client, ina3221_groups); if (IS_ERR(hwmon_dev)) { dev_err(dev, "Unable to register hwmon device\n"); + mutex_destroy(&ina->lock); return PTR_ERR(hwmon_dev); } return 0; } +static int ina3221_remove(struct i2c_client *client) +{ + struct ina3221_data *ina = dev_get_drvdata(&client->dev); + + mutex_destroy(&ina->lock); + + return 0; +} + static int __maybe_unused ina3221_suspend(struct device *dev) { struct ina3221_data *ina = dev_get_drvdata(dev); @@ -663,6 +701,7 @@ MODULE_DEVICE_TABLE(i2c, ina3221_ids); static struct i2c_driver ina3221_i2c_driver = { .probe = ina3221_probe, + .remove = ina3221_remove, .driver = { .name = INA3221_DRIVER_NAME, .of_match_table = ina3221_of_match_table, From patchwork Wed Oct 24 02:36:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolin Chen X-Patchwork-Id: 10654043 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0645F13A4 for ; Wed, 24 Oct 2018 02:44:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DD3C62A1B8 for ; Wed, 24 Oct 2018 02:44:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D15C92A1F6; Wed, 24 Oct 2018 02:44:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 61A032A1B8 for ; Wed, 24 Oct 2018 02:44:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726543AbeJXLKn (ORCPT ); Wed, 24 Oct 2018 07:10:43 -0400 Received: from mail-pf1-f195.google.com ([209.85.210.195]:46540 "EHLO mail-pf1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725826AbeJXLKn (ORCPT ); Wed, 24 Oct 2018 07:10:43 -0400 Received: by mail-pf1-f195.google.com with SMTP id r64-v6so1641056pfb.13; Tue, 23 Oct 2018 19:44:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=3Z70I5UUHxwSFhYj51uL4iC1Yky3MsOgzPMgaF7+w4g=; b=gd1QktYI4tSMO7b4/Sa4QEmyvgmgmT7CGGcrEMLkX9QmgTXauLQvTafZCQKibRDKkT vPG2NQJPlSXSVGrbiDaYuh+Y2Q61V4++VbE0DKnGjy+Cqu5QvELXfIzXM12P53D4IXeQ wJdSeAe4bUD1ATrC9LX2JTHRd/UuntCD3xOzwcAtLFtlKtAubEf86D1HgkDw+v4Em51A HQqeuxExXHDvcocM5CTsRODmz6quI+XhEfV5bzuKmTf6sjQmroIfsMmkcwEhSN8k6XKJ YqJOwZll8NlzTSgDR+IWvi4EQkdAmPU1w5IMl7wHbPl107luLczM4BgpdY0GWLYlJYgY aUcg== 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=3Z70I5UUHxwSFhYj51uL4iC1Yky3MsOgzPMgaF7+w4g=; b=qbTpU0GG5RHPyPoKAATC6NtyAOTKqind7Hhrb4nuAUsWzzS/jocrwo8O7JHKu5fTa7 DUbwBjtUzzvkhKjLmRiwvSb0pqKjk7+07fHa/Xaz2PYN5Eb471v4r32ZPS2cIn7rCqSa sOFXY4mVS6hi/Qh3VgMCiggTCcF0UWMBqlB3sfL4h0WC5ChW8OfLMAEQ1x4yWI4BPy/h 7++/wt32k/RkjO42a7cK2lpuvLM8rvn5LpkeF/hj+YTTwkXnP7OLYo1cJGeIhLdcJRln MTHfY/bE2IV3EL/WhKKtXy8GcMfCvZhG3JeCj0BbzaEWq426mC0wYc0OE/UGcTZ6cUzC yZ1Q== X-Gm-Message-State: AGRZ1gI+AmYK6F867f+423prosRAJ7rX47WEtFERczXLsdjKQmxKG295 M/fXO9I5cAafMDurKs+hmr0= X-Google-Smtp-Source: AJdET5f61svgfK4xDBFQfvnqk3YpIA5JLWOv6rPcJQxRtQWfV+ZdwIRSmFBw6ylkJMZXI5wj5s0LxA== X-Received: by 2002:a63:aa48:: with SMTP id x8-v6mr764163pgo.87.1540348592184; Tue, 23 Oct 2018 19:36:32 -0700 (PDT) Received: from Asurada-Nvidia.nvidia.com (thunderhill.nvidia.com. [216.228.112.22]) by smtp.gmail.com with ESMTPSA id n17-v6sm3606625pfj.84.2018.10.23.19.36.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 23 Oct 2018 19:36:31 -0700 (PDT) From: Nicolin Chen To: jdelvare@suse.com, linux@roeck-us.net Cc: linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 4/5] hwmon: (ina3221) Make sure data is ready before reading Date: Tue, 23 Oct 2018 19:36:22 -0700 Message-Id: <20181024023623.4231-5-nicoleotsuka@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181024023623.4231-1-nicoleotsuka@gmail.com> References: <20181024023623.4231-1-nicoleotsuka@gmail.com> Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The data might need some time to get ready after channel enabling, although the data register is always readable. The CVRF bit is to indicate that data conversion is finished, so polling the CVRF bit before data reading could ensure the result being valid. An alternative way could be to wait for expected time between the channel enabling and the data reading. And this could avoid extra I2C communications. However, INA3221 seemly takes longer time than what's stated in the datasheet. Test results show that sometimes it couldn't finish data conversion in time. So this patch plays safe by adding a CVRF polling to make sure the data register is updated with the new data. Signed-off-by: Nicolin Chen --- * Moved CVRF polling to data read routine * Added calculation of wait time based on conversion time setting drivers/hwmon/ina3221.c | 46 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/hwmon/ina3221.c b/drivers/hwmon/ina3221.c index 10e8347a3c80..9bbac826e50b 100644 --- a/drivers/hwmon/ina3221.c +++ b/drivers/hwmon/ina3221.c @@ -44,6 +44,13 @@ #define INA3221_CONFIG_MODE_SHUNT BIT(0) #define INA3221_CONFIG_MODE_BUS BIT(1) #define INA3221_CONFIG_MODE_CONTINUOUS BIT(2) +#define INA3221_CONFIG_VSH_CT_SHIFT 3 +#define INA3221_CONFIG_VSH_CT_MASK GENMASK(5, 3) +#define INA3221_CONFIG_VSH_CT(x) (((x) & GENMASK(5, 3)) >> 3) +#define INA3221_CONFIG_VBUS_CT_SHIFT 6 +#define INA3221_CONFIG_VBUS_CT_MASK GENMASK(8, 6) +#define INA3221_CONFIG_VBUS_CT(x) (((x) & GENMASK(8, 6)) >> 6) +#define INA3221_CONFIG_CHs_EN_MASK GENMASK(14, 12) #define INA3221_CONFIG_CHx_EN(x) BIT(14 - (x)) #define INA3221_RSHUNT_DEFAULT 10000 @@ -52,6 +59,9 @@ enum ina3221_fields { /* Configuration */ F_RST, + /* Status Flags */ + F_CVRF, + /* Alert Flags */ F_WF3, F_WF2, F_WF1, F_CF3, F_CF2, F_CF1, @@ -63,6 +73,7 @@ enum ina3221_fields { static const struct reg_field ina3221_reg_fields[] = { [F_RST] = REG_FIELD(INA3221_CONFIG, 15, 15), + [F_CVRF] = REG_FIELD(INA3221_MASK_ENABLE, 0, 0), [F_WF3] = REG_FIELD(INA3221_MASK_ENABLE, 3, 3), [F_WF2] = REG_FIELD(INA3221_MASK_ENABLE, 4, 4), [F_WF1] = REG_FIELD(INA3221_MASK_ENABLE, 5, 5), @@ -111,6 +122,28 @@ static inline bool ina3221_is_enabled(struct ina3221_data *ina, int channel) return ina->reg_config & INA3221_CONFIG_CHx_EN(channel); } +/* Lookup table for Bus and Shunt conversion times in usec */ +static const u16 ina3221_conv_time[] = { + 140, 204, 332, 588, 1100, 2116, 4156, 8244, +}; + +static inline int ina3221_wait_for_data(struct ina3221_data *ina) +{ + u32 channels = hweight16(ina->reg_config & INA3221_CONFIG_CHs_EN_MASK); + u32 vbus_ct_idx = INA3221_CONFIG_VBUS_CT(ina->reg_config); + u32 vsh_ct_idx = INA3221_CONFIG_VSH_CT(ina->reg_config); + u32 vbus_ct = ina3221_conv_time[vbus_ct_idx]; + u32 vsh_ct = ina3221_conv_time[vsh_ct_idx]; + u32 wait, cvrf; + + /* Calculate total conversion time */ + wait = channels * (vbus_ct + vsh_ct); + + /* Polling the CVRF bit to make sure read data is ready */ + return regmap_field_read_poll_timeout(ina->fields[F_CVRF], + cvrf, cvrf, wait, 100000); +} + static int ina3221_read_value(struct ina3221_data *ina, unsigned int reg, int *val) { @@ -150,6 +183,12 @@ static int ina3221_read_in(struct device *dev, u32 attr, int channel, long *val) if (!ina3221_is_enabled(ina, channel)) return -ENODATA; + ret = ina3221_wait_for_data(ina); + if (ret) { + dev_err(dev, "Timed out at waiting for CVRF bit\n"); + return ret; + } + ret = ina3221_read_value(ina, reg, ®val); if (ret) return ret; @@ -189,6 +228,13 @@ static int ina3221_read_curr(struct device *dev, u32 attr, case hwmon_curr_input: if (!ina3221_is_enabled(ina, channel)) return -ENODATA; + + ret = ina3221_wait_for_data(ina); + if (ret) { + dev_err(dev, "Timed out at waiting for CVRF bit\n"); + return ret; + } + /* fall through */ case hwmon_curr_crit: case hwmon_curr_max: From patchwork Wed Oct 24 02:36:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolin Chen X-Patchwork-Id: 10654041 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 153E114BD for ; Wed, 24 Oct 2018 02:44:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EC10F2A11D for ; Wed, 24 Oct 2018 02:44:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E02FD2A1F6; Wed, 24 Oct 2018 02:44:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D40BF2A11D for ; Wed, 24 Oct 2018 02:44:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726531AbeJXLKK (ORCPT ); Wed, 24 Oct 2018 07:10:10 -0400 Received: from mail-pf1-f194.google.com ([209.85.210.194]:45679 "EHLO mail-pf1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725826AbeJXLKJ (ORCPT ); Wed, 24 Oct 2018 07:10:09 -0400 Received: by mail-pf1-f194.google.com with SMTP id t10-v6so226456pfh.12; Tue, 23 Oct 2018 19:44:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=VSzfM2FPlRnOHYGBoEIGzU0Q6kBNbN42UAqLDYc6lSA=; b=dDayVFagjgbQUke+GEzMJG6/HXr+ka4l6cnlAMfW1cUMKenNULMTMeQ6TtEOD/xHLX GsUYmiEK/21YlowUMqVwOv4NiXBF2ivJJSW4M14moIVOabXJVVe/tAOTbKtDaUb1WQED mYgskJPHZHHO20mDEoTBXww9IBs4/7fdbJYa8oAGZfNrEbGb2PI5OuT/R4cTq43W7HXR vjUyg5A5uDUUOznD5bzrTuwwEOQJnAqhDZ5xiZfXzWI9Yevk8klQdvJK7lkgmgIH9Wbc Z4QksNeNxFjp20ZzxmcHwVObSqBky5qpw+wKbCENgJ+yjJYI+rHkk6PzEOlTD5LJ58yU p1kw== 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=VSzfM2FPlRnOHYGBoEIGzU0Q6kBNbN42UAqLDYc6lSA=; b=HeJOG137MHwGTxQVqVCXW/xAi7EysxMGUn7bO8fPHJerE2SXDzHgJsE29DciFoLpqR vhnwkA8TE6wqfl9UiA4l57aAaXvagOFW1b8vqU6Kl0K9X24OpcdumJbXMF7ocPMSDEvR goOETjchbo4COfHwARAPC6b2R9fbwLRWlPIflaszpb9suf+qA1i0HqeiXarCeSzFJNqG Nz8gLoBWi5mPI1cgsBU6PJXIc/3XkoTtC6XVbTgtIpaDtaEIXaUOWUw0aunJWQJ8+aQf fvNtPmMpLH+QnRXzQSkDiwTU9NxajrzyphdNbwobM+okxxlQpkRZGQufzbb9TJ2vNriI rJNA== X-Gm-Message-State: AGRZ1gKAN+EdmYybA00N0cQjN6HoUFQRucaZ+BWnjdoRi5e9WQVgkT0B Vsdz/01xLl2dzET0p8Xzmh4= X-Google-Smtp-Source: AJdET5fOXb6y4rEhGCqZbF8u1imK/QBim9KLtWqd5mUR75Ea0su0yy5N2HqlxsTZpJBnaQxscjZVSg== X-Received: by 2002:a63:4343:: with SMTP id q64-v6mr816389pga.276.1540348593285; Tue, 23 Oct 2018 19:36:33 -0700 (PDT) Received: from Asurada-Nvidia.nvidia.com (thunderhill.nvidia.com. [216.228.112.22]) by smtp.gmail.com with ESMTPSA id n17-v6sm3606625pfj.84.2018.10.23.19.36.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 23 Oct 2018 19:36:32 -0700 (PDT) From: Nicolin Chen To: jdelvare@suse.com, linux@roeck-us.net Cc: linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 5/5] hwmon: (ina3221) Add PM runtime support Date: Tue, 23 Oct 2018 19:36:23 -0700 Message-Id: <20181024023623.4231-6-nicoleotsuka@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181024023623.4231-1-nicoleotsuka@gmail.com> References: <20181024023623.4231-1-nicoleotsuka@gmail.com> Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP If all three channels are disabled via in[123]_enable ABI, the driver could suspend the chip for power saving purpose. So this patch addsd the PM runtime support in order to gain more power control than system suspend and resume use case. For PM runtime, there are a few related changes happening: 1) Added a new explicit hdev device pointer for all the pm runtime callbacks. This is because hwmon core registers a child device for each hwmon driver. So there might be a mismatch between two device pointers in the driver if mixing using them. 2) Added a check in ina3221_is_enabled() to make sure that the chip is resumed. 3) Bypassed the unchanged status in ina3221_write_enable() in order to keep the pm runtime refcount being matched. 4) Removed the reset routine in the probe() by calling the resume() via pm_runtime_get_sync(), as they're similar. It's also necessary to do so to match initial refcount with the number of enabled channels. 5) Bypassed the system suspend/resume callbacks from the i2c_client->dev, because both the i2c_client->dev and the ina->hdev coexist and share the same pair of system suspend/resume callback functions, which means there'd be two suspend() calls during the system suspend while the second one will fail. Signed-off-by: Nicolin Chen --- Changelog v1->v2: * Bypassed i2c_client->dev in suspend/resume() * Added a missing '\n' in one dev_err() drivers/hwmon/ina3221.c | 112 ++++++++++++++++++++++++++++++++-------- 1 file changed, 90 insertions(+), 22 deletions(-) diff --git a/drivers/hwmon/ina3221.c b/drivers/hwmon/ina3221.c index 9bbac826e50b..2cdc37ab0cf3 100644 --- a/drivers/hwmon/ina3221.c +++ b/drivers/hwmon/ina3221.c @@ -21,6 +21,7 @@ #include #include #include +#include #define INA3221_DRIVER_NAME "ina3221" @@ -53,6 +54,7 @@ #define INA3221_CONFIG_CHs_EN_MASK GENMASK(14, 12) #define INA3221_CONFIG_CHx_EN(x) BIT(14 - (x)) +#define INA3221_CONFIG_DEFAULT 0x7127 #define INA3221_RSHUNT_DEFAULT 10000 enum ina3221_fields { @@ -103,6 +105,7 @@ struct ina3221_input { /** * struct ina3221_data - device specific information + * @hdev: Device pointer of hwmon child device, used for pm runtime * @regmap: Register map of the device * @fields: Register fields of the device * @inputs: Array of channel input source specific structures @@ -110,6 +113,7 @@ struct ina3221_input { * @reg_config: Register value of INA3221_CONFIG */ struct ina3221_data { + struct device *hdev; struct regmap *regmap; struct regmap_field *fields[F_MAX_FIELDS]; struct ina3221_input inputs[INA3221_NUM_CHANNELS]; @@ -119,7 +123,8 @@ struct ina3221_data { static inline bool ina3221_is_enabled(struct ina3221_data *ina, int channel) { - return ina->reg_config & INA3221_CONFIG_CHx_EN(channel); + return pm_runtime_active(ina->hdev) && + (ina->reg_config & INA3221_CONFIG_CHx_EN(channel)); } /* Lookup table for Bus and Shunt conversion times in usec */ @@ -294,21 +299,48 @@ static int ina3221_write_enable(struct device *dev, int channel, bool enable) { struct ina3221_data *ina = dev_get_drvdata(dev); u16 config, mask = INA3221_CONFIG_CHx_EN(channel); + u16 config_old = ina->reg_config & mask; int ret; config = enable ? mask : 0; + /* Bypass if enable status is not being changed */ + if (config_old == config) + return 0; + + /* For enabling routine, increase refcount and resume() at first */ + if (enable) { + ret = pm_runtime_get_sync(ina->hdev); + if (ret < 0) { + dev_err(dev, "Failed to get PM runtime\n"); + return ret; + } + } + /* Enable or disable the channel */ ret = regmap_update_bits(ina->regmap, INA3221_CONFIG, mask, config); if (ret) - return ret; + goto fail; /* Cache the latest config register value */ ret = regmap_read(ina->regmap, INA3221_CONFIG, &ina->reg_config); if (ret) - return ret; + goto fail; + + /* For disabling routine, decrease refcount or suspend() at last */ + if (!enable) + pm_runtime_put_sync(ina->hdev); return 0; + +fail: + if (enable) { + dev_err(dev, "Reverting channel%d enabling: %d\n", + channel, ret); + pm_runtime_put_sync(ina->hdev); + } + + return ret; } static int ina3221_read(struct device *dev, enum hwmon_sensor_types type, @@ -603,7 +635,6 @@ static int ina3221_probe(struct i2c_client *client, { struct device *dev = &client->dev; struct ina3221_data *ina; - struct device *hwmon_dev; int i, ret; ina = devm_kzalloc(dev, sizeof(*ina), GFP_KERNEL); @@ -635,44 +666,71 @@ static int ina3221_probe(struct i2c_client *client, return ret; } - ret = regmap_field_write(ina->fields[F_RST], true); - if (ret) { - dev_err(dev, "Unable to reset device\n"); - return ret; - } - - /* Sync config register after reset */ - ret = regmap_read(ina->regmap, INA3221_CONFIG, &ina->reg_config); - if (ret) - return ret; + /* The driver will be reset, so use reset value */ + ina->reg_config = INA3221_CONFIG_DEFAULT; /* Disable channels if their inputs are disconnected */ for (i = 0; i < INA3221_NUM_CHANNELS; i++) { if (ina->inputs[i].disconnected) ina->reg_config &= ~INA3221_CONFIG_CHx_EN(i); } - ret = regmap_write(ina->regmap, INA3221_CONFIG, ina->reg_config); - if (ret) - return ret; mutex_init(&ina->lock); dev_set_drvdata(dev, ina); - hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, ina, + /* Fence sysfs nodes till pm_runtime is resumed */ + mutex_lock(&ina->lock); + + /* Use the returned hdev for pm_runtime */ + ina->hdev = devm_hwmon_device_register_with_info(dev, client->name, ina, &ina3221_chip_info, ina3221_groups); - if (IS_ERR(hwmon_dev)) { + if (IS_ERR(ina->hdev)) { dev_err(dev, "Unable to register hwmon device\n"); - mutex_destroy(&ina->lock); - return PTR_ERR(hwmon_dev); + ret = PTR_ERR(ina->hdev); + goto fail_lock; } + /* Enable PM runtime -- status is suspended by default */ + pm_runtime_enable(ina->hdev); + + /* Initialize (resume) the device */ + for (i = 0; i < INA3221_NUM_CHANNELS; i++) { + if (ina->inputs[i].disconnected) + continue; + /* Match the refcount with number of enabled channels */ + ret = pm_runtime_get_sync(ina->hdev); + if (ret < 0) + goto fail_pm; + } + + mutex_unlock(&ina->lock); + return 0; + +fail_pm: + pm_runtime_disable(ina->hdev); + pm_runtime_set_suspended(ina->hdev); + for (i = 0; i < INA3221_NUM_CHANNELS; i++) + pm_runtime_put_noidle(ina->hdev); +fail_lock: + mutex_unlock(&ina->lock); + mutex_destroy(&ina->lock); + + return ret; } static int ina3221_remove(struct i2c_client *client) { struct ina3221_data *ina = dev_get_drvdata(&client->dev); + int i; + + pm_runtime_disable(ina->hdev); + pm_runtime_set_suspended(ina->hdev); + + /* Decrease the PM refcount */ + for (i = 0; i < INA3221_NUM_CHANNELS; i++) + pm_runtime_put_noidle(ina->hdev); mutex_destroy(&ina->lock); @@ -684,6 +742,10 @@ static int __maybe_unused ina3221_suspend(struct device *dev) struct ina3221_data *ina = dev_get_drvdata(dev); int ret; + /* Let hdev control all PM runtime callbacks */ + if (dev != ina->hdev) + return 0; + /* Save config register value and enable cache-only */ ret = regmap_read(ina->regmap, INA3221_CONFIG, &ina->reg_config); if (ret) @@ -707,6 +769,10 @@ static int __maybe_unused ina3221_resume(struct device *dev) struct ina3221_data *ina = dev_get_drvdata(dev); int ret; + /* Let hdev control all PM runtime callbacks */ + if (dev != ina->hdev) + return 0; + regcache_cache_only(ina->regmap, false); /* Software reset the chip */ @@ -730,7 +796,9 @@ static int __maybe_unused ina3221_resume(struct device *dev) } static const struct dev_pm_ops ina3221_pm = { - SET_SYSTEM_SLEEP_PM_OPS(ina3221_suspend, ina3221_resume) + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) + SET_RUNTIME_PM_OPS(ina3221_suspend, ina3221_resume, NULL) }; static const struct of_device_id ina3221_of_match_table[] = {