diff options
author | Paul Mackerras <paulus@samba.org> | 2008-03-25 17:44:18 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-03-25 17:44:18 -0400 |
commit | 54f53f2b94feb72622bec7a8563fc487d9f97720 (patch) | |
tree | ab0c4e1dcadd25a00fa7a4febf41bc43b864cf73 /arch/powerpc/platforms | |
parent | f61fb8a52cdf8b9b6a6badde84aefe58cb35d315 (diff) | |
parent | a4083c9271e0a697278e089f2c0b9a95363ada0a (diff) |
Merge branch 'linux-2.6'
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r-- | arch/powerpc/platforms/cell/iommu.c | 41 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/setup.c | 36 |
2 files changed, 61 insertions, 16 deletions
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index d6a732503ea6..49fe641d4345 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c | |||
@@ -802,17 +802,24 @@ static int __init cell_iommu_init_disabled(void) | |||
802 | 802 | ||
803 | static u64 cell_iommu_get_fixed_address(struct device *dev) | 803 | static u64 cell_iommu_get_fixed_address(struct device *dev) |
804 | { | 804 | { |
805 | u64 cpu_addr, size, best_size, pci_addr = OF_BAD_ADDR; | 805 | u64 cpu_addr, size, best_size, dev_addr = OF_BAD_ADDR; |
806 | struct device_node *np; | 806 | struct device_node *np; |
807 | const u32 *ranges = NULL; | 807 | const u32 *ranges = NULL; |
808 | int i, len, best; | 808 | int i, len, best, naddr, nsize, pna, range_size; |
809 | 809 | ||
810 | np = of_node_get(dev->archdata.of_node); | 810 | np = of_node_get(dev->archdata.of_node); |
811 | while (np) { | 811 | while (1) { |
812 | naddr = of_n_addr_cells(np); | ||
813 | nsize = of_n_size_cells(np); | ||
814 | np = of_get_next_parent(np); | ||
815 | if (!np) | ||
816 | break; | ||
817 | |||
812 | ranges = of_get_property(np, "dma-ranges", &len); | 818 | ranges = of_get_property(np, "dma-ranges", &len); |
813 | if (ranges) | 819 | |
820 | /* Ignore empty ranges, they imply no translation required */ | ||
821 | if (ranges && len > 0) | ||
814 | break; | 822 | break; |
815 | np = of_get_next_parent(np); | ||
816 | } | 823 | } |
817 | 824 | ||
818 | if (!ranges) { | 825 | if (!ranges) { |
@@ -822,15 +829,17 @@ static u64 cell_iommu_get_fixed_address(struct device *dev) | |||
822 | 829 | ||
823 | len /= sizeof(u32); | 830 | len /= sizeof(u32); |
824 | 831 | ||
832 | pna = of_n_addr_cells(np); | ||
833 | range_size = naddr + nsize + pna; | ||
834 | |||
825 | /* dma-ranges format: | 835 | /* dma-ranges format: |
826 | * 1 cell: pci space | 836 | * child addr : naddr cells |
827 | * 2 cells: pci address | 837 | * parent addr : pna cells |
828 | * 2 cells: parent address | 838 | * size : nsize cells |
829 | * 2 cells: size | ||
830 | */ | 839 | */ |
831 | for (i = 0, best = -1, best_size = 0; i < len; i += 7) { | 840 | for (i = 0, best = -1, best_size = 0; i < len; i += range_size) { |
832 | cpu_addr = of_translate_dma_address(np, ranges +i + 3); | 841 | cpu_addr = of_translate_dma_address(np, ranges + i + naddr); |
833 | size = of_read_number(ranges + i + 5, 2); | 842 | size = of_read_number(ranges + i + naddr + pna, nsize); |
834 | 843 | ||
835 | if (cpu_addr == 0 && size > best_size) { | 844 | if (cpu_addr == 0 && size > best_size) { |
836 | best = i; | 845 | best = i; |
@@ -838,15 +847,15 @@ static u64 cell_iommu_get_fixed_address(struct device *dev) | |||
838 | } | 847 | } |
839 | } | 848 | } |
840 | 849 | ||
841 | if (best >= 0) | 850 | if (best >= 0) { |
842 | pci_addr = of_read_number(ranges + best + 1, 2); | 851 | dev_addr = of_read_number(ranges + best, naddr); |
843 | else | 852 | } else |
844 | dev_dbg(dev, "iommu: no suitable range found!\n"); | 853 | dev_dbg(dev, "iommu: no suitable range found!\n"); |
845 | 854 | ||
846 | out: | 855 | out: |
847 | of_node_put(np); | 856 | of_node_put(np); |
848 | 857 | ||
849 | return pci_addr; | 858 | return dev_addr; |
850 | } | 859 | } |
851 | 860 | ||
852 | static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask) | 861 | static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask) |
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index dda34650cb07..5c531e8f9f6f 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c | |||
@@ -81,6 +81,42 @@ static void cell_progress(char *s, unsigned short hex) | |||
81 | printk("*** %04x : %s\n", hex, s ? s : ""); | 81 | printk("*** %04x : %s\n", hex, s ? s : ""); |
82 | } | 82 | } |
83 | 83 | ||
84 | static void cell_fixup_pcie_rootcomplex(struct pci_dev *dev) | ||
85 | { | ||
86 | struct pci_controller *hose; | ||
87 | const char *s; | ||
88 | int i; | ||
89 | |||
90 | if (!machine_is(cell)) | ||
91 | return; | ||
92 | |||
93 | /* We're searching for a direct child of the PHB */ | ||
94 | if (dev->bus->self != NULL || dev->devfn != 0) | ||
95 | return; | ||
96 | |||
97 | hose = pci_bus_to_host(dev->bus); | ||
98 | if (hose == NULL) | ||
99 | return; | ||
100 | |||
101 | /* Only on PCIE */ | ||
102 | if (!of_device_is_compatible(hose->dn, "pciex")) | ||
103 | return; | ||
104 | |||
105 | /* And only on axon */ | ||
106 | s = of_get_property(hose->dn, "model", NULL); | ||
107 | if (!s || strcmp(s, "Axon") != 0) | ||
108 | return; | ||
109 | |||
110 | for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) { | ||
111 | dev->resource[i].start = dev->resource[i].end = 0; | ||
112 | dev->resource[i].flags = 0; | ||
113 | } | ||
114 | |||
115 | printk(KERN_DEBUG "PCI: Hiding resources on Axon PCIE RC %s\n", | ||
116 | pci_name(dev)); | ||
117 | } | ||
118 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, cell_fixup_pcie_rootcomplex); | ||
119 | |||
84 | static int __init cell_publish_devices(void) | 120 | static int __init cell_publish_devices(void) |
85 | { | 121 | { |
86 | int node; | 122 | int node; |