Commit c03cb664 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull i3c updates from Boris Brezillon:

 - Fix driver auto-probing related issues

 - Stop using the deprecated i2c_new_device() function

 - Replace zero-length array with flexible-array member

* tag 'i3c/for-5.7' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux:
  i3c: convert to use i2c_new_client_device()
  i3c: master: Replace zero-length array with flexible-array member
  i3c: Simplify i3c_device_match_id()
  i3c: Generate aliases for i3c modules
  i3c: Add a modalias sysfs attribute
  i3c: Fix MODALIAS uevents
  i3c: master: no need to iterate master device twice
parents 0f751396 c4b9de11
Loading
Loading
Loading
Loading
+22 −28
Original line number Diff line number Diff line
@@ -213,39 +213,33 @@ i3c_device_match_id(struct i3c_device *i3cdev,
{
	struct i3c_device_info devinfo;
	const struct i3c_device_id *id;
	u16 manuf, part, ext_info;
	bool rndpid;

	i3c_device_get_info(i3cdev, &devinfo);

	/*
	 * The lower 32bits of the provisional ID is just filled with a random
	 * value, try to match using DCR info.
	 */
	if (!I3C_PID_RND_LOWER_32BITS(devinfo.pid)) {
		u16 manuf = I3C_PID_MANUF_ID(devinfo.pid);
		u16 part = I3C_PID_PART_ID(devinfo.pid);
		u16 ext_info = I3C_PID_EXTRA_INFO(devinfo.pid);
	manuf = I3C_PID_MANUF_ID(devinfo.pid);
	part = I3C_PID_PART_ID(devinfo.pid);
	ext_info = I3C_PID_EXTRA_INFO(devinfo.pid);
	rndpid = I3C_PID_RND_LOWER_32BITS(devinfo.pid);

		/* First try to match by manufacturer/part ID. */
	for (id = id_table; id->match_flags != 0; id++) {
			if ((id->match_flags & I3C_MATCH_MANUF_AND_PART) !=
			    I3C_MATCH_MANUF_AND_PART)
		if ((id->match_flags & I3C_MATCH_DCR) &&
		    id->dcr != devinfo.dcr)
			continue;

			if (manuf != id->manuf_id || part != id->part_id)
		if ((id->match_flags & I3C_MATCH_MANUF) &&
		    id->manuf_id != manuf)
			continue;

			if ((id->match_flags & I3C_MATCH_EXTRA_INFO) &&
			    ext_info != id->extra_info)
		if ((id->match_flags & I3C_MATCH_PART) &&
		    (rndpid || id->part_id != part))
			continue;

			return id;
		}
	}
		if ((id->match_flags & I3C_MATCH_EXTRA_INFO) &&
		    (rndpid || id->extra_info != ext_info))
			continue;

	/* Fallback to DCR match. */
	for (id = id_table; id->match_flags != 0; id++) {
		if ((id->match_flags & I3C_MATCH_DCR) &&
		    id->dcr == devinfo.dcr)
		return id;
	}

+25 −3
Original line number Diff line number Diff line
@@ -241,12 +241,34 @@ out:
}
static DEVICE_ATTR_RO(hdrcap);

static ssize_t modalias_show(struct device *dev,
			     struct device_attribute *da, char *buf)
{
	struct i3c_device *i3c = dev_to_i3cdev(dev);
	struct i3c_device_info devinfo;
	u16 manuf, part, ext;

	i3c_device_get_info(i3c, &devinfo);
	manuf = I3C_PID_MANUF_ID(devinfo.pid);
	part = I3C_PID_PART_ID(devinfo.pid);
	ext = I3C_PID_EXTRA_INFO(devinfo.pid);

	if (I3C_PID_RND_LOWER_32BITS(devinfo.pid))
		return sprintf(buf, "i3c:dcr%02Xmanuf%04X", devinfo.dcr,
			       manuf);

	return sprintf(buf, "i3c:dcr%02Xmanuf%04Xpart%04Xext%04X",
		       devinfo.dcr, manuf, part, ext);
}
static DEVICE_ATTR_RO(modalias);

static struct attribute *i3c_device_attrs[] = {
	&dev_attr_bcr.attr,
	&dev_attr_dcr.attr,
	&dev_attr_pid.attr,
	&dev_attr_dynamic_address.attr,
	&dev_attr_hdrcap.attr,
	&dev_attr_modalias.attr,
	NULL,
};
ATTRIBUTE_GROUPS(i3c_device);
@@ -267,7 +289,7 @@ static int i3c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
				      devinfo.dcr, manuf);

	return add_uevent_var(env,
			      "MODALIAS=i3c:dcr%02Xmanuf%04Xpart%04xext%04x",
			      "MODALIAS=i3c:dcr%02Xmanuf%04Xpart%04Xext%04X",
			      devinfo.dcr, manuf, part, ext);
}

@@ -1953,7 +1975,7 @@ of_i3c_master_add_i2c_boardinfo(struct i3c_master_controller *master,
	 * DEFSLVS command.
	 */
	if (boardinfo->base.flags & I2C_CLIENT_TEN) {
		dev_err(&master->dev, "I2C device with 10 bit address not supported.");
		dev_err(dev, "I2C device with 10 bit address not supported.");
		return -ENOTSUPP;
	}

@@ -2138,7 +2160,7 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master)
	 * correctly even if one or more i2c devices are not registered.
	 */
	i3c_bus_for_each_i2cdev(&master->bus, i2cdev)
		i2cdev->dev = i2c_new_device(adap, &i2cdev->boardinfo->base);
		i2cdev->dev = i2c_new_client_device(adap, &i2cdev->boardinfo->base);

	return 0;
}
+1 −1
Original line number Diff line number Diff line
@@ -221,7 +221,7 @@ struct dw_i3c_xfer {
	struct completion comp;
	int ret;
	unsigned int ncmds;
	struct dw_i3c_cmd cmds[0];
	struct dw_i3c_cmd cmds[];
};

struct dw_i3c_master {
+1 −1
Original line number Diff line number Diff line
@@ -388,7 +388,7 @@ struct cdns_i3c_xfer {
	struct completion comp;
	int ret;
	unsigned int ncmds;
	struct cdns_i3c_cmd cmds[0];
	struct cdns_i3c_cmd cmds[];
};

struct cdns_i3c_data {
+7 −0
Original line number Diff line number Diff line
@@ -145,6 +145,13 @@ int main(void)
	DEVID(i2c_device_id);
	DEVID_FIELD(i2c_device_id, name);

	DEVID(i3c_device_id);
	DEVID_FIELD(i3c_device_id, match_flags);
	DEVID_FIELD(i3c_device_id, dcr);
	DEVID_FIELD(i3c_device_id, manuf_id);
	DEVID_FIELD(i3c_device_id, part_id);
	DEVID_FIELD(i3c_device_id, extra_info);

	DEVID(spi_device_id);
	DEVID_FIELD(spi_device_id, name);

Loading