diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2020-01-29 18:27:39 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2020-05-22 11:13:49 +1000 |
commit | b950c8c5d082d822b0134d1fc058101ab346e503 (patch) | |
tree | 93b3bc56e9e347db445ac01b47d3243b5383a2c4 | |
parent | 2dd4d163cd9c15432524aa9863155bc03a821361 (diff) |
drm/nouveau/bios: move ACPI _ROM handling
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_acpi.c | 54 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_acpi.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c | 65 |
3 files changed, 47 insertions, 76 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index fe3a10255c36..65440ec9b6f2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -49,7 +49,6 @@ static struct nouveau_dsm_priv { bool optimus_flags_detected; bool optimus_skip_dsm; acpi_handle dhandle; - acpi_handle rom_handle; } nouveau_dsm_priv; bool nouveau_is_optimus(void) { @@ -385,59 +384,6 @@ void nouveau_unregister_dsm_handler(void) {} void nouveau_switcheroo_optimus_dsm(void) {} #endif -/* retrieve the ROM in 4k blocks */ -static int nouveau_rom_call(acpi_handle rom_handle, uint8_t *bios, - int offset, int len) -{ - acpi_status status; - union acpi_object rom_arg_elements[2], *obj; - struct acpi_object_list rom_arg; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; - - rom_arg.count = 2; - rom_arg.pointer = &rom_arg_elements[0]; - - rom_arg_elements[0].type = ACPI_TYPE_INTEGER; - rom_arg_elements[0].integer.value = offset; - - rom_arg_elements[1].type = ACPI_TYPE_INTEGER; - rom_arg_elements[1].integer.value = len; - - status = acpi_evaluate_object(rom_handle, NULL, &rom_arg, &buffer); - if (ACPI_FAILURE(status)) { - pr_info("failed to evaluate ROM got %s\n", - acpi_format_exception(status)); - return -ENODEV; - } - obj = (union acpi_object *)buffer.pointer; - len = min(len, (int)obj->buffer.length); - memcpy(bios+offset, obj->buffer.pointer, len); - kfree(buffer.pointer); - return len; -} - -bool nouveau_acpi_rom_supported(struct device *dev) -{ - acpi_status status; - acpi_handle dhandle, rom_handle; - - dhandle = ACPI_HANDLE(dev); - if (!dhandle) - return false; - - status = acpi_get_handle(dhandle, "_ROM", &rom_handle); - if (ACPI_FAILURE(status)) - return false; - - nouveau_dsm_priv.rom_handle = rom_handle; - return true; -} - -int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) -{ - return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len); -} - void * nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.h b/drivers/gpu/drm/nouveau/nouveau_acpi.h index 1e6e8a8c0455..330f9b837066 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.h +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.h @@ -10,8 +10,6 @@ bool nouveau_is_v1_dsm(void); void nouveau_register_dsm_handler(void); void nouveau_unregister_dsm_handler(void); void nouveau_switcheroo_optimus_dsm(void); -int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len); -bool nouveau_acpi_rom_supported(struct device *); void *nouveau_acpi_edid(struct drm_device *, struct drm_connector *); #else static inline bool nouveau_is_optimus(void) { return false; }; @@ -19,8 +17,6 @@ static inline bool nouveau_is_v1_dsm(void) { return false; }; static inline void nouveau_register_dsm_handler(void) {} static inline void nouveau_unregister_dsm_handler(void) {} static inline void nouveau_switcheroo_optimus_dsm(void) {} -static inline bool nouveau_acpi_rom_supported(struct device *dev) { return false; } -static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; } static inline void *nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { return NULL; } #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c index 06572f8ce914..f9c427559538 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c @@ -22,22 +22,39 @@ */ #include "priv.h" -#if defined(CONFIG_ACPI) && defined(CONFIG_X86) -int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len); -bool nouveau_acpi_rom_supported(struct device *); -#else -static inline bool -nouveau_acpi_rom_supported(struct device *dev) +static int +acpi_read_bios(acpi_handle rom_handle, u8 *bios, u32 offset, u32 length) { - return false; -} +#if defined(CONFIG_ACPI) && defined(CONFIG_X86) + acpi_status status; + union acpi_object rom_arg_elements[2], *obj; + struct acpi_object_list rom_arg; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; -static inline int -nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) -{ + rom_arg.count = 2; + rom_arg.pointer = &rom_arg_elements[0]; + + rom_arg_elements[0].type = ACPI_TYPE_INTEGER; + rom_arg_elements[0].integer.value = offset; + + rom_arg_elements[1].type = ACPI_TYPE_INTEGER; + rom_arg_elements[1].integer.value = length; + + status = acpi_evaluate_object(rom_handle, NULL, &rom_arg, &buffer); + if (ACPI_FAILURE(status)) { + pr_info("failed to evaluate ROM got %s\n", + acpi_format_exception(status)); + return -ENODEV; + } + obj = (union acpi_object *)buffer.pointer; + length = min(length, obj->buffer.length); + memcpy(bios+offset, obj->buffer.pointer, length); + kfree(buffer.pointer); + return length; +#else return -EINVAL; -} #endif +} /* This version of the shadow function disobeys the ACPI spec and tries * to fetch in units of more than 4KiB at a time. This is a LOT faster @@ -51,7 +68,7 @@ acpi_read_fast(void *data, u32 offset, u32 length, struct nvkm_bios *bios) u32 fetch = limit - start; if (nvbios_extend(bios, limit) >= 0) { - int ret = nouveau_acpi_get_bios_chunk(bios->data, start, fetch); + int ret = acpi_read_bios(data, bios->data, start, fetch); if (ret == fetch) return fetch; } @@ -73,9 +90,8 @@ acpi_read_slow(void *data, u32 offset, u32 length, struct nvkm_bios *bios) if (nvbios_extend(bios, limit) >= 0) { while (start + fetch < limit) { - int ret = nouveau_acpi_get_bios_chunk(bios->data, - start + fetch, - 0x1000); + int ret = acpi_read_bios(data, bios->data, + start + fetch, 0x1000); if (ret != 0x1000) break; fetch += 0x1000; @@ -88,9 +104,22 @@ acpi_read_slow(void *data, u32 offset, u32 length, struct nvkm_bios *bios) static void * acpi_init(struct nvkm_bios *bios, const char *name) { - if (!nouveau_acpi_rom_supported(bios->subdev.device->dev)) +#if defined(CONFIG_ACPI) && defined(CONFIG_X86) + acpi_status status; + acpi_handle dhandle, rom_handle; + + dhandle = ACPI_HANDLE(bios->subdev.device->dev); + if (!dhandle) return ERR_PTR(-ENODEV); - return NULL; + + status = acpi_get_handle(dhandle, "_ROM", &rom_handle); + if (ACPI_FAILURE(status)) + return ERR_PTR(-ENODEV); + + return rom_handle; +#else + return ERR_PTR(-ENODEV); +#endif } const struct nvbios_source |