Merge branches 'arm', 'at91', 'bcmring', 'ep93xx', 'mach-types', 'misc' and 'w90x900' into devel

This commit is contained in:
Russell King 2009-09-12 12:01:34 +01:00 • committed by Russell King
1298 changed files with 53846 additions and 14528 deletions

View file

@ -616,6 +616,8 @@ config FB_STI
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select STI_CONSOLE
select VT
default y
---help---
STI refers to the HP "Standard Text Interface" which is a set of
@ -933,7 +935,7 @@ config FB_S1D13XXX
config FB_ATMEL
tristate "AT91/AT32 LCD Controller support"
depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || AVR32)
depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9G10 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 || ARCH_AT91CAP9 || AVR32)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@ -949,7 +951,7 @@ config FB_INTSRAM
config FB_ATMEL_STN
bool "Use a STN display with AT91/AT32 LCD Controller"
depends on FB_ATMEL && MACH_AT91SAM9261EK
depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK)
default n
help
Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD

View file

@ -226,9 +226,10 @@ static int clcdfb_set_par(struct fb_info *info)
clcdfb_enable(fb, regs.cntl);
#ifdef DEBUG
printk(KERN_INFO "CLCD: Registers set to\n"
KERN_INFO " %08x %08x %08x %08x\n"
KERN_INFO " %08x %08x %08x %08x\n",
printk(KERN_INFO
"CLCD: Registers set to\n"
" %08x %08x %08x %08x\n"
" %08x %08x %08x %08x\n",
readl(fb->regs + CLCD_TIM0), readl(fb->regs + CLCD_TIM1),
readl(fb->regs + CLCD_TIM2), readl(fb->regs + CLCD_TIM3),
readl(fb->regs + CLCD_UBAS), readl(fb->regs + CLCD_LBAS),

View file

@ -2405,6 +2405,9 @@ static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
return 0;
}
/* fbhw->encode_fix() must be called with fb_info->mm_lock held
* if it is called after the register_framebuffer() - not a case here
*/
static int atafb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
{
struct atafb_par par;
@ -2414,7 +2417,8 @@ static int atafb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
if (err)
return err;
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
return fbhw->encode_fix(fix, &par);
err = fbhw->encode_fix(fix, &par);
return err;
}
static int atafb_get_var(struct fb_var_screeninfo *var, struct fb_info *info)
@ -2743,7 +2747,9 @@ static int atafb_set_par(struct fb_info *info)
/* Decode wanted screen parameters */
fbhw->decode_var(&info->var, par);
mutex_lock(&info->mm_lock);
fbhw->encode_fix(&info->fix, par);
mutex_unlock(&info->mm_lock);
/* Set new videomode */
ata_set_par(par);

View file

@ -182,7 +182,8 @@ static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2)
{
unsigned long value;
if (!(cpu_is_at91sam9261() || cpu_is_at32ap7000()))
if (!(cpu_is_at91sam9261() || cpu_is_at91sam9g10()
|| cpu_is_at32ap7000()))
return xres;
value = xres;
@ -261,6 +262,9 @@ static inline void atmel_lcdfb_free_video_memory(struct atmel_lcdfb_info *sinfo)
/**
* atmel_lcdfb_alloc_video_memory - Allocate framebuffer memory
* @sinfo: the frame buffer to allocate memory for
*
* This function is called only from the atmel_lcdfb_probe()
* so no locking by fb_info->mm_lock around smem_len setting is needed.
*/
static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo)
{
@ -821,7 +825,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
info->fix = atmel_lcdfb_fix;
/* Enable LCDC Clocks */
if (cpu_is_at91sam9261() || cpu_is_at32ap7000()) {
if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()
|| cpu_is_at32ap7000()) {
sinfo->bus_clk = clk_get(dev, "hck1");
if (IS_ERR(sinfo->bus_clk)) {
ret = PTR_ERR(sinfo->bus_clk);

View file

@ -187,6 +187,8 @@ struct atyfb_par {
int mtrr_reg;
#endif
u32 mem_cntl;
struct crtc saved_crtc;
union aty_pll saved_pll;
};
/*
@ -217,6 +219,7 @@ struct atyfb_par {
#define M64F_XL_DLL 0x00080000
#define M64F_MFB_FORCE_4 0x00100000
#define M64F_HW_TRIPLE 0x00200000
#define M64F_XL_MEM 0x00400000
/*
* Register access
*/

View file

@ -66,6 +66,8 @@
#include <linux/spinlock.h>
#include <linux/wait.h>
#include <linux/backlight.h>
#include <linux/reboot.h>
#include <linux/dmi.h>
#include <asm/io.h>
#include <linux/uaccess.h>
@ -249,8 +251,6 @@ static int aty_init(struct fb_info *info);
static int store_video_par(char *videopar, unsigned char m64_num);
#endif
static struct crtc saved_crtc;
static union aty_pll saved_pll;
static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc);
static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc);
@ -261,6 +261,8 @@ static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info);
static int read_aty_sense(const struct atyfb_par *par);
#endif
static DEFINE_MUTEX(reboot_lock);
static struct fb_info *reboot_info;
/*
* Interface used by the world
@ -361,8 +363,8 @@ static unsigned long phys_guiregbase[FB_MAX] __devinitdata = { 0, };
#define ATI_CHIP_264GTPRO (ATI_MODERN_SET | M64F_SDRAM_MAGIC_PLL | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
#define ATI_CHIP_264LTPRO (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D)
#define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4)
#define ATI_CHIP_MOBILITY (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_MOBIL_BUS)
#define ATI_CHIP_264XL (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM)
#define ATI_CHIP_MOBILITY (ATI_MODERN_SET | M64F_HW_TRIPLE | M64F_FIFO_32 | M64F_RESET_3D | M64F_XL_DLL | M64F_MFB_FORCE_4 | M64F_XL_MEM | M64F_MOBIL_BUS)
static struct {
u16 pci_id;
@ -539,6 +541,7 @@ static char ram_edo[] __devinitdata = "EDO";
static char ram_sdram[] __devinitdata = "SDRAM (1:1)";
static char ram_sgram[] __devinitdata = "SGRAM (1:1)";
static char ram_sdram32[] __devinitdata = "SDRAM (2:1) (32-bit)";
static char ram_wram[] __devinitdata = "WRAM";
static char ram_off[] __devinitdata = "OFF";
#endif /* CONFIG_FB_ATY_CT */
@ -552,6 +555,10 @@ static char *aty_gx_ram[8] __devinitdata = {
#ifdef CONFIG_FB_ATY_CT
static char *aty_ct_ram[8] __devinitdata = {
ram_off, ram_dram, ram_edo, ram_edo,
ram_sdram, ram_sgram, ram_wram, ram_resv
};
static char *aty_xl_ram[8] __devinitdata = {
ram_off, ram_dram, ram_edo, ram_edo,
ram_sdram, ram_sgram, ram_sdram32, ram_resv
};
@ -760,6 +767,17 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc)
#endif /* CONFIG_FB_ATY_GENERIC_LCD */
}
static u32 calc_line_length(struct atyfb_par *par, u32 vxres, u32 bpp)
{
u32 line_length = vxres * bpp / 8;
if (par->ram_type == SGRAM ||
(!M64_HAS(XL_MEM) && par->ram_type == WRAM))
line_length = (line_length + 63) & ~63;
return line_length;
}
static int aty_var_to_crtc(const struct fb_info *info,
const struct fb_var_screeninfo *var, struct crtc *crtc)
{
@ -769,13 +787,14 @@ static int aty_var_to_crtc(const struct fb_info *info,
u32 h_total, h_disp, h_sync_strt, h_sync_end, h_sync_dly, h_sync_wid, h_sync_pol;
u32 v_total, v_disp, v_sync_strt, v_sync_end, v_sync_wid, v_sync_pol, c_sync;
u32 pix_width, dp_pix_width, dp_chain_mask;
u32 line_length;
/* input */
xres = var->xres;
xres = (var->xres + 7) & ~7;
yres = var->yres;
vxres = var->xres_virtual;
vxres = (var->xres_virtual + 7) & ~7;
vyres = var->yres_virtual;
xoffset = var->xoffset;
xoffset = (var->xoffset + 7) & ~7;
yoffset = var->yoffset;
bpp = var->bits_per_pixel;
if (bpp == 16)
@ -827,7 +846,9 @@ static int aty_var_to_crtc(const struct fb_info *info,
} else
FAIL("invalid bpp");
if (vxres * vyres * bpp / 8 > info->fix.smem_len)
line_length = calc_line_length(par, vxres, bpp);
if (vyres * line_length > info->fix.smem_len)
FAIL("not enough video RAM");
h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
@ -969,7 +990,9 @@ static int aty_var_to_crtc(const struct fb_info *info,
crtc->xoffset = xoffset;
crtc->yoffset = yoffset;
crtc->bpp = bpp;
crtc->off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19);
crtc->off_pitch =
((yoffset * line_length + xoffset * bpp / 8) / 8) |
((line_length / bpp) << 22);
crtc->vline_crnt_vline = 0;
crtc->h_tot_disp = h_total | (h_disp<<16);
@ -1394,7 +1417,9 @@ static int atyfb_set_par(struct fb_info *info)
}
aty_st_8(DAC_MASK, 0xff, par);
info->fix.line_length = var->xres_virtual * var->bits_per_pixel/8;
info->fix.line_length = calc_line_length(par, var->xres_virtual,
var->bits_per_pixel);
info->fix.visual = var->bits_per_pixel <= 8 ?
FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
@ -1505,10 +1530,12 @@ static void set_off_pitch(struct atyfb_par *par, const struct fb_info *info)
{
u32 xoffset = info->var.xoffset;
u32 yoffset = info->var.yoffset;
u32 vxres = par->crtc.vxres;
u32 line_length = info->fix.line_length;
u32 bpp = info->var.bits_per_pixel;
par->crtc.off_pitch = ((yoffset * vxres + xoffset) * bpp / 64) | (vxres << 19);
par->crtc.off_pitch =
((yoffset * line_length + xoffset * bpp / 8) / 8) |
((line_length / bpp) << 22);
}
@ -2201,7 +2228,7 @@ static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
const int *refresh_tbl;
int i, size;
if (IS_XL(par->pci_id) || IS_MOBILITY(par->pci_id)) {
if (M64_HAS(XL_MEM)) {
refresh_tbl = ragexl_tbl;
size = ARRAY_SIZE(ragexl_tbl);
} else {
@ -2335,7 +2362,10 @@ static int __devinit aty_init(struct fb_info *info)
par->pll_ops = &aty_pll_ct;
par->bus_type = PCI;
par->ram_type = (aty_ld_le32(CNFG_STAT0, par) & 0x07);
ramname = aty_ct_ram[par->ram_type];
if (M64_HAS(XL_MEM))
ramname = aty_xl_ram[par->ram_type];
else
ramname = aty_ct_ram[par->ram_type];
/* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM)
par->pll_limits.mclk = 63;
@ -2390,9 +2420,9 @@ static int __devinit aty_init(struct fb_info *info)
#endif /* CONFIG_FB_ATY_CT */
/* save previous video mode */
aty_get_crtc(par, &saved_crtc);
aty_get_crtc(par, &par->saved_crtc);
if(par->pll_ops->get_pll)
par->pll_ops->get_pll(info, &saved_pll);
par->pll_ops->get_pll(info, &par->saved_pll);
par->mem_cntl = aty_ld_le32(MEM_CNTL, par);
gtb_memsize = M64_HAS(GTB_DSP);
@ -2667,8 +2697,8 @@ static int __devinit aty_init(struct fb_info *info)
aty_init_exit:
/* restore video mode */
aty_set_crtc(par, &saved_crtc);
par->pll_ops->set_pll(info, &saved_pll);
aty_set_crtc(par, &par->saved_crtc);
par->pll_ops->set_pll(info, &par->saved_pll);
#ifdef CONFIG_MTRR
if (par->mtrr_reg >= 0) {
@ -3502,6 +3532,11 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi
par->mmap_map[1].prot_flag = _PAGE_E;
#endif /* __sparc__ */
mutex_lock(&reboot_lock);
if (!reboot_info)
reboot_info = info;
mutex_unlock(&reboot_lock);
return 0;
err_release_io:
@ -3614,8 +3649,8 @@ static void __devexit atyfb_remove(struct fb_info *info)
struct atyfb_par *par = (struct atyfb_par *) info->par;
/* restore video mode */
aty_set_crtc(par, &saved_crtc);
par->pll_ops->set_pll(info, &saved_pll);
aty_set_crtc(par, &par->saved_crtc);
par->pll_ops->set_pll(info, &par->saved_pll);
unregister_framebuffer(info);
@ -3661,6 +3696,11 @@ static void __devexit atyfb_pci_remove(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
mutex_lock(&reboot_lock);
if (reboot_info == info)
reboot_info = NULL;
mutex_unlock(&reboot_lock);
atyfb_remove(info);
}
@ -3808,6 +3848,56 @@ static int __init atyfb_setup(char *options)
}
#endif /* MODULE */
static int atyfb_reboot_notify(struct notifier_block *nb,
unsigned long code, void *unused)
{
struct atyfb_par *par;
if (code != SYS_RESTART)
return NOTIFY_DONE;
mutex_lock(&reboot_lock);
if (!reboot_info)
goto out;
if (!lock_fb_info(reboot_info))
goto out;
par = reboot_info->par;
/*
* HP OmniBook 500's BIOS doesn't like the state of the
* hardware after atyfb has been used. Restore the hardware
* to the original state to allow successful reboots.
*/
aty_set_crtc(par, &par->saved_crtc);
par->pll_ops->set_pll(reboot_info, &par->saved_pll);
unlock_fb_info(reboot_info);
out:
mutex_unlock(&reboot_lock);
return NOTIFY_DONE;
}
static struct notifier_block atyfb_reboot_notifier = {
.notifier_call = atyfb_reboot_notify,
};
static const struct dmi_system_id atyfb_reboot_ids[] = {
{
.ident = "HP OmniBook 500",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook 500 FA"),
},
},
{ }
};
static int __init atyfb_init(void)
{
int err1 = 1, err2 = 1;
@ -3826,11 +3916,20 @@ static int __init atyfb_init(void)
err2 = atyfb_atari_probe();
#endif
return (err1 && err2) ? -ENODEV : 0;
if (err1 && err2)
return -ENODEV;
if (dmi_check_system(atyfb_reboot_ids))
register_reboot_notifier(&atyfb_reboot_notifier);
return 0;
}
static void __exit atyfb_exit(void)
{
if (dmi_check_system(atyfb_reboot_ids))
unregister_reboot_notifier(&atyfb_reboot_notifier);
#ifdef CONFIG_PCI
pci_unregister_driver(&atyfb_driver);
#endif

View file

@ -63,14 +63,17 @@ static void reset_GTC_3D_engine(const struct atyfb_par *par)
void aty_init_engine(struct atyfb_par *par, struct fb_info *info)
{
u32 pitch_value;
u32 vxres;
/* determine modal information from global mode structure */
pitch_value = info->var.xres_virtual;
pitch_value = info->fix.line_length / (info->var.bits_per_pixel / 8);
vxres = info->var.xres_virtual;
if (info->var.bits_per_pixel == 24) {
/* In 24 bpp, the engine is in 8 bpp - this requires that all */
/* horizontal coordinates and widths must be adjusted */
pitch_value *= 3;
vxres *= 3;
}
/* On GTC (RagePro), we need to reset the 3D engine before */
@ -133,7 +136,7 @@ void aty_init_engine(struct atyfb_par *par, struct fb_info *info)
aty_st_le32(SC_LEFT, 0, par);
aty_st_le32(SC_TOP, 0, par);
aty_st_le32(SC_BOTTOM, par->crtc.vyres - 1, par);
aty_st_le32(SC_RIGHT, pitch_value - 1, par);
aty_st_le32(SC_RIGHT, vxres - 1, par);
/* set background color to minimum value (usually BLACK) */
aty_st_le32(DP_BKGD_CLR, 0, par);

View file

@ -110,7 +110,7 @@ config BACKLIGHT_CLASS_DEVICE
config BACKLIGHT_ATMEL_LCDC
bool "Atmel LCDC Contrast-as-Backlight control"
depends on BACKLIGHT_CLASS_DEVICE && FB_ATMEL
default y if MACH_SAM9261EK || MACH_SAM9263EK
default y if MACH_SAM9261EK || MACH_SAM9G10EK || MACH_SAM9263EK
help
This provides a backlight control internal to the Atmel LCDC
driver. If the LCD "contrast control" on your board is wired

View file

@ -356,7 +356,7 @@ static int __devinit tdo24m_probe(struct spi_device *spi)
lcd->power = FB_BLANK_POWERDOWN;
lcd->mode = MODE_VGA; /* default to VGA */
lcd->buf = kmalloc(TDO24M_SPI_BUFF_SIZE, sizeof(GFP_KERNEL));
lcd->buf = kmalloc(TDO24M_SPI_BUFF_SIZE, GFP_KERNEL);
if (lcd->buf == NULL) {
kfree(lcd);
return -ENOMEM;

View file

@ -1,7 +1,7 @@
/*
* Cobalt server LCD frame buffer driver.
*
* Copyright (C) 2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
* Copyright (C) 2008 Yoichi Yuasa <yuasa@linux-mips.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View file

@ -1310,8 +1310,6 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd,
static int
fb_mmap(struct file *file, struct vm_area_struct * vma)
__acquires(&info->lock)
__releases(&info->lock)
{
int fbidx = iminor(file->f_path.dentry->d_inode);
struct fb_info *info = registered_fb[fbidx];
@ -1325,16 +1323,14 @@ __releases(&info->lock)
off = vma->vm_pgoff << PAGE_SHIFT;
if (!fb)
return -ENODEV;
mutex_lock(&info->mm_lock);
if (fb->fb_mmap) {
int res;
mutex_lock(&info->lock);
res = fb->fb_mmap(info, vma);
mutex_unlock(&info->lock);
mutex_unlock(&info->mm_lock);
return res;
}
mutex_lock(&info->lock);
/* frame buffer memory */
start = info->fix.smem_start;
len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
@ -1342,13 +1338,13 @@ __releases(&info->lock)
/* memory mapped io */
off -= len;
if (info->var.accel_flags) {
mutex_unlock(&info->lock);
mutex_unlock(&info->mm_lock);
return -EINVAL;
}
start = info->fix.mmio_start;
len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
}
mutex_unlock(&info->lock);
mutex_unlock(&info->mm_lock);
start &= PAGE_MASK;
if ((vma->vm_end - vma->vm_start + off) > len)
return -EINVAL;
@ -1518,6 +1514,7 @@ register_framebuffer(struct fb_info *fb_info)
break;
fb_info->node = i;
mutex_init(&fb_info->lock);
mutex_init(&fb_info->mm_lock);
fb_info->dev = device_create(fb_class, fb_info->device,
MKDEV(FB_MAJOR, i), NULL, "fb%d", i);

View file

@ -750,24 +750,26 @@ static void update_lcdc(struct fb_info *info)
static int map_video_memory(struct fb_info *info)
{
phys_addr_t phys;
u32 smem_len = info->fix.line_length * info->var.yres_virtual;
pr_debug("info->var.xres_virtual = %d\n", info->var.xres_virtual);
pr_debug("info->var.yres_virtual = %d\n", info->var.yres_virtual);
pr_debug("info->fix.line_length = %d\n", info->fix.line_length);
pr_debug("MAP_VIDEO_MEMORY: smem_len = %u\n", smem_len);
info->fix.smem_len = info->fix.line_length * info->var.yres_virtual;
pr_debug("MAP_VIDEO_MEMORY: smem_len = %d\n", info->fix.smem_len);
info->screen_base = fsl_diu_alloc(info->fix.smem_len, &phys);
info->screen_base = fsl_diu_alloc(smem_len, &phys);
if (info->screen_base == NULL) {
printk(KERN_ERR "Unable to allocate fb memory\n");
return -ENOMEM;
}
mutex_lock(&info->mm_lock);
info->fix.smem_start = (unsigned long) phys;
info->fix.smem_len = smem_len;
mutex_unlock(&info->mm_lock);
info->screen_size = info->fix.smem_len;
pr_debug("Allocated fb @ paddr=0x%08lx, size=%d.\n",
info->fix.smem_start,
info->fix.smem_len);
info->fix.smem_start, info->fix.smem_len);
pr_debug("screen base %p\n", info->screen_base);
return 0;
@ -776,9 +778,11 @@ static int map_video_memory(struct fb_info *info)
static void unmap_video_memory(struct fb_info *info)
{
fsl_diu_free(info->screen_base, info->fix.smem_len);
mutex_lock(&info->mm_lock);
info->screen_base = NULL;
info->fix.smem_start = 0;
info->fix.smem_len = 0;
mutex_unlock(&info->mm_lock);
}
/*
@ -1219,12 +1223,6 @@ static int __devinit install_fb(struct fb_info *info)
return -EINVAL;
}
if (fsl_diu_set_par(info)) {
printk(KERN_ERR "fb_set_par failed");
fb_dealloc_cmap(&info->cmap);
return -EINVAL;
}
if (register_framebuffer(info) < 0) {
printk(KERN_ERR "register_framebuffer failed");
unmap_video_memory(info);

View file

@ -44,9 +44,6 @@ static struct fb_fix_screeninfo hitfb_fix __initdata = {
.accel = FB_ACCEL_NONE,
};
static u32 pseudo_palette[16];
static struct fb_info fb_info;
static inline void hitfb_accel_wait(void)
{
while (fb_readw(HD64461_GRCFGR) & HD64461_GRCFGR_ACCSTATUS) ;
@ -331,6 +328,8 @@ static struct fb_ops hitfb_ops = {
static int __init hitfb_probe(struct platform_device *dev)
{
unsigned short lcdclor, ldr3, ldvndr;
struct fb_info *info;
int ret;
if (fb_get_options("hitfb", NULL))
return -ENODEV;
@ -384,32 +383,53 @@ static int __init hitfb_probe(struct platform_device *dev)
break;
}
fb_info.fbops = &hitfb_ops;
fb_info.var = hitfb_var;
fb_info.fix = hitfb_fix;
fb_info.pseudo_palette = pseudo_palette;
fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |
info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
if (unlikely(!info))
return -ENOMEM;
info->fbops = &hitfb_ops;
info->var = hitfb_var;
info->fix = hitfb_fix;
info->pseudo_palette = info->par;
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |
FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_COPYAREA;
fb_info.screen_base = (void *)hitfb_fix.smem_start;
info->screen_base = (void *)hitfb_fix.smem_start;
fb_alloc_cmap(&fb_info.cmap, 256, 0);
ret = fb_alloc_cmap(&info->cmap, 256, 0);
if (unlikely(ret < 0))
goto err_fb;
if (register_framebuffer(&fb_info) < 0)
return -EINVAL;
ret = register_framebuffer(info);
if (unlikely(ret < 0))
goto err;
platform_set_drvdata(dev, info);
printk(KERN_INFO "fb%d: %s frame buffer device\n",
fb_info.node, fb_info.fix.id);
info->node, info->fix.id);
return 0;
err:
fb_dealloc_cmap(&info->cmap);
err_fb:
framebuffer_release(info);
return ret;
}
static int __exit hitfb_remove(struct platform_device *dev)
{
return unregister_framebuffer(&fb_info);
struct fb_info *info = platform_get_drvdata(dev);
unregister_framebuffer(info);
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
return 0;
}
#ifdef CONFIG_PM
static int hitfb_suspend(struct platform_device *dev, pm_message_t state)
static int hitfb_suspend(struct device *dev)
{
u16 v;
@ -421,7 +441,7 @@ static int hitfb_suspend(struct platform_device *dev, pm_message_t state)
return 0;
}
static int hitfb_resume(struct platform_device *dev)
static int hitfb_resume(struct device *dev)
{
u16 v;
@ -435,17 +455,19 @@ static int hitfb_resume(struct platform_device *dev)
return 0;
}
#endif
static struct dev_pm_ops hitfb_dev_pm_ops = {
.suspend = hitfb_suspend,
.resume = hitfb_resume,
};
static struct platform_driver hitfb_driver = {
.probe = hitfb_probe,
.remove = __exit_p(hitfb_remove),
#ifdef CONFIG_PM
.suspend = hitfb_suspend,
.resume = hitfb_resume,
#endif
.driver = {
.name = "hitfb",
.owner = THIS_MODULE,
.pm = &hitfb_dev_pm_ops,
},
};

View file

@ -1090,8 +1090,10 @@ static int encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, "I810");
mutex_lock(&info->mm_lock);
fix->smem_start = par->fb.physical;
fix->smem_len = par->fb.size;
mutex_unlock(&info->mm_lock);
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
fix->xpanstep = 8;
@ -2058,8 +2060,7 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
fb_var_to_videomode(&mode, &info->var);
fb_add_videomode(&mode, &info->modelist);
encode_fix(&info->fix, info);
i810fb_init_ringbuffer(info);
err = register_framebuffer(info);

View file

@ -454,9 +454,9 @@ static void DAC1064_restore_2(WPMINFO2) {
dprintk(KERN_DEBUG "DAC1064regs ");
for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], ACCESS_FBINFO(hw).DACreg[i]);
if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... ");
if ((i & 0x7) == 0x7) dprintk(KERN_DEBUG "continuing... ");
}
dprintk("\n" KERN_DEBUG "DAC1064clk ");
dprintk(KERN_DEBUG "DAC1064clk ");
for (i = 0; i < 6; i++)
dprintk("C%02X=%02X ", i, ACCESS_FBINFO(hw).DACclk[i]);
dprintk("\n");

View file

@ -651,9 +651,9 @@ static void Ti3026_restore(WPMINFO2) {
dprintk(KERN_DEBUG "3026DACregs ");
for (i = 0; i < 21; i++) {
dprintk("R%02X=%02X ", DACseq[i], hw->DACreg[i]);
if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... ");
if ((i & 0x7) == 0x7) dprintk(KERN_DEBUG "continuing... ");
}
dprintk("\n" KERN_DEBUG "DACclk ");
dprintk(KERN_DEBUG "DACclk ");
for (i = 0; i < 6; i++)
dprintk("C%02X=%02X ", i, hw->DACclk[i]);
dprintk("\n");

View file

@ -724,8 +724,10 @@ static void matroxfb_update_fix(WPMINFO2)
struct fb_fix_screeninfo *fix = &ACCESS_FBINFO(fbcon).fix;
DBG(__func__)
mutex_lock(&ACCESS_FBINFO(fbcon).mm_lock);
fix->smem_start = ACCESS_FBINFO(video.base) + ACCESS_FBINFO(curr.ydstorg.bytes);
fix->smem_len = ACCESS_FBINFO(video.len_usable) - ACCESS_FBINFO(curr.ydstorg.bytes);
mutex_unlock(&ACCESS_FBINFO(fbcon).mm_lock);
}
static int matroxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
@ -1874,7 +1876,6 @@ static int initMatrox2(WPMINFO struct board* b){
}
matroxfb_init_fix(PMINFO2);
ACCESS_FBINFO(fbcon.screen_base) = vaddr_va(ACCESS_FBINFO(video.vbase));
matroxfb_update_fix(PMINFO2);
/* Normalize values (namely yres_virtual) */
matroxfb_check_var(&vesafb_defined, &ACCESS_FBINFO(fbcon));
/* And put it into "current" var. Do NOT program hardware yet, or we'll not take over
@ -2081,6 +2082,7 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm
spin_lock_init(&ACCESS_FBINFO(lock.accel));
init_rwsem(&ACCESS_FBINFO(crtc2.lock));
init_rwsem(&ACCESS_FBINFO(altout.lock));
mutex_init(&ACCESS_FBINFO(fbcon).mm_lock);
ACCESS_FBINFO(irq_flags) = 0;
init_waitqueue_head(&ACCESS_FBINFO(crtc1.vsync.wait));
init_waitqueue_head(&ACCESS_FBINFO(crtc2.vsync.wait));

View file

@ -289,7 +289,12 @@ static int matroxfb_dh_release(struct fb_info* info, int user) {
#undef m2info
}
static void matroxfb_dh_init_fix(struct matroxfb_dh_fb_info *m2info) {
/*
* This function is called before the register_framebuffer so
* no locking is needed.
*/
static void matroxfb_dh_init_fix(struct matroxfb_dh_fb_info *m2info)
{
struct fb_fix_screeninfo *fix = &m2info->fbcon.fix;
strcpy(fix->id, "MATROX DH");

View file

@ -669,7 +669,7 @@ static uint32_t bpp_to_pixfmt(int bpp)
}
static int mx3fb_blank(int blank, struct fb_info *fbi);
static int mx3fb_map_video_memory(struct fb_info *fbi);
static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len);
static int mx3fb_unmap_video_memory(struct fb_info *fbi);
/**
@ -742,8 +742,7 @@ static int mx3fb_set_par(struct fb_info *fbi)
if (fbi->fix.smem_start)
mx3fb_unmap_video_memory(fbi);
fbi->fix.smem_len = mem_len;
if (mx3fb_map_video_memory(fbi) < 0) {
if (mx3fb_map_video_memory(fbi, mem_len) < 0) {
mutex_unlock(&mx3_fbi->mutex);
return -ENOMEM;
}
@ -1198,6 +1197,7 @@ static int mx3fb_resume(struct platform_device *pdev)
/**
* mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer.
* @fbi: framebuffer information pointer
* @mem_len: length of mapped memory
* @return: Error code indicating success or failure
*
* This buffer is remapped into a non-cached, non-buffered, memory region to
@ -1205,23 +1205,26 @@ static int mx3fb_resume(struct platform_device *pdev)
* area is remapped, all virtual memory access to the video memory should occur
* at the new region.
*/
static int mx3fb_map_video_memory(struct fb_info *fbi)
static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len)
{
int retval = 0;
dma_addr_t addr;
fbi->screen_base = dma_alloc_writecombine(fbi->device,
fbi->fix.smem_len,
mem_len,
&addr, GFP_DMA);
if (!fbi->screen_base) {
dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n",
fbi->fix.smem_len);
mem_len);
retval = -EBUSY;
goto err0;
}
mutex_lock(&fbi->mm_lock);
fbi->fix.smem_start = addr;
fbi->fix.smem_len = mem_len;
mutex_unlock(&fbi->mm_lock);
dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n",
(uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len);
@ -1251,8 +1254,10 @@ static int mx3fb_unmap_video_memory(struct fb_info *fbi)
fbi->screen_base, fbi->fix.smem_start);
fbi->screen_base = 0;
mutex_lock(&fbi->mm_lock);
fbi->fix.smem_start = 0;
fbi->fix.smem_len = 0;
mutex_unlock(&fbi->mm_lock);
return 0;
}
@ -1360,11 +1365,6 @@ static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan)
init_completion(&mx3fbi->flip_cmpl);
disable_irq(ichan->eof_irq);
dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq);
ret = mx3fb_set_par(fbi);
if (ret < 0)
goto esetpar;
mx3fb_blank(FB_BLANK_UNBLANK, fbi);
dev_info(dev, "registered, using mode %s\n", fb_mode);

View file

@ -393,8 +393,10 @@ static void set_fb_fix(struct fb_info *fbi)
rg = &plane->fbdev->mem_desc.region[plane->idx];
fbi->screen_base = rg->vaddr;
mutex_lock(&fbi->mm_lock);
fix->smem_start = rg->paddr;
fix->smem_len = rg->size;
mutex_unlock(&fbi->mm_lock);
fix->type = FB_TYPE_PACKED_PIXELS;
bpp = var->bits_per_pixel;
@ -886,8 +888,10 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
* plane memory is dealloce'd, the other
* screen parameters in var / fix are invalid.
*/
mutex_lock(&fbi->mm_lock);
fbi->fix.smem_start = 0;
fbi->fix.smem_len = 0;
mutex_unlock(&fbi->mm_lock);
}
}
}

View file

@ -141,7 +141,9 @@ static int platinumfb_set_par (struct fb_info *info)
offset = 0x10;
info->screen_base = pinfo->frame_buffer + init->fb_offset + offset;
mutex_lock(&info->mm_lock);
info->fix.smem_start = (pinfo->frame_buffer_phys) + init->fb_offset + offset;
mutex_unlock(&info->mm_lock);
info->fix.visual = (pinfo->cmode == CMODE_8) ?
FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
info->fix.line_length = vmode_attrs[pinfo->vmode-1].hres * (1<<pinfo->cmode)

View file

@ -815,8 +815,10 @@ static int overlayfb_map_video_memory(struct pxafb_layer *ofb)
ofb->video_mem_phys = virt_to_phys(ofb->video_mem);
ofb->video_mem_size = size;
mutex_lock(&ofb->fb.mm_lock);
ofb->fb.fix.smem_start = ofb->video_mem_phys;
ofb->fb.fix.smem_len = ofb->fb.fix.line_length * var->yres_virtual;
mutex_unlock(&ofb->fb.mm_lock);
ofb->fb.screen_base = ofb->video_mem;
return 0;
}

View file

@ -211,23 +211,21 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
/**
* s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock.
* @id: window id.
* @sfb: The hardware state.
* @pixclock: The pixel clock wanted, in picoseconds.
*
* Given the specified pixel clock, work out the necessary divider to get
* close to the output frequency.
*/
static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk)
static int s3c_fb_calc_pixclk(unsigned char id, struct s3c_fb *sfb, unsigned int pixclk)
{
struct s3c_fb_pd_win *win = sfb->pdata->win[id];
unsigned long clk = clk_get_rate(sfb->bus_clk);
unsigned long long tmp;
unsigned int result;
tmp = (unsigned long long)clk;
tmp *= pixclk;
do_div(tmp, 1000000000UL);
result = (unsigned int)tmp / 1000;
pixclk *= win->win_mode.refresh;
result = clk / pixclk;
dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n",
pixclk, clk, result, clk / result);
@ -267,6 +265,7 @@ static int s3c_fb_set_par(struct fb_info *info)
struct s3c_fb *sfb = win->parent;
void __iomem *regs = sfb->regs;
int win_no = win->index;
u32 osdc_data = 0;
u32 data;
u32 pagewidth;
int clkdiv;
@ -302,7 +301,7 @@ static int s3c_fb_set_par(struct fb_info *info)
/* use window 0 as the basis for the lcd output timings */
if (win_no == 0) {
clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock);
clkdiv = s3c_fb_calc_pixclk(win_no, sfb, var->pixclock);
data = sfb->pdata->vidcon0;
data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR);
@ -359,8 +358,6 @@ static int s3c_fb_set_par(struct fb_info *info)
data = var->xres * var->yres;
u32 osdc_data = 0;
osdc_data = VIDISD14C_ALPHA1_R(0xf) |
VIDISD14C_ALPHA1_G(0xf) |
VIDISD14C_ALPHA1_B(0xf);

View file

@ -120,18 +120,6 @@ static int sh7760_setcolreg (u_int regno,
return 0;
}
static void encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info,
unsigned long stride)
{
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, "sh7760-lcdc");
fix->smem_start = (unsigned long)info->screen_base;
fix->smem_len = info->screen_size;
fix->line_length = stride;
}
static int sh7760fb_get_color_info(struct device *dev,
u16 lddfr, int *bpp, int *gray)
{
@ -334,7 +322,8 @@ static int sh7760fb_set_par(struct fb_info *info)
iowrite32(ldsarl, par->base + LDSARL); /* mem for lower half of DSTN */
encode_fix(&info->fix, info, stride);
info->fix.line_length = stride;
sh7760fb_check_var(&info->var, info);
sh7760fb_blank(FB_BLANK_UNBLANK, info); /* panel on! */
@ -435,6 +424,8 @@ static int sh7760fb_alloc_mem(struct fb_info *info)
info->screen_base = fbmem;
info->screen_size = vram;
info->fix.smem_start = (unsigned long)info->screen_base;
info->fix.smem_len = info->screen_size;
return 0;
}
@ -520,6 +511,8 @@ static int __devinit sh7760fb_probe(struct platform_device *pdev)
info->var.transp.length = 0;
info->var.transp.msb_right = 0;
strcpy(info->fix.id, "sh7760-lcdc");
/* set the DON2 bit now, before cmap allocation, as it will randomize
* palette memory.
*/

View file

@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
#include <video/sh_mobile_lcdc.h>
#include <asm/atomic.h>
@ -30,9 +31,10 @@ struct sh_mobile_lcdc_chan {
unsigned long enabled; /* ME and SE in LDCNT2R */
struct sh_mobile_lcdc_chan_cfg cfg;
u32 pseudo_palette[PALETTE_NR];
struct fb_info info;
struct fb_info *info;
dma_addr_t dma_handle;
struct fb_deferred_io defio;
struct scatterlist *sglist;
unsigned long frame_end;
wait_queue_head_t frame_end_wait;
};
@ -206,16 +208,38 @@ static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) {}
static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) {}
#endif
static int sh_mobile_lcdc_sginit(struct fb_info *info,
struct list_head *pagelist)
{
struct sh_mobile_lcdc_chan *ch = info->par;
unsigned int nr_pages_max = info->fix.smem_len >> PAGE_SHIFT;
struct page *page;
int nr_pages = 0;
sg_init_table(ch->sglist, nr_pages_max);
list_for_each_entry(page, pagelist, lru)
sg_set_page(&ch->sglist[nr_pages++], page, PAGE_SIZE, 0);
return nr_pages;
}
static void sh_mobile_lcdc_deferred_io(struct fb_info *info,
struct list_head *pagelist)
{
struct sh_mobile_lcdc_chan *ch = info->par;
unsigned int nr_pages;
/* enable clocks before accessing hardware */
sh_mobile_lcdc_clk_on(ch->lcdc);
nr_pages = sh_mobile_lcdc_sginit(info, pagelist);
dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
/* trigger panel update */
lcdc_write_chan(ch, LDSM2R, 1);
dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
}
static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)
@ -418,22 +442,22 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
/* set bpp format in PKF[4:0] */
tmp = lcdc_read_chan(ch, LDDFR);
tmp &= ~(0x0001001f);
tmp |= (priv->ch[k].info.var.bits_per_pixel == 16) ? 3 : 0;
tmp |= (ch->info->var.bits_per_pixel == 16) ? 3 : 0;
lcdc_write_chan(ch, LDDFR, tmp);
/* point out our frame buffer */
lcdc_write_chan(ch, LDSA1R, ch->info.fix.smem_start);
lcdc_write_chan(ch, LDSA1R, ch->info->fix.smem_start);
/* set line size */
lcdc_write_chan(ch, LDMLSR, ch->info.fix.line_length);
lcdc_write_chan(ch, LDMLSR, ch->info->fix.line_length);
/* setup deferred io if SYS bus */
tmp = ch->cfg.sys_bus_cfg.deferred_io_msec;
if (ch->ldmt1r_value & (1 << 12) && tmp) {
ch->defio.deferred_io = sh_mobile_lcdc_deferred_io;
ch->defio.delay = msecs_to_jiffies(tmp);
ch->info.fbdefio = &ch->defio;
fb_deferred_io_init(&ch->info);
ch->info->fbdefio = &ch->defio;
fb_deferred_io_init(ch->info);
/* one-shot mode */
lcdc_write_chan(ch, LDSM1R, 1);
@ -479,12 +503,12 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
* flush frame, and wait for frame end interrupt
* clean up deferred io and enable clock
*/
if (ch->info.fbdefio) {
if (ch->info->fbdefio) {
ch->frame_end = 0;
schedule_delayed_work(&ch->info.deferred_work, 0);
schedule_delayed_work(&ch->info->deferred_work, 0);
wait_event(ch->frame_end_wait, ch->frame_end);
fb_deferred_io_cleanup(&ch->info);
ch->info.fbdefio = NULL;
fb_deferred_io_cleanup(ch->info);
ch->info->fbdefio = NULL;
sh_mobile_lcdc_clk_on(priv);
}
@ -793,9 +817,16 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1);
for (i = 0; i < j; i++) {
info = &priv->ch[i].info;
cfg = &priv->ch[i].cfg;
priv->ch[i].info = framebuffer_alloc(0, &pdev->dev);
if (!priv->ch[i].info) {
dev_err(&pdev->dev, "unable to allocate fb_info\n");
error = -ENOMEM;
break;
}
info = priv->ch[i].info;
info->fbops = &sh_mobile_lcdc_ops;
info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres;
info->var.yres = info->var.yres_virtual = cfg->lcd_cfg.yres;
@ -846,21 +877,31 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
}
for (i = 0; i < j; i++) {
error = register_framebuffer(&priv->ch[i].info);
struct sh_mobile_lcdc_chan *ch = priv->ch + i;
info = ch->info;
if (info->fbdefio) {
priv->ch->sglist = vmalloc(sizeof(struct scatterlist) *
info->fix.smem_len >> PAGE_SHIFT);
if (!priv->ch->sglist) {
dev_err(&pdev->dev, "cannot allocate sglist\n");
goto err1;
}
}
error = register_framebuffer(info);
if (error < 0)
goto err1;
}
for (i = 0; i < j; i++) {
info = &priv->ch[i].info;
dev_info(info->dev,
"registered %s/%s as %dx%d %dbpp.\n",
pdev->name,
(priv->ch[i].cfg.chan == LCDC_CHAN_MAINLCD) ?
(ch->cfg.chan == LCDC_CHAN_MAINLCD) ?
"mainlcd" : "sublcd",
(int) priv->ch[i].cfg.lcd_cfg.xres,
(int) priv->ch[i].cfg.lcd_cfg.yres,
priv->ch[i].cfg.bpp);
(int) ch->cfg.lcd_cfg.xres,
(int) ch->cfg.lcd_cfg.yres,
ch->cfg.bpp);
/* deferred io mode: disable clock to save power */
if (info->fbdefio)
@ -881,20 +922,24 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
int i;
for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
if (priv->ch[i].info.dev)
unregister_framebuffer(&priv->ch[i].info);
if (priv->ch[i].info->dev)
unregister_framebuffer(priv->ch[i].info);
sh_mobile_lcdc_stop(priv);
for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
info = &priv->ch[i].info;
info = priv->ch[i].info;
if (!info->device)
if (!info || !info->device)
continue;
if (priv->ch[i].sglist)
vfree(priv->ch[i].sglist);
dma_free_coherent(&pdev->dev, info->fix.smem_len,
info->screen_base, priv->ch[i].dma_handle);
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}
#ifdef CONFIG_HAVE_CLK

View file

@ -1847,8 +1847,10 @@ sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
strcpy(fix->id, ivideo->myid);
mutex_lock(&info->mm_lock);
fix->smem_start = ivideo->video_base + ivideo->video_offset;
fix->smem_len = ivideo->sisfb_mem;
mutex_unlock(&info->mm_lock);
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
fix->visual = (ivideo->video_bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
@ -6365,7 +6367,6 @@ error_3: vfree(ivideo->bios_abase);
sis_fb_info->fix = ivideo->sisfb_fix;
sis_fb_info->screen_base = ivideo->video_vbase + ivideo->video_offset;
sis_fb_info->fbops = &sisfb_ops;
sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info);
sis_fb_info->pseudo_palette = ivideo->pseudo_palette;
fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0);

View file

@ -145,7 +145,7 @@ static inline void sm501fb_sync_regs(struct sm501fb_info *info)
#define SM501_MEMF_ACCEL (8)
static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem,
unsigned int why, size_t size)
unsigned int why, size_t size, u32 smem_len)
{
struct sm501fb_par *par;
struct fb_info *fbi;
@ -172,7 +172,7 @@ static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem,
if (ptr > 0)
ptr &= ~(PAGE_SIZE - 1);
if (fbi && ptr < fbi->fix.smem_len)
if (fbi && ptr < smem_len)
return -ENOMEM;
break;
@ -197,7 +197,7 @@ static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem,
case SM501_MEMF_ACCEL:
fbi = inf->fb[HEAD_CRT];
ptr = fbi ? fbi->fix.smem_len : 0;
ptr = fbi ? smem_len : 0;
fbi = inf->fb[HEAD_PANEL];
if (fbi) {
@ -413,6 +413,7 @@ static int sm501fb_set_par_common(struct fb_info *info,
unsigned int mem_type;
unsigned int clock_type;
unsigned int head_addr;
unsigned int smem_len;
dev_dbg(fbi->dev, "%s: %dx%d, bpp = %d, virtual %dx%d\n",
__func__, var->xres, var->yres, var->bits_per_pixel,
@ -453,18 +454,20 @@ static int sm501fb_set_par_common(struct fb_info *info,
/* allocate fb memory within 501 */
info->fix.line_length = (var->xres_virtual * var->bits_per_pixel)/8;
info->fix.smem_len = info->fix.line_length * var->yres_virtual;
smem_len = info->fix.line_length * var->yres_virtual;
dev_dbg(fbi->dev, "%s: line length = %u\n", __func__,
info->fix.line_length);
if (sm501_alloc_mem(fbi, &par->screen, mem_type,
info->fix.smem_len)) {
if (sm501_alloc_mem(fbi, &par->screen, mem_type, smem_len, smem_len)) {
dev_err(fbi->dev, "no memory available\n");
return -ENOMEM;
}
mutex_lock(&info->mm_lock);
info->fix.smem_start = fbi->fbmem_res->start + par->screen.sm_addr;
info->fix.smem_len = smem_len;
mutex_unlock(&info->mm_lock);
info->screen_base = fbi->fbmem + par->screen.sm_addr;
info->screen_size = info->fix.smem_len;
@ -637,7 +640,8 @@ static int sm501fb_set_par_crt(struct fb_info *info)
if ((control & SM501_DC_CRT_CONTROL_SEL) == 0) {
/* the head is displaying panel data... */
sm501_alloc_mem(fbi, &par->screen, SM501_MEMF_CRT, 0);
sm501_alloc_mem(fbi, &par->screen, SM501_MEMF_CRT, 0,
info->fix.smem_len);
goto out_update;
}
@ -1289,7 +1293,8 @@ static int sm501_init_cursor(struct fb_info *fbi, unsigned int reg_base)
par->cursor_regs = info->regs + reg_base;
ret = sm501_alloc_mem(info, &par->cursor, SM501_MEMF_CURSOR, 1024);
ret = sm501_alloc_mem(info, &par->cursor, SM501_MEMF_CURSOR, 1024,
fbi->fix.smem_len);
if (ret < 0)
return ret;
@ -1535,9 +1540,6 @@ static int sm501fb_init_fb(struct fb_info *fb,
if (ret)
dev_err(info->dev, "check_var() failed on initial setup?\n");
/* ensure we've activated our new configuration */
(fb->fbops->fb_set_par)(fb);
return 0;
}
@ -1619,6 +1621,8 @@ static int __devinit sm501fb_start_one(struct sm501fb_info *info,
if (!fbi)
return 0;
mutex_init(&info->fb[head]->mm_lock);
ret = sm501fb_init_fb(info->fb[head], head, drvname);
if (ret) {
dev_err(info->dev, "cannot initialise fb %s\n", drvname);

View file

@ -1115,10 +1115,9 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
if the device name contains the string "DX" and tell the
user how to reconfigure the card. */
if (strstr(sti->outptr.dev_name, "DX")) {
printk(KERN_WARNING "WARNING: stifb framebuffer driver does not "
"support '%s' in double-buffer mode.\n"
KERN_WARNING "WARNING: Please disable the double-buffer mode "
"in IPL menu (the PARISC-BIOS).\n",
printk(KERN_WARNING
"WARNING: stifb framebuffer driver does not support '%s' in double-buffer mode.\n"
"WARNING: Please disable the double-buffer mode in IPL menu (the PARISC-BIOS).\n",
sti->outptr.dev_name);
goto out_err0;
}

View file

@ -523,6 +523,7 @@ static int w100fb_set_par(struct fb_info *info)
info->fix.ywrapstep = 0;
info->fix.line_length = par->xres * BITS_PER_PIXEL / 8;
mutex_lock(&info->mm_lock);
if ((par->xres*par->yres*BITS_PER_PIXEL/8) > (MEM_INT_SIZE+1)) {
par->extmem_active = 1;
info->fix.smem_len = par->mach->mem->size+1;
@ -530,6 +531,7 @@ static int w100fb_set_par(struct fb_info *info)
par->extmem_active = 0;
info->fix.smem_len = MEM_INT_SIZE+1;
}
mutex_unlock(&info->mm_lock);
w100fb_activate_var(par);
}
@ -746,8 +748,6 @@ int __init w100fb_probe(struct platform_device *pdev)
goto out;
}
w100fb_set_par(info);
if (register_framebuffer(info) < 0) {
err = -EINVAL;
goto out;