aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/pciehp_hpc.c
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2007-03-06 18:02:26 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2007-05-02 22:02:34 -0400
commit5d386e1ac4025b4bcc6bad6811e771cb76064dfe (patch)
treed673b9686ed60aa43c1c0f43abc8bc54d19b6649 /drivers/pci/hotplug/pciehp_hpc.c
parentf7bdd12d234d9064bd0aa1b5610508959120a9b4 (diff)
pciehp: Event handling rework
The event handler of PCIEHP driver is unnecessarily very complex. In addition, current event handler can only a fixed number of events at the same time, and some of events would be lost if several number of events happened at the same time. This patch simplify the event handler using 'work queue', and it also fix the above-mentioned issue. Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci/hotplug/pciehp_hpc.c')
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index fbc64aa2dd68..9aac6a87eb53 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -71,6 +71,8 @@
71#define DBG_LEAVE_ROUTINE 71#define DBG_LEAVE_ROUTINE
72#endif /* DEBUG */ 72#endif /* DEBUG */
73 73
74static atomic_t pciehp_num_controllers = ATOMIC_INIT(0);
75
74struct ctrl_reg { 76struct ctrl_reg {
75 u8 cap_id; 77 u8 cap_id;
76 u8 nxt_ptr; 78 u8 nxt_ptr;
@@ -219,10 +221,7 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value)
219#define EMI_STATE 0x0080 221#define EMI_STATE 0x0080
220#define EMI_STATUS_BIT 7 222#define EMI_STATUS_BIT 7
221 223
222static spinlock_t hpc_event_lock;
223
224DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ 224DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */
225static int ctlr_seq_num = 0; /* Controller sequence # */
226 225
227static irqreturn_t pcie_isr(int irq, void *dev_id); 226static irqreturn_t pcie_isr(int irq, void *dev_id);
228static void start_int_poll_timer(struct controller *ctrl, int sec); 227static void start_int_poll_timer(struct controller *ctrl, int sec);
@@ -656,6 +655,13 @@ static void hpc_release_ctlr(struct controller *ctrl)
656 else 655 else
657 free_irq(ctrl->pci_dev->irq, ctrl); 656 free_irq(ctrl->pci_dev->irq, ctrl);
658 657
658 /*
659 * If this is the last controller to be released, destroy the
660 * pciehp work queue
661 */
662 if (atomic_dec_and_test(&pciehp_num_controllers))
663 destroy_workqueue(pciehp_wq);
664
659 DBG_LEAVE_ROUTINE 665 DBG_LEAVE_ROUTINE
660} 666}
661 667
@@ -1152,7 +1158,6 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev)
1152int pcie_init(struct controller * ctrl, struct pcie_device *dev) 1158int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1153{ 1159{
1154 int rc; 1160 int rc;
1155 static int first = 1;
1156 u16 temp_word; 1161 u16 temp_word;
1157 u16 cap_reg; 1162 u16 cap_reg;
1158 u16 intr_enable = 0; 1163 u16 intr_enable = 0;
@@ -1221,11 +1226,6 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1221 dbg("%s: SLOTCTRL offset %x slot_ctrl %x\n", 1226 dbg("%s: SLOTCTRL offset %x slot_ctrl %x\n",
1222 __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl); 1227 __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
1223 1228
1224 if (first) {
1225 spin_lock_init(&hpc_event_lock);
1226 first = 0;
1227 }
1228
1229 for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++) 1229 for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
1230 if (pci_resource_len(pdev, rc) > 0) 1230 if (pci_resource_len(pdev, rc) > 0)
1231 dbg("pci resource[%d] start=0x%llx(len=0x%llx)\n", rc, 1231 dbg("pci resource[%d] start=0x%llx(len=0x%llx)\n", rc,
@@ -1286,7 +1286,8 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1286 rc = request_irq(ctrl->pci_dev->irq, pcie_isr, IRQF_SHARED, 1286 rc = request_irq(ctrl->pci_dev->irq, pcie_isr, IRQF_SHARED,
1287 MY_NAME, (void *)ctrl); 1287 MY_NAME, (void *)ctrl);
1288 dbg("%s: request_irq %d for hpc%d (returns %d)\n", 1288 dbg("%s: request_irq %d for hpc%d (returns %d)\n",
1289 __FUNCTION__, ctrl->pci_dev->irq, ctlr_seq_num, rc); 1289 __FUNCTION__, ctrl->pci_dev->irq,
1290 atomic_read(&pciehp_num_controllers), rc);
1290 if (rc) { 1291 if (rc) {
1291 err("Can't get irq %d for the hotplug controller\n", 1292 err("Can't get irq %d for the hotplug controller\n",
1292 ctrl->pci_dev->irq); 1293 ctrl->pci_dev->irq);
@@ -1296,6 +1297,18 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1296 dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number, 1297 dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number,
1297 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq); 1298 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
1298 1299
1300 /*
1301 * If this is the first controller to be initialized,
1302 * initialize the pciehp work queue
1303 */
1304 if (atomic_add_return(1, &pciehp_num_controllers) == 1) {
1305 pciehp_wq = create_singlethread_workqueue("pciehpd");
1306 if (!pciehp_wq) {
1307 rc = -ENOMEM;
1308 goto abort_free_irq;
1309 }
1310 }
1311
1299 rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); 1312 rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);
1300 if (rc) { 1313 if (rc) {
1301 err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); 1314 err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__);
@@ -1349,7 +1362,6 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1349 goto abort_disable_intr; 1362 goto abort_disable_intr;
1350 } 1363 }
1351 1364
1352 ctlr_seq_num++;
1353 ctrl->hpc_ops = &pciehp_hpc_ops; 1365 ctrl->hpc_ops = &pciehp_hpc_ops;
1354 1366
1355 DBG_LEAVE_ROUTINE 1367 DBG_LEAVE_ROUTINE