[PATCH] gx1fb: (try to) play nicer with various BIOSes

Seems that the CS5530A chip used in Geode GX1 systems has some crazy feature
that causes SMI traps when accessing the PCI configuration space of the video
device. Various GX1 BIOSes seem to use this 'feature' to hide the real BARs
of the device. This patch disables these traps (in an early PCI fixup) so
that Linux sees the real, physical BARs and not the virtual ones provided by
the BIOS.

This should allow the GX1 framebuffer driver to work on more systems that have
different BIOSes as the driver no longer guesses at what the virtual BARs
mean.

I'm not entirely sure it the correct solution as I can neither test regular
VGA console nor the X's 'cyrix' video driver so there might be some breakage
there -- probably best to get some more testers before applying it.

Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by David Vrabel and committed by Linus Torvalds a80da738 4836f574

+20 -7
+16
arch/i386/pci/fixup.c
··· 449 449 } 450 450 DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_TI, 0x8032, 451 451 pci_post_fixup_toshiba_ohci1394); 452 + 453 + 454 + /* 455 + * Prevent the BIOS trapping accesses to the Cyrix CS5530A video device 456 + * configuration space. 457 + */ 458 + static void __devinit pci_early_fixup_cyrix_5530(struct pci_dev *dev) 459 + { 460 + u8 r; 461 + /* clear 'F4 Video Configuration Trap' bit */ 462 + pci_read_config_byte(dev, 0x42, &r); 463 + r &= 0xfd; 464 + pci_write_config_byte(dev, 0x42, r); 465 + } 466 + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, 467 + pci_early_fixup_cyrix_5530);
+4 -7
drivers/video/geode/gx1fb_core.c
··· 215 215 if (ret < 0) 216 216 return ret; 217 217 218 - ret = pci_request_region(dev, 1, "gx1fb (video)"); 218 + ret = pci_request_region(dev, 0, "gx1fb (video)"); 219 219 if (ret < 0) 220 220 return ret; 221 - par->vid_regs = ioremap(pci_resource_start(dev, 1), 222 - pci_resource_len(dev, 1)); 221 + par->vid_regs = ioremap(pci_resource_start(dev, 0), 222 + pci_resource_len(dev, 0)); 223 223 if (!par->vid_regs) 224 224 return -ENOMEM; 225 225 ··· 229 229 if (!par->dc_regs) 230 230 return -ENOMEM; 231 231 232 - ret = pci_request_region(dev, 0, "gx1fb (frame buffer)"); 233 - if (ret < 0 ) 234 - return -EBUSY; 235 232 if ((fb_len = gx1_frame_buffer_size()) < 0) 236 233 return -ENOMEM; 237 - info->fix.smem_start = pci_resource_start(dev, 0); 234 + info->fix.smem_start = gx_base + 0x800000; 238 235 info->fix.smem_len = fb_len; 239 236 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len); 240 237 if (!info->screen_base)