Lines Matching +full:irq +full:- +full:syscfg

1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2008-2010 Nokia Corporation
6 * Copyright (C) 2013-2017 Texas Instruments Incorporated - https://www.ti.com/
12 #include <linux/dma-mapping.h>
19 #include <linux/omap-iommu.h>
30 #include <linux/platform_data/iommu-omap.h>
32 #include "omap-iopgtable.h"
33 #include "omap-iommu.h"
56 * to_omap_domain - Get struct omap_iommu_domain from generic iommu_domain
65 * omap_iommu_save_ctx - Save registers for pm off-mode support
81 while (arch_data->iommu_dev) { in omap_iommu_save_ctx()
82 obj = arch_data->iommu_dev; in omap_iommu_save_ctx()
83 p = obj->ctx; in omap_iommu_save_ctx()
86 dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, in omap_iommu_save_ctx()
95 * omap_iommu_restore_ctx - Restore registers for pm off-mode support
111 while (arch_data->iommu_dev) { in omap_iommu_restore_ctx()
112 obj = arch_data->iommu_dev; in omap_iommu_restore_ctx()
113 p = obj->ctx; in omap_iommu_restore_ctx()
116 dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, in omap_iommu_restore_ctx()
128 if (!obj->syscfg) in dra7_cfg_dspsys_mmu()
131 mask = (1 << (obj->id * DSP_SYS_MMU_CONFIG_EN_SHIFT)); in dra7_cfg_dspsys_mmu()
133 regmap_update_bits(obj->syscfg, DSP_SYS_MMU_CONFIG, mask, val); in dra7_cfg_dspsys_mmu()
158 if (!obj->iopgd || !IS_ALIGNED((unsigned long)obj->iopgd, SZ_16K)) in omap2_iommu_enable()
159 return -EINVAL; in omap2_iommu_enable()
161 pa = virt_to_phys(obj->iopgd); in omap2_iommu_enable()
163 return -EINVAL; in omap2_iommu_enable()
166 dev_info(obj->dev, "%s: version %d.%d\n", obj->name, in omap2_iommu_enable()
173 if (obj->has_bus_err_back) in omap2_iommu_enable()
189 dev_dbg(obj->dev, "%s is shutting down\n", obj->name); in omap2_iommu_disable()
196 ret = pm_runtime_get_sync(obj->dev); in iommu_enable()
198 pm_runtime_put_noidle(obj->dev); in iommu_enable()
205 pm_runtime_put_sync(obj->dev); in iommu_disable()
213 u32 page_size = cr->cam & MMU_CAM_PGSZ_MASK; in iotlb_cr_to_virt()
214 u32 mask = get_cam_va_mask(cr->cam & page_size); in iotlb_cr_to_virt()
216 return cr->cam & mask; in iotlb_cr_to_virt()
223 attr = e->mixed << 5; in get_iopte_attr()
224 attr |= e->endian; in get_iopte_attr()
225 attr |= e->elsz >> 3; in get_iopte_attr()
226 attr <<= (((e->pgsz == MMU_CAM_PGSZ_4K) || in get_iopte_attr()
227 (e->pgsz == MMU_CAM_PGSZ_64K)) ? 0 : 6); in get_iopte_attr()
256 l->base = MMU_LOCK_BASE(val); in iotlb_lock_get()
257 l->vict = MMU_LOCK_VICT(val); in iotlb_lock_get()
264 val = (l->base << MMU_LOCK_BASE_SHIFT); in iotlb_lock_set()
265 val |= (l->vict << MMU_LOCK_VICT_SHIFT); in iotlb_lock_set()
272 cr->cam = iommu_read_reg(obj, MMU_READ_CAM); in iotlb_read_cr()
273 cr->ram = iommu_read_reg(obj, MMU_READ_RAM); in iotlb_read_cr()
278 iommu_write_reg(obj, cr->cam | MMU_CAM_V, MMU_CAM); in iotlb_load_cr()
279 iommu_write_reg(obj, cr->ram, MMU_RAM); in iotlb_load_cr()
285 /* only used in iotlb iteration for-loop */
308 if (e->da & ~(get_cam_va_mask(e->pgsz))) { in iotlb_alloc_cr()
309 dev_err(obj->dev, "%s:\twrong alignment: %08x\n", __func__, in iotlb_alloc_cr()
310 e->da); in iotlb_alloc_cr()
311 return ERR_PTR(-EINVAL); in iotlb_alloc_cr()
316 return ERR_PTR(-ENOMEM); in iotlb_alloc_cr()
318 cr->cam = (e->da & MMU_CAM_VATAG_MASK) | e->prsvd | e->pgsz | e->valid; in iotlb_alloc_cr()
319 cr->ram = e->pa | e->endian | e->elsz | e->mixed; in iotlb_alloc_cr()
325 * load_iotlb_entry - Set an iommu tlb entry
335 if (!obj || !obj->nr_tlb_entries || !e) in load_iotlb_entry()
336 return -EINVAL; in load_iotlb_entry()
338 pm_runtime_get_sync(obj->dev); in load_iotlb_entry()
341 if (l.base == obj->nr_tlb_entries) { in load_iotlb_entry()
342 dev_warn(obj->dev, "%s: preserve entries full\n", __func__); in load_iotlb_entry()
343 err = -EBUSY; in load_iotlb_entry()
346 if (!e->prsvd) { in load_iotlb_entry()
350 for_each_iotlb_cr(obj, obj->nr_tlb_entries, i, tmp) in load_iotlb_entry()
354 if (i == obj->nr_tlb_entries) { in load_iotlb_entry()
355 dev_dbg(obj->dev, "%s: full: no entry\n", __func__); in load_iotlb_entry()
356 err = -EBUSY; in load_iotlb_entry()
368 pm_runtime_put_sync(obj->dev); in load_iotlb_entry()
375 if (e->prsvd) in load_iotlb_entry()
378 if (++l.vict == obj->nr_tlb_entries) in load_iotlb_entry()
382 pm_runtime_put_sync(obj->dev); in load_iotlb_entry()
401 * flush_iotlb_page - Clear an iommu tlb entry
412 pm_runtime_get_sync(obj->dev); in flush_iotlb_page()
414 for_each_iotlb_cr(obj, obj->nr_tlb_entries, i, cr) { in flush_iotlb_page()
425 dev_dbg(obj->dev, "%s: %08x<=%08x(%zx)\n", in flush_iotlb_page()
432 pm_runtime_put_sync(obj->dev); in flush_iotlb_page()
434 if (i == obj->nr_tlb_entries) in flush_iotlb_page()
435 dev_dbg(obj->dev, "%s: no page for %08x\n", __func__, da); in flush_iotlb_page()
439 * flush_iotlb_all - Clear all iommu tlb entries
446 pm_runtime_get_sync(obj->dev); in flush_iotlb_all()
454 pm_runtime_put_sync(obj->dev); in flush_iotlb_all()
472 /* Note: freed iopte's must be clean ready for re-use */ in iopte_free()
476 dma_unmap_single(obj->dev, pt_dma, IOPTE_TABLE_SIZE, in iopte_free()
497 spin_unlock(&obj->page_table_lock); in iopte_alloc()
499 spin_lock(&obj->page_table_lock); in iopte_alloc()
503 return ERR_PTR(-ENOMEM); in iopte_alloc()
505 *pt_dma = dma_map_single(obj->dev, iopte, IOPTE_TABLE_SIZE, in iopte_alloc()
507 if (dma_mapping_error(obj->dev, *pt_dma)) { in iopte_alloc()
508 dev_err(obj->dev, "DMA map error for L2 table\n"); in iopte_alloc()
510 return ERR_PTR(-ENOMEM); in iopte_alloc()
518 dev_err(obj->dev, "DMA translation error for L2 table\n"); in iopte_alloc()
519 dma_unmap_single(obj->dev, *pt_dma, IOPTE_TABLE_SIZE, in iopte_alloc()
522 return ERR_PTR(-ENOMEM); in iopte_alloc()
527 flush_iopte_range(obj->dev, obj->pd_dma, offset, 1); in iopte_alloc()
528 dev_vdbg(obj->dev, "%s: a new pte:%p\n", __func__, iopte); in iopte_alloc()
537 dev_vdbg(obj->dev, in iopte_alloc()
550 dev_err(obj->dev, "%s: %08x:%08x should aligned on %08lx\n", in iopgd_alloc_section()
552 return -EINVAL; in iopgd_alloc_section()
556 flush_iopte_range(obj->dev, obj->pd_dma, offset, 1); in iopgd_alloc_section()
567 dev_err(obj->dev, "%s: %08x:%08x should aligned on %08lx\n", in iopgd_alloc_super()
569 return -EINVAL; in iopgd_alloc_super()
574 flush_iopte_range(obj->dev, obj->pd_dma, offset, 16); in iopgd_alloc_super()
589 flush_iopte_range(obj->dev, pt_dma, offset, 1); in iopte_alloc_page()
591 dev_vdbg(obj->dev, "%s: da:%08x pa:%08x pte:%p *pte:%08x\n", in iopte_alloc_page()
606 dev_err(obj->dev, "%s: %08x:%08x should aligned on %08lx\n", in iopte_alloc_large()
608 return -EINVAL; in iopte_alloc_large()
616 flush_iopte_range(obj->dev, pt_dma, offset, 16); in iopte_alloc_large()
628 return -EINVAL; in iopgtable_store_entry_core()
630 switch (e->pgsz) { in iopgtable_store_entry_core()
649 return -EINVAL; in iopgtable_store_entry_core()
653 spin_lock(&obj->page_table_lock); in iopgtable_store_entry_core()
654 err = fn(obj, e->da, e->pa, prot); in iopgtable_store_entry_core()
655 spin_unlock(&obj->page_table_lock); in iopgtable_store_entry_core()
661 * omap_iopgtable_store_entry - Make an iommu pte entry
670 flush_iotlb_page(obj, e->da); in omap_iopgtable_store_entry()
678 * iopgtable_lookup_entry - Lookup an iommu pte entry
725 flush_iopte_range(obj->dev, pt_dma, pt_offset, nent); in iopgtable_clear_entry_core()
747 flush_iopte_range(obj->dev, obj->pd_dma, pd_offset, nent); in iopgtable_clear_entry_core()
753 * iopgtable_clear_entry - Remove an iommu pte entry
761 spin_lock(&obj->page_table_lock); in iopgtable_clear_entry()
766 spin_unlock(&obj->page_table_lock); in iopgtable_clear_entry()
776 spin_lock(&obj->page_table_lock); in iopgtable_clear_entry_all()
793 flush_iopte_range(obj->dev, obj->pd_dma, offset, 1); in iopgtable_clear_entry_all()
798 spin_unlock(&obj->page_table_lock); in iopgtable_clear_entry_all()
804 static irqreturn_t iommu_fault_handler(int irq, void *data) in iommu_fault_handler() argument
809 struct iommu_domain *domain = obj->domain; in iommu_fault_handler()
812 if (!omap_domain->dev) in iommu_fault_handler()
820 if (!report_iommu_fault(domain, obj->dev, da, 0)) in iommu_fault_handler()
828 dev_err(obj->dev, "%s: errs:0x%08x da:0x%08x pgd:0x%p *pgd:px%08x\n", in iommu_fault_handler()
829 obj->name, errs, da, iopgd, *iopgd); in iommu_fault_handler()
835 dev_err(obj->dev, "%s: errs:0x%08x da:0x%08x pgd:0x%p *pgd:0x%08x pte:0x%p *pte:0x%08x\n", in iommu_fault_handler()
836 obj->name, errs, da, iopgd, *iopgd, iopte, *iopte); in iommu_fault_handler()
842 * omap_iommu_attach() - attach iommu device to an iommu domain
850 spin_lock(&obj->iommu_lock); in omap_iommu_attach()
852 obj->pd_dma = dma_map_single(obj->dev, iopgd, IOPGD_TABLE_SIZE, in omap_iommu_attach()
854 if (dma_mapping_error(obj->dev, obj->pd_dma)) { in omap_iommu_attach()
855 dev_err(obj->dev, "DMA map error for L1 table\n"); in omap_iommu_attach()
856 err = -ENOMEM; in omap_iommu_attach()
860 obj->iopgd = iopgd; in omap_iommu_attach()
866 spin_unlock(&obj->iommu_lock); in omap_iommu_attach()
868 dev_dbg(obj->dev, "%s: %s\n", __func__, obj->name); in omap_iommu_attach()
873 spin_unlock(&obj->iommu_lock); in omap_iommu_attach()
879 * omap_iommu_detach - release iommu device
887 spin_lock(&obj->iommu_lock); in omap_iommu_detach()
889 dma_unmap_single(obj->dev, obj->pd_dma, IOPGD_TABLE_SIZE, in omap_iommu_detach()
891 obj->pd_dma = 0; in omap_iommu_detach()
892 obj->iopgd = NULL; in omap_iommu_detach()
895 spin_unlock(&obj->iommu_lock); in omap_iommu_detach()
897 dev_dbg(obj->dev, "%s: %s\n", __func__, obj->name); in omap_iommu_detach()
909 obj->num_cr_ctx = lock.base; in omap_iommu_save_tlb_entries()
910 if (!obj->num_cr_ctx) in omap_iommu_save_tlb_entries()
913 tmp = obj->cr_ctx; in omap_iommu_save_tlb_entries()
914 for_each_iotlb_cr(obj, obj->num_cr_ctx, i, cr) in omap_iommu_save_tlb_entries()
925 if (!obj->num_cr_ctx) in omap_iommu_restore_tlb_entries()
929 tmp = obj->cr_ctx; in omap_iommu_restore_tlb_entries()
930 for (i = 0; i < obj->num_cr_ctx; i++, tmp++) { in omap_iommu_restore_tlb_entries()
935 l.base = obj->num_cr_ctx; in omap_iommu_restore_tlb_entries()
941 * omap_iommu_domain_deactivate - deactivate attached iommu devices
956 if (!omap_domain->dev) in omap_iommu_domain_deactivate()
959 iommu = omap_domain->iommus; in omap_iommu_domain_deactivate()
960 iommu += (omap_domain->num_iommus - 1); in omap_iommu_domain_deactivate()
961 for (i = 0; i < omap_domain->num_iommus; i++, iommu--) { in omap_iommu_domain_deactivate()
962 oiommu = iommu->iommu_dev; in omap_iommu_domain_deactivate()
963 pm_runtime_put_sync(oiommu->dev); in omap_iommu_domain_deactivate()
971 * omap_iommu_domain_activate - activate attached iommu devices
985 if (!omap_domain->dev) in omap_iommu_domain_activate()
988 iommu = omap_domain->iommus; in omap_iommu_domain_activate()
989 for (i = 0; i < omap_domain->num_iommus; i++, iommu++) { in omap_iommu_domain_activate()
990 oiommu = iommu->iommu_dev; in omap_iommu_domain_activate()
991 pm_runtime_get_sync(oiommu->dev); in omap_iommu_domain_activate()
999 * omap_iommu_runtime_suspend - disable an iommu device
1018 if (obj->domain && obj->iopgd) in omap_iommu_runtime_suspend()
1023 if (pdata && pdata->device_idle) in omap_iommu_runtime_suspend()
1024 pdata->device_idle(pdev); in omap_iommu_runtime_suspend()
1026 if (pdata && pdata->assert_reset) in omap_iommu_runtime_suspend()
1027 pdata->assert_reset(pdev, pdata->reset_name); in omap_iommu_runtime_suspend()
1029 if (pdata && pdata->set_pwrdm_constraint) { in omap_iommu_runtime_suspend()
1030 ret = pdata->set_pwrdm_constraint(pdev, false, &obj->pwrst); in omap_iommu_runtime_suspend()
1032 dev_warn(obj->dev, "pwrdm_constraint failed to be reset, status = %d\n", in omap_iommu_runtime_suspend()
1041 * omap_iommu_runtime_resume - enable an iommu device
1059 if (pdata && pdata->set_pwrdm_constraint) { in omap_iommu_runtime_resume()
1060 ret = pdata->set_pwrdm_constraint(pdev, true, &obj->pwrst); in omap_iommu_runtime_resume()
1062 dev_warn(obj->dev, "pwrdm_constraint failed to be set, status = %d\n", in omap_iommu_runtime_resume()
1067 if (pdata && pdata->deassert_reset) { in omap_iommu_runtime_resume()
1068 ret = pdata->deassert_reset(pdev, pdata->reset_name); in omap_iommu_runtime_resume()
1075 if (pdata && pdata->device_enable) in omap_iommu_runtime_resume()
1076 pdata->device_enable(pdev); in omap_iommu_runtime_resume()
1079 if (obj->domain) in omap_iommu_runtime_resume()
1088 * omap_iommu_prepare - prepare() dev_pm_ops implementation
1106 struct device_node *np = pdev->dev.of_node; in omap_iommu_can_register()
1108 if (!of_device_is_compatible(np, "ti,dra7-dsp-iommu")) in omap_iommu_can_register()
1112 * restrict IOMMU core registration only for processor-port MDMA MMUs in omap_iommu_can_register()
1115 if ((!strcmp(dev_name(&pdev->dev), "40d01000.mmu")) || in omap_iommu_can_register()
1116 (!strcmp(dev_name(&pdev->dev), "41501000.mmu"))) in omap_iommu_can_register()
1125 struct device_node *np = pdev->dev.of_node; in omap_iommu_dra7_get_dsp_system_cfg()
1128 if (!of_device_is_compatible(np, "ti,dra7-dsp-iommu")) in omap_iommu_dra7_get_dsp_system_cfg()
1131 if (!of_property_read_bool(np, "ti,syscon-mmuconfig")) { in omap_iommu_dra7_get_dsp_system_cfg()
1132 dev_err(&pdev->dev, "ti,syscon-mmuconfig property is missing\n"); in omap_iommu_dra7_get_dsp_system_cfg()
1133 return -EINVAL; in omap_iommu_dra7_get_dsp_system_cfg()
1136 obj->syscfg = in omap_iommu_dra7_get_dsp_system_cfg()
1137 syscon_regmap_lookup_by_phandle(np, "ti,syscon-mmuconfig"); in omap_iommu_dra7_get_dsp_system_cfg()
1138 if (IS_ERR(obj->syscfg)) { in omap_iommu_dra7_get_dsp_system_cfg()
1139 /* can fail with -EPROBE_DEFER */ in omap_iommu_dra7_get_dsp_system_cfg()
1140 ret = PTR_ERR(obj->syscfg); in omap_iommu_dra7_get_dsp_system_cfg()
1144 if (of_property_read_u32_index(np, "ti,syscon-mmuconfig", 1, in omap_iommu_dra7_get_dsp_system_cfg()
1145 &obj->id)) { in omap_iommu_dra7_get_dsp_system_cfg()
1146 dev_err(&pdev->dev, "couldn't get the IOMMU instance id within subsystem\n"); in omap_iommu_dra7_get_dsp_system_cfg()
1147 return -EINVAL; in omap_iommu_dra7_get_dsp_system_cfg()
1150 if (obj->id != 0 && obj->id != 1) { in omap_iommu_dra7_get_dsp_system_cfg()
1151 dev_err(&pdev->dev, "invalid IOMMU instance id\n"); in omap_iommu_dra7_get_dsp_system_cfg()
1152 return -EINVAL; in omap_iommu_dra7_get_dsp_system_cfg()
1163 int err = -ENODEV; in omap_iommu_probe()
1164 int irq; in omap_iommu_probe() local
1167 struct device_node *of = pdev->dev.of_node; in omap_iommu_probe()
1170 pr_err("%s: only DT-based devices are supported\n", __func__); in omap_iommu_probe()
1171 return -ENODEV; in omap_iommu_probe()
1174 obj = devm_kzalloc(&pdev->dev, sizeof(*obj) + MMU_REG_SIZE, GFP_KERNEL); in omap_iommu_probe()
1176 return -ENOMEM; in omap_iommu_probe()
1179 * self-manage the ordering dependencies between omap_device_enable/idle in omap_iommu_probe()
1182 if (pdev->dev.pm_domain) { in omap_iommu_probe()
1183 dev_dbg(&pdev->dev, "device pm_domain is being reset\n"); in omap_iommu_probe()
1184 pdev->dev.pm_domain = NULL; in omap_iommu_probe()
1187 obj->name = dev_name(&pdev->dev); in omap_iommu_probe()
1188 obj->nr_tlb_entries = 32; in omap_iommu_probe()
1189 err = of_property_read_u32(of, "ti,#tlb-entries", &obj->nr_tlb_entries); in omap_iommu_probe()
1190 if (err && err != -EINVAL) in omap_iommu_probe()
1192 if (obj->nr_tlb_entries != 32 && obj->nr_tlb_entries != 8) in omap_iommu_probe()
1193 return -EINVAL; in omap_iommu_probe()
1194 if (of_property_read_bool(of, "ti,iommu-bus-err-back")) in omap_iommu_probe()
1195 obj->has_bus_err_back = MMU_GP_REG_BUS_ERR_BACK_EN; in omap_iommu_probe()
1197 obj->dev = &pdev->dev; in omap_iommu_probe()
1198 obj->ctx = (void *)obj + sizeof(*obj); in omap_iommu_probe()
1199 obj->cr_ctx = devm_kzalloc(&pdev->dev, in omap_iommu_probe()
1200 sizeof(*obj->cr_ctx) * obj->nr_tlb_entries, in omap_iommu_probe()
1202 if (!obj->cr_ctx) in omap_iommu_probe()
1203 return -ENOMEM; in omap_iommu_probe()
1205 spin_lock_init(&obj->iommu_lock); in omap_iommu_probe()
1206 spin_lock_init(&obj->page_table_lock); in omap_iommu_probe()
1209 obj->regbase = devm_ioremap_resource(obj->dev, res); in omap_iommu_probe()
1210 if (IS_ERR(obj->regbase)) in omap_iommu_probe()
1211 return PTR_ERR(obj->regbase); in omap_iommu_probe()
1217 irq = platform_get_irq(pdev, 0); in omap_iommu_probe()
1218 if (irq < 0) in omap_iommu_probe()
1219 return -ENODEV; in omap_iommu_probe()
1221 err = devm_request_irq(obj->dev, irq, iommu_fault_handler, IRQF_SHARED, in omap_iommu_probe()
1222 dev_name(obj->dev), obj); in omap_iommu_probe()
1228 err = iommu_device_sysfs_add(&obj->iommu, obj->dev, NULL, in omap_iommu_probe()
1229 obj->name); in omap_iommu_probe()
1233 err = iommu_device_register(&obj->iommu, &omap_iommu_ops, &pdev->dev); in omap_iommu_probe()
1236 obj->has_iommu_driver = true; in omap_iommu_probe()
1239 pm_runtime_enable(obj->dev); in omap_iommu_probe()
1243 dev_info(&pdev->dev, "%s registered\n", obj->name); in omap_iommu_probe()
1245 /* Re-probe bus to probe device attached to this IOMMU */ in omap_iommu_probe()
1251 iommu_device_sysfs_remove(&obj->iommu); in omap_iommu_probe()
1259 if (obj->has_iommu_driver) { in omap_iommu_remove()
1260 iommu_device_sysfs_remove(&obj->iommu); in omap_iommu_remove()
1261 iommu_device_unregister(&obj->iommu); in omap_iommu_remove()
1266 pm_runtime_disable(obj->dev); in omap_iommu_remove()
1268 dev_info(&pdev->dev, "%s removed\n", obj->name); in omap_iommu_remove()
1280 { .compatible = "ti,omap2-iommu" },
1281 { .compatible = "ti,omap4-iommu" },
1282 { .compatible = "ti,dra7-iommu" },
1283 { .compatible = "ti,dra7-dsp-iommu" },
1291 .name = "omap-iommu",
1301 e->da = da; in iotlb_init_entry()
1302 e->pa = pa; in iotlb_init_entry()
1303 e->valid = MMU_CAM_V; in iotlb_init_entry()
1304 e->pgsz = pgsz; in iotlb_init_entry()
1305 e->endian = MMU_RAM_ENDIAN_LITTLE; in iotlb_init_entry()
1306 e->elsz = MMU_RAM_ELSZ_8; in iotlb_init_entry()
1307 e->mixed = 0; in iotlb_init_entry()
1309 return iopgsz_to_bytes(e->pgsz); in iotlb_init_entry()
1317 struct device *dev = omap_domain->dev; in omap_iommu_map()
1322 u32 ret = -EINVAL; in omap_iommu_map()
1328 return -EINVAL; in omap_iommu_map()
1335 iommu = omap_domain->iommus; in omap_iommu_map()
1336 for (i = 0; i < omap_domain->num_iommus; i++, iommu++) { in omap_iommu_map()
1337 oiommu = iommu->iommu_dev; in omap_iommu_map()
1347 while (i--) { in omap_iommu_map()
1348 iommu--; in omap_iommu_map()
1349 oiommu = iommu->iommu_dev; in omap_iommu_map()
1363 struct device *dev = omap_domain->dev; in omap_iommu_unmap()
1372 iommu = omap_domain->iommus; in omap_iommu_unmap()
1373 for (i = 0; i < omap_domain->num_iommus; i++, iommu++) { in omap_iommu_unmap()
1374 oiommu = iommu->iommu_dev; in omap_iommu_unmap()
1381 * simplify return - we are only checking if any of the iommus in omap_iommu_unmap()
1394 while (arch_data->iommu_dev) { in omap_iommu_count()
1409 odomain->num_iommus = omap_iommu_count(dev); in omap_iommu_attach_init()
1410 if (!odomain->num_iommus) in omap_iommu_attach_init()
1411 return -ENODEV; in omap_iommu_attach_init()
1413 odomain->iommus = kcalloc(odomain->num_iommus, sizeof(*iommu), in omap_iommu_attach_init()
1415 if (!odomain->iommus) in omap_iommu_attach_init()
1416 return -ENOMEM; in omap_iommu_attach_init()
1418 iommu = odomain->iommus; in omap_iommu_attach_init()
1419 for (i = 0; i < odomain->num_iommus; i++, iommu++) { in omap_iommu_attach_init()
1420 iommu->pgtable = kzalloc(IOPGD_TABLE_SIZE, GFP_ATOMIC); in omap_iommu_attach_init()
1421 if (!iommu->pgtable) in omap_iommu_attach_init()
1422 return -ENOMEM; in omap_iommu_attach_init()
1428 if (WARN_ON(!IS_ALIGNED((long)iommu->pgtable, in omap_iommu_attach_init()
1430 return -EINVAL; in omap_iommu_attach_init()
1439 struct omap_iommu_device *iommu = odomain->iommus; in omap_iommu_detach_fini()
1441 for (i = 0; iommu && i < odomain->num_iommus; i++, iommu++) in omap_iommu_detach_fini()
1442 kfree(iommu->pgtable); in omap_iommu_detach_fini()
1444 kfree(odomain->iommus); in omap_iommu_detach_fini()
1445 odomain->num_iommus = 0; in omap_iommu_detach_fini()
1446 odomain->iommus = NULL; in omap_iommu_detach_fini()
1459 if (!arch_data || !arch_data->iommu_dev) { in omap_iommu_attach_dev()
1461 return -ENODEV; in omap_iommu_attach_dev()
1464 spin_lock(&omap_domain->lock); in omap_iommu_attach_dev()
1467 if (omap_domain->dev) { in omap_iommu_attach_dev()
1469 ret = -EINVAL; in omap_iommu_attach_dev()
1480 iommu = omap_domain->iommus; in omap_iommu_attach_dev()
1481 for (i = 0; i < omap_domain->num_iommus; i++, iommu++, arch_data++) { in omap_iommu_attach_dev()
1483 oiommu = arch_data->iommu_dev; in omap_iommu_attach_dev()
1484 ret = omap_iommu_attach(oiommu, iommu->pgtable); in omap_iommu_attach_dev()
1490 oiommu->domain = domain; in omap_iommu_attach_dev()
1491 iommu->iommu_dev = oiommu; in omap_iommu_attach_dev()
1494 omap_domain->dev = dev; in omap_iommu_attach_dev()
1499 while (i--) { in omap_iommu_attach_dev()
1500 iommu--; in omap_iommu_attach_dev()
1501 arch_data--; in omap_iommu_attach_dev()
1502 oiommu = iommu->iommu_dev; in omap_iommu_attach_dev()
1504 iommu->iommu_dev = NULL; in omap_iommu_attach_dev()
1505 oiommu->domain = NULL; in omap_iommu_attach_dev()
1510 spin_unlock(&omap_domain->lock); in omap_iommu_attach_dev()
1518 struct omap_iommu_device *iommu = omap_domain->iommus; in _omap_iommu_detach_dev()
1522 if (!omap_domain->dev) { in _omap_iommu_detach_dev()
1528 if (omap_domain->dev != dev) { in _omap_iommu_detach_dev()
1534 * cleanup in the reverse order of attachment - this addresses in _omap_iommu_detach_dev()
1537 iommu += (omap_domain->num_iommus - 1); in _omap_iommu_detach_dev()
1538 arch_data += (omap_domain->num_iommus - 1); in _omap_iommu_detach_dev()
1539 for (i = 0; i < omap_domain->num_iommus; i++, iommu--, arch_data--) { in _omap_iommu_detach_dev()
1540 oiommu = iommu->iommu_dev; in _omap_iommu_detach_dev()
1544 iommu->iommu_dev = NULL; in _omap_iommu_detach_dev()
1545 oiommu->domain = NULL; in _omap_iommu_detach_dev()
1550 omap_domain->dev = NULL; in _omap_iommu_detach_dev()
1563 spin_lock(&omap_domain->lock); in omap_iommu_identity_attach()
1565 spin_unlock(&omap_domain->lock); in omap_iommu_identity_attach()
1586 spin_lock_init(&omap_domain->lock); in omap_iommu_domain_alloc_paging()
1588 omap_domain->domain.geometry.aperture_start = 0; in omap_iommu_domain_alloc_paging()
1589 omap_domain->domain.geometry.aperture_end = (1ULL << 32) - 1; in omap_iommu_domain_alloc_paging()
1590 omap_domain->domain.geometry.force_aperture = true; in omap_iommu_domain_alloc_paging()
1592 return &omap_domain->domain; in omap_iommu_domain_alloc_paging()
1603 if (omap_domain->dev) in omap_iommu_domain_free()
1604 _omap_iommu_detach_dev(omap_domain, omap_domain->dev); in omap_iommu_domain_free()
1613 struct omap_iommu_device *iommu = omap_domain->iommus; in omap_iommu_iova_to_phys()
1614 struct omap_iommu *oiommu = iommu->iommu_dev; in omap_iommu_iova_to_phys()
1615 struct device *dev = oiommu->dev; in omap_iommu_iova_to_phys()
1655 * Allocate the per-device iommu structure for DT-based devices. in omap_iommu_probe_device()
1657 * TODO: Simplify this when removing non-DT support completely from the in omap_iommu_probe_device()
1660 if (!dev->of_node) in omap_iommu_probe_device()
1661 return ERR_PTR(-ENODEV); in omap_iommu_probe_device()
1665 * since #iommu-cells = 0 for OMAP in omap_iommu_probe_device()
1667 num_iommus = of_property_count_elems_of_size(dev->of_node, "iommus", in omap_iommu_probe_device()
1670 return ERR_PTR(-ENODEV); in omap_iommu_probe_device()
1674 return ERR_PTR(-ENOMEM); in omap_iommu_probe_device()
1677 np = of_parse_phandle(dev->of_node, "iommus", i); in omap_iommu_probe_device()
1680 return ERR_PTR(-EINVAL); in omap_iommu_probe_device()
1687 return ERR_PTR(-ENODEV); in omap_iommu_probe_device()
1694 return ERR_PTR(-EINVAL); in omap_iommu_probe_device()
1697 tmp->iommu_dev = oiommu; in omap_iommu_probe_device()
1698 tmp->dev = &pdev->dev; in omap_iommu_probe_device()
1710 oiommu = arch_data->iommu_dev; in omap_iommu_probe_device()
1712 return &oiommu->iommu; in omap_iommu_probe_device()
1719 if (!dev->of_node || !arch_data) in omap_iommu_release_device()
1759 return -ENOMEM; in omap_iommu_init()