From patchwork Thu Jan 11 08:22:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeffy Chen X-Patchwork-Id: 10157589 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DC0F0602B3 for ; Thu, 11 Jan 2018 08:40:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C679428517 for ; Thu, 11 Jan 2018 08:40:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B721428526; Thu, 11 Jan 2018 08:40:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1085A28517 for ; Thu, 11 Jan 2018 08:40:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=98EW/HoRqy3WbcnRVZzmX8uMTlj8Umw7tM/An/Vifvg=; b=aBbFYd175l7M4qv2qUBp2L2Q2n KGKWUyBOkMO82A7fi/MwHcVHkEDmpaHYQy7KEEWv5kT51sBQwIk8nBwVio96OJ2/uOZ1ZkhKJGTmf 7JUFRv0BYnDqwvng5l8IuBlqJAJk2/AtU3ayEii3JWL8+svQCBjIabFmrXzb3aEnK07jDJj79zAEG 76QKDSUIkuBfiRQZEmH9xjKGjWr6VSj7WikFywuZ/2yEYfgGl1l1tevANCte78mgQpJ5ZJQcRFdYi aA7H4PJoouEHP2rG0MlmGtGl/0goI1z5re/zYvfy2auiYQLKV7hsxlGDcmpGrUDSi8Tot0cwdn62Q jo6tjLEA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1eZYPa-0002t0-7W; Thu, 11 Jan 2018 08:40:34 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1eZYPK-00019q-6G; Thu, 11 Jan 2018 08:40:18 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=fVVHFhxqhoDQZzsz1fWUbSEAFQ3da5JJqnj7MLeL4EY=; b=Hp5vmaXXVW0THZhJUGyRGYF5q MZ9hFZPHFxDArP0IWpb6XP4gC48K1jntcJENGkc/gLBjBH2jczRcRzsnUSt5CBYoBDOWSpWZQPYML FB1hcFxntMqRE3pIoWjq9QKkMJHWeuxPmR54DWp4qLlatA6CmYQQh7BxZQXB0Y7hDYU2INmN8++Ui duukOiHfbYPuvhlM98Fa9kBoKgdmToGoMol/QxSSLPtsKyFO/LUPsHxcxf3gRrphcVx8ZLyMT6+kR G4P3o40zz//xBL2R+6HDHoiuYHZIovgjuiaNETfdHHoEnD/pY09lpv7o8IuEcMA9xOABxmi9pG3jQ uA/rPY8YA==; Received: from regular1.263xmail.com ([211.150.99.132]) by casper.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1eZYAP-000308-0O; Thu, 11 Jan 2018 08:24:56 +0000 Received: from jeffy.chen?rock-chips.com (unknown [192.168.167.201]) by regular1.263xmail.com (Postfix) with ESMTP id 2AC3795B5; Thu, 11 Jan 2018 16:24:25 +0800 (CST) X-263anti-spam: KSV:0; X-MAIL-GRAY: 0 X-MAIL-DELIVERY: 1 X-KSVirus-check: 0 X-ABS-CHECKED: 4 Received: from localhost (localhost [127.0.0.1]) by smtp.263.net (Postfix) with ESMTPA id 688363C1; Thu, 11 Jan 2018 16:24:21 +0800 (CST) X-RL-SENDER: jeffy.chen@rock-chips.com X-FST-TO: linux-kernel@vger.kernel.org X-SENDER-IP: 103.29.142.67 X-LOGIN-NAME: jeffy.chen@rock-chips.com X-UNIQUE-TAG: <5a0d3881335d0c8833aecf38203527df> X-ATTACHMENT-NUM: 0 X-SENDER: cjf@rock-chips.com X-DNS-TYPE: 0 Received: from localhost (unknown [103.29.142.67]) by smtp.263.net (Postfix) whith ESMTP id 25039BSAO3X; Thu, 11 Jan 2018 16:24:25 +0800 (CST) From: Jeffy Chen To: linux-kernel@vger.kernel.org Subject: [PATCH 8/9] iommu/rockchip: Use IOMMU device for dma mapping operations Date: Thu, 11 Jan 2018 16:22:28 +0800 Message-Id: <20180111082229.24011-9-jeffy.chen@rock-chips.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180111082229.24011-1-jeffy.chen@rock-chips.com> References: <20180111082229.24011-1-jeffy.chen@rock-chips.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180111_082454_466088_F64CC105 X-CRM114-Status: GOOD ( 20.32 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Heiko Stuebner , Joerg Roedel , Jeffy Chen , tfiga@chromium.org, jcliang@chromium.org, linux-rockchip@lists.infradead.org, iommu@lists.linux-foundation.org, robin.murphy@arm.com, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Use the first registered IOMMU device for dma mapping operations, and drop the domain platform device. This is similar to exynos iommu driver. Signed-off-by: Jeffy Chen --- drivers/iommu/rockchip-iommu.c | 96 ++++++++++++------------------------------ 1 file changed, 28 insertions(+), 68 deletions(-) diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index 86f8190d7bed..ab18a80fdd12 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -76,7 +76,6 @@ struct rk_iommu_domain { struct list_head iommus; - struct platform_device *pdev; u32 *dt; /* page directory table */ dma_addr_t dt_dma; spinlock_t iommus_lock; /* lock for iommus list */ @@ -97,12 +96,14 @@ struct rk_iommu { struct iommu_domain *domain; /* domain to which iommu is attached */ }; +static struct device *dma_dev; + static inline void rk_table_flush(struct rk_iommu_domain *dom, dma_addr_t dma, unsigned int count) { size_t size = count * sizeof(u32); /* count of u32 entry */ - dma_sync_single_for_device(&dom->pdev->dev, dma, size, DMA_TO_DEVICE); + dma_sync_single_for_device(dma_dev, dma, size, DMA_TO_DEVICE); } static struct rk_iommu_domain *to_rk_domain(struct iommu_domain *dom) @@ -606,7 +607,6 @@ static void rk_iommu_zap_iova_first_last(struct rk_iommu_domain *rk_domain, static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain, dma_addr_t iova) { - struct device *dev = &rk_domain->pdev->dev; u32 *page_table, *dte_addr; u32 dte_index, dte; phys_addr_t pt_phys; @@ -624,9 +624,9 @@ static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain, if (!page_table) return ERR_PTR(-ENOMEM); - pt_dma = dma_map_single(dev, page_table, SPAGE_SIZE, DMA_TO_DEVICE); - if (dma_mapping_error(dev, pt_dma)) { - dev_err(dev, "DMA mapping error while allocating page table\n"); + pt_dma = dma_map_single(dma_dev, page_table, SPAGE_SIZE, DMA_TO_DEVICE); + if (dma_mapping_error(dma_dev, pt_dma)) { + dev_err(dma_dev, "DMA mapping error while allocating page table\n"); free_page((unsigned long)page_table); return ERR_PTR(-ENOMEM); } @@ -905,29 +905,20 @@ static int rk_iommu_attach_device(struct iommu_domain *domain, static struct iommu_domain *rk_iommu_domain_alloc(unsigned type) { struct rk_iommu_domain *rk_domain; - struct platform_device *pdev; - struct device *iommu_dev; if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA) return NULL; - /* Register a pdev per domain, so DMA API can base on this *dev - * even some virtual master doesn't have an iommu slave - */ - pdev = platform_device_register_simple("rk_iommu_domain", - PLATFORM_DEVID_AUTO, NULL, 0); - if (IS_ERR(pdev)) + if (!dma_dev) return NULL; - rk_domain = devm_kzalloc(&pdev->dev, sizeof(*rk_domain), GFP_KERNEL); + rk_domain = devm_kzalloc(dma_dev, sizeof(*rk_domain), GFP_KERNEL); if (!rk_domain) - goto err_unreg_pdev; - - rk_domain->pdev = pdev; + return NULL; if (type == IOMMU_DOMAIN_DMA && iommu_get_dma_cookie(&rk_domain->domain)) - goto err_unreg_pdev; + return NULL; /* * rk32xx iommus use a 2 level pagetable. @@ -938,11 +929,10 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type) if (!rk_domain->dt) goto err_put_cookie; - iommu_dev = &pdev->dev; - rk_domain->dt_dma = dma_map_single(iommu_dev, rk_domain->dt, + rk_domain->dt_dma = dma_map_single(dma_dev, rk_domain->dt, SPAGE_SIZE, DMA_TO_DEVICE); - if (dma_mapping_error(iommu_dev, rk_domain->dt_dma)) { - dev_err(iommu_dev, "DMA map error for DT\n"); + if (dma_mapping_error(dma_dev, rk_domain->dt_dma)) { + dev_err(dma_dev, "DMA map error for DT\n"); goto err_free_dt; } @@ -963,8 +953,6 @@ static struct iommu_domain *rk_iommu_domain_alloc(unsigned type) err_put_cookie: if (type == IOMMU_DOMAIN_DMA) iommu_put_dma_cookie(&rk_domain->domain); -err_unreg_pdev: - platform_device_unregister(pdev); return NULL; } @@ -981,20 +969,18 @@ static void rk_iommu_domain_free(struct iommu_domain *domain) if (rk_dte_is_pt_valid(dte)) { phys_addr_t pt_phys = rk_dte_pt_address(dte); u32 *page_table = phys_to_virt(pt_phys); - dma_unmap_single(&rk_domain->pdev->dev, pt_phys, + dma_unmap_single(dma_dev, pt_phys, SPAGE_SIZE, DMA_TO_DEVICE); free_page((unsigned long)page_table); } } - dma_unmap_single(&rk_domain->pdev->dev, rk_domain->dt_dma, + dma_unmap_single(dma_dev, rk_domain->dt_dma, SPAGE_SIZE, DMA_TO_DEVICE); free_page((unsigned long)rk_domain->dt); if (domain->type == IOMMU_DOMAIN_DMA) iommu_put_dma_cookie(&rk_domain->domain); - - platform_device_unregister(rk_domain->pdev); } static bool rk_iommu_is_dev_iommu_master(struct device *dev) @@ -1120,30 +1106,6 @@ static const struct iommu_ops rk_iommu_ops = { .pgsize_bitmap = RK_IOMMU_PGSIZE_BITMAP, }; -static int rk_iommu_domain_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - - dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), GFP_KERNEL); - if (!dev->dma_parms) - return -ENOMEM; - - /* Set dma_ops for dev, otherwise it would be dummy_dma_ops */ - arch_setup_dma_ops(dev, 0, DMA_BIT_MASK(32), NULL, false); - - dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); - dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); - - return 0; -} - -static struct platform_driver rk_iommu_domain_driver = { - .probe = rk_iommu_domain_probe, - .driver = { - .name = "rk_iommu_domain", - }, -}; - static int rk_iommu_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -1210,6 +1172,14 @@ static int rk_iommu_probe(struct platform_device *pdev) return err; } + /* + * Use the first registered IOMMU device for domain to use with DMA + * API, since a domain might not physically correspond to a single + * IOMMU device.. + */ + if (!dma_dev) + dma_dev = &pdev->dev; + return 0; } @@ -1251,31 +1221,21 @@ static int __init rk_iommu_init(void) of_node_put(np); - ret = platform_driver_register(&rk_iommu_domain_driver); - if (ret) - return ret; - ret = platform_driver_register(&rk_iommu_driver); if (ret) - goto err_unreg_domain_drv; + return ret; ret = bus_set_iommu(&platform_bus_type, &rk_iommu_ops); - if (ret) - goto err_unreg_iommu_drv; + if (ret) { + platform_driver_unregister(&rk_iommu_driver); + return ret; + } return 0; - -err_unreg_iommu_drv: - platform_driver_unregister(&rk_iommu_driver); -err_unreg_domain_drv: - platform_driver_unregister(&rk_iommu_domain_driver); - - return ret; } static void __exit rk_iommu_exit(void) { platform_driver_unregister(&rk_iommu_driver); - platform_driver_unregister(&rk_iommu_domain_driver); } subsys_initcall(rk_iommu_init);