aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/omapfb
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@nokia.com>2010-03-17 15:42:06 -0400
committerTomi Valkeinen <tomi.valkeinen@nokia.com>2010-08-03 08:18:46 -0400
commit3d84b65aa63833a2ac07b1cc626984a1e1485fed (patch)
tree532d91bff861f241b6cd8e9031a286a557926398 /drivers/video/omap2/omapfb
parent2f642a17503838e256b8b7e9f1153512e2efc38b (diff)
OMAP: DSS2: OMAPFB: Make lockdep happy
When more than one memory region needs to be lockd at the same time use the memory region id to fix the order in which the locks are taken. Also one needs to use the _nested() versions of the locking primitives. The memory region id can serve as the lock class there as well. Signed-off-by: Ville Syrjälä <ville.syrjala@nokia.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Diffstat (limited to 'drivers/video/omap2/omapfb')
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c45
-rw-r--r--drivers/video/omap2/omapfb/omapfb-sysfs.c2
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h2
3 files changed, 36 insertions, 13 deletions
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 3a10146dc120..7975a99c33f9 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -55,7 +55,7 @@ static struct omapfb2_mem_region *get_mem_region(struct omapfb_info *ofbi,
55 if (mem_idx >= fbdev->num_fbs) 55 if (mem_idx >= fbdev->num_fbs)
56 return NULL; 56 return NULL;
57 57
58 return omapfb_get_mem_region(&fbdev->regions[mem_idx]); 58 return &fbdev->regions[mem_idx];
59} 59}
60 60
61static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi) 61static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
@@ -77,20 +77,30 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
77 /* XXX uses only the first overlay */ 77 /* XXX uses only the first overlay */
78 ovl = ofbi->overlays[0]; 78 ovl = ofbi->overlays[0];
79 79
80 old_rg = omapfb_get_mem_region(ofbi->region); 80 old_rg = ofbi->region;
81 new_rg = get_mem_region(ofbi, pi->mem_idx); 81 new_rg = get_mem_region(ofbi, pi->mem_idx);
82 if (!new_rg) { 82 if (!new_rg) {
83 r = -EINVAL; 83 r = -EINVAL;
84 goto put_old; 84 goto out;
85 } 85 }
86 86
87 /* Take the locks in a specific order to keep lockdep happy */
88 if (old_rg->id < new_rg->id) {
89 omapfb_get_mem_region(old_rg);
90 omapfb_get_mem_region(new_rg);
91 } else if (new_rg->id < old_rg->id) {
92 omapfb_get_mem_region(new_rg);
93 omapfb_get_mem_region(old_rg);
94 } else
95 omapfb_get_mem_region(old_rg);
96
87 if (pi->enabled && !new_rg->size) { 97 if (pi->enabled && !new_rg->size) {
88 /* 98 /*
89 * This plane's memory was freed, can't enable it 99 * This plane's memory was freed, can't enable it
90 * until it's reallocated. 100 * until it's reallocated.
91 */ 101 */
92 r = -EINVAL; 102 r = -EINVAL;
93 goto put_new; 103 goto put_mem;
94 } 104 }
95 105
96 ovl->get_overlay_info(ovl, &old_info); 106 ovl->get_overlay_info(ovl, &old_info);
@@ -135,8 +145,15 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
135 if (ovl->manager) 145 if (ovl->manager)
136 ovl->manager->apply(ovl->manager); 146 ovl->manager->apply(ovl->manager);
137 147
138 omapfb_put_mem_region(new_rg); 148 /* Release the locks in a specific order to keep lockdep happy */
139 omapfb_put_mem_region(old_rg); 149 if (old_rg->id > new_rg->id) {
150 omapfb_put_mem_region(old_rg);
151 omapfb_put_mem_region(new_rg);
152 } else if (new_rg->id > old_rg->id) {
153 omapfb_put_mem_region(new_rg);
154 omapfb_put_mem_region(old_rg);
155 } else
156 omapfb_put_mem_region(old_rg);
140 157
141 return 0; 158 return 0;
142 159
@@ -147,10 +164,16 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
147 } 164 }
148 165
149 ovl->set_overlay_info(ovl, &old_info); 166 ovl->set_overlay_info(ovl, &old_info);
150 put_new: 167 put_mem:
151 omapfb_put_mem_region(new_rg); 168 /* Release the locks in a specific order to keep lockdep happy */
152 put_old: 169 if (old_rg->id > new_rg->id) {
153 omapfb_put_mem_region(old_rg); 170 omapfb_put_mem_region(old_rg);
171 omapfb_put_mem_region(new_rg);
172 } else if (new_rg->id > old_rg->id) {
173 omapfb_put_mem_region(new_rg);
174 omapfb_put_mem_region(old_rg);
175 } else
176 omapfb_put_mem_region(old_rg);
154 out: 177 out:
155 dev_err(fbdev->dev, "setup_plane failed\n"); 178 dev_err(fbdev->dev, "setup_plane failed\n");
156 179
@@ -198,7 +221,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
198 221
199 rg = ofbi->region; 222 rg = ofbi->region;
200 223
201 down_write(&rg->lock); 224 down_write_nested(&rg->lock, rg->id);
202 225
203 if (atomic_read(&rg->map_count)) { 226 if (atomic_read(&rg->map_count)) {
204 r = -EBUSY; 227 r = -EBUSY;
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index 724b760404f2..1e714bb48d39 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -452,7 +452,7 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
452 452
453 rg = ofbi->region; 453 rg = ofbi->region;
454 454
455 down_write(&rg->lock); 455 down_write_nested(&rg->lock, rg->id);
456 456
457 if (atomic_read(&rg->map_count)) { 457 if (atomic_read(&rg->map_count)) {
458 r = -EBUSY; 458 r = -EBUSY;
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 195a760eef54..676b55d98941 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -165,7 +165,7 @@ static inline int omapfb_overlay_enable(struct omap_overlay *ovl,
165static inline struct omapfb2_mem_region * 165static inline struct omapfb2_mem_region *
166omapfb_get_mem_region(struct omapfb2_mem_region *rg) 166omapfb_get_mem_region(struct omapfb2_mem_region *rg)
167{ 167{
168 down_read(&rg->lock); 168 down_read_nested(&rg->lock, rg->id);
169 return rg; 169 return rg;
170} 170}
171 171