diff options
Diffstat (limited to 'arch/powerpc/platforms/powernv/pci-ioda.c')
-rw-r--r-- | arch/powerpc/platforms/powernv/pci-ioda.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index e36738291c32..572e9c9f1ea0 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
@@ -1860,6 +1860,17 @@ static int pnv_ioda1_tce_xchg(struct iommu_table *tbl, long index, | |||
1860 | 1860 | ||
1861 | return ret; | 1861 | return ret; |
1862 | } | 1862 | } |
1863 | |||
1864 | static int pnv_ioda1_tce_xchg_rm(struct iommu_table *tbl, long index, | ||
1865 | unsigned long *hpa, enum dma_data_direction *direction) | ||
1866 | { | ||
1867 | long ret = pnv_tce_xchg(tbl, index, hpa, direction); | ||
1868 | |||
1869 | if (!ret) | ||
1870 | pnv_pci_p7ioc_tce_invalidate(tbl, index, 1, true); | ||
1871 | |||
1872 | return ret; | ||
1873 | } | ||
1863 | #endif | 1874 | #endif |
1864 | 1875 | ||
1865 | static void pnv_ioda1_tce_free(struct iommu_table *tbl, long index, | 1876 | static void pnv_ioda1_tce_free(struct iommu_table *tbl, long index, |
@@ -1874,6 +1885,7 @@ static struct iommu_table_ops pnv_ioda1_iommu_ops = { | |||
1874 | .set = pnv_ioda1_tce_build, | 1885 | .set = pnv_ioda1_tce_build, |
1875 | #ifdef CONFIG_IOMMU_API | 1886 | #ifdef CONFIG_IOMMU_API |
1876 | .exchange = pnv_ioda1_tce_xchg, | 1887 | .exchange = pnv_ioda1_tce_xchg, |
1888 | .exchange_rm = pnv_ioda1_tce_xchg_rm, | ||
1877 | #endif | 1889 | #endif |
1878 | .clear = pnv_ioda1_tce_free, | 1890 | .clear = pnv_ioda1_tce_free, |
1879 | .get = pnv_tce_get, | 1891 | .get = pnv_tce_get, |
@@ -1948,7 +1960,7 @@ static void pnv_pci_ioda2_tce_invalidate(struct iommu_table *tbl, | |||
1948 | { | 1960 | { |
1949 | struct iommu_table_group_link *tgl; | 1961 | struct iommu_table_group_link *tgl; |
1950 | 1962 | ||
1951 | list_for_each_entry_rcu(tgl, &tbl->it_group_list, next) { | 1963 | list_for_each_entry_lockless(tgl, &tbl->it_group_list, next) { |
1952 | struct pnv_ioda_pe *pe = container_of(tgl->table_group, | 1964 | struct pnv_ioda_pe *pe = container_of(tgl->table_group, |
1953 | struct pnv_ioda_pe, table_group); | 1965 | struct pnv_ioda_pe, table_group); |
1954 | struct pnv_phb *phb = pe->phb; | 1966 | struct pnv_phb *phb = pe->phb; |
@@ -2004,6 +2016,17 @@ static int pnv_ioda2_tce_xchg(struct iommu_table *tbl, long index, | |||
2004 | 2016 | ||
2005 | return ret; | 2017 | return ret; |
2006 | } | 2018 | } |
2019 | |||
2020 | static int pnv_ioda2_tce_xchg_rm(struct iommu_table *tbl, long index, | ||
2021 | unsigned long *hpa, enum dma_data_direction *direction) | ||
2022 | { | ||
2023 | long ret = pnv_tce_xchg(tbl, index, hpa, direction); | ||
2024 | |||
2025 | if (!ret) | ||
2026 | pnv_pci_ioda2_tce_invalidate(tbl, index, 1, true); | ||
2027 | |||
2028 | return ret; | ||
2029 | } | ||
2007 | #endif | 2030 | #endif |
2008 | 2031 | ||
2009 | static void pnv_ioda2_tce_free(struct iommu_table *tbl, long index, | 2032 | static void pnv_ioda2_tce_free(struct iommu_table *tbl, long index, |
@@ -2024,6 +2047,7 @@ static struct iommu_table_ops pnv_ioda2_iommu_ops = { | |||
2024 | .set = pnv_ioda2_tce_build, | 2047 | .set = pnv_ioda2_tce_build, |
2025 | #ifdef CONFIG_IOMMU_API | 2048 | #ifdef CONFIG_IOMMU_API |
2026 | .exchange = pnv_ioda2_tce_xchg, | 2049 | .exchange = pnv_ioda2_tce_xchg, |
2050 | .exchange_rm = pnv_ioda2_tce_xchg_rm, | ||
2027 | #endif | 2051 | #endif |
2028 | .clear = pnv_ioda2_tce_free, | 2052 | .clear = pnv_ioda2_tce_free, |
2029 | .get = pnv_tce_get, | 2053 | .get = pnv_tce_get, |