aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/platform/efi/Makefile1
-rw-r--r--arch/x86/platform/efi/efi-bgrt.c76
-rw-r--r--arch/x86/platform/efi/efi.c6
-rw-r--r--drivers/acpi/Kconfig4
-rw-r--r--drivers/acpi/bgrt.c76
-rw-r--r--include/linux/efi-bgrt.h21
-rw-r--r--include/linux/efi.h2
-rw-r--r--init/main.c4
8 files changed, 120 insertions, 70 deletions
diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile
index 73b8be0f3675..6db1cc4c7534 100644
--- a/arch/x86/platform/efi/Makefile
+++ b/arch/x86/platform/efi/Makefile
@@ -1 +1,2 @@
1obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o 1obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o
2obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o
diff --git a/arch/x86/platform/efi/efi-bgrt.c b/arch/x86/platform/efi/efi-bgrt.c
new file mode 100644
index 000000000000..f6a0c1b8e518
--- /dev/null
+++ b/arch/x86/platform/efi/efi-bgrt.c
@@ -0,0 +1,76 @@
1/*
2 * Copyright 2012 Intel Corporation
3 * Author: Josh Triplett <josh@joshtriplett.org>
4 *
5 * Based on the bgrt driver:
6 * Copyright 2012 Red Hat, Inc <mjg@redhat.com>
7 * Author: Matthew Garrett
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#include <linux/kernel.h>
14#include <linux/acpi.h>
15#include <linux/efi.h>
16#include <linux/efi-bgrt.h>
17
18struct acpi_table_bgrt *bgrt_tab;
19void *bgrt_image;
20size_t bgrt_image_size;
21
22struct bmp_header {
23 u16 id;
24 u32 size;
25} __packed;
26
27void efi_bgrt_init(void)
28{
29 acpi_status status;
30 void __iomem *image;
31 bool ioremapped = false;
32 struct bmp_header bmp_header;
33
34 if (acpi_disabled)
35 return;
36
37 status = acpi_get_table("BGRT", 0,
38 (struct acpi_table_header **)&bgrt_tab);
39 if (ACPI_FAILURE(status))
40 return;
41
42 if (bgrt_tab->version != 1)
43 return;
44 if (bgrt_tab->image_type != 0 || !bgrt_tab->image_address)
45 return;
46
47 image = efi_lookup_mapped_addr(bgrt_tab->image_address);
48 if (!image) {
49 image = ioremap(bgrt_tab->image_address, sizeof(bmp_header));
50 ioremapped = true;
51 if (!image)
52 return;
53 }
54
55 memcpy_fromio(&bmp_header, image, sizeof(bmp_header));
56 if (ioremapped)
57 iounmap(image);
58 bgrt_image_size = bmp_header.size;
59
60 bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL);
61 if (!bgrt_image)
62 return;
63
64 if (ioremapped) {
65 image = ioremap(bgrt_tab->image_address, bmp_header.size);
66 if (!image) {
67 kfree(bgrt_image);
68 bgrt_image = NULL;
69 return;
70 }
71 }
72
73 memcpy_fromio(bgrt_image, image, bgrt_image_size);
74 if (ioremapped)
75 iounmap(image);
76}
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index f7f928c315da..aded2a91162a 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -31,6 +31,7 @@
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/efi.h> 33#include <linux/efi.h>
34#include <linux/efi-bgrt.h>
34#include <linux/export.h> 35#include <linux/export.h>
35#include <linux/bootmem.h> 36#include <linux/bootmem.h>
36#include <linux/memblock.h> 37#include <linux/memblock.h>
@@ -745,6 +746,11 @@ void __init efi_init(void)
745#endif 746#endif
746} 747}
747 748
749void __init efi_late_init(void)
750{
751 efi_bgrt_init();
752}
753
748void __init efi_set_executable(efi_memory_desc_t *md, bool executable) 754void __init efi_set_executable(efi_memory_desc_t *md, bool executable)
749{ 755{
750 u64 addr, npages; 756 u64 addr, npages;
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 80998958cf45..119d58db8342 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -385,8 +385,8 @@ config ACPI_CUSTOM_METHOD
385 to override that restriction). 385 to override that restriction).
386 386
387config ACPI_BGRT 387config ACPI_BGRT
388 tristate "Boottime Graphics Resource Table support" 388 bool "Boottime Graphics Resource Table support"
389 default n 389 depends on EFI
390 help 390 help
391 This driver adds support for exposing the ACPI Boottime Graphics 391 This driver adds support for exposing the ACPI Boottime Graphics
392 Resource Table, which allows the operating system to obtain 392 Resource Table, which allows the operating system to obtain
diff --git a/drivers/acpi/bgrt.c b/drivers/acpi/bgrt.c
index 6680df36b963..be6039958545 100644
--- a/drivers/acpi/bgrt.c
+++ b/drivers/acpi/bgrt.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright 2012 Red Hat, Inc <mjg@redhat.com> 2 * Copyright 2012 Red Hat, Inc <mjg@redhat.com>
3 * Copyright 2012 Intel Corporation
3 * 4 *
4 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
@@ -11,20 +12,10 @@
11#include <linux/init.h> 12#include <linux/init.h>
12#include <linux/device.h> 13#include <linux/device.h>
13#include <linux/sysfs.h> 14#include <linux/sysfs.h>
14#include <linux/io.h> 15#include <linux/efi-bgrt.h>
15#include <acpi/acpi.h>
16#include <acpi/acpi_bus.h>
17 16
18static struct acpi_table_bgrt *bgrt_tab;
19static struct kobject *bgrt_kobj; 17static struct kobject *bgrt_kobj;
20 18
21struct bmp_header {
22 u16 id;
23 u32 size;
24} __attribute ((packed));
25
26static struct bmp_header bmp_header;
27
28static ssize_t show_version(struct device *dev, 19static ssize_t show_version(struct device *dev,
29 struct device_attribute *attr, char *buf) 20 struct device_attribute *attr, char *buf)
30{ 21{
@@ -63,18 +54,7 @@ static DEVICE_ATTR(yoffset, S_IRUGO, show_yoffset, NULL);
63static ssize_t show_image(struct file *file, struct kobject *kobj, 54static ssize_t show_image(struct file *file, struct kobject *kobj,
64 struct bin_attribute *attr, char *buf, loff_t off, size_t count) 55 struct bin_attribute *attr, char *buf, loff_t off, size_t count)
65{ 56{
66 int size = attr->size; 57 memcpy(buf, attr->private + off, count);
67 void __iomem *image = attr->private;
68
69 if (off >= size) {
70 count = 0;
71 } else {
72 if (off + count > size)
73 count = size - off;
74
75 memcpy_fromio(buf, image+off, count);
76 }
77
78 return count; 58 return count;
79} 59}
80 60
@@ -101,45 +81,18 @@ static struct attribute_group bgrt_attribute_group = {
101 81
102static int __init bgrt_init(void) 82static int __init bgrt_init(void)
103{ 83{
104 acpi_status status;
105 int ret; 84 int ret;
106 void __iomem *bgrt;
107 85
108 if (acpi_disabled) 86 if (!bgrt_image)
109 return -ENODEV;
110
111 status = acpi_get_table("BGRT", 0,
112 (struct acpi_table_header **)&bgrt_tab);
113
114 if (ACPI_FAILURE(status))
115 return -ENODEV; 87 return -ENODEV;
116 88
117 sysfs_bin_attr_init(&image_attr); 89 sysfs_bin_attr_init(&image_attr);
118 90 image_attr.private = bgrt_image;
119 bgrt = ioremap(bgrt_tab->image_address, sizeof(struct bmp_header)); 91 image_attr.size = bgrt_image_size;
120
121 if (!bgrt) {
122 ret = -EINVAL;
123 goto out_err;
124 }
125
126 memcpy_fromio(&bmp_header, bgrt, sizeof(bmp_header));
127 image_attr.size = bmp_header.size;
128 iounmap(bgrt);
129
130 image_attr.private = ioremap(bgrt_tab->image_address, image_attr.size);
131
132 if (!image_attr.private) {
133 ret = -EINVAL;
134 goto out_err;
135 }
136
137 92
138 bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj); 93 bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj);
139 if (!bgrt_kobj) { 94 if (!bgrt_kobj)
140 ret = -EINVAL; 95 return -EINVAL;
141 goto out_iounmap;
142 }
143 96
144 ret = sysfs_create_group(bgrt_kobj, &bgrt_attribute_group); 97 ret = sysfs_create_group(bgrt_kobj, &bgrt_attribute_group);
145 if (ret) 98 if (ret)
@@ -155,22 +108,11 @@ out_group:
155 sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group); 108 sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group);
156out_kobject: 109out_kobject:
157 kobject_put(bgrt_kobj); 110 kobject_put(bgrt_kobj);
158out_iounmap:
159 iounmap(image_attr.private);
160out_err:
161 return ret; 111 return ret;
162} 112}
163 113
164static void __exit bgrt_exit(void)
165{
166 iounmap(image_attr.private);
167 sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group);
168 sysfs_remove_bin_file(bgrt_kobj, &image_attr);
169}
170
171module_init(bgrt_init); 114module_init(bgrt_init);
172module_exit(bgrt_exit);
173 115
174MODULE_AUTHOR("Matthew Garrett"); 116MODULE_AUTHOR("Matthew Garrett, Josh Triplett <josh@joshtriplett.org>");
175MODULE_DESCRIPTION("BGRT boot graphic support"); 117MODULE_DESCRIPTION("BGRT boot graphic support");
176MODULE_LICENSE("GPL"); 118MODULE_LICENSE("GPL");
diff --git a/include/linux/efi-bgrt.h b/include/linux/efi-bgrt.h
new file mode 100644
index 000000000000..051b21fedf68
--- /dev/null
+++ b/include/linux/efi-bgrt.h
@@ -0,0 +1,21 @@
1#ifndef _LINUX_EFI_BGRT_H
2#define _LINUX_EFI_BGRT_H
3
4#ifdef CONFIG_ACPI_BGRT
5
6#include <linux/acpi.h>
7
8void efi_bgrt_init(void);
9
10/* The BGRT data itself; only valid if bgrt_image != NULL. */
11extern void *bgrt_image;
12extern size_t bgrt_image_size;
13extern struct acpi_table_bgrt *bgrt_tab;
14
15#else /* !CONFIG_ACPI_BGRT */
16
17static inline void efi_bgrt_init(void) {}
18
19#endif /* !CONFIG_ACPI_BGRT */
20
21#endif /* _LINUX_EFI_BGRT_H */
diff --git a/include/linux/efi.h b/include/linux/efi.h
index fff135d9375e..8670eb1eb8cd 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -497,8 +497,10 @@ extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg);
497extern void efi_gettimeofday (struct timespec *ts); 497extern void efi_gettimeofday (struct timespec *ts);
498extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, if possible */ 498extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, if possible */
499#ifdef CONFIG_X86 499#ifdef CONFIG_X86
500extern void efi_late_init(void);
500extern void efi_free_boot_services(void); 501extern void efi_free_boot_services(void);
501#else 502#else
503static inline void efi_late_init(void) {}
502static inline void efi_free_boot_services(void) {} 504static inline void efi_free_boot_services(void) {}
503#endif 505#endif
504extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr); 506extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr);
diff --git a/init/main.c b/init/main.c
index d61ec542205c..db34c0ec4711 100644
--- a/init/main.c
+++ b/init/main.c
@@ -631,8 +631,10 @@ asmlinkage void __init start_kernel(void)
631 acpi_early_init(); /* before LAPIC and SMP init */ 631 acpi_early_init(); /* before LAPIC and SMP init */
632 sfi_init_late(); 632 sfi_init_late();
633 633
634 if (efi_enabled) 634 if (efi_enabled) {
635 efi_late_init();
635 efi_free_boot_services(); 636 efi_free_boot_services();
637 }
636 638
637 ftrace_init(); 639 ftrace_init();
638 640