aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/omapfb/omapfb-ioctl.c
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@nokia.com>2010-03-17 14:43:23 -0400
committerTomi Valkeinen <tomi.valkeinen@nokia.com>2010-08-03 08:18:46 -0400
commit430571d59a0b51c6541c153ad8b08e72fef26098 (patch)
tree8ad99c778576b985f5fbe6de57d1ea4dea0981c3 /drivers/video/omap2/omapfb/omapfb-ioctl.c
parent078ff546a806b2c2ab74c25c8edd4c6d4680656a (diff)
OMAP: DSS2: OMAPFB: Add locking for memory regions
Add locking to the memory regions to make sure the memory region size won't be changed while some other piece of code is performing some checks or setup based on that information. 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/omapfb-ioctl.c')
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 6635bd75aff..69bcbfca47f 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 &fbdev->regions[mem_idx]; 58 return omapfb_get_mem_region(&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,11 +77,11 @@ 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 = ofbi->region; 80 old_rg = omapfb_get_mem_region(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 out; 84 goto put_old;
85 } 85 }
86 86
87 if (pi->enabled && !new_rg->size) { 87 if (pi->enabled && !new_rg->size) {
@@ -90,7 +90,7 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
90 * until it's reallocated. 90 * until it's reallocated.
91 */ 91 */
92 r = -EINVAL; 92 r = -EINVAL;
93 goto out; 93 goto put_new;
94 } 94 }
95 95
96 ovl->get_overlay_info(ovl, &old_info); 96 ovl->get_overlay_info(ovl, &old_info);
@@ -135,6 +135,9 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
135 if (ovl->manager) 135 if (ovl->manager)
136 ovl->manager->apply(ovl->manager); 136 ovl->manager->apply(ovl->manager);
137 137
138 omapfb_put_mem_region(new_rg);
139 omapfb_put_mem_region(old_rg);
140
138 return 0; 141 return 0;
139 142
140 undo: 143 undo:
@@ -144,6 +147,10 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
144 } 147 }
145 148
146 ovl->set_overlay_info(ovl, &old_info); 149 ovl->set_overlay_info(ovl, &old_info);
150 put_new:
151 omapfb_put_mem_region(new_rg);
152 put_old:
153 omapfb_put_mem_region(old_rg);
147 out: 154 out:
148 dev_err(fbdev->dev, "setup_plane failed\n"); 155 dev_err(fbdev->dev, "setup_plane failed\n");
149 156
@@ -181,7 +188,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
181 struct omapfb_info *ofbi = FB2OFB(fbi); 188 struct omapfb_info *ofbi = FB2OFB(fbi);
182 struct omapfb2_device *fbdev = ofbi->fbdev; 189 struct omapfb2_device *fbdev = ofbi->fbdev;
183 struct omapfb2_mem_region *rg; 190 struct omapfb2_mem_region *rg;
184 int r, i; 191 int r = 0, i;
185 size_t size; 192 size_t size;
186 193
187 if (mi->type > OMAPFB_MEMTYPE_MAX) 194 if (mi->type > OMAPFB_MEMTYPE_MAX)
@@ -191,8 +198,18 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
191 198
192 rg = ofbi->region; 199 rg = ofbi->region;
193 200
194 if (atomic_read(&rg->map_count)) 201 /* FIXME probably should be a rwsem ... */
195 return -EBUSY; 202 mutex_lock(&rg->mtx);
203 while (rg->ref) {
204 mutex_unlock(&rg->mtx);
205 schedule();
206 mutex_lock(&rg->mtx);
207 }
208
209 if (atomic_read(&rg->map_count)) {
210 r = -EBUSY;
211 goto out;
212 }
196 213
197 for (i = 0; i < fbdev->num_fbs; i++) { 214 for (i = 0; i < fbdev->num_fbs; i++) {
198 struct omapfb_info *ofbi2 = FB2OFB(fbdev->fbs[i]); 215 struct omapfb_info *ofbi2 = FB2OFB(fbdev->fbs[i]);
@@ -204,7 +221,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
204 for (j = 0; j < ofbi2->num_overlays; j++) { 221 for (j = 0; j < ofbi2->num_overlays; j++) {
205 if (ofbi2->overlays[j]->info.enabled) { 222 if (ofbi2->overlays[j]->info.enabled) {
206 r = -EBUSY; 223 r = -EBUSY;
207 return r; 224 goto out;
208 } 225 }
209 } 226 }
210 } 227 }
@@ -213,11 +230,14 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
213 r = omapfb_realloc_fbmem(fbi, size, mi->type); 230 r = omapfb_realloc_fbmem(fbi, size, mi->type);
214 if (r) { 231 if (r) {
215 dev_err(fbdev->dev, "realloc fbmem failed\n"); 232 dev_err(fbdev->dev, "realloc fbmem failed\n");
216 return r; 233 goto out;
217 } 234 }
218 } 235 }
219 236
220 return 0; 237 out:
238 mutex_unlock(&rg->mtx);
239
240 return r;
221} 241}
222 242
223static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi) 243static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
@@ -225,12 +245,14 @@ static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
225 struct omapfb_info *ofbi = FB2OFB(fbi); 245 struct omapfb_info *ofbi = FB2OFB(fbi);
226 struct omapfb2_mem_region *rg; 246 struct omapfb2_mem_region *rg;
227 247
228 rg = ofbi->region; 248 rg = omapfb_get_mem_region(ofbi->region);
229 memset(mi, 0, sizeof(*mi)); 249 memset(mi, 0, sizeof(*mi));
230 250
231 mi->size = rg->size; 251 mi->size = rg->size;
232 mi->type = rg->type; 252 mi->type = rg->type;
233 253
254 omapfb_put_mem_region(rg);
255
234 return 0; 256 return 0;
235} 257}
236 258