aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/iommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/cell/iommu.c')
-rw-r--r--arch/powerpc/platforms/cell/iommu.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index df330666ccc9..edab631a8dcb 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -26,6 +26,7 @@
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/notifier.h> 28#include <linux/notifier.h>
29#include <linux/of.h>
29#include <linux/of_platform.h> 30#include <linux/of_platform.h>
30 31
31#include <asm/prom.h> 32#include <asm/prom.h>
@@ -789,18 +790,16 @@ static int __init cell_iommu_init_disabled(void)
789static u64 cell_iommu_get_fixed_address(struct device *dev) 790static u64 cell_iommu_get_fixed_address(struct device *dev)
790{ 791{
791 u64 cpu_addr, size, best_size, pci_addr = OF_BAD_ADDR; 792 u64 cpu_addr, size, best_size, pci_addr = OF_BAD_ADDR;
792 struct device_node *tmp, *np; 793 struct device_node *np;
793 const u32 *ranges = NULL; 794 const u32 *ranges = NULL;
794 int i, len, best; 795 int i, len, best;
795 796
796 np = dev->archdata.of_node; 797 np = of_node_get(dev->archdata.of_node);
797 of_node_get(np); 798 while (np) {
798 ranges = of_get_property(np, "dma-ranges", &len);
799 while (!ranges && np) {
800 tmp = of_get_parent(np);
801 of_node_put(np);
802 np = tmp;
803 ranges = of_get_property(np, "dma-ranges", &len); 799 ranges = of_get_property(np, "dma-ranges", &len);
800 if (ranges)
801 break;
802 np = of_get_next_parent(np);
804 } 803 }
805 804
806 if (!ranges) { 805 if (!ranges) {
@@ -842,19 +841,18 @@ static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask)
842 if (!dev->dma_mask || !dma_supported(dev, dma_mask)) 841 if (!dev->dma_mask || !dma_supported(dev, dma_mask))
843 return -EIO; 842 return -EIO;
844 843
845 if (dma_mask == DMA_BIT_MASK(64)) { 844 if (dma_mask == DMA_BIT_MASK(64) &&
846 if (cell_iommu_get_fixed_address(dev) == OF_BAD_ADDR) 845 cell_iommu_get_fixed_address(dev) != OF_BAD_ADDR)
847 dev_dbg(dev, "iommu: 64-bit OK, but bad addr\n"); 846 {
848 else { 847 dev_dbg(dev, "iommu: 64-bit OK, using fixed ops\n");
849 dev_dbg(dev, "iommu: 64-bit OK, using fixed ops\n"); 848 set_dma_ops(dev, &dma_iommu_fixed_ops);
850 set_dma_ops(dev, &dma_iommu_fixed_ops);
851 cell_dma_dev_setup(dev);
852 }
853 } else { 849 } else {
854 dev_dbg(dev, "iommu: not 64-bit, using default ops\n"); 850 dev_dbg(dev, "iommu: not 64-bit, using default ops\n");
855 set_dma_ops(dev, get_pci_dma_ops()); 851 set_dma_ops(dev, get_pci_dma_ops());
856 } 852 }
857 853
854 cell_dma_dev_setup(dev);
855
858 *dev->dma_mask = dma_mask; 856 *dev->dma_mask = dma_mask;
859 857
860 return 0; 858 return 0;
@@ -918,6 +916,18 @@ static int __init cell_iommu_fixed_mapping_init(void)
918 return -1; 916 return -1;
919 } 917 }
920 918
919 /* We must have dma-ranges properties for fixed mapping to work */
920 for (np = NULL; (np = of_find_all_nodes(np));) {
921 if (of_find_property(np, "dma-ranges", NULL))
922 break;
923 }
924 of_node_put(np);
925
926 if (!np) {
927 pr_debug("iommu: no dma-ranges found, no fixed mapping\n");
928 return -1;
929 }
930
921 /* The default setup is to have the fixed mapping sit after the 931 /* The default setup is to have the fixed mapping sit after the
922 * dynamic region, so find the top of the largest IOMMU window 932 * dynamic region, so find the top of the largest IOMMU window
923 * on any axon, then add the size of RAM and that's our max value. 933 * on any axon, then add the size of RAM and that's our max value.
@@ -981,8 +991,8 @@ static int __init cell_iommu_fixed_mapping_init(void)
981 dsize = htab_size_bytes; 991 dsize = htab_size_bytes;
982 } 992 }
983 993
984 pr_debug("iommu: setting up %d, dynamic window %lx-%lx " \ 994 printk(KERN_DEBUG "iommu: node %d, dynamic window 0x%lx-0x%lx "
985 "fixed window %lx-%lx\n", iommu->nid, dbase, 995 "fixed window 0x%lx-0x%lx\n", iommu->nid, dbase,
986 dbase + dsize, fbase, fbase + fsize); 996 dbase + dsize, fbase, fbase + fsize);
987 997
988 cell_iommu_setup_page_tables(iommu, dbase, dsize, fbase, fsize); 998 cell_iommu_setup_page_tables(iommu, dbase, dsize, fbase, fsize);
@@ -998,8 +1008,6 @@ static int __init cell_iommu_fixed_mapping_init(void)
998 dma_iommu_ops.set_dma_mask = dma_set_mask_and_switch; 1008 dma_iommu_ops.set_dma_mask = dma_set_mask_and_switch;
999 set_pci_dma_ops(&dma_iommu_ops); 1009 set_pci_dma_ops(&dma_iommu_ops);
1000 1010
1001 printk(KERN_DEBUG "IOMMU fixed mapping established.\n");
1002
1003 return 0; 1011 return 0;
1004} 1012}
1005 1013