On Tue, Jul 31, 2012 at 09:58:04AM -0400, Alex Deucher wrote: > On Tue, Jul 31, 2012 at 5:16 AM, Luca Tettamanti <kronos.it at gmail.com> > wrote: > > On Mon, Jul 30, 2012 at 10:45 PM, Alex Deucher <alexdeucher at gmail.com> > > wrote: > >> Regarding patches 3 and 4, it might be easier to just store a pointer > >> to the relevant encoder when you verify ATIF rather than walking the > >> encoder list every time.
Done. > > Makes sense, I was unsure about the lifetime of the encoders, but > > AFAICS they're destroyed only when the module in unloaded. > > They are present for the life of the driver. I had to move to call to radeon_acpi_init after radeon_modeset_init, otherwise the encoders are not present yet (the tear down code path is correct, acpi first, then modeset). Latest and greatest version is attached; I fixed notifications when using custom command codes (tested by Pali Roh?r) and implemented your suggestion. Luca -------------- next part -------------- >From f0f8699eabee0d47b93fba14f8126b821cc106a5 Mon Sep 17 00:00:00 2001 From: Luca Tettamanti <kronos...@gmail.com> Date: Sun, 29 Jul 2012 17:04:43 +0200 Subject: [PATCH 1/4] drm/radeon: refactor radeon_atif_call Don't hard-code function number, this will allow to reuse the function. v2: add support for the 2nd parameter (from Lee, Chun-Yi <jlee at suse.com>). Signed-off-by: Luca Tettamanti <kronos.it at gmail.com> --- drivers/gpu/drm/radeon/radeon_acpi.c | 38 ++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c index 5b32e49..158e514 100644 --- a/drivers/gpu/drm/radeon/radeon_acpi.c +++ b/drivers/gpu/drm/radeon/radeon_acpi.c @@ -14,23 +14,30 @@ #include <linux/vga_switcheroo.h> /* Call the ATIF method - * - * Note: currently we discard the output */ -static int radeon_atif_call(acpi_handle handle) +static union acpi_object *radeon_atif_call(acpi_handle handle, int function, + struct acpi_buffer *params) { acpi_status status; union acpi_object atif_arg_elements[2]; struct acpi_object_list atif_arg; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; atif_arg.count = 2; atif_arg.pointer = &atif_arg_elements[0]; atif_arg_elements[0].type = ACPI_TYPE_INTEGER; - atif_arg_elements[0].integer.value = ATIF_FUNCTION_VERIFY_INTERFACE; - atif_arg_elements[1].type = ACPI_TYPE_INTEGER; - atif_arg_elements[1].integer.value = 0; + atif_arg_elements[0].integer.value = function; + + if (params) { + atif_arg_elements[1].type = ACPI_TYPE_BUFFER; + atif_arg_elements[1].buffer.length = params->length; + atif_arg_elements[1].buffer.pointer = params->pointer; + } else { + /* We need a second fake parameter */ + atif_arg_elements[1].type = ACPI_TYPE_INTEGER; + atif_arg_elements[1].integer.value = 0; + } status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer); @@ -39,18 +46,18 @@ static int radeon_atif_call(acpi_handle handle) DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n", acpi_format_exception(status)); kfree(buffer.pointer); - return 1; + return NULL; } - kfree(buffer.pointer); - return 0; + return buffer.pointer; } /* Call all ACPI methods here */ int radeon_acpi_init(struct radeon_device *rdev) { acpi_handle handle; - int ret; + union acpi_object *info; + int ret = 0; /* Get the device handle */ handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); @@ -60,10 +67,11 @@ int radeon_acpi_init(struct radeon_device *rdev) return 0; /* Call the ATIF method */ - ret = radeon_atif_call(handle); - if (ret) - return ret; + info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); + if (!info) + ret = -EIO; - return 0; + kfree(info); + return ret; } -- 1.7.10.4 -------------- next part -------------- >From 427002ddf653b0abd0fb820b09322bf2a0b281af Mon Sep 17 00:00:00 2001 From: Luca Tettamanti <kronos...@gmail.com> Date: Mon, 30 Jul 2012 21:11:58 +0200 Subject: [PATCH 2/4] drm/radeon: implement radeon_atif_verify_interface Wrap the call to VERIFY_INTERFACE and add the parsing of the support vectors. v2: use a packed struct for handling the output of ACPI calls, hides ugly pointer arithmetics (Lee, Chun-Yi <jlee at suse.com>). Signed-off-by: Luca Tettamanti <kronos.it at gmail.com> --- drivers/gpu/drm/radeon/radeon.h | 40 +++++++++++++++++ drivers/gpu/drm/radeon/radeon_acpi.c | 79 +++++++++++++++++++++++++++++++--- 2 files changed, 113 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index fefcca5..0db98eb 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1456,6 +1456,44 @@ struct r600_vram_scratch { u64 gpu_addr; }; +/* + * ACPI + */ +struct radeon_atif_notification_cfg { + bool enabled; + int command_code; +}; + +struct radeon_atif_notifications { + bool display_switch; + bool expansion_mode_change; + bool thermal_state; + bool forced_power_state; + bool system_power_state; + bool display_conf_change; + bool px_gfx_switch; + bool brightness_change; + bool dgpu_display_event; +}; + +struct radeon_atif_functions { + bool system_params; + bool sbios_requests; + bool select_active_disp; + bool lid_state; + bool get_tv_standard; + bool set_tv_standard; + bool get_panel_expansion_mode; + bool set_panel_expansion_mode; + bool temperature_change; + bool graphics_device_types; +}; + +struct radeon_atif { + struct radeon_atif_notifications notifications; + struct radeon_atif_functions functions; + struct radeon_atif_notification_cfg notification_cfg; +}; /* * Core structure, functions and helpers. @@ -1548,6 +1586,8 @@ struct radeon_device { unsigned debugfs_count; /* virtual memory */ struct radeon_vm_manager vm_manager; + /* ACPI interface */ + struct radeon_atif atif; }; int radeon_device_init(struct radeon_device *rdev, diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c index 158e514..53c519d 100644 --- a/drivers/gpu/drm/radeon/radeon_acpi.c +++ b/drivers/gpu/drm/radeon/radeon_acpi.c @@ -13,6 +13,13 @@ #include <linux/vga_switcheroo.h> +struct atif_verify_interface { + u16 size; /* structure size in bytes (includes size field) */ + u16 version; /* version */ + u32 notification_mask; /* supported notifications mask */ + u32 function_bits; /* supported functions bit vector */ +} __packed; + /* Call the ATIF method */ static union acpi_object *radeon_atif_call(acpi_handle handle, int function, @@ -52,12 +59,73 @@ static union acpi_object *radeon_atif_call(acpi_handle handle, int function, return buffer.pointer; } +static void radeon_atif_parse_notification(struct radeon_atif_notifications *n, u32 mask) +{ + n->display_switch = mask & ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED; + n->expansion_mode_change = mask & ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED; + n->thermal_state = mask & ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED; + n->forced_power_state = mask & ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED; + n->system_power_state = mask & ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED; + n->display_conf_change = mask & ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED; + n->px_gfx_switch = mask & ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED; + n->brightness_change = mask & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED; + n->dgpu_display_event = mask & ATIF_DGPU_DISPLAY_EVENT_SUPPORTED; +} + +static void radeon_atif_parse_functions(struct radeon_atif_functions *f, u32 mask) +{ + f->system_params = ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED; + f->sbios_requests = ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED; + f->select_active_disp = ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED; + f->lid_state = ATIF_GET_LID_STATE_SUPPORTED; + f->get_tv_standard = ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED; + f->set_tv_standard = ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED; + f->get_panel_expansion_mode = ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED; + f->set_panel_expansion_mode = ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED; + f->temperature_change = ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED; + f->graphics_device_types = ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED; +} + +static int radeon_atif_verify_interface(acpi_handle handle, + struct radeon_atif *atif) +{ + union acpi_object *info; + struct atif_verify_interface output; + size_t size; + int err = 0; + + info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); + if (!info) + return -EIO; + + memset(&output, 0, sizeof(output)); + + size = *(u16 *) info->buffer.pointer; + if (size < 12) { + DRM_INFO("ATIF buffer is too small: %lu\n", size); + err = -EINVAL; + goto out; + } + size = min(sizeof(output), size); + + memcpy(&output, info->buffer.pointer, size); + + /* TODO: check version? */ + DRM_DEBUG_DRIVER("ATIF version %u\n", output.version); + + radeon_atif_parse_notification(&atif->notifications, output.notification_mask); + radeon_atif_parse_functions(&atif->functions, output.function_bits); + +out: + kfree(info); + return err; +} + /* Call all ACPI methods here */ int radeon_acpi_init(struct radeon_device *rdev) { acpi_handle handle; - union acpi_object *info; - int ret = 0; + int ret; /* Get the device handle */ handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); @@ -67,11 +135,10 @@ int radeon_acpi_init(struct radeon_device *rdev) return 0; /* Call the ATIF method */ - info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); - if (!info) - ret = -EIO; + ret = radeon_atif_verify_interface(handle, &rdev->atif); + if (ret) + DRM_DEBUG_DRIVER("Call to verify_interface failed: %d\n", ret); - kfree(info); return ret; } -- 1.7.10.4 -------------- next part -------------- >From e83d04d1b60c5cf46611f6afc9680024e1dad73b Mon Sep 17 00:00:00 2001 From: Luca Tettamanti <kronos...@gmail.com> Date: Mon, 30 Jul 2012 21:16:06 +0200 Subject: [PATCH 3/4] drm/radeon: implement wrapper for GET_SYSTEM_PARAMS Use GET_SYSTEM_PARAMS for retrieving the configuration for the system BIOS notifications. v2: packed struct (Lee, Chun-Yi <jlee at suse.com>) Signed-off-by: Luca Tettamanti <kronos.it at gmail.com> --- drivers/gpu/drm/radeon/radeon_acpi.c | 84 +++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c index 53c519d..3d025dd 100644 --- a/drivers/gpu/drm/radeon/radeon_acpi.c +++ b/drivers/gpu/drm/radeon/radeon_acpi.c @@ -20,6 +20,18 @@ struct atif_verify_interface { u32 function_bits; /* supported functions bit vector */ } __packed; +struct atif_system_params { + u16 size; + u32 valid_mask; + u32 flags; + u8 command_code; +} __packed; + +#define ATIF_NOTIFY_MASK 0x3 +#define ATIF_NOTIFY_NONE 0 +#define ATIF_NOTIFY_81 1 +#define ATIF_NOTIFY_N 2 + /* Call the ATIF method */ static union acpi_object *radeon_atif_call(acpi_handle handle, int function, @@ -121,10 +133,56 @@ out: return err; } +static int radeon_atif_get_notification_params(acpi_handle handle, + struct radeon_atif_notification_cfg *n) +{ + union acpi_object *info; + struct atif_system_params params; + size_t size; + int err = 0; + + info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL); + if (!info) { + err = -EIO; + goto out; + } + + size = *(u16 *) info->buffer.pointer; + if (size < 10) { + err = -EINVAL; + goto out; + } + + memset(¶ms, 0, sizeof(params)); + size = min(sizeof(params), size); + memcpy(¶ms, info->buffer.pointer, size); + + params.flags = params.flags & params.valid_mask; + + if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) { + n->enabled = false; + n->command_code = 0; + } else if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_81) { + n->enabled = true; + n->command_code = 0x81; + } else { + if (size < 11) { + err = -EINVAL; + goto out; + } + n->command_code = params.command_code; + } + +out: + kfree(info); + return err; +} + /* Call all ACPI methods here */ int radeon_acpi_init(struct radeon_device *rdev) { acpi_handle handle; + struct radeon_atif *atif = &rdev->atif; int ret; /* Get the device handle */ @@ -135,10 +193,32 @@ int radeon_acpi_init(struct radeon_device *rdev) return 0; /* Call the ATIF method */ - ret = radeon_atif_verify_interface(handle, &rdev->atif); - if (ret) + ret = radeon_atif_verify_interface(handle, atif); + if (ret) { DRM_DEBUG_DRIVER("Call to verify_interface failed: %d\n", ret); + goto out; + } + + if (atif->functions.sbios_requests && !atif->functions.system_params) { + /* XXX check this workraround, if sbios request function is + * present we have to see how it's configured in the system + * params + */ + atif->functions.system_params = true; + } + + if (atif->functions.system_params) { + ret = radeon_atif_get_notification_params(handle, + &atif->notification_cfg); + if (ret) { + DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n", + ret); + /* Disable notification */ + atif->notification_cfg.enabled = false; + } + } +out: return ret; } -- 1.7.10.4 -------------- next part -------------- >From 88a3e35a0495cfff7d1a8ea23b779c621b3e1faa Mon Sep 17 00:00:00 2001 From: Luca Tettamanti <kronos...@gmail.com> Date: Mon, 30 Jul 2012 21:20:35 +0200 Subject: [PATCH 4/4] drm/radeon: implement handler for ACPI event MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set up an handler for ACPI events and respond to brightness change requests from the system BIOS. v2: fix notification when using device-specific command codes (tested by Pali Roh?r <pali.rohar at gmail.com>); cache the encoder controlling the backlight during the initialization to avoid searching it every time (suggested by Alex Deucher). Signed-off-by: Luca Tettamanti <kronos.it at gmail.com> --- drivers/gpu/drm/radeon/atombios_encoders.c | 2 +- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_acpi.c | 132 +++++++++++++++++++++++++++- drivers/gpu/drm/radeon/radeon_acpi.h | 6 ++ drivers/gpu/drm/radeon/radeon_kms.c | 16 ++-- drivers/gpu/drm/radeon/radeon_mode.h | 2 + drivers/gpu/drm/radeon/radeon_pm.c | 4 +- 7 files changed, 152 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index c2d3552..e4152d6 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -72,7 +72,7 @@ radeon_atom_set_backlight_level_to_reg(struct radeon_device *rdev, WREG32(RADEON_BIOS_2_SCRATCH, bios_2_scratch); } -static void +void atombios_set_panel_brightness(struct radeon_encoder *radeon_encoder) { struct drm_encoder *encoder = &radeon_encoder->base; diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 0db98eb..a57795b 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1493,6 +1493,7 @@ struct radeon_atif { struct radeon_atif_notifications notifications; struct radeon_atif_functions functions; struct radeon_atif_notification_cfg notification_cfg; + struct radeon_encoder *backlight_ctl; }; /* diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c index 3d025dd..9a97914 100644 --- a/drivers/gpu/drm/radeon/radeon_acpi.c +++ b/drivers/gpu/drm/radeon/radeon_acpi.c @@ -3,6 +3,7 @@ #include <linux/slab.h> #include <acpi/acpi_drivers.h> #include <acpi/acpi_bus.h> +#include <acpi/video.h> #include "drmP.h" #include "drm.h" @@ -10,6 +11,7 @@ #include "drm_crtc_helper.h" #include "radeon.h" #include "radeon_acpi.h" +#include "atom.h" #include <linux/vga_switcheroo.h> @@ -21,10 +23,22 @@ struct atif_verify_interface { } __packed; struct atif_system_params { - u16 size; - u32 valid_mask; - u32 flags; - u8 command_code; + u16 size; /* structure size in bytes (includes size field) */ + u32 valid_mask; /* valid flags mask */ + u32 flags; /* flags */ + u8 command_code; /* notify command code */ +} __packed; + +struct atif_sbios_requests { + u16 size; /* structure size in bytes (includes size field) */ + u32 pending; /* pending sbios requests */ + u8 panel_exp_mode; /* panel expansion mode */ + u8 thermal_gfx; /* thermal state: target gfx controller */ + u8 thermal_state; /* thermal state: state id (0: exit state, non-0: state) */ + u8 forced_power_gfx; /* forced power state: target gfx controller */ + u8 forced_power_state; /* forced power state: state id */ + u8 system_power_src; /* system power source */ + u8 backlight_level; /* panel backlight level (0-255) */ } __packed; #define ATIF_NOTIFY_MASK 0x3 @@ -157,6 +171,8 @@ static int radeon_atif_get_notification_params(acpi_handle handle, size = min(sizeof(params), size); memcpy(¶ms, info->buffer.pointer, size); + DRM_DEBUG_DRIVER("SYSTEM_PARAMS: mask = %#x, flags = %#x\n", + params.flags, params.valid_mask); params.flags = params.flags & params.valid_mask; if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) { @@ -174,10 +190,91 @@ static int radeon_atif_get_notification_params(acpi_handle handle, } out: + DRM_DEBUG_DRIVER("Notification %s, command code = %#x\n", + (n->enabled ? "enabled" : "disabled"), + n->command_code); kfree(info); return err; } +static int radeon_atif_get_sbios_requests(acpi_handle handle, + struct atif_sbios_requests *req) +{ + union acpi_object *info; + size_t size; + int count = 0; + + info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL); + if (!info) + return -EIO; + + size = *(u16 *)info->buffer.pointer; + if (size < 0xd) { + count = -EINVAL; + goto out; + } + memset(req, 0, sizeof(*req)); + + size = min(sizeof(*req), size); + memcpy(req, info->buffer.pointer, size); + DRM_DEBUG_DRIVER("SBIOS pending requests: %#x\n", req->pending); + + count = hweight32(req->pending); + +out: + kfree(info); + return count; +} + +int radeon_atif_handler(struct radeon_device *rdev, + struct acpi_bus_event *event) +{ + struct radeon_atif *atif = &rdev->atif; + struct atif_sbios_requests req; + acpi_handle handle; + int count; + + DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n", + event->device_class, event->type); + + if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0) + return NOTIFY_DONE; + + if (!atif->notification_cfg.enabled || + event->type != atif->notification_cfg.command_code) + /* Not our event */ + return NOTIFY_DONE; + + /* Check pending SBIOS requests */ + handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); + count = radeon_atif_get_sbios_requests(handle, &req); + + if (count <= 0) + return NOTIFY_DONE; + + DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count); + + if (req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) { + struct radeon_encoder *enc = atif->backlight_ctl; + + if (enc) { + struct radeon_encoder_atom_dig *dig = enc->enc_priv; + dig->backlight_level = req.backlight_level; + + DRM_DEBUG_DRIVER("Changing brightness to %d\n", + req.backlight_level); + + atombios_set_panel_brightness(enc); + + backlight_force_update(dig->bl_dev, + BACKLIGHT_UPDATE_HOTKEY); + } + } + /* TODO: check other events */ + + return NOTIFY_OK; +} + /* Call all ACPI methods here */ int radeon_acpi_init(struct radeon_device *rdev) { @@ -199,6 +296,33 @@ int radeon_acpi_init(struct radeon_device *rdev) goto out; } + if (atif->notifications.brightness_change) { + struct drm_encoder *tmp; + struct radeon_encoder *target = NULL; + + /* Find the encoder controlling the brightness */ + list_for_each_entry(tmp, &rdev->ddev->mode_config.encoder_list, + head) { + struct radeon_encoder *enc = to_radeon_encoder(tmp); + struct radeon_encoder_atom_dig *dig = enc->enc_priv; + + if ((enc->devices & (ATOM_DEVICE_LCD_SUPPORT)) && + dig->bl_dev != NULL) { + target = enc; + break; + } + } + + atif->backlight_ctl = target; + if (!target) { + /* Brightness change notification is enabled, but we + * didn't find a backlight controller, this should + * never happen. + */ + DRM_ERROR("Cannot find a backlight controller\n"); + } + } + if (atif->functions.sbios_requests && !atif->functions.system_params) { /* XXX check this workraround, if sbios request function is * present we have to see how it's configured in the system diff --git a/drivers/gpu/drm/radeon/radeon_acpi.h b/drivers/gpu/drm/radeon/radeon_acpi.h index a42288d..df1f162 100644 --- a/drivers/gpu/drm/radeon/radeon_acpi.h +++ b/drivers/gpu/drm/radeon/radeon_acpi.h @@ -24,6 +24,12 @@ #ifndef RADEON_ACPI_H #define RADEON_ACPI_H +struct radeon_device; +struct acpi_bus_event; + +int radeon_atif_handler(struct radeon_device *rdev, + struct acpi_bus_event *event); + /* AMD hw uses four ACPI control methods: * 1. ATIF * ARG0: (ACPI_INTEGER) function code diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 5c58d7d..a13b2eb 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -78,11 +78,6 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) goto out; } - /* Call ACPI methods */ - acpi_status = radeon_acpi_init(rdev); - if (acpi_status) - dev_dbg(&dev->pdev->dev, "Error during ACPI methods call\n"); - /* Again modeset_init should fail only on fatal error * otherwise it should provide enough functionalities * for shadowfb to run @@ -90,6 +85,17 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) r = radeon_modeset_init(rdev); if (r) dev_err(&dev->pdev->dev, "Fatal error during modeset init\n"); + + /* Call ACPI methods: require modeset init + * but failure is not fatal + */ + if (!r) { + acpi_status = radeon_acpi_init(rdev); + if (acpi_status) + dev_dbg(&dev->pdev->dev, + "Error during ACPI methods call\n"); + } + out: if (r) radeon_driver_unload_kms(dev); diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 129ed8e..ce91d62 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -697,6 +697,8 @@ void radeon_panel_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *adjusted_mode); void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc); +void atombios_set_panel_brightness(struct radeon_encoder *radeon_encoder); + /* legacy tv */ void radeon_legacy_tv_adjust_crtc_reg(struct drm_encoder *encoder, uint32_t *h_total_disp, uint32_t *h_sync_strt_wid, diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 5b37e28..8621748 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -22,6 +22,7 @@ */ #include "drmP.h" #include "radeon.h" +#include "radeon_acpi.h" #include "avivod.h" #include "atom.h" #ifdef CONFIG_ACPI @@ -95,7 +96,8 @@ static int radeon_acpi_event(struct notifier_block *nb, } } - return NOTIFY_OK; + /* Check for pending SBIOS requests */ + return radeon_atif_handler(rdev, entry); } #endif -- 1.7.10.4