diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index e9b9e2db32cf33e0d7ca5d618b61d8a09a4b29c6..a65541b42b214e8879fa05f8fb81db3bfdf4ca17 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -224,6 +224,18 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) hotplug_mdev[node] = mem_device->device; num_enabled++; } + if (acpi_has_method(handle, "_HMA")) { + acpi_status status; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + + status = acpi_evaluate_object(handle, "_HMA", NULL, &buffer); + if (ACPI_SUCCESS(status) && buffer.length) { + union acpi_object *obj = buffer.pointer; + if (!obj->buffer.length) + hmat_restore_target(node); + } + } + if (!num_enabled) { dev_err(&mem_device->device->dev, "add_memory failed\n"); return -EINVAL; diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 5ac34c0eeb475f5f82ec659357cea3ae23fa8b32..82444a4cbf15b81a5186b3bba1594e04bd8b94c2 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -265,5 +265,6 @@ void acpi_init_lpit(void); #else static inline void acpi_init_lpit(void) { } #endif +void hmat_restore_target(int nid); #endif /* _ACPI_INTERNAL_H_ */ diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c index 26453a945da4401f043fd69f7f486a25bee50968..5be7334c51f3b5692cd564f25e0329d118126880 100644 --- a/drivers/acpi/numa/hmat.c +++ b/drivers/acpi/numa/hmat.c @@ -723,6 +723,23 @@ static void hmat_register_target_devices(struct memory_target *target) } } +void hmat_restore_target(int nid) +{ + struct memory_target *target; + int pxm; + + pxm = node_to_pxm(nid); + target = find_mem_target(pxm); + if (!target) + return; + + mutex_lock(&target_lock); + hmat_register_target_cache(target); + hmat_register_target_perf(target, 0); + hmat_register_target_perf(target, 1); + mutex_unlock(&target_lock); +} + static void hmat_register_target(struct memory_target *target) { int nid = pxm_to_node(target->memory_pxm); diff --git a/drivers/soc/hisilicon/hisi_hbmcache.c b/drivers/soc/hisilicon/hisi_hbmcache.c index c3295a7919d1505a09b7de6239c743d70ba48f2b..e06f613c143bb1b8a057554bdeb582cac5da55dc 100644 --- a/drivers/soc/hisilicon/hisi_hbmcache.c +++ b/drivers/soc/hisilicon/hisi_hbmcache.c @@ -14,27 +14,31 @@ #define MODULE_NAME "hbm_cache" static struct kobject *cache_kobj; +static struct mutex cache_lock; static ssize_t state_store(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { struct acpi_device *adev = ACPI_COMPANION(d); const int type = online_type_from_str(buf); - int ret = -EINVAL; + acpi_handle handle = adev->handle; + acpi_status status = AE_OK; + mutex_lock(&cache_lock); switch (type) { case STATE_ONLINE: - ret = acpi_device_set_power(adev, ACPI_STATE_D0); + status = acpi_evaluate_object(handle, "_ON", NULL, NULL); break; case STATE_OFFLINE: - ret = acpi_device_set_power(adev, ACPI_STATE_D3); + status = acpi_evaluate_object(handle, "_OFF", NULL, NULL); break; default: break; } + mutex_unlock(&cache_lock); - if (ret) - return ret; + if (ACPI_FAILURE(status)) + return -ENODEV; return count; } @@ -90,8 +94,8 @@ static int cache_remove(struct platform_device *pdev) } static const struct acpi_device_id cache_acpi_ids[] = { - {"HISI04A1"}, - {}, + {"HISI04A1", 0}, + {"", 0}, }; static struct platform_driver hbm_cache_driver = { @@ -111,6 +115,8 @@ static int __init hbm_cache_module_init(void) if (!cache_kobj) return -ENOMEM; + mutex_init(&cache_lock); + ret = platform_driver_register(&hbm_cache_driver); if (ret) { kobject_put(cache_kobj); diff --git a/drivers/soc/hisilicon/hisi_hbmdev.c b/drivers/soc/hisilicon/hisi_hbmdev.c index 33e5f0d9dde001d6695c0f9d5af91ee1204fcebc..4c7da1a0eb33ea8ace9c7960d3f7008a5ff45b7d 100644 --- a/drivers/soc/hisilicon/hisi_hbmdev.c +++ b/drivers/soc/hisilicon/hisi_hbmdev.c @@ -59,7 +59,9 @@ static int memdev_power_on(struct acpi_device *adev) acpi_handle handle = adev->handle; acpi_status status; + acpi_scan_lock_acquire(); status = acpi_evaluate_object(handle, "_ON", NULL, NULL); + acpi_scan_lock_release(); if (ACPI_FAILURE(status)) { acpi_handle_warn(handle, "Power on failed (0x%x)\n", status); return -ENODEV;