Skip to content

Commit 3b9d0a7

Browse files
James Morsectmarinas
authored andcommitted
ACPI: Add post_eject to struct acpi_scan_handler for cpu hotplug
struct acpi_scan_handler has a detach callback that is used to remove a driver when a bus is changed. When interacting with an eject-request, the detach callback is called before _EJ0. This means the ACPI processor driver can't use _STA to determine if a CPU has been made not-present, or some of the other _STA bits have been changed. acpi_processor_remove() needs to know the value of _STA after _EJ0 has been called. Add a post_eject callback to struct acpi_scan_handler. This is called after acpi_scan_hot_remove() has successfully called _EJ0. Because acpi_scan_check_and_detach() also clears the handler pointer, it needs to be told if the caller will go on to call acpi_bus_post_eject(), so that acpi_device_clear_enumerated() and clearing the handler pointer can be deferred. An extra flag is added to flags field introduced in the previous patch to achieve this. Signed-off-by: James Morse <[email protected]> Reviewed-by: Gavin Shan <[email protected]> Tested-by: Miguel Luis <[email protected]> Tested-by: Vishnu Pajjuri <[email protected]> Tested-by: Jianyong Wu <[email protected]> Acked-by: Rafael J. Wysocki <[email protected]> Reviewed-by: Hanjun Guo <[email protected]> Signed-off-by: Jonathan Cameron <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent 1859a67 commit 3b9d0a7

File tree

3 files changed

+30
-5
lines changed

3 files changed

+30
-5
lines changed

drivers/acpi/acpi_processor.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ static int acpi_processor_add(struct acpi_device *device,
475475

476476
#ifdef CONFIG_ACPI_HOTPLUG_CPU
477477
/* Removal */
478-
static void acpi_processor_remove(struct acpi_device *device)
478+
static void acpi_processor_post_eject(struct acpi_device *device)
479479
{
480480
struct acpi_processor *pr;
481481

@@ -643,7 +643,7 @@ static struct acpi_scan_handler processor_handler = {
643643
.ids = processor_device_ids,
644644
.attach = acpi_processor_add,
645645
#ifdef CONFIG_ACPI_HOTPLUG_CPU
646-
.detach = acpi_processor_remove,
646+
.post_eject = acpi_processor_post_eject,
647647
#endif
648648
.hotplug = {
649649
.enabled = true,

drivers/acpi/scan.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ static int acpi_scan_try_to_offline(struct acpi_device *device)
244244
}
245245

246246
#define ACPI_SCAN_CHECK_FLAG_STATUS BIT(0)
247+
#define ACPI_SCAN_CHECK_FLAG_EJECT BIT(1)
247248

248249
static int acpi_scan_check_and_detach(struct acpi_device *adev, void *p)
249250
{
@@ -272,8 +273,6 @@ static int acpi_scan_check_and_detach(struct acpi_device *adev, void *p)
272273
if (handler) {
273274
if (handler->detach)
274275
handler->detach(adev);
275-
276-
adev->handler = NULL;
277276
} else {
278277
device_release_driver(&adev->dev);
279278
}
@@ -283,6 +282,28 @@ static int acpi_scan_check_and_detach(struct acpi_device *adev, void *p)
283282
*/
284283
acpi_device_set_power(adev, ACPI_STATE_D3_COLD);
285284
adev->flags.initialized = false;
285+
286+
/* For eject this is deferred to acpi_bus_post_eject() */
287+
if (!(flags & ACPI_SCAN_CHECK_FLAG_EJECT)) {
288+
adev->handler = NULL;
289+
acpi_device_clear_enumerated(adev);
290+
}
291+
return 0;
292+
}
293+
294+
static int acpi_bus_post_eject(struct acpi_device *adev, void *not_used)
295+
{
296+
struct acpi_scan_handler *handler = adev->handler;
297+
298+
acpi_dev_for_each_child_reverse(adev, acpi_bus_post_eject, NULL);
299+
300+
if (handler) {
301+
if (handler->post_eject)
302+
handler->post_eject(adev);
303+
304+
adev->handler = NULL;
305+
}
306+
286307
acpi_device_clear_enumerated(adev);
287308

288309
return 0;
@@ -300,6 +321,7 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
300321
acpi_handle handle = device->handle;
301322
unsigned long long sta;
302323
acpi_status status;
324+
uintptr_t flags = ACPI_SCAN_CHECK_FLAG_EJECT;
303325

304326
if (device->handler && device->handler->hotplug.demand_offline) {
305327
if (!acpi_scan_is_offline(device, true))
@@ -312,7 +334,7 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
312334

313335
acpi_handle_debug(handle, "Ejecting\n");
314336

315-
acpi_bus_trim(device);
337+
acpi_scan_check_and_detach(device, (void *)flags);
316338

317339
acpi_evaluate_lck(handle, 0);
318340
/*
@@ -335,6 +357,8 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
335357
} else if (sta & ACPI_STA_DEVICE_ENABLED) {
336358
acpi_handle_warn(handle,
337359
"Eject incomplete - status 0x%llx\n", sta);
360+
} else {
361+
acpi_bus_post_eject(device, NULL);
338362
}
339363

340364
return 0;

include/acpi/acpi_bus.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ struct acpi_scan_handler {
134134
bool (*match)(const char *idstr, const struct acpi_device_id **matchid);
135135
int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id);
136136
void (*detach)(struct acpi_device *dev);
137+
void (*post_eject)(struct acpi_device *dev);
137138
void (*bind)(struct device *phys_dev);
138139
void (*unbind)(struct device *phys_dev);
139140
struct acpi_hotplug_profile hotplug;

0 commit comments

Comments
 (0)