Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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@suse.com>)
v3: fix enable with device specific command code

Signed-off-by: Luca Tettamanti <kronos.it@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Luca Tettamanti and committed by
Alex Deucher
ce3cf821 fd64ca8a

+83 -2
+83 -2
drivers/gpu/drm/radeon/radeon_acpi.c
··· 43 43 u32 function_bits; /* supported functions bit vector */ 44 44 } __packed; 45 45 46 + struct atif_system_params { 47 + u16 size; 48 + u32 valid_mask; 49 + u32 flags; 50 + u8 command_code; 51 + } __packed; 52 + 53 + #define ATIF_NOTIFY_MASK 0x3 54 + #define ATIF_NOTIFY_NONE 0 55 + #define ATIF_NOTIFY_81 1 56 + #define ATIF_NOTIFY_N 2 57 + 46 58 /* Call the ATIF method 47 59 */ 48 60 static union acpi_object *radeon_atif_call(acpi_handle handle, int function, ··· 156 144 return err; 157 145 } 158 146 147 + static int radeon_atif_get_notification_params(acpi_handle handle, 148 + struct radeon_atif_notification_cfg *n) 149 + { 150 + union acpi_object *info; 151 + struct atif_system_params params; 152 + size_t size; 153 + int err = 0; 154 + 155 + info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL); 156 + if (!info) { 157 + err = -EIO; 158 + goto out; 159 + } 160 + 161 + size = *(u16 *) info->buffer.pointer; 162 + if (size < 10) { 163 + err = -EINVAL; 164 + goto out; 165 + } 166 + 167 + memset(&params, 0, sizeof(params)); 168 + size = min(sizeof(params), size); 169 + memcpy(&params, info->buffer.pointer, size); 170 + 171 + params.flags = params.flags & params.valid_mask; 172 + 173 + if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) { 174 + n->enabled = false; 175 + n->command_code = 0; 176 + } else if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_81) { 177 + n->enabled = true; 178 + n->command_code = 0x81; 179 + } else { 180 + if (size < 11) { 181 + err = -EINVAL; 182 + goto out; 183 + } 184 + n->enabled = true; 185 + n->command_code = params.command_code; 186 + } 187 + 188 + out: 189 + kfree(info); 190 + return err; 191 + } 192 + 159 193 /* Call all ACPI methods here */ 160 194 int radeon_acpi_init(struct radeon_device *rdev) 161 195 { 162 196 acpi_handle handle; 197 + struct radeon_atif *atif = &rdev->atif; 163 198 int ret; 164 199 165 200 /* Get the device handle */ ··· 217 158 return 0; 218 159 219 160 /* Call the ATIF method */ 220 - ret = radeon_atif_verify_interface(handle, &rdev->atif); 221 - if (ret) 161 + ret = radeon_atif_verify_interface(handle, atif); 162 + if (ret) { 222 163 DRM_DEBUG_DRIVER("Call to verify_interface failed: %d\n", ret); 164 + goto out; 165 + } 223 166 167 + if (atif->functions.sbios_requests && !atif->functions.system_params) { 168 + /* XXX check this workraround, if sbios request function is 169 + * present we have to see how it's configured in the system 170 + * params 171 + */ 172 + atif->functions.system_params = true; 173 + } 174 + 175 + if (atif->functions.system_params) { 176 + ret = radeon_atif_get_notification_params(handle, 177 + &atif->notification_cfg); 178 + if (ret) { 179 + DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n", 180 + ret); 181 + /* Disable notification */ 182 + atif->notification_cfg.enabled = false; 183 + } 184 + } 185 + 186 + out: 224 187 return ret; 225 188 } 226 189