1*44e33a5aSSean Rhodes // SPDX-License-Identifier: GPL-2.0-only
2*44e33a5aSSean Rhodes /*
3*44e33a5aSSean Rhodes * Copyright 2010 Google Inc. All Rights Reserved.
4*44e33a5aSSean Rhodes * Author: dlaurie@google.com (Duncan Laurie)
5*44e33a5aSSean Rhodes *
6*44e33a5aSSean Rhodes * Re-worked to expose sysfs APIs by mikew@google.com (Mike Waychison)
7*44e33a5aSSean Rhodes *
8*44e33a5aSSean Rhodes * EFI SMI interface for Google platforms
9*44e33a5aSSean Rhodes */
10*44e33a5aSSean Rhodes
11*44e33a5aSSean Rhodes #include <linux/kernel.h>
12*44e33a5aSSean Rhodes #include <linux/init.h>
13*44e33a5aSSean Rhodes #include <linux/types.h>
14*44e33a5aSSean Rhodes #include <linux/device.h>
15*44e33a5aSSean Rhodes #include <linux/platform_device.h>
16*44e33a5aSSean Rhodes #include <linux/errno.h>
17*44e33a5aSSean Rhodes #include <linux/string.h>
18*44e33a5aSSean Rhodes #include <linux/spinlock.h>
19*44e33a5aSSean Rhodes #include <linux/dma-mapping.h>
20*44e33a5aSSean Rhodes #include <linux/fs.h>
21*44e33a5aSSean Rhodes #include <linux/slab.h>
22*44e33a5aSSean Rhodes #include <linux/panic_notifier.h>
23*44e33a5aSSean Rhodes #include <linux/ioctl.h>
24*44e33a5aSSean Rhodes #include <linux/acpi.h>
25*44e33a5aSSean Rhodes #include <linux/io.h>
26*44e33a5aSSean Rhodes #include <linux/uaccess.h>
27*44e33a5aSSean Rhodes #include <linux/dmi.h>
28*44e33a5aSSean Rhodes #include <linux/kdebug.h>
29*44e33a5aSSean Rhodes #include <linux/reboot.h>
30*44e33a5aSSean Rhodes #include <linux/efi.h>
31*44e33a5aSSean Rhodes #include <linux/module.h>
32*44e33a5aSSean Rhodes #include <linux/ucs2_string.h>
33*44e33a5aSSean Rhodes #include <linux/suspend.h>
34*44e33a5aSSean Rhodes
35*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_CLEAN 0 /* Clean Shutdown */
36*44e33a5aSSean Rhodes /* TODO(mikew@google.com): Tie in HARDLOCKUP_DETECTOR with NMIWDT */
37*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_NMIWDT 1 /* NMI Watchdog */
38*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_PANIC 2 /* Panic */
39*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_OOPS 3 /* Oops */
40*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_DIE 4 /* Die -- No longer meaningful */
41*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_MCE 5 /* Machine Check */
42*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_SOFTWDT 6 /* Software Watchdog */
43*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_MBE 7 /* Uncorrected ECC */
44*44e33a5aSSean Rhodes #define GSMI_SHUTDOWN_TRIPLE 8 /* Triple Fault */
45*44e33a5aSSean Rhodes
46*44e33a5aSSean Rhodes #define DRIVER_VERSION "1.0"
47*44e33a5aSSean Rhodes #define GSMI_GUID_SIZE 16
48*44e33a5aSSean Rhodes #define GSMI_BUF_SIZE 1024
49*44e33a5aSSean Rhodes #define GSMI_BUF_ALIGN sizeof(u64)
50*44e33a5aSSean Rhodes #define GSMI_CALLBACK 0xef
51*44e33a5aSSean Rhodes
52*44e33a5aSSean Rhodes /* SMI return codes */
53*44e33a5aSSean Rhodes #define GSMI_SUCCESS 0x00
54*44e33a5aSSean Rhodes #define GSMI_UNSUPPORTED2 0x03
55*44e33a5aSSean Rhodes #define GSMI_LOG_FULL 0x0b
56*44e33a5aSSean Rhodes #define GSMI_VAR_NOT_FOUND 0x0e
57*44e33a5aSSean Rhodes #define GSMI_HANDSHAKE_SPIN 0x7d
58*44e33a5aSSean Rhodes #define GSMI_HANDSHAKE_CF 0x7e
59*44e33a5aSSean Rhodes #define GSMI_HANDSHAKE_NONE 0x7f
60*44e33a5aSSean Rhodes #define GSMI_INVALID_PARAMETER 0x82
61*44e33a5aSSean Rhodes #define GSMI_UNSUPPORTED 0x83
62*44e33a5aSSean Rhodes #define GSMI_BUFFER_TOO_SMALL 0x85
63*44e33a5aSSean Rhodes #define GSMI_NOT_READY 0x86
64*44e33a5aSSean Rhodes #define GSMI_DEVICE_ERROR 0x87
65*44e33a5aSSean Rhodes #define GSMI_NOT_FOUND 0x8e
66*44e33a5aSSean Rhodes
67*44e33a5aSSean Rhodes #define QUIRKY_BOARD_HASH 0x78a30a50
68*44e33a5aSSean Rhodes
69*44e33a5aSSean Rhodes /* Internally used commands passed to the firmware */
70*44e33a5aSSean Rhodes #define GSMI_CMD_GET_NVRAM_VAR 0x01
71*44e33a5aSSean Rhodes #define GSMI_CMD_GET_NEXT_VAR 0x02
72*44e33a5aSSean Rhodes #define GSMI_CMD_SET_NVRAM_VAR 0x03
73*44e33a5aSSean Rhodes #define GSMI_CMD_SET_EVENT_LOG 0x08
74*44e33a5aSSean Rhodes #define GSMI_CMD_CLEAR_EVENT_LOG 0x09
75*44e33a5aSSean Rhodes #define GSMI_CMD_LOG_S0IX_SUSPEND 0x0a
76*44e33a5aSSean Rhodes #define GSMI_CMD_LOG_S0IX_RESUME 0x0b
77*44e33a5aSSean Rhodes #define GSMI_CMD_CLEAR_CONFIG 0x20
78*44e33a5aSSean Rhodes #define GSMI_CMD_HANDSHAKE_TYPE 0xC1
79*44e33a5aSSean Rhodes #define GSMI_CMD_RESERVED 0xff
80*44e33a5aSSean Rhodes
81*44e33a5aSSean Rhodes /* Magic entry type for kernel events */
82*44e33a5aSSean Rhodes #define GSMI_LOG_ENTRY_TYPE_KERNEL 0xDEAD
83*44e33a5aSSean Rhodes
84*44e33a5aSSean Rhodes /* SMI buffers must be in 32bit physical address space */
85*44e33a5aSSean Rhodes struct gsmi_buf {
86*44e33a5aSSean Rhodes u8 *start; /* start of buffer */
87*44e33a5aSSean Rhodes size_t length; /* length of buffer */
88*44e33a5aSSean Rhodes u32 address; /* physical address of buffer */
89*44e33a5aSSean Rhodes };
90*44e33a5aSSean Rhodes
91*44e33a5aSSean Rhodes static struct gsmi_device {
92*44e33a5aSSean Rhodes struct platform_device *pdev; /* platform device */
93*44e33a5aSSean Rhodes struct gsmi_buf *name_buf; /* variable name buffer */
94*44e33a5aSSean Rhodes struct gsmi_buf *data_buf; /* generic data buffer */
95*44e33a5aSSean Rhodes struct gsmi_buf *param_buf; /* parameter buffer */
96*44e33a5aSSean Rhodes spinlock_t lock; /* serialize access to SMIs */
97*44e33a5aSSean Rhodes u16 smi_cmd; /* SMI command port */
98*44e33a5aSSean Rhodes int handshake_type; /* firmware handler interlock type */
99*44e33a5aSSean Rhodes struct kmem_cache *mem_pool; /* kmem cache for gsmi_buf allocations */
100*44e33a5aSSean Rhodes } gsmi_dev;
101*44e33a5aSSean Rhodes
102*44e33a5aSSean Rhodes /* Packed structures for communicating with the firmware */
103*44e33a5aSSean Rhodes struct gsmi_nvram_var_param {
104*44e33a5aSSean Rhodes efi_guid_t guid;
105*44e33a5aSSean Rhodes u32 name_ptr;
106*44e33a5aSSean Rhodes u32 attributes;
107*44e33a5aSSean Rhodes u32 data_len;
108*44e33a5aSSean Rhodes u32 data_ptr;
109*44e33a5aSSean Rhodes } __packed;
110*44e33a5aSSean Rhodes
111*44e33a5aSSean Rhodes struct gsmi_get_next_var_param {
112*44e33a5aSSean Rhodes u8 guid[GSMI_GUID_SIZE];
113*44e33a5aSSean Rhodes u32 name_ptr;
114*44e33a5aSSean Rhodes u32 name_len;
115*44e33a5aSSean Rhodes } __packed;
116*44e33a5aSSean Rhodes
117*44e33a5aSSean Rhodes struct gsmi_set_eventlog_param {
118*44e33a5aSSean Rhodes u32 data_ptr;
119*44e33a5aSSean Rhodes u32 data_len;
120*44e33a5aSSean Rhodes u32 type;
121*44e33a5aSSean Rhodes } __packed;
122*44e33a5aSSean Rhodes
123*44e33a5aSSean Rhodes /* Event log formats */
124*44e33a5aSSean Rhodes struct gsmi_log_entry_type_1 {
125*44e33a5aSSean Rhodes u16 type;
126*44e33a5aSSean Rhodes u32 instance;
127*44e33a5aSSean Rhodes } __packed;
128*44e33a5aSSean Rhodes
129*44e33a5aSSean Rhodes /*
130*44e33a5aSSean Rhodes * Some platforms don't have explicit SMI handshake
131*44e33a5aSSean Rhodes * and need to wait for SMI to complete.
132*44e33a5aSSean Rhodes */
133*44e33a5aSSean Rhodes #define GSMI_DEFAULT_SPINCOUNT 0x10000
134*44e33a5aSSean Rhodes static unsigned int spincount = GSMI_DEFAULT_SPINCOUNT;
135*44e33a5aSSean Rhodes module_param(spincount, uint, 0600);
136*44e33a5aSSean Rhodes MODULE_PARM_DESC(spincount,
137*44e33a5aSSean Rhodes "The number of loop iterations to use when using the spin handshake.");
138*44e33a5aSSean Rhodes
139*44e33a5aSSean Rhodes /*
140*44e33a5aSSean Rhodes * Some older platforms with Apollo Lake chipsets do not support S0ix logging
141*44e33a5aSSean Rhodes * in their GSMI handlers, and behaved poorly when resuming via power button
142*44e33a5aSSean Rhodes * press if the logging was attempted. Updated firmware with proper behavior
143*44e33a5aSSean Rhodes * has long since shipped, removing the need for this opt-in parameter. It
144*44e33a5aSSean Rhodes * now exists as an opt-out parameter for folks defiantly running old
145*44e33a5aSSean Rhodes * firmware, or unforeseen circumstances. After the change from opt-in to
146*44e33a5aSSean Rhodes * opt-out has baked sufficiently, this parameter should probably be removed
147*44e33a5aSSean Rhodes * entirely.
148*44e33a5aSSean Rhodes */
149*44e33a5aSSean Rhodes static bool s0ix_logging_enable = true;
150*44e33a5aSSean Rhodes module_param(s0ix_logging_enable, bool, 0600);
151*44e33a5aSSean Rhodes
gsmi_buf_alloc(void)152*44e33a5aSSean Rhodes static struct gsmi_buf *gsmi_buf_alloc(void)
153*44e33a5aSSean Rhodes {
154*44e33a5aSSean Rhodes struct gsmi_buf *smibuf;
155*44e33a5aSSean Rhodes
156*44e33a5aSSean Rhodes smibuf = kzalloc_obj(*smibuf);
157*44e33a5aSSean Rhodes if (!smibuf) {
158*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: out of memory\n");
159*44e33a5aSSean Rhodes return NULL;
160*44e33a5aSSean Rhodes }
161*44e33a5aSSean Rhodes
162*44e33a5aSSean Rhodes /* allocate buffer in 32bit address space */
163*44e33a5aSSean Rhodes smibuf->start = kmem_cache_alloc(gsmi_dev.mem_pool, GFP_KERNEL);
164*44e33a5aSSean Rhodes if (!smibuf->start) {
165*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: failed to allocate name buffer\n");
166*44e33a5aSSean Rhodes kfree(smibuf);
167*44e33a5aSSean Rhodes return NULL;
168*44e33a5aSSean Rhodes }
169*44e33a5aSSean Rhodes
170*44e33a5aSSean Rhodes /* fill in the buffer handle */
171*44e33a5aSSean Rhodes smibuf->length = GSMI_BUF_SIZE;
172*44e33a5aSSean Rhodes smibuf->address = (u32)virt_to_phys(smibuf->start);
173*44e33a5aSSean Rhodes
174*44e33a5aSSean Rhodes return smibuf;
175*44e33a5aSSean Rhodes }
176*44e33a5aSSean Rhodes
gsmi_buf_free(struct gsmi_buf * smibuf)177*44e33a5aSSean Rhodes static void gsmi_buf_free(struct gsmi_buf *smibuf)
178*44e33a5aSSean Rhodes {
179*44e33a5aSSean Rhodes if (smibuf) {
180*44e33a5aSSean Rhodes if (smibuf->start)
181*44e33a5aSSean Rhodes kmem_cache_free(gsmi_dev.mem_pool, smibuf->start);
182*44e33a5aSSean Rhodes kfree(smibuf);
183*44e33a5aSSean Rhodes }
184*44e33a5aSSean Rhodes }
185*44e33a5aSSean Rhodes
186*44e33a5aSSean Rhodes /*
187*44e33a5aSSean Rhodes * Make a call to gsmi func(sub). GSMI error codes are translated to
188*44e33a5aSSean Rhodes * in-kernel errnos (0 on success, -ERRNO on error).
189*44e33a5aSSean Rhodes */
gsmi_exec(u8 func,u8 sub)190*44e33a5aSSean Rhodes static int gsmi_exec(u8 func, u8 sub)
191*44e33a5aSSean Rhodes {
192*44e33a5aSSean Rhodes u16 cmd = (sub << 8) | func;
193*44e33a5aSSean Rhodes u16 result = 0;
194*44e33a5aSSean Rhodes int rc = 0;
195*44e33a5aSSean Rhodes
196*44e33a5aSSean Rhodes /*
197*44e33a5aSSean Rhodes * AH : Subfunction number
198*44e33a5aSSean Rhodes * AL : Function number
199*44e33a5aSSean Rhodes * EBX : Parameter block address
200*44e33a5aSSean Rhodes * DX : SMI command port
201*44e33a5aSSean Rhodes *
202*44e33a5aSSean Rhodes * Three protocols here. See also the comment in gsmi_init().
203*44e33a5aSSean Rhodes */
204*44e33a5aSSean Rhodes if (gsmi_dev.handshake_type == GSMI_HANDSHAKE_CF) {
205*44e33a5aSSean Rhodes /*
206*44e33a5aSSean Rhodes * If handshake_type == HANDSHAKE_CF then set CF on the
207*44e33a5aSSean Rhodes * way in and wait for the handler to clear it; this avoids
208*44e33a5aSSean Rhodes * corrupting register state on those chipsets which have
209*44e33a5aSSean Rhodes * a delay between writing the SMI trigger register and
210*44e33a5aSSean Rhodes * entering SMM.
211*44e33a5aSSean Rhodes */
212*44e33a5aSSean Rhodes asm volatile (
213*44e33a5aSSean Rhodes "stc\n"
214*44e33a5aSSean Rhodes "outb %%al, %%dx\n"
215*44e33a5aSSean Rhodes "1: jc 1b\n"
216*44e33a5aSSean Rhodes : "=a" (result)
217*44e33a5aSSean Rhodes : "0" (cmd),
218*44e33a5aSSean Rhodes "d" (gsmi_dev.smi_cmd),
219*44e33a5aSSean Rhodes "b" (gsmi_dev.param_buf->address)
220*44e33a5aSSean Rhodes : "memory", "cc"
221*44e33a5aSSean Rhodes );
222*44e33a5aSSean Rhodes } else if (gsmi_dev.handshake_type == GSMI_HANDSHAKE_SPIN) {
223*44e33a5aSSean Rhodes /*
224*44e33a5aSSean Rhodes * If handshake_type == HANDSHAKE_SPIN we spin a
225*44e33a5aSSean Rhodes * hundred-ish usecs to ensure the SMI has triggered.
226*44e33a5aSSean Rhodes */
227*44e33a5aSSean Rhodes asm volatile (
228*44e33a5aSSean Rhodes "outb %%al, %%dx\n"
229*44e33a5aSSean Rhodes "1: loop 1b\n"
230*44e33a5aSSean Rhodes : "=a" (result)
231*44e33a5aSSean Rhodes : "0" (cmd),
232*44e33a5aSSean Rhodes "d" (gsmi_dev.smi_cmd),
233*44e33a5aSSean Rhodes "b" (gsmi_dev.param_buf->address),
234*44e33a5aSSean Rhodes "c" (spincount)
235*44e33a5aSSean Rhodes : "memory", "cc"
236*44e33a5aSSean Rhodes );
237*44e33a5aSSean Rhodes } else {
238*44e33a5aSSean Rhodes /*
239*44e33a5aSSean Rhodes * If handshake_type == HANDSHAKE_NONE we do nothing;
240*44e33a5aSSean Rhodes * either we don't need to or it's legacy firmware that
241*44e33a5aSSean Rhodes * doesn't understand the CF protocol.
242*44e33a5aSSean Rhodes */
243*44e33a5aSSean Rhodes asm volatile (
244*44e33a5aSSean Rhodes "outb %%al, %%dx\n\t"
245*44e33a5aSSean Rhodes : "=a" (result)
246*44e33a5aSSean Rhodes : "0" (cmd),
247*44e33a5aSSean Rhodes "d" (gsmi_dev.smi_cmd),
248*44e33a5aSSean Rhodes "b" (gsmi_dev.param_buf->address)
249*44e33a5aSSean Rhodes : "memory", "cc"
250*44e33a5aSSean Rhodes );
251*44e33a5aSSean Rhodes }
252*44e33a5aSSean Rhodes
253*44e33a5aSSean Rhodes /* check return code from SMI handler */
254*44e33a5aSSean Rhodes switch (result) {
255*44e33a5aSSean Rhodes case GSMI_SUCCESS:
256*44e33a5aSSean Rhodes break;
257*44e33a5aSSean Rhodes case GSMI_VAR_NOT_FOUND:
258*44e33a5aSSean Rhodes /* not really an error, but let the caller know */
259*44e33a5aSSean Rhodes rc = 1;
260*44e33a5aSSean Rhodes break;
261*44e33a5aSSean Rhodes case GSMI_INVALID_PARAMETER:
262*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: exec 0x%04x: Invalid parameter\n", cmd);
263*44e33a5aSSean Rhodes rc = -EINVAL;
264*44e33a5aSSean Rhodes break;
265*44e33a5aSSean Rhodes case GSMI_BUFFER_TOO_SMALL:
266*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: exec 0x%04x: Buffer too small\n", cmd);
267*44e33a5aSSean Rhodes rc = -ENOMEM;
268*44e33a5aSSean Rhodes break;
269*44e33a5aSSean Rhodes case GSMI_UNSUPPORTED:
270*44e33a5aSSean Rhodes case GSMI_UNSUPPORTED2:
271*44e33a5aSSean Rhodes if (sub != GSMI_CMD_HANDSHAKE_TYPE)
272*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: exec 0x%04x: Not supported\n",
273*44e33a5aSSean Rhodes cmd);
274*44e33a5aSSean Rhodes rc = -ENOSYS;
275*44e33a5aSSean Rhodes break;
276*44e33a5aSSean Rhodes case GSMI_NOT_READY:
277*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: exec 0x%04x: Not ready\n", cmd);
278*44e33a5aSSean Rhodes rc = -EBUSY;
279*44e33a5aSSean Rhodes break;
280*44e33a5aSSean Rhodes case GSMI_DEVICE_ERROR:
281*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: exec 0x%04x: Device error\n", cmd);
282*44e33a5aSSean Rhodes rc = -EFAULT;
283*44e33a5aSSean Rhodes break;
284*44e33a5aSSean Rhodes case GSMI_NOT_FOUND:
285*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: exec 0x%04x: Data not found\n", cmd);
286*44e33a5aSSean Rhodes rc = -ENOENT;
287*44e33a5aSSean Rhodes break;
288*44e33a5aSSean Rhodes case GSMI_LOG_FULL:
289*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: exec 0x%04x: Log full\n", cmd);
290*44e33a5aSSean Rhodes rc = -ENOSPC;
291*44e33a5aSSean Rhodes break;
292*44e33a5aSSean Rhodes case GSMI_HANDSHAKE_CF:
293*44e33a5aSSean Rhodes case GSMI_HANDSHAKE_SPIN:
294*44e33a5aSSean Rhodes case GSMI_HANDSHAKE_NONE:
295*44e33a5aSSean Rhodes rc = result;
296*44e33a5aSSean Rhodes break;
297*44e33a5aSSean Rhodes default:
298*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: exec 0x%04x: Unknown error 0x%04x\n",
299*44e33a5aSSean Rhodes cmd, result);
300*44e33a5aSSean Rhodes rc = -ENXIO;
301*44e33a5aSSean Rhodes }
302*44e33a5aSSean Rhodes
303*44e33a5aSSean Rhodes return rc;
304*44e33a5aSSean Rhodes }
305*44e33a5aSSean Rhodes
306*44e33a5aSSean Rhodes #ifdef CONFIG_EFI
307*44e33a5aSSean Rhodes
308*44e33a5aSSean Rhodes static struct efivars efivars;
309*44e33a5aSSean Rhodes
gsmi_get_variable(efi_char16_t * name,efi_guid_t * vendor,u32 * attr,unsigned long * data_size,void * data)310*44e33a5aSSean Rhodes static efi_status_t gsmi_get_variable(efi_char16_t *name,
311*44e33a5aSSean Rhodes efi_guid_t *vendor, u32 *attr,
312*44e33a5aSSean Rhodes unsigned long *data_size,
313*44e33a5aSSean Rhodes void *data)
314*44e33a5aSSean Rhodes {
315*44e33a5aSSean Rhodes struct gsmi_nvram_var_param param = {
316*44e33a5aSSean Rhodes .name_ptr = gsmi_dev.name_buf->address,
317*44e33a5aSSean Rhodes .data_ptr = gsmi_dev.data_buf->address,
318*44e33a5aSSean Rhodes .data_len = (u32)*data_size,
319*44e33a5aSSean Rhodes };
320*44e33a5aSSean Rhodes efi_status_t ret = EFI_SUCCESS;
321*44e33a5aSSean Rhodes unsigned long flags;
322*44e33a5aSSean Rhodes size_t name_len = ucs2_strnlen(name, GSMI_BUF_SIZE / 2);
323*44e33a5aSSean Rhodes int rc;
324*44e33a5aSSean Rhodes
325*44e33a5aSSean Rhodes if (name_len >= GSMI_BUF_SIZE / 2)
326*44e33a5aSSean Rhodes return EFI_BAD_BUFFER_SIZE;
327*44e33a5aSSean Rhodes
328*44e33a5aSSean Rhodes spin_lock_irqsave(&gsmi_dev.lock, flags);
329*44e33a5aSSean Rhodes
330*44e33a5aSSean Rhodes /* Vendor guid */
331*44e33a5aSSean Rhodes memcpy(¶m.guid, vendor, sizeof(param.guid));
332*44e33a5aSSean Rhodes
333*44e33a5aSSean Rhodes /* variable name, already in UTF-16 */
334*44e33a5aSSean Rhodes memset(gsmi_dev.name_buf->start, 0, gsmi_dev.name_buf->length);
335*44e33a5aSSean Rhodes memcpy(gsmi_dev.name_buf->start, name, name_len * 2);
336*44e33a5aSSean Rhodes
337*44e33a5aSSean Rhodes /* data pointer */
338*44e33a5aSSean Rhodes memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
339*44e33a5aSSean Rhodes
340*44e33a5aSSean Rhodes /* parameter buffer */
341*44e33a5aSSean Rhodes memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
342*44e33a5aSSean Rhodes memcpy(gsmi_dev.param_buf->start, ¶m, sizeof(param));
343*44e33a5aSSean Rhodes
344*44e33a5aSSean Rhodes rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_GET_NVRAM_VAR);
345*44e33a5aSSean Rhodes if (rc < 0) {
346*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: Get Variable failed\n");
347*44e33a5aSSean Rhodes ret = EFI_LOAD_ERROR;
348*44e33a5aSSean Rhodes } else if (rc == 1) {
349*44e33a5aSSean Rhodes /* variable was not found */
350*44e33a5aSSean Rhodes ret = EFI_NOT_FOUND;
351*44e33a5aSSean Rhodes } else {
352*44e33a5aSSean Rhodes /* Get the arguments back */
353*44e33a5aSSean Rhodes memcpy(¶m, gsmi_dev.param_buf->start, sizeof(param));
354*44e33a5aSSean Rhodes
355*44e33a5aSSean Rhodes /* The size reported is the min of all of our buffers */
356*44e33a5aSSean Rhodes *data_size = min_t(unsigned long, *data_size,
357*44e33a5aSSean Rhodes gsmi_dev.data_buf->length);
358*44e33a5aSSean Rhodes *data_size = min_t(unsigned long, *data_size, param.data_len);
359*44e33a5aSSean Rhodes
360*44e33a5aSSean Rhodes /* Copy data back to return buffer. */
361*44e33a5aSSean Rhodes memcpy(data, gsmi_dev.data_buf->start, *data_size);
362*44e33a5aSSean Rhodes
363*44e33a5aSSean Rhodes /* All variables are have the following attributes */
364*44e33a5aSSean Rhodes if (attr)
365*44e33a5aSSean Rhodes *attr = EFI_VARIABLE_NON_VOLATILE |
366*44e33a5aSSean Rhodes EFI_VARIABLE_BOOTSERVICE_ACCESS |
367*44e33a5aSSean Rhodes EFI_VARIABLE_RUNTIME_ACCESS;
368*44e33a5aSSean Rhodes }
369*44e33a5aSSean Rhodes
370*44e33a5aSSean Rhodes spin_unlock_irqrestore(&gsmi_dev.lock, flags);
371*44e33a5aSSean Rhodes
372*44e33a5aSSean Rhodes return ret;
373*44e33a5aSSean Rhodes }
374*44e33a5aSSean Rhodes
gsmi_get_next_variable(unsigned long * name_size,efi_char16_t * name,efi_guid_t * vendor)375*44e33a5aSSean Rhodes static efi_status_t gsmi_get_next_variable(unsigned long *name_size,
376*44e33a5aSSean Rhodes efi_char16_t *name,
377*44e33a5aSSean Rhodes efi_guid_t *vendor)
378*44e33a5aSSean Rhodes {
379*44e33a5aSSean Rhodes struct gsmi_get_next_var_param param = {
380*44e33a5aSSean Rhodes .name_ptr = gsmi_dev.name_buf->address,
381*44e33a5aSSean Rhodes .name_len = gsmi_dev.name_buf->length,
382*44e33a5aSSean Rhodes };
383*44e33a5aSSean Rhodes efi_status_t ret = EFI_SUCCESS;
384*44e33a5aSSean Rhodes int rc;
385*44e33a5aSSean Rhodes unsigned long flags;
386*44e33a5aSSean Rhodes
387*44e33a5aSSean Rhodes /* For the moment, only support buffers that exactly match in size */
388*44e33a5aSSean Rhodes if (*name_size != GSMI_BUF_SIZE)
389*44e33a5aSSean Rhodes return EFI_BAD_BUFFER_SIZE;
390*44e33a5aSSean Rhodes
391*44e33a5aSSean Rhodes /* Let's make sure the thing is at least null-terminated */
392*44e33a5aSSean Rhodes if (ucs2_strnlen(name, GSMI_BUF_SIZE / 2) == GSMI_BUF_SIZE / 2)
393*44e33a5aSSean Rhodes return EFI_INVALID_PARAMETER;
394*44e33a5aSSean Rhodes
395*44e33a5aSSean Rhodes spin_lock_irqsave(&gsmi_dev.lock, flags);
396*44e33a5aSSean Rhodes
397*44e33a5aSSean Rhodes /* guid */
398*44e33a5aSSean Rhodes memcpy(¶m.guid, vendor, sizeof(param.guid));
399*44e33a5aSSean Rhodes
400*44e33a5aSSean Rhodes /* variable name, already in UTF-16 */
401*44e33a5aSSean Rhodes memcpy(gsmi_dev.name_buf->start, name, *name_size);
402*44e33a5aSSean Rhodes
403*44e33a5aSSean Rhodes /* parameter buffer */
404*44e33a5aSSean Rhodes memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
405*44e33a5aSSean Rhodes memcpy(gsmi_dev.param_buf->start, ¶m, sizeof(param));
406*44e33a5aSSean Rhodes
407*44e33a5aSSean Rhodes rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_GET_NEXT_VAR);
408*44e33a5aSSean Rhodes if (rc < 0) {
409*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: Get Next Variable Name failed\n");
410*44e33a5aSSean Rhodes ret = EFI_LOAD_ERROR;
411*44e33a5aSSean Rhodes } else if (rc == 1) {
412*44e33a5aSSean Rhodes /* variable not found -- end of list */
413*44e33a5aSSean Rhodes ret = EFI_NOT_FOUND;
414*44e33a5aSSean Rhodes } else {
415*44e33a5aSSean Rhodes /* copy variable data back to return buffer */
416*44e33a5aSSean Rhodes memcpy(¶m, gsmi_dev.param_buf->start, sizeof(param));
417*44e33a5aSSean Rhodes
418*44e33a5aSSean Rhodes /* Copy the name back */
419*44e33a5aSSean Rhodes memcpy(name, gsmi_dev.name_buf->start, GSMI_BUF_SIZE);
420*44e33a5aSSean Rhodes *name_size = ucs2_strnlen(name, GSMI_BUF_SIZE / 2) * 2;
421*44e33a5aSSean Rhodes
422*44e33a5aSSean Rhodes /* copy guid to return buffer */
423*44e33a5aSSean Rhodes memcpy(vendor, ¶m.guid, sizeof(param.guid));
424*44e33a5aSSean Rhodes ret = EFI_SUCCESS;
425*44e33a5aSSean Rhodes }
426*44e33a5aSSean Rhodes
427*44e33a5aSSean Rhodes spin_unlock_irqrestore(&gsmi_dev.lock, flags);
428*44e33a5aSSean Rhodes
429*44e33a5aSSean Rhodes return ret;
430*44e33a5aSSean Rhodes }
431*44e33a5aSSean Rhodes
gsmi_set_variable(efi_char16_t * name,efi_guid_t * vendor,u32 attr,unsigned long data_size,void * data)432*44e33a5aSSean Rhodes static efi_status_t gsmi_set_variable(efi_char16_t *name,
433*44e33a5aSSean Rhodes efi_guid_t *vendor,
434*44e33a5aSSean Rhodes u32 attr,
435*44e33a5aSSean Rhodes unsigned long data_size,
436*44e33a5aSSean Rhodes void *data)
437*44e33a5aSSean Rhodes {
438*44e33a5aSSean Rhodes struct gsmi_nvram_var_param param = {
439*44e33a5aSSean Rhodes .name_ptr = gsmi_dev.name_buf->address,
440*44e33a5aSSean Rhodes .data_ptr = gsmi_dev.data_buf->address,
441*44e33a5aSSean Rhodes .data_len = (u32)data_size,
442*44e33a5aSSean Rhodes .attributes = EFI_VARIABLE_NON_VOLATILE |
443*44e33a5aSSean Rhodes EFI_VARIABLE_BOOTSERVICE_ACCESS |
444*44e33a5aSSean Rhodes EFI_VARIABLE_RUNTIME_ACCESS,
445*44e33a5aSSean Rhodes };
446*44e33a5aSSean Rhodes size_t name_len = ucs2_strnlen(name, GSMI_BUF_SIZE / 2);
447*44e33a5aSSean Rhodes efi_status_t ret = EFI_SUCCESS;
448*44e33a5aSSean Rhodes int rc;
449*44e33a5aSSean Rhodes unsigned long flags;
450*44e33a5aSSean Rhodes
451*44e33a5aSSean Rhodes if (name_len >= GSMI_BUF_SIZE / 2)
452*44e33a5aSSean Rhodes return EFI_BAD_BUFFER_SIZE;
453*44e33a5aSSean Rhodes
454*44e33a5aSSean Rhodes spin_lock_irqsave(&gsmi_dev.lock, flags);
455*44e33a5aSSean Rhodes
456*44e33a5aSSean Rhodes /* guid */
457*44e33a5aSSean Rhodes memcpy(¶m.guid, vendor, sizeof(param.guid));
458*44e33a5aSSean Rhodes
459*44e33a5aSSean Rhodes /* variable name, already in UTF-16 */
460*44e33a5aSSean Rhodes memset(gsmi_dev.name_buf->start, 0, gsmi_dev.name_buf->length);
461*44e33a5aSSean Rhodes memcpy(gsmi_dev.name_buf->start, name, name_len * 2);
462*44e33a5aSSean Rhodes
463*44e33a5aSSean Rhodes /* data pointer */
464*44e33a5aSSean Rhodes memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
465*44e33a5aSSean Rhodes memcpy(gsmi_dev.data_buf->start, data, data_size);
466*44e33a5aSSean Rhodes
467*44e33a5aSSean Rhodes /* parameter buffer */
468*44e33a5aSSean Rhodes memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
469*44e33a5aSSean Rhodes memcpy(gsmi_dev.param_buf->start, ¶m, sizeof(param));
470*44e33a5aSSean Rhodes
471*44e33a5aSSean Rhodes rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_SET_NVRAM_VAR);
472*44e33a5aSSean Rhodes if (rc < 0) {
473*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: Set Variable failed\n");
474*44e33a5aSSean Rhodes ret = EFI_INVALID_PARAMETER;
475*44e33a5aSSean Rhodes }
476*44e33a5aSSean Rhodes
477*44e33a5aSSean Rhodes spin_unlock_irqrestore(&gsmi_dev.lock, flags);
478*44e33a5aSSean Rhodes
479*44e33a5aSSean Rhodes return ret;
480*44e33a5aSSean Rhodes }
481*44e33a5aSSean Rhodes
482*44e33a5aSSean Rhodes static const struct efivar_operations efivar_ops = {
483*44e33a5aSSean Rhodes .get_variable = gsmi_get_variable,
484*44e33a5aSSean Rhodes .set_variable = gsmi_set_variable,
485*44e33a5aSSean Rhodes .get_next_variable = gsmi_get_next_variable,
486*44e33a5aSSean Rhodes };
487*44e33a5aSSean Rhodes
488*44e33a5aSSean Rhodes #endif /* CONFIG_EFI */
489*44e33a5aSSean Rhodes
eventlog_write(struct file * filp,struct kobject * kobj,const struct bin_attribute * bin_attr,char * buf,loff_t pos,size_t count)490*44e33a5aSSean Rhodes static ssize_t eventlog_write(struct file *filp, struct kobject *kobj,
491*44e33a5aSSean Rhodes const struct bin_attribute *bin_attr,
492*44e33a5aSSean Rhodes char *buf, loff_t pos, size_t count)
493*44e33a5aSSean Rhodes {
494*44e33a5aSSean Rhodes struct gsmi_set_eventlog_param param = {
495*44e33a5aSSean Rhodes .data_ptr = gsmi_dev.data_buf->address,
496*44e33a5aSSean Rhodes };
497*44e33a5aSSean Rhodes int rc = 0;
498*44e33a5aSSean Rhodes unsigned long flags;
499*44e33a5aSSean Rhodes
500*44e33a5aSSean Rhodes /* Pull the type out */
501*44e33a5aSSean Rhodes if (count < sizeof(u32))
502*44e33a5aSSean Rhodes return -EINVAL;
503*44e33a5aSSean Rhodes param.type = *(u32 *)buf;
504*44e33a5aSSean Rhodes buf += sizeof(u32);
505*44e33a5aSSean Rhodes
506*44e33a5aSSean Rhodes /* The remaining buffer is the data payload */
507*44e33a5aSSean Rhodes if ((count - sizeof(u32)) > gsmi_dev.data_buf->length)
508*44e33a5aSSean Rhodes return -EINVAL;
509*44e33a5aSSean Rhodes param.data_len = count - sizeof(u32);
510*44e33a5aSSean Rhodes
511*44e33a5aSSean Rhodes spin_lock_irqsave(&gsmi_dev.lock, flags);
512*44e33a5aSSean Rhodes
513*44e33a5aSSean Rhodes /* data pointer */
514*44e33a5aSSean Rhodes memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
515*44e33a5aSSean Rhodes memcpy(gsmi_dev.data_buf->start, buf, param.data_len);
516*44e33a5aSSean Rhodes
517*44e33a5aSSean Rhodes /* parameter buffer */
518*44e33a5aSSean Rhodes memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
519*44e33a5aSSean Rhodes memcpy(gsmi_dev.param_buf->start, ¶m, sizeof(param));
520*44e33a5aSSean Rhodes
521*44e33a5aSSean Rhodes rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_SET_EVENT_LOG);
522*44e33a5aSSean Rhodes if (rc < 0)
523*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: Set Event Log failed\n");
524*44e33a5aSSean Rhodes
525*44e33a5aSSean Rhodes spin_unlock_irqrestore(&gsmi_dev.lock, flags);
526*44e33a5aSSean Rhodes
527*44e33a5aSSean Rhodes return (rc == 0) ? count : rc;
528*44e33a5aSSean Rhodes
529*44e33a5aSSean Rhodes }
530*44e33a5aSSean Rhodes
531*44e33a5aSSean Rhodes static const struct bin_attribute eventlog_bin_attr = {
532*44e33a5aSSean Rhodes .attr = {.name = "append_to_eventlog", .mode = 0200},
533*44e33a5aSSean Rhodes .write = eventlog_write,
534*44e33a5aSSean Rhodes };
535*44e33a5aSSean Rhodes
gsmi_clear_eventlog_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)536*44e33a5aSSean Rhodes static ssize_t gsmi_clear_eventlog_store(struct kobject *kobj,
537*44e33a5aSSean Rhodes struct kobj_attribute *attr,
538*44e33a5aSSean Rhodes const char *buf, size_t count)
539*44e33a5aSSean Rhodes {
540*44e33a5aSSean Rhodes int rc;
541*44e33a5aSSean Rhodes unsigned long flags;
542*44e33a5aSSean Rhodes unsigned long val;
543*44e33a5aSSean Rhodes struct {
544*44e33a5aSSean Rhodes u32 percentage;
545*44e33a5aSSean Rhodes u32 data_type;
546*44e33a5aSSean Rhodes } param;
547*44e33a5aSSean Rhodes
548*44e33a5aSSean Rhodes rc = kstrtoul(buf, 0, &val);
549*44e33a5aSSean Rhodes if (rc)
550*44e33a5aSSean Rhodes return rc;
551*44e33a5aSSean Rhodes
552*44e33a5aSSean Rhodes /*
553*44e33a5aSSean Rhodes * Value entered is a percentage, 0 through 100, anything else
554*44e33a5aSSean Rhodes * is invalid.
555*44e33a5aSSean Rhodes */
556*44e33a5aSSean Rhodes if (val > 100)
557*44e33a5aSSean Rhodes return -EINVAL;
558*44e33a5aSSean Rhodes
559*44e33a5aSSean Rhodes /* data_type here selects the smbios event log. */
560*44e33a5aSSean Rhodes param.percentage = val;
561*44e33a5aSSean Rhodes param.data_type = 0;
562*44e33a5aSSean Rhodes
563*44e33a5aSSean Rhodes spin_lock_irqsave(&gsmi_dev.lock, flags);
564*44e33a5aSSean Rhodes
565*44e33a5aSSean Rhodes /* parameter buffer */
566*44e33a5aSSean Rhodes memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
567*44e33a5aSSean Rhodes memcpy(gsmi_dev.param_buf->start, ¶m, sizeof(param));
568*44e33a5aSSean Rhodes
569*44e33a5aSSean Rhodes rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_CLEAR_EVENT_LOG);
570*44e33a5aSSean Rhodes
571*44e33a5aSSean Rhodes spin_unlock_irqrestore(&gsmi_dev.lock, flags);
572*44e33a5aSSean Rhodes
573*44e33a5aSSean Rhodes if (rc)
574*44e33a5aSSean Rhodes return rc;
575*44e33a5aSSean Rhodes return count;
576*44e33a5aSSean Rhodes }
577*44e33a5aSSean Rhodes
578*44e33a5aSSean Rhodes static struct kobj_attribute gsmi_clear_eventlog_attr = {
579*44e33a5aSSean Rhodes .attr = {.name = "clear_eventlog", .mode = 0200},
580*44e33a5aSSean Rhodes .store = gsmi_clear_eventlog_store,
581*44e33a5aSSean Rhodes };
582*44e33a5aSSean Rhodes
gsmi_clear_config_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)583*44e33a5aSSean Rhodes static ssize_t gsmi_clear_config_store(struct kobject *kobj,
584*44e33a5aSSean Rhodes struct kobj_attribute *attr,
585*44e33a5aSSean Rhodes const char *buf, size_t count)
586*44e33a5aSSean Rhodes {
587*44e33a5aSSean Rhodes int rc;
588*44e33a5aSSean Rhodes unsigned long flags;
589*44e33a5aSSean Rhodes
590*44e33a5aSSean Rhodes spin_lock_irqsave(&gsmi_dev.lock, flags);
591*44e33a5aSSean Rhodes
592*44e33a5aSSean Rhodes /* clear parameter buffer */
593*44e33a5aSSean Rhodes memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
594*44e33a5aSSean Rhodes
595*44e33a5aSSean Rhodes rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_CLEAR_CONFIG);
596*44e33a5aSSean Rhodes
597*44e33a5aSSean Rhodes spin_unlock_irqrestore(&gsmi_dev.lock, flags);
598*44e33a5aSSean Rhodes
599*44e33a5aSSean Rhodes if (rc)
600*44e33a5aSSean Rhodes return rc;
601*44e33a5aSSean Rhodes return count;
602*44e33a5aSSean Rhodes }
603*44e33a5aSSean Rhodes
604*44e33a5aSSean Rhodes static struct kobj_attribute gsmi_clear_config_attr = {
605*44e33a5aSSean Rhodes .attr = {.name = "clear_config", .mode = 0200},
606*44e33a5aSSean Rhodes .store = gsmi_clear_config_store,
607*44e33a5aSSean Rhodes };
608*44e33a5aSSean Rhodes
609*44e33a5aSSean Rhodes static const struct attribute *gsmi_attrs[] = {
610*44e33a5aSSean Rhodes &gsmi_clear_config_attr.attr,
611*44e33a5aSSean Rhodes &gsmi_clear_eventlog_attr.attr,
612*44e33a5aSSean Rhodes NULL,
613*44e33a5aSSean Rhodes };
614*44e33a5aSSean Rhodes
gsmi_shutdown_reason(int reason)615*44e33a5aSSean Rhodes static int gsmi_shutdown_reason(int reason)
616*44e33a5aSSean Rhodes {
617*44e33a5aSSean Rhodes struct gsmi_log_entry_type_1 entry = {
618*44e33a5aSSean Rhodes .type = GSMI_LOG_ENTRY_TYPE_KERNEL,
619*44e33a5aSSean Rhodes .instance = reason,
620*44e33a5aSSean Rhodes };
621*44e33a5aSSean Rhodes struct gsmi_set_eventlog_param param = {
622*44e33a5aSSean Rhodes .data_len = sizeof(entry),
623*44e33a5aSSean Rhodes .type = 1,
624*44e33a5aSSean Rhodes };
625*44e33a5aSSean Rhodes static int saved_reason;
626*44e33a5aSSean Rhodes int rc = 0;
627*44e33a5aSSean Rhodes unsigned long flags;
628*44e33a5aSSean Rhodes
629*44e33a5aSSean Rhodes /* avoid duplicate entries in the log */
630*44e33a5aSSean Rhodes if (saved_reason & (1 << reason))
631*44e33a5aSSean Rhodes return 0;
632*44e33a5aSSean Rhodes
633*44e33a5aSSean Rhodes spin_lock_irqsave(&gsmi_dev.lock, flags);
634*44e33a5aSSean Rhodes
635*44e33a5aSSean Rhodes saved_reason |= (1 << reason);
636*44e33a5aSSean Rhodes
637*44e33a5aSSean Rhodes /* data pointer */
638*44e33a5aSSean Rhodes memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
639*44e33a5aSSean Rhodes memcpy(gsmi_dev.data_buf->start, &entry, sizeof(entry));
640*44e33a5aSSean Rhodes
641*44e33a5aSSean Rhodes /* parameter buffer */
642*44e33a5aSSean Rhodes param.data_ptr = gsmi_dev.data_buf->address;
643*44e33a5aSSean Rhodes memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
644*44e33a5aSSean Rhodes memcpy(gsmi_dev.param_buf->start, ¶m, sizeof(param));
645*44e33a5aSSean Rhodes
646*44e33a5aSSean Rhodes rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_SET_EVENT_LOG);
647*44e33a5aSSean Rhodes
648*44e33a5aSSean Rhodes spin_unlock_irqrestore(&gsmi_dev.lock, flags);
649*44e33a5aSSean Rhodes
650*44e33a5aSSean Rhodes if (rc < 0)
651*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: Log Shutdown Reason failed\n");
652*44e33a5aSSean Rhodes else
653*44e33a5aSSean Rhodes printk(KERN_EMERG "gsmi: Log Shutdown Reason 0x%02x\n",
654*44e33a5aSSean Rhodes reason);
655*44e33a5aSSean Rhodes
656*44e33a5aSSean Rhodes return rc;
657*44e33a5aSSean Rhodes }
658*44e33a5aSSean Rhodes
gsmi_reboot_callback(struct notifier_block * nb,unsigned long reason,void * arg)659*44e33a5aSSean Rhodes static int gsmi_reboot_callback(struct notifier_block *nb,
660*44e33a5aSSean Rhodes unsigned long reason, void *arg)
661*44e33a5aSSean Rhodes {
662*44e33a5aSSean Rhodes gsmi_shutdown_reason(GSMI_SHUTDOWN_CLEAN);
663*44e33a5aSSean Rhodes return NOTIFY_DONE;
664*44e33a5aSSean Rhodes }
665*44e33a5aSSean Rhodes
666*44e33a5aSSean Rhodes static struct notifier_block gsmi_reboot_notifier = {
667*44e33a5aSSean Rhodes .notifier_call = gsmi_reboot_callback
668*44e33a5aSSean Rhodes };
669*44e33a5aSSean Rhodes
gsmi_die_callback(struct notifier_block * nb,unsigned long reason,void * arg)670*44e33a5aSSean Rhodes static int gsmi_die_callback(struct notifier_block *nb,
671*44e33a5aSSean Rhodes unsigned long reason, void *arg)
672*44e33a5aSSean Rhodes {
673*44e33a5aSSean Rhodes if (reason == DIE_OOPS)
674*44e33a5aSSean Rhodes gsmi_shutdown_reason(GSMI_SHUTDOWN_OOPS);
675*44e33a5aSSean Rhodes return NOTIFY_DONE;
676*44e33a5aSSean Rhodes }
677*44e33a5aSSean Rhodes
678*44e33a5aSSean Rhodes static struct notifier_block gsmi_die_notifier = {
679*44e33a5aSSean Rhodes .notifier_call = gsmi_die_callback
680*44e33a5aSSean Rhodes };
681*44e33a5aSSean Rhodes
gsmi_panic_callback(struct notifier_block * nb,unsigned long reason,void * arg)682*44e33a5aSSean Rhodes static int gsmi_panic_callback(struct notifier_block *nb,
683*44e33a5aSSean Rhodes unsigned long reason, void *arg)
684*44e33a5aSSean Rhodes {
685*44e33a5aSSean Rhodes
686*44e33a5aSSean Rhodes /*
687*44e33a5aSSean Rhodes * Panic callbacks are executed with all other CPUs stopped,
688*44e33a5aSSean Rhodes * so we must not attempt to spin waiting for gsmi_dev.lock
689*44e33a5aSSean Rhodes * to be released.
690*44e33a5aSSean Rhodes */
691*44e33a5aSSean Rhodes if (spin_is_locked(&gsmi_dev.lock))
692*44e33a5aSSean Rhodes return NOTIFY_DONE;
693*44e33a5aSSean Rhodes
694*44e33a5aSSean Rhodes gsmi_shutdown_reason(GSMI_SHUTDOWN_PANIC);
695*44e33a5aSSean Rhodes return NOTIFY_DONE;
696*44e33a5aSSean Rhodes }
697*44e33a5aSSean Rhodes
698*44e33a5aSSean Rhodes static struct notifier_block gsmi_panic_notifier = {
699*44e33a5aSSean Rhodes .notifier_call = gsmi_panic_callback,
700*44e33a5aSSean Rhodes };
701*44e33a5aSSean Rhodes
702*44e33a5aSSean Rhodes /*
703*44e33a5aSSean Rhodes * This hash function was blatantly copied from include/linux/hash.h.
704*44e33a5aSSean Rhodes * It is used by this driver to obfuscate a board name that requires a
705*44e33a5aSSean Rhodes * quirk within this driver.
706*44e33a5aSSean Rhodes *
707*44e33a5aSSean Rhodes * Please do not remove this copy of the function as any changes to the
708*44e33a5aSSean Rhodes * global utility hash_64() function would break this driver's ability
709*44e33a5aSSean Rhodes * to identify a board and provide the appropriate quirk -- mikew@google.com
710*44e33a5aSSean Rhodes */
local_hash_64(u64 val,unsigned bits)711*44e33a5aSSean Rhodes static u64 __init local_hash_64(u64 val, unsigned bits)
712*44e33a5aSSean Rhodes {
713*44e33a5aSSean Rhodes u64 hash = val;
714*44e33a5aSSean Rhodes
715*44e33a5aSSean Rhodes /* Sigh, gcc can't optimise this alone like it does for 32 bits. */
716*44e33a5aSSean Rhodes u64 n = hash;
717*44e33a5aSSean Rhodes n <<= 18;
718*44e33a5aSSean Rhodes hash -= n;
719*44e33a5aSSean Rhodes n <<= 33;
720*44e33a5aSSean Rhodes hash -= n;
721*44e33a5aSSean Rhodes n <<= 3;
722*44e33a5aSSean Rhodes hash += n;
723*44e33a5aSSean Rhodes n <<= 3;
724*44e33a5aSSean Rhodes hash -= n;
725*44e33a5aSSean Rhodes n <<= 4;
726*44e33a5aSSean Rhodes hash += n;
727*44e33a5aSSean Rhodes n <<= 2;
728*44e33a5aSSean Rhodes hash += n;
729*44e33a5aSSean Rhodes
730*44e33a5aSSean Rhodes /* High bits are more random, so use them. */
731*44e33a5aSSean Rhodes return hash >> (64 - bits);
732*44e33a5aSSean Rhodes }
733*44e33a5aSSean Rhodes
hash_oem_table_id(char s[8])734*44e33a5aSSean Rhodes static u32 __init hash_oem_table_id(char s[8])
735*44e33a5aSSean Rhodes {
736*44e33a5aSSean Rhodes u64 input;
737*44e33a5aSSean Rhodes memcpy(&input, s, 8);
738*44e33a5aSSean Rhodes return local_hash_64(input, 32);
739*44e33a5aSSean Rhodes }
740*44e33a5aSSean Rhodes
741*44e33a5aSSean Rhodes static const struct dmi_system_id gsmi_dmi_table[] __initconst = {
742*44e33a5aSSean Rhodes {
743*44e33a5aSSean Rhodes .ident = "Google Board",
744*44e33a5aSSean Rhodes .matches = {
745*44e33a5aSSean Rhodes DMI_MATCH(DMI_BOARD_VENDOR, "Google, Inc."),
746*44e33a5aSSean Rhodes },
747*44e33a5aSSean Rhodes },
748*44e33a5aSSean Rhodes {
749*44e33a5aSSean Rhodes .ident = "Coreboot Firmware",
750*44e33a5aSSean Rhodes .matches = {
751*44e33a5aSSean Rhodes DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"),
752*44e33a5aSSean Rhodes },
753*44e33a5aSSean Rhodes },
754*44e33a5aSSean Rhodes {}
755*44e33a5aSSean Rhodes };
756*44e33a5aSSean Rhodes MODULE_DEVICE_TABLE(dmi, gsmi_dmi_table);
757*44e33a5aSSean Rhodes
gsmi_system_valid(void)758*44e33a5aSSean Rhodes static __init int gsmi_system_valid(void)
759*44e33a5aSSean Rhodes {
760*44e33a5aSSean Rhodes u32 hash;
761*44e33a5aSSean Rhodes u16 cmd, result;
762*44e33a5aSSean Rhodes
763*44e33a5aSSean Rhodes if (!dmi_check_system(gsmi_dmi_table))
764*44e33a5aSSean Rhodes return -ENODEV;
765*44e33a5aSSean Rhodes
766*44e33a5aSSean Rhodes /*
767*44e33a5aSSean Rhodes * Only newer firmware supports the gsmi interface. All older
768*44e33a5aSSean Rhodes * firmware that didn't support this interface used to plug the
769*44e33a5aSSean Rhodes * table name in the first four bytes of the oem_table_id field.
770*44e33a5aSSean Rhodes * Newer firmware doesn't do that though, so use that as the
771*44e33a5aSSean Rhodes * discriminant factor. We have to do this in order to
772*44e33a5aSSean Rhodes * whitewash our board names out of the public driver.
773*44e33a5aSSean Rhodes */
774*44e33a5aSSean Rhodes if (!strncmp(acpi_gbl_FADT.header.oem_table_id, "FACP", 4)) {
775*44e33a5aSSean Rhodes printk(KERN_INFO "gsmi: Board is too old\n");
776*44e33a5aSSean Rhodes return -ENODEV;
777*44e33a5aSSean Rhodes }
778*44e33a5aSSean Rhodes
779*44e33a5aSSean Rhodes /* Disable on board with 1.0 BIOS due to Google bug 2602657 */
780*44e33a5aSSean Rhodes hash = hash_oem_table_id(acpi_gbl_FADT.header.oem_table_id);
781*44e33a5aSSean Rhodes if (hash == QUIRKY_BOARD_HASH) {
782*44e33a5aSSean Rhodes const char *bios_ver = dmi_get_system_info(DMI_BIOS_VERSION);
783*44e33a5aSSean Rhodes if (strncmp(bios_ver, "1.0", 3) == 0) {
784*44e33a5aSSean Rhodes pr_info("gsmi: disabled on this board's BIOS %s\n",
785*44e33a5aSSean Rhodes bios_ver);
786*44e33a5aSSean Rhodes return -ENODEV;
787*44e33a5aSSean Rhodes }
788*44e33a5aSSean Rhodes }
789*44e33a5aSSean Rhodes
790*44e33a5aSSean Rhodes /* check for valid SMI command port in ACPI FADT */
791*44e33a5aSSean Rhodes if (acpi_gbl_FADT.smi_command == 0) {
792*44e33a5aSSean Rhodes pr_info("gsmi: missing smi_command\n");
793*44e33a5aSSean Rhodes return -ENODEV;
794*44e33a5aSSean Rhodes }
795*44e33a5aSSean Rhodes
796*44e33a5aSSean Rhodes /* Test the smihandler with a bogus command. If it leaves the
797*44e33a5aSSean Rhodes * calling argument in %ax untouched, there is no handler for
798*44e33a5aSSean Rhodes * GSMI commands.
799*44e33a5aSSean Rhodes */
800*44e33a5aSSean Rhodes cmd = GSMI_CALLBACK | GSMI_CMD_RESERVED << 8;
801*44e33a5aSSean Rhodes asm volatile (
802*44e33a5aSSean Rhodes "outb %%al, %%dx\n\t"
803*44e33a5aSSean Rhodes : "=a" (result)
804*44e33a5aSSean Rhodes : "0" (cmd),
805*44e33a5aSSean Rhodes "d" (acpi_gbl_FADT.smi_command)
806*44e33a5aSSean Rhodes : "memory", "cc"
807*44e33a5aSSean Rhodes );
808*44e33a5aSSean Rhodes if (cmd == result) {
809*44e33a5aSSean Rhodes pr_info("gsmi: no gsmi handler in firmware\n");
810*44e33a5aSSean Rhodes return -ENODEV;
811*44e33a5aSSean Rhodes }
812*44e33a5aSSean Rhodes
813*44e33a5aSSean Rhodes /* Found */
814*44e33a5aSSean Rhodes return 0;
815*44e33a5aSSean Rhodes }
816*44e33a5aSSean Rhodes
817*44e33a5aSSean Rhodes static struct kobject *gsmi_kobj;
818*44e33a5aSSean Rhodes
819*44e33a5aSSean Rhodes static const struct platform_device_info gsmi_dev_info = {
820*44e33a5aSSean Rhodes .name = "gsmi",
821*44e33a5aSSean Rhodes .id = -1,
822*44e33a5aSSean Rhodes /* SMI callbacks require 32bit addresses */
823*44e33a5aSSean Rhodes .dma_mask = DMA_BIT_MASK(32),
824*44e33a5aSSean Rhodes };
825*44e33a5aSSean Rhodes
826*44e33a5aSSean Rhodes #ifdef CONFIG_PM
gsmi_log_s0ix_info(u8 cmd)827*44e33a5aSSean Rhodes static void gsmi_log_s0ix_info(u8 cmd)
828*44e33a5aSSean Rhodes {
829*44e33a5aSSean Rhodes unsigned long flags;
830*44e33a5aSSean Rhodes
831*44e33a5aSSean Rhodes /*
832*44e33a5aSSean Rhodes * If platform has not enabled S0ix logging, then no action is
833*44e33a5aSSean Rhodes * necessary.
834*44e33a5aSSean Rhodes */
835*44e33a5aSSean Rhodes if (!s0ix_logging_enable)
836*44e33a5aSSean Rhodes return;
837*44e33a5aSSean Rhodes
838*44e33a5aSSean Rhodes spin_lock_irqsave(&gsmi_dev.lock, flags);
839*44e33a5aSSean Rhodes
840*44e33a5aSSean Rhodes memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
841*44e33a5aSSean Rhodes
842*44e33a5aSSean Rhodes gsmi_exec(GSMI_CALLBACK, cmd);
843*44e33a5aSSean Rhodes
844*44e33a5aSSean Rhodes spin_unlock_irqrestore(&gsmi_dev.lock, flags);
845*44e33a5aSSean Rhodes }
846*44e33a5aSSean Rhodes
gsmi_log_s0ix_suspend(struct device * dev)847*44e33a5aSSean Rhodes static int gsmi_log_s0ix_suspend(struct device *dev)
848*44e33a5aSSean Rhodes {
849*44e33a5aSSean Rhodes /*
850*44e33a5aSSean Rhodes * If system is not suspending via firmware using the standard ACPI Sx
851*44e33a5aSSean Rhodes * types, then make a GSMI call to log the suspend info.
852*44e33a5aSSean Rhodes */
853*44e33a5aSSean Rhodes if (!pm_suspend_via_firmware())
854*44e33a5aSSean Rhodes gsmi_log_s0ix_info(GSMI_CMD_LOG_S0IX_SUSPEND);
855*44e33a5aSSean Rhodes
856*44e33a5aSSean Rhodes /*
857*44e33a5aSSean Rhodes * Always return success, since we do not want suspend
858*44e33a5aSSean Rhodes * to fail just because of logging failure.
859*44e33a5aSSean Rhodes */
860*44e33a5aSSean Rhodes return 0;
861*44e33a5aSSean Rhodes }
862*44e33a5aSSean Rhodes
gsmi_log_s0ix_resume(struct device * dev)863*44e33a5aSSean Rhodes static int gsmi_log_s0ix_resume(struct device *dev)
864*44e33a5aSSean Rhodes {
865*44e33a5aSSean Rhodes /*
866*44e33a5aSSean Rhodes * If system did not resume via firmware, then make a GSMI call to log
867*44e33a5aSSean Rhodes * the resume info and wake source.
868*44e33a5aSSean Rhodes */
869*44e33a5aSSean Rhodes if (!pm_resume_via_firmware())
870*44e33a5aSSean Rhodes gsmi_log_s0ix_info(GSMI_CMD_LOG_S0IX_RESUME);
871*44e33a5aSSean Rhodes
872*44e33a5aSSean Rhodes /*
873*44e33a5aSSean Rhodes * Always return success, since we do not want resume
874*44e33a5aSSean Rhodes * to fail just because of logging failure.
875*44e33a5aSSean Rhodes */
876*44e33a5aSSean Rhodes return 0;
877*44e33a5aSSean Rhodes }
878*44e33a5aSSean Rhodes
879*44e33a5aSSean Rhodes static const struct dev_pm_ops gsmi_pm_ops = {
880*44e33a5aSSean Rhodes .suspend_noirq = gsmi_log_s0ix_suspend,
881*44e33a5aSSean Rhodes .resume_noirq = gsmi_log_s0ix_resume,
882*44e33a5aSSean Rhodes };
883*44e33a5aSSean Rhodes
gsmi_platform_driver_probe(struct platform_device * dev)884*44e33a5aSSean Rhodes static int gsmi_platform_driver_probe(struct platform_device *dev)
885*44e33a5aSSean Rhodes {
886*44e33a5aSSean Rhodes return 0;
887*44e33a5aSSean Rhodes }
888*44e33a5aSSean Rhodes
889*44e33a5aSSean Rhodes static struct platform_driver gsmi_driver_info = {
890*44e33a5aSSean Rhodes .driver = {
891*44e33a5aSSean Rhodes .name = "gsmi",
892*44e33a5aSSean Rhodes .pm = &gsmi_pm_ops,
893*44e33a5aSSean Rhodes },
894*44e33a5aSSean Rhodes .probe = gsmi_platform_driver_probe,
895*44e33a5aSSean Rhodes };
896*44e33a5aSSean Rhodes #endif
897*44e33a5aSSean Rhodes
gsmi_init(void)898*44e33a5aSSean Rhodes static __init int gsmi_init(void)
899*44e33a5aSSean Rhodes {
900*44e33a5aSSean Rhodes unsigned long flags;
901*44e33a5aSSean Rhodes int ret;
902*44e33a5aSSean Rhodes
903*44e33a5aSSean Rhodes ret = gsmi_system_valid();
904*44e33a5aSSean Rhodes if (ret)
905*44e33a5aSSean Rhodes return ret;
906*44e33a5aSSean Rhodes
907*44e33a5aSSean Rhodes gsmi_dev.smi_cmd = acpi_gbl_FADT.smi_command;
908*44e33a5aSSean Rhodes
909*44e33a5aSSean Rhodes #ifdef CONFIG_PM
910*44e33a5aSSean Rhodes ret = platform_driver_register(&gsmi_driver_info);
911*44e33a5aSSean Rhodes if (unlikely(ret)) {
912*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: unable to register platform driver\n");
913*44e33a5aSSean Rhodes return ret;
914*44e33a5aSSean Rhodes }
915*44e33a5aSSean Rhodes #endif
916*44e33a5aSSean Rhodes
917*44e33a5aSSean Rhodes /* register device */
918*44e33a5aSSean Rhodes gsmi_dev.pdev = platform_device_register_full(&gsmi_dev_info);
919*44e33a5aSSean Rhodes if (IS_ERR(gsmi_dev.pdev)) {
920*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: unable to register platform device\n");
921*44e33a5aSSean Rhodes ret = PTR_ERR(gsmi_dev.pdev);
922*44e33a5aSSean Rhodes goto out_unregister;
923*44e33a5aSSean Rhodes }
924*44e33a5aSSean Rhodes
925*44e33a5aSSean Rhodes /* SMI access needs to be serialized */
926*44e33a5aSSean Rhodes spin_lock_init(&gsmi_dev.lock);
927*44e33a5aSSean Rhodes
928*44e33a5aSSean Rhodes ret = -ENOMEM;
929*44e33a5aSSean Rhodes
930*44e33a5aSSean Rhodes /*
931*44e33a5aSSean Rhodes * SLAB cache is created using SLAB_CACHE_DMA32 to ensure that the
932*44e33a5aSSean Rhodes * allocations for gsmi_buf come from the DMA32 memory zone. These
933*44e33a5aSSean Rhodes * buffers have nothing to do with DMA. They are required for
934*44e33a5aSSean Rhodes * communication with firmware executing in SMI mode which can only
935*44e33a5aSSean Rhodes * access the bottom 4GiB of physical memory. Since DMA32 memory zone
936*44e33a5aSSean Rhodes * guarantees allocation under the 4GiB boundary, this driver creates
937*44e33a5aSSean Rhodes * a SLAB cache with SLAB_CACHE_DMA32 flag.
938*44e33a5aSSean Rhodes */
939*44e33a5aSSean Rhodes gsmi_dev.mem_pool = kmem_cache_create("gsmi", GSMI_BUF_SIZE,
940*44e33a5aSSean Rhodes GSMI_BUF_ALIGN,
941*44e33a5aSSean Rhodes SLAB_CACHE_DMA32, NULL);
942*44e33a5aSSean Rhodes if (!gsmi_dev.mem_pool)
943*44e33a5aSSean Rhodes goto out_err;
944*44e33a5aSSean Rhodes
945*44e33a5aSSean Rhodes /*
946*44e33a5aSSean Rhodes * pre-allocate buffers because sometimes we are called when
947*44e33a5aSSean Rhodes * this is not feasible: oops, panic, die, mce, etc
948*44e33a5aSSean Rhodes */
949*44e33a5aSSean Rhodes gsmi_dev.name_buf = gsmi_buf_alloc();
950*44e33a5aSSean Rhodes if (!gsmi_dev.name_buf) {
951*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: failed to allocate name buffer\n");
952*44e33a5aSSean Rhodes goto out_err;
953*44e33a5aSSean Rhodes }
954*44e33a5aSSean Rhodes
955*44e33a5aSSean Rhodes gsmi_dev.data_buf = gsmi_buf_alloc();
956*44e33a5aSSean Rhodes if (!gsmi_dev.data_buf) {
957*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: failed to allocate data buffer\n");
958*44e33a5aSSean Rhodes goto out_err;
959*44e33a5aSSean Rhodes }
960*44e33a5aSSean Rhodes
961*44e33a5aSSean Rhodes gsmi_dev.param_buf = gsmi_buf_alloc();
962*44e33a5aSSean Rhodes if (!gsmi_dev.param_buf) {
963*44e33a5aSSean Rhodes printk(KERN_ERR "gsmi: failed to allocate param buffer\n");
964*44e33a5aSSean Rhodes goto out_err;
965*44e33a5aSSean Rhodes }
966*44e33a5aSSean Rhodes
967*44e33a5aSSean Rhodes /*
968*44e33a5aSSean Rhodes * Determine type of handshake used to serialize the SMI
969*44e33a5aSSean Rhodes * entry. See also gsmi_exec().
970*44e33a5aSSean Rhodes *
971*44e33a5aSSean Rhodes * There's a "behavior" present on some chipsets where writing the
972*44e33a5aSSean Rhodes * SMI trigger register in the southbridge doesn't result in an
973*44e33a5aSSean Rhodes * immediate SMI. Rather, the processor can execute "a few" more
974*44e33a5aSSean Rhodes * instructions before the SMI takes effect. To ensure synchronous
975*44e33a5aSSean Rhodes * behavior, implement a handshake between the kernel driver and the
976*44e33a5aSSean Rhodes * firmware handler to spin until released. This ioctl determines
977*44e33a5aSSean Rhodes * the type of handshake.
978*44e33a5aSSean Rhodes *
979*44e33a5aSSean Rhodes * NONE: The firmware handler does not implement any
980*44e33a5aSSean Rhodes * handshake. Either it doesn't need to, or it's legacy firmware
981*44e33a5aSSean Rhodes * that doesn't know it needs to and never will.
982*44e33a5aSSean Rhodes *
983*44e33a5aSSean Rhodes * CF: The firmware handler will clear the CF in the saved
984*44e33a5aSSean Rhodes * state before returning. The driver may set the CF and test for
985*44e33a5aSSean Rhodes * it to clear before proceeding.
986*44e33a5aSSean Rhodes *
987*44e33a5aSSean Rhodes * SPIN: The firmware handler does not implement any handshake
988*44e33a5aSSean Rhodes * but the driver should spin for a hundred or so microseconds
989*44e33a5aSSean Rhodes * to ensure the SMI has triggered.
990*44e33a5aSSean Rhodes *
991*44e33a5aSSean Rhodes * Finally, the handler will return -ENOSYS if
992*44e33a5aSSean Rhodes * GSMI_CMD_HANDSHAKE_TYPE is unimplemented, which implies
993*44e33a5aSSean Rhodes * HANDSHAKE_NONE.
994*44e33a5aSSean Rhodes */
995*44e33a5aSSean Rhodes spin_lock_irqsave(&gsmi_dev.lock, flags);
996*44e33a5aSSean Rhodes gsmi_dev.handshake_type = GSMI_HANDSHAKE_SPIN;
997*44e33a5aSSean Rhodes gsmi_dev.handshake_type =
998*44e33a5aSSean Rhodes gsmi_exec(GSMI_CALLBACK, GSMI_CMD_HANDSHAKE_TYPE);
999*44e33a5aSSean Rhodes if (gsmi_dev.handshake_type == -ENOSYS)
1000*44e33a5aSSean Rhodes gsmi_dev.handshake_type = GSMI_HANDSHAKE_NONE;
1001*44e33a5aSSean Rhodes spin_unlock_irqrestore(&gsmi_dev.lock, flags);
1002*44e33a5aSSean Rhodes
1003*44e33a5aSSean Rhodes /* Remove and clean up gsmi if the handshake could not complete. */
1004*44e33a5aSSean Rhodes if (gsmi_dev.handshake_type == -ENXIO) {
1005*44e33a5aSSean Rhodes printk(KERN_INFO "gsmi version " DRIVER_VERSION
1006*44e33a5aSSean Rhodes " failed to load\n");
1007*44e33a5aSSean Rhodes ret = -ENODEV;
1008*44e33a5aSSean Rhodes goto out_err;
1009*44e33a5aSSean Rhodes }
1010*44e33a5aSSean Rhodes
1011*44e33a5aSSean Rhodes /* Register in the firmware directory */
1012*44e33a5aSSean Rhodes ret = -ENOMEM;
1013*44e33a5aSSean Rhodes gsmi_kobj = kobject_create_and_add("gsmi", firmware_kobj);
1014*44e33a5aSSean Rhodes if (!gsmi_kobj) {
1015*44e33a5aSSean Rhodes printk(KERN_INFO "gsmi: Failed to create firmware kobj\n");
1016*44e33a5aSSean Rhodes goto out_err;
1017*44e33a5aSSean Rhodes }
1018*44e33a5aSSean Rhodes
1019*44e33a5aSSean Rhodes /* Setup eventlog access */
1020*44e33a5aSSean Rhodes ret = sysfs_create_bin_file(gsmi_kobj, &eventlog_bin_attr);
1021*44e33a5aSSean Rhodes if (ret) {
1022*44e33a5aSSean Rhodes printk(KERN_INFO "gsmi: Failed to setup eventlog");
1023*44e33a5aSSean Rhodes goto out_err;
1024*44e33a5aSSean Rhodes }
1025*44e33a5aSSean Rhodes
1026*44e33a5aSSean Rhodes /* Other attributes */
1027*44e33a5aSSean Rhodes ret = sysfs_create_files(gsmi_kobj, gsmi_attrs);
1028*44e33a5aSSean Rhodes if (ret) {
1029*44e33a5aSSean Rhodes printk(KERN_INFO "gsmi: Failed to add attrs");
1030*44e33a5aSSean Rhodes goto out_remove_bin_file;
1031*44e33a5aSSean Rhodes }
1032*44e33a5aSSean Rhodes
1033*44e33a5aSSean Rhodes #ifdef CONFIG_EFI
1034*44e33a5aSSean Rhodes ret = efivars_register(&efivars, &efivar_ops);
1035*44e33a5aSSean Rhodes if (ret) {
1036*44e33a5aSSean Rhodes printk(KERN_INFO "gsmi: Failed to register efivars\n");
1037*44e33a5aSSean Rhodes sysfs_remove_files(gsmi_kobj, gsmi_attrs);
1038*44e33a5aSSean Rhodes goto out_remove_bin_file;
1039*44e33a5aSSean Rhodes }
1040*44e33a5aSSean Rhodes #endif
1041*44e33a5aSSean Rhodes
1042*44e33a5aSSean Rhodes register_reboot_notifier(&gsmi_reboot_notifier);
1043*44e33a5aSSean Rhodes register_die_notifier(&gsmi_die_notifier);
1044*44e33a5aSSean Rhodes atomic_notifier_chain_register(&panic_notifier_list,
1045*44e33a5aSSean Rhodes &gsmi_panic_notifier);
1046*44e33a5aSSean Rhodes
1047*44e33a5aSSean Rhodes printk(KERN_INFO "gsmi version " DRIVER_VERSION " loaded\n");
1048*44e33a5aSSean Rhodes
1049*44e33a5aSSean Rhodes return 0;
1050*44e33a5aSSean Rhodes
1051*44e33a5aSSean Rhodes out_remove_bin_file:
1052*44e33a5aSSean Rhodes sysfs_remove_bin_file(gsmi_kobj, &eventlog_bin_attr);
1053*44e33a5aSSean Rhodes out_err:
1054*44e33a5aSSean Rhodes kobject_put(gsmi_kobj);
1055*44e33a5aSSean Rhodes gsmi_buf_free(gsmi_dev.param_buf);
1056*44e33a5aSSean Rhodes gsmi_buf_free(gsmi_dev.data_buf);
1057*44e33a5aSSean Rhodes gsmi_buf_free(gsmi_dev.name_buf);
1058*44e33a5aSSean Rhodes kmem_cache_destroy(gsmi_dev.mem_pool);
1059*44e33a5aSSean Rhodes platform_device_unregister(gsmi_dev.pdev);
1060*44e33a5aSSean Rhodes out_unregister:
1061*44e33a5aSSean Rhodes #ifdef CONFIG_PM
1062*44e33a5aSSean Rhodes platform_driver_unregister(&gsmi_driver_info);
1063*44e33a5aSSean Rhodes #endif
1064*44e33a5aSSean Rhodes pr_info("gsmi: failed to load: %d\n", ret);
1065*44e33a5aSSean Rhodes return ret;
1066*44e33a5aSSean Rhodes }
1067*44e33a5aSSean Rhodes
gsmi_exit(void)1068*44e33a5aSSean Rhodes static void __exit gsmi_exit(void)
1069*44e33a5aSSean Rhodes {
1070*44e33a5aSSean Rhodes unregister_reboot_notifier(&gsmi_reboot_notifier);
1071*44e33a5aSSean Rhodes unregister_die_notifier(&gsmi_die_notifier);
1072*44e33a5aSSean Rhodes atomic_notifier_chain_unregister(&panic_notifier_list,
1073*44e33a5aSSean Rhodes &gsmi_panic_notifier);
1074*44e33a5aSSean Rhodes #ifdef CONFIG_EFI
1075*44e33a5aSSean Rhodes efivars_unregister(&efivars);
1076*44e33a5aSSean Rhodes #endif
1077*44e33a5aSSean Rhodes
1078*44e33a5aSSean Rhodes sysfs_remove_files(gsmi_kobj, gsmi_attrs);
1079*44e33a5aSSean Rhodes sysfs_remove_bin_file(gsmi_kobj, &eventlog_bin_attr);
1080*44e33a5aSSean Rhodes kobject_put(gsmi_kobj);
1081*44e33a5aSSean Rhodes gsmi_buf_free(gsmi_dev.param_buf);
1082*44e33a5aSSean Rhodes gsmi_buf_free(gsmi_dev.data_buf);
1083*44e33a5aSSean Rhodes gsmi_buf_free(gsmi_dev.name_buf);
1084*44e33a5aSSean Rhodes kmem_cache_destroy(gsmi_dev.mem_pool);
1085*44e33a5aSSean Rhodes platform_device_unregister(gsmi_dev.pdev);
1086*44e33a5aSSean Rhodes #ifdef CONFIG_PM
1087*44e33a5aSSean Rhodes platform_driver_unregister(&gsmi_driver_info);
1088*44e33a5aSSean Rhodes #endif
1089*44e33a5aSSean Rhodes }
1090*44e33a5aSSean Rhodes
1091*44e33a5aSSean Rhodes module_init(gsmi_init);
1092*44e33a5aSSean Rhodes module_exit(gsmi_exit);
1093*44e33a5aSSean Rhodes
1094*44e33a5aSSean Rhodes MODULE_AUTHOR("Google, Inc.");
1095*44e33a5aSSean Rhodes MODULE_DESCRIPTION("EFI SMI interface for Google platforms");
1096*44e33a5aSSean Rhodes MODULE_LICENSE("GPL");
1097