From: Nishanth Aravamudan <nacc@us.ibm.com>
To: nacc@us.ibm.com
Cc: Anton Vorontsov <avorontsov@mvista.com>,
miltonm@bga.com, linux-kernel@vger.kernel.org,
FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>,
Paul Mackerras <paulus@samba.org>,
Scott Wood <scottwood@freescale.com>,
Andrew Morton <akpm@linux-foundation.org>,
linuxppc-dev@lists.ozlabs.org
Subject: [RFC PATCH 03/11] ppc: Create ops to choose between direct window and iommu based on device mask
Date: Fri, 8 Oct 2010 10:33:04 -0700 [thread overview]
Message-ID: <1286559192-10898-4-git-send-email-nacc@us.ibm.com> (raw)
In-Reply-To: <1286559192-10898-1-git-send-email-nacc@us.ibm.com>
Also allow the coherent ops to be iommu if only the coherent mask is too
small, mostly for driver that do not set set the coherent mask but also
don't use the coherent api.
Signed-off-by: Milton Miller <miltonm@bga.com>
Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
---
arch/powerpc/include/asm/dma-mapping.h | 2 +
arch/powerpc/kernel/Makefile | 2 +-
arch/powerpc/kernel/dma-choose64.c | 167 ++++++++++++++++++++++++++++++++
3 files changed, 170 insertions(+), 1 deletions(-)
create mode 100644 arch/powerpc/kernel/dma-choose64.c
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index 644103a..9ffb16a 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -68,6 +68,8 @@ static inline unsigned long device_to_mask(struct device *dev)
*/
#ifdef CONFIG_PPC64
extern struct dma_map_ops dma_iommu_ops;
+extern struct dma_map_ops dma_choose64_ops;
+extern struct dma_map_ops dma_iommu_coherent_ops;
#endif
extern struct dma_map_ops dma_direct_ops;
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 1dda701..21b8ea1 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -82,7 +82,7 @@ obj-y += time.o prom.o traps.o setup-common.o \
udbg.o misc.o io.o dma.o \
misc_$(CONFIG_WORD_SIZE).o
obj-$(CONFIG_PPC32) += entry_32.o setup_32.o
-obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o
+obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o dma-choose64.o
obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init.o
obj-$(CONFIG_MODULES) += ppc_ksyms.o
diff --git a/arch/powerpc/kernel/dma-choose64.c b/arch/powerpc/kernel/dma-choose64.c
new file mode 100644
index 0000000..17c716f
--- /dev/null
+++ b/arch/powerpc/kernel/dma-choose64.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corporation
+ *
+ * Provide default implementations of the DMA mapping callbacks for
+ * directly mapped busses.
+ */
+
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/bug.h>
+
+/*
+ * DMA operations that choose between a 64-bit direct mapping and and iommu
+ *
+ * This set of dma ops chooses between directing to a static 1:1 mapping
+ * that may require a 64 bit address and a iommu based on the declared
+ * streaming and coherent masks for the device. The choice is made on
+ * the first dma map call.
+ */
+
+/* first BUG ops for calls out of sequence */
+
+void *dma_bug_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag)
+{
+ BUG();
+
+ return NULL;
+}
+
+void dma_bug_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ BUG();
+}
+
+static int dma_bug_dma_supported(struct device *dev, u64 mask)
+{
+ BUG();
+
+ return 0;
+}
+
+static int dma_bug_map_sg(struct device *dev, struct scatterlist *sgl,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ BUG();
+
+ return 0;
+}
+
+
+static void dma_bug_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ BUG();
+}
+
+static dma_addr_t dma_bug_map_page(struct device *dev,
+ struct page *page,
+ unsigned long offset,
+ size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ BUG();
+
+ return DMA_ERROR_CODE;
+}
+
+
+static void dma_bug_unmap_page(struct device *dev,
+ dma_addr_t dma_address,
+ size_t size,
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ BUG();
+}
+
+
+static struct dma_map_ops *choose(struct device *dev)
+{
+ if (dma_direct_ops.dma_supported(dev, device_to_mask(dev))) {
+ if (dma_direct_ops.dma_supported(dev, dev->coherent_dma_mask))
+ return &dma_direct_ops;
+ return &dma_iommu_coherent_ops;
+ }
+ return &dma_iommu_ops;
+}
+
+void *dma_choose64_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag)
+{
+ struct dma_map_ops *new = choose(dev);
+
+ set_dma_ops(dev, new);
+ return new->alloc_coherent(dev, size, dma_handle, flag);
+}
+
+static int dma_choose64_map_sg(struct device *dev, struct scatterlist *sgl,
+ int nents, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ struct dma_map_ops *new = choose(dev);
+
+ set_dma_ops(dev, new);
+ return new->map_sg(dev, sgl, nents, direction, attrs);
+}
+
+
+static int dma_choose64_dma_supported(struct device *dev, u64 mask)
+{
+ return dma_direct_ops.dma_supported(dev, mask) ||
+ dma_iommu_ops.dma_supported(dev, mask);
+}
+
+static dma_addr_t dma_choose64_map_page(struct device *dev,
+ struct page *page,
+ unsigned long offset,
+ size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ struct dma_map_ops *new = choose(dev);
+
+ set_dma_ops(dev, new);
+ return new->map_page(dev, page, offset, size, dir, attrs);
+}
+
+struct dma_map_ops dma_choose64_ops = {
+ .alloc_coherent = dma_choose64_alloc_coherent,
+ .free_coherent = dma_bug_free_coherent,
+ .map_sg = dma_choose64_map_sg,
+ .unmap_sg = dma_bug_unmap_sg,
+ .dma_supported = dma_choose64_dma_supported,
+ .map_page = dma_choose64_map_page,
+ .unmap_page = dma_bug_unmap_page,
+};
+EXPORT_SYMBOL(dma_choose64_ops);
+
+/* set these up to BUG() until we initialze them in the arch initcall below */
+struct dma_map_ops dma_iommu_coherent_ops = {
+ .alloc_coherent = dma_bug_alloc_coherent,
+ .free_coherent = dma_bug_free_coherent,
+ .map_sg = dma_bug_map_sg,
+ .unmap_sg = dma_bug_unmap_sg,
+ .dma_supported = dma_bug_dma_supported,
+ .map_page = dma_bug_map_page,
+ .unmap_page = dma_bug_unmap_page,
+};
+EXPORT_SYMBOL(dma_iommu_coherent_ops);
+
+static int setup_choose64_ops(void)
+{
+ dma_iommu_coherent_ops = dma_direct_ops;
+ dma_iommu_coherent_ops.alloc_coherent = dma_iommu_ops.alloc_coherent;
+ dma_iommu_coherent_ops.free_coherent = dma_iommu_ops.free_coherent;
+
+ /* should we be stricter? */
+ dma_iommu_coherent_ops.dma_supported = dma_choose64_dma_supported;
+
+ return 0;
+}
+arch_initcall(setup_choose64_ops);
--
1.7.1
next prev parent reply other threads:[~2010-10-08 17:33 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-08 17:33 [RFC PATCH 00/11] ppc: enable dynamic dma window support Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 01/11] macio: ensure all dma routines get copied over Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 02/11] ppc: allow direct and iommu to coexist Nishanth Aravamudan
2010-10-08 23:38 ` Benjamin Herrenschmidt
2010-10-08 17:33 ` Nishanth Aravamudan [this message]
2010-10-08 23:43 ` [RFC PATCH 03/11] ppc: Create ops to choose between direct window and iommu based on device mask Benjamin Herrenschmidt
2010-10-08 23:44 ` Benjamin Herrenschmidt
2010-10-10 15:09 ` FUJITA Tomonori
2010-10-10 23:41 ` Benjamin Herrenschmidt
2010-10-08 17:33 ` [RFC PATCH 04/11] ppc: add memory_hotplug_max Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 05/11] ppc: do not search for dma-window property on dlpar remove Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 06/11] ppc: checking for pdn->parent is redundant Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 07/11] ppc/iommu: do not need to check for dma_window == NULL Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 08/11] ppc/iommu: remove unneeded pci_dma_bus_setup_pSeriesLP Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 09/11] ppc/iommu: pass phb only to iommu_table_setparms_lpar Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 10/11] ppc/iommu: add routines to pseries iommu to map tces 1-1 Nishanth Aravamudan
2010-10-08 17:33 ` [RFC PATCH 11/11] ppc: add dynamic dma window support Nishanth Aravamudan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1286559192-10898-4-git-send-email-nacc@us.ibm.com \
--to=nacc@us.ibm.com \
--cc=akpm@linux-foundation.org \
--cc=avorontsov@mvista.com \
--cc=fujita.tomonori@lab.ntt.co.jp \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=miltonm@bga.com \
--cc=paulus@samba.org \
--cc=scottwood@freescale.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).