summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcnanda <chetan.nanda@stericsson.com>2011-10-13 16:00:18 +0530
committerJonas ABERG <jonas.aberg@stericsson.com>2011-10-21 07:47:43 +0200
commite405869e707f7fda778cb114a582cbec6448a8f5 (patch)
tree97fd5a7c56c27c32d656d44e15cd13ca508da435
parent9a881f7e6baa224db54e9130edb13b20b602cec7 (diff)
staging: mmio: protect shared resource using mutex
mmio_trace structure maintains information about the shared log buffer from camera firmware. As it is accessed from two different contexts, it needs to be protected using mutex to guard against possible corruption. ST-Ericsson ID: 356426 ST-Ericsson FOSS-OUT ID: Trivial ST-Ericsson Linux next: NA Change-Id: I806b4d26b3466a9873a8a02f8c9ac51e0ad44fd5 Signed-off-by: cnanda <chetan.nanda@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/33915 Reviewed-by: QATOOLS Tested-by: Rajat VERMA <rajat.verma@stericsson.com> Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
-rw-r--r--drivers/staging/mmio/st_mmio.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/staging/mmio/st_mmio.c b/drivers/staging/mmio/st_mmio.c
index 45726c8f405..da30844b28c 100644
--- a/drivers/staging/mmio/st_mmio.c
+++ b/drivers/staging/mmio/st_mmio.c
@@ -16,9 +16,11 @@
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
+#include <linux/mutex.h>
#include <linux/workqueue.h>
#include <linux/mfd/dbx500-prcmu.h>
#include <linux/mmio.h>
+#include <linux/ratelimit.h>
#define ISP_REGION_IO (0xE0000000)
#define SIA_ISP_REG_ADDR (0x521E4)
@@ -103,6 +105,7 @@ struct mmio_info {
struct mmio_trace *trace_buffer;
struct delayed_work trace_work;
int trace_allowed;
+ struct mutex lock;
};
/*
@@ -507,6 +510,7 @@ static int mmio_set_trace_buffer(struct mmio_info *info,
goto out;
}
+ mutex_lock(&info->lock);
if (info->trace_buffer) {
dev_info(info->dev, "unmap old buffer");
iounmap(info->trace_buffer);
@@ -518,7 +522,7 @@ static int mmio_set_trace_buffer(struct mmio_info *info,
if (!info->trace_buffer) {
dev_err(info->dev, "failed to map trace buffer\n");
ret = -ENOMEM;
- goto out;
+ goto out_unlock;
}
dev_info(info->dev, "xp70 overwrite_cnt=%d (0x%x) blk_id=%d (0x%x)",
@@ -544,6 +548,8 @@ static int mmio_set_trace_buffer(struct mmio_info *info,
msecs_to_jiffies(XP70_TIMEOUT_MSEC)))
dev_err(info->dev, "failed to schedule work\n");
+out_unlock:
+ mutex_unlock(&info->lock);
out:
return ret;
}
@@ -763,12 +769,13 @@ static int mmio_release(struct inode *node, struct file *filp)
info->pdata->config_xshutdown_pins(info->pdata, MMIO_DISABLE_XSHUTDOWN,
-1);
+ mutex_lock(&info->lock);
if (info->trace_buffer) {
+ flush_delayed_work_sync(&info->trace_work);
iounmap(info->trace_buffer);
info->trace_buffer = NULL;
}
-
- flush_delayed_work(&info->trace_work);
+ mutex_unlock(&info->lock);
return 0;
}
@@ -794,6 +801,7 @@ static ssize_t xp70_data_show(struct device *device,
int size = 0;
int count = 0;
int first_index;
+ mutex_lock(&info->lock);
first_index = info->trace_status.prev_block_id + 1;
if (!info->trace_buffer || info->trace_buffer->block_id ==
@@ -859,6 +867,7 @@ static ssize_t xp70_data_show(struct device *device,
}
out_unlock:
+ mutex_unlock(&info->lock);
return size;
}
@@ -903,6 +912,7 @@ static void xp70_buffer_wqtask(struct work_struct *data)
int i;
int first_index = info->trace_status.prev_block_id + 1;
int count;
+ mutex_lock(&info->lock);
if (!info->trace_buffer)
goto out_err;
@@ -929,8 +939,7 @@ static void xp70_buffer_wqtask(struct work_struct *data)
first_index = info->trace_buffer->block_id + 1;
count = XP70_NB_BLOCK;
- if (printk_ratelimit())
- dev_info(info->dev, "XP70 trace overflow\n");
+ pr_info_ratelimited("XP70 trace overflow\n");
} else if (info->trace_buffer->block_id
>= info->trace_status.prev_block_id) {
count = info->trace_buffer->block_id -
@@ -945,8 +954,7 @@ static void xp70_buffer_wqtask(struct work_struct *data)
for (i = first_index; count; count--) {
if (i < 0 || i >= XP70_NB_BLOCK || count > XP70_NB_BLOCK) {
- if (printk_ratelimit())
- dev_info(info->dev, "trace index out-of-bounds"
+ pr_info_ratelimited("trace index out-of-bounds"
"i=%d count=%d XP70_NB_BLOCK=%d\n",
i, count, XP70_NB_BLOCK);
@@ -978,13 +986,13 @@ static void xp70_buffer_wqtask(struct work_struct *data)
info->trace_buffer->overwrite_count;
info->trace_status.prev_block_id = info->trace_buffer->block_id;
out:
-
/* Schedule work */
if (!schedule_delayed_work(&info->trace_work,
msecs_to_jiffies(XP70_TIMEOUT_MSEC)))
dev_info(info->dev, "failed to schedule work\n");
out_err:
+ mutex_unlock(&info->lock);
return;
}
@@ -1023,6 +1031,7 @@ static int __devinit mmio_probe(struct platform_device *pdev)
info->misc_dev.name = MMIO_NAME;
info->misc_dev.fops = &mmio_fops;
info->misc_dev.parent = pdev->dev.parent;
+ mutex_init(&info->lock);
info->xshutdown_enabled = 0;
info->xshutdown_is_active_high = 0;
info->trace_allowed = 0;
@@ -1119,6 +1128,7 @@ static int __devexit mmio_remove(struct platform_device *pdev)
info->pdata->platform_exit(info->pdata);
iounmap(info->siabase);
iounmap(info->crbase);
+ mutex_destroy(&info->lock);
kfree(info);
info = NULL;
return 0;