Commit 0aaf539b authored by Jesse Barnes's avatar Jesse Barnes Committed by Linus Torvalds

[PATCH] fix ROM enable/disable in r128 and radeon fb drivers

Both the r128 and radeon fb drivers do bad things with the PCI BAR
corresponding to their option ROM.  They incorrectly use the host address
instead of the BAR address to enable the ROM, and then incorrectly lose the
original value on unmap.  This patch fixes both problems.  Tested on Altix.
Signed-off-by: default avatarJesse Barnes <jbarnes@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 8b3ee85f
...@@ -452,7 +452,6 @@ static int aty128_decode_var(struct fb_var_screeninfo *var, ...@@ -452,7 +452,6 @@ static int aty128_decode_var(struct fb_var_screeninfo *var,
static void __init aty128_get_pllinfo(struct aty128fb_par *par, static void __init aty128_get_pllinfo(struct aty128fb_par *par,
void __iomem *bios); void __iomem *bios);
static void __init __iomem *aty128_map_ROM(struct pci_dev *pdev, const struct aty128fb_par *par); static void __init __iomem *aty128_map_ROM(struct pci_dev *pdev, const struct aty128fb_par *par);
static void __init aty128_unmap_ROM(struct pci_dev *dev, void __iomem * rom);
#endif #endif
static void aty128_timings(struct aty128fb_par *par); static void aty128_timings(struct aty128fb_par *par);
static void aty128_init_engine(struct aty128fb_par *par); static void aty128_init_engine(struct aty128fb_par *par);
...@@ -788,30 +787,12 @@ static u32 depth_to_dst(u32 depth) ...@@ -788,30 +787,12 @@ static u32 depth_to_dst(u32 depth)
#ifndef __sparc__ #ifndef __sparc__
static void __init aty128_unmap_ROM(struct pci_dev *dev, void __iomem * rom)
{
struct resource *r = &dev->resource[PCI_ROM_RESOURCE];
iounmap(rom);
/* Release the ROM resource if we used it in the first place */
if (r->parent && r->flags & PCI_ROM_ADDRESS_ENABLE) {
release_resource(r);
r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
r->end -= r->start;
r->start = 0;
}
/* This will disable and set address to unassigned */
pci_write_config_dword(dev, dev->rom_base_reg, 0);
}
static void __iomem * __init aty128_map_ROM(const struct aty128fb_par *par, struct pci_dev *dev) static void __iomem * __init aty128_map_ROM(const struct aty128fb_par *par, struct pci_dev *dev)
{ {
struct resource *r;
u16 dptr; u16 dptr;
u8 rom_type; u8 rom_type;
void __iomem *bios; void __iomem *bios;
size_t rom_size;
/* Fix from ATI for problem with Rage128 hardware not leaving ROM enabled */ /* Fix from ATI for problem with Rage128 hardware not leaving ROM enabled */
unsigned int temp; unsigned int temp;
...@@ -821,21 +802,8 @@ static void __iomem * __init aty128_map_ROM(const struct aty128fb_par *par, stru ...@@ -821,21 +802,8 @@ static void __iomem * __init aty128_map_ROM(const struct aty128fb_par *par, stru
aty_st_le32(RAGE128_MPP_TB_CONFIG, temp); aty_st_le32(RAGE128_MPP_TB_CONFIG, temp);
temp = aty_ld_le32(RAGE128_MPP_TB_CONFIG); temp = aty_ld_le32(RAGE128_MPP_TB_CONFIG);
/* no need to search for the ROM, just ask the card where it is. */ bios = pci_map_rom(dev, &rom_size);
r = &dev->resource[PCI_ROM_RESOURCE];
/* assign the ROM an address if it doesn't have one */
if (r->parent == NULL)
pci_assign_resource(dev, PCI_ROM_RESOURCE);
/* enable if needed */
if (!(r->flags & PCI_ROM_ADDRESS_ENABLE)) {
pci_write_config_dword(dev, dev->rom_base_reg,
r->start | PCI_ROM_ADDRESS_ENABLE);
r->flags |= PCI_ROM_ADDRESS_ENABLE;
}
bios = ioremap(r->start, r->end - r->start + 1);
if (!bios) { if (!bios) {
printk(KERN_ERR "aty128fb: ROM failed to map\n"); printk(KERN_ERR "aty128fb: ROM failed to map\n");
return NULL; return NULL;
...@@ -899,7 +867,7 @@ static void __iomem * __init aty128_map_ROM(const struct aty128fb_par *par, stru ...@@ -899,7 +867,7 @@ static void __iomem * __init aty128_map_ROM(const struct aty128fb_par *par, stru
return bios; return bios;
failed: failed:
aty128_unmap_ROM(dev, bios); pci_unmap_rom(dev, bios);
return NULL; return NULL;
} }
...@@ -1959,7 +1927,7 @@ static int __init aty128_probe(struct pci_dev *pdev, const struct pci_device_id ...@@ -1959,7 +1927,7 @@ static int __init aty128_probe(struct pci_dev *pdev, const struct pci_device_id
else { else {
printk(KERN_INFO "aty128fb: Rage128 BIOS located\n"); printk(KERN_INFO "aty128fb: Rage128 BIOS located\n");
aty128_get_pllinfo(par, bios); aty128_get_pllinfo(par, bios);
aty128_unmap_ROM(pdev, bios); pci_unmap_rom(pdev, bios);
} }
#endif /* __sparc__ */ #endif /* __sparc__ */
......
...@@ -263,30 +263,17 @@ static struct backlight_controller radeon_backlight_controller = { ...@@ -263,30 +263,17 @@ static struct backlight_controller radeon_backlight_controller = {
static void __devexit radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev) static void __devexit radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev)
{ {
// leave it disabled and unassigned
struct resource *r = &dev->resource[PCI_ROM_RESOURCE];
if (!rinfo->bios_seg) if (!rinfo->bios_seg)
return; return;
iounmap(rinfo->bios_seg); pci_unmap_rom(dev, rinfo->bios_seg);
/* Release the ROM resource if we used it in the first place */
if (r->parent && r->flags & PCI_ROM_ADDRESS_ENABLE) {
release_resource(r);
r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
r->end -= r->start;
r->start = 0;
}
/* This will disable and set address to unassigned */
pci_write_config_dword(dev, dev->rom_base_reg, 0);
} }
static int __devinit radeon_map_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev) static int __devinit radeon_map_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev)
{ {
void __iomem *rom; void __iomem *rom;
struct resource *r;
u16 dptr; u16 dptr;
u8 rom_type; u8 rom_type;
size_t rom_size;
/* If this is a primary card, there is a shadow copy of the /* If this is a primary card, there is a shadow copy of the
* ROM somewhere in the first meg. We will just ignore the copy * ROM somewhere in the first meg. We will just ignore the copy
...@@ -301,21 +288,7 @@ static int __devinit radeon_map_ROM(struct radeonfb_info *rinfo, struct pci_dev ...@@ -301,21 +288,7 @@ static int __devinit radeon_map_ROM(struct radeonfb_info *rinfo, struct pci_dev
OUTREG(MPP_TB_CONFIG, temp); OUTREG(MPP_TB_CONFIG, temp);
temp = INREG(MPP_TB_CONFIG); temp = INREG(MPP_TB_CONFIG);
/* no need to search for the ROM, just ask the card where it is. */ rom = pci_map_rom(dev, &rom_size);
r = &dev->resource[PCI_ROM_RESOURCE];
/* assign the ROM an address if it doesn't have one */
if (r->parent == NULL)
pci_assign_resource(dev, PCI_ROM_RESOURCE);
/* enable if needed */
if (!(r->flags & PCI_ROM_ADDRESS_ENABLE)) {
pci_write_config_dword(dev, dev->rom_base_reg,
r->start | PCI_ROM_ADDRESS_ENABLE);
r->flags |= PCI_ROM_ADDRESS_ENABLE;
}
rom = ioremap(r->start, r->end - r->start + 1);
if (!rom) { if (!rom) {
printk(KERN_ERR "radeonfb: ROM failed to map\n"); printk(KERN_ERR "radeonfb: ROM failed to map\n");
return -ENOMEM; return -ENOMEM;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment