msm: ramdump: fix duplicated sysfs ramdump
subsystem creates sysfs for ramdump. In some cases, it tries to create
same name sysfs which is created previously in other subsystem. To fix
duplicated sysfs, if sysfs is already existed when creating ramdump node,
return previous device handle but not create new sysfs.
Change-Id: I1aa020aa50ec487a1d3041f3d6e24366988f0289
diff --git a/arch/arm/mach-msm/ramdump.c b/arch/arm/mach-msm/ramdump.c
index a18acd6..5d7cd76 100644
--- a/arch/arm/mach-msm/ramdump.c
+++ b/arch/arm/mach-msm/ramdump.c
@@ -26,6 +26,7 @@
#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/uaccess.h>
+#include <linux/mutex.h>
#include <asm-generic/poll.h>
@@ -33,6 +34,12 @@
#define RAMDUMP_WAIT_MSECS 120000
+/*
+ * Head entry for linked list
+ */
+static LIST_HEAD(ramdump_list);
+static DEFINE_MUTEX(ramdump_mtx);
+
struct ramdump_device {
char name[256];
@@ -46,6 +53,7 @@
wait_queue_head_t dump_wait_q;
int nsegments;
struct ramdump_segment *segments;
+ struct list_head list;
};
static int ramdump_open(struct inode *inode, struct file *filep)
@@ -185,12 +193,25 @@
{
int ret;
struct ramdump_device *rd_dev;
+ char name[256];
if (!dev_name) {
pr_err("%s: Invalid device name.\n", __func__);
return NULL;
}
+ snprintf(name, ARRAY_SIZE(name), "ramdump_%s", dev_name);
+ mutex_lock(&ramdump_mtx);
+ list_for_each_entry(rd_dev, &ramdump_list, list) {
+ if (!strcmp(rd_dev->device.name, name)) {
+ mutex_unlock(&ramdump_mtx);
+ pr_warning("%s: already exist: %s",
+ __func__, name);
+ return (void *)rd_dev;
+ }
+ }
+ mutex_unlock(&ramdump_mtx);
+
rd_dev = kzalloc(sizeof(struct ramdump_device), GFP_KERNEL);
if (!rd_dev) {
@@ -198,6 +219,7 @@
__func__);
return NULL;
}
+ INIT_LIST_HEAD(&rd_dev->list);
snprintf(rd_dev->name, ARRAY_SIZE(rd_dev->name), "ramdump_%s",
dev_name);
@@ -219,6 +241,10 @@
return NULL;
}
+ mutex_lock(&ramdump_mtx);
+ list_add(&rd_dev->list, &ramdump_list);
+ mutex_unlock(&ramdump_mtx);
+
return (void *)rd_dev;
}