aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c125
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c71
-rw-r--r--drivers/video/omap2/omapfb/omapfb-sysfs.c37
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h9
4 files changed, 179 insertions, 63 deletions
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 9c7361871d78..6635bd75affa 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -34,12 +34,37 @@
34 34
35#include "omapfb.h" 35#include "omapfb.h"
36 36
37static u8 get_mem_idx(struct omapfb_info *ofbi)
38{
39 if (ofbi->id == ofbi->region->id)
40 return 0;
41
42 return OMAPFB_MEM_IDX_ENABLED | ofbi->region->id;
43}
44
45static struct omapfb2_mem_region *get_mem_region(struct omapfb_info *ofbi,
46 u8 mem_idx)
47{
48 struct omapfb2_device *fbdev = ofbi->fbdev;
49
50 if (mem_idx & OMAPFB_MEM_IDX_ENABLED)
51 mem_idx &= OMAPFB_MEM_IDX_MASK;
52 else
53 mem_idx = ofbi->id;
54
55 if (mem_idx >= fbdev->num_fbs)
56 return NULL;
57
58 return &fbdev->regions[mem_idx];
59}
60
37static 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)
38{ 62{
39 struct omapfb_info *ofbi = FB2OFB(fbi); 63 struct omapfb_info *ofbi = FB2OFB(fbi);
40 struct omapfb2_device *fbdev = ofbi->fbdev; 64 struct omapfb2_device *fbdev = ofbi->fbdev;
41 struct omap_overlay *ovl; 65 struct omap_overlay *ovl;
42 struct omap_overlay_info info; 66 struct omap_overlay_info old_info;
67 struct omapfb2_mem_region *old_rg, *new_rg;
43 int r = 0; 68 int r = 0;
44 69
45 DBG("omapfb_setup_plane\n"); 70 DBG("omapfb_setup_plane\n");
@@ -52,7 +77,14 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
52 /* XXX uses only the first overlay */ 77 /* XXX uses only the first overlay */
53 ovl = ofbi->overlays[0]; 78 ovl = ofbi->overlays[0];
54 79
55 if (pi->enabled && !ofbi->region.size) { 80 old_rg = ofbi->region;
81 new_rg = get_mem_region(ofbi, pi->mem_idx);
82 if (!new_rg) {
83 r = -EINVAL;
84 goto out;
85 }
86
87 if (pi->enabled && !new_rg->size) {
56 /* 88 /*
57 * This plane's memory was freed, can't enable it 89 * This plane's memory was freed, can't enable it
58 * until it's reallocated. 90 * until it's reallocated.
@@ -61,27 +93,60 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
61 goto out; 93 goto out;
62 } 94 }
63 95
64 ovl->get_overlay_info(ovl, &info); 96 ovl->get_overlay_info(ovl, &old_info);
65 97
66 info.pos_x = pi->pos_x; 98 if (old_rg != new_rg) {
67 info.pos_y = pi->pos_y; 99 ofbi->region = new_rg;
68 info.out_width = pi->out_width; 100 set_fb_fix(fbi);
69 info.out_height = pi->out_height; 101 }
70 info.enabled = pi->enabled;
71 102
72 r = ovl->set_overlay_info(ovl, &info); 103 if (pi->enabled) {
73 if (r) 104 struct omap_overlay_info info;
74 goto out; 105
106 r = omapfb_setup_overlay(fbi, ovl, pi->pos_x, pi->pos_y,
107 pi->out_width, pi->out_height);
108 if (r)
109 goto undo;
75 110
76 if (ovl->manager) { 111 ovl->get_overlay_info(ovl, &info);
77 r = ovl->manager->apply(ovl->manager); 112
113 if (!info.enabled) {
114 info.enabled = pi->enabled;
115 r = ovl->set_overlay_info(ovl, &info);
116 if (r)
117 goto undo;
118 }
119 } else {
120 struct omap_overlay_info info;
121
122 ovl->get_overlay_info(ovl, &info);
123
124 info.enabled = pi->enabled;
125 info.pos_x = pi->pos_x;
126 info.pos_y = pi->pos_y;
127 info.out_width = pi->out_width;
128 info.out_height = pi->out_height;
129
130 r = ovl->set_overlay_info(ovl, &info);
78 if (r) 131 if (r)
79 goto out; 132 goto undo;
80 } 133 }
81 134
82out: 135 if (ovl->manager)
83 if (r) 136 ovl->manager->apply(ovl->manager);
84 dev_err(fbdev->dev, "setup_plane failed\n"); 137
138 return 0;
139
140 undo:
141 if (old_rg != new_rg) {
142 ofbi->region = old_rg;
143 set_fb_fix(fbi);
144 }
145
146 ovl->set_overlay_info(ovl, &old_info);
147 out:
148 dev_err(fbdev->dev, "setup_plane failed\n");
149
85 return r; 150 return r;
86} 151}
87 152
@@ -92,8 +157,8 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
92 if (ofbi->num_overlays != 1) { 157 if (ofbi->num_overlays != 1) {
93 memset(pi, 0, sizeof(*pi)); 158 memset(pi, 0, sizeof(*pi));
94 } else { 159 } else {
95 struct omap_overlay_info *ovli;
96 struct omap_overlay *ovl; 160 struct omap_overlay *ovl;
161 struct omap_overlay_info *ovli;
97 162
98 ovl = ofbi->overlays[0]; 163 ovl = ofbi->overlays[0];
99 ovli = &ovl->info; 164 ovli = &ovl->info;
@@ -103,6 +168,7 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
103 pi->enabled = ovli->enabled; 168 pi->enabled = ovli->enabled;
104 pi->channel_out = 0; /* xxx */ 169 pi->channel_out = 0; /* xxx */
105 pi->mirror = 0; 170 pi->mirror = 0;
171 pi->mem_idx = get_mem_idx(ofbi);
106 pi->out_width = ovli->out_width; 172 pi->out_width = ovli->out_width;
107 pi->out_height = ovli->out_height; 173 pi->out_height = ovli->out_height;
108 } 174 }
@@ -123,11 +189,24 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
123 189
124 size = PAGE_ALIGN(mi->size); 190 size = PAGE_ALIGN(mi->size);
125 191
126 rg = &ofbi->region; 192 rg = ofbi->region;
127 193
128 for (i = 0; i < ofbi->num_overlays; i++) { 194 if (atomic_read(&rg->map_count))
129 if (ofbi->overlays[i]->info.enabled) 195 return -EBUSY;
130 return -EBUSY; 196
197 for (i = 0; i < fbdev->num_fbs; i++) {
198 struct omapfb_info *ofbi2 = FB2OFB(fbdev->fbs[i]);
199 int j;
200
201 if (ofbi2->region != rg)
202 continue;
203
204 for (j = 0; j < ofbi2->num_overlays; j++) {
205 if (ofbi2->overlays[j]->info.enabled) {
206 r = -EBUSY;
207 return r;
208 }
209 }
131 } 210 }
132 211
133 if (rg->size != size || rg->type != mi->type) { 212 if (rg->size != size || rg->type != mi->type) {
@@ -146,7 +225,7 @@ static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
146 struct omapfb_info *ofbi = FB2OFB(fbi); 225 struct omapfb_info *ofbi = FB2OFB(fbi);
147 struct omapfb2_mem_region *rg; 226 struct omapfb2_mem_region *rg;
148 227
149 rg = &ofbi->region; 228 rg = ofbi->region;
150 memset(mi, 0, sizeof(*mi)); 229 memset(mi, 0, sizeof(*mi));
151 230
152 mi->size = rg->size; 231 mi->size = rg->size;
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index ccccf3d71a39..4a0588022b33 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -157,7 +157,7 @@ static void fill_fb(struct fb_info *fbi)
157 157
158static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot) 158static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot)
159{ 159{
160 const struct vrfb *vrfb = &ofbi->region.vrfb; 160 const struct vrfb *vrfb = &ofbi->region->vrfb;
161 unsigned offset; 161 unsigned offset;
162 162
163 switch (rot) { 163 switch (rot) {
@@ -185,27 +185,27 @@ static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot)
185static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot) 185static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot)
186{ 186{
187 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 187 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
188 return ofbi->region.vrfb.paddr[rot] 188 return ofbi->region->vrfb.paddr[rot]
189 + omapfb_get_vrfb_offset(ofbi, rot); 189 + omapfb_get_vrfb_offset(ofbi, rot);
190 } else { 190 } else {
191 return ofbi->region.paddr; 191 return ofbi->region->paddr;
192 } 192 }
193} 193}
194 194
195static u32 omapfb_get_region_paddr(const struct omapfb_info *ofbi) 195static u32 omapfb_get_region_paddr(const struct omapfb_info *ofbi)
196{ 196{
197 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 197 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
198 return ofbi->region.vrfb.paddr[0]; 198 return ofbi->region->vrfb.paddr[0];
199 else 199 else
200 return ofbi->region.paddr; 200 return ofbi->region->paddr;
201} 201}
202 202
203static void __iomem *omapfb_get_region_vaddr(const struct omapfb_info *ofbi) 203static void __iomem *omapfb_get_region_vaddr(const struct omapfb_info *ofbi)
204{ 204{
205 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 205 if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
206 return ofbi->region.vrfb.vaddr[0]; 206 return ofbi->region->vrfb.vaddr[0];
207 else 207 else
208 return ofbi->region.vaddr; 208 return ofbi->region->vaddr;
209} 209}
210 210
211static struct omapfb_colormode omapfb_colormodes[] = { 211static struct omapfb_colormode omapfb_colormodes[] = {
@@ -450,7 +450,7 @@ static int check_vrfb_fb_size(unsigned long region_size,
450static int check_fb_size(const struct omapfb_info *ofbi, 450static int check_fb_size(const struct omapfb_info *ofbi,
451 struct fb_var_screeninfo *var) 451 struct fb_var_screeninfo *var)
452{ 452{
453 unsigned long max_frame_size = ofbi->region.size; 453 unsigned long max_frame_size = ofbi->region->size;
454 int bytespp = var->bits_per_pixel >> 3; 454 int bytespp = var->bits_per_pixel >> 3;
455 unsigned long line_size = var->xres_virtual * bytespp; 455 unsigned long line_size = var->xres_virtual * bytespp;
456 456
@@ -497,7 +497,7 @@ static int check_fb_size(const struct omapfb_info *ofbi,
497static int setup_vrfb_rotation(struct fb_info *fbi) 497static int setup_vrfb_rotation(struct fb_info *fbi)
498{ 498{
499 struct omapfb_info *ofbi = FB2OFB(fbi); 499 struct omapfb_info *ofbi = FB2OFB(fbi);
500 struct omapfb2_mem_region *rg = &ofbi->region; 500 struct omapfb2_mem_region *rg = ofbi->region;
501 struct vrfb *vrfb = &rg->vrfb; 501 struct vrfb *vrfb = &rg->vrfb;
502 struct fb_var_screeninfo *var = &fbi->var; 502 struct fb_var_screeninfo *var = &fbi->var;
503 struct fb_fix_screeninfo *fix = &fbi->fix; 503 struct fb_fix_screeninfo *fix = &fbi->fix;
@@ -558,9 +558,9 @@ static int setup_vrfb_rotation(struct fb_info *fbi)
558 return r; 558 return r;
559 559
560 /* used by open/write in fbmem.c */ 560 /* used by open/write in fbmem.c */
561 fbi->screen_base = ofbi->region.vrfb.vaddr[0]; 561 fbi->screen_base = ofbi->region->vrfb.vaddr[0];
562 562
563 fix->smem_start = ofbi->region.vrfb.paddr[0]; 563 fix->smem_start = ofbi->region->vrfb.paddr[0];
564 564
565 switch (var->nonstd) { 565 switch (var->nonstd) {
566 case OMAPFB_COLOR_YUV422: 566 case OMAPFB_COLOR_YUV422:
@@ -599,7 +599,7 @@ void set_fb_fix(struct fb_info *fbi)
599 struct fb_fix_screeninfo *fix = &fbi->fix; 599 struct fb_fix_screeninfo *fix = &fbi->fix;
600 struct fb_var_screeninfo *var = &fbi->var; 600 struct fb_var_screeninfo *var = &fbi->var;
601 struct omapfb_info *ofbi = FB2OFB(fbi); 601 struct omapfb_info *ofbi = FB2OFB(fbi);
602 struct omapfb2_mem_region *rg = &ofbi->region; 602 struct omapfb2_mem_region *rg = ofbi->region;
603 603
604 DBG("set_fb_fix\n"); 604 DBG("set_fb_fix\n");
605 605
@@ -688,7 +688,7 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
688 return -EINVAL; 688 return -EINVAL;
689 689
690 /* When no memory is allocated ignore the size check */ 690 /* When no memory is allocated ignore the size check */
691 if (ofbi->region.size != 0 && check_fb_size(ofbi, var)) 691 if (ofbi->region->size != 0 && check_fb_size(ofbi, var))
692 return -EINVAL; 692 return -EINVAL;
693 693
694 if (var->xres + var->xoffset > var->xres_virtual) 694 if (var->xres + var->xoffset > var->xres_virtual)
@@ -856,7 +856,7 @@ static void omapfb_calc_addr(const struct omapfb_info *ofbi,
856} 856}
857 857
858/* setup overlay according to the fb */ 858/* setup overlay according to the fb */
859static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, 859int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
860 u16 posx, u16 posy, u16 outw, u16 outh) 860 u16 posx, u16 posy, u16 outw, u16 outh)
861{ 861{
862 int r = 0; 862 int r = 0;
@@ -892,7 +892,7 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
892 yres = var->yres; 892 yres = var->yres;
893 } 893 }
894 894
895 if (ofbi->region.size) 895 if (ofbi->region->size)
896 omapfb_calc_addr(ofbi, var, fix, rotation, 896 omapfb_calc_addr(ofbi, var, fix, rotation,
897 &data_start_p, &data_start_v); 897 &data_start_p, &data_start_v);
898 898
@@ -971,7 +971,7 @@ int omapfb_apply_changes(struct fb_info *fbi, int init)
971 971
972 DBG("apply_changes, fb %d, ovl %d\n", ofbi->id, ovl->id); 972 DBG("apply_changes, fb %d, ovl %d\n", ofbi->id, ovl->id);
973 973
974 if (ofbi->region.size == 0) { 974 if (ofbi->region->size == 0) {
975 /* the fb is not available. disable the overlay */ 975 /* the fb is not available. disable the overlay */
976 omapfb_overlay_enable(ovl, 0); 976 omapfb_overlay_enable(ovl, 0);
977 if (!init && ovl->manager) 977 if (!init && ovl->manager)
@@ -1071,16 +1071,16 @@ static int omapfb_pan_display(struct fb_var_screeninfo *var,
1071 1071
1072static void mmap_user_open(struct vm_area_struct *vma) 1072static void mmap_user_open(struct vm_area_struct *vma)
1073{ 1073{
1074 struct omapfb_info *ofbi = (struct omapfb_info *)vma->vm_private_data; 1074 struct omapfb2_mem_region *rg = vma->vm_private_data;
1075 1075
1076 atomic_inc(&ofbi->map_count); 1076 atomic_inc(&rg->map_count);
1077} 1077}
1078 1078
1079static void mmap_user_close(struct vm_area_struct *vma) 1079static void mmap_user_close(struct vm_area_struct *vma)
1080{ 1080{
1081 struct omapfb_info *ofbi = (struct omapfb_info *)vma->vm_private_data; 1081 struct omapfb2_mem_region *rg = vma->vm_private_data;
1082 1082
1083 atomic_dec(&ofbi->map_count); 1083 atomic_dec(&rg->map_count);
1084} 1084}
1085 1085
1086static struct vm_operations_struct mmap_user_ops = { 1086static struct vm_operations_struct mmap_user_ops = {
@@ -1092,6 +1092,7 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
1092{ 1092{
1093 struct omapfb_info *ofbi = FB2OFB(fbi); 1093 struct omapfb_info *ofbi = FB2OFB(fbi);
1094 struct fb_fix_screeninfo *fix = &fbi->fix; 1094 struct fb_fix_screeninfo *fix = &fbi->fix;
1095 struct omapfb2_mem_region *rg;
1095 unsigned long off; 1096 unsigned long off;
1096 unsigned long start; 1097 unsigned long start;
1097 u32 len; 1098 u32 len;
@@ -1102,6 +1103,8 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
1102 return -EINVAL; 1103 return -EINVAL;
1103 off = vma->vm_pgoff << PAGE_SHIFT; 1104 off = vma->vm_pgoff << PAGE_SHIFT;
1104 1105
1106 rg = ofbi->region;
1107
1105 start = omapfb_get_region_paddr(ofbi); 1108 start = omapfb_get_region_paddr(ofbi);
1106 len = fix->smem_len; 1109 len = fix->smem_len;
1107 if (off >= len) 1110 if (off >= len)
@@ -1117,12 +1120,12 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
1117 vma->vm_flags |= VM_IO | VM_RESERVED; 1120 vma->vm_flags |= VM_IO | VM_RESERVED;
1118 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); 1121 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
1119 vma->vm_ops = &mmap_user_ops; 1122 vma->vm_ops = &mmap_user_ops;
1120 vma->vm_private_data = ofbi; 1123 vma->vm_private_data = rg;
1121 if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, 1124 if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
1122 vma->vm_end - vma->vm_start, vma->vm_page_prot)) 1125 vma->vm_end - vma->vm_start, vma->vm_page_prot))
1123 return -EAGAIN; 1126 return -EAGAIN;
1124 /* vm_ops.open won't be called for mmap itself. */ 1127 /* vm_ops.open won't be called for mmap itself. */
1125 atomic_inc(&ofbi->map_count); 1128 atomic_inc(&rg->map_count);
1126 return 0; 1129 return 0;
1127} 1130}
1128 1131
@@ -1312,7 +1315,9 @@ static void omapfb_free_fbmem(struct fb_info *fbi)
1312 struct omapfb2_device *fbdev = ofbi->fbdev; 1315 struct omapfb2_device *fbdev = ofbi->fbdev;
1313 struct omapfb2_mem_region *rg; 1316 struct omapfb2_mem_region *rg;
1314 1317
1315 rg = &ofbi->region; 1318 rg = ofbi->region;
1319
1320 WARN_ON(atomic_read(&rg->map_count));
1316 1321
1317 if (rg->paddr) 1322 if (rg->paddr)
1318 if (omap_vram_free(rg->paddr, rg->size)) 1323 if (omap_vram_free(rg->paddr, rg->size))
@@ -1367,8 +1372,15 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
1367 void __iomem *vaddr; 1372 void __iomem *vaddr;
1368 int r; 1373 int r;
1369 1374
1370 rg = &ofbi->region; 1375 rg = ofbi->region;
1371 memset(rg, 0, sizeof(*rg)); 1376
1377 rg->paddr = 0;
1378 rg->vaddr = NULL;
1379 memset(&rg->vrfb, 0, sizeof rg->vrfb);
1380 rg->size = 0;
1381 rg->type = 0;
1382 rg->alloc = false;
1383 rg->map = false;
1372 1384
1373 size = PAGE_ALIGN(size); 1385 size = PAGE_ALIGN(size);
1374 1386
@@ -1621,7 +1633,7 @@ static int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev)
1621 for (i = 0; i < fbdev->num_fbs; i++) { 1633 for (i = 0; i < fbdev->num_fbs; i++) {
1622 struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); 1634 struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]);
1623 struct omapfb2_mem_region *rg; 1635 struct omapfb2_mem_region *rg;
1624 rg = &ofbi->region; 1636 rg = ofbi->region;
1625 1637
1626 DBG("region%d phys %08x virt %p size=%lu\n", 1638 DBG("region%d phys %08x virt %p size=%lu\n",
1627 i, 1639 i,
@@ -1638,7 +1650,7 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
1638 struct omapfb_info *ofbi = FB2OFB(fbi); 1650 struct omapfb_info *ofbi = FB2OFB(fbi);
1639 struct omapfb2_device *fbdev = ofbi->fbdev; 1651 struct omapfb2_device *fbdev = ofbi->fbdev;
1640 struct omap_dss_device *display = fb2display(fbi); 1652 struct omap_dss_device *display = fb2display(fbi);
1641 struct omapfb2_mem_region *rg = &ofbi->region; 1653 struct omapfb2_mem_region *rg = ofbi->region;
1642 unsigned long old_size = rg->size; 1654 unsigned long old_size = rg->size;
1643 unsigned long old_paddr = rg->paddr; 1655 unsigned long old_paddr = rg->paddr;
1644 int old_type = rg->type; 1656 int old_type = rg->type;
@@ -1721,7 +1733,7 @@ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
1721 fbi->flags = FBINFO_FLAG_DEFAULT; 1733 fbi->flags = FBINFO_FLAG_DEFAULT;
1722 fbi->pseudo_palette = fbdev->pseudo_palette; 1734 fbi->pseudo_palette = fbdev->pseudo_palette;
1723 1735
1724 if (ofbi->region.size == 0) { 1736 if (ofbi->region->size == 0) {
1725 clear_fb_info(fbi); 1737 clear_fb_info(fbi);
1726 return 0; 1738 return 0;
1727 } 1739 }
@@ -1883,6 +1895,9 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
1883 ofbi->fbdev = fbdev; 1895 ofbi->fbdev = fbdev;
1884 ofbi->id = i; 1896 ofbi->id = i;
1885 1897
1898 ofbi->region = &fbdev->regions[i];
1899 ofbi->region->id = i;
1900
1886 /* assign these early, so that fb alloc can use them */ 1901 /* assign these early, so that fb alloc can use them */
1887 ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB : 1902 ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB :
1888 OMAP_DSS_ROT_DMA; 1903 OMAP_DSS_ROT_DMA;
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index 5179219128bd..dea1aa46a7db 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -64,7 +64,7 @@ static ssize_t store_rotate_type(struct device *dev,
64 if (rot_type == ofbi->rotation_type) 64 if (rot_type == ofbi->rotation_type)
65 goto out; 65 goto out;
66 66
67 if (ofbi->region.size) { 67 if (ofbi->region->size) {
68 r = -EBUSY; 68 r = -EBUSY;
69 goto out; 69 goto out;
70 } 70 }
@@ -408,7 +408,7 @@ static ssize_t show_size(struct device *dev,
408 struct fb_info *fbi = dev_get_drvdata(dev); 408 struct fb_info *fbi = dev_get_drvdata(dev);
409 struct omapfb_info *ofbi = FB2OFB(fbi); 409 struct omapfb_info *ofbi = FB2OFB(fbi);
410 410
411 return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region.size); 411 return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region->size);
412} 412}
413 413
414static ssize_t store_size(struct device *dev, struct device_attribute *attr, 414static ssize_t store_size(struct device *dev, struct device_attribute *attr,
@@ -416,6 +416,8 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
416{ 416{
417 struct fb_info *fbi = dev_get_drvdata(dev); 417 struct fb_info *fbi = dev_get_drvdata(dev);
418 struct omapfb_info *ofbi = FB2OFB(fbi); 418 struct omapfb_info *ofbi = FB2OFB(fbi);
419 struct omapfb2_device *fbdev = ofbi->fbdev;
420 struct omapfb2_mem_region *rg;
419 unsigned long size; 421 unsigned long size;
420 int r; 422 int r;
421 int i; 423 int i;
@@ -425,15 +427,30 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
425 if (!lock_fb_info(fbi)) 427 if (!lock_fb_info(fbi))
426 return -ENODEV; 428 return -ENODEV;
427 429
428 for (i = 0; i < ofbi->num_overlays; i++) { 430 rg = ofbi->region;
429 if (ofbi->overlays[i]->info.enabled) { 431
430 r = -EBUSY; 432 if (atomic_read(&rg->map_count)) {
431 goto out; 433 r = -EBUSY;
434 goto out;
435 }
436
437 for (i = 0; i < fbdev->num_fbs; i++) {
438 struct omapfb_info *ofbi2 = FB2OFB(fbdev->fbs[i]);
439 int j;
440
441 if (ofbi2->region != rg)
442 continue;
443
444 for (j = 0; j < ofbi2->num_overlays; j++) {
445 if (ofbi2->overlays[j]->info.enabled) {
446 r = -EBUSY;
447 goto out;
448 }
432 } 449 }
433 } 450 }
434 451
435 if (size != ofbi->region.size) { 452 if (size != ofbi->region->size) {
436 r = omapfb_realloc_fbmem(fbi, size, ofbi->region.type); 453 r = omapfb_realloc_fbmem(fbi, size, ofbi->region->type);
437 if (r) { 454 if (r) {
438 dev_err(dev, "realloc fbmem failed\n"); 455 dev_err(dev, "realloc fbmem failed\n");
439 goto out; 456 goto out;
@@ -453,7 +470,7 @@ static ssize_t show_phys(struct device *dev,
453 struct fb_info *fbi = dev_get_drvdata(dev); 470 struct fb_info *fbi = dev_get_drvdata(dev);
454 struct omapfb_info *ofbi = FB2OFB(fbi); 471 struct omapfb_info *ofbi = FB2OFB(fbi);
455 472
456 return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region.paddr); 473 return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region->paddr);
457} 474}
458 475
459static ssize_t show_virt(struct device *dev, 476static ssize_t show_virt(struct device *dev,
@@ -462,7 +479,7 @@ static ssize_t show_virt(struct device *dev,
462 struct fb_info *fbi = dev_get_drvdata(dev); 479 struct fb_info *fbi = dev_get_drvdata(dev);
463 struct omapfb_info *ofbi = FB2OFB(fbi); 480 struct omapfb_info *ofbi = FB2OFB(fbi);
464 481
465 return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region.vaddr); 482 return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region->vaddr);
466} 483}
467 484
468static struct device_attribute omapfb_attrs[] = { 485static struct device_attribute omapfb_attrs[] = {
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index c9866be0460a..02f1ba9b228c 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -44,6 +44,7 @@ extern unsigned int omapfb_debug;
44#define OMAPFB_MAX_OVL_PER_FB 3 44#define OMAPFB_MAX_OVL_PER_FB 3
45 45
46struct omapfb2_mem_region { 46struct omapfb2_mem_region {
47 int id;
47 u32 paddr; 48 u32 paddr;
48 void __iomem *vaddr; 49 void __iomem *vaddr;
49 struct vrfb vrfb; 50 struct vrfb vrfb;
@@ -51,13 +52,13 @@ struct omapfb2_mem_region {
51 u8 type; /* OMAPFB_PLANE_MEM_* */ 52 u8 type; /* OMAPFB_PLANE_MEM_* */
52 bool alloc; /* allocated by the driver */ 53 bool alloc; /* allocated by the driver */
53 bool map; /* kernel mapped by the driver */ 54 bool map; /* kernel mapped by the driver */
55 atomic_t map_count;
54}; 56};
55 57
56/* appended to fb_info */ 58/* appended to fb_info */
57struct omapfb_info { 59struct omapfb_info {
58 int id; 60 int id;
59 struct omapfb2_mem_region region; 61 struct omapfb2_mem_region *region;
60 atomic_t map_count;
61 int num_overlays; 62 int num_overlays;
62 struct omap_overlay *overlays[OMAPFB_MAX_OVL_PER_FB]; 63 struct omap_overlay *overlays[OMAPFB_MAX_OVL_PER_FB];
63 struct omapfb2_device *fbdev; 64 struct omapfb2_device *fbdev;
@@ -76,6 +77,7 @@ struct omapfb2_device {
76 77
77 unsigned num_fbs; 78 unsigned num_fbs;
78 struct fb_info *fbs[10]; 79 struct fb_info *fbs[10];
80 struct omapfb2_mem_region regions[10];
79 81
80 unsigned num_displays; 82 unsigned num_displays;
81 struct omap_dss_device *displays[10]; 83 struct omap_dss_device *displays[10];
@@ -117,6 +119,9 @@ int omapfb_update_window(struct fb_info *fbi,
117int dss_mode_to_fb_mode(enum omap_color_mode dssmode, 119int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
118 struct fb_var_screeninfo *var); 120 struct fb_var_screeninfo *var);
119 121
122int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
123 u16 posx, u16 posy, u16 outw, u16 outh);
124
120/* find the display connected to this fb, if any */ 125/* find the display connected to this fb, if any */
121static inline struct omap_dss_device *fb2display(struct fb_info *fbi) 126static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
122{ 127{