aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/pci_sun4v.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 23:32:43 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 23:32:43 -0400
commit0c23664ee8c42f247dba7ceb620baabd892cef88 (patch)
treee3f37e3260bd938b293cfb8f70f8969b19539973 /arch/sparc64/kernel/pci_sun4v.c
parent6ec129c3a2f8b38bc37e42348470ccfcb7460146 (diff)
parent127cda1e8cc282de1ca7a9dcc3866841977b9fcc (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6: [SPARC64]: Optimize fault kprobe handling just like powerpc. [SPARC]: Wire up utimensat syscall. [SPARC64]: Fix request_irq() ignored result warnings in PCI controller code. [SPARC64]: Kill asm-sparc64/pbm.h [ATYFB]: Fix sparc includes. [QLA2XXX]: Fix build on sparc. [SPARC64]: Removal of trivial pci_controller_info uses. [SPARC64]: Move index info pci_pbm_info. [SPARC64]: Move {setup,teardown}_msi_irq into pci_pbm_info. [SPARC64]: Move pci_ops into pci_pbm_info. [SPARC64] SBUS: Error interrupt registry cleanups. [SPARC64] PCI: Use root list of pbm's instead of pci_controller_info's [SPARC64] PCI: Kill PROM_PCIRNG_MAX and PROM_PCIIMAP_MAX. [SPARC64] PCI: Use common routine to fetch PBM properties.
Diffstat (limited to 'arch/sparc64/kernel/pci_sun4v.c')
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c294
1 files changed, 128 insertions, 166 deletions
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index 1ccf4c9a9a43..0c76a8891a96 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -13,7 +13,6 @@
13#include <linux/irq.h> 13#include <linux/irq.h>
14#include <linux/msi.h> 14#include <linux/msi.h>
15 15
16#include <asm/pbm.h>
17#include <asm/iommu.h> 16#include <asm/iommu.h>
18#include <asm/irq.h> 17#include <asm/irq.h>
19#include <asm/upa.h> 18#include <asm/upa.h>
@@ -677,29 +676,15 @@ static struct pci_ops pci_sun4v_ops = {
677}; 676};
678 677
679 678
680static void pbm_scan_bus(struct pci_controller_info *p, 679static void pci_sun4v_scan_bus(struct pci_pbm_info *pbm)
681 struct pci_pbm_info *pbm)
682{
683 pbm->pci_bus = pci_scan_one_pbm(pbm);
684}
685
686static void pci_sun4v_scan_bus(struct pci_controller_info *p)
687{ 680{
688 struct property *prop; 681 struct property *prop;
689 struct device_node *dp; 682 struct device_node *dp;
690 683
691 if ((dp = p->pbm_A.prom_node) != NULL) { 684 dp = pbm->prom_node;
692 prop = of_find_property(dp, "66mhz-capable", NULL); 685 prop = of_find_property(dp, "66mhz-capable", NULL);
693 p->pbm_A.is_66mhz_capable = (prop != NULL); 686 pbm->is_66mhz_capable = (prop != NULL);
694 687 pbm->pci_bus = pci_scan_one_pbm(pbm);
695 pbm_scan_bus(p, &p->pbm_A);
696 }
697 if ((dp = p->pbm_B.prom_node) != NULL) {
698 prop = of_find_property(dp, "66mhz-capable", NULL);
699 p->pbm_B.is_66mhz_capable = (prop != NULL);
700
701 pbm_scan_bus(p, &p->pbm_B);
702 }
703 688
704 /* XXX register error interrupt handlers XXX */ 689 /* XXX register error interrupt handlers XXX */
705} 690}
@@ -802,20 +787,6 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
802 pbm->name, sz); 787 pbm->name, sz);
803} 788}
804 789
805static void pci_sun4v_get_bus_range(struct pci_pbm_info *pbm)
806{
807 struct property *prop;
808 unsigned int *busrange;
809
810 prop = of_find_property(pbm->prom_node, "bus-range", NULL);
811
812 busrange = prop->value;
813
814 pbm->pci_first_busno = busrange[0];
815 pbm->pci_last_busno = busrange[1];
816
817}
818
819#ifdef CONFIG_PCI_MSI 790#ifdef CONFIG_PCI_MSI
820struct pci_sun4v_msiq_entry { 791struct pci_sun4v_msiq_entry {
821 u64 version_type; 792 u64 version_type;
@@ -1019,114 +990,6 @@ h_error:
1019 return -EINVAL; 990 return -EINVAL;
1020} 991}
1021 992
1022static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
1023{
1024 const u32 *val;
1025 int len;
1026
1027 val = of_get_property(pbm->prom_node, "#msi-eqs", &len);
1028 if (!val || len != 4)
1029 goto no_msi;
1030 pbm->msiq_num = *val;
1031 if (pbm->msiq_num) {
1032 const struct msiq_prop {
1033 u32 first_msiq;
1034 u32 num_msiq;
1035 u32 first_devino;
1036 } *mqp;
1037 const struct msi_range_prop {
1038 u32 first_msi;
1039 u32 num_msi;
1040 } *mrng;
1041 const struct addr_range_prop {
1042 u32 msi32_high;
1043 u32 msi32_low;
1044 u32 msi32_len;
1045 u32 msi64_high;
1046 u32 msi64_low;
1047 u32 msi64_len;
1048 } *arng;
1049
1050 val = of_get_property(pbm->prom_node, "msi-eq-size", &len);
1051 if (!val || len != 4)
1052 goto no_msi;
1053
1054 pbm->msiq_ent_count = *val;
1055
1056 mqp = of_get_property(pbm->prom_node,
1057 "msi-eq-to-devino", &len);
1058 if (!mqp || len != sizeof(struct msiq_prop))
1059 goto no_msi;
1060
1061 pbm->msiq_first = mqp->first_msiq;
1062 pbm->msiq_first_devino = mqp->first_devino;
1063
1064 val = of_get_property(pbm->prom_node, "#msi", &len);
1065 if (!val || len != 4)
1066 goto no_msi;
1067 pbm->msi_num = *val;
1068
1069 mrng = of_get_property(pbm->prom_node, "msi-ranges", &len);
1070 if (!mrng || len != sizeof(struct msi_range_prop))
1071 goto no_msi;
1072 pbm->msi_first = mrng->first_msi;
1073
1074 val = of_get_property(pbm->prom_node, "msi-data-mask", &len);
1075 if (!val || len != 4)
1076 goto no_msi;
1077 pbm->msi_data_mask = *val;
1078
1079 val = of_get_property(pbm->prom_node, "msix-data-width", &len);
1080 if (!val || len != 4)
1081 goto no_msi;
1082 pbm->msix_data_width = *val;
1083
1084 arng = of_get_property(pbm->prom_node, "msi-address-ranges",
1085 &len);
1086 if (!arng || len != sizeof(struct addr_range_prop))
1087 goto no_msi;
1088 pbm->msi32_start = ((u64)arng->msi32_high << 32) |
1089 (u64) arng->msi32_low;
1090 pbm->msi64_start = ((u64)arng->msi64_high << 32) |
1091 (u64) arng->msi64_low;
1092 pbm->msi32_len = arng->msi32_len;
1093 pbm->msi64_len = arng->msi64_len;
1094
1095 if (msi_bitmap_alloc(pbm))
1096 goto no_msi;
1097
1098 if (msi_queue_alloc(pbm)) {
1099 msi_bitmap_free(pbm);
1100 goto no_msi;
1101 }
1102
1103 printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] "
1104 "devino[0x%x]\n",
1105 pbm->name,
1106 pbm->msiq_first, pbm->msiq_num,
1107 pbm->msiq_ent_count,
1108 pbm->msiq_first_devino);
1109 printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] "
1110 "width[%u]\n",
1111 pbm->name,
1112 pbm->msi_first, pbm->msi_num, pbm->msi_data_mask,
1113 pbm->msix_data_width);
1114 printk(KERN_INFO "%s: MSI addr32[0x%lx:0x%x] "
1115 "addr64[0x%lx:0x%x]\n",
1116 pbm->name,
1117 pbm->msi32_start, pbm->msi32_len,
1118 pbm->msi64_start, pbm->msi64_len);
1119 printk(KERN_INFO "%s: MSI queues at RA [%p]\n",
1120 pbm->name,
1121 pbm->msi_queues);
1122 }
1123
1124 return;
1125
1126no_msi:
1127 pbm->msiq_num = 0;
1128 printk(KERN_INFO "%s: No MSI support.\n", pbm->name);
1129}
1130 993
1131static int alloc_msi(struct pci_pbm_info *pbm) 994static int alloc_msi(struct pci_pbm_info *pbm)
1132{ 995{
@@ -1245,6 +1108,117 @@ static void pci_sun4v_teardown_msi_irq(unsigned int virt_irq,
1245 */ 1108 */
1246 sun4v_destroy_msi(virt_irq); 1109 sun4v_destroy_msi(virt_irq);
1247} 1110}
1111
1112static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
1113{
1114 const u32 *val;
1115 int len;
1116
1117 val = of_get_property(pbm->prom_node, "#msi-eqs", &len);
1118 if (!val || len != 4)
1119 goto no_msi;
1120 pbm->msiq_num = *val;
1121 if (pbm->msiq_num) {
1122 const struct msiq_prop {
1123 u32 first_msiq;
1124 u32 num_msiq;
1125 u32 first_devino;
1126 } *mqp;
1127 const struct msi_range_prop {
1128 u32 first_msi;
1129 u32 num_msi;
1130 } *mrng;
1131 const struct addr_range_prop {
1132 u32 msi32_high;
1133 u32 msi32_low;
1134 u32 msi32_len;
1135 u32 msi64_high;
1136 u32 msi64_low;
1137 u32 msi64_len;
1138 } *arng;
1139
1140 val = of_get_property(pbm->prom_node, "msi-eq-size", &len);
1141 if (!val || len != 4)
1142 goto no_msi;
1143
1144 pbm->msiq_ent_count = *val;
1145
1146 mqp = of_get_property(pbm->prom_node,
1147 "msi-eq-to-devino", &len);
1148 if (!mqp || len != sizeof(struct msiq_prop))
1149 goto no_msi;
1150
1151 pbm->msiq_first = mqp->first_msiq;
1152 pbm->msiq_first_devino = mqp->first_devino;
1153
1154 val = of_get_property(pbm->prom_node, "#msi", &len);
1155 if (!val || len != 4)
1156 goto no_msi;
1157 pbm->msi_num = *val;
1158
1159 mrng = of_get_property(pbm->prom_node, "msi-ranges", &len);
1160 if (!mrng || len != sizeof(struct msi_range_prop))
1161 goto no_msi;
1162 pbm->msi_first = mrng->first_msi;
1163
1164 val = of_get_property(pbm->prom_node, "msi-data-mask", &len);
1165 if (!val || len != 4)
1166 goto no_msi;
1167 pbm->msi_data_mask = *val;
1168
1169 val = of_get_property(pbm->prom_node, "msix-data-width", &len);
1170 if (!val || len != 4)
1171 goto no_msi;
1172 pbm->msix_data_width = *val;
1173
1174 arng = of_get_property(pbm->prom_node, "msi-address-ranges",
1175 &len);
1176 if (!arng || len != sizeof(struct addr_range_prop))
1177 goto no_msi;
1178 pbm->msi32_start = ((u64)arng->msi32_high << 32) |
1179 (u64) arng->msi32_low;
1180 pbm->msi64_start = ((u64)arng->msi64_high << 32) |
1181 (u64) arng->msi64_low;
1182 pbm->msi32_len = arng->msi32_len;
1183 pbm->msi64_len = arng->msi64_len;
1184
1185 if (msi_bitmap_alloc(pbm))
1186 goto no_msi;
1187
1188 if (msi_queue_alloc(pbm)) {
1189 msi_bitmap_free(pbm);
1190 goto no_msi;
1191 }
1192
1193 printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] "
1194 "devino[0x%x]\n",
1195 pbm->name,
1196 pbm->msiq_first, pbm->msiq_num,
1197 pbm->msiq_ent_count,
1198 pbm->msiq_first_devino);
1199 printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] "
1200 "width[%u]\n",
1201 pbm->name,
1202 pbm->msi_first, pbm->msi_num, pbm->msi_data_mask,
1203 pbm->msix_data_width);
1204 printk(KERN_INFO "%s: MSI addr32[0x%lx:0x%x] "
1205 "addr64[0x%lx:0x%x]\n",
1206 pbm->name,
1207 pbm->msi32_start, pbm->msi32_len,
1208 pbm->msi64_start, pbm->msi64_len);
1209 printk(KERN_INFO "%s: MSI queues at RA [%p]\n",
1210 pbm->name,
1211 pbm->msi_queues);
1212 }
1213 pbm->setup_msi_irq = pci_sun4v_setup_msi_irq;
1214 pbm->teardown_msi_irq = pci_sun4v_teardown_msi_irq;
1215
1216 return;
1217
1218no_msi:
1219 pbm->msiq_num = 0;
1220 printk(KERN_INFO "%s: No MSI support.\n", pbm->name);
1221}
1248#else /* CONFIG_PCI_MSI */ 1222#else /* CONFIG_PCI_MSI */
1249static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) 1223static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
1250{ 1224{
@@ -1260,6 +1234,14 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node
1260 else 1234 else
1261 pbm = &p->pbm_A; 1235 pbm = &p->pbm_A;
1262 1236
1237 pbm->next = pci_pbm_root;
1238 pci_pbm_root = pbm;
1239
1240 pbm->scan_bus = pci_sun4v_scan_bus;
1241 pbm->pci_ops = &pci_sun4v_ops;
1242
1243 pbm->index = pci_num_pbms++;
1244
1263 pbm->parent = p; 1245 pbm->parent = p;
1264 pbm->prom_node = dp; 1246 pbm->prom_node = dp;
1265 1247
@@ -1271,7 +1253,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node
1271 1253
1272 pci_determine_mem_io_space(pbm); 1254 pci_determine_mem_io_space(pbm);
1273 1255
1274 pci_sun4v_get_bus_range(pbm); 1256 pci_get_pbm_props(pbm);
1275 pci_sun4v_iommu_init(pbm); 1257 pci_sun4v_iommu_init(pbm);
1276 pci_sun4v_msi_init(pbm); 1258 pci_sun4v_msi_init(pbm);
1277} 1259}
@@ -1279,6 +1261,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node
1279void sun4v_pci_init(struct device_node *dp, char *model_name) 1261void sun4v_pci_init(struct device_node *dp, char *model_name)
1280{ 1262{
1281 struct pci_controller_info *p; 1263 struct pci_controller_info *p;
1264 struct pci_pbm_info *pbm;
1282 struct iommu *iommu; 1265 struct iommu *iommu;
1283 struct property *prop; 1266 struct property *prop;
1284 struct linux_prom64_registers *regs; 1267 struct linux_prom64_registers *regs;
@@ -1290,18 +1273,9 @@ void sun4v_pci_init(struct device_node *dp, char *model_name)
1290 1273
1291 devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; 1274 devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff;
1292 1275
1293 for (p = pci_controller_root; p; p = p->next) { 1276 for (pbm = pci_pbm_root; pbm; pbm = pbm->next) {
1294 struct pci_pbm_info *pbm;
1295
1296 if (p->pbm_A.prom_node && p->pbm_B.prom_node)
1297 continue;
1298
1299 pbm = (p->pbm_A.prom_node ?
1300 &p->pbm_A :
1301 &p->pbm_B);
1302
1303 if (pbm->devhandle == (devhandle ^ 0x40)) { 1277 if (pbm->devhandle == (devhandle ^ 0x40)) {
1304 pci_sun4v_pbm_init(p, dp, devhandle); 1278 pci_sun4v_pbm_init(pbm->parent, dp, devhandle);
1305 return; 1279 return;
1306 } 1280 }
1307 } 1281 }
@@ -1331,18 +1305,6 @@ void sun4v_pci_init(struct device_node *dp, char *model_name)
1331 1305
1332 p->pbm_B.iommu = iommu; 1306 p->pbm_B.iommu = iommu;
1333 1307
1334 p->next = pci_controller_root;
1335 pci_controller_root = p;
1336
1337 p->index = pci_num_controllers++;
1338
1339 p->scan_bus = pci_sun4v_scan_bus;
1340#ifdef CONFIG_PCI_MSI
1341 p->setup_msi_irq = pci_sun4v_setup_msi_irq;
1342 p->teardown_msi_irq = pci_sun4v_teardown_msi_irq;
1343#endif
1344 p->pci_ops = &pci_sun4v_ops;
1345
1346 /* Like PSYCHO and SCHIZO we have a 2GB aligned area 1308 /* Like PSYCHO and SCHIZO we have a 2GB aligned area
1347 * for memory space. 1309 * for memory space.
1348 */ 1310 */