diff options
author | David S. Miller <davem@davemloft.net> | 2008-09-10 02:54:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-09-11 02:07:41 -0400 |
commit | d3ae4b5bc7186a53731d35187ad4ba3bca147cf6 (patch) | |
tree | 53fbab0e70a170a3f6576e44e0b65fdbffe33258 /arch/sparc64/kernel/pci_sun4v.c | |
parent | ab138c031f72f6d030afa1a06a3a537e85ae843e (diff) |
sparc64: Get rid of pci_controller_info.
It is just used as a parent to encapsulate two PBM objects.
But that layout is only really relevant and necessary for
psycho PCI controllers, which unlike all the others share
a single IOMMU instance between sibling PCI busses.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/pci_sun4v.c')
-rw-r--r-- | arch/sparc64/kernel/pci_sun4v.c | 66 |
1 files changed, 27 insertions, 39 deletions
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 6bed2f6bf7cd..233b22b8b576 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c | |||
@@ -42,6 +42,7 @@ struct iommu_batch { | |||
42 | }; | 42 | }; |
43 | 43 | ||
44 | static DEFINE_PER_CPU(struct iommu_batch, iommu_batch); | 44 | static DEFINE_PER_CPU(struct iommu_batch, iommu_batch); |
45 | static int iommu_batch_initialized; | ||
45 | 46 | ||
46 | /* Interrupts must be disabled. */ | 47 | /* Interrupts must be disabled. */ |
47 | static inline void iommu_batch_start(struct device *dev, unsigned long prot, unsigned long entry) | 48 | static inline void iommu_batch_start(struct device *dev, unsigned long prot, unsigned long entry) |
@@ -887,21 +888,12 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) | |||
887 | } | 888 | } |
888 | #endif /* !(CONFIG_PCI_MSI) */ | 889 | #endif /* !(CONFIG_PCI_MSI) */ |
889 | 890 | ||
890 | static int __init pci_sun4v_pbm_init(struct pci_controller_info *p, | 891 | static int __init pci_sun4v_pbm_init(struct pci_pbm_info *pbm, |
891 | struct of_device *op, u32 devhandle) | 892 | struct of_device *op, u32 devhandle) |
892 | { | 893 | { |
893 | struct device_node *dp = op->node; | 894 | struct device_node *dp = op->node; |
894 | struct pci_pbm_info *pbm; | ||
895 | int err; | 895 | int err; |
896 | 896 | ||
897 | if (devhandle & 0x40) | ||
898 | pbm = &p->pbm_B; | ||
899 | else | ||
900 | pbm = &p->pbm_A; | ||
901 | |||
902 | pbm->next = pci_pbm_root; | ||
903 | pci_pbm_root = pbm; | ||
904 | |||
905 | pbm->numa_node = of_node_to_nid(dp); | 897 | pbm->numa_node = of_node_to_nid(dp); |
906 | 898 | ||
907 | pbm->pci_ops = &sun4v_pci_ops; | 899 | pbm->pci_ops = &sun4v_pci_ops; |
@@ -909,7 +901,6 @@ static int __init pci_sun4v_pbm_init(struct pci_controller_info *p, | |||
909 | 901 | ||
910 | pbm->index = pci_num_pbms++; | 902 | pbm->index = pci_num_pbms++; |
911 | 903 | ||
912 | pbm->parent = p; | ||
913 | pbm->prom_node = dp; | 904 | pbm->prom_node = dp; |
914 | 905 | ||
915 | pbm->devhandle = devhandle; | 906 | pbm->devhandle = devhandle; |
@@ -931,6 +922,9 @@ static int __init pci_sun4v_pbm_init(struct pci_controller_info *p, | |||
931 | 922 | ||
932 | pci_sun4v_scan_bus(pbm, &op->dev); | 923 | pci_sun4v_scan_bus(pbm, &op->dev); |
933 | 924 | ||
925 | pbm->next = pci_pbm_root; | ||
926 | pci_pbm_root = pbm; | ||
927 | |||
934 | return 0; | 928 | return 0; |
935 | } | 929 | } |
936 | 930 | ||
@@ -939,7 +933,6 @@ static int __devinit pci_sun4v_probe(struct of_device *op, | |||
939 | { | 933 | { |
940 | const struct linux_prom64_registers *regs; | 934 | const struct linux_prom64_registers *regs; |
941 | static int hvapi_negotiated = 0; | 935 | static int hvapi_negotiated = 0; |
942 | struct pci_controller_info *p; | ||
943 | struct pci_pbm_info *pbm; | 936 | struct pci_pbm_info *pbm; |
944 | struct device_node *dp; | 937 | struct device_node *dp; |
945 | struct iommu *iommu; | 938 | struct iommu *iommu; |
@@ -972,51 +965,46 @@ static int __devinit pci_sun4v_probe(struct of_device *op, | |||
972 | } | 965 | } |
973 | devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; | 966 | devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; |
974 | 967 | ||
975 | for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { | ||
976 | if (pbm->devhandle == (devhandle ^ 0x40)) { | ||
977 | return pci_sun4v_pbm_init(pbm->parent, op, devhandle); | ||
978 | } | ||
979 | } | ||
980 | |||
981 | err = -ENOMEM; | 968 | err = -ENOMEM; |
982 | for_each_possible_cpu(i) { | 969 | if (!iommu_batch_initialized) { |
983 | unsigned long page = get_zeroed_page(GFP_ATOMIC); | 970 | for_each_possible_cpu(i) { |
971 | unsigned long page = get_zeroed_page(GFP_KERNEL); | ||
984 | 972 | ||
985 | if (!page) | 973 | if (!page) |
986 | goto out_err; | 974 | goto out_err; |
987 | 975 | ||
988 | per_cpu(iommu_batch, i).pglist = (u64 *) page; | 976 | per_cpu(iommu_batch, i).pglist = (u64 *) page; |
977 | } | ||
978 | iommu_batch_initialized = 1; | ||
989 | } | 979 | } |
990 | 980 | ||
991 | p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); | 981 | pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); |
992 | if (!p) { | 982 | if (!pbm) { |
993 | printk(KERN_ERR PFX "Could not allocate pci_controller_info\n"); | 983 | printk(KERN_ERR PFX "Could not allocate pci_pbm_info\n"); |
994 | goto out_err; | 984 | goto out_err; |
995 | } | 985 | } |
996 | 986 | ||
997 | iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); | 987 | iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); |
998 | if (!iommu) { | 988 | if (!iommu) { |
999 | printk(KERN_ERR PFX "Could not allocate pbm A iommu\n"); | 989 | printk(KERN_ERR PFX "Could not allocate pbm iommu\n"); |
1000 | goto out_free_controller; | 990 | goto out_free_controller; |
1001 | } | 991 | } |
1002 | 992 | ||
1003 | p->pbm_A.iommu = iommu; | 993 | pbm->iommu = iommu; |
1004 | 994 | ||
1005 | iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); | 995 | err = pci_sun4v_pbm_init(pbm, op, devhandle); |
1006 | if (!iommu) { | 996 | if (err) |
1007 | printk(KERN_ERR PFX "Could not allocate pbm B iommu\n"); | 997 | goto out_free_iommu; |
1008 | goto out_free_iommu_A; | ||
1009 | } | ||
1010 | 998 | ||
1011 | p->pbm_B.iommu = iommu; | 999 | dev_set_drvdata(&op->dev, pbm); |
1012 | 1000 | ||
1013 | return pci_sun4v_pbm_init(p, op, devhandle); | 1001 | return 0; |
1014 | 1002 | ||
1015 | out_free_iommu_A: | 1003 | out_free_iommu: |
1016 | kfree(p->pbm_A.iommu); | 1004 | kfree(pbm->iommu); |
1017 | 1005 | ||
1018 | out_free_controller: | 1006 | out_free_controller: |
1019 | kfree(p); | 1007 | kfree(pbm); |
1020 | 1008 | ||
1021 | out_err: | 1009 | out_err: |
1022 | return err; | 1010 | return err; |