1 /* 2 * BGRT boot graphic support 3 * Authors: Matthew Garrett, Josh Triplett <josh@joshtriplett.org> 4 * Copyright 2012 Red Hat, Inc <mjg@redhat.com> 5 * Copyright 2012 Intel Corporation 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 12 #include <linux/kernel.h> 13 #include <linux/init.h> 14 #include <linux/device.h> 15 #include <linux/sysfs.h> 16 #include <linux/efi-bgrt.h> 17 18 static void *bgrt_image; 19 static struct kobject *bgrt_kobj; 20 21 static ssize_t show_version(struct device *dev, 22 struct device_attribute *attr, char *buf) 23 { 24 return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.version); 25 } 26 static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); 27 28 static ssize_t show_status(struct device *dev, 29 struct device_attribute *attr, char *buf) 30 { 31 return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.status); 32 } 33 static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); 34 35 static ssize_t show_type(struct device *dev, 36 struct device_attribute *attr, char *buf) 37 { 38 return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_type); 39 } 40 static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); 41 42 static ssize_t show_xoffset(struct device *dev, 43 struct device_attribute *attr, char *buf) 44 { 45 return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_x); 46 } 47 static DEVICE_ATTR(xoffset, S_IRUGO, show_xoffset, NULL); 48 49 static ssize_t show_yoffset(struct device *dev, 50 struct device_attribute *attr, char *buf) 51 { 52 return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_y); 53 } 54 static DEVICE_ATTR(yoffset, S_IRUGO, show_yoffset, NULL); 55 56 static ssize_t image_read(struct file *file, struct kobject *kobj, 57 struct bin_attribute *attr, char *buf, loff_t off, size_t count) 58 { 59 memcpy(buf, attr->private + off, count); 60 return count; 61 } 62 63 static BIN_ATTR_RO(image, 0); /* size gets filled in later */ 64 65 static struct attribute *bgrt_attributes[] = { 66 &dev_attr_version.attr, 67 &dev_attr_status.attr, 68 &dev_attr_type.attr, 69 &dev_attr_xoffset.attr, 70 &dev_attr_yoffset.attr, 71 NULL, 72 }; 73 74 static struct bin_attribute *bgrt_bin_attributes[] = { 75 &bin_attr_image, 76 NULL, 77 }; 78 79 static const struct attribute_group bgrt_attribute_group = { 80 .attrs = bgrt_attributes, 81 .bin_attrs = bgrt_bin_attributes, 82 }; 83 84 int __init acpi_parse_bgrt(struct acpi_table_header *table) 85 { 86 efi_bgrt_init(table); 87 return 0; 88 } 89 90 static int __init bgrt_init(void) 91 { 92 int ret; 93 94 if (!bgrt_tab.image_address) 95 return -ENODEV; 96 97 bgrt_image = memremap(bgrt_tab.image_address, bgrt_image_size, 98 MEMREMAP_WB); 99 if (!bgrt_image) { 100 pr_notice("Ignoring BGRT: failed to map image memory\n"); 101 return -ENOMEM; 102 } 103 104 bin_attr_image.private = bgrt_image; 105 bin_attr_image.size = bgrt_image_size; 106 107 bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj); 108 if (!bgrt_kobj) { 109 ret = -EINVAL; 110 goto out_memmap; 111 } 112 113 ret = sysfs_create_group(bgrt_kobj, &bgrt_attribute_group); 114 if (ret) 115 goto out_kobject; 116 117 return 0; 118 119 out_kobject: 120 kobject_put(bgrt_kobj); 121 out_memmap: 122 memunmap(bgrt_image); 123 return ret; 124 } 125 device_initcall(bgrt_init); 126