Skip to content

Commit b362179

Browse files
tdzhdeller
authored andcommitted
fbdev/stifb: Allocate fb_info instance with framebuffer_alloc()
Allocate stifb's instance of fb_info with framebuffer_alloc(). This is the preferred way of creating fb_info with associated driver data stored in struct fb_info.par. Requires several, but minor, changes through out the driver's code. The intended side effect of this patch is that the new instance of struct fb_info now has its device field correctly set to the parent device of the STI ROM. A later patch can detect if the device is the firmware's primary output. It is also now correctly located within the Linux device hierarchy. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Tested-by: Helge Deller <deller@gmx.de> Reviewed-by: Helge Deller <deller@gmx.de> Signed-off-by: Helge Deller <deller@gmx.de>
1 parent 12b8de5 commit b362179

1 file changed

Lines changed: 56 additions & 50 deletions

File tree

drivers/video/fbdev/stifb.c

Lines changed: 56 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ typedef struct {
103103
} ngle_rom_t;
104104

105105
struct stifb_info {
106-
struct fb_info info;
106+
struct fb_info *info;
107107
unsigned int id;
108108
ngle_rom_t ngle_rom;
109109
struct sti_struct *sti;
@@ -153,27 +153,27 @@ static int __initdata stifb_bpp_pref[MAX_STI_ROMS];
153153
#define REG_44 0x210030
154154
#define REG_45 0x210034
155155

156-
#define READ_BYTE(fb,reg) gsc_readb((fb)->info.fix.mmio_start + (reg))
157-
#define READ_WORD(fb,reg) gsc_readl((fb)->info.fix.mmio_start + (reg))
156+
#define READ_BYTE(fb, reg) gsc_readb((fb)->info->fix.mmio_start + (reg))
157+
#define READ_WORD(fb, reg) gsc_readl((fb)->info->fix.mmio_start + (reg))
158158

159159

160160
#ifndef DEBUG_STIFB_REGS
161161
# define DEBUG_OFF()
162162
# define DEBUG_ON()
163-
# define WRITE_BYTE(value,fb,reg) gsc_writeb((value),(fb)->info.fix.mmio_start + (reg))
164-
# define WRITE_WORD(value,fb,reg) gsc_writel((value),(fb)->info.fix.mmio_start + (reg))
163+
# define WRITE_BYTE(value, fb, reg) gsc_writeb((value), (fb)->info->fix.mmio_start + (reg))
164+
# define WRITE_WORD(value, fb, reg) gsc_writel((value), (fb)->info->fix.mmio_start + (reg))
165165
#else
166166
static int debug_on = 1;
167167
# define DEBUG_OFF() debug_on=0
168168
# define DEBUG_ON() debug_on=1
169169
# define WRITE_BYTE(value,fb,reg) do { if (debug_on) \
170170
printk(KERN_DEBUG "%30s: WRITE_BYTE(0x%06x) = 0x%02x (old=0x%02x)\n", \
171171
__func__, reg, value, READ_BYTE(fb,reg)); \
172-
gsc_writeb((value),(fb)->info.fix.mmio_start + (reg)); } while (0)
172+
gsc_writeb((value), (fb)->info->fix.mmio_start + (reg)); } while (0)
173173
# define WRITE_WORD(value,fb,reg) do { if (debug_on) \
174174
printk(KERN_DEBUG "%30s: WRITE_WORD(0x%06x) = 0x%08x (old=0x%08x)\n", \
175175
__func__, reg, value, READ_WORD(fb,reg)); \
176-
gsc_writel((value),(fb)->info.fix.mmio_start + (reg)); } while (0)
176+
gsc_writel((value), (fb)->info->fix.mmio_start + (reg)); } while (0)
177177
#endif /* DEBUG_STIFB_REGS */
178178

179179

@@ -210,13 +210,13 @@ SETUP_FB(struct stifb_info *fb)
210210
reg10_value = 0x13601000;
211211
break;
212212
case S9000_ID_A1439A:
213-
if (fb->info.var.bits_per_pixel == 32)
213+
if (fb->info->var.bits_per_pixel == 32)
214214
reg10_value = 0xBBA0A000;
215215
else
216216
reg10_value = 0x13601000;
217217
break;
218218
case S9000_ID_HCRX:
219-
if (fb->info.var.bits_per_pixel == 32)
219+
if (fb->info->var.bits_per_pixel == 32)
220220
reg10_value = 0xBBA0A000;
221221
else
222222
reg10_value = 0x13602000;
@@ -254,7 +254,7 @@ static void
254254
FINISH_IMAGE_COLORMAP_ACCESS(struct stifb_info *fb)
255255
{
256256
WRITE_WORD(0x400, fb, REG_2);
257-
if (fb->info.var.bits_per_pixel == 32) {
257+
if (fb->info->var.bits_per_pixel == 32) {
258258
WRITE_WORD(0x83000100, fb, REG_1);
259259
} else {
260260
if (fb->id == S9000_ID_ARTIST || fb->id == CRT_ID_VISUALIZE_EG)
@@ -503,7 +503,7 @@ static void
503503
ngleSetupAttrPlanes(struct stifb_info *fb, int BufferNumber)
504504
{
505505
SETUP_ATTR_ACCESS(fb, BufferNumber);
506-
SET_ATTR_SIZE(fb, fb->info.var.xres, fb->info.var.yres);
506+
SET_ATTR_SIZE(fb, fb->info->var.xres, fb->info->var.yres);
507507
FINISH_ATTR_ACCESS(fb);
508508
SETUP_FB(fb);
509509
}
@@ -526,9 +526,9 @@ rattlerSetupPlanes(struct stifb_info *fb)
526526
SETUP_FB(fb);
527527
fb->id = saved_id;
528528

529-
for (y = 0; y < fb->info.var.yres; ++y)
530-
fb_memset_io(fb->info.screen_base + y * fb->info.fix.line_length,
531-
0xff, fb->info.var.xres * fb->info.var.bits_per_pixel/8);
529+
for (y = 0; y < fb->info->var.yres; ++y)
530+
fb_memset_io(fb->info->screen_base + y * fb->info->fix.line_length,
531+
0xff, fb->info->var.xres * fb->info->var.bits_per_pixel/8);
532532

533533
CRX24_SET_OVLY_MASK(fb);
534534
SETUP_FB(fb);
@@ -607,7 +607,7 @@ setHyperLutBltCtl(struct stifb_info *fb, int offsetWithinLut, int length)
607607
lutBltCtl.fields.lutType = HYPER_CMAP_TYPE;
608608

609609
/* Expect lutIndex to be 0 or 1 for image cmaps, 2 or 3 for overlay cmaps */
610-
if (fb->info.var.bits_per_pixel == 8)
610+
if (fb->info->var.bits_per_pixel == 8)
611611
lutBltCtl.fields.lutOffset = 2 * 256;
612612
else
613613
lutBltCtl.fields.lutOffset = 0 * 256;
@@ -688,7 +688,7 @@ ngleResetAttrPlanes(struct stifb_info *fb, unsigned int ctlPlaneReg)
688688
DataDynamic, MaskOtc,
689689
BGx(0), FGx(0)));
690690
packed_dst = 0;
691-
packed_len = (fb->info.var.xres << 16) | fb->info.var.yres;
691+
packed_len = (fb->info->var.xres << 16) | fb->info->var.yres;
692692
GET_FIFO_SLOTS(fb, nFreeFifoSlots, 2);
693693
NGLE_SET_DSTXY(fb, packed_dst);
694694
SET_LENXY_START_RECFILL(fb, packed_len);
@@ -738,7 +738,7 @@ ngleClearOverlayPlanes(struct stifb_info *fb, int mask, int data)
738738
NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, mask);
739739

740740
packed_dst = 0;
741-
packed_len = (fb->info.var.xres << 16) | fb->info.var.yres;
741+
packed_len = (fb->info->var.xres << 16) | fb->info->var.yres;
742742
NGLE_SET_DSTXY(fb, packed_dst);
743743

744744
/* Write zeroes to overlay planes */
@@ -760,7 +760,7 @@ hyperResetPlanes(struct stifb_info *fb, int enable)
760760
NGLE_LOCK(fb);
761761

762762
if (IS_24_DEVICE(fb))
763-
if (fb->info.var.bits_per_pixel == 32)
763+
if (fb->info->var.bits_per_pixel == 32)
764764
controlPlaneReg = 0x04000F00;
765765
else
766766
controlPlaneReg = 0x00000F00; /* 0x00000800 should be enough, but lets clear all 4 bits */
@@ -890,7 +890,7 @@ SETUP_HCRX(struct stifb_info *fb)
890890
GET_FIFO_SLOTS(fb, nFreeFifoSlots, 7);
891891

892892
if (IS_24_DEVICE(fb)) {
893-
hyperbowl = (fb->info.var.bits_per_pixel == 32) ?
893+
hyperbowl = (fb->info->var.bits_per_pixel == 32) ?
894894
HYPERBOWL_MODE01_8_24_LUT0_TRANSPARENT_LUT1_OPAQUE :
895895
HYPERBOWL_MODE01_8_24_LUT0_OPAQUE_LUT1_OPAQUE;
896896

@@ -924,21 +924,21 @@ SETUP_HCRX(struct stifb_info *fb)
924924
static int
925925
stifb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
926926
{
927-
struct stifb_info *fb = container_of(info, struct stifb_info, info);
927+
struct stifb_info *fb = info->par;
928928

929-
if (var->xres != fb->info.var.xres ||
930-
var->yres != fb->info.var.yres ||
931-
var->bits_per_pixel != fb->info.var.bits_per_pixel)
929+
if (var->xres != fb->info->var.xres ||
930+
var->yres != fb->info->var.yres ||
931+
var->bits_per_pixel != fb->info->var.bits_per_pixel)
932932
return -EINVAL;
933933

934934
var->xres_virtual = var->xres;
935935
var->yres_virtual = var->yres;
936936
var->xoffset = 0;
937937
var->yoffset = 0;
938-
var->grayscale = fb->info.var.grayscale;
939-
var->red.length = fb->info.var.red.length;
940-
var->green.length = fb->info.var.green.length;
941-
var->blue.length = fb->info.var.blue.length;
938+
var->grayscale = fb->info->var.grayscale;
939+
var->red.length = fb->info->var.red.length;
940+
var->green.length = fb->info->var.green.length;
941+
var->blue.length = fb->info->var.blue.length;
942942

943943
return 0;
944944
}
@@ -947,7 +947,7 @@ static int
947947
stifb_setcolreg(u_int regno, u_int red, u_int green,
948948
u_int blue, u_int transp, struct fb_info *info)
949949
{
950-
struct stifb_info *fb = container_of(info, struct stifb_info, info);
950+
struct stifb_info *fb = info->par;
951951
u32 color;
952952

953953
if (regno >= NR_PALETTE)
@@ -961,7 +961,7 @@ stifb_setcolreg(u_int regno, u_int red, u_int green,
961961

962962
START_IMAGE_COLORMAP_ACCESS(fb);
963963

964-
if (unlikely(fb->info.var.grayscale)) {
964+
if (unlikely(fb->info->var.grayscale)) {
965965
/* gray = 0.30*R + 0.59*G + 0.11*B */
966966
color = ((red * 77) +
967967
(green * 151) +
@@ -972,10 +972,10 @@ stifb_setcolreg(u_int regno, u_int red, u_int green,
972972
(blue));
973973
}
974974

975-
if (fb->info.fix.visual == FB_VISUAL_DIRECTCOLOR) {
976-
struct fb_var_screeninfo *var = &fb->info.var;
975+
if (fb->info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
976+
struct fb_var_screeninfo *var = &fb->info->var;
977977
if (regno < 16)
978-
((u32 *)fb->info.pseudo_palette)[regno] =
978+
((u32 *)fb->info->pseudo_palette)[regno] =
979979
regno << var->red.offset |
980980
regno << var->green.offset |
981981
regno << var->blue.offset;
@@ -1007,7 +1007,7 @@ stifb_setcolreg(u_int regno, u_int red, u_int green,
10071007
static int
10081008
stifb_blank(int blank_mode, struct fb_info *info)
10091009
{
1010-
struct stifb_info *fb = container_of(info, struct stifb_info, info);
1010+
struct stifb_info *fb = info->par;
10111011
int enable = (blank_mode == 0) ? ENABLE : DISABLE;
10121012

10131013
switch (fb->id) {
@@ -1036,12 +1036,12 @@ stifb_blank(int blank_mode, struct fb_info *info)
10361036
static void
10371037
stifb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
10381038
{
1039-
struct stifb_info *fb = container_of(info, struct stifb_info, info);
1039+
struct stifb_info *fb = info->par;
10401040

10411041
SETUP_COPYAREA(fb);
10421042

10431043
SETUP_HW(fb);
1044-
if (fb->info.var.bits_per_pixel == 32) {
1044+
if (fb->info->var.bits_per_pixel == 32) {
10451045
WRITE_WORD(0xBBA0A000, fb, REG_10);
10461046

10471047
NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xffffffff);
@@ -1075,15 +1075,15 @@ stifb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
10751075
static void
10761076
stifb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
10771077
{
1078-
struct stifb_info *fb = container_of(info, struct stifb_info, info);
1078+
struct stifb_info *fb = info->par;
10791079

10801080
if (rect->rop != ROP_COPY ||
1081-
(fb->id == S9000_ID_HCRX && fb->info.var.bits_per_pixel == 32))
1081+
(fb->id == S9000_ID_HCRX && fb->info->var.bits_per_pixel == 32))
10821082
return cfb_fillrect(info, rect);
10831083

10841084
SETUP_HW(fb);
10851085

1086-
if (fb->info.var.bits_per_pixel == 32) {
1086+
if (fb->info->var.bits_per_pixel == 32) {
10871087
WRITE_WORD(0xBBA0A000, fb, REG_10);
10881088

10891089
NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xffffffff);
@@ -1141,7 +1141,7 @@ stifb_init_display(struct stifb_info *fb)
11411141
switch (id) {
11421142
case S9000_ID_A1659A:
11431143
case S9000_ID_A1439A:
1144-
if (fb->info.var.bits_per_pixel == 32)
1144+
if (fb->info->var.bits_per_pixel == 32)
11451145
ngleSetupAttrPlanes(fb, BUFF1_CMAP3);
11461146
else {
11471147
ngleSetupAttrPlanes(fb, BUFF1_CMAP0);
@@ -1151,7 +1151,7 @@ stifb_init_display(struct stifb_info *fb)
11511151
break;
11521152
case S9000_ID_ARTIST:
11531153
case CRT_ID_VISUALIZE_EG:
1154-
if (fb->info.var.bits_per_pixel == 32)
1154+
if (fb->info->var.bits_per_pixel == 32)
11551155
ngleSetupAttrPlanes(fb, BUFF1_CMAP3);
11561156
else {
11571157
ngleSetupAttrPlanes(fb, ARTIST_CMAP0);
@@ -1193,11 +1193,11 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
11931193
char *dev_name;
11941194
int bpp, xres, yres;
11951195

1196-
fb = kzalloc(sizeof(*fb), GFP_ATOMIC);
1197-
if (!fb)
1196+
info = framebuffer_alloc(sizeof(*fb), sti->dev);
1197+
if (!info)
11981198
return -ENOMEM;
1199-
1200-
info = &fb->info;
1199+
fb = info->par;
1200+
fb->info = info;
12011201

12021202
/* set struct to a known state */
12031203
fix = &info->fix;
@@ -1390,10 +1390,10 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
13901390

13911391
/* save for primary gfx device detection & unregister_framebuffer() */
13921392
sti->info = info;
1393-
if (register_framebuffer(&fb->info) < 0)
1393+
if (register_framebuffer(fb->info) < 0)
13941394
goto out_err4;
13951395

1396-
fb_info(&fb->info, "%s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n",
1396+
fb_info(fb->info, "%s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n",
13971397
fix->id,
13981398
var->xres,
13991399
var->yres,
@@ -1402,6 +1402,8 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
14021402
fb->id,
14031403
fix->mmio_start);
14041404

1405+
dev_set_drvdata(sti->dev, info);
1406+
14051407
return 0;
14061408

14071409

@@ -1414,7 +1416,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
14141416
out_err1:
14151417
iounmap(info->screen_base);
14161418
out_err0:
1417-
kfree(fb);
1419+
framebuffer_release(info);
14181420
sti->info = NULL;
14191421
return -ENXIO;
14201422
}
@@ -1480,15 +1482,19 @@ stifb_cleanup(void)
14801482
sti = sti_get_rom(i);
14811483
if (!sti)
14821484
break;
1483-
if (sti->info) {
1484-
struct fb_info *info = sti->info;
1485-
unregister_framebuffer(sti->info);
1485+
if (sti->dev) {
1486+
struct fb_info *info = dev_get_drvdata(sti->dev);
1487+
1488+
if (!info)
1489+
continue;
1490+
unregister_framebuffer(info);
14861491
release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
14871492
release_mem_region(info->fix.smem_start, info->fix.smem_len);
14881493
if (info->screen_base)
14891494
iounmap(info->screen_base);
14901495
fb_dealloc_cmap(&info->cmap);
14911496
framebuffer_release(info);
1497+
dev_set_drvdata(sti->dev, NULL);
14921498
}
14931499
sti->info = NULL;
14941500
}

0 commit comments

Comments
 (0)