Commit dbc7e1e5 authored by Eric W. Biederman's avatar Eric W. Biederman Committed by Jesse Barnes

PCI: pciehp: Handle interrupts that happen during initialization.

Move the enabling of interrupts after all of the data structures
are setup so that we can safely run the interrupt handler as
soon as it is registered.
Reviewed-by: default avatarKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Tested-by: default avatarKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: default avatarEric W. Biederman <ebiederm@aristanetworks.com>
Signed-off-by: default avatarJesse Barnes <jbarnes@hobbes.lan>
parent 1dec6b05
...@@ -111,6 +111,7 @@ struct controller { ...@@ -111,6 +111,7 @@ struct controller {
int cmd_busy; int cmd_busy;
unsigned int no_cmd_complete:1; unsigned int no_cmd_complete:1;
unsigned int link_active_reporting:1; unsigned int link_active_reporting:1;
unsigned int notification_enabled:1;
}; };
#define INT_BUTTON_IGNORE 0 #define INT_BUTTON_IGNORE 0
...@@ -170,6 +171,7 @@ extern int pciehp_configure_device(struct slot *p_slot); ...@@ -170,6 +171,7 @@ extern int pciehp_configure_device(struct slot *p_slot);
extern int pciehp_unconfigure_device(struct slot *p_slot); extern int pciehp_unconfigure_device(struct slot *p_slot);
extern void pciehp_queue_pushbutton_work(struct work_struct *work); extern void pciehp_queue_pushbutton_work(struct work_struct *work);
struct controller *pcie_init(struct pcie_device *dev); 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_enable_slot(struct slot *p_slot);
int pciehp_disable_slot(struct slot *p_slot); int pciehp_disable_slot(struct slot *p_slot);
int pcie_enable_notification(struct controller *ctrl); int pcie_enable_notification(struct controller *ctrl);
......
...@@ -434,6 +434,13 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ ...@@ -434,6 +434,13 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
goto err_out_release_ctlr; 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 */ /* Check if slot is occupied */
t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset);
t_slot->hpc_ops->get_adapter_status(t_slot, &value); t_slot->hpc_ops->get_adapter_status(t_slot, &value);
......
...@@ -934,7 +934,7 @@ static void pcie_disable_notification(struct controller *ctrl) ...@@ -934,7 +934,7 @@ static void pcie_disable_notification(struct controller *ctrl)
ctrl_warn(ctrl, "Cannot disable software notification\n"); 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)) if (pciehp_request_irq(ctrl))
return -1; return -1;
...@@ -942,13 +942,17 @@ static int pcie_init_notification(struct controller *ctrl) ...@@ -942,13 +942,17 @@ static int pcie_init_notification(struct controller *ctrl)
pciehp_free_irq(ctrl); pciehp_free_irq(ctrl);
return -1; return -1;
} }
ctrl->notification_enabled = 1;
return 0; return 0;
} }
static void pcie_shutdown_notification(struct controller *ctrl) static void pcie_shutdown_notification(struct controller *ctrl)
{ {
pcie_disable_notification(ctrl); if (ctrl->notification_enabled) {
pciehp_free_irq(ctrl); pcie_disable_notification(ctrl);
pciehp_free_irq(ctrl);
ctrl->notification_enabled = 0;
}
} }
static int pcie_init_slot(struct controller *ctrl) static int pcie_init_slot(struct controller *ctrl)
...@@ -1110,13 +1114,8 @@ struct controller *pcie_init(struct pcie_device *dev) ...@@ -1110,13 +1114,8 @@ struct controller *pcie_init(struct pcie_device *dev)
if (pcie_init_slot(ctrl)) if (pcie_init_slot(ctrl))
goto abort_ctrl; goto abort_ctrl;
if (pcie_init_notification(ctrl))
goto abort_slot;
return ctrl; return ctrl;
abort_slot:
pcie_cleanup_slot(ctrl);
abort_ctrl: abort_ctrl:
kfree(ctrl); kfree(ctrl);
abort: abort:
......
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