mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 19:51:31 -04:00
Merge branches 'irq/sparseirq', 'irq/genirq' and 'irq/urgent'; commit 'v2.6.28' into irq/core
This commit is contained in:
commit
860cf8894b
703 changed files with 12777 additions and 6888 deletions
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 "
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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, ',');
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
®16);
|
||||
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, ®16);
|
||||
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, ®16);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in a new issue