diff options
author | John Keller <jpk@sgi.com> | 2006-10-04 17:49:52 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-12-01 17:36:58 -0500 |
commit | a2302c68d923537436b1114aa207787c1a31bd50 (patch) | |
tree | bf0407f2176a32ec79d2b7ab82e1fc9e54308fd2 | |
parent | 9f581f162e2b304be25dee49bf3945d4ed65dfb6 (diff) |
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>
-rw-r--r-- | arch/ia64/sn/kernel/io_acpi_init.c | 33 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/io_common.c | 5 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/io_init.c | 3 | ||||
-rw-r--r-- | drivers/pci/rom.c | 9 | ||||
-rw-r--r-- | include/linux/ioport.h | 1 |
5 files changed, 46 insertions, 5 deletions
diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c index a9dc36901b19..99d7f278612a 100644 --- a/arch/ia64/sn/kernel/io_acpi_init.c +++ b/arch/ia64/sn/kernel/io_acpi_init.c | |||
@@ -169,6 +169,39 @@ sn_acpi_bus_fixup(struct pci_bus *bus) | |||
169 | } | 169 | } |
170 | } | 170 | } |
171 | 171 | ||
172 | /* | ||
173 | * sn_acpi_slot_fixup - Perform any SN specific slot fixup. | ||
174 | * At present there does not appear to be | ||
175 | * any generic way to handle a ROM image | ||
176 | * that has been shadowed by the PROM, so | ||
177 | * we pass a pointer to it within the | ||
178 | * pcidev_info structure. | ||
179 | */ | ||
180 | |||
181 | void | ||
182 | sn_acpi_slot_fixup(struct pci_dev *dev, struct pcidev_info *pcidev_info) | ||
183 | { | ||
184 | void __iomem *addr; | ||
185 | size_t size; | ||
186 | |||
187 | if (pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE]) { | ||
188 | /* | ||
189 | * A valid ROM image exists and has been shadowed by the | ||
190 | * PROM. Setup the pci_dev ROM resource to point to | ||
191 | * the shadowed copy. | ||
192 | */ | ||
193 | size = dev->resource[PCI_ROM_RESOURCE].end - | ||
194 | dev->resource[PCI_ROM_RESOURCE].start; | ||
195 | addr = | ||
196 | ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE], | ||
197 | size); | ||
198 | dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr; | ||
199 | dev->resource[PCI_ROM_RESOURCE].end = | ||
200 | (unsigned long) addr + size; | ||
201 | dev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_BIOS_COPY; | ||
202 | } | ||
203 | } | ||
204 | |||
172 | static struct acpi_driver acpi_sn_hubdev_driver = { | 205 | static struct acpi_driver acpi_sn_hubdev_driver = { |
173 | .name = "SGI HUBDEV Driver", | 206 | .name = "SGI HUBDEV Driver", |
174 | .ids = "SGIHUB,SGITIO", | 207 | .ids = "SGIHUB,SGITIO", |
diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c index 12531de6754c..d4dd8f4b6b8d 100644 --- a/arch/ia64/sn/kernel/io_common.c +++ b/arch/ia64/sn/kernel/io_common.c | |||
@@ -286,9 +286,10 @@ void sn_pci_fixup_slot(struct pci_dev *dev) | |||
286 | list_add_tail(&pcidev_info->pdi_list, | 286 | list_add_tail(&pcidev_info->pdi_list, |
287 | &(SN_PLATFORM_DATA(dev->bus)->pcidev_info)); | 287 | &(SN_PLATFORM_DATA(dev->bus)->pcidev_info)); |
288 | 288 | ||
289 | if (!SN_ACPI_BASE_SUPPORT()) | 289 | if (SN_ACPI_BASE_SUPPORT()) |
290 | sn_acpi_slot_fixup(dev, pcidev_info); | ||
291 | else | ||
290 | sn_more_slot_fixup(dev, pcidev_info); | 292 | sn_more_slot_fixup(dev, pcidev_info); |
291 | |||
292 | /* | 293 | /* |
293 | * Using the PROMs values for the PCI host bus, get the Linux | 294 | * Using the PROMs values for the PCI host bus, get the Linux |
294 | * PCI host_pci_dev struct and set up host bus linkages | 295 | * PCI host_pci_dev struct and set up host bus linkages |
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 990224a44121..9ad843e0383b 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
@@ -210,6 +210,9 @@ sn_more_slot_fixup(struct pci_dev *dev, struct pcidev_info *pcidev_info) | |||
210 | dev->resource[idx].parent = &ioport_resource; | 210 | dev->resource[idx].parent = &ioport_resource; |
211 | else | 211 | else |
212 | dev->resource[idx].parent = &iomem_resource; | 212 | dev->resource[idx].parent = &iomem_resource; |
213 | /* If ROM, mark as shadowed in PROM */ | ||
214 | if (idx == PCI_ROM_RESOURCE) | ||
215 | dev->resource[idx].flags |= IORESOURCE_ROM_BIOS_COPY; | ||
213 | } | 216 | } |
214 | /* Create a pci_window in the pci_controller struct for | 217 | /* Create a pci_window in the pci_controller struct for |
215 | * each device resource. | 218 | * each device resource. |
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index e1dcefc69bb4..d087e0817715 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
@@ -81,7 +81,8 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) | |||
81 | start = (loff_t)0xC0000; | 81 | start = (loff_t)0xC0000; |
82 | *size = 0x20000; /* cover C000:0 through E000:0 */ | 82 | *size = 0x20000; /* cover C000:0 through E000:0 */ |
83 | } else { | 83 | } else { |
84 | if (res->flags & IORESOURCE_ROM_COPY) { | 84 | if (res->flags & |
85 | (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) { | ||
85 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); | 86 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); |
86 | return (void __iomem *)(unsigned long) | 87 | return (void __iomem *)(unsigned long) |
87 | pci_resource_start(pdev, PCI_ROM_RESOURCE); | 88 | 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 | if (!rom) | 166 | if (!rom) |
166 | return NULL; | 167 | return NULL; |
167 | 168 | ||
168 | if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW)) | 169 | if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW | |
170 | IORESOURCE_ROM_BIOS_COPY)) | ||
169 | return rom; | 171 | return rom; |
170 | 172 | ||
171 | res->start = (unsigned long)kmalloc(*size, GFP_KERNEL); | 173 | res->start = (unsigned long)kmalloc(*size, GFP_KERNEL); |
@@ -191,7 +193,7 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) | |||
191 | { | 193 | { |
192 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; | 194 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; |
193 | 195 | ||
194 | if (res->flags & IORESOURCE_ROM_COPY) | 196 | if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) |
195 | return; | 197 | return; |
196 | 198 | ||
197 | iounmap(rom); | 199 | iounmap(rom); |
@@ -215,6 +217,7 @@ void pci_remove_rom(struct pci_dev *pdev) | |||
215 | sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); | 217 | sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); |
216 | if (!(res->flags & (IORESOURCE_ROM_ENABLE | | 218 | if (!(res->flags & (IORESOURCE_ROM_ENABLE | |
217 | IORESOURCE_ROM_SHADOW | | 219 | IORESOURCE_ROM_SHADOW | |
220 | IORESOURCE_ROM_BIOS_COPY | | ||
218 | IORESOURCE_ROM_COPY))) | 221 | IORESOURCE_ROM_COPY))) |
219 | pci_disable_rom(pdev); | 222 | pci_disable_rom(pdev); |
220 | } | 223 | } |
diff --git a/include/linux/ioport.h b/include/linux/ioport.h index d42c83399071..cf8696d4a138 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h | |||
@@ -89,6 +89,7 @@ struct resource_list { | |||
89 | #define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */ | 89 | #define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */ |
90 | #define IORESOURCE_ROM_SHADOW (1<<1) /* ROM is copy at C000:0 */ | 90 | #define IORESOURCE_ROM_SHADOW (1<<1) /* ROM is copy at C000:0 */ |
91 | #define IORESOURCE_ROM_COPY (1<<2) /* ROM is alloc'd copy, resource field overlaid */ | 91 | #define IORESOURCE_ROM_COPY (1<<2) /* ROM is alloc'd copy, resource field overlaid */ |
92 | #define IORESOURCE_ROM_BIOS_COPY (1<<3) /* ROM is BIOS copy, resource field overlaid */ | ||
92 | 93 | ||
93 | /* PC/ISA/whatever - the normal PC address spaces: IO and memory */ | 94 | /* PC/ISA/whatever - the normal PC address spaces: IO and memory */ |
94 | extern struct resource ioport_resource; | 95 | extern struct resource ioport_resource; |