Altix: Initial ACPI support - ROM shadowing.
Support a shadowed ROM when running with an ACPI capable PROM. Define a new dev.resource flag IORESOURCE_ROM_BIOS_COPY to describe the case of a BIOS shadowed ROM, which can then be used to avoid pci_map_rom() making an unneeded call to pci_enable_rom(). Signed-off-by: John Keller <jpk@sgi.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
9f581f162e
commit
a2302c68d9
@@ -169,6 +169,39 @@ sn_acpi_bus_fixup(struct pci_bus *bus)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sn_acpi_slot_fixup - Perform any SN specific slot fixup.
|
||||||
|
* At present there does not appear to be
|
||||||
|
* any generic way to handle a ROM image
|
||||||
|
* that has been shadowed by the PROM, so
|
||||||
|
* we pass a pointer to it within the
|
||||||
|
* pcidev_info structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
sn_acpi_slot_fixup(struct pci_dev *dev, struct pcidev_info *pcidev_info)
|
||||||
|
{
|
||||||
|
void __iomem *addr;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
if (pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE]) {
|
||||||
|
/*
|
||||||
|
* A valid ROM image exists and has been shadowed by the
|
||||||
|
* PROM. Setup the pci_dev ROM resource to point to
|
||||||
|
* the shadowed copy.
|
||||||
|
*/
|
||||||
|
size = dev->resource[PCI_ROM_RESOURCE].end -
|
||||||
|
dev->resource[PCI_ROM_RESOURCE].start;
|
||||||
|
addr =
|
||||||
|
ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE],
|
||||||
|
size);
|
||||||
|
dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr;
|
||||||
|
dev->resource[PCI_ROM_RESOURCE].end =
|
||||||
|
(unsigned long) addr + size;
|
||||||
|
dev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_BIOS_COPY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct acpi_driver acpi_sn_hubdev_driver = {
|
static struct acpi_driver acpi_sn_hubdev_driver = {
|
||||||
.name = "SGI HUBDEV Driver",
|
.name = "SGI HUBDEV Driver",
|
||||||
.ids = "SGIHUB,SGITIO",
|
.ids = "SGIHUB,SGITIO",
|
||||||
|
@@ -286,9 +286,10 @@ void sn_pci_fixup_slot(struct pci_dev *dev)
|
|||||||
list_add_tail(&pcidev_info->pdi_list,
|
list_add_tail(&pcidev_info->pdi_list,
|
||||||
&(SN_PLATFORM_DATA(dev->bus)->pcidev_info));
|
&(SN_PLATFORM_DATA(dev->bus)->pcidev_info));
|
||||||
|
|
||||||
if (!SN_ACPI_BASE_SUPPORT())
|
if (SN_ACPI_BASE_SUPPORT())
|
||||||
|
sn_acpi_slot_fixup(dev, pcidev_info);
|
||||||
|
else
|
||||||
sn_more_slot_fixup(dev, pcidev_info);
|
sn_more_slot_fixup(dev, pcidev_info);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Using the PROMs values for the PCI host bus, get the Linux
|
* Using the PROMs values for the PCI host bus, get the Linux
|
||||||
* PCI host_pci_dev struct and set up host bus linkages
|
* PCI host_pci_dev struct and set up host bus linkages
|
||||||
|
@@ -210,6 +210,9 @@ sn_more_slot_fixup(struct pci_dev *dev, struct pcidev_info *pcidev_info)
|
|||||||
dev->resource[idx].parent = &ioport_resource;
|
dev->resource[idx].parent = &ioport_resource;
|
||||||
else
|
else
|
||||||
dev->resource[idx].parent = &iomem_resource;
|
dev->resource[idx].parent = &iomem_resource;
|
||||||
|
/* If ROM, mark as shadowed in PROM */
|
||||||
|
if (idx == PCI_ROM_RESOURCE)
|
||||||
|
dev->resource[idx].flags |= IORESOURCE_ROM_BIOS_COPY;
|
||||||
}
|
}
|
||||||
/* Create a pci_window in the pci_controller struct for
|
/* Create a pci_window in the pci_controller struct for
|
||||||
* each device resource.
|
* each device resource.
|
||||||
|
@@ -81,7 +81,8 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
|
|||||||
start = (loff_t)0xC0000;
|
start = (loff_t)0xC0000;
|
||||||
*size = 0x20000; /* cover C000:0 through E000:0 */
|
*size = 0x20000; /* cover C000:0 through E000:0 */
|
||||||
} else {
|
} else {
|
||||||
if (res->flags & IORESOURCE_ROM_COPY) {
|
if (res->flags &
|
||||||
|
(IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) {
|
||||||
*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
|
*size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
|
||||||
return (void __iomem *)(unsigned long)
|
return (void __iomem *)(unsigned long)
|
||||||
pci_resource_start(pdev, PCI_ROM_RESOURCE);
|
pci_resource_start(pdev, PCI_ROM_RESOURCE);
|
||||||
@@ -165,7 +166,8 @@ void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size)
|
|||||||
if (!rom)
|
if (!rom)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW))
|
if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW |
|
||||||
|
IORESOURCE_ROM_BIOS_COPY))
|
||||||
return rom;
|
return rom;
|
||||||
|
|
||||||
res->start = (unsigned long)kmalloc(*size, GFP_KERNEL);
|
res->start = (unsigned long)kmalloc(*size, GFP_KERNEL);
|
||||||
@@ -191,7 +193,7 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
|
|||||||
{
|
{
|
||||||
struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
|
struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
|
||||||
|
|
||||||
if (res->flags & IORESOURCE_ROM_COPY)
|
if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
iounmap(rom);
|
iounmap(rom);
|
||||||
@@ -215,6 +217,7 @@ void pci_remove_rom(struct pci_dev *pdev)
|
|||||||
sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
|
sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
|
||||||
if (!(res->flags & (IORESOURCE_ROM_ENABLE |
|
if (!(res->flags & (IORESOURCE_ROM_ENABLE |
|
||||||
IORESOURCE_ROM_SHADOW |
|
IORESOURCE_ROM_SHADOW |
|
||||||
|
IORESOURCE_ROM_BIOS_COPY |
|
||||||
IORESOURCE_ROM_COPY)))
|
IORESOURCE_ROM_COPY)))
|
||||||
pci_disable_rom(pdev);
|
pci_disable_rom(pdev);
|
||||||
}
|
}
|
||||||
|
@@ -89,6 +89,7 @@ struct resource_list {
|
|||||||
#define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */
|
#define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */
|
||||||
#define IORESOURCE_ROM_SHADOW (1<<1) /* ROM is copy at C000:0 */
|
#define IORESOURCE_ROM_SHADOW (1<<1) /* ROM is copy at C000:0 */
|
||||||
#define IORESOURCE_ROM_COPY (1<<2) /* ROM is alloc'd copy, resource field overlaid */
|
#define IORESOURCE_ROM_COPY (1<<2) /* ROM is alloc'd copy, resource field overlaid */
|
||||||
|
#define IORESOURCE_ROM_BIOS_COPY (1<<3) /* ROM is BIOS copy, resource field overlaid */
|
||||||
|
|
||||||
/* PC/ISA/whatever - the normal PC address spaces: IO and memory */
|
/* PC/ISA/whatever - the normal PC address spaces: IO and memory */
|
||||||
extern struct resource ioport_resource;
|
extern struct resource ioport_resource;
|
||||||
|
Reference in New Issue
Block a user