hc
2024-09-20 cf4ce59b3b70238352c7f1729f0f7223214828ad
kernel/kernel/irq/msi.c
....@@ -5,7 +5,7 @@
55 *
66 * This file is licensed under GPLv2.
77 *
8
- * This file contains common code to support Message Signalled Interrupt for
8
+ * This file contains common code to support Message Signaled Interrupts for
99 * PCI compatible and non PCI compatible devices.
1010 */
1111 #include <linux/types.h>
....@@ -23,11 +23,11 @@
2323 * @nvec: The number of vectors used in this entry
2424 * @affinity: Optional pointer to an affinity mask array size of @nvec
2525 *
26
- * If @affinity is not NULL then a an affinity array[@nvec] is allocated
27
- * and the affinity masks from @affinity are copied.
26
+ * If @affinity is not NULL then an affinity array[@nvec] is allocated
27
+ * and the affinity masks and flags from @affinity are copied.
2828 */
29
-struct msi_desc *
30
-alloc_msi_entry(struct device *dev, int nvec, const struct cpumask *affinity)
29
+struct msi_desc *alloc_msi_entry(struct device *dev, int nvec,
30
+ const struct irq_affinity_desc *affinity)
3131 {
3232 struct msi_desc *desc;
3333
....@@ -187,7 +187,6 @@
187187 .deactivate = msi_domain_deactivate,
188188 };
189189
190
-#ifdef GENERIC_MSI_DOMAIN_OPS
191190 static irq_hw_number_t msi_domain_ops_get_hwirq(struct msi_domain_info *info,
192191 msi_alloc_info_t *arg)
193192 {
....@@ -206,11 +205,6 @@
206205 {
207206 arg->desc = desc;
208207 }
209
-#else
210
-#define msi_domain_ops_get_hwirq NULL
211
-#define msi_domain_ops_prepare NULL
212
-#define msi_domain_ops_set_desc NULL
213
-#endif /* !GENERIC_MSI_DOMAIN_OPS */
214208
215209 static int msi_domain_ops_init(struct irq_domain *domain,
216210 struct msi_domain_info *info,
....@@ -235,11 +229,13 @@
235229 }
236230
237231 static struct msi_domain_ops msi_domain_ops_default = {
238
- .get_hwirq = msi_domain_ops_get_hwirq,
239
- .msi_init = msi_domain_ops_init,
240
- .msi_check = msi_domain_ops_check,
241
- .msi_prepare = msi_domain_ops_prepare,
242
- .set_desc = msi_domain_ops_set_desc,
232
+ .get_hwirq = msi_domain_ops_get_hwirq,
233
+ .msi_init = msi_domain_ops_init,
234
+ .msi_check = msi_domain_ops_check,
235
+ .msi_prepare = msi_domain_ops_prepare,
236
+ .set_desc = msi_domain_ops_set_desc,
237
+ .domain_alloc_irqs = __msi_domain_alloc_irqs,
238
+ .domain_free_irqs = __msi_domain_free_irqs,
243239 };
244240
245241 static void msi_domain_update_dom_ops(struct msi_domain_info *info)
....@@ -250,6 +246,14 @@
250246 info->ops = &msi_domain_ops_default;
251247 return;
252248 }
249
+
250
+ if (ops->domain_alloc_irqs == NULL)
251
+ ops->domain_alloc_irqs = msi_domain_ops_default.domain_alloc_irqs;
252
+ if (ops->domain_free_irqs == NULL)
253
+ ops->domain_free_irqs = msi_domain_ops_default.domain_free_irqs;
254
+
255
+ if (!(info->flags & MSI_FLAG_USE_DEF_DOM_OPS))
256
+ return;
253257
254258 if (ops->get_hwirq == NULL)
255259 ops->get_hwirq = msi_domain_ops_default.get_hwirq;
....@@ -284,8 +288,7 @@
284288 {
285289 struct irq_domain *domain;
286290
287
- if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS)
288
- msi_domain_update_dom_ops(info);
291
+ msi_domain_update_dom_ops(info);
289292 if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
290293 msi_domain_update_chip_ops(info);
291294
....@@ -370,8 +373,13 @@
370373 {
371374 struct msi_desc *desc;
372375
373
- if (domain->bus_token != DOMAIN_BUS_PCI_MSI)
376
+ switch(domain->bus_token) {
377
+ case DOMAIN_BUS_PCI_MSI:
378
+ case DOMAIN_BUS_VMD_MSI:
379
+ break;
380
+ default:
374381 return false;
382
+ }
375383
376384 if (!(info->flags & MSI_FLAG_MUST_REACTIVATE))
377385 return false;
....@@ -387,17 +395,8 @@
387395 return desc->msi_attrib.is_msix || desc->msi_attrib.maskbit;
388396 }
389397
390
-/**
391
- * msi_domain_alloc_irqs - Allocate interrupts from a MSI interrupt domain
392
- * @domain: The domain to allocate from
393
- * @dev: Pointer to device struct of the device for which the interrupts
394
- * are allocated
395
- * @nvec: The number of interrupts to allocate
396
- *
397
- * Returns 0 on success or an error code.
398
- */
399
-int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
400
- int nvec)
398
+int __msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
399
+ int nvec)
401400 {
402401 struct msi_domain_info *info = domain->host_data;
403402 struct msi_domain_ops *ops = info->ops;
....@@ -457,6 +456,13 @@
457456 irqd_clr_can_reserve(irq_data);
458457 if (domain->flags & IRQ_DOMAIN_MSI_NOMASK_QUIRK)
459458 irqd_set_msi_nomask_quirk(irq_data);
459
+ if ((info->flags & MSI_FLAG_ACTIVATE_EARLY) &&
460
+ irqd_affinity_is_managed(irq_data) &&
461
+ !cpumask_intersects(irq_data_get_affinity_mask(irq_data),
462
+ cpu_online_mask)) {
463
+ irqd_set_managed_shutdown(irq_data);
464
+ continue;
465
+ }
460466 }
461467 ret = irq_domain_activate_irq(irq_data, can_reserve);
462468 if (ret)
....@@ -482,12 +488,24 @@
482488 }
483489
484490 /**
485
- * msi_domain_free_irqs - Free interrupts from a MSI interrupt @domain associated tp @dev
486
- * @domain: The domain to managing the interrupts
491
+ * msi_domain_alloc_irqs - Allocate interrupts from a MSI interrupt domain
492
+ * @domain: The domain to allocate from
487493 * @dev: Pointer to device struct of the device for which the interrupts
488
- * are free
494
+ * are allocated
495
+ * @nvec: The number of interrupts to allocate
496
+ *
497
+ * Returns 0 on success or an error code.
489498 */
490
-void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev)
499
+int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
500
+ int nvec)
501
+{
502
+ struct msi_domain_info *info = domain->host_data;
503
+ struct msi_domain_ops *ops = info->ops;
504
+
505
+ return ops->domain_alloc_irqs(domain, dev, nvec);
506
+}
507
+
508
+void __msi_domain_free_irqs(struct irq_domain *domain, struct device *dev)
491509 {
492510 struct irq_data *irq_data;
493511 struct msi_desc *desc;
....@@ -513,6 +531,20 @@
513531 }
514532
515533 /**
534
+ * __msi_domain_free_irqs - Free interrupts from a MSI interrupt @domain associated tp @dev
535
+ * @domain: The domain to managing the interrupts
536
+ * @dev: Pointer to device struct of the device for which the interrupts
537
+ * are free
538
+ */
539
+void msi_domain_free_irqs(struct irq_domain *domain, struct device *dev)
540
+{
541
+ struct msi_domain_info *info = domain->host_data;
542
+ struct msi_domain_ops *ops = info->ops;
543
+
544
+ return ops->domain_free_irqs(domain, dev);
545
+}
546
+
547
+/**
516548 * msi_get_domain_info - Get the MSI interrupt domain info for @domain
517549 * @domain: The interrupt domain to retrieve data from
518550 *