aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/omapfb/omapfb-main.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-main.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-main.c')
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c62
1 files changed, 54 insertions, 8 deletions
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 4a0588022b33..eb4338bbaa2b 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1019,36 +1019,48 @@ err:
1019 * DO NOT MODIFY PAR */ 1019 * DO NOT MODIFY PAR */
1020static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi) 1020static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
1021{ 1021{
1022 struct omapfb_info *ofbi = FB2OFB(fbi);
1022 int r; 1023 int r;
1023 1024
1024 DBG("check_var(%d)\n", FB2OFB(fbi)->id); 1025 DBG("check_var(%d)\n", FB2OFB(fbi)->id);
1025 1026
1027 omapfb_get_mem_region(ofbi->region);
1028
1026 r = check_fb_var(fbi, var); 1029 r = check_fb_var(fbi, var);
1027 1030
1031 omapfb_put_mem_region(ofbi->region);
1032
1028 return r; 1033 return r;
1029} 1034}
1030 1035
1031/* set the video mode according to info->var */ 1036/* set the video mode according to info->var */
1032static int omapfb_set_par(struct fb_info *fbi) 1037static int omapfb_set_par(struct fb_info *fbi)
1033{ 1038{
1039 struct omapfb_info *ofbi = FB2OFB(fbi);
1034 int r; 1040 int r;
1035 1041
1036 DBG("set_par(%d)\n", FB2OFB(fbi)->id); 1042 DBG("set_par(%d)\n", FB2OFB(fbi)->id);
1037 1043
1044 omapfb_get_mem_region(ofbi->region);
1045
1038 set_fb_fix(fbi); 1046 set_fb_fix(fbi);
1039 1047
1040 r = setup_vrfb_rotation(fbi); 1048 r = setup_vrfb_rotation(fbi);
1041 if (r) 1049 if (r)
1042 return r; 1050 goto out;
1043 1051
1044 r = omapfb_apply_changes(fbi, 0); 1052 r = omapfb_apply_changes(fbi, 0);
1045 1053
1054 out:
1055 omapfb_put_mem_region(ofbi->region);
1056
1046 return r; 1057 return r;
1047} 1058}
1048 1059
1049static int omapfb_pan_display(struct fb_var_screeninfo *var, 1060static int omapfb_pan_display(struct fb_var_screeninfo *var,
1050 struct fb_info *fbi) 1061 struct fb_info *fbi)
1051{ 1062{
1063 struct omapfb_info *ofbi = FB2OFB(fbi);
1052 struct fb_var_screeninfo new_var; 1064 struct fb_var_screeninfo new_var;
1053 int r; 1065 int r;
1054 1066
@@ -1064,8 +1076,12 @@ static int omapfb_pan_display(struct fb_var_screeninfo *var,
1064 1076
1065 fbi->var = new_var; 1077 fbi->var = new_var;
1066 1078
1079 omapfb_get_mem_region(ofbi->region);
1080
1067 r = omapfb_apply_changes(fbi, 0); 1081 r = omapfb_apply_changes(fbi, 0);
1068 1082
1083 omapfb_put_mem_region(ofbi->region);
1084
1069 return r; 1085 return r;
1070} 1086}
1071 1087
@@ -1073,14 +1089,18 @@ static void mmap_user_open(struct vm_area_struct *vma)
1073{ 1089{
1074 struct omapfb2_mem_region *rg = vma->vm_private_data; 1090 struct omapfb2_mem_region *rg = vma->vm_private_data;
1075 1091
1092 omapfb_get_mem_region(rg);
1076 atomic_inc(&rg->map_count); 1093 atomic_inc(&rg->map_count);
1094 omapfb_put_mem_region(rg);
1077} 1095}
1078 1096
1079static void mmap_user_close(struct vm_area_struct *vma) 1097static void mmap_user_close(struct vm_area_struct *vma)
1080{ 1098{
1081 struct omapfb2_mem_region *rg = vma->vm_private_data; 1099 struct omapfb2_mem_region *rg = vma->vm_private_data;
1082 1100
1101 omapfb_get_mem_region(rg);
1083 atomic_dec(&rg->map_count); 1102 atomic_dec(&rg->map_count);
1103 omapfb_put_mem_region(rg);
1084} 1104}
1085 1105
1086static struct vm_operations_struct mmap_user_ops = { 1106static struct vm_operations_struct mmap_user_ops = {
@@ -1096,6 +1116,7 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
1096 unsigned long off; 1116 unsigned long off;
1097 unsigned long start; 1117 unsigned long start;
1098 u32 len; 1118 u32 len;
1119 int r = -EINVAL;
1099 1120
1100 if (vma->vm_end - vma->vm_start == 0) 1121 if (vma->vm_end - vma->vm_start == 0)
1101 return 0; 1122 return 0;
@@ -1103,14 +1124,14 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
1103 return -EINVAL; 1124 return -EINVAL;
1104 off = vma->vm_pgoff << PAGE_SHIFT; 1125 off = vma->vm_pgoff << PAGE_SHIFT;
1105 1126
1106 rg = ofbi->region; 1127 rg = omapfb_get_mem_region(ofbi->region);
1107 1128
1108 start = omapfb_get_region_paddr(ofbi); 1129 start = omapfb_get_region_paddr(ofbi);
1109 len = fix->smem_len; 1130 len = fix->smem_len;
1110 if (off >= len) 1131 if (off >= len)
1111 return -EINVAL; 1132 goto error;
1112 if ((vma->vm_end - vma->vm_start + off) > len) 1133 if ((vma->vm_end - vma->vm_start + off) > len)
1113 return -EINVAL; 1134 goto error;
1114 1135
1115 off += start; 1136 off += start;
1116 1137
@@ -1122,11 +1143,23 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
1122 vma->vm_ops = &mmap_user_ops; 1143 vma->vm_ops = &mmap_user_ops;
1123 vma->vm_private_data = rg; 1144 vma->vm_private_data = rg;
1124 if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, 1145 if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
1125 vma->vm_end - vma->vm_start, vma->vm_page_prot)) 1146 vma->vm_end - vma->vm_start,
1126 return -EAGAIN; 1147 vma->vm_page_prot)) {
1148 r = -EAGAIN;
1149 goto error;
1150 }
1151
1127 /* vm_ops.open won't be called for mmap itself. */ 1152 /* vm_ops.open won't be called for mmap itself. */
1128 atomic_inc(&rg->map_count); 1153 atomic_inc(&rg->map_count);
1154
1155 omapfb_put_mem_region(rg);
1156
1129 return 0; 1157 return 0;
1158
1159 error:
1160 omapfb_put_mem_region(ofbi->region);
1161
1162 return r;
1130} 1163}
1131 1164
1132/* Store a single color palette entry into a pseudo palette or the hardware 1165/* Store a single color palette entry into a pseudo palette or the hardware
@@ -1897,6 +1930,7 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
1897 1930
1898 ofbi->region = &fbdev->regions[i]; 1931 ofbi->region = &fbdev->regions[i];
1899 ofbi->region->id = i; 1932 ofbi->region->id = i;
1933 mutex_init(&ofbi->region->mtx);
1900 1934
1901 /* assign these early, so that fb alloc can use them */ 1935 /* assign these early, so that fb alloc can use them */
1902 ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB : 1936 ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB :
@@ -1927,7 +1961,13 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
1927 1961
1928 /* setup fb_infos */ 1962 /* setup fb_infos */
1929 for (i = 0; i < fbdev->num_fbs; i++) { 1963 for (i = 0; i < fbdev->num_fbs; i++) {
1930 r = omapfb_fb_init(fbdev, fbdev->fbs[i]); 1964 struct fb_info *fbi = fbdev->fbs[i];
1965 struct omapfb_info *ofbi = FB2OFB(fbi);
1966
1967 omapfb_get_mem_region(ofbi->region);
1968 r = omapfb_fb_init(fbdev, fbi);
1969 omapfb_put_mem_region(ofbi->region);
1970
1931 if (r) { 1971 if (r) {
1932 dev_err(fbdev->dev, "failed to setup fb_info\n"); 1972 dev_err(fbdev->dev, "failed to setup fb_info\n");
1933 return r; 1973 return r;
@@ -1948,7 +1988,13 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
1948 DBG("framebuffers registered\n"); 1988 DBG("framebuffers registered\n");
1949 1989
1950 for (i = 0; i < fbdev->num_fbs; i++) { 1990 for (i = 0; i < fbdev->num_fbs; i++) {
1951 r = omapfb_apply_changes(fbdev->fbs[i], 1); 1991 struct fb_info *fbi = fbdev->fbs[i];
1992 struct omapfb_info *ofbi = FB2OFB(fbi);
1993
1994 omapfb_get_mem_region(ofbi->region);
1995 r = omapfb_apply_changes(fbi, 1);
1996 omapfb_put_mem_region(ofbi->region);
1997
1952 if (r) { 1998 if (r) {
1953 dev_err(fbdev->dev, "failed to change mode\n"); 1999 dev_err(fbdev->dev, "failed to change mode\n");
1954 return r; 2000 return r;