aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Paul <seanpaul@chromium.org>2016-08-16 19:11:28 -0400
committerSean Paul <seanpaul@chromium.org>2016-08-23 11:44:34 -0400
commit18d8d4d2287b790360ee58d2ace4896e2e10cbb6 (patch)
treec6d908191d30f6e1424179b28d457f4235b2bb15
parent8f0ac5c4835291c6cf47aa60f42d0a4f15335670 (diff)
drm/rockchip: Convert psr_list_mutex to spinlock and use it
This patch converts the psr_list_mutex to a spinlock and locks all access to psr_list to avoid races (however unlikely they were). Reviewed-by: Yakir Yang <ykk@rock-chips.com> Signed-off-by: Sean Paul <seanpaul@chromium.org>
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.c2
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.h2
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_psr.c25
3 files changed, 20 insertions, 9 deletions
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index b43fe5d93828..76eaf1de52e4 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -157,7 +157,7 @@ static int rockchip_drm_bind(struct device *dev)
157 drm_dev->dev_private = private; 157 drm_dev->dev_private = private;
158 158
159 INIT_LIST_HEAD(&private->psr_list); 159 INIT_LIST_HEAD(&private->psr_list);
160 mutex_init(&private->psr_list_mutex); 160 spin_lock_init(&private->psr_list_lock);
161 161
162 drm_mode_config_init(drm_dev); 162 drm_mode_config_init(drm_dev);
163 163
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 9c34c9e181d0..5c698456aa1c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -63,7 +63,7 @@ struct rockchip_drm_private {
63 struct drm_atomic_state *state; 63 struct drm_atomic_state *state;
64 64
65 struct list_head psr_list; 65 struct list_head psr_list;
66 struct mutex psr_list_mutex; 66 spinlock_t psr_list_lock;
67}; 67};
68 68
69int rockchip_register_crtc_funcs(struct drm_crtc *crtc, 69int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
index a6d3bd25b905..bd25273a89bb 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
@@ -45,12 +45,18 @@ static struct psr_drv *find_psr_by_crtc(struct drm_crtc *crtc)
45{ 45{
46 struct rockchip_drm_private *drm_drv = crtc->dev->dev_private; 46 struct rockchip_drm_private *drm_drv = crtc->dev->dev_private;
47 struct psr_drv *psr; 47 struct psr_drv *psr;
48 unsigned long flags;
48 49
49 list_for_each_entry(psr, &drm_drv->psr_list, list) 50 spin_lock_irqsave(&drm_drv->psr_list_lock, flags);
51 list_for_each_entry(psr, &drm_drv->psr_list, list) {
50 if (psr->encoder->crtc == crtc) 52 if (psr->encoder->crtc == crtc)
51 return psr; 53 goto out;
54 }
55 psr = ERR_PTR(-ENODEV);
52 56
53 return ERR_PTR(-ENODEV); 57out:
58 spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags);
59 return psr;
54} 60}
55 61
56static void psr_state_work(struct work_struct *work) 62static void psr_state_work(struct work_struct *work)
@@ -173,7 +179,9 @@ void rockchip_drm_psr_flush(struct drm_device *dev)
173{ 179{
174 struct rockchip_drm_private *drm_drv = dev->dev_private; 180 struct rockchip_drm_private *drm_drv = dev->dev_private;
175 struct psr_drv *psr; 181 struct psr_drv *psr;
182 unsigned long flags;
176 183
184 spin_lock_irqsave(&drm_drv->psr_list_lock, flags);
177 list_for_each_entry(psr, &drm_drv->psr_list, list) { 185 list_for_each_entry(psr, &drm_drv->psr_list, list) {
178 if (psr->request_state == PSR_DISABLE) 186 if (psr->request_state == PSR_DISABLE)
179 continue; 187 continue;
@@ -183,6 +191,7 @@ void rockchip_drm_psr_flush(struct drm_device *dev)
183 191
184 psr_set_state(psr, PSR_FLUSH); 192 psr_set_state(psr, PSR_FLUSH);
185 } 193 }
194 spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags);
186} 195}
187EXPORT_SYMBOL(rockchip_drm_psr_flush); 196EXPORT_SYMBOL(rockchip_drm_psr_flush);
188 197
@@ -199,6 +208,7 @@ int rockchip_drm_psr_register(struct drm_encoder *encoder,
199{ 208{
200 struct rockchip_drm_private *drm_drv = encoder->dev->dev_private; 209 struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
201 struct psr_drv *psr; 210 struct psr_drv *psr;
211 unsigned long flags;
202 212
203 if (!encoder || !psr_set) 213 if (!encoder || !psr_set)
204 return -EINVAL; 214 return -EINVAL;
@@ -215,9 +225,9 @@ int rockchip_drm_psr_register(struct drm_encoder *encoder,
215 psr->encoder = encoder; 225 psr->encoder = encoder;
216 psr->set = psr_set; 226 psr->set = psr_set;
217 227
218 mutex_lock(&drm_drv->psr_list_mutex); 228 spin_lock_irqsave(&drm_drv->psr_list_lock, flags);
219 list_add_tail(&psr->list, &drm_drv->psr_list); 229 list_add_tail(&psr->list, &drm_drv->psr_list);
220 mutex_unlock(&drm_drv->psr_list_mutex); 230 spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags);
221 231
222 return 0; 232 return 0;
223} 233}
@@ -235,8 +245,9 @@ void rockchip_drm_psr_unregister(struct drm_encoder *encoder)
235{ 245{
236 struct rockchip_drm_private *drm_drv = encoder->dev->dev_private; 246 struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
237 struct psr_drv *psr, *n; 247 struct psr_drv *psr, *n;
248 unsigned long flags;
238 249
239 mutex_lock(&drm_drv->psr_list_mutex); 250 spin_lock_irqsave(&drm_drv->psr_list_lock, flags);
240 list_for_each_entry_safe(psr, n, &drm_drv->psr_list, list) { 251 list_for_each_entry_safe(psr, n, &drm_drv->psr_list, list) {
241 if (psr->encoder == encoder) { 252 if (psr->encoder == encoder) {
242 del_timer(&psr->flush_timer); 253 del_timer(&psr->flush_timer);
@@ -244,6 +255,6 @@ void rockchip_drm_psr_unregister(struct drm_encoder *encoder)
244 kfree(psr); 255 kfree(psr);
245 } 256 }
246 } 257 }
247 mutex_unlock(&drm_drv->psr_list_mutex); 258 spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags);
248} 259}
249EXPORT_SYMBOL(rockchip_drm_psr_unregister); 260EXPORT_SYMBOL(rockchip_drm_psr_unregister);