diff options
Diffstat (limited to 'drivers/video')
125 files changed, 3329 insertions, 2856 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 168ede7902bd..17de4c84db69 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -4,6 +4,21 @@ menu "Graphics support" +config FIRMWARE_EDID + bool "Enable firmware EDID" + default y + ---help--- + This enables access to the EDID transferred from the firmware. + On the i386, this is from the Video BIOS. Enable this if DDC/I2C + transfers do not work for your driver and if you are using + nvidiafb, i810fb or savagefb. + + In general, choosing Y for this option is safe. If you + experience extremely long delays while booting before you get + something on your display, try setting this to N. Matrox cards in + combination with certain motherboards and monitors are known to + suffer from this problem. + config FB tristate "Support for frame buffer devices" ---help--- @@ -70,22 +85,6 @@ config FB_MACMODES depends on FB default n -config FB_FIRMWARE_EDID - bool "Enable firmware EDID" - depends on FB - default y - ---help--- - This enables access to the EDID transferred from the firmware. - On the i386, this is from the Video BIOS. Enable this if DDC/I2C - transfers do not work for your driver and if you are using - nvidiafb, i810fb or savagefb. - - In general, choosing Y for this option is safe. If you - experience extremely long delays while booting before you get - something on your display, try setting this to N. Matrox cards in - combination with certain motherboards and monitors are known to - suffer from this problem. - config FB_BACKLIGHT bool depends on FB @@ -551,10 +550,14 @@ config FB_VESA You will get a boot time penguin logo at no additional cost. Please read <file:Documentation/fb/vesafb.txt>. If unsure, say Y. -config VIDEO_SELECT - bool - depends on FB_VESA - default y +config FB_IMAC + bool "Intel-based Macintosh Framebuffer Support" + depends on (FB = y) && X86 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the Intel-based Macintosh config FB_HGA tristate "Hercules mono graphics support" @@ -578,12 +581,6 @@ config FB_HGA_ACCEL This will compile the Hercules mono graphics with acceleration functions. - -config VIDEO_SELECT - bool - depends on (FB = y) && X86 - default y - config FB_SGIVW tristate "SGI Visual Workstation framebuffer support" depends on FB && X86_VISWS diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 23de3b2c7856..c335e9bc3b20 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -4,15 +4,15 @@ # Each configuration option enables a list of files. -obj-$(CONFIG_VT) += console/ -obj-$(CONFIG_LOGO) += logo/ -obj-$(CONFIG_SYSFS) += backlight/ - obj-$(CONFIG_FB) += fb.o fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ modedb.o fbcvt.o fb-objs := $(fb-y) +obj-$(CONFIG_VT) += console/ +obj-$(CONFIG_LOGO) += logo/ +obj-$(CONFIG_SYSFS) += backlight/ + obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o @@ -97,6 +97,7 @@ obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o # Platform or fallback drivers go here obj-$(CONFIG_FB_VESA) += vesafb.o +obj-$(CONFIG_FB_IMAC) += imacfb.o obj-$(CONFIG_FB_VGA16) += vga16fb.o vgastate.o obj-$(CONFIG_FB_OF) += offb.o diff --git a/drivers/video/S3triofb.c b/drivers/video/S3triofb.c index 455fda990ff7..e714e8449c1d 100644 --- a/drivers/video/S3triofb.c +++ b/drivers/video/S3triofb.c @@ -23,7 +23,6 @@ */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/errno.h> diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c index 98baecccb3fd..61a8bf159cb0 100644 --- a/drivers/video/acornfb.c +++ b/drivers/video/acornfb.c @@ -17,7 +17,6 @@ * - Blanking 8bpp displays with VIDC */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c index 3033c72dea20..f9bc9f777e75 100644 --- a/drivers/video/amifb.c +++ b/drivers/video/amifb.c @@ -48,7 +48,6 @@ #include <linux/tty.h> #include <linux/slab.h> #include <linux/delay.h> -#include <linux/config.h> #include <linux/interrupt.h> #include <linux/fb.h> #include <linux/init.h> diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c index 466042808daf..fd95c2dbd4f7 100644 --- a/drivers/video/arcfb.c +++ b/drivers/video/arcfb.c @@ -561,7 +561,7 @@ static int __init arcfb_probe(struct platform_device *dev) platform_set_drvdata(dev, info); if (irq) { par->irq = irq; - if (request_irq(par->irq, &arcfb_interrupt, SA_SHIRQ, + if (request_irq(par->irq, &arcfb_interrupt, IRQF_SHARED, "arcfb", info)) { printk(KERN_INFO "arcfb: Failed req IRQ %d\n", par->irq); diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c index 29f9f0dfe3b4..eaeaf4d1a094 100644 --- a/drivers/video/asiliantfb.c +++ b/drivers/video/asiliantfb.c @@ -29,7 +29,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index db878fd55fb2..72c589109471 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c @@ -46,7 +46,6 @@ */ -#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> @@ -100,7 +99,7 @@ #ifndef CONFIG_PPC_PMAC /* default mode */ -static struct fb_var_screeninfo default_var __initdata = { +static struct fb_var_screeninfo default_var __devinitdata = { /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */ 640, 480, 640, 480, 0, 0, 8, 0, {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, @@ -123,7 +122,7 @@ static struct fb_var_screeninfo default_var = { /* default modedb mode */ /* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */ -static struct fb_videomode defaultmode __initdata = { +static struct fb_videomode defaultmode __devinitdata = { .refresh = 60, .xres = 640, .yres = 480, @@ -335,7 +334,7 @@ static const struct aty128_meminfo sdr_sgram = static const struct aty128_meminfo ddr_sgram = { 4, 4, 3, 3, 2, 3, 1, 16, 31, 16, "64-bit DDR SGRAM" }; -static struct fb_fix_screeninfo aty128fb_fix __initdata = { +static struct fb_fix_screeninfo aty128fb_fix __devinitdata = { .id = "ATY Rage128", .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_PSEUDOCOLOR, @@ -345,15 +344,15 @@ static struct fb_fix_screeninfo aty128fb_fix __initdata = { .accel = FB_ACCEL_ATI_RAGE128, }; -static char *mode_option __initdata = NULL; +static char *mode_option __devinitdata = NULL; #ifdef CONFIG_PPC_PMAC -static int default_vmode __initdata = VMODE_1024_768_60; -static int default_cmode __initdata = CMODE_8; +static int default_vmode __devinitdata = VMODE_1024_768_60; +static int default_cmode __devinitdata = CMODE_8; #endif -static int default_crt_on __initdata = 0; -static int default_lcd_on __initdata = 1; +static int default_crt_on __devinitdata = 0; +static int default_lcd_on __devinitdata = 1; #ifdef CONFIG_MTRR static int mtrr = 1; @@ -445,9 +444,9 @@ static int aty128_encode_var(struct fb_var_screeninfo *var, static int aty128_decode_var(struct fb_var_screeninfo *var, struct aty128fb_par *par); #if 0 -static void __init aty128_get_pllinfo(struct aty128fb_par *par, +static void __devinit aty128_get_pllinfo(struct aty128fb_par *par, void __iomem *bios); -static void __init __iomem *aty128_map_ROM(struct pci_dev *pdev, const struct aty128fb_par *par); +static void __devinit __iomem *aty128_map_ROM(struct pci_dev *pdev, const struct aty128fb_par *par); #endif static void aty128_timings(struct aty128fb_par *par); static void aty128_init_engine(struct aty128fb_par *par); @@ -573,7 +572,7 @@ static void aty_pll_writeupdate(const struct aty128fb_par *par) /* write to the scratch register to test r/w functionality */ -static int __init register_test(const struct aty128fb_par *par) +static int __devinit register_test(const struct aty128fb_par *par) { u32 val; int flag = 0; @@ -772,7 +771,7 @@ static u32 depth_to_dst(u32 depth) #ifndef __sparc__ -static void __iomem * __init aty128_map_ROM(const struct aty128fb_par *par, struct pci_dev *dev) +static void __iomem * __devinit aty128_map_ROM(const struct aty128fb_par *par, struct pci_dev *dev) { u16 dptr; u8 rom_type; @@ -856,7 +855,7 @@ static void __iomem * __init aty128_map_ROM(const struct aty128fb_par *par, stru return NULL; } -static void __init aty128_get_pllinfo(struct aty128fb_par *par, unsigned char __iomem *bios) +static void __devinit aty128_get_pllinfo(struct aty128fb_par *par, unsigned char __iomem *bios) { unsigned int bios_hdr; unsigned int bios_pll; @@ -903,7 +902,7 @@ static void __iomem * __devinit aty128_find_mem_vbios(struct aty128fb_par *par) #endif /* ndef(__sparc__) */ /* fill in known card constants if pll_block is not available */ -static void __init aty128_timings(struct aty128fb_par *par) +static void __devinit aty128_timings(struct aty128fb_par *par) { #ifdef CONFIG_PPC_OF /* instead of a table lookup, assume OF has properly @@ -1645,7 +1644,7 @@ static int aty128fb_sync(struct fb_info *info) } #ifndef MODULE -static int __init aty128fb_setup(char *options) +static int __devinit aty128fb_setup(char *options) { char *this_opt; @@ -1893,7 +1892,7 @@ static void aty128_early_resume(void *data) } #endif /* CONFIG_PPC_PMAC */ -static int __init aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent) +static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent) { struct fb_info *info = pci_get_drvdata(pdev); struct aty128fb_par *par = info->par; @@ -2037,7 +2036,7 @@ static int __init aty128_init(struct pci_dev *pdev, const struct pci_device_id * #ifdef CONFIG_PCI /* register a card ++ajoshi */ -static int __init aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +static int __devinit aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { unsigned long fb_addr, reg_addr; struct aty128fb_par *par; @@ -2556,7 +2555,7 @@ static int aty128_pci_resume(struct pci_dev *pdev) } -static int __init aty128fb_init(void) +static int __devinit aty128fb_init(void) { #ifndef MODULE char *option = NULL; diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h index 43d2cb58af87..55fb8b04489b 100644 --- a/drivers/video/aty/atyfb.h +++ b/drivers/video/aty/atyfb.h @@ -2,7 +2,6 @@ * ATI Frame Buffer Device Driver Core Definitions */ -#include <linux/config.h> #include <linux/spinlock.h> #include <linux/wait.h> /* diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index c5185f7cf4ba..0c9706746d79 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -49,7 +49,6 @@ ******************************************************************************/ -#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> @@ -316,12 +315,12 @@ static int vram; static int pll; static int mclk; static int xclk; -static int comp_sync __initdata = -1; +static int comp_sync __devinitdata = -1; static char *mode; #ifdef CONFIG_PPC -static int default_vmode __initdata = VMODE_CHOOSE; -static int default_cmode __initdata = CMODE_CHOOSE; +static int default_vmode __devinitdata = VMODE_CHOOSE; +static int default_cmode __devinitdata = CMODE_CHOOSE; module_param_named(vmode, default_vmode, int, 0); MODULE_PARM_DESC(vmode, "int: video mode for mac"); @@ -330,10 +329,10 @@ MODULE_PARM_DESC(cmode, "int: color mode for mac"); #endif #ifdef CONFIG_ATARI -static unsigned int mach64_count __initdata = 0; -static unsigned long phys_vmembase[FB_MAX] __initdata = { 0, }; -static unsigned long phys_size[FB_MAX] __initdata = { 0, }; -static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, }; +static unsigned int mach64_count __devinitdata = 0; +static unsigned long phys_vmembase[FB_MAX] __devinitdata = { 0, }; +static unsigned long phys_size[FB_MAX] __devinitdata = { 0, }; +static unsigned long phys_guiregbase[FB_MAX] __devinitdata = { 0, }; #endif /* top -> down is an evolution of mach64 chipset, any corrections? */ @@ -583,7 +582,7 @@ static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, struct atyfb_par *p * Apple monitor sense */ -static int __init read_aty_sense(const struct atyfb_par *par) +static int __devinit read_aty_sense(const struct atyfb_par *par) { int sense, i; @@ -1281,6 +1280,14 @@ static int atyfb_set_par(struct fb_info *info) par->accel_flags = var->accel_flags; /* hack */ + if (var->accel_flags) { + info->fbops->fb_sync = atyfb_sync; + info->flags &= ~FBINFO_HWACCEL_DISABLED; + } else { + info->fbops->fb_sync = NULL; + info->flags |= FBINFO_HWACCEL_DISABLED; + } + if (par->blitter_may_be_busy) wait_for_idle(par); @@ -1560,7 +1567,7 @@ static int aty_enable_irq(struct atyfb_par *par, int reenable) u32 int_cntl; if (!test_and_set_bit(0, &par->irq_flags)) { - if (request_irq(par->irq, aty_irq, SA_SHIRQ, "atyfb", par)) { + if (request_irq(par->irq, aty_irq, IRQF_SHARED, "atyfb", par)) { clear_bit(0, &par->irq_flags); return -EINVAL; } @@ -2253,7 +2260,7 @@ static void aty_bl_exit(struct atyfb_par *par) #endif /* CONFIG_FB_ATY_BACKLIGHT */ -static void __init aty_calc_mem_refresh(struct atyfb_par *par, int xclk) +static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk) { const int ragepro_tbl[] = { 44, 50, 55, 66, 75, 80, 100 @@ -2313,7 +2320,7 @@ static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par, } #endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */ -static int __init aty_init(struct fb_info *info, const char *name) +static int __devinit aty_init(struct fb_info *info, const char *name) { struct atyfb_par *par = (struct atyfb_par *) info->par; const char *ramname = NULL, *xtal; @@ -2394,12 +2401,15 @@ static int __init aty_init(struct fb_info *info, const char *name) break; } switch (clk_type) { +#ifdef CONFIG_ATARI case CLK_ATI18818_1: par->pll_ops = &aty_pll_ati18818_1; break; +#else case CLK_IBMRGB514: par->pll_ops = &aty_pll_ibm514; break; +#endif #if 0 /* dead code */ case CLK_STG1703: par->pll_ops = &aty_pll_stg1703; @@ -2604,7 +2614,11 @@ static int __init aty_init(struct fb_info *info, const char *name) info->fbops = &atyfb_ops; info->pseudo_palette = pseudo_palette; - info->flags = FBINFO_FLAG_DEFAULT; + info->flags = FBINFO_DEFAULT | + FBINFO_HWACCEL_IMAGEBLIT | + FBINFO_HWACCEL_FILLRECT | + FBINFO_HWACCEL_COPYAREA | + FBINFO_HWACCEL_YPAN; #ifdef CONFIG_PMAC_BACKLIGHT if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) { @@ -2733,7 +2747,7 @@ aty_init_exit: } #ifdef CONFIG_ATARI -static int __init store_video_par(char *video_str, unsigned char m64_num) +static int __devinit store_video_par(char *video_str, unsigned char m64_num) { char *p; unsigned long vmembase, size, guiregbase; @@ -3764,7 +3778,7 @@ static struct pci_driver atyfb_driver = { #endif /* CONFIG_PCI */ #ifndef MODULE -static int __init atyfb_setup(char *options) +static int __devinit atyfb_setup(char *options) { char *this_opt; @@ -3836,7 +3850,7 @@ static int __init atyfb_setup(char *options) } #endif /* MODULE */ -static int __init atyfb_init(void) +static int __devinit atyfb_init(void) { #ifndef MODULE char *option = NULL; diff --git a/drivers/video/aty/mach64_accel.c b/drivers/video/aty/mach64_accel.c index c98f4a442134..1490e5e1c232 100644 --- a/drivers/video/aty/mach64_accel.c +++ b/drivers/video/aty/mach64_accel.c @@ -200,8 +200,6 @@ void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) if (!area->width || !area->height) return; if (!par->accel_flags) { - if (par->blitter_may_be_busy) - wait_for_idle(par); cfb_copyarea(info, area); return; } @@ -248,8 +246,6 @@ void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) if (!rect->width || !rect->height) return; if (!par->accel_flags) { - if (par->blitter_may_be_busy) - wait_for_idle(par); cfb_fillrect(info, rect); return; } @@ -288,14 +284,10 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) return; if (!par->accel_flags || (image->depth != 1 && info->var.bits_per_pixel != image->depth)) { - if (par->blitter_may_be_busy) - wait_for_idle(par); - cfb_imageblit(info, image); return; } - wait_for_idle(par); pix_width = pix_width_save = aty_ld_le32(DP_PIX_WIDTH, par); host_cntl = aty_ld_le32(HOST_CNTL, par) | HOST_BYTE_ALIGN; @@ -425,8 +417,6 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) } } - wait_for_idle(par); - /* restore pix_width */ wait_for_fifo(1, par); aty_st_le32(DP_PIX_WIDTH, pix_width_save, par); diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c index ad8b7496f853..2a7f381c330f 100644 --- a/drivers/video/aty/mach64_cursor.c +++ b/drivers/video/aty/mach64_cursor.c @@ -66,11 +66,6 @@ static const u8 cursor_bits_lookup[16] = { 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55 }; -static const u8 cursor_mask_lookup[16] = { - 0xaa, 0x2a, 0x8a, 0x0a, 0xa2, 0x22, 0x82, 0x02, - 0xa8, 0x28, 0x88, 0x08, 0xa0, 0x20, 0x80, 0x00 -}; - static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) { struct atyfb_par *par = (struct atyfb_par *) info->par; @@ -130,13 +125,13 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) fg_idx = cursor->image.fg_color; bg_idx = cursor->image.bg_color; - fg = (info->cmap.red[fg_idx] << 24) | - (info->cmap.green[fg_idx] << 16) | - (info->cmap.blue[fg_idx] << 8) | 15; + fg = ((info->cmap.red[fg_idx] & 0xff) << 24) | + ((info->cmap.green[fg_idx] & 0xff) << 16) | + ((info->cmap.blue[fg_idx] & 0xff) << 8) | 0xff; - bg = (info->cmap.red[bg_idx] << 24) | - (info->cmap.green[bg_idx] << 16) | - (info->cmap.blue[bg_idx] << 8); + bg = ((info->cmap.red[bg_idx] & 0xff) << 24) | + ((info->cmap.green[bg_idx] & 0xff) << 16) | + ((info->cmap.blue[bg_idx] & 0xff) << 8); wait_for_fifo(2, par); aty_st_le32(CUR_CLR0, bg, par); @@ -166,19 +161,17 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) switch (cursor->rop) { case ROP_XOR: // Upper 4 bits of mask data - fb_writeb(cursor_mask_lookup[m >> 4 ] | - cursor_bits_lookup[(b ^ m) >> 4], dst++); + fb_writeb(cursor_bits_lookup[(b ^ m) >> 4], dst++); // Lower 4 bits of mask - fb_writeb(cursor_mask_lookup[m & 0x0f ] | - cursor_bits_lookup[(b ^ m) & 0x0f], dst++); + fb_writeb(cursor_bits_lookup[(b ^ m) & 0x0f], + dst++); break; case ROP_COPY: // Upper 4 bits of mask data - fb_writeb(cursor_mask_lookup[m >> 4 ] | - cursor_bits_lookup[(b & m) >> 4], dst++); + fb_writeb(cursor_bits_lookup[(b & m) >> 4], dst++); // Lower 4 bits of mask - fb_writeb(cursor_mask_lookup[m & 0x0f ] | - cursor_bits_lookup[(b & m) & 0x0f], dst++); + fb_writeb(cursor_bits_lookup[(b & m) & 0x0f], + dst++); break; } } @@ -194,7 +187,7 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) return 0; } -int __init aty_init_cursor(struct fb_info *info) +int __devinit aty_init_cursor(struct fb_info *info) { unsigned long addr; diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c index 7de66b855d4e..1755dddf1899 100644 --- a/drivers/video/aty/radeon_backlight.c +++ b/drivers/video/aty/radeon_backlight.c @@ -40,14 +40,14 @@ static int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata, mutex_unlock(&info->bl_mutex); - if (pdata->negative) - rlevel = MAX_RADEON_LEVEL - rlevel; - if (rlevel < 0) rlevel = 0; else if (rlevel > MAX_RADEON_LEVEL) rlevel = MAX_RADEON_LEVEL; + if (pdata->negative) + rlevel = MAX_RADEON_LEVEL - rlevel; + return rlevel; } diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index c5ecbb02e01d..51b78f8de949 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c @@ -52,7 +52,6 @@ #define RADEON_VERSION "0.2.0" -#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> @@ -2379,7 +2378,6 @@ err_release_pci0: err_release_fb: framebuffer_release(info); err_disable: - pci_disable_device(pdev); err_out: return ret; } @@ -2436,7 +2434,6 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev) #endif fb_dealloc_cmap(&info->cmap); framebuffer_release(info); - pci_disable_device(pdev); } diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c index a9d0414e4655..9aaca58c074a 100644 --- a/drivers/video/aty/radeon_i2c.c +++ b/drivers/video/aty/radeon_i2c.c @@ -1,4 +1,3 @@ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h index 1645943b1123..38657b2d10eb 100644 --- a/drivers/video/aty/radeonfb.h +++ b/drivers/video/aty/radeonfb.h @@ -1,7 +1,6 @@ #ifndef __RADEONFB_H__ #define __RADEONFB_H__ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -382,7 +381,7 @@ struct radeonfb_info { /* Note about this function: we have some rare cases where we must not schedule, * this typically happen with our special "wake up early" hook which allows us to * wake up the graphic chip (and thus get the console back) before everything else - * on some machines that support that mecanism. At this point, interrupts are off + * on some machines that support that mechanism. At this point, interrupts are off * and scheduling is not permitted */ static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms) diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index 789450bb0bc9..a92a91fef16f 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c @@ -7,6 +7,8 @@ * Karl Lessard <klessard@sunrisetelecom.com> * <c.pellegrin@exadron.com> * + * PM support added by Rodolfo Giometti <giometti@linux.it> + * * Copyright 2002 MontaVista Software * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com @@ -38,7 +40,6 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -602,17 +603,52 @@ int au1100fb_drv_remove(struct device *dev) return 0; } +#ifdef CONFIG_PM +static u32 sys_clksrc; +static struct au1100fb_regs fbregs; + int au1100fb_drv_suspend(struct device *dev, pm_message_t state) { - /* TODO */ + struct au1100fb_device *fbdev = dev_get_drvdata(dev); + + if (!fbdev) + return 0; + + /* Save the clock source state */ + sys_clksrc = au_readl(SYS_CLKSRC); + + /* Blank the LCD */ + au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); + + /* Stop LCD clocking */ + au_writel(sys_clksrc & ~SYS_CS_ML_MASK, SYS_CLKSRC); + + memcpy(&fbregs, fbdev->regs, sizeof(struct au1100fb_regs)); + return 0; } int au1100fb_drv_resume(struct device *dev) { - /* TODO */ + struct au1100fb_device *fbdev = dev_get_drvdata(dev); + + if (!fbdev) + return 0; + + memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs)); + + /* Restart LCD clocking */ + au_writel(sys_clksrc, SYS_CLKSRC); + + /* Unblank the LCD */ + au1100fb_fb_blank(VESA_NO_BLANKING, &fbdev->info); + return 0; } +#else +#define au1100fb_drv_suspend NULL +#define au1100fb_drv_resume NULL +#endif static struct device_driver au1100fb_driver = { .name = "au1100-lcd", @@ -706,8 +742,7 @@ void __exit au1100fb_cleanup(void) { driver_unregister(&au1100fb_driver); - if (drv_info.opt_mode) - kfree(drv_info.opt_mode); + kfree(drv_info.opt_mode); } module_init(au1100fb_init); diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c index 600d3e0e08b7..c6a5f0ccc107 100644 --- a/drivers/video/au1200fb.c +++ b/drivers/video/au1200fb.c @@ -1694,7 +1694,7 @@ static int au1200fb_drv_probe(struct device *dev) /* Now hook interrupt too */ if ((ret = request_irq(AU1200_LCD_INT, au1200fb_handle_irq, - SA_INTERRUPT | SA_SHIRQ, "lcd", (void *)dev)) < 0) { + IRQF_DISABLED | IRQF_SHARED, "lcd", (void *)dev)) < 0) { print_err("fail to request interrupt line %d (err: %d)", AU1200_LCD_INT, ret); goto failed; diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index b895eaaa73fd..022f9d3473f5 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -10,7 +10,7 @@ menuconfig BACKLIGHT_LCD_SUPPORT config BACKLIGHT_CLASS_DEVICE tristate "Lowlevel Backlight controls" - depends on BACKLIGHT_LCD_SUPPORT + depends on BACKLIGHT_LCD_SUPPORT && FB default m help This framework adds support for low-level control of the LCD @@ -26,7 +26,7 @@ config BACKLIGHT_DEVICE config LCD_CLASS_DEVICE tristate "Lowlevel LCD controls" - depends on BACKLIGHT_LCD_SUPPORT + depends on BACKLIGHT_LCD_SUPPORT && FB default m help This framework adds support for low-level control of LCD. @@ -50,6 +50,14 @@ config BACKLIGHT_CORGI If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the backlight driver. +config BACKLIGHT_LOCOMO + tristate "Sharp LOCOMO LCD/Backlight Driver" + depends on BACKLIGHT_DEVICE && SHARP_LOCOMO + default y + help + If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to + enable the LCD/backlight driver. + config BACKLIGHT_HP680 tristate "HP Jornada 680 Backlight Driver" depends on BACKLIGHT_DEVICE && SH_HP6XX diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 744210c38e74..65e5553fc849 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o -obj-$(CONFIG_SHARP_LOCOMO) += locomolcd.o +obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index a71e984c93d4..ffc72ae3ada8 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c @@ -27,7 +27,7 @@ static int hp680bl_suspended; static int current_intensity = 0; -static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(bl_lock); static struct backlight_device *hp680_backlight_device; static void hp680bl_send_intensity(struct backlight_device *bd) diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c index 60831bb23685..caf1eca199b0 100644 --- a/drivers/video/backlight/locomolcd.c +++ b/drivers/video/backlight/locomolcd.c @@ -11,12 +11,13 @@ */ /* LCD power functions */ -#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/interrupt.h> +#include <linux/fb.h> +#include <linux/backlight.h> #include <asm/hardware/locomo.h> #include <asm/irq.h> @@ -25,7 +26,10 @@ #include "../../../arch/arm/mach-sa1100/generic.h" +static struct backlight_device *locomolcd_bl_device; static struct locomo_dev *locomolcd_dev; +static unsigned long locomolcd_flags; +#define LOCOMOLCD_SUSPENDED 0x01 static void locomolcd_on(int comadj) { @@ -89,12 +93,10 @@ void locomolcd_power(int on) } /* read comadj */ - if (comadj == -1) { - if (machine_is_poodle()) - comadj = 118; - if (machine_is_collie()) - comadj = 128; - } + if (comadj == -1 && machine_is_collie()) + comadj = 128; + if (comadj == -1 && machine_is_poodle()) + comadj = 118; if (on) locomolcd_on(comadj); @@ -105,26 +107,100 @@ void locomolcd_power(int on) } EXPORT_SYMBOL(locomolcd_power); -static int poodle_lcd_probe(struct locomo_dev *dev) + +static int current_intensity; + +static int locomolcd_set_intensity(struct backlight_device *bd) +{ + int intensity = bd->props->brightness; + + if (bd->props->power != FB_BLANK_UNBLANK) + intensity = 0; + if (bd->props->fb_blank != FB_BLANK_UNBLANK) + intensity = 0; + if (locomolcd_flags & LOCOMOLCD_SUSPENDED) + intensity = 0; + + switch (intensity) { + /* AC and non-AC are handled differently, but produce same results in sharp code? */ + case 0: locomo_frontlight_set(locomolcd_dev, 0, 0, 161); break; + case 1: locomo_frontlight_set(locomolcd_dev, 117, 0, 161); break; + case 2: locomo_frontlight_set(locomolcd_dev, 163, 0, 148); break; + case 3: locomo_frontlight_set(locomolcd_dev, 194, 0, 161); break; + case 4: locomo_frontlight_set(locomolcd_dev, 194, 1, 161); break; + + default: + return -ENODEV; + } + current_intensity = intensity; + return 0; +} + +static int locomolcd_get_intensity(struct backlight_device *bd) +{ + return current_intensity; +} + +static struct backlight_properties locomobl_data = { + .owner = THIS_MODULE, + .get_brightness = locomolcd_get_intensity, + .update_status = locomolcd_set_intensity, + .max_brightness = 4, +}; + +#ifdef CONFIG_PM +static int locomolcd_suspend(struct locomo_dev *dev, pm_message_t state) +{ + locomolcd_flags |= LOCOMOLCD_SUSPENDED; + locomolcd_set_intensity(locomolcd_bl_device); + return 0; +} + +static int locomolcd_resume(struct locomo_dev *dev) +{ + locomolcd_flags &= ~LOCOMOLCD_SUSPENDED; + locomolcd_set_intensity(locomolcd_bl_device); + return 0; +} +#else +#define locomolcd_suspend NULL +#define locomolcd_resume NULL +#endif + +static int locomolcd_probe(struct locomo_dev *dev) { unsigned long flags; local_irq_save(flags); locomolcd_dev = dev; + locomo_gpio_set_dir(dev, LOCOMO_GPIO_FL_VR, 0); + /* the poodle_lcd_power function is called for the first time * from fs_initcall, which is before locomo is activated. * We need to recall poodle_lcd_power here*/ -#ifdef CONFIG_MACH_POODLE - locomolcd_power(1); -#endif + if (machine_is_poodle()) + locomolcd_power(1); + local_irq_restore(flags); + + locomolcd_bl_device = backlight_device_register("locomo-bl", NULL, &locomobl_data); + + if (IS_ERR (locomolcd_bl_device)) + return PTR_ERR (locomolcd_bl_device); + + /* Set up frontlight so that screen is readable */ + locomobl_data.brightness = 2; + locomolcd_set_intensity(locomolcd_bl_device); + return 0; } -static int poodle_lcd_remove(struct locomo_dev *dev) +static int locomolcd_remove(struct locomo_dev *dev) { unsigned long flags; + + backlight_device_unregister(locomolcd_bl_device); local_irq_save(flags); locomolcd_dev = NULL; local_irq_restore(flags); @@ -136,19 +212,33 @@ static struct locomo_driver poodle_lcd_driver = { .name = "locomo-backlight", }, .devid = LOCOMO_DEVID_BACKLIGHT, - .probe = poodle_lcd_probe, - .remove = poodle_lcd_remove, + .probe = locomolcd_probe, + .remove = locomolcd_remove, + .suspend = locomolcd_suspend, + .resume = locomolcd_resume, }; -static int __init poodle_lcd_init(void) + +static int __init locomolcd_init(void) { int ret = locomo_driver_register(&poodle_lcd_driver); - if (ret) return ret; + if (ret) + return ret; #ifdef CONFIG_SA1100_COLLIE sa1100fb_lcd_power = locomolcd_power; #endif return 0; } -device_initcall(poodle_lcd_init); +static void __exit locomolcd_exit(void) +{ + locomo_driver_unregister(&poodle_lcd_driver); +} + +module_init(locomolcd_init); +module_exit(locomolcd_exit); + +MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@suse.cz>"); +MODULE_DESCRIPTION("Collie LCD driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index 6577fdfdfc16..c66e3d52cbf3 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c @@ -1,6 +1,6 @@ /* bw2.c: BWTWO frame buffer driver * - * Copyright (C) 2003 David S. Miller (davem@redhat.com) + * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -19,14 +19,11 @@ #include <linux/mm.h> #include <asm/io.h> -#include <asm/sbus.h> #include <asm/oplib.h> +#include <asm/prom.h> +#include <asm/of_device.h> #include <asm/fbio.h> -#ifdef CONFIG_SPARC32 -#include <asm/sun4paddr.h> -#endif - #include "sbuslib.h" /* @@ -59,30 +56,30 @@ static struct fb_ops bw2_ops = { #define BWTWO_REGISTER_OFFSET 0x400000 struct bt_regs { - volatile u32 addr; - volatile u32 color_map; - volatile u32 control; - volatile u32 cursor; + u32 addr; + u32 color_map; + u32 control; + u32 cursor; }; struct bw2_regs { struct bt_regs cmap; - volatile u8 control; - volatile u8 status; - volatile u8 cursor_start; - volatile u8 cursor_end; - volatile u8 h_blank_start; - volatile u8 h_blank_end; - volatile u8 h_sync_start; - volatile u8 h_sync_end; - volatile u8 comp_sync_end; - volatile u8 v_blank_start_high; - volatile u8 v_blank_start_low; - volatile u8 v_blank_end; - volatile u8 v_sync_start; - volatile u8 v_sync_end; - volatile u8 xfer_holdoff_start; - volatile u8 xfer_holdoff_end; + u8 control; + u8 status; + u8 cursor_start; + u8 cursor_end; + u8 h_blank_start; + u8 h_blank_end; + u8 h_sync_start; + u8 h_sync_end; + u8 comp_sync_end; + u8 v_blank_start_high; + u8 v_blank_start_low; + u8 v_blank_end; + u8 v_sync_start; + u8 v_sync_end; + u8 xfer_holdoff_start; + u8 xfer_holdoff_end; }; /* Status Register Constants */ @@ -117,9 +114,8 @@ struct bw2_par { #define BW2_FLAG_BLANKED 0x00000001 unsigned long physbase; + unsigned long which_io; unsigned long fbsize; - - struct sbus_dev *sdev; }; /** @@ -174,9 +170,7 @@ static int bw2_mmap(struct fb_info *info, struct vm_area_struct *vma) return sbusfb_mmap_helper(bw2_mmap_map, par->physbase, par->fbsize, - (par->sdev ? - par->sdev->reg_addrs[0].which_io : - 0), + par->which_io, vma); } @@ -288,139 +282,124 @@ static void bw2_do_default_mode(struct bw2_par *par, struct fb_info *info, struct all_info { struct fb_info info; struct bw2_par par; - struct list_head list; }; -static LIST_HEAD(bw2_list); -static void bw2_init_one(struct sbus_dev *sdev) +static int __devinit bw2_init_one(struct of_device *op) { + struct device_node *dp = op->node; struct all_info *all; - struct resource *resp; -#ifdef CONFIG_SUN4 - struct resource res; -#endif - int linebytes; + int linebytes, err; - all = kmalloc(sizeof(*all), GFP_KERNEL); - if (!all) { - printk(KERN_ERR "bw2: Cannot allocate memory.\n"); - return; - } - memset(all, 0, sizeof(*all)); - - INIT_LIST_HEAD(&all->list); + all = kzalloc(sizeof(*all), GFP_KERNEL); + if (!all) + return -ENOMEM; spin_lock_init(&all->par.lock); - all->par.sdev = sdev; - -#ifdef CONFIG_SUN4 - if (!sdev) { - all->par.physbase = sun4_bwtwo_physaddr; - res.start = sun4_bwtwo_physaddr; - res.end = res.start + BWTWO_REGISTER_OFFSET + sizeof(struct bw2_regs) - 1; - res.flags = IORESOURCE_IO; - resp = &res; - all->info.var.xres = all->info.var.xres_virtual = 1152; - all->info.var.yres = all->info.var.yres_virtual = 900; - all->info.var.bits_per_pixel = 1; - linebytes = 1152 / 8; - } else -#else - { - BUG_ON(!sdev); - all->par.physbase = sdev->reg_addrs[0].phys_addr; - resp = &sdev->resource[0]; - sbusfb_fill_var(&all->info.var, (sdev ? sdev->prom_node : 0), 1); - linebytes = prom_getintdefault(sdev->prom_node, "linebytes", - all->info.var.xres); - } -#endif + + all->par.physbase = op->resource[0].start; + all->par.which_io = op->resource[0].flags & IORESOURCE_BITS; + + sbusfb_fill_var(&all->info.var, dp->node, 1); + linebytes = of_getintprop_default(dp, "linebytes", + all->info.var.xres); + all->info.var.red.length = all->info.var.green.length = all->info.var.blue.length = all->info.var.bits_per_pixel; all->info.var.red.offset = all->info.var.green.offset = all->info.var.blue.offset = 0; - all->par.regs = sbus_ioremap(resp, BWTWO_REGISTER_OFFSET, - sizeof(struct bw2_regs), "bw2 regs"); + all->par.regs = of_ioremap(&op->resource[0], BWTWO_REGISTER_OFFSET, + sizeof(struct bw2_regs), "bw2 regs"); - if (sdev && !prom_getbool(sdev->prom_node, "width")) + if (!of_find_property(dp, "width", NULL)) bw2_do_default_mode(&all->par, &all->info, &linebytes); all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); all->info.flags = FBINFO_DEFAULT; all->info.fbops = &bw2_ops; -#if defined(CONFIG_SPARC32) - if (sdev) - all->info.screen_base = (char __iomem *) - prom_getintdefault(sdev->prom_node, "address", 0); -#endif - if (!all->info.screen_base) - all->info.screen_base = - sbus_ioremap(resp, 0, all->par.fbsize, "bw2 ram"); + + all->info.screen_base = + sbus_ioremap(&op->resource[0], 0, all->par.fbsize, "bw2 ram"); all->info.par = &all->par; bw2_blank(0, &all->info); bw2_init_fix(&all->info, linebytes); - if (register_framebuffer(&all->info) < 0) { - printk(KERN_ERR "bw2: Could not register framebuffer.\n"); + err= register_framebuffer(&all->info); + if (err < 0) { + of_iounmap(all->par.regs, sizeof(struct bw2_regs)); + of_iounmap(all->info.screen_base, all->par.fbsize); kfree(all); - return; + return err; } - list_add(&all->list, &bw2_list); + dev_set_drvdata(&op->dev, all); + + printk("%s: bwtwo at %lx:%lx\n", + dp->full_name, + all->par.which_io, all->par.physbase); - printk("bw2: bwtwo at %lx:%lx\n", - (long) (sdev ? sdev->reg_addrs[0].which_io : 0), - (long) all->par.physbase); + return 0; } -int __init bw2_init(void) +static int __devinit bw2_probe(struct of_device *dev, const struct of_device_id *match) { - struct sbus_bus *sbus; - struct sbus_dev *sdev; + struct of_device *op = to_of_device(&dev->dev); - if (fb_get_options("bw2fb", NULL)) - return -ENODEV; + return bw2_init_one(op); +} -#ifdef CONFIG_SUN4 - bw2_init_one(NULL); -#endif - for_all_sbusdev(sdev, sbus) { - if (!strcmp(sdev->prom_name, "bwtwo")) - bw2_init_one(sdev); - } +static int __devexit bw2_remove(struct of_device *dev) +{ + struct all_info *all = dev_get_drvdata(&dev->dev); + + unregister_framebuffer(&all->info); + + of_iounmap(all->par.regs, sizeof(struct bw2_regs)); + of_iounmap(all->info.screen_base, all->par.fbsize); + + kfree(all); + + dev_set_drvdata(&dev->dev, NULL); return 0; } -void __exit bw2_exit(void) -{ - struct list_head *pos, *tmp; +static struct of_device_id bw2_match[] = { + { + .name = "bwtwo", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, bw2_match); - list_for_each_safe(pos, tmp, &bw2_list) { - struct all_info *all = list_entry(pos, typeof(*all), list); +static struct of_platform_driver bw2_driver = { + .name = "bw2", + .match_table = bw2_match, + .probe = bw2_probe, + .remove = __devexit_p(bw2_remove), +}; - unregister_framebuffer(&all->info); - kfree(all); - } +static int __init bw2_init(void) +{ + if (fb_get_options("bw2fb", NULL)) + return -ENODEV; + + return of_register_driver(&bw2_driver, &of_bus_type); } -int __init -bw2_setup(char *arg) +static void __exit bw2_exit(void) { - /* No cmdline options yet... */ - return 0; + return of_unregister_driver(&bw2_driver); } -module_init(bw2_init); -#ifdef MODULE +module_init(bw2_init); module_exit(bw2_exit); -#endif MODULE_DESCRIPTION("framebuffer driver for BWTWO chipsets"); -MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); +MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); +MODULE_VERSION("2.0"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c index 74415325b016..6faea4034e3d 100644 --- a/drivers/video/cfbcopyarea.c +++ b/drivers/video/cfbcopyarea.c @@ -24,7 +24,6 @@ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/string.h> diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c index e5ff62e9cfb8..f00b50aab606 100644 --- a/drivers/video/cfbfillrect.c +++ b/drivers/video/cfbfillrect.c @@ -17,7 +17,6 @@ * the native cpu endians. I also need to deal with MSB position in the word. * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/string.h> #include <linux/fb.h> diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c index 8ba6152db2fd..51d35386a945 100644 --- a/drivers/video/cfbimgblt.c +++ b/drivers/video/cfbimgblt.c @@ -29,7 +29,6 @@ * Also need to add code to deal with cards endians that are different than * the native cpu endians. I also need to deal with MSB position in the word. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/string.h> #include <linux/fb.h> @@ -230,6 +229,7 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * tab = cfb_tab16; break; case 32: + default: tab = cfb_tab32; break; } diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c index 63b6c79c8a0a..7f926c619b61 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/cg14.c @@ -1,6 +1,6 @@ /* cg14.c: CGFOURTEEN frame buffer driver * - * Copyright (C) 2003 David S. Miller (davem@redhat.com) + * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) * @@ -18,8 +18,8 @@ #include <linux/mm.h> #include <asm/io.h> -#include <asm/sbus.h> -#include <asm/oplib.h> +#include <asm/prom.h> +#include <asm/of_device.h> #include <asm/fbio.h> #include "sbuslib.h" @@ -99,73 +99,73 @@ static struct fb_ops cg14_ops = { #define CG14_MCR_PIXMODE_32 3 struct cg14_regs{ - volatile u8 mcr; /* Master Control Reg */ - volatile u8 ppr; /* Packed Pixel Reg */ - volatile u8 tms[2]; /* Test Mode Status Regs */ - volatile u8 msr; /* Master Status Reg */ - volatile u8 fsr; /* Fault Status Reg */ - volatile u8 rev; /* Revision & Impl */ - volatile u8 ccr; /* Clock Control Reg */ - volatile u32 tmr; /* Test Mode Read Back */ - volatile u8 mod; /* Monitor Operation Data Reg */ - volatile u8 acr; /* Aux Control */ + u8 mcr; /* Master Control Reg */ + u8 ppr; /* Packed Pixel Reg */ + u8 tms[2]; /* Test Mode Status Regs */ + u8 msr; /* Master Status Reg */ + u8 fsr; /* Fault Status Reg */ + u8 rev; /* Revision & Impl */ + u8 ccr; /* Clock Control Reg */ + u32 tmr; /* Test Mode Read Back */ + u8 mod; /* Monitor Operation Data Reg */ + u8 acr; /* Aux Control */ u8 xxx0[6]; - volatile u16 hct; /* Hor Counter */ - volatile u16 vct; /* Vert Counter */ - volatile u16 hbs; /* Hor Blank Start */ - volatile u16 hbc; /* Hor Blank Clear */ - volatile u16 hss; /* Hor Sync Start */ - volatile u16 hsc; /* Hor Sync Clear */ - volatile u16 csc; /* Composite Sync Clear */ - volatile u16 vbs; /* Vert Blank Start */ - volatile u16 vbc; /* Vert Blank Clear */ - volatile u16 vss; /* Vert Sync Start */ - volatile u16 vsc; /* Vert Sync Clear */ - volatile u16 xcs; - volatile u16 xcc; - volatile u16 fsa; /* Fault Status Address */ - volatile u16 adr; /* Address Registers */ + u16 hct; /* Hor Counter */ + u16 vct; /* Vert Counter */ + u16 hbs; /* Hor Blank Start */ + u16 hbc; /* Hor Blank Clear */ + u16 hss; /* Hor Sync Start */ + u16 hsc; /* Hor Sync Clear */ + u16 csc; /* Composite Sync Clear */ + u16 vbs; /* Vert Blank Start */ + u16 vbc; /* Vert Blank Clear */ + u16 vss; /* Vert Sync Start */ + u16 vsc; /* Vert Sync Clear */ + u16 xcs; + u16 xcc; + u16 fsa; /* Fault Status Address */ + u16 adr; /* Address Registers */ u8 xxx1[0xce]; - volatile u8 pcg[0x100]; /* Pixel Clock Generator */ - volatile u32 vbr; /* Frame Base Row */ - volatile u32 vmcr; /* VBC Master Control */ - volatile u32 vcr; /* VBC refresh */ - volatile u32 vca; /* VBC Config */ + u8 pcg[0x100]; /* Pixel Clock Generator */ + u32 vbr; /* Frame Base Row */ + u32 vmcr; /* VBC Master Control */ + u32 vcr; /* VBC refresh */ + u32 vca; /* VBC Config */ }; #define CG14_CCR_ENABLE 0x04 #define CG14_CCR_SELECT 0x02 /* HW/Full screen */ struct cg14_cursor { - volatile u32 cpl0[32]; /* Enable plane 0 */ - volatile u32 cpl1[32]; /* Color selection plane */ - volatile u8 ccr; /* Cursor Control Reg */ + u32 cpl0[32]; /* Enable plane 0 */ + u32 cpl1[32]; /* Color selection plane */ + u8 ccr; /* Cursor Control Reg */ u8 xxx0[3]; - volatile u16 cursx; /* Cursor x,y position */ - volatile u16 cursy; /* Cursor x,y position */ - volatile u32 color0; - volatile u32 color1; + u16 cursx; /* Cursor x,y position */ + u16 cursy; /* Cursor x,y position */ + u32 color0; + u32 color1; u32 xxx1[0x1bc]; - volatile u32 cpl0i[32]; /* Enable plane 0 autoinc */ - volatile u32 cpl1i[32]; /* Color selection autoinc */ + u32 cpl0i[32]; /* Enable plane 0 autoinc */ + u32 cpl1i[32]; /* Color selection autoinc */ }; struct cg14_dac { - volatile u8 addr; /* Address Register */ + u8 addr; /* Address Register */ u8 xxx0[255]; - volatile u8 glut; /* Gamma table */ + u8 glut; /* Gamma table */ u8 xxx1[255]; - volatile u8 select; /* Register Select */ + u8 select; /* Register Select */ u8 xxx2[255]; - volatile u8 mode; /* Mode Register */ + u8 mode; /* Mode Register */ }; struct cg14_xlut{ - volatile u8 x_xlut [256]; - volatile u8 x_xlutd [256]; + u8 x_xlut [256]; + u8 x_xlutd [256]; u8 xxx0[0x600]; - volatile u8 x_xlut_inc [256]; - volatile u8 x_xlutd_inc [256]; + u8 x_xlut_inc [256]; + u8 x_xlutd_inc [256]; }; /* Color look up table (clut) */ @@ -204,7 +204,6 @@ struct cg14_par { int mode; int ramsize; - struct sbus_dev *sdev; }; static void __cg14_reset(struct cg14_par *par) @@ -355,14 +354,9 @@ static int cg14_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) * Initialisation */ -static void cg14_init_fix(struct fb_info *info, int linebytes) +static void cg14_init_fix(struct fb_info *info, int linebytes, struct device_node *dp) { - struct cg14_par *par = (struct cg14_par *)info->par; - const char *name; - - name = "cgfourteen"; - if (par->sdev) - name = par->sdev->prom_name; + const char *name = dp->name; strlcpy(info->fix.id, name, sizeof(info->fix.id)); @@ -456,98 +450,81 @@ static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] __initdata = { struct all_info { struct fb_info info; struct cg14_par par; - struct list_head list; }; -static LIST_HEAD(cg14_list); -static void cg14_init_one(struct sbus_dev *sdev, int node, int parent_node) +static void cg14_unmap_regs(struct all_info *all) { - struct all_info *all; - unsigned long phys, rphys; - u32 bases[6]; - int is_8mb, linebytes, i; - - if (!sdev) { - if (prom_getproperty(node, "address", - (char *) &bases[0], sizeof(bases)) <= 0 - || !bases[0]) { - printk(KERN_ERR "cg14: Device is not mapped.\n"); - return; - } - if (__get_iospace(bases[0]) != __get_iospace(bases[1])) { - printk(KERN_ERR "cg14: I/O spaces don't match.\n"); - return; - } - } + if (all->par.regs) + of_iounmap(all->par.regs, sizeof(struct cg14_regs)); + if (all->par.clut) + of_iounmap(all->par.clut, sizeof(struct cg14_clut)); + if (all->par.cursor) + of_iounmap(all->par.cursor, sizeof(struct cg14_cursor)); + if (all->info.screen_base) + of_iounmap(all->info.screen_base, all->par.fbsize); +} - all = kmalloc(sizeof(*all), GFP_KERNEL); - if (!all) { - printk(KERN_ERR "cg14: Cannot allocate memory.\n"); - return; - } - memset(all, 0, sizeof(*all)); +static int __devinit cg14_init_one(struct of_device *op) +{ + struct device_node *dp = op->node; + struct all_info *all; + int is_8mb, linebytes, i, err; - INIT_LIST_HEAD(&all->list); + all = kzalloc(sizeof(*all), GFP_KERNEL); + if (!all) + return -ENOMEM; spin_lock_init(&all->par.lock); - sbusfb_fill_var(&all->info.var, node, 8); + sbusfb_fill_var(&all->info.var, dp->node, 8); all->info.var.red.length = 8; all->info.var.green.length = 8; all->info.var.blue.length = 8; - linebytes = prom_getintdefault(node, "linebytes", - all->info.var.xres); + linebytes = of_getintprop_default(dp, "linebytes", + all->info.var.xres); all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); - all->par.sdev = sdev; - if (sdev) { - rphys = sdev->reg_addrs[0].phys_addr; - all->par.physbase = phys = sdev->reg_addrs[1].phys_addr; - all->par.iospace = sdev->reg_addrs[0].which_io; - - all->par.regs = sbus_ioremap(&sdev->resource[0], 0, - sizeof(struct cg14_regs), - "cg14 regs"); - all->par.clut = sbus_ioremap(&sdev->resource[0], CG14_CLUT1, - sizeof(struct cg14_clut), - "cg14 clut"); - all->par.cursor = sbus_ioremap(&sdev->resource[0], CG14_CURSORREGS, - sizeof(struct cg14_cursor), - "cg14 cursor"); - all->info.screen_base = sbus_ioremap(&sdev->resource[1], 0, - all->par.fbsize, "cg14 ram"); + if (!strcmp(dp->parent->name, "sbus") || + !strcmp(dp->parent->name, "sbi")) { + all->par.physbase = op->resource[0].start; + all->par.iospace = op->resource[0].flags & IORESOURCE_BITS; } else { - rphys = __get_phys(bases[0]); - all->par.physbase = phys = __get_phys(bases[1]); - all->par.iospace = __get_iospace(bases[0]); - all->par.regs = (struct cg14_regs __iomem *)(unsigned long)bases[0]; - all->par.clut = (struct cg14_clut __iomem *)((unsigned long)bases[0] + - CG14_CLUT1); - all->par.cursor = - (struct cg14_cursor __iomem *)((unsigned long)bases[0] + - CG14_CURSORREGS); - - all->info.screen_base = (char __iomem *)(unsigned long)bases[1]; + all->par.physbase = op->resource[1].start; + all->par.iospace = op->resource[0].flags & IORESOURCE_BITS; } - prom_getproperty(node, "reg", (char *) &bases[0], sizeof(bases)); - is_8mb = (bases[5] == 0x800000); + all->par.regs = of_ioremap(&op->resource[0], 0, + sizeof(struct cg14_regs), "cg14 regs"); + all->par.clut = of_ioremap(&op->resource[0], CG14_CLUT1, + sizeof(struct cg14_clut), "cg14 clut"); + all->par.cursor = of_ioremap(&op->resource[0], CG14_CURSORREGS, + sizeof(struct cg14_cursor), "cg14 cursor"); - if (sizeof(all->par.mmap_map) != sizeof(__cg14_mmap_map)) { - extern void __cg14_mmap_sized_wrongly(void); + all->info.screen_base = of_ioremap(&op->resource[1], 0, + all->par.fbsize, "cg14 ram"); - __cg14_mmap_sized_wrongly(); - } + if (!all->par.regs || !all->par.clut || !all->par.cursor || + !all->info.screen_base) + cg14_unmap_regs(all); + + is_8mb = (((op->resource[1].end - op->resource[1].start) + 1) == + (8 * 1024 * 1024)); + + BUILD_BUG_ON(sizeof(all->par.mmap_map) != sizeof(__cg14_mmap_map)); - memcpy(&all->par.mmap_map, &__cg14_mmap_map, sizeof(all->par.mmap_map)); + memcpy(&all->par.mmap_map, &__cg14_mmap_map, + sizeof(all->par.mmap_map)); + for (i = 0; i < CG14_MMAP_ENTRIES; i++) { struct sbus_mmap_map *map = &all->par.mmap_map[i]; if (!map->size) break; if (map->poff & 0x80000000) - map->poff = (map->poff & 0x7fffffff) + rphys - phys; + map->poff = (map->poff & 0x7fffffff) + + (op->resource[0].start - + op->resource[1].start); if (is_8mb && map->size >= 0x100000 && map->size <= 0x400000) @@ -564,84 +541,87 @@ static void cg14_init_one(struct sbus_dev *sdev, int node, int parent_node) __cg14_reset(&all->par); if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { - printk(KERN_ERR "cg14: Could not allocate color map.\n"); + cg14_unmap_regs(all); kfree(all); - return; + return -ENOMEM; } fb_set_cmap(&all->info.cmap, &all->info); - cg14_init_fix(&all->info, linebytes); + cg14_init_fix(&all->info, linebytes, dp); - if (register_framebuffer(&all->info) < 0) { - printk(KERN_ERR "cg14: Could not register framebuffer.\n"); + err = register_framebuffer(&all->info); + if (err < 0) { fb_dealloc_cmap(&all->info.cmap); + cg14_unmap_regs(all); kfree(all); - return; + return err; } - list_add(&all->list, &cg14_list); + dev_set_drvdata(&op->dev, all); - printk("cg14: cgfourteen at %lx:%lx, %dMB\n", - all->par.iospace, all->par.physbase, all->par.ramsize >> 20); + printk("%s: cgfourteen at %lx:%lx, %dMB\n", + dp->full_name, + all->par.iospace, all->par.physbase, + all->par.ramsize >> 20); + return 0; } -int __init cg14_init(void) +static int __devinit cg14_probe(struct of_device *dev, const struct of_device_id *match) { - struct sbus_bus *sbus; - struct sbus_dev *sdev; + struct of_device *op = to_of_device(&dev->dev); - if (fb_get_options("cg14fb", NULL)) - return -ENODEV; + return cg14_init_one(op); +} -#ifdef CONFIG_SPARC32 - { - int root, node; - - root = prom_getchild(prom_root_node); - root = prom_searchsiblings(root, "obio"); - if (root) { - node = prom_searchsiblings(prom_getchild(root), - "cgfourteen"); - if (node) - cg14_init_one(NULL, node, root); - } - } -#endif - for_all_sbusdev(sdev, sbus) { - if (!strcmp(sdev->prom_name, "cgfourteen")) - cg14_init_one(sdev, sdev->prom_node, sbus->prom_node); - } +static int __devexit cg14_remove(struct of_device *dev) +{ + struct all_info *all = dev_get_drvdata(&dev->dev); + + unregister_framebuffer(&all->info); + fb_dealloc_cmap(&all->info.cmap); + + cg14_unmap_regs(all); + + kfree(all); + + dev_set_drvdata(&dev->dev, NULL); return 0; } -void __exit cg14_exit(void) -{ - struct list_head *pos, *tmp; +static struct of_device_id cg14_match[] = { + { + .name = "cgfourteen", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, cg14_match); - list_for_each_safe(pos, tmp, &cg14_list) { - struct all_info *all = list_entry(pos, typeof(*all), list); +static struct of_platform_driver cg14_driver = { + .name = "cg14", + .match_table = cg14_match, + .probe = cg14_probe, + .remove = __devexit_p(cg14_remove), +}; - unregister_framebuffer(&all->info); - fb_dealloc_cmap(&all->info.cmap); - kfree(all); - } +int __init cg14_init(void) +{ + if (fb_get_options("cg14fb", NULL)) + return -ENODEV; + + return of_register_driver(&cg14_driver, &of_bus_type); } -int __init -cg14_setup(char *arg) +void __exit cg14_exit(void) { - /* No cmdline options yet... */ - return 0; + of_unregister_driver(&cg14_driver); } module_init(cg14_init); - -#ifdef MODULE module_exit(cg14_exit); -#endif MODULE_DESCRIPTION("framebuffer driver for CGfourteen chipsets"); -MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); +MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); +MODULE_VERSION("2.0"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c index 3de6e1b5ab2f..9c8c753ef454 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/cg3.c @@ -1,6 +1,6 @@ /* cg3.c: CGTHREE frame buffer driver * - * Copyright (C) 2003 David S. Miller (davem@redhat.com) + * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -19,8 +19,9 @@ #include <linux/mm.h> #include <asm/io.h> -#include <asm/sbus.h> #include <asm/oplib.h> +#include <asm/prom.h> +#include <asm/of_device.h> #include <asm/fbio.h> #include "sbuslib.h" @@ -80,30 +81,30 @@ enum cg3_type { }; struct bt_regs { - volatile u32 addr; - volatile u32 color_map; - volatile u32 control; - volatile u32 cursor; + u32 addr; + u32 color_map; + u32 control; + u32 cursor; }; struct cg3_regs { struct bt_regs cmap; - volatile u8 control; - volatile u8 status; - volatile u8 cursor_start; - volatile u8 cursor_end; - volatile u8 h_blank_start; - volatile u8 h_blank_end; - volatile u8 h_sync_start; - volatile u8 h_sync_end; - volatile u8 comp_sync_end; - volatile u8 v_blank_start_high; - volatile u8 v_blank_start_low; - volatile u8 v_blank_end; - volatile u8 v_sync_start; - volatile u8 v_sync_end; - volatile u8 xfer_holdoff_start; - volatile u8 xfer_holdoff_end; + u8 control; + u8 status; + u8 cursor_start; + u8 cursor_end; + u8 h_blank_start; + u8 h_blank_end; + u8 h_sync_start; + u8 h_sync_end; + u8 comp_sync_end; + u8 v_blank_start_high; + u8 v_blank_start_low; + u8 v_blank_end; + u8 v_sync_start; + u8 v_sync_end; + u8 xfer_holdoff_start; + u8 xfer_holdoff_end; }; /* Offset of interesting structures in the OBIO space */ @@ -120,9 +121,8 @@ struct cg3_par { #define CG3_FLAG_RDI 0x00000002 unsigned long physbase; + unsigned long which_io; unsigned long fbsize; - - struct sbus_dev *sdev; }; /** @@ -235,7 +235,7 @@ static int cg3_mmap(struct fb_info *info, struct vm_area_struct *vma) return sbusfb_mmap_helper(cg3_mmap_map, par->physbase, par->fbsize, - par->sdev->reg_addrs[0].which_io, + par->which_io, vma); } @@ -252,11 +252,9 @@ static int cg3_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) */ static void -cg3_init_fix(struct fb_info *info, int linebytes) +cg3_init_fix(struct fb_info *info, int linebytes, struct device_node *dp) { - struct cg3_par *par = (struct cg3_par *)info->par; - - strlcpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id)); + strlcpy(info->fix.id, dp->name, sizeof(info->fix.id)); info->fix.type = FB_TYPE_PACKED_PIXELS; info->fix.visual = FB_VISUAL_PSEUDOCOLOR; @@ -267,16 +265,15 @@ cg3_init_fix(struct fb_info *info, int linebytes) } static void cg3_rdi_maybe_fixup_var(struct fb_var_screeninfo *var, - struct sbus_dev *sdev) + struct device_node *dp) { - char buffer[40]; + char *params; char *p; int ww, hh; - *buffer = 0; - prom_getstring(sdev->prom_node, "params", buffer, sizeof(buffer)); - if (*buffer) { - ww = simple_strtoul(buffer, &p, 10); + params = of_get_property(dp, "params", NULL); + if (params) { + ww = simple_strtoul(params, &p, 10); if (ww && *p == 'x') { hh = simple_strtoul(p + 1, &p, 10); if (hh && *p == '-') { @@ -348,11 +345,11 @@ static void cg3_do_default_mode(struct cg3_par *par) sbus_writeb(p[1], regp); } for (p = cg3_dacvals; *p; p += 2) { - volatile u8 __iomem *regp; + u8 __iomem *regp; - regp = (volatile u8 __iomem *)&par->regs->cmap.addr; + regp = (u8 __iomem *)&par->regs->cmap.addr; sbus_writeb(p[0], regp); - regp = (volatile u8 __iomem *)&par->regs->cmap.control; + regp = (u8 __iomem *)&par->regs->cmap.control; sbus_writeb(p[1], regp); } } @@ -360,129 +357,137 @@ static void cg3_do_default_mode(struct cg3_par *par) struct all_info { struct fb_info info; struct cg3_par par; - struct list_head list; }; -static LIST_HEAD(cg3_list); -static void cg3_init_one(struct sbus_dev *sdev) +static int __devinit cg3_init_one(struct of_device *op) { + struct device_node *dp = op->node; struct all_info *all; - int linebytes; - - all = kmalloc(sizeof(*all), GFP_KERNEL); - if (!all) { - printk(KERN_ERR "cg3: Cannot allocate memory.\n"); - return; - } - memset(all, 0, sizeof(*all)); + int linebytes, err; - INIT_LIST_HEAD(&all->list); + all = kzalloc(sizeof(*all), GFP_KERNEL); + if (!all) + return -ENOMEM; spin_lock_init(&all->par.lock); - all->par.sdev = sdev; - all->par.physbase = sdev->reg_addrs[0].phys_addr; + all->par.physbase = op->resource[0].start; + all->par.which_io = op->resource[0].flags & IORESOURCE_BITS; - sbusfb_fill_var(&all->info.var, sdev->prom_node, 8); + sbusfb_fill_var(&all->info.var, dp->node, 8); all->info.var.red.length = 8; all->info.var.green.length = 8; all->info.var.blue.length = 8; - if (!strcmp(sdev->prom_name, "cgRDI")) + if (!strcmp(dp->name, "cgRDI")) all->par.flags |= CG3_FLAG_RDI; if (all->par.flags & CG3_FLAG_RDI) - cg3_rdi_maybe_fixup_var(&all->info.var, sdev); + cg3_rdi_maybe_fixup_var(&all->info.var, dp); - linebytes = prom_getintdefault(sdev->prom_node, "linebytes", - all->info.var.xres); + linebytes = of_getintprop_default(dp, "linebytes", + all->info.var.xres); all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); - all->par.regs = sbus_ioremap(&sdev->resource[0], CG3_REGS_OFFSET, - sizeof(struct cg3_regs), "cg3 regs"); + all->par.regs = of_ioremap(&op->resource[0], CG3_REGS_OFFSET, + sizeof(struct cg3_regs), "cg3 regs"); all->info.flags = FBINFO_DEFAULT; all->info.fbops = &cg3_ops; -#ifdef CONFIG_SPARC32 - all->info.screen_base = (char __iomem *) - prom_getintdefault(sdev->prom_node, "address", 0); -#endif - if (!all->info.screen_base) - all->info.screen_base = - sbus_ioremap(&sdev->resource[0], CG3_RAM_OFFSET, - all->par.fbsize, "cg3 ram"); + all->info.screen_base = + of_ioremap(&op->resource[0], CG3_RAM_OFFSET, + all->par.fbsize, "cg3 ram"); all->info.par = &all->par; cg3_blank(0, &all->info); - if (!prom_getbool(sdev->prom_node, "width")) + if (!of_find_property(dp, "width", NULL)) cg3_do_default_mode(&all->par); if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { - printk(KERN_ERR "cg3: Could not allocate color map.\n"); + of_iounmap(all->par.regs, sizeof(struct cg3_regs)); + of_iounmap(all->info.screen_base, all->par.fbsize); kfree(all); - return; + return -ENOMEM; } fb_set_cmap(&all->info.cmap, &all->info); - cg3_init_fix(&all->info, linebytes); + cg3_init_fix(&all->info, linebytes, dp); - if (register_framebuffer(&all->info) < 0) { - printk(KERN_ERR "cg3: Could not register framebuffer.\n"); + err = register_framebuffer(&all->info); + if (err < 0) { fb_dealloc_cmap(&all->info.cmap); + of_iounmap(all->par.regs, sizeof(struct cg3_regs)); + of_iounmap(all->info.screen_base, all->par.fbsize); kfree(all); - return; + return err; } - list_add(&all->list, &cg3_list); + dev_set_drvdata(&op->dev, all); + + printk("%s: cg3 at %lx:%lx\n", + dp->full_name, all->par.which_io, all->par.physbase); - printk("cg3: %s at %lx:%lx\n", - sdev->prom_name, - (long) sdev->reg_addrs[0].which_io, - (long) sdev->reg_addrs[0].phys_addr); + return 0; } -int __init cg3_init(void) +static int __devinit cg3_probe(struct of_device *dev, const struct of_device_id *match) { - struct sbus_bus *sbus; - struct sbus_dev *sdev; + struct of_device *op = to_of_device(&dev->dev); - if (fb_get_options("cg3fb", NULL)) - return -ENODEV; + return cg3_init_one(op); +} - for_all_sbusdev(sdev, sbus) { - if (!strcmp(sdev->prom_name, "cgthree") || - !strcmp(sdev->prom_name, "cgRDI")) - cg3_init_one(sdev); - } +static int __devexit cg3_remove(struct of_device *dev) +{ + struct all_info *all = dev_get_drvdata(&dev->dev); + + unregister_framebuffer(&all->info); + fb_dealloc_cmap(&all->info.cmap); + + of_iounmap(all->par.regs, sizeof(struct cg3_regs)); + of_iounmap(all->info.screen_base, all->par.fbsize); + + kfree(all); + + dev_set_drvdata(&dev->dev, NULL); return 0; } -void __exit cg3_exit(void) -{ - struct list_head *pos, *tmp; +static struct of_device_id cg3_match[] = { + { + .name = "cgthree", + }, + { + .name = "cgRDI", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, cg3_match); - list_for_each_safe(pos, tmp, &cg3_list) { - struct all_info *all = list_entry(pos, typeof(*all), list); +static struct of_platform_driver cg3_driver = { + .name = "cg3", + .match_table = cg3_match, + .probe = cg3_probe, + .remove = __devexit_p(cg3_remove), +}; - unregister_framebuffer(&all->info); - fb_dealloc_cmap(&all->info.cmap); - kfree(all); - } +static int __init cg3_init(void) +{ + if (fb_get_options("cg3fb", NULL)) + return -ENODEV; + + return of_register_driver(&cg3_driver, &of_bus_type); } -int __init -cg3_setup(char *arg) +static void __exit cg3_exit(void) { - /* No cmdline options yet... */ - return 0; + of_unregister_driver(&cg3_driver); } module_init(cg3_init); - -#ifdef MODULE module_exit(cg3_exit); -#endif MODULE_DESCRIPTION("framebuffer driver for CGthree chipsets"); -MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); +MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); +MODULE_VERSION("2.0"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index 7aab91ead681..64146be2eeb0 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c @@ -1,6 +1,6 @@ /* cg6.c: CGSIX (GX, GXplus, TGX) frame buffer driver * - * Copyright (C) 2003 David S. Miller (davem@redhat.com) + * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) @@ -19,8 +19,8 @@ #include <linux/mm.h> #include <asm/io.h> -#include <asm/sbus.h> -#include <asm/oplib.h> +#include <asm/prom.h> +#include <asm/of_device.h> #include <asm/fbio.h> #include "sbuslib.h" @@ -164,89 +164,89 @@ static struct fb_ops cg6_ops = { /* The contents are unknown */ struct cg6_tec { - volatile int tec_matrix; - volatile int tec_clip; - volatile int tec_vdc; + int tec_matrix; + int tec_clip; + int tec_vdc; }; struct cg6_thc { - uint thc_pad0[512]; - volatile uint thc_hs; /* hsync timing */ - volatile uint thc_hsdvs; - volatile uint thc_hd; - volatile uint thc_vs; /* vsync timing */ - volatile uint thc_vd; - volatile uint thc_refresh; - volatile uint thc_misc; - uint thc_pad1[56]; - volatile uint thc_cursxy; /* cursor x,y position (16 bits each) */ - volatile uint thc_cursmask[32]; /* cursor mask bits */ - volatile uint thc_cursbits[32]; /* what to show where mask enabled */ + u32 thc_pad0[512]; + u32 thc_hs; /* hsync timing */ + u32 thc_hsdvs; + u32 thc_hd; + u32 thc_vs; /* vsync timing */ + u32 thc_vd; + u32 thc_refresh; + u32 thc_misc; + u32 thc_pad1[56]; + u32 thc_cursxy; /* cursor x,y position (16 bits each) */ + u32 thc_cursmask[32]; /* cursor mask bits */ + u32 thc_cursbits[32]; /* what to show where mask enabled */ }; struct cg6_fbc { - u32 xxx0[1]; - volatile u32 mode; - volatile u32 clip; - u32 xxx1[1]; - volatile u32 s; - volatile u32 draw; - volatile u32 blit; - volatile u32 font; - u32 xxx2[24]; - volatile u32 x0, y0, z0, color0; - volatile u32 x1, y1, z1, color1; - volatile u32 x2, y2, z2, color2; - volatile u32 x3, y3, z3, color3; - volatile u32 offx, offy; - u32 xxx3[2]; - volatile u32 incx, incy; - u32 xxx4[2]; - volatile u32 clipminx, clipminy; - u32 xxx5[2]; - volatile u32 clipmaxx, clipmaxy; - u32 xxx6[2]; - volatile u32 fg; - volatile u32 bg; - volatile u32 alu; - volatile u32 pm; - volatile u32 pixelm; - u32 xxx7[2]; - volatile u32 patalign; - volatile u32 pattern[8]; - u32 xxx8[432]; - volatile u32 apointx, apointy, apointz; - u32 xxx9[1]; - volatile u32 rpointx, rpointy, rpointz; - u32 xxx10[5]; - volatile u32 pointr, pointg, pointb, pointa; - volatile u32 alinex, aliney, alinez; - u32 xxx11[1]; - volatile u32 rlinex, rliney, rlinez; - u32 xxx12[5]; - volatile u32 liner, lineg, lineb, linea; - volatile u32 atrix, atriy, atriz; - u32 xxx13[1]; - volatile u32 rtrix, rtriy, rtriz; - u32 xxx14[5]; - volatile u32 trir, trig, trib, tria; - volatile u32 aquadx, aquady, aquadz; - u32 xxx15[1]; - volatile u32 rquadx, rquady, rquadz; - u32 xxx16[5]; - volatile u32 quadr, quadg, quadb, quada; - volatile u32 arectx, arecty, arectz; - u32 xxx17[1]; - volatile u32 rrectx, rrecty, rrectz; - u32 xxx18[5]; - volatile u32 rectr, rectg, rectb, recta; + u32 xxx0[1]; + u32 mode; + u32 clip; + u32 xxx1[1]; + u32 s; + u32 draw; + u32 blit; + u32 font; + u32 xxx2[24]; + u32 x0, y0, z0, color0; + u32 x1, y1, z1, color1; + u32 x2, y2, z2, color2; + u32 x3, y3, z3, color3; + u32 offx, offy; + u32 xxx3[2]; + u32 incx, incy; + u32 xxx4[2]; + u32 clipminx, clipminy; + u32 xxx5[2]; + u32 clipmaxx, clipmaxy; + u32 xxx6[2]; + u32 fg; + u32 bg; + u32 alu; + u32 pm; + u32 pixelm; + u32 xxx7[2]; + u32 patalign; + u32 pattern[8]; + u32 xxx8[432]; + u32 apointx, apointy, apointz; + u32 xxx9[1]; + u32 rpointx, rpointy, rpointz; + u32 xxx10[5]; + u32 pointr, pointg, pointb, pointa; + u32 alinex, aliney, alinez; + u32 xxx11[1]; + u32 rlinex, rliney, rlinez; + u32 xxx12[5]; + u32 liner, lineg, lineb, linea; + u32 atrix, atriy, atriz; + u32 xxx13[1]; + u32 rtrix, rtriy, rtriz; + u32 xxx14[5]; + u32 trir, trig, trib, tria; + u32 aquadx, aquady, aquadz; + u32 xxx15[1]; + u32 rquadx, rquady, rquadz; + u32 xxx16[5]; + u32 quadr, quadg, quadb, quada; + u32 arectx, arecty, arectz; + u32 xxx17[1]; + u32 rrectx, rrecty, rrectz; + u32 xxx18[5]; + u32 rectr, rectg, rectb, recta; }; struct bt_regs { - volatile u32 addr; - volatile u32 color_map; - volatile u32 control; - volatile u32 cursor; + u32 addr; + u32 color_map; + u32 control; + u32 cursor; }; struct cg6_par { @@ -255,15 +255,14 @@ struct cg6_par { struct cg6_fbc __iomem *fbc; struct cg6_thc __iomem *thc; struct cg6_tec __iomem *tec; - volatile u32 __iomem *fhc; + u32 __iomem *fhc; u32 flags; #define CG6_FLAG_BLANKED 0x00000001 unsigned long physbase; + unsigned long which_io; unsigned long fbsize; - - struct sbus_dev *sdev; }; static int cg6_sync(struct fb_info *info) @@ -529,8 +528,7 @@ static int cg6_mmap(struct fb_info *info, struct vm_area_struct *vma) return sbusfb_mmap_helper(cg6_mmap_map, par->physbase, par->fbsize, - par->sdev->reg_addrs[0].which_io, - vma); + par->which_io, vma); } static int cg6_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) @@ -658,62 +656,75 @@ static void cg6_chip_init(struct fb_info *info) struct all_info { struct fb_info info; struct cg6_par par; - struct list_head list; }; -static LIST_HEAD(cg6_list); -static void cg6_init_one(struct sbus_dev *sdev) +static void cg6_unmap_regs(struct all_info *all) { - struct all_info *all; - int linebytes; + if (all->par.fbc) + of_iounmap(all->par.fbc, 4096); + if (all->par.tec) + of_iounmap(all->par.tec, sizeof(struct cg6_tec)); + if (all->par.thc) + of_iounmap(all->par.thc, sizeof(struct cg6_thc)); + if (all->par.bt) + of_iounmap(all->par.bt, sizeof(struct bt_regs)); + if (all->par.fhc) + of_iounmap(all->par.fhc, sizeof(u32)); + + if (all->info.screen_base) + of_iounmap(all->info.screen_base, all->par.fbsize); +} - all = kmalloc(sizeof(*all), GFP_KERNEL); - if (!all) { - printk(KERN_ERR "cg6: Cannot allocate memory.\n"); - return; - } - memset(all, 0, sizeof(*all)); +static int __devinit cg6_init_one(struct of_device *op) +{ + struct device_node *dp = op->node; + struct all_info *all; + int linebytes, err; - INIT_LIST_HEAD(&all->list); + all = kzalloc(sizeof(*all), GFP_KERNEL); + if (!all) + return -ENOMEM; spin_lock_init(&all->par.lock); - all->par.sdev = sdev; - all->par.physbase = sdev->reg_addrs[0].phys_addr; + all->par.physbase = op->resource[0].start; + all->par.which_io = op->resource[0].flags & IORESOURCE_BITS; - sbusfb_fill_var(&all->info.var, sdev->prom_node, 8); + sbusfb_fill_var(&all->info.var, dp->node, 8); all->info.var.red.length = 8; all->info.var.green.length = 8; all->info.var.blue.length = 8; - linebytes = prom_getintdefault(sdev->prom_node, "linebytes", - all->info.var.xres); + linebytes = of_getintprop_default(dp, "linebytes", + all->info.var.xres); all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); - if (prom_getbool(sdev->prom_node, "dblbuf")) + if (of_find_property(dp, "dblbuf", NULL)) all->par.fbsize *= 4; - all->par.fbc = sbus_ioremap(&sdev->resource[0], CG6_FBC_OFFSET, - 4096, "cgsix fbc"); - all->par.tec = sbus_ioremap(&sdev->resource[0], CG6_TEC_OFFSET, - sizeof(struct cg6_tec), "cgsix tec"); - all->par.thc = sbus_ioremap(&sdev->resource[0], CG6_THC_OFFSET, - sizeof(struct cg6_thc), "cgsix thc"); - all->par.bt = sbus_ioremap(&sdev->resource[0], CG6_BROOKTREE_OFFSET, - sizeof(struct bt_regs), "cgsix dac"); - all->par.fhc = sbus_ioremap(&sdev->resource[0], CG6_FHC_OFFSET, - sizeof(u32), "cgsix fhc"); + all->par.fbc = of_ioremap(&op->resource[0], CG6_FBC_OFFSET, + 4096, "cgsix fbc"); + all->par.tec = of_ioremap(&op->resource[0], CG6_TEC_OFFSET, + sizeof(struct cg6_tec), "cgsix tec"); + all->par.thc = of_ioremap(&op->resource[0], CG6_THC_OFFSET, + sizeof(struct cg6_thc), "cgsix thc"); + all->par.bt = of_ioremap(&op->resource[0], CG6_BROOKTREE_OFFSET, + sizeof(struct bt_regs), "cgsix dac"); + all->par.fhc = of_ioremap(&op->resource[0], CG6_FHC_OFFSET, + sizeof(u32), "cgsix fhc"); all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; all->info.fbops = &cg6_ops; -#ifdef CONFIG_SPARC32 - all->info.screen_base = (char __iomem *) - prom_getintdefault(sdev->prom_node, "address", 0); -#endif - if (!all->info.screen_base) - all->info.screen_base = - sbus_ioremap(&sdev->resource[0], CG6_RAM_OFFSET, - all->par.fbsize, "cgsix ram"); + + all->info.screen_base = of_ioremap(&op->resource[0], CG6_RAM_OFFSET, + all->par.fbsize, "cgsix ram"); + if (!all->par.fbc || !all->par.tec || !all->par.thc || + !all->par.bt || !all->par.fhc || !all->info.screen_base) { + cg6_unmap_regs(all); + kfree(all); + return -ENOMEM; + } + all->info.par = &all->par; all->info.var.accel_flags = FB_ACCELF_TEXT; @@ -723,72 +734,90 @@ static void cg6_init_one(struct sbus_dev *sdev) cg6_blank(0, &all->info); if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { - printk(KERN_ERR "cg6: Could not allocate color map.\n"); + cg6_unmap_regs(all); kfree(all); - return; + return -ENOMEM; } fb_set_cmap(&all->info.cmap, &all->info); cg6_init_fix(&all->info, linebytes); - if (register_framebuffer(&all->info) < 0) { - printk(KERN_ERR "cg6: Could not register framebuffer.\n"); + err = register_framebuffer(&all->info); + if (err < 0) { + cg6_unmap_regs(all); fb_dealloc_cmap(&all->info.cmap); kfree(all); - return; + return err; } - list_add(&all->list, &cg6_list); + dev_set_drvdata(&op->dev, all); - printk("cg6: CGsix [%s] at %lx:%lx\n", + printk("%s: CGsix [%s] at %lx:%lx\n", + dp->full_name, all->info.fix.id, - (long) sdev->reg_addrs[0].which_io, - (long) sdev->reg_addrs[0].phys_addr); + all->par.which_io, all->par.physbase); + + return 0; } -int __init cg6_init(void) +static int __devinit cg6_probe(struct of_device *dev, const struct of_device_id *match) { - struct sbus_bus *sbus; - struct sbus_dev *sdev; + struct of_device *op = to_of_device(&dev->dev); - if (fb_get_options("cg6fb", NULL)) - return -ENODEV; + return cg6_init_one(op); +} - for_all_sbusdev(sdev, sbus) { - if (!strcmp(sdev->prom_name, "cgsix") || - !strcmp(sdev->prom_name, "cgthree+")) - cg6_init_one(sdev); - } +static int __devexit cg6_remove(struct of_device *dev) +{ + struct all_info *all = dev_get_drvdata(&dev->dev); + + unregister_framebuffer(&all->info); + fb_dealloc_cmap(&all->info.cmap); + + cg6_unmap_regs(all); + + kfree(all); + + dev_set_drvdata(&dev->dev, NULL); return 0; } -void __exit cg6_exit(void) -{ - struct list_head *pos, *tmp; +static struct of_device_id cg6_match[] = { + { + .name = "cgsix", + }, + { + .name = "cgthree+", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, cg6_match); - list_for_each_safe(pos, tmp, &cg6_list) { - struct all_info *all = list_entry(pos, typeof(*all), list); +static struct of_platform_driver cg6_driver = { + .name = "cg6", + .match_table = cg6_match, + .probe = cg6_probe, + .remove = __devexit_p(cg6_remove), +}; - unregister_framebuffer(&all->info); - fb_dealloc_cmap(&all->info.cmap); - kfree(all); - } +static int __init cg6_init(void) +{ + if (fb_get_options("cg6fb", NULL)) + return -ENODEV; + + return of_register_driver(&cg6_driver, &of_bus_type); } -int __init -cg6_setup(char *arg) +static void __exit cg6_exit(void) { - /* No cmdline options yet... */ - return 0; + of_unregister_driver(&cg6_driver); } module_init(cg6_init); - -#ifdef MODULE module_exit(cg6_exit); -#endif MODULE_DESCRIPTION("framebuffer driver for CGsix chipsets"); -MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); +MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); +MODULE_VERSION("2.0"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c index d76bbfac92cc..0e465c80ef24 100644 --- a/drivers/video/chipsfb.c +++ b/drivers/video/chipsfb.c @@ -14,7 +14,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index 1103010af54a..7355da09c721 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c @@ -36,7 +36,6 @@ #define CIRRUSFB_VERSION "2.0-pre2" -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -2227,7 +2226,6 @@ static void cirrusfb_pci_unmap (struct cirrusfb_info *cinfo) release_region(0x3C0, 32); pci_release_regions(pdev); framebuffer_release(cinfo->info); - pci_disable_device(pdev); } #endif /* CONFIG_PCI */ @@ -2458,7 +2456,6 @@ err_release_regions: err_release_fb: framebuffer_release(info); err_disable: - pci_disable_device(pdev); err_out: return ret; } diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c index eea422eb1ab5..308850df16fe 100644 --- a/drivers/video/console/bitblit.c +++ b/drivers/video/console/bitblit.c @@ -10,7 +10,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/string.h> #include <linux/fb.h> diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index 1ecda91e5a9c..878707a04398 100644 --- a/drivers/video/console/dummycon.c +++ b/drivers/video/console/dummycon.c @@ -22,7 +22,6 @@ #define DUMMY_ROWS ORIG_VIDEO_LINES #elif defined(__hppa__) /* set by Kconfig. Use 80x25 for 640x480 and 160x64 for 1280x1024 */ -#include <linux/config.h> #define DUMMY_COLUMNS CONFIG_DUMMY_CONSOLE_COLUMNS #define DUMMY_ROWS CONFIG_DUMMY_CONSOLE_ROWS #else diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 47ba1a79adcd..94e9f7069bef 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -58,7 +58,6 @@ #undef FBCONDEBUG -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/sched.h> @@ -125,6 +124,8 @@ static int softback_lines; static int first_fb_vc; static int last_fb_vc = MAX_NR_CONSOLES - 1; static int fbcon_is_default = 1; +static int fbcon_has_exited; + /* font data */ static char fontname[40]; @@ -140,7 +141,6 @@ static const struct consw fb_con; #define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row) -static void fbcon_free_font(struct display *); static int fbcon_set_origin(struct vc_data *); #define CURSOR_DRAW_DELAY (1) @@ -194,6 +194,9 @@ static void fbcon_redraw_move(struct vc_data *vc, struct display *p, int line, int count, int dy); static void fbcon_modechanged(struct fb_info *info); static void fbcon_set_all_vcs(struct fb_info *info); +static void fbcon_start(void); +static void fbcon_exit(void); +static struct class_device *fbcon_class_device; #ifdef CONFIG_MAC /* @@ -252,7 +255,7 @@ static void fbcon_rotate_all(struct fb_info *info, u32 rotate) if (!ops || ops->currcon < 0 || rotate > 3) return; - for (i = 0; i < MAX_NR_CONSOLES; i++) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { vc = vc_cons[i].d; if (!vc || vc->vc_mode != KD_TEXT || registered_fb[con2fb_map[i]] != info) @@ -389,15 +392,18 @@ static void fb_flashcursor(void *private) int c; int mode; - if (ops->currcon != -1) + acquire_console_sem(); + if (ops && ops->currcon != -1) vc = vc_cons[ops->currcon].d; if (!vc || !CON_IS_VISIBLE(vc) || fbcon_is_inactive(vc, info) || registered_fb[con2fb_map[vc->vc_num]] != info || - vc_cons[ops->currcon].d->vc_deccm != 1) + vc_cons[ops->currcon].d->vc_deccm != 1) { + release_console_sem(); return; - acquire_console_sem(); + } + p = &fb_display[vc->vc_num]; c = scr_readw((u16 *) vc->vc_pos); mode = (!ops->cursor_flash || ops->cursor_state.enable) ? @@ -528,7 +534,7 @@ static int search_fb_in_map(int idx) { int i, retval = 0; - for (i = 0; i < MAX_NR_CONSOLES; i++) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { if (con2fb_map[i] == idx) retval = 1; } @@ -539,7 +545,7 @@ static int search_for_mapped_con(void) { int i, retval = 0; - for (i = 0; i < MAX_NR_CONSOLES; i++) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { if (con2fb_map[i] != -1) retval = 1; } @@ -561,6 +567,7 @@ static int fbcon_takeover(int show_logo) err = take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default); + if (err) { for (i = first_fb_vc; i <= last_fb_vc; i++) { con2fb_map[i] = -1; @@ -795,8 +802,8 @@ static int set_con2fb_map(int unit, int newidx, int user) if (oldidx == newidx) return 0; - if (!info) - err = -EINVAL; + if (!info || fbcon_has_exited) + return -EINVAL; if (!err && !search_for_mapped_con()) { info_idx = newidx; @@ -832,6 +839,9 @@ static int set_con2fb_map(int unit, int newidx, int user) con2fb_init_display(vc, info, unit, show_logo); } + if (!search_fb_in_map(info_idx)) + info_idx = newidx; + release_console_sem(); return err; } @@ -1034,6 +1044,7 @@ static const char *fbcon_startup(void) #endif /* CONFIG_MAC */ fbcon_add_cursor_timer(info); + fbcon_has_exited = 0; return display_desc; } @@ -1061,17 +1072,36 @@ static void fbcon_init(struct vc_data *vc, int init) /* If we are not the first console on this fb, copy the font from that console */ - t = &fb_display[svc->vc_num]; - if (!vc->vc_font.data) { - vc->vc_font.data = (void *)(p->fontdata = t->fontdata); - vc->vc_font.width = (*default_mode)->vc_font.width; - vc->vc_font.height = (*default_mode)->vc_font.height; - p->userfont = t->userfont; - if (p->userfont) - REFCOUNT(p->fontdata)++; + t = &fb_display[fg_console]; + if (!p->fontdata) { + if (t->fontdata) { + struct vc_data *fvc = vc_cons[fg_console].d; + + vc->vc_font.data = (void *)(p->fontdata = + fvc->vc_font.data); + vc->vc_font.width = fvc->vc_font.width; + vc->vc_font.height = fvc->vc_font.height; + p->userfont = t->userfont; + + if (p->userfont) + REFCOUNT(p->fontdata)++; + } else { + const struct font_desc *font = NULL; + + if (!fontname[0] || !(font = find_font(fontname))) + font = get_default_font(info->var.xres, + info->var.yres); + vc->vc_font.width = font->width; + vc->vc_font.height = font->height; + vc->vc_font.data = (void *)(p->fontdata = font->data); + vc->vc_font.charcount = 256; /* FIXME Need to + support more fonts */ + } } + if (p->userfont) charcnt = FNTCHARCNT(p->fontdata); + vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; if (charcnt == 256) { @@ -1145,13 +1175,47 @@ static void fbcon_init(struct vc_data *vc, int init) ops->p = &fb_display[fg_console]; } +static void fbcon_free_font(struct display *p) +{ + if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) + kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int)); + p->fontdata = NULL; + p->userfont = 0; +} + static void fbcon_deinit(struct vc_data *vc) { struct display *p = &fb_display[vc->vc_num]; + struct fb_info *info; + struct fbcon_ops *ops; + int idx; - if (info_idx != -1) - return; fbcon_free_font(p); + idx = con2fb_map[vc->vc_num]; + + if (idx == -1) + goto finished; + + info = registered_fb[idx]; + + if (!info) + goto finished; + + ops = info->fbcon_par; + + if (!ops) + goto finished; + + if (CON_IS_VISIBLE(vc)) + fbcon_del_cursor_timer(info); + + ops->flags &= ~FBCON_FLAGS_INIT; +finished: + + if (!con_is_bound(&fb_con)) + fbcon_exit(); + + return; } /* ====================================================================== */ @@ -2099,12 +2163,11 @@ static int fbcon_switch(struct vc_data *vc) if (info->fbops->fb_set_par) info->fbops->fb_set_par(info); - if (old_info != info) { + if (old_info != info) fbcon_del_cursor_timer(old_info); - fbcon_add_cursor_timer(info); - } } + fbcon_add_cursor_timer(info); set_blitting_type(vc, info); ops->cursor_reset = 1; @@ -2222,14 +2285,6 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) return 0; } -static void fbcon_free_font(struct display *p) -{ - if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) - kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int)); - p->fontdata = NULL; - p->userfont = 0; -} - static int fbcon_get_font(struct vc_data *vc, struct console_font *font) { u8 *fontdata = vc->vc_font.data; @@ -2443,7 +2498,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigne FNTSUM(new_data) = csum; /* Check if the same font is on some other console already */ - for (i = 0; i < MAX_NR_CONSOLES; i++) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { struct vc_data *tmp = vc_cons[i].d; if (fb_display[i].userfont && @@ -2768,7 +2823,7 @@ static void fbcon_set_all_vcs(struct fb_info *info) if (!ops || ops->currcon < 0) return; - for (i = 0; i < MAX_NR_CONSOLES; i++) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { vc = vc_cons[i].d; if (!vc || vc->vc_mode != KD_TEXT || registered_fb[con2fb_map[i]] != info) @@ -2830,22 +2885,57 @@ static int fbcon_mode_deleted(struct fb_info *info, return found; } +static int fbcon_fb_unregistered(int idx) +{ + int i; + + for (i = first_fb_vc; i <= last_fb_vc; i++) { + if (con2fb_map[i] == idx) + con2fb_map[i] = -1; + } + + if (idx == info_idx) { + info_idx = -1; + + for (i = 0; i < FB_MAX; i++) { + if (registered_fb[i] != NULL) { + info_idx = i; + break; + } + } + } + + if (info_idx != -1) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { + if (con2fb_map[i] == -1) + con2fb_map[i] = info_idx; + } + } + + if (!num_registered_fb) + unregister_con_driver(&fb_con); + + return 0; +} + static int fbcon_fb_registered(int idx) { int ret = 0, i; if (info_idx == -1) { - for (i = 0; i < MAX_NR_CONSOLES; i++) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { if (con2fb_map_boot[i] == idx) { info_idx = idx; break; } } + if (info_idx != -1) ret = fbcon_takeover(1); } else { - for (i = 0; i < MAX_NR_CONSOLES; i++) { - if (con2fb_map_boot[i] == idx) + for (i = first_fb_vc; i <= last_fb_vc; i++) { + if (con2fb_map_boot[i] == idx && + con2fb_map[i] == -1) set_con2fb_map(i, idx, 0); } } @@ -2882,7 +2972,7 @@ static void fbcon_new_modelist(struct fb_info *info) struct fb_var_screeninfo var; struct fb_videomode *mode; - for (i = 0; i < MAX_NR_CONSOLES; i++) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { if (registered_fb[con2fb_map[i]] != info) continue; if (!fb_display[i].mode) @@ -2910,6 +3000,14 @@ static int fbcon_event_notify(struct notifier_block *self, struct fb_con2fbmap *con2fb; int ret = 0; + /* + * ignore all events except driver registration and deregistration + * if fbcon is not active + */ + if (fbcon_has_exited && !(action == FB_EVENT_FB_REGISTERED || + action == FB_EVENT_FB_UNREGISTERED)) + goto done; + switch(action) { case FB_EVENT_SUSPEND: fbcon_suspended(info); @@ -2930,6 +3028,9 @@ static int fbcon_event_notify(struct notifier_block *self, case FB_EVENT_FB_REGISTERED: ret = fbcon_fb_registered(info->node); break; + case FB_EVENT_FB_UNREGISTERED: + ret = fbcon_fb_unregistered(info->node); + break; case FB_EVENT_SET_CONSOLE_MAP: con2fb = event->data; ret = set_con2fb_map(con2fb->console - 1, @@ -2945,16 +3046,9 @@ static int fbcon_event_notify(struct notifier_block *self, case FB_EVENT_NEW_MODELIST: fbcon_new_modelist(info); break; - case FB_EVENT_SET_CON_ROTATE: - fbcon_rotate(info, *(int *)event->data); - break; - case FB_EVENT_GET_CON_ROTATE: - ret = fbcon_get_rotate(info); - break; - case FB_EVENT_SET_CON_ROTATE_ALL: - fbcon_rotate_all(info, *(int *)event->data); } +done: return ret; } @@ -2992,27 +3086,181 @@ static struct notifier_block fbcon_event_notifier = { .notifier_call = fbcon_event_notify, }; -static int __init fb_console_init(void) +static ssize_t store_rotate(struct class_device *class_device, + const char *buf, size_t count) { - int i; + struct fb_info *info; + int rotate, idx; + char **last = NULL; + + if (fbcon_has_exited) + return count; acquire_console_sem(); - fb_register_client(&fbcon_event_notifier); + idx = con2fb_map[fg_console]; + + if (idx == -1 || registered_fb[idx] == NULL) + goto err; + + info = registered_fb[idx]; + rotate = simple_strtoul(buf, last, 0); + fbcon_rotate(info, rotate); +err: release_console_sem(); + return count; +} - for (i = 0; i < MAX_NR_CONSOLES; i++) - con2fb_map[i] = -1; +static ssize_t store_rotate_all(struct class_device *class_device, + const char *buf, size_t count) +{ + struct fb_info *info; + int rotate, idx; + char **last = NULL; + + if (fbcon_has_exited) + return count; + + acquire_console_sem(); + idx = con2fb_map[fg_console]; + + if (idx == -1 || registered_fb[idx] == NULL) + goto err; + info = registered_fb[idx]; + rotate = simple_strtoul(buf, last, 0); + fbcon_rotate_all(info, rotate); +err: + release_console_sem(); + return count; +} + +static ssize_t show_rotate(struct class_device *class_device, char *buf) +{ + struct fb_info *info; + int rotate = 0, idx; + + if (fbcon_has_exited) + return 0; + + acquire_console_sem(); + idx = con2fb_map[fg_console]; + + if (idx == -1 || registered_fb[idx] == NULL) + goto err; + + info = registered_fb[idx]; + rotate = fbcon_get_rotate(info); +err: + release_console_sem(); + return snprintf(buf, PAGE_SIZE, "%d\n", rotate); +} + +static struct class_device_attribute class_device_attrs[] = { + __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate), + __ATTR(rotate_all, S_IWUSR, NULL, store_rotate_all), +}; + +static int fbcon_init_class_device(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) + class_device_create_file(fbcon_class_device, + &class_device_attrs[i]); + return 0; +} + +static void fbcon_start(void) +{ if (num_registered_fb) { + int i; + + acquire_console_sem(); + for (i = 0; i < FB_MAX; i++) { if (registered_fb[i] != NULL) { info_idx = i; break; } } + + release_console_sem(); fbcon_takeover(0); } +} + +static void fbcon_exit(void) +{ + struct fb_info *info; + int i, j, mapped; + + if (fbcon_has_exited) + return; + +#ifdef CONFIG_ATARI + free_irq(IRQ_AUTO_4, fbcon_vbl_handler); +#endif +#ifdef CONFIG_MAC + if (MACH_IS_MAC && vbl_detected) + free_irq(IRQ_MAC_VBL, fbcon_vbl_handler); +#endif + + kfree((void *)softback_buf); + softback_buf = 0UL; + + for (i = 0; i < FB_MAX; i++) { + mapped = 0; + info = registered_fb[i]; + + if (info == NULL) + continue; + + for (j = first_fb_vc; j <= last_fb_vc; j++) { + if (con2fb_map[j] == i) + mapped = 1; + } + + if (mapped) { + if (info->fbops->fb_release) + info->fbops->fb_release(info, 0); + module_put(info->fbops->owner); + + if (info->fbcon_par) { + fbcon_del_cursor_timer(info); + kfree(info->fbcon_par); + info->fbcon_par = NULL; + } + if (info->queue.func == fb_flashcursor) + info->queue.func = NULL; + } + } + + fbcon_has_exited = 1; +} + +static int __init fb_console_init(void) +{ + int i; + + acquire_console_sem(); + fb_register_client(&fbcon_event_notifier); + fbcon_class_device = + class_device_create(fb_class, NULL, MKDEV(0, 0), NULL, "fbcon"); + + if (IS_ERR(fbcon_class_device)) { + printk(KERN_WARNING "Unable to create class_device " + "for fbcon; errno = %ld\n", + PTR_ERR(fbcon_class_device)); + fbcon_class_device = NULL; + } else + fbcon_init_class_device(); + + for (i = 0; i < MAX_NR_CONSOLES; i++) + con2fb_map[i] = -1; + + release_console_sem(); + fbcon_start(); return 0; } @@ -3020,12 +3268,24 @@ module_init(fb_console_init); #ifdef MODULE +static void __exit fbcon_deinit_class_device(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) + class_device_remove_file(fbcon_class_device, + &class_device_attrs[i]); +} + static void __exit fb_console_exit(void) { acquire_console_sem(); fb_unregister_client(&fbcon_event_notifier); + fbcon_deinit_class_device(); + class_device_destroy(fb_class, MKDEV(0, 0)); + fbcon_exit(); release_console_sem(); - give_up_console(&fb_con); + unregister_con_driver(&fb_con); } module_exit(fb_console_exit); diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h index c38c3d8e7a74..f244ad066d68 100644 --- a/drivers/video/console/fbcon.h +++ b/drivers/video/console/fbcon.h @@ -11,7 +11,6 @@ #ifndef _VIDEO_FBCON_H #define _VIDEO_FBCON_H -#include <linux/config.h> #include <linux/types.h> #include <linux/vt_buffer.h> #include <linux/vt_kern.h> @@ -175,6 +174,7 @@ extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info); #endif extern void fbcon_set_bitops(struct fbcon_ops *ops); extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor); +extern struct class *fb_class; #define FBCON_ATTRIBUTE_UNDERLINE 1 #define FBCON_ATTRIBUTE_REVERSE 2 diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c index 990289a69b78..4481c80b8b2a 100644 --- a/drivers/video/console/fbcon_ccw.c +++ b/drivers/video/console/fbcon_ccw.c @@ -8,7 +8,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/string.h> #include <linux/fb.h> diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c index d44c5fa515fb..7f92c06afea7 100644 --- a/drivers/video/console/fbcon_cw.c +++ b/drivers/video/console/fbcon_cw.c @@ -8,7 +8,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/string.h> #include <linux/fb.h> diff --git a/drivers/video/console/fbcon_rotate.c b/drivers/video/console/fbcon_rotate.c index 2dc091fbd5c9..00884e013f0f 100644 --- a/drivers/video/console/fbcon_rotate.c +++ b/drivers/video/console/fbcon_rotate.c @@ -8,7 +8,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/string.h> #include <linux/fb.h> diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c index f56ed068a5bc..ab91005e64dc 100644 --- a/drivers/video/console/fbcon_ud.c +++ b/drivers/video/console/fbcon_ud.c @@ -8,7 +8,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/string.h> #include <linux/fb.h> diff --git a/drivers/video/console/font_acorn_8x8.c b/drivers/video/console/font_acorn_8x8.c index 2d2e39632e2d..40f3d4eeb198 100644 --- a/drivers/video/console/font_acorn_8x8.c +++ b/drivers/video/console/font_acorn_8x8.c @@ -1,6 +1,5 @@ /* Acorn-like font definition, with PC graphics characters */ -#include <linux/config.h> #include <linux/font.h> static const unsigned char acorndata_8x8[] = { diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c index 0cc1bfda76a6..c960728b7e82 100644 --- a/drivers/video/console/fonts.c +++ b/drivers/video/console/fonts.c @@ -12,7 +12,6 @@ * for more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/string.h> diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index 7f939d066a5a..c89f90edf8ac 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c @@ -308,7 +308,7 @@ static void __init mda_initialize(void) outb_p(0x00, mda_gfx_port); } -static const char __init *mdacon_startup(void) +static const char *mdacon_startup(void) { mda_num_columns = 80; mda_num_lines = 25; diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index e99fe30e568c..03041311711b 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -51,6 +51,7 @@ static int topscan; static int xcurs_correction = 29; static int newport_xsize; static int newport_ysize; +static int newport_has_init; static int newport_set_def_font(int unit, struct console_font *op); @@ -283,6 +284,15 @@ static void newport_get_revisions(void) xcurs_correction = 21; } +static void newport_exit(void) +{ + int i; + + /* free memory used by user font */ + for (i = 0; i < MAX_NR_CONSOLES; i++) + newport_set_def_font(i, NULL); +} + /* Can't be __init, take_over_console may call it later */ static const char *newport_startup(void) { @@ -290,8 +300,10 @@ static const char *newport_startup(void) if (!sgi_gfxaddr) return NULL; - npregs = (struct newport_regs *) /* ioremap cannot fail */ - ioremap(sgi_gfxaddr, sizeof(struct newport_regs)); + + if (!npregs) + npregs = (struct newport_regs *)/* ioremap cannot fail */ + ioremap(sgi_gfxaddr, sizeof(struct newport_regs)); npregs->cset.config = NPORT_CFG_GD0; if (newport_wait(npregs)) @@ -307,11 +319,11 @@ static const char *newport_startup(void) newport_reset(); newport_get_revisions(); newport_get_screensize(); + newport_has_init = 1; return "SGI Newport"; out_unmap: - iounmap((void *)npregs); return NULL; } @@ -324,11 +336,10 @@ static void newport_init(struct vc_data *vc, int init) static void newport_deinit(struct vc_data *c) { - int i; - - /* free memory used by user font */ - for (i = 0; i < MAX_NR_CONSOLES; i++) - newport_set_def_font(i, NULL); + if (!con_is_bound(&newport_con) && newport_has_init) { + newport_exit(); + newport_has_init = 0; + } } static void newport_clear(struct vc_data *vc, int sy, int sx, int height, @@ -728,16 +739,23 @@ const struct consw newport_con = { #ifdef MODULE static int __init newport_console_init(void) { + + if (!sgi_gfxaddr) + return NULL; + + if (!npregs) + npregs = (struct newport_regs *)/* ioremap cannot fail */ + ioremap(sgi_gfxaddr, sizeof(struct newport_regs)); + return take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1); } +module_init(newport_console_init); static void __exit newport_console_exit(void) { give_up_console(&newport_con); iounmap((void *)npregs); } - -module_init(newport_console_init); module_exit(newport_console_exit); #endif diff --git a/drivers/video/console/promcon.c b/drivers/video/console/promcon.c index 04f42fcaac59..5cd5e114d1e6 100644 --- a/drivers/video/console/promcon.c +++ b/drivers/video/console/promcon.c @@ -5,7 +5,6 @@ * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -109,7 +108,7 @@ promcon_end(struct vc_data *conp, char *b) return b - p; } -const char __init *promcon_startup(void) +const char *promcon_startup(void) { const char *display_desc = "PROM"; int node; @@ -133,7 +132,7 @@ const char __init *promcon_startup(void) return display_desc; } -static void __init +static void promcon_init_unimap(struct vc_data *conp) { mm_segment_t old_fs = get_fs(); diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index fd5940f41271..45c4f227e56e 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -75,7 +75,7 @@ static inline void cursor_undrawn(void) cursor_drawn = 0; } -static const char *__init sticon_startup(void) +static const char *sticon_startup(void) { return "STI console"; } diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index 74ac2acaf72c..88e7038eab88 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -13,7 +13,6 @@ * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h> diff --git a/drivers/video/console/tileblit.c b/drivers/video/console/tileblit.c index 153352ca9461..d981fe4d86c6 100644 --- a/drivers/video/console/tileblit.c +++ b/drivers/video/console/tileblit.c @@ -8,7 +8,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/string.h> #include <linux/fb.h> diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index e64d42e2449e..05735ff4e9c5 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -33,7 +33,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/sched.h> @@ -114,6 +113,7 @@ static int vga_512_chars; static int vga_video_font_height; static int vga_scan_lines; static unsigned int vga_rolled_over = 0; +static int vga_init_done; static int __init no_scroll(char *str) { @@ -190,7 +190,7 @@ static void vgacon_scrollback_init(int pitch) } } -static void __init vgacon_scrollback_startup(void) +static void vgacon_scrollback_startup(void) { vgacon_scrollback = alloc_bootmem(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024); @@ -355,7 +355,7 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines) } #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */ -static const char __init *vgacon_startup(void) +static const char *vgacon_startup(void) { const char *display_desc = NULL; u16 saved1, saved2; @@ -389,7 +389,7 @@ static const char __init *vgacon_startup(void) vga_video_port_val = VGA_CRT_DM; if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { static struct resource ega_console_resource = - { "ega", 0x3B0, 0x3BF }; + { .name = "ega", .start = 0x3B0, .end = 0x3BF }; vga_video_type = VIDEO_TYPE_EGAM; vga_vram_size = 0x8000; display_desc = "EGA+"; @@ -397,9 +397,9 @@ static const char __init *vgacon_startup(void) &ega_console_resource); } else { static struct resource mda1_console_resource = - { "mda", 0x3B0, 0x3BB }; + { .name = "mda", .start = 0x3B0, .end = 0x3BB }; static struct resource mda2_console_resource = - { "mda", 0x3BF, 0x3BF }; + { .name = "mda", .start = 0x3BF, .end = 0x3BF }; vga_video_type = VIDEO_TYPE_MDA; vga_vram_size = 0x2000; display_desc = "*MDA"; @@ -422,14 +422,14 @@ static const char __init *vgacon_startup(void) if (!ORIG_VIDEO_ISVGA) { static struct resource ega_console_resource - = { "ega", 0x3C0, 0x3DF }; + = { .name = "ega", .start = 0x3C0, .end = 0x3DF }; vga_video_type = VIDEO_TYPE_EGAC; display_desc = "EGA"; request_resource(&ioport_resource, &ega_console_resource); } else { static struct resource vga_console_resource - = { "vga+", 0x3C0, 0x3DF }; + = { .name = "vga+", .start = 0x3C0, .end = 0x3DF }; vga_video_type = VIDEO_TYPE_VGAC; display_desc = "VGA+"; request_resource(&ioport_resource, @@ -473,7 +473,7 @@ static const char __init *vgacon_startup(void) } } else { static struct resource cga_console_resource = - { "cga", 0x3D4, 0x3D5 }; + { .name = "cga", .start = 0x3D4, .end = 0x3D5 }; vga_video_type = VIDEO_TYPE_CGA; vga_vram_size = 0x2000; display_desc = "*CGA"; @@ -523,7 +523,12 @@ static const char __init *vgacon_startup(void) vgacon_xres = ORIG_VIDEO_COLS * VGA_FONTWIDTH; vgacon_yres = vga_scan_lines; - vgacon_scrollback_startup(); + + if (!vga_init_done) { + vgacon_scrollback_startup(); + vga_init_done = 1; + } + return display_desc; } @@ -531,10 +536,20 @@ static void vgacon_init(struct vc_data *c, int init) { unsigned long p; - /* We cannot be loaded as a module, therefore init is always 1 */ + /* + * We cannot be loaded as a module, therefore init is always 1, + * but vgacon_init can be called more than once, and init will + * not be 1. + */ c->vc_can_do_color = vga_can_do_color; - c->vc_cols = vga_video_num_columns; - c->vc_rows = vga_video_num_lines; + + /* set dimensions manually if init != 0 since vc_resize() will fail */ + if (init) { + c->vc_cols = vga_video_num_columns; + c->vc_rows = vga_video_num_lines; + } else + vc_resize(c, vga_video_num_columns, vga_video_num_lines); + c->vc_scan_lines = vga_scan_lines; c->vc_font.height = vga_video_font_height; c->vc_complement_mask = 0x7700; diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c index 655301a8671c..acdd6a103dbb 100644 --- a/drivers/video/controlfb.c +++ b/drivers/video/controlfb.c @@ -31,7 +31,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c index 55a3514157ed..2e2924957d8f 100644 --- a/drivers/video/cyber2000fb.c +++ b/drivers/video/cyber2000fb.c @@ -36,7 +36,6 @@ * (which, incidentally, is about the same saving as a 2.5in hard disk * entering standby mode.) */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/video/cyber2000fb.h b/drivers/video/cyber2000fb.h index bd7e1c040781..de4fc43e51c1 100644 --- a/drivers/video/cyber2000fb.h +++ b/drivers/video/cyber2000fb.h @@ -9,7 +9,6 @@ * * Integraphics Cyber2000 frame buffer device */ -#include <linux/config.h> /* * Internal CyberPro sizes and offsets. diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c index 0ae0a97b0fed..94a66c2d2cf5 100644 --- a/drivers/video/cyblafb.c +++ b/drivers/video/cyblafb.c @@ -14,7 +14,6 @@ #define CYBLAFB_PIXMAPSIZE 8192 -#include <linux/config.h> #include <linux/module.h> #include <linux/string.h> #include <linux/fb.h> diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c index 082759447bf6..f0a621ecc288 100644 --- a/drivers/video/epson1355fb.c +++ b/drivers/video/epson1355fb.c @@ -605,11 +605,6 @@ static void clearfb16(struct fb_info *info) fb_writeb(0, dst); } -static void epson1355fb_platform_release(struct device *device) -{ - dev_err(device, "This driver is broken, please bug the authors so they will fix it.\n"); -} - static int epson1355fb_remove(struct platform_device *dev) { struct fb_info *info = platform_get_drvdata(dev); @@ -733,13 +728,7 @@ static struct platform_driver epson1355fb_driver = { }, }; -static struct platform_device epson1355fb_device = { - .name = "epson1355fb", - .id = 0, - .dev = { - .release = epson1355fb_platform_release, - } -}; +static struct platform_device *epson1355fb_device; int __init epson1355fb_init(void) { @@ -749,11 +738,21 @@ int __init epson1355fb_init(void) return -ENODEV; ret = platform_driver_register(&epson1355fb_driver); + if (!ret) { - ret = platform_device_register(&epson1355fb_device); - if (ret) + epson1355fb_device = platform_device_alloc("epson1355fb", 0); + + if (epson1355fb_device) + ret = platform_device_add(epson1355fb_device); + else + ret = -ENOMEM; + + if (ret) { + platform_device_put(epson1355fb_device); platform_driver_unregister(&epson1355fb_driver); + } } + return ret; } @@ -762,7 +761,7 @@ module_init(epson1355fb_init); #ifdef MODULE static void __exit epson1355fb_exit(void) { - platform_device_unregister(&epson1355fb_device); + platform_device_unregister(epson1355fb_device); platform_driver_unregister(&epson1355fb_driver); } diff --git a/drivers/video/fbcvt.c b/drivers/video/fbcvt.c index ac90883dc3aa..b5498999c4ec 100644 --- a/drivers/video/fbcvt.c +++ b/drivers/video/fbcvt.c @@ -376,4 +376,3 @@ int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb) return 0; } -EXPORT_SYMBOL(fb_find_mode_cvt); diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 372aa1776827..33034f81114d 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -11,7 +11,6 @@ * for more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/compat.h> @@ -32,9 +31,7 @@ #ifdef CONFIG_KMOD #include <linux/kmod.h> #endif -#include <linux/devfs_fs_kernel.h> #include <linux/err.h> -#include <linux/kernel.h> #include <linux/device.h> #include <linux/efi.h> @@ -162,7 +159,6 @@ char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size } #ifdef CONFIG_LOGO -#include <linux/linux_logo.h> static inline unsigned safe_shift(unsigned d, int n) { @@ -336,11 +332,11 @@ static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height) static void fb_rotate_logo_cw(const u8 *in, u8 *out, u32 width, u32 height) { - int i, j, w = width - 1; + int i, j, h = height - 1; for (i = 0; i < height; i++) for (j = 0; j < width; j++) - out[height * j + w - i] = *in++; + out[height * j + h - i] = *in++; } static void fb_rotate_logo_ccw(const u8 *in, u8 *out, u32 width, u32 height) @@ -358,24 +354,24 @@ static void fb_rotate_logo(struct fb_info *info, u8 *dst, u32 tmp; if (rotate == FB_ROTATE_UD) { - image->dx = info->var.xres - image->width; - image->dy = info->var.yres - image->height; fb_rotate_logo_ud(image->data, dst, image->width, image->height); + image->dx = info->var.xres - image->width; + image->dy = info->var.yres - image->height; } else if (rotate == FB_ROTATE_CW) { - tmp = image->width; - image->width = image->height; - image->height = tmp; - image->dx = info->var.xres - image->height; fb_rotate_logo_cw(image->data, dst, image->width, image->height); - } else if (rotate == FB_ROTATE_CCW) { tmp = image->width; image->width = image->height; image->height = tmp; - image->dy = info->var.yres - image->width; + image->dx = info->var.xres - image->width; + } else if (rotate == FB_ROTATE_CCW) { fb_rotate_logo_ccw(image->data, dst, image->width, image->height); + tmp = image->width; + image->width = image->height; + image->height = tmp; + image->dy = info->var.yres - image->height; } image->data = dst; @@ -435,7 +431,7 @@ int fb_prepare_logo(struct fb_info *info, int rotate) depth = info->var.green.length; } - if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) { + if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR && depth > 4) { /* assume console colormap */ depth = 4; } @@ -1278,8 +1274,8 @@ static struct file_operations fb_fops = { #endif }; -static struct class *fb_class; - +struct class *fb_class; +EXPORT_SYMBOL(fb_class); /** * register_framebuffer - registers a frame buffer device * @fb_info: frame buffer info structure @@ -1333,8 +1329,6 @@ register_framebuffer(struct fb_info *fb_info) fb_add_videomode(&mode, &fb_info->modelist); registered_fb[i] = fb_info; - devfs_mk_cdev(MKDEV(FB_MAJOR, i), - S_IFCHR | S_IRUGO | S_IWUGO, "fb/%d", i); event.info = fb_info; blocking_notifier_call_chain(&fb_notifier_list, FB_EVENT_FB_REGISTERED, &event); @@ -1355,20 +1349,24 @@ register_framebuffer(struct fb_info *fb_info) int unregister_framebuffer(struct fb_info *fb_info) { + struct fb_event event; int i; i = fb_info->node; if (!registered_fb[i]) return -EINVAL; - devfs_remove("fb/%d", i); - if (fb_info->pixmap.addr && (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) + if (fb_info->pixmap.addr && + (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) kfree(fb_info->pixmap.addr); fb_destroy_modelist(&fb_info->modelist); registered_fb[i]=NULL; num_registered_fb--; fb_cleanup_class_device(fb_info); class_device_destroy(fb_class, MKDEV(FB_MAJOR, i)); + event.info = fb_info; + blocking_notifier_call_chain(&fb_notifier_list, + FB_EVENT_FB_UNREGISTERED, &event); return 0; } @@ -1429,7 +1427,6 @@ fbmem_init(void) { create_proc_read_entry("fb", 0, NULL, fbmem_read_proc, NULL); - devfs_mk_dir("fb"); if (register_chrdev(FB_MAJOR,"fb",&fb_fops)) printk("unable to get major %d for fb devs\n", FB_MAJOR); @@ -1491,28 +1488,6 @@ int fb_new_modelist(struct fb_info *info) return err; } -/** - * fb_con_duit - user<->fbcon passthrough - * @info: struct fb_info - * @event: notification event to be passed to fbcon - * @data: private data - * - * DESCRIPTION - * This function is an fbcon-user event passing channel - * which bypasses fbdev. This is hopefully temporary - * until a user interface for fbcon is created - */ -int fb_con_duit(struct fb_info *info, int event, void *data) -{ - struct fb_event evnt; - - evnt.info = info; - evnt.data = data; - - return blocking_notifier_call_chain(&fb_notifier_list, event, &evnt); -} -EXPORT_SYMBOL(fb_con_duit); - static char *video_options[FB_MAX]; static int ofonly; @@ -1622,6 +1597,5 @@ EXPORT_SYMBOL(fb_set_suspend); EXPORT_SYMBOL(fb_register_client); EXPORT_SYMBOL(fb_unregister_client); EXPORT_SYMBOL(fb_get_options); -EXPORT_SYMBOL(fb_new_modelist); MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 53beeb4a9998..3ccfff715a51 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c @@ -29,9 +29,9 @@ #include <linux/tty.h> #include <linux/fb.h> #include <linux/module.h> +#include <linux/pci.h> #include <video/edid.h> #ifdef CONFIG_PPC_OF -#include <linux/pci.h> #include <asm/prom.h> #include <asm/pci-bridge.h> #endif @@ -605,6 +605,7 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs) block = edid + DETAILED_TIMING_DESCRIPTIONS_START; DPRINTK(" Monitor Operating Limits: "); + for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) { if (edid_is_limits_block(block)) { specs->hfmin = H_MIN_RATE * 1000; @@ -618,11 +619,12 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs) break; } } - + /* estimate monitor limits based on modes supported */ if (retval) { - struct fb_videomode *modes; + struct fb_videomode *modes, *mode; int num_modes, i, hz, hscan, pixclock; + int vtotal, htotal; modes = fb_create_modedb(edid, &num_modes); if (!modes) { @@ -632,20 +634,38 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs) retval = 0; for (i = 0; i < num_modes; i++) { - hz = modes[i].refresh; + mode = &modes[i]; pixclock = PICOS2KHZ(modes[i].pixclock) * 1000; - hscan = (modes[i].yres * 105 * hz + 5000)/100; + htotal = mode->xres + mode->right_margin + mode->hsync_len + + mode->left_margin; + vtotal = mode->yres + mode->lower_margin + mode->vsync_len + + mode->upper_margin; + + if (mode->vmode & FB_VMODE_INTERLACED) + vtotal /= 2; + + if (mode->vmode & FB_VMODE_DOUBLE) + vtotal *= 2; + + hscan = (pixclock + htotal / 2) / htotal; + hscan = (hscan + 500) / 1000 * 1000; + hz = (hscan + vtotal / 2) / vtotal; if (specs->dclkmax == 0 || specs->dclkmax < pixclock) specs->dclkmax = pixclock; + if (specs->dclkmin == 0 || specs->dclkmin > pixclock) specs->dclkmin = pixclock; + if (specs->hfmax == 0 || specs->hfmax < hscan) specs->hfmax = hscan; + if (specs->hfmin == 0 || specs->hfmin > hscan) specs->hfmin = hscan; + if (specs->vfmax == 0 || specs->vfmax < hz) specs->vfmax = hz; + if (specs->vfmin == 0 || specs->vfmin > hz) specs->vfmin = hz; } @@ -1281,8 +1301,7 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info) -EINVAL : 0; } -#if defined(CONFIG_FB_FIRMWARE_EDID) && defined(__i386__) -#include <linux/pci.h> +#if defined(CONFIG_FIRMWARE_EDID) && defined(CONFIG_X86) /* * We need to ensure that the EDID block is only returned for diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index 3ceb8c1b392e..4f78f234473d 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c @@ -100,13 +100,22 @@ static int mode_string(char *buf, unsigned int offset, const struct fb_videomode *mode) { char m = 'U'; + char v = 'p'; + if (mode->flag & FB_MODE_IS_DETAILED) m = 'D'; if (mode->flag & FB_MODE_IS_VESA) m = 'V'; if (mode->flag & FB_MODE_IS_STANDARD) m = 'S'; - return snprintf(&buf[offset], PAGE_SIZE - offset, "%c:%dx%d-%d\n", m, mode->xres, mode->yres, mode->refresh); + + if (mode->vmode & FB_VMODE_INTERLACED) + v = 'i'; + if (mode->vmode & FB_VMODE_DOUBLE) + v = 'd'; + + return snprintf(&buf[offset], PAGE_SIZE - offset, "%c:%dx%d%c-%d\n", + m, mode->xres, mode->yres, v, mode->refresh); } static ssize_t store_mode(struct class_device *class_device, const char * buf, @@ -238,45 +247,6 @@ static ssize_t show_rotate(struct class_device *class_device, char *buf) return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.rotate); } -static ssize_t store_con_rotate(struct class_device *class_device, - const char *buf, size_t count) -{ - struct fb_info *fb_info = class_get_devdata(class_device); - int rotate; - char **last = NULL; - - acquire_console_sem(); - rotate = simple_strtoul(buf, last, 0); - fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE, &rotate); - release_console_sem(); - return count; -} - -static ssize_t store_con_rotate_all(struct class_device *class_device, - const char *buf, size_t count) -{ - struct fb_info *fb_info = class_get_devdata(class_device); - int rotate; - char **last = NULL; - - acquire_console_sem(); - rotate = simple_strtoul(buf, last, 0); - fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE_ALL, &rotate); - release_console_sem(); - return count; -} - -static ssize_t show_con_rotate(struct class_device *class_device, char *buf) -{ - struct fb_info *fb_info = class_get_devdata(class_device); - int rotate; - - acquire_console_sem(); - rotate = fb_con_duit(fb_info, FB_EVENT_GET_CON_ROTATE, NULL); - release_console_sem(); - return snprintf(buf, PAGE_SIZE, "%d\n", rotate); -} - static ssize_t store_virtual(struct class_device *class_device, const char * buf, size_t count) { @@ -493,8 +463,6 @@ static struct class_device_attribute class_device_attrs[] = { __ATTR(name, S_IRUGO, show_name, NULL), __ATTR(stride, S_IRUGO, show_stride, NULL), __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate), - __ATTR(con_rotate, S_IRUGO|S_IWUSR, show_con_rotate, store_con_rotate), - __ATTR(con_rotate_all, S_IWUSR, NULL, store_con_rotate_all), __ATTR(state, S_IRUGO|S_IWUSR, show_fbstate, store_fbstate), #ifdef CONFIG_FB_BACKLIGHT __ATTR(bl_curve, S_IRUGO|S_IWUSR, show_bl_curve, store_bl_curve), diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index 7633e41adda1..2a0e8210d398 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c @@ -1,6 +1,6 @@ /* ffb.c: Creator/Elite3D frame buffer driver * - * Copyright (C) 2003 David S. Miller (davem@redhat.com) + * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz) * * Driver layout based loosely on tgafb.c, see that file for credits. @@ -19,7 +19,8 @@ #include <asm/io.h> #include <asm/upa.h> -#include <asm/oplib.h> +#include <asm/prom.h> +#include <asm/of_device.h> #include <asm/fbio.h> #include "sbuslib.h" @@ -184,161 +185,161 @@ static struct fb_ops ffb_ops = { struct ffb_fbc { /* Next vertex registers */ - u32 xxx1[3]; - volatile u32 alpha; - volatile u32 red; - volatile u32 green; - volatile u32 blue; - volatile u32 depth; - volatile u32 y; - volatile u32 x; - u32 xxx2[2]; - volatile u32 ryf; - volatile u32 rxf; - u32 xxx3[2]; + u32 xxx1[3]; + u32 alpha; + u32 red; + u32 green; + u32 blue; + u32 depth; + u32 y; + u32 x; + u32 xxx2[2]; + u32 ryf; + u32 rxf; + u32 xxx3[2]; - volatile u32 dmyf; - volatile u32 dmxf; - u32 xxx4[2]; - volatile u32 ebyi; - volatile u32 ebxi; - u32 xxx5[2]; - volatile u32 by; - volatile u32 bx; - u32 dy; - u32 dx; - volatile u32 bh; - volatile u32 bw; - u32 xxx6[2]; + u32 dmyf; + u32 dmxf; + u32 xxx4[2]; + u32 ebyi; + u32 ebxi; + u32 xxx5[2]; + u32 by; + u32 bx; + u32 dy; + u32 dx; + u32 bh; + u32 bw; + u32 xxx6[2]; - u32 xxx7[32]; + u32 xxx7[32]; /* Setup unit vertex state register */ - volatile u32 suvtx; - u32 xxx8[63]; + u32 suvtx; + u32 xxx8[63]; /* Control registers */ - volatile u32 ppc; - volatile u32 wid; - volatile u32 fg; - volatile u32 bg; - volatile u32 consty; - volatile u32 constz; - volatile u32 xclip; - volatile u32 dcss; - volatile u32 vclipmin; - volatile u32 vclipmax; - volatile u32 vclipzmin; - volatile u32 vclipzmax; - volatile u32 dcsf; - volatile u32 dcsb; - volatile u32 dczf; - volatile u32 dczb; + u32 ppc; + u32 wid; + u32 fg; + u32 bg; + u32 consty; + u32 constz; + u32 xclip; + u32 dcss; + u32 vclipmin; + u32 vclipmax; + u32 vclipzmin; + u32 vclipzmax; + u32 dcsf; + u32 dcsb; + u32 dczf; + u32 dczb; - u32 xxx9; - volatile u32 blendc; - volatile u32 blendc1; - volatile u32 blendc2; - volatile u32 fbramitc; - volatile u32 fbc; - volatile u32 rop; - volatile u32 cmp; - volatile u32 matchab; - volatile u32 matchc; - volatile u32 magnab; - volatile u32 magnc; - volatile u32 fbcfg0; - volatile u32 fbcfg1; - volatile u32 fbcfg2; - volatile u32 fbcfg3; + u32 xxx9; + u32 blendc; + u32 blendc1; + u32 blendc2; + u32 fbramitc; + u32 fbc; + u32 rop; + u32 cmp; + u32 matchab; + u32 matchc; + u32 magnab; + u32 magnc; + u32 fbcfg0; + u32 fbcfg1; + u32 fbcfg2; + u32 fbcfg3; - u32 ppcfg; - volatile u32 pick; - volatile u32 fillmode; - volatile u32 fbramwac; - volatile u32 pmask; - volatile u32 xpmask; - volatile u32 ypmask; - volatile u32 zpmask; - volatile u32 clip0min; - volatile u32 clip0max; - volatile u32 clip1min; - volatile u32 clip1max; - volatile u32 clip2min; - volatile u32 clip2max; - volatile u32 clip3min; - volatile u32 clip3max; + u32 ppcfg; + u32 pick; + u32 fillmode; + u32 fbramwac; + u32 pmask; + u32 xpmask; + u32 ypmask; + u32 zpmask; + u32 clip0min; + u32 clip0max; + u32 clip1min; + u32 clip1max; + u32 clip2min; + u32 clip2max; + u32 clip3min; + u32 clip3max; /* New 3dRAM III support regs */ - volatile u32 rawblend2; - volatile u32 rawpreblend; - volatile u32 rawstencil; - volatile u32 rawstencilctl; - volatile u32 threedram1; - volatile u32 threedram2; - volatile u32 passin; - volatile u32 rawclrdepth; - volatile u32 rawpmask; - volatile u32 rawcsrc; - volatile u32 rawmatch; - volatile u32 rawmagn; - volatile u32 rawropblend; - volatile u32 rawcmp; - volatile u32 rawwac; - volatile u32 fbramid; + u32 rawblend2; + u32 rawpreblend; + u32 rawstencil; + u32 rawstencilctl; + u32 threedram1; + u32 threedram2; + u32 passin; + u32 rawclrdepth; + u32 rawpmask; + u32 rawcsrc; + u32 rawmatch; + u32 rawmagn; + u32 rawropblend; + u32 rawcmp; + u32 rawwac; + u32 fbramid; - volatile u32 drawop; - u32 xxx10[2]; - volatile u32 fontlpat; - u32 xxx11; - volatile u32 fontxy; - volatile u32 fontw; - volatile u32 fontinc; - volatile u32 font; - u32 xxx12[3]; - volatile u32 blend2; - volatile u32 preblend; - volatile u32 stencil; - volatile u32 stencilctl; - - u32 xxx13[4]; - volatile u32 dcss1; - volatile u32 dcss2; - volatile u32 dcss3; - volatile u32 widpmask; - volatile u32 dcs2; - volatile u32 dcs3; - volatile u32 dcs4; - u32 xxx14; - volatile u32 dcd2; - volatile u32 dcd3; - volatile u32 dcd4; - u32 xxx15; + u32 drawop; + u32 xxx10[2]; + u32 fontlpat; + u32 xxx11; + u32 fontxy; + u32 fontw; + u32 fontinc; + u32 font; + u32 xxx12[3]; + u32 blend2; + u32 preblend; + u32 stencil; + u32 stencilctl; + + u32 xxx13[4]; + u32 dcss1; + u32 dcss2; + u32 dcss3; + u32 widpmask; + u32 dcs2; + u32 dcs3; + u32 dcs4; + u32 xxx14; + u32 dcd2; + u32 dcd3; + u32 dcd4; + u32 xxx15; - volatile u32 pattern[32]; + u32 pattern[32]; - u32 xxx16[256]; + u32 xxx16[256]; - volatile u32 devid; - u32 xxx17[63]; + u32 devid; + u32 xxx17[63]; - volatile u32 ucsr; - u32 xxx18[31]; + u32 ucsr; + u32 xxx18[31]; - volatile u32 mer; + u32 mer; }; struct ffb_dac { - volatile u32 type; - volatile u32 value; - volatile u32 type2; - volatile u32 value2; + u32 type; + u32 value; + u32 type2; + u32 value2; }; struct ffb_par { spinlock_t lock; - struct ffb_fbc *fbc; - struct ffb_dac *dac; + struct ffb_fbc __iomem *fbc; + struct ffb_dac __iomem *dac; u32 flags; #define FFB_FLAG_AFB 0x00000001 @@ -353,16 +354,13 @@ struct ffb_par { unsigned long physbase; unsigned long fbsize; - char name[64]; - int prom_node; - int prom_parent_node; int dac_rev; int board_type; }; static void FFBFifo(struct ffb_par *par, int n) { - struct ffb_fbc *fbc; + struct ffb_fbc __iomem *fbc; int cache = par->fifo_cache; if (cache - n < 0) { @@ -375,7 +373,7 @@ static void FFBFifo(struct ffb_par *par, int n) static void FFBWait(struct ffb_par *par) { - struct ffb_fbc *fbc; + struct ffb_fbc __iomem *fbc; int limit = 10000; fbc = par->fbc; @@ -408,8 +406,8 @@ static __inline__ void ffb_rop(struct ffb_par *par, u32 rop) static void ffb_switch_from_graph(struct ffb_par *par) { - struct ffb_fbc *fbc = par->fbc; - struct ffb_dac *dac = par->dac; + struct ffb_fbc __iomem *fbc = par->fbc; + struct ffb_dac __iomem *dac = par->dac; unsigned long flags; spin_lock_irqsave(&par->lock, flags); @@ -462,7 +460,7 @@ static int ffb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { struct ffb_par *par = (struct ffb_par *) info->par; - struct ffb_fbc *fbc = par->fbc; + struct ffb_fbc __iomem *fbc = par->fbc; unsigned long flags; u32 fg; @@ -505,7 +503,7 @@ static void ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area) { struct ffb_par *par = (struct ffb_par *) info->par; - struct ffb_fbc *fbc = par->fbc; + struct ffb_fbc __iomem *fbc = par->fbc; unsigned long flags; if (area->dx != area->sx || @@ -541,7 +539,7 @@ ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area) static void ffb_imageblit(struct fb_info *info, const struct fb_image *image) { struct ffb_par *par = (struct ffb_par *) info->par; - struct ffb_fbc *fbc = par->fbc; + struct ffb_fbc __iomem *fbc = par->fbc; const u8 *data = image->data; unsigned long flags; u32 fg, bg, xy; @@ -664,7 +662,7 @@ static int ffb_blank(int blank, struct fb_info *info) { struct ffb_par *par = (struct ffb_par *) info->par; - struct ffb_dac *dac = par->dac; + struct ffb_dac __iomem *dac = par->dac; unsigned long flags; u32 tmp; @@ -883,78 +881,42 @@ ffb_init_fix(struct fb_info *info) info->fix.accel = FB_ACCEL_SUN_CREATOR; } -static int ffb_apply_upa_parent_ranges(int parent, - struct linux_prom64_registers *regs) -{ - struct linux_prom64_ranges ranges[PROMREG_MAX]; - char name[128]; - int len, i; - - prom_getproperty(parent, "name", name, sizeof(name)); - if (strcmp(name, "upa") != 0) - return 0; - - len = prom_getproperty(parent, "ranges", (void *) ranges, sizeof(ranges)); - if (len <= 0) - return 1; - - len /= sizeof(struct linux_prom64_ranges); - for (i = 0; i < len; i++) { - struct linux_prom64_ranges *rng = &ranges[i]; - u64 phys_addr = regs->phys_addr; - - if (phys_addr >= rng->ot_child_base && - phys_addr < (rng->ot_child_base + rng->or_size)) { - regs->phys_addr -= rng->ot_child_base; - regs->phys_addr += rng->ot_parent_base; - return 0; - } - } - - return 1; -} - struct all_info { struct fb_info info; struct ffb_par par; u32 pseudo_palette[256]; - struct list_head list; }; -static LIST_HEAD(ffb_list); -static void ffb_init_one(int node, int parent) +static int ffb_init_one(struct of_device *op) { - struct linux_prom64_registers regs[2*PROMREG_MAX]; - struct ffb_fbc *fbc; - struct ffb_dac *dac; + struct device_node *dp = op->node; + struct ffb_fbc __iomem *fbc; + struct ffb_dac __iomem *dac; struct all_info *all; + int err; - if (prom_getproperty(node, "reg", (void *) regs, sizeof(regs)) <= 0) { - printk("ffb: Cannot get reg device node property.\n"); - return; - } + all = kzalloc(sizeof(*all), GFP_KERNEL); + if (!all) + return -ENOMEM; - if (ffb_apply_upa_parent_ranges(parent, ®s[0])) { - printk("ffb: Cannot apply parent ranges to regs.\n"); - return; + spin_lock_init(&all->par.lock); + all->par.fbc = of_ioremap(&op->resource[2], 0, + sizeof(struct ffb_fbc), "ffb fbc"); + if (!all->par.fbc) { + kfree(all); + return -ENOMEM; } - all = kmalloc(sizeof(*all), GFP_KERNEL); - if (!all) { - printk(KERN_ERR "ffb: Cannot allocate memory.\n"); - return; + all->par.dac = of_ioremap(&op->resource[1], 0, + sizeof(struct ffb_dac), "ffb dac"); + if (!all->par.dac) { + of_iounmap(all->par.fbc, sizeof(struct ffb_fbc)); + kfree(all); + return -ENOMEM; } - memset(all, 0, sizeof(*all)); - - INIT_LIST_HEAD(&all->list); - spin_lock_init(&all->par.lock); - all->par.fbc = (struct ffb_fbc *)(regs[0].phys_addr + FFB_FBC_REGS_POFF); - all->par.dac = (struct ffb_dac *)(regs[0].phys_addr + FFB_DAC_POFF); all->par.rop_cache = FFB_ROP_NEW; - all->par.physbase = regs[0].phys_addr; - all->par.prom_node = node; - all->par.prom_parent_node = parent; + all->par.physbase = op->resource[0].start; /* Don't mention copyarea, so SCROLL_REDRAW is always * used. It is the fastest on this chip. @@ -968,7 +930,7 @@ static void ffb_init_one(int node, int parent) all->info.par = &all->par; all->info.pseudo_palette = all->pseudo_palette; - sbusfb_fill_var(&all->info.var, all->par.prom_node, 32); + sbusfb_fill_var(&all->info.var, dp->node, 32); all->par.fbsize = PAGE_ALIGN(all->info.var.xres * all->info.var.yres * 4); @@ -976,14 +938,13 @@ static void ffb_init_one(int node, int parent) all->info.var.accel_flags = FB_ACCELF_TEXT; - prom_getstring(node, "name", all->par.name, sizeof(all->par.name)); - if (!strcmp(all->par.name, "SUNW,afb")) + if (!strcmp(dp->name, "SUNW,afb")) all->par.flags |= FFB_FLAG_AFB; - all->par.board_type = prom_getintdefault(node, "board_type", 0); + all->par.board_type = of_getintprop_default(dp, "board_type", 0); fbc = all->par.fbc; - if((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0) + if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0) upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr); ffb_switch_from_graph(&all->par); @@ -1008,81 +969,88 @@ static void ffb_init_one(int node, int parent) if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { printk(KERN_ERR "ffb: Could not allocate color map.\n"); kfree(all); - return; + return -ENOMEM; } ffb_init_fix(&all->info); - if (register_framebuffer(&all->info) < 0) { + err = register_framebuffer(&all->info); + if (err < 0) { printk(KERN_ERR "ffb: Could not register framebuffer.\n"); fb_dealloc_cmap(&all->info.cmap); kfree(all); - return; + return err; } - list_add(&all->list, &ffb_list); + dev_set_drvdata(&op->dev, all); - printk("ffb: %s at %016lx type %d DAC %d\n", + printk("%s: %s at %016lx, type %d, DAC revision %d\n", + dp->full_name, ((all->par.flags & FFB_FLAG_AFB) ? "AFB" : "FFB"), - regs[0].phys_addr, all->par.board_type, all->par.dac_rev); + all->par.physbase, all->par.board_type, all->par.dac_rev); + + return 0; } -static void ffb_scan_siblings(int root) +static int __devinit ffb_probe(struct of_device *dev, const struct of_device_id *match) { - int node, child; - - child = prom_getchild(root); - for (node = prom_searchsiblings(child, "SUNW,ffb"); node; - node = prom_searchsiblings(prom_getsibling(node), "SUNW,ffb")) - ffb_init_one(node, root); - for (node = prom_searchsiblings(child, "SUNW,afb"); node; - node = prom_searchsiblings(prom_getsibling(node), "SUNW,afb")) - ffb_init_one(node, root); + struct of_device *op = to_of_device(&dev->dev); + + return ffb_init_one(op); } -int __init ffb_init(void) +static int __devexit ffb_remove(struct of_device *dev) { - int root; + struct all_info *all = dev_get_drvdata(&dev->dev); - if (fb_get_options("ffb", NULL)) - return -ENODEV; + unregister_framebuffer(&all->info); + fb_dealloc_cmap(&all->info.cmap); - ffb_scan_siblings(prom_root_node); + of_iounmap(all->par.fbc, sizeof(struct ffb_fbc)); + of_iounmap(all->par.dac, sizeof(struct ffb_dac)); - root = prom_getchild(prom_root_node); - for (root = prom_searchsiblings(root, "upa"); root; - root = prom_searchsiblings(prom_getsibling(root), "upa")) - ffb_scan_siblings(root); + kfree(all); + + dev_set_drvdata(&dev->dev, NULL); return 0; } -void __exit ffb_exit(void) -{ - struct list_head *pos, *tmp; +static struct of_device_id ffb_match[] = { + { + .name = "SUNW,ffb", + }, + { + .name = "SUNW,afb", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, ffb_match); + +static struct of_platform_driver ffb_driver = { + .name = "ffb", + .match_table = ffb_match, + .probe = ffb_probe, + .remove = __devexit_p(ffb_remove), +}; - list_for_each_safe(pos, tmp, &ffb_list) { - struct all_info *all = list_entry(pos, typeof(*all), list); +int __init ffb_init(void) +{ + if (fb_get_options("ffb", NULL)) + return -ENODEV; - unregister_framebuffer(&all->info); - fb_dealloc_cmap(&all->info.cmap); - kfree(all); - } + return of_register_driver(&ffb_driver, &of_bus_type); } -int __init -ffb_setup(char *arg) +void __exit ffb_exit(void) { - /* No cmdline options yet... */ - return 0; + of_unregister_driver(&ffb_driver); } module_init(ffb_init); - -#ifdef MODULE module_exit(ffb_exit); -#endif MODULE_DESCRIPTION("framebuffer driver for Creator/Elite3D chipsets"); -MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); +MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); +MODULE_VERSION("2.0"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c index 5e25b9860196..bf0e60b5a3b6 100644 --- a/drivers/video/gbefb.c +++ b/drivers/video/gbefb.c @@ -9,7 +9,6 @@ * more details. */ -#include <linux/config.h> #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c index 20e69156d728..4d3a8871d3d1 100644 --- a/drivers/video/geode/gx1fb_core.c +++ b/drivers/video/geode/gx1fb_core.c @@ -376,8 +376,6 @@ static int __init gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id * release_mem_region(gx1_gx_base() + 0x8300, 0x100); } - pci_disable_device(pdev); - if (info) framebuffer_release(info); return ret; @@ -399,7 +397,6 @@ static void gx1fb_remove(struct pci_dev *pdev) iounmap(par->dc_regs); release_mem_region(gx1_gx_base() + 0x8300, 0x100); - pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); framebuffer_release(info); diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c index 89c34b15f5d4..5ef12a3dfa50 100644 --- a/drivers/video/geode/gxfb_core.c +++ b/drivers/video/geode/gxfb_core.c @@ -354,8 +354,6 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i pci_release_region(pdev, 2); } - pci_disable_device(pdev); - if (info) framebuffer_release(info); return ret; @@ -377,7 +375,6 @@ static void gxfb_remove(struct pci_dev *pdev) iounmap(par->dc_regs); pci_release_region(pdev, 2); - pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); framebuffer_release(info); diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c index f04ca721f94c..01864767450d 100644 --- a/drivers/video/hitfb.c +++ b/drivers/video/hitfb.c @@ -11,7 +11,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c index 3fe3ae1aff12..c1f7b49975dd 100644 --- a/drivers/video/i810/i810-i2c.c +++ b/drivers/video/i810/i810-i2c.c @@ -8,7 +8,6 @@ * License. See the file COPYING in the main directory of this archive for * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index 44aa2ffff973..fbe8a2c4b04c 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c @@ -29,7 +29,6 @@ */ #include <linux/module.h> -#include <linux/config.h> #include <linux/kernel.h> #include <linux/errno.h> #include <linux/string.h> @@ -2110,9 +2109,6 @@ static void i810fb_release_resource(struct fb_info *info, if (par->res_flags & MMIO_REQ) release_mem_region(par->mmio_start_phys, MMIO_SIZE); - if (par->res_flags & PCI_DEVICE_ENABLED) - pci_disable_device(par->dev); - framebuffer_release(info); } diff --git a/drivers/video/imacfb.c b/drivers/video/imacfb.c new file mode 100644 index 000000000000..cdbae173d69a --- /dev/null +++ b/drivers/video/imacfb.c @@ -0,0 +1,341 @@ +/* + * framebuffer driver for Intel Based Mac's + * + * (c) 2006 Edgar Hucek <gimli@dark-green.com> + * Original imac driver written by Gerd Knorr <kraxel@goldbach.in-berlin.de> + * + */ + +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/fb.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <linux/tty.h> + +#include <asm/io.h> + +#include <video/vga.h> + +typedef enum _MAC_TYPE { + M_I17, + M_I20, + M_MINI, + M_MACBOOK, + M_NEW +} MAC_TYPE; + +/* --------------------------------------------------------------------- */ + +static struct fb_var_screeninfo imacfb_defined __initdata = { + .activate = FB_ACTIVATE_NOW, + .height = -1, + .width = -1, + .right_margin = 32, + .upper_margin = 16, + .lower_margin = 4, + .vsync_len = 4, + .vmode = FB_VMODE_NONINTERLACED, +}; + +static struct fb_fix_screeninfo imacfb_fix __initdata = { + .id = "IMAC VGA", + .type = FB_TYPE_PACKED_PIXELS, + .accel = FB_ACCEL_NONE, + .visual = FB_VISUAL_TRUECOLOR, +}; + +static int inverse; +static int model = M_NEW; +static int manual_height; +static int manual_width; + +#define DEFAULT_FB_MEM 1024*1024*16 + +/* --------------------------------------------------------------------- */ + +static int imacfb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *info) +{ + /* + * Set a single color register. The values supplied are + * already rounded down to the hardware's capabilities + * (according to the entries in the `var' structure). Return + * != 0 for invalid regno. + */ + + if (regno >= info->cmap.len) + return 1; + + if (regno < 16) { + red >>= 8; + green >>= 8; + blue >>= 8; + ((u32 *)(info->pseudo_palette))[regno] = + (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset); + } + return 0; +} + +static struct fb_ops imacfb_ops = { + .owner = THIS_MODULE, + .fb_setcolreg = imacfb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, +}; + +static int __init imacfb_setup(char *options) +{ + char *this_opt; + + if (!options || !*options) + return 0; + + while ((this_opt = strsep(&options, ",")) != NULL) { + if (!*this_opt) continue; + + if (!strcmp(this_opt, "inverse")) + inverse = 1; + else if (!strcmp(this_opt, "i17")) + model = M_I17; + else if (!strcmp(this_opt, "i20")) + model = M_I20; + else if (!strcmp(this_opt, "mini")) + model = M_MINI; + else if (!strcmp(this_opt, "macbook")) + model = M_MACBOOK; + else if (!strncmp(this_opt, "height:", 7)) + manual_height = simple_strtoul(this_opt+7, NULL, 0); + else if (!strncmp(this_opt, "width:", 6)) + manual_width = simple_strtoul(this_opt+6, NULL, 0); + } + return 0; +} + +static int __init imacfb_probe(struct platform_device *dev) +{ + struct fb_info *info; + int err; + unsigned int size_vmode; + unsigned int size_remap; + unsigned int size_total; + + screen_info.lfb_depth = 32; + screen_info.lfb_size = DEFAULT_FB_MEM / 0x10000; + screen_info.pages=1; + screen_info.blue_size = 8; + screen_info.blue_pos = 0; + screen_info.green_size = 8; + screen_info.green_pos = 8; + screen_info.red_size = 8; + screen_info.red_pos = 16; + screen_info.rsvd_size = 8; + screen_info.rsvd_pos = 24; + + switch (model) { + case M_I17: + screen_info.lfb_width = 1440; + screen_info.lfb_height = 900; + screen_info.lfb_linelength = 1472 * 4; + screen_info.lfb_base = 0x80010000; + break; + case M_NEW: + case M_I20: + screen_info.lfb_width = 1680; + screen_info.lfb_height = 1050; + screen_info.lfb_linelength = 1728 * 4; + screen_info.lfb_base = 0x80010000; + break; + case M_MINI: + screen_info.lfb_width = 1024; + screen_info.lfb_height = 768; + screen_info.lfb_linelength = 2048 * 4; + screen_info.lfb_base = 0x80000000; + break; + case M_MACBOOK: + screen_info.lfb_width = 1280; + screen_info.lfb_height = 800; + screen_info.lfb_linelength = 2048 * 4; + screen_info.lfb_base = 0x80000000; + break; + } + + /* if the user wants to manually specify height/width, + we will override the defaults */ + /* TODO: eventually get auto-detection working */ + if (manual_height > 0) + screen_info.lfb_height = manual_height; + if (manual_width > 0) + screen_info.lfb_width = manual_width; + + imacfb_fix.smem_start = screen_info.lfb_base; + imacfb_defined.bits_per_pixel = screen_info.lfb_depth; + imacfb_defined.xres = screen_info.lfb_width; + imacfb_defined.yres = screen_info.lfb_height; + imacfb_fix.line_length = screen_info.lfb_linelength; + + /* size_vmode -- that is the amount of memory needed for the + * used video mode, i.e. the minimum amount of + * memory we need. */ + size_vmode = imacfb_defined.yres * imacfb_fix.line_length; + + /* size_total -- all video memory we have. Used for + * entries, ressource allocation and bounds + * checking. */ + size_total = screen_info.lfb_size * 65536; + if (size_total < size_vmode) + size_total = size_vmode; + + /* size_remap -- the amount of video memory we are going to + * use for imacfb. With modern cards it is no + * option to simply use size_total as that + * wastes plenty of kernel address space. */ + size_remap = size_vmode * 2; + if (size_remap < size_vmode) + size_remap = size_vmode; + if (size_remap > size_total) + size_remap = size_total; + imacfb_fix.smem_len = size_remap; + + if (!request_mem_region(imacfb_fix.smem_start, size_total, "imacfb")) { + printk(KERN_WARNING + "imacfb: cannot reserve video memory at 0x%lx\n", + imacfb_fix.smem_start); + /* We cannot make this fatal. Sometimes this comes from magic + spaces our resource handlers simply don't know about */ + } + + info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev); + if (!info) { + err = -ENOMEM; + goto err_release_mem; + } + info->pseudo_palette = info->par; + info->par = NULL; + + info->screen_base = ioremap(imacfb_fix.smem_start, imacfb_fix.smem_len); + if (!info->screen_base) { + printk(KERN_ERR "imacfb: abort, cannot ioremap video memory " + "0x%x @ 0x%lx\n", + imacfb_fix.smem_len, imacfb_fix.smem_start); + err = -EIO; + goto err_unmap; + } + + printk(KERN_INFO "imacfb: framebuffer at 0x%lx, mapped to 0x%p, " + "using %dk, total %dk\n", + imacfb_fix.smem_start, info->screen_base, + size_remap/1024, size_total/1024); + printk(KERN_INFO "imacfb: mode is %dx%dx%d, linelength=%d, pages=%d\n", + imacfb_defined.xres, imacfb_defined.yres, + imacfb_defined.bits_per_pixel, imacfb_fix.line_length, + screen_info.pages); + + imacfb_defined.xres_virtual = imacfb_defined.xres; + imacfb_defined.yres_virtual = imacfb_fix.smem_len / + imacfb_fix.line_length; + printk(KERN_INFO "imacfb: scrolling: redraw\n"); + imacfb_defined.yres_virtual = imacfb_defined.yres; + + /* some dummy values for timing to make fbset happy */ + imacfb_defined.pixclock = 10000000 / imacfb_defined.xres * + 1000 / imacfb_defined.yres; + imacfb_defined.left_margin = (imacfb_defined.xres / 8) & 0xf8; + imacfb_defined.hsync_len = (imacfb_defined.xres / 8) & 0xf8; + + imacfb_defined.red.offset = screen_info.red_pos; + imacfb_defined.red.length = screen_info.red_size; + imacfb_defined.green.offset = screen_info.green_pos; + imacfb_defined.green.length = screen_info.green_size; + imacfb_defined.blue.offset = screen_info.blue_pos; + imacfb_defined.blue.length = screen_info.blue_size; + imacfb_defined.transp.offset = screen_info.rsvd_pos; + imacfb_defined.transp.length = screen_info.rsvd_size; + + printk(KERN_INFO "imacfb: %s: " + "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n", + "Truecolor", + screen_info.rsvd_size, + screen_info.red_size, + screen_info.green_size, + screen_info.blue_size, + screen_info.rsvd_pos, + screen_info.red_pos, + screen_info.green_pos, + screen_info.blue_pos); + + imacfb_fix.ypanstep = 0; + imacfb_fix.ywrapstep = 0; + + /* request failure does not faze us, as vgacon probably has this + * region already (FIXME) */ + request_region(0x3c0, 32, "imacfb"); + + info->fbops = &imacfb_ops; + info->var = imacfb_defined; + info->fix = imacfb_fix; + info->flags = FBINFO_FLAG_DEFAULT; + + if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { + err = -ENOMEM; + goto err_unmap; + } + if (register_framebuffer(info)<0) { + err = -EINVAL; + goto err_fb_dealoc; + } + printk(KERN_INFO "fb%d: %s frame buffer device\n", + info->node, info->fix.id); + return 0; + +err_fb_dealoc: + fb_dealloc_cmap(&info->cmap); +err_unmap: + iounmap(info->screen_base); + framebuffer_release(info); +err_release_mem: + release_mem_region(imacfb_fix.smem_start, size_total); + return err; +} + +static struct platform_driver imacfb_driver = { + .probe = imacfb_probe, + .driver = { + .name = "imacfb", + }, +}; + +static struct platform_device imacfb_device = { + .name = "imacfb", +}; + +static int __init imacfb_init(void) +{ + int ret; + char *option = NULL; + + /* ignore error return of fb_get_options */ + fb_get_options("imacfb", &option); + imacfb_setup(option); + ret = platform_driver_register(&imacfb_driver); + + if (!ret) { + ret = platform_device_register(&imacfb_device); + if (ret) + platform_driver_unregister(&imacfb_driver); + } + return ret; +} +module_init(imacfb_init); + +MODULE_LICENSE("GPL"); diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c index f73c642b50c2..5f393d985b11 100644 --- a/drivers/video/imsttfb.c +++ b/drivers/video/imsttfb.c @@ -16,7 +16,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 1718baaeed2a..0f9b2fdc28b1 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -18,7 +18,6 @@ //#define DEBUG 1 -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 0a0a8b199ecc..3f39d84015f1 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c @@ -108,7 +108,6 @@ * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index 7533b3dd08ac..3b78a57924f0 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c @@ -19,7 +19,6 @@ /* $DHD: intelfb/intelfbhw.c,v 1.9 2003/06/27 15:06:25 dawes Exp $ */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c index 477ad297de4e..2fdbe9b2b04b 100644 --- a/drivers/video/kyro/fbdev.c +++ b/drivers/video/kyro/fbdev.c @@ -9,7 +9,6 @@ * for more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h> diff --git a/drivers/video/leo.c b/drivers/video/leo.c index a23cfdb9d826..f3a24338d9ac 100644 --- a/drivers/video/leo.c +++ b/drivers/video/leo.c @@ -1,6 +1,6 @@ /* leo.c: LEO frame buffer driver * - * Copyright (C) 2003 David S. Miller (davem@redhat.com) + * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) * Copyright (C) 1996-1999 Jakub Jelinek (jj@ultra.linux.cz) * Copyright (C) 1997 Michal Rehacek (Michal.Rehacek@st.mff.cuni.cz) * @@ -18,8 +18,8 @@ #include <linux/mm.h> #include <asm/io.h> -#include <asm/sbus.h> -#include <asm/oplib.h> +#include <asm/prom.h> +#include <asm/of_device.h> #include <asm/fbio.h> #include "sbuslib.h" @@ -80,10 +80,10 @@ static struct fb_ops leo_ops = { struct leo_cursor { u8 xxx0[16]; - volatile u32 cur_type; - volatile u32 cur_misc; - volatile u32 cur_cursxy; - volatile u32 cur_data; + u32 cur_type; + u32 cur_misc; + u32 cur_cursxy; + u32 cur_data; }; #define LEO_KRN_TYPE_CLUT0 0x00001000 @@ -99,27 +99,27 @@ struct leo_cursor { #define LEO_KRN_CSR_UNK2 0x00000001 struct leo_lx_krn { - volatile u32 krn_type; - volatile u32 krn_csr; - volatile u32 krn_value; + u32 krn_type; + u32 krn_csr; + u32 krn_value; }; struct leo_lc_ss0_krn { - volatile u32 misc; + u32 misc; u8 xxx0[0x800-4]; - volatile u32 rev; + u32 rev; }; struct leo_lc_ss0_usr { - volatile u32 csr; - volatile u32 addrspace; - volatile u32 fontmsk; - volatile u32 fontt; - volatile u32 extent; - volatile u32 src; + u32 csr; + u32 addrspace; + u32 fontmsk; + u32 fontt; + u32 extent; + u32 src; u32 dst; - volatile u32 copy; - volatile u32 fill; + u32 copy; + u32 fill; }; struct leo_lc_ss1_krn { @@ -132,47 +132,47 @@ struct leo_lc_ss1_usr { struct leo_ld { u8 xxx0[0xe00]; - volatile u32 csr; - volatile u32 wid; - volatile u32 wmask; - volatile u32 widclip; - volatile u32 vclipmin; - volatile u32 vclipmax; - volatile u32 pickmin; /* SS1 only */ - volatile u32 pickmax; /* SS1 only */ - volatile u32 fg; - volatile u32 bg; - volatile u32 src; /* Copy/Scroll (SS0 only) */ - volatile u32 dst; /* Copy/Scroll/Fill (SS0 only) */ - volatile u32 extent; /* Copy/Scroll/Fill size (SS0 only) */ + u32 csr; + u32 wid; + u32 wmask; + u32 widclip; + u32 vclipmin; + u32 vclipmax; + u32 pickmin; /* SS1 only */ + u32 pickmax; /* SS1 only */ + u32 fg; + u32 bg; + u32 src; /* Copy/Scroll (SS0 only) */ + u32 dst; /* Copy/Scroll/Fill (SS0 only) */ + u32 extent; /* Copy/Scroll/Fill size (SS0 only) */ u32 xxx1[3]; - volatile u32 setsem; /* SS1 only */ - volatile u32 clrsem; /* SS1 only */ - volatile u32 clrpick; /* SS1 only */ - volatile u32 clrdat; /* SS1 only */ - volatile u32 alpha; /* SS1 only */ + u32 setsem; /* SS1 only */ + u32 clrsem; /* SS1 only */ + u32 clrpick; /* SS1 only */ + u32 clrdat; /* SS1 only */ + u32 alpha; /* SS1 only */ u8 xxx2[0x2c]; - volatile u32 winbg; - volatile u32 planemask; - volatile u32 rop; - volatile u32 z; - volatile u32 dczf; /* SS1 only */ - volatile u32 dczb; /* SS1 only */ - volatile u32 dcs; /* SS1 only */ - volatile u32 dczs; /* SS1 only */ - volatile u32 pickfb; /* SS1 only */ - volatile u32 pickbb; /* SS1 only */ - volatile u32 dcfc; /* SS1 only */ - volatile u32 forcecol; /* SS1 only */ - volatile u32 door[8]; /* SS1 only */ - volatile u32 pick[5]; /* SS1 only */ + u32 winbg; + u32 planemask; + u32 rop; + u32 z; + u32 dczf; /* SS1 only */ + u32 dczb; /* SS1 only */ + u32 dcs; /* SS1 only */ + u32 dczs; /* SS1 only */ + u32 pickfb; /* SS1 only */ + u32 pickbb; /* SS1 only */ + u32 dcfc; /* SS1 only */ + u32 forcecol; /* SS1 only */ + u32 door[8]; /* SS1 only */ + u32 pick[5]; /* SS1 only */ }; #define LEO_SS1_MISC_ENABLE 0x00000001 #define LEO_SS1_MISC_STEREO 0x00000002 struct leo_ld_ss1 { - u8 xxx0[0xef4]; - volatile u32 ss1_misc; + u8 xxx0[0xef4]; + u32 ss1_misc; }; struct leo_ld_gbl { @@ -193,9 +193,8 @@ struct leo_par { #define LEO_FLAG_BLANKED 0x00000001 unsigned long physbase; + unsigned long which_io; unsigned long fbsize; - - struct sbus_dev *sdev; }; static void leo_wait(struct leo_lx_krn __iomem *lx_krn) @@ -368,8 +367,7 @@ static int leo_mmap(struct fb_info *info, struct vm_area_struct *vma) return sbusfb_mmap_helper(leo_mmap_map, par->physbase, par->fbsize, - par->sdev->reg_addrs[0].which_io, - vma); + par->which_io, vma); } static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) @@ -385,11 +383,9 @@ static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) */ static void -leo_init_fix(struct fb_info *info) +leo_init_fix(struct fb_info *info, struct device_node *dp) { - struct leo_par *par = (struct leo_par *)info->par; - - strlcpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id)); + strlcpy(info->fix.id, dp->name, sizeof(info->fix.id)); info->fix.type = FB_TYPE_PACKED_PIXELS; info->fix.visual = FB_VISUAL_TRUECOLOR; @@ -532,60 +528,74 @@ static void leo_fixup_var_rgb(struct fb_var_screeninfo *var) struct all_info { struct fb_info info; struct leo_par par; - struct list_head list; }; -static LIST_HEAD(leo_list); -static void leo_init_one(struct sbus_dev *sdev) +static void leo_unmap_regs(struct all_info *all) { - struct all_info *all; - int linebytes; + if (all->par.lc_ss0_usr) + of_iounmap(all->par.lc_ss0_usr, 0x1000); + if (all->par.ld_ss0) + of_iounmap(all->par.ld_ss0, 0x1000); + if (all->par.ld_ss1) + of_iounmap(all->par.ld_ss1, 0x1000); + if (all->par.lx_krn) + of_iounmap(all->par.lx_krn, 0x1000); + if (all->par.cursor) + of_iounmap(all->par.cursor, sizeof(struct leo_cursor)); + if (all->info.screen_base) + of_iounmap(all->info.screen_base, 0x800000); +} - all = kmalloc(sizeof(*all), GFP_KERNEL); - if (!all) { - printk(KERN_ERR "leo: Cannot allocate memory.\n"); - return; - } - memset(all, 0, sizeof(*all)); +static int __devinit leo_init_one(struct of_device *op) +{ + struct device_node *dp = op->node; + struct all_info *all; + int linebytes, err; - INIT_LIST_HEAD(&all->list); + all = kzalloc(sizeof(*all), GFP_KERNEL); + if (!all) + return -ENOMEM; spin_lock_init(&all->par.lock); - all->par.sdev = sdev; - all->par.physbase = sdev->reg_addrs[0].phys_addr; + all->par.physbase = op->resource[0].start; + all->par.which_io = op->resource[0].flags & IORESOURCE_BITS; - sbusfb_fill_var(&all->info.var, sdev->prom_node, 32); + sbusfb_fill_var(&all->info.var, dp->node, 32); leo_fixup_var_rgb(&all->info.var); - linebytes = prom_getintdefault(sdev->prom_node, "linebytes", - all->info.var.xres); + linebytes = of_getintprop_default(dp, "linebytes", + all->info.var.xres); all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); -#ifdef CONFIG_SPARC32 - all->info.screen_base = (char __iomem *) - prom_getintdefault(sdev->prom_node, "address", 0); -#endif - if (!all->info.screen_base) - all->info.screen_base = - sbus_ioremap(&sdev->resource[0], LEO_OFF_SS0, - 0x800000, "leo ram"); - all->par.lc_ss0_usr = - sbus_ioremap(&sdev->resource[0], LEO_OFF_LC_SS0_USR, - 0x1000, "leolc ss0usr"); + of_ioremap(&op->resource[0], LEO_OFF_LC_SS0_USR, + 0x1000, "leolc ss0usr"); all->par.ld_ss0 = - sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS0, - 0x1000, "leold ss0"); + of_ioremap(&op->resource[0], LEO_OFF_LD_SS0, + 0x1000, "leold ss0"); all->par.ld_ss1 = - sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS1, - 0x1000, "leold ss1"); + of_ioremap(&op->resource[0], LEO_OFF_LD_SS1, + 0x1000, "leold ss1"); all->par.lx_krn = - sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_KRN, - 0x1000, "leolx krn"); + of_ioremap(&op->resource[0], LEO_OFF_LX_KRN, + 0x1000, "leolx krn"); all->par.cursor = - sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_CURSOR, - sizeof(struct leo_cursor), "leolx cursor"); + of_ioremap(&op->resource[0], LEO_OFF_LX_CURSOR, + sizeof(struct leo_cursor), "leolx cursor"); + all->info.screen_base = + of_ioremap(&op->resource[0], LEO_OFF_SS0, + 0x800000, "leo ram"); + if (!all->par.lc_ss0_usr || + !all->par.ld_ss0 || + !all->par.ld_ss1 || + !all->par.lx_krn || + !all->par.cursor || + !all->info.screen_base) { + leo_unmap_regs(all); + kfree(all); + return -ENOMEM; + } all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; all->info.fbops = &leo_ops; @@ -597,69 +607,85 @@ static void leo_init_one(struct sbus_dev *sdev) leo_blank(0, &all->info); if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { - printk(KERN_ERR "leo: Could not allocate color map.\n"); + leo_unmap_regs(all); kfree(all); - return; + return -ENOMEM;; } - leo_init_fix(&all->info); + leo_init_fix(&all->info, dp); - if (register_framebuffer(&all->info) < 0) { - printk(KERN_ERR "leo: Could not register framebuffer.\n"); + err = register_framebuffer(&all->info); + if (err < 0) { fb_dealloc_cmap(&all->info.cmap); + leo_unmap_regs(all); kfree(all); - return; + return err; } - list_add(&all->list, &leo_list); + dev_set_drvdata(&op->dev, all); + + printk("%s: leo at %lx:%lx\n", + dp->full_name, + all->par.which_io, all->par.physbase); - printk("leo: %s at %lx:%lx\n", - sdev->prom_name, - (long) sdev->reg_addrs[0].which_io, - (long) sdev->reg_addrs[0].phys_addr); + return 0; } -int __init leo_init(void) +static int __devinit leo_probe(struct of_device *dev, const struct of_device_id *match) { - struct sbus_bus *sbus; - struct sbus_dev *sdev; + struct of_device *op = to_of_device(&dev->dev); - if (fb_get_options("leofb", NULL)) - return -ENODEV; + return leo_init_one(op); +} - for_all_sbusdev(sdev, sbus) { - if (!strcmp(sdev->prom_name, "leo")) - leo_init_one(sdev); - } +static int __devexit leo_remove(struct of_device *dev) +{ + struct all_info *all = dev_get_drvdata(&dev->dev); + + unregister_framebuffer(&all->info); + fb_dealloc_cmap(&all->info.cmap); + + leo_unmap_regs(all); + + kfree(all); + + dev_set_drvdata(&dev->dev, NULL); return 0; } -void __exit leo_exit(void) -{ - struct list_head *pos, *tmp; +static struct of_device_id leo_match[] = { + { + .name = "leo", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, leo_match); + +static struct of_platform_driver leo_driver = { + .name = "leo", + .match_table = leo_match, + .probe = leo_probe, + .remove = __devexit_p(leo_remove), +}; - list_for_each_safe(pos, tmp, &leo_list) { - struct all_info *all = list_entry(pos, typeof(*all), list); +static int __init leo_init(void) +{ + if (fb_get_options("leofb", NULL)) + return -ENODEV; - unregister_framebuffer(&all->info); - fb_dealloc_cmap(&all->info.cmap); - kfree(all); - } + return of_register_driver(&leo_driver, &of_bus_type); } -int __init -leo_setup(char *arg) +static void __exit leo_exit(void) { - /* No cmdline options yet... */ - return 0; + of_unregister_driver(&leo_driver); } module_init(leo_init); -#ifdef MODULE module_exit(leo_exit); -#endif MODULE_DESCRIPTION("framebuffer driver for LEO chipsets"); -MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); +MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); +MODULE_VERSION("2.0"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c index 788fa812c871..80c03618eb53 100644 --- a/drivers/video/logo/logo.c +++ b/drivers/video/logo/logo.c @@ -9,7 +9,6 @@ * Copyright (C) 2003 Geert Uytterhoeven <geert@linux-m68k.org> */ -#include <linux/config.h> #include <linux/linux_logo.h> #include <linux/stddef.h> #include <linux/module.h> diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c index c0385c6f7db5..ab2149531a04 100644 --- a/drivers/video/macmodes.c +++ b/drivers/video/macmodes.c @@ -15,7 +15,6 @@ * more details. */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/fb.h> #include <linux/string.h> @@ -327,7 +326,6 @@ int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode, } return -EINVAL; } -EXPORT_SYMBOL(mac_var_to_vmode); /** * mac_map_monitor_sense - Convert monitor sense to vmode @@ -371,8 +369,9 @@ EXPORT_SYMBOL(mac_map_monitor_sense); * */ -int __init mac_find_mode(struct fb_var_screeninfo *var, struct fb_info *info, - const char *mode_option, unsigned int default_bpp) +int __devinit mac_find_mode(struct fb_var_screeninfo *var, + struct fb_info *info, const char *mode_option, + unsigned int default_bpp) { const struct fb_videomode *db = NULL; unsigned int dbsize = 0; diff --git a/drivers/video/macmodes.h b/drivers/video/macmodes.h index 232f5a09a499..babeb81f467d 100644 --- a/drivers/video/macmodes.h +++ b/drivers/video/macmodes.h @@ -55,9 +55,10 @@ extern int mac_vmode_to_var(int vmode, int cmode, extern int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode, int *cmode); extern int mac_map_monitor_sense(int sense); -extern int __init mac_find_mode(struct fb_var_screeninfo *var, - struct fb_info *info, const char *mode_option, - unsigned int default_bpp); +extern int __devinit mac_find_mode(struct fb_var_screeninfo *var, + struct fb_info *info, + const char *mode_option, + unsigned int default_bpp); /* diff --git a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/matrox/matroxfb_DAC1064.c index a456e67a5b00..c4b570b4a4df 100644 --- a/drivers/video/matrox/matroxfb_DAC1064.c +++ b/drivers/video/matrox/matroxfb_DAC1064.c @@ -12,7 +12,6 @@ * */ -#include <linux/config.h> #include "matroxfb_DAC1064.h" #include "matroxfb_misc.h" diff --git a/drivers/video/matrox/matroxfb_DAC1064.h b/drivers/video/matrox/matroxfb_DAC1064.h index 56513a5d220b..df39c3193735 100644 --- a/drivers/video/matrox/matroxfb_DAC1064.h +++ b/drivers/video/matrox/matroxfb_DAC1064.h @@ -1,7 +1,6 @@ #ifndef __MATROXFB_DAC1064_H__ #define __MATROXFB_DAC1064_H__ -#include <linux/config.h> #include "matroxfb_base.h" diff --git a/drivers/video/matrox/matroxfb_Ti3026.c b/drivers/video/matrox/matroxfb_Ti3026.c index 23ebad0a12d8..a5690a5f29d5 100644 --- a/drivers/video/matrox/matroxfb_Ti3026.c +++ b/drivers/video/matrox/matroxfb_Ti3026.c @@ -78,7 +78,6 @@ * */ -#include <linux/config.h> #include "matroxfb_Ti3026.h" #include "matroxfb_misc.h" diff --git a/drivers/video/matrox/matroxfb_Ti3026.h b/drivers/video/matrox/matroxfb_Ti3026.h index 536e5f69de9f..27872aaa0a17 100644 --- a/drivers/video/matrox/matroxfb_Ti3026.h +++ b/drivers/video/matrox/matroxfb_Ti3026.h @@ -1,7 +1,6 @@ #ifndef __MATROXFB_TI3026_H__ #define __MATROXFB_TI3026_H__ -#include <linux/config.h> #include "matroxfb_base.h" diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index f4ddd3431f17..4a57dabb77d4 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c @@ -99,7 +99,6 @@ * */ -#include <linux/config.h> #include <linux/version.h> #define __OLD_VIDIOC_ @@ -234,7 +233,7 @@ int matroxfb_enable_irq(WPMINFO int reenable) { if (!test_and_set_bit(0, &ACCESS_FBINFO(irq_flags))) { if (request_irq(ACCESS_FBINFO(pcidev)->irq, matrox_irq, - SA_SHIRQ, "matroxfb", MINFO)) { + IRQF_SHARED, "matroxfb", MINFO)) { clear_bit(0, &ACCESS_FBINFO(irq_flags)); return -EINVAL; } diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h index b71737178d0d..b95779b57c06 100644 --- a/drivers/video/matrox/matroxfb_base.h +++ b/drivers/video/matrox/matroxfb_base.h @@ -25,7 +25,6 @@ /* Guard accelerator accesses with spin_lock_irqsave... */ #undef MATROXFB_USE_SPINLOCKS -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/matrox/matroxfb_misc.c index 263d801ef78f..18886b629cb1 100644 --- a/drivers/video/matrox/matroxfb_misc.c +++ b/drivers/video/matrox/matroxfb_misc.c @@ -84,7 +84,6 @@ * */ -#include <linux/config.h> #include "matroxfb_misc.h" #include <linux/interrupt.h> diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 26a1c618a205..ff5454601e22 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c @@ -259,6 +259,10 @@ static const struct fb_videomode modedb[] = { /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */ NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6, FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */ + NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5, + 0, FB_VMODE_NONINTERLACED }, }; @@ -787,8 +791,9 @@ struct fb_videomode *fb_find_best_mode(struct fb_var_screeninfo *var, if (diff > d) { diff = d; best = mode; - } else if (diff == d && mode->refresh > best->refresh) - best = mode; + } else if (diff == d && best && + mode->refresh > best->refresh) + best = mode; } } return best; @@ -1016,8 +1021,6 @@ EXPORT_SYMBOL(fb_videomode_to_var); EXPORT_SYMBOL(fb_var_to_videomode); EXPORT_SYMBOL(fb_mode_is_equal); EXPORT_SYMBOL(fb_add_videomode); -EXPORT_SYMBOL(fb_delete_videomode); -EXPORT_SYMBOL(fb_destroy_modelist); EXPORT_SYMBOL(fb_match_mode); EXPORT_SYMBOL(fb_find_best_mode); EXPORT_SYMBOL(fb_find_nearest_mode); diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index 24b12f71d5a8..773855a311e8 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c @@ -54,7 +54,6 @@ * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -1333,17 +1332,22 @@ static int neofb_blank(int blank_mode, struct fb_info *info) * run "setterm -powersave powerdown" to take advantage */ struct neofb_par *par = info->par; - int seqflags, lcdflags, dpmsflags, reg; - + int seqflags, lcdflags, dpmsflags, reg, tmpdisp; /* - * Reload the value stored in the register, if sensible. It might have - * been changed via FN keystroke. + * Read back the register bits related to display configuration. They might + * have been changed underneath the driver via Fn key stroke. + */ + neoUnlock(); + tmpdisp = vga_rgfx(NULL, 0x20) & 0x03; + neoLock(&par->state); + + /* In case we blank the screen, we want to store the possibly new + * configuration in the driver. During un-blank, we re-apply this setting, + * since the LCD bit will be cleared in order to switch off the backlight. */ if (par->PanelDispCntlRegRead) { - neoUnlock(); - par->PanelDispCntlReg1 = vga_rgfx(NULL, 0x20) & 0x03; - neoLock(&par->state); + par->PanelDispCntlReg1 = tmpdisp; } par->PanelDispCntlRegRead = !blank_mode; @@ -1378,12 +1382,21 @@ static int neofb_blank(int blank_mode, struct fb_info *info) break; case FB_BLANK_NORMAL: /* just blank screen (backlight stays on) */ seqflags = VGA_SR01_SCREEN_OFF; /* Disable sequencer */ - lcdflags = par->PanelDispCntlReg1 & 0x02; /* LCD normal */ + /* + * During a blank operation with the LID shut, we might store "LCD off" + * by mistake. Due to timing issues, the BIOS may switch the lights + * back on, and we turn it back off once we "unblank". + * + * So here is an attempt to implement ">=" - if we are in the process + * of unblanking, and the LCD bit is unset in the driver but set in the + * register, we must keep it. + */ + lcdflags = ((par->PanelDispCntlReg1 | tmpdisp) & 0x02); /* LCD normal */ dpmsflags = 0x00; /* no hsync/vsync suppression */ break; case FB_BLANK_UNBLANK: /* unblank */ seqflags = 0; /* Enable sequencer */ - lcdflags = par->PanelDispCntlReg1 & 0x02; /* LCD normal */ + lcdflags = ((par->PanelDispCntlReg1 | tmpdisp) & 0x02); /* LCD normal */ dpmsflags = 0x00; /* no hsync/vsync suppression */ #ifdef CONFIG_TOSHIBA /* Do we still need this ? */ diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c index 99c3a8e6a237..9ed640d35728 100644 --- a/drivers/video/nvidia/nv_hw.c +++ b/drivers/video/nvidia/nv_hw.c @@ -886,7 +886,10 @@ void NVCalcStateExt(struct nvidia_par *par, case NV_ARCH_20: case NV_ARCH_30: default: - if (((par->Chipset & 0xffff) == 0x01A0) || + if ((par->Chipset & 0xfff0) == 0x0240) { + state->arbitration0 = 256; + state->arbitration1 = 0x0480; + } else if (((par->Chipset & 0xffff) == 0x01A0) || ((par->Chipset & 0xffff) == 0x01f0)) { nForceUpdateArbitrationSettings(VClk, pixelDepth * 8, @@ -1235,6 +1238,7 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) break; case 0x0160: case 0x01D0: + case 0x0240: NV_WR32(par->PMC, 0x1700, NV_RD32(par->PFB, 0x020C)); NV_WR32(par->PMC, 0x1704, 0); @@ -1359,7 +1363,9 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) if(((par->Chipset & 0xfff0) != 0x0160) && ((par->Chipset & 0xfff0) - != 0x0220)) + != 0x0220) && + ((par->Chipset & 0xfff0) + != 0x240)) NV_WR32(par->PGRAPH, 0x6900 + i*4, NV_RD32(par->PFB, diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c index 1edb1c432b75..19eef3a09023 100644 --- a/drivers/video/nvidia/nv_i2c.c +++ b/drivers/video/nvidia/nv_i2c.c @@ -10,7 +10,6 @@ * for more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> diff --git a/drivers/video/nvidia/nv_of.c b/drivers/video/nvidia/nv_of.c index 7a03d040b1a3..8209106e26ee 100644 --- a/drivers/video/nvidia/nv_of.c +++ b/drivers/video/nvidia/nv_of.c @@ -10,7 +10,6 @@ * for more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index 03a7c1e9ce38..b02d6033cc0c 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c @@ -9,7 +9,6 @@ * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -67,359 +66,10 @@ #define MAX_CURS 32 static struct pci_device_id nvidiafb_pci_tbl[] = { - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UTNT2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT_UNKNOWN, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_VTNT2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UVTNT2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_ITNT2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440_SE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_460_GO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_200, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_410_GO_M16, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440_8X, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440SE_8X, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420_8X, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_4000, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_448_GO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_488_GO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_580_XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_MAC, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_280_NVS, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_380_XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_IGEFORCE2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_1, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_DDC, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_4200_GO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_980_XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_780_XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700_GOGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_2000, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1000, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600SE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5600, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5650, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO700, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_1, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200SE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5200, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5250, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5250_32, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO_5200, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_NVS_280_PCI, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_500, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5300, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5100, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900XT, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5950_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_3000, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700LE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700VE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_1, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO1000, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1100, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5500, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5100, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_700, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900ZT, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_LE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_GT, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_4000, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6600_GT, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6600, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6610_XL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_540, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6200, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_ALT1, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT1, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6200_ALT1, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_GT, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_QUADRO_NVS280, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0252, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0313, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0316, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0317, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x031D, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x031E, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x031F, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0329, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x032F, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0345, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0349, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x034B, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x034F, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x00c0, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_6800A, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_6800A_LE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_GO_6800, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_GO_6800_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_QUADRO_FX_GO1400, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x00cd, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_QUADRO_FX_1400, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0142, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0143, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0144, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0145, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0146, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0147, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0148, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0149, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x014b, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x14c, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x014d, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0160, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6200_TURBOCACHE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0162, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0163, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6200, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0165, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6250, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6200_1, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6250_1, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0169, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x016b, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x016c, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x016d, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x016e, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0210, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B_LE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B_GT, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GT, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GTX, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800_GTX, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x021d, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x021e, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0220, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0221, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0222, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0228, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0,} /* terminate list */ + {PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_BASE_CLASS_DISPLAY << 16, 0xff0000, 0}, + { 0, } }; - MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl); /* command line data, set in nvidiafb_setup() */ @@ -1465,10 +1115,10 @@ static u32 __devinit nvidia_get_chipset(struct fb_info *info) struct nvidia_par *par = info->par; u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device; - printk("nvidiafb: PCI id - %x\n", id); + printk(KERN_INFO PFX "Device ID: %x \n", id); + if ((id & 0xfff0) == 0x00f0) { /* pci-e */ - printk("nvidiafb: PCI-E card\n"); id = NV_RD32(par->REGS, 0x1800); if ((id & 0x0000ffff) == 0x000010DE) @@ -1476,9 +1126,9 @@ static u32 __devinit nvidia_get_chipset(struct fb_info *info) else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */ id = 0x10DE0000 | ((id << 8) & 0x0000ff00) | ((id >> 8) & 0x000000ff); + printk(KERN_INFO PFX "Subsystem ID: %x \n", id); } - printk("nvidiafb: Actual id - %x\n", id); return id; } @@ -1520,6 +1170,7 @@ static u32 __devinit nvidia_get_arch(struct fb_info *info) case 0x0210: case 0x0220: case 0x0230: + case 0x0240: case 0x0290: case 0x0390: arch = NV_ARCH_40; @@ -1567,7 +1218,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, if (pci_request_regions(pd, "nvidiafb")) { printk(KERN_ERR PFX "cannot request PCI regions\n"); - goto err_out_request; + goto err_out_enable; } par->FlatPanel = flatpanel; @@ -1596,7 +1247,6 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, } par->Chipset = nvidia_get_chipset(info); - printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset); par->Architecture = nvidia_get_arch(info); if (par->Architecture == 0) { @@ -1687,10 +1337,8 @@ err_out_free_base1: nvidia_delete_i2c_busses(par); err_out_arch: iounmap(par->REGS); -err_out_free_base0: + err_out_free_base0: pci_release_regions(pd); -err_out_request: - pci_disable_device(pd); err_out_enable: kfree(info->pixmap.addr); err_out_kfree: @@ -1720,7 +1368,6 @@ static void __exit nvidiafb_remove(struct pci_dev *pd) nvidia_delete_i2c_busses(par); iounmap(par->REGS); pci_release_regions(pd); - pci_disable_device(pd); kfree(info->pixmap.addr); framebuffer_release(info); pci_set_drvdata(pd, NULL); diff --git a/drivers/video/offb.c b/drivers/video/offb.c index ad1434e3f227..71ce1fa45cf4 100644 --- a/drivers/video/offb.c +++ b/drivers/video/offb.c @@ -12,7 +12,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -98,14 +97,43 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) { struct offb_par *par = (struct offb_par *) info->par; + int i, depth; + u32 *pal = info->pseudo_palette; - if (!par->cmap_adr || regno > 255) + depth = info->var.bits_per_pixel; + if (depth == 16) + depth = (info->var.green.length == 5) ? 15 : 16; + + if (regno > 255 || + (depth == 16 && regno > 63) || + (depth == 15 && regno > 31)) return 1; + if (regno < 16) { + switch (depth) { + case 15: + pal[regno] = (regno << 10) | (regno << 5) | regno; + break; + case 16: + pal[regno] = (regno << 11) | (regno << 5) | regno; + break; + case 24: + pal[regno] = (regno << 16) | (regno << 8) | regno; + break; + case 32: + i = (regno << 8) | regno; + pal[regno] = (i << 16) | i; + break; + } + } + red >>= 8; green >>= 8; blue >>= 8; + if (!par->cmap_adr) + return 0; + switch (par->cmap_type) { case cmap_m64: writeb(regno, par->cmap_adr); @@ -142,20 +170,6 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, break; } - if (regno < 16) - switch (info->var.bits_per_pixel) { - case 16: - ((u16 *) (info->pseudo_palette))[regno] = - (regno << 10) | (regno << 5) | regno; - break; - case 32: - { - int i = (regno << 8) | regno; - ((u32 *) (info->pseudo_palette))[regno] = - (i << 16) | i; - break; - } - } return 0; } @@ -224,81 +238,9 @@ int __init offb_init(void) { struct device_node *dp = NULL, *boot_disp = NULL; -#if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) - struct device_node *macos_display = NULL; -#endif if (fb_get_options("offb", NULL)) return -ENODEV; -#if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) - /* If we're booted from BootX... */ - if (boot_infos != 0) { - unsigned long addr = - (unsigned long) boot_infos->dispDeviceBase; - u32 *addrp; - u64 daddr, dsize; - unsigned int flags; - - /* find the device node corresponding to the macos display */ - while ((dp = of_find_node_by_type(dp, "display"))) { - int i; - - /* - * Look for an AAPL,address property first. - */ - unsigned int na; - unsigned int *ap = - (unsigned int *)get_property(dp, "AAPL,address", - &na); - if (ap != 0) { - for (na /= sizeof(unsigned int); na > 0; - --na, ++ap) - if (*ap <= addr && - addr < *ap + 0x1000000) { - macos_display = dp; - goto foundit; - } - } - - /* - * See if the display address is in one of the address - * ranges for this display. - */ - i = 0; - for (;;) { - addrp = of_get_address(dp, i++, &dsize, &flags); - if (addrp == NULL) - break; - if (!(flags & IORESOURCE_MEM)) - continue; - daddr = of_translate_address(dp, addrp); - if (daddr == OF_BAD_ADDR) - continue; - if (daddr <= addr && addr < (daddr + dsize)) { - macos_display = dp; - goto foundit; - } - } - foundit: - if (macos_display) { - printk(KERN_INFO "MacOS display is %s\n", - dp->full_name); - break; - } - } - - /* initialize it */ - offb_init_fb(macos_display ? macos_display-> - name : "MacOS display", - macos_display ? macos_display-> - full_name : "MacOS display", - boot_infos->dispDeviceRect[2], - boot_infos->dispDeviceRect[3], - boot_infos->dispDeviceDepth, - boot_infos->dispDeviceRowBytes, addr, NULL); - } -#endif /* defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) */ - for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) { if (get_property(dp, "linux,opened", NULL) && get_property(dp, "linux,boot-display", NULL)) { @@ -318,94 +260,93 @@ int __init offb_init(void) static void __init offb_init_nodriver(struct device_node *dp) { - int *pp, i; unsigned int len; - int width = 640, height = 480, depth = 8, pitch; - unsigned int flags, rsize, *up; - u64 address = OF_BAD_ADDR; - u32 *addrp; + int i, width = 640, height = 480, depth = 8, pitch = 640; + unsigned int flags, rsize, addr_prop = 0; + unsigned long max_size = 0; + u64 rstart, address = OF_BAD_ADDR; + u32 *pp, *addrp, *up; u64 asize; - if ((pp = (int *) get_property(dp, "depth", &len)) != NULL - && len == sizeof(int)) + pp = (u32 *)get_property(dp, "linux,bootx-depth", &len); + if (pp == NULL) + pp = (u32 *)get_property(dp, "depth", &len); + if (pp && len == sizeof(u32)) depth = *pp; - if ((pp = (int *) get_property(dp, "width", &len)) != NULL - && len == sizeof(int)) + + pp = (u32 *)get_property(dp, "linux,bootx-width", &len); + if (pp == NULL) + pp = (u32 *)get_property(dp, "width", &len); + if (pp && len == sizeof(u32)) width = *pp; - if ((pp = (int *) get_property(dp, "height", &len)) != NULL - && len == sizeof(int)) + + pp = (u32 *)get_property(dp, "linux,bootx-height", &len); + if (pp == NULL) + pp = (u32 *)get_property(dp, "height", &len); + if (pp && len == sizeof(u32)) height = *pp; - if ((pp = (int *) get_property(dp, "linebytes", &len)) != NULL - && len == sizeof(int)) { + + pp = (u32 *)get_property(dp, "linux,bootx-linebytes", &len); + if (pp == NULL) + pp = (u32 *)get_property(dp, "linebytes", &len); + if (pp && len == sizeof(u32)) pitch = *pp; - if (pitch == 1) - pitch = 0x1000; - } else - pitch = width; - - rsize = (unsigned long)pitch * (unsigned long)height * - (unsigned long)(depth / 8); - - /* Try to match device to a PCI device in order to get a properly - * translated address rather then trying to decode the open firmware - * stuff in various incorrect ways - */ -#ifdef CONFIG_PCI - /* First try to locate the PCI device if any */ - { - struct pci_dev *pdev = NULL; - - for_each_pci_dev(pdev) { - if (dp == pci_device_to_OF_node(pdev)) - break; - } - if (pdev) { - for (i = 0; i < 6 && address == OF_BAD_ADDR; i++) { - if ((pci_resource_flags(pdev, i) & - IORESOURCE_MEM) && - (pci_resource_len(pdev, i) >= rsize)) - address = pci_resource_start(pdev, i); - } - pci_dev_put(pdev); - } - } -#endif /* CONFIG_PCI */ - - /* This one is dodgy, we may drop it ... */ - if (address == OF_BAD_ADDR && - (up = (unsigned *) get_property(dp, "address", &len)) != NULL && - len == sizeof(unsigned int)) - address = (u64) * up; - - if (address == OF_BAD_ADDR) { - for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags)) - != NULL; i++) { - if (!(flags & IORESOURCE_MEM)) - continue; - if (asize >= pitch * height * depth / 8) - break; - } - if (addrp == NULL) { - printk(KERN_ERR - "no framebuffer address found for %s\n", - dp->full_name); - return; - } - address = of_translate_address(dp, addrp); - if (address == OF_BAD_ADDR) { - printk(KERN_ERR - "can't translate framebuffer address for %s\n", - dp->full_name); - return; + else + pitch = width * ((depth + 7) / 8); + + rsize = (unsigned long)pitch * (unsigned long)height; + + /* Ok, now we try to figure out the address of the framebuffer. + * + * Unfortunately, Open Firmware doesn't provide a standard way to do + * so. All we can do is a dodgy heuristic that happens to work in + * practice. On most machines, the "address" property contains what + * we need, though not on Matrox cards found in IBM machines. What I've + * found that appears to give good results is to go through the PCI + * ranges and pick one that is both big enough and if possible encloses + * the "address" property. If none match, we pick the biggest + */ + up = (u32 *)get_property(dp, "linux,bootx-addr", &len); + if (up == NULL) + up = (u32 *)get_property(dp, "address", &len); + if (up && len == sizeof(u32)) + addr_prop = *up; + + for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags)) + != NULL; i++) { + int match_addrp = 0; + + if (!(flags & IORESOURCE_MEM)) + continue; + if (asize < rsize) + continue; + rstart = of_translate_address(dp, addrp); + if (rstart == OF_BAD_ADDR) + continue; + if (addr_prop && (rstart <= addr_prop) && + ((rstart + asize) >= (addr_prop + rsize))) + match_addrp = 1; + if (match_addrp) { + address = addr_prop; + break; } + if (rsize > max_size) { + max_size = rsize; + address = OF_BAD_ADDR; + } + if (address == OF_BAD_ADDR) + address = rstart; + } + if (address == OF_BAD_ADDR && addr_prop) + address = (u64)addr_prop; + if (address != OF_BAD_ADDR) { /* kludge for valkyrie */ if (strcmp(dp->name, "valkyrie") == 0) address += 0x1000; + offb_init_fb(dp->name, dp->full_name, width, height, depth, + pitch, address, dp); } - offb_init_fb(dp->name, dp->full_name, width, height, depth, - pitch, address, dp); - } static void __init offb_init_fb(const char *name, const char *full_name, @@ -413,7 +354,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, int pitch, unsigned long address, struct device_node *dp) { - unsigned long res_size = pitch * height * depth / 8; + unsigned long res_size = pitch * height * (depth + 7) / 8; struct offb_par *par = &default_par; unsigned long res_start = address; struct fb_fix_screeninfo *fix; @@ -427,7 +368,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, printk(KERN_INFO "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n", width, height, name, address, depth, pitch); - if (depth != 8 && depth != 16 && depth != 32) { + if (depth != 8 && depth != 15 && depth != 16 && depth != 32) { printk(KERN_ERR "%s: can't use depth = %d\n", full_name, depth); release_mem_region(res_start, res_size); @@ -503,7 +444,6 @@ static void __init offb_init_fb(const char *name, const char *full_name, : */ FB_VISUAL_TRUECOLOR; var->xoffset = var->yoffset = 0; - var->bits_per_pixel = depth; switch (depth) { case 8: var->bits_per_pixel = 8; @@ -516,7 +456,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, var->transp.offset = 0; var->transp.length = 0; break; - case 16: /* RGB 555 */ + case 15: /* RGB 555 */ var->bits_per_pixel = 16; var->red.offset = 10; var->red.length = 5; @@ -527,6 +467,17 @@ static void __init offb_init_fb(const char *name, const char *full_name, var->transp.offset = 0; var->transp.length = 0; break; + case 16: /* RGB 565 */ + var->bits_per_pixel = 16; + var->red.offset = 11; + var->red.length = 5; + var->green.offset = 5; + var->green.length = 6; + var->blue.offset = 0; + var->blue.length = 5; + var->transp.offset = 0; + var->transp.length = 0; + break; case 32: /* RGB 888 */ var->bits_per_pixel = 32; var->red.offset = 16; diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c index 0d1957505359..56ac51d6a7f3 100644 --- a/drivers/video/p9100.c +++ b/drivers/video/p9100.c @@ -1,6 +1,6 @@ /* p9100.c: P9100 frame buffer driver * - * Copyright (C) 2003 David S. Miller (davem@redhat.com) + * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) * Copyright 1999 Derrick J Brashear (shadow@dementia.org) * * Driver layout based loosely on tgafb.c, see that file for credits. @@ -17,8 +17,8 @@ #include <linux/mm.h> #include <asm/io.h> -#include <asm/sbus.h> -#include <asm/oplib.h> +#include <asm/prom.h> +#include <asm/of_device.h> #include <asm/fbio.h> #include "sbuslib.h" @@ -72,60 +72,60 @@ static struct fb_ops p9100_ops = { struct p9100_regs { /* Registers for the system control */ - volatile u32 sys_base; - volatile u32 sys_config; - volatile u32 sys_intr; - volatile u32 sys_int_ena; - volatile u32 sys_alt_rd; - volatile u32 sys_alt_wr; - volatile u32 sys_xxx[58]; + u32 sys_base; + u32 sys_config; + u32 sys_intr; + u32 sys_int_ena; + u32 sys_alt_rd; + u32 sys_alt_wr; + u32 sys_xxx[58]; /* Registers for the video control */ - volatile u32 vid_base; - volatile u32 vid_hcnt; - volatile u32 vid_htotal; - volatile u32 vid_hsync_rise; - volatile u32 vid_hblank_rise; - volatile u32 vid_hblank_fall; - volatile u32 vid_hcnt_preload; - volatile u32 vid_vcnt; - volatile u32 vid_vlen; - volatile u32 vid_vsync_rise; - volatile u32 vid_vblank_rise; - volatile u32 vid_vblank_fall; - volatile u32 vid_vcnt_preload; - volatile u32 vid_screenpaint_addr; - volatile u32 vid_screenpaint_timectl1; - volatile u32 vid_screenpaint_qsfcnt; - volatile u32 vid_screenpaint_timectl2; - volatile u32 vid_xxx[15]; + u32 vid_base; + u32 vid_hcnt; + u32 vid_htotal; + u32 vid_hsync_rise; + u32 vid_hblank_rise; + u32 vid_hblank_fall; + u32 vid_hcnt_preload; + u32 vid_vcnt; + u32 vid_vlen; + u32 vid_vsync_rise; + u32 vid_vblank_rise; + u32 vid_vblank_fall; + u32 vid_vcnt_preload; + u32 vid_screenpaint_addr; + u32 vid_screenpaint_timectl1; + u32 vid_screenpaint_qsfcnt; + u32 vid_screenpaint_timectl2; + u32 vid_xxx[15]; /* Registers for the video control */ - volatile u32 vram_base; - volatile u32 vram_memcfg; - volatile u32 vram_refresh_pd; - volatile u32 vram_refresh_cnt; - volatile u32 vram_raslo_max; - volatile u32 vram_raslo_cur; - volatile u32 pwrup_cfg; - volatile u32 vram_xxx[25]; + u32 vram_base; + u32 vram_memcfg; + u32 vram_refresh_pd; + u32 vram_refresh_cnt; + u32 vram_raslo_max; + u32 vram_raslo_cur; + u32 pwrup_cfg; + u32 vram_xxx[25]; /* Registers for IBM RGB528 Palette */ - volatile u32 ramdac_cmap_wridx; - volatile u32 ramdac_palette_data; - volatile u32 ramdac_pixel_mask; - volatile u32 ramdac_palette_rdaddr; - volatile u32 ramdac_idx_lo; - volatile u32 ramdac_idx_hi; - volatile u32 ramdac_idx_data; - volatile u32 ramdac_idx_ctl; - volatile u32 ramdac_xxx[1784]; + u32 ramdac_cmap_wridx; + u32 ramdac_palette_data; + u32 ramdac_pixel_mask; + u32 ramdac_palette_rdaddr; + u32 ramdac_idx_lo; + u32 ramdac_idx_hi; + u32 ramdac_idx_data; + u32 ramdac_idx_ctl; + u32 ramdac_xxx[1784]; }; struct p9100_cmd_parameng { - volatile u32 parameng_status; - volatile u32 parameng_bltcmd; - volatile u32 parameng_quadcmd; + u32 parameng_status; + u32 parameng_bltcmd; + u32 parameng_quadcmd; }; struct p9100_par { @@ -136,9 +136,8 @@ struct p9100_par { #define P9100_FLAG_BLANKED 0x00000001 unsigned long physbase; + unsigned long which_io; unsigned long fbsize; - - struct sbus_dev *sdev; }; /** @@ -227,8 +226,7 @@ static int p9100_mmap(struct fb_info *info, struct vm_area_struct *vma) return sbusfb_mmap_helper(p9100_mmap_map, par->physbase, par->fbsize, - par->sdev->reg_addrs[0].which_io, - vma); + par->which_io, vma); } static int p9100_ioctl(struct fb_info *info, unsigned int cmd, @@ -245,12 +243,9 @@ static int p9100_ioctl(struct fb_info *info, unsigned int cmd, * Initialisation */ -static void -p9100_init_fix(struct fb_info *info, int linebytes) +static void p9100_init_fix(struct fb_info *info, int linebytes, struct device_node *dp) { - struct p9100_par *par = (struct p9100_par *)info->par; - - strlcpy(info->fix.id, par->sdev->prom_name, sizeof(info->fix.id)); + strlcpy(info->fix.id, dp->name, sizeof(info->fix.id)); info->fix.type = FB_TYPE_PACKED_PIXELS; info->fix.visual = FB_VISUAL_PSEUDOCOLOR; @@ -263,121 +258,137 @@ p9100_init_fix(struct fb_info *info, int linebytes) struct all_info { struct fb_info info; struct p9100_par par; - struct list_head list; }; -static LIST_HEAD(p9100_list); -static void p9100_init_one(struct sbus_dev *sdev) +static int __devinit p9100_init_one(struct of_device *op) { + struct device_node *dp = op->node; struct all_info *all; - int linebytes; - - all = kmalloc(sizeof(*all), GFP_KERNEL); - if (!all) { - printk(KERN_ERR "p9100: Cannot allocate memory.\n"); - return; - } - memset(all, 0, sizeof(*all)); + int linebytes, err; - INIT_LIST_HEAD(&all->list); + all = kzalloc(sizeof(*all), GFP_KERNEL); + if (!all) + return -ENOMEM; spin_lock_init(&all->par.lock); - all->par.sdev = sdev; /* This is the framebuffer and the only resource apps can mmap. */ - all->par.physbase = sdev->reg_addrs[2].phys_addr; + all->par.physbase = op->resource[2].start; + all->par.which_io = op->resource[2].flags & IORESOURCE_BITS; - sbusfb_fill_var(&all->info.var, sdev->prom_node, 8); + sbusfb_fill_var(&all->info.var, dp->node, 8); all->info.var.red.length = 8; all->info.var.green.length = 8; all->info.var.blue.length = 8; - linebytes = prom_getintdefault(sdev->prom_node, "linebytes", - all->info.var.xres); + linebytes = of_getintprop_default(dp, "linebytes", + all->info.var.xres); all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); - all->par.regs = sbus_ioremap(&sdev->resource[0], 0, - sizeof(struct p9100_regs), "p9100 regs"); + all->par.regs = of_ioremap(&op->resource[0], 0, + sizeof(struct p9100_regs), "p9100 regs"); + if (!all->par.regs) { + kfree(all); + return -ENOMEM; + } all->info.flags = FBINFO_DEFAULT; all->info.fbops = &p9100_ops; -#ifdef CONFIG_SPARC32 - all->info.screen_base = (char __iomem *) - prom_getintdefault(sdev->prom_node, "address", 0); -#endif - if (!all->info.screen_base) - all->info.screen_base = sbus_ioremap(&sdev->resource[2], 0, - all->par.fbsize, "p9100 ram"); + all->info.screen_base = of_ioremap(&op->resource[2], 0, + all->par.fbsize, "p9100 ram"); + if (!all->info.screen_base) { + of_iounmap(all->par.regs, sizeof(struct p9100_regs)); + kfree(all); + return -ENOMEM; + } all->info.par = &all->par; p9100_blank(0, &all->info); if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { - printk(KERN_ERR "p9100: Could not allocate color map.\n"); + of_iounmap(all->par.regs, sizeof(struct p9100_regs)); + of_iounmap(all->info.screen_base, all->par.fbsize); kfree(all); - return; + return -ENOMEM; } - p9100_init_fix(&all->info, linebytes); + p9100_init_fix(&all->info, linebytes, dp); - if (register_framebuffer(&all->info) < 0) { - printk(KERN_ERR "p9100: Could not register framebuffer.\n"); + err = register_framebuffer(&all->info); + if (err < 0) { fb_dealloc_cmap(&all->info.cmap); + of_iounmap(all->par.regs, sizeof(struct p9100_regs)); + of_iounmap(all->info.screen_base, all->par.fbsize); kfree(all); - return; + return err; } fb_set_cmap(&all->info.cmap, &all->info); - list_add(&all->list, &p9100_list); + dev_set_drvdata(&op->dev, all); + + printk("%s: p9100 at %lx:%lx\n", + dp->full_name, + all->par.which_io, all->par.physbase); - printk("p9100: %s at %lx:%lx\n", - sdev->prom_name, - (long) sdev->reg_addrs[0].which_io, - (long) sdev->reg_addrs[0].phys_addr); + return 0; } -int __init p9100_init(void) +static int __devinit p9100_probe(struct of_device *dev, const struct of_device_id *match) { - struct sbus_bus *sbus; - struct sbus_dev *sdev; + struct of_device *op = to_of_device(&dev->dev); - if (fb_get_options("p9100fb", NULL)) - return -ENODEV; + return p9100_init_one(op); +} - for_all_sbusdev(sdev, sbus) { - if (!strcmp(sdev->prom_name, "p9100")) - p9100_init_one(sdev); - } +static int __devexit p9100_remove(struct of_device *dev) +{ + struct all_info *all = dev_get_drvdata(&dev->dev); + + unregister_framebuffer(&all->info); + fb_dealloc_cmap(&all->info.cmap); + + of_iounmap(all->par.regs, sizeof(struct p9100_regs)); + of_iounmap(all->info.screen_base, all->par.fbsize); + + kfree(all); + + dev_set_drvdata(&dev->dev, NULL); return 0; } -void __exit p9100_exit(void) -{ - struct list_head *pos, *tmp; +static struct of_device_id p9100_match[] = { + { + .name = "p9100", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, p9100_match); - list_for_each_safe(pos, tmp, &p9100_list) { - struct all_info *all = list_entry(pos, typeof(*all), list); +static struct of_platform_driver p9100_driver = { + .name = "p9100", + .match_table = p9100_match, + .probe = p9100_probe, + .remove = __devexit_p(p9100_remove), +}; - unregister_framebuffer(&all->info); - fb_dealloc_cmap(&all->info.cmap); - kfree(all); - } +static int __init p9100_init(void) +{ + if (fb_get_options("p9100fb", NULL)) + return -ENODEV; + + return of_register_driver(&p9100_driver, &of_bus_type); } -int __init -p9100_setup(char *arg) +static void __exit p9100_exit(void) { - /* No cmdline options yet... */ - return 0; + of_unregister_driver(&p9100_driver); } module_init(p9100_init); - -#ifdef MODULE module_exit(p9100_exit); -#endif MODULE_DESCRIPTION("framebuffer driver for P9100 chipsets"); -MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); +MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); +MODULE_VERSION("2.0"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index 335e37465559..450e802e0aa8 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c @@ -17,7 +17,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c index 4e963930b50a..49a203e1591c 100644 --- a/drivers/video/pm2fb.c +++ b/drivers/video/pm2fb.c @@ -27,7 +27,6 @@ * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c index 52c18a35fb41..0e0f977b05ee 100644 --- a/drivers/video/pm3fb.c +++ b/drivers/video/pm3fb.c @@ -52,7 +52,6 @@ * Wed Feb 21 14:47:06 CET 2001, v 1.0.0: First working version */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c index ec4bacf9dd2e..4a1e0e856920 100644 --- a/drivers/video/pvr2fb.c +++ b/drivers/video/pvr2fb.c @@ -56,7 +56,6 @@ #include <linux/tty.h> #include <linux/slab.h> #include <linux/delay.h> -#include <linux/config.h> #include <linux/interrupt.h> #include <linux/fb.h> #include <linux/init.h> diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 809fc5eefc15..bbb07106cd54 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -22,7 +22,6 @@ * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> @@ -1335,7 +1334,7 @@ int __init pxafb_probe(struct platform_device *dev) goto failed; } - ret = request_irq(IRQ_LCD, pxafb_handle_irq, SA_INTERRUPT, "LCD", fbi); + ret = request_irq(IRQ_LCD, pxafb_handle_irq, IRQF_DISABLED, "LCD", fbi); if (ret) { dev_err(&dev->dev, "request_irq failed: %d\n", ret); ret = -EBUSY; diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index d4384ab1df65..2788655e6e7d 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -29,7 +29,6 @@ * doublescan modes are broken */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -2152,7 +2151,6 @@ err_iounmap_ctrl_base: err_release_region: pci_release_regions(pd); err_disable_device: - pci_disable_device(pd); err_free_pixmap: kfree(info->pixmap.addr); err_framebuffer_release: @@ -2187,7 +2185,6 @@ static void __exit rivafb_remove(struct pci_dev *pd) if (par->riva.Architecture == NV_ARCH_03) iounmap(par->riva.PRAMIN); pci_release_regions(pd); - pci_disable_device(pd); kfree(info->pixmap.addr); framebuffer_release(info); pci_set_drvdata(pd, NULL); diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c index 8b1967fc116a..9751c37c0bfd 100644 --- a/drivers/video/riva/rivafb-i2c.c +++ b/drivers/video/riva/rivafb-i2c.c @@ -12,7 +12,6 @@ * for more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> diff --git a/drivers/video/riva/rivafb.h b/drivers/video/riva/rivafb.h index 440ff445689b..7fa13fc9c413 100644 --- a/drivers/video/riva/rivafb.h +++ b/drivers/video/riva/rivafb.h @@ -1,7 +1,6 @@ #ifndef __RIVAFB_H #define __RIVAFB_H -#include <linux/config.h> #include <linux/fb.h> #include <video/vga.h> #include <linux/i2c.h> diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c index feec47bdd479..a5333c190789 100644 --- a/drivers/video/s1d13xxxfb.c +++ b/drivers/video/s1d13xxxfb.c @@ -28,7 +28,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/delay.h> diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index 9451932fbaf2..f461eb10cc79 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c @@ -641,6 +641,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) int ret; int irq; int i; + u32 lcdcon1; mach_info = pdev->dev.platform_data; if (mach_info == NULL) { @@ -672,6 +673,11 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) memcpy(&info->regs, &mach_info->regs, sizeof(info->regs)); + /* Stop the video and unset ENVID if set */ + info->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID; + lcdcon1 = readl(S3C2410_LCDCON1); + writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1); + info->mach_info = pdev->dev.platform_data; fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; @@ -729,7 +735,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) dprintk("got LCD region\n"); - ret = request_irq(irq, s3c2410fb_irq, SA_INTERRUPT, pdev->name, info); + ret = request_irq(irq, s3c2410fb_irq, IRQF_DISABLED, pdev->name, info); if (ret) { dev_err(&pdev->dev, "cannot get irq %d - err %d\n", irq, ret); ret = -EBUSY; @@ -794,15 +800,14 @@ dealloc_fb: * shutdown the lcd controller */ -static void s3c2410fb_stop_lcd(void) +static void s3c2410fb_stop_lcd(struct s3c2410fb_info *fbi) { unsigned long flags; - unsigned long tmp; local_irq_save(flags); - tmp = readl(S3C2410_LCDCON1); - writel(tmp & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1); + fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID; + writel(fbi->regs.lcdcon1, S3C2410_LCDCON1); local_irq_restore(flags); } @@ -816,7 +821,7 @@ static int s3c2410fb_remove(struct platform_device *pdev) struct s3c2410fb_info *info = fbinfo->par; int irq; - s3c2410fb_stop_lcd(); + s3c2410fb_stop_lcd(info); msleep(1); s3c2410fb_unmap_video_memory(info); @@ -844,7 +849,7 @@ static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state) struct fb_info *fbinfo = platform_get_drvdata(dev); struct s3c2410fb_info *info = fbinfo->par; - s3c2410fb_stop_lcd(); + s3c2410fb_stop_lcd(info); /* sleep before disabling the clock, we need to ensure * the LCD DMA engine is not going to get back on the bus diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c index d9831fd42341..a2e6e7205d7e 100644 --- a/drivers/video/sa1100fb.c +++ b/drivers/video/sa1100fb.c @@ -160,7 +160,6 @@ * - Add patch 681/1 and clean up stork definitions. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -1473,7 +1472,7 @@ static int __init sa1100fb_probe(struct platform_device *pdev) if (ret) goto failed; - ret = request_irq(irq, sa1100fb_handle_irq, SA_INTERRUPT, + ret = request_irq(irq, sa1100fb_handle_irq, IRQF_DISABLED, "LCD", fbi); if (ret) { printk(KERN_ERR "sa1100fb: request_irq failed: %d\n", ret); diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c index 21debed863ac..e83befd16d63 100644 --- a/drivers/video/savage/savagefb-i2c.c +++ b/drivers/video/savage/savagefb-i2c.c @@ -10,7 +10,6 @@ * for more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h index 58cfdfb41833..e648a6c0f6d9 100644 --- a/drivers/video/savage/savagefb.h +++ b/drivers/video/savage/savagefb.h @@ -147,7 +147,27 @@ struct xtimings { int interlaced; }; +struct savage_reg { + unsigned char MiscOutReg; /* Misc */ + unsigned char CRTC[25]; /* Crtc Controller */ + unsigned char Sequencer[5]; /* Video Sequencer */ + unsigned char Graphics[9]; /* Video Graphics */ + unsigned char Attribute[21]; /* Video Atribute */ + unsigned int mode, refresh; + unsigned char SR08, SR0E, SR0F; + unsigned char SR10, SR11, SR12, SR13, SR15, SR18, SR29, SR30; + unsigned char SR54[8]; + unsigned char Clock; + unsigned char CR31, CR32, CR33, CR34, CR36, CR3A, CR3B, CR3C; + unsigned char CR40, CR41, CR42, CR43, CR45; + unsigned char CR50, CR51, CR53, CR55, CR58, CR5B, CR5D, CR5E; + unsigned char CR60, CR63, CR65, CR66, CR67, CR68, CR69, CR6D, CR6F; + unsigned char CR86, CR88; + unsigned char CR90, CR91, CRB0; + unsigned int STREAMS[22]; /* yuck, streams regs */ + unsigned int MMPR0, MMPR1, MMPR2, MMPR3; +}; /* --------------------------------------------------------------------- */ #define NR_PALETTE 256 @@ -167,6 +187,8 @@ struct savagefb_par { struct pci_dev *pcidev; savage_chipset chip; struct savagefb_i2c_chan chan; + struct savage_reg state; + struct savage_reg save; unsigned char *edid; u32 pseudo_palette[16]; int paletteEnabled; @@ -179,6 +201,7 @@ struct savagefb_par { int minClock; int numClocks; int clock[4]; + int MCLK, REFCLK, LCDclk; struct { u8 __iomem *vbase; u32 pbase; @@ -196,7 +219,6 @@ struct savagefb_par { volatile u32 __iomem *bci_base; unsigned int bci_ptr; - u32 cob_offset; u32 cob_size; int cob_index; @@ -204,7 +226,6 @@ struct savagefb_par { void (*SavageWaitIdle) (struct savagefb_par *par); void (*SavageWaitFifo) (struct savagefb_par *par, int space); - int MCLK, REFCLK, LCDclk; int HorizScaleFactor; /* Panels size */ @@ -217,26 +238,6 @@ struct savagefb_par { int depth; int vwidth; - - unsigned char MiscOutReg; /* Misc */ - unsigned char CRTC[25]; /* Crtc Controller */ - unsigned char Sequencer[5]; /* Video Sequencer */ - unsigned char Graphics[9]; /* Video Graphics */ - unsigned char Attribute[21]; /* Video Atribute */ - - unsigned int mode, refresh; - unsigned char SR08, SR0E, SR0F; - unsigned char SR10, SR11, SR12, SR13, SR15, SR18, SR29, SR30; - unsigned char SR54[8]; - unsigned char Clock; - unsigned char CR31, CR32, CR33, CR34, CR36, CR3A, CR3B, CR3C; - unsigned char CR40, CR41, CR42, CR43, CR45; - unsigned char CR50, CR51, CR53, CR55, CR58, CR5B, CR5D, CR5E; - unsigned char CR60, CR63, CR65, CR66, CR67, CR68, CR69, CR6D, CR6F; - unsigned char CR86, CR88; - unsigned char CR90, CR91, CRB0; - unsigned int STREAMS[22]; /* yuck, streams regs */ - unsigned int MMPR0, MMPR1, MMPR2, MMPR3; }; #define BCI_BD_BW_DISABLE 0x10000000 diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index 0da624e6524f..4729af477fbf 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c @@ -41,7 +41,6 @@ * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -86,15 +85,15 @@ MODULE_DESCRIPTION("FBDev driver for S3 Savage PCI/AGP Chips"); /* --------------------------------------------------------------------- */ -static void vgaHWSeqReset (struct savagefb_par *par, int start) +static void vgaHWSeqReset(struct savagefb_par *par, int start) { if (start) - VGAwSEQ (0x00, 0x01, par); /* Synchronous Reset */ + VGAwSEQ(0x00, 0x01, par); /* Synchronous Reset */ else - VGAwSEQ (0x00, 0x03, par); /* End Reset */ + VGAwSEQ(0x00, 0x03, par); /* End Reset */ } -static void vgaHWProtect (struct savagefb_par *par, int on) +static void vgaHWProtect(struct savagefb_par *par, int on) { unsigned char tmp; @@ -102,10 +101,10 @@ static void vgaHWProtect (struct savagefb_par *par, int on) /* * Turn off screen and disable sequencer. */ - tmp = VGArSEQ (0x01, par); + tmp = VGArSEQ(0x01, par); - vgaHWSeqReset (par, 1); /* start synchronous reset */ - VGAwSEQ (0x01, tmp | 0x20, par);/* disable the display */ + vgaHWSeqReset(par, 1); /* start synchronous reset */ + VGAwSEQ(0x01, tmp | 0x20, par);/* disable the display */ VGAenablePalette(par); } else { @@ -113,75 +112,76 @@ static void vgaHWProtect (struct savagefb_par *par, int on) * Reenable sequencer, then turn on screen. */ - tmp = VGArSEQ (0x01, par); + tmp = VGArSEQ(0x01, par); - VGAwSEQ (0x01, tmp & ~0x20, par);/* reenable display */ - vgaHWSeqReset (par, 0); /* clear synchronous reset */ + VGAwSEQ(0x01, tmp & ~0x20, par);/* reenable display */ + vgaHWSeqReset(par, 0); /* clear synchronous reset */ VGAdisablePalette(par); } } -static void vgaHWRestore (struct savagefb_par *par) +static void vgaHWRestore(struct savagefb_par *par, struct savage_reg *reg) { int i; - VGAwMISC (par->MiscOutReg, par); + VGAwMISC(reg->MiscOutReg, par); for (i = 1; i < 5; i++) - VGAwSEQ (i, par->Sequencer[i], par); + VGAwSEQ(i, reg->Sequencer[i], par); /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */ - VGAwCR (17, par->CRTC[17] & ~0x80, par); + VGAwCR(17, reg->CRTC[17] & ~0x80, par); for (i = 0; i < 25; i++) - VGAwCR (i, par->CRTC[i], par); + VGAwCR(i, reg->CRTC[i], par); for (i = 0; i < 9; i++) - VGAwGR (i, par->Graphics[i], par); + VGAwGR(i, reg->Graphics[i], par); VGAenablePalette(par); for (i = 0; i < 21; i++) - VGAwATTR (i, par->Attribute[i], par); + VGAwATTR(i, reg->Attribute[i], par); VGAdisablePalette(par); } -static void vgaHWInit (struct fb_var_screeninfo *var, - struct savagefb_par *par, - struct xtimings *timings) +static void vgaHWInit(struct fb_var_screeninfo *var, + struct savagefb_par *par, + struct xtimings *timings, + struct savage_reg *reg) { - par->MiscOutReg = 0x23; + reg->MiscOutReg = 0x23; if (!(timings->sync & FB_SYNC_HOR_HIGH_ACT)) - par->MiscOutReg |= 0x40; + reg->MiscOutReg |= 0x40; if (!(timings->sync & FB_SYNC_VERT_HIGH_ACT)) - par->MiscOutReg |= 0x80; + reg->MiscOutReg |= 0x80; /* * Time Sequencer */ - par->Sequencer[0x00] = 0x00; - par->Sequencer[0x01] = 0x01; - par->Sequencer[0x02] = 0x0F; - par->Sequencer[0x03] = 0x00; /* Font select */ - par->Sequencer[0x04] = 0x0E; /* Misc */ + reg->Sequencer[0x00] = 0x00; + reg->Sequencer[0x01] = 0x01; + reg->Sequencer[0x02] = 0x0F; + reg->Sequencer[0x03] = 0x00; /* Font select */ + reg->Sequencer[0x04] = 0x0E; /* Misc */ /* * CRTC Controller */ - par->CRTC[0x00] = (timings->HTotal >> 3) - 5; - par->CRTC[0x01] = (timings->HDisplay >> 3) - 1; - par->CRTC[0x02] = (timings->HSyncStart >> 3) - 1; - par->CRTC[0x03] = (((timings->HSyncEnd >> 3) - 1) & 0x1f) | 0x80; - par->CRTC[0x04] = (timings->HSyncStart >> 3); - par->CRTC[0x05] = ((((timings->HSyncEnd >> 3) - 1) & 0x20) << 2) | + reg->CRTC[0x00] = (timings->HTotal >> 3) - 5; + reg->CRTC[0x01] = (timings->HDisplay >> 3) - 1; + reg->CRTC[0x02] = (timings->HSyncStart >> 3) - 1; + reg->CRTC[0x03] = (((timings->HSyncEnd >> 3) - 1) & 0x1f) | 0x80; + reg->CRTC[0x04] = (timings->HSyncStart >> 3); + reg->CRTC[0x05] = ((((timings->HSyncEnd >> 3) - 1) & 0x20) << 2) | (((timings->HSyncEnd >> 3)) & 0x1f); - par->CRTC[0x06] = (timings->VTotal - 2) & 0xFF; - par->CRTC[0x07] = (((timings->VTotal - 2) & 0x100) >> 8) | + reg->CRTC[0x06] = (timings->VTotal - 2) & 0xFF; + reg->CRTC[0x07] = (((timings->VTotal - 2) & 0x100) >> 8) | (((timings->VDisplay - 1) & 0x100) >> 7) | ((timings->VSyncStart & 0x100) >> 6) | (((timings->VSyncStart - 1) & 0x100) >> 5) | @@ -189,27 +189,27 @@ static void vgaHWInit (struct fb_var_screeninfo *var, (((timings->VTotal - 2) & 0x200) >> 4) | (((timings->VDisplay - 1) & 0x200) >> 3) | ((timings->VSyncStart & 0x200) >> 2); - par->CRTC[0x08] = 0x00; - par->CRTC[0x09] = (((timings->VSyncStart - 1) & 0x200) >> 4) | 0x40; + reg->CRTC[0x08] = 0x00; + reg->CRTC[0x09] = (((timings->VSyncStart - 1) & 0x200) >> 4) | 0x40; if (timings->dblscan) - par->CRTC[0x09] |= 0x80; - - par->CRTC[0x0a] = 0x00; - par->CRTC[0x0b] = 0x00; - par->CRTC[0x0c] = 0x00; - par->CRTC[0x0d] = 0x00; - par->CRTC[0x0e] = 0x00; - par->CRTC[0x0f] = 0x00; - par->CRTC[0x10] = timings->VSyncStart & 0xff; - par->CRTC[0x11] = (timings->VSyncEnd & 0x0f) | 0x20; - par->CRTC[0x12] = (timings->VDisplay - 1) & 0xff; - par->CRTC[0x13] = var->xres_virtual >> 4; - par->CRTC[0x14] = 0x00; - par->CRTC[0x15] = (timings->VSyncStart - 1) & 0xff; - par->CRTC[0x16] = (timings->VSyncEnd - 1) & 0xff; - par->CRTC[0x17] = 0xc3; - par->CRTC[0x18] = 0xff; + reg->CRTC[0x09] |= 0x80; + + reg->CRTC[0x0a] = 0x00; + reg->CRTC[0x0b] = 0x00; + reg->CRTC[0x0c] = 0x00; + reg->CRTC[0x0d] = 0x00; + reg->CRTC[0x0e] = 0x00; + reg->CRTC[0x0f] = 0x00; + reg->CRTC[0x10] = timings->VSyncStart & 0xff; + reg->CRTC[0x11] = (timings->VSyncEnd & 0x0f) | 0x20; + reg->CRTC[0x12] = (timings->VDisplay - 1) & 0xff; + reg->CRTC[0x13] = var->xres_virtual >> 4; + reg->CRTC[0x14] = 0x00; + reg->CRTC[0x15] = (timings->VSyncStart - 1) & 0xff; + reg->CRTC[0x16] = (timings->VSyncEnd - 1) & 0xff; + reg->CRTC[0x17] = 0xc3; + reg->CRTC[0x18] = 0xff; /* * are these unnecessary? @@ -220,38 +220,38 @@ static void vgaHWInit (struct fb_var_screeninfo *var, /* * Graphics Display Controller */ - par->Graphics[0x00] = 0x00; - par->Graphics[0x01] = 0x00; - par->Graphics[0x02] = 0x00; - par->Graphics[0x03] = 0x00; - par->Graphics[0x04] = 0x00; - par->Graphics[0x05] = 0x40; - par->Graphics[0x06] = 0x05; /* only map 64k VGA memory !!!! */ - par->Graphics[0x07] = 0x0F; - par->Graphics[0x08] = 0xFF; - - - par->Attribute[0x00] = 0x00; /* standard colormap translation */ - par->Attribute[0x01] = 0x01; - par->Attribute[0x02] = 0x02; - par->Attribute[0x03] = 0x03; - par->Attribute[0x04] = 0x04; - par->Attribute[0x05] = 0x05; - par->Attribute[0x06] = 0x06; - par->Attribute[0x07] = 0x07; - par->Attribute[0x08] = 0x08; - par->Attribute[0x09] = 0x09; - par->Attribute[0x0a] = 0x0A; - par->Attribute[0x0b] = 0x0B; - par->Attribute[0x0c] = 0x0C; - par->Attribute[0x0d] = 0x0D; - par->Attribute[0x0e] = 0x0E; - par->Attribute[0x0f] = 0x0F; - par->Attribute[0x10] = 0x41; - par->Attribute[0x11] = 0xFF; - par->Attribute[0x12] = 0x0F; - par->Attribute[0x13] = 0x00; - par->Attribute[0x14] = 0x00; + reg->Graphics[0x00] = 0x00; + reg->Graphics[0x01] = 0x00; + reg->Graphics[0x02] = 0x00; + reg->Graphics[0x03] = 0x00; + reg->Graphics[0x04] = 0x00; + reg->Graphics[0x05] = 0x40; + reg->Graphics[0x06] = 0x05; /* only map 64k VGA memory !!!! */ + reg->Graphics[0x07] = 0x0F; + reg->Graphics[0x08] = 0xFF; + + + reg->Attribute[0x00] = 0x00; /* standard colormap translation */ + reg->Attribute[0x01] = 0x01; + reg->Attribute[0x02] = 0x02; + reg->Attribute[0x03] = 0x03; + reg->Attribute[0x04] = 0x04; + reg->Attribute[0x05] = 0x05; + reg->Attribute[0x06] = 0x06; + reg->Attribute[0x07] = 0x07; + reg->Attribute[0x08] = 0x08; + reg->Attribute[0x09] = 0x09; + reg->Attribute[0x0a] = 0x0A; + reg->Attribute[0x0b] = 0x0B; + reg->Attribute[0x0c] = 0x0C; + reg->Attribute[0x0d] = 0x0D; + reg->Attribute[0x0e] = 0x0E; + reg->Attribute[0x0f] = 0x0F; + reg->Attribute[0x10] = 0x41; + reg->Attribute[0x11] = 0xFF; + reg->Attribute[0x12] = 0x0F; + reg->Attribute[0x13] = 0x00; + reg->Attribute[0x14] = 0x00; } /* -------------------- Hardware specific routines ------------------------- */ @@ -304,15 +304,15 @@ savage2000_waitidle(struct savagefb_par *par) while ((savage_in32(0x48C60, par) & 0x009fffff)); } - +#ifdef CONFIG_FB_SAVAGE_ACCEL static void -SavageSetup2DEngine (struct savagefb_par *par) +SavageSetup2DEngine(struct savagefb_par *par) { unsigned long GlobalBitmapDescriptor; GlobalBitmapDescriptor = 1 | 8 | BCI_BD_BW_DISABLE; - BCI_BD_SET_BPP (GlobalBitmapDescriptor, par->depth); - BCI_BD_SET_STRIDE (GlobalBitmapDescriptor, par->vwidth); + BCI_BD_SET_BPP(GlobalBitmapDescriptor, par->depth); + BCI_BD_SET_STRIDE(GlobalBitmapDescriptor, par->vwidth); switch(par->chip) { case S3_SAVAGE3D: @@ -361,32 +361,48 @@ SavageSetup2DEngine (struct savagefb_par *par) vga_out8(0x3d5, 0x0c, par); /* Set stride to use GBD. */ - vga_out8 (0x3d4, 0x50, par); - vga_out8 (0x3d5, vga_in8(0x3d5, par) | 0xC1, par); + vga_out8(0x3d4, 0x50, par); + vga_out8(0x3d5, vga_in8(0x3d5, par) | 0xC1, par); /* Enable 2D engine. */ - vga_out8 (0x3d4, 0x40, par); - vga_out8 (0x3d5, 0x01, par); + vga_out8(0x3d4, 0x40, par); + vga_out8(0x3d5, 0x01, par); - savage_out32 (MONO_PAT_0, ~0, par); - savage_out32 (MONO_PAT_1, ~0, par); + savage_out32(MONO_PAT_0, ~0, par); + savage_out32(MONO_PAT_1, ~0, par); /* Setup plane masks */ - savage_out32 (0x8128, ~0, par); /* enable all write planes */ - savage_out32 (0x812C, ~0, par); /* enable all read planes */ - savage_out16 (0x8134, 0x27, par); - savage_out16 (0x8136, 0x07, par); + savage_out32(0x8128, ~0, par); /* enable all write planes */ + savage_out32(0x812C, ~0, par); /* enable all read planes */ + savage_out16(0x8134, 0x27, par); + savage_out16(0x8136, 0x07, par); /* Now set the GBD */ par->bci_ptr = 0; - par->SavageWaitFifo (par, 4); + par->SavageWaitFifo(par, 4); - BCI_SEND( BCI_CMD_SETREG | (1 << 16) | BCI_GBD1 ); - BCI_SEND( 0 ); - BCI_SEND( BCI_CMD_SETREG | (1 << 16) | BCI_GBD2 ); - BCI_SEND( GlobalBitmapDescriptor ); + BCI_SEND(BCI_CMD_SETREG | (1 << 16) | BCI_GBD1); + BCI_SEND(0); + BCI_SEND(BCI_CMD_SETREG | (1 << 16) | BCI_GBD2); + BCI_SEND(GlobalBitmapDescriptor); } +static void savagefb_set_clip(struct fb_info *info) +{ + struct savagefb_par *par = info->par; + int cmd; + + cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW; + par->bci_ptr = 0; + par->SavageWaitFifo(par,3); + BCI_SEND(cmd); + BCI_SEND(BCI_CLIP_TL(0, 0)); + BCI_SEND(BCI_CLIP_BR(0xfff, 0xfff)); +} +#else +static void SavageSetup2DEngine(struct savagefb_par *par) {} + +#endif static void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1, int min_n2, int max_n2, long freq_min, @@ -398,11 +414,11 @@ static void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1, unsigned char n1, n2, best_n1=16+2, best_n2=2, best_m=125+2; if (freq < freq_min / (1 << max_n2)) { - printk (KERN_ERR "invalid frequency %ld Khz\n", freq); + printk(KERN_ERR "invalid frequency %ld Khz\n", freq); freq = freq_min / (1 << max_n2); } if (freq > freq_max / (1 << min_n2)) { - printk (KERN_ERR "invalid frequency %ld Khz\n", freq); + printk(KERN_ERR "invalid frequency %ld Khz\n", freq); freq = freq_max / (1 << min_n2); } @@ -453,12 +469,12 @@ static int common_calc_clock(long freq, int min_m, int min_n1, int max_n1, BASE_FREQ; if (m < min_m + 2 || m > 127+2) continue; - if((m * BASE_FREQ >= freq_min * n1) && - (m * BASE_FREQ <= freq_max * n1)) { + if ((m * BASE_FREQ >= freq_min * n1) && + (m * BASE_FREQ <= freq_max * n1)) { diff = freq * (1 << n2) * n1 - BASE_FREQ * m; - if(diff < 0) + if (diff < 0) diff = -diff; - if(diff < best_diff) { + if (diff < best_diff) { best_diff = diff; best_m = m; best_n1 = n1; @@ -468,7 +484,7 @@ static int common_calc_clock(long freq, int min_m, int min_n1, int max_n1, } } - if(max_n1 == 63) + if (max_n1 == 63) *ndiv = (best_n1 - 2) | (best_n2 << 6); else *ndiv = (best_n1 - 2) | (best_n2 << 5); @@ -488,23 +504,23 @@ static void SavagePrintRegs(void) int vgaCRReg = 0x3d5; printk(KERN_DEBUG "SR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE " - "xF" ); + "xF"); - for( i = 0; i < 0x70; i++ ) { - if( !(i % 16) ) - printk(KERN_DEBUG "\nSR%xx ", i >> 4 ); - vga_out8( 0x3c4, i, par); - printk(KERN_DEBUG " %02x", vga_in8(0x3c5, par) ); + for (i = 0; i < 0x70; i++) { + if (!(i % 16)) + printk(KERN_DEBUG "\nSR%xx ", i >> 4); + vga_out8(0x3c4, i, par); + printk(KERN_DEBUG " %02x", vga_in8(0x3c5, par)); } printk(KERN_DEBUG "\n\nCR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC " - "xD xE xF" ); + "xD xE xF"); - for( i = 0; i < 0xB7; i++ ) { - if( !(i % 16) ) - printk(KERN_DEBUG "\nCR%xx ", i >> 4 ); - vga_out8( vgaCRIndex, i, par); - printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg, par) ); + for (i = 0; i < 0xB7; i++) { + if (!(i % 16)) + printk(KERN_DEBUG "\nCR%xx ", i >> 4); + vga_out8(vgaCRIndex, i, par); + printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg, par)); } printk(KERN_DEBUG "\n\n"); @@ -513,156 +529,309 @@ static void SavagePrintRegs(void) /* --------------------------------------------------------------------- */ -static void savage_get_default_par(struct savagefb_par *par) +static void savage_get_default_par(struct savagefb_par *par, struct savage_reg *reg) { unsigned char cr3a, cr53, cr66; - vga_out16 (0x3d4, 0x4838, par); - vga_out16 (0x3d4, 0xa039, par); - vga_out16 (0x3c4, 0x0608, par); - - vga_out8 (0x3d4, 0x66, par); - cr66 = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr66 | 0x80, par); - vga_out8 (0x3d4, 0x3a, par); - cr3a = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr3a | 0x80, par); - vga_out8 (0x3d4, 0x53, par); - cr53 = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr53 & 0x7f, par); - - vga_out8 (0x3d4, 0x66, par); - vga_out8 (0x3d5, cr66, par); - vga_out8 (0x3d4, 0x3a, par); - vga_out8 (0x3d5, cr3a, par); - - vga_out8 (0x3d4, 0x66, par); - vga_out8 (0x3d5, cr66, par); - vga_out8 (0x3d4, 0x3a, par); - vga_out8 (0x3d5, cr3a, par); + vga_out16(0x3d4, 0x4838, par); + vga_out16(0x3d4, 0xa039, par); + vga_out16(0x3c4, 0x0608, par); + + vga_out8(0x3d4, 0x66, par); + cr66 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr66 | 0x80, par); + vga_out8(0x3d4, 0x3a, par); + cr3a = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr3a | 0x80, par); + vga_out8(0x3d4, 0x53, par); + cr53 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr53 & 0x7f, par); + + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, cr66, par); + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, cr3a, par); + + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, cr66, par); + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, cr3a, par); /* unlock extended seq regs */ - vga_out8 (0x3c4, 0x08, par); - par->SR08 = vga_in8 (0x3c5, par); - vga_out8 (0x3c5, 0x06, par); + vga_out8(0x3c4, 0x08, par); + reg->SR08 = vga_in8(0x3c5, par); + vga_out8(0x3c5, 0x06, par); /* now save all the extended regs we need */ - vga_out8 (0x3d4, 0x31, par); - par->CR31 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x32, par); - par->CR32 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x34, par); - par->CR34 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x36, par); - par->CR36 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x3a, par); - par->CR3A = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x40, par); - par->CR40 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x42, par); - par->CR42 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x45, par); - par->CR45 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x50, par); - par->CR50 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x51, par); - par->CR51 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x53, par); - par->CR53 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x58, par); - par->CR58 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x60, par); - par->CR60 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x66, par); - par->CR66 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x67, par); - par->CR67 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x68, par); - par->CR68 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x69, par); - par->CR69 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x6f, par); - par->CR6F = vga_in8 (0x3d5, par); - - vga_out8 (0x3d4, 0x33, par); - par->CR33 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x86, par); - par->CR86 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x88, par); - par->CR88 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x90, par); - par->CR90 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x91, par); - par->CR91 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0xb0, par); - par->CRB0 = vga_in8 (0x3d5, par) | 0x80; + vga_out8(0x3d4, 0x31, par); + reg->CR31 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x32, par); + reg->CR32 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x34, par); + reg->CR34 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x36, par); + reg->CR36 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x3a, par); + reg->CR3A = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x40, par); + reg->CR40 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x42, par); + reg->CR42 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x45, par); + reg->CR45 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x50, par); + reg->CR50 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x51, par); + reg->CR51 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x53, par); + reg->CR53 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x58, par); + reg->CR58 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x60, par); + reg->CR60 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x66, par); + reg->CR66 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x67, par); + reg->CR67 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x68, par); + reg->CR68 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x69, par); + reg->CR69 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x6f, par); + reg->CR6F = vga_in8(0x3d5, par); + + vga_out8(0x3d4, 0x33, par); + reg->CR33 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x86, par); + reg->CR86 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x88, par); + reg->CR88 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x90, par); + reg->CR90 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x91, par); + reg->CR91 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0xb0, par); + reg->CRB0 = vga_in8(0x3d5, par) | 0x80; + + /* extended mode timing regs */ + vga_out8(0x3d4, 0x3b, par); + reg->CR3B = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x3c, par); + reg->CR3C = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x43, par); + reg->CR43 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x5d, par); + reg->CR5D = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x5e, par); + reg->CR5E = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x65, par); + reg->CR65 = vga_in8(0x3d5, par); + + /* save seq extended regs for DCLK PLL programming */ + vga_out8(0x3c4, 0x0e, par); + reg->SR0E = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x0f, par); + reg->SR0F = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x10, par); + reg->SR10 = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x11, par); + reg->SR11 = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x12, par); + reg->SR12 = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x13, par); + reg->SR13 = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x29, par); + reg->SR29 = vga_in8(0x3c5, par); + + vga_out8(0x3c4, 0x15, par); + reg->SR15 = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x30, par); + reg->SR30 = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x18, par); + reg->SR18 = vga_in8(0x3c5, par); + + /* Save flat panel expansion regsters. */ + if (par->chip == S3_SAVAGE_MX) { + int i; + + for (i = 0; i < 8; i++) { + vga_out8(0x3c4, 0x54+i, par); + reg->SR54[i] = vga_in8(0x3c5, par); + } + } + + vga_out8(0x3d4, 0x66, par); + cr66 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr66 | 0x80, par); + vga_out8(0x3d4, 0x3a, par); + cr3a = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr3a | 0x80, par); + + /* now save MIU regs */ + if (par->chip != S3_SAVAGE_MX) { + reg->MMPR0 = savage_in32(FIFO_CONTROL_REG, par); + reg->MMPR1 = savage_in32(MIU_CONTROL_REG, par); + reg->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG, par); + reg->MMPR3 = savage_in32(MISC_TIMEOUT_REG, par); + } + + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, cr3a, par); + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, cr66, par); +} + +static void savage_set_default_par(struct savagefb_par *par, + struct savage_reg *reg) +{ + unsigned char cr3a, cr53, cr66; + + vga_out16(0x3d4, 0x4838, par); + vga_out16(0x3d4, 0xa039, par); + vga_out16(0x3c4, 0x0608, par); + + vga_out8(0x3d4, 0x66, par); + cr66 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr66 | 0x80, par); + vga_out8(0x3d4, 0x3a, par); + cr3a = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr3a | 0x80, par); + vga_out8(0x3d4, 0x53, par); + cr53 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr53 & 0x7f, par); + + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, cr66, par); + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, cr3a, par); + + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, cr66, par); + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, cr3a, par); + + /* unlock extended seq regs */ + vga_out8(0x3c4, 0x08, par); + vga_out8(0x3c5, reg->SR08, par); + vga_out8(0x3c5, 0x06, par); + + /* now restore all the extended regs we need */ + vga_out8(0x3d4, 0x31, par); + vga_out8(0x3d5, reg->CR31, par); + vga_out8(0x3d4, 0x32, par); + vga_out8(0x3d5, reg->CR32, par); + vga_out8(0x3d4, 0x34, par); + vga_out8(0x3d5, reg->CR34, par); + vga_out8(0x3d4, 0x36, par); + vga_out8(0x3d5,reg->CR36, par); + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, reg->CR3A, par); + vga_out8(0x3d4, 0x40, par); + vga_out8(0x3d5, reg->CR40, par); + vga_out8(0x3d4, 0x42, par); + vga_out8(0x3d5, reg->CR42, par); + vga_out8(0x3d4, 0x45, par); + vga_out8(0x3d5, reg->CR45, par); + vga_out8(0x3d4, 0x50, par); + vga_out8(0x3d5, reg->CR50, par); + vga_out8(0x3d4, 0x51, par); + vga_out8(0x3d5, reg->CR51, par); + vga_out8(0x3d4, 0x53, par); + vga_out8(0x3d5, reg->CR53, par); + vga_out8(0x3d4, 0x58, par); + vga_out8(0x3d5, reg->CR58, par); + vga_out8(0x3d4, 0x60, par); + vga_out8(0x3d5, reg->CR60, par); + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, reg->CR66, par); + vga_out8(0x3d4, 0x67, par); + vga_out8(0x3d5, reg->CR67, par); + vga_out8(0x3d4, 0x68, par); + vga_out8(0x3d5, reg->CR68, par); + vga_out8(0x3d4, 0x69, par); + vga_out8(0x3d5, reg->CR69, par); + vga_out8(0x3d4, 0x6f, par); + vga_out8(0x3d5, reg->CR6F, par); + + vga_out8(0x3d4, 0x33, par); + vga_out8(0x3d5, reg->CR33, par); + vga_out8(0x3d4, 0x86, par); + vga_out8(0x3d5, reg->CR86, par); + vga_out8(0x3d4, 0x88, par); + vga_out8(0x3d5, reg->CR88, par); + vga_out8(0x3d4, 0x90, par); + vga_out8(0x3d5, reg->CR90, par); + vga_out8(0x3d4, 0x91, par); + vga_out8(0x3d5, reg->CR91, par); + vga_out8(0x3d4, 0xb0, par); + vga_out8(0x3d5, reg->CRB0, par); /* extended mode timing regs */ - vga_out8 (0x3d4, 0x3b, par); - par->CR3B = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x3c, par); - par->CR3C = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x43, par); - par->CR43 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x5d, par); - par->CR5D = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x5e, par); - par->CR5E = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x65, par); - par->CR65 = vga_in8 (0x3d5, par); + vga_out8(0x3d4, 0x3b, par); + vga_out8(0x3d5, reg->CR3B, par); + vga_out8(0x3d4, 0x3c, par); + vga_out8(0x3d5, reg->CR3C, par); + vga_out8(0x3d4, 0x43, par); + vga_out8(0x3d5, reg->CR43, par); + vga_out8(0x3d4, 0x5d, par); + vga_out8(0x3d5, reg->CR5D, par); + vga_out8(0x3d4, 0x5e, par); + vga_out8(0x3d5, reg->CR5E, par); + vga_out8(0x3d4, 0x65, par); + vga_out8(0x3d5, reg->CR65, par); /* save seq extended regs for DCLK PLL programming */ - vga_out8 (0x3c4, 0x0e, par); - par->SR0E = vga_in8 (0x3c5, par); - vga_out8 (0x3c4, 0x0f, par); - par->SR0F = vga_in8 (0x3c5, par); - vga_out8 (0x3c4, 0x10, par); - par->SR10 = vga_in8 (0x3c5, par); - vga_out8 (0x3c4, 0x11, par); - par->SR11 = vga_in8 (0x3c5, par); - vga_out8 (0x3c4, 0x12, par); - par->SR12 = vga_in8 (0x3c5, par); - vga_out8 (0x3c4, 0x13, par); - par->SR13 = vga_in8 (0x3c5, par); - vga_out8 (0x3c4, 0x29, par); - par->SR29 = vga_in8 (0x3c5, par); - - vga_out8 (0x3c4, 0x15, par); - par->SR15 = vga_in8 (0x3c5, par); - vga_out8 (0x3c4, 0x30, par); - par->SR30 = vga_in8 (0x3c5, par); - vga_out8 (0x3c4, 0x18, par); - par->SR18 = vga_in8 (0x3c5, par); + vga_out8(0x3c4, 0x0e, par); + vga_out8(0x3c5, reg->SR0E, par); + vga_out8(0x3c4, 0x0f, par); + vga_out8(0x3c5, reg->SR0F, par); + vga_out8(0x3c4, 0x10, par); + vga_out8(0x3c5, reg->SR10, par); + vga_out8(0x3c4, 0x11, par); + vga_out8(0x3c5, reg->SR11, par); + vga_out8(0x3c4, 0x12, par); + vga_out8(0x3c5, reg->SR12, par); + vga_out8(0x3c4, 0x13, par); + vga_out8(0x3c5, reg->SR13, par); + vga_out8(0x3c4, 0x29, par); + vga_out8(0x3c5, reg->SR29, par); + + vga_out8(0x3c4, 0x15, par); + vga_out8(0x3c5, reg->SR15, par); + vga_out8(0x3c4, 0x30, par); + vga_out8(0x3c5, reg->SR30, par); + vga_out8(0x3c4, 0x18, par); + vga_out8(0x3c5, reg->SR18, par); /* Save flat panel expansion regsters. */ if (par->chip == S3_SAVAGE_MX) { int i; for (i = 0; i < 8; i++) { - vga_out8 (0x3c4, 0x54+i, par); - par->SR54[i] = vga_in8 (0x3c5, par); + vga_out8(0x3c4, 0x54+i, par); + vga_out8(0x3c5, reg->SR54[i], par); } } - vga_out8 (0x3d4, 0x66, par); - cr66 = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr66 | 0x80, par); - vga_out8 (0x3d4, 0x3a, par); - cr3a = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr3a | 0x80, par); + vga_out8(0x3d4, 0x66, par); + cr66 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr66 | 0x80, par); + vga_out8(0x3d4, 0x3a, par); + cr3a = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr3a | 0x80, par); /* now save MIU regs */ if (par->chip != S3_SAVAGE_MX) { - par->MMPR0 = savage_in32(FIFO_CONTROL_REG, par); - par->MMPR1 = savage_in32(MIU_CONTROL_REG, par); - par->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG, par); - par->MMPR3 = savage_in32(MISC_TIMEOUT_REG, par); + savage_out32(FIFO_CONTROL_REG, reg->MMPR0, par); + savage_out32(MIU_CONTROL_REG, reg->MMPR1, par); + savage_out32(STREAMS_TIMEOUT_REG, reg->MMPR2, par); + savage_out32(MISC_TIMEOUT_REG, reg->MMPR3, par); } - vga_out8 (0x3d4, 0x3a, par); - vga_out8 (0x3d5, cr3a, par); - vga_out8 (0x3d4, 0x66, par); - vga_out8 (0x3d5, cr66, par); + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, cr3a, par); + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, cr66, par); } static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb) @@ -683,8 +852,8 @@ static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode var->vmode = modedb->vmode; } -static int savagefb_check_var (struct fb_var_screeninfo *var, - struct fb_info *info) +static int savagefb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) { struct savagefb_par *par = info->par; int memlen, vramlen, mode_valid = 0; @@ -750,10 +919,10 @@ static int savagefb_check_var (struct fb_var_screeninfo *var, if (par->SavagePanelWidth && (var->xres > par->SavagePanelWidth || var->yres > par->SavagePanelHeight)) { - printk (KERN_INFO "Mode (%dx%d) larger than the LCD panel " - "(%dx%d)\n", var->xres, var->yres, - par->SavagePanelWidth, - par->SavagePanelHeight); + printk(KERN_INFO "Mode (%dx%d) larger than the LCD panel " + "(%dx%d)\n", var->xres, var->yres, + par->SavagePanelWidth, + par->SavagePanelHeight); return -1; } @@ -788,8 +957,9 @@ static int savagefb_check_var (struct fb_var_screeninfo *var, } -static int savagefb_decode_var (struct fb_var_screeninfo *var, - struct savagefb_par *par) +static int savagefb_decode_var(struct fb_var_screeninfo *var, + struct savagefb_par *par, + struct savage_reg *reg) { struct xtimings timings; int width, dclk, i, j; /*, refresh; */ @@ -799,7 +969,7 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var, DBG("savagefb_decode_var"); - memset (&timings, 0, sizeof(timings)); + memset(&timings, 0, sizeof(timings)); if (!pixclock) pixclock = 10000; /* 10ns = 100MHz */ timings.Clock = 1000000000 / pixclock; @@ -831,39 +1001,39 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var, * This will allocate the datastructure and initialize all of the * generic VGA registers. */ - vgaHWInit (var, par, &timings); + vgaHWInit(var, par, &timings, reg); /* We need to set CR67 whether or not we use the BIOS. */ dclk = timings.Clock; - par->CR67 = 0x00; + reg->CR67 = 0x00; - switch( var->bits_per_pixel ) { + switch(var->bits_per_pixel) { case 8: - if( (par->chip == S3_SAVAGE2000) && (dclk >= 230000) ) - par->CR67 = 0x10; /* 8bpp, 2 pixels/clock */ + if ((par->chip == S3_SAVAGE2000) && (dclk >= 230000)) + reg->CR67 = 0x10; /* 8bpp, 2 pixels/clock */ else - par->CR67 = 0x00; /* 8bpp, 1 pixel/clock */ + reg->CR67 = 0x00; /* 8bpp, 1 pixel/clock */ break; case 15: - if ( S3_SAVAGE_MOBILE_SERIES(par->chip) || - ((par->chip == S3_SAVAGE2000) && (dclk >= 230000)) ) - par->CR67 = 0x30; /* 15bpp, 2 pixel/clock */ + if (S3_SAVAGE_MOBILE_SERIES(par->chip) || + ((par->chip == S3_SAVAGE2000) && (dclk >= 230000))) + reg->CR67 = 0x30; /* 15bpp, 2 pixel/clock */ else - par->CR67 = 0x20; /* 15bpp, 1 pixels/clock */ + reg->CR67 = 0x20; /* 15bpp, 1 pixels/clock */ break; case 16: - if( S3_SAVAGE_MOBILE_SERIES(par->chip) || - ((par->chip == S3_SAVAGE2000) && (dclk >= 230000)) ) - par->CR67 = 0x50; /* 16bpp, 2 pixel/clock */ + if (S3_SAVAGE_MOBILE_SERIES(par->chip) || + ((par->chip == S3_SAVAGE2000) && (dclk >= 230000))) + reg->CR67 = 0x50; /* 16bpp, 2 pixel/clock */ else - par->CR67 = 0x40; /* 16bpp, 1 pixels/clock */ + reg->CR67 = 0x40; /* 16bpp, 1 pixels/clock */ break; case 24: - par->CR67 = 0x70; + reg->CR67 = 0x70; break; case 32: - par->CR67 = 0xd0; + reg->CR67 = 0xd0; break; } @@ -872,61 +1042,61 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var, * match. Fall back to traditional register-crunching. */ - vga_out8 (0x3d4, 0x3a, par); - tmp = vga_in8 (0x3d5, par); + vga_out8(0x3d4, 0x3a, par); + tmp = vga_in8(0x3d5, par); if (1 /*FIXME:psav->pci_burst*/) - par->CR3A = (tmp & 0x7f) | 0x15; + reg->CR3A = (tmp & 0x7f) | 0x15; else - par->CR3A = tmp | 0x95; + reg->CR3A = tmp | 0x95; - par->CR53 = 0x00; - par->CR31 = 0x8c; - par->CR66 = 0x89; + reg->CR53 = 0x00; + reg->CR31 = 0x8c; + reg->CR66 = 0x89; - vga_out8 (0x3d4, 0x58, par); - par->CR58 = vga_in8 (0x3d5, par) & 0x80; - par->CR58 |= 0x13; + vga_out8(0x3d4, 0x58, par); + reg->CR58 = vga_in8(0x3d5, par) & 0x80; + reg->CR58 |= 0x13; - par->SR15 = 0x03 | 0x80; - par->SR18 = 0x00; - par->CR43 = par->CR45 = par->CR65 = 0x00; + reg->SR15 = 0x03 | 0x80; + reg->SR18 = 0x00; + reg->CR43 = reg->CR45 = reg->CR65 = 0x00; - vga_out8 (0x3d4, 0x40, par); - par->CR40 = vga_in8 (0x3d5, par) & ~0x01; + vga_out8(0x3d4, 0x40, par); + reg->CR40 = vga_in8(0x3d5, par) & ~0x01; - par->MMPR0 = 0x010400; - par->MMPR1 = 0x00; - par->MMPR2 = 0x0808; - par->MMPR3 = 0x08080810; + reg->MMPR0 = 0x010400; + reg->MMPR1 = 0x00; + reg->MMPR2 = 0x0808; + reg->MMPR3 = 0x08080810; - SavageCalcClock (dclk, 1, 1, 127, 0, 4, 180000, 360000, &m, &n, &r); + SavageCalcClock(dclk, 1, 1, 127, 0, 4, 180000, 360000, &m, &n, &r); /* m = 107; n = 4; r = 2; */ if (par->MCLK <= 0) { - par->SR10 = 255; - par->SR11 = 255; + reg->SR10 = 255; + reg->SR11 = 255; } else { - common_calc_clock (par->MCLK, 1, 1, 31, 0, 3, 135000, 270000, - &par->SR11, &par->SR10); - /* par->SR10 = 80; // MCLK == 286000 */ - /* par->SR11 = 125; */ + common_calc_clock(par->MCLK, 1, 1, 31, 0, 3, 135000, 270000, + ®->SR11, ®->SR10); + /* reg->SR10 = 80; // MCLK == 286000 */ + /* reg->SR11 = 125; */ } - par->SR12 = (r << 6) | (n & 0x3f); - par->SR13 = m & 0xff; - par->SR29 = (r & 4) | (m & 0x100) >> 5 | (n & 0x40) >> 2; + reg->SR12 = (r << 6) | (n & 0x3f); + reg->SR13 = m & 0xff; + reg->SR29 = (r & 4) | (m & 0x100) >> 5 | (n & 0x40) >> 2; if (var->bits_per_pixel < 24) - par->MMPR0 -= 0x8000; + reg->MMPR0 -= 0x8000; else - par->MMPR0 -= 0x4000; + reg->MMPR0 -= 0x4000; if (timings.interlaced) - par->CR42 = 0x20; + reg->CR42 = 0x20; else - par->CR42 = 0x00; + reg->CR42 = 0x00; - par->CR34 = 0x10; /* display fifo */ + reg->CR34 = 0x10; /* display fifo */ i = ((((timings.HTotal >> 3) - 5) & 0x100) >> 8) | ((((timings.HDisplay >> 3) - 1) & 0x100) >> 7) | @@ -938,77 +1108,77 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var, if ((timings.HSyncEnd >> 3) - (timings.HSyncStart >> 3) > 32) i |= 0x20; - j = (par->CRTC[0] + ((i & 0x01) << 8) + - par->CRTC[4] + ((i & 0x10) << 4) + 1) / 2; + j = (reg->CRTC[0] + ((i & 0x01) << 8) + + reg->CRTC[4] + ((i & 0x10) << 4) + 1) / 2; - if (j - (par->CRTC[4] + ((i & 0x10) << 4)) < 4) { - if (par->CRTC[4] + ((i & 0x10) << 4) + 4 <= - par->CRTC[0] + ((i & 0x01) << 8)) - j = par->CRTC[4] + ((i & 0x10) << 4) + 4; + if (j - (reg->CRTC[4] + ((i & 0x10) << 4)) < 4) { + if (reg->CRTC[4] + ((i & 0x10) << 4) + 4 <= + reg->CRTC[0] + ((i & 0x01) << 8)) + j = reg->CRTC[4] + ((i & 0x10) << 4) + 4; else - j = par->CRTC[0] + ((i & 0x01) << 8) + 1; + j = reg->CRTC[0] + ((i & 0x01) << 8) + 1; } - par->CR3B = j & 0xff; + reg->CR3B = j & 0xff; i |= (j & 0x100) >> 2; - par->CR3C = (par->CRTC[0] + ((i & 0x01) << 8)) / 2; - par->CR5D = i; - par->CR5E = (((timings.VTotal - 2) & 0x400) >> 10) | + reg->CR3C = (reg->CRTC[0] + ((i & 0x01) << 8)) / 2; + reg->CR5D = i; + reg->CR5E = (((timings.VTotal - 2) & 0x400) >> 10) | (((timings.VDisplay - 1) & 0x400) >> 9) | (((timings.VSyncStart) & 0x400) >> 8) | (((timings.VSyncStart) & 0x400) >> 6) | 0x40; width = (var->xres_virtual * ((var->bits_per_pixel+7) / 8)) >> 3; - par->CR91 = par->CRTC[19] = 0xff & width; - par->CR51 = (0x300 & width) >> 4; - par->CR90 = 0x80 | (width >> 8); - par->MiscOutReg |= 0x0c; + reg->CR91 = reg->CRTC[19] = 0xff & width; + reg->CR51 = (0x300 & width) >> 4; + reg->CR90 = 0x80 | (width >> 8); + reg->MiscOutReg |= 0x0c; /* Set frame buffer description. */ if (var->bits_per_pixel <= 8) - par->CR50 = 0; + reg->CR50 = 0; else if (var->bits_per_pixel <= 16) - par->CR50 = 0x10; + reg->CR50 = 0x10; else - par->CR50 = 0x30; + reg->CR50 = 0x30; if (var->xres_virtual <= 640) - par->CR50 |= 0x40; + reg->CR50 |= 0x40; else if (var->xres_virtual == 800) - par->CR50 |= 0x80; + reg->CR50 |= 0x80; else if (var->xres_virtual == 1024) - par->CR50 |= 0x00; + reg->CR50 |= 0x00; else if (var->xres_virtual == 1152) - par->CR50 |= 0x01; + reg->CR50 |= 0x01; else if (var->xres_virtual == 1280) - par->CR50 |= 0xc0; + reg->CR50 |= 0xc0; else if (var->xres_virtual == 1600) - par->CR50 |= 0x81; + reg->CR50 |= 0x81; else - par->CR50 |= 0xc1; /* Use GBD */ + reg->CR50 |= 0xc1; /* Use GBD */ - if( par->chip == S3_SAVAGE2000 ) - par->CR33 = 0x08; + if (par->chip == S3_SAVAGE2000) + reg->CR33 = 0x08; else - par->CR33 = 0x20; + reg->CR33 = 0x20; - par->CRTC[0x17] = 0xeb; + reg->CRTC[0x17] = 0xeb; - par->CR67 |= 1; + reg->CR67 |= 1; vga_out8(0x3d4, 0x36, par); - par->CR36 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x68, par); - par->CR68 = vga_in8 (0x3d5, par); - par->CR69 = 0; - vga_out8 (0x3d4, 0x6f, par); - par->CR6F = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x86, par); - par->CR86 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x88, par); - par->CR88 = vga_in8 (0x3d5, par) | 0x08; - vga_out8 (0x3d4, 0xb0, par); - par->CRB0 = vga_in8 (0x3d5, par) | 0x80; + reg->CR36 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x68, par); + reg->CR68 = vga_in8(0x3d5, par); + reg->CR69 = 0; + vga_out8(0x3d4, 0x6f, par); + reg->CR6F = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x86, par); + reg->CR86 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x88, par); + reg->CR88 = vga_in8(0x3d5, par) | 0x08; + vga_out8(0x3d4, 0xb0, par); + reg->CRB0 = vga_in8(0x3d5, par) | 0x80; return 0; } @@ -1037,11 +1207,11 @@ static int savagefb_setcolreg(unsigned regno, switch (info->var.bits_per_pixel) { case 8: - vga_out8 (0x3c8, regno, par); + vga_out8(0x3c8, regno, par); - vga_out8 (0x3c9, red >> 10, par); - vga_out8 (0x3c9, green >> 10, par); - vga_out8 (0x3c9, blue >> 10, par); + vga_out8(0x3c9, red >> 10, par); + vga_out8(0x3c9, green >> 10, par); + vga_out8(0x3c9, blue >> 10, par); break; case 16: @@ -1075,21 +1245,21 @@ static int savagefb_setcolreg(unsigned regno, return 0; } -static void savagefb_set_par_int (struct savagefb_par *par) +static void savagefb_set_par_int(struct savagefb_par *par, struct savage_reg *reg) { unsigned char tmp, cr3a, cr66, cr67; - DBG ("savagefb_set_par_int"); + DBG("savagefb_set_par_int"); - par->SavageWaitIdle (par); + par->SavageWaitIdle(par); - vga_out8 (0x3c2, 0x23, par); + vga_out8(0x3c2, 0x23, par); - vga_out16 (0x3d4, 0x4838, par); - vga_out16 (0x3d4, 0xa539, par); - vga_out16 (0x3c4, 0x0608, par); + vga_out16(0x3d4, 0x4838, par); + vga_out16(0x3d4, 0xa539, par); + vga_out16(0x3c4, 0x0608, par); - vgaHWProtect (par, 1); + vgaHWProtect(par, 1); /* * Some Savage/MX and /IX systems go nuts when trying to exit the @@ -1099,203 +1269,202 @@ static void savagefb_set_par_int (struct savagefb_par *par) */ VerticalRetraceWait(par); - vga_out8 (0x3d4, 0x67, par); - cr67 = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr67/*par->CR67*/ & ~0x0c, par); /* no STREAMS yet */ + vga_out8(0x3d4, 0x67, par); + cr67 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr67/*par->CR67*/ & ~0x0c, par); /* no STREAMS yet */ - vga_out8 (0x3d4, 0x23, par); - vga_out8 (0x3d5, 0x00, par); - vga_out8 (0x3d4, 0x26, par); - vga_out8 (0x3d5, 0x00, par); + vga_out8(0x3d4, 0x23, par); + vga_out8(0x3d5, 0x00, par); + vga_out8(0x3d4, 0x26, par); + vga_out8(0x3d5, 0x00, par); /* restore extended regs */ - vga_out8 (0x3d4, 0x66, par); - vga_out8 (0x3d5, par->CR66, par); - vga_out8 (0x3d4, 0x3a, par); - vga_out8 (0x3d5, par->CR3A, par); - vga_out8 (0x3d4, 0x31, par); - vga_out8 (0x3d5, par->CR31, par); - vga_out8 (0x3d4, 0x32, par); - vga_out8 (0x3d5, par->CR32, par); - vga_out8 (0x3d4, 0x58, par); - vga_out8 (0x3d5, par->CR58, par); - vga_out8 (0x3d4, 0x53, par); - vga_out8 (0x3d5, par->CR53 & 0x7f, par); - - vga_out16 (0x3c4, 0x0608, par); + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, reg->CR66, par); + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, reg->CR3A, par); + vga_out8(0x3d4, 0x31, par); + vga_out8(0x3d5, reg->CR31, par); + vga_out8(0x3d4, 0x32, par); + vga_out8(0x3d5, reg->CR32, par); + vga_out8(0x3d4, 0x58, par); + vga_out8(0x3d5, reg->CR58, par); + vga_out8(0x3d4, 0x53, par); + vga_out8(0x3d5, reg->CR53 & 0x7f, par); + + vga_out16(0x3c4, 0x0608, par); /* Restore DCLK registers. */ - vga_out8 (0x3c4, 0x0e, par); - vga_out8 (0x3c5, par->SR0E, par); - vga_out8 (0x3c4, 0x0f, par); - vga_out8 (0x3c5, par->SR0F, par); - vga_out8 (0x3c4, 0x29, par); - vga_out8 (0x3c5, par->SR29, par); - vga_out8 (0x3c4, 0x15, par); - vga_out8 (0x3c5, par->SR15, par); + vga_out8(0x3c4, 0x0e, par); + vga_out8(0x3c5, reg->SR0E, par); + vga_out8(0x3c4, 0x0f, par); + vga_out8(0x3c5, reg->SR0F, par); + vga_out8(0x3c4, 0x29, par); + vga_out8(0x3c5, reg->SR29, par); + vga_out8(0x3c4, 0x15, par); + vga_out8(0x3c5, reg->SR15, par); /* Restore flat panel expansion regsters. */ - if( par->chip == S3_SAVAGE_MX ) { + if (par->chip == S3_SAVAGE_MX) { int i; - for( i = 0; i < 8; i++ ) { - vga_out8 (0x3c4, 0x54+i, par); - vga_out8 (0x3c5, par->SR54[i], par); + for (i = 0; i < 8; i++) { + vga_out8(0x3c4, 0x54+i, par); + vga_out8(0x3c5, reg->SR54[i], par); } } - vgaHWRestore (par); + vgaHWRestore (par, reg); /* extended mode timing registers */ - vga_out8 (0x3d4, 0x53, par); - vga_out8 (0x3d5, par->CR53, par); - vga_out8 (0x3d4, 0x5d, par); - vga_out8 (0x3d5, par->CR5D, par); - vga_out8 (0x3d4, 0x5e, par); - vga_out8 (0x3d5, par->CR5E, par); - vga_out8 (0x3d4, 0x3b, par); - vga_out8 (0x3d5, par->CR3B, par); - vga_out8 (0x3d4, 0x3c, par); - vga_out8 (0x3d5, par->CR3C, par); - vga_out8 (0x3d4, 0x43, par); - vga_out8 (0x3d5, par->CR43, par); - vga_out8 (0x3d4, 0x65, par); - vga_out8 (0x3d5, par->CR65, par); + vga_out8(0x3d4, 0x53, par); + vga_out8(0x3d5, reg->CR53, par); + vga_out8(0x3d4, 0x5d, par); + vga_out8(0x3d5, reg->CR5D, par); + vga_out8(0x3d4, 0x5e, par); + vga_out8(0x3d5, reg->CR5E, par); + vga_out8(0x3d4, 0x3b, par); + vga_out8(0x3d5, reg->CR3B, par); + vga_out8(0x3d4, 0x3c, par); + vga_out8(0x3d5, reg->CR3C, par); + vga_out8(0x3d4, 0x43, par); + vga_out8(0x3d5, reg->CR43, par); + vga_out8(0x3d4, 0x65, par); + vga_out8(0x3d5, reg->CR65, par); /* restore the desired video mode with cr67 */ - vga_out8 (0x3d4, 0x67, par); + vga_out8(0x3d4, 0x67, par); /* following part not present in X11 driver */ - cr67 = vga_in8 (0x3d5, par) & 0xf; - vga_out8 (0x3d5, 0x50 | cr67, par); - udelay (10000); - vga_out8 (0x3d4, 0x67, par); + cr67 = vga_in8(0x3d5, par) & 0xf; + vga_out8(0x3d5, 0x50 | cr67, par); + udelay(10000); + vga_out8(0x3d4, 0x67, par); /* end of part */ - vga_out8 (0x3d5, par->CR67 & ~0x0c, par); + vga_out8(0x3d5, reg->CR67 & ~0x0c, par); /* other mode timing and extended regs */ - vga_out8 (0x3d4, 0x34, par); - vga_out8 (0x3d5, par->CR34, par); - vga_out8 (0x3d4, 0x40, par); - vga_out8 (0x3d5, par->CR40, par); - vga_out8 (0x3d4, 0x42, par); - vga_out8 (0x3d5, par->CR42, par); - vga_out8 (0x3d4, 0x45, par); - vga_out8 (0x3d5, par->CR45, par); - vga_out8 (0x3d4, 0x50, par); - vga_out8 (0x3d5, par->CR50, par); - vga_out8 (0x3d4, 0x51, par); - vga_out8 (0x3d5, par->CR51, par); + vga_out8(0x3d4, 0x34, par); + vga_out8(0x3d5, reg->CR34, par); + vga_out8(0x3d4, 0x40, par); + vga_out8(0x3d5, reg->CR40, par); + vga_out8(0x3d4, 0x42, par); + vga_out8(0x3d5, reg->CR42, par); + vga_out8(0x3d4, 0x45, par); + vga_out8(0x3d5, reg->CR45, par); + vga_out8(0x3d4, 0x50, par); + vga_out8(0x3d5, reg->CR50, par); + vga_out8(0x3d4, 0x51, par); + vga_out8(0x3d5, reg->CR51, par); /* memory timings */ - vga_out8 (0x3d4, 0x36, par); - vga_out8 (0x3d5, par->CR36, par); - vga_out8 (0x3d4, 0x60, par); - vga_out8 (0x3d5, par->CR60, par); - vga_out8 (0x3d4, 0x68, par); - vga_out8 (0x3d5, par->CR68, par); - vga_out8 (0x3d4, 0x69, par); - vga_out8 (0x3d5, par->CR69, par); - vga_out8 (0x3d4, 0x6f, par); - vga_out8 (0x3d5, par->CR6F, par); - - vga_out8 (0x3d4, 0x33, par); - vga_out8 (0x3d5, par->CR33, par); - vga_out8 (0x3d4, 0x86, par); - vga_out8 (0x3d5, par->CR86, par); - vga_out8 (0x3d4, 0x88, par); - vga_out8 (0x3d5, par->CR88, par); - vga_out8 (0x3d4, 0x90, par); - vga_out8 (0x3d5, par->CR90, par); - vga_out8 (0x3d4, 0x91, par); - vga_out8 (0x3d5, par->CR91, par); + vga_out8(0x3d4, 0x36, par); + vga_out8(0x3d5, reg->CR36, par); + vga_out8(0x3d4, 0x60, par); + vga_out8(0x3d5, reg->CR60, par); + vga_out8(0x3d4, 0x68, par); + vga_out8(0x3d5, reg->CR68, par); + vga_out8(0x3d4, 0x69, par); + vga_out8(0x3d5, reg->CR69, par); + vga_out8(0x3d4, 0x6f, par); + vga_out8(0x3d5, reg->CR6F, par); + + vga_out8(0x3d4, 0x33, par); + vga_out8(0x3d5, reg->CR33, par); + vga_out8(0x3d4, 0x86, par); + vga_out8(0x3d5, reg->CR86, par); + vga_out8(0x3d4, 0x88, par); + vga_out8(0x3d5, reg->CR88, par); + vga_out8(0x3d4, 0x90, par); + vga_out8(0x3d5, reg->CR90, par); + vga_out8(0x3d4, 0x91, par); + vga_out8(0x3d5, reg->CR91, par); if (par->chip == S3_SAVAGE4) { - vga_out8 (0x3d4, 0xb0, par); - vga_out8 (0x3d5, par->CRB0, par); + vga_out8(0x3d4, 0xb0, par); + vga_out8(0x3d5, reg->CRB0, par); } - vga_out8 (0x3d4, 0x32, par); - vga_out8 (0x3d5, par->CR32, par); + vga_out8(0x3d4, 0x32, par); + vga_out8(0x3d5, reg->CR32, par); /* unlock extended seq regs */ - vga_out8 (0x3c4, 0x08, par); - vga_out8 (0x3c5, 0x06, par); + vga_out8(0x3c4, 0x08, par); + vga_out8(0x3c5, 0x06, par); /* Restore extended sequencer regs for MCLK. SR10 == 255 indicates * that we should leave the default SR10 and SR11 values there. */ - if (par->SR10 != 255) { - vga_out8 (0x3c4, 0x10, par); - vga_out8 (0x3c5, par->SR10, par); - vga_out8 (0x3c4, 0x11, par); - vga_out8 (0x3c5, par->SR11, par); + if (reg->SR10 != 255) { + vga_out8(0x3c4, 0x10, par); + vga_out8(0x3c5, reg->SR10, par); + vga_out8(0x3c4, 0x11, par); + vga_out8(0x3c5, reg->SR11, par); } /* restore extended seq regs for dclk */ - vga_out8 (0x3c4, 0x0e, par); - vga_out8 (0x3c5, par->SR0E, par); - vga_out8 (0x3c4, 0x0f, par); - vga_out8 (0x3c5, par->SR0F, par); - vga_out8 (0x3c4, 0x12, par); - vga_out8 (0x3c5, par->SR12, par); - vga_out8 (0x3c4, 0x13, par); - vga_out8 (0x3c5, par->SR13, par); - vga_out8 (0x3c4, 0x29, par); - vga_out8 (0x3c5, par->SR29, par); - - vga_out8 (0x3c4, 0x18, par); - vga_out8 (0x3c5, par->SR18, par); + vga_out8(0x3c4, 0x0e, par); + vga_out8(0x3c5, reg->SR0E, par); + vga_out8(0x3c4, 0x0f, par); + vga_out8(0x3c5, reg->SR0F, par); + vga_out8(0x3c4, 0x12, par); + vga_out8(0x3c5, reg->SR12, par); + vga_out8(0x3c4, 0x13, par); + vga_out8(0x3c5, reg->SR13, par); + vga_out8(0x3c4, 0x29, par); + vga_out8(0x3c5, reg->SR29, par); + vga_out8(0x3c4, 0x18, par); + vga_out8(0x3c5, reg->SR18, par); /* load new m, n pll values for dclk & mclk */ - vga_out8 (0x3c4, 0x15, par); - tmp = vga_in8 (0x3c5, par) & ~0x21; + vga_out8(0x3c4, 0x15, par); + tmp = vga_in8(0x3c5, par) & ~0x21; - vga_out8 (0x3c5, tmp | 0x03, par); - vga_out8 (0x3c5, tmp | 0x23, par); - vga_out8 (0x3c5, tmp | 0x03, par); - vga_out8 (0x3c5, par->SR15, par); - udelay (100); + vga_out8(0x3c5, tmp | 0x03, par); + vga_out8(0x3c5, tmp | 0x23, par); + vga_out8(0x3c5, tmp | 0x03, par); + vga_out8(0x3c5, reg->SR15, par); + udelay(100); - vga_out8 (0x3c4, 0x30, par); - vga_out8 (0x3c5, par->SR30, par); - vga_out8 (0x3c4, 0x08, par); - vga_out8 (0x3c5, par->SR08, par); + vga_out8(0x3c4, 0x30, par); + vga_out8(0x3c5, reg->SR30, par); + vga_out8(0x3c4, 0x08, par); + vga_out8(0x3c5, reg->SR08, par); /* now write out cr67 in full, possibly starting STREAMS */ VerticalRetraceWait(par); - vga_out8 (0x3d4, 0x67, par); - vga_out8 (0x3d5, par->CR67, par); + vga_out8(0x3d4, 0x67, par); + vga_out8(0x3d5, reg->CR67, par); - vga_out8 (0x3d4, 0x66, par); - cr66 = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr66 | 0x80, par); - vga_out8 (0x3d4, 0x3a, par); - cr3a = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr3a | 0x80, par); + vga_out8(0x3d4, 0x66, par); + cr66 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr66 | 0x80, par); + vga_out8(0x3d4, 0x3a, par); + cr3a = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr3a | 0x80, par); if (par->chip != S3_SAVAGE_MX) { VerticalRetraceWait(par); - savage_out32 (FIFO_CONTROL_REG, par->MMPR0, par); - par->SavageWaitIdle (par); - savage_out32 (MIU_CONTROL_REG, par->MMPR1, par); - par->SavageWaitIdle (par); - savage_out32 (STREAMS_TIMEOUT_REG, par->MMPR2, par); - par->SavageWaitIdle (par); - savage_out32 (MISC_TIMEOUT_REG, par->MMPR3, par); + savage_out32(FIFO_CONTROL_REG, reg->MMPR0, par); + par->SavageWaitIdle(par); + savage_out32(MIU_CONTROL_REG, reg->MMPR1, par); + par->SavageWaitIdle(par); + savage_out32(STREAMS_TIMEOUT_REG, reg->MMPR2, par); + par->SavageWaitIdle(par); + savage_out32(MISC_TIMEOUT_REG, reg->MMPR3, par); } - vga_out8 (0x3d4, 0x66, par); - vga_out8 (0x3d5, cr66, par); - vga_out8 (0x3d4, 0x3a, par); - vga_out8 (0x3d5, cr3a, par); + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, cr66, par); + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, cr3a, par); - SavageSetup2DEngine (par); - vgaHWProtect (par, 0); + SavageSetup2DEngine(par); + vgaHWProtect(par, 0); } -static void savagefb_update_start (struct savagefb_par *par, - struct fb_var_screeninfo *var) +static void savagefb_update_start(struct savagefb_par *par, + struct fb_var_screeninfo *var) { int base; @@ -1305,8 +1474,8 @@ static void savagefb_update_start (struct savagefb_par *par, /* now program the start address registers */ vga_out16(0x3d4, (base & 0x00ff00) | 0x0c, par); vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d, par); - vga_out8 (0x3d4, 0x69, par); - vga_out8 (0x3d5, (base & 0x7f0000) >> 16, par); + vga_out8(0x3d4, 0x69, par); + vga_out8(0x3d5, (base & 0x7f0000) >> 16, par); } @@ -1325,29 +1494,14 @@ static void savagefb_set_fix(struct fb_info *info) } -#if defined(CONFIG_FB_SAVAGE_ACCEL) -static void savagefb_set_clip(struct fb_info *info) -{ - struct savagefb_par *par = info->par; - int cmd; - - cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW; - par->bci_ptr = 0; - par->SavageWaitFifo(par,3); - BCI_SEND(cmd); - BCI_SEND(BCI_CLIP_TL(0, 0)); - BCI_SEND(BCI_CLIP_BR(0xfff, 0xfff)); -} -#endif - -static int savagefb_set_par (struct fb_info *info) +static int savagefb_set_par(struct fb_info *info) { struct savagefb_par *par = info->par; struct fb_var_screeninfo *var = &info->var; int err; DBG("savagefb_set_par"); - err = savagefb_decode_var (var, par); + err = savagefb_decode_var(var, par, &par->state); if (err) return err; @@ -1366,8 +1520,8 @@ static int savagefb_set_par (struct fb_info *info) par->maxClock = par->dacSpeedBpp; par->minClock = 10000; - savagefb_set_par_int (par); - fb_set_cmap (&info->cmap, info); + savagefb_set_par_int(par, &par->state); + fb_set_cmap(&info->cmap, info); savagefb_set_fix(info); savagefb_set_clip(info); @@ -1378,12 +1532,12 @@ static int savagefb_set_par (struct fb_info *info) /* * Pan or Wrap the Display */ -static int savagefb_pan_display (struct fb_var_screeninfo *var, - struct fb_info *info) +static int savagefb_pan_display(struct fb_var_screeninfo *var, + struct fb_info *info) { struct savagefb_par *par = info->par; - savagefb_update_start (par, var); + savagefb_update_start(par, var); return 0; } @@ -1440,6 +1594,22 @@ static int savagefb_blank(int blank, struct fb_info *info) return (blank == FB_BLANK_NORMAL) ? 1 : 0; } +static void savagefb_save_state(struct fb_info *info) +{ + struct savagefb_par *par = info->par; + + savage_get_default_par(par, &par->save); +} + +static void savagefb_restore_state(struct fb_info *info) +{ + struct savagefb_par *par = info->par; + + savagefb_blank(FB_BLANK_POWERDOWN, info); + savage_set_default_par(par, &par->save); + savagefb_blank(FB_BLANK_UNBLANK, info); +} + static struct fb_ops savagefb_ops = { .owner = THIS_MODULE, .fb_check_var = savagefb_check_var, @@ -1447,6 +1617,8 @@ static struct fb_ops savagefb_ops = { .fb_setcolreg = savagefb_setcolreg, .fb_pan_display = savagefb_pan_display, .fb_blank = savagefb_blank, + .fb_save_state = savagefb_save_state, + .fb_restore_state = savagefb_restore_state, #if defined(CONFIG_FB_SAVAGE_ACCEL) .fb_fillrect = savagefb_fillrect, .fb_copyarea = savagefb_copyarea, @@ -1479,59 +1651,59 @@ static struct fb_var_screeninfo __devinitdata savagefb_var800x600x8 = { .vmode = FB_VMODE_NONINTERLACED }; -static void savage_enable_mmio (struct savagefb_par *par) +static void savage_enable_mmio(struct savagefb_par *par) { unsigned char val; - DBG ("savage_enable_mmio\n"); + DBG("savage_enable_mmio\n"); - val = vga_in8 (0x3c3, par); - vga_out8 (0x3c3, val | 0x01, par); - val = vga_in8 (0x3cc, par); - vga_out8 (0x3c2, val | 0x01, par); + val = vga_in8(0x3c3, par); + vga_out8(0x3c3, val | 0x01, par); + val = vga_in8(0x3cc, par); + vga_out8(0x3c2, val | 0x01, par); if (par->chip >= S3_SAVAGE4) { - vga_out8 (0x3d4, 0x40, par); - val = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, val | 1, par); + vga_out8(0x3d4, 0x40, par); + val = vga_in8(0x3d5, par); + vga_out8(0x3d5, val | 1, par); } } -static void savage_disable_mmio (struct savagefb_par *par) +static void savage_disable_mmio(struct savagefb_par *par) { unsigned char val; - DBG ("savage_disable_mmio\n"); + DBG("savage_disable_mmio\n"); - if(par->chip >= S3_SAVAGE4 ) { - vga_out8 (0x3d4, 0x40, par); - val = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, val | 1, par); + if (par->chip >= S3_SAVAGE4) { + vga_out8(0x3d4, 0x40, par); + val = vga_in8(0x3d5, par); + vga_out8(0x3d5, val | 1, par); } } -static int __devinit savage_map_mmio (struct fb_info *info) +static int __devinit savage_map_mmio(struct fb_info *info) { struct savagefb_par *par = info->par; - DBG ("savage_map_mmio"); + DBG("savage_map_mmio"); - if (S3_SAVAGE3D_SERIES (par->chip)) - par->mmio.pbase = pci_resource_start (par->pcidev, 0) + + if (S3_SAVAGE3D_SERIES(par->chip)) + par->mmio.pbase = pci_resource_start(par->pcidev, 0) + SAVAGE_NEWMMIO_REGBASE_S3; else - par->mmio.pbase = pci_resource_start (par->pcidev, 0) + + par->mmio.pbase = pci_resource_start(par->pcidev, 0) + SAVAGE_NEWMMIO_REGBASE_S4; par->mmio.len = SAVAGE_NEWMMIO_REGSIZE; - par->mmio.vbase = ioremap (par->mmio.pbase, par->mmio.len); + par->mmio.vbase = ioremap(par->mmio.pbase, par->mmio.len); if (!par->mmio.vbase) { - printk ("savagefb: unable to map memory mapped IO\n"); + printk("savagefb: unable to map memory mapped IO\n"); return -ENOMEM; } else - printk (KERN_INFO "savagefb: mapped io at %p\n", + printk(KERN_INFO "savagefb: mapped io at %p\n", par->mmio.vbase); info->fix.mmio_start = par->mmio.pbase; @@ -1540,15 +1712,15 @@ static int __devinit savage_map_mmio (struct fb_info *info) par->bci_base = (u32 __iomem *)(par->mmio.vbase + BCI_BUFFER_OFFSET); par->bci_ptr = 0; - savage_enable_mmio (par); + savage_enable_mmio(par); return 0; } -static void savage_unmap_mmio (struct fb_info *info) +static void savage_unmap_mmio(struct fb_info *info) { struct savagefb_par *par = info->par; - DBG ("savage_unmap_mmio"); + DBG("savage_unmap_mmio"); savage_disable_mmio(par); @@ -1558,46 +1730,46 @@ static void savage_unmap_mmio (struct fb_info *info) } } -static int __devinit savage_map_video (struct fb_info *info, - int video_len) +static int __devinit savage_map_video(struct fb_info *info, + int video_len) { struct savagefb_par *par = info->par; int resource; DBG("savage_map_video"); - if (S3_SAVAGE3D_SERIES (par->chip)) + if (S3_SAVAGE3D_SERIES(par->chip)) resource = 0; else resource = 1; - par->video.pbase = pci_resource_start (par->pcidev, resource); + par->video.pbase = pci_resource_start(par->pcidev, resource); par->video.len = video_len; - par->video.vbase = ioremap (par->video.pbase, par->video.len); + par->video.vbase = ioremap(par->video.pbase, par->video.len); if (!par->video.vbase) { - printk ("savagefb: unable to map screen memory\n"); + printk("savagefb: unable to map screen memory\n"); return -ENOMEM; } else - printk (KERN_INFO "savagefb: mapped framebuffer at %p, " - "pbase == %x\n", par->video.vbase, par->video.pbase); + printk(KERN_INFO "savagefb: mapped framebuffer at %p, " + "pbase == %x\n", par->video.vbase, par->video.pbase); info->fix.smem_start = par->video.pbase; info->fix.smem_len = par->video.len - par->cob_size; info->screen_base = par->video.vbase; #ifdef CONFIG_MTRR - par->video.mtrr = mtrr_add (par->video.pbase, video_len, - MTRR_TYPE_WRCOMB, 1); + par->video.mtrr = mtrr_add(par->video.pbase, video_len, + MTRR_TYPE_WRCOMB, 1); #endif /* Clear framebuffer, it's all white in memory after boot */ - memset_io (par->video.vbase, 0, par->video.len); + memset_io(par->video.vbase, 0, par->video.len); return 0; } -static void savage_unmap_video (struct fb_info *info) +static void savage_unmap_video(struct fb_info *info) { struct savagefb_par *par = info->par; @@ -1605,16 +1777,16 @@ static void savage_unmap_video (struct fb_info *info) if (par->video.vbase) { #ifdef CONFIG_MTRR - mtrr_del (par->video.mtrr, par->video.pbase, par->video.len); + mtrr_del(par->video.mtrr, par->video.pbase, par->video.len); #endif - iounmap (par->video.vbase); + iounmap(par->video.vbase); par->video.vbase = NULL; info->screen_base = NULL; } } -static int savage_init_hw (struct savagefb_par *par) +static int savage_init_hw(struct savagefb_par *par) { unsigned char config1, m, n, n1, n2, sr8, cr3f, cr66 = 0, tmp; @@ -1656,7 +1828,7 @@ static int savage_init_hw (struct savagefb_par *par) switch (par->chip) { case S3_SAVAGE3D: - videoRam = RamSavage3D[ (config1 & 0xC0) >> 6 ] * 1024; + videoRam = RamSavage3D[(config1 & 0xC0) >> 6 ] * 1024; break; case S3_SAVAGE4: @@ -1667,22 +1839,22 @@ static int savage_init_hw (struct savagefb_par *par) * can do it different... */ vga_out8(0x3d4, 0x68, par); /* memory control 1 */ - if( (vga_in8(0x3d5, par) & 0xC0) == (0x01 << 6) ) + if ((vga_in8(0x3d5, par) & 0xC0) == (0x01 << 6)) RamSavage4[1] = 8; /*FALLTHROUGH*/ case S3_SAVAGE2000: - videoRam = RamSavage4[ (config1 & 0xE0) >> 5 ] * 1024; + videoRam = RamSavage4[(config1 & 0xE0) >> 5] * 1024; break; case S3_SAVAGE_MX: case S3_SUPERSAVAGE: - videoRam = RamSavageMX[ (config1 & 0x0E) >> 1 ] * 1024; + videoRam = RamSavageMX[(config1 & 0x0E) >> 1] * 1024; break; case S3_PROSAVAGE: - videoRam = RamSavageNB[ (config1 & 0xE0) >> 5 ] * 1024; + videoRam = RamSavageNB[(config1 & 0xE0) >> 5] * 1024; break; default: @@ -1693,31 +1865,31 @@ static int savage_init_hw (struct savagefb_par *par) videoRambytes = videoRam * 1024; - printk (KERN_INFO "savagefb: probed videoram: %dk\n", videoRam); + printk(KERN_INFO "savagefb: probed videoram: %dk\n", videoRam); /* reset graphics engine to avoid memory corruption */ - vga_out8 (0x3d4, 0x66, par); - cr66 = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr66 | 0x02, par); - udelay (10000); + vga_out8(0x3d4, 0x66, par); + cr66 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr66 | 0x02, par); + udelay(10000); - vga_out8 (0x3d4, 0x66, par); - vga_out8 (0x3d5, cr66 & ~0x02, par); /* clear reset flag */ - udelay (10000); + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, cr66 & ~0x02, par); /* clear reset flag */ + udelay(10000); /* * reset memory interface, 3D engine, AGP master, PCI master, * master engine unit, motion compensation/LPB */ - vga_out8 (0x3d4, 0x3f, par); - cr3f = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr3f | 0x08, par); - udelay (10000); + vga_out8(0x3d4, 0x3f, par); + cr3f = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr3f | 0x08, par); + udelay(10000); - vga_out8 (0x3d4, 0x3f, par); - vga_out8 (0x3d5, cr3f & ~0x08, par); /* clear reset flags */ - udelay (10000); + vga_out8(0x3d4, 0x3f, par); + vga_out8(0x3d5, cr3f & ~0x08, par); /* clear reset flags */ + udelay(10000); /* Savage ramdac speeds */ par->numClocks = 4; @@ -1740,7 +1912,7 @@ static int savage_init_hw (struct savagefb_par *par) n1 = n & 0x1f; n2 = (n >> 5) & 0x03; par->MCLK = ((1431818 * (m+2)) / (n1+2) / (1 << n2) + 50) / 100; - printk (KERN_INFO "savagefb: Detected current MCLK value of %d kHz\n", + printk(KERN_INFO "savagefb: Detected current MCLK value of %d kHz\n", par->MCLK); /* check for DVI/flat panel */ @@ -1769,12 +1941,12 @@ static int savage_init_hw (struct savagefb_par *par) /* Check LCD panel parrmation */ if (par->display_type == DISP_LCD) { - unsigned char cr6b = VGArCR( 0x6b, par); + unsigned char cr6b = VGArCR(0x6b, par); - int panelX = (VGArSEQ (0x61, par) + - ((VGArSEQ (0x66, par) & 0x02) << 7) + 1) * 8; - int panelY = (VGArSEQ (0x69, par) + - ((VGArSEQ (0x6e, par) & 0x70) << 4) + 1); + int panelX = (VGArSEQ(0x61, par) + + ((VGArSEQ(0x66, par) & 0x02) << 7) + 1) * 8; + int panelY = (VGArSEQ(0x69, par) + + ((VGArSEQ(0x6e, par) & 0x70) << 4) + 1); char * sTechnology = "Unknown"; @@ -1796,26 +1968,26 @@ static int savage_init_hw (struct savagefb_par *par) ActiveDUO = 0x80 }; - if ((VGArSEQ (0x39, par) & 0x03) == 0) { + if ((VGArSEQ(0x39, par) & 0x03) == 0) { sTechnology = "TFT"; - } else if ((VGArSEQ (0x30, par) & 0x01) == 0) { + } else if ((VGArSEQ(0x30, par) & 0x01) == 0) { sTechnology = "DSTN"; } else { sTechnology = "STN"; } - printk (KERN_INFO "savagefb: %dx%d %s LCD panel detected %s\n", - panelX, panelY, sTechnology, - cr6b & ActiveLCD ? "and active" : "but not active"); + printk(KERN_INFO "savagefb: %dx%d %s LCD panel detected %s\n", + panelX, panelY, sTechnology, + cr6b & ActiveLCD ? "and active" : "but not active"); - if( cr6b & ActiveLCD ) { + if (cr6b & ActiveLCD) { /* * If the LCD is active and panel expansion is enabled, * we probably want to kill the HW cursor. */ - printk (KERN_INFO "savagefb: Limiting video mode to " - "%dx%d\n", panelX, panelY ); + printk(KERN_INFO "savagefb: Limiting video mode to " + "%dx%d\n", panelX, panelY); par->SavagePanelWidth = panelX; par->SavagePanelHeight = panelY; @@ -1824,9 +1996,10 @@ static int savage_init_hw (struct savagefb_par *par) par->display_type = DISP_CRT; } - savage_get_default_par (par); + savage_get_default_par(par, &par->state); + par->save = par->state; - if( S3_SAVAGE4_SERIES(par->chip) ) { + if (S3_SAVAGE4_SERIES(par->chip)) { /* * The Savage4 and ProSavage have COB coherency bugs which * render the buffer useless. We disable it. @@ -1845,9 +2018,9 @@ static int savage_init_hw (struct savagefb_par *par) return videoRambytes; } -static int __devinit savage_init_fb_info (struct fb_info *info, - struct pci_dev *dev, - const struct pci_device_id *id) +static int __devinit savage_init_fb_info(struct fb_info *info, + struct pci_dev *dev, + const struct pci_device_id *id) { struct savagefb_par *par = info->par; int err = 0; @@ -1863,63 +2036,63 @@ static int __devinit savage_init_fb_info (struct fb_info *info, switch (info->fix.accel) { case FB_ACCEL_SUPERSAVAGE: par->chip = S3_SUPERSAVAGE; - snprintf (info->fix.id, 16, "SuperSavage"); + snprintf(info->fix.id, 16, "SuperSavage"); break; case FB_ACCEL_SAVAGE4: par->chip = S3_SAVAGE4; - snprintf (info->fix.id, 16, "Savage4"); + snprintf(info->fix.id, 16, "Savage4"); break; case FB_ACCEL_SAVAGE3D: par->chip = S3_SAVAGE3D; - snprintf (info->fix.id, 16, "Savage3D"); + snprintf(info->fix.id, 16, "Savage3D"); break; case FB_ACCEL_SAVAGE3D_MV: par->chip = S3_SAVAGE3D; - snprintf (info->fix.id, 16, "Savage3D-MV"); + snprintf(info->fix.id, 16, "Savage3D-MV"); break; case FB_ACCEL_SAVAGE2000: par->chip = S3_SAVAGE2000; - snprintf (info->fix.id, 16, "Savage2000"); + snprintf(info->fix.id, 16, "Savage2000"); break; case FB_ACCEL_SAVAGE_MX_MV: par->chip = S3_SAVAGE_MX; - snprintf (info->fix.id, 16, "Savage/MX-MV"); + snprintf(info->fix.id, 16, "Savage/MX-MV"); break; case FB_ACCEL_SAVAGE_MX: par->chip = S3_SAVAGE_MX; - snprintf (info->fix.id, 16, "Savage/MX"); + snprintf(info->fix.id, 16, "Savage/MX"); break; case FB_ACCEL_SAVAGE_IX_MV: par->chip = S3_SAVAGE_MX; - snprintf (info->fix.id, 16, "Savage/IX-MV"); + snprintf(info->fix.id, 16, "Savage/IX-MV"); break; case FB_ACCEL_SAVAGE_IX: par->chip = S3_SAVAGE_MX; - snprintf (info->fix.id, 16, "Savage/IX"); + snprintf(info->fix.id, 16, "Savage/IX"); break; case FB_ACCEL_PROSAVAGE_PM: par->chip = S3_PROSAVAGE; - snprintf (info->fix.id, 16, "ProSavagePM"); + snprintf(info->fix.id, 16, "ProSavagePM"); break; case FB_ACCEL_PROSAVAGE_KM: par->chip = S3_PROSAVAGE; - snprintf (info->fix.id, 16, "ProSavageKM"); + snprintf(info->fix.id, 16, "ProSavageKM"); break; case FB_ACCEL_S3TWISTER_P: par->chip = S3_PROSAVAGE; - snprintf (info->fix.id, 16, "TwisterP"); + snprintf(info->fix.id, 16, "TwisterP"); break; case FB_ACCEL_S3TWISTER_K: par->chip = S3_PROSAVAGE; - snprintf (info->fix.id, 16, "TwisterK"); + snprintf(info->fix.id, 16, "TwisterK"); break; case FB_ACCEL_PROSAVAGE_DDR: par->chip = S3_PROSAVAGE; - snprintf (info->fix.id, 16, "ProSavageDDR"); + snprintf(info->fix.id, 16, "ProSavageDDR"); break; case FB_ACCEL_PROSAVAGE_DDRK: par->chip = S3_PROSAVAGE; - snprintf (info->fix.id, 16, "ProSavage8"); + snprintf(info->fix.id, 16, "ProSavage8"); break; } @@ -1960,7 +2133,7 @@ static int __devinit savage_init_fb_info (struct fb_info *info, info->pixmap.buf_align = 4; info->pixmap.access_align = 32; - err = fb_alloc_cmap (&info->cmap, NR_PALETTE, 0); + err = fb_alloc_cmap(&info->cmap, NR_PALETTE, 0); if (!err) info->flags |= FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | @@ -1972,8 +2145,8 @@ static int __devinit savage_init_fb_info (struct fb_info *info, /* --------------------------------------------------------------------- */ -static int __devinit savagefb_probe (struct pci_dev* dev, - const struct pci_device_id* id) +static int __devinit savagefb_probe(struct pci_dev* dev, + const struct pci_device_id* id) { struct fb_info *info; struct savagefb_par *par; @@ -2085,12 +2258,12 @@ static int __devinit savagefb_probe (struct pci_dev* dev, fb_destroy_modedb(info->monspecs.modedb); info->monspecs.modedb = NULL; - err = register_framebuffer (info); + err = register_framebuffer(info); if (err < 0) goto failed; - printk (KERN_INFO "fb: S3 %s frame buffer device\n", - info->fix.id); + printk(KERN_INFO "fb: S3 %s frame buffer device\n", + info->fix.id); /* * Our driver data @@ -2103,10 +2276,10 @@ static int __devinit savagefb_probe (struct pci_dev* dev, #ifdef CONFIG_FB_SAVAGE_I2C savagefb_delete_i2c_busses(info); #endif - fb_alloc_cmap (&info->cmap, 0, 0); + fb_alloc_cmap(&info->cmap, 0, 0); savage_unmap_video(info); failed_video: - savage_unmap_mmio (info); + savage_unmap_mmio(info); failed_mmio: kfree(info->pixmap.addr); failed_init: @@ -2117,7 +2290,7 @@ static int __devinit savagefb_probe (struct pci_dev* dev, return err; } -static void __devexit savagefb_remove (struct pci_dev *dev) +static void __devexit savagefb_remove(struct pci_dev *dev) { struct fb_info *info = pci_get_drvdata(dev); @@ -2129,16 +2302,16 @@ static void __devexit savagefb_remove (struct pci_dev *dev) * we will be leaving hooks that could cause * oopsen laying around. */ - if (unregister_framebuffer (info)) - printk (KERN_WARNING "savagefb: danger danger! " - "Oopsen imminent!\n"); + if (unregister_framebuffer(info)) + printk(KERN_WARNING "savagefb: danger danger! " + "Oopsen imminent!\n"); #ifdef CONFIG_FB_SAVAGE_I2C savagefb_delete_i2c_busses(info); #endif - fb_alloc_cmap (&info->cmap, 0, 0); - savage_unmap_video (info); - savage_unmap_mmio (info); + fb_alloc_cmap(&info->cmap, 0, 0); + savage_unmap_video(info); + savage_unmap_mmio(info); kfree(info->pixmap.addr); pci_release_regions(dev); framebuffer_release(info); @@ -2151,7 +2324,7 @@ static void __devexit savagefb_remove (struct pci_dev *dev) } } -static int savagefb_suspend (struct pci_dev* dev, pm_message_t state) +static int savagefb_suspend(struct pci_dev* dev, pm_message_t state) { struct fb_info *info = pci_get_drvdata(dev); struct savagefb_par *par = info->par; @@ -2177,6 +2350,7 @@ static int savagefb_suspend (struct pci_dev* dev, pm_message_t state) info->fbops->fb_sync(info); savagefb_blank(FB_BLANK_POWERDOWN, info); + savage_set_default_par(par, &par->save); savage_disable_mmio(par); pci_save_state(dev); pci_disable_device(dev); @@ -2186,7 +2360,7 @@ static int savagefb_suspend (struct pci_dev* dev, pm_message_t state) return 0; } -static int savagefb_resume (struct pci_dev* dev) +static int savagefb_resume(struct pci_dev* dev) { struct fb_info *info = pci_get_drvdata(dev); struct savagefb_par *par = info->par; @@ -2210,15 +2384,15 @@ static int savagefb_resume (struct pci_dev* dev) pci_set_power_state(dev, PCI_D0); pci_restore_state(dev); - if(pci_enable_device(dev)) + if (pci_enable_device(dev)) DBG("err"); pci_set_master(dev); savage_enable_mmio(par); savage_init_hw(par); - savagefb_set_par (info); + savagefb_set_par(info); + fb_set_suspend(info, 0); savagefb_blank(FB_BLANK_UNBLANK, info); - fb_set_suspend (info, 0); release_console_sem(); return 0; @@ -2311,10 +2485,10 @@ static struct pci_driver savagefb_driver = { /* **************************** exit-time only **************************** */ -static void __exit savage_done (void) +static void __exit savage_done(void) { DBG("savage_done"); - pci_unregister_driver (&savagefb_driver); + pci_unregister_driver(&savagefb_driver); } @@ -2345,7 +2519,7 @@ static int __init savagefb_init(void) return -ENODEV; savagefb_setup(option); - return pci_register_driver (&savagefb_driver); + return pci_register_driver(&savagefb_driver); } diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c index 2e6df1fcb2b9..ebb6756aea08 100644 --- a/drivers/video/sgivwfb.c +++ b/drivers/video/sgivwfb.c @@ -9,7 +9,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/mm.h> @@ -23,6 +22,8 @@ #include <asm/io.h> #include <asm/mtrr.h> +#include <setup_arch.h> + #define INCLUDE_TIMING_TABLE_DATA #define DBE_REG_BASE par->regs #include <video/sgivw.h> @@ -42,10 +43,6 @@ struct sgivw_par { * The default can be overridden if the driver is compiled as a module */ -/* set by arch/i386/kernel/setup.c */ -extern unsigned long sgivwfb_mem_phys; -extern unsigned long sgivwfb_mem_size; - static int ypan = 0; static int ywrap = 0; diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h index 634c0a9d219b..7ecab87cef02 100644 --- a/drivers/video/sis/init.h +++ b/drivers/video/sis/init.h @@ -73,7 +73,6 @@ #ifdef SIS_CP #undef SIS_CP #endif -#include <linux/config.h> #include <linux/version.h> #include <linux/types.h> #include <asm/io.h> diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c index c3e070a6effd..f13faddc6181 100644 --- a/drivers/video/sis/init301.c +++ b/drivers/video/sis/init301.c @@ -8043,8 +8043,8 @@ SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short SiS_SetCH700x(SiS_Pr,0x01,0x28); /* Set video bandwidth - High bandwith Luma composite video filter(S0=1) - low bandwith Luma S-video filter (S2-1=00) + High bandwidth Luma composite video filter(S0=1) + low bandwidth Luma S-video filter (S2-1=00) disable peak filter in S-video channel (S3=0) high bandwidth Chroma Filter (S5-4=11) =00110001=0x31 diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h index f475b21a85cf..bc321dc57e92 100644 --- a/drivers/video/sis/init301.h +++ b/drivers/video/sis/init301.h @@ -67,7 +67,6 @@ #ifdef SIS_CP #undef SIS_CP #endif -#include <linux/config.h> #include <linux/version.h> #include <linux/types.h> #include <asm/io.h> diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/sis/initextlfb.c index cc856d90903c..09f5d758b6c0 100644 --- a/drivers/video/sis/initextlfb.c +++ b/drivers/video/sis/initextlfb.c @@ -30,7 +30,6 @@ #include "vgatypes.h" #include "vstruct.h" -#include <linux/config.h> #include <linux/version.h> #include <linux/types.h> #include <linux/fb.h> diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h index 841ca3190cd4..f59568020eb2 100644 --- a/drivers/video/sis/osdef.h +++ b/drivers/video/sis/osdef.h @@ -90,7 +90,6 @@ /**********************************************************************/ #ifdef SIS_LINUX_KERNEL -#include <linux/config.h> #include <linux/version.h> #ifdef CONFIG_FB_SIS_300 diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h index 0b6e625d7331..a259446ca7fe 100644 --- a/drivers/video/sis/sis.h +++ b/drivers/video/sis/sis.h @@ -24,7 +24,6 @@ #ifndef _SIS_H_ #define _SIS_H_ -#include <linux/config.h> #include <linux/version.h> #include "osdef.h" diff --git a/drivers/video/sis/sis_accel.c b/drivers/video/sis/sis_accel.c index bab933e6c6a6..3b7ce032e2ed 100644 --- a/drivers/video/sis/sis_accel.c +++ b/drivers/video/sis/sis_accel.c @@ -28,7 +28,6 @@ * for more information and updates) */ -#include <linux/config.h> #include <linux/version.h> #include <linux/module.h> #include <linux/kernel.h> diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 8adf5bf91eee..b848ca7db7f9 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c @@ -33,7 +33,6 @@ * */ -#include <linux/config.h> #include <linux/version.h> #include <linux/module.h> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) @@ -275,7 +274,7 @@ sisfb_search_mode(char *name, BOOLEAN quiet) static void __devinit sisfb_get_vga_mode_from_kernel(void) { -#if (defined(__i386__) || defined(__x86_64__)) && defined(CONFIG_VIDEO_SELECT) +#ifdef CONFIG_X86 char mymode[32]; int mydepth = screen_info.lfb_depth; diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c index 9b707771d757..67f429e93189 100644 --- a/drivers/video/skeletonfb.c +++ b/drivers/video/skeletonfb.c @@ -906,11 +906,6 @@ static void __exit xxxfb_exit(void) } #endif -MODULE_LICENSE("GPL"); -module_init(xxxfb_init); -module_exit(xxxfb_exit); - - /* * Setup */ diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c index c44de90ca12e..dad54e73147b 100644 --- a/drivers/video/sstfb.c +++ b/drivers/video/sstfb.c @@ -82,7 +82,6 @@ * Includes */ -#include <linux/config.h> #include <linux/string.h> #include <linux/kernel.h> #include <linux/module.h> diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index 4a292aae6eb2..3e16e2d9d55d 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c @@ -54,7 +54,6 @@ #undef DEBUG_STIFB_REGS /* debug sti register accesses */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/video/sun3fb.c b/drivers/video/sun3fb.c index 9b36b9df535f..e046e20f02b9 100644 --- a/drivers/video/sun3fb.c +++ b/drivers/video/sun3fb.c @@ -25,7 +25,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c index 95b918229d9b..6990ab11cd06 100644 --- a/drivers/video/tcx.c +++ b/drivers/video/tcx.c @@ -1,6 +1,6 @@ /* tcx.c: TCX frame buffer driver * - * Copyright (C) 2003 David S. Miller (davem@redhat.com) + * Copyright (C) 2003, 2006 David S. Miller (davem@davemloft.net) * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz) * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) @@ -19,8 +19,8 @@ #include <linux/mm.h> #include <asm/io.h> -#include <asm/sbus.h> -#include <asm/oplib.h> +#include <asm/prom.h> +#include <asm/of_device.h> #include <asm/fbio.h> #include "sbuslib.h" @@ -77,32 +77,32 @@ static struct fb_ops tcx_ops = { /* The contents are unknown */ struct tcx_tec { - volatile u32 tec_matrix; - volatile u32 tec_clip; - volatile u32 tec_vdc; + u32 tec_matrix; + u32 tec_clip; + u32 tec_vdc; }; struct tcx_thc { - volatile u32 thc_rev; + u32 thc_rev; u32 thc_pad0[511]; - volatile u32 thc_hs; /* hsync timing */ - volatile u32 thc_hsdvs; - volatile u32 thc_hd; - volatile u32 thc_vs; /* vsync timing */ - volatile u32 thc_vd; - volatile u32 thc_refresh; - volatile u32 thc_misc; + u32 thc_hs; /* hsync timing */ + u32 thc_hsdvs; + u32 thc_hd; + u32 thc_vs; /* vsync timing */ + u32 thc_vd; + u32 thc_refresh; + u32 thc_misc; u32 thc_pad1[56]; - volatile u32 thc_cursxy; /* cursor x,y position (16 bits each) */ - volatile u32 thc_cursmask[32]; /* cursor mask bits */ - volatile u32 thc_cursbits[32]; /* what to show where mask enabled */ + u32 thc_cursxy; /* cursor x,y position (16 bits each) */ + u32 thc_cursmask[32]; /* cursor mask bits */ + u32 thc_cursbits[32]; /* what to show where mask enabled */ }; struct bt_regs { - volatile u32 addr; - volatile u32 color_map; - volatile u32 control; - volatile u32 cursor; + u32 addr; + u32 color_map; + u32 control; + u32 cursor; }; #define TCX_MMAP_ENTRIES 14 @@ -112,24 +112,23 @@ struct tcx_par { struct bt_regs __iomem *bt; struct tcx_thc __iomem *thc; struct tcx_tec __iomem *tec; - volatile u32 __iomem *cplane; + u32 __iomem *cplane; u32 flags; #define TCX_FLAG_BLANKED 0x00000001 unsigned long physbase; + unsigned long which_io; unsigned long fbsize; struct sbus_mmap_map mmap_map[TCX_MMAP_ENTRIES]; int lowdepth; - - struct sbus_dev *sdev; }; /* Reset control plane so that WID is 8-bit plane. */ static void __tcx_set_control_plane (struct tcx_par *par) { - volatile u32 __iomem *p, *pend; + u32 __iomem *p, *pend; if (par->lowdepth) return; @@ -307,8 +306,7 @@ static int tcx_mmap(struct fb_info *info, struct vm_area_struct *vma) return sbusfb_mmap_helper(par->mmap_map, par->physbase, par->fbsize, - par->sdev->reg_addrs[0].which_io, - vma); + par->which_io, vma); } static int tcx_ioctl(struct fb_info *info, unsigned int cmd, @@ -350,48 +348,71 @@ tcx_init_fix(struct fb_info *info, int linebytes) struct all_info { struct fb_info info; struct tcx_par par; - struct list_head list; }; -static LIST_HEAD(tcx_list); -static void tcx_init_one(struct sbus_dev *sdev) +static void tcx_unmap_regs(struct all_info *all) { - struct all_info *all; - int linebytes, i; + if (all->par.tec) + of_iounmap(all->par.tec, sizeof(struct tcx_tec)); + if (all->par.thc) + of_iounmap(all->par.thc, sizeof(struct tcx_thc)); + if (all->par.bt) + of_iounmap(all->par.bt, sizeof(struct bt_regs)); + if (all->par.cplane) + of_iounmap(all->par.cplane, all->par.fbsize * sizeof(u32)); + if (all->info.screen_base) + of_iounmap(all->info.screen_base, all->par.fbsize); +} - all = kmalloc(sizeof(*all), GFP_KERNEL); - if (!all) { - printk(KERN_ERR "tcx: Cannot allocate memory.\n"); - return; - } - memset(all, 0, sizeof(*all)); +static int __devinit tcx_init_one(struct of_device *op) +{ + struct device_node *dp = op->node; + struct all_info *all; + int linebytes, i, err; - INIT_LIST_HEAD(&all->list); + all = kzalloc(sizeof(*all), GFP_KERNEL); + if (!all) + return -ENOMEM; spin_lock_init(&all->par.lock); - all->par.sdev = sdev; - all->par.lowdepth = prom_getbool(sdev->prom_node, "tcx-8-bit"); + all->par.lowdepth = + (of_find_property(dp, "tcx-8-bit", NULL) != NULL); - sbusfb_fill_var(&all->info.var, sdev->prom_node, 8); + sbusfb_fill_var(&all->info.var, dp->node, 8); all->info.var.red.length = 8; all->info.var.green.length = 8; all->info.var.blue.length = 8; - linebytes = prom_getintdefault(sdev->prom_node, "linebytes", - all->info.var.xres); + linebytes = of_getintprop_default(dp, "linebytes", + all->info.var.xres); all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); - all->par.tec = sbus_ioremap(&sdev->resource[7], 0, - sizeof(struct tcx_tec), "tcx tec"); - all->par.thc = sbus_ioremap(&sdev->resource[9], 0, - sizeof(struct tcx_thc), "tcx thc"); - all->par.bt = sbus_ioremap(&sdev->resource[8], 0, - sizeof(struct bt_regs), "tcx dac"); + all->par.tec = of_ioremap(&op->resource[7], 0, + sizeof(struct tcx_tec), "tcx tec"); + all->par.thc = of_ioremap(&op->resource[9], 0, + sizeof(struct tcx_thc), "tcx thc"); + all->par.bt = of_ioremap(&op->resource[8], 0, + sizeof(struct bt_regs), "tcx dac"); + all->info.screen_base = of_ioremap(&op->resource[0], 0, + all->par.fbsize, "tcx ram"); + if (!all->par.tec || !all->par.thc || + !all->par.bt || !all->info.screen_base) { + tcx_unmap_regs(all); + kfree(all); + return -ENOMEM; + } + memcpy(&all->par.mmap_map, &__tcx_mmap_map, sizeof(all->par.mmap_map)); if (!all->par.lowdepth) { - all->par.cplane = sbus_ioremap(&sdev->resource[4], 0, - all->par.fbsize * sizeof(u32), "tcx cplane"); + all->par.cplane = of_ioremap(&op->resource[4], 0, + all->par.fbsize * sizeof(u32), + "tcx cplane"); + if (!all->par.cplane) { + tcx_unmap_regs(all); + kfree(all); + return -ENOMEM; + } } else { all->par.mmap_map[1].size = SBUS_MMAP_EMPTY; all->par.mmap_map[4].size = SBUS_MMAP_EMPTY; @@ -400,6 +421,8 @@ static void tcx_init_one(struct sbus_dev *sdev) } all->par.physbase = 0; + all->par.which_io = op->resource[0].flags & IORESOURCE_BITS; + for (i = 0; i < TCX_MMAP_ENTRIES; i++) { int j; @@ -416,18 +439,11 @@ static void tcx_init_one(struct sbus_dev *sdev) j = i; break; }; - all->par.mmap_map[i].poff = sdev->reg_addrs[j].phys_addr; + all->par.mmap_map[i].poff = op->resource[j].start; } all->info.flags = FBINFO_DEFAULT; all->info.fbops = &tcx_ops; -#ifdef CONFIG_SPARC32 - all->info.screen_base = (char __iomem *) - prom_getintdefault(sdev->prom_node, "address", 0); -#endif - if (!all->info.screen_base) - all->info.screen_base = sbus_ioremap(&sdev->resource[0], 0, - all->par.fbsize, "tcx ram"); all->info.par = &all->par; /* Initialize brooktree DAC. */ @@ -445,72 +461,88 @@ static void tcx_init_one(struct sbus_dev *sdev) tcx_blank(FB_BLANK_UNBLANK, &all->info); if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { - printk(KERN_ERR "tcx: Could not allocate color map.\n"); + tcx_unmap_regs(all); kfree(all); - return; + return -ENOMEM; } fb_set_cmap(&all->info.cmap, &all->info); tcx_init_fix(&all->info, linebytes); - if (register_framebuffer(&all->info) < 0) { - printk(KERN_ERR "tcx: Could not register framebuffer.\n"); + err = register_framebuffer(&all->info); + if (err < 0) { fb_dealloc_cmap(&all->info.cmap); + tcx_unmap_regs(all); kfree(all); - return; + return err; } - list_add(&all->list, &tcx_list); + dev_set_drvdata(&op->dev, all); - printk("tcx: %s at %lx:%lx, %s\n", - sdev->prom_name, - (long) sdev->reg_addrs[0].which_io, - (long) sdev->reg_addrs[0].phys_addr, + printk("%s: TCX at %lx:%lx, %s\n", + dp->full_name, + all->par.which_io, + op->resource[0].start, all->par.lowdepth ? "8-bit only" : "24-bit depth"); + + return 0; } -int __init tcx_init(void) +static int __devinit tcx_probe(struct of_device *dev, const struct of_device_id *match) { - struct sbus_bus *sbus; - struct sbus_dev *sdev; + struct of_device *op = to_of_device(&dev->dev); - if (fb_get_options("tcxfb", NULL)) - return -ENODEV; + return tcx_init_one(op); +} - for_all_sbusdev(sdev, sbus) { - if (!strcmp(sdev->prom_name, "SUNW,tcx")) - tcx_init_one(sdev); - } +static int __devexit tcx_remove(struct of_device *dev) +{ + struct all_info *all = dev_get_drvdata(&dev->dev); + + unregister_framebuffer(&all->info); + fb_dealloc_cmap(&all->info.cmap); + + tcx_unmap_regs(all); + + kfree(all); + + dev_set_drvdata(&dev->dev, NULL); return 0; } -void __exit tcx_exit(void) -{ - struct list_head *pos, *tmp; +static struct of_device_id tcx_match[] = { + { + .name = "SUNW,tcx", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, tcx_match); - list_for_each_safe(pos, tmp, &tcx_list) { - struct all_info *all = list_entry(pos, typeof(*all), list); +static struct of_platform_driver tcx_driver = { + .name = "tcx", + .match_table = tcx_match, + .probe = tcx_probe, + .remove = __devexit_p(tcx_remove), +}; - unregister_framebuffer(&all->info); - fb_dealloc_cmap(&all->info.cmap); - kfree(all); - } +int __init tcx_init(void) +{ + if (fb_get_options("tcxfb", NULL)) + return -ENODEV; + + return of_register_driver(&tcx_driver, &of_bus_type); } -int __init -tcx_setup(char *arg) +void __exit tcx_exit(void) { - /* No cmdline options yet... */ - return 0; + of_unregister_driver(&tcx_driver); } module_init(tcx_init); - -#ifdef MODULE module_exit(tcx_exit); -#endif MODULE_DESCRIPTION("framebuffer driver for TCX chipsets"); -MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); +MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); +MODULE_VERSION("2.0"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index 5e5328d682db..239b1496874b 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/tdfxfb.c @@ -58,7 +58,6 @@ * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c index 7398bd48ba6c..6c2c78ab9827 100644 --- a/drivers/video/tgafb.c +++ b/drivers/video/tgafb.c @@ -26,7 +26,6 @@ #include <linux/selection.h> #include <asm/io.h> #include <video/tgafb.h> -#include <linux/selection.h> /* * Local functions. diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c index 41f8c2d93892..14175cdb9c9c 100644 --- a/drivers/video/tridentfb.c +++ b/drivers/video/tridentfb.c @@ -15,7 +15,6 @@ * TGUI acceleration */ -#include <linux/config.h> #include <linux/module.h> #include <linux/fb.h> #include <linux/init.h> diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c index 2bdeb4baa952..1d76c035050e 100644 --- a/drivers/video/valkyriefb.c +++ b/drivers/video/valkyriefb.c @@ -39,7 +39,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index b0b9acfdd430..5718924b677f 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c @@ -51,7 +51,7 @@ static int inverse = 0; static int mtrr = 0; /* disable mtrr */ static int vram_remap __initdata = 0; /* Set amount of memory to be used */ static int vram_total __initdata = 0; /* Set total amount of memory */ -static int pmi_setpal = 0; /* pmi for palette changes ??? */ +static int pmi_setpal = 1; /* pmi for palette changes ??? */ static int ypan = 0; /* 0..nothing, 1..ypan, 2..ywrap */ static unsigned short *pmi_base = NULL; static void (*pmi_start)(void); @@ -80,15 +80,30 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var, return 0; } -static void vesa_setpalette(int regno, unsigned red, unsigned green, +static int vesa_setpalette(int regno, unsigned red, unsigned green, unsigned blue) { int shift = 16 - depth; + int err = -EINVAL; + +/* + * Try VGA registers first... + */ + if (vga_compat) { + outb_p(regno, dac_reg); + outb_p(red >> shift, dac_val); + outb_p(green >> shift, dac_val); + outb_p(blue >> shift, dac_val); + err = 0; + } #ifdef __i386__ - struct { u_char blue, green, red, pad; } entry; +/* + * Fallback to the PMI.... + */ + if (err && pmi_setpal) { + struct { u_char blue, green, red, pad; } entry; - if (pmi_setpal) { entry.red = red >> shift; entry.green = green >> shift; entry.blue = blue >> shift; @@ -102,26 +117,19 @@ static void vesa_setpalette(int regno, unsigned red, unsigned green, "d" (regno), /* EDX */ "D" (&entry), /* EDI */ "S" (&pmi_pal)); /* ESI */ - return; + err = 0; } #endif -/* - * without protected mode interface and if VGA compatible, - * try VGA registers... - */ - if (vga_compat) { - outb_p(regno, dac_reg); - outb_p(red >> shift, dac_val); - outb_p(green >> shift, dac_val); - outb_p(blue >> shift, dac_val); - } + return err; } static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) { + int err = 0; + /* * Set a single color register. The values supplied are * already rounded down to the hardware's capabilities @@ -133,7 +141,7 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, return 1; if (info->var.bits_per_pixel == 8) - vesa_setpalette(regno,red,green,blue); + err = vesa_setpalette(regno,red,green,blue); else if (regno < 16) { switch (info->var.bits_per_pixel) { case 16: @@ -164,7 +172,7 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, } } - return 0; + return err; } static struct fb_ops vesafb_ops = { @@ -460,9 +468,7 @@ static struct platform_driver vesafb_driver = { }, }; -static struct platform_device vesafb_device = { - .name = "vesafb", -}; +static struct platform_device *vesafb_device; static int __init vesafb_init(void) { @@ -475,10 +481,19 @@ static int __init vesafb_init(void) ret = platform_driver_register(&vesafb_driver); if (!ret) { - ret = platform_device_register(&vesafb_device); - if (ret) + vesafb_device = platform_device_alloc("vesafb", 0); + + if (vesafb_device) + ret = platform_device_add(vesafb_device); + else + ret = -ENOMEM; + + if (ret) { + platform_device_put(vesafb_device); platform_driver_unregister(&vesafb_driver); + } } + return ret; } module_init(vesafb_init); diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c index 77eed1fd9943..d073ffb6e1f9 100644 --- a/drivers/video/vfb.c +++ b/drivers/video/vfb.c @@ -398,12 +398,6 @@ static int __init vfb_setup(char *options) * Initialisation */ -static void vfb_platform_release(struct device *device) -{ - // This is called when the reference count goes to zero. - dev_err(device, "This driver is broken, please bug the authors so they will fix it.\n"); -} - static int __init vfb_probe(struct platform_device *dev) { struct fb_info *info; @@ -482,13 +476,7 @@ static struct platform_driver vfb_driver = { }, }; -static struct platform_device vfb_device = { - .name = "vfb", - .id = 0, - .dev = { - .release = vfb_platform_release, - } -}; +static struct platform_device *vfb_device; static int __init vfb_init(void) { @@ -508,10 +496,19 @@ static int __init vfb_init(void) ret = platform_driver_register(&vfb_driver); if (!ret) { - ret = platform_device_register(&vfb_device); - if (ret) + vfb_device = platform_device_alloc("vfb", 0); + + if (vfb_device) + ret = platform_device_add(vfb_device); + else + ret = -ENOMEM; + + if (ret) { + platform_device_put(vfb_device); platform_driver_unregister(&vfb_driver); + } } + return ret; } @@ -520,7 +517,7 @@ module_init(vfb_init); #ifdef MODULE static void __exit vfb_exit(void) { - platform_device_unregister(&vfb_device); + platform_device_unregister(vfb_device); platform_driver_unregister(&vfb_driver); } diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c index 4fd2a272e03d..3c404c9bd36c 100644 --- a/drivers/video/vga16fb.c +++ b/drivers/video/vga16fb.c @@ -1334,9 +1334,8 @@ static int vga16fb_setup(char *options) } #endif -static int __init vga16fb_probe(struct device *device) +static int __init vga16fb_probe(struct platform_device *dev) { - struct platform_device *dev = to_platform_device(device); struct fb_info *info; struct vga16fb_par *par; int i; @@ -1403,7 +1402,7 @@ static int __init vga16fb_probe(struct device *device) printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); - dev_set_drvdata(device, info); + platform_set_drvdata(dev, info); return 0; @@ -1417,9 +1416,9 @@ static int __init vga16fb_probe(struct device *device) return ret; } -static int vga16fb_remove(struct device *device) +static int vga16fb_remove(struct platform_device *dev) { - struct fb_info *info = dev_get_drvdata(device); + struct fb_info *info = platform_get_drvdata(dev); if (info) { unregister_framebuffer(info); @@ -1432,16 +1431,15 @@ static int vga16fb_remove(struct device *device) return 0; } -static struct device_driver vga16fb_driver = { - .name = "vga16fb", - .bus = &platform_bus_type, +static struct platform_driver vga16fb_driver = { .probe = vga16fb_probe, .remove = vga16fb_remove, + .driver = { + .name = "vga16fb", + }, }; -static struct platform_device vga16fb_device = { - .name = "vga16fb", -}; +static struct platform_device *vga16fb_device; static int __init vga16fb_init(void) { @@ -1454,12 +1452,20 @@ static int __init vga16fb_init(void) vga16fb_setup(option); #endif - ret = driver_register(&vga16fb_driver); + ret = platform_driver_register(&vga16fb_driver); if (!ret) { - ret = platform_device_register(&vga16fb_device); - if (ret) - driver_unregister(&vga16fb_driver); + vga16fb_device = platform_device_alloc("vga16fb", 0); + + if (vga16fb_device) + ret = platform_device_add(vga16fb_device); + else + ret = -ENOMEM; + + if (ret) { + platform_device_put(vga16fb_device); + platform_driver_unregister(&vga16fb_driver); + } } return ret; @@ -1467,8 +1473,8 @@ static int __init vga16fb_init(void) static void __exit vga16fb_exit(void) { - platform_device_unregister(&vga16fb_device); - driver_unregister(&vga16fb_driver); + platform_device_unregister(vga16fb_device); + platform_driver_unregister(&vga16fb_driver); } MODULE_LICENSE("GPL"); diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c index 15179ec62339..d94efafc77b5 100644 --- a/drivers/video/vgastate.c +++ b/drivers/video/vgastate.c @@ -13,7 +13,6 @@ * archive for more details. * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/fb.h> |