hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/firmware/google/gsmi.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright 2010 Google Inc. All Rights Reserved.
34 * Author: dlaurie@google.com (Duncan Laurie)
....@@ -29,6 +30,7 @@
2930 #include <linux/efi.h>
3031 #include <linux/module.h>
3132 #include <linux/ucs2_string.h>
33
+#include <linux/suspend.h>
3234
3335 #define GSMI_SHUTDOWN_CLEAN 0 /* Clean Shutdown */
3436 /* TODO(mikew@google.com): Tie in HARDLOCKUP_DETECTOR with NMIWDT */
....@@ -70,8 +72,11 @@
7072 #define GSMI_CMD_SET_NVRAM_VAR 0x03
7173 #define GSMI_CMD_SET_EVENT_LOG 0x08
7274 #define GSMI_CMD_CLEAR_EVENT_LOG 0x09
75
+#define GSMI_CMD_LOG_S0IX_SUSPEND 0x0a
76
+#define GSMI_CMD_LOG_S0IX_RESUME 0x0b
7377 #define GSMI_CMD_CLEAR_CONFIG 0x20
7478 #define GSMI_CMD_HANDSHAKE_TYPE 0xC1
79
+#define GSMI_CMD_RESERVED 0xff
7580
7681 /* Magic entry type for kernel events */
7782 #define GSMI_LOG_ENTRY_TYPE_KERNEL 0xDEAD
....@@ -84,7 +89,7 @@
8489 u32 address; /* physical address of buffer */
8590 };
8691
87
-struct gsmi_device {
92
+static struct gsmi_device {
8893 struct platform_device *pdev; /* platform device */
8994 struct gsmi_buf *name_buf; /* variable name buffer */
9095 struct gsmi_buf *data_buf; /* generic data buffer */
....@@ -122,7 +127,6 @@
122127 u32 instance;
123128 } __packed;
124129
125
-
126130 /*
127131 * Some platforms don't have explicit SMI handshake
128132 * and need to wait for SMI to complete.
....@@ -132,6 +136,15 @@
132136 module_param(spincount, uint, 0600);
133137 MODULE_PARM_DESC(spincount,
134138 "The number of loop iterations to use when using the spin handshake.");
139
+
140
+/*
141
+ * Platforms might not support S0ix logging in their GSMI handlers. In order to
142
+ * avoid any side-effects of generating an SMI for S0ix logging, use the S0ix
143
+ * related GSMI commands only for those platforms that explicitly enable this
144
+ * option.
145
+ */
146
+static bool s0ix_logging_enable;
147
+module_param(s0ix_logging_enable, bool, 0600);
135148
136149 static struct gsmi_buf *gsmi_buf_alloc(void)
137150 {
....@@ -289,6 +302,10 @@
289302 return rc;
290303 }
291304
305
+#ifdef CONFIG_EFI
306
+
307
+static struct efivars efivars;
308
+
292309 static efi_status_t gsmi_get_variable(efi_char16_t *name,
293310 efi_guid_t *vendor, u32 *attr,
294311 unsigned long *data_size,
....@@ -343,9 +360,10 @@
343360 memcpy(data, gsmi_dev.data_buf->start, *data_size);
344361
345362 /* All variables are have the following attributes */
346
- *attr = EFI_VARIABLE_NON_VOLATILE |
347
- EFI_VARIABLE_BOOTSERVICE_ACCESS |
348
- EFI_VARIABLE_RUNTIME_ACCESS;
363
+ if (attr)
364
+ *attr = EFI_VARIABLE_NON_VOLATILE |
365
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
366
+ EFI_VARIABLE_RUNTIME_ACCESS;
349367 }
350368
351369 spin_unlock_irqrestore(&gsmi_dev.lock, flags);
....@@ -465,6 +483,8 @@
465483 .set_variable = gsmi_set_variable,
466484 .get_next_variable = gsmi_get_next_variable,
467485 };
486
+
487
+#endif /* CONFIG_EFI */
468488
469489 static ssize_t eventlog_write(struct file *filp, struct kobject *kobj,
470490 struct bin_attribute *bin_attr,
....@@ -661,6 +681,15 @@
661681 static int gsmi_panic_callback(struct notifier_block *nb,
662682 unsigned long reason, void *arg)
663683 {
684
+
685
+ /*
686
+ * Panic callbacks are executed with all other CPUs stopped,
687
+ * so we must not attempt to spin waiting for gsmi_dev.lock
688
+ * to be released.
689
+ */
690
+ if (spin_is_locked(&gsmi_dev.lock))
691
+ return NOTIFY_DONE;
692
+
664693 gsmi_shutdown_reason(GSMI_SHUTDOWN_PANIC);
665694 return NOTIFY_DONE;
666695 }
....@@ -715,6 +744,12 @@
715744 DMI_MATCH(DMI_BOARD_VENDOR, "Google, Inc."),
716745 },
717746 },
747
+ {
748
+ .ident = "Coreboot Firmware",
749
+ .matches = {
750
+ DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"),
751
+ },
752
+ },
718753 {}
719754 };
720755 MODULE_DEVICE_TABLE(dmi, gsmi_dmi_table);
....@@ -722,6 +757,7 @@
722757 static __init int gsmi_system_valid(void)
723758 {
724759 u32 hash;
760
+ u16 cmd, result;
725761
726762 if (!dmi_check_system(gsmi_dmi_table))
727763 return -ENODEV;
....@@ -756,12 +792,28 @@
756792 return -ENODEV;
757793 }
758794
795
+ /* Test the smihandler with a bogus command. If it leaves the
796
+ * calling argument in %ax untouched, there is no handler for
797
+ * GSMI commands.
798
+ */
799
+ cmd = GSMI_CALLBACK | GSMI_CMD_RESERVED << 8;
800
+ asm volatile (
801
+ "outb %%al, %%dx\n\t"
802
+ : "=a" (result)
803
+ : "0" (cmd),
804
+ "d" (acpi_gbl_FADT.smi_command)
805
+ : "memory", "cc"
806
+ );
807
+ if (cmd == result) {
808
+ pr_info("gsmi: no gsmi handler in firmware\n");
809
+ return -ENODEV;
810
+ }
811
+
759812 /* Found */
760813 return 0;
761814 }
762815
763816 static struct kobject *gsmi_kobj;
764
-static struct efivars efivars;
765817
766818 static const struct platform_device_info gsmi_dev_info = {
767819 .name = "gsmi",
....@@ -769,6 +821,78 @@
769821 /* SMI callbacks require 32bit addresses */
770822 .dma_mask = DMA_BIT_MASK(32),
771823 };
824
+
825
+#ifdef CONFIG_PM
826
+static void gsmi_log_s0ix_info(u8 cmd)
827
+{
828
+ unsigned long flags;
829
+
830
+ /*
831
+ * If platform has not enabled S0ix logging, then no action is
832
+ * necessary.
833
+ */
834
+ if (!s0ix_logging_enable)
835
+ return;
836
+
837
+ spin_lock_irqsave(&gsmi_dev.lock, flags);
838
+
839
+ memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
840
+
841
+ gsmi_exec(GSMI_CALLBACK, cmd);
842
+
843
+ spin_unlock_irqrestore(&gsmi_dev.lock, flags);
844
+}
845
+
846
+static int gsmi_log_s0ix_suspend(struct device *dev)
847
+{
848
+ /*
849
+ * If system is not suspending via firmware using the standard ACPI Sx
850
+ * types, then make a GSMI call to log the suspend info.
851
+ */
852
+ if (!pm_suspend_via_firmware())
853
+ gsmi_log_s0ix_info(GSMI_CMD_LOG_S0IX_SUSPEND);
854
+
855
+ /*
856
+ * Always return success, since we do not want suspend
857
+ * to fail just because of logging failure.
858
+ */
859
+ return 0;
860
+}
861
+
862
+static int gsmi_log_s0ix_resume(struct device *dev)
863
+{
864
+ /*
865
+ * If system did not resume via firmware, then make a GSMI call to log
866
+ * the resume info and wake source.
867
+ */
868
+ if (!pm_resume_via_firmware())
869
+ gsmi_log_s0ix_info(GSMI_CMD_LOG_S0IX_RESUME);
870
+
871
+ /*
872
+ * Always return success, since we do not want resume
873
+ * to fail just because of logging failure.
874
+ */
875
+ return 0;
876
+}
877
+
878
+static const struct dev_pm_ops gsmi_pm_ops = {
879
+ .suspend_noirq = gsmi_log_s0ix_suspend,
880
+ .resume_noirq = gsmi_log_s0ix_resume,
881
+};
882
+
883
+static int gsmi_platform_driver_probe(struct platform_device *dev)
884
+{
885
+ return 0;
886
+}
887
+
888
+static struct platform_driver gsmi_driver_info = {
889
+ .driver = {
890
+ .name = "gsmi",
891
+ .pm = &gsmi_pm_ops,
892
+ },
893
+ .probe = gsmi_platform_driver_probe,
894
+};
895
+#endif
772896
773897 static __init int gsmi_init(void)
774898 {
....@@ -780,6 +904,14 @@
780904 return ret;
781905
782906 gsmi_dev.smi_cmd = acpi_gbl_FADT.smi_command;
907
+
908
+#ifdef CONFIG_PM
909
+ ret = platform_driver_register(&gsmi_driver_info);
910
+ if (unlikely(ret)) {
911
+ printk(KERN_ERR "gsmi: unable to register platform driver\n");
912
+ return ret;
913
+ }
914
+#endif
783915
784916 /* register device */
785917 gsmi_dev.pdev = platform_device_register_full(&gsmi_dev_info);
....@@ -885,11 +1017,14 @@
8851017 goto out_remove_bin_file;
8861018 }
8871019
1020
+#ifdef CONFIG_EFI
8881021 ret = efivars_register(&efivars, &efivar_ops, gsmi_kobj);
8891022 if (ret) {
8901023 printk(KERN_INFO "gsmi: Failed to register efivars\n");
891
- goto out_remove_sysfs_files;
1024
+ sysfs_remove_files(gsmi_kobj, gsmi_attrs);
1025
+ goto out_remove_bin_file;
8921026 }
1027
+#endif
8931028
8941029 register_reboot_notifier(&gsmi_reboot_notifier);
8951030 register_die_notifier(&gsmi_die_notifier);
....@@ -900,8 +1035,6 @@
9001035
9011036 return 0;
9021037
903
-out_remove_sysfs_files:
904
- sysfs_remove_files(gsmi_kobj, gsmi_attrs);
9051038 out_remove_bin_file:
9061039 sysfs_remove_bin_file(gsmi_kobj, &eventlog_bin_attr);
9071040 out_err:
....@@ -912,6 +1045,9 @@
9121045 dma_pool_destroy(gsmi_dev.dma_pool);
9131046 platform_device_unregister(gsmi_dev.pdev);
9141047 pr_info("gsmi: failed to load: %d\n", ret);
1048
+#ifdef CONFIG_PM
1049
+ platform_driver_unregister(&gsmi_driver_info);
1050
+#endif
9151051 return ret;
9161052 }
9171053
....@@ -921,7 +1057,9 @@
9211057 unregister_die_notifier(&gsmi_die_notifier);
9221058 atomic_notifier_chain_unregister(&panic_notifier_list,
9231059 &gsmi_panic_notifier);
1060
+#ifdef CONFIG_EFI
9241061 efivars_unregister(&efivars);
1062
+#endif
9251063
9261064 sysfs_remove_files(gsmi_kobj, gsmi_attrs);
9271065 sysfs_remove_bin_file(gsmi_kobj, &eventlog_bin_attr);
....@@ -931,6 +1069,9 @@
9311069 gsmi_buf_free(gsmi_dev.name_buf);
9321070 dma_pool_destroy(gsmi_dev.dma_pool);
9331071 platform_device_unregister(gsmi_dev.pdev);
1072
+#ifdef CONFIG_PM
1073
+ platform_driver_unregister(&gsmi_driver_info);
1074
+#endif
9341075 }
9351076
9361077 module_init(gsmi_init);