Commit 25a3a555 authored by Dely Sy's avatar Dely Sy Committed by Greg Kroah-Hartman

[PATCH] PCI: Updates for PCI Express hot-plug driver

parent bae19b18
......@@ -37,6 +37,7 @@
#include <linux/spinlock.h>
#include <linux/pci.h>
#include <asm/system.h>
#include "../pci.h"
#include "pciehp.h"
#ifdef DEBUG
......@@ -315,12 +316,13 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__);
}
retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, cmd);
dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd);
retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, cmd | CMD_CMPL_INTR_ENABLE);
if (retval) {
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return retval;
}
dbg("%s : hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd);
dbg("%s : hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd | CMD_CMPL_INTR_ENABLE);
dbg("%s : Exit\n", __FUNCTION__);
DBG_LEAVE_ROUTINE
......@@ -918,13 +920,32 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
return IRQ_NONE;;
}
temp_word = (temp_word & ~HP_INTR_ENABLE) | 0x00;
dbg("%s: Set Mask Hot-plug Interrupt Enable\n", __FUNCTION__);
dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
if (rc) {
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return IRQ_NONE;;
return IRQ_NONE;
}
dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE;
}
dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status);
/* Clear command complete interrupt caused by this write */
temp_word = 0x1f;
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
if (rc) {
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE;
}
dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word);
}
if (intr_loc & CMD_COMPLETED) {
......@@ -949,7 +970,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
hp_slot, php_ctlr->callback_instance_id);
/* Clear all events after serving them */
temp_word = slot_status | 0xff;
temp_word = 0x1F;
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
if (rc) {
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
......@@ -963,6 +984,8 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
return IRQ_NONE;
}
dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__);
dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word);
......@@ -970,6 +993,23 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
return IRQ_NONE;
}
dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE;
}
dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status);
/* Clear command complete interrupt caused by this write */
temp_word = 0x1F;
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
if (rc) {
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
return IRQ_NONE;
}
dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word);
}
return IRQ_HANDLED;
......@@ -1330,7 +1370,7 @@ int pcie_init(struct controller * ctrl,
}
dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word);
temp_word = (temp_word & ~HP_INTR_ENABLE) | 0x00;
temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word);
if (rc) {
......@@ -1346,12 +1386,13 @@ int pcie_init(struct controller * ctrl,
}
dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status);
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
temp_word = 0x1F; /* Clear all events */
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
if (rc) {
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status);
dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word);
if (pciehp_poll_mode) {/* Install interrupt polling code */
/* Install and start the interrupt polling timer */
......@@ -1359,15 +1400,16 @@ int pcie_init(struct controller * ctrl,
start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */
} else {
/* Installs the interrupt handler */
#ifdef CONFIG_PCI_USE_VECTOR
rc = pci_enable_msi(pdev);
if (rc) {
err("Can't get msi for the hotplug controller\n");
dbg("%s: rc = %x\n", __FUNCTION__, rc);
goto abort_free_ctlr;
dbg("%s: pciehp_msi_quirk = %x\n", __FUNCTION__, pciehp_msi_quirk);
if (!pciehp_msi_quirk) {
rc = pci_enable_msi(pdev);
if (rc) {
info("Can't get msi for the hotplug controller\n");
info("Use INTx for the hotplug controller\n");
dbg("%s: rc = %x\n", __FUNCTION__, rc);
} else
php_ctlr->irq = pdev->irq;
}
php_ctlr->irq = pdev->irq;
#endif
rc = request_irq(php_ctlr->irq, pcie_isr, SA_SHIRQ, MY_NAME, (void *) ctrl);
dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
if (rc) {
......@@ -1384,7 +1426,7 @@ int pcie_init(struct controller * ctrl,
dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word);
intr_enable = ATTN_BUTTN_ENABLE | PWR_FAULT_DETECT_ENABLE | MRL_DETECT_ENABLE |
PRSN_DETECT_ENABLE | CMD_CMPL_INTR_ENABLE;
PRSN_DETECT_ENABLE;
temp_word = (temp_word & ~intr_enable) | intr_enable;
......@@ -1402,6 +1444,21 @@ int pcie_init(struct controller * ctrl,
goto abort_free_ctlr;
}
dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word);
rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status);
if (rc) {
err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__,
SLOT_STATUS, slot_status);
temp_word = 0x1F; /* Clear all events */
rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word);
if (rc) {
err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
goto abort_free_ctlr;
}
dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word);
/* Add this HPC instance into the HPC list */
spin_lock(&list_lock);
......
......@@ -192,7 +192,6 @@ int pciehp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slot
for (device = FirstSupported; device <= LastSupported; device++) {
ID = 0xFFFFFFFF;
rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
dbg("%s: ID = %x\n", __FUNCTION__, ID);
if (ID != 0xFFFFFFFF) { /* device in slot */
dbg("%s: ID = %x\n", __FUNCTION__, ID);
......@@ -325,7 +324,6 @@ int pciehp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slot
new_slot->presence_save = 0;
new_slot->switch_save = 0;
}
dbg("%s: End of For loop\n", __FUNCTION__);
} /* End of FOR loop */
dbg("%s: Exit\n", __FUNCTION__);
......
......@@ -1441,6 +1441,7 @@ int shpc_init(struct controller * ctrl,
err("%s : shpc_cap_offset == 0\n", __FUNCTION__);
goto abort_free_ctlr;
}
dbg("%s: shpc_cap_offset = %x\n", __FUNCTION__, shpc_cap_offset);
rc = pci_write_config_byte(pdev, (u8)shpc_cap_offset + DWORD_SELECT , BASE_OFFSET);
if (rc) {
......@@ -1547,15 +1548,13 @@ int shpc_init(struct controller * ctrl,
start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */
} else {
/* Installs the interrupt handler */
#ifdef CONFIG_PCI_USE_VECTOR
rc = pci_enable_msi(pdev);
if (rc) {
err("Can't get msi for the hotplug controller\n");
info("Can't get msi for the hotplug controller\n");
info("Use INTx for the hotplug controller\n");
dbg("%s: rc = %x\n", __FUNCTION__, rc);
goto abort_free_ctlr;
}
php_ctlr->irq = pdev->irq;
#endif
} else
php_ctlr->irq = pdev->irq;
rc = request_irq(php_ctlr->irq, shpc_isr, SA_SHIRQ, MY_NAME, (void *) ctrl);
dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
......
......@@ -1267,7 +1267,8 @@ static int print_acpi_resources (struct acpi_bridge *ab)
int shpchprm_print_pirt(void)
{
dbg("SHPCHPRM ACPI Slots\n");
print_acpi_resources (acpi_bridges_head);
if (acpi_bridges_head)
print_acpi_resources (acpi_bridges_head);
return 0;
}
......
......@@ -96,23 +96,6 @@ static void *detect_HRT_floating_pointer(void *begin, void *end)
return fp;
}
#if link_available
/*
* Links available memory, IO, and IRQ resources for programming
* devices which may be added to the system
*
* Returns 0 if success
*/
static int
link_available_resources (
struct controller *ctrl,
struct pci_func *func,
int index )
{
return shpchp_save_used_resources (ctrl, func, !DISABLE_CARD);
}
#endif
/*
* shpchprm_find_available_resources
*
......@@ -345,19 +328,6 @@ int shpchprm_find_available_resources(struct controller *ctrl)
}
}
#if link_available
++index;
while (index < 8) {
if (((func = shpchp_slot_find(primary_bus, dev_func >> 3, index)) != NULL) && populated_slot)
rc = link_available_resources(ctrl, func, index);
if (rc)
break;
++index;
}
#endif
i--;
one_slot += sizeof(struct slot_rt);
}
......
......@@ -60,3 +60,5 @@ extern int pci_visit_dev(struct pci_visit *fn,
/* Lock for read/write access to pci device and bus lists */
extern spinlock_t pci_bus_lock;
extern int pciehp_msi_quirk;
......@@ -868,6 +868,13 @@ static void __init quirk_intel_ide_combined(struct pci_dev *pdev)
}
#endif /* CONFIG_SCSI_SATA */
int pciehp_msi_quirk;
static void __devinit quirk_pciehp_msi(struct pci_dev *pdev)
{
pciehp_msi_quirk = 1;
}
/*
* The main table of quirks.
*
......@@ -984,6 +991,8 @@ static struct pci_fixup pci_fixups[] __devinitdata = {
quirk_intel_ide_combined },
#endif /* CONFIG_SCSI_SATA */
{ PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SMCH, quirk_pciehp_msi },
{ 0 }
};
......@@ -1008,3 +1017,5 @@ void pci_fixup_device(int pass, struct pci_dev *dev)
pci_do_fixups(dev, pass, pcibios_fixups);
pci_do_fixups(dev, pass, pci_fixups);
}
EXPORT_SYMBOL(pciehp_msi_quirk);
......@@ -2073,6 +2073,7 @@
#define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577
#define PCI_DEVICE_ID_INTEL_82855GM_HB 0x3580
#define PCI_DEVICE_ID_INTEL_82855GM_IG 0x3582
#define PCI_DEVICE_ID_INTEL_SMCH 0x3590
#define PCI_DEVICE_ID_INTEL_80310 0x530d
#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment