| 1 | // SPDX-License-Identifier: GPL-2.0-only | 
|---|
| 2 | /* | 
|---|
| 3 | * BGRT boot graphic support | 
|---|
| 4 | * Authors: Matthew Garrett, Josh Triplett <josh@joshtriplett.org> | 
|---|
| 5 | * Copyright 2012 Red Hat, Inc <mjg@redhat.com> | 
|---|
| 6 | * Copyright 2012 Intel Corporation | 
|---|
| 7 | */ | 
|---|
| 8 |  | 
|---|
| 9 | #include <linux/kernel.h> | 
|---|
| 10 | #include <linux/init.h> | 
|---|
| 11 | #include <linux/device.h> | 
|---|
| 12 | #include <linux/sysfs.h> | 
|---|
| 13 | #include <linux/efi-bgrt.h> | 
|---|
| 14 |  | 
|---|
| 15 | static void *bgrt_image; | 
|---|
| 16 | static struct kobject *bgrt_kobj; | 
|---|
| 17 |  | 
|---|
| 18 | #define BGRT_SHOW(_name, _member) \ | 
|---|
| 19 | static ssize_t _name##_show(struct kobject *kobj,			\ | 
|---|
| 20 | struct kobj_attribute *attr, char *buf)	\ | 
|---|
| 21 | {									\ | 
|---|
| 22 | return sysfs_emit(buf, "%d\n", bgrt_tab._member);		\ | 
|---|
| 23 | }									\ | 
|---|
| 24 | static struct kobj_attribute bgrt_attr_##_name = __ATTR_RO(_name) | 
|---|
| 25 |  | 
|---|
| 26 | BGRT_SHOW(version, version); | 
|---|
| 27 | BGRT_SHOW(status, status); | 
|---|
| 28 | BGRT_SHOW(type, image_type); | 
|---|
| 29 | BGRT_SHOW(xoffset, image_offset_x); | 
|---|
| 30 | BGRT_SHOW(yoffset, image_offset_y); | 
|---|
| 31 |  | 
|---|
| 32 | static __ro_after_init BIN_ATTR_SIMPLE_RO(image); | 
|---|
| 33 |  | 
|---|
| 34 | static struct attribute *bgrt_attributes[] = { | 
|---|
| 35 | &bgrt_attr_version.attr, | 
|---|
| 36 | &bgrt_attr_status.attr, | 
|---|
| 37 | &bgrt_attr_type.attr, | 
|---|
| 38 | &bgrt_attr_xoffset.attr, | 
|---|
| 39 | &bgrt_attr_yoffset.attr, | 
|---|
| 40 | NULL, | 
|---|
| 41 | }; | 
|---|
| 42 |  | 
|---|
| 43 | static const struct bin_attribute *const bgrt_bin_attributes[] = { | 
|---|
| 44 | &bin_attr_image, | 
|---|
| 45 | NULL, | 
|---|
| 46 | }; | 
|---|
| 47 |  | 
|---|
| 48 | static const struct attribute_group bgrt_attribute_group = { | 
|---|
| 49 | .attrs = bgrt_attributes, | 
|---|
| 50 | .bin_attrs = bgrt_bin_attributes, | 
|---|
| 51 | }; | 
|---|
| 52 |  | 
|---|
| 53 | int __init acpi_parse_bgrt(struct acpi_table_header *table) | 
|---|
| 54 | { | 
|---|
| 55 | efi_bgrt_init(table); | 
|---|
| 56 | return 0; | 
|---|
| 57 | } | 
|---|
| 58 |  | 
|---|
| 59 | static int __init bgrt_init(void) | 
|---|
| 60 | { | 
|---|
| 61 | int ret; | 
|---|
| 62 |  | 
|---|
| 63 | if (!bgrt_tab.image_address) | 
|---|
| 64 | return -ENODEV; | 
|---|
| 65 |  | 
|---|
| 66 | bgrt_image = memremap(offset: bgrt_tab.image_address, size: bgrt_image_size, | 
|---|
| 67 | flags: MEMREMAP_WB); | 
|---|
| 68 | if (!bgrt_image) { | 
|---|
| 69 | pr_notice( "Ignoring BGRT: failed to map image memory\n"); | 
|---|
| 70 | return -ENOMEM; | 
|---|
| 71 | } | 
|---|
| 72 |  | 
|---|
| 73 | bin_attr_image.private = bgrt_image; | 
|---|
| 74 | bin_attr_image.size = bgrt_image_size; | 
|---|
| 75 |  | 
|---|
| 76 | bgrt_kobj = kobject_create_and_add(name: "bgrt", parent: acpi_kobj); | 
|---|
| 77 | if (!bgrt_kobj) { | 
|---|
| 78 | ret = -EINVAL; | 
|---|
| 79 | goto out_memmap; | 
|---|
| 80 | } | 
|---|
| 81 |  | 
|---|
| 82 | ret = sysfs_create_group(kobj: bgrt_kobj, grp: &bgrt_attribute_group); | 
|---|
| 83 | if (ret) | 
|---|
| 84 | goto out_kobject; | 
|---|
| 85 |  | 
|---|
| 86 | return 0; | 
|---|
| 87 |  | 
|---|
| 88 | out_kobject: | 
|---|
| 89 | kobject_put(kobj: bgrt_kobj); | 
|---|
| 90 | out_memmap: | 
|---|
| 91 | memunmap(addr: bgrt_image); | 
|---|
| 92 | return ret; | 
|---|
| 93 | } | 
|---|
| 94 | device_initcall(bgrt_init); | 
|---|
| 95 |  | 
|---|