summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcnanda <chetan.nanda@stericsson.com>2011-10-13 16:00:18 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:07:02 +0200
commitc6458fb663047d93f8b8453eef114d90e324ca39 (patch)
treeafec89e077a3bbb10d2a1561df671cdc0aef12a7
parente302925edc2a78569e1742e523db4b55a3fc4e26 (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 655f7ce3a93..51e92666e28 100644
--- a/drivers/staging/mmio/st_mmio.c
+++ b/drivers/staging/mmio/st_mmio.c
@@ -16,8 +16,10 @@
#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/ratelimit.h>
#include "mmio.h"
#define ISP_REGION_IO (0xE0000000)
@@ -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;