From patchwork Thu Jan 13 09:05:35 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kristoffer Glembo X-Patchwork-Id: 78700 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 17DA7B70E7 for ; Thu, 13 Jan 2011 20:06:20 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932891Ab1AMJGS (ORCPT ); Thu, 13 Jan 2011 04:06:18 -0500 Received: from mail201c2.megamailservers.com ([69.49.111.102]:43734 "EHLO mail201c2.megamailservers.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932895Ab1AMJGN (ORCPT ); Thu, 13 Jan 2011 04:06:13 -0500 X-Authenticated-User: kristoffer.gaisler.com Received: from localhost.localdomain (static-92-33-28-242.sme.bredbandsbolaget.se [92.33.28.242]) (authenticated bits=0) by mail201c2.megamailservers.com (8.13.6/8.13.1) with ESMTP id p0D961ku003400; Thu, 13 Jan 2011 04:06:08 -0500 From: Kristoffer Glembo To: sparclinux@vger.kernel.org Cc: sam@ravnborg.org, davem@davemloft.net Subject: [PATCH 4/4 V2] sparc/leon: Add LEON dma_ops. Date: Thu, 13 Jan 2011 10:05:35 +0100 Message-Id: <1294909535-6290-5-git-send-email-kristoffer@gaisler.com> X-Mailer: git-send-email 1.6.4.1 In-Reply-To: <1294909535-6290-1-git-send-email-kristoffer@gaisler.com> References: <1294909535-6290-1-git-send-email-kristoffer@gaisler.com> X-CSC: 0 X-CHA: v=1.1 cv=7mdt3cZwcPjaoOsfh2HHasJqDel8T9IFNftJhWNFW5M= c=1 sm=1 a=Xxk11-YaCrwA:10 a=jXKJviUpWSOlMmIvGrHOfw==:17 a=ebG-ZW-8AAAA:8 a=bQxnGAxHQmpN1pQN8WUA:9 a=ttb6QmU2lj5-L2D4qBYA:7 a=Nj5WLUvDymlwfTWExbmkbvSpH5wA:4 a=cCYF7-FHeg4A:10 a=jXKJviUpWSOlMmIvGrHOfw==:117 Sender: sparclinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: sparclinux@vger.kernel.org This patch introduces a dma_ops structure for LEON. It reuses parts of the SBUS and PCI API to avoid code duplication. Signed-off-by: Kristoffer Glembo --- arch/sparc/kernel/ioport.c | 69 +++++++++++++++++++++++++++++++++++++------- 1 files changed, 58 insertions(+), 11 deletions(-) diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 699120a..466f1dc 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -291,16 +291,22 @@ static void *sbus_alloc_coherent(struct device *dev, size_t len, /* * XXX That's where sdev would be used. Currently we load * all iommu tables with the same translations. + * + * For LEON we only set up the SRMMU, no IOMMU. */ - if (mmu_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0) - goto err_noiommu; - +#ifdef CONFIG_SPARC_LEON + sparc_mapiorange(0, virt_to_phys(va), res->start, len_total); + *dma_addrp = virt_to_phys(va); +#else + if (mmu_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0) { + release_resource(res); + goto err_nova; + } +#endif res->name = op->dev.of_node->name; return (void *)(unsigned long)res->start; -err_noiommu: - release_resource(res); err_nova: free_pages(va, order); err_nomem: @@ -336,9 +342,15 @@ static void sbus_free_coherent(struct device *dev, size_t n, void *p, release_resource(res); kfree(res); - /* mmu_inval_dma_area(va, n); */ /* it's consistent, isn't it */ pgv = virt_to_page(p); + + /* No IOMMU support for LEON */ +#ifdef CONFIG_SPARC_LEON + mmu_inval_dma_area((unsigned long)p, n); + sparc_unmapiorange((unsigned long)p, n); +#else mmu_unmap_dma_area(dev, ba, n); +#endif __free_pages(pgv, get_order(n)); } @@ -413,9 +425,6 @@ struct dma_map_ops sbus_dma_ops = { .sync_sg_for_device = sbus_sync_sg_for_device, }; -struct dma_map_ops *dma_ops = &sbus_dma_ops; -EXPORT_SYMBOL(dma_ops); - static int __init sparc_register_ioport(void) { register_proc_sparc_ioport(); @@ -427,7 +436,9 @@ arch_initcall(sparc_register_ioport); #endif /* CONFIG_SBUS */ -#ifdef CONFIG_PCI + +/* LEON reuses PCI DMA ops */ +#if defined(CONFIG_PCI) || defined(CONFIG_SPARC_LEON) /* Allocate and map kernel buffer using consistent mode DMA for a device. * hwdev should be valid struct pci_dev pointer for PCI devices. @@ -667,7 +678,43 @@ struct dma_map_ops pci32_dma_ops = { }; EXPORT_SYMBOL(pci32_dma_ops); -#endif /* CONFIG_PCI */ +/* + * We can only invalidate the whole cache + */ +static void leon_unmap_sg(struct device *dev, struct scatterlist *sgl, + int nents, enum dma_data_direction dir, + struct dma_attrs *attrs) +{ + if (dir != PCI_DMA_TODEVICE) + mmu_inval_dma_area(0, 0); +} + +struct dma_map_ops leon_dma_ops = { + .alloc_coherent = sbus_alloc_coherent, + .free_coherent = sbus_free_coherent, + .map_page = pci32_map_page, + .unmap_page = pci32_unmap_page, + .map_sg = pci32_map_sg, + .unmap_sg = leon_unmap_sg, + .sync_single_for_cpu = pci32_sync_single_for_cpu, + .sync_single_for_device = pci32_sync_single_for_device, + .sync_sg_for_cpu = pci32_sync_sg_for_cpu, + .sync_sg_for_device = pci32_sync_sg_for_device, +}; + +#endif /* CONFIG_PCI || CONFIG_SPARC_LEON */ + +#ifdef CONFIG_SBUS + +#ifdef CONFIG_SPARC_LEON +struct dma_map_ops *dma_ops = &leon_dma_ops; +#else +struct dma_map_ops *dma_ops = &sbus_dma_ops; +#endif + +EXPORT_SYMBOL(dma_ops); + +#endif /* * Return whether the given PCI device DMA address mask can be