File Index
Files and directories
Sign in
FILE

msi.c

File preview with syntax highlighting.

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