diff options
Diffstat (limited to 'arch/powerpc/platforms/pseries/iommu.c')
-rw-r--r-- | arch/powerpc/platforms/pseries/iommu.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 01faab9456ca..fe5ededf0d60 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -1077,12 +1077,38 @@ check_mask: return 0; } +static u64 dma_get_required_mask_pSeriesLP(struct device *dev) +{ + if (!dev->dma_mask) + return 0; + + if (!disable_ddw && dev_is_pci(dev)) { + struct pci_dev *pdev = to_pci_dev(dev); + struct device_node *dn; + + dn = pci_device_to_OF_node(pdev); + + /* search upwards for ibm,dma-window */ + for (; dn && PCI_DN(dn) && !PCI_DN(dn)->iommu_table; + dn = dn->parent) + if (of_get_property(dn, "ibm,dma-window", NULL)) + break; + /* if there is a ibm,ddw-applicable property require 64 bits */ + if (dn && PCI_DN(dn) && + of_get_property(dn, "ibm,ddw-applicable", NULL)) + return DMA_BIT_MASK(64); + } + + return dma_iommu_get_required_mask(dev); +} + #else /* CONFIG_PCI */ #define pci_dma_bus_setup_pSeries NULL #define pci_dma_dev_setup_pSeries NULL #define pci_dma_bus_setup_pSeriesLP NULL #define pci_dma_dev_setup_pSeriesLP NULL #define dma_set_mask_pSeriesLP NULL +#define dma_get_required_mask_pSeriesLP NULL #endif /* !CONFIG_PCI */ static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action, @@ -1186,6 +1212,7 @@ void iommu_init_early_pSeries(void) ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeriesLP; ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeriesLP; ppc_md.dma_set_mask = dma_set_mask_pSeriesLP; + ppc_md.dma_get_required_mask = dma_get_required_mask_pSeriesLP; } else { ppc_md.tce_build = tce_build_pSeries; ppc_md.tce_free = tce_free_pSeries; |