From patchwork Fri Mar 25 15:13:25 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sakari Ailus X-Patchwork-Id: 6203 Return-path: Envelope-to: mchehab@pedra Delivery-date: Fri, 25 Mar 2011 12:13:58 -0300 Received: from mchehab by pedra with local (Exim 4.72) (envelope-from ) id 1Q38i5-0004Ic-Mq for mchehab@pedra; Fri, 25 Mar 2011 12:13:57 -0300 Received: from casper.infradead.org [85.118.1.10] by pedra with IMAP (fetchmail-6.3.17) for (single-drop); Fri, 25 Mar 2011 12:13:57 -0300 (BRT) Received: from vger.kernel.org ([209.132.180.67]) by casper.infradead.org with esmtp (Exim 4.72 #1 (Red Hat Linux)) id 1Q38hu-0006sN-WD; Fri, 25 Mar 2011 15:13:47 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751916Ab1CYPNp (ORCPT + 1 other); Fri, 25 Mar 2011 11:13:45 -0400 Received: from smtp.nokia.com ([147.243.128.26]:41987 "EHLO mgw-da02.nokia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750922Ab1CYPNo (ORCPT ); Fri, 25 Mar 2011 11:13:44 -0400 Received: from nokia.com (localhost [127.0.0.1]) by mgw-da02.nokia.com (Switch-3.4.3/Switch-3.4.3) with ESMTP id p2PFDehb019972; Fri, 25 Mar 2011 17:13:41 +0200 Received: from maxwell.research.nokia.com ([maxwell.research.nokia.com [172.21.50.162]]) by mgw-da02.nokia.com with ESMTP id p2PFDQpv019737 ; Fri, 25 Mar 2011 17:13:28 +0200 Received: from kaali.localdomain (kaali.localdomain [192.168.239.7]) by maxwell.research.nokia.com (Postfix) with ESMTPS id A72E03861EA; Fri, 25 Mar 2011 17:13:25 +0200 (EET) Received: from sailus by kaali.localdomain with local (Exim 4.72) (envelope-from ) id 1Q38hZ-00023z-Jc; Fri, 25 Mar 2011 17:13:25 +0200 From: Sakari Ailus To: linux-media@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, david.cohen@nokia.com, hiroshi.doyu@nokia.com Subject: [PATCH 4/4] omap iommu: Prevent iommu implementations from being unloaded while in use Date: Fri, 25 Mar 2011 17:13:25 +0200 Message-Id: <1301066005-7882-4-git-send-email-sakari.ailus@maxwell.research.nokia.com> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <4D8CB106.7030608@maxwell.research.nokia.com> References: <4D8CB106.7030608@maxwell.research.nokia.com> X-Nokia-AV: Clean Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Sender: Prevent module implementing arch_iommu from being unloaded while the arch_iommu is in use, essentially while the iommu has been acquired using iommu_get() by increasing module use count. This assumes that the arch_iommu has to be uninstalled at module unload time. Signed-off-by: Sakari Ailus --- arch/arm/plat-omap/iommu.c | 31 +++++++++++++++++++++++++++++-- 1 files changed, 29 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index f0fea0b..430ed94 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -35,6 +35,7 @@ static const struct iommu_functions *arch_iommu; static struct platform_driver omap_iommu_driver; static struct kmem_cache *iopte_cachep; +static struct mutex arch_iommu_mutex; /** * install_iommu_arch - Install archtecure specific iommu functions @@ -45,10 +46,17 @@ static struct kmem_cache *iopte_cachep; **/ int install_iommu_arch(const struct iommu_functions *ops) { - if (arch_iommu) + mutex_lock(&arch_iommu_mutex); + + if (arch_iommu) { + mutex_unlock(&arch_iommu_mutex); return -EBUSY; + } arch_iommu = ops; + + mutex_unlock(&arch_iommu_mutex); + return 0; } EXPORT_SYMBOL_GPL(install_iommu_arch); @@ -58,13 +66,22 @@ EXPORT_SYMBOL_GPL(install_iommu_arch); * @ops: a pointer to architecture specific iommu functions * * This interface uninstalls the iommu algorighm installed previously. + * + * Note: This function may only be called at module_exit() function of + * a module which implements arch_iommu. Otherwise another mechanism + * from the module use count only to ensure the arch_iommu stays there + * has to be implemented. **/ void uninstall_iommu_arch(const struct iommu_functions *ops) { + mutex_lock(&arch_iommu_mutex); + if (arch_iommu != ops) pr_err("%s: not your arch\n", __func__); arch_iommu = NULL; + + mutex_unlock(&arch_iommu_mutex); } EXPORT_SYMBOL_GPL(uninstall_iommu_arch); @@ -104,14 +121,20 @@ static int iommu_enable(struct iommu *obj) if (!obj) return -EINVAL; - if (!arch_iommu) + mutex_lock(&arch_iommu_mutex); + if (!arch_iommu || !try_module_get(arch_iommu->module)) { + mutex_unlock(&arch_iommu_mutex); return -ENOENT; + } clk_enable(obj->clk); err = arch_iommu->enable(obj); clk_disable(obj->clk); + + mutex_unlock(&arch_iommu_mutex); + return err; } @@ -125,6 +148,8 @@ static void iommu_disable(struct iommu *obj) arch_iommu->disable(obj); clk_disable(obj->clk); + + module_put(arch_iommu->module); } /* @@ -1058,6 +1083,8 @@ static int __init omap_iommu_init(void) return -ENOMEM; iopte_cachep = p; + mutex_init(&arch_iommu_mutex); + return platform_driver_register(&omap_iommu_driver); } module_init(omap_iommu_init);