aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2')
-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