aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-16 22:50:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-16 22:50:13 -0400
commit517d08699b250021303f9a7cf0d758b6dc0748ed (patch)
tree5e5b0134c3fffb78fe9d8b1641a64ff28fdd7bbc /drivers/video
parent8eeee4e2f04fc551f50c9d9847da2d73d7d33728 (diff)
parenta34601c5d84134055782ee031d58d82f5440e918 (diff)
Merge branch 'akpm'
* akpm: (182 commits) fbdev: bf54x-lq043fb: use kzalloc over kmalloc/memset fbdev: *bfin*: fix __dev{init,exit} markings fbdev: *bfin*: drop unnecessary calls to memset fbdev: bfin-t350mcqb-fb: drop unused local variables fbdev: blackfin has __raw I/O accessors, so use them in fb.h fbdev: s1d13xxxfb: add accelerated bitblt functions tcx: use standard fields for framebuffer physical address and length fbdev: add support for handoff from firmware to hw framebuffers intelfb: fix a bug when changing video timing fbdev: use framebuffer_release() for freeing fb_info structures radeon: P2G2CLK_ALWAYS_ONb tested twice, should 2nd be P2G2CLK_DAC_ALWAYS_ONb? s3c-fb: CPUFREQ frequency scaling support s3c-fb: fix resource releasing on error during probing carminefb: fix possible access beyond end of carmine_modedb[] acornfb: remove fb_mmap function mb862xxfb: use CONFIG_OF instead of CONFIG_PPC_OF mb862xxfb: restrict compliation of platform driver to PPC Samsung SoC Framebuffer driver: add Alpha Channel support atmel-lcdc: fix pixclock upper bound detection offb: use framebuffer_alloc() to allocate fb_info struct ... Manually fix up conflicts due to kmemcheck in mm/slab.c
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig1
-rw-r--r--drivers/video/acornfb.c38
-rw-r--r--drivers/video/atmel_lcdfb.c2
-rw-r--r--drivers/video/aty/radeon_pm.c3
-rw-r--r--drivers/video/bf54x-lq043fb.c15
-rw-r--r--drivers/video/bfin-t350mcqb-fb.c15
-rw-r--r--drivers/video/carminefb.c2
-rw-r--r--drivers/video/chipsfb.c1
-rw-r--r--drivers/video/efifb.c5
-rw-r--r--drivers/video/fbmem.c31
-rw-r--r--drivers/video/igafb.c8
-rw-r--r--drivers/video/intelfb/intelfbdrv.c5
-rw-r--r--drivers/video/logo/Makefile12
-rw-r--r--drivers/video/logo/logo.c15
-rw-r--r--drivers/video/mb862xx/mb862xxfb.c2
-rw-r--r--drivers/video/modedb.c8
-rw-r--r--drivers/video/offb.c8
-rw-r--r--drivers/video/pm2fb.c2
-rw-r--r--drivers/video/s1d13xxxfb.c341
-rw-r--r--drivers/video/s3c-fb.c53
-rw-r--r--drivers/video/s3c2410fb.c67
-rw-r--r--drivers/video/s3c2410fb.h5
-rw-r--r--drivers/video/sis/sis_main.c4
-rw-r--r--drivers/video/stifb.c2
-rw-r--r--drivers/video/tcx.c27
-rw-r--r--drivers/video/vesafb.c15
26 files changed, 519 insertions, 168 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 2b5a691064b7..932ffdbf86d9 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2104,6 +2104,7 @@ config FB_MB862XX_LIME
2104 bool "Lime GDC" 2104 bool "Lime GDC"
2105 depends on FB_MB862XX 2105 depends on FB_MB862XX
2106 depends on OF && !FB_MB862XX_PCI_GDC 2106 depends on OF && !FB_MB862XX_PCI_GDC
2107 depends on PPC
2107 select FB_FOREIGN_ENDIAN 2108 select FB_FOREIGN_ENDIAN
2108 select FB_LITTLE_ENDIAN 2109 select FB_LITTLE_ENDIAN
2109 ---help--- 2110 ---help---
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index 6995fe1e86d4..0bcc59eb37fa 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -859,43 +859,6 @@ acornfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
859 return 0; 859 return 0;
860} 860}
861 861
862/*
863 * Note that we are entered with the kernel locked.
864 */
865static int
866acornfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
867{
868 unsigned long off, start;
869 u32 len;
870
871 off = vma->vm_pgoff << PAGE_SHIFT;
872
873 start = info->fix.smem_start;
874 len = PAGE_ALIGN(start & ~PAGE_MASK) + info->fix.smem_len;
875 start &= PAGE_MASK;
876 if ((vma->vm_end - vma->vm_start + off) > len)
877 return -EINVAL;
878 off += start;
879 vma->vm_pgoff = off >> PAGE_SHIFT;
880
881 /* This is an IO map - tell maydump to skip this VMA */
882 vma->vm_flags |= VM_IO;
883
884 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
885
886 /*
887 * Don't alter the page protection flags; we want to keep the area
888 * cached for better performance. This does mean that we may miss
889 * some updates to the screen occasionally, but process switches
890 * should cause the caches and buffers to be flushed often enough.
891 */
892 if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
893 vma->vm_end - vma->vm_start,
894 vma->vm_page_prot))
895 return -EAGAIN;
896 return 0;
897}
898
899static struct fb_ops acornfb_ops = { 862static struct fb_ops acornfb_ops = {
900 .owner = THIS_MODULE, 863 .owner = THIS_MODULE,
901 .fb_check_var = acornfb_check_var, 864 .fb_check_var = acornfb_check_var,
@@ -905,7 +868,6 @@ static struct fb_ops acornfb_ops = {
905 .fb_fillrect = cfb_fillrect, 868 .fb_fillrect = cfb_fillrect,
906 .fb_copyarea = cfb_copyarea, 869 .fb_copyarea = cfb_copyarea,
907 .fb_imageblit = cfb_imageblit, 870 .fb_imageblit = cfb_imageblit,
908 .fb_mmap = acornfb_mmap,
909}; 871};
910 872
911/* 873/*
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 2fb63f6ea2f1..5afd64482f55 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -345,7 +345,7 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
345 dev_dbg(dev, " bpp: %u\n", var->bits_per_pixel); 345 dev_dbg(dev, " bpp: %u\n", var->bits_per_pixel);
346 dev_dbg(dev, " clk: %lu KHz\n", clk_value_khz); 346 dev_dbg(dev, " clk: %lu KHz\n", clk_value_khz);
347 347
348 if ((PICOS2KHZ(var->pixclock) * var->bits_per_pixel / 8) > clk_value_khz) { 348 if (PICOS2KHZ(var->pixclock) > clk_value_khz) {
349 dev_err(dev, "%lu KHz pixel clock is too fast\n", PICOS2KHZ(var->pixclock)); 349 dev_err(dev, "%lu KHz pixel clock is too fast\n", PICOS2KHZ(var->pixclock));
350 return -EINVAL; 350 return -EINVAL;
351 } 351 }
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index 97a1f095f327..515cf1978d19 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -213,7 +213,6 @@ static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo)
213 PIXCLKS_CNTL__R300_PIXCLK_TRANS_ALWAYS_ONb | 213 PIXCLKS_CNTL__R300_PIXCLK_TRANS_ALWAYS_ONb |
214 PIXCLKS_CNTL__R300_PIXCLK_TVO_ALWAYS_ONb | 214 PIXCLKS_CNTL__R300_PIXCLK_TVO_ALWAYS_ONb |
215 PIXCLKS_CNTL__R300_P2G2CLK_ALWAYS_ONb | 215 PIXCLKS_CNTL__R300_P2G2CLK_ALWAYS_ONb |
216 PIXCLKS_CNTL__R300_P2G2CLK_ALWAYS_ONb |
217 PIXCLKS_CNTL__R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF); 216 PIXCLKS_CNTL__R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
218 OUTPLL(pllPIXCLKS_CNTL, tmp); 217 OUTPLL(pllPIXCLKS_CNTL, tmp);
219 218
@@ -395,7 +394,7 @@ static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
395 PIXCLKS_CNTL__R300_PIXCLK_TRANS_ALWAYS_ONb | 394 PIXCLKS_CNTL__R300_PIXCLK_TRANS_ALWAYS_ONb |
396 PIXCLKS_CNTL__R300_PIXCLK_TVO_ALWAYS_ONb | 395 PIXCLKS_CNTL__R300_PIXCLK_TVO_ALWAYS_ONb |
397 PIXCLKS_CNTL__R300_P2G2CLK_ALWAYS_ONb | 396 PIXCLKS_CNTL__R300_P2G2CLK_ALWAYS_ONb |
398 PIXCLKS_CNTL__R300_P2G2CLK_ALWAYS_ONb); 397 PIXCLKS_CNTL__R300_P2G2CLK_DAC_ALWAYS_ONb);
399 OUTPLL(pllPIXCLKS_CNTL, tmp); 398 OUTPLL(pllPIXCLKS_CNTL, tmp);
400 399
401 tmp = INPLL(pllMCLK_MISC); 400 tmp = INPLL(pllMCLK_MISC);
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
index 37e60b1d2ed9..e49ae5edcc00 100644
--- a/drivers/video/bf54x-lq043fb.c
+++ b/drivers/video/bf54x-lq043fb.c
@@ -323,7 +323,6 @@ static int bfin_bf54x_fb_release(struct fb_info *info, int user)
323 bfin_write_EPPI0_CONTROL(0); 323 bfin_write_EPPI0_CONTROL(0);
324 SSYNC(); 324 SSYNC();
325 disable_dma(CH_EPPI0); 325 disable_dma(CH_EPPI0);
326 memset(fbi->fb_buffer, 0, info->fix.smem_len);
327 } 326 }
328 327
329 spin_unlock(&fbi->lock); 328 spin_unlock(&fbi->lock);
@@ -530,7 +529,7 @@ static irqreturn_t bfin_bf54x_irq_error(int irq, void *dev_id)
530 return IRQ_HANDLED; 529 return IRQ_HANDLED;
531} 530}
532 531
533static int __init bfin_bf54x_probe(struct platform_device *pdev) 532static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
534{ 533{
535 struct bfin_bf54xfb_info *info; 534 struct bfin_bf54xfb_info *info;
536 struct fb_info *fbinfo; 535 struct fb_info *fbinfo;
@@ -626,14 +625,12 @@ static int __init bfin_bf54x_probe(struct platform_device *pdev)
626 goto out3; 625 goto out3;
627 } 626 }
628 627
629 memset(info->fb_buffer, 0, fbinfo->fix.smem_len);
630
631 fbinfo->screen_base = (void *)info->fb_buffer; 628 fbinfo->screen_base = (void *)info->fb_buffer;
632 fbinfo->fix.smem_start = (int)info->fb_buffer; 629 fbinfo->fix.smem_start = (int)info->fb_buffer;
633 630
634 fbinfo->fbops = &bfin_bf54x_fb_ops; 631 fbinfo->fbops = &bfin_bf54x_fb_ops;
635 632
636 fbinfo->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); 633 fbinfo->pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL);
637 if (!fbinfo->pseudo_palette) { 634 if (!fbinfo->pseudo_palette) {
638 printk(KERN_ERR DRIVER_NAME 635 printk(KERN_ERR DRIVER_NAME
639 "Fail to allocate pseudo_palette\n"); 636 "Fail to allocate pseudo_palette\n");
@@ -642,8 +639,6 @@ static int __init bfin_bf54x_probe(struct platform_device *pdev)
642 goto out4; 639 goto out4;
643 } 640 }
644 641
645 memset(fbinfo->pseudo_palette, 0, sizeof(u32) * 16);
646
647 if (fb_alloc_cmap(&fbinfo->cmap, BFIN_LCD_NBR_PALETTE_ENTRIES, 0) 642 if (fb_alloc_cmap(&fbinfo->cmap, BFIN_LCD_NBR_PALETTE_ENTRIES, 0)
648 < 0) { 643 < 0) {
649 printk(KERN_ERR DRIVER_NAME 644 printk(KERN_ERR DRIVER_NAME
@@ -712,7 +707,7 @@ out1:
712 return ret; 707 return ret;
713} 708}
714 709
715static int bfin_bf54x_remove(struct platform_device *pdev) 710static int __devexit bfin_bf54x_remove(struct platform_device *pdev)
716{ 711{
717 712
718 struct fb_info *fbinfo = platform_get_drvdata(pdev); 713 struct fb_info *fbinfo = platform_get_drvdata(pdev);
@@ -781,7 +776,7 @@ static int bfin_bf54x_resume(struct platform_device *pdev)
781 776
782static struct platform_driver bfin_bf54x_driver = { 777static struct platform_driver bfin_bf54x_driver = {
783 .probe = bfin_bf54x_probe, 778 .probe = bfin_bf54x_probe,
784 .remove = bfin_bf54x_remove, 779 .remove = __devexit_p(bfin_bf54x_remove),
785 .suspend = bfin_bf54x_suspend, 780 .suspend = bfin_bf54x_suspend,
786 .resume = bfin_bf54x_resume, 781 .resume = bfin_bf54x_resume,
787 .driver = { 782 .driver = {
@@ -790,7 +785,7 @@ static struct platform_driver bfin_bf54x_driver = {
790 }, 785 },
791}; 786};
792 787
793static int __devinit bfin_bf54x_driver_init(void) 788static int __init bfin_bf54x_driver_init(void)
794{ 789{
795 return platform_driver_register(&bfin_bf54x_driver); 790 return platform_driver_register(&bfin_bf54x_driver);
796} 791}
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c
index 90cfddabf1f7..5cc36cfbf07b 100644
--- a/drivers/video/bfin-t350mcqb-fb.c
+++ b/drivers/video/bfin-t350mcqb-fb.c
@@ -242,7 +242,6 @@ static int bfin_t350mcqb_fb_release(struct fb_info *info, int user)
242 SSYNC(); 242 SSYNC();
243 disable_dma(CH_PPI); 243 disable_dma(CH_PPI);
244 bfin_t350mcqb_stop_timers(); 244 bfin_t350mcqb_stop_timers();
245 memset(fbi->fb_buffer, 0, info->fix.smem_len);
246 } 245 }
247 246
248 spin_unlock(&fbi->lock); 247 spin_unlock(&fbi->lock);
@@ -527,8 +526,6 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
527 goto out3; 526 goto out3;
528 } 527 }
529 528
530 memset(info->fb_buffer, 0, fbinfo->fix.smem_len);
531
532 fbinfo->screen_base = (void *)info->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET; 529 fbinfo->screen_base = (void *)info->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET;
533 fbinfo->fix.smem_start = (int)info->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET; 530 fbinfo->fix.smem_start = (int)info->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET;
534 531
@@ -602,7 +599,7 @@ out1:
602 return ret; 599 return ret;
603} 600}
604 601
605static int bfin_t350mcqb_remove(struct platform_device *pdev) 602static int __devexit bfin_t350mcqb_remove(struct platform_device *pdev)
606{ 603{
607 604
608 struct fb_info *fbinfo = platform_get_drvdata(pdev); 605 struct fb_info *fbinfo = platform_get_drvdata(pdev);
@@ -637,9 +634,6 @@ static int bfin_t350mcqb_remove(struct platform_device *pdev)
637#ifdef CONFIG_PM 634#ifdef CONFIG_PM
638static int bfin_t350mcqb_suspend(struct platform_device *pdev, pm_message_t state) 635static int bfin_t350mcqb_suspend(struct platform_device *pdev, pm_message_t state)
639{ 636{
640 struct fb_info *fbinfo = platform_get_drvdata(pdev);
641 struct bfin_t350mcqbfb_info *info = fbinfo->par;
642
643 bfin_t350mcqb_disable_ppi(); 637 bfin_t350mcqb_disable_ppi();
644 disable_dma(CH_PPI); 638 disable_dma(CH_PPI);
645 bfin_write_PPI_STATUS(0xFFFF); 639 bfin_write_PPI_STATUS(0xFFFF);
@@ -649,9 +643,6 @@ static int bfin_t350mcqb_suspend(struct platform_device *pdev, pm_message_t stat
649 643
650static int bfin_t350mcqb_resume(struct platform_device *pdev) 644static int bfin_t350mcqb_resume(struct platform_device *pdev)
651{ 645{
652 struct fb_info *fbinfo = platform_get_drvdata(pdev);
653 struct bfin_t350mcqbfb_info *info = fbinfo->par;
654
655 enable_dma(CH_PPI); 646 enable_dma(CH_PPI);
656 bfin_t350mcqb_enable_ppi(); 647 bfin_t350mcqb_enable_ppi();
657 648
@@ -664,7 +655,7 @@ static int bfin_t350mcqb_resume(struct platform_device *pdev)
664 655
665static struct platform_driver bfin_t350mcqb_driver = { 656static struct platform_driver bfin_t350mcqb_driver = {
666 .probe = bfin_t350mcqb_probe, 657 .probe = bfin_t350mcqb_probe,
667 .remove = bfin_t350mcqb_remove, 658 .remove = __devexit_p(bfin_t350mcqb_remove),
668 .suspend = bfin_t350mcqb_suspend, 659 .suspend = bfin_t350mcqb_suspend,
669 .resume = bfin_t350mcqb_resume, 660 .resume = bfin_t350mcqb_resume,
670 .driver = { 661 .driver = {
@@ -673,7 +664,7 @@ static struct platform_driver bfin_t350mcqb_driver = {
673 }, 664 },
674}; 665};
675 666
676static int __devinit bfin_t350mcqb_driver_init(void) 667static int __init bfin_t350mcqb_driver_init(void)
677{ 668{
678 return platform_driver_register(&bfin_t350mcqb_driver); 669 return platform_driver_register(&bfin_t350mcqb_driver);
679} 670}
diff --git a/drivers/video/carminefb.c b/drivers/video/carminefb.c
index c7ff3c1a266a..0c02f8ec4bf3 100644
--- a/drivers/video/carminefb.c
+++ b/drivers/video/carminefb.c
@@ -562,7 +562,7 @@ static int __devinit alloc_carmine_fb(void __iomem *regs, void __iomem *smem_bas
562 if (ret < 0) 562 if (ret < 0)
563 goto err_free_fb; 563 goto err_free_fb;
564 564
565 if (fb_mode > ARRAY_SIZE(carmine_modedb)) 565 if (fb_mode >= ARRAY_SIZE(carmine_modedb))
566 fb_mode = CARMINEFB_DEFAULT_VIDEO_MODE; 566 fb_mode = CARMINEFB_DEFAULT_VIDEO_MODE;
567 567
568 par->cur_mode = par->new_mode = ~0; 568 par->cur_mode = par->new_mode = ~0;
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index 777389c40988..57b9d276497e 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -414,7 +414,6 @@ chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
414 } 414 }
415 415
416 pci_set_drvdata(dp, p); 416 pci_set_drvdata(dp, p);
417 p->device = &dp->dev;
418 417
419 init_chips(p, addr); 418 init_chips(p, addr);
420 419
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index 8dea2bc92705..eb12182b2059 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -280,6 +280,9 @@ static int __init efifb_probe(struct platform_device *dev)
280 info->pseudo_palette = info->par; 280 info->pseudo_palette = info->par;
281 info->par = NULL; 281 info->par = NULL;
282 282
283 info->aperture_base = efifb_fix.smem_start;
284 info->aperture_size = size_total;
285
283 info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len); 286 info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
284 if (!info->screen_base) { 287 if (!info->screen_base) {
285 printk(KERN_ERR "efifb: abort, cannot ioremap video memory " 288 printk(KERN_ERR "efifb: abort, cannot ioremap video memory "
@@ -337,7 +340,7 @@ static int __init efifb_probe(struct platform_device *dev)
337 info->fbops = &efifb_ops; 340 info->fbops = &efifb_ops;
338 info->var = efifb_defined; 341 info->var = efifb_defined;
339 info->fix = efifb_fix; 342 info->fix = efifb_fix;
340 info->flags = FBINFO_FLAG_DEFAULT; 343 info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE;
341 344
342 if ((err = fb_alloc_cmap(&info->cmap, 256, 0)) < 0) { 345 if ((err = fb_alloc_cmap(&info->cmap, 256, 0)) < 0) {
343 printk(KERN_ERR "efifb: cannot allocate colormap\n"); 346 printk(KERN_ERR "efifb: cannot allocate colormap\n");
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index d412a1ddc12f..f8a09bf8d0cd 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1462,6 +1462,16 @@ static int fb_check_foreignness(struct fb_info *fi)
1462 return 0; 1462 return 0;
1463} 1463}
1464 1464
1465static bool fb_do_apertures_overlap(struct fb_info *gen, struct fb_info *hw)
1466{
1467 /* is the generic aperture base the same as the HW one */
1468 if (gen->aperture_base == hw->aperture_base)
1469 return true;
1470 /* is the generic aperture base inside the hw base->hw base+size */
1471 if (gen->aperture_base > hw->aperture_base && gen->aperture_base <= hw->aperture_base + hw->aperture_size)
1472 return true;
1473 return false;
1474}
1465/** 1475/**
1466 * register_framebuffer - registers a frame buffer device 1476 * register_framebuffer - registers a frame buffer device
1467 * @fb_info: frame buffer info structure 1477 * @fb_info: frame buffer info structure
@@ -1485,6 +1495,23 @@ register_framebuffer(struct fb_info *fb_info)
1485 if (fb_check_foreignness(fb_info)) 1495 if (fb_check_foreignness(fb_info))
1486 return -ENOSYS; 1496 return -ENOSYS;
1487 1497
1498 /* check all firmware fbs and kick off if the base addr overlaps */
1499 for (i = 0 ; i < FB_MAX; i++) {
1500 if (!registered_fb[i])
1501 continue;
1502
1503 if (registered_fb[i]->flags & FBINFO_MISC_FIRMWARE) {
1504 if (fb_do_apertures_overlap(registered_fb[i], fb_info)) {
1505 printk(KERN_ERR "fb: conflicting fb hw usage "
1506 "%s vs %s - removing generic driver\n",
1507 fb_info->fix.id,
1508 registered_fb[i]->fix.id);
1509 unregister_framebuffer(registered_fb[i]);
1510 break;
1511 }
1512 }
1513 }
1514
1488 num_registered_fb++; 1515 num_registered_fb++;
1489 for (i = 0 ; i < FB_MAX; i++) 1516 for (i = 0 ; i < FB_MAX; i++)
1490 if (!registered_fb[i]) 1517 if (!registered_fb[i])
@@ -1586,6 +1613,10 @@ unregister_framebuffer(struct fb_info *fb_info)
1586 device_destroy(fb_class, MKDEV(FB_MAJOR, i)); 1613 device_destroy(fb_class, MKDEV(FB_MAJOR, i));
1587 event.info = fb_info; 1614 event.info = fb_info;
1588 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); 1615 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
1616
1617 /* this may free fb info */
1618 if (fb_info->fbops->fb_destroy)
1619 fb_info->fbops->fb_destroy(fb_info);
1589done: 1620done:
1590 return ret; 1621 return ret;
1591} 1622}
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c
index 3a81060137a2..15d200109446 100644
--- a/drivers/video/igafb.c
+++ b/drivers/video/igafb.c
@@ -395,17 +395,16 @@ int __init igafb_init(void)
395 /* We leak a reference here but as it cannot be unloaded this is 395 /* We leak a reference here but as it cannot be unloaded this is
396 fine. If you write unload code remember to free it in unload */ 396 fine. If you write unload code remember to free it in unload */
397 397
398 size = sizeof(struct fb_info) + sizeof(struct iga_par) + sizeof(u32)*16; 398 size = sizeof(struct iga_par) + sizeof(u32)*16;
399 399
400 info = kzalloc(size, GFP_ATOMIC); 400 info = framebuffer_alloc(size, &pdev->dev);
401 if (!info) { 401 if (!info) {
402 printk("igafb_init: can't alloc fb_info\n"); 402 printk("igafb_init: can't alloc fb_info\n");
403 pci_dev_put(pdev); 403 pci_dev_put(pdev);
404 return -ENOMEM; 404 return -ENOMEM;
405 } 405 }
406 406
407 par = (struct iga_par *) (info + 1); 407 par = info->par;
408
409 408
410 if ((addr = pdev->resource[0].start) == 0) { 409 if ((addr = pdev->resource[0].start) == 0) {
411 printk("igafb_init: no memory start\n"); 410 printk("igafb_init: no memory start\n");
@@ -526,7 +525,6 @@ int __init igafb_init(void)
526 info->var = default_var; 525 info->var = default_var;
527 info->fix = igafb_fix; 526 info->fix = igafb_fix;
528 info->pseudo_palette = (void *)(par + 1); 527 info->pseudo_palette = (void *)(par + 1);
529 info->device = &pdev->dev;
530 528
531 if (!iga_init(info, par)) { 529 if (!iga_init(info, par)) {
532 iounmap((void *)par->io_base); 530 iounmap((void *)par->io_base);
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index ace14fe02fc4..0cafd642fbc0 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -1365,6 +1365,11 @@ static int intelfb_set_par(struct fb_info *info)
1365 DBG_MSG("intelfb_set_par (%dx%d-%d)\n", info->var.xres, 1365 DBG_MSG("intelfb_set_par (%dx%d-%d)\n", info->var.xres,
1366 info->var.yres, info->var.bits_per_pixel); 1366 info->var.yres, info->var.bits_per_pixel);
1367 1367
1368 /*
1369 * Disable VCO prior to timing register change.
1370 */
1371 OUTREG(DPLL_A, INREG(DPLL_A) & ~DPLL_VCO_ENABLE);
1372
1368 intelfb_blank(FB_BLANK_POWERDOWN, info); 1373 intelfb_blank(FB_BLANK_POWERDOWN, info);
1369 1374
1370 if (ACCEL(dinfo, info)) 1375 if (ACCEL(dinfo, info))
diff --git a/drivers/video/logo/Makefile b/drivers/video/logo/Makefile
index b91251d1fe41..3b437813584c 100644
--- a/drivers/video/logo/Makefile
+++ b/drivers/video/logo/Makefile
@@ -37,22 +37,24 @@ extra-y += $(call logo-cfiles,_clut224,ppm)
37# Gray 256 37# Gray 256
38extra-y += $(call logo-cfiles,_gray256,pgm) 38extra-y += $(call logo-cfiles,_gray256,pgm)
39 39
40pnmtologo := scripts/pnmtologo
41
40# Create commands like "pnmtologo -t mono -n logo_mac_mono -o ..." 42# Create commands like "pnmtologo -t mono -n logo_mac_mono -o ..."
41quiet_cmd_logo = LOGO $@ 43quiet_cmd_logo = LOGO $@
42 cmd_logo = scripts/pnmtologo \ 44 cmd_logo = $(pnmtologo) \
43 -t $(patsubst $*_%,%,$(notdir $(basename $<))) \ 45 -t $(patsubst $*_%,%,$(notdir $(basename $<))) \
44 -n $(notdir $(basename $<)) -o $@ $< 46 -n $(notdir $(basename $<)) -o $@ $<
45 47
46$(obj)/%_mono.c: $(src)/%_mono.pbm FORCE 48$(obj)/%_mono.c: $(src)/%_mono.pbm $(pnmtologo) FORCE
47 $(call if_changed,logo) 49 $(call if_changed,logo)
48 50
49$(obj)/%_vga16.c: $(src)/%_vga16.ppm FORCE 51$(obj)/%_vga16.c: $(src)/%_vga16.ppm $(pnmtologo) FORCE
50 $(call if_changed,logo) 52 $(call if_changed,logo)
51 53
52$(obj)/%_clut224.c: $(src)/%_clut224.ppm FORCE 54$(obj)/%_clut224.c: $(src)/%_clut224.ppm $(pnmtologo) FORCE
53 $(call if_changed,logo) 55 $(call if_changed,logo)
54 56
55$(obj)/%_gray256.c: $(src)/%_gray256.pgm FORCE 57$(obj)/%_gray256.c: $(src)/%_gray256.pgm $(pnmtologo) FORCE
56 $(call if_changed,logo) 58 $(call if_changed,logo)
57 59
58# Files generated that shall be removed upon make clean 60# Files generated that shall be removed upon make clean
diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
index 2e85a2b52d05..ea7a8ccc830c 100644
--- a/drivers/video/logo/logo.c
+++ b/drivers/video/logo/logo.c
@@ -21,21 +21,6 @@
21#include <asm/bootinfo.h> 21#include <asm/bootinfo.h>
22#endif 22#endif
23 23
24extern const struct linux_logo logo_linux_mono;
25extern const struct linux_logo logo_linux_vga16;
26extern const struct linux_logo logo_linux_clut224;
27extern const struct linux_logo logo_blackfin_vga16;
28extern const struct linux_logo logo_blackfin_clut224;
29extern const struct linux_logo logo_dec_clut224;
30extern const struct linux_logo logo_mac_clut224;
31extern const struct linux_logo logo_parisc_clut224;
32extern const struct linux_logo logo_sgi_clut224;
33extern const struct linux_logo logo_sun_clut224;
34extern const struct linux_logo logo_superh_mono;
35extern const struct linux_logo logo_superh_vga16;
36extern const struct linux_logo logo_superh_clut224;
37extern const struct linux_logo logo_m32r_clut224;
38
39static int nologo; 24static int nologo;
40module_param(nologo, bool, 0); 25module_param(nologo, bool, 0);
41MODULE_PARM_DESC(nologo, "Disables startup logo"); 26MODULE_PARM_DESC(nologo, "Disables startup logo");
diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfb.c
index fb64234a3825..a28e3cfbbf70 100644
--- a/drivers/video/mb862xx/mb862xxfb.c
+++ b/drivers/video/mb862xx/mb862xxfb.c
@@ -19,7 +19,7 @@
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/pci.h> 21#include <linux/pci.h>
22#if defined(CONFIG_PPC_OF) 22#if defined(CONFIG_OF)
23#include <linux/of_platform.h> 23#include <linux/of_platform.h>
24#endif 24#endif
25#include "mb862xxfb.h" 25#include "mb862xxfb.h"
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 16186240c5f2..34e4e7995169 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -264,6 +264,14 @@ static const struct fb_videomode modedb[] = {
264 /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */ 264 /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
265 NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3, 265 NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
266 0, FB_VMODE_NONINTERLACED 266 0, FB_VMODE_NONINTERLACED
267 }, {
268 /* 720x576i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */
269 NULL, 50, 720, 576, 74074, 64, 16, 39, 5, 64, 5,
270 0, FB_VMODE_INTERLACED
271 }, {
272 /* 800x520i @ 50 Hz, 15.625 kHz hsync (PAL RGB) */
273 NULL, 50, 800, 520, 58823, 144, 64, 72, 28, 80, 5,
274 0, FB_VMODE_INTERLACED
267 }, 275 },
268}; 276};
269 277
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index e1d9eeb1aeaf..4d8c54c23dd7 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -378,7 +378,6 @@ static void __init offb_init_fb(const char *name, const char *full_name,
378 struct fb_fix_screeninfo *fix; 378 struct fb_fix_screeninfo *fix;
379 struct fb_var_screeninfo *var; 379 struct fb_var_screeninfo *var;
380 struct fb_info *info; 380 struct fb_info *info;
381 int size;
382 381
383 if (!request_mem_region(res_start, res_size, "offb")) 382 if (!request_mem_region(res_start, res_size, "offb"))
384 return; 383 return;
@@ -393,15 +392,12 @@ static void __init offb_init_fb(const char *name, const char *full_name,
393 return; 392 return;
394 } 393 }
395 394
396 size = sizeof(struct fb_info) + sizeof(u32) * 16; 395 info = framebuffer_alloc(sizeof(u32) * 16, NULL);
397
398 info = kmalloc(size, GFP_ATOMIC);
399 396
400 if (info == 0) { 397 if (info == 0) {
401 release_mem_region(res_start, res_size); 398 release_mem_region(res_start, res_size);
402 return; 399 return;
403 } 400 }
404 memset(info, 0, size);
405 401
406 fix = &info->fix; 402 fix = &info->fix;
407 var = &info->var; 403 var = &info->var;
@@ -497,7 +493,7 @@ static void __init offb_init_fb(const char *name, const char *full_name,
497 iounmap(par->cmap_adr); 493 iounmap(par->cmap_adr);
498 par->cmap_adr = NULL; 494 par->cmap_adr = NULL;
499 iounmap(info->screen_base); 495 iounmap(info->screen_base);
500 kfree(info); 496 framebuffer_release(info);
501 release_mem_region(res_start, res_size); 497 release_mem_region(res_start, res_size);
502 return; 498 return;
503 } 499 }
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index c6dd924976a4..36436ee6c1a4 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -1748,7 +1748,7 @@ static void __devexit pm2fb_remove(struct pci_dev *pdev)
1748 pci_set_drvdata(pdev, NULL); 1748 pci_set_drvdata(pdev, NULL);
1749 fb_dealloc_cmap(&info->cmap); 1749 fb_dealloc_cmap(&info->cmap);
1750 kfree(info->pixmap.addr); 1750 kfree(info->pixmap.addr);
1751 kfree(info); 1751 framebuffer_release(info);
1752} 1752}
1753 1753
1754static struct pci_device_id pm2fb_id_table[] = { 1754static struct pci_device_id pm2fb_id_table[] = {
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index 0726aecf3b7e..0deb0a8867b7 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -2,6 +2,7 @@
2 * 2 *
3 * (c) 2004 Simtec Electronics 3 * (c) 2004 Simtec Electronics
4 * (c) 2005 Thibaut VARENE <varenet@parisc-linux.org> 4 * (c) 2005 Thibaut VARENE <varenet@parisc-linux.org>
5 * (c) 2009 Kristoffer Ericson <kristoffer.ericson@gmail.com>
5 * 6 *
6 * Driver for Epson S1D13xxx series framebuffer chips 7 * Driver for Epson S1D13xxx series framebuffer chips
7 * 8 *
@@ -10,18 +11,10 @@
10 * linux/drivers/video/epson1355fb.c 11 * linux/drivers/video/epson1355fb.c
11 * linux/drivers/video/epson/s1d13xxxfb.c (2.4 driver by Epson) 12 * linux/drivers/video/epson/s1d13xxxfb.c (2.4 driver by Epson)
12 * 13 *
13 * Note, currently only tested on S1D13806 with 16bit CRT.
14 * As such, this driver might still contain some hardcoded bits relating to
15 * S1D13806.
16 * Making it work on other S1D13XXX chips should merely be a matter of adding
17 * a few switch()s, some missing glue here and there maybe, and split header
18 * files.
19 *
20 * TODO: - handle dual screen display (CRT and LCD at the same time). 14 * TODO: - handle dual screen display (CRT and LCD at the same time).
21 * - check_var(), mode change, etc. 15 * - check_var(), mode change, etc.
22 * - PM untested. 16 * - probably not SMP safe :)
23 * - Accelerated interfaces. 17 * - support all bitblt operations on all cards
24 * - Probably not SMP safe :)
25 * 18 *
26 * This file is subject to the terms and conditions of the GNU General Public 19 * This file is subject to the terms and conditions of the GNU General Public
27 * License. See the file COPYING in the main directory of this archive for 20 * License. See the file COPYING in the main directory of this archive for
@@ -31,19 +24,24 @@
31#include <linux/module.h> 24#include <linux/module.h>
32#include <linux/platform_device.h> 25#include <linux/platform_device.h>
33#include <linux/delay.h> 26#include <linux/delay.h>
34
35#include <linux/types.h> 27#include <linux/types.h>
36#include <linux/errno.h> 28#include <linux/errno.h>
37#include <linux/mm.h> 29#include <linux/mm.h>
38#include <linux/mman.h> 30#include <linux/mman.h>
39#include <linux/fb.h> 31#include <linux/fb.h>
32#include <linux/spinlock_types.h>
33#include <linux/spinlock.h>
40 34
41#include <asm/io.h> 35#include <asm/io.h>
42 36
43#include <video/s1d13xxxfb.h> 37#include <video/s1d13xxxfb.h>
44 38
45#define PFX "s1d13xxxfb: " 39#define PFX "s1d13xxxfb: "
40#define BLIT "s1d13xxxfb_bitblt: "
46 41
42/*
43 * set this to enable debugging on general functions
44 */
47#if 0 45#if 0
48#define dbg(fmt, args...) do { printk(KERN_INFO fmt, ## args); } while(0) 46#define dbg(fmt, args...) do { printk(KERN_INFO fmt, ## args); } while(0)
49#else 47#else
@@ -51,7 +49,21 @@
51#endif 49#endif
52 50
53/* 51/*
54 * List of card production ids 52 * set this to enable debugging on 2D acceleration
53 */
54#if 0
55#define dbg_blit(fmt, args...) do { printk(KERN_INFO BLIT fmt, ## args); } while (0)
56#else
57#define dbg_blit(fmt, args...) do { } while (0)
58#endif
59
60/*
61 * we make sure only one bitblt operation is running
62 */
63static DEFINE_SPINLOCK(s1d13xxxfb_bitblt_lock);
64
65/*
66 * list of card production ids
55 */ 67 */
56static const int s1d13xxxfb_prod_ids[] = { 68static const int s1d13xxxfb_prod_ids[] = {
57 S1D13505_PROD_ID, 69 S1D13505_PROD_ID,
@@ -69,7 +81,7 @@ static const char *s1d13xxxfb_prod_names[] = {
69}; 81};
70 82
71/* 83/*
72 * Here we define the default struct fb_fix_screeninfo 84 * here we define the default struct fb_fix_screeninfo
73 */ 85 */
74static struct fb_fix_screeninfo __devinitdata s1d13xxxfb_fix = { 86static struct fb_fix_screeninfo __devinitdata s1d13xxxfb_fix = {
75 .id = S1D_FBID, 87 .id = S1D_FBID,
@@ -145,8 +157,10 @@ crt_enable(struct s1d13xxxfb_par *par, int enable)
145 s1d13xxxfb_writereg(par, S1DREG_COM_DISP_MODE, mode); 157 s1d13xxxfb_writereg(par, S1DREG_COM_DISP_MODE, mode);
146} 158}
147 159
148/* framebuffer control routines */
149 160
161/*************************************************************
162 framebuffer control functions
163 *************************************************************/
150static inline void 164static inline void
151s1d13xxxfb_setup_pseudocolour(struct fb_info *info) 165s1d13xxxfb_setup_pseudocolour(struct fb_info *info)
152{ 166{
@@ -242,13 +256,13 @@ s1d13xxxfb_set_par(struct fb_info *info)
242} 256}
243 257
244/** 258/**
245 * s1d13xxxfb_setcolreg - sets a color register. 259 * s1d13xxxfb_setcolreg - sets a color register.
246 * @regno: Which register in the CLUT we are programming 260 * @regno: Which register in the CLUT we are programming
247 * @red: The red value which can be up to 16 bits wide 261 * @red: The red value which can be up to 16 bits wide
248 * @green: The green value which can be up to 16 bits wide 262 * @green: The green value which can be up to 16 bits wide
249 * @blue: The blue value which can be up to 16 bits wide. 263 * @blue: The blue value which can be up to 16 bits wide.
250 * @transp: If supported the alpha value which can be up to 16 bits wide. 264 * @transp: If supported the alpha value which can be up to 16 bits wide.
251 * @info: frame buffer info structure 265 * @info: frame buffer info structure
252 * 266 *
253 * Returns negative errno on error, or zero on success. 267 * Returns negative errno on error, or zero on success.
254 */ 268 */
@@ -351,15 +365,15 @@ s1d13xxxfb_blank(int blank_mode, struct fb_info *info)
351} 365}
352 366
353/** 367/**
354 * s1d13xxxfb_pan_display - Pans the display. 368 * s1d13xxxfb_pan_display - Pans the display.
355 * @var: frame buffer variable screen structure 369 * @var: frame buffer variable screen structure
356 * @info: frame buffer structure that represents a single frame buffer 370 * @info: frame buffer structure that represents a single frame buffer
357 * 371 *
358 * Pan (or wrap, depending on the `vmode' field) the display using the 372 * Pan (or wrap, depending on the `vmode' field) the display using the
359 * `yoffset' field of the `var' structure (`xoffset' not yet supported). 373 * `yoffset' field of the `var' structure (`xoffset' not yet supported).
360 * If the values don't fit, return -EINVAL. 374 * If the values don't fit, return -EINVAL.
361 * 375 *
362 * Returns negative errno on error, or zero on success. 376 * Returns negative errno on error, or zero on success.
363 */ 377 */
364static int 378static int
365s1d13xxxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 379s1d13xxxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
@@ -390,8 +404,259 @@ s1d13xxxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
390 return 0; 404 return 0;
391} 405}
392 406
393/* framebuffer information structures */ 407/************************************************************
408 functions to handle bitblt acceleration
409 ************************************************************/
410
411/**
412 * bltbit_wait_bitset - waits for change in register value
413 * @info : framebuffer structure
414 * @bit : value expected in register
415 * @timeout : ...
416 *
417 * waits until value changes INTO bit
418 */
419static u8
420bltbit_wait_bitset(struct fb_info *info, u8 bit, int timeout)
421{
422 while (!(s1d13xxxfb_readreg(info->par, S1DREG_BBLT_CTL0) & bit)) {
423 udelay(10);
424 if (!--timeout) {
425 dbg_blit("wait_bitset timeout\n");
426 break;
427 }
428 }
429
430 return timeout;
431}
432
433/**
434 * bltbit_wait_bitclear - waits for change in register value
435 * @info : frambuffer structure
436 * @bit : value currently in register
437 * @timeout : ...
438 *
439 * waits until value changes FROM bit
440 *
441 */
442static u8
443bltbit_wait_bitclear(struct fb_info *info, u8 bit, int timeout)
444{
445 while (s1d13xxxfb_readreg(info->par, S1DREG_BBLT_CTL0) & bit) {
446 udelay(10);
447 if (!--timeout) {
448 dbg_blit("wait_bitclear timeout\n");
449 break;
450 }
451 }
452
453 return timeout;
454}
455
456/**
457 * bltbit_fifo_status - checks the current status of the fifo
458 * @info : framebuffer structure
459 *
460 * returns number of free words in buffer
461 */
462static u8
463bltbit_fifo_status(struct fb_info *info)
464{
465 u8 status;
394 466
467 status = s1d13xxxfb_readreg(info->par, S1DREG_BBLT_CTL0);
468
469 /* its empty so room for 16 words */
470 if (status & BBLT_FIFO_EMPTY)
471 return 16;
472
473 /* its full so we dont want to add */
474 if (status & BBLT_FIFO_FULL)
475 return 0;
476
477 /* its atleast half full but we can add one atleast */
478 if (status & BBLT_FIFO_NOT_FULL)
479 return 1;
480
481 return 0;
482}
483
484/*
485 * s1d13xxxfb_bitblt_copyarea - accelerated copyarea function
486 * @info : framebuffer structure
487 * @area : fb_copyarea structure
488 *
489 * supports (atleast) S1D13506
490 *
491 */
492static void
493s1d13xxxfb_bitblt_copyarea(struct fb_info *info, const struct fb_copyarea *area)
494{
495 u32 dst, src;
496 u32 stride;
497 u16 reverse = 0;
498 u16 sx = area->sx, sy = area->sy;
499 u16 dx = area->dx, dy = area->dy;
500 u16 width = area->width, height = area->height;
501 u16 bpp;
502
503 spin_lock(&s1d13xxxfb_bitblt_lock);
504
505 /* bytes per xres line */
506 bpp = (info->var.bits_per_pixel >> 3);
507 stride = bpp * info->var.xres;
508
509 /* reverse, calculate the last pixel in rectangle */
510 if ((dy > sy) || ((dy == sy) && (dx >= sx))) {
511 dst = (((dy + height - 1) * stride) + (bpp * (dx + width - 1)));
512 src = (((sy + height - 1) * stride) + (bpp * (sx + width - 1)));
513 reverse = 1;
514 /* not reverse, calculate the first pixel in rectangle */
515 } else { /* (y * xres) + (bpp * x) */
516 dst = (dy * stride) + (bpp * dx);
517 src = (sy * stride) + (bpp * sx);
518 }
519
520 /* set source adress */
521 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START0, (src & 0xff));
522 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START1, (src >> 8) & 0x00ff);
523 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_SRC_START2, (src >> 16) & 0x00ff);
524
525 /* set destination adress */
526 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START0, (dst & 0xff));
527 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START1, (dst >> 8) & 0x00ff);
528 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START2, (dst >> 16) & 0x00ff);
529
530 /* program height and width */
531 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_WIDTH0, (width & 0xff) - 1);
532 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_WIDTH1, (width >> 8));
533
534 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_HEIGHT0, (height & 0xff) - 1);
535 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_HEIGHT1, (height >> 8));
536
537 /* negative direction ROP */
538 if (reverse == 1) {
539 dbg_blit("(copyarea) negative rop\n");
540 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_OP, 0x03);
541 } else /* positive direction ROP */ {
542 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_OP, 0x02);
543 dbg_blit("(copyarea) positive rop\n");
544 }
545
546 /* set for rectangel mode and not linear */
547 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL0, 0x0);
548
549 /* setup the bpp 1 = 16bpp, 0 = 8bpp*/
550 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL1, (bpp >> 1));
551
552 /* set words per xres */
553 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_MEM_OFF0, (stride >> 1) & 0xff);
554 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_MEM_OFF1, (stride >> 9));
555
556 dbg_blit("(copyarea) dx=%d, dy=%d\n", dx, dy);
557 dbg_blit("(copyarea) sx=%d, sy=%d\n", sx, sy);
558 dbg_blit("(copyarea) width=%d, height=%d\n", width - 1, height - 1);
559 dbg_blit("(copyarea) stride=%d\n", stride);
560 dbg_blit("(copyarea) bpp=%d=0x0%d, mem_offset1=%d, mem_offset2=%d\n", bpp, (bpp >> 1),
561 (stride >> 1) & 0xff, stride >> 9);
562
563 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CC_EXP, 0x0c);
564
565 /* initialize the engine */
566 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL0, 0x80);
567
568 /* wait to complete */
569 bltbit_wait_bitclear(info, 0x80, 8000);
570
571 spin_unlock(&s1d13xxxfb_bitblt_lock);
572}
573
574/**
575 *
576 * s1d13xxxfb_bitblt_solidfill - accelerated solidfill function
577 * @info : framebuffer structure
578 * @rect : fb_fillrect structure
579 *
580 * supports (atleast 13506)
581 *
582 **/
583static void
584s1d13xxxfb_bitblt_solidfill(struct fb_info *info, const struct fb_fillrect *rect)
585{
586 u32 screen_stride, dest;
587 u32 fg;
588 u16 bpp = (info->var.bits_per_pixel >> 3);
589
590 /* grab spinlock */
591 spin_lock(&s1d13xxxfb_bitblt_lock);
592
593 /* bytes per x width */
594 screen_stride = (bpp * info->var.xres);
595
596 /* bytes to starting point */
597 dest = ((rect->dy * screen_stride) + (bpp * rect->dx));
598
599 dbg_blit("(solidfill) dx=%d, dy=%d, stride=%d, dest=%d\n"
600 "(solidfill) : rect_width=%d, rect_height=%d\n",
601 rect->dx, rect->dy, screen_stride, dest,
602 rect->width - 1, rect->height - 1);
603
604 dbg_blit("(solidfill) : xres=%d, yres=%d, bpp=%d\n",
605 info->var.xres, info->var.yres,
606 info->var.bits_per_pixel);
607 dbg_blit("(solidfill) : rop=%d\n", rect->rop);
608
609 /* We split the destination into the three registers */
610 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START0, (dest & 0x00ff));
611 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START1, ((dest >> 8) & 0x00ff));
612 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_DST_START2, ((dest >> 16) & 0x00ff));
613
614 /* give information regarding rectangel width */
615 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_WIDTH0, ((rect->width) & 0x00ff) - 1);
616 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_WIDTH1, (rect->width >> 8));
617
618 /* give information regarding rectangel height */
619 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_HEIGHT0, ((rect->height) & 0x00ff) - 1);
620 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_HEIGHT1, (rect->height >> 8));
621
622 if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
623 info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
624 fg = ((u32 *)info->pseudo_palette)[rect->color];
625 dbg_blit("(solidfill) truecolor/directcolor\n");
626 dbg_blit("(solidfill) pseudo_palette[%d] = %d\n", rect->color, fg);
627 } else {
628 fg = rect->color;
629 dbg_blit("(solidfill) color = %d\n", rect->color);
630 }
631
632 /* set foreground color */
633 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_FGC0, (fg & 0xff));
634 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_FGC1, (fg >> 8) & 0xff);
635
636 /* set rectangual region of memory (rectangle and not linear) */
637 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL0, 0x0);
638
639 /* set operation mode SOLID_FILL */
640 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_OP, BBLT_SOLID_FILL);
641
642 /* set bits per pixel (1 = 16bpp, 0 = 8bpp) */
643 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL1, (info->var.bits_per_pixel >> 4));
644
645 /* set the memory offset for the bblt in word sizes */
646 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_MEM_OFF0, (screen_stride >> 1) & 0x00ff);
647 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_MEM_OFF1, (screen_stride >> 9));
648
649 /* and away we go.... */
650 s1d13xxxfb_writereg(info->par, S1DREG_BBLT_CTL0, 0x80);
651
652 /* wait until its done */
653 bltbit_wait_bitclear(info, 0x80, 8000);
654
655 /* let others play */
656 spin_unlock(&s1d13xxxfb_bitblt_lock);
657}
658
659/* framebuffer information structures */
395static struct fb_ops s1d13xxxfb_fbops = { 660static struct fb_ops s1d13xxxfb_fbops = {
396 .owner = THIS_MODULE, 661 .owner = THIS_MODULE,
397 .fb_set_par = s1d13xxxfb_set_par, 662 .fb_set_par = s1d13xxxfb_set_par,
@@ -400,7 +665,7 @@ static struct fb_ops s1d13xxxfb_fbops = {
400 665
401 .fb_pan_display = s1d13xxxfb_pan_display, 666 .fb_pan_display = s1d13xxxfb_pan_display,
402 667
403 /* to be replaced by any acceleration we can */ 668 /* gets replaced at chip detection time */
404 .fb_fillrect = cfb_fillrect, 669 .fb_fillrect = cfb_fillrect,
405 .fb_copyarea = cfb_copyarea, 670 .fb_copyarea = cfb_copyarea,
406 .fb_imageblit = cfb_imageblit, 671 .fb_imageblit = cfb_imageblit,
@@ -412,9 +677,9 @@ static int s1d13xxxfb_width_tab[2][4] __devinitdata = {
412}; 677};
413 678
414/** 679/**
415 * s1d13xxxfb_fetch_hw_state - Configure the framebuffer according to 680 * s1d13xxxfb_fetch_hw_state - Configure the framebuffer according to
416 * hardware setup. 681 * hardware setup.
417 * @info: frame buffer structure 682 * @info: frame buffer structure
418 * 683 *
419 * We setup the framebuffer structures according to the current 684 * We setup the framebuffer structures according to the current
420 * hardware setup. On some machines, the BIOS will have filled 685 * hardware setup. On some machines, the BIOS will have filled
@@ -569,7 +834,6 @@ s1d13xxxfb_probe(struct platform_device *pdev)
569 if (pdata && pdata->platform_init_video) 834 if (pdata && pdata->platform_init_video)
570 pdata->platform_init_video(); 835 pdata->platform_init_video();
571 836
572
573 if (pdev->num_resources != 2) { 837 if (pdev->num_resources != 2) {
574 dev_err(&pdev->dev, "invalid num_resources: %i\n", 838 dev_err(&pdev->dev, "invalid num_resources: %i\n",
575 pdev->num_resources); 839 pdev->num_resources);
@@ -655,16 +919,27 @@ s1d13xxxfb_probe(struct platform_device *pdev)
655 919
656 info->fix = s1d13xxxfb_fix; 920 info->fix = s1d13xxxfb_fix;
657 info->fix.mmio_start = pdev->resource[1].start; 921 info->fix.mmio_start = pdev->resource[1].start;
658 info->fix.mmio_len = pdev->resource[1].end - pdev->resource[1].start +1; 922 info->fix.mmio_len = pdev->resource[1].end - pdev->resource[1].start + 1;
659 info->fix.smem_start = pdev->resource[0].start; 923 info->fix.smem_start = pdev->resource[0].start;
660 info->fix.smem_len = pdev->resource[0].end - pdev->resource[0].start +1; 924 info->fix.smem_len = pdev->resource[0].end - pdev->resource[0].start + 1;
661 925
662 printk(KERN_INFO PFX "regs mapped at 0x%p, fb %d KiB mapped at 0x%p\n", 926 printk(KERN_INFO PFX "regs mapped at 0x%p, fb %d KiB mapped at 0x%p\n",
663 default_par->regs, info->fix.smem_len / 1024, info->screen_base); 927 default_par->regs, info->fix.smem_len / 1024, info->screen_base);
664 928
665 info->par = default_par; 929 info->par = default_par;
666 info->fbops = &s1d13xxxfb_fbops;
667 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 930 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
931 info->fbops = &s1d13xxxfb_fbops;
932
933 switch(prod_id) {
934 case S1D13506_PROD_ID: /* activate acceleration */
935 s1d13xxxfb_fbops.fb_fillrect = s1d13xxxfb_bitblt_solidfill;
936 s1d13xxxfb_fbops.fb_copyarea = s1d13xxxfb_bitblt_copyarea;
937 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |
938 FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_COPYAREA;
939 break;
940 default:
941 break;
942 }
668 943
669 /* perform "manual" chip initialization, if needed */ 944 /* perform "manual" chip initialization, if needed */
670 if (pdata && pdata->initregs) 945 if (pdata && pdata->initregs)
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index d3a568e6b169..43680e545427 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -358,9 +358,16 @@ static int s3c_fb_set_par(struct fb_info *info)
358 writel(data, regs + VIDOSD_B(win_no)); 358 writel(data, regs + VIDOSD_B(win_no));
359 359
360 data = var->xres * var->yres; 360 data = var->xres * var->yres;
361
362 u32 osdc_data = 0;
363
364 osdc_data = VIDISD14C_ALPHA1_R(0xf) |
365 VIDISD14C_ALPHA1_G(0xf) |
366 VIDISD14C_ALPHA1_B(0xf);
367
361 if (s3c_fb_has_osd_d(win_no)) { 368 if (s3c_fb_has_osd_d(win_no)) {
362 writel(data, regs + VIDOSD_D(win_no)); 369 writel(data, regs + VIDOSD_D(win_no));
363 writel(0, regs + VIDOSD_C(win_no)); 370 writel(osdc_data, regs + VIDOSD_C(win_no));
364 } else 371 } else
365 writel(data, regs + VIDOSD_C(win_no)); 372 writel(data, regs + VIDOSD_C(win_no));
366 373
@@ -409,8 +416,12 @@ static int s3c_fb_set_par(struct fb_info *info)
409 data |= WINCON1_BPPMODE_19BPP_A1666; 416 data |= WINCON1_BPPMODE_19BPP_A1666;
410 else 417 else
411 data |= WINCON1_BPPMODE_18BPP_666; 418 data |= WINCON1_BPPMODE_18BPP_666;
412 } else if (var->transp.length != 0) 419 } else if (var->transp.length == 1)
413 data |= WINCON1_BPPMODE_25BPP_A1888; 420 data |= WINCON1_BPPMODE_25BPP_A1888
421 | WINCON1_BLD_PIX;
422 else if (var->transp.length == 4)
423 data |= WINCON1_BPPMODE_28BPP_A4888
424 | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL;
414 else 425 else
415 data |= WINCON0_BPPMODE_24BPP_888; 426 data |= WINCON0_BPPMODE_24BPP_888;
416 427
@@ -418,6 +429,20 @@ static int s3c_fb_set_par(struct fb_info *info)
418 break; 429 break;
419 } 430 }
420 431
432 /* It has no color key control register for window0 */
433 if (win_no > 0) {
434 u32 keycon0_data = 0, keycon1_data = 0;
435
436 keycon0_data = ~(WxKEYCON0_KEYBL_EN |
437 WxKEYCON0_KEYEN_F |
438 WxKEYCON0_DIRCON) | WxKEYCON0_COMPKEY(0);
439
440 keycon1_data = WxKEYCON1_COLVAL(0xffffff);
441
442 writel(keycon0_data, regs + WxKEYCONy(win_no-1, 0));
443 writel(keycon1_data, regs + WxKEYCONy(win_no-1, 1));
444 }
445
421 writel(data, regs + WINCON(win_no)); 446 writel(data, regs + WINCON(win_no));
422 writel(0x0, regs + WINxMAP(win_no)); 447 writel(0x0, regs + WINxMAP(win_no));
423 448
@@ -700,9 +725,12 @@ static void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win)
700 */ 725 */
701static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win) 726static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win)
702{ 727{
703 fb_dealloc_cmap(&win->fbinfo->cmap); 728 if (win->fbinfo) {
704 unregister_framebuffer(win->fbinfo); 729 unregister_framebuffer(win->fbinfo);
705 s3c_fb_free_memory(sfb, win); 730 fb_dealloc_cmap(&win->fbinfo->cmap);
731 s3c_fb_free_memory(sfb, win);
732 framebuffer_release(win->fbinfo);
733 }
706} 734}
707 735
708/** 736/**
@@ -753,7 +781,7 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
753 ret = s3c_fb_alloc_memory(sfb, win); 781 ret = s3c_fb_alloc_memory(sfb, win);
754 if (ret) { 782 if (ret) {
755 dev_err(sfb->dev, "failed to allocate display memory\n"); 783 dev_err(sfb->dev, "failed to allocate display memory\n");
756 goto err_framebuffer; 784 return ret;
757 } 785 }
758 786
759 /* setup the r/b/g positions for the window's palette */ 787 /* setup the r/b/g positions for the window's palette */
@@ -776,7 +804,7 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
776 ret = s3c_fb_check_var(&fbinfo->var, fbinfo); 804 ret = s3c_fb_check_var(&fbinfo->var, fbinfo);
777 if (ret < 0) { 805 if (ret < 0) {
778 dev_err(sfb->dev, "check_var failed on initial video params\n"); 806 dev_err(sfb->dev, "check_var failed on initial video params\n");
779 goto err_alloc_mem; 807 return ret;
780 } 808 }
781 809
782 /* create initial colour map */ 810 /* create initial colour map */
@@ -796,20 +824,13 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
796 ret = register_framebuffer(fbinfo); 824 ret = register_framebuffer(fbinfo);
797 if (ret < 0) { 825 if (ret < 0) {
798 dev_err(sfb->dev, "failed to register framebuffer\n"); 826 dev_err(sfb->dev, "failed to register framebuffer\n");
799 goto err_alloc_mem; 827 return ret;
800 } 828 }
801 829
802 *res = win; 830 *res = win;
803 dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id); 831 dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id);
804 832
805 return 0; 833 return 0;
806
807err_alloc_mem:
808 s3c_fb_free_memory(sfb, win);
809
810err_framebuffer:
811 unregister_framebuffer(fbinfo);
812 return ret;
813} 834}
814 835
815/** 836/**
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index b0b4513ba537..7da0027e2409 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -24,6 +24,7 @@
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/clk.h> 26#include <linux/clk.h>
27#include <linux/cpufreq.h>
27 28
28#include <asm/io.h> 29#include <asm/io.h>
29#include <asm/div64.h> 30#include <asm/div64.h>
@@ -89,7 +90,7 @@ static void s3c2410fb_set_lcdaddr(struct fb_info *info)
89static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi, 90static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi,
90 unsigned long pixclk) 91 unsigned long pixclk)
91{ 92{
92 unsigned long clk = clk_get_rate(fbi->clk); 93 unsigned long clk = fbi->clk_rate;
93 unsigned long long div; 94 unsigned long long div;
94 95
95 /* pixclk is in picoseconds, our clock is in Hz 96 /* pixclk is in picoseconds, our clock is in Hz
@@ -758,6 +759,57 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)
758 return IRQ_HANDLED; 759 return IRQ_HANDLED;
759} 760}
760 761
762#ifdef CONFIG_CPU_FREQ
763
764static int s3c2410fb_cpufreq_transition(struct notifier_block *nb,
765 unsigned long val, void *data)
766{
767 struct cpufreq_freqs *freqs = data;
768 struct s3c2410fb_info *info;
769 struct fb_info *fbinfo;
770 long delta_f;
771
772 info = container_of(nb, struct s3c2410fb_info, freq_transition);
773 fbinfo = platform_get_drvdata(to_platform_device(info->dev));
774
775 /* work out change, <0 for speed-up */
776 delta_f = info->clk_rate - clk_get_rate(info->clk);
777
778 if ((val == CPUFREQ_POSTCHANGE && delta_f > 0) ||
779 (val == CPUFREQ_PRECHANGE && delta_f < 0)) {
780 info->clk_rate = clk_get_rate(info->clk);
781 s3c2410fb_activate_var(fbinfo);
782 }
783
784 return 0;
785}
786
787static inline int s3c2410fb_cpufreq_register(struct s3c2410fb_info *info)
788{
789 info->freq_transition.notifier_call = s3c2410fb_cpufreq_transition;
790
791 return cpufreq_register_notifier(&info->freq_transition,
792 CPUFREQ_TRANSITION_NOTIFIER);
793}
794
795static inline void s3c2410fb_cpufreq_deregister(struct s3c2410fb_info *info)
796{
797 cpufreq_unregister_notifier(&info->freq_transition,
798 CPUFREQ_TRANSITION_NOTIFIER);
799}
800
801#else
802static inline int s3c2410fb_cpufreq_register(struct s3c2410fb_info *info)
803{
804 return 0;
805}
806
807static inline void s3c2410fb_cpufreq_deregister(struct s3c2410fb_info *info)
808{
809}
810#endif
811
812
761static char driver_name[] = "s3c2410fb"; 813static char driver_name[] = "s3c2410fb";
762 814
763static int __init s3c24xxfb_probe(struct platform_device *pdev, 815static int __init s3c24xxfb_probe(struct platform_device *pdev,
@@ -875,6 +927,8 @@ static int __init s3c24xxfb_probe(struct platform_device *pdev,
875 927
876 msleep(1); 928 msleep(1);
877 929
930 info->clk_rate = clk_get_rate(info->clk);
931
878 /* find maximum required memory size for display */ 932 /* find maximum required memory size for display */
879 for (i = 0; i < mach_info->num_displays; i++) { 933 for (i = 0; i < mach_info->num_displays; i++) {
880 unsigned long smem_len = mach_info->displays[i].xres; 934 unsigned long smem_len = mach_info->displays[i].xres;
@@ -904,11 +958,17 @@ static int __init s3c24xxfb_probe(struct platform_device *pdev,
904 958
905 s3c2410fb_check_var(&fbinfo->var, fbinfo); 959 s3c2410fb_check_var(&fbinfo->var, fbinfo);
906 960
961 ret = s3c2410fb_cpufreq_register(info);
962 if (ret < 0) {
963 dev_err(&pdev->dev, "Failed to register cpufreq\n");
964 goto free_video_memory;
965 }
966
907 ret = register_framebuffer(fbinfo); 967 ret = register_framebuffer(fbinfo);
908 if (ret < 0) { 968 if (ret < 0) {
909 printk(KERN_ERR "Failed to register framebuffer device: %d\n", 969 printk(KERN_ERR "Failed to register framebuffer device: %d\n",
910 ret); 970 ret);
911 goto free_video_memory; 971 goto free_cpufreq;
912 } 972 }
913 973
914 /* create device files */ 974 /* create device files */
@@ -922,6 +982,8 @@ static int __init s3c24xxfb_probe(struct platform_device *pdev,
922 982
923 return 0; 983 return 0;
924 984
985 free_cpufreq:
986 s3c2410fb_cpufreq_deregister(info);
925free_video_memory: 987free_video_memory:
926 s3c2410fb_unmap_video_memory(fbinfo); 988 s3c2410fb_unmap_video_memory(fbinfo);
927release_clock: 989release_clock:
@@ -961,6 +1023,7 @@ static int s3c2410fb_remove(struct platform_device *pdev)
961 int irq; 1023 int irq;
962 1024
963 unregister_framebuffer(fbinfo); 1025 unregister_framebuffer(fbinfo);
1026 s3c2410fb_cpufreq_deregister(info);
964 1027
965 s3c2410fb_lcd_enable(info, 0); 1028 s3c2410fb_lcd_enable(info, 0);
966 msleep(1); 1029 msleep(1);
diff --git a/drivers/video/s3c2410fb.h b/drivers/video/s3c2410fb.h
index 9a6ba3e9d1b8..47a17bd23011 100644
--- a/drivers/video/s3c2410fb.h
+++ b/drivers/video/s3c2410fb.h
@@ -29,8 +29,13 @@ struct s3c2410fb_info {
29 enum s3c_drv_type drv_type; 29 enum s3c_drv_type drv_type;
30 struct s3c2410fb_hw regs; 30 struct s3c2410fb_hw regs;
31 31
32 unsigned long clk_rate;
32 unsigned int palette_ready; 33 unsigned int palette_ready;
33 34
35#ifdef CONFIG_CPU_FREQ
36 struct notifier_block freq_transition;
37#endif
38
34 /* keep these registers in case we need to re-write palette */ 39 /* keep these registers in case we need to re-write palette */
35 u32 palette_buffer[256]; 40 u32 palette_buffer[256];
36 u32 pseudo_pal[16]; 41 u32 pseudo_pal[16];
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 7e17ee95a97a..7072d19080d5 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -5928,7 +5928,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
5928 if(pci_enable_device(pdev)) { 5928 if(pci_enable_device(pdev)) {
5929 if(ivideo->nbridge) pci_dev_put(ivideo->nbridge); 5929 if(ivideo->nbridge) pci_dev_put(ivideo->nbridge);
5930 pci_set_drvdata(pdev, NULL); 5930 pci_set_drvdata(pdev, NULL);
5931 kfree(sis_fb_info); 5931 framebuffer_release(sis_fb_info);
5932 return -EIO; 5932 return -EIO;
5933 } 5933 }
5934 } 5934 }
@@ -6134,7 +6134,7 @@ error_3: vfree(ivideo->bios_abase);
6134 pci_set_drvdata(pdev, NULL); 6134 pci_set_drvdata(pdev, NULL);
6135 if(!ivideo->sisvga_enabled) 6135 if(!ivideo->sisvga_enabled)
6136 pci_disable_device(pdev); 6136 pci_disable_device(pdev);
6137 kfree(sis_fb_info); 6137 framebuffer_release(sis_fb_info);
6138 return ret; 6138 return ret;
6139 } 6139 }
6140 6140
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c
index eabaad765aeb..eec9dcb7f599 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/stifb.c
@@ -1380,7 +1380,7 @@ stifb_cleanup(void)
1380 if (info->screen_base) 1380 if (info->screen_base)
1381 iounmap(info->screen_base); 1381 iounmap(info->screen_base);
1382 fb_dealloc_cmap(&info->cmap); 1382 fb_dealloc_cmap(&info->cmap);
1383 kfree(info); 1383 framebuffer_release(info);
1384 } 1384 }
1385 sti->info = NULL; 1385 sti->info = NULL;
1386 } 1386 }
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 643afbfe8277..45b883598bf0 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -116,17 +116,16 @@ struct tcx_par {
116 u32 flags; 116 u32 flags;
117#define TCX_FLAG_BLANKED 0x00000001 117#define TCX_FLAG_BLANKED 0x00000001
118 118
119 unsigned long physbase;
120 unsigned long which_io; 119 unsigned long which_io;
121 unsigned long fbsize;
122 120
123 struct sbus_mmap_map mmap_map[TCX_MMAP_ENTRIES]; 121 struct sbus_mmap_map mmap_map[TCX_MMAP_ENTRIES];
124 int lowdepth; 122 int lowdepth;
125}; 123};
126 124
127/* Reset control plane so that WID is 8-bit plane. */ 125/* Reset control plane so that WID is 8-bit plane. */
128static void __tcx_set_control_plane(struct tcx_par *par) 126static void __tcx_set_control_plane(struct fb_info *info)
129{ 127{
128 struct tcx_par *par = info->par;
130 u32 __iomem *p, *pend; 129 u32 __iomem *p, *pend;
131 130
132 if (par->lowdepth) 131 if (par->lowdepth)
@@ -135,7 +134,7 @@ static void __tcx_set_control_plane(struct tcx_par *par)
135 p = par->cplane; 134 p = par->cplane;
136 if (p == NULL) 135 if (p == NULL)
137 return; 136 return;
138 for (pend = p + par->fbsize; p < pend; p++) { 137 for (pend = p + info->fix.smem_len; p < pend; p++) {
139 u32 tmp = sbus_readl(p); 138 u32 tmp = sbus_readl(p);
140 139
141 tmp &= 0xffffff; 140 tmp &= 0xffffff;
@@ -149,7 +148,7 @@ static void tcx_reset(struct fb_info *info)
149 unsigned long flags; 148 unsigned long flags;
150 149
151 spin_lock_irqsave(&par->lock, flags); 150 spin_lock_irqsave(&par->lock, flags);
152 __tcx_set_control_plane(par); 151 __tcx_set_control_plane(info);
153 spin_unlock_irqrestore(&par->lock, flags); 152 spin_unlock_irqrestore(&par->lock, flags);
154} 153}
155 154
@@ -304,7 +303,7 @@ static int tcx_mmap(struct fb_info *info, struct vm_area_struct *vma)
304 struct tcx_par *par = (struct tcx_par *)info->par; 303 struct tcx_par *par = (struct tcx_par *)info->par;
305 304
306 return sbusfb_mmap_helper(par->mmap_map, 305 return sbusfb_mmap_helper(par->mmap_map,
307 par->physbase, par->fbsize, 306 info->fix.smem_start, info->fix.smem_len,
308 par->which_io, vma); 307 par->which_io, vma);
309} 308}
310 309
@@ -316,7 +315,7 @@ static int tcx_ioctl(struct fb_info *info, unsigned int cmd,
316 return sbusfb_ioctl_helper(cmd, arg, info, 315 return sbusfb_ioctl_helper(cmd, arg, info,
317 FBTYPE_TCXCOLOR, 316 FBTYPE_TCXCOLOR,
318 (par->lowdepth ? 8 : 24), 317 (par->lowdepth ? 8 : 24),
319 par->fbsize); 318 info->fix.smem_len);
320} 319}
321 320
322/* 321/*
@@ -358,10 +357,10 @@ static void tcx_unmap_regs(struct of_device *op, struct fb_info *info,
358 par->bt, sizeof(struct bt_regs)); 357 par->bt, sizeof(struct bt_regs));
359 if (par->cplane) 358 if (par->cplane)
360 of_iounmap(&op->resource[4], 359 of_iounmap(&op->resource[4],
361 par->cplane, par->fbsize * sizeof(u32)); 360 par->cplane, info->fix.smem_len * sizeof(u32));
362 if (info->screen_base) 361 if (info->screen_base)
363 of_iounmap(&op->resource[0], 362 of_iounmap(&op->resource[0],
364 info->screen_base, par->fbsize); 363 info->screen_base, info->fix.smem_len);
365} 364}
366 365
367static int __devinit tcx_probe(struct of_device *op, 366static int __devinit tcx_probe(struct of_device *op,
@@ -391,7 +390,7 @@ static int __devinit tcx_probe(struct of_device *op,
391 390
392 linebytes = of_getintprop_default(dp, "linebytes", 391 linebytes = of_getintprop_default(dp, "linebytes",
393 info->var.xres); 392 info->var.xres);
394 par->fbsize = PAGE_ALIGN(linebytes * info->var.yres); 393 info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres);
395 394
396 par->tec = of_ioremap(&op->resource[7], 0, 395 par->tec = of_ioremap(&op->resource[7], 0,
397 sizeof(struct tcx_tec), "tcx tec"); 396 sizeof(struct tcx_tec), "tcx tec");
@@ -400,7 +399,7 @@ static int __devinit tcx_probe(struct of_device *op,
400 par->bt = of_ioremap(&op->resource[8], 0, 399 par->bt = of_ioremap(&op->resource[8], 0,
401 sizeof(struct bt_regs), "tcx dac"); 400 sizeof(struct bt_regs), "tcx dac");
402 info->screen_base = of_ioremap(&op->resource[0], 0, 401 info->screen_base = of_ioremap(&op->resource[0], 0,
403 par->fbsize, "tcx ram"); 402 info->fix.smem_len, "tcx ram");
404 if (!par->tec || !par->thc || 403 if (!par->tec || !par->thc ||
405 !par->bt || !info->screen_base) 404 !par->bt || !info->screen_base)
406 goto out_unmap_regs; 405 goto out_unmap_regs;
@@ -408,7 +407,7 @@ static int __devinit tcx_probe(struct of_device *op,
408 memcpy(&par->mmap_map, &__tcx_mmap_map, sizeof(par->mmap_map)); 407 memcpy(&par->mmap_map, &__tcx_mmap_map, sizeof(par->mmap_map));
409 if (!par->lowdepth) { 408 if (!par->lowdepth) {
410 par->cplane = of_ioremap(&op->resource[4], 0, 409 par->cplane = of_ioremap(&op->resource[4], 0,
411 par->fbsize * sizeof(u32), 410 info->fix.smem_len * sizeof(u32),
412 "tcx cplane"); 411 "tcx cplane");
413 if (!par->cplane) 412 if (!par->cplane)
414 goto out_unmap_regs; 413 goto out_unmap_regs;
@@ -419,7 +418,7 @@ static int __devinit tcx_probe(struct of_device *op,
419 par->mmap_map[6].size = SBUS_MMAP_EMPTY; 418 par->mmap_map[6].size = SBUS_MMAP_EMPTY;
420 } 419 }
421 420
422 par->physbase = op->resource[0].start; 421 info->fix.smem_start = op->resource[0].start;
423 par->which_io = op->resource[0].flags & IORESOURCE_BITS; 422 par->which_io = op->resource[0].flags & IORESOURCE_BITS;
424 423
425 for (i = 0; i < TCX_MMAP_ENTRIES; i++) { 424 for (i = 0; i < TCX_MMAP_ENTRIES; i++) {
@@ -473,7 +472,7 @@ static int __devinit tcx_probe(struct of_device *op,
473 printk(KERN_INFO "%s: TCX at %lx:%lx, %s\n", 472 printk(KERN_INFO "%s: TCX at %lx:%lx, %s\n",
474 dp->full_name, 473 dp->full_name,
475 par->which_io, 474 par->which_io,
476 par->physbase, 475 info->fix.smem_start,
477 par->lowdepth ? "8-bit only" : "24-bit depth"); 476 par->lowdepth ? "8-bit only" : "24-bit depth");
478 477
479 return 0; 478 return 0;
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index d6856f43d241..bd37ee1f6a25 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -174,8 +174,17 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
174 return err; 174 return err;
175} 175}
176 176
177static void vesafb_destroy(struct fb_info *info)
178{
179 if (info->screen_base)
180 iounmap(info->screen_base);
181 release_mem_region(info->aperture_base, info->aperture_size);
182 framebuffer_release(info);
183}
184
177static struct fb_ops vesafb_ops = { 185static struct fb_ops vesafb_ops = {
178 .owner = THIS_MODULE, 186 .owner = THIS_MODULE,
187 .fb_destroy = vesafb_destroy,
179 .fb_setcolreg = vesafb_setcolreg, 188 .fb_setcolreg = vesafb_setcolreg,
180 .fb_pan_display = vesafb_pan_display, 189 .fb_pan_display = vesafb_pan_display,
181 .fb_fillrect = cfb_fillrect, 190 .fb_fillrect = cfb_fillrect,
@@ -286,6 +295,10 @@ static int __init vesafb_probe(struct platform_device *dev)
286 info->pseudo_palette = info->par; 295 info->pseudo_palette = info->par;
287 info->par = NULL; 296 info->par = NULL;
288 297
298 /* set vesafb aperture size for generic probing */
299 info->aperture_base = screen_info.lfb_base;
300 info->aperture_size = size_total;
301
289 info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len); 302 info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
290 if (!info->screen_base) { 303 if (!info->screen_base) {
291 printk(KERN_ERR 304 printk(KERN_ERR
@@ -437,7 +450,7 @@ static int __init vesafb_probe(struct platform_device *dev)
437 info->fbops = &vesafb_ops; 450 info->fbops = &vesafb_ops;
438 info->var = vesafb_defined; 451 info->var = vesafb_defined;
439 info->fix = vesafb_fix; 452 info->fix = vesafb_fix;
440 info->flags = FBINFO_FLAG_DEFAULT | 453 info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE |
441 (ypan ? FBINFO_HWACCEL_YPAN : 0); 454 (ypan ? FBINFO_HWACCEL_YPAN : 0);
442 455
443 if (!ypan) 456 if (!ypan)