aboutsummaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig4
-rw-r--r--drivers/video/aty/aty128fb.c14
-rw-r--r--drivers/video/aty/radeon_base.c5
-rw-r--r--drivers/video/au1100fb.c18
-rw-r--r--drivers/video/chipsfb.c176
-rw-r--r--drivers/video/console/Kconfig5
-rw-r--r--drivers/video/console/fbcon.c11
-rw-r--r--drivers/video/fbcmap.c96
-rw-r--r--drivers/video/fbmem.c7
-rw-r--r--drivers/video/fbmon.c2
-rw-r--r--drivers/video/fbsysfs.c92
-rw-r--r--drivers/video/imxfb.c14
-rw-r--r--drivers/video/imxfb.h1
-rw-r--r--drivers/video/logo/Kconfig5
-rw-r--r--drivers/video/logo/Makefile1
-rw-r--r--drivers/video/logo/logo.c5
-rw-r--r--drivers/video/logo/logo_m32r_clut224.ppm1292
-rw-r--r--drivers/video/matrox/matroxfb_maven.c1
-rw-r--r--drivers/video/matrox/matroxfb_misc.c5
-rw-r--r--drivers/video/modedb.c5
-rw-r--r--drivers/video/nvidia/nvidia.c7
-rw-r--r--drivers/video/platinumfb.c6
-rw-r--r--drivers/video/pm2fb.c16
-rw-r--r--drivers/video/pxafb.c3
-rw-r--r--drivers/video/riva/fbdev.c2
-rw-r--r--drivers/video/s1d13xxxfb.c10
-rw-r--r--drivers/video/sa1100fb.c2
-rw-r--r--drivers/video/savage/savagefb_driver.c2
-rw-r--r--drivers/video/tridentfb.c28
-rw-r--r--drivers/video/vesafb.c46
30 files changed, 1638 insertions, 243 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 04d3120f723..cde0ed097af 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1399,8 +1399,8 @@ config FB_TX3912
Say Y here to enable kernel support for the on-board framebuffer.
config FB_G364
- bool
- depends on MIPS_MAGNUM_4000 || OLIVETTI_M700
+ bool "G364 frame buffer support"
+ depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 9789115980a..7bc1d44d881 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -350,10 +350,8 @@ static int default_vmode __initdata = VMODE_1024_768_60;
static int default_cmode __initdata = CMODE_8;
#endif
-#ifdef CONFIG_PMAC_PBOOK
static int default_crt_on __initdata = 0;
static int default_lcd_on __initdata = 1;
-#endif
#ifdef CONFIG_MTRR
static int mtrr = 1;
@@ -1249,7 +1247,6 @@ static int aty128_crtc_to_var(const struct aty128_crtc *crtc,
return 0;
}
-#ifdef CONFIG_PMAC_PBOOK
static void aty128_set_crt_enable(struct aty128fb_par *par, int on)
{
if (on) {
@@ -1284,7 +1281,6 @@ static void aty128_set_lcd_enable(struct aty128fb_par *par, int on)
aty_st_le32(LVDS_GEN_CNTL, reg);
}
}
-#endif /* CONFIG_PMAC_PBOOK */
static void aty128_set_pll(struct aty128_pll *pll, const struct aty128fb_par *par)
{
@@ -1491,12 +1487,10 @@ static int aty128fb_set_par(struct fb_info *info)
info->fix.visual = par->crtc.bpp == 8 ? FB_VISUAL_PSEUDOCOLOR
: FB_VISUAL_DIRECTCOLOR;
-#ifdef CONFIG_PMAC_PBOOK
if (par->chip_gen == rage_M3) {
aty128_set_crt_enable(par, par->crt_on);
aty128_set_lcd_enable(par, par->lcd_on);
}
-#endif
if (par->accel_flags & FB_ACCELF_TEXT)
aty128_init_engine(par);
@@ -1652,7 +1646,6 @@ static int __init aty128fb_setup(char *options)
return 0;
while ((this_opt = strsep(&options, ",")) != NULL) {
-#ifdef CONFIG_PMAC_PBOOK
if (!strncmp(this_opt, "lcd:", 4)) {
default_lcd_on = simple_strtoul(this_opt+4, NULL, 0);
continue;
@@ -1660,7 +1653,6 @@ static int __init aty128fb_setup(char *options)
default_crt_on = simple_strtoul(this_opt+4, NULL, 0);
continue;
}
-#endif
#ifdef CONFIG_MTRR
if(!strncmp(this_opt, "nomtrr", 6)) {
mtrr = 0;
@@ -1752,10 +1744,8 @@ static int __init aty128_init(struct pci_dev *pdev, const struct pci_device_id *
info->fbops = &aty128fb_ops;
info->flags = FBINFO_FLAG_DEFAULT;
-#ifdef CONFIG_PMAC_PBOOK
par->lcd_on = default_lcd_on;
par->crt_on = default_crt_on;
-#endif
var = default_var;
#ifdef CONFIG_PPC_PMAC
@@ -2035,12 +2025,10 @@ static int aty128fb_blank(int blank, struct fb_info *fb)
aty_st_8(CRTC_EXT_CNTL+1, state);
-#ifdef CONFIG_PMAC_PBOOK
if (par->chip_gen == rage_M3) {
aty128_set_crt_enable(par, par->crt_on && !blank);
aty128_set_lcd_enable(par, par->lcd_on && !blank);
}
-#endif
#ifdef CONFIG_PMAC_BACKLIGHT
if ((_machine == _MACH_Pmac) && !blank)
set_backlight_enable(1);
@@ -2124,7 +2112,6 @@ static int aty128fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
u_long arg, struct fb_info *info)
{
-#ifdef CONFIG_PMAC_PBOOK
struct aty128fb_par *par = info->par;
u32 value;
int rc;
@@ -2149,7 +2136,6 @@ static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
value = (par->crt_on << 1) | par->lcd_on;
return put_user(value, (__u32 __user *)arg);
}
-#endif
return -EINVAL;
}
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 47a6b12bc96..e7e8b52014c 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -2521,6 +2521,11 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
radeonfb_pm_exit(rinfo);
+ if (rinfo->mon1_EDID)
+ sysfs_remove_bin_file(&rinfo->pdev->dev.kobj, &edid1_attr);
+ if (rinfo->mon2_EDID)
+ sysfs_remove_bin_file(&rinfo->pdev->dev.kobj, &edid2_attr);
+
#if 0
/* restore original state
*
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index cacd88cc84a..b6fe30c3ad6 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -111,15 +111,15 @@ static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
void au1100_nocursor(struct display *p, int mode, int xx, int yy){};
static struct fb_ops au1100fb_ops = {
- owner: THIS_MODULE,
- fb_get_fix: fbgen_get_fix,
- fb_get_var: fbgen_get_var,
- fb_set_var: fbgen_set_var,
- fb_get_cmap: fbgen_get_cmap,
- fb_set_cmap: fbgen_set_cmap,
- fb_pan_display: fbgen_pan_display,
- fb_ioctl: au1100fb_ioctl,
- fb_mmap: au1100fb_mmap,
+ .owner = THIS_MODULE,
+ .fb_get_fix = fbgen_get_fix,
+ .fb_get_var = fbgen_get_var,
+ .fb_set_var = fbgen_set_var,
+ .fb_get_cmap = fbgen_get_cmap,
+ .fb_set_cmap = fbgen_set_cmap,
+ .fb_pan_display = fbgen_pan_display,
+ .fb_ioctl = au1100fb_ioctl,
+ .fb_mmap = au1100fb_mmap,
};
static void au1100_detect(void)
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index 95e72550d43..e75a965ec76 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -28,22 +28,17 @@
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/console.h>
#include <asm/io.h>
#ifdef CONFIG_PMAC_BACKLIGHT
#include <asm/backlight.h>
#endif
-#ifdef CONFIG_PMAC_PBOOK
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#endif
/*
* Since we access the display with inb/outb to fixed port numbers,
* we can only handle one 6555x chip. -- paulus
*/
-static struct fb_info chipsfb_info;
-
#define write_ind(num, val, ap, dp) do { \
outb((num), (ap)); outb((val), (dp)); \
} while (0)
@@ -74,14 +69,6 @@ static struct fb_info chipsfb_info;
inb(0x3da); read_ind(num, var, 0x3c0, 0x3c1); \
} while (0)
-#ifdef CONFIG_PMAC_PBOOK
-static unsigned char *save_framebuffer;
-int chips_sleep_notify(struct pmu_sleep_notifier *self, int when);
-static struct pmu_sleep_notifier chips_sleep_notifier = {
- chips_sleep_notify, SLEEP_LEVEL_VIDEO,
-};
-#endif
-
/*
* Exported functions
*/
@@ -356,6 +343,8 @@ static struct fb_var_screeninfo chipsfb_var __initdata = {
static void __init init_chips(struct fb_info *p, unsigned long addr)
{
+ memset(p->screen_base, 0, 0x100000);
+
p->fix = chipsfb_fix;
p->fix.smem_start = addr;
@@ -366,34 +355,41 @@ static void __init init_chips(struct fb_info *p, unsigned long addr)
fb_alloc_cmap(&p->cmap, 256, 0);
- if (register_framebuffer(p) < 0) {
- printk(KERN_ERR "C&T 65550 framebuffer failed to register\n");
- return;
- }
-
- printk(KERN_INFO "fb%d: Chips 65550 frame buffer (%dK RAM detected)\n",
- p->node, p->fix.smem_len / 1024);
-
chips_hw_init();
}
static int __devinit
chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
{
- struct fb_info *p = &chipsfb_info;
+ struct fb_info *p;
unsigned long addr, size;
unsigned short cmd;
+ int rc = -ENODEV;
+
+ if (pci_enable_device(dp) < 0) {
+ dev_err(&dp->dev, "Cannot enable PCI device\n");
+ goto err_out;
+ }
if ((dp->resource[0].flags & IORESOURCE_MEM) == 0)
- return -ENODEV;
+ goto err_disable;
addr = pci_resource_start(dp, 0);
size = pci_resource_len(dp, 0);
if (addr == 0)
- return -ENODEV;
- if (p->screen_base != 0)
- return -EBUSY;
- if (!request_mem_region(addr, size, "chipsfb"))
- return -EBUSY;
+ goto err_disable;
+
+ p = framebuffer_alloc(0, &dp->dev);
+ if (p == NULL) {
+ dev_err(&dp->dev, "Cannot allocate framebuffer structure\n");
+ rc = -ENOMEM;
+ goto err_disable;
+ }
+
+ if (pci_request_region(dp, 0, "chipsfb") != 0) {
+ dev_err(&dp->dev, "Cannot request framebuffer\n");
+ rc = -EBUSY;
+ goto err_release_fb;
+ }
#ifdef __BIG_ENDIAN
addr += 0x800000; // Use big-endian aperture
@@ -411,37 +407,89 @@ chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
set_backlight_enable(1);
#endif /* CONFIG_PMAC_BACKLIGHT */
+#ifdef CONFIG_PPC
p->screen_base = __ioremap(addr, 0x200000, _PAGE_NO_CACHE);
+#else
+ p->screen_base = ioremap(addr, 0x200000);
+#endif
if (p->screen_base == NULL) {
- release_mem_region(addr, size);
- return -ENOMEM;
+ dev_err(&dp->dev, "Cannot map framebuffer\n");
+ rc = -ENOMEM;
+ goto err_release_pci;
}
+
+ pci_set_drvdata(dp, p);
p->device = &dp->dev;
+
init_chips(p, addr);
-#ifdef CONFIG_PMAC_PBOOK
- pmu_register_sleep_notifier(&chips_sleep_notifier);
-#endif /* CONFIG_PMAC_PBOOK */
+ if (register_framebuffer(p) < 0) {
+ dev_err(&dp->dev,"C&T 65550 framebuffer failed to register\n");
+ goto err_unmap;
+ }
+
+ dev_info(&dp->dev,"fb%d: Chips 65550 frame buffer"
+ " (%dK RAM detected)\n",
+ p->node, p->fix.smem_len / 1024);
- pci_set_drvdata(dp, p);
return 0;
+
+ err_unmap:
+ iounmap(p->screen_base);
+ err_release_pci:
+ pci_release_region(dp, 0);
+ err_release_fb:
+ framebuffer_release(p);
+ err_disable:
+ err_out:
+ return rc;
}
static void __devexit chipsfb_remove(struct pci_dev *dp)
{
struct fb_info *p = pci_get_drvdata(dp);
- if (p != &chipsfb_info || p->screen_base == NULL)
+ if (p->screen_base == NULL)
return;
unregister_framebuffer(p);
iounmap(p->screen_base);
p->screen_base = NULL;
- release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0));
+ pci_release_region(dp, 0);
+}
+
+#ifdef CONFIG_PM
+static int chipsfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct fb_info *p = pci_get_drvdata(pdev);
+
+ if (state == pdev->dev.power.power_state)
+ return 0;
+ if (state != PM_SUSPEND_MEM)
+ goto done;
+
+ acquire_console_sem();
+ chipsfb_blank(1, p);
+ fb_set_suspend(p, 1);
+ release_console_sem();
+ done:
+ pdev->dev.power.power_state = state;
+ return 0;
+}
+
+static int chipsfb_pci_resume(struct pci_dev *pdev)
+{
+ struct fb_info *p = pci_get_drvdata(pdev);
-#ifdef CONFIG_PMAC_PBOOK
- pmu_unregister_sleep_notifier(&chips_sleep_notifier);
-#endif /* CONFIG_PMAC_PBOOK */
+ acquire_console_sem();
+ fb_set_suspend(p, 0);
+ chipsfb_blank(0, p);
+ release_console_sem();
+
+ pdev->dev.power.power_state = PMSG_ON;
+ return 0;
}
+#endif /* CONFIG_PM */
+
static struct pci_device_id chipsfb_pci_tbl[] = {
{ PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_65550, PCI_ANY_ID, PCI_ANY_ID },
@@ -455,6 +503,10 @@ static struct pci_driver chipsfb_driver = {
.id_table = chipsfb_pci_tbl,
.probe = chipsfb_pci_init,
.remove = __devexit_p(chipsfb_remove),
+#ifdef CONFIG_PM
+ .suspend = chipsfb_pci_suspend,
+ .resume = chipsfb_pci_resume,
+#endif
};
int __init chips_init(void)
@@ -472,48 +524,4 @@ static void __exit chipsfb_exit(void)
pci_unregister_driver(&chipsfb_driver);
}
-#ifdef CONFIG_PMAC_PBOOK
-/*
- * Save the contents of the frame buffer when we go to sleep,
- * and restore it when we wake up again.
- */
-int
-chips_sleep_notify(struct pmu_sleep_notifier *self, int when)
-{
- struct fb_info *p = &chipsfb_info;
- int nb = p->var.yres * p->fix.line_length;
-
- if (p->screen_base == NULL)
- return PBOOK_SLEEP_OK;
-
- switch (when) {
- case PBOOK_SLEEP_REQUEST:
- save_framebuffer = vmalloc(nb);
- if (save_framebuffer == NULL)
- return PBOOK_SLEEP_REFUSE;
- break;
- case PBOOK_SLEEP_REJECT:
- if (save_framebuffer) {
- vfree(save_framebuffer);
- save_framebuffer = NULL;
- }
- break;
- case PBOOK_SLEEP_NOW:
- chipsfb_blank(1, p);
- if (save_framebuffer)
- memcpy(save_framebuffer, p->screen_base, nb);
- break;
- case PBOOK_WAKE:
- if (save_framebuffer) {
- memcpy(p->screen_base, save_framebuffer, nb);
- vfree(save_framebuffer);
- save_framebuffer = NULL;
- }
- chipsfb_blank(0, p);
- break;
- }
- return PBOOK_SLEEP_OK;
-}
-#endif /* CONFIG_PMAC_PBOOK */
-
MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index e4b91a4b936..cbff98337aa 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -156,7 +156,6 @@ config FONT_6x11
config FONT_7x14
bool "console 7x14 font (not supported by all drivers)" if FONTS
depends on FRAMEBUFFER_CONSOLE
- default y if !SPARC32 && !SPARC64 && !FONTS
help
Console font with characters just a bit smaller than the default.
If the standard 8x16 font is a little too big for you, say Y.
@@ -197,8 +196,8 @@ config FONT_SUN12x22
standard font is unreadable for you, say Y, otherwise say N.
config FONT_10x18
- bool "console 10x18 font (not supported by all drivers)"
- depends on FONTS
+ bool "console 10x18 font (not supported by all drivers)" if FONTS
+ depends on FRAMEBUFFER_CONSOLE
help
This is a high resolution console font for machines with very
big letters. It fits between the sun 12x22 and the normal 8x16 font.
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index b209adbd508..35c88bd7ba5 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -142,7 +142,6 @@ static int fbcon_set_origin(struct vc_data *);
#define CURSOR_DRAW_DELAY (1)
/* # VBL ints between cursor state changes */
-#define ARM_CURSOR_BLINK_RATE (10)
#define ATARI_CURSOR_BLINK_RATE (42)
#define MAC_CURSOR_BLINK_RATE (32)
#define DEFAULT_CURSOR_BLINK_RATE (20)
@@ -276,7 +275,8 @@ static void fb_flashcursor(void *private)
if (!vc || !CON_IS_VISIBLE(vc) ||
fbcon_is_inactive(vc, info) ||
- registered_fb[con2fb_map[vc->vc_num]] != info)
+ registered_fb[con2fb_map[vc->vc_num]] != info ||
+ vc_cons[ops->currcon].d->vc_deccm != 1)
return;
acquire_console_sem();
p = &fb_display[vc->vc_num];
@@ -288,7 +288,7 @@ static void fb_flashcursor(void *private)
release_console_sem();
}
-#if (defined(__arm__) && defined(IRQ_VSYNCPULSE)) || defined(CONFIG_ATARI) || defined(CONFIG_MAC)
+#if defined(CONFIG_ATARI) || defined(CONFIG_MAC)
static int cursor_blink_rate;
static irqreturn_t fb_vbl_handler(int irq, void *dev_id, struct pt_regs *fp)
{
@@ -878,11 +878,6 @@ static const char *fbcon_startup(void)
}
#endif /* CONFIG_MAC */
-#if defined(__arm__) && defined(IRQ_VSYNCPULSE)
- cursor_blink_rate = ARM_CURSOR_BLINK_RATE;
- irqres = request_irq(IRQ_VSYNCPULSE, fb_vbl_handler, SA_SHIRQ,
- "framebuffer vbl", info);
-#endif
/* Initialize the work queue. If the driver provides its
* own work queue this means it will use something besides
* default timer to flash the cursor. */
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index 4e5ce8f7d65..c32a2a50bfa 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -212,7 +212,7 @@ int fb_cmap_to_user(struct fb_cmap *from, struct fb_cmap_user *to)
int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info)
{
- int i, start;
+ int i, start, rc = 0;
u16 *red, *green, *blue, *transp;
u_int hred, hgreen, hblue, htransp = 0xffff;
@@ -225,75 +225,51 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info)
if (start < 0 || (!info->fbops->fb_setcolreg &&
!info->fbops->fb_setcmap))
return -EINVAL;
- if (info->fbops->fb_setcmap)
- return info->fbops->fb_setcmap(cmap, info);
- for (i = 0; i < cmap->len; i++) {
- hred = *red++;
- hgreen = *green++;
- hblue = *blue++;
- if (transp)
- htransp = *transp++;
- if (info->fbops->fb_setcolreg(start++,
- hred, hgreen, hblue, htransp,
- info))
- break;
+ if (info->fbops->fb_setcmap) {
+ rc = info->fbops->fb_setcmap(cmap, info);
+ } else {
+ for (i = 0; i < cmap->len; i++) {
+ hred = *red++;
+ hgreen = *green++;
+ hblue = *blue++;
+ if (transp)
+ htransp = *transp++;
+ if (info->fbops->fb_setcolreg(start++,
+ hred, hgreen, hblue,
+ htransp, info))
+ break;
+ }
}
- return 0;
+ if (rc == 0)
+ fb_copy_cmap(cmap, &info->cmap);
+
+ return rc;
}
int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
{
- int i, start;
- u16 __user *red, *green, *blue, *transp;
- u_int hred, hgreen, hblue, htransp = 0xffff;
-
- red = cmap->red;
- green = cmap->green;
- blue = cmap->blue;
- transp = cmap->transp;
- start = cmap->start;
+ int rc, size = cmap->len * sizeof(u16);
+ struct fb_cmap umap;
- if (start < 0 || (!info->fbops->fb_setcolreg &&
- !info->fbops->fb_setcmap))
+ if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
+ !info->fbops->fb_setcmap))
return -EINVAL;
- /* If we can batch, do it */
- if (info->fbops->fb_setcmap && cmap->len > 1) {
- struct fb_cmap umap;
- int size = cmap->len * sizeof(u16);
- int rc;
-
- memset(&umap, 0, sizeof(struct fb_cmap));
- rc = fb_alloc_cmap(&umap, cmap->len, transp != NULL);
- if (rc)
- return rc;
- if (copy_from_user(umap.red, red, size) ||
- copy_from_user(umap.green, green, size) ||
- copy_from_user(umap.blue, blue, size) ||
- (transp && copy_from_user(umap.transp, transp, size))) {
- rc = -EFAULT;
- }
- umap.start = start;
- if (rc == 0)
- rc = info->fbops->fb_setcmap(&umap, info);
- fb_dealloc_cmap(&umap);
+ memset(&umap, 0, sizeof(struct fb_cmap));
+ rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL);
+ if (rc)
return rc;
+ if (copy_from_user(umap.red, cmap->red, size) ||
+ copy_from_user(umap.green, cmap->green, size) ||
+ copy_from_user(umap.blue, cmap->blue, size) ||
+ (cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) {
+ fb_dealloc_cmap(&umap);
+ return -EFAULT;
}
-
- for (i = 0; i < cmap->len; i++, red++, blue++, green++) {
- if (get_user(hred, red) ||
- get_user(hgreen, green) ||
- get_user(hblue, blue) ||
- (transp && get_user(htransp, transp)))
- return -EFAULT;
- if (info->fbops->fb_setcolreg(start++,
- hred, hgreen, hblue, htransp,
- info))
- return 0;
- if (transp)
- transp++;
- }
- return 0;
+ umap.start = cmap->start;
+ rc = fb_set_cmap(&umap, info);
+ fb_dealloc_cmap(&umap);
+ return rc;
}
/**
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 2222de6ad84..d2e19f6dd72 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -80,10 +80,12 @@ EXPORT_SYMBOL(fb_get_color_depth);
*/
void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height)
{
- int i;
+ int i, j;
for (i = height; i--; ) {
- memcpy(dst, src, s_pitch);
+ /* s_pitch is a few bytes at the most, memcpy is suboptimal */
+ for (j = 0; j < s_pitch; j++)
+ dst[j] = src[j];
src += s_pitch;
dst += d_pitch;
}
@@ -1164,6 +1166,7 @@ static void __exit
fbmem_exit(void)
{
class_destroy(fb_class);
+ unregister_chrdev(FB_MAJOR, "fb");
}
module_exit(fbmem_exit);
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 6cd1976548d..c2718bb9494 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -1241,6 +1241,8 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info)
vtotal *= 2;
hfreq = pixclock/htotal;
+ hfreq = (hfreq + 500) / 1000 * 1000;
+
vfreq = hfreq/vtotal;
return (vfreq < vfmin || vfreq > vfmax ||
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 277d733c6d0..1147b899f00 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -228,8 +228,6 @@ static ssize_t store_virtual(struct class_device *class_device,
if (last - buf >= count)
return -EINVAL;
var.yres_virtual = simple_strtoul(last, &last, 0);
- printk(KERN_ERR "fb: xres %d yres %d\n", var.xres_virtual,
- var.yres_virtual);
if ((err = activate(fb_info, &var)))
return err;
@@ -244,10 +242,68 @@ static ssize_t show_virtual(struct class_device *class_device, char *buf)
fb_info->var.yres_virtual);
}
-static ssize_t store_cmap(struct class_device *class_device, const char * buf,
+/* Format for cmap is "%02x%c%4x%4x%4x\n" */
+/* %02x entry %c transp %4x red %4x blue %4x green \n */
+/* 256 rows at 16 chars equals 4096, the normal page size */
+/* the code will automatically adjust for different page sizes */
+static ssize_t store_cmap(struct class_device *class_device, const char *buf,
size_t count)
{
-// struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ int rc, i, start, length, transp = 0;
+
+ if ((count > PAGE_SIZE) || ((count % 16) != 0))
+ return -EINVAL;
+
+ if (!fb_info->fbops->fb_setcolreg && !fb_info->fbops->fb_setcmap)
+ return -EINVAL;
+
+ sscanf(buf, "%02x", &start);
+ length = count / 16;
+
+ for (i = 0; i < length; i++)
+ if (buf[i * 16 + 2] != ' ')
+ transp = 1;
+
+ /* If we can batch, do it */
+ if (fb_info->fbops->fb_setcmap && length > 1) {
+ struct fb_cmap umap;
+
+ memset(&umap, 0, sizeof(umap));
+ if ((rc = fb_alloc_cmap(&umap, length, transp)))
+ return rc;
+
+ umap.start = start;
+ for (i = 0; i < length; i++) {
+ sscanf(&buf[i * 16 + 3], "%4hx", &umap.red[i]);
+ sscanf(&buf[i * 16 + 7], "%4hx", &umap.blue[i]);
+ sscanf(&buf[i * 16 + 11], "%4hx", &umap.green[i]);
+ if (transp)
+ umap.transp[i] = (buf[i * 16 + 2] != ' ');
+ }
+ rc = fb_info->fbops->fb_setcmap(&umap, fb_info);
+ fb_copy_cmap(&umap, &fb_info->cmap);
+ fb_dealloc_cmap(&umap);
+
+ return rc;
+ }
+ for (i = 0; i < length; i++) {
+ u16 red, blue, green, tsp;
+
+ sscanf(&buf[i * 16 + 3], "%4hx", &red);
+ sscanf(&buf[i * 16 + 7], "%4hx", &blue);
+ sscanf(&buf[i * 16 + 11], "%4hx", &green);
+ tsp = (buf[i * 16 + 2] != ' ');
+ if ((rc = fb_info->fbops->fb_setcolreg(start++,
+ red, green, blue, tsp, fb_info)))
+ return rc;
+
+ fb_info->cmap.red[i] = red;
+ fb_info->cmap.blue[i] = blue;
+ fb_info->cmap.green[i] = green;
+ if (transp)
+ fb_info->cmap.transp[i] = tsp;
+ }
return 0;
}
@@ -255,20 +311,24 @@ static ssize_t show_cmap(struct class_device *class_device, char *buf)
{
struct fb_info *fb_info =
(struct fb_info *)class_get_devdata(class_device);
- unsigned int offset = 0, i;
+ unsigned int i;
if (!fb_info->cmap.red || !fb_info->cmap.blue ||
- fb_info->cmap.green || fb_info->cmap.transp)
+ !fb_info->cmap.green)
+ return -EINVAL;
+
+ if (fb_info->cmap.len > PAGE_SIZE / 16)
return -EINVAL;
+ /* don't mess with the format, the buffer is PAGE_SIZE */
+ /* 256 entries at 16 chars per line equals 4096 = PAGE_SIZE */
for (i = 0; i < fb_info->cmap.len; i++) {
- offset += snprintf(buf, PAGE_SIZE - offset,
- "%d,%d,%d,%d,%d\n", i + fb_info->cmap.start,
- fb_info->cmap.red[i], fb_info->cmap.blue[i],
- fb_info->cmap.green[i],
- fb_info->cmap.transp[i]);
+ snprintf(&buf[ i * 16], PAGE_SIZE - i * 16, "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start,
+ ((fb_info->cmap.transp && fb_info->cmap.transp[i]) ? '*' : ' '),
+ fb_info->cmap.red[i], fb_info->cmap.blue[i],
+ fb_info->cmap.green[i]);
}
- return offset;
+ return 16 * fb_info->cmap.len;
}
static ssize_t store_blank(struct class_device *class_device, const char * buf,
@@ -354,6 +414,13 @@ static ssize_t show_pan(struct class_device *class_device, char *buf)
fb_info->var.xoffset);
}
+static ssize_t show_name(struct class_device *class_device, char *buf)
+{
+ struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", fb_info->fix.id);
+}
+
static struct class_device_attribute class_device_attrs[] = {
__ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp),
__ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank),
@@ -364,6 +431,7 @@ static struct class_device_attribute class_device_attrs[] = {
__ATTR(modes, S_IRUGO|S_IWUSR, show_modes, store_modes),
__ATTR(pan, S_IRUGO|S_IWUSR, show_pan, store_pan),
__ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual),
+ __ATTR(name, S_IRUGO, show_name, NULL),
};
int fb_init_class_device(struct fb_info *fb_info)
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 8fe1c12a17b..cabd53cec99 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -249,9 +249,6 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
/* disable hardware cursor */
LCDC_CPOS &= ~(CPOS_CC0 | CPOS_CC1);
- /* fixed burst length (see erratum 11) */
- LCDC_DMACR = DMACR_BURST | DMACR_HM(8) | DMACR_TM(2);
-
LCDC_RMCR = RMCR_LCDC_EN;
if(fbi->backlight_power)
@@ -359,6 +356,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
LCDC_PCR = fbi->pcr;
LCDC_PWMR = fbi->pwmr;
LCDC_LSCR1 = fbi->lscr1;
+ LCDC_DMACR = fbi->dmacr;
return 0;
}
@@ -509,6 +507,7 @@ static int __init imxfb_init_fbinfo(struct device *dev)
fbi->cmap_inverse = inf->cmap_inverse;
fbi->pcr = inf->pcr;
fbi->lscr1 = inf->lscr1;
+ fbi->dmacr = inf->dmacr;
fbi->pwmr = inf->pwmr;
fbi->lcd_power = inf->lcd_power;
fbi->backlight_power = inf->backlight_power;
@@ -642,12 +641,12 @@ static int imxfb_remove(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct fb_info *info = dev_get_drvdata(dev);
+ struct imxfb_info *fbi = info->par;
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- /* disable LCD controller */
- LCDC_RMCR &= ~RMCR_LCDC_EN;
+ imxfb_disable_controller(fbi);
unregister_framebuffer(info);
@@ -663,8 +662,9 @@ static int imxfb_remove(struct device *dev)
void imxfb_shutdown(struct device * dev)
{
- /* disable LCD Controller */
- LCDC_RMCR &= ~RMCR_LCDC_EN;
+ struct fb_info *info = dev_get_drvdata(dev);
+ struct imxfb_info *fbi = info->par;
+ imxfb_disable_controller(fbi);
}
static struct device_driver imxfb_driver = {
diff --git a/drivers/video/imxfb.h b/drivers/video/imxfb.h
index 128c3ee515c..e837a8b48eb 100644
--- a/drivers/video/imxfb.h
+++ b/drivers/video/imxfb.h
@@ -54,6 +54,7 @@ struct imxfb_info {
u_int pcr;
u_int pwmr;
u_int lscr1;
+ u_i