From patchwork Tue Aug 5 10:47:52 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 4677401 Return-Path: X-Original-To: patchwork-linux-samsung-soc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 8DA1CC0338 for ; Tue, 5 Aug 2014 10:51:03 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B7E2F20160 for ; Tue, 5 Aug 2014 10:51:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D262420166 for ; Tue, 5 Aug 2014 10:51:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755628AbaHEKu7 (ORCPT ); Tue, 5 Aug 2014 06:50:59 -0400 Received: from mailout4.w1.samsung.com ([210.118.77.14]:52908 "EHLO mailout4.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755077AbaHEKtL (ORCPT ); Tue, 5 Aug 2014 06:49:11 -0400 Received: from eucpsbgm2.samsung.com (unknown [203.254.199.245]) by mailout4.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0N9T00DA4Y1NLQ00@mailout4.w1.samsung.com>; Tue, 05 Aug 2014 11:49:00 +0100 (BST) X-AuditID: cbfec7f5-b7f776d000003e54-ba-53e0b6a57051 Received: from eusync3.samsung.com ( [203.254.199.213]) by eucpsbgm2.samsung.com (EUCPMTA) with SMTP id 72.EC.15956.5A6B0E35; Tue, 05 Aug 2014 11:49:09 +0100 (BST) Received: from amdc1339.digital.local ([106.116.147.30]) by eusync3.samsung.com (Oracle Communications Messaging Server 7u4-23.01 (7.0.4.23.0) 64bit (built Aug 10 2011)) with ESMTPA id <0N9T0057MY17SE80@eusync3.samsung.com>; Tue, 05 Aug 2014 11:49:09 +0100 (BST) From: Marek Szyprowski To: iommu@lists.linux-foundation.org, linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: Marek Szyprowski , linaro-mm-sig@lists.linaro.org, Arnd Bergmann , Shaik Ameer Basha , Cho KyongHo , Joerg Roedel , Thierry Reding , Olof Johansson , Laurent Pinchart , Rob Herring , Greg Kroah-Hartman , "Rafael J. Wysocki" , Inki Dae , Kukjin Kim , Sylwester Nawrocki , Tomasz Figa , Kyungmin Park Subject: [PATCH 24/29] iommu: exynos: create default iommu-based dma-mapping for master devices Date: Tue, 05 Aug 2014 12:47:52 +0200 Message-id: <1407235677-26324-25-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.2 In-reply-to: <1407235677-26324-1-git-send-email-m.szyprowski@samsung.com> References: <1407235677-26324-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrBLMWRmVeSWpSXmKPExsVy+t/xq7pLtz0INvhx1Mji76Rj7BbNi9ez WUy6P4HFYsF+a4vO2RvYLXoXXGWzONv0ht2ic+ISdosvVx4yWWx6fI3V4vKuOWwWM87vY7JY e+Quu8Wp65/ZLP71HmS0OHP6EqvF/z072C0Ov2lntTjycDe7xapdfxgtbv/mcxD1eHJwHpPH 71+TGD12zrrL7jG7Yyarx6ZVnWwe++euYffYvKTe4/a/x8wek28sZ/S4cqKJ1aO3+R2bx5ar 7SwefVtWMXp83iQXwBfFZZOSmpNZllqkb5fAlXH49w3GgvOiFb/2dDA2MP4S7GLk5JAQMJFY dnAXM4QtJnHh3nq2LkYuDiGBpYwSr4/tYoJw+pgkWibvZQWpYhMwlOh62wVWJSLQyyjR3/QD rIpZYB2rxP7e6ywgVcICiRIbJrYygtgsAqoSP3ZuYQOxeQU8Jd53P2OC2Ccn8f/lCjCbEyh+ +OYBsA1CAh4SPzesYZ/AyLuAkWEVo2hqaXJBcVJ6rpFecWJucWleul5yfu4mRkjsfN3BuPSY 1SFGAQ5GJR5ehb13g4VYE8uKK3MPMUpwMCuJ8EqseRAsxJuSWFmVWpQfX1Sak1p8iJGJg1Oq gVH26gGumhvi1Zs3lq/9dv7dW82aGdsn5O6MeebW9su6s+lTZOn6pp/Prm24dr9cx4NVum3Z ZLGHuRtt/U5OXux34Nmb2QEHHLb4Wj7ZfHC5DldvnoMOq1HRLCaJcxlf5WJvbeSoDgnf+k2S nVfBwVfk4tQ47h97gjT2LVgWzzR19sM+phnviz4psRRnJBpqMRcVJwIAZXTVTHsCAAA= Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds code to create default per-device iommu-based dma-mapping instance for all master devices, whose driver didn't set DRIVER_HAS_OWN_IOMMU_MANAGER flag. Signed-off-by: Marek Szyprowski --- drivers/iommu/exynos-iommu.c | 49 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 845f547..336b2f8 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -12,6 +12,7 @@ #define DEBUG #endif +#include #include #include #include @@ -29,6 +30,7 @@ #include #include +#include #include typedef u32 sysmmu_iova_t; @@ -1064,6 +1066,43 @@ static phys_addr_t exynos_iommu_iova_to_phys(struct iommu_domain *domain, return phys; } +static int sysmmu_master_device_event(struct notifier_block *nb, + unsigned long val, void *p) +{ + struct device *dev = p; + struct exynos_iommu_owner *owner = dev->archdata.iommu; + struct sysmmu_drvdata *data; + + if (!owner) + return 0; + + data = list_first_entry(&owner->clients, struct sysmmu_drvdata, + owner_node); + if (!data) + return 0; + + switch (val) { + + case IOMMU_GROUP_NOTIFY_BIND_DRIVER: + if (!(dev->driver->flags & DRIVER_HAS_OWN_IOMMU_MANAGER)) + arm_iommu_create_default_mapping(dev, data->base, + data->size); + break; + + case IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER: + case IOMMU_GROUP_NOTIFY_DRVBIND_FAILED: + if (!(dev->driver->flags & DRIVER_HAS_OWN_IOMMU_MANAGER)) + arm_iommu_release_default_mapping(dev); + break; + } + + return 0; +} + +static struct notifier_block sysmmu_master_device_notifier = { + .notifier_call = sysmmu_master_device_event, +}; + static void __free_owner_struct(struct exynos_iommu_owner *owner, struct device *dev) { @@ -1202,6 +1241,7 @@ static int exynos_iommu_add_device(struct device *dev) if (ret != 0) goto err; + iommu_group_register_notifier(group, &sysmmu_master_device_notifier); iommu_group_put(group); return 0; @@ -1213,8 +1253,15 @@ err: static void exynos_iommu_remove_device(struct device *dev) { struct exynos_iommu_owner *owner = dev->archdata.iommu; + struct iommu_group *group = iommu_group_get(dev); + + if (group) { + iommu_group_unregister_notifier(group, + &sysmmu_master_device_notifier); + iommu_group_remove_device(dev); + iommu_group_put(group); + } - iommu_group_remove_device(dev); if (owner) __free_owner_struct(owner, dev); }