Skip to content

Commit

Permalink
Merge branch 'pci/host-vmd' into next
Browse files Browse the repository at this point in the history
* pci/host-vmd:
  x86/PCI: Add driver for Intel Volume Management Device (VMD)
  PCI/AER: Use 32 bit PCI domain numbers
  x86/PCI: Allow DMA ops specific to a PCI domain
  irqdomain: Export irq_domain_set_info() for module use
  genirq/MSI: Relax msi_domain_alloc() to support parentless MSI irqdomains
  • Loading branch information
Bjorn Helgaas committed Jan 15, 2016
2 parents 4723584 + 185a383 commit 3a6384b
Show file tree
Hide file tree
Showing 10 changed files with 811 additions and 11 deletions.
6 changes: 6 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -8216,6 +8216,12 @@ S: Maintained
F: Documentation/devicetree/bindings/pci/host-generic-pci.txt
F: drivers/pci/host/pci-host-generic.c

PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD)
M: Keith Busch <keith.busch@intel.com>
L: linux-pci@vger.kernel.org
S: Supported
F: arch/x86/pci/vmd.c

PCIE DRIVER FOR ST SPEAR13XX
M: Pratyush Anand <pratyush.anand@gmail.com>
L: linux-pci@vger.kernel.org
Expand Down
13 changes: 13 additions & 0 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2665,6 +2665,19 @@ config PMC_ATOM
def_bool y
depends on PCI

config VMD
depends on PCI_MSI
tristate "Volume Management Device Driver"
default N
---help---
Adds support for the Intel Volume Management Device (VMD). VMD is a
secondary PCI host bridge that allows PCI Express root ports,
and devices attached to them, to be removed from the default
PCI domain and placed within the VMD domain. This provides
more bus resources than are otherwise possible with a
single domain. If you know your system provides one of these and
has devices attached to it, say Y; if you are not sure, say N.

source "net/Kconfig"

source "drivers/Kconfig"
Expand Down
10 changes: 10 additions & 0 deletions arch/x86/include/asm/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ struct dev_archdata {
#endif
};

#if defined(CONFIG_X86_DEV_DMA_OPS) && defined(CONFIG_PCI_DOMAINS)
struct dma_domain {
struct list_head node;
struct dma_map_ops *dma_ops;
int domain_nr;
};
void add_dma_domain(struct dma_domain *domain);
void del_dma_domain(struct dma_domain *domain);
#endif

struct pdev_archdata {
};

Expand Down
5 changes: 5 additions & 0 deletions arch/x86/include/asm/hw_irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ struct irq_alloc_info {
unsigned long uv_offset;
char *uv_name;
};
#endif
#if IS_ENABLED(CONFIG_VMD)
struct {
struct msi_desc *desc;
};
#endif
};
};
Expand Down
2 changes: 2 additions & 0 deletions arch/x86/pci/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ obj-y += bus_numa.o
obj-$(CONFIG_AMD_NB) += amd_bus.o
obj-$(CONFIG_PCI_CNB20LE_QUIRK) += broadcom_bus.o

obj-$(CONFIG_VMD) += vmd.o

ifeq ($(CONFIG_PCI_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
endif
38 changes: 38 additions & 0 deletions arch/x86/pci/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,43 @@ unsigned int pcibios_assign_all_busses(void)
return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
}

#if defined(CONFIG_X86_DEV_DMA_OPS) && defined(CONFIG_PCI_DOMAINS)
static LIST_HEAD(dma_domain_list);
static DEFINE_SPINLOCK(dma_domain_list_lock);

void add_dma_domain(struct dma_domain *domain)
{
spin_lock(&dma_domain_list_lock);
list_add(&domain->node, &dma_domain_list);
spin_unlock(&dma_domain_list_lock);
}
EXPORT_SYMBOL_GPL(add_dma_domain);

void del_dma_domain(struct dma_domain *domain)
{
spin_lock(&dma_domain_list_lock);
list_del(&domain->node);
spin_unlock(&dma_domain_list_lock);
}
EXPORT_SYMBOL_GPL(del_dma_domain);

static void set_dma_domain_ops(struct pci_dev *pdev)
{
struct dma_domain *domain;

spin_lock(&dma_domain_list_lock);
list_for_each_entry(domain, &dma_domain_list, node) {
if (pci_domain_nr(pdev->bus) == domain->domain_nr) {
pdev->dev.archdata.dma_ops = domain->dma_ops;
break;
}
}
spin_unlock(&dma_domain_list_lock);
}
#else
static void set_dma_domain_ops(struct pci_dev *pdev) {}
#endif

int pcibios_add_device(struct pci_dev *dev)
{
struct setup_data *data;
Expand Down Expand Up @@ -670,6 +707,7 @@ int pcibios_add_device(struct pci_dev *dev)
pa_data = data->next;
iounmap(data);
}
set_dma_domain_ops(dev);
return 0;
}

Expand Down
Loading

0 comments on commit 3a6384b

Please sign in to comment.