Merge tag 'dt-for-linus' of git://git.secretlab.ca/git/linux-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 21 Mar 2012 17:30:03 +0000 (10:30 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 21 Mar 2012 17:30:03 +0000 (10:30 -0700)
Pull core device tree changes for Linux v3.4 from Grant Likely:
 "This branch contains a minor documentation addition, a utility
  function for parsing string properties needed by some of the new ARM
  platforms, disables dynamic DT code that isn't used anywhere but on a
  few PPC machines, and exports DT node compatible data to userspace via
  UEVENT properties.  Nothing earth shattering here."

* tag 'dt-for-linus' of git://git.secretlab.ca/git/linux-2.6:
  of: Only compile OF_DYNAMIC on PowerPC pseries and iseries
  arm/dts: OMAP3: Add omap3evm and am335xevm support
  drivercore: Output common devicetree information in uevent
  of: Add of_property_match_string() to find index into a string list

16 files changed:
Documentation/devicetree/bindings/arm/omap/omap.txt
arch/arm/boot/dts/testcases/tests-phandle.dtsi
arch/powerpc/kernel/ibmebus.c
arch/powerpc/platforms/8xx/Kconfig
arch/powerpc/platforms/iseries/Kconfig
arch/powerpc/platforms/pseries/Kconfig
arch/powerpc/platforms/wsp/Kconfig
drivers/base/core.c
drivers/base/platform.c
drivers/macintosh/macio_asic.c
drivers/of/Kconfig
drivers/of/base.c
drivers/of/device.c
drivers/of/selftest.c
include/linux/of.h
include/linux/of_device.h

index edc618a8aab22da80037c2a8b406757d86171535..e78e8bccac302ee2fb4ea8f1dfbf6e8c8be94ca8 100644 (file)
@@ -41,3 +41,9 @@ Boards:
 
 - OMAP4 PandaBoard : Low cost community board
   compatible = "ti,omap4-panda", "ti,omap4430"
+
+- OMAP3 EVM : Software Developement Board for OMAP35x, AM/DM37x
+  compatible = "ti,omap3-evm", "ti,omap3"
+
+- AM335X EVM : Software Developement Board for AM335x
+  compatible = "ti,am335x-evm", "ti,am33xx", "ti,omap3"
index ec0c4e6212c998819bf113e31c2a93eb11ecd6a6..0007d3cd7dc25c5d674309079a24bd6e725b7195 100644 (file)
@@ -31,6 +31,8 @@
                                phandle-list-bad-phandle = <12345678 0 0>;
                                phandle-list-bad-args = <&provider2 1 0>,
                                                        <&provider3 0>;
+                               empty-property;
+                               unterminated-string = [40 41 42 43];
                        };
                };
        };
index d39ae606ff8db4e0cc7286cb6393ca9dace0ab4b..79bb282e650161d8478887fde87cb9d99e00c97f 100644 (file)
@@ -713,7 +713,7 @@ static struct dev_pm_ops ibmebus_bus_dev_pm_ops = {
 
 struct bus_type ibmebus_bus_type = {
        .name      = "ibmebus",
-       .uevent    = of_device_uevent,
+       .uevent    = of_device_uevent_modalias,
        .bus_attrs = ibmebus_bus_attrs,
        .match     = ibmebus_bus_bus_match,
        .probe     = ibmebus_bus_device_probe,
index ee56a9ea6a792d95761c53b0ac5821654d0f065b..1fb0b3cddeb35ee173c9022c25c4d60f8baea475 100644 (file)
@@ -26,6 +26,7 @@ config MPC86XADS
 config MPC885ADS
        bool "MPC885ADS"
        select CPM1
+       select OF_DYNAMIC
        help
          Freescale Semiconductor MPC885 Application Development System (ADS).
          Also known as DUET.
index b57cda3a0817098953e64ff63427f25891462dae..63835e09e5cccf81997470c10194365d9628280b 100644 (file)
@@ -1,6 +1,7 @@
 config PPC_ISERIES
        bool "IBM Legacy iSeries"
        depends on PPC64 && PPC_BOOK3S
+       select OF_DYNAMIC
        select PPC_SMP_MUXED_IPI
        select PPC_INDIRECT_PIO
        select PPC_INDIRECT_MMIO
index 31f22c1f657dbf4c7e2f68ca25002a24f485b83d..f2556257bbdca1c983391902670c2355ca1b8744 100644 (file)
@@ -3,6 +3,7 @@ config PPC_PSERIES
        bool "IBM pSeries & new (POWER5-based) iSeries"
        select HAVE_PCSPKR_PLATFORM
        select MPIC
+       select OF_DYNAMIC
        select PCI_MSI
        select PPC_XICS
        select PPC_ICP_NATIVE
index 57d22a2f4ba9cff69569bf33115e184408a26ec5..79d2225b76081da109cd39a59a4c59a0c8430ca5 100644 (file)
@@ -25,6 +25,7 @@ config PPC_CHROMA
        bool "PowerEN PCIe Chroma Card"
        select EPAPR_BOOT
        select PPC_WSP
+       select OF_DYNAMIC
        default y
 
 endmenu
index 7050a75dde3825fc4099bd6ff7a489246ba43e97..e28ce9898af4e1bab331fa3b9411b2bbc6575856 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/string.h>
 #include <linux/kdev_t.h>
 #include <linux/notifier.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/genhd.h>
 #include <linux/kallsyms.h>
 #include <linux/mutex.h>
@@ -267,6 +269,9 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
        if (dev->driver)
                add_uevent_var(env, "DRIVER=%s", dev->driver->name);
 
+       /* Add common DT information about the device */
+       of_device_uevent(dev, env);
+
        /* have the bus specific function add its stuff */
        if (dev->bus && dev->bus->uevent) {
                retval = dev->bus->uevent(dev, env);
index f0c605e99ade2816c7c998efb4e19f1264b9ca81..a1a72250258705eb059b6601b086cf9d296b1d1b 100644 (file)
@@ -621,7 +621,7 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
        int rc;
 
        /* Some devices have extra OF data and an OF-style MODALIAS */
-       rc = of_device_uevent(dev,env);
+       rc = of_device_uevent_modalias(dev,env);
        if (rc != -ENODEV)
                return rc;
 
index 4daf9e5a7736f415023ff1ce07d6cb2d79d526b9..20e5c2cda430e9f0a8ffbab8fbd1fc7e2f8dbf8b 100644 (file)
@@ -137,7 +137,7 @@ extern struct device_attribute macio_dev_attrs[];
 struct bus_type macio_bus_type = {
        .name   = "macio",
        .match  = macio_bus_match,
-       .uevent = of_device_uevent,
+       .uevent = of_device_uevent_modalias,
        .probe  = macio_device_probe,
        .remove = macio_device_remove,
        .shutdown = macio_device_shutdown,
index 268163dd71c7ae52f6b309d9f46117e27fa58c46..6ea51dcbc728d43685aa20ef4553c743698e749e 100644 (file)
@@ -35,9 +35,10 @@ config OF_EARLY_FLATTREE
 config OF_PROMTREE
        bool
 
+# Hardly any platforms need this.  It is safe to select, but only do so if you
+# need it.
 config OF_DYNAMIC
-       def_bool y
-       depends on PPC_OF
+       bool
 
 config OF_ADDRESS
        def_bool y
index 133908a6fd8db5270f3845ce387b3724d3845b7d..580644986945cb704d94de09bb602848fd13aede 100644 (file)
@@ -88,7 +88,7 @@ int of_n_size_cells(struct device_node *np)
 }
 EXPORT_SYMBOL(of_n_size_cells);
 
-#if !defined(CONFIG_SPARC)   /* SPARC doesn't do ref counting (yet) */
+#if defined(CONFIG_OF_DYNAMIC)
 /**
  *     of_node_get - Increment refcount of a node
  *     @node:  Node to inc refcount, NULL is supported to
@@ -161,7 +161,7 @@ void of_node_put(struct device_node *node)
                kref_put(&node->kref, of_node_release);
 }
 EXPORT_SYMBOL(of_node_put);
-#endif /* !CONFIG_SPARC */
+#endif /* CONFIG_OF_DYNAMIC */
 
 struct property *of_find_property(const struct device_node *np,
                                  const char *name,
@@ -761,6 +761,42 @@ int of_property_read_string_index(struct device_node *np, const char *propname,
 }
 EXPORT_SYMBOL_GPL(of_property_read_string_index);
 
+/**
+ * of_property_match_string() - Find string in a list and return index
+ * @np: pointer to node containing string list property
+ * @propname: string list property name
+ * @string: pointer to string to search for in string list
+ *
+ * This function searches a string list property and returns the index
+ * of a specific string value.
+ */
+int of_property_match_string(struct device_node *np, const char *propname,
+                            const char *string)
+{
+       struct property *prop = of_find_property(np, propname, NULL);
+       size_t l;
+       int i;
+       const char *p, *end;
+
+       if (!prop)
+               return -EINVAL;
+       if (!prop->value)
+               return -ENODATA;
+
+       p = prop->value;
+       end = p + prop->length;
+
+       for (i = 0; p < end; i++, p += l) {
+               l = strlen(p) + 1;
+               if (p + l > end)
+                       return -EILSEQ;
+               pr_debug("comparing %s with %s\n", string, p);
+               if (strcmp(string, p) == 0)
+                       return i; /* Found it; return index */
+       }
+       return -ENODATA;
+}
+EXPORT_SYMBOL_GPL(of_property_match_string);
 
 /**
  * of_property_count_strings - Find and return the number of strings from a
index 62b4b32ac8878eb13ca06ab57cc014a4ba843dfe..4c74e4fc5a5190857be5eaa749b82284ee8a2fb1 100644 (file)
@@ -128,39 +128,41 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
 /**
  * of_device_uevent - Display OF related uevent information
  */
-int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+void of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
        const char *compat;
        int seen = 0, cplen, sl;
 
        if ((!dev) || (!dev->of_node))
-               return -ENODEV;
-
-       if (add_uevent_var(env, "OF_NAME=%s", dev->of_node->name))
-               return -ENOMEM;
+               return;
 
-       if (add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type))
-               return -ENOMEM;
+       add_uevent_var(env, "OF_NAME=%s", dev->of_node->name);
+       add_uevent_var(env, "OF_FULLNAME=%s", dev->of_node->full_name);
+       if (dev->of_node->type && strcmp("<NULL>", dev->of_node->type) != 0)
+               add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type);
 
        /* Since the compatible field can contain pretty much anything
         * it's not really legal to split it out with commas. We split it
         * up using a number of environment variables instead. */
-
        compat = of_get_property(dev->of_node, "compatible", &cplen);
        while (compat && *compat && cplen > 0) {
-               if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
-                       return -ENOMEM;
-
+               add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat);
                sl = strlen(compat) + 1;
                compat += sl;
                cplen -= sl;
                seen++;
        }
+       add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen);
+}
 
-       if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
-               return -ENOMEM;
+int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
+{
+       int sl;
+
+       if ((!dev) || (!dev->of_node))
+               return -ENODEV;
 
-       /* modalias is trickier, we add it in 2 steps */
+       /* Devicetree modalias is tricky, we add it in 2 steps */
        if (add_uevent_var(env, "MODALIAS="))
                return -ENOMEM;
 
index 9d2b4803a9d67011b2de99cdbcfb6c9ceffb7dc2..f24ffd7088d20c590c14da6082c6354ff433bce4 100644 (file)
@@ -120,6 +120,34 @@ static void __init of_selftest_parse_phandle_with_args(void)
        pr_info("end - %s\n", passed_all ? "PASS" : "FAIL");
 }
 
+static void __init of_selftest_property_match_string(void)
+{
+       struct device_node *np;
+       int rc;
+
+       pr_info("start\n");
+       np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
+       if (!np) {
+               pr_err("No testcase data in device tree\n");
+               return;
+       }
+
+       rc = of_property_match_string(np, "phandle-list-names", "first");
+       selftest(rc == 0, "first expected:0 got:%i\n", rc);
+       rc = of_property_match_string(np, "phandle-list-names", "second");
+       selftest(rc == 1, "second expected:0 got:%i\n", rc);
+       rc = of_property_match_string(np, "phandle-list-names", "third");
+       selftest(rc == 2, "third expected:0 got:%i\n", rc);
+       rc = of_property_match_string(np, "phandle-list-names", "fourth");
+       selftest(rc == -ENODATA, "unmatched string; rc=%i", rc);
+       rc = of_property_match_string(np, "missing-property", "blah");
+       selftest(rc == -EINVAL, "missing property; rc=%i", rc);
+       rc = of_property_match_string(np, "empty-property", "blah");
+       selftest(rc == -ENODATA, "empty property; rc=%i", rc);
+       rc = of_property_match_string(np, "unterminated-string", "blah");
+       selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc);
+}
+
 static int __init of_selftest(void)
 {
        struct device_node *np;
@@ -133,6 +161,7 @@ static int __init of_selftest(void)
 
        pr_info("start of selftest - you will see error messages\n");
        of_selftest_parse_phandle_with_args();
+       of_selftest_property_match_string();
        pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL");
        return 0;
 }
index 92cf6ad35e0ea01d33ab70ea3cb70394f96762e2..f02d8b2f799d114c21455b9cdd5d4561fe69463b 100644 (file)
@@ -72,19 +72,17 @@ struct of_phandle_args {
        uint32_t args[MAX_PHANDLE_ARGS];
 };
 
-#if defined(CONFIG_SPARC) || !defined(CONFIG_OF)
+#ifdef CONFIG_OF_DYNAMIC
+extern struct device_node *of_node_get(struct device_node *node);
+extern void of_node_put(struct device_node *node);
+#else /* CONFIG_OF_DYNAMIC */
 /* Dummy ref counting routines - to be implemented later */
 static inline struct device_node *of_node_get(struct device_node *node)
 {
        return node;
 }
-static inline void of_node_put(struct device_node *node)
-{
-}
-#else
-extern struct device_node *of_node_get(struct device_node *node);
-extern void of_node_put(struct device_node *node);
-#endif
+static inline void of_node_put(struct device_node *node) { }
+#endif /* !CONFIG_OF_DYNAMIC */
 
 #ifdef CONFIG_OF
 
@@ -217,6 +215,9 @@ extern int of_property_read_string(struct device_node *np,
 extern int of_property_read_string_index(struct device_node *np,
                                         const char *propname,
                                         int index, const char **output);
+extern int of_property_match_string(struct device_node *np,
+                                   const char *propname,
+                                   const char *string);
 extern int of_property_count_strings(struct device_node *np,
                                     const char *propname);
 extern int of_device_is_compatible(const struct device_node *device,
index ae5638480ef22141f0699854d4b59fbba57aeffe..cbc42143fa5bb6f3124704c1f59775f02f624856 100644 (file)
@@ -34,7 +34,8 @@ extern void of_device_unregister(struct platform_device *ofdev);
 extern ssize_t of_device_get_modalias(struct device *dev,
                                        char *str, ssize_t len);
 
-extern int of_device_uevent(struct device *dev, struct kobj_uevent_env *env);
+extern void of_device_uevent(struct device *dev, struct kobj_uevent_env *env);
+extern int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env);
 
 static inline void of_device_node_put(struct device *dev)
 {
@@ -49,7 +50,10 @@ static inline int of_driver_match_device(struct device *dev,
        return 0;
 }
 
-static inline int of_device_uevent(struct device *dev,
+static inline void of_device_uevent(struct device *dev,
+                       struct kobj_uevent_env *env) { }
+
+static inline int of_device_uevent_modalias(struct device *dev,
                                   struct kobj_uevent_env *env)
 {
        return -ENODEV;