ARM: 9148/1: handle CONFIG_CPU_ENDIAN_BE32 in arch/arm/kernel/head.S
[platform/kernel/linux-rpi.git] / arch / powerpc / platforms / pseries / msi.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright 2006 Jake Moilanen <moilanen@austin.ibm.com>, IBM Corp.
4  * Copyright 2006-2007 Michael Ellerman, IBM Corp.
5  */
6
7 #include <linux/crash_dump.h>
8 #include <linux/device.h>
9 #include <linux/irq.h>
10 #include <linux/msi.h>
11
12 #include <asm/rtas.h>
13 #include <asm/hw_irq.h>
14 #include <asm/ppc-pci.h>
15 #include <asm/machdep.h>
16 #include <asm/xive.h>
17
18 #include "pseries.h"
19
20 static int query_token, change_token;
21
22 #define RTAS_QUERY_FN           0
23 #define RTAS_CHANGE_FN          1
24 #define RTAS_RESET_FN           2
25 #define RTAS_CHANGE_MSI_FN      3
26 #define RTAS_CHANGE_MSIX_FN     4
27 #define RTAS_CHANGE_32MSI_FN    5
28
29 /* RTAS Helpers */
30
31 static int rtas_change_msi(struct pci_dn *pdn, u32 func, u32 num_irqs)
32 {
33         u32 addr, seq_num, rtas_ret[3];
34         unsigned long buid;
35         int rc;
36
37         addr = rtas_config_addr(pdn->busno, pdn->devfn, 0);
38         buid = pdn->phb->buid;
39
40         seq_num = 1;
41         do {
42                 if (func == RTAS_CHANGE_MSI_FN || func == RTAS_CHANGE_MSIX_FN ||
43                     func == RTAS_CHANGE_32MSI_FN)
44                         rc = rtas_call(change_token, 6, 4, rtas_ret, addr,
45                                         BUID_HI(buid), BUID_LO(buid),
46                                         func, num_irqs, seq_num);
47                 else
48                         rc = rtas_call(change_token, 6, 3, rtas_ret, addr,
49                                         BUID_HI(buid), BUID_LO(buid),
50                                         func, num_irqs, seq_num);
51
52                 seq_num = rtas_ret[1];
53         } while (rtas_busy_delay(rc));
54
55         /*
56          * If the RTAS call succeeded, return the number of irqs allocated.
57          * If not, make sure we return a negative error code.
58          */
59         if (rc == 0)
60                 rc = rtas_ret[0];
61         else if (rc > 0)
62                 rc = -rc;
63
64         pr_debug("rtas_msi: ibm,change_msi(func=%d,num=%d), got %d rc = %d\n",
65                  func, num_irqs, rtas_ret[0], rc);
66
67         return rc;
68 }
69
70 static void rtas_disable_msi(struct pci_dev *pdev)
71 {
72         struct pci_dn *pdn;
73
74         pdn = pci_get_pdn(pdev);
75         if (!pdn)
76                 return;
77
78         /*
79          * disabling MSI with the explicit interface also disables MSI-X
80          */
81         if (rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, 0) != 0) {
82                 /* 
83                  * may have failed because explicit interface is not
84                  * present
85                  */
86                 if (rtas_change_msi(pdn, RTAS_CHANGE_FN, 0) != 0) {
87                         pr_debug("rtas_msi: Setting MSIs to 0 failed!\n");
88                 }
89         }
90 }
91
92 static int rtas_query_irq_number(struct pci_dn *pdn, int offset)
93 {
94         u32 addr, rtas_ret[2];
95         unsigned long buid;
96         int rc;
97
98         addr = rtas_config_addr(pdn->busno, pdn->devfn, 0);
99         buid = pdn->phb->buid;
100
101         do {
102                 rc = rtas_call(query_token, 4, 3, rtas_ret, addr,
103                                BUID_HI(buid), BUID_LO(buid), offset);
104         } while (rtas_busy_delay(rc));
105
106         if (rc) {
107                 pr_debug("rtas_msi: error (%d) querying source number\n", rc);
108                 return rc;
109         }
110
111         return rtas_ret[0];
112 }
113
114 static int check_req(struct pci_dev *pdev, int nvec, char *prop_name)
115 {
116         struct device_node *dn;
117         const __be32 *p;
118         u32 req_msi;
119
120         dn = pci_device_to_OF_node(pdev);
121
122         p = of_get_property(dn, prop_name, NULL);
123         if (!p) {
124                 pr_debug("rtas_msi: No %s on %pOF\n", prop_name, dn);
125                 return -ENOENT;
126         }
127
128         req_msi = be32_to_cpup(p);
129         if (req_msi < nvec) {
130                 pr_debug("rtas_msi: %s requests < %d MSIs\n", prop_name, nvec);
131
132                 if (req_msi == 0) /* Be paranoid */
133                         return -ENOSPC;
134
135                 return req_msi;
136         }
137
138         return 0;
139 }
140
141 static int check_req_msi(struct pci_dev *pdev, int nvec)
142 {
143         return check_req(pdev, nvec, "ibm,req#msi");
144 }
145
146 static int check_req_msix(struct pci_dev *pdev, int nvec)
147 {
148         return check_req(pdev, nvec, "ibm,req#msi-x");
149 }
150
151 /* Quota calculation */
152
153 static struct device_node *__find_pe_total_msi(struct device_node *node, int *total)
154 {
155         struct device_node *dn;
156         const __be32 *p;
157
158         dn = of_node_get(node);
159         while (dn) {
160                 p = of_get_property(dn, "ibm,pe-total-#msi", NULL);
161                 if (p) {
162                         pr_debug("rtas_msi: found prop on dn %pOF\n",
163                                 dn);
164                         *total = be32_to_cpup(p);
165                         return dn;
166                 }
167
168                 dn = of_get_next_parent(dn);
169         }
170
171         return NULL;
172 }
173
174 static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total)
175 {
176         return __find_pe_total_msi(pci_device_to_OF_node(dev), total);
177 }
178
179 static struct device_node *find_pe_dn(struct pci_dev *dev, int *total)
180 {
181         struct device_node *dn;
182         struct eeh_dev *edev;
183
184         /* Found our PE and assume 8 at that point. */
185
186         dn = pci_device_to_OF_node(dev);
187         if (!dn)
188                 return NULL;
189
190         /* Get the top level device in the PE */
191         edev = pdn_to_eeh_dev(PCI_DN(dn));
192         if (edev->pe)
193                 edev = list_first_entry(&edev->pe->edevs, struct eeh_dev,
194                                         entry);
195         dn = pci_device_to_OF_node(edev->pdev);
196         if (!dn)
197                 return NULL;
198
199         /* We actually want the parent */
200         dn = of_get_parent(dn);
201         if (!dn)
202                 return NULL;
203
204         /* Hardcode of 8 for old firmwares */
205         *total = 8;
206         pr_debug("rtas_msi: using PE dn %pOF\n", dn);
207
208         return dn;
209 }
210
211 struct msi_counts {
212         struct device_node *requestor;
213         int num_devices;
214         int request;
215         int quota;
216         int spare;
217         int over_quota;
218 };
219
220 static void *count_non_bridge_devices(struct device_node *dn, void *data)
221 {
222         struct msi_counts *counts = data;
223         const __be32 *p;
224         u32 class;
225
226         pr_debug("rtas_msi: counting %pOF\n", dn);
227
228         p = of_get_property(dn, "class-code", NULL);
229         class = p ? be32_to_cpup(p) : 0;
230
231         if ((class >> 8) != PCI_CLASS_BRIDGE_PCI)
232                 counts->num_devices++;
233
234         return NULL;
235 }
236
237 static void *count_spare_msis(struct device_node *dn, void *data)
238 {
239         struct msi_counts *counts = data;
240         const __be32 *p;
241         int req;
242
243         if (dn == counts->requestor)
244                 req = counts->request;
245         else {
246                 /* We don't know if a driver will try to use MSI or MSI-X,
247                  * so we just have to punt and use the larger of the two. */
248                 req = 0;
249                 p = of_get_property(dn, "ibm,req#msi", NULL);
250                 if (p)
251                         req = be32_to_cpup(p);
252
253                 p = of_get_property(dn, "ibm,req#msi-x", NULL);
254                 if (p)
255                         req = max(req, (int)be32_to_cpup(p));
256         }
257
258         if (req < counts->quota)
259                 counts->spare += counts->quota - req;
260         else if (req > counts->quota)
261                 counts->over_quota++;
262
263         return NULL;
264 }
265
266 static int msi_quota_for_device(struct pci_dev *dev, int request)
267 {
268         struct device_node *pe_dn;
269         struct msi_counts counts;
270         int total;
271
272         pr_debug("rtas_msi: calc quota for %s, request %d\n", pci_name(dev),
273                   request);
274
275         pe_dn = find_pe_total_msi(dev, &total);
276         if (!pe_dn)
277                 pe_dn = find_pe_dn(dev, &total);
278
279         if (!pe_dn) {
280                 pr_err("rtas_msi: couldn't find PE for %s\n", pci_name(dev));
281                 goto out;
282         }
283
284         pr_debug("rtas_msi: found PE %pOF\n", pe_dn);
285
286         memset(&counts, 0, sizeof(struct msi_counts));
287
288         /* Work out how many devices we have below this PE */
289         pci_traverse_device_nodes(pe_dn, count_non_bridge_devices, &counts);
290
291         if (counts.num_devices == 0) {
292                 pr_err("rtas_msi: found 0 devices under PE for %s\n",
293                         pci_name(dev));
294                 goto out;
295         }
296
297         counts.quota = total / counts.num_devices;
298         if (request <= counts.quota)
299                 goto out;
300
301         /* else, we have some more calculating to do */
302         counts.requestor = pci_device_to_OF_node(dev);
303         counts.request = request;
304         pci_traverse_device_nodes(pe_dn, count_spare_msis, &counts);
305
306         /* If the quota isn't an integer multiple of the total, we can
307          * use the remainder as spare MSIs for anyone that wants them. */
308         counts.spare += total % counts.num_devices;
309
310         /* Divide any spare by the number of over-quota requestors */
311         if (counts.over_quota)
312                 counts.quota += counts.spare / counts.over_quota;
313
314         /* And finally clamp the request to the possibly adjusted quota */
315         request = min(counts.quota, request);
316
317         pr_debug("rtas_msi: request clamped to quota %d\n", request);
318 out:
319         of_node_put(pe_dn);
320
321         return request;
322 }
323
324 static int check_msix_entries(struct pci_dev *pdev)
325 {
326         struct msi_desc *entry;
327         int expected;
328
329         /* There's no way for us to express to firmware that we want
330          * a discontiguous, or non-zero based, range of MSI-X entries.
331          * So we must reject such requests. */
332
333         expected = 0;
334         for_each_pci_msi_entry(entry, pdev) {
335                 if (entry->msi_attrib.entry_nr != expected) {
336                         pr_debug("rtas_msi: bad MSI-X entries.\n");
337                         return -EINVAL;
338                 }
339                 expected++;
340         }
341
342         return 0;
343 }
344
345 static void rtas_hack_32bit_msi_gen2(struct pci_dev *pdev)
346 {
347         u32 addr_hi, addr_lo;
348
349         /*
350          * We should only get in here for IODA1 configs. This is based on the
351          * fact that we using RTAS for MSIs, we don't have the 32 bit MSI RTAS
352          * support, and we are in a PCIe Gen2 slot.
353          */
354         dev_info(&pdev->dev,
355                  "rtas_msi: No 32 bit MSI firmware support, forcing 32 bit MSI\n");
356         pci_read_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_HI, &addr_hi);
357         addr_lo = 0xffff0000 | ((addr_hi >> (48 - 32)) << 4);
358         pci_write_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_LO, addr_lo);
359         pci_write_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_HI, 0);
360 }
361
362 static int rtas_prepare_msi_irqs(struct pci_dev *pdev, int nvec_in, int type,
363                                  msi_alloc_info_t *arg)
364 {
365         struct pci_dn *pdn;
366         int quota, rc;
367         int nvec = nvec_in;
368         int use_32bit_msi_hack = 0;
369
370         if (type == PCI_CAP_ID_MSIX)
371                 rc = check_req_msix(pdev, nvec);
372         else
373                 rc = check_req_msi(pdev, nvec);
374
375         if (rc)
376                 return rc;
377
378         quota = msi_quota_for_device(pdev, nvec);
379
380         if (quota && quota < nvec)
381                 return quota;
382
383         if (type == PCI_CAP_ID_MSIX && check_msix_entries(pdev))
384                 return -EINVAL;
385
386         /*
387          * Firmware currently refuse any non power of two allocation
388          * so we round up if the quota will allow it.
389          */
390         if (type == PCI_CAP_ID_MSIX) {
391                 int m = roundup_pow_of_two(nvec);
392                 quota = msi_quota_for_device(pdev, m);
393
394                 if (quota >= m)
395                         nvec = m;
396         }
397
398         pdn = pci_get_pdn(pdev);
399
400         /*
401          * Try the new more explicit firmware interface, if that fails fall
402          * back to the old interface. The old interface is known to never
403          * return MSI-Xs.
404          */
405 again:
406         if (type == PCI_CAP_ID_MSI) {
407                 if (pdev->no_64bit_msi) {
408                         rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec);
409                         if (rc < 0) {
410                                 /*
411                                  * We only want to run the 32 bit MSI hack below if
412                                  * the max bus speed is Gen2 speed
413                                  */
414                                 if (pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT)
415                                         return rc;
416
417                                 use_32bit_msi_hack = 1;
418                         }
419                 } else
420                         rc = -1;
421
422                 if (rc < 0)
423                         rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec);
424
425                 if (rc < 0) {
426                         pr_debug("rtas_msi: trying the old firmware call.\n");
427                         rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec);
428                 }
429
430                 if (use_32bit_msi_hack && rc > 0)
431                         rtas_hack_32bit_msi_gen2(pdev);
432         } else
433                 rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec);
434
435         if (rc != nvec) {
436                 if (nvec != nvec_in) {
437                         nvec = nvec_in;
438                         goto again;
439                 }
440                 pr_debug("rtas_msi: rtas_change_msi() failed\n");
441                 return rc;
442         }
443
444         return 0;
445 }
446
447 static int pseries_msi_ops_prepare(struct irq_domain *domain, struct device *dev,
448                                    int nvec, msi_alloc_info_t *arg)
449 {
450         struct pci_dev *pdev = to_pci_dev(dev);
451         struct msi_desc *desc = first_pci_msi_entry(pdev);
452         int type = desc->msi_attrib.is_msix ? PCI_CAP_ID_MSIX : PCI_CAP_ID_MSI;
453
454         return rtas_prepare_msi_irqs(pdev, nvec, type, arg);
455 }
456
457 /*
458  * ->msi_free() is called before irq_domain_free_irqs_top() when the
459  * handler data is still available. Use that to clear the XIVE
460  * controller data.
461  */
462 static void pseries_msi_ops_msi_free(struct irq_domain *domain,
463                                      struct msi_domain_info *info,
464                                      unsigned int irq)
465 {
466         if (xive_enabled())
467                 xive_irq_free_data(irq);
468 }
469
470 /*
471  * RTAS can not disable one MSI at a time. It's all or nothing. Do it
472  * at the end after all IRQs have been freed.
473  */
474 static void pseries_msi_domain_free_irqs(struct irq_domain *domain,
475                                          struct device *dev)
476 {
477         if (WARN_ON_ONCE(!dev_is_pci(dev)))
478                 return;
479
480         __msi_domain_free_irqs(domain, dev);
481
482         rtas_disable_msi(to_pci_dev(dev));
483 }
484
485 static struct msi_domain_ops pseries_pci_msi_domain_ops = {
486         .msi_prepare    = pseries_msi_ops_prepare,
487         .msi_free       = pseries_msi_ops_msi_free,
488         .domain_free_irqs = pseries_msi_domain_free_irqs,
489 };
490
491 static void pseries_msi_shutdown(struct irq_data *d)
492 {
493         d = d->parent_data;
494         if (d->chip->irq_shutdown)
495                 d->chip->irq_shutdown(d);
496 }
497
498 static void pseries_msi_mask(struct irq_data *d)
499 {
500         pci_msi_mask_irq(d);
501         irq_chip_mask_parent(d);
502 }
503
504 static void pseries_msi_unmask(struct irq_data *d)
505 {
506         pci_msi_unmask_irq(d);
507         irq_chip_unmask_parent(d);
508 }
509
510 static struct irq_chip pseries_pci_msi_irq_chip = {
511         .name           = "pSeries-PCI-MSI",
512         .irq_shutdown   = pseries_msi_shutdown,
513         .irq_mask       = pseries_msi_mask,
514         .irq_unmask     = pseries_msi_unmask,
515         .irq_eoi        = irq_chip_eoi_parent,
516 };
517
518 static struct msi_domain_info pseries_msi_domain_info = {
519         .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
520                   MSI_FLAG_MULTI_PCI_MSI  | MSI_FLAG_PCI_MSIX),
521         .ops   = &pseries_pci_msi_domain_ops,
522         .chip  = &pseries_pci_msi_irq_chip,
523 };
524
525 static void pseries_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
526 {
527         __pci_read_msi_msg(irq_data_get_msi_desc(data), msg);
528 }
529
530 static struct irq_chip pseries_msi_irq_chip = {
531         .name                   = "pSeries-MSI",
532         .irq_shutdown           = pseries_msi_shutdown,
533         .irq_mask               = irq_chip_mask_parent,
534         .irq_unmask             = irq_chip_unmask_parent,
535         .irq_eoi                = irq_chip_eoi_parent,
536         .irq_set_affinity       = irq_chip_set_affinity_parent,
537         .irq_compose_msi_msg    = pseries_msi_compose_msg,
538 };
539
540 static int pseries_irq_parent_domain_alloc(struct irq_domain *domain, unsigned int virq,
541                                            irq_hw_number_t hwirq)
542 {
543         struct irq_fwspec parent_fwspec;
544         int ret;
545
546         parent_fwspec.fwnode = domain->parent->fwnode;
547         parent_fwspec.param_count = 2;
548         parent_fwspec.param[0] = hwirq;
549         parent_fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
550
551         ret = irq_domain_alloc_irqs_parent(domain, virq, 1, &parent_fwspec);
552         if (ret)
553                 return ret;
554
555         return 0;
556 }
557
558 static int pseries_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
559                                     unsigned int nr_irqs, void *arg)
560 {
561         struct pci_controller *phb = domain->host_data;
562         msi_alloc_info_t *info = arg;
563         struct msi_desc *desc = info->desc;
564         struct pci_dev *pdev = msi_desc_to_pci_dev(desc);
565         int hwirq;
566         int i, ret;
567
568         hwirq = rtas_query_irq_number(pci_get_pdn(pdev), desc->msi_attrib.entry_nr);
569         if (hwirq < 0) {
570                 dev_err(&pdev->dev, "Failed to query HW IRQ: %d\n", hwirq);
571                 return hwirq;
572         }
573
574         dev_dbg(&pdev->dev, "%s bridge %pOF %d/%x #%d\n", __func__,
575                 phb->dn, virq, hwirq, nr_irqs);
576
577         for (i = 0; i < nr_irqs; i++) {
578                 ret = pseries_irq_parent_domain_alloc(domain, virq + i, hwirq + i);
579                 if (ret)
580                         goto out;
581
582                 irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
583                                               &pseries_msi_irq_chip, domain->host_data);
584         }
585
586         return 0;
587
588 out:
589         /* TODO: handle RTAS cleanup in ->msi_finish() ? */
590         irq_domain_free_irqs_parent(domain, virq, i - 1);
591         return ret;
592 }
593
594 static void pseries_irq_domain_free(struct irq_domain *domain, unsigned int virq,
595                                     unsigned int nr_irqs)
596 {
597         struct irq_data *d = irq_domain_get_irq_data(domain, virq);
598         struct pci_controller *phb = irq_data_get_irq_chip_data(d);
599
600         pr_debug("%s bridge %pOF %d #%d\n", __func__, phb->dn, virq, nr_irqs);
601
602         /* XIVE domain data is cleared through ->msi_free() */
603 }
604
605 static const struct irq_domain_ops pseries_irq_domain_ops = {
606         .alloc  = pseries_irq_domain_alloc,
607         .free   = pseries_irq_domain_free,
608 };
609
610 static int __pseries_msi_allocate_domains(struct pci_controller *phb,
611                                           unsigned int count)
612 {
613         struct irq_domain *parent = irq_get_default_host();
614
615         phb->fwnode = irq_domain_alloc_named_id_fwnode("pSeries-MSI",
616                                                        phb->global_number);
617         if (!phb->fwnode)
618                 return -ENOMEM;
619
620         phb->dev_domain = irq_domain_create_hierarchy(parent, 0, count,
621                                                       phb->fwnode,
622                                                       &pseries_irq_domain_ops, phb);
623         if (!phb->dev_domain) {
624                 pr_err("PCI: failed to create IRQ domain bridge %pOF (domain %d)\n",
625                        phb->dn, phb->global_number);
626                 irq_domain_free_fwnode(phb->fwnode);
627                 return -ENOMEM;
628         }
629
630         phb->msi_domain = pci_msi_create_irq_domain(of_node_to_fwnode(phb->dn),
631                                                     &pseries_msi_domain_info,
632                                                     phb->dev_domain);
633         if (!phb->msi_domain) {
634                 pr_err("PCI: failed to create MSI IRQ domain bridge %pOF (domain %d)\n",
635                        phb->dn, phb->global_number);
636                 irq_domain_free_fwnode(phb->fwnode);
637                 irq_domain_remove(phb->dev_domain);
638                 return -ENOMEM;
639         }
640
641         return 0;
642 }
643
644 int pseries_msi_allocate_domains(struct pci_controller *phb)
645 {
646         int count;
647
648         if (!__find_pe_total_msi(phb->dn, &count)) {
649                 pr_err("PCI: failed to find MSIs for bridge %pOF (domain %d)\n",
650                        phb->dn, phb->global_number);
651                 return -ENOSPC;
652         }
653
654         return __pseries_msi_allocate_domains(phb, count);
655 }
656
657 void pseries_msi_free_domains(struct pci_controller *phb)
658 {
659         if (phb->msi_domain)
660                 irq_domain_remove(phb->msi_domain);
661         if (phb->dev_domain)
662                 irq_domain_remove(phb->dev_domain);
663         if (phb->fwnode)
664                 irq_domain_free_fwnode(phb->fwnode);
665 }
666
667 static void rtas_msi_pci_irq_fixup(struct pci_dev *pdev)
668 {
669         /* No LSI -> leave MSIs (if any) configured */
670         if (!pdev->irq) {
671                 dev_dbg(&pdev->dev, "rtas_msi: no LSI, nothing to do.\n");
672                 return;
673         }
674
675         /* No MSI -> MSIs can't have been assigned by fw, leave LSI */
676         if (check_req_msi(pdev, 1) && check_req_msix(pdev, 1)) {
677                 dev_dbg(&pdev->dev, "rtas_msi: no req#msi/x, nothing to do.\n");
678                 return;
679         }
680
681         dev_dbg(&pdev->dev, "rtas_msi: disabling existing MSI.\n");
682         rtas_disable_msi(pdev);
683 }
684
685 static int rtas_msi_init(void)
686 {
687         query_token  = rtas_token("ibm,query-interrupt-source-number");
688         change_token = rtas_token("ibm,change-msi");
689
690         if ((query_token == RTAS_UNKNOWN_SERVICE) ||
691                         (change_token == RTAS_UNKNOWN_SERVICE)) {
692                 pr_debug("rtas_msi: no RTAS tokens, no MSI support.\n");
693                 return -1;
694         }
695
696         pr_debug("rtas_msi: Registering RTAS MSI callbacks.\n");
697
698         WARN_ON(ppc_md.pci_irq_fixup);
699         ppc_md.pci_irq_fixup = rtas_msi_pci_irq_fixup;
700
701         return 0;
702 }
703 machine_arch_initcall(pseries, rtas_msi_init);