mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
Merge commit 'konrad/stable/xen-pcifront-0.8.2' into 2.6.36-rc8-initial-domain-v6
This commit is contained in:
commit
67ba37293e
122 changed files with 3944 additions and 2270 deletions
|
|
@ -40,6 +40,27 @@ config PCI_STUB
|
|||
|
||||
When in doubt, say N.
|
||||
|
||||
config XEN_PCIDEV_FRONTEND
|
||||
tristate "Xen PCI Frontend"
|
||||
depends on PCI && X86 && XEN
|
||||
select HOTPLUG
|
||||
select PCI_XEN
|
||||
default y
|
||||
help
|
||||
The PCI device frontend driver allows the kernel to import arbitrary
|
||||
PCI devices from a PCI backend to support PCI driver domains.
|
||||
|
||||
config XEN_PCIDEV_FE_DEBUG
|
||||
bool "Xen PCI Frontend debugging"
|
||||
depends on XEN_PCIDEV_FRONTEND && PCI_DEBUG
|
||||
help
|
||||
Say Y here if you want the Xen PCI frontend to produce a bunch of debug
|
||||
messages to the system log. Select this if you are having a
|
||||
problem with Xen PCI frontend support and want to see more of what is
|
||||
going on.
|
||||
|
||||
When in doubt, say N.
|
||||
|
||||
config HT_IRQ
|
||||
bool "Interrupts on hypertransport devices"
|
||||
default y
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ obj-$(CONFIG_PCI_SYSCALL) += syscall.o
|
|||
|
||||
obj-$(CONFIG_PCI_STUB) += pci-stub.o
|
||||
|
||||
obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o
|
||||
|
||||
ifeq ($(CONFIG_PCI_DEBUG),y)
|
||||
EXTRA_CFLAGS += -DDEBUG
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -299,6 +299,7 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *),
|
|||
}
|
||||
up_read(&pci_bus_sem);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_walk_bus);
|
||||
|
||||
EXPORT_SYMBOL(pci_bus_alloc_resource);
|
||||
EXPORT_SYMBOL_GPL(pci_bus_add_device);
|
||||
|
|
|
|||
|
|
@ -1221,9 +1221,9 @@ const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type)
|
|||
}
|
||||
}
|
||||
|
||||
void dmar_msi_unmask(unsigned int irq)
|
||||
void dmar_msi_unmask(struct irq_data *data)
|
||||
{
|
||||
struct intel_iommu *iommu = get_irq_data(irq);
|
||||
struct intel_iommu *iommu = irq_data_get_irq_data(data);
|
||||
unsigned long flag;
|
||||
|
||||
/* unmask it */
|
||||
|
|
@ -1234,10 +1234,10 @@ void dmar_msi_unmask(unsigned int irq)
|
|||
spin_unlock_irqrestore(&iommu->register_lock, flag);
|
||||
}
|
||||
|
||||
void dmar_msi_mask(unsigned int irq)
|
||||
void dmar_msi_mask(struct irq_data *data)
|
||||
{
|
||||
unsigned long flag;
|
||||
struct intel_iommu *iommu = get_irq_data(irq);
|
||||
struct intel_iommu *iommu = irq_data_get_irq_data(data);
|
||||
|
||||
/* mask it */
|
||||
spin_lock_irqsave(&iommu->register_lock, flag);
|
||||
|
|
|
|||
|
|
@ -57,28 +57,22 @@ void fetch_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg)
|
|||
*msg = cfg->msg;
|
||||
}
|
||||
|
||||
void mask_ht_irq(unsigned int irq)
|
||||
void mask_ht_irq(struct irq_data *data)
|
||||
{
|
||||
struct ht_irq_cfg *cfg;
|
||||
struct ht_irq_msg msg;
|
||||
struct ht_irq_cfg *cfg = irq_data_get_irq_data(data);
|
||||
struct ht_irq_msg msg = cfg->msg;
|
||||
|
||||
cfg = get_irq_data(irq);
|
||||
|
||||
msg = cfg->msg;
|
||||
msg.address_lo |= 1;
|
||||
write_ht_irq_msg(irq, &msg);
|
||||
write_ht_irq_msg(data->irq, &msg);
|
||||
}
|
||||
|
||||
void unmask_ht_irq(unsigned int irq)
|
||||
void unmask_ht_irq(struct irq_data *data)
|
||||
{
|
||||
struct ht_irq_cfg *cfg;
|
||||
struct ht_irq_msg msg;
|
||||
struct ht_irq_cfg *cfg = irq_data_get_irq_data(data);
|
||||
struct ht_irq_msg msg = cfg->msg;
|
||||
|
||||
cfg = get_irq_data(irq);
|
||||
|
||||
msg = cfg->msg;
|
||||
msg.address_lo &= ~1;
|
||||
write_ht_irq_msg(irq, &msg);
|
||||
write_ht_irq_msg(data->irq, &msg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -46,109 +46,24 @@ static __init int setup_intremap(char *str)
|
|||
}
|
||||
early_param("intremap", setup_intremap);
|
||||
|
||||
struct irq_2_iommu {
|
||||
struct intel_iommu *iommu;
|
||||
u16 irte_index;
|
||||
u16 sub_handle;
|
||||
u8 irte_mask;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_GENERIC_HARDIRQS
|
||||
static struct irq_2_iommu *get_one_free_irq_2_iommu(int node)
|
||||
{
|
||||
struct irq_2_iommu *iommu;
|
||||
|
||||
iommu = kzalloc_node(sizeof(*iommu), GFP_ATOMIC, node);
|
||||
printk(KERN_DEBUG "alloc irq_2_iommu on node %d\n", node);
|
||||
|
||||
return iommu;
|
||||
}
|
||||
|
||||
static struct irq_2_iommu *irq_2_iommu(unsigned int irq)
|
||||
{
|
||||
struct irq_desc *desc;
|
||||
|
||||
desc = irq_to_desc(irq);
|
||||
|
||||
if (WARN_ON_ONCE(!desc))
|
||||
return NULL;
|
||||
|
||||
return desc->irq_2_iommu;
|
||||
}
|
||||
|
||||
static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq)
|
||||
{
|
||||
struct irq_desc *desc;
|
||||
struct irq_2_iommu *irq_iommu;
|
||||
|
||||
desc = irq_to_desc(irq);
|
||||
if (!desc) {
|
||||
printk(KERN_INFO "can not get irq_desc for %d\n", irq);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
irq_iommu = desc->irq_2_iommu;
|
||||
|
||||
if (!irq_iommu)
|
||||
desc->irq_2_iommu = get_one_free_irq_2_iommu(irq_node(irq));
|
||||
|
||||
return desc->irq_2_iommu;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_SPARSE_IRQ */
|
||||
|
||||
static struct irq_2_iommu irq_2_iommuX[NR_IRQS];
|
||||
|
||||
static struct irq_2_iommu *irq_2_iommu(unsigned int irq)
|
||||
{
|
||||
if (irq < nr_irqs)
|
||||
return &irq_2_iommuX[irq];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq)
|
||||
{
|
||||
return irq_2_iommu(irq);
|
||||
}
|
||||
#endif
|
||||
|
||||
static DEFINE_SPINLOCK(irq_2_ir_lock);
|
||||
|
||||
static struct irq_2_iommu *valid_irq_2_iommu(unsigned int irq)
|
||||
static struct irq_2_iommu *irq_2_iommu(unsigned int irq)
|
||||
{
|
||||
struct irq_2_iommu *irq_iommu;
|
||||
|
||||
irq_iommu = irq_2_iommu(irq);
|
||||
|
||||
if (!irq_iommu)
|
||||
return NULL;
|
||||
|
||||
if (!irq_iommu->iommu)
|
||||
return NULL;
|
||||
|
||||
return irq_iommu;
|
||||
}
|
||||
|
||||
int irq_remapped(int irq)
|
||||
{
|
||||
return valid_irq_2_iommu(irq) != NULL;
|
||||
struct irq_cfg *cfg = get_irq_chip_data(irq);
|
||||
return cfg ? &cfg->irq_2_iommu : NULL;
|
||||
}
|
||||
|
||||
int get_irte(int irq, struct irte *entry)
|
||||
{
|
||||
int index;
|
||||
struct irq_2_iommu *irq_iommu;
|
||||
struct irq_2_iommu *irq_iommu = irq_2_iommu(irq);
|
||||
unsigned long flags;
|
||||
int index;
|
||||
|
||||
if (!entry)
|
||||
if (!entry || !irq_iommu)
|
||||
return -1;
|
||||
|
||||
spin_lock_irqsave(&irq_2_ir_lock, flags);
|
||||
irq_iommu = valid_irq_2_iommu(irq);
|
||||
if (!irq_iommu) {
|
||||
spin_unlock_irqrestore(&irq_2_ir_lock, flags);
|
||||
return -1;
|
||||
}
|
||||
|
||||
index = irq_iommu->irte_index + irq_iommu->sub_handle;
|
||||
*entry = *(irq_iommu->iommu->ir_table->base + index);
|
||||
|
|
@ -160,21 +75,15 @@ int get_irte(int irq, struct irte *entry)
|
|||
int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
|
||||
{
|
||||
struct ir_table *table = iommu->ir_table;
|
||||
struct irq_2_iommu *irq_iommu;
|
||||
struct irq_2_iommu *irq_iommu = irq_2_iommu(irq);
|
||||
u16 index, start_index;
|
||||
unsigned int mask = 0;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
if (!count)
|
||||
if (!count || !irq_iommu)
|
||||
return -1;
|
||||
|
||||
#ifndef CONFIG_SPARSE_IRQ
|
||||
/* protect irq_2_iommu_alloc later */
|
||||
if (irq >= nr_irqs)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* start the IRTE search from index 0.
|
||||
*/
|
||||
|
|
@ -214,13 +123,6 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
|
|||
for (i = index; i < index + count; i++)
|
||||
table->base[i].present = 1;
|
||||
|
||||
irq_iommu = irq_2_iommu_alloc(irq);
|
||||
if (!irq_iommu) {
|
||||
spin_unlock_irqrestore(&irq_2_ir_lock, flags);
|
||||
printk(KERN_ERR "can't allocate irq_2_iommu\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
irq_iommu->iommu = iommu;
|
||||
irq_iommu->irte_index = index;
|
||||
irq_iommu->sub_handle = 0;
|
||||
|
|
@ -244,17 +146,14 @@ static int qi_flush_iec(struct intel_iommu *iommu, int index, int mask)
|
|||
|
||||
int map_irq_to_irte_handle(int irq, u16 *sub_handle)
|
||||
{
|
||||
int index;
|
||||
struct irq_2_iommu *irq_iommu;
|
||||
struct irq_2_iommu *irq_iommu = irq_2_iommu(irq);
|
||||
unsigned long flags;
|
||||
int index;
|
||||
|
||||
if (!irq_iommu)
|
||||
return -1;
|
||||
|
||||
spin_lock_irqsave(&irq_2_ir_lock, flags);
|
||||
irq_iommu = valid_irq_2_iommu(irq);
|
||||
if (!irq_iommu) {
|
||||
spin_unlock_irqrestore(&irq_2_ir_lock, flags);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*sub_handle = irq_iommu->sub_handle;
|
||||
index = irq_iommu->irte_index;
|
||||
spin_unlock_irqrestore(&irq_2_ir_lock, flags);
|
||||
|
|
@ -263,18 +162,13 @@ int map_irq_to_irte_handle(int irq, u16 *sub_handle)
|
|||
|
||||
int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
|
||||
{
|
||||
struct irq_2_iommu *irq_iommu;
|
||||
struct irq_2_iommu *irq_iommu = irq_2_iommu(irq);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&irq_2_ir_lock, flags);
|
||||
|
||||
irq_iommu = irq_2_iommu_alloc(irq);
|
||||
|
||||
if (!irq_iommu) {
|
||||
spin_unlock_irqrestore(&irq_2_ir_lock, flags);
|
||||
printk(KERN_ERR "can't allocate irq_2_iommu\n");
|
||||
if (!irq_iommu)
|
||||
return -1;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&irq_2_ir_lock, flags);
|
||||
|
||||
irq_iommu->iommu = iommu;
|
||||
irq_iommu->irte_index = index;
|
||||
|
|
@ -286,43 +180,18 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index)
|
||||
{
|
||||
struct irq_2_iommu *irq_iommu;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&irq_2_ir_lock, flags);
|
||||
irq_iommu = valid_irq_2_iommu(irq);
|
||||
if (!irq_iommu) {
|
||||
spin_unlock_irqrestore(&irq_2_ir_lock, flags);
|
||||
return -1;
|
||||
}
|
||||
|
||||
irq_iommu->iommu = NULL;
|
||||
irq_iommu->irte_index = 0;
|
||||
irq_iommu->sub_handle = 0;
|
||||
irq_2_iommu(irq)->irte_mask = 0;
|
||||
|
||||
spin_unlock_irqrestore(&irq_2_ir_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int modify_irte(int irq, struct irte *irte_modified)
|
||||
{
|
||||
int rc;
|
||||
int index;
|
||||
struct irte *irte;
|
||||
struct irq_2_iommu *irq_iommu = irq_2_iommu(irq);
|
||||
struct intel_iommu *iommu;
|
||||
struct irq_2_iommu *irq_iommu;
|
||||
unsigned long flags;
|
||||
struct irte *irte;
|
||||
int rc, index;
|
||||
|
||||
if (!irq_iommu)
|
||||
return -1;
|
||||
|
||||
spin_lock_irqsave(&irq_2_ir_lock, flags);
|
||||
irq_iommu = valid_irq_2_iommu(irq);
|
||||
if (!irq_iommu) {
|
||||
spin_unlock_irqrestore(&irq_2_ir_lock, flags);
|
||||
return -1;
|
||||
}
|
||||
|
||||
iommu = irq_iommu->iommu;
|
||||
|
||||
|
|
@ -339,31 +208,6 @@ int modify_irte(int irq, struct irte *irte_modified)
|
|||
return rc;
|
||||
}
|
||||
|
||||
int flush_irte(int irq)
|
||||
{
|
||||
int rc;
|
||||
int index;
|
||||
struct intel_iommu *iommu;
|
||||
struct irq_2_iommu *irq_iommu;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&irq_2_ir_lock, flags);
|
||||
irq_iommu = valid_irq_2_iommu(irq);
|
||||
if (!irq_iommu) {
|
||||
spin_unlock_irqrestore(&irq_2_ir_lock, flags);
|
||||
return -1;
|
||||
}
|
||||
|
||||
iommu = irq_iommu->iommu;
|
||||
|
||||
index = irq_iommu->irte_index + irq_iommu->sub_handle;
|
||||
|
||||
rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask);
|
||||
spin_unlock_irqrestore(&irq_2_ir_lock, flags);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct intel_iommu *map_hpet_to_ir(u8 hpet_id)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -420,16 +264,14 @@ static int clear_entries(struct irq_2_iommu *irq_iommu)
|
|||
|
||||
int free_irte(int irq)
|
||||
{
|
||||
int rc = 0;
|
||||
struct irq_2_iommu *irq_iommu;
|
||||
struct irq_2_iommu *irq_iommu = irq_2_iommu(irq);
|
||||
unsigned long flags;
|
||||
int rc;
|
||||
|
||||
if (!irq_iommu)
|
||||
return -1;
|
||||
|
||||
spin_lock_irqsave(&irq_2_ir_lock, flags);
|
||||
irq_iommu = valid_irq_2_iommu(irq);
|
||||
if (!irq_iommu) {
|
||||
spin_unlock_irqrestore(&irq_2_ir_lock, flags);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = clear_entries(irq_iommu);
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,12 @@ int arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
|
|||
#endif
|
||||
|
||||
#ifndef arch_setup_msi_irqs
|
||||
int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
|
||||
# define arch_setup_msi_irqs default_setup_msi_irqs
|
||||
# define HAVE_DEFAULT_MSI_SETUP_IRQS
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DEFAULT_MSI_SETUP_IRQS
|
||||
int default_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
|
||||
{
|
||||
struct msi_desc *entry;
|
||||
int ret;
|
||||
|
|
@ -60,7 +65,12 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
|
|||
#endif
|
||||
|
||||
#ifndef arch_teardown_msi_irqs
|
||||
void arch_teardown_msi_irqs(struct pci_dev *dev)
|
||||
# define arch_teardown_msi_irqs default_teardown_msi_irqs
|
||||
# define HAVE_DEFAULT_MSI_TEARDOWN_IRQS
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DEFAULT_MSI_TEARDOWN_IRQS
|
||||
void default_teardown_msi_irqs(struct pci_dev *dev)
|
||||
{
|
||||
struct msi_desc *entry;
|
||||
|
||||
|
|
@ -170,33 +180,31 @@ static void msix_mask_irq(struct msi_desc *desc, u32 flag)
|
|||
desc->masked = __msix_mask_irq(desc, flag);
|
||||
}
|
||||
|
||||
static void msi_set_mask_bit(unsigned irq, u32 flag)
|
||||
static void msi_set_mask_bit(struct irq_data *data, u32 flag)
|
||||
{
|
||||
struct msi_desc *desc = get_irq_msi(irq);
|
||||
struct msi_desc *desc = irq_data_get_msi(data);
|
||||
|
||||
if (desc->msi_attrib.is_msix) {
|
||||
msix_mask_irq(desc, flag);
|
||||
readl(desc->mask_base); /* Flush write to device */
|
||||
} else {
|
||||
unsigned offset = irq - desc->dev->irq;
|
||||
unsigned offset = data->irq - desc->dev->irq;
|
||||
msi_mask_irq(desc, 1 << offset, flag << offset);
|
||||
}
|
||||
}
|
||||
|
||||
void mask_msi_irq(unsigned int irq)
|
||||
void mask_msi_irq(struct irq_data *data)
|
||||
{
|
||||
msi_set_mask_bit(irq, 1);
|
||||
msi_set_mask_bit(data, 1);
|
||||
}
|
||||
|
||||
void unmask_msi_irq(unsigned int irq)
|
||||
void unmask_msi_irq(struct irq_data *data)
|
||||
{
|
||||
msi_set_mask_bit(irq, 0);
|
||||
msi_set_mask_bit(data, 0);
|
||||
}
|
||||
|
||||
void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
|
||||
void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
|
||||
{
|
||||
struct msi_desc *entry = get_irq_desc_msi(desc);
|
||||
|
||||
BUG_ON(entry->dev->current_state != PCI_D0);
|
||||
|
||||
if (entry->msi_attrib.is_msix) {
|
||||
|
|
@ -227,15 +235,13 @@ void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
|
|||
|
||||
void read_msi_msg(unsigned int irq, struct msi_msg *msg)
|
||||
{
|
||||
struct irq_desc *desc = irq_to_desc(irq);
|
||||
struct msi_desc *entry = get_irq_msi(irq);
|
||||
|
||||
read_msi_msg_desc(desc, msg);
|
||||
__read_msi_msg(entry, msg);
|
||||
}
|
||||
|
||||
void get_cached_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
|
||||
void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
|
||||
{
|
||||
struct msi_desc *entry = get_irq_desc_msi(desc);
|
||||
|
||||
/* Assert that the cache is valid, assuming that
|
||||
* valid messages are not all-zeroes. */
|
||||
BUG_ON(!(entry->msg.address_hi | entry->msg.address_lo |
|
||||
|
|
@ -246,15 +252,13 @@ void get_cached_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
|
|||
|
||||
void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg)
|
||||
{
|
||||
struct irq_desc *desc = irq_to_desc(irq);
|
||||
struct msi_desc *entry = get_irq_msi(irq);
|
||||
|
||||
get_cached_msi_msg_desc(desc, msg);
|
||||
__get_cached_msi_msg(entry, msg);
|
||||
}
|
||||
|
||||
void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
|
||||
void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
|
||||
{
|
||||
struct msi_desc *entry = get_irq_desc_msi(desc);
|
||||
|
||||
if (entry->dev->current_state != PCI_D0) {
|
||||
/* Don't touch the hardware now */
|
||||
} else if (entry->msi_attrib.is_msix) {
|
||||
|
|
@ -292,9 +296,9 @@ void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
|
|||
|
||||
void write_msi_msg(unsigned int irq, struct msi_msg *msg)
|
||||
{
|
||||
struct irq_desc *desc = irq_to_desc(irq);
|
||||
struct msi_desc *entry = get_irq_msi(irq);
|
||||
|
||||
write_msi_msg_desc(desc, msg);
|
||||
__write_msi_msg(entry, msg);
|
||||
}
|
||||
|
||||
static void free_msi_irqs(struct pci_dev *dev)
|
||||
|
|
|
|||
1148
drivers/pci/xen-pcifront.c
Normal file
1148
drivers/pci/xen-pcifront.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue