On 11/5/07, Scott Wood <[EMAIL PROTECTED]> wrote:
> >>> Or push these strings into the chip drivers and modify
> >>> i2c-core to also match on the device tree style names.
> >> That would be ideal; it just hasn't been done yet.
> >
> > This is not hard to do but the i2c people will have to agree. I need
> > to change the i2c_driver structure to include the additional names.
>
> I got a fair bit of resistance from them on the topic of multiple match
> names for i2c clients.

Here's a first pass at pushing the strings back into the i2c drivers.
If this looks reasonable it can be optimized a lot more.  A more
advanced version of this code would combine the alias, name, and
driver_name fields. The existing pairing of driver_name/name could be
merged into the concept of alias names for the driver.

Extend i2c-core to support lists of device tree compatible names when
matching drivers

From: Jon Smirl <[EMAIL PROTECTED]>


---

 drivers/i2c/busses/i2c-mpc.c |   35 ++++-------------------------------
 drivers/i2c/i2c-core.c       |   17 +++++++++++++++--
 drivers/rtc/rtc-pcf8563.c    |    1 +
 drivers/rtc/rtc-rs5c372.c    |    1 +
 include/linux/i2c.h          |   11 +++++++++--
 5 files changed, 30 insertions(+), 35 deletions(-)


diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 4ddebe4..6313631 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -312,34 +312,6 @@ static struct i2c_adapter mpc_ops = {
        .retries = 1
 };

-struct i2c_driver_device {
-       char    *of_device;
-       char    *i2c_driver;
-       char    *i2c_type;
-};
-
-static struct i2c_driver_device i2c_devices[] = {
-       {"ricoh,rs5c372a", "rtc-rs5c372", "rs5c372a",},
-       {"ricoh,rs5c372b", "rtc-rs5c372", "rs5c372b",},
-       {"ricoh,rv5c386",  "rtc-rs5c372", "rv5c386",},
-       {"ricoh,rv5c387a", "rtc-rs5c372", "rv5c387a",},
-       {"epson,pcf8564", "rtc-pcf8563", "pcf8564",},
-};
-
-static int of_find_i2c_driver(struct device_node *node, struct
i2c_board_info *info)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
-               if (!of_device_is_compatible(node, i2c_devices[i].of_device))
-                       continue;
-               strncpy(info->driver_name, i2c_devices[i].i2c_driver, 
KOBJ_NAME_LEN);
-               strncpy(info->type, i2c_devices[i].i2c_type, I2C_NAME_SIZE);
-               return 0;
-       }
-       return -ENODEV;
-}
-
 static void of_register_i2c_devices(struct i2c_adapter *adap, struct
device_node *adap_node)
 {
        struct device_node *node = NULL;
@@ -347,6 +319,7 @@ static void of_register_i2c_devices(struct
i2c_adapter *adap, struct device_node
        while ((node = of_get_next_child(adap_node, node))) {
                struct i2c_board_info info;
                const u32 *addr;
+               const char *compatible;
                int len;

                addr = of_get_property(node, "reg", &len);
@@ -359,9 +332,9 @@ static void of_register_i2c_devices(struct
i2c_adapter *adap, struct device_node
                if (info.irq == NO_IRQ)
                        info.irq = -1;

-               if (of_find_i2c_driver(node, &info) < 0)
-                       continue;
-
+               compatible = of_get_property(node, "compatible", &len);
+               strlcpy(info.driver_name, compatible, len);
+               info.type[0] = '\0';
                info.platform_data = NULL;
                info.addr = *addr;

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index d663e69..4128cd1 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -17,7 +17,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               */
 /* ------------------------------------------------------------------------- */

-/* With some changes from Kyösti Mälkki <[EMAIL PROTECTED]>.
+/* With some changes from Kyᅵsti Mᅵlkki <[EMAIL PROTECTED]>.
    All SMBus-related things are written by Frodo Looijaard <[EMAIL PROTECTED]>
    SMBus 2.0 support by Mark Studebaker <[EMAIL PROTECTED]> and
    Jean Delvare <[EMAIL PROTECTED]> */
@@ -51,6 +51,7 @@ static int i2c_device_match(struct device *dev,
struct device_driver *drv)
 {
        struct i2c_client       *client = to_i2c_client(dev);
        struct i2c_driver       *driver = to_i2c_driver(drv);
+       char **alias;

        /* make legacy i2c drivers bypass driver model probing entirely;
         * such drivers scan each i2c adapter/bus themselves.
@@ -61,7 +62,19 @@ static int i2c_device_match(struct device *dev,
struct device_driver *drv)
        /* new style drivers use the same kind of driver matching policy
         * as platform devices or SPI:  compare device and driver IDs.
         */
-       return strcmp(client->driver_name, drv->name) == 0;
+       if (strcmp(client->driver_name, drv->name) == 0)
+               return true;
+
+       /* Match against alias device tree names */
+       if (!driver->alias)
+               return 0;
+       alias = driver->alias;
+       while (*alias) {
+               if (strcmp(client->driver_name, *alias) == 0)
+                       return true;
+               alias++;
+       }
+       return 0;
 }

 #ifdef CONFIG_HOTPLUG
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index b778d35..7c8caf5 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -266,6 +266,7 @@ static struct i2c_driver pcf8563_driver = {
        .driver         = {
                .name   = "rtc-pcf8563",
        },
+       .alias  = (char *[]){"epson,pcf8564", 0},
        .id             = I2C_DRIVERID_PCF8563,
        .probe = &pcf8563_probe,
        .remove = &pcf8563_remove,
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 6b67b50..0f37d04 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -649,6 +649,7 @@ static struct i2c_driver rs5c372_driver = {
        .driver         = {
                .name   = "rtc-rs5c372",
        },
+       .alias  = (char
*[]){"ricoh,rs5c372a","ricoh,rs5c372b","ricoh,rv5c386","ricoh,rv5c387a",0},
        .probe          = rs5c372_probe,
        .remove         = rs5c372_remove,
 };
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 2a32f2f..d55748c 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -107,6 +107,13 @@ extern s32 i2c_smbus_write_i2c_block_data(struct
i2c_client * client,
 struct i2c_driver {
        int id;
        unsigned int class;
+       
+       /* Alias name for the driver. Used to support device trees on
+        * the PowerPC architecture. Device tree names take the form of
+        * vendor,chip. For example "epson,pcf8564". Alias is a list of
+        * strings terminated by a zero entry.
+        */
+       char **alias;

        /* Notifies the driver that a new bus has appeared. This routine
         * can be used by the driver to test if the bus meets its conditions
@@ -146,7 +153,7 @@ struct i2c_driver {
 };
 #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)

-#define I2C_NAME_SIZE  20
+#define I2C_NAME_SIZE  40

 /**
  * struct i2c_client - represent an I2C slave device
@@ -225,7 +232,7 @@ static inline void i2c_set_clientdata (struct
i2c_client *dev, void *data)
  * with the adapter already known.
  */
 struct i2c_board_info {
-       char            driver_name[KOBJ_NAME_LEN];
+       char            driver_name[I2C_NAME_SIZE];
        char            type[I2C_NAME_SIZE];
        unsigned short  flags;
        unsigned short  addr;


-- 
Jon Smirl
[EMAIL PROTECTED]
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to