aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/sn/kernel/io_init.c
diff options
context:
space:
mode:
authorJohn Keller <jpk@sgi.com>2007-01-30 01:17:37 -0500
committerLen Brown <len.brown@intel.com>2007-02-02 22:14:35 -0500
commit6f09a9250a5d76c0765cd51a33e0a042e9761cfc (patch)
tree764db1dcd196fc1c272a8c6930924a5bc60623bc /arch/ia64/sn/kernel/io_init.c
parent647fb47dfabeffd2f1706013ebf5cfc92b70d273 (diff)
Altix: ACPI SSDT PCI device support
Add SN platform support for running with an ACPI capable PROM that defines PCI devices in SSDT tables. There is a SSDT table for every occupied slot on a root bus, containing info for every PPB and/or device on the bus. The SSDTs will be dynamically loaded/unloaded at hotplug enable/disable. Platform specific information that is currently passed via a SAL call, will now be passed via the Vendor resource in the ACPI Device object(s) defined in each SSDT. Signed-off-by: John Keller <jpk@sgi.com> Cc: Greg KH <greg@kroah.com> Cc: "Luck, Tony" <tony.luck@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'arch/ia64/sn/kernel/io_init.c')
-rw-r--r--arch/ia64/sn/kernel/io_init.c54
1 files changed, 48 insertions, 6 deletions
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 9ad843e0383b..600be3ebae05 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -56,6 +56,25 @@ static inline u64 sal_get_pcibus_info(u64 segment, u64 busnum, u64 address)
56 return ret_stuff.v0; 56 return ret_stuff.v0;
57} 57}
58 58
59/*
60 * Retrieve the pci device information given the bus and device|function number.
61 */
62static inline u64
63sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev,
64 u64 sn_irq_info)
65{
66 struct ia64_sal_retval ret_stuff;
67 ret_stuff.status = 0;
68 ret_stuff.v0 = 0;
69
70 SAL_CALL_NOLOCK(ret_stuff,
71 (u64) SN_SAL_IOIF_GET_PCIDEV_INFO,
72 (u64) segment, (u64) bus_number, (u64) devfn,
73 (u64) pci_dev,
74 sn_irq_info, 0, 0);
75 return ret_stuff.v0;
76}
77
59 78
60/* 79/*
61 * sn_fixup_ionodes() - This routine initializes the HUB data structure for 80 * sn_fixup_ionodes() - This routine initializes the HUB data structure for
@@ -172,18 +191,40 @@ sn_pci_window_fixup(struct pci_dev *dev, unsigned int count,
172} 191}
173 192
174/* 193/*
175 * sn_more_slot_fixup() - We are not running with an ACPI capable PROM, 194 * sn_io_slot_fixup() - We are not running with an ACPI capable PROM,
176 * and need to convert the pci_dev->resource 195 * and need to convert the pci_dev->resource
177 * 'start' and 'end' addresses to mapped addresses, 196 * 'start' and 'end' addresses to mapped addresses,
178 * and setup the pci_controller->window array entries. 197 * and setup the pci_controller->window array entries.
179 */ 198 */
180void 199void
181sn_more_slot_fixup(struct pci_dev *dev, struct pcidev_info *pcidev_info) 200sn_io_slot_fixup(struct pci_dev *dev)
182{ 201{
183 unsigned int count = 0; 202 unsigned int count = 0;
184 int idx; 203 int idx;
185 s64 pci_addrs[PCI_ROM_RESOURCE + 1]; 204 s64 pci_addrs[PCI_ROM_RESOURCE + 1];
186 unsigned long addr, end, size, start; 205 unsigned long addr, end, size, start;
206 struct pcidev_info *pcidev_info;
207 struct sn_irq_info *sn_irq_info;
208 int status;
209
210 pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL);
211 if (!pcidev_info)
212 panic("%s: Unable to alloc memory for pcidev_info", __FUNCTION__);
213
214 sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
215 if (!sn_irq_info)
216 panic("%s: Unable to alloc memory for sn_irq_info", __FUNCTION__);
217
218 /* Call to retrieve pci device information needed by kernel. */
219 status = sal_get_pcidev_info((u64) pci_domain_nr(dev),
220 (u64) dev->bus->number,
221 dev->devfn,
222 (u64) __pa(pcidev_info),
223 (u64) __pa(sn_irq_info));
224
225 if (status)
226 BUG(); /* Cannot get platform pci device information */
227
187 228
188 /* Copy over PIO Mapped Addresses */ 229 /* Copy over PIO Mapped Addresses */
189 for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { 230 for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) {
@@ -219,8 +260,12 @@ sn_more_slot_fixup(struct pci_dev *dev, struct pcidev_info *pcidev_info)
219 */ 260 */
220 if (count > 0) 261 if (count > 0)
221 sn_pci_window_fixup(dev, count, pci_addrs); 262 sn_pci_window_fixup(dev, count, pci_addrs);
263
264 sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info);
222} 265}
223 266
267EXPORT_SYMBOL(sn_io_slot_fixup);
268
224/* 269/*
225 * sn_pci_controller_fixup() - This routine sets up a bus's resources 270 * sn_pci_controller_fixup() - This routine sets up a bus's resources
226 * consistent with the Linux PCI abstraction layer. 271 * consistent with the Linux PCI abstraction layer.
@@ -272,9 +317,6 @@ sn_bus_fixup(struct pci_bus *bus)
272{ 317{
273 struct pci_dev *pci_dev = NULL; 318 struct pci_dev *pci_dev = NULL;
274 struct pcibus_bussoft *prom_bussoft_ptr; 319 struct pcibus_bussoft *prom_bussoft_ptr;
275 extern void sn_common_bus_fixup(struct pci_bus *,
276 struct pcibus_bussoft *);
277
278 320
279 if (!bus->parent) { /* If root bus */ 321 if (!bus->parent) { /* If root bus */
280 prom_bussoft_ptr = PCI_CONTROLLER(bus)->platform_data; 322 prom_bussoft_ptr = PCI_CONTROLLER(bus)->platform_data;
@@ -291,7 +333,7 @@ sn_bus_fixup(struct pci_bus *bus)
291 prom_bussoft_ptr->bs_legacy_mem); 333 prom_bussoft_ptr->bs_legacy_mem);
292 } 334 }
293 list_for_each_entry(pci_dev, &bus->devices, bus_list) { 335 list_for_each_entry(pci_dev, &bus->devices, bus_list) {
294 sn_pci_fixup_slot(pci_dev); 336 sn_io_slot_fixup(pci_dev);
295 } 337 }
296 338
297} 339}