diff options
author | cnanda <chetan.nanda@stericsson.com> | 2011-10-13 16:00:18 +0530 |
---|---|---|
committer | Philippe Langlais <philippe.langlais@stericsson.com> | 2012-05-22 11:07:02 +0200 |
commit | c6458fb663047d93f8b8453eef114d90e324ca39 (patch) | |
tree | afec89e077a3bbb10d2a1561df671cdc0aef12a7 | |
parent | e302925edc2a78569e1742e523db4b55a3fc4e26 (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.c | 26 |
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; |