Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 37ad04d7 authored by Guenter Roeck's avatar Guenter Roeck
Browse files

hwmon: (lm90) Simplify read functions



Return both error code and register value as return code from
read functions, and always check for errors.

This reduces code size on x86_64 by more than 1k while at
the same time improving error resiliency.

Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
parent 6e5f62b9
Loading
Loading
Loading
Loading
+193 −115
Original line number Diff line number Diff line
@@ -171,7 +171,6 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,

#define SA56004_REG_R_LOCAL_TEMPL 0x22

#define LM90_DEF_CONVRATE_RVAL	6	/* Def conversion rate register value */
#define LM90_MAX_CONVRATE_MS	16000	/* Maximum conversion rate in ms */

/* TMP451 registers */
@@ -410,7 +409,7 @@ static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value)
 * because we don't want the address pointer to change between the write
 * byte and the read byte transactions.
 */
static int lm90_read_reg(struct i2c_client *client, u8 reg, u8 *value)
static int lm90_read_reg(struct i2c_client *client, u8 reg)
{
	int err;

@@ -421,20 +420,12 @@ static int lm90_read_reg(struct i2c_client *client, u8 reg, u8 *value)
	} else
		err = i2c_smbus_read_byte_data(client, reg);

	if (err < 0) {
		dev_warn(&client->dev, "Register %#02x read failed (%d)\n",
			 reg, err);
	return err;
}
	*value = err;

	return 0;
}

static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value)
static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl)
{
	int err;
	u8 oldh, newh, l;
	int oldh, newh, l;

	/*
	 * There is a trick here. We have to read two registers to have the
@@ -449,18 +440,21 @@ static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value)
	 * we have to read the low byte again, and now we believe we have a
	 * correct reading.
	 */
	if ((err = lm90_read_reg(client, regh, &oldh))
	 || (err = lm90_read_reg(client, regl, &l))
	 || (err = lm90_read_reg(client, regh, &newh)))
		return err;
	oldh = lm90_read_reg(client, regh);
	if (oldh < 0)
		return oldh;
	l = lm90_read_reg(client, regl);
	if (l < 0)
		return l;
	newh = lm90_read_reg(client, regh);
	if (newh < 0)
		return newh;
	if (oldh != newh) {
		err = lm90_read_reg(client, regl, &l);
		if (err)
			return err;
		l = lm90_read_reg(client, regl);
		if (l < 0)
			return l;
	}
	*value = (newh << 8) | l;

	return 0;
	return (newh << 8) | l;
}

/*
@@ -471,20 +465,23 @@ static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value)
 * various registers have different meanings as a result of selecting a
 * non-default remote channel.
 */
static inline void lm90_select_remote_channel(struct i2c_client *client,
static inline int lm90_select_remote_channel(struct i2c_client *client,
					     struct lm90_data *data,
					     int channel)
{
	u8 config;
	int config;

	if (data->kind == max6696) {
		lm90_read_reg(client, LM90_REG_R_CONFIG1, &config);
		config = lm90_read_reg(client, LM90_REG_R_CONFIG1);
		if (config < 0)
			return config;
		config &= ~0x08;
		if (channel)
			config |= 0x08;
		i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
					  config);
	}
	return 0;
}

/*
@@ -516,104 +513,153 @@ static struct lm90_data *lm90_update_device(struct device *dev)
	struct lm90_data *data = dev_get_drvdata(dev);
	struct i2c_client *client = data->client;
	unsigned long next_update;
	int val = 0;

	mutex_lock(&data->update_lock);

	next_update = data->last_updated +
		      msecs_to_jiffies(data->update_interval);
	if (time_after(jiffies, next_update) || !data->valid) {
		u8 h, l;
		u8 alarms;

		dev_dbg(&client->dev, "Updating lm90 data.\n");
		lm90_read_reg(client, LM90_REG_R_LOCAL_LOW,
			      &data->temp8[LOCAL_LOW]);
		lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH,
			      &data->temp8[LOCAL_HIGH]);
		lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT,
			      &data->temp8[LOCAL_CRIT]);
		lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT,
			      &data->temp8[REMOTE_CRIT]);
		lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst);
		val = lm90_read_reg(client, LM90_REG_R_LOCAL_LOW);
		if (val < 0)
			goto error;
		data->temp8[LOCAL_LOW] = val;

		val = lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH);
		if (val < 0)
			goto error;
		data->temp8[LOCAL_HIGH] = val;

		val = lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT);
		if (val < 0)
			goto error;
		data->temp8[LOCAL_CRIT] = val;

		val = lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT);
		if (val < 0)
			goto error;
		data->temp8[REMOTE_CRIT] = val;
		val = lm90_read_reg(client, LM90_REG_R_TCRIT_HYST);
		if (val < 0)
			goto error;
		data->temp_hyst = val;

		if (data->reg_local_ext) {
			lm90_read16(client, LM90_REG_R_LOCAL_TEMP,
				    data->reg_local_ext,
				    &data->temp11[LOCAL_TEMP]);
			val = lm90_read16(client, LM90_REG_R_LOCAL_TEMP,
					  data->reg_local_ext);
			if (val < 0)
				goto error;
			data->temp11[LOCAL_TEMP] = val;
		} else {
			if (lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP,
					  &h) == 0)
				data->temp11[LOCAL_TEMP] = h << 8;
			val = lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP);
			if (val < 0)
				goto error;
			data->temp11[LOCAL_TEMP] = val << 8;
		}
		lm90_read16(client, LM90_REG_R_REMOTE_TEMPH,
			    LM90_REG_R_REMOTE_TEMPL,
			    &data->temp11[REMOTE_TEMP]);
		val = lm90_read16(client, LM90_REG_R_REMOTE_TEMPH,
				  LM90_REG_R_REMOTE_TEMPL);
		if (val < 0)
			goto error;
		data->temp11[REMOTE_TEMP] = val;

		if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h) == 0) {
			data->temp11[REMOTE_LOW] = h << 8;
			if ((data->flags & LM90_HAVE_REM_LIMIT_EXT)
			 && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL,
					  &l) == 0)
				data->temp11[REMOTE_LOW] |= l;
		lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH);
		if (val < 0)
			goto error;
		data->temp11[REMOTE_LOW] = val << 8;
		if (data->flags & LM90_HAVE_REM_LIMIT_EXT) {
			val = lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL);
			if (val < 0)
				goto error;
			data->temp11[REMOTE_LOW] |= val;
		}
		if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h) == 0) {
			data->temp11[REMOTE_HIGH] = h << 8;
			if ((data->flags & LM90_HAVE_REM_LIMIT_EXT)
			 && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL,
					  &l) == 0)
				data->temp11[REMOTE_HIGH] |= l;
		val = lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH);
		if (val < 0)
			goto error;
		data->temp11[REMOTE_HIGH] = val << 8;
		if (data->flags & LM90_HAVE_REM_LIMIT_EXT) {
			val = lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL);
			if (val < 0)
				goto error;
			data->temp11[REMOTE_HIGH] |= val;
		}

		if (data->flags & LM90_HAVE_OFFSET) {
			if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH,
					  &h) == 0
			 && lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL,
					  &l) == 0)
				data->temp11[REMOTE_OFFSET] = (h << 8) | l;
			val = lm90_read16(client, LM90_REG_R_REMOTE_OFFSH,
					  LM90_REG_R_REMOTE_OFFSL);
			if (val < 0)
				goto error;
			data->temp11[REMOTE_OFFSET] = val;
		}
		if (data->flags & LM90_HAVE_EMERGENCY) {
			lm90_read_reg(client, MAX6659_REG_R_LOCAL_EMERG,
				      &data->temp8[LOCAL_EMERG]);
			lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG,
				      &data->temp8[REMOTE_EMERG]);
			val = lm90_read_reg(client, MAX6659_REG_R_LOCAL_EMERG);
			if (val < 0)
				goto error;
			data->temp8[LOCAL_EMERG] = val;
			val = lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG);
			if (val < 0)
				goto error;
			data->temp8[REMOTE_EMERG] = val;
		}
		lm90_read_reg(client, LM90_REG_R_STATUS, &alarms);
		data->alarms = alarms;	/* save as 16 bit value */
		val = lm90_read_reg(client, LM90_REG_R_STATUS);
		if (val < 0)
			goto error;
		data->alarms = val;	/* lower 8 bit of alarms */

		if (data->kind == max6696) {
			lm90_select_remote_channel(client, data, 1);
			lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT,
				      &data->temp8[REMOTE2_CRIT]);
			lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG,
				      &data->temp8[REMOTE2_EMERG]);
			lm90_read16(client, LM90_REG_R_REMOTE_TEMPH,
				    LM90_REG_R_REMOTE_TEMPL,
				    &data->temp11[REMOTE2_TEMP]);
			if (!lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h))
				data->temp11[REMOTE2_LOW] = h << 8;
			if (!lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h))
				data->temp11[REMOTE2_HIGH] = h << 8;
			val = lm90_select_remote_channel(client, data, 1);
			if (val < 0)
				goto error;

			val = lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT);
			if (val < 0)
				goto error;
			data->temp8[REMOTE2_CRIT] = val;

			val = lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG);
			if (val < 0)
				goto error;
			data->temp8[REMOTE2_EMERG] = val;

			val = lm90_read16(client, LM90_REG_R_REMOTE_TEMPH,
					  LM90_REG_R_REMOTE_TEMPL);
			if (val < 0)
				goto error;
			data->temp11[REMOTE2_TEMP] = val;

			val = lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH);
			if (val < 0)
				goto error;
			data->temp11[REMOTE2_LOW] = val << 8;

			val = lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH);
			if (val < 0)
				goto error;
			data->temp11[REMOTE2_HIGH] = val << 8;

			lm90_select_remote_channel(client, data, 0);

			if (!lm90_read_reg(client, MAX6696_REG_R_STATUS2,
					   &alarms))
				data->alarms |= alarms << 8;
			val = lm90_read_reg(client, MAX6696_REG_R_STATUS2);
			if (val < 0)
				goto error;
			data->alarms |= val << 8;
		}

		/*
		 * Re-enable ALERT# output if it was originally enabled and
		 * relevant alarms are all clear
		 */
		if ((data->config_orig & 0x80) == 0
		 && (data->alarms & data->alert_alarms) == 0) {
			u8 config;
		if (!(data->config_orig & 0x80) &&
		    !(data->alarms & data->alert_alarms)) {
			val = lm90_read_reg(client, LM90_REG_R_CONFIG1);
			if (val < 0)
				goto error;

			lm90_read_reg(client, LM90_REG_R_CONFIG1, &config);
			if (config & 0x80) {
			if (val & 0x80) {
				dev_dbg(&client->dev, "Re-enabling ALERT#\n");
				i2c_smbus_write_byte_data(client,
							  LM90_REG_W_CONFIG1,
							  config & ~0x80);
							  val & ~0x80);
			}
		}

@@ -621,8 +667,12 @@ static struct lm90_data *lm90_update_device(struct device *dev)
		data->valid = 1;
	}

error:
	mutex_unlock(&data->update_lock);

	if (val < 0)
		return ERR_PTR(val);

	return data;
}

@@ -764,6 +814,9 @@ static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr,
	struct lm90_data *data = lm90_update_device(dev);
	int temp;

	if (IS_ERR(data))
		return PTR_ERR(data);

	if (data->kind == adt7461 || data->kind == tmp451)
		temp = temp_from_u8_adt7461(data, data->temp8[attr->index]);
	else if (data->kind == max6646)
@@ -830,6 +883,9 @@ static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr,
	struct lm90_data *data = lm90_update_device(dev);
	int temp;

	if (IS_ERR(data))
		return PTR_ERR(data);

	if (data->kind == adt7461 || data->kind == tmp451)
		temp = temp_from_u16_adt7461(data, data->temp11[attr->index]);
	else if (data->kind == max6646)
@@ -905,6 +961,9 @@ static ssize_t show_temphyst(struct device *dev,
	struct lm90_data *data = lm90_update_device(dev);
	int temp;

	if (IS_ERR(data))
		return PTR_ERR(data);

	if (data->kind == adt7461 || data->kind == tmp451)
		temp = temp_from_u8_adt7461(data, data->temp8[attr->index]);
	else if (data->kind == max6646)
@@ -951,6 +1010,10 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy,
			   char *buf)
{
	struct lm90_data *data = lm90_update_device(dev);

	if (IS_ERR(data))
		return PTR_ERR(data);

	return sprintf(buf, "%d\n", data->alarms);
}

@@ -961,6 +1024,9 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute
	struct lm90_data *data = lm90_update_device(dev);
	int bitnr = attr->index;

	if (IS_ERR(data))
		return PTR_ERR(data);

	return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1);
}

@@ -1414,24 +1480,22 @@ static void lm90_restore_conf(void *_data)
				  data->config_orig);
}

static void lm90_init_client(struct i2c_client *client, struct lm90_data *data)
static int lm90_init_client(struct i2c_client *client, struct lm90_data *data)
{
	u8 config, convrate;
	int config, convrate;

	if (lm90_read_reg(client, LM90_REG_R_CONVRATE, &convrate) < 0) {
		dev_warn(&client->dev, "Failed to read convrate register!\n");
		convrate = LM90_DEF_CONVRATE_RVAL;
	}
	convrate = lm90_read_reg(client, LM90_REG_R_CONVRATE);
	if (convrate < 0)
		return convrate;
	data->convrate_orig = convrate;

	/*
	 * Start the conversions.
	 */
	lm90_set_convrate(client, data, 500);	/* 500ms; 2Hz conversion rate */
	if (lm90_read_reg(client, LM90_REG_R_CONFIG1, &config) < 0) {
		dev_warn(&client->dev, "Initialization failed!\n");
		return;
	}
	config = lm90_read_reg(client, LM90_REG_R_CONFIG1);
	if (config < 0)
		return config;
	data->config_orig = config;

	/* Check Temperature Range Select */
@@ -1459,17 +1523,24 @@ static void lm90_init_client(struct i2c_client *client, struct lm90_data *data)
		i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config);

	devm_add_action(&client->dev, lm90_restore_conf, data);

	return 0;
}

static bool lm90_is_tripped(struct i2c_client *client, u16 *status)
{
	struct lm90_data *data = i2c_get_clientdata(client);
	u8 st, st2 = 0;
	int st, st2 = 0;

	lm90_read_reg(client, LM90_REG_R_STATUS, &st);
	st = lm90_read_reg(client, LM90_REG_R_STATUS);
	if (st < 0)
		return false;

	if (data->kind == max6696)
		lm90_read_reg(client, MAX6696_REG_R_STATUS2, &st2);
	if (data->kind == max6696) {
		st2 = lm90_read_reg(client, MAX6696_REG_R_STATUS2);
		if (st2 < 0)
			return false;
	}

	*status = st | (st2 << 8);

@@ -1571,7 +1642,11 @@ static int lm90_probe(struct i2c_client *client,
	data->max_convrate = lm90_params[data->kind].max_convrate;

	/* Initialize the LM90 chip */
	lm90_init_client(client, data);
	err = lm90_init_client(client, data);
	if (err < 0) {
		dev_err(dev, "Failed to initialize device\n");
		return err;
	}

	/* Register sysfs hooks */
	data->groups[groups++] = &lm90_group;
@@ -1627,12 +1702,15 @@ static void lm90_alert(struct i2c_client *client, unsigned int flag)
		 */
		struct lm90_data *data = i2c_get_clientdata(client);

		if ((data->flags & LM90_HAVE_BROKEN_ALERT)
		 && (alarms & data->alert_alarms)) {
			u8 config;
		if ((data->flags & LM90_HAVE_BROKEN_ALERT) &&
		    (alarms & data->alert_alarms)) {
			int config;

			dev_dbg(&client->dev, "Disabling ALERT#\n");
			lm90_read_reg(client, LM90_REG_R_CONFIG1, &config);
			i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
			config = lm90_read_reg(client, LM90_REG_R_CONFIG1);
			if (config >= 0)
				i2c_smbus_write_byte_data(client,
							  LM90_REG_W_CONFIG1,
							  config | 0x80);
		}
	} else {