diff options
author | Liu Ying <Ying.Liu@freescale.com> | 2015-11-13 14:55:55 +0800 |
---|---|---|
committer | Liu Ying <Ying.Liu@freescale.com> | 2015-11-20 15:27:29 +0800 |
commit | 0df10a86fa7e2ea6c8269d77239f558aad0e550c (patch) | |
tree | 6bfbefcd0f7b1c1a974036adf0616ace17b0a61e | |
parent | 7c81c6e463dd4e646005f51e2dc60668076cab61 (diff) |
MLK-11857 mxc IPUv3: PRE: Use spinlock to protect pre_list instead of mutex
The pre_list can be accessed in an irq context. To avoid potential hang up
issue, use spinlock to protect pre_list instead of mutex.
Signed-off-by: Liu Ying <Ying.Liu@freescale.com>
(cherry picked from commit 16f552fb1fbd2626f81eacc7f2f7b2ce9b5ad11c)
(cherry picked from commit 0d0c18b34b3fa889bbc22e10244c355c639ac694)
-rw-r--r-- | drivers/mxc/ipu3/pre.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/mxc/ipu3/pre.c b/drivers/mxc/ipu3/pre.c index e625d272d60c..6df0dd5ce1d8 100644 --- a/drivers/mxc/ipu3/pre.c +++ b/drivers/mxc/ipu3/pre.c @@ -51,7 +51,7 @@ struct ipu_pre_data { }; static LIST_HEAD(pre_list); -static DEFINE_MUTEX(pre_list_lock); +static DEFINE_SPINLOCK(pre_list_lock); static inline void pre_write(struct ipu_pre_data *pre, u32 value, unsigned int offset) @@ -67,15 +67,16 @@ static inline u32 pre_read(struct ipu_pre_data *pre, unsigned offset) static struct ipu_pre_data *get_pre(unsigned int id) { struct ipu_pre_data *pre; + unsigned long lock_flags; - mutex_lock(&pre_list_lock); + spin_lock_irqsave(&pre_list_lock, lock_flags); list_for_each_entry(pre, &pre_list, list) { if (pre->id == id) { - mutex_unlock(&pre_list_lock); + spin_unlock_irqrestore(&pre_list_lock, lock_flags); return pre; } } - mutex_unlock(&pre_list_lock); + spin_unlock_irqrestore(&pre_list_lock, lock_flags); return NULL; } @@ -893,6 +894,7 @@ static int ipu_pre_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct ipu_pre_data *pre; struct resource *res; + unsigned long lock_flags; int id, irq, err; pre = devm_kzalloc(&pdev->dev, sizeof(*pre), GFP_KERNEL); @@ -935,9 +937,9 @@ static int ipu_pre_probe(struct platform_device *pdev) return -ENOMEM; } - mutex_lock(&pre_list_lock); + spin_lock_irqsave(&pre_list_lock, lock_flags); list_add_tail(&pre->list, &pre_list); - mutex_unlock(&pre_list_lock); + spin_unlock_irqrestore(&pre_list_lock, lock_flags); ipu_pre_alloc_double_buffer(pre->id, IPU_PRE_MAX_WIDTH * 8 * IPU_PRE_MAX_BPP); @@ -958,6 +960,7 @@ static int ipu_pre_probe(struct platform_device *pdev) static int ipu_pre_remove(struct platform_device *pdev) { struct ipu_pre_data *pre = platform_get_drvdata(pdev); + unsigned long lock_flags; if (pre->iram_pool && pre->double_buffer_base) { gen_pool_free(pre->iram_pool, @@ -965,9 +968,9 @@ static int ipu_pre_remove(struct platform_device *pdev) pre->double_buffer_size); } - mutex_lock(&pre_list_lock); + spin_lock_irqsave(&pre_list_lock, lock_flags); list_del(&pre->list); - mutex_unlock(&pre_list_lock); + spin_unlock_irqrestore(&pre_list_lock, lock_flags); return 0; } |