i2c: core: Allow empty id_table in ACPI case as well
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Mon, 17 Jul 2017 14:13:28 +0000 (17:13 +0300)
committerWolfram Sang <wsa@the-dreams.de>
Mon, 31 Jul 2017 13:50:33 +0000 (15:50 +0200)
For now empty ID table is not allowed with ACPI and prevents driver to
be probed.

Add a check to allow empty ID table.

This introduces a helper i2c_acpi_match_device().

Note, we rename some static function in i2c-core-acpi.c to distinguish
with public API.

Fixes: da10c06a044b ("i2c: Make I2C ID tables non-mandatory for DT'ed devices")
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: Rajmohan Mani <rajmohan.mani@intel.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
[wsa: needed to get some drivers probed again]
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
drivers/i2c/i2c-core-acpi.c
drivers/i2c/i2c-core-base.c
drivers/i2c/i2c-core.h

index 4842ec3a5451ed479446fc13352405aca45697d2..a9126b3cda61bc95f6a9d1282821ab7552484534 100644 (file)
@@ -230,6 +230,16 @@ void i2c_acpi_register_devices(struct i2c_adapter *adap)
                dev_warn(&adap->dev, "failed to enumerate I2C slaves\n");
 }
 
+const struct acpi_device_id *
+i2c_acpi_match_device(const struct acpi_device_id *matches,
+                     struct i2c_client *client)
+{
+       if (!(client && matches))
+               return NULL;
+
+       return acpi_match_device(matches, &client->dev);
+}
+
 static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level,
                                           void *data, void **return_value)
 {
@@ -289,7 +299,7 @@ u32 i2c_acpi_find_bus_speed(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(i2c_acpi_find_bus_speed);
 
-static int i2c_acpi_match_adapter(struct device *dev, void *data)
+static int i2c_acpi_find_match_adapter(struct device *dev, void *data)
 {
        struct i2c_adapter *adapter = i2c_verify_adapter(dev);
 
@@ -299,7 +309,7 @@ static int i2c_acpi_match_adapter(struct device *dev, void *data)
        return ACPI_HANDLE(dev) == (acpi_handle)data;
 }
 
-static int i2c_acpi_match_device(struct device *dev, void *data)
+static int i2c_acpi_find_match_device(struct device *dev, void *data)
 {
        return ACPI_COMPANION(dev) == data;
 }
@@ -309,7 +319,7 @@ static struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle)
        struct device *dev;
 
        dev = bus_find_device(&i2c_bus_type, NULL, handle,
-                             i2c_acpi_match_adapter);
+                             i2c_acpi_find_match_adapter);
        return dev ? i2c_verify_adapter(dev) : NULL;
 }
 
@@ -317,7 +327,8 @@ static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev)
 {
        struct device *dev;
 
-       dev = bus_find_device(&i2c_bus_type, NULL, adev, i2c_acpi_match_device);
+       dev = bus_find_device(&i2c_bus_type, NULL, adev,
+                             i2c_acpi_find_match_device);
        return dev ? i2c_verify_client(dev) : NULL;
 }
 
index c89dac7fd2e7b793217119f2ccee849cf75ebcfe..12822a4b8f8f09b5c080f7338a89e0ea00cbb4f2 100644 (file)
@@ -357,6 +357,7 @@ static int i2c_device_probe(struct device *dev)
         * Tree match table entry is supplied for the probing device.
         */
        if (!driver->id_table &&
+           !i2c_acpi_match_device(dev->driver->acpi_match_table, client) &&
            !i2c_of_match_device(dev->driver->of_match_table, client))
                return -ENODEV;
 
index 3b63f5e5b89cbda662a580c387bfa2d23e2ebcef..3d3d9bf02101bddf06fc6597f107cc3ac8e3beb8 100644 (file)
@@ -31,9 +31,18 @@ int i2c_check_addr_validity(unsigned addr, unsigned short flags);
 int i2c_check_7bit_addr_validity_strict(unsigned short addr);
 
 #ifdef CONFIG_ACPI
+const struct acpi_device_id *
+i2c_acpi_match_device(const struct acpi_device_id *matches,
+                     struct i2c_client *client);
 void i2c_acpi_register_devices(struct i2c_adapter *adap);
 #else /* CONFIG_ACPI */
 static inline void i2c_acpi_register_devices(struct i2c_adapter *adap) { }
+static inline const struct acpi_device_id *
+i2c_acpi_match_device(const struct acpi_device_id *matches,
+                     struct i2c_client *client)
+{
+       return NULL;
+}
 #endif /* CONFIG_ACPI */
 extern struct notifier_block i2c_acpi_notifier;