aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorMatthew Garrett <mjg59@srcf.ucam.org>2013-07-02 18:41:03 -0400
committerMatthew Garrett <matthew.garrett@nebula.com>2013-07-10 15:42:48 -0400
commit34a956db3774e8cba3f6b52aa9c1d67cf9a496fe (patch)
treefbc6a170ee548c9cf4a170bd6e399bfe5fd1f557 /drivers/platform
parent8667ca9518bbe0eff2222e69d611f4c8549fcbde (diff)
Add support driver for Intel Rapid Start Technology
Intel Rapid Start Technology is a firmware-based suspend-to-disk implementation. Once placed in S3, the device will wake once either a timeout elapses or the battery reaches a critical level. It will then resume to the firmware and copy the contents of RAM to a specialised partition, and then power off the machine. If the user turns the machine back on the firmware will copy the contents of the partition back to RAM and then resume from S3 as normal. This driver provides an interface for configuring the wakeup events and timeout. It still requires firmware support and an appropriate suspend partition. Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org> Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/Kconfig12
-rw-r--r--drivers/platform/x86/Makefile1
-rw-r--r--drivers/platform/x86/intel-rst.c209
3 files changed, 222 insertions, 0 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 37645b923c52..36057f481162 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -782,6 +782,18 @@ config APPLE_GMUX
782 graphics as well as the backlight. Currently only backlight 782 graphics as well as the backlight. Currently only backlight
783 control is supported by the driver. 783 control is supported by the driver.
784 784
785config INTEL_RST
786 tristate "Intel Rapid Start Technology Driver"
787 depends on ACPI
788 ---help---
789 This driver provides support for modifying paramaters on systems
790 equipped with Intel's Rapid Start Technology. When put in an ACPI
791 sleep state, these devices will wake after either a configured
792 timeout or when the system battery reaches a critical state,
793 automatically copying memory contents to disk. On resume, the
794 firmware will copy the memory contents back to RAM and resume the OS
795 as usual.
796
785config PVPANIC 797config PVPANIC
786 tristate "pvpanic device support" 798 tristate "pvpanic device support"
787 depends on ACPI 799 depends on ACPI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index ef0ec746f78c..5c669ce8d243 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -51,5 +51,6 @@ obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o
51obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o 51obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o
52obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o 52obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o
53obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o 53obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o
54obj-$(CONFIG_INTEL_RST) += intel-rst.o
54 55
55obj-$(CONFIG_PVPANIC) += pvpanic.o 56obj-$(CONFIG_PVPANIC) += pvpanic.o
diff --git a/drivers/platform/x86/intel-rst.c b/drivers/platform/x86/intel-rst.c
new file mode 100644
index 000000000000..9385afd9b558
--- /dev/null
+++ b/drivers/platform/x86/intel-rst.c
@@ -0,0 +1,209 @@
1/*
2 * Copyright 2013 Matthew Garrett <mjg59@srcf.ucam.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19
20#include <linux/init.h>
21#include <linux/module.h>
22#include <linux/slab.h>
23#include <acpi/acpi_drivers.h>
24
25MODULE_LICENSE("GPL");
26
27static ssize_t irst_show_wakeup_events(struct device *dev,
28 struct device_attribute *attr,
29 char *buf)
30{
31 struct acpi_device *acpi;
32 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
33 union acpi_object *result;
34 acpi_status status;
35
36 acpi = to_acpi_device(dev);
37
38 status = acpi_evaluate_object(acpi->handle, "GFFS", NULL, &output);
39 if (!ACPI_SUCCESS(status))
40 return -EINVAL;
41
42 result = output.pointer;
43
44 if (result->type != ACPI_TYPE_INTEGER) {
45 kfree(result);
46 return -EINVAL;
47 }
48
49 return sprintf(buf, "%lld\n", result->integer.value);
50}
51
52static ssize_t irst_store_wakeup_events(struct device *dev,
53 struct device_attribute *attr,
54 const char *buf, size_t count)
55{
56 struct acpi_device *acpi;
57 struct acpi_object_list input;
58 union acpi_object param;
59 acpi_status status;
60 unsigned long value;
61 int error;
62
63 acpi = to_acpi_device(dev);
64
65 error = kstrtoul(buf, 0, &value);
66
67 if (error)
68 return error;
69
70 param.type = ACPI_TYPE_INTEGER;
71 param.integer.value = value;
72
73 input.count = 1;
74 input.pointer = &param;
75
76 status = acpi_evaluate_object(acpi->handle, "SFFS", &input, NULL);
77
78 if (!ACPI_SUCCESS(status))
79 return -EINVAL;
80
81 return count;
82}
83
84static struct device_attribute irst_wakeup_attr = {
85 .attr = { .name = "wakeup_events", .mode = 0600 },
86 .show = irst_show_wakeup_events,
87 .store = irst_store_wakeup_events
88};
89
90static ssize_t irst_show_wakeup_time(struct device *dev,
91 struct device_attribute *attr, char *buf)
92{
93 struct acpi_device *acpi;
94 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
95 union acpi_object *result;
96 acpi_status status;
97
98 acpi = to_acpi_device(dev);
99
100 status = acpi_evaluate_object(acpi->handle, "GFTV", NULL, &output);
101 if (!ACPI_SUCCESS(status))
102 return -EINVAL;
103
104 result = output.pointer;
105
106 if (result->type != ACPI_TYPE_INTEGER) {
107 kfree(result);
108 return -EINVAL;
109 }
110
111 return sprintf(buf, "%lld\n", result->integer.value);
112}
113
114static ssize_t irst_store_wakeup_time(struct device *dev,
115 struct device_attribute *attr,
116 const char *buf, size_t count)
117{
118 struct acpi_device *acpi;
119 struct acpi_object_list input;
120 union acpi_object param;
121 acpi_status status;
122 unsigned long value;
123 int error;
124
125 acpi = to_acpi_device(dev);
126
127 error = kstrtoul(buf, 0, &value);
128
129 if (error)
130 return error;
131
132 param.type = ACPI_TYPE_INTEGER;
133 param.integer.value = value;
134
135 input.count = 1;
136 input.pointer = &param;
137
138 status = acpi_evaluate_object(acpi->handle, "SFTV", &input, NULL);
139
140 if (!ACPI_SUCCESS(status))
141 return -EINVAL;
142
143 return count;
144}
145
146static struct device_attribute irst_timeout_attr = {
147 .attr = { .name = "wakeup_time", .mode = 0600 },
148 .show = irst_show_wakeup_time,
149 .store = irst_store_wakeup_time
150};
151
152static int irst_add(struct acpi_device *acpi)
153{
154 int error = 0;
155
156 error = device_create_file(&acpi->dev, &irst_timeout_attr);
157 if (error)
158 goto out;
159
160 error = device_create_file(&acpi->dev, &irst_wakeup_attr);
161 if (error)
162 goto out_timeout;
163
164 return 0;
165
166out_timeout:
167 device_remove_file(&acpi->dev, &irst_timeout_attr);
168out:
169 return error;
170}
171
172static int irst_remove(struct acpi_device *acpi)
173{
174 device_remove_file(&acpi->dev, &irst_wakeup_attr);
175 device_remove_file(&acpi->dev, &irst_timeout_attr);
176
177 return 0;
178}
179
180static const struct acpi_device_id irst_ids[] = {
181 {"INT3392", 0},
182 {"", 0}
183};
184
185static struct acpi_driver irst_driver = {
186 .owner = THIS_MODULE,
187 .name = "intel_rapid_start",
188 .class = "intel_rapid_start",
189 .ids = irst_ids,
190 .ops = {
191 .add = irst_add,
192 .remove = irst_remove,
193 },
194};
195
196static int irst_init(void)
197{
198 return acpi_bus_register_driver(&irst_driver);
199}
200
201static void irst_exit(void)
202{
203 acpi_bus_unregister_driver(&irst_driver);
204}
205
206module_init(irst_init);
207module_exit(irst_exit);
208
209MODULE_DEVICE_TABLE(acpi, irst_ids);