+10
drivers/acpi/bus.c
+10
drivers/acpi/bus.c
···
156
156
}
157
157
EXPORT_SYMBOL(acpi_bus_get_private_data);
158
158
159
+
void acpi_bus_no_hotplug(acpi_handle handle)
160
+
{
161
+
struct acpi_device *adev = NULL;
162
+
163
+
acpi_bus_get_device(handle, &adev);
164
+
if (adev)
165
+
adev->flags.no_hotplug = true;
166
+
}
167
+
EXPORT_SYMBOL_GPL(acpi_bus_no_hotplug);
168
+
159
169
static void acpi_print_osc_error(acpi_handle handle,
160
170
struct acpi_osc_context *context, char *error)
161
171
{
+14
-2
drivers/gpu/drm/nouveau/nouveau_acpi.c
+14
-2
drivers/gpu/drm/nouveau/nouveau_acpi.c
···
51
51
bool dsm_detected;
52
52
bool optimus_detected;
53
53
acpi_handle dhandle;
54
+
acpi_handle other_handle;
54
55
acpi_handle rom_handle;
55
56
} nouveau_dsm_priv;
56
57
···
261
260
if (!dhandle)
262
261
return false;
263
262
264
-
if (!acpi_has_method(dhandle, "_DSM"))
263
+
if (!acpi_has_method(dhandle, "_DSM")) {
264
+
nouveau_dsm_priv.other_handle = dhandle;
265
265
return false;
266
-
266
+
}
267
267
if (nouveau_test_dsm(dhandle, nouveau_dsm, NOUVEAU_DSM_POWER))
268
268
retval |= NOUVEAU_DSM_HAS_MUX;
269
269
···
340
338
printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n",
341
339
acpi_method_name);
342
340
nouveau_dsm_priv.dsm_detected = true;
341
+
/*
342
+
* On some systems hotplug events are generated for the device
343
+
* being switched off when _DSM is executed. They cause ACPI
344
+
* hotplug to trigger and attempt to remove the device from
345
+
* the system, which causes it to break down. Prevent that from
346
+
* happening by setting the no_hotplug flag for the involved
347
+
* ACPI device objects.
348
+
*/
349
+
acpi_bus_no_hotplug(nouveau_dsm_priv.dhandle);
350
+
acpi_bus_no_hotplug(nouveau_dsm_priv.other_handle);
343
351
ret = true;
344
352
}
345
353
+14
-2
drivers/gpu/drm/radeon/radeon_atpx_handler.c
+14
-2
drivers/gpu/drm/radeon/radeon_atpx_handler.c
···
33
33
bool atpx_detected;
34
34
/* handle for device - and atpx */
35
35
acpi_handle dhandle;
36
+
acpi_handle other_handle;
36
37
struct radeon_atpx atpx;
37
38
} radeon_atpx_priv;
38
39
···
452
451
return false;
453
452
454
453
status = acpi_get_handle(dhandle, "ATPX", &atpx_handle);
455
-
if (ACPI_FAILURE(status))
454
+
if (ACPI_FAILURE(status)) {
455
+
radeon_atpx_priv.other_handle = dhandle;
456
456
return false;
457
-
457
+
}
458
458
radeon_atpx_priv.dhandle = dhandle;
459
459
radeon_atpx_priv.atpx.handle = atpx_handle;
460
460
return true;
···
532
530
printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n",
533
531
acpi_method_name);
534
532
radeon_atpx_priv.atpx_detected = true;
533
+
/*
534
+
* On some systems hotplug events are generated for the device
535
+
* being switched off when ATPX is executed. They cause ACPI
536
+
* hotplug to trigger and attempt to remove the device from
537
+
* the system, which causes it to break down. Prevent that from
538
+
* happening by setting the no_hotplug flag for the involved
539
+
* ACPI device objects.
540
+
*/
541
+
acpi_bus_no_hotplug(radeon_atpx_priv.dhandle);
542
+
acpi_bus_no_hotplug(radeon_atpx_priv.other_handle);
535
543
return true;
536
544
}
537
545
return false;
+26
-4
drivers/pci/hotplug/acpiphp_glue.c
+26
-4
drivers/pci/hotplug/acpiphp_glue.c
···
279
279
280
280
status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
281
281
if (ACPI_FAILURE(status)) {
282
-
acpi_handle_warn(handle, "can't evaluate _ADR (%#x)\n", status);
282
+
if (status != AE_NOT_FOUND)
283
+
acpi_handle_warn(handle,
284
+
"can't evaluate _ADR (%#x)\n", status);
283
285
return AE_OK;
284
286
}
285
287
···
645
643
slot->flags &= (~SLOT_ENABLED);
646
644
}
647
645
646
+
static bool acpiphp_no_hotplug(acpi_handle handle)
647
+
{
648
+
struct acpi_device *adev = NULL;
649
+
650
+
acpi_bus_get_device(handle, &adev);
651
+
return adev && adev->flags.no_hotplug;
652
+
}
653
+
654
+
static bool slot_no_hotplug(struct acpiphp_slot *slot)
655
+
{
656
+
struct acpiphp_func *func;
657
+
658
+
list_for_each_entry(func, &slot->funcs, sibling)
659
+
if (acpiphp_no_hotplug(func_to_handle(func)))
660
+
return true;
661
+
662
+
return false;
663
+
}
648
664
649
665
/**
650
666
* get_slot_status - get ACPI slot status
···
721
701
unsigned long long sta;
722
702
723
703
status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
724
-
alive = ACPI_SUCCESS(status) && sta == ACPI_STA_ALL;
704
+
alive = (ACPI_SUCCESS(status) && sta == ACPI_STA_ALL)
705
+
|| acpiphp_no_hotplug(handle);
725
706
}
726
707
if (!alive) {
727
708
u32 v;
···
762
741
struct pci_dev *dev, *tmp;
763
742
764
743
mutex_lock(&slot->crit_sect);
765
-
/* wake up all functions */
766
-
if (get_slot_status(slot) == ACPI_STA_ALL) {
744
+
if (slot_no_hotplug(slot)) {
745
+
; /* do nothing */
746
+
} else if (get_slot_status(slot) == ACPI_STA_ALL) {
767
747
/* remove stale devices if any */
768
748
list_for_each_entry_safe(dev, tmp, &bus->devices,
769
749
bus_list)
+12
-9
drivers/pci/pci-acpi.c
+12
-9
drivers/pci/pci-acpi.c
···
330
330
static void pci_acpi_setup(struct device *dev)
331
331
{
332
332
struct pci_dev *pci_dev = to_pci_dev(dev);
333
-
acpi_handle handle = ACPI_HANDLE(dev);
334
-
struct acpi_device *adev;
333
+
struct acpi_device *adev = ACPI_COMPANION(dev);
335
334
336
-
if (acpi_bus_get_device(handle, &adev) || !adev->wakeup.flags.valid)
335
+
if (!adev)
336
+
return;
337
+
338
+
pci_acpi_add_pm_notifier(adev, pci_dev);
339
+
if (!adev->wakeup.flags.valid)
337
340
return;
338
341
339
342
device_set_wakeup_capable(dev, true);
340
343
acpi_pci_sleep_wake(pci_dev, false);
341
-
342
-
pci_acpi_add_pm_notifier(adev, pci_dev);
343
344
if (adev->wakeup.flags.run_wake)
344
345
device_set_run_wake(dev, true);
345
346
}
346
347
347
348
static void pci_acpi_cleanup(struct device *dev)
348
349
{
349
-
acpi_handle handle = ACPI_HANDLE(dev);
350
-
struct acpi_device *adev;
350
+
struct acpi_device *adev = ACPI_COMPANION(dev);
351
351
352
-
if (!acpi_bus_get_device(handle, &adev) && adev->wakeup.flags.valid) {
352
+
if (!adev)
353
+
return;
354
+
355
+
pci_acpi_remove_pm_notifier(adev);
356
+
if (adev->wakeup.flags.valid) {
353
357
device_set_wakeup_capable(dev, false);
354
358
device_set_run_wake(dev, false);
355
-
pci_acpi_remove_pm_notifier(adev);
356
359
}
357
360
}
358
361
+3
-1
include/acpi/acpi_bus.h
+3
-1
include/acpi/acpi_bus.h
···
169
169
u32 ejectable:1;
170
170
u32 power_manageable:1;
171
171
u32 match_driver:1;
172
-
u32 reserved:27;
172
+
u32 no_hotplug:1;
173
+
u32 reserved:26;
173
174
};
174
175
175
176
/* File System */
···
345
344
extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int);
346
345
void acpi_bus_private_data_handler(acpi_handle, void *);
347
346
int acpi_bus_get_private_data(acpi_handle, void **);
347
+
void acpi_bus_no_hotplug(acpi_handle handle);
348
348
extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32);
349
349
extern int register_acpi_notifier(struct notifier_block *);
350
350
extern int unregister_acpi_notifier(struct notifier_block *);