Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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