diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-02-13 01:06:53 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-20 04:12:33 -0500 |
commit | 3833789bb2e15eb85fad296d8fb40f1437925645 (patch) | |
tree | 31304e25c2d7c9c5f06b0bc74a5f4e9578de904c /arch/sparc64/kernel | |
parent | cf627156c450cd5a0741b31f55181db3400d4887 (diff) |
[SPARC64]: PCI-SUN4V fixes.
Clear top 8-bits of physical addresses in "ranges" property.
This gives the actual physical address.
Detect PBM-A vs. PBM-B by checking bit 0x40 of the devhandle.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r-- | arch/sparc64/kernel/pci_sun4v.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 699e91e3e429..19a07f0115ca 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c | |||
@@ -776,22 +776,22 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) | |||
776 | probe_existing_entries(pbm, iommu); | 776 | probe_existing_entries(pbm, iommu); |
777 | } | 777 | } |
778 | 778 | ||
779 | static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node) | 779 | static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, unsigned int devhandle) |
780 | { | 780 | { |
781 | struct pci_pbm_info *pbm; | 781 | struct pci_pbm_info *pbm; |
782 | struct linux_prom64_registers regs; | ||
783 | unsigned int busrange[2]; | 782 | unsigned int busrange[2]; |
784 | int err; | 783 | int err, i; |
785 | 784 | ||
786 | /* XXX */ | 785 | if (devhandle & 0x40) |
787 | pbm = &p->pbm_A; | 786 | pbm = &p->pbm_B; |
787 | else | ||
788 | pbm = &p->pbm_A; | ||
788 | 789 | ||
789 | pbm->parent = p; | 790 | pbm->parent = p; |
790 | pbm->prom_node = prom_node; | 791 | pbm->prom_node = prom_node; |
791 | pbm->pci_first_slot = 1; | 792 | pbm->pci_first_slot = 1; |
792 | 793 | ||
793 | prom_getproperty(prom_node, "reg", (char *)®s, sizeof(regs)); | 794 | pbm->devhandle = devhandle; |
794 | pbm->devhandle = (regs.phys_addr >> 32UL) & 0x0fffffff; | ||
795 | 795 | ||
796 | sprintf(pbm->name, "SUN4V-PCI%d PBM%c", | 796 | sprintf(pbm->name, "SUN4V-PCI%d PBM%c", |
797 | p->index, (pbm == &p->pbm_A ? 'A' : 'B')); | 797 | p->index, (pbm == &p->pbm_A ? 'A' : 'B')); |
@@ -813,6 +813,12 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node) | |||
813 | pbm->num_pbm_ranges = | 813 | pbm->num_pbm_ranges = |
814 | (err / sizeof(struct linux_prom_pci_ranges)); | 814 | (err / sizeof(struct linux_prom_pci_ranges)); |
815 | 815 | ||
816 | /* Mask out the top 8 bits of the ranges, leaving the real | ||
817 | * physical address. | ||
818 | */ | ||
819 | for (i = 0; i < pbm->num_pbm_ranges; i++) | ||
820 | pbm->pbm_ranges[i].parent_phys_hi &= 0x0fffffff; | ||
821 | |||
816 | pci_sun4v_determine_mem_io_space(pbm); | 822 | pci_sun4v_determine_mem_io_space(pbm); |
817 | pbm_register_toplevel_resources(p, pbm); | 823 | pbm_register_toplevel_resources(p, pbm); |
818 | 824 | ||
@@ -851,6 +857,25 @@ void sun4v_pci_init(int node, char *model_name) | |||
851 | { | 857 | { |
852 | struct pci_controller_info *p; | 858 | struct pci_controller_info *p; |
853 | struct pci_iommu *iommu; | 859 | struct pci_iommu *iommu; |
860 | struct linux_prom64_registers regs; | ||
861 | unsigned int devhandle; | ||
862 | |||
863 | prom_getproperty(node, "reg", (char *)®s, sizeof(regs)); | ||
864 | devhandle = (regs.phys_addr >> 32UL) & 0x0fffffff;; | ||
865 | |||
866 | for (p = pci_controller_root; p; p = p->next) { | ||
867 | struct pci_pbm_info *pbm; | ||
868 | |||
869 | if (p->pbm_A.prom_node && p->pbm_B.prom_node) | ||
870 | continue; | ||
871 | |||
872 | pbm = (p->pbm_A.prom_node ? | ||
873 | &p->pbm_A : | ||
874 | &p->pbm_B); | ||
875 | |||
876 | if (pbm->devhandle == (devhandle ^ 0x40)) | ||
877 | pci_sun4v_pbm_init(p, node, devhandle); | ||
878 | } | ||
854 | 879 | ||
855 | p = kmalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); | 880 | p = kmalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); |
856 | if (!p) { | 881 | if (!p) { |
@@ -892,7 +917,7 @@ void sun4v_pci_init(int node, char *model_name) | |||
892 | */ | 917 | */ |
893 | pci_memspace_mask = 0x7fffffffUL; | 918 | pci_memspace_mask = 0x7fffffffUL; |
894 | 919 | ||
895 | pci_sun4v_pbm_init(p, node); | 920 | pci_sun4v_pbm_init(p, node, devhandle); |
896 | 921 | ||
897 | prom_printf("sun4v_pci_init: Implement me.\n"); | 922 | prom_printf("sun4v_pci_init: Implement me.\n"); |
898 | prom_halt(); | 923 | prom_halt(); |