Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/powerpc/sysdev/mpic_msi.c
10817 views
1
/*
2
* Copyright 2006-2007, Michael Ellerman, IBM Corporation.
3
*
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License
6
* as published by the Free Software Foundation; version 2 of the
7
* License.
8
*
9
*/
10
11
#include <linux/irq.h>
12
#include <linux/bitmap.h>
13
#include <linux/msi.h>
14
#include <asm/mpic.h>
15
#include <asm/prom.h>
16
#include <asm/hw_irq.h>
17
#include <asm/ppc-pci.h>
18
#include <asm/msi_bitmap.h>
19
20
#include <sysdev/mpic.h>
21
22
void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq)
23
{
24
/* The mpic calls this even when there is no allocator setup */
25
if (!mpic->msi_bitmap.bitmap)
26
return;
27
28
msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq);
29
}
30
31
#ifdef CONFIG_MPIC_U3_HT_IRQS
32
static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
33
{
34
irq_hw_number_t hwirq;
35
struct irq_host_ops *ops = mpic->irqhost->ops;
36
struct device_node *np;
37
int flags, index, i;
38
struct of_irq oirq;
39
40
pr_debug("mpic: found U3, guessing msi allocator setup\n");
41
42
/* Reserve source numbers we know are reserved in the HW.
43
*
44
* This is a bit of a mix of U3 and U4 reserves but that's going
45
* to work fine, we have plenty enugh numbers left so let's just
46
* mark anything we don't like reserved.
47
*/
48
for (i = 0; i < 8; i++)
49
msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
50
51
for (i = 42; i < 46; i++)
52
msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
53
54
for (i = 100; i < 105; i++)
55
msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
56
57
for (i = 124; i < mpic->irq_count; i++)
58
msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
59
60
61
np = NULL;
62
while ((np = of_find_all_nodes(np))) {
63
pr_debug("mpic: mapping hwirqs for %s\n", np->full_name);
64
65
index = 0;
66
while (of_irq_map_one(np, index++, &oirq) == 0) {
67
ops->xlate(mpic->irqhost, NULL, oirq.specifier,
68
oirq.size, &hwirq, &flags);
69
msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq);
70
}
71
}
72
73
return 0;
74
}
75
#else
76
static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
77
{
78
return -1;
79
}
80
#endif
81
82
int mpic_msi_init_allocator(struct mpic *mpic)
83
{
84
int rc;
85
86
rc = msi_bitmap_alloc(&mpic->msi_bitmap, mpic->irq_count,
87
mpic->irqhost->of_node);
88
if (rc)
89
return rc;
90
91
rc = msi_bitmap_reserve_dt_hwirqs(&mpic->msi_bitmap);
92
if (rc > 0) {
93
if (mpic->flags & MPIC_U3_HT_IRQS)
94
rc = mpic_msi_reserve_u3_hwirqs(mpic);
95
96
if (rc) {
97
msi_bitmap_free(&mpic->msi_bitmap);
98
return rc;
99
}
100
}
101
102
return 0;
103
}
104
105