aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-01 18:14:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-01 18:14:04 -0400
commit4b1779c2cf030c68aefe939d946475e4136c1895 (patch)
tree27e4bda2f6c8d269d02dec52a62dd1443880c6dc /drivers/pci/hotplug
parent62ff577fa2fec87edbf26f53e87210ba726d4d44 (diff)
parent30723cbf6f7aec2ab4810bdc4bf12c5749a09e33 (diff)
Merge tag 'pci-v3.15-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas: "Enumeration - Increment max correctly in pci_scan_bridge() (Andreas Noever) - Clarify the "scan anyway" comment in pci_scan_bridge() (Andreas Noever) - Assign CardBus bus number only during the second pass (Andreas Noever) - Use request_resource_conflict() instead of insert_ for bus numbers (Andreas Noever) - Make sure bus number resources stay within their parents bounds (Andreas Noever) - Remove pci_fixup_parent_subordinate_busnr() (Andreas Noever) - Check for child busses which use more bus numbers than allocated (Andreas Noever) - Don't scan random busses in pci_scan_bridge() (Andreas Noever) - x86: Drop pcibios_scan_root() check for bus already scanned (Bjorn Helgaas) - x86: Use pcibios_scan_root() instead of pci_scan_bus_with_sysdata() (Bjorn Helgaas) - x86: Use pcibios_scan_root() instead of pci_scan_bus_on_node() (Bjorn Helgaas) - x86: Merge pci_scan_bus_on_node() into pcibios_scan_root() (Bjorn Helgaas) - x86: Drop return value of pcibios_scan_root() (Bjorn Helgaas) NUMA - x86: Add x86_pci_root_bus_node() to look up NUMA node from PCI bus (Bjorn Helgaas) - x86: Use x86_pci_root_bus_node() instead of get_mp_bus_to_node() (Bjorn Helgaas) - x86: Remove mp_bus_to_node[], set_mp_bus_to_node(), get_mp_bus_to_node() (Bjorn Helgaas) - x86: Use NUMA_NO_NODE, not -1, for unknown node (Bjorn Helgaas) - x86: Remove acpi_get_pxm() usage (Bjorn Helgaas) - ia64: Use NUMA_NO_NODE, not MAX_NUMNODES, for unknown node (Bjorn Helgaas) - ia64: Remove acpi_get_pxm() usage (Bjorn Helgaas) - ACPI: Fix acpi_get_node() prototype (Bjorn Helgaas) Resource management - i2o: Fix and refactor PCI space allocation (Bjorn Helgaas) - Add resource_contains() (Bjorn Helgaas) - Add %pR support for IORESOURCE_UNSET (Bjorn Helgaas) - Mark resources as IORESOURCE_UNSET if we can't assign them (Bjorn Helgaas) - Don't clear IORESOURCE_UNSET when updating BAR (Bjorn Helgaas) - Check IORESOURCE_UNSET before updating BAR (Bjorn Helgaas) - Don't try to claim IORESOURCE_UNSET resources (Bjorn Helgaas) - Mark 64-bit resource as IORESOURCE_UNSET if we only support 32-bit (Bjorn Helgaas) - Don't enable decoding if BAR hasn't been assigned an address (Bjorn Helgaas) - Add "weak" generic pcibios_enable_device() implementation (Bjorn Helgaas) - alpha, microblaze, sh, sparc, tile: Use default pcibios_enable_device() (Bjorn Helgaas) - s390: Use generic pci_enable_resources() (Bjorn Helgaas) - Don't check resource_size() in pci_bus_alloc_resource() (Bjorn Helgaas) - Set type in __request_region() (Bjorn Helgaas) - Check all IORESOURCE_TYPE_BITS in pci_bus_alloc_from_region() (Bjorn Helgaas) - Change pci_bus_alloc_resource() type_mask to unsigned long (Bjorn Helgaas) - Log IDE resource quirk in dmesg (Bjorn Helgaas) - Revert "[PATCH] Insert GART region into resource map" (Bjorn Helgaas) PCI device hotplug - Make check_link_active() non-static (Rajat Jain) - Use link change notifications for hot-plug and removal (Rajat Jain) - Enable link state change notifications (Rajat Jain) - Don't disable the link permanently during removal (Rajat Jain) - Don't check adapter or latch status while disabling (Rajat Jain) - Disable link notification across slot reset (Rajat Jain) - Ensure very fast hotplug events are also processed (Rajat Jain) - Add hotplug_lock to serialize hotplug events (Rajat Jain) - Remove a non-existent card, regardless of "surprise" capability (Rajat Jain) - Don't turn slot off when hot-added device already exists (Yijing Wang) MSI - Keep pci_enable_msi() documentation (Alexander Gordeev) - ahci: Fix broken single MSI fallback (Alexander Gordeev) - ahci, vfio: Use pci_enable_msi_range() (Alexander Gordeev) - Check kmalloc() return value, fix leak of name (Greg Kroah-Hartman) - Fix leak of msi_attrs (Greg Kroah-Hartman) - Fix pci_msix_vec_count() htmldocs failure (Masanari Iida) Virtualization - Device-specific ACS support (Alex Williamson) Freescale i.MX6 - Wait for retraining (Marek Vasut) Marvell MVEBU - Use Device ID and revision from underlying endpoint (Andrew Lunn) - Fix incorrect size for PCI aperture resources (Jason Gunthorpe) - Call request_resource() on the apertures (Jason Gunthorpe) - Fix potential issue in range parsing (Jean-Jacques Hiblot) Renesas R-Car - Check platform_get_irq() return code (Ben Dooks) - Add error interrupt handling (Ben Dooks) - Fix bridge logic configuration accesses (Ben Dooks) - Register each instance independently (Magnus Damm) - Break out window size handling (Magnus Damm) - Make the Kconfig dependencies more generic (Magnus Damm) Synopsys DesignWare - Fix RC BAR to be single 64-bit non-prefetchable memory (Mohit Kumar) Miscellaneous - Remove unused SR-IOV VF Migration support (Bjorn Helgaas) - Enable INTx if BIOS left them disabled (Bjorn Helgaas) - Fix hex vs decimal typo in cpqhpc_probe() (Dan Carpenter) - Clean up par-arch object file list (Liviu Dudau) - Set IORESOURCE_ROM_SHADOW only for the default VGA device (Sander Eikelenboom) - ACPI, ARM, drm, powerpc, pcmcia, PCI: Use list_for_each_entry() for bus traversal (Yijing Wang) - Fix pci_bus_b() build failure (Paul Gortmaker)" * tag 'pci-v3.15-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (108 commits) Revert "[PATCH] Insert GART region into resource map" PCI: Log IDE resource quirk in dmesg PCI: Change pci_bus_alloc_resource() type_mask to unsigned long PCI: Check all IORESOURCE_TYPE_BITS in pci_bus_alloc_from_region() resources: Set type in __request_region() PCI: Don't check resource_size() in pci_bus_alloc_resource() s390/PCI: Use generic pci_enable_resources() tile PCI RC: Use default pcibios_enable_device() sparc/PCI: Use default pcibios_enable_device() (Leon only) sh/PCI: Use default pcibios_enable_device() microblaze/PCI: Use default pcibios_enable_device() alpha/PCI: Use default pcibios_enable_device() PCI: Add "weak" generic pcibios_enable_device() implementation PCI: Don't enable decoding if BAR hasn't been assigned an address PCI: Enable INTx in pci_reenable_device() only when MSI/MSI-X not enabled PCI: Mark 64-bit resource as IORESOURCE_UNSET if we only support 32-bit PCI: Don't try to claim IORESOURCE_UNSET resources PCI: Check IORESOURCE_UNSET before updating BAR PCI: Don't clear IORESOURCE_UNSET when updating BAR PCI: Mark resources as IORESOURCE_UNSET if we can't assign them ... Conflicts: arch/x86/include/asm/topology.h drivers/ata/ahci.c
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c6
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c4
-rw-r--r--drivers/pci/hotplug/pciehp.h5
-rw-r--r--drivers/pci/hotplug/pciehp_acpi.c1
-rw-r--r--drivers/pci/hotplug/pciehp_core.c8
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c173
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c75
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c2
8 files changed, 194 insertions, 80 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 828acf422c17..bccc27ee1030 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -424,7 +424,7 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
424 */ 424 */
425static unsigned char acpiphp_max_busnr(struct pci_bus *bus) 425static unsigned char acpiphp_max_busnr(struct pci_bus *bus)
426{ 426{
427 struct list_head *tmp; 427 struct pci_bus *tmp;
428 unsigned char max, n; 428 unsigned char max, n;
429 429
430 /* 430 /*
@@ -437,8 +437,8 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus)
437 */ 437 */
438 max = bus->busn_res.start; 438 max = bus->busn_res.start;
439 439
440 list_for_each(tmp, &bus->children) { 440 list_for_each_entry(tmp, &bus->children, node) {
441 n = pci_bus_max_busnr(pci_bus_b(tmp)); 441 n = pci_bus_max_busnr(tmp);
442 if (n > max) 442 if (n > max)
443 max = n; 443 max = n;
444 } 444 }
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index 31273e155e6c..037e2612c5bd 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -920,12 +920,12 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
920 bus->max_bus_speed = PCI_SPEED_100MHz_PCIX; 920 bus->max_bus_speed = PCI_SPEED_100MHz_PCIX;
921 break; 921 break;
922 } 922 }
923 if (bus_cap & 20) { 923 if (bus_cap & 0x20) {
924 dbg("bus max supports 66MHz PCI-X\n"); 924 dbg("bus max supports 66MHz PCI-X\n");
925 bus->max_bus_speed = PCI_SPEED_66MHz_PCIX; 925 bus->max_bus_speed = PCI_SPEED_66MHz_PCIX;
926 break; 926 break;
927 } 927 }
928 if (bus_cap & 10) { 928 if (bus_cap & 0x10) {
929 dbg("bus max supports 66MHz PCI\n"); 929 dbg("bus max supports 66MHz PCI\n");
930 bus->max_bus_speed = PCI_SPEED_66MHz; 930 bus->max_bus_speed = PCI_SPEED_66MHz;
931 break; 931 break;
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 88b37cad4b35..8a66866b8cf1 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -76,6 +76,7 @@ struct slot {
76 struct hotplug_slot *hotplug_slot; 76 struct hotplug_slot *hotplug_slot;
77 struct delayed_work work; /* work for button event */ 77 struct delayed_work work; /* work for button event */
78 struct mutex lock; 78 struct mutex lock;
79 struct mutex hotplug_lock;
79 struct workqueue_struct *wq; 80 struct workqueue_struct *wq;
80}; 81};
81 82
@@ -109,6 +110,8 @@ struct controller {
109#define INT_BUTTON_PRESS 7 110#define INT_BUTTON_PRESS 7
110#define INT_BUTTON_RELEASE 8 111#define INT_BUTTON_RELEASE 8
111#define INT_BUTTON_CANCEL 9 112#define INT_BUTTON_CANCEL 9
113#define INT_LINK_UP 10
114#define INT_LINK_DOWN 11
112 115
113#define STATIC_STATE 0 116#define STATIC_STATE 0
114#define BLINKINGON_STATE 1 117#define BLINKINGON_STATE 1
@@ -132,6 +135,7 @@ u8 pciehp_handle_attention_button(struct slot *p_slot);
132u8 pciehp_handle_switch_change(struct slot *p_slot); 135u8 pciehp_handle_switch_change(struct slot *p_slot);
133u8 pciehp_handle_presence_change(struct slot *p_slot); 136u8 pciehp_handle_presence_change(struct slot *p_slot);
134u8 pciehp_handle_power_fault(struct slot *p_slot); 137u8 pciehp_handle_power_fault(struct slot *p_slot);
138void pciehp_handle_linkstate_change(struct slot *p_slot);
135int pciehp_configure_device(struct slot *p_slot); 139int pciehp_configure_device(struct slot *p_slot);
136int pciehp_unconfigure_device(struct slot *p_slot); 140int pciehp_unconfigure_device(struct slot *p_slot);
137void pciehp_queue_pushbutton_work(struct work_struct *work); 141void pciehp_queue_pushbutton_work(struct work_struct *work);
@@ -153,6 +157,7 @@ void pciehp_green_led_on(struct slot *slot);
153void pciehp_green_led_off(struct slot *slot); 157void pciehp_green_led_off(struct slot *slot);
154void pciehp_green_led_blink(struct slot *slot); 158void pciehp_green_led_blink(struct slot *slot);
155int pciehp_check_link_status(struct controller *ctrl); 159int pciehp_check_link_status(struct controller *ctrl);
160bool pciehp_check_link_active(struct controller *ctrl);
156void pciehp_release_ctrl(struct controller *ctrl); 161void pciehp_release_ctrl(struct controller *ctrl);
157int pciehp_reset_slot(struct slot *slot, int probe); 162int pciehp_reset_slot(struct slot *slot, int probe);
158 163
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c
index eddddd447d0d..20fea57d2149 100644
--- a/drivers/pci/hotplug/pciehp_acpi.c
+++ b/drivers/pci/hotplug/pciehp_acpi.c
@@ -112,6 +112,7 @@ static struct pcie_port_service_driver __initdata dummy_driver = {
112static int __init select_detection_mode(void) 112static int __init select_detection_mode(void)
113{ 113{
114 struct dummy_slot *slot, *tmp; 114 struct dummy_slot *slot, *tmp;
115
115 if (pcie_port_service_register(&dummy_driver)) 116 if (pcie_port_service_register(&dummy_driver))
116 return PCIEHP_DETECT_ACPI; 117 return PCIEHP_DETECT_ACPI;
117 pcie_port_service_unregister(&dummy_driver); 118 pcie_port_service_unregister(&dummy_driver);
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 53b58debc288..0e0a2fff20a3 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -108,6 +108,7 @@ static int init_slot(struct controller *ctrl)
108 ops = kzalloc(sizeof(*ops), GFP_KERNEL); 108 ops = kzalloc(sizeof(*ops), GFP_KERNEL);
109 if (!ops) 109 if (!ops)
110 goto out; 110 goto out;
111
111 ops->enable_slot = enable_slot; 112 ops->enable_slot = enable_slot;
112 ops->disable_slot = disable_slot; 113 ops->disable_slot = disable_slot;
113 ops->get_power_status = get_power_status; 114 ops->get_power_status = get_power_status;
@@ -283,8 +284,11 @@ static int pciehp_probe(struct pcie_device *dev)
283 slot = ctrl->slot; 284 slot = ctrl->slot;
284 pciehp_get_adapter_status(slot, &occupied); 285 pciehp_get_adapter_status(slot, &occupied);
285 pciehp_get_power_status(slot, &poweron); 286 pciehp_get_power_status(slot, &poweron);
286 if (occupied && pciehp_force) 287 if (occupied && pciehp_force) {
288 mutex_lock(&slot->hotplug_lock);
287 pciehp_enable_slot(slot); 289 pciehp_enable_slot(slot);
290 mutex_unlock(&slot->hotplug_lock);
291 }
288 /* If empty slot's power status is on, turn power off */ 292 /* If empty slot's power status is on, turn power off */
289 if (!occupied && poweron && POWER_CTRL(ctrl)) 293 if (!occupied && poweron && POWER_CTRL(ctrl))
290 pciehp_power_off_slot(slot); 294 pciehp_power_off_slot(slot);
@@ -328,10 +332,12 @@ static int pciehp_resume (struct pcie_device *dev)
328 332
329 /* Check if slot is occupied */ 333 /* Check if slot is occupied */
330 pciehp_get_adapter_status(slot, &status); 334 pciehp_get_adapter_status(slot, &status);
335 mutex_lock(&slot->hotplug_lock);
331 if (status) 336 if (status)
332 pciehp_enable_slot(slot); 337 pciehp_enable_slot(slot);
333 else 338 else
334 pciehp_disable_slot(slot); 339 pciehp_disable_slot(slot);
340 mutex_unlock(&slot->hotplug_lock);
335 return 0; 341 return 0;
336} 342}
337#endif /* PM */ 343#endif /* PM */
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 50628487597d..c75e6a678dcc 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -150,6 +150,27 @@ u8 pciehp_handle_power_fault(struct slot *p_slot)
150 return 1; 150 return 1;
151} 151}
152 152
153void pciehp_handle_linkstate_change(struct slot *p_slot)
154{
155 u32 event_type;
156 struct controller *ctrl = p_slot->ctrl;
157
158 /* Link Status Change */
159 ctrl_dbg(ctrl, "Data Link Layer State change\n");
160
161 if (pciehp_check_link_active(ctrl)) {
162 ctrl_info(ctrl, "slot(%s): Link Up event\n",
163 slot_name(p_slot));
164 event_type = INT_LINK_UP;
165 } else {
166 ctrl_info(ctrl, "slot(%s): Link Down event\n",
167 slot_name(p_slot));
168 event_type = INT_LINK_DOWN;
169 }
170
171 queue_interrupt_event(p_slot, event_type);
172}
173
153/* The following routines constitute the bulk of the 174/* The following routines constitute the bulk of the
154 hotplug controller logic 175 hotplug controller logic
155 */ 176 */
@@ -212,7 +233,8 @@ static int board_added(struct slot *p_slot)
212 if (retval) { 233 if (retval) {
213 ctrl_err(ctrl, "Cannot add device at %04x:%02x:00\n", 234 ctrl_err(ctrl, "Cannot add device at %04x:%02x:00\n",
214 pci_domain_nr(parent), parent->number); 235 pci_domain_nr(parent), parent->number);
215 goto err_exit; 236 if (retval != -EEXIST)
237 goto err_exit;
216 } 238 }
217 239
218 pciehp_green_led_on(p_slot); 240 pciehp_green_led_on(p_slot);
@@ -255,6 +277,9 @@ static int remove_board(struct slot *p_slot)
255struct power_work_info { 277struct power_work_info {
256 struct slot *p_slot; 278 struct slot *p_slot;
257 struct work_struct work; 279 struct work_struct work;
280 unsigned int req;
281#define DISABLE_REQ 0
282#define ENABLE_REQ 1
258}; 283};
259 284
260/** 285/**
@@ -269,30 +294,38 @@ static void pciehp_power_thread(struct work_struct *work)
269 struct power_work_info *info = 294 struct power_work_info *info =
270 container_of(work, struct power_work_info, work); 295 container_of(work, struct power_work_info, work);
271 struct slot *p_slot = info->p_slot; 296 struct slot *p_slot = info->p_slot;
297 int ret;
272 298
273 mutex_lock(&p_slot->lock); 299 switch (info->req) {
274 switch (p_slot->state) { 300 case DISABLE_REQ:
275 case POWEROFF_STATE:
276 mutex_unlock(&p_slot->lock);
277 ctrl_dbg(p_slot->ctrl, 301 ctrl_dbg(p_slot->ctrl,
278 "Disabling domain:bus:device=%04x:%02x:00\n", 302 "Disabling domain:bus:device=%04x:%02x:00\n",
279 pci_domain_nr(p_slot->ctrl->pcie->port->subordinate), 303 pci_domain_nr(p_slot->ctrl->pcie->port->subordinate),
280 p_slot->ctrl->pcie->port->subordinate->number); 304 p_slot->ctrl->pcie->port->subordinate->number);
305 mutex_lock(&p_slot->hotplug_lock);
281 pciehp_disable_slot(p_slot); 306 pciehp_disable_slot(p_slot);
307 mutex_unlock(&p_slot->hotplug_lock);
282 mutex_lock(&p_slot->lock); 308 mutex_lock(&p_slot->lock);
283 p_slot->state = STATIC_STATE; 309 p_slot->state = STATIC_STATE;
284 break;
285 case POWERON_STATE:
286 mutex_unlock(&p_slot->lock); 310 mutex_unlock(&p_slot->lock);
287 if (pciehp_enable_slot(p_slot)) 311 break;
312 case ENABLE_REQ:
313 ctrl_dbg(p_slot->ctrl,
314 "Enabling domain:bus:device=%04x:%02x:00\n",
315 pci_domain_nr(p_slot->ctrl->pcie->port->subordinate),
316 p_slot->ctrl->pcie->port->subordinate->number);
317 mutex_lock(&p_slot->hotplug_lock);
318 ret = pciehp_enable_slot(p_slot);
319 mutex_unlock(&p_slot->hotplug_lock);
320 if (ret)
288 pciehp_green_led_off(p_slot); 321 pciehp_green_led_off(p_slot);
289 mutex_lock(&p_slot->lock); 322 mutex_lock(&p_slot->lock);
290 p_slot->state = STATIC_STATE; 323 p_slot->state = STATIC_STATE;
324 mutex_unlock(&p_slot->lock);
291 break; 325 break;
292 default: 326 default:
293 break; 327 break;
294 } 328 }
295 mutex_unlock(&p_slot->lock);
296 329
297 kfree(info); 330 kfree(info);
298} 331}
@@ -315,9 +348,11 @@ void pciehp_queue_pushbutton_work(struct work_struct *work)
315 switch (p_slot->state) { 348 switch (p_slot->state) {
316 case BLINKINGOFF_STATE: 349 case BLINKINGOFF_STATE:
317 p_slot->state = POWEROFF_STATE; 350 p_slot->state = POWEROFF_STATE;
351 info->req = DISABLE_REQ;
318 break; 352 break;
319 case BLINKINGON_STATE: 353 case BLINKINGON_STATE:
320 p_slot->state = POWERON_STATE; 354 p_slot->state = POWERON_STATE;
355 info->req = ENABLE_REQ;
321 break; 356 break;
322 default: 357 default:
323 kfree(info); 358 kfree(info);
@@ -364,11 +399,10 @@ static void handle_button_press_event(struct slot *p_slot)
364 */ 399 */
365 ctrl_info(ctrl, "Button cancel on Slot(%s)\n", slot_name(p_slot)); 400 ctrl_info(ctrl, "Button cancel on Slot(%s)\n", slot_name(p_slot));
366 cancel_delayed_work(&p_slot->work); 401 cancel_delayed_work(&p_slot->work);
367 if (p_slot->state == BLINKINGOFF_STATE) { 402 if (p_slot->state == BLINKINGOFF_STATE)
368 pciehp_green_led_on(p_slot); 403 pciehp_green_led_on(p_slot);
369 } else { 404 else
370 pciehp_green_led_off(p_slot); 405 pciehp_green_led_off(p_slot);
371 }
372 pciehp_set_attention_status(p_slot, 0); 406 pciehp_set_attention_status(p_slot, 0);
373 ctrl_info(ctrl, "PCI slot #%s - action canceled " 407 ctrl_info(ctrl, "PCI slot #%s - action canceled "
374 "due to button press\n", slot_name(p_slot)); 408 "due to button press\n", slot_name(p_slot));
@@ -407,14 +441,81 @@ static void handle_surprise_event(struct slot *p_slot)
407 INIT_WORK(&info->work, pciehp_power_thread); 441 INIT_WORK(&info->work, pciehp_power_thread);
408 442
409 pciehp_get_adapter_status(p_slot, &getstatus); 443 pciehp_get_adapter_status(p_slot, &getstatus);
410 if (!getstatus) 444 if (!getstatus) {
411 p_slot->state = POWEROFF_STATE; 445 p_slot->state = POWEROFF_STATE;
412 else 446 info->req = DISABLE_REQ;
447 } else {
413 p_slot->state = POWERON_STATE; 448 p_slot->state = POWERON_STATE;
449 info->req = ENABLE_REQ;
450 }
414 451
415 queue_work(p_slot->wq, &info->work); 452 queue_work(p_slot->wq, &info->work);
416} 453}
417 454
455/*
456 * Note: This function must be called with slot->lock held
457 */
458static void handle_link_event(struct slot *p_slot, u32 event)
459{
460 struct controller *ctrl = p_slot->ctrl;
461 struct power_work_info *info;
462
463 info = kmalloc(sizeof(*info), GFP_KERNEL);
464 if (!info) {
465 ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
466 __func__);
467 return;
468 }
469 info->p_slot = p_slot;
470 info->req = event == INT_LINK_UP ? ENABLE_REQ : DISABLE_REQ;
471 INIT_WORK(&info->work, pciehp_power_thread);
472
473 switch (p_slot->state) {
474 case BLINKINGON_STATE:
475 case BLINKINGOFF_STATE:
476 cancel_delayed_work(&p_slot->work);
477 /* Fall through */
478 case STATIC_STATE:
479 p_slot->state = event == INT_LINK_UP ?
480 POWERON_STATE : POWEROFF_STATE;
481 queue_work(p_slot->wq, &info->work);
482 break;
483 case POWERON_STATE:
484 if (event == INT_LINK_UP) {
485 ctrl_info(ctrl,
486 "Link Up event ignored on slot(%s): already powering on\n",
487 slot_name(p_slot));
488 kfree(info);
489 } else {
490 ctrl_info(ctrl,
491 "Link Down event queued on slot(%s): currently getting powered on\n",
492 slot_name(p_slot));
493 p_slot->state = POWEROFF_STATE;
494 queue_work(p_slot->wq, &info->work);
495 }
496 break;
497 case POWEROFF_STATE:
498 if (event == INT_LINK_UP) {
499 ctrl_info(ctrl,
500 "Link Up event queued on slot(%s): currently getting powered off\n",
501 slot_name(p_slot));
502 p_slot->state = POWERON_STATE;
503 queue_work(p_slot->wq, &info->work);
504 } else {
505 ctrl_info(ctrl,
506 "Link Down event ignored on slot(%s): already powering off\n",
507 slot_name(p_slot));
508 kfree(info);
509 }
510 break;
511 default:
512 ctrl_err(ctrl, "Not a valid state on slot(%s)\n",
513 slot_name(p_slot));
514 kfree(info);
515 break;
516 }
517}
518
418static void interrupt_event_handler(struct work_struct *work) 519static void interrupt_event_handler(struct work_struct *work)
419{ 520{
420 struct event_info *info = container_of(work, struct event_info, work); 521 struct event_info *info = container_of(work, struct event_info, work);
@@ -433,12 +534,23 @@ static void interrupt_event_handler(struct work_struct *work)
433 pciehp_green_led_off(p_slot); 534 pciehp_green_led_off(p_slot);
434 break; 535 break;
435 case INT_PRESENCE_ON: 536 case INT_PRESENCE_ON:
436 case INT_PRESENCE_OFF:
437 if (!HP_SUPR_RM(ctrl)) 537 if (!HP_SUPR_RM(ctrl))
438 break; 538 break;
539 ctrl_dbg(ctrl, "Surprise Insertion\n");
540 handle_surprise_event(p_slot);
541 break;
542 case INT_PRESENCE_OFF:
543 /*
544 * Regardless of surprise capability, we need to
545 * definitely remove a card that has been pulled out!
546 */
439 ctrl_dbg(ctrl, "Surprise Removal\n"); 547 ctrl_dbg(ctrl, "Surprise Removal\n");
440 handle_surprise_event(p_slot); 548 handle_surprise_event(p_slot);
441 break; 549 break;
550 case INT_LINK_UP:
551 case INT_LINK_DOWN:
552 handle_link_event(p_slot, info->event_type);
553 break;
442 default: 554 default:
443 break; 555 break;
444 } 556 }
@@ -447,6 +559,9 @@ static void interrupt_event_handler(struct work_struct *work)
447 kfree(info); 559 kfree(info);
448} 560}
449 561
562/*
563 * Note: This function must be called with slot->hotplug_lock held
564 */
450int pciehp_enable_slot(struct slot *p_slot) 565int pciehp_enable_slot(struct slot *p_slot)
451{ 566{
452 u8 getstatus = 0; 567 u8 getstatus = 0;
@@ -479,13 +594,15 @@ int pciehp_enable_slot(struct slot *p_slot)
479 pciehp_get_latch_status(p_slot, &getstatus); 594 pciehp_get_latch_status(p_slot, &getstatus);
480 595
481 rc = board_added(p_slot); 596 rc = board_added(p_slot);
482 if (rc) { 597 if (rc)
483 pciehp_get_latch_status(p_slot, &getstatus); 598 pciehp_get_latch_status(p_slot, &getstatus);
484 } 599
485 return rc; 600 return rc;
486} 601}
487 602
488 603/*
604 * Note: This function must be called with slot->hotplug_lock held
605 */
489int pciehp_disable_slot(struct slot *p_slot) 606int pciehp_disable_slot(struct slot *p_slot)
490{ 607{
491 u8 getstatus = 0; 608 u8 getstatus = 0;
@@ -494,24 +611,6 @@ int pciehp_disable_slot(struct slot *p_slot)
494 if (!p_slot->ctrl) 611 if (!p_slot->ctrl)
495 return 1; 612 return 1;
496 613
497 if (!HP_SUPR_RM(p_slot->ctrl)) {
498 pciehp_get_adapter_status(p_slot, &getstatus);
499 if (!getstatus) {
500 ctrl_info(ctrl, "No adapter on slot(%s)\n",
501 slot_name(p_slot));
502 return -ENODEV;
503 }
504 }
505
506 if (MRL_SENS(p_slot->ctrl)) {
507 pciehp_get_latch_status(p_slot, &getstatus);
508 if (getstatus) {
509 ctrl_info(ctrl, "Latch open on slot(%s)\n",
510 slot_name(p_slot));
511 return -ENODEV;
512 }
513 }
514
515 if (POWER_CTRL(p_slot->ctrl)) { 614 if (POWER_CTRL(p_slot->ctrl)) {
516 pciehp_get_power_status(p_slot, &getstatus); 615 pciehp_get_power_status(p_slot, &getstatus);
517 if (!getstatus) { 616 if (!getstatus) {
@@ -536,7 +635,9 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot)
536 case STATIC_STATE: 635 case STATIC_STATE:
537 p_slot->state = POWERON_STATE; 636 p_slot->state = POWERON_STATE;
538 mutex_unlock(&p_slot->lock); 637 mutex_unlock(&p_slot->lock);
638 mutex_lock(&p_slot->hotplug_lock);
539 retval = pciehp_enable_slot(p_slot); 639 retval = pciehp_enable_slot(p_slot);
640 mutex_unlock(&p_slot->hotplug_lock);
540 mutex_lock(&p_slot->lock); 641 mutex_lock(&p_slot->lock);
541 p_slot->state = STATIC_STATE; 642 p_slot->state = STATIC_STATE;
542 break; 643 break;
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 14acfccb7670..d7d058fa19a4 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -206,7 +206,7 @@ static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
206 mutex_unlock(&ctrl->ctrl_lock); 206 mutex_unlock(&ctrl->ctrl_lock);
207} 207}
208 208
209static bool check_link_active(struct controller *ctrl) 209bool pciehp_check_link_active(struct controller *ctrl)
210{ 210{
211 struct pci_dev *pdev = ctrl_dev(ctrl); 211 struct pci_dev *pdev = ctrl_dev(ctrl);
212 u16 lnk_status; 212 u16 lnk_status;
@@ -225,12 +225,12 @@ static void __pcie_wait_link_active(struct controller *ctrl, bool active)
225{ 225{
226 int timeout = 1000; 226 int timeout = 1000;
227 227
228 if (check_link_active(ctrl) == active) 228 if (pciehp_check_link_active(ctrl) == active)
229 return; 229 return;
230 while (timeout > 0) { 230 while (timeout > 0) {
231 msleep(10); 231 msleep(10);
232 timeout -= 10; 232 timeout -= 10;
233 if (check_link_active(ctrl) == active) 233 if (pciehp_check_link_active(ctrl) == active)
234 return; 234 return;
235 } 235 }
236 ctrl_dbg(ctrl, "Data Link Layer Link Active not %s in 1000 msec\n", 236 ctrl_dbg(ctrl, "Data Link Layer Link Active not %s in 1000 msec\n",
@@ -242,11 +242,6 @@ static void pcie_wait_link_active(struct controller *ctrl)
242 __pcie_wait_link_active(ctrl, true); 242 __pcie_wait_link_active(ctrl, true);
243} 243}
244 244
245static void pcie_wait_link_not_active(struct controller *ctrl)
246{
247 __pcie_wait_link_active(ctrl, false);
248}
249
250static bool pci_bus_check_dev(struct pci_bus *bus, int devfn) 245static bool pci_bus_check_dev(struct pci_bus *bus, int devfn)
251{ 246{
252 u32 l; 247 u32 l;
@@ -332,11 +327,6 @@ static int pciehp_link_enable(struct controller *ctrl)
332 return __pciehp_link_set(ctrl, true); 327 return __pciehp_link_set(ctrl, true);
333} 328}
334 329
335static int pciehp_link_disable(struct controller *ctrl)
336{
337 return __pciehp_link_set(ctrl, false);
338}
339
340void pciehp_get_attention_status(struct slot *slot, u8 *status) 330void pciehp_get_attention_status(struct slot *slot, u8 *status)
341{ 331{
342 struct controller *ctrl = slot->ctrl; 332 struct controller *ctrl = slot->ctrl;
@@ -508,14 +498,6 @@ void pciehp_power_off_slot(struct slot * slot)
508{ 498{
509 struct controller *ctrl = slot->ctrl; 499 struct controller *ctrl = slot->ctrl;
510 500
511 /* Disable the link at first */
512 pciehp_link_disable(ctrl);
513 /* wait the link is down */
514 if (ctrl->link_active_reporting)
515 pcie_wait_link_not_active(ctrl);
516 else
517 msleep(1000);
518
519 pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_OFF, PCI_EXP_SLTCTL_PCC); 501 pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_OFF, PCI_EXP_SLTCTL_PCC);
520 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, 502 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
521 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, 503 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL,
@@ -540,7 +522,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
540 522
541 detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | 523 detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD |
542 PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | 524 PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC |
543 PCI_EXP_SLTSTA_CC); 525 PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_DLLSC);
544 detected &= ~intr_loc; 526 detected &= ~intr_loc;
545 intr_loc |= detected; 527 intr_loc |= detected;
546 if (!intr_loc) 528 if (!intr_loc)
@@ -579,6 +561,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
579 ctrl->power_fault_detected = 1; 561 ctrl->power_fault_detected = 1;
580 pciehp_handle_power_fault(slot); 562 pciehp_handle_power_fault(slot);
581 } 563 }
564
565 if (intr_loc & PCI_EXP_SLTSTA_DLLSC)
566 pciehp_handle_linkstate_change(slot);
567
582 return IRQ_HANDLED; 568 return IRQ_HANDLED;
583} 569}
584 570
@@ -596,9 +582,17 @@ void pcie_enable_notification(struct controller *ctrl)
596 * when it is cleared in the interrupt service routine, and 582 * when it is cleared in the interrupt service routine, and
597 * next power fault detected interrupt was notified again. 583 * next power fault detected interrupt was notified again.
598 */ 584 */
599 cmd = PCI_EXP_SLTCTL_PDCE; 585
586 /*
587 * Always enable link events: thus link-up and link-down shall
588 * always be treated as hotplug and unplug respectively. Enable
589 * presence detect only if Attention Button is not present.
590 */
591 cmd = PCI_EXP_SLTCTL_DLLSCE;
600 if (ATTN_BUTTN(ctrl)) 592 if (ATTN_BUTTN(ctrl))
601 cmd |= PCI_EXP_SLTCTL_ABPE; 593 cmd |= PCI_EXP_SLTCTL_ABPE;
594 else
595 cmd |= PCI_EXP_SLTCTL_PDCE;
602 if (MRL_SENS(ctrl)) 596 if (MRL_SENS(ctrl))
603 cmd |= PCI_EXP_SLTCTL_MRLSCE; 597 cmd |= PCI_EXP_SLTCTL_MRLSCE;
604 if (!pciehp_poll_mode) 598 if (!pciehp_poll_mode)
@@ -606,7 +600,8 @@ void pcie_enable_notification(struct controller *ctrl)
606 600
607 mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE | 601 mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE |
608 PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE | 602 PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE |
609 PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE); 603 PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE |
604 PCI_EXP_SLTCTL_DLLSCE);
610 605
611 pcie_write_cmd(ctrl, cmd, mask); 606 pcie_write_cmd(ctrl, cmd, mask);
612} 607}
@@ -624,33 +619,38 @@ static void pcie_disable_notification(struct controller *ctrl)
624 619
625/* 620/*
626 * pciehp has a 1:1 bus:slot relationship so we ultimately want a secondary 621 * pciehp has a 1:1 bus:slot relationship so we ultimately want a secondary
627 * bus reset of the bridge, but if the slot supports surprise removal we need 622 * bus reset of the bridge, but at the same time we want to ensure that it is
628 * to disable presence detection around the bus reset and clear any spurious 623 * not seen as a hot-unplug, followed by the hot-plug of the device. Thus,
624 * disable link state notification and presence detection change notification
625 * momentarily, if we see that they could interfere. Also, clear any spurious
629 * events after. 626 * events after.
630 */ 627 */
631int pciehp_reset_slot(struct slot *slot, int probe) 628int pciehp_reset_slot(struct slot *slot, int probe)
632{ 629{
633 struct controller *ctrl = slot->ctrl; 630 struct controller *ctrl = slot->ctrl;
634 struct pci_dev *pdev = ctrl_dev(ctrl); 631 struct pci_dev *pdev = ctrl_dev(ctrl);
632 u16 stat_mask = 0, ctrl_mask = 0;
635 633
636 if (probe) 634 if (probe)
637 return 0; 635 return 0;
638 636
639 if (HP_SUPR_RM(ctrl)) { 637 if (!ATTN_BUTTN(ctrl)) {
640 pcie_write_cmd(ctrl, 0, PCI_EXP_SLTCTL_PDCE); 638 ctrl_mask |= PCI_EXP_SLTCTL_PDCE;
641 if (pciehp_poll_mode) 639 stat_mask |= PCI_EXP_SLTSTA_PDC;
642 del_timer_sync(&ctrl->poll_timer);
643 } 640 }
641 ctrl_mask |= PCI_EXP_SLTCTL_DLLSCE;
642 stat_mask |= PCI_EXP_SLTSTA_DLLSC;
643
644 pcie_write_cmd(ctrl, 0, ctrl_mask);
645 if (pciehp_poll_mode)
646 del_timer_sync(&ctrl->poll_timer);
644 647
645 pci_reset_bridge_secondary_bus(ctrl->pcie->port); 648 pci_reset_bridge_secondary_bus(ctrl->pcie->port);
646 649
647 if (HP_SUPR_RM(ctrl)) { 650 pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, stat_mask);
648 pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, 651 pcie_write_cmd(ctrl, ctrl_mask, ctrl_mask);
649 PCI_EXP_SLTSTA_PDC); 652 if (pciehp_poll_mode)
650 pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PDCE, PCI_EXP_SLTCTL_PDCE); 653 int_poll_timeout(ctrl->poll_timer.data);
651 if (pciehp_poll_mode)
652 int_poll_timeout(ctrl->poll_timer.data);
653 }
654 654
655 return 0; 655 return 0;
656} 656}
@@ -687,6 +687,7 @@ static int pcie_init_slot(struct controller *ctrl)
687 687
688 slot->ctrl = ctrl; 688 slot->ctrl = ctrl;
689 mutex_init(&slot->lock); 689 mutex_init(&slot->lock);
690 mutex_init(&slot->hotplug_lock);
690 INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work); 691 INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work);
691 ctrl->slot = slot; 692 ctrl->slot = slot;
692 return 0; 693 return 0;
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index b07d7cc2d697..1b533060ce65 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -50,7 +50,7 @@ int pciehp_configure_device(struct slot *p_slot)
50 "at %04x:%02x:00, cannot hot-add\n", pci_name(dev), 50 "at %04x:%02x:00, cannot hot-add\n", pci_name(dev),
51 pci_domain_nr(parent), parent->number); 51 pci_domain_nr(parent), parent->number);
52 pci_dev_put(dev); 52 pci_dev_put(dev);
53 ret = -EINVAL; 53 ret = -EEXIST;
54 goto out; 54 goto out;
55 } 55 }
56 56