static int msm_iommu_ctx_probe(struct platform_device *pdev) { struct msm_iommu_ctx_dev *c = pdev->dev.platform_data; struct msm_iommu_drvdata *drvdata; struct msm_iommu_ctx_drvdata *ctx_drvdata = NULL; int i, ret = 0; if (!c || !pdev->dev.parent) { ret = -EINVAL; goto fail; } drvdata = dev_get_drvdata(pdev->dev.parent); if (!drvdata) { ret = -ENODEV; goto fail; } ctx_drvdata = kzalloc(sizeof(*ctx_drvdata), GFP_KERNEL); if (!ctx_drvdata) { ret = -ENOMEM; goto fail; } ctx_drvdata->num = c->num; ctx_drvdata->pdev = pdev; INIT_LIST_HEAD(&ctx_drvdata->attached_elm); platform_set_drvdata(pdev, ctx_drvdata); /* Program the M2V tables for this context */ for (i = 0; i < MAX_NUM_MIDS; i++) { int mid = c->mids[i]; if (mid == -1) break; SET_M2VCBR_N(drvdata->base, mid, 0); SET_CBACR_N(drvdata->base, c->num, 0); /* Set VMID = MID */ SET_VMID(drvdata->base, mid, mid); /* Set the context number for that MID to this context */ SET_CBNDX(drvdata->base, mid, c->num); /* Set MID associated with this context bank */ SET_CBVMID(drvdata->base, c->num, mid); /* Set security bit override to be Non-secure */ SET_NSCFG(drvdata->base, mid, 3); } pr_info("context device %s with bank index %d\n", c->name, c->num); return 0; fail: kfree(ctx_drvdata); return ret; }
static int ctx_driver_probe(struct platform_device *pdev) { struct smmu_ctx *c = pdev->dev.platform_data; struct smmu_driver *drv = NULL; int i; if (!c) { pr_err("no platform data defined\n"); goto fail; } printk(KERN_INFO "Probing SMMU context %s with number %d\n", c->name, c->num); if (!pdev->dev.parent) { pr_err("context has no parent\n"); goto fail; } drv = dev_get_drvdata(pdev->dev.parent); if (!drv) { pr_err("context's parent has no drvdata\n"); goto fail; } printk(KERN_INFO "Programming M2V tables for context at %08x\n", (unsigned int) drv->base); for (i = 0; i < MAX_NUM_MIDS; i++) { int mid = c->mids[i]; if (mid == -1) break; SET_M2VCBR_N(drv->base, mid, 0); SET_CBACR_N(drv->base, c->num, 0); SET_VMID(drv->base, mid, mid); SET_CBNDX(drv->base, mid, c->num); SET_CBVMID(drv->base, c->num, mid); SET_NSCFG(drv->base, mid, 3); } return 0; fail: return -1; }
static int ctx_driver_probe(struct platform_device *pdev) { struct smmu_ctx *c = pdev->dev.platform_data; struct smmu_driver *drv = NULL; int i; if (!c) { pr_err("No platform data defined\n"); return -ENODEV; } printk(KERN_INFO "Probing SMMU context %s with number %d\n", c->name, c->num); if (!pdev->dev.parent) return -ENODEV; drv = dev_get_drvdata(pdev->dev.parent); if (!drv) return -ENODEV; printk(KERN_INFO "Programming M2V tables for context at %08x\n", (unsigned int) drv->base); /* Program the M2V tables for this context */ for (i = 0; i < MAX_NUM_MIDS; i++) { int mid = c->mids[i]; if (mid == -1) break; SET_M2VCBR_N(drv->base, mid, 0); SET_CBACR_N(drv->base, c->num, 0); /* Set VMID = MID */ SET_VMID(drv->base, mid, mid); /* Set the context number for that MID to this context */ SET_CBNDX(drv->base, mid, c->num); /* Set MID associated with this context bank */ SET_CBVMID(drv->base, c->num, mid); /* Set security bit override to be Non-secure */ SET_NSCFG(drv->base, mid, 3); } return 0; }
static int msm_iommu_ctx_probe(struct platform_device *pdev) { struct msm_iommu_ctx_dev *c = pdev->dev.platform_data; struct msm_iommu_drvdata *drvdata; struct msm_iommu_ctx_drvdata *ctx_drvdata = NULL; int i, ret, irq; if (!c || !pdev->dev.parent) { ret = -EINVAL; goto fail; } drvdata = dev_get_drvdata(pdev->dev.parent); if (!drvdata) { ret = -ENODEV; goto fail; } ctx_drvdata = kzalloc(sizeof(*ctx_drvdata), GFP_KERNEL); if (!ctx_drvdata) { ret = -ENOMEM; goto fail; } ctx_drvdata->num = c->num; ctx_drvdata->pdev = pdev; ctx_drvdata->name = c->name; irq = platform_get_irq_byname(to_platform_device(pdev->dev.parent), "nonsecure_irq"); if (irq < 0) { ret = -ENODEV; goto fail; } ret = request_threaded_irq(irq, NULL, msm_iommu_fault_handler, IRQF_ONESHOT | IRQF_SHARED, "msm_iommu_nonsecure_irq", ctx_drvdata); if (ret) { pr_err("request_threaded_irq %d failed: %d\n", irq, ret); goto fail; } INIT_LIST_HEAD(&ctx_drvdata->attached_elm); platform_set_drvdata(pdev, ctx_drvdata); ret = clk_prepare_enable(drvdata->pclk); if (ret) goto fail; if (drvdata->clk) { ret = clk_prepare_enable(drvdata->clk); if (ret) { clk_disable_unprepare(drvdata->pclk); goto fail; } } /* Program the M2V tables for this context */ for (i = 0; i < MAX_NUM_MIDS; i++) { int mid = c->mids[i]; if (mid == -1) break; SET_M2VCBR_N(drvdata->base, mid, 0); SET_CBACR_N(drvdata->base, c->num, 0); /* Route page faults to the non-secure interrupt */ SET_IRPTNDX(drvdata->base, c->num, 1); /* Set VMID = 0 */ SET_VMID(drvdata->base, mid, 0); /* Set the context number for that MID to this context */ SET_CBNDX(drvdata->base, mid, c->num); /* Set MID associated with this context bank to 0 */ SET_CBVMID(drvdata->base, c->num, 0); /* Set the ASID for TLB tagging for this context to 0 */ SET_CONTEXTIDR_ASID(drvdata->base, c->num, 0); /* Set security bit override to be Non-secure */ SET_NSCFG(drvdata->base, mid, 3); } mb(); if (drvdata->clk) clk_disable_unprepare(drvdata->clk); clk_disable_unprepare(drvdata->pclk); dev_info(&pdev->dev, "context %s using bank %d\n", c->name, c->num); return 0; fail: kfree(ctx_drvdata); return ret; }
static int msm_iommu_ctx_probe(struct platform_device *pdev) { struct msm_iommu_ctx_dev *c = pdev->dev.platform_data; struct msm_iommu_drvdata *drvdata; struct msm_iommu_ctx_drvdata *ctx_drvdata = NULL; int i, ret; if (!c || !pdev->dev.parent) { ret = -EINVAL; goto fail; } drvdata = dev_get_drvdata(pdev->dev.parent); if (!drvdata) { ret = -ENODEV; goto fail; } ctx_drvdata = kzalloc(sizeof(*ctx_drvdata), GFP_KERNEL); if (!ctx_drvdata) { ret = -ENOMEM; goto fail; } ctx_drvdata->num = c->num; ctx_drvdata->pdev = pdev; INIT_LIST_HEAD(&ctx_drvdata->attached_elm); platform_set_drvdata(pdev, ctx_drvdata); ret = clk_enable(drvdata->pclk); if (ret) goto fail; if (drvdata->clk) { ret = clk_enable(drvdata->clk); if (ret) { clk_disable(drvdata->pclk); goto fail; } } /* Program the M2V tables for this context */ for (i = 0; i < MAX_NUM_MIDS; i++) { int mid = c->mids[i]; if (mid == -1) break; SET_M2VCBR_N(drvdata->base, mid, 0); SET_CBACR_N(drvdata->base, c->num, 0); /* Set VMID = 0 */ SET_VMID(drvdata->base, mid, 0); /* Set the context number for that MID to this context */ SET_CBNDX(drvdata->base, mid, c->num); /* Set MID associated with this context bank to 0 */ SET_CBVMID(drvdata->base, c->num, 0); /* Set the ASID for TLB tagging for this context to 0 */ SET_CONTEXTIDR_ASID(drvdata->base, c->num, 0); /* Set security bit override to be Non-secure */ SET_NSCFG(drvdata->base, mid, 3); } mb(); if (drvdata->clk) clk_disable(drvdata->clk); clk_disable(drvdata->pclk); dev_info(&pdev->dev, "context %s using bank %d\n", c->name, c->num); return 0; fail: kfree(ctx_drvdata); return ret; }