[PATCH v4 4/4] OMAP3/4: iommu: adapt to runtime pm

Felipe Contreras felipe.contreras at gmail.com
Thu Dec 15 19:33:08 EST 2011


On Thu, Dec 15, 2011 at 6:18 AM, Omar Ramirez Luna <omar.ramirez at ti.com> wrote:
> @@ -123,11 +123,10 @@ static int iommu_enable(struct omap_iommu *obj)
>        if (!arch_iommu)
>                return -ENODEV;
>
> -       clk_enable(obj->clk);
> +       pm_runtime_get_sync(obj->dev);
>
>        err = arch_iommu->enable(obj);
>
> -       clk_disable(obj->clk);
>        return err;
>  }

Hmm, this is called on omap_iommu_attach, and iommu_disable is not
called until omap_iommu_detach, so this means the device will never
sleep. Why don't you call pm_runtime_put() instead of clk_disable()?

All the rest of the calls to pm_runtime_get/put after this are
basically no-ops, because the count will never go below 1.

You mention some irq issues, but could it be due to some bad clocks in
the hwmod data?

> @@ -136,11 +135,9 @@ static void iommu_disable(struct omap_iommu *obj)
>        if (!obj)
>                return;
>
> -       clk_enable(obj->clk);
> -
>        arch_iommu->disable(obj);
>
> -       clk_disable(obj->clk);
> +       pm_runtime_put(obj->dev);
>  }
>
>  /*
> @@ -263,7 +260,7 @@ static int load_iotlb_entry(struct omap_iommu *obj, struct iotlb_entry *e)
>        if (!obj || !obj->nr_tlb_entries || !e)
>                return -EINVAL;
>
> -       clk_enable(obj->clk);
> +       pm_runtime_get_sync(obj->dev);
>
>        iotlb_lock_get(obj, &l);
>        if (l.base == obj->nr_tlb_entries) {
> @@ -293,7 +290,7 @@ static int load_iotlb_entry(struct omap_iommu *obj, struct iotlb_entry *e)
>
>        cr = iotlb_alloc_cr(obj, e);
>        if (IS_ERR(cr)) {
> -               clk_disable(obj->clk);
> +               pm_runtime_put(obj->dev);
>                return PTR_ERR(cr);
>        }
>
> @@ -307,7 +304,7 @@ static int load_iotlb_entry(struct omap_iommu *obj, struct iotlb_entry *e)
>                l.vict = l.base;
>        iotlb_lock_set(obj, &l);
>  out:
> -       clk_disable(obj->clk);
> +       pm_runtime_put(obj->dev);
>        return err;
>  }
>
> @@ -337,7 +334,7 @@ static void flush_iotlb_page(struct omap_iommu *obj, u32 da)
>        int i;
>        struct cr_regs cr;
>
> -       clk_enable(obj->clk);
> +       pm_runtime_get_sync(obj->dev);
>
>        for_each_iotlb_cr(obj, obj->nr_tlb_entries, i, cr) {
>                u32 start;
> @@ -356,7 +353,7 @@ static void flush_iotlb_page(struct omap_iommu *obj, u32 da)
>                        iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY);
>                }
>        }
> -       clk_disable(obj->clk);
> +       pm_runtime_put(obj->dev);
>
>        if (i == obj->nr_tlb_entries)
>                dev_dbg(obj->dev, "%s: no page for %08x\n", __func__, da);
> @@ -370,7 +367,7 @@ static void flush_iotlb_all(struct omap_iommu *obj)
>  {
>        struct iotlb_lock l;
>
> -       clk_enable(obj->clk);
> +       pm_runtime_get_sync(obj->dev);
>
>        l.base = 0;
>        l.vict = 0;
> @@ -378,7 +375,7 @@ static void flush_iotlb_all(struct omap_iommu *obj)
>
>        iommu_write_reg(obj, 1, MMU_GFLUSH);
>
> -       clk_disable(obj->clk);
> +       pm_runtime_put(obj->dev);
>  }
>
>  #if defined(CONFIG_OMAP_IOMMU_DEBUG) || defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE)
> @@ -388,11 +385,11 @@ ssize_t omap_iommu_dump_ctx(struct omap_iommu *obj, char *buf, ssize_t bytes)
>        if (!obj || !buf)
>                return -EINVAL;
>
> -       clk_enable(obj->clk);
> +       pm_runtime_get_sync(obj->dev);
>
>        bytes = arch_iommu->dump_ctx(obj, buf, bytes);
>
> -       clk_disable(obj->clk);
> +       pm_runtime_put(obj->dev);
>
>        return bytes;
>  }
> @@ -406,7 +403,7 @@ __dump_tlb_entries(struct omap_iommu *obj, struct cr_regs *crs, int num)
>        struct cr_regs tmp;
>        struct cr_regs *p = crs;
>
> -       clk_enable(obj->clk);
> +       pm_runtime_get_sync(obj->dev);
>        iotlb_lock_get(obj, &saved);
>
>        for_each_iotlb_cr(obj, num, i, tmp) {
> @@ -416,7 +413,7 @@ __dump_tlb_entries(struct omap_iommu *obj, struct cr_regs *crs, int num)
>        }
>
>        iotlb_lock_set(obj, &saved);
> -       clk_disable(obj->clk);
> +       pm_runtime_put(obj->dev);
>
>        return  p - crs;
>  }
> @@ -780,9 +777,7 @@ static irqreturn_t iommu_fault_handler(int irq, void *data)
>        if (!obj->refcount)
>                return IRQ_NONE;
>
> -       clk_enable(obj->clk);
>        errs = iommu_report_fault(obj, &da);
> -       clk_disable(obj->clk);

Why?

>        if (errs == 0)
>                return IRQ_HANDLED;
>
> @@ -920,10 +915,6 @@ static int __devinit omap_iommu_probe(struct platform_device *pdev)
>        if (!obj)
>                return -ENOMEM;
>
> -       obj->clk = clk_get(&pdev->dev, pdata->clk_name);
> -       if (IS_ERR(obj->clk))
> -               goto err_clk;
> -
>        obj->nr_tlb_entries = pdata->nr_tlb_entries;
>        obj->name = pdata->name;
>        obj->dev = &pdev->dev;
> @@ -966,6 +957,8 @@ static int __devinit omap_iommu_probe(struct platform_device *pdev)
>                goto err_irq;
>        platform_set_drvdata(pdev, obj);
>
> +       pm_runtime_enable(obj->dev);
> +
>        dev_info(&pdev->dev, "%s registered\n", obj->name);
>        return 0;
>
> @@ -974,8 +967,6 @@ err_irq:
>  err_ioremap:
>        release_mem_region(res->start, resource_size(res));
>  err_mem:
> -       clk_put(obj->clk);
> -err_clk:
>        kfree(obj);
>        return err;
>  }
> @@ -996,7 +987,8 @@ static int __devexit omap_iommu_remove(struct platform_device *pdev)
>        release_mem_region(res->start, resource_size(res));
>        iounmap(obj->regbase);
>
> -       clk_put(obj->clk);
> +       pm_runtime_disable(obj->dev);

I'm not sure if this is needed; you want to resume the driver? AFAICS
kfree will take care of that _without_ resuming.

>        dev_info(&pdev->dev, "%s removed\n", obj->name);
>        kfree(obj);
>        return 0;

Cheers.

-- 
Felipe Contreras



More information about the linux-arm-kernel mailing list