Commit c359a80c authored by Alexandru Ardelean's avatar Alexandru Ardelean Committed by Jonathan Cameron

iio: temperature: tmp006: make sure the chip is powered up in probe

When the device is probed, there's no guarantee that the device is not in
power-down mode. This can happen if the driver is unregistered and
re-probed.

To make sure this doesn't happen, the value of the TMP006_CONFIG register
(which is read in the probe function and stored in the device's private
data) is being checked to see if the MOD bits have the correct value.

This is a fix for a somewhat-rare corner case. As it stands, this doesn't
look like a high priority to go into the Fixes route.
Signed-off-by: default avatarAlexandru Ardelean <aardelean@deviqon.com>
Link: https://lore.kernel.org/r/20210624081924.15897-2-aardelean@deviqon.comSigned-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 2bb3b8f6
...@@ -193,15 +193,23 @@ static bool tmp006_check_identification(struct i2c_client *client) ...@@ -193,15 +193,23 @@ static bool tmp006_check_identification(struct i2c_client *client)
return mid == TMP006_MANUFACTURER_MAGIC && did == TMP006_DEVICE_MAGIC; return mid == TMP006_MANUFACTURER_MAGIC && did == TMP006_DEVICE_MAGIC;
} }
static int tmp006_powerdown(struct tmp006_data *data) static int tmp006_power(struct device *dev, bool up)
{ {
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
struct tmp006_data *data = iio_priv(indio_dev);
if (up)
data->config |= TMP006_CONFIG_MOD_MASK;
else
data->config &= ~TMP006_CONFIG_MOD_MASK;
return i2c_smbus_write_word_swapped(data->client, TMP006_CONFIG, return i2c_smbus_write_word_swapped(data->client, TMP006_CONFIG,
data->config & ~TMP006_CONFIG_MOD_MASK); data->config);
} }
static void tmp006_powerdown_cleanup(void *data) static void tmp006_powerdown_cleanup(void *dev)
{ {
tmp006_powerdown(data); tmp006_power(dev, false);
} }
static int tmp006_probe(struct i2c_client *client, static int tmp006_probe(struct i2c_client *client,
...@@ -239,7 +247,14 @@ static int tmp006_probe(struct i2c_client *client, ...@@ -239,7 +247,14 @@ static int tmp006_probe(struct i2c_client *client,
return ret; return ret;
data->config = ret; data->config = ret;
ret = devm_add_action(&client->dev, tmp006_powerdown_cleanup, data); if ((ret & TMP006_CONFIG_MOD_MASK) != TMP006_CONFIG_MOD_MASK) {
ret = tmp006_power(&client->dev, true);
if (ret < 0)
return ret;
}
ret = devm_add_action_or_reset(&client->dev, tmp006_powerdown_cleanup,
&client->dev);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -249,16 +264,12 @@ static int tmp006_probe(struct i2c_client *client, ...@@ -249,16 +264,12 @@ static int tmp006_probe(struct i2c_client *client,
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static int tmp006_suspend(struct device *dev) static int tmp006_suspend(struct device *dev)
{ {
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); return tmp006_power(dev, false);
return tmp006_powerdown(iio_priv(indio_dev));
} }
static int tmp006_resume(struct device *dev) static int tmp006_resume(struct device *dev)
{ {
struct tmp006_data *data = iio_priv(i2c_get_clientdata( return tmp006_power(dev, true);
to_i2c_client(dev)));
return i2c_smbus_write_word_swapped(data->client, TMP006_CONFIG,
data->config | TMP006_CONFIG_MOD_MASK);
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment