parisc: sticon - unbreak on 64bit kernel
authorHelge Deller <deller@gmx.de>
Wed, 6 Nov 2013 22:38:59 +0000 (23:38 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Dec 2013 18:55:46 +0000 (10:55 -0800)
commit 0219132fe7c26574371232b50db085573f6fbd3f upstream.

STI text console (sticon) was broken on 64bit machines with more than
4GB RAM and this lead in some cases to a kernel crash.

Since sticon uses the 32bit STI API it needs to keep pointers to memory
below 4GB. But on a 64bit kernel some memory regions (e.g. the kernel
stack) might be above 4GB which then may crash the kernel in the STI
functions.

Additionally sticon didn't selected the built-in framebuffer fonts by
default. This is now fixed.

On a side-note: Theoretically we could enhance the sticon driver to
use the 64bit STI API. But - beside the fact that some machines don't
provide a 64bit STI ROM - this would just add complexity.

Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/video/console/sticore.c
drivers/video/sticore.h
drivers/video/stifb.c

index 35687fd56456a82318b631e4ffc3df81b74759ca..4ad24f2c64727fdbaea36fe76124444aa3e34014 100644 (file)
@@ -3,7 +3,7 @@
  *     core code for console driver using HP's STI firmware
  *
  *     Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- *     Copyright (C) 2001-2003 Helge Deller <deller@gmx.de>
+ *     Copyright (C) 2001-2013 Helge Deller <deller@gmx.de>
  *     Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
  * 
  * TODO:
@@ -30,7 +30,7 @@
 
 #include "../sticore.h"
 
-#define STI_DRIVERVERSION "Version 0.9a"
+#define STI_DRIVERVERSION "Version 0.9b"
 
 static struct sti_struct *default_sti __read_mostly;
 
@@ -73,28 +73,34 @@ static const struct sti_init_flags default_init_flags = {
 
 static int sti_init_graph(struct sti_struct *sti)
 {
-       struct sti_init_inptr_ext inptr_ext = { 0, };
-       struct sti_init_inptr inptr = {
-               .text_planes    = 3, /* # of text planes (max 3 for STI) */
-               .ext_ptr        = STI_PTR(&inptr_ext)
-       };
-       struct sti_init_outptr outptr = { 0, };
+       struct sti_init_inptr *inptr = &sti->sti_data->init_inptr;
+       struct sti_init_inptr_ext *inptr_ext = &sti->sti_data->init_inptr_ext;
+       struct sti_init_outptr *outptr = &sti->sti_data->init_outptr;
        unsigned long flags;
-       int ret;
+       int ret, err;
 
        spin_lock_irqsave(&sti->lock, flags);
 
-       ret = STI_CALL(sti->init_graph, &default_init_flags, &inptr,
-               &outptr, sti->glob_cfg);
+       memset(inptr, 0, sizeof(*inptr));
+       inptr->text_planes = 3; /* # of text planes (max 3 for STI) */
+       memset(inptr_ext, 0, sizeof(*inptr_ext));
+       inptr->ext_ptr = STI_PTR(inptr_ext);
+       outptr->errno = 0;
+
+       ret = sti_call(sti, sti->init_graph, &default_init_flags, inptr,
+               outptr, sti->glob_cfg);
+
+       if (ret >= 0)
+               sti->text_planes = outptr->text_planes;
+       err = outptr->errno;
 
        spin_unlock_irqrestore(&sti->lock, flags);
 
        if (ret < 0) {
-               printk(KERN_ERR "STI init_graph failed (ret %d, errno %d)\n",ret,outptr.errno);
+               pr_err("STI init_graph failed (ret %d, errno %d)\n", ret, err);
                return -1;
        }
        
-       sti->text_planes = outptr.text_planes;
        return 0;
 }
 
@@ -104,16 +110,18 @@ static const struct sti_conf_flags default_conf_flags = {
 
 static void sti_inq_conf(struct sti_struct *sti)
 {
-       struct sti_conf_inptr inptr = { 0, };
+       struct sti_conf_inptr *inptr = &sti->sti_data->inq_inptr;
+       struct sti_conf_outptr *outptr = &sti->sti_data->inq_outptr;
        unsigned long flags;
        s32 ret;
 
-       sti->outptr.ext_ptr = STI_PTR(&sti->outptr_ext);
+       outptr->ext_ptr = STI_PTR(&sti->sti_data->inq_outptr_ext);
        
        do {
                spin_lock_irqsave(&sti->lock, flags);
-               ret = STI_CALL(sti->inq_conf, &default_conf_flags,
-                       &inptr, &sti->outptr, sti->glob_cfg);
+               memset(inptr, 0, sizeof(*inptr));
+               ret = sti_call(sti, sti->inq_conf, &default_conf_flags,
+                       inptr, outptr, sti->glob_cfg);
                spin_unlock_irqrestore(&sti->lock, flags);
        } while (ret == 1);
 }
@@ -126,7 +134,8 @@ static const struct sti_font_flags default_font_flags = {
 void
 sti_putc(struct sti_struct *sti, int c, int y, int x)
 {
-       struct sti_font_inptr inptr = {
+       struct sti_font_inptr *inptr = &sti->sti_data->font_inptr;
+       struct sti_font_inptr inptr_default = {
                .font_start_addr= STI_PTR(sti->font->raw),
                .index          = c_index(sti, c),
                .fg_color       = c_fg(sti, c),
@@ -134,14 +143,15 @@ sti_putc(struct sti_struct *sti, int c, int y, int x)
                .dest_x         = x * sti->font_width,
                .dest_y         = y * sti->font_height,
        };
-       struct sti_font_outptr outptr = { 0, };
+       struct sti_font_outptr *outptr = &sti->sti_data->font_outptr;
        s32 ret;
        unsigned long flags;
 
        do {
                spin_lock_irqsave(&sti->lock, flags);
-               ret = STI_CALL(sti->font_unpmv, &default_font_flags,
-                       &inptr, &outptr, sti->glob_cfg);
+               *inptr = inptr_default;
+               ret = sti_call(sti, sti->font_unpmv, &default_font_flags,
+                       inptr, outptr, sti->glob_cfg);
                spin_unlock_irqrestore(&sti->lock, flags);
        } while (ret == 1);
 }
@@ -156,7 +166,8 @@ void
 sti_set(struct sti_struct *sti, int src_y, int src_x,
        int height, int width, u8 color)
 {
-       struct sti_blkmv_inptr inptr = {
+       struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr;
+       struct sti_blkmv_inptr inptr_default = {
                .fg_color       = color,
                .bg_color       = color,
                .src_x          = src_x,
@@ -166,14 +177,15 @@ sti_set(struct sti_struct *sti, int src_y, int src_x,
                .width          = width,
                .height         = height,
        };
-       struct sti_blkmv_outptr outptr = { 0, };
+       struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;
        s32 ret;
        unsigned long flags;
        
        do {
                spin_lock_irqsave(&sti->lock, flags);
-               ret = STI_CALL(sti->block_move, &clear_blkmv_flags,
-                       &inptr, &outptr, sti->glob_cfg);
+               *inptr = inptr_default;
+               ret = sti_call(sti, sti->block_move, &clear_blkmv_flags,
+                       inptr, outptr, sti->glob_cfg);
                spin_unlock_irqrestore(&sti->lock, flags);
        } while (ret == 1);
 }
@@ -182,7 +194,8 @@ void
 sti_clear(struct sti_struct *sti, int src_y, int src_x,
          int height, int width, int c)
 {
-       struct sti_blkmv_inptr inptr = {
+       struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr;
+       struct sti_blkmv_inptr inptr_default = {
                .fg_color       = c_fg(sti, c),
                .bg_color       = c_bg(sti, c),
                .src_x          = src_x * sti->font_width,
@@ -192,14 +205,15 @@ sti_clear(struct sti_struct *sti, int src_y, int src_x,
                .width          = width * sti->font_width,
                .height         = height* sti->font_height,
        };
-       struct sti_blkmv_outptr outptr = { 0, };
+       struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;
        s32 ret;
        unsigned long flags;
 
        do {
                spin_lock_irqsave(&sti->lock, flags);
-               ret = STI_CALL(sti->block_move, &clear_blkmv_flags,
-                       &inptr, &outptr, sti->glob_cfg);
+               *inptr = inptr_default;
+               ret = sti_call(sti, sti->block_move, &clear_blkmv_flags,
+                       inptr, outptr, sti->glob_cfg);
                spin_unlock_irqrestore(&sti->lock, flags);
        } while (ret == 1);
 }
@@ -212,7 +226,8 @@ void
 sti_bmove(struct sti_struct *sti, int src_y, int src_x,
          int dst_y, int dst_x, int height, int width)
 {
-       struct sti_blkmv_inptr inptr = {
+       struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr;
+       struct sti_blkmv_inptr inptr_default = {
                .src_x          = src_x * sti->font_width,
                .src_y          = src_y * sti->font_height,
                .dest_x         = dst_x * sti->font_width,
@@ -220,14 +235,15 @@ sti_bmove(struct sti_struct *sti, int src_y, int src_x,
                .width          = width * sti->font_width,
                .height         = height* sti->font_height,
        };
-       struct sti_blkmv_outptr outptr = { 0, };
+       struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;
        s32 ret;
        unsigned long flags;
 
        do {
                spin_lock_irqsave(&sti->lock, flags);
-               ret = STI_CALL(sti->block_move, &default_blkmv_flags,
-                       &inptr, &outptr, sti->glob_cfg);
+               *inptr = inptr_default;
+               ret = sti_call(sti, sti->block_move, &default_blkmv_flags,
+                       inptr, outptr, sti->glob_cfg);
                spin_unlock_irqrestore(&sti->lock, flags);
        } while (ret == 1);
 }
@@ -284,7 +300,7 @@ __setup("sti=", sti_setup);
 
 
 
-static char *font_name[MAX_STI_ROMS] = { "VGA8x16", };
+static char *font_name[MAX_STI_ROMS];
 static int font_index[MAX_STI_ROMS],
           font_height[MAX_STI_ROMS],
           font_width[MAX_STI_ROMS];
@@ -389,10 +405,10 @@ static void sti_dump_outptr(struct sti_struct *sti)
                "%d used bits\n"
                "%d planes\n"
                "attributes %08x\n",
-                sti->outptr.bits_per_pixel,
-                sti->outptr.bits_used,
-                sti->outptr.planes,
-                sti->outptr.attributes));
+                sti->sti_data->inq_outptr.bits_per_pixel,
+                sti->sti_data->inq_outptr.bits_used,
+                sti->sti_data->inq_outptr.planes,
+                sti->sti_data->inq_outptr.attributes));
 }
 
 static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
@@ -402,24 +418,21 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
        struct sti_glob_cfg_ext *glob_cfg_ext;
        void *save_addr;
        void *sti_mem_addr;
-       const int save_addr_size = 1024;        /* XXX */
-       int i;
+       int i, size;
 
-       if (!sti->sti_mem_request)
+       if (sti->sti_mem_request < 256)
                sti->sti_mem_request = 256; /* STI default */
 
-       glob_cfg = kzalloc(sizeof(*sti->glob_cfg), GFP_KERNEL);
-       glob_cfg_ext = kzalloc(sizeof(*glob_cfg_ext), GFP_KERNEL);
-       save_addr = kzalloc(save_addr_size, GFP_KERNEL);
-       sti_mem_addr = kzalloc(sti->sti_mem_request, GFP_KERNEL);
+       size = sizeof(struct sti_all_data) + sti->sti_mem_request - 256;
 
-       if (!(glob_cfg && glob_cfg_ext && save_addr && sti_mem_addr)) {
-               kfree(glob_cfg);
-               kfree(glob_cfg_ext);
-               kfree(save_addr);
-               kfree(sti_mem_addr);
+       sti->sti_data = kzalloc(size, STI_LOWMEM);
+       if (!sti->sti_data)
                return -ENOMEM;
-       }
+
+       glob_cfg        = &sti->sti_data->glob_cfg;
+       glob_cfg_ext    = &sti->sti_data->glob_cfg_ext;
+       save_addr       = &sti->sti_data->save_addr;
+       sti_mem_addr    = &sti->sti_data->sti_mem_addr;
 
        glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext);
        glob_cfg->save_addr = STI_PTR(save_addr);
@@ -475,32 +488,31 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
        return 0;
 }
 
-#ifdef CONFIG_FB
+#ifdef CONFIG_FONTS
 static struct sti_cooked_font *
 sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
 {
-       const struct font_desc *fbfont;
+       const struct font_desc *fbfont = NULL;
        unsigned int size, bpc;
        void *dest;
        struct sti_rom_font *nf;
        struct sti_cooked_font *cooked_font;
        
-       if (!fbfont_name || !strlen(fbfont_name))
-               return NULL;
-       fbfont = find_font(fbfont_name);
+       if (fbfont_name && strlen(fbfont_name))
+               fbfont = find_font(fbfont_name);
        if (!fbfont)
                fbfont = get_default_font(1024,768, ~(u32)0, ~(u32)0);
        if (!fbfont)
                return NULL;
 
-       DPRINTK((KERN_DEBUG "selected %dx%d fb-font %s\n",
-                       fbfont->width, fbfont->height, fbfont->name));
+       pr_info("STI selected %dx%d framebuffer font %s for sticon\n",
+                       fbfont->width, fbfont->height, fbfont->name);
                        
        bpc = ((fbfont->width+7)/8) * fbfont->height; 
        size = bpc * 256;
        size += sizeof(struct sti_rom_font);
 
-       nf = kzalloc(size, GFP_KERNEL);
+       nf = kzalloc(size, STI_LOWMEM);
        if (!nf)
                return NULL;
 
@@ -637,7 +649,7 @@ static void *sti_bmode_font_raw(struct sti_cooked_font *f)
        unsigned char *n, *p, *q;
        int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font);
        
-       n = kzalloc (4*size, GFP_KERNEL);
+       n = kzalloc(4*size, STI_LOWMEM);
        if (!n)
                return NULL;
        p = n + 3;
@@ -673,7 +685,7 @@ static struct sti_rom *sti_get_bmode_rom (unsigned long address)
        sti_bmode_rom_copy(address + BMODE_LAST_ADDR_OFFS, sizeof(size), &size);
 
        size = (size+3) / 4;
-       raw = kmalloc(size, GFP_KERNEL);
+       raw = kmalloc(size, STI_LOWMEM);
        if (raw) {
                sti_bmode_rom_copy(address, size, raw);
                memmove (&raw->res004, &raw->type[0], 0x3c);
@@ -707,7 +719,7 @@ static struct sti_rom *sti_get_wmode_rom(unsigned long address)
        /* read the ROM size directly from the struct in ROM */ 
        size = gsc_readl(address + offsetof(struct sti_rom,last_addr));
 
-       raw = kmalloc(size, GFP_KERNEL);
+       raw = kmalloc(size, STI_LOWMEM);
        if (raw)
                sti_rom_copy(address, size, raw);
 
@@ -743,6 +755,10 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti,
 
        address = (unsigned long) STI_PTR(raw);
 
+       pr_info("STI ROM supports 32 %sbit firmware functions.\n",
+               raw->alt_code_type == ALT_CODE_TYPE_PA_RISC_64
+               ? "and 64 " : "");
+
        sti->font_unpmv = address + (raw->font_unpmv & 0x03ffffff);
        sti->block_move = address + (raw->block_move & 0x03ffffff);
        sti->init_graph = address + (raw->init_graph & 0x03ffffff);
@@ -901,7 +917,8 @@ test_rom:
        sti_dump_globcfg(sti->glob_cfg, sti->sti_mem_request);
        sti_dump_outptr(sti);
        
-       printk(KERN_INFO "    graphics card name: %s\n", sti->outptr.dev_name );
+       pr_info("    graphics card name: %s\n",
+               sti->sti_data->inq_outptr.dev_name);
 
        sti_roms[num_sti_roms] = sti;
        num_sti_roms++;
@@ -1073,6 +1090,29 @@ struct sti_struct * sti_get_rom(unsigned int index)
 }
 EXPORT_SYMBOL(sti_get_rom);
 
+
+int sti_call(const struct sti_struct *sti, unsigned long func,
+               const void *flags, void *inptr, void *outptr,
+               struct sti_glob_cfg *glob_cfg)
+{
+       unsigned long _flags = STI_PTR(flags);
+       unsigned long _inptr = STI_PTR(inptr);
+       unsigned long _outptr = STI_PTR(outptr);
+       unsigned long _glob_cfg = STI_PTR(glob_cfg);
+       int ret;
+
+#ifdef CONFIG_64BIT
+       /* Check for overflow when using 32bit STI on 64bit kernel. */
+       if (WARN_ONCE(_flags>>32 || _inptr>>32 || _outptr>>32 || _glob_cfg>>32,
+                       "Out of 32bit-range pointers!"))
+               return -1;
+#endif
+
+       ret = pdc_sti_call(func, _flags, _inptr, _outptr, _glob_cfg);
+
+       return ret;
+}
+
 MODULE_AUTHOR("Philipp Rumpf, Helge Deller, Thomas Bogendoerfer");
 MODULE_DESCRIPTION("Core STI driver for HP's NGLE series graphics cards in HP PARISC machines");
 MODULE_LICENSE("GPL v2");
index addf7b615ef8d2e88a8130a73ce1f5aac12032db..af1619536ac84f3d2b638c400f7bf674cd087724 100644 (file)
@@ -18,6 +18,9 @@
 #define STI_FONT_HPROMAN8 1
 #define STI_FONT_KANA8 2
 
+#define ALT_CODE_TYPE_UNKNOWN 0x00     /* alt code type values */
+#define ALT_CODE_TYPE_PA_RISC_64 0x01
+
 /* The latency of the STI functions cannot really be reduced by setting
  * this to 0;  STI doesn't seem to be designed to allow calling a different
  * function (or the same function with different arguments) after a
 
 #define STI_PTR(p)     ( virt_to_phys(p) )
 #define PTR_STI(p)     ( phys_to_virt((unsigned long)p) )
-#define STI_CALL(func, flags, inptr, outptr, glob_cfg) \
-       ({                                              \
-               pdc_sti_call( func, STI_PTR(flags),     \
-                                  STI_PTR(inptr),      \
-                                  STI_PTR(outptr),     \
-                                  STI_PTR(glob_cfg));  \
-       })
-
 
 #define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x)
 #define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y)
 #define sti_font_x(sti) (PTR_STI(sti->font)->width)
 #define sti_font_y(sti) (PTR_STI(sti->font)->height)
 
+#ifdef CONFIG_64BIT
+#define STI_LOWMEM     (GFP_KERNEL | GFP_DMA)
+#else
+#define STI_LOWMEM     (GFP_KERNEL)
+#endif
+
 
 /* STI function configuration structs */
 
@@ -306,6 +307,34 @@ struct sti_blkmv_outptr {
 };
 
 
+/* sti_all_data is an internal struct which needs to be allocated in
+ * low memory (< 4GB) if STI is used with 32bit STI on a 64bit kernel */
+
+struct sti_all_data {
+       struct sti_glob_cfg glob_cfg;
+       struct sti_glob_cfg_ext glob_cfg_ext;
+
+       struct sti_conf_inptr           inq_inptr;
+       struct sti_conf_outptr          inq_outptr; /* configuration */
+       struct sti_conf_outptr_ext      inq_outptr_ext;
+
+       struct sti_init_inptr_ext       init_inptr_ext;
+       struct sti_init_inptr           init_inptr;
+       struct sti_init_outptr          init_outptr;
+
+       struct sti_blkmv_inptr          blkmv_inptr;
+       struct sti_blkmv_outptr         blkmv_outptr;
+
+       struct sti_font_inptr           font_inptr;
+       struct sti_font_outptr          font_outptr;
+
+       /* leave as last entries */
+       unsigned long save_addr[1024 / sizeof(unsigned long)];
+          /* min 256 bytes which is STI default, max sti->sti_mem_request */
+       unsigned long sti_mem_addr[256 / sizeof(unsigned long)];
+       /* do not add something below here ! */
+};
+
 /* internal generic STI struct */
 
 struct sti_struct {
@@ -330,11 +359,9 @@ struct sti_struct {
        region_t regions[STI_REGION_MAX];
        unsigned long regions_phys[STI_REGION_MAX];
 
-       struct sti_glob_cfg *glob_cfg;
-       struct sti_cooked_font *font;   /* ptr to selected font (cooked) */
+       struct sti_glob_cfg *glob_cfg;  /* points into sti_all_data */
 
-       struct sti_conf_outptr outptr; /* configuration */
-       struct sti_conf_outptr_ext outptr_ext;
+       struct sti_cooked_font *font;   /* ptr to selected font (cooked) */
 
        struct pci_dev *pd;
 
@@ -343,6 +370,9 @@ struct sti_struct {
 
        /* pointer to the fb_info where this STI device is used */
        struct fb_info *info;
+
+       /* pointer to all internal data */
+       struct sti_all_data *sti_data;
 };
 
 
@@ -350,6 +380,14 @@ struct sti_struct {
 
 struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */
 
+
+/* sticore main function to call STI firmware */
+
+int sti_call(const struct sti_struct *sti, unsigned long func,
+               const void *flags, void *inptr, void *outptr,
+               struct sti_glob_cfg *glob_cfg);
+
+
 /* functions to call the STI ROM directly */
 
 void sti_putc(struct sti_struct *sti, int c, int y, int x);
index 876648e15e9d6d7cdd3d423da4401c2252ac3357..019a1feef995adcbfaff37c3e092a002eb190a4b 100644 (file)
@@ -1101,6 +1101,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
        var = &info->var;
 
        fb->sti = sti;
+       dev_name = sti->sti_data->inq_outptr.dev_name;
        /* store upper 32bits of the graphics id */
        fb->id = fb->sti->graphics_id[0];
 
@@ -1114,11 +1115,11 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
                  Since this driver only supports standard mode, we check
                  if the device name contains the string "DX" and tell the
                  user how to reconfigure the card. */
-               if (strstr(sti->outptr.dev_name, "DX")) {
+               if (strstr(dev_name, "DX")) {
                   printk(KERN_WARNING
 "WARNING: stifb framebuffer driver does not support '%s' in double-buffer mode.\n"
 "WARNING: Please disable the double-buffer mode in IPL menu (the PARISC-BIOS).\n",
-                       sti->outptr.dev_name);
+                       dev_name);
                   goto out_err0;
                }
                /* fall though */
@@ -1130,7 +1131,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
                break;
        default:
                printk(KERN_WARNING "stifb: '%s' (id: 0x%08x) not supported.\n",
-                       sti->outptr.dev_name, fb->id);
+                       dev_name, fb->id);
                goto out_err0;
        }
        
@@ -1154,7 +1155,6 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
                fb->id = S9000_ID_A1659A;
                break;
        case S9000_ID_TIMBER:   /* HP9000/710 Any (may be a grayscale device) */
-               dev_name = fb->sti->outptr.dev_name;
                if (strstr(dev_name, "GRAYSCALE") || 
                    strstr(dev_name, "Grayscale") ||
                    strstr(dev_name, "grayscale"))
@@ -1290,7 +1290,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
                var->xres, 
                var->yres,
                var->bits_per_pixel,
-               sti->outptr.dev_name,
+               dev_name,
                fb->id, 
                fix->mmio_start);