diff options
-rw-r--r-- | drivers/video/tridentfb.c | 82 |
1 files changed, 46 insertions, 36 deletions
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c index 3e8a1ef892ce..cb37e10734b6 100644 --- a/drivers/video/tridentfb.c +++ b/drivers/video/tridentfb.c | |||
@@ -33,10 +33,7 @@ struct tridentfb_par { | |||
33 | static unsigned char eng_oper; /* engine operation... */ | 33 | static unsigned char eng_oper; /* engine operation... */ |
34 | static struct fb_ops tridentfb_ops; | 34 | static struct fb_ops tridentfb_ops; |
35 | 35 | ||
36 | static struct tridentfb_par default_par; | ||
37 | |||
38 | /* FIXME:kmalloc these 3 instead */ | 36 | /* FIXME:kmalloc these 3 instead */ |
39 | static struct fb_info fb_info; | ||
40 | static u32 pseudo_pal[16]; | 37 | static u32 pseudo_pal[16]; |
41 | 38 | ||
42 | static struct fb_var_screeninfo default_var; | 39 | static struct fb_var_screeninfo default_var; |
@@ -1217,16 +1214,23 @@ static struct fb_ops tridentfb_ops = { | |||
1217 | .fb_imageblit = cfb_imageblit, | 1214 | .fb_imageblit = cfb_imageblit, |
1218 | }; | 1215 | }; |
1219 | 1216 | ||
1220 | static int __devinit trident_pci_probe(struct pci_dev * dev, | 1217 | static int __devinit trident_pci_probe(struct pci_dev *dev, |
1221 | const struct pci_device_id * id) | 1218 | const struct pci_device_id *id) |
1222 | { | 1219 | { |
1223 | int err; | 1220 | int err; |
1224 | unsigned char revision; | 1221 | unsigned char revision; |
1222 | struct fb_info *info; | ||
1223 | struct tridentfb_par *default_par; | ||
1225 | 1224 | ||
1226 | err = pci_enable_device(dev); | 1225 | err = pci_enable_device(dev); |
1227 | if (err) | 1226 | if (err) |
1228 | return err; | 1227 | return err; |
1229 | 1228 | ||
1229 | info = framebuffer_alloc(sizeof(struct tridentfb_par), &dev->dev); | ||
1230 | if (!info) | ||
1231 | return -ENOMEM; | ||
1232 | default_par = info->par; | ||
1233 | |||
1230 | chip_id = id->device; | 1234 | chip_id = id->device; |
1231 | 1235 | ||
1232 | if (chip_id == CYBERBLADEi1) | 1236 | if (chip_id == CYBERBLADEi1) |
@@ -1282,8 +1286,6 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, | |||
1282 | /* acceleration is on by default for 3D chips */ | 1286 | /* acceleration is on by default for 3D chips */ |
1283 | defaultaccel = chip3D && !noaccel; | 1287 | defaultaccel = chip3D && !noaccel; |
1284 | 1288 | ||
1285 | fb_info.par = &default_par; | ||
1286 | |||
1287 | /* setup MMIO region */ | 1289 | /* setup MMIO region */ |
1288 | tridentfb_fix.mmio_start = pci_resource_start(dev, 1); | 1290 | tridentfb_fix.mmio_start = pci_resource_start(dev, 1); |
1289 | tridentfb_fix.mmio_len = chip3D ? 0x20000 : 0x10000; | 1291 | tridentfb_fix.mmio_len = chip3D ? 0x20000 : 0x10000; |
@@ -1293,9 +1295,10 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, | |||
1293 | return -1; | 1295 | return -1; |
1294 | } | 1296 | } |
1295 | 1297 | ||
1296 | default_par.io_virt = ioremap_nocache(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); | 1298 | default_par->io_virt = ioremap_nocache(tridentfb_fix.mmio_start, |
1299 | tridentfb_fix.mmio_len); | ||
1297 | 1300 | ||
1298 | if (!default_par.io_virt) { | 1301 | if (!default_par->io_virt) { |
1299 | debug("ioremap failed\n"); | 1302 | debug("ioremap failed\n"); |
1300 | err = -1; | 1303 | err = -1; |
1301 | goto out_unmap1; | 1304 | goto out_unmap1; |
@@ -1305,46 +1308,46 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, | |||
1305 | 1308 | ||
1306 | /* setup framebuffer memory */ | 1309 | /* setup framebuffer memory */ |
1307 | tridentfb_fix.smem_start = pci_resource_start(dev, 0); | 1310 | tridentfb_fix.smem_start = pci_resource_start(dev, 0); |
1308 | tridentfb_fix.smem_len = get_memsize(&default_par); | 1311 | tridentfb_fix.smem_len = get_memsize(default_par); |
1309 | 1312 | ||
1310 | if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) { | 1313 | if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) { |
1311 | debug("request_mem_region failed!\n"); | 1314 | debug("request_mem_region failed!\n"); |
1312 | disable_mmio(fb_info.par); | 1315 | disable_mmio(info->par); |
1313 | err = -1; | 1316 | err = -1; |
1314 | goto out_unmap1; | 1317 | goto out_unmap1; |
1315 | } | 1318 | } |
1316 | 1319 | ||
1317 | fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start, | 1320 | info->screen_base = ioremap_nocache(tridentfb_fix.smem_start, |
1318 | tridentfb_fix.smem_len); | 1321 | tridentfb_fix.smem_len); |
1319 | 1322 | ||
1320 | if (!fb_info.screen_base) { | 1323 | if (!info->screen_base) { |
1321 | debug("ioremap failed\n"); | 1324 | debug("ioremap failed\n"); |
1322 | err = -1; | 1325 | err = -1; |
1323 | goto out_unmap2; | 1326 | goto out_unmap2; |
1324 | } | 1327 | } |
1325 | 1328 | ||
1326 | output("%s board found\n", pci_name(dev)); | 1329 | output("%s board found\n", pci_name(dev)); |
1327 | displaytype = get_displaytype(&default_par); | 1330 | displaytype = get_displaytype(default_par); |
1328 | 1331 | ||
1329 | if (flatpanel) | 1332 | if (flatpanel) |
1330 | nativex = get_nativex(&default_par); | 1333 | nativex = get_nativex(default_par); |
1331 | 1334 | ||
1332 | fb_info.fix = tridentfb_fix; | 1335 | info->fix = tridentfb_fix; |
1333 | fb_info.fbops = &tridentfb_ops; | 1336 | info->fbops = &tridentfb_ops; |
1334 | 1337 | ||
1335 | 1338 | ||
1336 | fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; | 1339 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; |
1337 | #ifdef CONFIG_FB_TRIDENT_ACCEL | 1340 | #ifdef CONFIG_FB_TRIDENT_ACCEL |
1338 | fb_info.flags |= FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; | 1341 | info->flags |= FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; |
1339 | #endif | 1342 | #endif |
1340 | fb_info.pseudo_palette = pseudo_pal; | 1343 | info->pseudo_palette = pseudo_pal; |
1341 | 1344 | ||
1342 | if (!fb_find_mode(&default_var, &fb_info, | 1345 | if (!fb_find_mode(&default_var, info, |
1343 | mode_option, NULL, 0, NULL, bpp)) { | 1346 | mode_option, NULL, 0, NULL, bpp)) { |
1344 | err = -EINVAL; | 1347 | err = -EINVAL; |
1345 | goto out_unmap2; | 1348 | goto out_unmap2; |
1346 | } | 1349 | } |
1347 | err = fb_alloc_cmap(&fb_info.cmap, 256, 0); | 1350 | err = fb_alloc_cmap(&info->cmap, 256, 0); |
1348 | if (err < 0) | 1351 | if (err < 0) |
1349 | goto out_unmap2; | 1352 | goto out_unmap2; |
1350 | 1353 | ||
@@ -1353,39 +1356,46 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, | |||
1353 | else | 1356 | else |
1354 | default_var.accel_flags &= ~FB_ACCELF_TEXT; | 1357 | default_var.accel_flags &= ~FB_ACCELF_TEXT; |
1355 | default_var.activate |= FB_ACTIVATE_NOW; | 1358 | default_var.activate |= FB_ACTIVATE_NOW; |
1356 | fb_info.var = default_var; | 1359 | info->var = default_var; |
1357 | fb_info.device = &dev->dev; | 1360 | info->device = &dev->dev; |
1358 | if (register_framebuffer(&fb_info) < 0) { | 1361 | if (register_framebuffer(info) < 0) { |
1359 | printk(KERN_ERR "tridentfb: could not register Trident framebuffer\n"); | 1362 | printk(KERN_ERR "tridentfb: could not register Trident framebuffer\n"); |
1360 | fb_dealloc_cmap(&fb_info.cmap); | 1363 | fb_dealloc_cmap(&info->cmap); |
1361 | err = -EINVAL; | 1364 | err = -EINVAL; |
1362 | goto out_unmap2; | 1365 | goto out_unmap2; |
1363 | } | 1366 | } |
1364 | output("fb%d: %s frame buffer device %dx%d-%dbpp\n", | 1367 | output("fb%d: %s frame buffer device %dx%d-%dbpp\n", |
1365 | fb_info.node, fb_info.fix.id, default_var.xres, | 1368 | info->node, info->fix.id, default_var.xres, |
1366 | default_var.yres, default_var.bits_per_pixel); | 1369 | default_var.yres, default_var.bits_per_pixel); |
1370 | |||
1371 | pci_set_drvdata(dev, info); | ||
1367 | return 0; | 1372 | return 0; |
1368 | 1373 | ||
1369 | out_unmap2: | 1374 | out_unmap2: |
1370 | if (fb_info.screen_base) | 1375 | if (info->screen_base) |
1371 | iounmap(fb_info.screen_base); | 1376 | iounmap(info->screen_base); |
1372 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); | 1377 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); |
1373 | disable_mmio(fb_info.par); | 1378 | disable_mmio(info->par); |
1374 | out_unmap1: | 1379 | out_unmap1: |
1375 | if (default_par.io_virt) | 1380 | if (default_par->io_virt) |
1376 | iounmap(default_par.io_virt); | 1381 | iounmap(default_par->io_virt); |
1377 | release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); | 1382 | release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); |
1383 | framebuffer_release(info); | ||
1378 | return err; | 1384 | return err; |
1379 | } | 1385 | } |
1380 | 1386 | ||
1381 | static void __devexit trident_pci_remove(struct pci_dev *dev) | 1387 | static void __devexit trident_pci_remove(struct pci_dev *dev) |
1382 | { | 1388 | { |
1383 | struct tridentfb_par *par = (struct tridentfb_par*)fb_info.par; | 1389 | struct fb_info *info = pci_get_drvdata(dev); |
1384 | unregister_framebuffer(&fb_info); | 1390 | struct tridentfb_par *par = info->par; |
1391 | |||
1392 | unregister_framebuffer(info); | ||
1385 | iounmap(par->io_virt); | 1393 | iounmap(par->io_virt); |
1386 | iounmap(fb_info.screen_base); | 1394 | iounmap(info->screen_base); |
1387 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); | 1395 | release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); |
1388 | release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); | 1396 | release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); |
1397 | pci_set_drvdata(dev, NULL); | ||
1398 | framebuffer_release(info); | ||
1389 | } | 1399 | } |
1390 | 1400 | ||
1391 | /* List of boards that we are trying to support */ | 1401 | /* List of boards that we are trying to support */ |