aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/iseries
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2007-12-20 23:50:09 -0500
committerPaul Mackerras <paulus@samba.org>2008-01-16 22:57:05 -0500
commit885b86e4e7ccc360f8ce4d7fb10dfdfb6e3c8650 (patch)
tree306b7438cdce8479397ee1ae8c9f244a07f9d9f7 /arch/powerpc/platforms/iseries
parentb6ed42a794e1ca51fb46ff2bdc562315c46dd9a8 (diff)
[POWERPC] iSeries: eliminate pci_dn bussubno
xlate_iomm_address() really wants the ds_addr to pass to the HV, so store that value (instead of the BAR number) when we allocate the device bars. This is not a fast path, so we can look up the device_node property there instead of using the bussubno field of the pci_dn. The other user of iseries_ds_addr() was already scanning the device tree, so looking up a property will not slow it down any more. Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/iseries')
-rw-r--r--arch/powerpc/platforms/iseries/pci.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 931941036b91..cc562e4c2f32 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -29,6 +29,7 @@
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/pci.h> 31#include <linux/pci.h>
32#include <linux/of.h>
32 33
33#include <asm/types.h> 34#include <asm/types.h>
34#include <asm/io.h> 35#include <asm/io.h>
@@ -70,7 +71,7 @@ static long current_iomm_table_entry;
70 * Lookup Tables. 71 * Lookup Tables.
71 */ 72 */
72static struct device_node *iomm_table[IOMM_TABLE_MAX_ENTRIES]; 73static struct device_node *iomm_table[IOMM_TABLE_MAX_ENTRIES];
73static u8 iobar_table[IOMM_TABLE_MAX_ENTRIES]; 74static u64 ds_addr_table[IOMM_TABLE_MAX_ENTRIES];
74 75
75static DEFINE_SPINLOCK(iomm_table_lock); 76static DEFINE_SPINLOCK(iomm_table_lock);
76 77
@@ -80,8 +81,9 @@ static DEFINE_SPINLOCK(iomm_table_lock);
80static inline u64 iseries_ds_addr(struct device_node *node) 81static inline u64 iseries_ds_addr(struct device_node *node)
81{ 82{
82 struct pci_dn *pdn = PCI_DN(node); 83 struct pci_dn *pdn = PCI_DN(node);
84 const u32 *sbp = of_get_property(node, "linux,subbus", NULL);
83 85
84 return ((u64)pdn->busno << 48) + ((u64)pdn->bussubno << 40) 86 return ((u64)pdn->busno << 48) + ((u64)(sbp ? *sbp : 0) << 40)
85 + ((u64)0x10 << 32); 87 + ((u64)0x10 << 32);
86} 88}
87 89
@@ -333,7 +335,8 @@ static void __init iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
333 */ 335 */
334 while (bar_size > 0 ) { 336 while (bar_size > 0 ) {
335 iomm_table[current_iomm_table_entry] = dev->sysdata; 337 iomm_table[current_iomm_table_entry] = dev->sysdata;
336 iobar_table[current_iomm_table_entry] = bar_num; 338 ds_addr_table[current_iomm_table_entry] =
339 iseries_ds_addr(dev->sysdata) | (bar_num << 24);
337 bar_size -= IOMM_TABLE_ENTRY_SIZE; 340 bar_size -= IOMM_TABLE_ENTRY_SIZE;
338 ++current_iomm_table_entry; 341 ++current_iomm_table_entry;
339 } 342 }
@@ -598,8 +601,7 @@ static inline struct device_node *xlate_iomm_address(
598 dn = iomm_table[ind]; 601 dn = iomm_table[ind];
599 602
600 if (dn != NULL) { 603 if (dn != NULL) {
601 int barnum = iobar_table[ind]; 604 *dsaptr = ds_addr_table[ind];
602 *dsaptr = iseries_ds_addr(dn) | (barnum << 24);
603 *bar_offset = base_addr % IOMM_TABLE_ENTRY_SIZE; 605 *bar_offset = base_addr % IOMM_TABLE_ENTRY_SIZE;
604 } else 606 } else
605 panic("PCI: Invalid PCI IO address detected!\n"); 607 panic("PCI: Invalid PCI IO address detected!\n");