aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Keller <jpk@sgi.com>2006-10-04 17:49:52 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-12-01 17:36:58 -0500
commita2302c68d923537436b1114aa207787c1a31bd50 (patch)
treebf0407f2176a32ec79d2b7ab82e1fc9e54308fd2
parent9f581f162e2b304be25dee49bf3945d4ed65dfb6 (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.c33
-rw-r--r--arch/ia64/sn/kernel/io_common.c5
-rw-r--r--arch/ia64/sn/kernel/io_init.c3
-rw-r--r--drivers/pci/rom.c9
-rw-r--r--include/linux/ioport.h1
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
181void
182sn_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
172static struct acpi_driver acpi_sn_hubdev_driver = { 205static 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 */
94extern struct resource ioport_resource; 95extern struct resource ioport_resource;