forked from Minki/linux
- Prevent device managed IRQ allocation helpers from returning IRQ 0.
- A fix for MSI activation of PCI endpoints with multiple MSIs. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAmAf9E8ACgkQEsHwGGHe VUrdnBAAshn35KlffL7TayhPnO9FArEHw9GRoRdVOvfLp/NEQsALlEFx3ecaYo5j Rxoh/+/UdIx3pp/OTWu6uDnAxSnwctNZ50o1MFSiXZlYkoC/vVawauOPS29+W3bL 40fhGcA8RNx6Hi7a0Cgj0uioxmRJpZ0x8NvLzKT5uvkPYnRfLQSf7xqrkhQR9pm/ lJaG11aa/LNXndamYlrC1PllkDmX2UwZ6z0XBP9PJf6tDHlfR8sLHhGJ1E/ACaY6 Vw03DKsXHdiqqa+1bc8XduagHfchL4RCQXe9FS0IymH0a3lrjdOtdqZznTHR8S7N uwyPyNSdQDOV6Ni+qgc/Icoxfkj0/ZXytD4wkgpLP6ShUnGUaO6PrA5tm7CX/eoj 900eh1p2ZHHB5UP3FtG1ldUV0vn2HVtk7XOwSiPURoUldcBAnvJThQvxFA2wkeZA BnhTfoWCl2cncyWmUndNJ5kQFObGW7u8V6rU8kHgKNQDUKrD7hOGgOeFcPQ4j4I6 lXqrHKXu3yGCxVNZKt+4Ay5rRVQL8vKzXjDZbHhmLAomxuX4BCOqTCgWVFszX2Nr 3mLHw13tXAYobFDnq24CfPhljgGj7HUIOvadOJtoTG/5Kb4M7hybyqnlHRx8GVMh fOS3/o6TKhHQbfwMkx1Km3EiKQkDmvhJrzp/fQ6NcxXa8PY65T8= =v33D -----END PGP SIGNATURE----- Merge tag 'irq_urgent_for_v5.11_rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull irq fixes from Borislav Petkov: - Prevent device managed IRQ allocation helpers from returning IRQ 0 - A fix for MSI activation of PCI endpoints with multiple MSIs * tag 'irq_urgent_for_v5.11_rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: genirq: Prevent [devm_]irq_alloc_desc from returning irq 0 genirq/msi: Activate Multi-MSI early when MSI_FLAG_ACTIVATE_EARLY is set
This commit is contained in:
commit
fc6c0ae53a
@ -928,7 +928,7 @@ int __devm_irq_alloc_descs(struct device *dev, int irq, unsigned int from,
|
||||
__irq_alloc_descs(irq, from, cnt, node, THIS_MODULE, NULL)
|
||||
|
||||
#define irq_alloc_desc(node) \
|
||||
irq_alloc_descs(-1, 0, 1, node)
|
||||
irq_alloc_descs(-1, 1, 1, node)
|
||||
|
||||
#define irq_alloc_desc_at(at, node) \
|
||||
irq_alloc_descs(at, at, 1, node)
|
||||
@ -943,7 +943,7 @@ int __devm_irq_alloc_descs(struct device *dev, int irq, unsigned int from,
|
||||
__devm_irq_alloc_descs(dev, irq, from, cnt, node, THIS_MODULE, NULL)
|
||||
|
||||
#define devm_irq_alloc_desc(dev, node) \
|
||||
devm_irq_alloc_descs(dev, -1, 0, 1, node)
|
||||
devm_irq_alloc_descs(dev, -1, 1, 1, node)
|
||||
|
||||
#define devm_irq_alloc_desc_at(dev, at, node) \
|
||||
devm_irq_alloc_descs(dev, at, at, 1, node)
|
||||
|
@ -178,6 +178,12 @@ struct msi_desc {
|
||||
list_for_each_entry((desc), dev_to_msi_list((dev)), list)
|
||||
#define for_each_msi_entry_safe(desc, tmp, dev) \
|
||||
list_for_each_entry_safe((desc), (tmp), dev_to_msi_list((dev)), list)
|
||||
#define for_each_msi_vector(desc, __irq, dev) \
|
||||
for_each_msi_entry((desc), (dev)) \
|
||||
if ((desc)->irq) \
|
||||
for (__irq = (desc)->irq; \
|
||||
__irq < ((desc)->irq + (desc)->nvec_used); \
|
||||
__irq++)
|
||||
|
||||
#ifdef CONFIG_IRQ_MSI_IOMMU
|
||||
static inline const void *msi_desc_get_iommu_cookie(struct msi_desc *desc)
|
||||
|
@ -436,22 +436,22 @@ int __msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
|
||||
|
||||
can_reserve = msi_check_reservation_mode(domain, info, dev);
|
||||
|
||||
for_each_msi_entry(desc, dev) {
|
||||
virq = desc->irq;
|
||||
if (desc->nvec_used == 1)
|
||||
dev_dbg(dev, "irq %d for MSI\n", virq);
|
||||
else
|
||||
dev_dbg(dev, "irq [%d-%d] for MSI\n",
|
||||
virq, virq + desc->nvec_used - 1);
|
||||
/*
|
||||
* This flag is set by the PCI layer as we need to activate
|
||||
* the MSI entries before the PCI layer enables MSI in the
|
||||
* card. Otherwise the card latches a random msi message.
|
||||
*/
|
||||
if (!(info->flags & MSI_FLAG_ACTIVATE_EARLY))
|
||||
continue;
|
||||
goto skip_activate;
|
||||
|
||||
irq_data = irq_domain_get_irq_data(domain, desc->irq);
|
||||
for_each_msi_vector(desc, i, dev) {
|
||||
if (desc->irq == i) {
|
||||
virq = desc->irq;
|
||||
dev_dbg(dev, "irq [%d-%d] for MSI\n",
|
||||
virq, virq + desc->nvec_used - 1);
|
||||
}
|
||||
|
||||
irq_data = irq_domain_get_irq_data(domain, i);
|
||||
if (!can_reserve) {
|
||||
irqd_clr_can_reserve(irq_data);
|
||||
if (domain->flags & IRQ_DOMAIN_MSI_NOMASK_QUIRK)
|
||||
@ -462,28 +462,24 @@ int __msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
skip_activate:
|
||||
/*
|
||||
* If these interrupts use reservation mode, clear the activated bit
|
||||
* so request_irq() will assign the final vector.
|
||||
*/
|
||||
if (can_reserve) {
|
||||
for_each_msi_entry(desc, dev) {
|
||||
irq_data = irq_domain_get_irq_data(domain, desc->irq);
|
||||
for_each_msi_vector(desc, i, dev) {
|
||||
irq_data = irq_domain_get_irq_data(domain, i);
|
||||
irqd_clr_activated(irq_data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
for_each_msi_entry(desc, dev) {
|
||||
struct irq_data *irqd;
|
||||
|
||||
if (desc->irq == virq)
|
||||
break;
|
||||
|
||||
irqd = irq_domain_get_irq_data(domain, desc->irq);
|
||||
if (irqd_is_activated(irqd))
|
||||
irq_domain_deactivate_irq(irqd);
|
||||
for_each_msi_vector(desc, i, dev) {
|
||||
irq_data = irq_domain_get_irq_data(domain, i);
|
||||
if (irqd_is_activated(irq_data))
|
||||
irq_domain_deactivate_irq(irq_data);
|
||||
}
|
||||
msi_domain_free_irqs(domain, dev);
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user