From 5055057f4c8a73c9aa1fa2d84be230d8078c8e7a Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 28 Jan 2009 19:31:18 -0800 Subject: [PATCH] --- yaml --- r: 131810 b: refs/heads/master c: dbc7e1e567ef8cfc4b792ef6acb51d4ceb15746a h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/pci/hotplug/pciehp.h | 2 ++ trunk/drivers/pci/hotplug/pciehp_core.c | 7 +++++++ trunk/drivers/pci/hotplug/pciehp_hpc.c | 15 +++++++-------- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/[refs] b/[refs] index cf52c4363af2..25b468e9a008 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1dec6b054dd1fc780e18b815068bf5677409eb2d +refs/heads/master: dbc7e1e567ef8cfc4b792ef6acb51d4ceb15746a diff --git a/trunk/drivers/pci/hotplug/pciehp.h b/trunk/drivers/pci/hotplug/pciehp.h index db85284ffb62..39ae37589fda 100644 --- a/trunk/drivers/pci/hotplug/pciehp.h +++ b/trunk/drivers/pci/hotplug/pciehp.h @@ -111,6 +111,7 @@ struct controller { int cmd_busy; unsigned int no_cmd_complete:1; unsigned int link_active_reporting:1; + unsigned int notification_enabled:1; }; #define INT_BUTTON_IGNORE 0 @@ -170,6 +171,7 @@ extern int pciehp_configure_device(struct slot *p_slot); extern int pciehp_unconfigure_device(struct slot *p_slot); extern void pciehp_queue_pushbutton_work(struct work_struct *work); struct controller *pcie_init(struct pcie_device *dev); +int pcie_init_notification(struct controller *ctrl); int pciehp_enable_slot(struct slot *p_slot); int pciehp_disable_slot(struct slot *p_slot); int pcie_enable_notification(struct controller *ctrl); diff --git a/trunk/drivers/pci/hotplug/pciehp_core.c b/trunk/drivers/pci/hotplug/pciehp_core.c index c2485542f543..681e3912b821 100644 --- a/trunk/drivers/pci/hotplug/pciehp_core.c +++ b/trunk/drivers/pci/hotplug/pciehp_core.c @@ -434,6 +434,13 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ goto err_out_release_ctlr; } + /* Enable events after we have setup the data structures */ + rc = pcie_init_notification(ctrl); + if (rc) { + ctrl_err(ctrl, "Notification initialization failed\n"); + 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); diff --git a/trunk/drivers/pci/hotplug/pciehp_hpc.c b/trunk/drivers/pci/hotplug/pciehp_hpc.c index 71a8012886b0..7a16c6897bb9 100644 --- a/trunk/drivers/pci/hotplug/pciehp_hpc.c +++ b/trunk/drivers/pci/hotplug/pciehp_hpc.c @@ -934,7 +934,7 @@ static void pcie_disable_notification(struct controller *ctrl) ctrl_warn(ctrl, "Cannot disable software notification\n"); } -static int pcie_init_notification(struct controller *ctrl) +int pcie_init_notification(struct controller *ctrl) { if (pciehp_request_irq(ctrl)) return -1; @@ -942,13 +942,17 @@ static int pcie_init_notification(struct controller *ctrl) pciehp_free_irq(ctrl); return -1; } + ctrl->notification_enabled = 1; return 0; } static void pcie_shutdown_notification(struct controller *ctrl) { - pcie_disable_notification(ctrl); - pciehp_free_irq(ctrl); + if (ctrl->notification_enabled) { + pcie_disable_notification(ctrl); + pciehp_free_irq(ctrl); + ctrl->notification_enabled = 0; + } } static int pcie_init_slot(struct controller *ctrl) @@ -1110,13 +1114,8 @@ struct controller *pcie_init(struct pcie_device *dev) if (pcie_init_slot(ctrl)) goto abort_ctrl; - if (pcie_init_notification(ctrl)) - goto abort_slot; - return ctrl; -abort_slot: - pcie_cleanup_slot(ctrl); abort_ctrl: kfree(ctrl); abort: