aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorKristoffer Glembo <kristoffer@gaisler.com>2011-04-28 18:17:00 -0400
committerDavid S. Miller <davem@davemloft.net>2011-05-16 16:41:40 -0400
commitd81f087f1f1c1aacdb4f17224a554237285ddd11 (patch)
tree8be22ee127abee5e493a3ed427f0d94fb5bb7f6e /arch/sparc
parentfb1fece5da027d3c7e69cf44ca8e58aaf0faf520 (diff)
sparc32,leon: Remove unnecessary page_address calls in LEON DMA API.
The function mmu_inval_dma_area takes a virtual address as a parameter which is problematic in case the buffer is located in highmem and the mapping currently is unavailable. Since the function was only implemented for LEON this patch removes calls to it in non LEON code paths and renames it to dma_make_coherent which instead takes a physical address (which for now is unused since we flush the whole cache). This way it is possible to remove several unnecessary calls to page_address which will fail if the virtual mapping is unavailable. Signed-off-by: Kristoffer Glembo <kristoffer@gaisler.com> Acked-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/kernel/ioport.c42
1 files changed, 16 insertions, 26 deletions
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index c6ce9a6a4790..1c9c80a1a86a 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -50,10 +50,15 @@
50#include <asm/io-unit.h> 50#include <asm/io-unit.h>
51#include <asm/leon.h> 51#include <asm/leon.h>
52 52
53/* This function must make sure that caches and memory are coherent after DMA
54 * On LEON systems without cache snooping it flushes the entire D-CACHE.
55 */
53#ifndef CONFIG_SPARC_LEON 56#ifndef CONFIG_SPARC_LEON
54#define mmu_inval_dma_area(p, l) /* Anton pulled it out for 2.4.0-xx */ 57static inline void dma_make_coherent(unsigned long pa, unsigned long len)
58{
59}
55#else 60#else
56static inline void mmu_inval_dma_area(void *va, unsigned long len) 61static inline void dma_make_coherent(unsigned long pa, unsigned long len)
57{ 62{
58 if (!sparc_leon3_snooping_enabled()) 63 if (!sparc_leon3_snooping_enabled())
59 leon_flush_dcache_all(); 64 leon_flush_dcache_all();
@@ -284,7 +289,6 @@ static void *sbus_alloc_coherent(struct device *dev, size_t len,
284 printk("sbus_alloc_consistent: cannot occupy 0x%lx", len_total); 289 printk("sbus_alloc_consistent: cannot occupy 0x%lx", len_total);
285 goto err_nova; 290 goto err_nova;
286 } 291 }
287 mmu_inval_dma_area((void *)va, len_total);
288 292
289 // XXX The mmu_map_dma_area does this for us below, see comments. 293 // XXX The mmu_map_dma_area does this for us below, see comments.
290 // sparc_mapiorange(0, virt_to_phys(va), res->start, len_total); 294 // sparc_mapiorange(0, virt_to_phys(va), res->start, len_total);
@@ -336,7 +340,6 @@ static void sbus_free_coherent(struct device *dev, size_t n, void *p,
336 release_resource(res); 340 release_resource(res);
337 kfree(res); 341 kfree(res);
338 342
339 /* mmu_inval_dma_area(va, n); */ /* it's consistent, isn't it */
340 pgv = virt_to_page(p); 343 pgv = virt_to_page(p);
341 mmu_unmap_dma_area(dev, ba, n); 344 mmu_unmap_dma_area(dev, ba, n);
342 345
@@ -463,7 +466,6 @@ static void *pci32_alloc_coherent(struct device *dev, size_t len,
463 printk("pci_alloc_consistent: cannot occupy 0x%lx", len_total); 466 printk("pci_alloc_consistent: cannot occupy 0x%lx", len_total);
464 goto err_nova; 467 goto err_nova;
465 } 468 }
466 mmu_inval_dma_area(va, len_total);
467 sparc_mapiorange(0, virt_to_phys(va), res->start, len_total); 469 sparc_mapiorange(0, virt_to_phys(va), res->start, len_total);
468 470
469 *pba = virt_to_phys(va); /* equals virt_to_bus (R.I.P.) for us. */ 471 *pba = virt_to_phys(va); /* equals virt_to_bus (R.I.P.) for us. */
@@ -489,7 +491,6 @@ static void pci32_free_coherent(struct device *dev, size_t n, void *p,
489 dma_addr_t ba) 491 dma_addr_t ba)
490{ 492{
491 struct resource *res; 493 struct resource *res;
492 void *pgp;
493 494
494 if ((res = _sparc_find_resource(&_sparc_dvma, 495 if ((res = _sparc_find_resource(&_sparc_dvma,
495 (unsigned long)p)) == NULL) { 496 (unsigned long)p)) == NULL) {
@@ -509,14 +510,12 @@ static void pci32_free_coherent(struct device *dev, size_t n, void *p,
509 return; 510 return;
510 } 511 }
511 512
512 pgp = phys_to_virt(ba); /* bus_to_virt actually */ 513 dma_make_coherent(ba, n);
513 mmu_inval_dma_area(pgp, n);
514 sparc_unmapiorange((unsigned long)p, n); 514 sparc_unmapiorange((unsigned long)p, n);
515 515
516 release_resource(res); 516 release_resource(res);
517 kfree(res); 517 kfree(res);
518 518 free_pages((unsigned long)phys_to_virt(ba), get_order(n));
519 free_pages((unsigned long)pgp, get_order(n));
520} 519}
521 520
522/* 521/*
@@ -535,7 +534,7 @@ static void pci32_unmap_page(struct device *dev, dma_addr_t ba, size_t size,
535 enum dma_data_direction dir, struct dma_attrs *attrs) 534 enum dma_data_direction dir, struct dma_attrs *attrs)
536{ 535{
537 if (dir != PCI_DMA_TODEVICE) 536 if (dir != PCI_DMA_TODEVICE)
538 mmu_inval_dma_area(phys_to_virt(ba), PAGE_ALIGN(size)); 537 dma_make_coherent(ba, PAGE_ALIGN(size));
539} 538}
540 539
541/* Map a set of buffers described by scatterlist in streaming 540/* Map a set of buffers described by scatterlist in streaming
@@ -562,8 +561,7 @@ static int pci32_map_sg(struct device *device, struct scatterlist *sgl,
562 561
563 /* IIep is write-through, not flushing. */ 562 /* IIep is write-through, not flushing. */
564 for_each_sg(sgl, sg, nents, n) { 563 for_each_sg(sgl, sg, nents, n) {
565 BUG_ON(page_address(sg_page(sg)) == NULL); 564 sg->dma_address = sg_phys(sg);
566 sg->dma_address = virt_to_phys(sg_virt(sg));
567 sg->dma_length = sg->length; 565 sg->dma_length = sg->length;
568 } 566 }
569 return nents; 567 return nents;
@@ -582,9 +580,7 @@ static void pci32_unmap_sg(struct device *dev, struct scatterlist *sgl,
582 580
583 if (dir != PCI_DMA_TODEVICE) { 581 if (dir != PCI_DMA_TODEVICE) {
584 for_each_sg(sgl, sg, nents, n) { 582 for_each_sg(sgl, sg, nents, n) {
585 BUG_ON(page_address(sg_page(sg)) == NULL); 583 dma_make_coherent(sg_phys(sg), PAGE_ALIGN(sg->length));
586 mmu_inval_dma_area(page_address(sg_page(sg)),
587 PAGE_ALIGN(sg->length));
588 } 584 }
589 } 585 }
590} 586}
@@ -603,8 +599,7 @@ static void pci32_sync_single_for_cpu(struct device *dev, dma_addr_t ba,
603 size_t size, enum dma_data_direction dir) 599 size_t size, enum dma_data_direction dir)
604{ 600{
605 if (dir != PCI_DMA_TODEVICE) { 601 if (dir != PCI_DMA_TODEVICE) {
606 mmu_inval_dma_area(phys_to_virt(ba), 602 dma_make_coherent(ba, PAGE_ALIGN(size));
607 PAGE_ALIGN(size));
608 } 603 }
609} 604}
610 605
@@ -612,8 +607,7 @@ static void pci32_sync_single_for_device(struct device *dev, dma_addr_t ba,
612 size_t size, enum dma_data_direction dir) 607 size_t size, enum dma_data_direction dir)
613{ 608{
614 if (dir != PCI_DMA_TODEVICE) { 609 if (dir != PCI_DMA_TODEVICE) {
615 mmu_inval_dma_area(phys_to_virt(ba), 610 dma_make_coherent(ba, PAGE_ALIGN(size));
616 PAGE_ALIGN(size));
617 } 611 }
618} 612}
619 613
@@ -631,9 +625,7 @@ static void pci32_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl,
631 625
632 if (dir != PCI_DMA_TODEVICE) { 626 if (dir != PCI_DMA_TODEVICE) {
633 for_each_sg(sgl, sg, nents, n) { 627 for_each_sg(sgl, sg, nents, n) {
634 BUG_ON(page_address(sg_page(sg)) == NULL); 628 dma_make_coherent(sg_phys(sg), PAGE_ALIGN(sg->length));
635 mmu_inval_dma_area(page_address(sg_page(sg)),
636 PAGE_ALIGN(sg->length));
637 } 629 }
638 } 630 }
639} 631}
@@ -646,9 +638,7 @@ static void pci32_sync_sg_for_device(struct device *device, struct scatterlist *
646 638
647 if (dir != PCI_DMA_TODEVICE) { 639 if (dir != PCI_DMA_TODEVICE) {
648 for_each_sg(sgl, sg, nents, n) { 640 for_each_sg(sgl, sg, nents, n) {
649 BUG_ON(page_address(sg_page(sg)) == NULL); 641 dma_make_coherent(sg_phys(sg), PAGE_ALIGN(sg->length));
650 mmu_inval_dma_area(page_address(sg_page(sg)),
651 PAGE_ALIGN(sg->length));
652 } 642 }
653 } 643 }
654} 644}