diff options
Diffstat (limited to 'arch/ppc64/kernel/pSeries_iommu.c')
-rw-r--r-- | arch/ppc64/kernel/pSeries_iommu.c | 72 |
1 files changed, 41 insertions, 31 deletions
diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c index 9d5e1e7fc389..f0fd7fbd6531 100644 --- a/arch/ppc64/kernel/pSeries_iommu.c +++ b/arch/ppc64/kernel/pSeries_iommu.c @@ -295,7 +295,7 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb, struct iommu_table *tbl, unsigned int *dma_window) { - tbl->it_busno = dn->bussubno; + tbl->it_busno = PCI_DN(dn)->bussubno; /* TODO: Parse field size properties properly. */ tbl->it_size = (((unsigned long)dma_window[4] << 32) | @@ -311,6 +311,7 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb, static void iommu_bus_setup_pSeries(struct pci_bus *bus) { struct device_node *dn, *pdn; + struct pci_dn *pci; struct iommu_table *tbl; DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self); @@ -325,6 +326,7 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) */ dn = pci_bus_to_OF_node(bus); + pci = dn->data; if (!bus->self) { /* Root bus */ @@ -341,18 +343,18 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) * alltogether. This leaves 768MB for the window. */ DBG("PHB has io-hole, reserving 256MB\n"); - dn->phb->dma_window_size = 3 << 28; - dn->phb->dma_window_base_cur = 1 << 28; + pci->phb->dma_window_size = 3 << 28; + pci->phb->dma_window_base_cur = 1 << 28; } else { /* 1GB window by default */ - dn->phb->dma_window_size = 1 << 30; - dn->phb->dma_window_base_cur = 0; + pci->phb->dma_window_size = 1 << 30; + pci->phb->dma_window_base_cur = 0; } tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); - iommu_table_setparms(dn->phb, dn, tbl); - dn->iommu_table = iommu_init_table(tbl); + iommu_table_setparms(pci->phb, dn, tbl); + pci->iommu_table = iommu_init_table(tbl); } else { /* Do a 128MB table at root. This is used for the IDE * controller on some SMP-mode POWER4 machines. It @@ -363,16 +365,16 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) * Allocate at offset 128MB to avoid having to deal * with ISA holes; 128MB table for IDE is plenty. */ - dn->phb->dma_window_size = 1 << 27; - dn->phb->dma_window_base_cur = 1 << 27; + pci->phb->dma_window_size = 1 << 27; + pci->phb->dma_window_base_cur = 1 << 27; tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); - iommu_table_setparms(dn->phb, dn, tbl); - dn->iommu_table = iommu_init_table(tbl); + iommu_table_setparms(pci->phb, dn, tbl); + pci->iommu_table = iommu_init_table(tbl); /* All child buses have 256MB tables */ - dn->phb->dma_window_size = 1 << 28; + pci->phb->dma_window_size = 1 << 28; } } else { pdn = pci_bus_to_OF_node(bus->parent); @@ -386,12 +388,12 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); - iommu_table_setparms(dn->phb, dn, tbl); + iommu_table_setparms(pci->phb, dn, tbl); - dn->iommu_table = iommu_init_table(tbl); + pci->iommu_table = iommu_init_table(tbl); } else { /* Lower than first child or under python, use parent table */ - dn->iommu_table = pdn->iommu_table; + pci->iommu_table = PCI_DN(pdn)->iommu_table; } } } @@ -401,6 +403,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) { struct iommu_table *tbl; struct device_node *dn, *pdn; + struct pci_dn *ppci; unsigned int *dma_window = NULL; DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self); @@ -419,22 +422,24 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) return; } - if (!pdn->iommu_table) { + ppci = pdn->data; + if (!ppci->iommu_table) { /* Bussubno hasn't been copied yet. * Do it now because iommu_table_setparms_lpar needs it. */ - pdn->bussubno = bus->number; + + ppci->bussubno = bus->number; tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), GFP_KERNEL); - iommu_table_setparms_lpar(pdn->phb, pdn, tbl, dma_window); + iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); - pdn->iommu_table = iommu_init_table(tbl); + ppci->iommu_table = iommu_init_table(tbl); } if (pdn != dn) - dn->iommu_table = pdn->iommu_table; + PCI_DN(dn)->iommu_table = ppci->iommu_table; } @@ -449,11 +454,11 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev) */ mydn = dn = pci_device_to_OF_node(dev); - while (dn && dn->iommu_table == NULL) + while (dn && dn->data && PCI_DN(dn)->iommu_table == NULL) dn = dn->parent; - if (dn) { - mydn->iommu_table = dn->iommu_table; + if (dn && dn->data) { + PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table; } else { DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, dev->pretty_name); } @@ -463,10 +468,11 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti { int err = NOTIFY_OK; struct device_node *np = node; + struct pci_dn *pci = np->data; switch (action) { case PSERIES_RECONFIG_REMOVE: - if (np->iommu_table && + if (pci->iommu_table && get_property(np, "ibm,dma-window", NULL)) iommu_free_table(np); break; @@ -486,6 +492,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) struct device_node *pdn, *dn; struct iommu_table *tbl; int *dma_window = NULL; + struct pci_dn *pci; DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, dev->pretty_name); @@ -497,8 +504,10 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) */ dn = pci_device_to_OF_node(dev); - for (pdn = dn; pdn && !pdn->iommu_table; pdn = pdn->parent) { - dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL); + for (pdn = dn; pdn && pdn->data && !PCI_DN(pdn)->iommu_table; + pdn = pdn->parent) { + dma_window = (unsigned int *) + get_property(pdn, "ibm,dma-window", NULL); if (dma_window) break; } @@ -515,20 +524,21 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) DBG("Found DMA window, allocating table\n"); } - if (!pdn->iommu_table) { + pci = pdn->data; + if (!pci->iommu_table) { /* iommu_table_setparms_lpar needs bussubno. */ - pdn->bussubno = pdn->phb->bus->number; + pci->bussubno = pci->phb->bus->number; tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), GFP_KERNEL); - iommu_table_setparms_lpar(pdn->phb, pdn, tbl, dma_window); + iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); - pdn->iommu_table = iommu_init_table(tbl); + pci->iommu_table = iommu_init_table(tbl); } if (pdn != dn) - dn->iommu_table = pdn->iommu_table; + PCI_DN(dn)->iommu_table = pci->iommu_table; } static void iommu_bus_setup_null(struct pci_bus *b) { } |