Message ID | 1294909535-6290-5-git-send-email-kristoffer@gaisler.com |
---|---|
State | Changes Requested |
Delegated to: | David Miller |
Headers | show |
Hi Kristoffer. On Thu, Jan 13, 2011 at 10:05:35AM +0100, Kristoffer Glembo wrote: > 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 <kristoffer@gaisler.com> > --- > 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: I have failed to see what is the difference between pci32_alloc_coherent() and the LEON variant of sbus_alloc_coherent(). > @@ -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)); > } Likewise for this. It looks equal to pci32_free_coherent(). If they are equal then this patch can be simplified a lot. Please investigate. > @@ -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); > +} Please investigate if you can use pci32_unmap_sg. If this is the case you can reuse pci32_dma_ops direct. As you can use pci32_map_sg() I would assume you can also use the counterpart for unmap.. Sam -- To unsubscribe from this list: send the line "unsubscribe sparclinux" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi, Sam Ravnborg wrote: > > I have failed to see what is the difference between pci32_alloc_coherent() > and the LEON variant of sbus_alloc_coherent(). Yes the only difference it the setting of the name in the resource. Maybe it does not warrant the messy code. > > Likewise for this. It looks equal to pci32_free_coherent(). > Yes this case is actually totally equal. For me it is no problem using the pci versions. I tried using the sbus versions on advice from Dave but maybe it was not very successful :) > Please investigate if you can use pci32_unmap_sg. > If this is the case you can reuse pci32_dma_ops direct. > As you can use pci32_map_sg() I would assume you can also > use the counterpart for unmap.. > Yes I can remove it. It was pretty unnecessary. Thanks, Kristoffer -- To unsubscribe from this list: send the line "unsubscribe sparclinux" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, Jan 18, 2011 at 10:25:24AM +0100, Kristoffer Glembo wrote: > Hi, > > > Sam Ravnborg wrote: > > > > I have failed to see what is the difference between pci32_alloc_coherent() > > and the LEON variant of sbus_alloc_coherent(). > > Yes the only difference it the setting of the name in the resource. Maybe it does not warrant the messy code. > > > > > Likewise for this. It looks equal to pci32_free_coherent(). > > > > Yes this case is actually totally equal. > > For me it is no problem using the pci versions. I tried using the sbus versions on advice from Dave but maybe it was not very successful :) > > > > Please investigate if you can use pci32_unmap_sg. > > If this is the case you can reuse pci32_dma_ops direct. > > As you can use pci32_map_sg() I would assume you can also > > use the counterpart for unmap.. > > > > Yes I can remove it. It was pretty unnecessary. I look forward for next version. Note: I review this with only limited knowledge of the DMA stuff etc. So you shall (as always) treat the input as such. Sam -- To unsubscribe from this list: send the line "unsubscribe sparclinux" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
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
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 <kristoffer@gaisler.com> --- arch/sparc/kernel/ioport.c | 69 +++++++++++++++++++++++++++++++++++++------- 1 files changed, 58 insertions(+), 11 deletions(-)