mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-04 20:19:47 +08:00 
			
		
		
		
	irqchip/armada-370-xp: Allow allocation of multiple MSIs
Add support for allocating multiple MSIs at the same time, so that the MSI_FLAG_MULTI_PCI_MSI flag can be added to the msi_domain_info structure. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Reviewed-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Link: https://lkml.kernel.org/r/1455115621-22846-6-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
This commit is contained in:
		
							parent
							
								
									f692a172de
								
							
						
					
					
						commit
						a71b9412c9
					
				| @ -123,7 +123,8 @@ static struct irq_chip armada_370_xp_msi_irq_chip = { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static struct msi_domain_info armada_370_xp_msi_domain_info = { | static struct msi_domain_info armada_370_xp_msi_domain_info = { | ||||||
| 	.flags	= (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS), | 	.flags	= (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | | ||||||
|  | 		   MSI_FLAG_MULTI_PCI_MSI), | ||||||
| 	.chip	= &armada_370_xp_msi_irq_chip, | 	.chip	= &armada_370_xp_msi_irq_chip, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -149,21 +150,26 @@ static struct irq_chip armada_370_xp_msi_bottom_irq_chip = { | |||||||
| static int armada_370_xp_msi_alloc(struct irq_domain *domain, unsigned int virq, | static int armada_370_xp_msi_alloc(struct irq_domain *domain, unsigned int virq, | ||||||
| 				   unsigned int nr_irqs, void *args) | 				   unsigned int nr_irqs, void *args) | ||||||
| { | { | ||||||
| 	int hwirq; | 	int hwirq, i; | ||||||
| 
 | 
 | ||||||
| 	mutex_lock(&msi_used_lock); | 	mutex_lock(&msi_used_lock); | ||||||
| 	hwirq = find_first_zero_bit(&msi_used, PCI_MSI_DOORBELL_NR); | 
 | ||||||
|  | 	hwirq = bitmap_find_next_zero_area(msi_used, PCI_MSI_DOORBELL_NR, | ||||||
|  | 					   0, nr_irqs, 0); | ||||||
| 	if (hwirq >= PCI_MSI_DOORBELL_NR) { | 	if (hwirq >= PCI_MSI_DOORBELL_NR) { | ||||||
| 		mutex_unlock(&msi_used_lock); | 		mutex_unlock(&msi_used_lock); | ||||||
| 		return -ENOSPC; | 		return -ENOSPC; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	set_bit(hwirq, msi_used); | 	bitmap_set(msi_used, hwirq, nr_irqs); | ||||||
| 	mutex_unlock(&msi_used_lock); | 	mutex_unlock(&msi_used_lock); | ||||||
| 
 | 
 | ||||||
| 	irq_domain_set_info(domain, virq, hwirq, &armada_370_xp_msi_bottom_irq_chip, | 	for (i = 0; i < nr_irqs; i++) { | ||||||
|  | 		irq_domain_set_info(domain, virq + i, hwirq + i, | ||||||
|  | 				    &armada_370_xp_msi_bottom_irq_chip, | ||||||
| 				    domain->host_data, handle_simple_irq, | 				    domain->host_data, handle_simple_irq, | ||||||
| 				    NULL, NULL); | 				    NULL, NULL); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	return hwirq; | 	return hwirq; | ||||||
| } | } | ||||||
| @ -174,10 +180,7 @@ static void armada_370_xp_msi_free(struct irq_domain *domain, | |||||||
| 	struct irq_data *d = irq_domain_get_irq_data(domain, virq); | 	struct irq_data *d = irq_domain_get_irq_data(domain, virq); | ||||||
| 
 | 
 | ||||||
| 	mutex_lock(&msi_used_lock); | 	mutex_lock(&msi_used_lock); | ||||||
| 	if (!test_bit(d->hwirq, msi_used)) | 	bitmap_clear(msi_used, d->hwirq, nr_irqs); | ||||||
| 		pr_err("trying to free unused MSI#%lu\n", d->hwirq); |  | ||||||
| 	else |  | ||||||
| 		clear_bit(d->hwirq, msi_used); |  | ||||||
| 	mutex_unlock(&msi_used_lock); | 	mutex_unlock(&msi_used_lock); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Thomas Petazzoni
						Thomas Petazzoni