diff options
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c | 32 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_aca.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h | 3 |
4 files changed, 51 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c index f106a04363ea..8a3c3a49415d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c @@ -572,15 +572,45 @@ static int add_aca_handle(struct amdgpu_device *adev, struct aca_handle_manager return 0; } +static ssize_t aca_sysfs_read(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aca_handle *handle = container_of(attr, struct aca_handle, aca_attr); + + /* NOTE: the aca cache will be auto cleared once read, + * So the driver should unify the query entry point, forward request to ras query interface directly */ + return amdgpu_ras_aca_sysfs_read(dev, attr, handle, buf, handle->data); +} + +static int add_aca_sysfs(struct amdgpu_device *adev, struct aca_handle *handle) +{ + struct device_attribute *aca_attr = &handle->aca_attr; + + snprintf(handle->attr_name, sizeof(handle->attr_name) - 1, "aca_%s", handle->name); + aca_attr->show = aca_sysfs_read; + aca_attr->attr.name = handle->attr_name; + aca_attr->attr.mode = S_IRUGO; + sysfs_attr_init(&aca_attr->attr); + + return sysfs_add_file_to_group(&adev->dev->kobj, + &aca_attr->attr, + "ras"); +} + int amdgpu_aca_add_handle(struct amdgpu_device *adev, struct aca_handle *handle, const char *name, const struct aca_info *ras_info, void *data) { struct amdgpu_aca *aca = &adev->aca; + int ret; if (!amdgpu_aca_is_enabled(adev)) return 0; - return add_aca_handle(adev, &aca->mgr, handle, name, ras_info, data); + ret = add_aca_handle(adev, &aca->mgr, handle, name, ras_info, data); + if (ret) + return ret; + + return add_aca_sysfs(adev, handle); } static void remove_aca(struct aca_handle *handle) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.h index f6c72371244e..6e9a35eda683 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.h @@ -149,6 +149,8 @@ struct aca_handle { struct aca_handle_manager *mgr; struct aca_error_cache error_cache; const struct aca_bank_ops *bank_ops; + struct device_attribute aca_attr; + char attr_name[64]; const char *name; u32 mask; void *data; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index bb93e4e3969f..bc459dff42f3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -1214,6 +1214,21 @@ static int amdgpu_aca_log_ras_error_data(struct amdgpu_device *adev, enum amdgpu return amdgpu_aca_get_error_data(adev, &obj->aca_handle, type, err_data); } +ssize_t amdgpu_ras_aca_sysfs_read(struct device *dev, struct device_attribute *attr, + struct aca_handle *handle, char *buf, void *data) +{ + struct ras_manager *obj = container_of(handle, struct ras_manager, aca_handle); + struct ras_query_if info = { + .head = obj->head, + }; + + if (amdgpu_ras_query_error_status(obj->adev, &info)) + return -EINVAL; + + return sysfs_emit(buf, "%s: %lu\n%s: %lu\n", "ue", info.ue_count, + "ce", info.ce_count); +} + static int amdgpu_ras_query_error_status_helper(struct amdgpu_device *adev, struct ras_query_if *info, struct ras_err_data *err_data, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h index 1d568a25f1de..394394d98bc3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h @@ -840,4 +840,7 @@ int amdgpu_ras_bind_aca(struct amdgpu_device *adev, enum amdgpu_ras_block blk, const struct aca_info *aca_info, void *data); int amdgpu_ras_unbind_aca(struct amdgpu_device *adev, enum amdgpu_ras_block blk); +ssize_t amdgpu_ras_aca_sysfs_read(struct device *dev, struct device_attribute *attr, + struct aca_handle *handle, char *buf, void *data); + #endif |