Commit a2302c68d923537436b1114aa207787c1a31bd50
Committed by
Greg Kroah-Hartman
1 parent
9f581f162e
Exists in
master
and in
7 other branches
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>
Showing 5 changed files with 46 additions and 5 deletions Side-by-side Diff
arch/ia64/sn/kernel/io_acpi_init.c
... | ... | @@ -169,6 +169,39 @@ |
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 | 205 | static struct acpi_driver acpi_sn_hubdev_driver = { |
173 | 206 | .name = "SGI HUBDEV Driver", |
174 | 207 | .ids = "SGIHUB,SGITIO", |
arch/ia64/sn/kernel/io_common.c
... | ... | @@ -286,9 +286,10 @@ |
286 | 286 | list_add_tail(&pcidev_info->pdi_list, |
287 | 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 | 292 | sn_more_slot_fixup(dev, pcidev_info); |
291 | - | |
292 | 293 | /* |
293 | 294 | * Using the PROMs values for the PCI host bus, get the Linux |
294 | 295 | * PCI host_pci_dev struct and set up host bus linkages |
arch/ia64/sn/kernel/io_init.c
... | ... | @@ -210,6 +210,9 @@ |
210 | 210 | dev->resource[idx].parent = &ioport_resource; |
211 | 211 | else |
212 | 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 | 217 | /* Create a pci_window in the pci_controller struct for |
215 | 218 | * each device resource. |
drivers/pci/rom.c
... | ... | @@ -81,7 +81,8 @@ |
81 | 81 | start = (loff_t)0xC0000; |
82 | 82 | *size = 0x20000; /* cover C000:0 through E000:0 */ |
83 | 83 | } else { |
84 | - if (res->flags & IORESOURCE_ROM_COPY) { | |
84 | + if (res->flags & | |
85 | + (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) { | |
85 | 86 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); |
86 | 87 | return (void __iomem *)(unsigned long) |
87 | 88 | pci_resource_start(pdev, PCI_ROM_RESOURCE); |
... | ... | @@ -165,7 +166,8 @@ |
165 | 166 | if (!rom) |
166 | 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 | 171 | return rom; |
170 | 172 | |
171 | 173 | res->start = (unsigned long)kmalloc(*size, GFP_KERNEL); |
... | ... | @@ -191,7 +193,7 @@ |
191 | 193 | { |
192 | 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 | 197 | return; |
196 | 198 | |
197 | 199 | iounmap(rom); |
... | ... | @@ -215,6 +217,7 @@ |
215 | 217 | sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); |
216 | 218 | if (!(res->flags & (IORESOURCE_ROM_ENABLE | |
217 | 219 | IORESOURCE_ROM_SHADOW | |
220 | + IORESOURCE_ROM_BIOS_COPY | | |
218 | 221 | IORESOURCE_ROM_COPY))) |
219 | 222 | pci_disable_rom(pdev); |
220 | 223 | } |
include/linux/ioport.h
... | ... | @@ -89,6 +89,7 @@ |
89 | 89 | #define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */ |
90 | 90 | #define IORESOURCE_ROM_SHADOW (1<<1) /* ROM is copy at C000:0 */ |
91 | 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 | 94 | /* PC/ISA/whatever - the normal PC address spaces: IO and memory */ |
94 | 95 | extern struct resource ioport_resource; |