.. | .. |
---|
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 | |
---|