From: Nicolin Chen <nicoleotsuka@gmail.com>
To: jdelvare@suse.com, linux@roeck-us.net
Cc: linux-hwmon@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v3 3/5] hwmon: (ina3221) Serialize sysfs ABI accesses
Date: Wed, 24 Oct 2018 12:34:00 -0700 [thread overview]
Message-ID: <20181024193402.16698-4-nicoleotsuka@gmail.com> (raw)
In-Reply-To: <20181024193402.16698-1-nicoleotsuka@gmail.com>
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 <nicoleotsuka@gmail.com>
---
Changlog
v1->v3:
* N/A
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 <linux/hwmon-sysfs.h>
#include <linux/i2c.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/regmap.h>
@@ -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,
--
2.17.1
next prev parent reply other threads:[~2018-10-25 4:03 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-24 19:33 [PATCH v3 0/5] hwmon: (ina3221) Implement PM runtime to save power Nicolin Chen
2018-10-24 19:33 ` [PATCH v3 1/5] hwmon: (core) Inherit power properties to hdev Nicolin Chen
2018-10-25 0:13 ` linux
2018-10-25 1:01 ` Nicolin Chen
2018-10-25 1:33 ` Nicolin Chen
2018-10-25 6:55 ` linux
2018-10-25 23:21 ` Nicolin Chen
2018-10-24 19:33 ` [PATCH v3 2/5] hwmon: (ina3221) Check channel status for alarms attribute read Nicolin Chen
2018-10-24 19:34 ` Nicolin Chen [this message]
2018-10-24 19:34 ` [PATCH v3 4/5] hwmon: (ina3221) Make sure data is ready before reading Nicolin Chen
2018-10-24 19:34 ` [PATCH v3 5/5] hwmon: (ina3221) Add PM runtime support Nicolin Chen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181024193402.16698-4-nicoleotsuka@gmail.com \
--to=nicoleotsuka@gmail.com \
--cc=jdelvare@suse.com \
--cc=linux-hwmon@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@roeck-us.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.