Commit a2302c68 authored by John Keller's avatar John Keller Committed by Greg Kroah-Hartman

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: default avatarJohn Keller <jpk@sgi.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 9f581f16
...@@ -169,6 +169,39 @@ sn_acpi_bus_fixup(struct pci_bus *bus) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 { ...@@ -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;
......
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