diff options
| -rw-r--r-- | drivers/pci/hotplug/pciehp.h | 2 | ||||
| -rw-r--r-- | drivers/pci/hotplug/pciehp_core.c | 7 | ||||
| -rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 15 |
3 files changed, 16 insertions, 8 deletions
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index db85284ffb62..39ae37589fda 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
| @@ -111,6 +111,7 @@ struct controller { | |||
| 111 | int cmd_busy; | 111 | int cmd_busy; |
| 112 | unsigned int no_cmd_complete:1; | 112 | unsigned int no_cmd_complete:1; |
| 113 | unsigned int link_active_reporting:1; | 113 | unsigned int link_active_reporting:1; |
| 114 | unsigned int notification_enabled:1; | ||
| 114 | }; | 115 | }; |
| 115 | 116 | ||
| 116 | #define INT_BUTTON_IGNORE 0 | 117 | #define INT_BUTTON_IGNORE 0 |
| @@ -170,6 +171,7 @@ extern int pciehp_configure_device(struct slot *p_slot); | |||
| 170 | extern int pciehp_unconfigure_device(struct slot *p_slot); | 171 | extern int pciehp_unconfigure_device(struct slot *p_slot); |
| 171 | extern void pciehp_queue_pushbutton_work(struct work_struct *work); | 172 | extern void pciehp_queue_pushbutton_work(struct work_struct *work); |
| 172 | struct controller *pcie_init(struct pcie_device *dev); | 173 | struct controller *pcie_init(struct pcie_device *dev); |
| 174 | int pcie_init_notification(struct controller *ctrl); | ||
| 173 | int pciehp_enable_slot(struct slot *p_slot); | 175 | int pciehp_enable_slot(struct slot *p_slot); |
| 174 | int pciehp_disable_slot(struct slot *p_slot); | 176 | int pciehp_disable_slot(struct slot *p_slot); |
| 175 | int pcie_enable_notification(struct controller *ctrl); | 177 | int pcie_enable_notification(struct controller *ctrl); |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index c2485542f543..681e3912b821 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
| @@ -434,6 +434,13 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
| 434 | goto err_out_release_ctlr; | 434 | goto err_out_release_ctlr; |
| 435 | } | 435 | } |
| 436 | 436 | ||
| 437 | /* Enable events after we have setup the data structures */ | ||
| 438 | rc = pcie_init_notification(ctrl); | ||
| 439 | if (rc) { | ||
| 440 | ctrl_err(ctrl, "Notification initialization failed\n"); | ||
| 441 | goto err_out_release_ctlr; | ||
| 442 | } | ||
| 443 | |||
| 437 | /* Check if slot is occupied */ | 444 | /* Check if slot is occupied */ |
| 438 | t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); | 445 | t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); |
| 439 | t_slot->hpc_ops->get_adapter_status(t_slot, &value); | 446 | t_slot->hpc_ops->get_adapter_status(t_slot, &value); |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 71a8012886b0..7a16c6897bb9 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
| @@ -934,7 +934,7 @@ static void pcie_disable_notification(struct controller *ctrl) | |||
| 934 | ctrl_warn(ctrl, "Cannot disable software notification\n"); | 934 | ctrl_warn(ctrl, "Cannot disable software notification\n"); |
| 935 | } | 935 | } |
| 936 | 936 | ||
| 937 | static int pcie_init_notification(struct controller *ctrl) | 937 | int pcie_init_notification(struct controller *ctrl) |
| 938 | { | 938 | { |
| 939 | if (pciehp_request_irq(ctrl)) | 939 | if (pciehp_request_irq(ctrl)) |
| 940 | return -1; | 940 | return -1; |
| @@ -942,13 +942,17 @@ static int pcie_init_notification(struct controller *ctrl) | |||
| 942 | pciehp_free_irq(ctrl); | 942 | pciehp_free_irq(ctrl); |
| 943 | return -1; | 943 | return -1; |
| 944 | } | 944 | } |
| 945 | ctrl->notification_enabled = 1; | ||
| 945 | return 0; | 946 | return 0; |
| 946 | } | 947 | } |
| 947 | 948 | ||
| 948 | static void pcie_shutdown_notification(struct controller *ctrl) | 949 | static void pcie_shutdown_notification(struct controller *ctrl) |
| 949 | { | 950 | { |
| 950 | pcie_disable_notification(ctrl); | 951 | if (ctrl->notification_enabled) { |
| 951 | pciehp_free_irq(ctrl); | 952 | pcie_disable_notification(ctrl); |
| 953 | pciehp_free_irq(ctrl); | ||
| 954 | ctrl->notification_enabled = 0; | ||
| 955 | } | ||
| 952 | } | 956 | } |
| 953 | 957 | ||
| 954 | static int pcie_init_slot(struct controller *ctrl) | 958 | static int pcie_init_slot(struct controller *ctrl) |
| @@ -1110,13 +1114,8 @@ struct controller *pcie_init(struct pcie_device *dev) | |||
| 1110 | if (pcie_init_slot(ctrl)) | 1114 | if (pcie_init_slot(ctrl)) |
| 1111 | goto abort_ctrl; | 1115 | goto abort_ctrl; |
| 1112 | 1116 | ||
| 1113 | if (pcie_init_notification(ctrl)) | ||
| 1114 | goto abort_slot; | ||
| 1115 | |||
| 1116 | return ctrl; | 1117 | return ctrl; |
| 1117 | 1118 | ||
| 1118 | abort_slot: | ||
| 1119 | pcie_cleanup_slot(ctrl); | ||
| 1120 | abort_ctrl: | 1119 | abort_ctrl: |
| 1121 | kfree(ctrl); | 1120 | kfree(ctrl); |
| 1122 | abort: | 1121 | abort: |
