aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc64/kernel/pci.c16
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c224
-rw-r--r--include/asm-sparc64/pbm.h10
3 files changed, 119 insertions, 131 deletions
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index b583deb05062..4d30d57c4619 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -1092,17 +1092,12 @@ EXPORT_SYMBOL(pci_domain_nr);
1092int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) 1092int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
1093{ 1093{
1094 struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; 1094 struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;
1095 struct pci_controller_info *p = pbm->parent; 1095 int virt_irq;
1096 int virt_irq, err;
1097 1096
1098 if (!pbm->msi_num || !p->setup_msi_irq) 1097 if (!pbm->setup_msi_irq)
1099 return -EINVAL; 1098 return -EINVAL;
1100 1099
1101 err = p->setup_msi_irq(&virt_irq, pdev, desc); 1100 return pbm->setup_msi_irq(&virt_irq, pdev, desc);
1102 if (err)
1103 return err;
1104
1105 return 0;
1106} 1101}
1107 1102
1108void arch_teardown_msi_irq(unsigned int virt_irq) 1103void arch_teardown_msi_irq(unsigned int virt_irq)
@@ -1110,12 +1105,11 @@ void arch_teardown_msi_irq(unsigned int virt_irq)
1110 struct msi_desc *entry = get_irq_msi(virt_irq); 1105 struct msi_desc *entry = get_irq_msi(virt_irq);
1111 struct pci_dev *pdev = entry->dev; 1106 struct pci_dev *pdev = entry->dev;
1112 struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; 1107 struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;
1113 struct pci_controller_info *p = pbm->parent;
1114 1108
1115 if (!pbm->msi_num || !p->setup_msi_irq) 1109 if (!pbm->teardown_msi_irq)
1116 return; 1110 return;
1117 1111
1118 return p->teardown_msi_irq(virt_irq, pdev); 1112 return pbm->teardown_msi_irq(virt_irq, pdev);
1119} 1113}
1120#endif /* !(CONFIG_PCI_MSI) */ 1114#endif /* !(CONFIG_PCI_MSI) */
1121 1115
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index ea61fec206a7..7ebc04f9a880 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -991,114 +991,6 @@ h_error:
991 return -EINVAL; 991 return -EINVAL;
992} 992}
993 993
994static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
995{
996 const u32 *val;
997 int len;
998
999 val = of_get_property(pbm->prom_node, "#msi-eqs", &len);
1000 if (!val || len != 4)
1001 goto no_msi;
1002 pbm->msiq_num = *val;
1003 if (pbm->msiq_num) {
1004 const struct msiq_prop {
1005 u32 first_msiq;
1006 u32 num_msiq;
1007 u32 first_devino;
1008 } *mqp;
1009 const struct msi_range_prop {
1010 u32 first_msi;
1011 u32 num_msi;
1012 } *mrng;
1013 const struct addr_range_prop {
1014 u32 msi32_high;
1015 u32 msi32_low;
1016 u32 msi32_len;
1017 u32 msi64_high;
1018 u32 msi64_low;
1019 u32 msi64_len;
1020 } *arng;
1021
1022 val = of_get_property(pbm->prom_node, "msi-eq-size", &len);
1023 if (!val || len != 4)
1024 goto no_msi;
1025
1026 pbm->msiq_ent_count = *val;
1027
1028 mqp = of_get_property(pbm->prom_node,
1029 "msi-eq-to-devino", &len);
1030 if (!mqp || len != sizeof(struct msiq_prop))
1031 goto no_msi;
1032
1033 pbm->msiq_first = mqp->first_msiq;
1034 pbm->msiq_first_devino = mqp->first_devino;
1035
1036 val = of_get_property(pbm->prom_node, "#msi", &len);
1037 if (!val || len != 4)
1038 goto no_msi;
1039 pbm->msi_num = *val;
1040
1041 mrng = of_get_property(pbm->prom_node, "msi-ranges", &len);
1042 if (!mrng || len != sizeof(struct msi_range_prop))
1043 goto no_msi;
1044 pbm->msi_first = mrng->first_msi;
1045
1046 val = of_get_property(pbm->prom_node, "msi-data-mask", &len);
1047 if (!val || len != 4)
1048 goto no_msi;
1049 pbm->msi_data_mask = *val;
1050
1051 val = of_get_property(pbm->prom_node, "msix-data-width", &len);
1052 if (!val || len != 4)
1053 goto no_msi;
1054 pbm->msix_data_width = *val;
1055
1056 arng = of_get_property(pbm->prom_node, "msi-address-ranges",
1057 &len);
1058 if (!arng || len != sizeof(struct addr_range_prop))
1059 goto no_msi;
1060 pbm->msi32_start = ((u64)arng->msi32_high << 32) |
1061 (u64) arng->msi32_low;
1062 pbm->msi64_start = ((u64)arng->msi64_high << 32) |
1063 (u64) arng->msi64_low;
1064 pbm->msi32_len = arng->msi32_len;
1065 pbm->msi64_len = arng->msi64_len;
1066
1067 if (msi_bitmap_alloc(pbm))
1068 goto no_msi;
1069
1070 if (msi_queue_alloc(pbm)) {
1071 msi_bitmap_free(pbm);
1072 goto no_msi;
1073 }
1074
1075 printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] "
1076 "devino[0x%x]\n",
1077 pbm->name,
1078 pbm->msiq_first, pbm->msiq_num,
1079 pbm->msiq_ent_count,
1080 pbm->msiq_first_devino);
1081 printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] "
1082 "width[%u]\n",
1083 pbm->name,
1084 pbm->msi_first, pbm->msi_num, pbm->msi_data_mask,
1085 pbm->msix_data_width);
1086 printk(KERN_INFO "%s: MSI addr32[0x%lx:0x%x] "
1087 "addr64[0x%lx:0x%x]\n",
1088 pbm->name,
1089 pbm->msi32_start, pbm->msi32_len,
1090 pbm->msi64_start, pbm->msi64_len);
1091 printk(KERN_INFO "%s: MSI queues at RA [%p]\n",
1092 pbm->name,
1093 pbm->msi_queues);
1094 }
1095
1096 return;
1097
1098no_msi:
1099 pbm->msiq_num = 0;
1100 printk(KERN_INFO "%s: No MSI support.\n", pbm->name);
1101}
1102 994
1103static int alloc_msi(struct pci_pbm_info *pbm) 995static int alloc_msi(struct pci_pbm_info *pbm)
1104{ 996{
@@ -1217,6 +1109,117 @@ static void pci_sun4v_teardown_msi_irq(unsigned int virt_irq,
1217 */ 1109 */
1218 sun4v_destroy_msi(virt_irq); 1110 sun4v_destroy_msi(virt_irq);
1219} 1111}
1112
1113static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
1114{
1115 const u32 *val;
1116 int len;
1117
1118 val = of_get_property(pbm->prom_node, "#msi-eqs", &len);
1119 if (!val || len != 4)
1120 goto no_msi;
1121 pbm->msiq_num = *val;
1122 if (pbm->msiq_num) {
1123 const struct msiq_prop {
1124 u32 first_msiq;
1125 u32 num_msiq;
1126 u32 first_devino;
1127 } *mqp;
1128 const struct msi_range_prop {
1129 u32 first_msi;
1130 u32 num_msi;
1131 } *mrng;
1132 const struct addr_range_prop {
1133 u32 msi32_high;
1134 u32 msi32_low;
1135 u32 msi32_len;
1136 u32 msi64_high;
1137 u32 msi64_low;
1138 u32 msi64_len;
1139 } *arng;
1140
1141 val = of_get_property(pbm->prom_node, "msi-eq-size", &len);
1142 if (!val || len != 4)
1143 goto no_msi;
1144
1145 pbm->msiq_ent_count = *val;
1146
1147 mqp = of_get_property(pbm->prom_node,
1148 "msi-eq-to-devino", &len);
1149 if (!mqp || len != sizeof(struct msiq_prop))
1150 goto no_msi;
1151
1152 pbm->msiq_first = mqp->first_msiq;
1153 pbm->msiq_first_devino = mqp->first_devino;
1154
1155 val = of_get_property(pbm->prom_node, "#msi", &len);
1156 if (!val || len != 4)
1157 goto no_msi;
1158 pbm->msi_num = *val;
1159
1160 mrng = of_get_property(pbm->prom_node, "msi-ranges", &len);
1161 if (!mrng || len != sizeof(struct msi_range_prop))
1162 goto no_msi;
1163 pbm->msi_first = mrng->first_msi;
1164
1165 val = of_get_property(pbm->prom_node, "msi-data-mask", &len);
1166 if (!val || len != 4)
1167 goto no_msi;
1168 pbm->msi_data_mask = *val;
1169
1170 val = of_get_property(pbm->prom_node, "msix-data-width", &len);
1171 if (!val || len != 4)
1172 goto no_msi;
1173 pbm->msix_data_width = *val;
1174
1175 arng = of_get_property(pbm->prom_node, "msi-address-ranges",
1176 &len);
1177 if (!arng || len != sizeof(struct addr_range_prop))
1178 goto no_msi;
1179 pbm->msi32_start = ((u64)arng->msi32_high << 32) |
1180 (u64) arng->msi32_low;
1181 pbm->msi64_start = ((u64)arng->msi64_high << 32) |
1182 (u64) arng->msi64_low;
1183 pbm->msi32_len = arng->msi32_len;
1184 pbm->msi64_len = arng->msi64_len;
1185
1186 if (msi_bitmap_alloc(pbm))
1187 goto no_msi;
1188
1189 if (msi_queue_alloc(pbm)) {
1190 msi_bitmap_free(pbm);
1191 goto no_msi;
1192 }
1193
1194 printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] "
1195 "devino[0x%x]\n",
1196 pbm->name,
1197 pbm->msiq_first, pbm->msiq_num,
1198 pbm->msiq_ent_count,
1199 pbm->msiq_first_devino);
1200 printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] "
1201 "width[%u]\n",
1202 pbm->name,
1203 pbm->msi_first, pbm->msi_num, pbm->msi_data_mask,
1204 pbm->msix_data_width);
1205 printk(KERN_INFO "%s: MSI addr32[0x%lx:0x%x] "
1206 "addr64[0x%lx:0x%x]\n",
1207 pbm->name,
1208 pbm->msi32_start, pbm->msi32_len,
1209 pbm->msi64_start, pbm->msi64_len);
1210 printk(KERN_INFO "%s: MSI queues at RA [%p]\n",
1211 pbm->name,
1212 pbm->msi_queues);
1213 }
1214 pbm->setup_msi_irq = pci_sun4v_setup_msi_irq;
1215 pbm->teardown_msi_irq = pci_sun4v_teardown_msi_irq;
1216
1217 return;
1218
1219no_msi:
1220 pbm->msiq_num = 0;
1221 printk(KERN_INFO "%s: No MSI support.\n", pbm->name);
1222}
1220#else /* CONFIG_PCI_MSI */ 1223#else /* CONFIG_PCI_MSI */
1221static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) 1224static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
1222{ 1225{
@@ -1303,11 +1306,6 @@ void sun4v_pci_init(struct device_node *dp, char *model_name)
1303 1306
1304 p->index = pci_num_controllers++; 1307 p->index = pci_num_controllers++;
1305 1308
1306#ifdef CONFIG_PCI_MSI
1307 p->setup_msi_irq = pci_sun4v_setup_msi_irq;
1308 p->teardown_msi_irq = pci_sun4v_teardown_msi_irq;
1309#endif
1310
1311 /* Like PSYCHO and SCHIZO we have a 2GB aligned area 1309 /* Like PSYCHO and SCHIZO we have a 2GB aligned area
1312 * for memory space. 1310 * for memory space.
1313 */ 1311 */
diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h
index 1f4de53dcd03..1d5dcfe133a2 100644
--- a/include/asm-sparc64/pbm.h
+++ b/include/asm-sparc64/pbm.h
@@ -103,6 +103,9 @@ struct pci_pbm_info {
103 u32 msi64_len; 103 u32 msi64_len;
104 void *msi_queues; 104 void *msi_queues;
105 unsigned long *msi_bitmap; 105 unsigned long *msi_bitmap;
106 int (*setup_msi_irq)(unsigned int *virt_irq_p, struct pci_dev *pdev,
107 struct msi_desc *entry);
108 void (*teardown_msi_irq)(unsigned int virt_irq, struct pci_dev *pdev);
106#endif /* !(CONFIG_PCI_MSI) */ 109#endif /* !(CONFIG_PCI_MSI) */
107 110
108 /* This PBM's streaming buffer. */ 111 /* This PBM's streaming buffer. */
@@ -128,13 +131,6 @@ struct pci_controller_info {
128 /* The PCI bus modules controlled by us. */ 131 /* The PCI bus modules controlled by us. */
129 struct pci_pbm_info pbm_A; 132 struct pci_pbm_info pbm_A;
130 struct pci_pbm_info pbm_B; 133 struct pci_pbm_info pbm_B;
131
132 /* Operations which are controller specific. */
133#ifdef CONFIG_PCI_MSI
134 int (*setup_msi_irq)(unsigned int *virt_irq_p, struct pci_dev *pdev,
135 struct msi_desc *entry);
136 void (*teardown_msi_irq)(unsigned int virt_irq, struct pci_dev *pdev);
137#endif
138}; 134};
139 135
140#endif /* !(__SPARC64_PBM_H) */ 136#endif /* !(__SPARC64_PBM_H) */