This repository has been archived on 2025-07-24. You can view files and clone it, but cannot push or open issues or pull requests.
sst-linux/arch/arm/mach-omap2/omap-iommu.c
Omar Ramirez Luna ebf7cda0f9 iommu/omap: Adapt to runtime pm
Use runtime PM functionality interfaced with hwmod enable/idle
functions, to replace direct clock operations and sysconfig
handling.

Due to reset sequence, pm_runtime_[get|put]_sync must be used, to
avoid possible operations with the module under reset. Because of
this and given that the driver uses spin_locks to protect their
critical sections, we must use pm_runtime_irq_safe in order for the
runtime ops to be happy, otherwise might_sleep_if checks in runtime
framework will complain.

The remaining pm_runtime out of iommu_enable and iommu_disable
corresponds to paths that can be accessed through debugfs, some of
them doesn't work if the module is not enabled first, but in future
if the mmu is idled withouth freeing, these are needed to debug.

Signed-off-by: Omar Ramirez Luna <omar.luna@linaro.org>
Tested-by: Ohad Ben-Cohen <ohad@wizery.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Joerg Roedel <joro@8bytes.org>
2012-12-03 18:48:23 +01:00

75 lines
1.8 KiB
C

/*
* omap iommu: omap device registration
*
* Copyright (C) 2008-2009 Nokia Corporation
*
* Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/platform_data/iommu-omap.h>
#include <plat/omap_hwmod.h>
#include <plat/omap_device.h>
static int __init omap_iommu_dev_init(struct omap_hwmod *oh, void *unused)
{
struct platform_device *pdev;
struct iommu_platform_data *pdata;
struct omap_mmu_dev_attr *a = (struct omap_mmu_dev_attr *)oh->dev_attr;
static int i;
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
pdata->name = oh->name;
pdata->nr_tlb_entries = a->nr_tlb_entries;
pdata->da_start = a->da_start;
pdata->da_end = a->da_end;
if (oh->rst_lines_cnt == 1) {
pdata->reset_name = oh->rst_lines->name;
pdata->assert_reset = omap_device_assert_hardreset;
pdata->deassert_reset = omap_device_deassert_hardreset;
}
pdev = omap_device_build("omap-iommu", i, oh, pdata, sizeof(*pdata),
NULL, 0, 0);
kfree(pdata);
if (IS_ERR(pdev)) {
pr_err("%s: device build err: %ld\n", __func__, PTR_ERR(pdev));
return PTR_ERR(pdev);
}
i++;
return 0;
}
static int __init omap_iommu_init(void)
{
return omap_hwmod_for_each_by_class("mmu", omap_iommu_dev_init, NULL);
}
/* must be ready before omap3isp is probed */
subsys_initcall(omap_iommu_init);
static void __exit omap_iommu_exit(void)
{
/* Do nothing */
}
module_exit(omap_iommu_exit);
MODULE_AUTHOR("Hiroshi DOYU");
MODULE_DESCRIPTION("omap iommu: omap device registration");
MODULE_LICENSE("GPL v2");