diff options
author | John Keller <jpk@sgi.com> | 2007-01-30 01:17:37 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-02-02 22:14:35 -0500 |
commit | 6f09a9250a5d76c0765cd51a33e0a042e9761cfc (patch) | |
tree | 764db1dcd196fc1c272a8c6930924a5bc60623bc /arch/ia64/sn/kernel/io_init.c | |
parent | 647fb47dfabeffd2f1706013ebf5cfc92b70d273 (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.c | 54 |
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 | */ | ||
62 | static inline u64 | ||
63 | sal_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 | */ |
180 | void | 199 | void |
181 | sn_more_slot_fixup(struct pci_dev *dev, struct pcidev_info *pcidev_info) | 200 | sn_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 | ||
267 | EXPORT_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 | } |