diff options
author | Sean Paul <seanpaul@chromium.org> | 2016-08-16 19:11:28 -0400 |
---|---|---|
committer | Sean Paul <seanpaul@chromium.org> | 2016-08-23 11:44:34 -0400 |
commit | 18d8d4d2287b790360ee58d2ace4896e2e10cbb6 (patch) | |
tree | c6d908191d30f6e1424179b28d457f4235b2bb15 | |
parent | 8f0ac5c4835291c6cf47aa60f42d0a4f15335670 (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.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 25 |
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 | ||
69 | int rockchip_register_crtc_funcs(struct drm_crtc *crtc, | 69 | int 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); | 57 | out: |
58 | spin_unlock_irqrestore(&drm_drv->psr_list_lock, flags); | ||
59 | return psr; | ||
54 | } | 60 | } |
55 | 61 | ||
56 | static void psr_state_work(struct work_struct *work) | 62 | static 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 | } |
187 | EXPORT_SYMBOL(rockchip_drm_psr_flush); | 196 | EXPORT_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 | } |
249 | EXPORT_SYMBOL(rockchip_drm_psr_unregister); | 260 | EXPORT_SYMBOL(rockchip_drm_psr_unregister); |