diff options
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r-- | arch/powerpc/platforms/cell/iommu.c | 21 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/iommu.c | 12 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/pci.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/setup.c | 16 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/iommu.c | 90 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/pci_dlpar.c | 4 |
6 files changed, 63 insertions, 82 deletions
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index aca4c3db0dd..0e6ab8a55ef 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -255,9 +255,6 @@ static void enable_mapping(void __iomem *base, void __iomem *mmio_base) set_iost_origin(mmio_base); } -static void iommu_dev_setup_null(struct pci_dev *d) { } -static void iommu_bus_setup_null(struct pci_bus *b) { } - struct cell_iommu { unsigned long base; unsigned long mmio_base; @@ -306,12 +303,15 @@ static void cell_do_map_iommu(struct cell_iommu *iommu, } } -static void iommu_devnode_setup(struct device_node *d) +static void pci_dma_cell_bus_setup(struct pci_bus *b) { const unsigned int *ioid; unsigned long map_start, map_size, token; const unsigned long *dma_window; struct cell_iommu *iommu; + struct device_node *d; + + d = pci_bus_to_OF_node(b); ioid = get_property(d, "ioid", NULL); if (!ioid) @@ -330,12 +330,6 @@ static void iommu_devnode_setup(struct device_node *d) cell_do_map_iommu(iommu, *ioid, map_start, map_size); } -static void iommu_bus_setup(struct pci_bus *b) -{ - struct device_node *d = (struct device_node *)b->sysdata; - iommu_devnode_setup(d); -} - static int cell_map_iommu_hardcoded(int num_nodes) { @@ -499,16 +493,13 @@ void cell_init_iommu(void) if (setup_bus) { pr_debug("%s: IOMMU mapping activated\n", __FUNCTION__); - ppc_md.iommu_dev_setup = iommu_dev_setup_null; - ppc_md.iommu_bus_setup = iommu_bus_setup; + ppc_md.pci_dma_bus_setup = pci_dma_cell_bus_setup; } else { pr_debug("%s: IOMMU mapping activated, " "no device action necessary\n", __FUNCTION__); /* Direct I/O, IOMMU off */ - ppc_md.iommu_dev_setup = iommu_dev_setup_null; - ppc_md.iommu_bus_setup = iommu_bus_setup_null; } } - pci_dma_ops = cell_iommu_ops; + pci_dma_ops = &cell_iommu_ops; } diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index 218817d13c5..ee0a4e42e4f 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -27,6 +27,7 @@ #include <linux/types.h> #include <linux/dma-mapping.h> #include <linux/list.h> +#include <linux/pci.h> #include <asm/iommu.h> #include <asm/tce.h> @@ -168,7 +169,7 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl) } -void iommu_devnode_init_iSeries(struct device_node *dn) +void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn) { struct iommu_table *tbl; struct pci_dn *pdn = PCI_DN(dn); @@ -186,19 +187,14 @@ void iommu_devnode_init_iSeries(struct device_node *dn) pdn->iommu_table = iommu_init_table(tbl, -1); else kfree(tbl); + pdev->dev.archdata.dma_data = pdn->iommu_table; } #endif -static void iommu_dev_setup_iSeries(struct pci_dev *dev) { } -static void iommu_bus_setup_iSeries(struct pci_bus *bus) { } - void iommu_init_early_iSeries(void) { ppc_md.tce_build = tce_build_iSeries; ppc_md.tce_free = tce_free_iSeries; - ppc_md.iommu_dev_setup = iommu_dev_setup_iSeries; - ppc_md.iommu_bus_setup = iommu_bus_setup_iSeries; - - pci_iommu_init(); + pci_dma_ops = &dma_iommu_ops; } diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index 4aa165e010d..a90ae42a7bc 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c @@ -253,7 +253,7 @@ void __init iSeries_pci_final_fixup(void) PCI_DN(node)->pcidev = pdev; allocate_device_bars(pdev); iSeries_Device_Information(pdev, DeviceCount); - iommu_devnode_init_iSeries(node); + iommu_devnode_init_iSeries(pdev, node); } else printk("PCI: Device Tree not found for 0x%016lX\n", (unsigned long)pdev); diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index eb2457567f8..89d6e295dbf 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c @@ -26,6 +26,7 @@ #include <linux/kernel.h> #include <linux/delay.h> #include <linux/console.h> +#include <linux/pci.h> #include <asm/prom.h> #include <asm/system.h> @@ -71,6 +72,9 @@ void __init pas_setup_arch(void) /* Setup SMP callback */ smp_ops = &pas_smp_ops; #endif + /* no iommu yet */ + pci_dma_ops = &dma_direct_ops; + /* Lookup PCI hosts */ pas_pci_init(); @@ -81,17 +85,6 @@ void __init pas_setup_arch(void) printk(KERN_DEBUG "Using default idle loop\n"); } -static void iommu_dev_setup_null(struct pci_dev *dev) { } -static void iommu_bus_setup_null(struct pci_bus *bus) { } - -static void __init pas_init_early(void) -{ - /* No iommu code yet */ - ppc_md.iommu_dev_setup = iommu_dev_setup_null; - ppc_md.iommu_bus_setup = iommu_bus_setup_null; - pci_direct_iommu_init(); -} - /* No legacy IO on our parts */ static int pas_check_legacy_ioport(unsigned int baseport) { @@ -173,7 +166,6 @@ define_machine(pas) { .name = "PA Semi PA6T-1682M", .probe = pas_probe, .setup_arch = pas_setup_arch, - .init_early = pas_init_early, .init_IRQ = pas_init_IRQ, .get_irq = mpic_get_irq, .restart = pas_restart, diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 556c279a789..3c95392f4f4 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -309,7 +309,7 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb, tbl->it_size = size >> IOMMU_PAGE_SHIFT; } -static void iommu_bus_setup_pSeries(struct pci_bus *bus) +static void pci_dma_bus_setup_pSeries(struct pci_bus *bus) { struct device_node *dn; struct iommu_table *tbl; @@ -318,10 +318,9 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) struct pci_dn *pci; int children; - DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self); - dn = pci_bus_to_OF_node(bus); - pci = PCI_DN(dn); + + DBG("pci_dma_bus_setup_pSeries: setting up bus %s\n", dn->full_name); if (bus->self) { /* This is not a root bus, any setup will be done for the @@ -329,6 +328,7 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) */ return; } + pci = PCI_DN(dn); /* Check if the ISA bus on the system is under * this PHB. @@ -390,17 +390,17 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) } -static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) +static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus) { struct iommu_table *tbl; struct device_node *dn, *pdn; struct pci_dn *ppci; const void *dma_window = NULL; - DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self); - dn = pci_bus_to_OF_node(bus); + DBG("pci_dma_bus_setup_pSeriesLP: setting up bus %s\n", dn->full_name); + /* Find nearest ibm,dma-window, walking up the device tree */ for (pdn = dn; pdn != NULL; pdn = pdn->parent) { dma_window = get_property(pdn, "ibm,dma-window", NULL); @@ -409,11 +409,15 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) } if (dma_window == NULL) { - DBG("iommu_bus_setup_pSeriesLP: bus %s seems to have no ibm,dma-window property\n", dn->full_name); + DBG(" no ibm,dma-window property !\n"); return; } ppci = PCI_DN(pdn); + + DBG(" parent is %s, iommu_table: 0x%p\n", + pdn->full_name, ppci->iommu_table); + if (!ppci->iommu_table) { /* Bussubno hasn't been copied yet. * Do it now because iommu_table_setparms_lpar needs it. @@ -427,6 +431,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node); + DBG(" created table: %p\n", ppci->iommu_table); } if (pdn != dn) @@ -434,27 +439,27 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) } -static void iommu_dev_setup_pSeries(struct pci_dev *dev) +static void pci_dma_dev_setup_pSeries(struct pci_dev *dev) { - struct device_node *dn, *mydn; + struct device_node *dn; struct iommu_table *tbl; - DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, pci_name(dev)); + DBG("pci_dma_dev_setup_pSeries: %s\n", pci_name(dev)); - mydn = dn = pci_device_to_OF_node(dev); + dn = dev->dev.archdata.of_node; /* If we're the direct child of a root bus, then we need to allocate * an iommu table ourselves. The bus setup code should have setup * the window sizes already. */ if (!dev->bus->self) { + struct pci_controller *phb = PCI_DN(dn)->phb; + DBG(" --> first child, no bridge. Allocating iommu table.\n"); tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, - PCI_DN(dn)->phb->node); - iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl); - PCI_DN(dn)->iommu_table = iommu_init_table(tbl, - PCI_DN(dn)->phb->node); - + phb->node); + iommu_table_setparms(phb, dn, tbl); + dev->dev.archdata.dma_data = iommu_init_table(tbl, phb->node); return; } @@ -465,11 +470,11 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev) while (dn && PCI_DN(dn) && PCI_DN(dn)->iommu_table == NULL) dn = dn->parent; - if (dn && PCI_DN(dn)) { - 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, pci_name(dev)); - } + if (dn && PCI_DN(dn)) + dev->dev.archdata.dma_data = PCI_DN(dn)->iommu_table; + else + printk(KERN_WARNING "iommu: Device %s has no iommu table\n", + pci_name(dev)); } static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) @@ -495,13 +500,15 @@ static struct notifier_block iommu_reconfig_nb = { .notifier_call = iommu_reconfig_notifier, }; -static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) +static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) { struct device_node *pdn, *dn; struct iommu_table *tbl; const void *dma_window = NULL; struct pci_dn *pci; + DBG("pci_dma_dev_setup_pSeriesLP: %s\n", pci_name(dev)); + /* dev setup for LPAR is a little tricky, since the device tree might * contain the dma-window properties per-device and not neccesarily * for the bus. So we need to search upwards in the tree until we @@ -509,9 +516,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) * already allocated. */ dn = pci_device_to_OF_node(dev); - - DBG("iommu_dev_setup_pSeriesLP, dev %p (%s) %s\n", - dev, pci_name(dev), dn->full_name); + DBG(" node is %s\n", dn->full_name); for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table; pdn = pdn->parent) { @@ -520,16 +525,17 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) break; } + DBG(" parent is %s\n", pdn->full_name); + /* Check for parent == NULL so we don't try to setup the empty EADS * slots on POWER4 machines. */ if (dma_window == NULL || pdn->parent == NULL) { - DBG("No dma window for device, linking to parent\n"); - PCI_DN(dn)->iommu_table = PCI_DN(pdn)->iommu_table; + DBG(" no dma window for device, linking to parent\n"); + dev->dev.archdata.dma_data = PCI_DN(pdn)->iommu_table; return; - } else { - DBG("Found DMA window, allocating table\n"); } + DBG(" found DMA window, table: %p\n", pci->iommu_table); pci = PCI_DN(pdn); if (!pci->iommu_table) { @@ -542,24 +548,20 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); pci->iommu_table = iommu_init_table(tbl, pci->phb->node); + DBG(" created table: %p\n", pci->iommu_table); } - if (pdn != dn) - PCI_DN(dn)->iommu_table = pci->iommu_table; + dev->dev.archdata.dma_data = pci->iommu_table; } -static void iommu_bus_setup_null(struct pci_bus *b) { } -static void iommu_dev_setup_null(struct pci_dev *d) { } - /* These are called very early. */ void iommu_init_early_pSeries(void) { if (of_chosen && get_property(of_chosen, "linux,iommu-off", NULL)) { /* Direct I/O, IOMMU off */ - ppc_md.iommu_dev_setup = iommu_dev_setup_null; - ppc_md.iommu_bus_setup = iommu_bus_setup_null; - pci_direct_iommu_init(); - + ppc_md.pci_dma_dev_setup = NULL; + ppc_md.pci_dma_bus_setup = NULL; + pci_dma_ops = &dma_direct_ops; return; } @@ -572,19 +574,19 @@ void iommu_init_early_pSeries(void) ppc_md.tce_free = tce_free_pSeriesLP; } ppc_md.tce_get = tce_get_pSeriesLP; - ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP; - ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP; + ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeriesLP; + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeriesLP; } else { ppc_md.tce_build = tce_build_pSeries; ppc_md.tce_free = tce_free_pSeries; ppc_md.tce_get = tce_get_pseries; - ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries; - ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries; + ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeries; + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeries; } pSeries_reconfig_notifier_register(&iommu_reconfig_nb); - pci_iommu_init(); + pci_dma_ops = &dma_iommu_ops; } diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index 6bfacc21708..bb0cb5c5b56 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -93,8 +93,8 @@ pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus) if (list_empty(&dev->global_list)) { int i; - /* Need to setup IOMMU tables */ - ppc_md.iommu_dev_setup(dev); + /* Fill device archdata and setup iommu table */ + pcibios_setup_new_device(dev); if(fix_bus) pcibios_fixup_device_resources(dev, bus); |