aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/pci_32.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-12-10 22:48:18 -0500
committerPaul Mackerras <paulus@samba.org>2007-12-10 23:43:35 -0500
commit13dccb9e65dc0fa4de83e5bd5639f7a7f3f6fb9e (patch)
treee072ef034d6021359993253d1101ba7a03609760 /arch/powerpc/kernel/pci_32.c
parent25e81f925d4be0a0f60520e1c3c1b5af744404e1 (diff)
[POWERPC] Merge pci_process_bridge_OF_ranges()
This merges the 32-bit and 64-bit implementations of pci_process_bridge_OF_ranges(). The new function is cleaner than both the old ones, and supports 64 bits ranges on ppc32 which is necessary for the 4xx port. It also adds some better (hopefully) output to the kernel log which should help diagnose problems and makes better use of existing OF parsing helpers (avoiding a few bugs of both implementations along the way). There are still a few unfortunate ifdef's but there is no way around these for now at least not until some other bits of the PCI code are made common. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/pci_32.c')
-rw-r--r--arch/powerpc/kernel/pci_32.c114
1 files changed, 0 insertions, 114 deletions
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index a33c2820c200..20a1192de1a2 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -842,120 +842,6 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
842} 842}
843EXPORT_SYMBOL(pci_device_from_OF_node); 843EXPORT_SYMBOL(pci_device_from_OF_node);
844 844
845void __init
846pci_process_bridge_OF_ranges(struct pci_controller *hose,
847 struct device_node *dev, int primary)
848{
849 static unsigned int static_lc_ranges[256] __initdata;
850 const unsigned int *dt_ranges;
851 unsigned int *lc_ranges, *ranges, *prev, size;
852 int rlen = 0, orig_rlen;
853 int memno = 0;
854 struct resource *res;
855 int np, na = of_n_addr_cells(dev);
856 np = na + 5;
857
858 /* First we try to merge ranges to fix a problem with some pmacs
859 * that can have more than 3 ranges, fortunately using contiguous
860 * addresses -- BenH
861 */
862 dt_ranges = of_get_property(dev, "ranges", &rlen);
863 if (!dt_ranges)
864 return;
865 /* Sanity check, though hopefully that never happens */
866 if (rlen > sizeof(static_lc_ranges)) {
867 printk(KERN_WARNING "OF ranges property too large !\n");
868 rlen = sizeof(static_lc_ranges);
869 }
870 lc_ranges = static_lc_ranges;
871 memcpy(lc_ranges, dt_ranges, rlen);
872 orig_rlen = rlen;
873
874 /* Let's work on a copy of the "ranges" property instead of damaging
875 * the device-tree image in memory
876 */
877 ranges = lc_ranges;
878 prev = NULL;
879 while ((rlen -= np * sizeof(unsigned int)) >= 0) {
880 if (prev) {
881 if (prev[0] == ranges[0] && prev[1] == ranges[1] &&
882 (prev[2] + prev[na+4]) == ranges[2] &&
883 (prev[na+2] + prev[na+4]) == ranges[na+2]) {
884 prev[na+4] += ranges[na+4];
885 ranges[0] = 0;
886 ranges += np;
887 continue;
888 }
889 }
890 prev = ranges;
891 ranges += np;
892 }
893
894 /*
895 * The ranges property is laid out as an array of elements,
896 * each of which comprises:
897 * cells 0 - 2: a PCI address
898 * cells 3 or 3+4: a CPU physical address
899 * (size depending on dev->n_addr_cells)
900 * cells 4+5 or 5+6: the size of the range
901 */
902 ranges = lc_ranges;
903 rlen = orig_rlen;
904 while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) {
905 res = NULL;
906 size = ranges[na+4];
907 switch ((ranges[0] >> 24) & 0x3) {
908 case 1: /* I/O space */
909 if (ranges[2] != 0)
910 break;
911 hose->io_base_phys = ranges[na+2];
912 /* limit I/O space to 16MB */
913 if (size > 0x01000000)
914 size = 0x01000000;
915 hose->io_base_virt = ioremap(ranges[na+2], size);
916 if (primary)
917 isa_io_base = (unsigned long) hose->io_base_virt;
918 res = &hose->io_resource;
919 res->flags = IORESOURCE_IO;
920 res->start = ranges[2];
921 DBG("PCI: IO 0x%llx -> 0x%llx\n",
922 (u64)res->start, (u64)res->start + size - 1);
923 break;
924 case 2: /* memory space */
925 memno = 0;
926 if (ranges[1] == 0 && ranges[2] == 0
927 && ranges[na+4] <= (16 << 20)) {
928 /* 1st 16MB, i.e. ISA memory area */
929 if (primary)
930 isa_mem_base = ranges[na+2];
931 memno = 1;
932 }
933 while (memno < 3 && hose->mem_resources[memno].flags)
934 ++memno;
935 if (memno == 0)
936 hose->pci_mem_offset = ranges[na+2] - ranges[2];
937 if (memno < 3) {
938 res = &hose->mem_resources[memno];
939 res->flags = IORESOURCE_MEM;
940 if(ranges[0] & 0x40000000)
941 res->flags |= IORESOURCE_PREFETCH;
942 res->start = ranges[na+2];
943 DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno,
944 (u64)res->start, (u64)res->start + size - 1);
945 }
946 break;
947 }
948 if (res != NULL) {
949 res->name = dev->full_name;
950 res->end = res->start + size - 1;
951 res->parent = NULL;
952 res->sibling = NULL;
953 res->child = NULL;
954 }
955 ranges += np;
956 }
957}
958
959/* We create the "pci-OF-bus-map" property now so it appears in the 845/* We create the "pci-OF-bus-map" property now so it appears in the
960 * /proc device tree 846 * /proc device tree
961 */ 847 */