diff options
Diffstat (limited to 'arch/powerpc/platforms/cell/iommu.c')
-rw-r--r-- | arch/powerpc/platforms/cell/iommu.c | 48 |
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) | |||
789 | static u64 cell_iommu_get_fixed_address(struct device *dev) | 790 | static 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 | ||