* Fix driver auto-probing related issues

* Stop using the deprecated i2c_new_device() function
 * Replace zero-length array with flexible-array member
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEKmCqpbOU668PNA69Ze02AX4ItwAFAl6AX4QACgkQZe02AX4I
 twCodw/9F+m/IPY7dFTIjQeJvFW/fbERMmtPBDeSW9x9Pu6ikOxz4kEieswXi8jR
 gWPscKoZLDd9cQe0iMC4EZV8TEOk6pQt+J2PLxniIvw4WUngjRwrMHjgSz0QCKp0
 jge03ltjlxqsZ0TY+IrgYFXC+LaGhjvZ8LT9vLLk1z4BvVasuT5JOPk2QC4kPKrn
 0oymnf/ROR9QWAYDP7GMET2buCJtGkDgZFxMBy1wDNOt4r5i8t4jq4ZtNfun7uA5
 5yHEEnh5smFV5/8/L+yAjwK64CYtQwgukpSjJnNfVSgoOWMtcK13BDQ5YNKhxW9O
 mPBAzwS/kfGU96k/v7xuaxbT50YrG7RHpi9tX2peUowV2wbaRIu1dZIVHYQPsmp0
 RMBoQCvK62jPJFJdCCiLS164C6JHM/3/wk2Z4OSDy27XEGiOSyiDpTI/KlmwdVNC
 R6am3TnCwwVB1bXsrn9kMVxThQeuKJJEQp1xCbR9A+HmGO2W24L5GpoxWIdfkuc/
 SrvQt2fOzqMzY02/PqQXrqdJlyqfHA/ARe/QEz8a6YU2kf+uGl/ebmH9vJm04yV3
 JdpAGa0+EfVmS4/WyblUHPRq/jnTAB9opBRnNi6pHJBuWr6SeZaGdVhk5TTM3yck
 eJipGlzYAWB6N7/tHYYMV6qg1ta526i0xrYpvxJ+ECJXU0uez/U=
 =79Ge
 -----END PGP SIGNATURE-----

Merge tag 'i3c/for-5.7' of git://git.kernel.org/pub/scm/linux/kernel/git/i3c/linux

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
This commit is contained in:
Linus Torvalds 2020-03-30 11:03:19 -07:00
commit c03cb66464
6 changed files with 75 additions and 33 deletions

View File

@ -213,40 +213,34 @@ 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)
continue;
if (manuf != id->manuf_id || part != id->part_id)
continue;
if ((id->match_flags & I3C_MATCH_EXTRA_INFO) &&
ext_info != id->extra_info)
continue;
return id;
}
}
/* 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;
id->dcr != devinfo.dcr)
continue;
if ((id->match_flags & I3C_MATCH_MANUF) &&
id->manuf_id != manuf)
continue;
if ((id->match_flags & I3C_MATCH_PART) &&
(rndpid || id->part_id != part))
continue;
if ((id->match_flags & I3C_MATCH_EXTRA_INFO) &&
(rndpid || id->extra_info != ext_info))
continue;
return id;
}
return NULL;

View File

@ -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;
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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);

View File

@ -919,6 +919,24 @@ static int do_i2c_entry(const char *filename, void *symval,
return 1;
}
static int do_i3c_entry(const char *filename, void *symval,
char *alias)
{
DEF_FIELD(symval, i3c_device_id, match_flags);
DEF_FIELD(symval, i3c_device_id, dcr);
DEF_FIELD(symval, i3c_device_id, manuf_id);
DEF_FIELD(symval, i3c_device_id, part_id);
DEF_FIELD(symval, i3c_device_id, extra_info);
strcpy(alias, "i3c:");
ADD(alias, "dcr", match_flags & I3C_MATCH_DCR, dcr);
ADD(alias, "manuf", match_flags & I3C_MATCH_MANUF, manuf_id);
ADD(alias, "part", match_flags & I3C_MATCH_PART, part_id);
ADD(alias, "ext", match_flags & I3C_MATCH_EXTRA_INFO, extra_info);
return 1;
}
/* Looks like: spi:S */
static int do_spi_entry(const char *filename, void *symval,
char *alias)
@ -1386,6 +1404,7 @@ static const struct devtable devtable[] = {
{"vmbus", SIZE_hv_vmbus_device_id, do_vmbus_entry},
{"rpmsg", SIZE_rpmsg_device_id, do_rpmsg_entry},
{"i2c", SIZE_i2c_device_id, do_i2c_entry},
{"i3c", SIZE_i3c_device_id, do_i3c_entry},
{"spi", SIZE_spi_device_id, do_spi_entry},
{"dmi", SIZE_dmi_system_id, do_dmi_entry},
{"platform", SIZE_platform_device_id, do_platform_entry},