diff options
Diffstat (limited to 'arch/sparc64/kernel/pci_sun4v.c')
-rw-r--r-- | arch/sparc64/kernel/pci_sun4v.c | 224 |
1 files changed, 111 insertions, 113 deletions
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 | ||
994 | static 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 | |||
1098 | no_msi: | ||
1099 | pbm->msiq_num = 0; | ||
1100 | printk(KERN_INFO "%s: No MSI support.\n", pbm->name); | ||
1101 | } | ||
1102 | 994 | ||
1103 | static int alloc_msi(struct pci_pbm_info *pbm) | 995 | static 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 | |||
1113 | static 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 | |||
1219 | no_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 */ |
1221 | static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) | 1224 | static 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 | */ |