]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/iommu/tegra-smmu.c
pinctrl: baytrail: Allocate IRQ chip dynamic
[linux.git] / drivers / iommu / tegra-smmu.c
index 7293fc3f796d69f61f8cbe8a4ef3176d3b9ff5b0..63a147b623e6d0f3e3ddadbe5d35e26b0a811356 100644 (file)
@@ -159,9 +159,9 @@ static bool smmu_dma_addr_valid(struct tegra_smmu *smmu, dma_addr_t addr)
        return (addr & smmu->pfn_mask) == addr;
 }
 
-static dma_addr_t smmu_pde_to_dma(u32 pde)
+static dma_addr_t smmu_pde_to_dma(struct tegra_smmu *smmu, u32 pde)
 {
-       return pde << 12;
+       return (dma_addr_t)(pde & smmu->pfn_mask) << 12;
 }
 
 static void smmu_flush_ptc_all(struct tegra_smmu *smmu)
@@ -240,7 +240,7 @@ static inline void smmu_flush_tlb_group(struct tegra_smmu *smmu,
 
 static inline void smmu_flush(struct tegra_smmu *smmu)
 {
-       smmu_readl(smmu, SMMU_CONFIG);
+       smmu_readl(smmu, SMMU_PTB_ASID);
 }
 
 static int tegra_smmu_alloc_asid(struct tegra_smmu *smmu, unsigned int *idp)
@@ -351,6 +351,20 @@ static void tegra_smmu_enable(struct tegra_smmu *smmu, unsigned int swgroup,
        unsigned int i;
        u32 value;
 
+       group = tegra_smmu_find_swgroup(smmu, swgroup);
+       if (group) {
+               value = smmu_readl(smmu, group->reg);
+               value &= ~SMMU_ASID_MASK;
+               value |= SMMU_ASID_VALUE(asid);
+               value |= SMMU_ASID_ENABLE;
+               smmu_writel(smmu, value, group->reg);
+       } else {
+               pr_warn("%s group from swgroup %u not found\n", __func__,
+                               swgroup);
+               /* No point moving ahead if group was not found */
+               return;
+       }
+
        for (i = 0; i < smmu->soc->num_clients; i++) {
                const struct tegra_mc_client *client = &smmu->soc->clients[i];
 
@@ -361,15 +375,6 @@ static void tegra_smmu_enable(struct tegra_smmu *smmu, unsigned int swgroup,
                value |= BIT(client->smmu.bit);
                smmu_writel(smmu, value, client->smmu.reg);
        }
-
-       group = tegra_smmu_find_swgroup(smmu, swgroup);
-       if (group) {
-               value = smmu_readl(smmu, group->reg);
-               value &= ~SMMU_ASID_MASK;
-               value |= SMMU_ASID_VALUE(asid);
-               value |= SMMU_ASID_ENABLE;
-               smmu_writel(smmu, value, group->reg);
-       }
 }
 
 static void tegra_smmu_disable(struct tegra_smmu *smmu, unsigned int swgroup,
@@ -549,6 +554,7 @@ static u32 *tegra_smmu_pte_lookup(struct tegra_smmu_as *as, unsigned long iova,
                                  dma_addr_t *dmap)
 {
        unsigned int pd_index = iova_pd_index(iova);
+       struct tegra_smmu *smmu = as->smmu;
        struct page *pt_page;
        u32 *pd;
 
@@ -557,7 +563,7 @@ static u32 *tegra_smmu_pte_lookup(struct tegra_smmu_as *as, unsigned long iova,
                return NULL;
 
        pd = page_address(as->pd);
-       *dmap = smmu_pde_to_dma(pd[pd_index]);
+       *dmap = smmu_pde_to_dma(smmu, pd[pd_index]);
 
        return tegra_smmu_pte_offset(pt_page, iova);
 }
@@ -599,7 +605,7 @@ static u32 *as_get_pte(struct tegra_smmu_as *as, dma_addr_t iova,
        } else {
                u32 *pd = page_address(as->pd);
 
-               *dmap = smmu_pde_to_dma(pd[pde]);
+               *dmap = smmu_pde_to_dma(smmu, pd[pde]);
        }
 
        return tegra_smmu_pte_offset(as->pts[pde], iova);
@@ -624,7 +630,7 @@ static void tegra_smmu_pte_put_use(struct tegra_smmu_as *as, unsigned long iova)
        if (--as->count[pde] == 0) {
                struct tegra_smmu *smmu = as->smmu;
                u32 *pd = page_address(as->pd);
-               dma_addr_t pte_dma = smmu_pde_to_dma(pd[pde]);
+               dma_addr_t pte_dma = smmu_pde_to_dma(smmu, pd[pde]);
 
                tegra_smmu_set_pde(as, iova, 0);
 
@@ -650,7 +656,7 @@ static void tegra_smmu_set_pte(struct tegra_smmu_as *as, unsigned long iova,
 }
 
 static int tegra_smmu_map(struct iommu_domain *domain, unsigned long iova,
-                         phys_addr_t paddr, size_t size, int prot)
+                         phys_addr_t paddr, size_t size, int prot, gfp_t gfp)
 {
        struct tegra_smmu_as *as = to_smmu_as(domain);
        dma_addr_t pte_dma;