Blame view
arch/ia64/kernel/msi_ia64.c
4.39 KB
fd58e55fc [PATCH] PCI: msi ... |
1 2 3 4 5 6 |
/* * MSI hooks for standard x86 apic */ #include <linux/pci.h> #include <linux/irq.h> |
3b7d1921f [PATCH] msi: refa... |
7 |
#include <linux/msi.h> |
62fdd7678 [IA64] Add Variab... |
8 |
#include <linux/dmar.h> |
a4cffb644 [PATCH] x86_64: m... |
9 |
#include <asm/smp.h> |
2fa8937f3 ia64: Move the ma... |
10 |
#include <asm/msidef.h> |
fd58e55fc [PATCH] PCI: msi ... |
11 |
|
3b7d1921f [PATCH] msi: refa... |
12 |
static struct irq_chip ia64_msi_chip; |
fd58e55fc [PATCH] PCI: msi ... |
13 |
|
3b7d1921f [PATCH] msi: refa... |
14 |
#ifdef CONFIG_SMP |
f1f701e93 ia64: Convert msi... |
15 16 |
static int ia64_set_msi_irq_affinity(struct irq_data *idata, const cpumask_t *cpu_mask, bool force) |
fd58e55fc [PATCH] PCI: msi ... |
17 |
{ |
3b7d1921f [PATCH] msi: refa... |
18 |
struct msi_msg msg; |
cd378f18c [IA64] Support ir... |
19 |
u32 addr, data; |
0de26520c cpumask: make irq... |
20 |
int cpu = first_cpu(*cpu_mask); |
f1f701e93 ia64: Convert msi... |
21 |
unsigned int irq = idata->irq; |
3b7d1921f [PATCH] msi: refa... |
22 |
|
cd378f18c [IA64] Support ir... |
23 |
if (!cpu_online(cpu)) |
d5dedd450 irq: change ->set... |
24 |
return -1; |
cd378f18c [IA64] Support ir... |
25 |
|
a6cd6322d [IA64] Fix irq mi... |
26 |
if (irq_prepare_move(irq, cpu)) |
d5dedd450 irq: change ->set... |
27 |
return -1; |
4994be1b3 [IA64] Add suppor... |
28 |
|
30da55242 PCI: MSI: Restore... |
29 |
get_cached_msi_msg(irq, &msg); |
fd58e55fc [PATCH] PCI: msi ... |
30 |
|
3b7d1921f [PATCH] msi: refa... |
31 |
addr = msg.address_lo; |
2fa8937f3 ia64: Move the ma... |
32 33 |
addr &= MSI_ADDR_DEST_ID_MASK; addr |= MSI_ADDR_DEST_ID_CPU(cpu_physical_id(cpu)); |
3b7d1921f [PATCH] msi: refa... |
34 |
msg.address_lo = addr; |
fd58e55fc [PATCH] PCI: msi ... |
35 |
|
cd378f18c [IA64] Support ir... |
36 37 38 39 |
data = msg.data; data &= MSI_DATA_VECTOR_MASK; data |= MSI_DATA_VECTOR(irq_to_vector(irq)); msg.data = data; |
3b7d1921f [PATCH] msi: refa... |
40 |
write_msi_msg(irq, &msg); |
f1f701e93 ia64: Convert msi... |
41 |
cpumask_copy(idata->affinity, cpumask_of(cpu)); |
d5dedd450 irq: change ->set... |
42 43 |
return 0; |
fd58e55fc [PATCH] PCI: msi ... |
44 |
} |
3b7d1921f [PATCH] msi: refa... |
45 |
#endif /* CONFIG_SMP */ |
fd58e55fc [PATCH] PCI: msi ... |
46 |
|
f7feaca77 msi: Make MSI use... |
47 |
int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) |
fd58e55fc [PATCH] PCI: msi ... |
48 |
{ |
3b7d1921f [PATCH] msi: refa... |
49 |
struct msi_msg msg; |
fd58e55fc [PATCH] PCI: msi ... |
50 |
unsigned long dest_phys_id; |
8a3a0ee73 [IA64] Fix possib... |
51 |
int irq, vector; |
4994be1b3 [IA64] Add suppor... |
52 |
cpumask_t mask; |
fd58e55fc [PATCH] PCI: msi ... |
53 |
|
f7feaca77 msi: Make MSI use... |
54 55 56 |
irq = create_irq(); if (irq < 0) return irq; |
53c909c96 ia64: Convert to ... |
57 |
irq_set_msi_desc(irq, desc); |
4994be1b3 [IA64] Add suppor... |
58 59 |
cpus_and(mask, irq_to_domain(irq), cpu_online_map); dest_phys_id = cpu_physical_id(first_cpu(mask)); |
9438a1218 [IA64] Fix wrong ... |
60 |
vector = irq_to_vector(irq); |
fd58e55fc [PATCH] PCI: msi ... |
61 |
|
3b7d1921f [PATCH] msi: refa... |
62 63 |
msg.address_hi = 0; msg.address_lo = |
38bc03613 [PATCH] genirq: m... |
64 |
MSI_ADDR_HEADER | |
2fa8937f3 ia64: Move the ma... |
65 |
MSI_ADDR_DEST_MODE_PHYS | |
38bc03613 [PATCH] genirq: m... |
66 |
MSI_ADDR_REDIRECTION_CPU | |
2fa8937f3 ia64: Move the ma... |
67 |
MSI_ADDR_DEST_ID_CPU(dest_phys_id); |
fd58e55fc [PATCH] PCI: msi ... |
68 |
|
3b7d1921f [PATCH] msi: refa... |
69 |
msg.data = |
38bc03613 [PATCH] genirq: m... |
70 |
MSI_DATA_TRIGGER_EDGE | |
fd58e55fc [PATCH] PCI: msi ... |
71 72 73 |
MSI_DATA_LEVEL_ASSERT | MSI_DATA_DELIVERY_FIXED | MSI_DATA_VECTOR(vector); |
3b7d1921f [PATCH] msi: refa... |
74 |
write_msi_msg(irq, &msg); |
53c909c96 ia64: Convert to ... |
75 |
irq_set_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq); |
3b7d1921f [PATCH] msi: refa... |
76 |
|
3aff03739 [IA64] Fix incorr... |
77 |
return 0; |
fd58e55fc [PATCH] PCI: msi ... |
78 |
} |
3b7d1921f [PATCH] msi: refa... |
79 |
void ia64_teardown_msi_irq(unsigned int irq) |
fd58e55fc [PATCH] PCI: msi ... |
80 |
{ |
f7feaca77 msi: Make MSI use... |
81 |
destroy_irq(irq); |
fd58e55fc [PATCH] PCI: msi ... |
82 |
} |
f1f701e93 ia64: Convert msi... |
83 |
static void ia64_ack_msi_irq(struct irq_data *data) |
3b7d1921f [PATCH] msi: refa... |
84 |
{ |
f1f701e93 ia64: Convert msi... |
85 |
irq_complete_move(data->irq); |
97499b2ed ia64: msi: Use ir... |
86 |
irq_move_irq(data); |
3b7d1921f [PATCH] msi: refa... |
87 88 |
ia64_eoi(); } |
f1f701e93 ia64: Convert msi... |
89 |
static int ia64_msi_retrigger_irq(struct irq_data *data) |
3b7d1921f [PATCH] msi: refa... |
90 |
{ |
f1f701e93 ia64: Convert msi... |
91 |
unsigned int vector = irq_to_vector(data->irq); |
3b7d1921f [PATCH] msi: refa... |
92 93 94 95 |
ia64_resend_irq(vector); return 1; } |
fd58e55fc [PATCH] PCI: msi ... |
96 |
/* |
3b7d1921f [PATCH] msi: refa... |
97 |
* Generic ops used on most IA64 platforms. |
fd58e55fc [PATCH] PCI: msi ... |
98 |
*/ |
3b7d1921f [PATCH] msi: refa... |
99 |
static struct irq_chip ia64_msi_chip = { |
f1f701e93 ia64: Convert msi... |
100 101 102 103 |
.name = "PCI-MSI", .irq_mask = mask_msi_irq, .irq_unmask = unmask_msi_irq, .irq_ack = ia64_ack_msi_irq, |
3b7d1921f [PATCH] msi: refa... |
104 |
#ifdef CONFIG_SMP |
f1f701e93 ia64: Convert msi... |
105 |
.irq_set_affinity = ia64_set_msi_irq_affinity, |
3b7d1921f [PATCH] msi: refa... |
106 |
#endif |
f1f701e93 ia64: Convert msi... |
107 |
.irq_retrigger = ia64_msi_retrigger_irq, |
fd58e55fc [PATCH] PCI: msi ... |
108 |
}; |
3b7d1921f [PATCH] msi: refa... |
109 |
|
f7feaca77 msi: Make MSI use... |
110 |
int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) |
3b7d1921f [PATCH] msi: refa... |
111 112 |
{ if (platform_setup_msi_irq) |
f7feaca77 msi: Make MSI use... |
113 |
return platform_setup_msi_irq(pdev, desc); |
3b7d1921f [PATCH] msi: refa... |
114 |
|
f7feaca77 msi: Make MSI use... |
115 |
return ia64_setup_msi_irq(pdev, desc); |
3b7d1921f [PATCH] msi: refa... |
116 117 118 119 120 121 122 123 124 |
} void arch_teardown_msi_irq(unsigned int irq) { if (platform_teardown_msi_irq) return platform_teardown_msi_irq(irq); return ia64_teardown_msi_irq(irq); } |
62fdd7678 [IA64] Add Variab... |
125 |
|
d3f138106 iommu: Rename the... |
126 |
#ifdef CONFIG_INTEL_IOMMU |
62fdd7678 [IA64] Add Variab... |
127 |
#ifdef CONFIG_SMP |
f1f701e93 ia64: Convert msi... |
128 129 |
static int dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) |
62fdd7678 [IA64] Add Variab... |
130 |
{ |
f1f701e93 ia64: Convert msi... |
131 |
unsigned int irq = data->irq; |
62fdd7678 [IA64] Add Variab... |
132 133 |
struct irq_cfg *cfg = irq_cfg + irq; struct msi_msg msg; |
0de26520c cpumask: make irq... |
134 |
int cpu = cpumask_first(mask); |
62fdd7678 [IA64] Add Variab... |
135 136 |
if (!cpu_online(cpu)) |
d5dedd450 irq: change ->set... |
137 |
return -1; |
62fdd7678 [IA64] Add Variab... |
138 139 |
if (irq_prepare_move(irq, cpu)) |
d5dedd450 irq: change ->set... |
140 |
return -1; |
62fdd7678 [IA64] Add Variab... |
141 142 143 144 145 |
dmar_msi_read(irq, &msg); msg.data &= ~MSI_DATA_VECTOR_MASK; msg.data |= MSI_DATA_VECTOR(cfg->vector); |
2fa8937f3 ia64: Move the ma... |
146 147 |
msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK; msg.address_lo |= MSI_ADDR_DEST_ID_CPU(cpu_physical_id(cpu)); |
62fdd7678 [IA64] Add Variab... |
148 149 |
dmar_msi_write(irq, &msg); |
f1f701e93 ia64: Convert msi... |
150 |
cpumask_copy(data->affinity, mask); |
d5dedd450 irq: change ->set... |
151 152 |
return 0; |
62fdd7678 [IA64] Add Variab... |
153 154 |
} #endif /* CONFIG_SMP */ |
9542b21e4 [IA64] msi_ia64.c... |
155 |
static struct irq_chip dmar_msi_type = { |
62fdd7678 [IA64] Add Variab... |
156 |
.name = "DMAR_MSI", |
5c2837fba dmar: Convert to ... |
157 158 |
.irq_unmask = dmar_msi_unmask, .irq_mask = dmar_msi_mask, |
f1f701e93 ia64: Convert msi... |
159 |
.irq_ack = ia64_ack_msi_irq, |
62fdd7678 [IA64] Add Variab... |
160 |
#ifdef CONFIG_SMP |
f1f701e93 ia64: Convert msi... |
161 |
.irq_set_affinity = dmar_msi_set_affinity, |
62fdd7678 [IA64] Add Variab... |
162 |
#endif |
f1f701e93 ia64: Convert msi... |
163 |
.irq_retrigger = ia64_msi_retrigger_irq, |
62fdd7678 [IA64] Add Variab... |
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
}; static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg) { struct irq_cfg *cfg = irq_cfg + irq; unsigned dest; cpumask_t mask; cpus_and(mask, irq_to_domain(irq), cpu_online_map); dest = cpu_physical_id(first_cpu(mask)); msg->address_hi = 0; msg->address_lo = MSI_ADDR_HEADER | |
2fa8937f3 ia64: Move the ma... |
179 |
MSI_ADDR_DEST_MODE_PHYS | |
62fdd7678 [IA64] Add Variab... |
180 |
MSI_ADDR_REDIRECTION_CPU | |
2fa8937f3 ia64: Move the ma... |
181 |
MSI_ADDR_DEST_ID_CPU(dest); |
62fdd7678 [IA64] Add Variab... |
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
msg->data = MSI_DATA_TRIGGER_EDGE | MSI_DATA_LEVEL_ASSERT | MSI_DATA_DELIVERY_FIXED | MSI_DATA_VECTOR(cfg->vector); return 0; } int arch_setup_dmar_msi(unsigned int irq) { int ret; struct msi_msg msg; ret = msi_compose_msg(NULL, irq, &msg); if (ret < 0) return ret; dmar_msi_write(irq, &msg); |
53c909c96 ia64: Convert to ... |
200 201 |
irq_set_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq, "edge"); |
62fdd7678 [IA64] Add Variab... |
202 203 |
return 0; } |
d3f138106 iommu: Rename the... |
204 |
#endif /* CONFIG_INTEL_IOMMU */ |
62fdd7678 [IA64] Add Variab... |
205 |