sparc: Add mutex for set property calls.
authorDavid S. Miller <davem@davemloft.net>
Wed, 20 Aug 2008 04:56:35 +0000 (21:56 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 25 Aug 2008 03:33:55 +0000 (20:33 -0700)
On some platforms, the I2C controller is shared between the OS and
OBP.  OBP uses this I2C controller to access the EEPROM, and thus is
programmed when the kernel calls prom_setprop().

Wrap such calls with the new of_set_property_mutex.

Relevant I2C bus drivers can grab this mutex around top-level I2C
operations to provide the proper protection.

Signed-off-by: David S. Miller <davem@davemloft.net>
arch/sparc/include/asm/prom.h
arch/sparc/kernel/prom.c
arch/sparc64/kernel/prom.c

index fd55522..b5efc4d 100644 (file)
@@ -18,6 +18,7 @@
  */
 #include <linux/types.h>
 #include <linux/proc_fs.h>
+#include <linux/mutex.h>
 #include <asm/atomic.h>
 
 #define OF_ROOT_NODE_ADDR_CELLS_DEFAULT        2
@@ -73,6 +74,7 @@ struct of_irq_controller {
 
 extern struct device_node *of_find_node_by_cpuid(int cpuid);
 extern int of_set_property(struct device_node *node, const char *name, void *val, int len);
+extern struct mutex of_set_property_mutex;
 extern int of_getintprop_default(struct device_node *np,
                                 const char *name,
                                 int def);
index cd4fb79..43e8624 100644 (file)
@@ -54,6 +54,9 @@ int of_getintprop_default(struct device_node *np, const char *name, int def)
 }
 EXPORT_SYMBOL(of_getintprop_default);
 
+DEFINE_MUTEX(of_set_property_mutex);
+EXPORT_SYMBOL(of_set_property_mutex);
+
 int of_set_property(struct device_node *dp, const char *name, void *val, int len)
 {
        struct property **prevp;
@@ -77,7 +80,10 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
                        void *old_val = prop->value;
                        int ret;
 
+                       mutex_lock(&of_set_property_mutex);
                        ret = prom_setprop(dp->node, (char *) name, val, len);
+                       mutex_unlock(&of_set_property_mutex);
+
                        err = -EINVAL;
                        if (ret >= 0) {
                                prop->value = new_val;
index 3c048ac..922dd61 100644 (file)
@@ -59,6 +59,9 @@ int of_getintprop_default(struct device_node *np, const char *name, int def)
 }
 EXPORT_SYMBOL(of_getintprop_default);
 
+DEFINE_MUTEX(of_set_property_mutex);
+EXPORT_SYMBOL(of_set_property_mutex);
+
 int of_set_property(struct device_node *dp, const char *name, void *val, int len)
 {
        struct property **prevp;
@@ -82,7 +85,10 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
                        void *old_val = prop->value;
                        int ret;
 
+                       mutex_lock(&of_set_property_mutex);
                        ret = prom_setprop(dp->node, name, val, len);
+                       mutex_unlock(&of_set_property_mutex);
+
                        err = -EINVAL;
                        if (ret >= 0) {
                                prop->value = new_val;