Merge branches 'irq/sparseirq', 'irq/genirq' and 'irq/urgent'; commit 'v2.6.28' into irq/core

This commit is contained in:
Ingo Molnar 2008-12-25 16:27:54 +01:00
703 changed files with 12777 additions and 6888 deletions

View file

@ -113,7 +113,7 @@ struct acpiphp_slot {
u8 device; /* pci device# */
u32 sun; /* ACPI _SUN (slot unique number) */
unsigned long long sun; /* ACPI _SUN (slot unique number) */
u32 flags; /* see below */
};

View file

@ -337,7 +337,7 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot)
slot->hotplug_slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
acpiphp_slot->slot = slot;
snprintf(name, SLOT_NAME_SIZE, "%u", slot->acpi_slot->sun);
snprintf(name, SLOT_NAME_SIZE, "%llu", slot->acpi_slot->sun);
retval = pci_hp_register(slot->hotplug_slot,
acpiphp_slot->bridge->pci_bus,

View file

@ -255,13 +255,13 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
bridge->nr_slots++;
dbg("found ACPI PCI Hotplug slot %d at PCI %04x:%02x:%02x\n",
dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n",
slot->sun, pci_domain_nr(bridge->pci_bus),
bridge->pci_bus->number, slot->device);
retval = acpiphp_register_hotplug_slot(slot);
if (retval) {
if (retval == -EBUSY)
warn("Slot %d already registered by another "
warn("Slot %llu already registered by another "
"hotplug driver\n", slot->sun);
else
warn("acpiphp_register_hotplug_slot failed "

View file

@ -1402,10 +1402,6 @@ static int __init ibmphp_init(void)
goto error;
}
/* lock ourselves into memory with a module
* count of -1 so that no one can unload us. */
module_put(THIS_MODULE);
exit:
return rc;
@ -1423,4 +1419,3 @@ static void __exit ibmphp_exit(void)
}
module_init(ibmphp_init);
module_exit(ibmphp_exit);

View file

@ -432,18 +432,19 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
goto err_out_release_ctlr;
}
/* Check if slot is occupied */
t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset);
t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
if (value && pciehp_force) {
rc = pciehp_enable_slot(t_slot);
if (rc) /* -ENODEV: shouldn't happen, but deal with it */
value = 0;
}
if ((POWER_CTRL(ctrl)) && !value) {
rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
if (rc)
goto err_out_free_ctrl_slot;
t_slot->hpc_ops->get_adapter_status(t_slot, &value);
if (value) {
if (pciehp_force)
pciehp_enable_slot(t_slot);
} else {
/* Power off slot if not occupied */
if (POWER_CTRL(ctrl)) {
rc = t_slot->hpc_ops->power_off_slot(t_slot);
if (rc)
goto err_out_free_ctrl_slot;
}
}
return 0;

View file

@ -5,6 +5,7 @@
#include <linux/pci.h>
#include <linux/irq.h>
#include <asm/io_apic.h>
#include <asm/smp.h>
#include <linux/intel-iommu.h>
#include "intr_remapping.h"
@ -19,17 +20,75 @@ struct irq_2_iommu {
u8 irte_mask;
};
static struct irq_2_iommu irq_2_iommuX[NR_IRQS];
#ifdef CONFIG_SPARSE_IRQ
static struct irq_2_iommu *get_one_free_irq_2_iommu(int cpu)
{
struct irq_2_iommu *iommu;
int node;
node = cpu_to_node(cpu);
iommu = kzalloc_node(sizeof(*iommu), GFP_ATOMIC, node);
printk(KERN_DEBUG "alloc irq_2_iommu on cpu %d node %d\n", cpu, node);
return iommu;
}
static struct irq_2_iommu *irq_2_iommu(unsigned int irq)
{
return (irq < nr_irqs) ? irq_2_iommuX + irq : NULL;
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_cpu(unsigned int irq, int cpu)
{
struct irq_desc *desc;
struct irq_2_iommu *irq_iommu;
/*
* alloc irq desc if not allocated already.
*/
desc = irq_to_desc_alloc_cpu(irq, cpu);
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(cpu);
return desc->irq_2_iommu;
}
static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq)
{
return irq_2_iommu_alloc_cpu(irq, boot_cpu_id);
}
#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);
@ -86,9 +145,11 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
if (!count)
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.
@ -130,6 +191,12 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
table->base[i].present = 1;
irq_iommu = irq_2_iommu_alloc(irq);
if (!irq_iommu) {
spin_unlock(&irq_2_ir_lock);
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;
@ -177,6 +244,12 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
irq_iommu = irq_2_iommu_alloc(irq);
if (!irq_iommu) {
spin_unlock(&irq_2_ir_lock);
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 = subhandle;

View file

@ -103,11 +103,11 @@ static void msix_set_enable(struct pci_dev *dev, int enable)
}
}
static void msix_flush_writes(unsigned int irq)
static void msix_flush_writes(struct irq_desc *desc)
{
struct msi_desc *entry;
entry = get_irq_msi(irq);
entry = get_irq_desc_msi(desc);
BUG_ON(!entry || !entry->dev);
switch (entry->msi_attrib.type) {
case PCI_CAP_ID_MSI:
@ -135,11 +135,11 @@ static void msix_flush_writes(unsigned int irq)
* Returns 1 if it succeeded in masking the interrupt and 0 if the device
* doesn't support MSI masking.
*/
static int msi_set_mask_bits(unsigned int irq, u32 mask, u32 flag)
static int msi_set_mask_bits(struct irq_desc *desc, u32 mask, u32 flag)
{
struct msi_desc *entry;
entry = get_irq_msi(irq);
entry = get_irq_desc_msi(desc);
BUG_ON(!entry || !entry->dev);
switch (entry->msi_attrib.type) {
case PCI_CAP_ID_MSI:
@ -172,9 +172,9 @@ static int msi_set_mask_bits(unsigned int irq, u32 mask, u32 flag)
return 1;
}
void read_msi_msg(unsigned int irq, struct msi_msg *msg)
void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
{
struct msi_desc *entry = get_irq_msi(irq);
struct msi_desc *entry = get_irq_desc_msi(desc);
switch(entry->msi_attrib.type) {
case PCI_CAP_ID_MSI:
{
@ -211,9 +211,16 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg)
}
}
void write_msi_msg(unsigned int irq, struct msi_msg *msg)
void read_msi_msg(unsigned int irq, struct msi_msg *msg)
{
struct msi_desc *entry = get_irq_msi(irq);
struct irq_desc *desc = irq_to_desc(irq);
read_msi_msg_desc(desc, msg);
}
void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
{
struct msi_desc *entry = get_irq_desc_msi(desc);
switch (entry->msi_attrib.type) {
case PCI_CAP_ID_MSI:
{
@ -252,21 +259,31 @@ void write_msi_msg(unsigned int irq, struct msi_msg *msg)
entry->msg = *msg;
}
void write_msi_msg(unsigned int irq, struct msi_msg *msg)
{
struct irq_desc *desc = irq_to_desc(irq);
write_msi_msg_desc(desc, msg);
}
void mask_msi_irq(unsigned int irq)
{
msi_set_mask_bits(irq, 1, 1);
msix_flush_writes(irq);
struct irq_desc *desc = irq_to_desc(irq);
msi_set_mask_bits(desc, 1, 1);
msix_flush_writes(desc);
}
void unmask_msi_irq(unsigned int irq)
{
msi_set_mask_bits(irq, 1, 0);
msix_flush_writes(irq);
struct irq_desc *desc = irq_to_desc(irq);
msi_set_mask_bits(desc, 1, 0);
msix_flush_writes(desc);
}
static int msi_free_irqs(struct pci_dev* dev);
static struct msi_desc* alloc_msi_entry(void)
{
struct msi_desc *entry;
@ -303,9 +320,11 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
pci_intx_for_msi(dev, 0);
msi_set_enable(dev, 0);
write_msi_msg(dev->irq, &entry->msg);
if (entry->msi_attrib.maskbit)
msi_set_mask_bits(dev->irq, entry->msi_attrib.maskbits_mask,
if (entry->msi_attrib.maskbit) {
struct irq_desc *desc = irq_to_desc(dev->irq);
msi_set_mask_bits(desc, entry->msi_attrib.maskbits_mask,
entry->msi_attrib.masked);
}
pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
control &= ~PCI_MSI_FLAGS_QSIZE;
@ -327,8 +346,9 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
msix_set_enable(dev, 0);
list_for_each_entry(entry, &dev->msi_list, list) {
struct irq_desc *desc = irq_to_desc(entry->irq);
write_msi_msg(entry->irq, &entry->msg);
msi_set_mask_bits(entry->irq, 1, entry->msi_attrib.masked);
msi_set_mask_bits(desc, 1, entry->msi_attrib.masked);
}
BUG_ON(list_empty(&dev->msi_list));
@ -596,7 +616,8 @@ void pci_msi_shutdown(struct pci_dev* dev)
/* Return the the pci reset with msi irqs unmasked */
if (entry->msi_attrib.maskbit) {
u32 mask = entry->msi_attrib.maskbits_mask;
msi_set_mask_bits(dev->irq, mask, ~mask);
struct irq_desc *desc = irq_to_desc(dev->irq);
msi_set_mask_bits(desc, mask, ~mask);
}
if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI)
return;

View file

@ -2042,7 +2042,7 @@ static int __devinit pci_init(void)
return 0;
}
static int __devinit pci_setup(char *str)
static int __init pci_setup(char *str)
{
while (str) {
char *k = strchr(str, ',');

View file

@ -252,7 +252,7 @@ static void report_resume(struct pci_dev *dev, void *data)
if (!dev->driver ||
!dev->driver->err_handler ||
!dev->driver->err_handler->slot_reset)
!dev->driver->err_handler->resume)
return;
err_handler = dev->driver->err_handler;

View file

@ -16,6 +16,7 @@
#include <linux/pm.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/pci-aspm.h>
#include "../pci.h"
@ -161,11 +162,12 @@ static void pcie_check_clock_pm(struct pci_dev *pdev)
*/
static void pcie_aspm_configure_common_clock(struct pci_dev *pdev)
{
int pos, child_pos;
int pos, child_pos, i = 0;
u16 reg16 = 0;
struct pci_dev *child_dev;
int same_clock = 1;
unsigned long start_jiffies;
u16 child_regs[8], parent_reg;
/*
* all functions of a slot should have the same Slot Clock
* Configuration, so just check one function
@ -191,16 +193,19 @@ static void pcie_aspm_configure_common_clock(struct pci_dev *pdev)
child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP);
pci_read_config_word(child_dev, child_pos + PCI_EXP_LNKCTL,
&reg16);
child_regs[i] = reg16;
if (same_clock)
reg16 |= PCI_EXP_LNKCTL_CCC;
else
reg16 &= ~PCI_EXP_LNKCTL_CCC;
pci_write_config_word(child_dev, child_pos + PCI_EXP_LNKCTL,
reg16);
i++;
}
/* Configure upstream component */
pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
parent_reg = reg16;
if (same_clock)
reg16 |= PCI_EXP_LNKCTL_CCC;
else
@ -212,12 +217,30 @@ static void pcie_aspm_configure_common_clock(struct pci_dev *pdev)
pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
/* Wait for link training end */
while (1) {
/* break out after waiting for 1 second */
start_jiffies = jiffies;
while ((jiffies - start_jiffies) < HZ) {
pci_read_config_word(pdev, pos + PCI_EXP_LNKSTA, &reg16);
if (!(reg16 & PCI_EXP_LNKSTA_LT))
break;
cpu_relax();
}
/* training failed -> recover */
if ((jiffies - start_jiffies) >= HZ) {
dev_printk (KERN_ERR, &pdev->dev, "ASPM: Could not configure"
" common clock\n");
i = 0;
list_for_each_entry(child_dev, &pdev->subordinate->devices,
bus_list) {
child_pos = pci_find_capability(child_dev,
PCI_CAP_ID_EXP);
pci_write_config_word(child_dev,
child_pos + PCI_EXP_LNKCTL,
child_regs[i]);
i++;
}
pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, parent_reg);
}
}
/*

View file

@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/acpi.h>
#include <linux/kallsyms.h>
#include <linux/dmi.h>
#include "pci.h"
int isa_dma_bridge_buggy;
@ -1828,6 +1829,22 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS,
PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB,
ht_enable_msi_mapping);
/* The P5N32-SLI Premium motherboard from Asus has a problem with msi
* for the MCP55 NIC. It is not yet determined whether the msi problem
* also affects other devices. As for now, turn off msi for this device.
*/
static void __devinit nvenet_msi_disable(struct pci_dev *dev)
{
if (dmi_name_in_vendors("P5N32-SLI PREMIUM")) {
dev_info(&dev->dev,
"Disabling msi for MCP55 NIC on P5N32-SLI Premium\n");
dev->no_msi = 1;
}
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA,
PCI_DEVICE_ID_NVIDIA_NVENET_15,
nvenet_msi_disable);
static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
{
struct pci_dev *host_bridge;

View file

@ -253,6 +253,7 @@ placeholder:
__func__, pci_domain_nr(parent), parent->number, slot_nr);
out:
kfree(slot_name);
up_write(&pci_bus_sem);
return slot;
err: