aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-13 01:06:53 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:12:33 -0500
commit3833789bb2e15eb85fad296d8fb40f1437925645 (patch)
tree31304e25c2d7c9c5f06b0bc74a5f4e9578de904c /arch/sparc64/kernel
parentcf627156c450cd5a0741b31f55181db3400d4887 (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.c41
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
779static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node) 779static 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 *)&regs, 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 *)&regs, 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();