diff options
Diffstat (limited to 'drivers/video/console/newport_con.c')
| -rw-r--r-- | drivers/video/console/newport_con.c | 124 |
1 files changed, 91 insertions, 33 deletions
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 762c7a59314..a6ab9299813 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -6,13 +6,12 @@ * * This driver is based on sgicons.c and cons_newport. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 David S. Miller (davem@davemloft.net) * Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx) */ #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> @@ -23,17 +22,15 @@ #include <asm/io.h> #include <asm/uaccess.h> -#include <asm/system.h> #include <asm/page.h> #include <asm/pgtable.h> +#include <asm/gio_device.h> + #include <video/newport.h> #include <linux/linux_logo.h> #include <linux/font.h> - -extern unsigned long sgi_gfxaddr; - #define FONT_DATA ((unsigned char *)font_vga_8x16.data) /* borrowed from fbcon.c */ @@ -51,6 +48,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); @@ -98,14 +96,19 @@ static inline void newport_init_cmap(void) } } -static void newport_show_logo(void) +static const struct linux_logo *newport_show_logo(void) { #ifdef CONFIG_LOGO_SGI_CLUT224 const struct linux_logo *logo = fb_find_logo(8); - const unsigned char *clut = logo->clut; - const unsigned char *data = logo->data; + const unsigned char *clut; + const unsigned char *data; unsigned long i; + if (!logo) + return NULL; + clut = logo->clut; + data = logo->data; + for (i = 0; i < logo->clutsize; i++) { newport_bfwait(npregs); newport_cmap_setaddr(npregs, i + 0x20); @@ -123,6 +126,8 @@ static void newport_show_logo(void) for (i = 0; i < logo->width*logo->height; i++) npregs->go.hostrw0 = *data++ << 24; + + return logo; #endif /* CONFIG_LOGO_SGI_CLUT224 */ } @@ -149,7 +154,7 @@ 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; @@ -193,7 +198,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; @@ -209,7 +214,7 @@ void newport_get_screensize(void) } newport_xsize = newport_ysize = 0; - for (i = 0; linetable[i + 1] && (i < sizeof(linetable)); i += 2) { + for (i = 0; i < ARRAY_SIZE(linetable) - 1 && linetable[i + 1]; i += 2) { cols = 0; newport_vc2_set(npregs, VC2_IREG_RADDR, linetable[i]); npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM | @@ -283,15 +288,20 @@ static void newport_get_revisions(void) xcurs_correction = 21; } -/* Can't be __init, take_over_console may call it later */ +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, do_take_over_console may call it later */ static const char *newport_startup(void) { int i; - if (!sgi_gfxaddr) - return NULL; - 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,28 +317,34 @@ 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; } static void newport_init(struct vc_data *vc, int init) { - vc->vc_cols = newport_xsize / 8; - vc->vc_rows = newport_ysize / 16; + int cols, rows; + + cols = newport_xsize / 8; + rows = newport_ysize / 16; vc->vc_can_do_color = 1; + if (init) { + vc->vc_cols = cols; + vc->vc_rows = rows; + } else + vc_resize(vc, cols, rows); } 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, @@ -455,9 +471,10 @@ static int newport_switch(struct vc_data *vc) npregs->cset.topscan = 0x3ff; if (!logo_drawn) { - newport_show_logo(); - logo_drawn = 1; - logo_active = 1; + if (newport_show_logo()) { + logo_drawn = 1; + logo_active = 1; + } } return 1; @@ -725,20 +742,61 @@ const struct consw newport_con = { .con_save_screen = DUMMY }; -#ifdef MODULE -static int __init newport_console_init(void) +static int newport_probe(struct gio_device *dev, + const struct gio_device_id *id) { - return take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1); + unsigned long newport_addr; + int err; + + if (!dev->resource.start) + return -EINVAL; + + if (npregs) + return -EBUSY; /* we only support one Newport as console */ + + newport_addr = dev->resource.start + 0xF0000; + if (!request_mem_region(newport_addr, 0x10000, "Newport")) + return -ENODEV; + + npregs = (struct newport_regs *)/* ioremap cannot fail */ + ioremap(newport_addr, sizeof(struct newport_regs)); + console_lock(); + err = do_take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1); + console_unlock(); + return err; } -static void __exit newport_console_exit(void) +static void newport_remove(struct gio_device *dev) { give_up_console(&newport_con); iounmap((void *)npregs); } +static struct gio_device_id newport_ids[] = { + { .id = 0x7e }, + { .id = 0xff } +}; + +MODULE_ALIAS("gio:7e"); + +static struct gio_driver newport_driver = { + .name = "newport", + .id_table = newport_ids, + .probe = newport_probe, + .remove = newport_remove, +}; + +int __init newport_console_init(void) +{ + return gio_register_driver(&newport_driver); +} + +void __exit newport_console_exit(void) +{ + gio_unregister_driver(&newport_driver); +} + module_init(newport_console_init); module_exit(newport_console_exit); -#endif MODULE_LICENSE("GPL"); |
