aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/vesafb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/vesafb.c')
-rw-r--r--drivers/video/vesafb.c59
1 files changed, 37 insertions, 22 deletions
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;
51static int mtrr = 0; /* disable mtrr */ 51static int mtrr = 0; /* disable mtrr */
52static int vram_remap __initdata = 0; /* Set amount of memory to be used */ 52static int vram_remap __initdata = 0; /* Set amount of memory to be used */
53static int vram_total __initdata = 0; /* Set total amount of memory */ 53static int vram_total __initdata = 0; /* Set total amount of memory */
54static int pmi_setpal = 0; /* pmi for palette changes ??? */ 54static int pmi_setpal = 1; /* pmi for palette changes ??? */
55static int ypan = 0; /* 0..nothing, 1..ypan, 2..ywrap */ 55static int ypan = 0; /* 0..nothing, 1..ypan, 2..ywrap */
56static unsigned short *pmi_base = NULL; 56static unsigned short *pmi_base = NULL;
57static void (*pmi_start)(void); 57static void (*pmi_start)(void);
@@ -80,15 +80,30 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var,
80 return 0; 80 return 0;
81} 81}
82 82
83static void vesa_setpalette(int regno, unsigned red, unsigned green, 83static int vesa_setpalette(int regno, unsigned red, unsigned green,
84 unsigned blue) 84 unsigned blue)
85{ 85{
86 int shift = 16 - depth; 86 int shift = 16 - depth;
87 int err = -EINVAL;
88
89/*
90 * Try VGA registers first...
91 */
92 if (vga_compat) {
93 outb_p(regno, dac_reg);
94 outb_p(red >> shift, dac_val);
95 outb_p(green >> shift, dac_val);
96 outb_p(blue >> shift, dac_val);
97 err = 0;
98 }
87 99
88#ifdef __i386__ 100#ifdef __i386__
89 struct { u_char blue, green, red, pad; } entry; 101/*
102 * Fallback to the PMI....
103 */
104 if (err && pmi_setpal) {
105 struct { u_char blue, green, red, pad; } entry;
90 106
91 if (pmi_setpal) {
92 entry.red = red >> shift; 107 entry.red = red >> shift;
93 entry.green = green >> shift; 108 entry.green = green >> shift;
94 entry.blue = blue >> shift; 109 entry.blue = blue >> shift;
@@ -102,26 +117,19 @@ static void vesa_setpalette(int regno, unsigned red, unsigned green,
102 "d" (regno), /* EDX */ 117 "d" (regno), /* EDX */
103 "D" (&entry), /* EDI */ 118 "D" (&entry), /* EDI */
104 "S" (&pmi_pal)); /* ESI */ 119 "S" (&pmi_pal)); /* ESI */
105 return; 120 err = 0;
106 } 121 }
107#endif 122#endif
108 123
109/* 124 return err;
110 * without protected mode interface and if VGA compatible,
111 * try VGA registers...
112 */
113 if (vga_compat) {
114 outb_p(regno, dac_reg);
115 outb_p(red >> shift, dac_val);
116 outb_p(green >> shift, dac_val);
117 outb_p(blue >> shift, dac_val);
118 }
119} 125}
120 126
121static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, 127static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
122 unsigned blue, unsigned transp, 128 unsigned blue, unsigned transp,
123 struct fb_info *info) 129 struct fb_info *info)
124{ 130{
131 int err = 0;
132
125 /* 133 /*
126 * Set a single color register. The values supplied are 134 * Set a single color register. The values supplied are
127 * already rounded down to the hardware's capabilities 135 * already rounded down to the hardware's capabilities
@@ -133,7 +141,7 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
133 return 1; 141 return 1;
134 142
135 if (info->var.bits_per_pixel == 8) 143 if (info->var.bits_per_pixel == 8)
136 vesa_setpalette(regno,red,green,blue); 144 err = vesa_setpalette(regno,red,green,blue);
137 else if (regno < 16) { 145 else if (regno < 16) {
138 switch (info->var.bits_per_pixel) { 146 switch (info->var.bits_per_pixel) {
139 case 16: 147 case 16:
@@ -164,7 +172,7 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
164 } 172 }
165 } 173 }
166 174
167 return 0; 175 return err;
168} 176}
169 177
170static struct fb_ops vesafb_ops = { 178static struct fb_ops vesafb_ops = {
@@ -460,9 +468,7 @@ static struct platform_driver vesafb_driver = {
460 }, 468 },
461}; 469};
462 470
463static struct platform_device vesafb_device = { 471static struct platform_device *vesafb_device;
464 .name = "vesafb",
465};
466 472
467static int __init vesafb_init(void) 473static int __init vesafb_init(void)
468{ 474{
@@ -475,10 +481,19 @@ static int __init vesafb_init(void)
475 ret = platform_driver_register(&vesafb_driver); 481 ret = platform_driver_register(&vesafb_driver);
476 482
477 if (!ret) { 483 if (!ret) {
478 ret = platform_device_register(&vesafb_device); 484 vesafb_device = platform_device_alloc("vesafb", 0);
479 if (ret) 485
486 if (vesafb_device)
487 ret = platform_device_add(vesafb_device);
488 else
489 ret = -ENOMEM;
490
491 if (ret) {
492 platform_device_put(vesafb_device);
480 platform_driver_unregister(&vesafb_driver); 493 platform_driver_unregister(&vesafb_driver);
494 }
481 } 495 }
496
482 return ret; 497 return ret;
483} 498}
484module_init(vesafb_init); 499module_init(vesafb_init);