소스 검색

sparc: Add mutex for set property calls.

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>
David S. Miller 17 년 전
부모
커밋
2481d76615
3개의 변경된 파일14개의 추가작업 그리고 0개의 파일을 삭제
  1. 2 0
      arch/sparc/include/asm/prom.h
  2. 6 0
      arch/sparc/kernel/prom.c
  3. 6 0
      arch/sparc64/kernel/prom.c

+ 2 - 0
arch/sparc/include/asm/prom.h

@@ -18,6 +18,7 @@
  */
  */
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/proc_fs.h>
+#include <linux/mutex.h>
 #include <asm/atomic.h>
 #include <asm/atomic.h>
 
 
 #define OF_ROOT_NODE_ADDR_CELLS_DEFAULT	2
 #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 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 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,
 extern int of_getintprop_default(struct device_node *np,
 				 const char *name,
 				 const char *name,
 				 int def);
 				 int def);

+ 6 - 0
arch/sparc/kernel/prom.c

@@ -54,6 +54,9 @@ int of_getintprop_default(struct device_node *np, const char *name, int def)
 }
 }
 EXPORT_SYMBOL(of_getintprop_default);
 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)
 int of_set_property(struct device_node *dp, const char *name, void *val, int len)
 {
 {
 	struct property **prevp;
 	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;
 			void *old_val = prop->value;
 			int ret;
 			int ret;
 
 
+			mutex_lock(&of_set_property_mutex);
 			ret = prom_setprop(dp->node, (char *) name, val, len);
 			ret = prom_setprop(dp->node, (char *) name, val, len);
+			mutex_unlock(&of_set_property_mutex);
+
 			err = -EINVAL;
 			err = -EINVAL;
 			if (ret >= 0) {
 			if (ret >= 0) {
 				prop->value = new_val;
 				prop->value = new_val;

+ 6 - 0
arch/sparc64/kernel/prom.c

@@ -59,6 +59,9 @@ int of_getintprop_default(struct device_node *np, const char *name, int def)
 }
 }
 EXPORT_SYMBOL(of_getintprop_default);
 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)
 int of_set_property(struct device_node *dp, const char *name, void *val, int len)
 {
 {
 	struct property **prevp;
 	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;
 			void *old_val = prop->value;
 			int ret;
 			int ret;
 
 
+			mutex_lock(&of_set_property_mutex);
 			ret = prom_setprop(dp->node, name, val, len);
 			ret = prom_setprop(dp->node, name, val, len);
+			mutex_unlock(&of_set_property_mutex);
+
 			err = -EINVAL;
 			err = -EINVAL;
 			if (ret >= 0) {
 			if (ret >= 0) {
 				prop->value = new_val;
 				prop->value = new_val;