fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / video / console / newport_con.c
index 5e4fdc0..7fa1afe 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/tty.h>
 #include <linux/kd.h>
 #include <linux/selection.h>
 #include <linux/console.h>
@@ -21,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 
+#include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/page.h>
@@ -31,7 +31,6 @@
 #include <linux/font.h>
 
 
-extern struct font_desc font_vga_8x16;
 extern unsigned long sgi_gfxaddr;
 
 #define FONT_DATA ((unsigned char *)font_vga_8x16.data)
@@ -51,8 +50,9 @@ 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 *op);
+static int newport_set_def_font(int unit, struct console_font *op);
 
 #define BMASK(c) (c << 24)
 
@@ -73,7 +73,7 @@ static int newport_set_def_font(int unit, struct console_font_op *op);
 static inline void newport_render_background(int xstart, int ystart,
                                             int xend, int yend, int ci)
 {
-       newport_wait();
+       newport_wait(npregs);
        npregs->set.wrmask = 0xffffffff;
        npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
                                 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
@@ -90,7 +90,7 @@ static inline void newport_init_cmap(void)
        unsigned short i;
 
        for (i = 0; i < 16; i++) {
-               newport_bfwait();
+               newport_bfwait(npregs);
                newport_cmap_setaddr(npregs, color_table[i]);
                newport_cmap_setrgb(npregs,
                                    default_red[i],
@@ -107,19 +107,19 @@ static void newport_show_logo(void)
        unsigned long i;
 
        for (i = 0; i < logo->clutsize; i++) {
-               newport_bfwait();
+               newport_bfwait(npregs);
                newport_cmap_setaddr(npregs, i + 0x20);
                newport_cmap_setrgb(npregs, clut[0], clut[1], clut[2]);
                clut += 3;
        }
 
-       newport_wait();
+       newport_wait(npregs);
        npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
                                 NPORT_DMODE0_CHOST);
 
        npregs->set.xystarti = ((newport_xsize - logo->width) << 16) | (0);
        npregs->set.xyendi = ((newport_xsize - 1) << 16);
-       newport_wait();
+       newport_wait(npregs);
 
        for (i = 0; i < logo->width*logo->height; i++)
                npregs->go.hostrw0 = *data++ << 24;
@@ -132,7 +132,7 @@ static inline void newport_clear_screen(int xstart, int ystart, int xend,
        if (logo_active)
                return;
 
-       newport_wait();
+       newport_wait(npregs);
        npregs->set.wrmask = 0xffffffff;
        npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
                                 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
@@ -149,12 +149,12 @@ static inline void newport_clear_lines(int ystart, int yend, int ci)
        newport_clear_screen(0, ystart, 1280 + 63, yend, ci);
 }
 
-void newport_reset(void)
+static void newport_reset(void)
 {
        unsigned short treg;
        int i;
 
-       newport_wait();
+       newport_wait(npregs);
        treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
        newport_vc2_set(npregs, VC2_IREG_CONTROL,
                        (treg | VC2_CTRL_EVIDEO));
@@ -164,7 +164,7 @@ void newport_reset(void)
        npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
                               NPORT_DMODE_W2 | VC2_PROTOCOL);
        for (i = 0; i < 128; i++) {
-               newport_bfwait();
+               newport_bfwait(npregs);
                if (i == 92 || i == 94)
                        npregs->set.dcbdata0.byshort.s1 = 0xff00;
                else
@@ -193,7 +193,7 @@ void newport_reset(void)
  * calculate the actual screen size by reading
  * the video timing out of the VC2
  */
-void newport_get_screensize(void)
+static void newport_get_screensize(void)
 {
        int i, cols;
        unsigned short ventry, treg;
@@ -204,7 +204,7 @@ void newport_get_screensize(void)
        npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
                               NPORT_DMODE_W2 | VC2_PROTOCOL);
        for (i = 0; i < 128; i++) {
-               newport_bfwait();
+               newport_bfwait(npregs);
                linetable[i] = npregs->set.dcbdata0.byshort.s1;
        }
 
@@ -215,12 +215,12 @@ void newport_get_screensize(void)
                npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
                                       NPORT_DMODE_W2 | VC2_PROTOCOL);
                do {
-                       newport_bfwait();
+                       newport_bfwait(npregs);
                        treg = npregs->set.dcbdata0.byshort.s1;
                        if ((treg & 1) == 0)
                                cols += (treg >> 7) & 0xfe;
                        if ((treg & 0x80) == 0) {
-                               newport_bfwait();
+                               newport_bfwait(npregs);
                                treg = npregs->set.dcbdata0.byshort.s1;
                        }
                } while ((treg & 0x8000) == 0);
@@ -283,6 +283,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,16 +299,18 @@ static const char *newport_startup(void)
 
        if (!sgi_gfxaddr)
                return NULL;
-       npregs = (struct newport_regs *) (KSEG1 + sgi_gfxaddr);
+
+       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()) {
-               return NULL;
-       }
+       if (newport_wait(npregs))
+               goto out_unmap;
 
        npregs->set.xstarti = TESTVAL;
        if (npregs->set._xstart.word != XSTI_TO_FXSTART(TESTVAL))
-               return NULL;
+               goto out_unmap;
 
        for (i = 0; i < MAX_NR_CONSOLES; i++)
                font_data[i] = FONT_DATA;
@@ -307,8 +318,12 @@ static const char *newport_startup(void)
        newport_reset();
        newport_get_revisions();
        newport_get_screensize();
+       newport_has_init = 1;
 
        return "SGI Newport";
+
+out_unmap:
+       return NULL;
 }
 
 static void newport_init(struct vc_data *vc, int init)
@@ -320,11 +335,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,
@@ -362,7 +376,7 @@ static void newport_putc(struct vc_data *vc, int charattr, int ypos,
                                  (charattr & 0xf0) >> 4);
 
        /* Set the color and drawing mode. */
-       newport_wait();
+       newport_wait(npregs);
        npregs->set.colori = charattr & 0xf;
        npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
                                 NPORT_DMODE0_STOPX | NPORT_DMODE0_ZPENAB |
@@ -371,7 +385,7 @@ static void newport_putc(struct vc_data *vc, int charattr, int ypos,
        /* Set coordinates for bitmap operation. */
        npregs->set.xystarti = (xpos << 16) | ((ypos + topscan) & 0x3ff);
        npregs->set.xyendi = ((xpos + 7) << 16);
-       newport_wait();
+       newport_wait(npregs);
 
        /* Go, baby, go... */
        RENDER(npregs, p);
@@ -395,7 +409,7 @@ static void newport_putcs(struct vc_data *vc, const unsigned short *s,
                                          xpos + ((count - 1) << 3), ypos,
                                          (charattr & 0xf0) >> 4);
 
-       newport_wait();
+       newport_wait(npregs);
 
        /* Set the color and drawing mode. */
        npregs->set.colori = charattr & 0xf;
@@ -406,7 +420,7 @@ static void newport_putcs(struct vc_data *vc, const unsigned short *s,
        for (i = 0; i < count; i++, xpos += 8) {
                p = &font_data[vc->vc_num][(scr_readw(s++) & 0xff) << 4];
 
-               newport_wait();
+               newport_wait(npregs);
 
                /* Set coordinates for bitmap operation. */
                npregs->set.xystarti =
@@ -459,7 +473,7 @@ static int newport_switch(struct vc_data *vc)
        return 1;
 }
 
-static int newport_blank(struct vc_data *c, int blank)
+static int newport_blank(struct vc_data *c, int blank, int mode_switch)
 {
        unsigned short treg;
 
@@ -477,7 +491,7 @@ static int newport_blank(struct vc_data *c, int blank)
        return 1;
 }
 
-static int newport_set_font(int unit, struct console_font_op *op)
+static int newport_set_font(int unit, struct console_font *op)
 {
        int w = op->width;
        int h = op->height;
@@ -531,7 +545,7 @@ static int newport_set_font(int unit, struct console_font_op *op)
        return 0;
 }
 
-static int newport_set_def_font(int unit, struct console_font_op *op)
+static int newport_set_def_font(int unit, struct console_font *op)
 {
        if (font_data[unit] != FONT_DATA) {
                if (--REFCOUNT(font_data[unit]) == 0)
@@ -543,18 +557,14 @@ static int newport_set_def_font(int unit, struct console_font_op *op)
        return 0;
 }
 
-static int newport_font_op(struct vc_data *vc, struct console_font_op *op)
+static int newport_font_default(struct vc_data *vc, struct console_font *op, char *name)
 {
-       int unit = vc->vc_num;
-
-       switch (op->op) {
-       case KD_FONT_OP_SET:
-               return newport_set_font(unit, op);
-       case KD_FONT_OP_SET_DEFAULT:
-               return newport_set_def_font(unit, op);
-       default:
-               return -ENOSYS;
-       }
+       return newport_set_def_font(vc->vc_num, op);
+}
+
+static int newport_font_set(struct vc_data *vc, struct console_font *font, unsigned flags)
+{
+       return newport_set_font(vc->vc_num, font);
 }
 
 static int newport_set_palette(struct vc_data *vc, unsigned char *table)
@@ -688,7 +698,7 @@ static void newport_bmove(struct vc_data *vc, int sy, int sx, int dy,
                xe = xs;
                xs = tmp;
        }
-       newport_wait();
+       newport_wait(npregs);
        npregs->set.drawmode0 = (NPORT_DMODE0_S2S | NPORT_DMODE0_BLOCK |
                                 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
                                 | NPORT_DMODE0_STOPY);
@@ -705,37 +715,46 @@ static int newport_dummy(struct vc_data *c)
 #define DUMMY (void *) newport_dummy
 
 const struct consw newport_con = {
-    .owner =           THIS_MODULE,
-    .con_startup =     newport_startup,
-    .con_init =                newport_init,
-    .con_deinit =      newport_deinit,
-    .con_clear =       newport_clear,
-    .con_putc =                newport_putc,
-    .con_putcs =       newport_putcs,
-    .con_cursor =      newport_cursor,
-    .con_scroll =      newport_scroll,
-    .con_bmove =       newport_bmove,
-    .con_switch =      newport_switch,
-    .con_blank =       newport_blank,
-    .con_font_op =     newport_font_op,
-    .con_set_palette = newport_set_palette,
-    .con_scrolldelta = newport_scrolldelta,
-    .con_set_origin =  DUMMY,
-    .con_save_screen = DUMMY
+       .owner            = THIS_MODULE,
+       .con_startup      = newport_startup,
+       .con_init         = newport_init,
+       .con_deinit       = newport_deinit,
+       .con_clear        = newport_clear,
+       .con_putc         = newport_putc,
+       .con_putcs        = newport_putcs,
+       .con_cursor       = newport_cursor,
+       .con_scroll       = newport_scroll,
+       .con_bmove        = newport_bmove,
+       .con_switch       = newport_switch,
+       .con_blank        = newport_blank,
+       .con_font_set     = newport_font_set,
+       .con_font_default = newport_font_default,
+       .con_set_palette  = newport_set_palette,
+       .con_scrolldelta  = newport_scrolldelta,
+       .con_set_origin   = DUMMY,
+       .con_save_screen  = DUMMY
 };
 
 #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