i2c: move OF helpers into the core
authorWolfram Sang <wsa@the-dreams.de>
Thu, 11 Jul 2013 11:56:15 +0000 (12:56 +0100)
committerMark Brown <broonie@kernel.org>
Sat, 21 Feb 2015 03:10:58 +0000 (12:10 +0900)
I2C of helpers used to live in of_i2c.c but experience (from SPI) shows
that it is much cleaner to have this in the core. This also removes a
circular dependency between the helpers and the core, and so we can
finally register child nodes in the core instead of doing this manually
in each driver. So, fix the drivers and documentation, too.

[Modified to keep a stub device registration API exposed to drivers in
order to avoid disruption]

Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
(cherry picked from commit 687b81d083c082bc1e853032e3a2a54f8c251d27)
Signed-off-by: Mark Brown <broonie@kernel.org>
Conflicts:
drivers/i2c/busses/i2c-designware-platdrv.c
drivers/i2c/busses/i2c-imx.c
drivers/i2c/busses/i2c-stu300.c
drivers/i2c/busses/i2c-wmt.c
drivers/of/Kconfig
drivers/of/Makefile
drivers/staging/imx-drm/imx-tve.c
sound/soc/fsl/imx-wm8962.c

drivers/i2c/i2c-core.c
drivers/i2c/i2c-mux.c
drivers/of/Kconfig
drivers/of/Makefile
drivers/of/of_i2c.c [deleted file]
include/linux/i2c.h
include/linux/of_i2c.h

index 48e31ed69dbf159f5e44f2ab2a4968896320c3eb..c00292aa52216fe36220889f0b15a9c6bbf6cb23 100644 (file)
    SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and
    Jean Delvare <khali@linux-fr.org>
    Mux support by Rodolfo Giometti <giometti@enneenne.com> and
-   Michael Lawnick <michael.lawnick.ext@nsn.com> */
+   Michael Lawnick <michael.lawnick.ext@nsn.com>
+   OF support is copyright (c) 2008 Jochen Friedrich <jochen@scram.de>
+   (based on a previous patch from Jon Smirl <jonsmirl@gmail.com>) and
+   (c) 2013  Wolfram Sang <wsa@the-dreams.de>
+ */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -35,7 +39,9 @@
 #include <linux/init.h>
 #include <linux/idr.h>
 #include <linux/mutex.h>
+#include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 #include <linux/completion.h>
 #include <linux/hardirq.h>
 #include <linux/irqflags.h>
@@ -954,6 +960,104 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
        up_read(&__i2c_board_lock);
 }
 
+/* OF support code */
+
+#if IS_ENABLED(CONFIG_OF)
+static void internal_of_i2c_register_devices(struct i2c_adapter *adap)
+{
+       void *result;
+       struct device_node *node;
+
+       /* Only register child devices if the adapter has a node pointer set */
+       if (!adap->dev.of_node)
+               return;
+
+       dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
+
+       for_each_available_child_of_node(adap->dev.of_node, node) {
+               struct i2c_board_info info = {};
+               struct dev_archdata dev_ad = {};
+               const __be32 *addr;
+               int len;
+
+               dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
+
+               if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
+                       dev_err(&adap->dev, "of_i2c: modalias failure on %s\n",
+                               node->full_name);
+                       continue;
+               }
+
+               addr = of_get_property(node, "reg", &len);
+               if (!addr || (len < sizeof(int))) {
+                       dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
+                               node->full_name);
+                       continue;
+               }
+
+               info.addr = be32_to_cpup(addr);
+               if (info.addr > (1 << 10) - 1) {
+                       dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
+                               info.addr, node->full_name);
+                       continue;
+               }
+
+               info.irq = irq_of_parse_and_map(node, 0);
+               info.of_node = of_node_get(node);
+               info.archdata = &dev_ad;
+
+               if (of_get_property(node, "wakeup-source", NULL))
+                       info.flags |= I2C_CLIENT_WAKE;
+
+               request_module("%s%s", I2C_MODULE_PREFIX, info.type);
+
+               result = i2c_new_device(adap, &info);
+               if (result == NULL) {
+                       dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
+                               node->full_name);
+                       of_node_put(node);
+                       irq_dispose_mapping(info.irq);
+                       continue;
+               }
+       }
+}
+
+static int of_dev_node_match(struct device *dev, void *data)
+{
+       return dev->of_node == data;
+}
+
+/* must call put_device() when done with returned i2c_client device */
+struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
+{
+       struct device *dev;
+
+       dev = bus_find_device(&i2c_bus_type, NULL, node,
+                                        of_dev_node_match);
+       if (!dev)
+               return NULL;
+
+       return i2c_verify_client(dev);
+}
+EXPORT_SYMBOL(of_find_i2c_device_by_node);
+
+/* must call put_device() when done with returned i2c_adapter device */
+struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
+{
+       struct device *dev;
+
+       dev = bus_find_device(&i2c_bus_type, NULL, node,
+                                        of_dev_node_match);
+       if (!dev)
+               return NULL;
+
+       return i2c_verify_adapter(dev);
+}
+EXPORT_SYMBOL(of_find_i2c_adapter_by_node);
+#else
+static void internal_of_i2c_register_devices(struct i2c_adapter *adap) { }
+#endif /* CONFIG_OF */
+
 static int i2c_do_add_adapter(struct i2c_driver *driver,
                              struct i2c_adapter *adap)
 {
@@ -1058,6 +1162,8 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
 
 exit_recovery:
        /* create pre-declared device nodes */
+       internal_of_i2c_register_devices(adap);
+
        if (adap->nr < __i2c_first_dynamic_bus_num)
                i2c_scan_static_board_info(adap);
 
@@ -1282,7 +1388,6 @@ void i2c_del_adapter(struct i2c_adapter *adap)
 }
 EXPORT_SYMBOL(i2c_del_adapter);
 
-
 /* ------------------------------------------------------------------------- */
 
 int i2c_for_each_dev(void *data, int (*fn)(struct device *, void *))
index 7409ebb33c47df7166087f937d0d5eb91d9d70c9..797e3117bef7437ef2d6f734431a16e43acaed34 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/i2c.h>
 #include <linux/i2c-mux.h>
 #include <linux/of.h>
-#include <linux/of_i2c.h>
 
 /* multiplexer per channel data */
 struct i2c_mux_priv {
@@ -185,8 +184,6 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
        dev_info(&parent->dev, "Added multiplexed i2c bus %d\n",
                 i2c_adapter_id(&priv->adap));
 
-       of_i2c_register_devices(&priv->adap);
-
        return &priv->adap;
 }
 EXPORT_SYMBOL_GPL(i2c_add_mux_adapter);
index 841a16443b593777c8c7680ed246f23269952ac1..df876e1c38646c4d896b257b1538ed9243cf3e8b 100644 (file)
@@ -43,12 +43,6 @@ config OF_IRQ
 config OF_DEVICE
        def_bool y
 
-config OF_I2C
-       def_tristate I2C
-       depends on I2C
-       help
-         OpenFirmware I2C accessors
-
 config OF_NET
        depends on NETDEVICES
        def_bool y
index 14cb50372b3b4504a4b25ce6f7dd70e87bb2a427..f5162cce7faf75d5ccf7311b5fab874d388cd8b9 100644 (file)
@@ -5,7 +5,6 @@ obj-$(CONFIG_OF_PROMTREE) += pdt.o
 obj-$(CONFIG_OF_ADDRESS)  += address.o
 obj-$(CONFIG_OF_IRQ)    += irq.o
 obj-$(CONFIG_OF_DEVICE) += device.o platform.o
-obj-$(CONFIG_OF_I2C)   += of_i2c.o
 obj-$(CONFIG_OF_NET)   += of_net.o
 obj-$(CONFIG_OF_SELFTEST) += selftest.o
 obj-$(CONFIG_OF_MDIO)  += of_mdio.o
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
deleted file mode 100644 (file)
index b667264..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * OF helpers for the I2C API
- *
- * Copyright (c) 2008 Jochen Friedrich <jochen@scram.de>
- *
- * Based on a previous patch from Jon Smirl <jonsmirl@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/i2c.h>
-#include <linux/irq.h>
-#include <linux/of.h>
-#include <linux/of_i2c.h>
-#include <linux/of_irq.h>
-#include <linux/module.h>
-
-void of_i2c_register_devices(struct i2c_adapter *adap)
-{
-       void *result;
-       struct device_node *node;
-
-       /* Only register child devices if the adapter has a node pointer set */
-       if (!adap->dev.of_node)
-               return;
-
-       dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
-
-       for_each_available_child_of_node(adap->dev.of_node, node) {
-               struct i2c_board_info info = {};
-               struct dev_archdata dev_ad = {};
-               const __be32 *addr;
-               int len;
-
-               dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
-
-               if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
-                       dev_err(&adap->dev, "of_i2c: modalias failure on %s\n",
-                               node->full_name);
-                       continue;
-               }
-
-               addr = of_get_property(node, "reg", &len);
-               if (!addr || (len < sizeof(int))) {
-                       dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
-                               node->full_name);
-                       continue;
-               }
-
-               info.addr = be32_to_cpup(addr);
-               if (info.addr > (1 << 10) - 1) {
-                       dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
-                               info.addr, node->full_name);
-                       continue;
-               }
-
-               info.irq = irq_of_parse_and_map(node, 0);
-               info.of_node = of_node_get(node);
-               info.archdata = &dev_ad;
-
-               if (of_get_property(node, "wakeup-source", NULL))
-                       info.flags |= I2C_CLIENT_WAKE;
-
-               request_module("%s%s", I2C_MODULE_PREFIX, info.type);
-
-               result = i2c_new_device(adap, &info);
-               if (result == NULL) {
-                       dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
-                               node->full_name);
-                       of_node_put(node);
-                       irq_dispose_mapping(info.irq);
-                       continue;
-               }
-       }
-}
-EXPORT_SYMBOL(of_i2c_register_devices);
-
-static int of_dev_node_match(struct device *dev, void *data)
-{
-        return dev->of_node == data;
-}
-
-/* must call put_device() when done with returned i2c_client device */
-struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
-{
-       struct device *dev;
-
-       dev = bus_find_device(&i2c_bus_type, NULL, node,
-                                        of_dev_node_match);
-       if (!dev)
-               return NULL;
-
-       return i2c_verify_client(dev);
-}
-EXPORT_SYMBOL(of_find_i2c_device_by_node);
-
-/* must call put_device() when done with returned i2c_adapter device */
-struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
-{
-       struct device *dev;
-
-       dev = bus_find_device(&i2c_bus_type, NULL, node,
-                                        of_dev_node_match);
-       if (!dev)
-               return NULL;
-
-       return i2c_verify_adapter(dev);
-}
-EXPORT_SYMBOL(of_find_i2c_adapter_by_node);
-
-MODULE_LICENSE("GPL");
index e988fa935b3c4ad22e5a6e47e8f4ccea0f0e1c3d..21891898ced0a9f3d90013aa44a9a30ae01d6311 100644 (file)
@@ -542,6 +542,26 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap)
 
 #endif /* I2C */
 
+#if IS_ENABLED(CONFIG_OF)
+/* must call put_device() when done with returned i2c_client device */
+extern struct i2c_client *of_find_i2c_device_by_node(struct device_node *node);
+
+/* must call put_device() when done with returned i2c_adapter device */
+extern struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node);
+
+#else
+
+static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
+{
+       return NULL;
+}
+
+static inline struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
+{
+       return NULL;
+}
+#endif /* CONFIG_OF */
+
 #if IS_ENABLED(CONFIG_ACPI_I2C)
 extern void acpi_i2c_register_devices(struct i2c_adapter *adap);
 #else
index cfb545cd86b5a1baaf6c39b7ba91f2d90c129c43..686786c87c73c220d19e4f79d801028f1994b6a1 100644 (file)
 #ifndef __LINUX_OF_I2C_H
 #define __LINUX_OF_I2C_H
 
-#if defined(CONFIG_OF_I2C) || defined(CONFIG_OF_I2C_MODULE)
 #include <linux/i2c.h>
 
-extern void of_i2c_register_devices(struct i2c_adapter *adap);
-
-/* must call put_device() when done with returned i2c_client device */
-extern struct i2c_client *of_find_i2c_device_by_node(struct device_node *node);
-
-/* must call put_device() when done with returned i2c_adapter device */
-extern struct i2c_adapter *of_find_i2c_adapter_by_node(
-                                               struct device_node *node);
-
-#else
-static inline void of_i2c_register_devices(struct i2c_adapter *adap)
-{
-       return;
-}
-
-static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
-{
-       return NULL;
-}
-
-/* must call put_device() when done with returned i2c_adapter device */
-static inline struct i2c_adapter *of_find_i2c_adapter_by_node(
-                                               struct device_node *node)
-{
-       return NULL;
-}
-#endif /* CONFIG_OF_I2C */
+static inline void of_i2c_register_devices(struct i2c_adapter *adap) { };
 
 #endif /* __LINUX_OF_I2C_H */