aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms')
-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");