diff options
Diffstat (limited to 'drivers/pci/controller/vmd.c')
| -rw-r--r-- | drivers/pci/controller/vmd.c | 19 | 
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c index 942b64fc7f1f..e50b0b5815ff 100644 --- a/drivers/pci/controller/vmd.c +++ b/drivers/pci/controller/vmd.c @@ -197,9 +197,20 @@ static struct vmd_irq_list *vmd_next_irq(struct vmd_dev *vmd, struct msi_desc *d  	int i, best = 1;  	unsigned long flags; -	if (pci_is_bridge(msi_desc_to_pci_dev(desc)) || vmd->msix_count == 1) +	if (vmd->msix_count == 1)  		return &vmd->irqs[0]; +	/* +	 * White list for fast-interrupt handlers. All others will share the +	 * "slow" interrupt vector. +	 */ +	switch (msi_desc_to_pci_dev(desc)->class) { +	case PCI_CLASS_STORAGE_EXPRESS: +		break; +	default: +		return &vmd->irqs[0]; +	} +  	raw_spin_lock_irqsave(&list_lock, flags);  	for (i = 1; i < vmd->msix_count; i++)  		if (vmd->irqs[i].count < vmd->irqs[best].count) @@ -393,12 +404,10 @@ static int vmd_dma_supported(struct device *dev, u64 mask)  	return vmd_dma_ops(dev)->dma_supported(to_vmd_dev(dev), mask);  } -#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK  static u64 vmd_get_required_mask(struct device *dev)  {  	return vmd_dma_ops(dev)->get_required_mask(to_vmd_dev(dev));  } -#endif  static void vmd_teardown_dma_ops(struct vmd_dev *vmd)  { @@ -439,9 +448,7 @@ static void vmd_setup_dma_ops(struct vmd_dev *vmd)  	ASSIGN_VMD_DMA_OPS(source, dest, sync_sg_for_device);  	ASSIGN_VMD_DMA_OPS(source, dest, mapping_error);  	ASSIGN_VMD_DMA_OPS(source, dest, dma_supported); -#ifdef ARCH_HAS_DMA_GET_REQUIRED_MASK  	ASSIGN_VMD_DMA_OPS(source, dest, get_required_mask); -#endif  	add_dma_domain(domain);  }  #undef ASSIGN_VMD_DMA_OPS @@ -802,12 +809,12 @@ static void vmd_remove(struct pci_dev *dev)  {  	struct vmd_dev *vmd = pci_get_drvdata(dev); -	vmd_detach_resources(vmd);  	sysfs_remove_link(&vmd->dev->dev.kobj, "domain");  	pci_stop_root_bus(vmd->bus);  	pci_remove_root_bus(vmd->bus);  	vmd_cleanup_srcu(vmd);  	vmd_teardown_dma_ops(vmd); +	vmd_detach_resources(vmd);  	irq_domain_remove(vmd->irq_domain);  }  | 
