const struct linux_logo *logo;
 } fb_logo;
 
-int fb_prepare_logo(struct fb_info *info)
+static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height)
+{
+       u32 size = width * height, i;
+
+       out += size - 1;
+
+       for (i = size; i--; )
+               *out-- = *in++;
+}
+
+static void fb_rotate_logo_cw(const u8 *in, u8 *out, u32 width, u32 height)
+{
+       int i, j, w = width - 1;
+
+       for (i = 0; i < height; i++)
+               for (j = 0; j < width; j++)
+                       out[height * j + w - i] = *in++;
+}
+
+static void fb_rotate_logo_ccw(const u8 *in, u8 *out, u32 width, u32 height)
+{
+       int i, j, w = width - 1;
+
+       for (i = 0; i < height; i++)
+               for (j = 0; j < width; j++)
+                       out[height * (w - j) + i] = *in++;
+}
+
+static void fb_rotate_logo(struct fb_info *info, u8 *dst,
+                          struct fb_image *image, int rotate)
+{
+       u32 tmp;
+
+       if (rotate == FB_ROTATE_UD) {
+               image->dx = info->var.xres - image->width;
+               image->dy = info->var.yres - image->height;
+               fb_rotate_logo_ud(image->data, dst, image->width,
+                                 image->height);
+       } else if (rotate == FB_ROTATE_CW) {
+               tmp = image->width;
+               image->width = image->height;
+               image->height = tmp;
+               image->dx = info->var.xres - image->height;
+               fb_rotate_logo_cw(image->data, dst, image->width,
+                                 image->height);
+       } else if (rotate == FB_ROTATE_CCW) {
+               tmp = image->width;
+               image->width = image->height;
+               image->height = tmp;
+               image->dy = info->var.yres - image->width;
+               fb_rotate_logo_ccw(image->data, dst, image->width,
+                                  image->height);
+       }
+
+       image->data = dst;
+}
+
+static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,
+                           int rotate)
+{
+       int x;
+
+       if (rotate == FB_ROTATE_UR) {
+               for (x = 0; x < num_online_cpus() &&
+                            x * (fb_logo.logo->width + 8) <=
+                            info->var.xres - fb_logo.logo->width; x++) {
+                       info->fbops->fb_imageblit(info, image);
+                       image->dx += fb_logo.logo->width + 8;
+               }
+       } else if (rotate == FB_ROTATE_UD) {
+               for (x = 0; x < num_online_cpus() &&
+                            x * (fb_logo.logo->width + 8) <=
+                            info->var.xres - fb_logo.logo->width; x++) {
+                       info->fbops->fb_imageblit(info, image);
+                       image->dx -= fb_logo.logo->width + 8;
+               }
+       } else if (rotate == FB_ROTATE_CW) {
+               for (x = 0; x < num_online_cpus() &&
+                            x * (fb_logo.logo->width + 8) <=
+                            info->var.yres - fb_logo.logo->width; x++) {
+                       info->fbops->fb_imageblit(info, image);
+                       image->dy += fb_logo.logo->width + 8;
+               }
+       } else if (rotate == FB_ROTATE_CCW) {
+               for (x = 0; x < num_online_cpus() &&
+                            x * (fb_logo.logo->width + 8) <=
+                            info->var.yres - fb_logo.logo->width; x++) {
+                       info->fbops->fb_imageblit(info, image);
+                       image->dy -= fb_logo.logo->width + 8;
+               }
+       }
+}
+
+int fb_prepare_logo(struct fb_info *info, int rotate)
 {
        int depth = fb_get_color_depth(&info->var, &info->fix);
+       int yres;
 
        memset(&fb_logo, 0, sizeof(struct logo_data));
 
        /* Return if no suitable logo was found */
        fb_logo.logo = fb_find_logo(depth);
        
-       if (!fb_logo.logo || fb_logo.logo->height > info->var.yres) {
+       if (rotate == FB_ROTATE_UR || rotate == FB_ROTATE_UD)
+               yres = info->var.yres;
+       else
+               yres = info->var.xres;
+
+       if (fb_logo.logo && fb_logo.logo->height > yres) {
                fb_logo.logo = NULL;
                return 0;
        }
+
        /* What depth we asked for might be different from what we get */
        if (fb_logo.logo->type == LINUX_LOGO_CLUT224)
                fb_logo.depth = 8;
        return fb_logo.logo->height;
 }
 
-int fb_show_logo(struct fb_info *info)
+int fb_show_logo(struct fb_info *info, int rotate)
 {
        u32 *palette = NULL, *saved_pseudo_palette = NULL;
-       unsigned char *logo_new = NULL;
+       unsigned char *logo_new = NULL, *logo_rotate = NULL;
        struct fb_image image;
-       int x;
 
        /* Return if the frame buffer is not mapped or suspended */
        if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING)
                fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.depth);
        }
 
+       image.dx = 0;
+       image.dy = 0;
        image.width = fb_logo.logo->width;
        image.height = fb_logo.logo->height;
-       image.dy = 0;
 
-       for (x = 0; x < num_online_cpus() * (fb_logo.logo->width + 8) &&
-            x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) {
-               image.dx = x;
-               info->fbops->fb_imageblit(info, &image);
+       if (rotate) {
+               logo_rotate = kmalloc(fb_logo.logo->width *
+                                     fb_logo.logo->height, GFP_KERNEL);
+               if (logo_rotate)
+                       fb_rotate_logo(info, logo_rotate, &image, rotate);
        }
-       
+
+       fb_do_show_logo(info, &image, rotate);
+
        kfree(palette);
        if (saved_pseudo_palette != NULL)
                info->pseudo_palette = saved_pseudo_palette;
        kfree(logo_new);
+       kfree(logo_rotate);
        return fb_logo.logo->height;
 }
 #else
-int fb_prepare_logo(struct fb_info *info) { return 0; }
-int fb_show_logo(struct fb_info *info) { return 0; }
+int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; }
+int fb_show_logo(struct fb_info *info, int rotate) { return 0; }
 #endif /* CONFIG_LOGO */
 
 static int fbmem_read_proc(char *buf, char **start, off_t offset,