Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/vapier...
[safe/jmp/linux-2.6] / drivers / video / omap / omapfb_main.c
index 8862233..0d0c8c8 100644 (file)
@@ -67,6 +67,7 @@ static struct caps_table_struct ctrl_caps[] = {
        { OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE, "pixel double window" },
        { OMAPFB_CAPS_WINDOW_SCALE,   "scale window" },
        { OMAPFB_CAPS_WINDOW_OVERLAY, "overlay window" },
+       { OMAPFB_CAPS_WINDOW_ROTATE,  "rotate window" },
        { OMAPFB_CAPS_SET_BACKLIGHT,  "backlight setting" },
 };
 
@@ -215,6 +216,15 @@ static int ctrl_change_mode(struct fb_info *fbi)
                                 offset, var->xres_virtual,
                                 plane->info.pos_x, plane->info.pos_y,
                                 var->xres, var->yres, plane->color_mode);
+       if (r < 0)
+               return r;
+
+       if (fbdev->ctrl->set_rotate != NULL) {
+               r = fbdev->ctrl->set_rotate(var->rotate);
+               if (r < 0)
+                       return r;
+       }
+
        if (fbdev->ctrl->set_scale != NULL)
                r = fbdev->ctrl->set_scale(plane->idx,
                                   var->xres, var->yres,
@@ -383,7 +393,7 @@ static void omapfb_sync(struct fb_info *fbi)
  * Set fb_info.fix fields and also updates fbdev.
  * When calling this fb_info.var must be set up already.
  */
-static void set_fb_fix(struct fb_info *fbi)
+static void set_fb_fix(struct fb_info *fbi, int from_init)
 {
        struct fb_fix_screeninfo *fix = &fbi->fix;
        struct fb_var_screeninfo *var = &fbi->var;
@@ -393,10 +403,16 @@ static void set_fb_fix(struct fb_info *fbi)
 
        rg = &plane->fbdev->mem_desc.region[plane->idx];
        fbi->screen_base        = rg->vaddr;
-       mutex_lock(&fbi->mm_lock);
-       fix->smem_start         = rg->paddr;
-       fix->smem_len           = rg->size;
-       mutex_unlock(&fbi->mm_lock);
+
+       if (!from_init) {
+               mutex_lock(&fbi->mm_lock);
+               fix->smem_start         = rg->paddr;
+               fix->smem_len           = rg->size;
+               mutex_unlock(&fbi->mm_lock);
+       } else {
+               fix->smem_start         = rg->paddr;
+               fix->smem_len           = rg->size;
+       }
 
        fix->type = FB_TYPE_PACKED_PIXELS;
        bpp = var->bits_per_pixel;
@@ -554,7 +570,6 @@ static int set_fb_var(struct fb_info *fbi,
                var->xoffset = var->xres_virtual - var->xres;
        if (var->yres + var->yoffset > var->yres_virtual)
                var->yoffset = var->yres_virtual - var->yres;
-       line_size = var->xres * bpp / 8;
 
        if (plane->color_mode == OMAPFB_COLOR_RGB444) {
                var->red.offset   = 8; var->red.length   = 4;
@@ -600,7 +615,7 @@ static void omapfb_rotate(struct fb_info *fbi, int rotate)
        struct omapfb_device *fbdev = plane->fbdev;
 
        omapfb_rqueue_lock(fbdev);
-       if (cpu_is_omap15xx() && rotate != fbi->var.rotate) {
+       if (rotate != fbi->var.rotate) {
                struct fb_var_screeninfo *new_var = &fbdev->new_var;
 
                memcpy(new_var, &fbi->var, sizeof(*new_var));
@@ -695,7 +710,7 @@ static int omapfb_set_par(struct fb_info *fbi)
        int r = 0;
 
        omapfb_rqueue_lock(fbdev);
-       set_fb_fix(fbi);
+       set_fb_fix(fbi, 0);
        r = ctrl_change_mode(fbi);
        omapfb_rqueue_unlock(fbdev);
 
@@ -707,28 +722,42 @@ int omapfb_update_window_async(struct fb_info *fbi,
                                void (*callback)(void *),
                                void *callback_data)
 {
+       int xres, yres;
        struct omapfb_plane_struct *plane = fbi->par;
        struct omapfb_device *fbdev = plane->fbdev;
-       struct fb_var_screeninfo *var;
+       struct fb_var_screeninfo *var = &fbi->var;
 
-       var = &fbi->var;
-       if (win->x >= var->xres || win->y >= var->yres ||
-           win->out_x > var->xres || win->out_y >= var->yres)
+       switch (var->rotate) {
+       case 0:
+       case 180:
+               xres = fbdev->panel->x_res;
+               yres = fbdev->panel->y_res;
+               break;
+       case 90:
+       case 270:
+               xres = fbdev->panel->y_res;
+               yres = fbdev->panel->x_res;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (win->x >= xres || win->y >= yres ||
+           win->out_x > xres || win->out_y > yres)
                return -EINVAL;
 
        if (!fbdev->ctrl->update_window ||
            fbdev->ctrl->get_update_mode() != OMAPFB_MANUAL_UPDATE)
                return -ENODEV;
 
-       if (win->x + win->width >= var->xres)
-               win->width = var->xres - win->x;
-       if (win->y + win->height >= var->yres)
-               win->height = var->yres - win->y;
-       /* The out sizes should be cropped to the LCD size */
-       if (win->out_x + win->out_width > fbdev->panel->x_res)
-               win->out_width = fbdev->panel->x_res - win->out_x;
-       if (win->out_y + win->out_height > fbdev->panel->y_res)
-               win->out_height = fbdev->panel->y_res - win->out_y;
+       if (win->x + win->width > xres)
+               win->width = xres - win->x;
+       if (win->y + win->height > yres)
+               win->height = yres - win->y;
+       if (win->out_x + win->out_width > xres)
+               win->out_width = xres - win->out_x;
+       if (win->out_y + win->out_height > yres)
+               win->out_height = yres - win->out_y;
        if (!win->width || !win->height || !win->out_width || !win->out_height)
                return 0;
 
@@ -881,7 +910,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
                if (old_size != size) {
                        if (size) {
                                memcpy(&fbi->var, new_var, sizeof(fbi->var));
-                               set_fb_fix(fbi);
+                               set_fb_fix(fbi, 0);
                        } else {
                                /*
                                 * Set these explicitly to indicate that the
@@ -1481,7 +1510,7 @@ static int fbinfo_init(struct omapfb_device *fbdev, struct fb_info *info)
        var->bits_per_pixel = fbdev->panel->bpp;
 
        set_fb_var(info, var);
-       set_fb_fix(info);
+       set_fb_fix(info, 1);
 
        r = fb_alloc_cmap(&info->cmap, 16, 0);
        if (r != 0)
@@ -1699,8 +1728,8 @@ static int omapfb_do_probe(struct platform_device *pdev,
 
        pr_info("omapfb: configured for panel %s\n", fbdev->panel->name);
 
-       def_vxres = def_vxres ? : fbdev->panel->x_res;
-       def_vyres = def_vyres ? : fbdev->panel->y_res;
+       def_vxres = def_vxres ? def_vxres : fbdev->panel->x_res;
+       def_vyres = def_vyres ? def_vyres : fbdev->panel->y_res;
 
        init_state++;
 
@@ -1822,8 +1851,8 @@ static int omapfb_suspend(struct platform_device *pdev, pm_message_t mesg)
 {
        struct omapfb_device *fbdev = platform_get_drvdata(pdev);
 
-       omapfb_blank(FB_BLANK_POWERDOWN, fbdev->fb_info[0]);
-
+       if (fbdev != NULL)
+               omapfb_blank(FB_BLANK_POWERDOWN, fbdev->fb_info[0]);
        return 0;
 }
 
@@ -1832,7 +1861,8 @@ static int omapfb_resume(struct platform_device *pdev)
 {
        struct omapfb_device *fbdev = platform_get_drvdata(pdev);
 
-       omapfb_blank(FB_BLANK_UNBLANK, fbdev->fb_info[0]);
+       if (fbdev != NULL)
+               omapfb_blank(FB_BLANK_UNBLANK, fbdev->fb_info[0]);
        return 0;
 }