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

Commit af5fdf80 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
  at24: Use timeout also for read
  i2c: Fix userspace_device list corruption
  MAINTAINERS: Add missing i2c files
  i2c/tsl2550: Fix lux value in extended mode
parents 07a6d5a4 4d29196c
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -2562,8 +2562,7 @@ S: Maintained
F:	Documentation/i2c/
F:	drivers/i2c/
F:	include/linux/i2c.h
F:	include/linux/i2c-dev.h
F:	include/linux/i2c-id.h
F:	include/linux/i2c-*.h

I2C-TINY-USB DRIVER
M:	Till Harbaum <till@harbaum.org>
+3 −0
Original line number Diff line number Diff line
@@ -257,6 +257,7 @@ static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,

static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
{
	struct tsl2550_data *data = i2c_get_clientdata(client);
	u8 ch0, ch1;
	int ret;

@@ -274,6 +275,8 @@ static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
	ret = tsl2550_calculate_lux(ch0, ch1);
	if (ret < 0)
		return ret;
	if (data->operating_mode == 1)
		ret *= 5;

	return sprintf(buf, "%d\n", ret);
}
+11 −0
Original line number Diff line number Diff line
@@ -762,6 +762,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
{
	int res = 0;
	struct i2c_adapter *found;
	struct i2c_client *client, *next;

	/* First make sure that this adapter was ever added */
	mutex_lock(&core_lock);
@@ -781,6 +782,16 @@ int i2c_del_adapter(struct i2c_adapter *adap)
	if (res)
		return res;

	/* Remove devices instantiated from sysfs */
	list_for_each_entry_safe(client, next, &userspace_devices, detected) {
		if (client->adapter == adap) {
			dev_dbg(&adap->dev, "Removing %s at 0x%x\n",
				client->name, client->addr);
			list_del(&client->detected);
			i2c_unregister_device(client);
		}
	}

	/* Detach any active clients. This can't fail, thus we do not
	   checking the returned value. */
	res = device_for_each_child(&adap->dev, NULL, __unregister_client);
+45 −31
Original line number Diff line number Diff line
@@ -158,6 +158,7 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
	struct i2c_msg msg[2];
	u8 msgbuf[2];
	struct i2c_client *client;
	unsigned long timeout, read_time;
	int status, i;

	memset(msg, 0, sizeof(msg));
@@ -183,22 +184,17 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
	if (count > io_limit)
		count = io_limit;

	/* Smaller eeproms can work given some SMBus extension calls */
	if (at24->use_smbus) {
		/* Smaller eeproms can work given some SMBus extension calls */
		if (count > I2C_SMBUS_BLOCK_MAX)
			count = I2C_SMBUS_BLOCK_MAX;
		status = i2c_smbus_read_i2c_block_data(client, offset,
				count, buf);
		dev_dbg(&client->dev, "smbus read %zu@%d --> %d\n",
				count, offset, status);
		return (status < 0) ? -EIO : status;
	}

	} else {
		/*
	 * When we have a better choice than SMBus calls, use a combined
	 * I2C message. Write address; then read up to io_limit data bytes.
	 * Note that read page rollover helps us here (unlike writes).
	 * msgbuf is u8 and will cast to our needs.
		 * When we have a better choice than SMBus calls, use a
		 * combined I2C message. Write address; then read up to
		 * io_limit data bytes. Note that read page rollover helps us
		 * here (unlike writes). msgbuf is u8 and will cast to our
		 * needs.
		 */
		i = 0;
		if (at24->chip.flags & AT24_FLAG_ADDR16)
@@ -213,17 +209,35 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
		msg[1].flags = I2C_M_RD;
		msg[1].buf = buf;
		msg[1].len = count;
	}

	/*
	 * Reads fail if the previous write didn't complete yet. We may
	 * loop a few times until this one succeeds, waiting at least
	 * long enough for one entire page write to work.
	 */
	timeout = jiffies + msecs_to_jiffies(write_timeout);
	do {
		read_time = jiffies;
		if (at24->use_smbus) {
			status = i2c_smbus_read_i2c_block_data(client, offset,
					count, buf);
		} else {
			status = i2c_transfer(client->adapter, msg, 2);
	dev_dbg(&client->dev, "i2c read %zu@%d --> %d\n",
			count, offset, status);

			if (status == 2)
				status = count;
		}
		dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n",
				count, offset, status, jiffies);

		if (status == count)
			return count;
	else if (status >= 0)
		return -EIO;
	else
		return status;

		/* REVISIT: at HZ=100, this is sloooow */
		msleep(1);
	} while (time_before(read_time, timeout));

	return -ETIMEDOUT;
}

static ssize_t at24_read(struct at24_data *at24,