[PATCH] gpu: drm: amd: amdgpu: Fix calls to dev_{info,err}

Bert Karwatzki spasswolf at web.de
Mon Jul 31 09:55:22 UTC 2023


Commit b0bd0a92b8158ea9c809d885e0f0c21518bdbd14 introduced
dev_{info,err} calls which failed (leading to a hang on boot) because of an
incorrect usage of the container_of macro. This fixes the error by introducing
a pointer to the device as an additional element in struct amdgpu_atpx and
struct radeon_atpx.

Fixes: https://gitlab.freedesktop.org/drm/amd/-/issues/2744
Signed-off-by: Bert Karwatzki <spasswolf at web.de>
---
 .../gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c  | 40 +++++++++----------
 drivers/gpu/drm/radeon/radeon_atpx_handler.c  | 30 +++++++-------
 2 files changed, 32 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
index 6f241c574665..29242ecec7b0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
@@ -37,6 +37,7 @@ struct amdgpu_atpx_functions {

 struct amdgpu_atpx {
 	acpi_handle handle;
+	struct device *dev;
 	struct amdgpu_atpx_functions functions;
 	bool is_hybrid;
 	bool dgpu_req_power_for_displays;
@@ -104,22 +105,20 @@ void *amdgpu_atpx_get_dhandle(void)
 /**
  * amdgpu_atpx_call - call an ATPX method
  *
- * @handle: acpi handle
+ * @atpx: amdgpu atpx struct
  * @function: the ATPX function to execute
  * @params: ATPX function params
  *
  * Executes the requested ATPX function (all asics).
  * Returns a pointer to the acpi output buffer.
  */
-static union acpi_object *amdgpu_atpx_call(acpi_handle handle, int function,
+static union acpi_object *amdgpu_atpx_call(struct amdgpu_atpx *atpx, int
function,
 					   struct acpi_buffer *params)
 {
 	acpi_status status;
 	union acpi_object atpx_arg_elements[2];
 	struct acpi_object_list atpx_arg;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-	struct acpi_device *adev = container_of(handle, struct acpi_device,
handle);
-	struct device *dev = &adev->dev;

 	atpx_arg.count = 2;
 	atpx_arg.pointer = &atpx_arg_elements[0];
@@ -137,11 +136,11 @@ static union acpi_object *amdgpu_atpx_call(acpi_handle
handle, int function,
 		atpx_arg_elements[1].integer.value = 0;
 	}

-	status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer);
+	status = acpi_evaluate_object(atpx->handle, NULL, &atpx_arg, &buffer);

 	/* Fail only if calling the method fails and ATPX is supported */
 	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
-		dev_err(dev, "failed to evaluate ATPX got %s\n",
+		dev_err(atpx->dev, "failed to evaluate ATPX got %s\n",
 			acpi_format_exception(status));
 		kfree(buffer.pointer);
 		return NULL;
@@ -183,15 +182,13 @@ static void amdgpu_atpx_parse_functions(struct
amdgpu_atpx_functions *f, u32 mas
 static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx)
 {
 	u32 valid_bits = 0;
-	struct acpi_device *adev = container_of(atpx->handle, struct
acpi_device, handle);
-	struct device *dev = &adev->dev;

 	if (atpx->functions.px_params) {
 		union acpi_object *info;
 		struct atpx_px_params output;
 		size_t size;

-		info = amdgpu_atpx_call(atpx->handle,
ATPX_FUNCTION_GET_PX_PARAMETERS, NULL);
+		info = amdgpu_atpx_call(atpx, ATPX_FUNCTION_GET_PX_PARAMETERS,
NULL);
 		if (!info)
 			return -EIO;

@@ -199,7 +196,7 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx)

 		size = *(u16 *) info->buffer.pointer;
 		if (size < 10) {
-			dev_err(dev, "ATPX buffer is too small: %zu\n", size);
+			dev_err(atpx->dev, "ATPX buffer is too small: %zu\n",
size);
 			kfree(info);
 			return -EINVAL;
 		}
@@ -232,11 +229,11 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx)
 	atpx->is_hybrid = false;
 	if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) {
 		if (amdgpu_atpx_priv.quirks & AMDGPU_PX_QUIRK_FORCE_ATPX) {
-			dev_info(dev, "ATPX Hybrid Graphics, forcing to
ATPX\n");
+			dev_info(atpx->dev, "ATPX Hybrid Graphics, forcing to
ATPX\n");
 			atpx->functions.power_cntl = true;
 			atpx->is_hybrid = false;
 		} else {
-			dev_info(dev, "ATPX Hybrid Graphics\n");
+			dev_info(atpx->dev, "ATPX Hybrid Graphics\n");
 			/*
 			 * Disable legacy PM methods only when pcie port PM is
usable,
 			 * otherwise the device might fail to power off or
power on.
@@ -269,10 +266,8 @@ static int amdgpu_atpx_verify_interface(struct amdgpu_atpx
*atpx)
 	struct atpx_verify_interface output;
 	size_t size;
 	int err = 0;
-	struct acpi_device *adev = container_of(atpx->handle, struct
acpi_device, handle);
-	struct device *dev = &adev->dev;

-	info = amdgpu_atpx_call(atpx->handle, ATPX_FUNCTION_VERIFY_INTERFACE,
NULL);
+	info = amdgpu_atpx_call(atpx, ATPX_FUNCTION_VERIFY_INTERFACE, NULL);
 	if (!info)
 		return -EIO;

@@ -280,7 +275,7 @@ static int amdgpu_atpx_verify_interface(struct amdgpu_atpx
*atpx)

 	size = *(u16 *) info->buffer.pointer;
 	if (size < 8) {
-		printk("ATPX buffer is too small: %zu\n", size);
+		dev_err(atpx->dev, "ATPX buffer is too small: %zu\n", size);
 		err = -EINVAL;
 		goto out;
 	}
@@ -289,7 +284,7 @@ static int amdgpu_atpx_verify_interface(struct amdgpu_atpx
*atpx)
 	memcpy(&output, info->buffer.pointer, size);

 	/* TODO: check version? */
-	dev_info(dev, "ATPX version %u, functions 0x%08x\n",
+	dev_info(atpx->dev, "ATPX version %u, functions 0x%08x\n",
 		 output.version, output.function_bits);

 	amdgpu_atpx_parse_functions(&atpx->functions, output.function_bits);
@@ -320,7 +315,7 @@ static int amdgpu_atpx_set_discrete_state(struct amdgpu_atpx
*atpx, u8 state)
 		input.dgpu_state = state;
 		params.length = input.size;
 		params.pointer = &input;
-		info = amdgpu_atpx_call(atpx->handle,
+		info = amdgpu_atpx_call(atpx,
 					ATPX_FUNCTION_POWER_CONTROL,
 					&params);
 		if (!info)
@@ -356,7 +351,7 @@ static int amdgpu_atpx_switch_disp_mux(struct amdgpu_atpx
*atpx, u16 mux_id)
 		input.mux = mux_id;
 		params.length = input.size;
 		params.pointer = &input;
-		info = amdgpu_atpx_call(atpx->handle,
+		info = amdgpu_atpx_call(atpx,
 					ATPX_FUNCTION_DISPLAY_MUX_CONTROL,
 					&params);
 		if (!info)
@@ -388,7 +383,7 @@ static int amdgpu_atpx_switch_i2c_mux(struct amdgpu_atpx
*atpx, u16 mux_id)
 		input.mux = mux_id;
 		params.length = input.size;
 		params.pointer = &input;
-		info = amdgpu_atpx_call(atpx->handle,
+		info = amdgpu_atpx_call(atpx,
 					ATPX_FUNCTION_I2C_MUX_CONTROL,
 					&params);
 		if (!info)
@@ -420,7 +415,7 @@ static int amdgpu_atpx_switch_start(struct amdgpu_atpx
*atpx, u16 mux_id)
 		input.mux = mux_id;
 		params.length = input.size;
 		params.pointer = &input;
-		info = amdgpu_atpx_call(atpx->handle,
+		info = amdgpu_atpx_call(atpx,
					ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION,
 					&params);
 		if (!info)
@@ -452,7 +447,7 @@ static int amdgpu_atpx_switch_end(struct amdgpu_atpx *atpx,
u16 mux_id)
 		input.mux = mux_id;
 		params.length = input.size;
 		params.pointer = &input;
-		info = amdgpu_atpx_call(atpx->handle,
+		info = amdgpu_atpx_call(atpx,
					ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION,
 					&params);
 		if (!info)
@@ -533,6 +528,7 @@ static bool amdgpu_atpx_pci_probe_handle(struct pci_dev
*pdev)
 	}
 	amdgpu_atpx_priv.dhandle = dhandle;
 	amdgpu_atpx_priv.atpx.handle = atpx_handle;
+	amdgpu_atpx_priv.atpx.dev = &pdev->dev;
 	return true;
 }

diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index fb4d931fdf18..f6a005520b55 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -26,6 +26,7 @@ struct radeon_atpx_functions {

 struct radeon_atpx {
 	acpi_handle handle;
+	struct device *dev;
 	struct radeon_atpx_functions functions;
 	bool is_hybrid;
 	bool dgpu_req_power_for_displays;
@@ -87,15 +88,13 @@ bool radeon_atpx_dgpu_req_power_for_displays(void) {
  * Executes the requested ATPX function (all asics).
  * Returns a pointer to the acpi output buffer.
  */
-static union acpi_object *radeon_atpx_call(acpi_handle handle, int function,
+static union acpi_object *radeon_atpx_call(struct radeon_atpx *atpx, int
function,
 					   struct acpi_buffer *params)
 {
 	acpi_status status;
 	union acpi_object atpx_arg_elements[2];
 	struct acpi_object_list atpx_arg;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-	struct acpi_device *adev = container_of(handle, struct acpi_device,
handle);
-	struct device *dev = &adev->dev;

 	atpx_arg.count = 2;
 	atpx_arg.pointer = &atpx_arg_elements[0];
@@ -113,11 +112,11 @@ static union acpi_object *radeon_atpx_call(acpi_handle
handle, int function,
 		atpx_arg_elements[1].integer.value = 0;
 	}

-	status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer);
+	status = acpi_evaluate_object(atpx->handle, NULL, &atpx_arg, &buffer);

 	/* Fail only if calling the method fails and ATPX is supported */
 	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
-		dev_err(dev, "failed to evaluate ATPX got %s\n",
+		dev_err(atpx->dev, "failed to evaluate ATPX got %s\n",
 			acpi_format_exception(status));
 		kfree(buffer.pointer);
 		return NULL;
@@ -159,15 +158,13 @@ static void radeon_atpx_parse_functions(struct
radeon_atpx_functions *f, u32 mas
 static int radeon_atpx_validate(struct radeon_atpx *atpx)
 {
 	u32 valid_bits = 0;
-	struct acpi_device *adev = container_of(atpx->handle, struct
acpi_device, handle);
-	struct device *dev = &adev->dev;

 	if (atpx->functions.px_params) {
 		union acpi_object *info;
 		struct atpx_px_params output;
 		size_t size;

-		info = radeon_atpx_call(atpx->handle,
ATPX_FUNCTION_GET_PX_PARAMETERS, NULL);
+		info = radeon_atpx_call(atpx, ATPX_FUNCTION_GET_PX_PARAMETERS,
NULL);
 		if (!info)
 			return -EIO;

@@ -175,7 +172,7 @@ static int radeon_atpx_validate(struct radeon_atpx *atpx)

 		size = *(u16 *) info->buffer.pointer;
 		if (size < 10) {
-			dev_err(dev, "ATPX buffer is too small: %zu\n", size);
+			dev_err(atpx->dev, "ATPX buffer is too small: %zu\n",
size);
 			kfree(info);
 			return -EINVAL;
 		}
@@ -206,7 +203,7 @@ static int radeon_atpx_validate(struct radeon_atpx *atpx)

 	atpx->is_hybrid = false;
 	if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) {
-		dev_info(dev, "ATPX Hybrid Graphics\n");
+		dev_info(atpx->dev, "ATPX Hybrid Graphics\n");
 		/*
 		 * Disable legacy PM methods only when pcie port PM is usable,
 		 * otherwise the device might fail to power off or power on.
@@ -235,7 +232,7 @@ static int radeon_atpx_verify_interface(struct radeon_atpx
*atpx)
 	size_t size;
 	int err = 0;

-	info = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_VERIFY_INTERFACE,
NULL);
+	info = radeon_atpx_call(atpx, ATPX_FUNCTION_VERIFY_INTERFACE, NULL);
 	if (!info)
 		return -EIO;

@@ -283,7 +280,7 @@ static int radeon_atpx_set_discrete_state(struct radeon_atpx
*atpx, u8 state)
 		input.dgpu_state = state;
 		params.length = input.size;
 		params.pointer = &input;
-		info = radeon_atpx_call(atpx->handle,
+		info = radeon_atpx_call(atpx,
 					ATPX_FUNCTION_POWER_CONTROL,
 					&params);
 		if (!info)
@@ -319,7 +316,7 @@ static int radeon_atpx_switch_disp_mux(struct radeon_atpx
*atpx, u16 mux_id)
 		input.mux = mux_id;
 		params.length = input.size;
 		params.pointer = &input;
-		info = radeon_atpx_call(atpx->handle,
+		info = radeon_atpx_call(atpx,
 					ATPX_FUNCTION_DISPLAY_MUX_CONTROL,
 					&params);
 		if (!info)
@@ -351,7 +348,7 @@ static int radeon_atpx_switch_i2c_mux(struct radeon_atpx
*atpx, u16 mux_id)
 		input.mux = mux_id;
 		params.length = input.size;
 		params.pointer = &input;
-		info = radeon_atpx_call(atpx->handle,
+		info = radeon_atpx_call(atpx,
 					ATPX_FUNCTION_I2C_MUX_CONTROL,
 					&params);
 		if (!info)
@@ -383,7 +380,7 @@ static int radeon_atpx_switch_start(struct radeon_atpx
*atpx, u16 mux_id)
 		input.mux = mux_id;
 		params.length = input.size;
 		params.pointer = &input;
-		info = radeon_atpx_call(atpx->handle,
+		info = radeon_atpx_call(atpx,
					ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_START_NOTIFICATION,
 					&params);
 		if (!info)
@@ -415,7 +412,7 @@ static int radeon_atpx_switch_end(struct radeon_atpx *atpx,
u16 mux_id)
 		input.mux = mux_id;
 		params.length = input.size;
 		params.pointer = &input;
-		info = radeon_atpx_call(atpx->handle,
+		info = radeon_atpx_call(atpx,
					ATPX_FUNCTION_GRAPHICS_DEVICE_SWITCH_END_NOTIFICATION,
 					&params);
 		if (!info)
@@ -495,6 +492,7 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev
*pdev)

 	radeon_atpx_priv.dhandle = dhandle;
 	radeon_atpx_priv.atpx.handle = atpx_handle;
+	radeon_atpx_priv.atpx.dev = &pdev->dev;
 	return true;
 }

--
2.39.2

If the introduction of new elements to {amdgpu,radeon}_atpx is to not wanted I
think using pr_{info,err} instead of dev_{info_err} is fine here.

Bert Karwatzki


More information about the amd-gfx mailing list