提交 2e8c4ad1 编写于 作者: P Pierre-Louis Bossart 提交者: Vinod Koul

soundwire: ignore uniqueID when irrelevant

The uniqueID is useful when there are two or more devices of the same
type (identical manufacturer ID, part ID) on the same link.

When there is a single device of a given type on a link, its uniqueID
is irrelevant. It's not uncommon on actual platforms to see variations
of the uniqueID, or differences between devID registers and ACPI _ADR
fields.

This patch suggests a filter on startup to identify 'single' devices
and tag them accordingly. The uniqueID is then not used for the probe,
and the device name omits the uniqueID as well.
Signed-off-by: NPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20191022234808.17432-4-pierre-louis.bossart@linux.intel.comSigned-off-by: NVinod Koul <vkoul@kernel.org>
上级 de5b174b
...@@ -422,10 +422,11 @@ static struct sdw_slave *sdw_get_slave(struct sdw_bus *bus, int i) ...@@ -422,10 +422,11 @@ static struct sdw_slave *sdw_get_slave(struct sdw_bus *bus, int i)
static int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id) static int sdw_compare_devid(struct sdw_slave *slave, struct sdw_slave_id id)
{ {
if (slave->id.unique_id != id.unique_id || if (slave->id.mfg_id != id.mfg_id ||
slave->id.mfg_id != id.mfg_id ||
slave->id.part_id != id.part_id || slave->id.part_id != id.part_id ||
slave->id.class_id != id.class_id) slave->id.class_id != id.class_id ||
(slave->id.unique_id != SDW_IGNORED_UNIQUE_ID &&
slave->id.unique_id != id.unique_id))
return -ENODEV; return -ENODEV;
return 0; return 0;
......
...@@ -29,10 +29,17 @@ static int sdw_slave_add(struct sdw_bus *bus, ...@@ -29,10 +29,17 @@ static int sdw_slave_add(struct sdw_bus *bus,
slave->dev.parent = bus->dev; slave->dev.parent = bus->dev;
slave->dev.fwnode = fwnode; slave->dev.fwnode = fwnode;
/* name shall be sdw:link:mfg:part:class:unique */ if (id->unique_id == SDW_IGNORED_UNIQUE_ID) {
dev_set_name(&slave->dev, "sdw:%x:%x:%x:%x:%x", /* name shall be sdw:link:mfg:part:class */
bus->link_id, id->mfg_id, id->part_id, dev_set_name(&slave->dev, "sdw:%x:%x:%x:%x",
id->class_id, id->unique_id); bus->link_id, id->mfg_id, id->part_id,
id->class_id);
} else {
/* name shall be sdw:link:mfg:part:class:unique */
dev_set_name(&slave->dev, "sdw:%x:%x:%x:%x:%x",
bus->link_id, id->mfg_id, id->part_id,
id->class_id, id->unique_id);
}
slave->dev.release = sdw_slave_release; slave->dev.release = sdw_slave_release;
slave->dev.bus = &sdw_bus_type; slave->dev.bus = &sdw_bus_type;
...@@ -103,6 +110,7 @@ static bool find_slave(struct sdw_bus *bus, ...@@ -103,6 +110,7 @@ static bool find_slave(struct sdw_bus *bus,
int sdw_acpi_find_slaves(struct sdw_bus *bus) int sdw_acpi_find_slaves(struct sdw_bus *bus)
{ {
struct acpi_device *adev, *parent; struct acpi_device *adev, *parent;
struct acpi_device *adev2, *parent2;
parent = ACPI_COMPANION(bus->dev); parent = ACPI_COMPANION(bus->dev);
if (!parent) { if (!parent) {
...@@ -112,10 +120,46 @@ int sdw_acpi_find_slaves(struct sdw_bus *bus) ...@@ -112,10 +120,46 @@ int sdw_acpi_find_slaves(struct sdw_bus *bus)
list_for_each_entry(adev, &parent->children, node) { list_for_each_entry(adev, &parent->children, node) {
struct sdw_slave_id id; struct sdw_slave_id id;
struct sdw_slave_id id2;
bool ignore_unique_id = true;
if (!find_slave(bus, adev, &id)) if (!find_slave(bus, adev, &id))
continue; continue;
/* brute-force O(N^2) search for duplicates */
parent2 = parent;
list_for_each_entry(adev2, &parent2->children, node) {
if (adev == adev2)
continue;
if (!find_slave(bus, adev2, &id2))
continue;
if (id.sdw_version != id2.sdw_version ||
id.mfg_id != id2.mfg_id ||
id.part_id != id2.part_id ||
id.class_id != id2.class_id)
continue;
if (id.unique_id != id2.unique_id) {
dev_dbg(bus->dev,
"Valid unique IDs %x %x for Slave mfg %x part %d\n",
id.unique_id, id2.unique_id,
id.mfg_id, id.part_id);
ignore_unique_id = false;
} else {
dev_err(bus->dev,
"Invalid unique IDs %x %x for Slave mfg %x part %d\n",
id.unique_id, id2.unique_id,
id.mfg_id, id.part_id);
return -ENODEV;
}
}
if (ignore_unique_id)
id.unique_id = SDW_IGNORED_UNIQUE_ID;
/* /*
* don't error check for sdw_slave_add as we want to continue * don't error check for sdw_slave_add as we want to continue
* adding Slaves * adding Slaves
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册