1
2#ifndef LINUX_MSI_H
3#define LINUX_MSI_H
4
5#include <linux/kobject.h>
6#include <linux/list.h>
7#include <asm/msi.h>
8
9
10#ifndef arch_msi_msg_addr_lo
11typedef struct arch_msi_msg_addr_lo {
12 u32 address_lo;
13} __attribute__ ((packed)) arch_msi_msg_addr_lo_t;
14#endif
15
16#ifndef arch_msi_msg_addr_hi
17typedef struct arch_msi_msg_addr_hi {
18 u32 address_hi;
19} __attribute__ ((packed)) arch_msi_msg_addr_hi_t;
20#endif
21
22#ifndef arch_msi_msg_data
23typedef struct arch_msi_msg_data {
24 u32 data;
25} __attribute__ ((packed)) arch_msi_msg_data_t;
26#endif
27
28
29
30
31
32
33
34
35
36
37
38struct msi_msg {
39 union {
40 u32 address_lo;
41 arch_msi_msg_addr_lo_t arch_addr_lo;
42 };
43 union {
44 u32 address_hi;
45 arch_msi_msg_addr_hi_t arch_addr_hi;
46 };
47 union {
48 u32 data;
49 arch_msi_msg_data_t arch_data;
50 };
51};
52
53extern int pci_msi_ignore_mask;
54
55struct irq_data;
56struct msi_desc;
57struct pci_dev;
58struct platform_msi_priv_data;
59void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
60#ifdef CONFIG_GENERIC_MSI_IRQ
61void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg);
62#else
63static inline void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg)
64{
65}
66#endif
67
68typedef void (*irq_write_msi_msg_t)(struct msi_desc *desc,
69 struct msi_msg *msg);
70
71
72
73
74
75
76struct platform_msi_desc {
77 struct platform_msi_priv_data *msi_priv_data;
78 u16 msi_index;
79};
80
81
82
83
84
85struct fsl_mc_msi_desc {
86 u16 msi_index;
87};
88
89
90
91
92
93struct ti_sci_inta_msi_desc {
94 u16 dev_index;
95};
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124struct msi_desc {
125
126 struct list_head list;
127 unsigned int irq;
128 unsigned int nvec_used;
129 struct device *dev;
130 struct msi_msg msg;
131 struct irq_affinity_desc *affinity;
132#ifdef CONFIG_IRQ_MSI_IOMMU
133 const void *iommu_cookie;
134#endif
135
136 void (*write_msi_msg)(struct msi_desc *entry, void *data);
137 void *write_msi_msg_data;
138
139 union {
140
141 struct {
142 u32 masked;
143 struct {
144 u8 is_msix : 1;
145 u8 multiple : 3;
146 u8 multi_cap : 3;
147 u8 maskbit : 1;
148 u8 is_64 : 1;
149 u8 is_virtual : 1;
150 u16 entry_nr;
151 unsigned default_irq;
152 } msi_attrib;
153 union {
154 u8 mask_pos;
155 void __iomem *mask_base;
156 };
157 };
158
159
160
161
162
163
164
165
166 struct platform_msi_desc platform;
167 struct fsl_mc_msi_desc fsl_mc;
168 struct ti_sci_inta_msi_desc inta;
169 };
170};
171
172
173#define msi_desc_to_dev(desc) ((desc)->dev)
174#define dev_to_msi_list(dev) (&(dev)->msi_list)
175#define first_msi_entry(dev) \
176 list_first_entry(dev_to_msi_list((dev)), struct msi_desc, list)
177#define for_each_msi_entry(desc, dev) \
178 list_for_each_entry((desc), dev_to_msi_list((dev)), list)
179#define for_each_msi_entry_safe(desc, tmp, dev) \
180 list_for_each_entry_safe((desc), (tmp), dev_to_msi_list((dev)), list)
181#define for_each_msi_vector(desc, __irq, dev) \
182 for_each_msi_entry((desc), (dev)) \
183 if ((desc)->irq) \
184 for (__irq = (desc)->irq; \
185 __irq < ((desc)->irq + (desc)->nvec_used); \
186 __irq++)
187
188#ifdef CONFIG_IRQ_MSI_IOMMU
189static inline const void *msi_desc_get_iommu_cookie(struct msi_desc *desc)
190{
191 return desc->iommu_cookie;
192}
193
194static inline void msi_desc_set_iommu_cookie(struct msi_desc *desc,
195 const void *iommu_cookie)
196{
197 desc->iommu_cookie = iommu_cookie;
198}
199#else
200static inline const void *msi_desc_get_iommu_cookie(struct msi_desc *desc)
201{
202 return NULL;
203}
204
205static inline void msi_desc_set_iommu_cookie(struct msi_desc *desc,
206 const void *iommu_cookie)
207{
208}
209#endif
210
211#ifdef CONFIG_PCI_MSI
212#define first_pci_msi_entry(pdev) first_msi_entry(&(pdev)->dev)
213#define for_each_pci_msi_entry(desc, pdev) \
214 for_each_msi_entry((desc), &(pdev)->dev)
215
216struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc);
217void *msi_desc_to_pci_sysdata(struct msi_desc *desc);
218void pci_write_msi_msg(unsigned int irq, struct msi_msg *msg);
219#else
220static inline void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
221{
222 return NULL;
223}
224static inline void pci_write_msi_msg(unsigned int irq, struct msi_msg *msg)
225{
226}
227#endif
228
229struct msi_desc *alloc_msi_entry(struct device *dev, int nvec,
230 const struct irq_affinity_desc *affinity);
231void free_msi_entry(struct msi_desc *entry);
232void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
233void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
234
235u32 __pci_msix_desc_mask_irq(struct msi_desc *desc, u32 flag);
236void __pci_msi_desc_mask_irq(struct msi_desc *desc, u32 mask, u32 flag);
237void pci_msi_mask_irq(struct irq_data *data);
238void pci_msi_unmask_irq(struct irq_data *data);
239
240
241
242
243
244
245
246
247
248#ifdef CONFIG_PCI_MSI_ARCH_FALLBACKS
249int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc);
250void arch_teardown_msi_irq(unsigned int irq);
251int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
252void arch_teardown_msi_irqs(struct pci_dev *dev);
253#else
254static inline int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
255{
256 WARN_ON_ONCE(1);
257 return -ENODEV;
258}
259
260static inline void arch_teardown_msi_irqs(struct pci_dev *dev)
261{
262 WARN_ON_ONCE(1);
263}
264#endif
265
266
267
268
269
270void arch_restore_msi_irqs(struct pci_dev *dev);
271void default_restore_msi_irqs(struct pci_dev *dev);
272
273#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
274
275#include <linux/irqhandler.h>
276
277struct irq_domain;
278struct irq_domain_ops;
279struct irq_chip;
280struct device_node;
281struct fwnode_handle;
282struct msi_domain_info;
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322struct msi_domain_ops {
323 irq_hw_number_t (*get_hwirq)(struct msi_domain_info *info,
324 msi_alloc_info_t *arg);
325 int (*msi_init)(struct irq_domain *domain,
326 struct msi_domain_info *info,
327 unsigned int virq, irq_hw_number_t hwirq,
328 msi_alloc_info_t *arg);
329 void (*msi_free)(struct irq_domain *domain,
330 struct msi_domain_info *info,
331 unsigned int virq);
332 int (*msi_check)(struct irq_domain *domain,
333 struct msi_domain_info *info,
334 struct device *dev);
335 int (*msi_prepare)(struct irq_domain *domain,
336 struct device *dev, int nvec,
337 msi_alloc_info_t *arg);
338 void (*msi_finish)(msi_alloc_info_t *arg, int retval);
339 void (*set_desc)(msi_alloc_info_t *arg,
340 struct msi_desc *desc);
341 int (*handle_error)(struct irq_domain *domain,
342 struct msi_desc *desc, int error);
343 int (*domain_alloc_irqs)(struct irq_domain *domain,
344 struct device *dev, int nvec);
345 void (*domain_free_irqs)(struct irq_domain *domain,
346 struct device *dev);
347};
348
349
350
351
352
353
354
355
356
357
358
359
360struct msi_domain_info {
361 u32 flags;
362 struct msi_domain_ops *ops;
363 struct irq_chip *chip;
364 void *chip_data;
365 irq_flow_handler_t handler;
366 void *handler_data;
367 const char *handler_name;
368 void *data;
369};
370
371
372enum {
373
374
375
376
377 MSI_FLAG_USE_DEF_DOM_OPS = (1 << 0),
378
379
380
381
382 MSI_FLAG_USE_DEF_CHIP_OPS = (1 << 1),
383
384 MSI_FLAG_MULTI_PCI_MSI = (1 << 2),
385
386 MSI_FLAG_PCI_MSIX = (1 << 3),
387
388 MSI_FLAG_ACTIVATE_EARLY = (1 << 4),
389
390
391
392
393 MSI_FLAG_MUST_REACTIVATE = (1 << 5),
394
395 MSI_FLAG_LEVEL_CAPABLE = (1 << 6),
396};
397
398int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask,
399 bool force);
400
401struct irq_domain *msi_create_irq_domain(struct fwnode_handle *fwnode,
402 struct msi_domain_info *info,
403 struct irq_domain *parent);
404int __msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
405 int nvec);
406int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
407 int nvec);
408void __msi_domain_free_irqs(struct irq_domain *domain, struct device *dev);
409void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev);
410struct msi_domain_info *msi_get_domain_info(struct irq_domain *domain);
411
412struct irq_domain *platform_msi_create_irq_domain(struct fwnode_handle *fwnode,
413 struct msi_domain_info *info,
414 struct irq_domain *parent);
415int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec,
416 irq_write_msi_msg_t write_msi_msg);
417void platform_msi_domain_free_irqs(struct device *dev);
418
419
420int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev,
421 int nvec, msi_alloc_info_t *args);
422int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev,
423 int virq, int nvec, msi_alloc_info_t *args);
424struct irq_domain *
425__platform_msi_create_device_domain(struct device *dev,
426 unsigned int nvec,
427 bool is_tree,
428 irq_write_msi_msg_t write_msi_msg,
429 const struct irq_domain_ops *ops,
430 void *host_data);
431
432#define platform_msi_create_device_domain(dev, nvec, write, ops, data) \
433 __platform_msi_create_device_domain(dev, nvec, false, write, ops, data)
434#define platform_msi_create_device_tree_domain(dev, nvec, write, ops, data) \
435 __platform_msi_create_device_domain(dev, nvec, true, write, ops, data)
436
437int platform_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
438 unsigned int nr_irqs);
439void platform_msi_domain_free(struct irq_domain *domain, unsigned int virq,
440 unsigned int nvec);
441void *platform_msi_get_host_data(struct irq_domain *domain);
442#endif
443
444#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
445void pci_msi_domain_write_msg(struct irq_data *irq_data, struct msi_msg *msg);
446struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode,
447 struct msi_domain_info *info,
448 struct irq_domain *parent);
449int pci_msi_domain_check_cap(struct irq_domain *domain,
450 struct msi_domain_info *info, struct device *dev);
451u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev);
452struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev);
453bool pci_dev_has_special_msi_domain(struct pci_dev *pdev);
454#else
455static inline struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev)
456{
457 return NULL;
458}
459#endif
460
461#endif
462