1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2d1ff4b1cSMatthew Garrett /*
3cc079f8cSPaul Gortmaker * BGRT boot graphic support
4cc079f8cSPaul Gortmaker * Authors: Matthew Garrett, Josh Triplett <josh@joshtriplett.org>
5d1ff4b1cSMatthew Garrett * Copyright 2012 Red Hat, Inc <mjg@redhat.com>
62223af38SJosh Triplett * Copyright 2012 Intel Corporation
7d1ff4b1cSMatthew Garrett */
8d1ff4b1cSMatthew Garrett
9d1ff4b1cSMatthew Garrett #include <linux/kernel.h>
10d1ff4b1cSMatthew Garrett #include <linux/init.h>
11d1ff4b1cSMatthew Garrett #include <linux/device.h>
12d1ff4b1cSMatthew Garrett #include <linux/sysfs.h>
132223af38SJosh Triplett #include <linux/efi-bgrt.h>
14d1ff4b1cSMatthew Garrett
157b0a9114SDave Young static void *bgrt_image;
16d1ff4b1cSMatthew Garrett static struct kobject *bgrt_kobj;
17d1ff4b1cSMatthew Garrett
18f37ccf8fSNathan Chancellor #define BGRT_SHOW(_name, _member) \
19f37ccf8fSNathan Chancellor static ssize_t _name##_show(struct kobject *kobj, \
20f37ccf8fSNathan Chancellor struct kobj_attribute *attr, char *buf) \
21f37ccf8fSNathan Chancellor { \
226554ca9cSNathan Chancellor return sysfs_emit(buf, "%d\n", bgrt_tab._member); \
23f37ccf8fSNathan Chancellor } \
24*db2d1693STom Rix static struct kobj_attribute bgrt_attr_##_name = __ATTR_RO(_name)
25d1ff4b1cSMatthew Garrett
26f37ccf8fSNathan Chancellor BGRT_SHOW(version, version);
27f37ccf8fSNathan Chancellor BGRT_SHOW(status, status);
28f37ccf8fSNathan Chancellor BGRT_SHOW(type, image_type);
29f37ccf8fSNathan Chancellor BGRT_SHOW(xoffset, image_offset_x);
30f37ccf8fSNathan Chancellor BGRT_SHOW(yoffset, image_offset_y);
31d1ff4b1cSMatthew Garrett
image_read(struct file * file,struct kobject * kobj,struct bin_attribute * attr,char * buf,loff_t off,size_t count)3265f44679SGreg KH static ssize_t image_read(struct file *file, struct kobject *kobj,
33d1ff4b1cSMatthew Garrett struct bin_attribute *attr, char *buf, loff_t off, size_t count)
34d1ff4b1cSMatthew Garrett {
352223af38SJosh Triplett memcpy(buf, attr->private + off, count);
36d1ff4b1cSMatthew Garrett return count;
37d1ff4b1cSMatthew Garrett }
38d1ff4b1cSMatthew Garrett
3965f44679SGreg KH static BIN_ATTR_RO(image, 0); /* size gets filled in later */
40d1ff4b1cSMatthew Garrett
41d1ff4b1cSMatthew Garrett static struct attribute *bgrt_attributes[] = {
42f37ccf8fSNathan Chancellor &bgrt_attr_version.attr,
43f37ccf8fSNathan Chancellor &bgrt_attr_status.attr,
44f37ccf8fSNathan Chancellor &bgrt_attr_type.attr,
45f37ccf8fSNathan Chancellor &bgrt_attr_xoffset.attr,
46f37ccf8fSNathan Chancellor &bgrt_attr_yoffset.attr,
47d1ff4b1cSMatthew Garrett NULL,
48d1ff4b1cSMatthew Garrett };
49d1ff4b1cSMatthew Garrett
5065f44679SGreg KH static struct bin_attribute *bgrt_bin_attributes[] = {
5165f44679SGreg KH &bin_attr_image,
5265f44679SGreg KH NULL,
5365f44679SGreg KH };
5465f44679SGreg KH
557e536269SArvind Yadav static const struct attribute_group bgrt_attribute_group = {
56d1ff4b1cSMatthew Garrett .attrs = bgrt_attributes,
5765f44679SGreg KH .bin_attrs = bgrt_bin_attributes,
58d1ff4b1cSMatthew Garrett };
59d1ff4b1cSMatthew Garrett
acpi_parse_bgrt(struct acpi_table_header * table)606e7300cfSBhupesh Sharma int __init acpi_parse_bgrt(struct acpi_table_header *table)
616e7300cfSBhupesh Sharma {
626e7300cfSBhupesh Sharma efi_bgrt_init(table);
636e7300cfSBhupesh Sharma return 0;
646e7300cfSBhupesh Sharma }
656e7300cfSBhupesh Sharma
bgrt_init(void)66d1ff4b1cSMatthew Garrett static int __init bgrt_init(void)
67d1ff4b1cSMatthew Garrett {
68d1ff4b1cSMatthew Garrett int ret;
69d1ff4b1cSMatthew Garrett
707b0a9114SDave Young if (!bgrt_tab.image_address)
71d1ff4b1cSMatthew Garrett return -ENODEV;
72d1ff4b1cSMatthew Garrett
737b0a9114SDave Young bgrt_image = memremap(bgrt_tab.image_address, bgrt_image_size,
747b0a9114SDave Young MEMREMAP_WB);
757b0a9114SDave Young if (!bgrt_image) {
767b0a9114SDave Young pr_notice("Ignoring BGRT: failed to map image memory\n");
777b0a9114SDave Young return -ENOMEM;
787b0a9114SDave Young }
797b0a9114SDave Young
8065f44679SGreg KH bin_attr_image.private = bgrt_image;
8165f44679SGreg KH bin_attr_image.size = bgrt_image_size;
82d1ff4b1cSMatthew Garrett
83d1ff4b1cSMatthew Garrett bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj);
847b0a9114SDave Young if (!bgrt_kobj) {
857b0a9114SDave Young ret = -EINVAL;
867b0a9114SDave Young goto out_memmap;
877b0a9114SDave Young }
88d1ff4b1cSMatthew Garrett
89d1ff4b1cSMatthew Garrett ret = sysfs_create_group(bgrt_kobj, &bgrt_attribute_group);
90d1ff4b1cSMatthew Garrett if (ret)
91d1ff4b1cSMatthew Garrett goto out_kobject;
92d1ff4b1cSMatthew Garrett
93d1ff4b1cSMatthew Garrett return 0;
94d1ff4b1cSMatthew Garrett
95d1ff4b1cSMatthew Garrett out_kobject:
96d1ff4b1cSMatthew Garrett kobject_put(bgrt_kobj);
977b0a9114SDave Young out_memmap:
987b0a9114SDave Young memunmap(bgrt_image);
99d1ff4b1cSMatthew Garrett return ret;
100d1ff4b1cSMatthew Garrett }
101cc079f8cSPaul Gortmaker device_initcall(bgrt_init);
102