| .. | .. |
|---|
| 28 | 28 | #include <linux/types.h> |
|---|
| 29 | 29 | |
|---|
| 30 | 30 | #define IOMMU_RESET_REG 0x010 |
|---|
| 31 | +#define IOMMU_RESET_RELEASE_ALL 0xffffffff |
|---|
| 31 | 32 | #define IOMMU_ENABLE_REG 0x020 |
|---|
| 32 | 33 | #define IOMMU_ENABLE_ENABLE BIT(0) |
|---|
| 33 | 34 | |
|---|
| .. | .. |
|---|
| 271 | 272 | enum sun50i_iommu_aci aci; |
|---|
| 272 | 273 | u32 flags = 0; |
|---|
| 273 | 274 | |
|---|
| 274 | | - if (prot & (IOMMU_READ | IOMMU_WRITE)) |
|---|
| 275 | + if ((prot & (IOMMU_READ | IOMMU_WRITE)) == (IOMMU_READ | IOMMU_WRITE)) |
|---|
| 275 | 276 | aci = SUN50I_IOMMU_ACI_RD_WR; |
|---|
| 276 | 277 | else if (prot & IOMMU_READ) |
|---|
| 277 | 278 | aci = SUN50I_IOMMU_ACI_RD; |
|---|
| .. | .. |
|---|
| 512 | 513 | sun50i_iommu_free_page_table(iommu, drop_pt); |
|---|
| 513 | 514 | } |
|---|
| 514 | 515 | |
|---|
| 515 | | - sun50i_table_flush(sun50i_domain, page_table, PT_SIZE); |
|---|
| 516 | + sun50i_table_flush(sun50i_domain, page_table, NUM_PT_ENTRIES); |
|---|
| 516 | 517 | sun50i_table_flush(sun50i_domain, dte_addr, 1); |
|---|
| 517 | 518 | |
|---|
| 518 | 519 | return page_table; |
|---|
| .. | .. |
|---|
| 602 | 603 | struct sun50i_iommu_domain *sun50i_domain; |
|---|
| 603 | 604 | |
|---|
| 604 | 605 | if (type != IOMMU_DOMAIN_DMA && |
|---|
| 605 | | - type != IOMMU_DOMAIN_IDENTITY && |
|---|
| 606 | 606 | type != IOMMU_DOMAIN_UNMANAGED) |
|---|
| 607 | 607 | return NULL; |
|---|
| 608 | 608 | |
|---|
| .. | .. |
|---|
| 880 | 880 | |
|---|
| 881 | 881 | static irqreturn_t sun50i_iommu_irq(int irq, void *dev_id) |
|---|
| 882 | 882 | { |
|---|
| 883 | + u32 status, l1_status, l2_status, resets; |
|---|
| 883 | 884 | struct sun50i_iommu *iommu = dev_id; |
|---|
| 884 | | - u32 status; |
|---|
| 885 | 885 | |
|---|
| 886 | 886 | spin_lock(&iommu->iommu_lock); |
|---|
| 887 | 887 | |
|---|
| .. | .. |
|---|
| 890 | 890 | spin_unlock(&iommu->iommu_lock); |
|---|
| 891 | 891 | return IRQ_NONE; |
|---|
| 892 | 892 | } |
|---|
| 893 | + |
|---|
| 894 | + l1_status = iommu_read(iommu, IOMMU_L1PG_INT_REG); |
|---|
| 895 | + l2_status = iommu_read(iommu, IOMMU_L2PG_INT_REG); |
|---|
| 893 | 896 | |
|---|
| 894 | 897 | if (status & IOMMU_INT_INVALID_L2PG) |
|---|
| 895 | 898 | sun50i_iommu_handle_pt_irq(iommu, |
|---|
| .. | .. |
|---|
| 904 | 907 | |
|---|
| 905 | 908 | iommu_write(iommu, IOMMU_INT_CLR_REG, status); |
|---|
| 906 | 909 | |
|---|
| 907 | | - iommu_write(iommu, IOMMU_RESET_REG, ~status); |
|---|
| 908 | | - iommu_write(iommu, IOMMU_RESET_REG, status); |
|---|
| 910 | + resets = (status | l1_status | l2_status) & IOMMU_INT_MASTER_MASK; |
|---|
| 911 | + iommu_write(iommu, IOMMU_RESET_REG, ~resets); |
|---|
| 912 | + iommu_write(iommu, IOMMU_RESET_REG, IOMMU_RESET_RELEASE_ALL); |
|---|
| 909 | 913 | |
|---|
| 910 | 914 | spin_unlock(&iommu->iommu_lock); |
|---|
| 911 | 915 | |
|---|