media: ipu3-cio2: support multiple sensors and VCMs with same HID
authorBingbu Cao <bingbu.cao@intel.com>
Fri, 10 Mar 2023 15:19:10 +0000 (23:19 +0800)
committerHans Verkuil <hverkuil-cisco@xs4all.nl>
Tue, 11 Apr 2023 16:54:01 +0000 (18:54 +0200)
In current cio2-bridge, it is using the hid name to register software
node and software node will create kobject and sysfs entry according to
the node name, if there are multiple sensors and VCMs which are sharing
same HID name, it will cause the software nodes registration failure:

sysfs: cannot create duplicate filename '/kernel/software_nodes/dw9714'
...
Call Trace:
software_node_register_nodes
cio2_bridge_init
...
kobject_add_internal failed for dw9714 with -EEXIST,
don't try to register things with the same name in the same directory.

One solution is appending the sensor link(Mipi Port) in SSDB as suffix
of the node name to fix this problem.

Signed-off-by: Bingbu Cao <bingbu.cao@intel.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
drivers/media/pci/intel/ipu3/cio2-bridge.c
drivers/media/pci/intel/ipu3/cio2-bridge.h

index dfefe0d8aa959e432af958649bdaf33b07ba9ddc..45427a3a3a252a81d30cdbc2f05c162e79de299f 100644 (file)
@@ -212,6 +212,7 @@ static void cio2_bridge_create_connection_swnodes(struct cio2_bridge *bridge,
                                                  struct cio2_sensor *sensor)
 {
        struct software_node *nodes = sensor->swnodes;
+       char vcm_name[ACPI_ID_LEN + 4];
 
        cio2_bridge_init_swnode_names(sensor);
 
@@ -229,9 +230,13 @@ static void cio2_bridge_create_connection_swnodes(struct cio2_bridge *bridge,
                                                sensor->node_names.endpoint,
                                                &nodes[SWNODE_CIO2_PORT],
                                                sensor->cio2_properties);
-       if (sensor->ssdb.vcmtype)
-               nodes[SWNODE_VCM] =
-                       NODE_VCM(cio2_vcm_types[sensor->ssdb.vcmtype - 1]);
+       if (sensor->ssdb.vcmtype) {
+               /* append ssdb.link to distinguish VCM nodes with same HID */
+               snprintf(vcm_name, sizeof(vcm_name), "%s-%u",
+                        cio2_vcm_types[sensor->ssdb.vcmtype - 1],
+                        sensor->ssdb.link);
+               nodes[SWNODE_VCM] = NODE_VCM(vcm_name);
+       }
 
        cio2_bridge_init_swnode_group(sensor);
 }
@@ -295,7 +300,6 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
                }
 
                sensor = &bridge->sensors[bridge->n_sensors];
-               strscpy(sensor->name, cfg->hid, sizeof(sensor->name));
 
                ret = cio2_bridge_read_acpi_buffer(adev, "SSDB",
                                                   &sensor->ssdb,
@@ -303,6 +307,9 @@ static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
                if (ret)
                        goto err_put_adev;
 
+               snprintf(sensor->name, sizeof(sensor->name), "%s-%u",
+                        cfg->hid, sensor->ssdb.link);
+
                if (sensor->ssdb.vcmtype > ARRAY_SIZE(cio2_vcm_types)) {
                        dev_warn(&adev->dev, "Unknown VCM type %d\n",
                                 sensor->ssdb.vcmtype);
index b93b749c65bda33b27bb3e8a532baa7f9cfd6359..b76ed8a641e2017de3b506327746b10dc2501fca 100644 (file)
@@ -113,7 +113,8 @@ struct cio2_sensor_config {
 };
 
 struct cio2_sensor {
-       char name[ACPI_ID_LEN];
+       /* append ssdb.link(u8) in "-%u" format as suffix of HID */
+       char name[ACPI_ID_LEN + 4];
        struct acpi_device *adev;
        struct i2c_client *vcm_i2c_client;