int smmu_driver_probe(struct platform_device *pdev) { static void __iomem *regs_base; struct resource *r; struct smmu_device *smmu_dev = pdev->dev.platform_data; struct clk *smmu_clk = NULL; int irq = 0; int ret; int ncb, nm2v; struct smmu_driver *drv = NULL; resource_size_t len; if (pdev->id != -1) { if (!smmu_dev) { pr_err("smmu device lacks platform data\n"); goto fail_nodev; } if (smmu_dev->clk) { smmu_clk = clk_get(NULL, smmu_dev->clk); if (!smmu_clk) { pr_err("clock defined but not present\n"); goto fail_nodev; } if (smmu_dev->clk_rate != 0) clk_set_rate(smmu_clk, smmu_dev->clk_rate); clk_enable(smmu_clk); clk_put(smmu_clk); } drv = kzalloc(sizeof(struct smmu_driver), GFP_KERNEL); if (!drv) { pr_err("could not allocate memory\n"); goto fail_nomem; } r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "physbase"); if (!r) { pr_err("could not get resources\n"); goto fail_nodev; } len = r->end - r->start + 1; r = request_mem_region(r->start, len, r->name); if (!r) { pr_err("could not request memory region: " "start=%p, len=%d\n", (void *) r->start, len); goto fail_busy; } regs_base = ioremap(r->start, len); if (!regs_base) { pr_err("could not ioremap: start=%p, len=%d\n", (void *) r->start, len); goto fail_busy; } irq = platform_get_irq_byname(pdev, "secure_irq"); if (irq < 0) { pr_err("could not retrieve irq\n"); goto fail_nodev; } mb(); if (GET_IDR((unsigned long) regs_base) == 0) { pr_err("IDR reads as 0\n"); goto fail_nodev; } ret = smmu_drvdata_init(drv, (unsigned long) regs_base, irq); if (ret != 0) { pr_err("could not init drvdata: error %d\n", ret); goto fail_nodev; } nm2v = GET_NM2VCBMT((unsigned long) regs_base); ncb = GET_NCB((unsigned long) regs_base); printk(KERN_INFO "Registered driver for %s at %lx, " "irq %d (%d cb, %d m2v) \n", pdev->name, (unsigned long) regs_base, irq, ncb+1, nm2v+1); platform_set_drvdata(pdev, drv); } else { printk(KERN_INFO "Registered SMMU root device.\n"); ret = vcm_setup_tex_classes(); if (ret != 0) { pr_err("vcm_setup_tex_classes: returned %d\n", ret); goto fail_nodev; } all_smmus = pdev; } return 0; fail_busy: kfree(drv); return -EBUSY; fail_nodev: kfree(drv); return -ENODEV; fail_nomem: return -ENOMEM; }
static int msm_iommu_probe(struct platform_device *pdev) { struct resource *r; struct clk *iommu_clk; struct msm_iommu_drvdata *drvdata; struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data; void __iomem *regs_base; resource_size_t len; int ret = 0, ncb, nm2v, irq; if (pdev->id != -1) { drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); if (!drvdata) { ret = -ENOMEM; goto fail; } if (!iommu_dev) { ret = -ENODEV; goto fail; } if (iommu_dev->clk_rate != 0) { iommu_clk = clk_get(&pdev->dev, "iommu_clk"); if (IS_ERR(iommu_clk)) { ret = -ENODEV; goto fail; } if (iommu_dev->clk_rate > 0) { ret = clk_set_rate(iommu_clk, iommu_dev->clk_rate); if (ret) { clk_put(iommu_clk); goto fail; } } ret = clk_enable(iommu_clk); if (ret) { clk_put(iommu_clk); goto fail; } clk_put(iommu_clk); } r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "physbase"); if (!r) { ret = -ENODEV; goto fail; } len = r->end - r->start + 1; r = request_mem_region(r->start, len, r->name); if (!r) { pr_err("Could not request memory region: " "start=%p, len=%d\n", (void *) r->start, len); ret = -EBUSY; goto fail; } regs_base = ioremap(r->start, len); if (!regs_base) { pr_err("Could not ioremap: start=%p, len=%d\n", (void *) r->start, len); ret = -EBUSY; goto fail; } irq = platform_get_irq_byname(pdev, "secure_irq"); if (irq < 0) { ret = -ENODEV; goto fail; } mb(); if (GET_IDR(regs_base) == 0) { pr_err("Invalid IDR value detected\n"); ret = -ENODEV; goto fail; } ret = request_irq(irq, msm_iommu_fault_handler, 0, "msm_iommu_secure_irpt_handler", drvdata); if (ret) { pr_err("Request IRQ %d failed with ret=%d\n", irq, ret); goto fail; } msm_iommu_reset(regs_base); drvdata->base = regs_base; drvdata->irq = irq; nm2v = GET_NM2VCBMT((unsigned long) regs_base); ncb = GET_NCB((unsigned long) regs_base); pr_info("device %s mapped at %p, irq %d with %d ctx banks\n", iommu_dev->name, regs_base, irq, ncb+1); platform_set_drvdata(pdev, drvdata); } else msm_iommu_root_dev = pdev; return 0; fail: kfree(drvdata); return ret; }