aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-02-10 20:41:02 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2007-02-11 02:50:37 -0500
commit35a17eb6a87c9ceb0d35dcb51f464fe6faf584ab (patch)
tree7f56095a56e9f62dca7514cdfe781739548011f5 /arch/sparc64
parent68c921869491c119142612fa5796c9f8b4e9970b (diff)
[SPARC64]: Add PCI MSI support on Niagara.
This is kind of hokey, we could use the hardware provided facilities much better. MSIs are assosciated with MSI Queues. MSI Queues generate interrupts when any MSI assosciated with it is signalled. This suggests a two-tiered IRQ dispatch scheme: MSI Queue interrupt --> queue interrupt handler MSI dispatch --> driver interrupt handler But we just get one-level under Linux currently. What I'd like to do is possibly stick the IRQ actions into a per-MSI-Queue data structure, and dispatch them form there, but the generic IRQ layer doesn't provide a way to do that right now. So, the current kludge is to "ACK" the interrupt by processing the MSI Queue data structures and ACK'ing them, then we run the actual handler like normal. We are wasting a lot of useful information, for example the MSI data and address are provided with ever MSI, as well as a system tick if available. If we could pass this into the IRQ handler it could help with certain things, in particular for PCI-Express error messages. The MSI entries on sparc64 also tell you exactly which bus/device/fn sent the MSI, which would be great for error handling when no registered IRQ handler can service the interrupt. We override the disable/enable IRQ chip methods in sun4v_msi, so we have to call {mask,unmask}_msi_irq() directly from there. This is another ugly wart. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64')
-rw-r--r--arch/sparc64/kernel/irq.c104
-rw-r--r--arch/sparc64/kernel/pci.c35
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c444
-rw-r--r--arch/sparc64/kernel/pci_sun4v.h61
-rw-r--r--arch/sparc64/kernel/pci_sun4v_asm.S266
5 files changed, 901 insertions, 9 deletions
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 2873835e2626..b5ff3ee5ace1 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -22,6 +22,7 @@
22#include <linux/seq_file.h> 22#include <linux/seq_file.h>
23#include <linux/bootmem.h> 23#include <linux/bootmem.h>
24#include <linux/irq.h> 24#include <linux/irq.h>
25#include <linux/msi.h>
25 26
26#include <asm/ptrace.h> 27#include <asm/ptrace.h>
27#include <asm/processor.h> 28#include <asm/processor.h>
@@ -87,7 +88,6 @@ struct ino_bucket ivector_table[NUM_IVECS] __attribute__ ((aligned (SMP_CACHE_BY
87#define irq_work(__cpu) &(trap_block[(__cpu)].irq_worklist) 88#define irq_work(__cpu) &(trap_block[(__cpu)].irq_worklist)
88 89
89static unsigned int virt_to_real_irq_table[NR_IRQS]; 90static unsigned int virt_to_real_irq_table[NR_IRQS];
90static unsigned char virt_irq_cur = 1;
91 91
92static unsigned char virt_irq_alloc(unsigned int real_irq) 92static unsigned char virt_irq_alloc(unsigned int real_irq)
93{ 93{
@@ -95,26 +95,32 @@ static unsigned char virt_irq_alloc(unsigned int real_irq)
95 95
96 BUILD_BUG_ON(NR_IRQS >= 256); 96 BUILD_BUG_ON(NR_IRQS >= 256);
97 97
98 ent = virt_irq_cur; 98 for (ent = 1; ent < NR_IRQS; ent++) {
99 if (!virt_to_real_irq_table[ent])
100 break;
101 }
99 if (ent >= NR_IRQS) { 102 if (ent >= NR_IRQS) {
100 printk(KERN_ERR "IRQ: Out of virtual IRQs.\n"); 103 printk(KERN_ERR "IRQ: Out of virtual IRQs.\n");
101 return 0; 104 return 0;
102 } 105 }
103 106
104 virt_irq_cur = ent + 1;
105 virt_to_real_irq_table[ent] = real_irq; 107 virt_to_real_irq_table[ent] = real_irq;
106 108
107 return ent; 109 return ent;
108} 110}
109 111
110#if 0 /* Currently unused. */ 112static void virt_irq_free(unsigned int virt_irq)
111static unsigned char real_to_virt_irq(unsigned int real_irq)
112{ 113{
113 struct ino_bucket *bucket = __bucket(real_irq); 114 unsigned int real_irq;
114 115
115 return bucket->virt_irq; 116 if (virt_irq >= NR_IRQS)
117 return;
118
119 real_irq = virt_to_real_irq_table[virt_irq];
120 virt_to_real_irq_table[virt_irq] = 0;
121
122 __bucket(real_irq)->virt_irq = 0;
116} 123}
117#endif
118 124
119static unsigned int virt_to_real_irq(unsigned char virt_irq) 125static unsigned int virt_to_real_irq(unsigned char virt_irq)
120{ 126{
@@ -341,6 +347,20 @@ static void sun4v_irq_disable(unsigned int virt_irq)
341 } 347 }
342} 348}
343 349
350#ifdef CONFIG_PCI_MSI
351static void sun4v_msi_enable(unsigned int virt_irq)
352{
353 sun4v_irq_enable(virt_irq);
354 unmask_msi_irq(virt_irq);
355}
356
357static void sun4v_msi_disable(unsigned int virt_irq)
358{
359 mask_msi_irq(virt_irq);
360 sun4v_irq_disable(virt_irq);
361}
362#endif
363
344static void sun4v_irq_end(unsigned int virt_irq) 364static void sun4v_irq_end(unsigned int virt_irq)
345{ 365{
346 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 366 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
@@ -398,6 +418,18 @@ static struct irq_chip sun4v_irq_ack = {
398 .end = sun4v_irq_end, 418 .end = sun4v_irq_end,
399}; 419};
400 420
421#ifdef CONFIG_PCI_MSI
422static struct irq_chip sun4v_msi = {
423 .typename = "sun4v+msi",
424 .mask = mask_msi_irq,
425 .unmask = unmask_msi_irq,
426 .enable = sun4v_msi_enable,
427 .disable = sun4v_msi_disable,
428 .ack = run_pre_handler,
429 .end = sun4v_irq_end,
430};
431#endif
432
401void irq_install_pre_handler(int virt_irq, 433void irq_install_pre_handler(int virt_irq,
402 void (*func)(unsigned int, void *, void *), 434 void (*func)(unsigned int, void *, void *),
403 void *arg1, void *arg2) 435 void *arg1, void *arg2)
@@ -411,7 +443,11 @@ void irq_install_pre_handler(int virt_irq,
411 443
412 chip = get_irq_chip(virt_irq); 444 chip = get_irq_chip(virt_irq);
413 if (chip == &sun4u_irq_ack || 445 if (chip == &sun4u_irq_ack ||
414 chip == &sun4v_irq_ack) 446 chip == &sun4v_irq_ack
447#ifdef CONFIG_PCI_MSI
448 || chip == &sun4v_msi
449#endif
450 )
415 return; 451 return;
416 452
417 chip = (chip == &sun4u_irq ? 453 chip = (chip == &sun4u_irq ?
@@ -489,6 +525,56 @@ out:
489 return bucket->virt_irq; 525 return bucket->virt_irq;
490} 526}
491 527
528#ifdef CONFIG_PCI_MSI
529unsigned int sun4v_build_msi(u32 devhandle, unsigned int *virt_irq_p,
530 unsigned int msi_start, unsigned int msi_end)
531{
532 struct ino_bucket *bucket;
533 struct irq_handler_data *data;
534 unsigned long sysino;
535 unsigned int devino;
536
537 BUG_ON(tlb_type != hypervisor);
538
539 /* Find a free devino in the given range. */
540 for (devino = msi_start; devino < msi_end; devino++) {
541 sysino = sun4v_devino_to_sysino(devhandle, devino);
542 bucket = &ivector_table[sysino];
543 if (!bucket->virt_irq)
544 break;
545 }
546 if (devino >= msi_end)
547 return 0;
548
549 sysino = sun4v_devino_to_sysino(devhandle, devino);
550 bucket = &ivector_table[sysino];
551 bucket->virt_irq = virt_irq_alloc(__irq(bucket));
552 *virt_irq_p = bucket->virt_irq;
553 set_irq_chip(bucket->virt_irq, &sun4v_msi);
554
555 data = get_irq_chip_data(bucket->virt_irq);
556 if (unlikely(data))
557 return devino;
558
559 data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC);
560 if (unlikely(!data)) {
561 prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n");
562 prom_halt();
563 }
564 set_irq_chip_data(bucket->virt_irq, data);
565
566 data->imap = ~0UL;
567 data->iclr = ~0UL;
568
569 return devino;
570}
571
572void sun4v_destroy_msi(unsigned int virt_irq)
573{
574 virt_irq_free(virt_irq);
575}
576#endif
577
492void ack_bad_irq(unsigned int virt_irq) 578void ack_bad_irq(unsigned int virt_irq)
493{ 579{
494 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 580 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index dfc41cd4bb5d..6b740eb6fe7e 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -13,6 +13,8 @@
13#include <linux/capability.h> 13#include <linux/capability.h>
14#include <linux/errno.h> 14#include <linux/errno.h>
15#include <linux/smp_lock.h> 15#include <linux/smp_lock.h>
16#include <linux/msi.h>
17#include <linux/irq.h>
16#include <linux/init.h> 18#include <linux/init.h>
17 19
18#include <asm/uaccess.h> 20#include <asm/uaccess.h>
@@ -646,4 +648,37 @@ int pci_domain_nr(struct pci_bus *pbus)
646} 648}
647EXPORT_SYMBOL(pci_domain_nr); 649EXPORT_SYMBOL(pci_domain_nr);
648 650
651#ifdef CONFIG_PCI_MSI
652int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
653{
654 struct pcidev_cookie *pcp = pdev->sysdata;
655 struct pci_pbm_info *pbm = pcp->pbm;
656 struct pci_controller_info *p = pbm->parent;
657 int virt_irq, err;
658
659 if (!pbm->msi_num || !p->setup_msi_irq)
660 return -EINVAL;
661
662 err = p->setup_msi_irq(&virt_irq, pdev, desc);
663 if (err < 0)
664 return err;
665
666 return virt_irq;
667}
668
669void arch_teardown_msi_irq(unsigned int virt_irq)
670{
671 struct msi_desc *entry = get_irq_data(virt_irq);
672 struct pci_dev *pdev = entry->dev;
673 struct pcidev_cookie *pcp = pdev->sysdata;
674 struct pci_pbm_info *pbm = pcp->pbm;
675 struct pci_controller_info *p = pbm->parent;
676
677 if (!pbm->msi_num || !p->setup_msi_irq)
678 return;
679
680 return p->teardown_msi_irq(virt_irq, pdev);
681}
682#endif /* !(CONFIG_PCI_MSI) */
683
649#endif /* !(CONFIG_PCI) */ 684#endif /* !(CONFIG_PCI) */
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index 6b04794b7a97..ec22cd61ec8c 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -10,6 +10,8 @@
10#include <linux/slab.h> 10#include <linux/slab.h>
11#include <linux/interrupt.h> 11#include <linux/interrupt.h>
12#include <linux/percpu.h> 12#include <linux/percpu.h>
13#include <linux/irq.h>
14#include <linux/msi.h>
13 15
14#include <asm/pbm.h> 16#include <asm/pbm.h>
15#include <asm/iommu.h> 17#include <asm/iommu.h>
@@ -1074,6 +1076,443 @@ static void pci_sun4v_get_bus_range(struct pci_pbm_info *pbm)
1074 1076
1075} 1077}
1076 1078
1079#ifdef CONFIG_PCI_MSI
1080struct pci_sun4v_msiq_entry {
1081 u64 version_type;
1082#define MSIQ_VERSION_MASK 0xffffffff00000000UL
1083#define MSIQ_VERSION_SHIFT 32
1084#define MSIQ_TYPE_MASK 0x00000000000000ffUL
1085#define MSIQ_TYPE_SHIFT 0
1086#define MSIQ_TYPE_NONE 0x00
1087#define MSIQ_TYPE_MSG 0x01
1088#define MSIQ_TYPE_MSI32 0x02
1089#define MSIQ_TYPE_MSI64 0x03
1090#define MSIQ_TYPE_INTX 0x08
1091#define MSIQ_TYPE_NONE2 0xff
1092
1093 u64 intx_sysino;
1094 u64 reserved1;
1095 u64 stick;
1096 u64 req_id; /* bus/device/func */
1097#define MSIQ_REQID_BUS_MASK 0xff00UL
1098#define MSIQ_REQID_BUS_SHIFT 8
1099#define MSIQ_REQID_DEVICE_MASK 0x00f8UL
1100#define MSIQ_REQID_DEVICE_SHIFT 3
1101#define MSIQ_REQID_FUNC_MASK 0x0007UL
1102#define MSIQ_REQID_FUNC_SHIFT 0
1103
1104 u64 msi_address;
1105
1106 /* The format of this value is message type dependant.
1107 * For MSI bits 15:0 are the data from the MSI packet.
1108 * For MSI-X bits 31:0 are the data from the MSI packet.
1109 * For MSG, the message code and message routing code where:
1110 * bits 39:32 is the bus/device/fn of the msg target-id
1111 * bits 18:16 is the message routing code
1112 * bits 7:0 is the message code
1113 * For INTx the low order 2-bits are:
1114 * 00 - INTA
1115 * 01 - INTB
1116 * 10 - INTC
1117 * 11 - INTD
1118 */
1119 u64 msi_data;
1120
1121 u64 reserved2;
1122};
1123
1124/* For now this just runs as a pre-handler for the real interrupt handler.
1125 * So we just walk through the queue and ACK all the entries, update the
1126 * head pointer, and return.
1127 *
1128 * In the longer term it would be nice to do something more integrated
1129 * wherein we can pass in some of this MSI info to the drivers. This
1130 * would be most useful for PCIe fabric error messages, although we could
1131 * invoke those directly from the loop here in order to pass the info around.
1132 */
1133static void pci_sun4v_msi_prehandler(unsigned int ino, void *data1, void *data2)
1134{
1135 struct pci_pbm_info *pbm = data1;
1136 struct pci_sun4v_msiq_entry *base, *ep;
1137 unsigned long msiqid, orig_head, head, type, err;
1138
1139 msiqid = (unsigned long) data2;
1140
1141 head = 0xdeadbeef;
1142 err = pci_sun4v_msiq_gethead(pbm->devhandle, msiqid, &head);
1143 if (unlikely(err))
1144 goto hv_error_get;
1145
1146 if (unlikely(head >= (pbm->msiq_ent_count * sizeof(struct pci_sun4v_msiq_entry))))
1147 goto bad_offset;
1148
1149 head /= sizeof(struct pci_sun4v_msiq_entry);
1150 orig_head = head;
1151 base = (pbm->msi_queues + ((msiqid - pbm->msiq_first) *
1152 (pbm->msiq_ent_count *
1153 sizeof(struct pci_sun4v_msiq_entry))));
1154 ep = &base[head];
1155 while ((ep->version_type & MSIQ_TYPE_MASK) != 0) {
1156 type = (ep->version_type & MSIQ_TYPE_MASK) >> MSIQ_TYPE_SHIFT;
1157 if (unlikely(type != MSIQ_TYPE_MSI32 &&
1158 type != MSIQ_TYPE_MSI64))
1159 goto bad_type;
1160
1161 pci_sun4v_msi_setstate(pbm->devhandle,
1162 ep->msi_data /* msi_num */,
1163 HV_MSISTATE_IDLE);
1164
1165 /* Clear the entry. */
1166 ep->version_type &= ~MSIQ_TYPE_MASK;
1167
1168 /* Go to next entry in ring. */
1169 head++;
1170 if (head >= pbm->msiq_ent_count)
1171 head = 0;
1172 ep = &base[head];
1173 }
1174
1175 if (likely(head != orig_head)) {
1176 /* ACK entries by updating head pointer. */
1177 head *= sizeof(struct pci_sun4v_msiq_entry);
1178 err = pci_sun4v_msiq_sethead(pbm->devhandle, msiqid, head);
1179 if (unlikely(err))
1180 goto hv_error_set;
1181 }
1182 return;
1183
1184hv_error_set:
1185 printk(KERN_EMERG "MSI: Hypervisor set head gives error %lu\n", err);
1186 goto hv_error_cont;
1187
1188hv_error_get:
1189 printk(KERN_EMERG "MSI: Hypervisor get head gives error %lu\n", err);
1190
1191hv_error_cont:
1192 printk(KERN_EMERG "MSI: devhandle[%x] msiqid[%lx] head[%lu]\n",
1193 pbm->devhandle, msiqid, head);
1194 return;
1195
1196bad_offset:
1197 printk(KERN_EMERG "MSI: Hypervisor gives bad offset %lx max(%lx)\n",
1198 head, pbm->msiq_ent_count * sizeof(struct pci_sun4v_msiq_entry));
1199 return;
1200
1201bad_type:
1202 printk(KERN_EMERG "MSI: Entry has bad type %lx\n", type);
1203 return;
1204}
1205
1206static int msi_bitmap_alloc(struct pci_pbm_info *pbm)
1207{
1208 unsigned long size, bits_per_ulong;
1209
1210 bits_per_ulong = sizeof(unsigned long) * 8;
1211 size = (pbm->msi_num + (bits_per_ulong - 1)) & ~(bits_per_ulong - 1);
1212 size /= 8;
1213 BUG_ON(size % sizeof(unsigned long));
1214
1215 pbm->msi_bitmap = kzalloc(size, GFP_KERNEL);
1216 if (!pbm->msi_bitmap)
1217 return -ENOMEM;
1218
1219 return 0;
1220}
1221
1222static void msi_bitmap_free(struct pci_pbm_info *pbm)
1223{
1224 kfree(pbm->msi_bitmap);
1225 pbm->msi_bitmap = NULL;
1226}
1227
1228static int msi_queue_alloc(struct pci_pbm_info *pbm)
1229{
1230 unsigned long q_size, alloc_size, pages, order;
1231 int i;
1232
1233 q_size = pbm->msiq_ent_count * sizeof(struct pci_sun4v_msiq_entry);
1234 alloc_size = (pbm->msiq_num * q_size);
1235 order = get_order(alloc_size);
1236 pages = __get_free_pages(GFP_KERNEL | __GFP_COMP, order);
1237 if (pages == 0UL) {
1238 printk(KERN_ERR "MSI: Cannot allocate MSI queues (o=%lu).\n",
1239 order);
1240 return -ENOMEM;
1241 }
1242 memset((char *)pages, 0, PAGE_SIZE << order);
1243 pbm->msi_queues = (void *) pages;
1244
1245 for (i = 0; i < pbm->msiq_num; i++) {
1246 unsigned long err, base = __pa(pages + (i * q_size));
1247 unsigned long ret1, ret2;
1248
1249 err = pci_sun4v_msiq_conf(pbm->devhandle,
1250 pbm->msiq_first + i,
1251 base, pbm->msiq_ent_count);
1252 if (err) {
1253 printk(KERN_ERR "MSI: msiq register fails (err=%lu)\n",
1254 err);
1255 goto h_error;
1256 }
1257
1258 err = pci_sun4v_msiq_info(pbm->devhandle,
1259 pbm->msiq_first + i,
1260 &ret1, &ret2);
1261 if (err) {
1262 printk(KERN_ERR "MSI: Cannot read msiq (err=%lu)\n",
1263 err);
1264 goto h_error;
1265 }
1266 if (ret1 != base || ret2 != pbm->msiq_ent_count) {
1267 printk(KERN_ERR "MSI: Bogus qconf "
1268 "expected[%lx:%x] got[%lx:%lx]\n",
1269 base, pbm->msiq_ent_count,
1270 ret1, ret2);
1271 goto h_error;
1272 }
1273 }
1274
1275 return 0;
1276
1277h_error:
1278 free_pages(pages, order);
1279 return -EINVAL;
1280}
1281
1282static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
1283{
1284 u32 *val;
1285 int len;
1286
1287 val = of_get_property(pbm->prom_node, "#msi-eqs", &len);
1288 if (!val || len != 4)
1289 goto no_msi;
1290 pbm->msiq_num = *val;
1291 if (pbm->msiq_num) {
1292 struct msiq_prop {
1293 u32 first_msiq;
1294 u32 num_msiq;
1295 u32 first_devino;
1296 } *mqp;
1297 struct msi_range_prop {
1298 u32 first_msi;
1299 u32 num_msi;
1300 } *mrng;
1301 struct addr_range_prop {
1302 u32 msi32_high;
1303 u32 msi32_low;
1304 u32 msi32_len;
1305 u32 msi64_high;
1306 u32 msi64_low;
1307 u32 msi64_len;
1308 } *arng;
1309
1310 val = of_get_property(pbm->prom_node, "msi-eq-size", &len);
1311 if (!val || len != 4)
1312 goto no_msi;
1313
1314 pbm->msiq_ent_count = *val;
1315
1316 mqp = of_get_property(pbm->prom_node,
1317 "msi-eq-to-devino", &len);
1318 if (!mqp || len != sizeof(struct msiq_prop))
1319 goto no_msi;
1320
1321 pbm->msiq_first = mqp->first_msiq;
1322 pbm->msiq_first_devino = mqp->first_devino;
1323
1324 val = of_get_property(pbm->prom_node, "#msi", &len);
1325 if (!val || len != 4)
1326 goto no_msi;
1327 pbm->msi_num = *val;
1328
1329 mrng = of_get_property(pbm->prom_node, "msi-ranges", &len);
1330 if (!mrng || len != sizeof(struct msi_range_prop))
1331 goto no_msi;
1332 pbm->msi_first = mrng->first_msi;
1333
1334 val = of_get_property(pbm->prom_node, "msi-data-mask", &len);
1335 if (!val || len != 4)
1336 goto no_msi;
1337 pbm->msi_data_mask = *val;
1338
1339 val = of_get_property(pbm->prom_node, "msix-data-width", &len);
1340 if (!val || len != 4)
1341 goto no_msi;
1342 pbm->msix_data_width = *val;
1343
1344 arng = of_get_property(pbm->prom_node, "msi-address-ranges",
1345 &len);
1346 if (!arng || len != sizeof(struct addr_range_prop))
1347 goto no_msi;
1348 pbm->msi32_start = ((u64)arng->msi32_high << 32) |
1349 (u64) arng->msi32_low;
1350 pbm->msi64_start = ((u64)arng->msi64_high << 32) |
1351 (u64) arng->msi64_low;
1352 pbm->msi32_len = arng->msi32_len;
1353 pbm->msi64_len = arng->msi64_len;
1354
1355 if (msi_bitmap_alloc(pbm))
1356 goto no_msi;
1357
1358 if (msi_queue_alloc(pbm)) {
1359 msi_bitmap_free(pbm);
1360 goto no_msi;
1361 }
1362
1363 printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] "
1364 "devino[0x%x]\n",
1365 pbm->name,
1366 pbm->msiq_first, pbm->msiq_num,
1367 pbm->msiq_ent_count,
1368 pbm->msiq_first_devino);
1369 printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] "
1370 "width[%u]\n",
1371 pbm->name,
1372 pbm->msi_first, pbm->msi_num, pbm->msi_data_mask,
1373 pbm->msix_data_width);
1374 printk(KERN_INFO "%s: MSI addr32[0x%lx:0x%x] "
1375 "addr64[0x%lx:0x%x]\n",
1376 pbm->name,
1377 pbm->msi32_start, pbm->msi32_len,
1378 pbm->msi64_start, pbm->msi64_len);
1379 printk(KERN_INFO "%s: MSI queues at RA [%p]\n",
1380 pbm->name,
1381 pbm->msi_queues);
1382 }
1383
1384 return;
1385
1386no_msi:
1387 pbm->msiq_num = 0;
1388 printk(KERN_INFO "%s: No MSI support.\n", pbm->name);
1389}
1390
1391static int alloc_msi(struct pci_pbm_info *pbm)
1392{
1393 int i;
1394
1395 for (i = 0; i < pbm->msi_num; i++) {
1396 if (!test_and_set_bit(i, pbm->msi_bitmap))
1397 return i + pbm->msi_first;
1398 }
1399
1400 return -ENOENT;
1401}
1402
1403static void free_msi(struct pci_pbm_info *pbm, int msi_num)
1404{
1405 msi_num -= pbm->msi_first;
1406 clear_bit(msi_num, pbm->msi_bitmap);
1407}
1408
1409static int pci_sun4v_setup_msi_irq(unsigned int *virt_irq_p,
1410 struct pci_dev *pdev,
1411 struct msi_desc *entry)
1412{
1413 struct pcidev_cookie *pcp = pdev->sysdata;
1414 struct pci_pbm_info *pbm = pcp->pbm;
1415 unsigned long devino, msiqid;
1416 struct msi_msg msg;
1417 int msi_num, err;
1418
1419 *virt_irq_p = 0;
1420
1421 msi_num = alloc_msi(pbm);
1422 if (msi_num < 0)
1423 return msi_num;
1424
1425 devino = sun4v_build_msi(pbm->devhandle, virt_irq_p,
1426 pbm->msiq_first_devino,
1427 (pbm->msiq_first_devino +
1428 pbm->msiq_num));
1429 err = -ENOMEM;
1430 if (!devino)
1431 goto out_err;
1432
1433 set_irq_msi(*virt_irq_p, entry);
1434
1435 msiqid = ((devino - pbm->msiq_first_devino) +
1436 pbm->msiq_first);
1437
1438 err = -EINVAL;
1439 if (pci_sun4v_msiq_setstate(pbm->devhandle, msiqid, HV_MSIQSTATE_IDLE))
1440 if (err)
1441 goto out_err;
1442
1443 if (pci_sun4v_msiq_setvalid(pbm->devhandle, msiqid, HV_MSIQ_VALID))
1444 goto out_err;
1445
1446 if (pci_sun4v_msi_setmsiq(pbm->devhandle,
1447 msi_num, msiqid,
1448 (entry->msi_attrib.is_64 ?
1449 HV_MSITYPE_MSI64 : HV_MSITYPE_MSI32)))
1450 goto out_err;
1451
1452 if (pci_sun4v_msi_setstate(pbm->devhandle, msi_num, HV_MSISTATE_IDLE))
1453 goto out_err;
1454
1455 if (pci_sun4v_msi_setvalid(pbm->devhandle, msi_num, HV_MSIVALID_VALID))
1456 goto out_err;
1457
1458 pcp->msi_num = msi_num;
1459
1460 if (entry->msi_attrib.is_64) {
1461 msg.address_hi = pbm->msi64_start >> 32;
1462 msg.address_lo = pbm->msi64_start & 0xffffffff;
1463 } else {
1464 msg.address_hi = 0;
1465 msg.address_lo = pbm->msi32_start;
1466 }
1467 msg.data = msi_num;
1468 write_msi_msg(*virt_irq_p, &msg);
1469
1470 irq_install_pre_handler(*virt_irq_p,
1471 pci_sun4v_msi_prehandler,
1472 pbm, (void *) msiqid);
1473
1474 return 0;
1475
1476out_err:
1477 free_msi(pbm, msi_num);
1478 sun4v_destroy_msi(*virt_irq_p);
1479 *virt_irq_p = 0;
1480 return err;
1481
1482}
1483
1484static void pci_sun4v_teardown_msi_irq(unsigned int virt_irq,
1485 struct pci_dev *pdev)
1486{
1487 struct pcidev_cookie *pcp = pdev->sysdata;
1488 struct pci_pbm_info *pbm = pcp->pbm;
1489 unsigned long msiqid, err;
1490 unsigned int msi_num;
1491
1492 msi_num = pcp->msi_num;
1493 err = pci_sun4v_msi_getmsiq(pbm->devhandle, msi_num, &msiqid);
1494 if (err) {
1495 printk(KERN_ERR "%s: getmsiq gives error %lu\n",
1496 pbm->name, err);
1497 return;
1498 }
1499
1500 pci_sun4v_msi_setvalid(pbm->devhandle, msi_num, HV_MSIVALID_INVALID);
1501 pci_sun4v_msiq_setvalid(pbm->devhandle, msiqid, HV_MSIQ_INVALID);
1502
1503 free_msi(pbm, msi_num);
1504
1505 /* The sun4v_destroy_msi() will liberate the devino and thus the MSIQ
1506 * allocation.
1507 */
1508 sun4v_destroy_msi(virt_irq);
1509}
1510#else /* CONFIG_PCI_MSI */
1511static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
1512{
1513}
1514#endif /* !(CONFIG_PCI_MSI) */
1515
1077static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 devhandle) 1516static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 devhandle)
1078{ 1517{
1079 struct pci_pbm_info *pbm; 1518 struct pci_pbm_info *pbm;
@@ -1119,6 +1558,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node
1119 1558
1120 pci_sun4v_get_bus_range(pbm); 1559 pci_sun4v_get_bus_range(pbm);
1121 pci_sun4v_iommu_init(pbm); 1560 pci_sun4v_iommu_init(pbm);
1561 pci_sun4v_msi_init(pbm);
1122 1562
1123 pdev_htab_populate(pbm); 1563 pdev_htab_populate(pbm);
1124} 1564}
@@ -1187,6 +1627,10 @@ void sun4v_pci_init(struct device_node *dp, char *model_name)
1187 p->scan_bus = pci_sun4v_scan_bus; 1627 p->scan_bus = pci_sun4v_scan_bus;
1188 p->base_address_update = pci_sun4v_base_address_update; 1628 p->base_address_update = pci_sun4v_base_address_update;
1189 p->resource_adjust = pci_sun4v_resource_adjust; 1629 p->resource_adjust = pci_sun4v_resource_adjust;
1630#ifdef CONFIG_PCI_MSI
1631 p->setup_msi_irq = pci_sun4v_setup_msi_irq;
1632 p->teardown_msi_irq = pci_sun4v_teardown_msi_irq;
1633#endif
1190 p->pci_ops = &pci_sun4v_ops; 1634 p->pci_ops = &pci_sun4v_ops;
1191 1635
1192 /* Like PSYCHO and SCHIZO we have a 2GB aligned area 1636 /* Like PSYCHO and SCHIZO we have a 2GB aligned area
diff --git a/arch/sparc64/kernel/pci_sun4v.h b/arch/sparc64/kernel/pci_sun4v.h
index 884d25f6158d..8e9fc3a5b4f5 100644
--- a/arch/sparc64/kernel/pci_sun4v.h
+++ b/arch/sparc64/kernel/pci_sun4v.h
@@ -28,4 +28,65 @@ extern int pci_sun4v_config_put(unsigned long devhandle,
28 unsigned long size, 28 unsigned long size,
29 unsigned long data); 29 unsigned long data);
30 30
31extern unsigned long pci_sun4v_msiq_conf(unsigned long devhandle,
32 unsigned long msiqid,
33 unsigned long msiq_paddr,
34 unsigned long num_entries);
35extern unsigned long pci_sun4v_msiq_info(unsigned long devhandle,
36 unsigned long msiqid,
37 unsigned long *msiq_paddr,
38 unsigned long *num_entries);
39extern unsigned long pci_sun4v_msiq_getvalid(unsigned long devhandle,
40 unsigned long msiqid,
41 unsigned long *valid);
42extern unsigned long pci_sun4v_msiq_setvalid(unsigned long devhandle,
43 unsigned long msiqid,
44 unsigned long valid);
45extern unsigned long pci_sun4v_msiq_getstate(unsigned long devhandle,
46 unsigned long msiqid,
47 unsigned long *state);
48extern unsigned long pci_sun4v_msiq_setstate(unsigned long devhandle,
49 unsigned long msiqid,
50 unsigned long state);
51extern unsigned long pci_sun4v_msiq_gethead(unsigned long devhandle,
52 unsigned long msiqid,
53 unsigned long *head);
54extern unsigned long pci_sun4v_msiq_sethead(unsigned long devhandle,
55 unsigned long msiqid,
56 unsigned long head);
57extern unsigned long pci_sun4v_msiq_gettail(unsigned long devhandle,
58 unsigned long msiqid,
59 unsigned long *head);
60extern unsigned long pci_sun4v_msi_getvalid(unsigned long devhandle,
61 unsigned long msinum,
62 unsigned long *valid);
63extern unsigned long pci_sun4v_msi_setvalid(unsigned long devhandle,
64 unsigned long msinum,
65 unsigned long valid);
66extern unsigned long pci_sun4v_msi_getmsiq(unsigned long devhandle,
67 unsigned long msinum,
68 unsigned long *msiq);
69extern unsigned long pci_sun4v_msi_setmsiq(unsigned long devhandle,
70 unsigned long msinum,
71 unsigned long msiq,
72 unsigned long msitype);
73extern unsigned long pci_sun4v_msi_getstate(unsigned long devhandle,
74 unsigned long msinum,
75 unsigned long *state);
76extern unsigned long pci_sun4v_msi_setstate(unsigned long devhandle,
77 unsigned long msinum,
78 unsigned long state);
79extern unsigned long pci_sun4v_msg_getmsiq(unsigned long devhandle,
80 unsigned long msinum,
81 unsigned long *msiq);
82extern unsigned long pci_sun4v_msg_setmsiq(unsigned long devhandle,
83 unsigned long msinum,
84 unsigned long msiq);
85extern unsigned long pci_sun4v_msg_getvalid(unsigned long devhandle,
86 unsigned long msinum,
87 unsigned long *valid);
88extern unsigned long pci_sun4v_msg_setvalid(unsigned long devhandle,
89 unsigned long msinum,
90 unsigned long valid);
91
31#endif /* !(_PCI_SUN4V_H) */ 92#endif /* !(_PCI_SUN4V_H) */
diff --git a/arch/sparc64/kernel/pci_sun4v_asm.S b/arch/sparc64/kernel/pci_sun4v_asm.S
index 6604fdbf746c..ecb81f389b06 100644
--- a/arch/sparc64/kernel/pci_sun4v_asm.S
+++ b/arch/sparc64/kernel/pci_sun4v_asm.S
@@ -93,3 +93,269 @@ pci_sun4v_config_put:
93 mov -1, %o1 93 mov -1, %o1
941: retl 941: retl
95 mov %o1, %o0 95 mov %o1, %o0
96
97 /* %o0: devhandle
98 * %o1: msiqid
99 * %o2: msiq phys address
100 * %o3: num entries
101 *
102 * returns %o0: status
103 *
104 * status will be zero if the operation completed
105 * successfully, else -1 if not
106 */
107 .globl pci_sun4v_msiq_conf
108pci_sun4v_msiq_conf:
109 mov HV_FAST_PCI_MSIQ_CONF, %o5
110 ta HV_FAST_TRAP
111 retl
112 mov %o0, %o0
113
114 /* %o0: devhandle
115 * %o1: msiqid
116 * %o2: &msiq_phys_addr
117 * %o3: &msiq_num_entries
118 *
119 * returns %o0: status
120 */
121 .globl pci_sun4v_msiq_info
122pci_sun4v_msiq_info:
123 mov %o2, %o4
124 mov HV_FAST_PCI_MSIQ_INFO, %o5
125 ta HV_FAST_TRAP
126 stx %o1, [%o4]
127 stx %o2, [%o3]
128 retl
129 mov %o0, %o0
130
131 /* %o0: devhandle
132 * %o1: msiqid
133 * %o2: &valid
134 *
135 * returns %o0: status
136 */
137 .globl pci_sun4v_msiq_getvalid
138pci_sun4v_msiq_getvalid:
139 mov HV_FAST_PCI_MSIQ_GETVALID, %o5
140 ta HV_FAST_TRAP
141 stx %o1, [%o2]
142 retl
143 mov %o0, %o0
144
145 /* %o0: devhandle
146 * %o1: msiqid
147 * %o2: valid
148 *
149 * returns %o0: status
150 */
151 .globl pci_sun4v_msiq_setvalid
152pci_sun4v_msiq_setvalid:
153 mov HV_FAST_PCI_MSIQ_SETVALID, %o5
154 ta HV_FAST_TRAP
155 retl
156 mov %o0, %o0
157
158 /* %o0: devhandle
159 * %o1: msiqid
160 * %o2: &state
161 *
162 * returns %o0: status
163 */
164 .globl pci_sun4v_msiq_getstate
165pci_sun4v_msiq_getstate:
166 mov HV_FAST_PCI_MSIQ_GETSTATE, %o5
167 ta HV_FAST_TRAP
168 stx %o1, [%o2]
169 retl
170 mov %o0, %o0
171
172 /* %o0: devhandle
173 * %o1: msiqid
174 * %o2: state
175 *
176 * returns %o0: status
177 */
178 .globl pci_sun4v_msiq_setstate
179pci_sun4v_msiq_setstate:
180 mov HV_FAST_PCI_MSIQ_SETSTATE, %o5
181 ta HV_FAST_TRAP
182 retl
183 mov %o0, %o0
184
185 /* %o0: devhandle
186 * %o1: msiqid
187 * %o2: &head
188 *
189 * returns %o0: status
190 */
191 .globl pci_sun4v_msiq_gethead
192pci_sun4v_msiq_gethead:
193 mov HV_FAST_PCI_MSIQ_GETHEAD, %o5
194 ta HV_FAST_TRAP
195 stx %o1, [%o2]
196 retl
197 mov %o0, %o0
198
199 /* %o0: devhandle
200 * %o1: msiqid
201 * %o2: head
202 *
203 * returns %o0: status
204 */
205 .globl pci_sun4v_msiq_sethead
206pci_sun4v_msiq_sethead:
207 mov HV_FAST_PCI_MSIQ_SETHEAD, %o5
208 ta HV_FAST_TRAP
209 retl
210 mov %o0, %o0
211
212 /* %o0: devhandle
213 * %o1: msiqid
214 * %o2: &tail
215 *
216 * returns %o0: status
217 */
218 .globl pci_sun4v_msiq_gettail
219pci_sun4v_msiq_gettail:
220 mov HV_FAST_PCI_MSIQ_GETTAIL, %o5
221 ta HV_FAST_TRAP
222 stx %o1, [%o2]
223 retl
224 mov %o0, %o0
225
226 /* %o0: devhandle
227 * %o1: msinum
228 * %o2: &valid
229 *
230 * returns %o0: status
231 */
232 .globl pci_sun4v_msi_getvalid
233pci_sun4v_msi_getvalid:
234 mov HV_FAST_PCI_MSI_GETVALID, %o5
235 ta HV_FAST_TRAP
236 stx %o1, [%o2]
237 retl
238 mov %o0, %o0
239
240 /* %o0: devhandle
241 * %o1: msinum
242 * %o2: valid
243 *
244 * returns %o0: status
245 */
246 .globl pci_sun4v_msi_setvalid
247pci_sun4v_msi_setvalid:
248 mov HV_FAST_PCI_MSI_SETVALID, %o5
249 ta HV_FAST_TRAP
250 retl
251 mov %o0, %o0
252
253 /* %o0: devhandle
254 * %o1: msinum
255 * %o2: &msiq
256 *
257 * returns %o0: status
258 */
259 .globl pci_sun4v_msi_getmsiq
260pci_sun4v_msi_getmsiq:
261 mov HV_FAST_PCI_MSI_GETMSIQ, %o5
262 ta HV_FAST_TRAP
263 stx %o1, [%o2]
264 retl
265 mov %o0, %o0
266
267 /* %o0: devhandle
268 * %o1: msinum
269 * %o2: msitype
270 * %o3: msiq
271 *
272 * returns %o0: status
273 */
274 .globl pci_sun4v_msi_setmsiq
275pci_sun4v_msi_setmsiq:
276 mov HV_FAST_PCI_MSI_SETMSIQ, %o5
277 ta HV_FAST_TRAP
278 retl
279 mov %o0, %o0
280
281 /* %o0: devhandle
282 * %o1: msinum
283 * %o2: &state
284 *
285 * returns %o0: status
286 */
287 .globl pci_sun4v_msi_getstate
288pci_sun4v_msi_getstate:
289 mov HV_FAST_PCI_MSI_GETSTATE, %o5
290 ta HV_FAST_TRAP
291 stx %o1, [%o2]
292 retl
293 mov %o0, %o0
294
295 /* %o0: devhandle
296 * %o1: msinum
297 * %o2: state
298 *
299 * returns %o0: status
300 */
301 .globl pci_sun4v_msi_setstate
302pci_sun4v_msi_setstate:
303 mov HV_FAST_PCI_MSI_SETSTATE, %o5
304 ta HV_FAST_TRAP
305 retl
306 mov %o0, %o0
307
308 /* %o0: devhandle
309 * %o1: msinum
310 * %o2: &msiq
311 *
312 * returns %o0: status
313 */
314 .globl pci_sun4v_msg_getmsiq
315pci_sun4v_msg_getmsiq:
316 mov HV_FAST_PCI_MSG_GETMSIQ, %o5
317 ta HV_FAST_TRAP
318 stx %o1, [%o2]
319 retl
320 mov %o0, %o0
321
322 /* %o0: devhandle
323 * %o1: msinum
324 * %o2: msiq
325 *
326 * returns %o0: status
327 */
328 .globl pci_sun4v_msg_setmsiq
329pci_sun4v_msg_setmsiq:
330 mov HV_FAST_PCI_MSG_SETMSIQ, %o5
331 ta HV_FAST_TRAP
332 retl
333 mov %o0, %o0
334
335 /* %o0: devhandle
336 * %o1: msinum
337 * %o2: &valid
338 *
339 * returns %o0: status
340 */
341 .globl pci_sun4v_msg_getvalid
342pci_sun4v_msg_getvalid:
343 mov HV_FAST_PCI_MSG_GETVALID, %o5
344 ta HV_FAST_TRAP
345 stx %o1, [%o2]
346 retl
347 mov %o0, %o0
348
349 /* %o0: devhandle
350 * %o1: msinum
351 * %o2: valid
352 *
353 * returns %o0: status
354 */
355 .globl pci_sun4v_msg_setvalid
356pci_sun4v_msg_setvalid:
357 mov HV_FAST_PCI_MSG_SETVALID, %o5
358 ta HV_FAST_TRAP
359 retl
360 mov %o0, %o0
361