[Public] Hi Bert, Thanks for your patch. However, I guess adding a dev member for printing purpose only does not introduce much benefit. So, instead, the culprit commits have been reverted. https://patchwork.freedesktop.org/patch/550297/ https://patchwork.freedesktop.org/patch/550396/ Regards, Guchun > -----Original Message----- > From: Bert Karwatzki <spasswolf@xxxxxx> > Sent: Monday, July 31, 2023 5:55 PM > To: amd-gfx@xxxxxxxxxxxxxxxxxxxxx > Cc: SHANMUGAM, SRINIVASAN <SRINIVASAN.SHANMUGAM@xxxxxxx>; > Chen, Guchun <Guchun.Chen@xxxxxxx>; Alex Deucher > <alexdeucher@xxxxxxxxx> > Subject: [PATCH] gpu: drm: amd: amdgpu: Fix calls to dev_{info,err} > > 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@xxxxxx> > --- > .../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, > ¶ms); > 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, > ¶ms); > 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, > ¶ms); > 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, > ¶ms); > 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, > ¶ms); > 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, > ¶ms); > 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, > ¶ms); > 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, > ¶ms); > 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, > ¶ms); > 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, > ¶ms); > 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