mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
Char/Misc driver patches for 4.20-rc1
Here is the big set of char/misc patches for 4.20-rc1. Loads of things here, we have new code in all of these driver subsystems: fpga stm extcon nvmem eeprom hyper-v gsmi coresight thunderbolt vmw_balloon goldfish soundwire along with lots of fixes and minor changes to other small drivers. All of these have been in linux-next for a while with no reported issues. Signed-off-by: Greg Kroah-Hartman <[email protected]> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCW9Le5A8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+yn+BQCfZ6DtCIgqo0UW3dLV8Fd0wya9kw0AoNglzJJ6 YRZiaSdRiggARpNdh3ME =97BX -----END PGP SIGNATURE----- Merge tag 'char-misc-4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc Pull char/misc driver updates from Greg KH: "Here is the big set of char/misc patches for 4.20-rc1. Loads of things here, we have new code in all of these driver subsystems: - fpga - stm - extcon - nvmem - eeprom - hyper-v - gsmi - coresight - thunderbolt - vmw_balloon - goldfish - soundwire along with lots of fixes and minor changes to other small drivers. All of these have been in linux-next for a while with no reported issues" * tag 'char-misc-4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (245 commits) Documentation/security-bugs: Clarify treatment of embargoed information lib: Fix ia64 bootloader linkage MAINTAINERS: Clarify UIO vs UIOVEC maintainer docs/uio: fix a grammar nitpick docs: fpga: document programming fpgas using regions fpga: add devm_fpga_region_create fpga: bridge: add devm_fpga_bridge_create fpga: mgr: add devm_fpga_mgr_create hv_balloon: Replace spin_is_locked() with lockdep sgi-xp: Replace spin_is_locked() with lockdep eeprom: New ee1004 driver for DDR4 memory eeprom: at25: remove unneeded 'at25_remove' w1: IAD Register is yet readable trough iad sys file. Fix snprintf (%u for unsigned, count for max size). misc: mic: scif: remove set but not used variables 'src_dma_addr, dst_dma_addr' misc: mic: fix a DMA pool free failure platform: goldfish: pipe: Add a blank line to separate varibles and code platform: goldfish: pipe: Remove redundant casting platform: goldfish: pipe: Call misc_deregister if init fails platform: goldfish: pipe: Move the file-scope goldfish_pipe_dev variable into the driver state platform: goldfish: pipe: Move the file-scope goldfish_pipe_miscdev variable into the driver state ...
This commit is contained in:
commit
18d0eae30e
180 changed files with 6878 additions and 3351 deletions
|
|
@ -10,37 +10,31 @@ if GOOGLE_FIRMWARE
|
|||
|
||||
config GOOGLE_SMI
|
||||
tristate "SMI interface for Google platforms"
|
||||
depends on X86 && ACPI && DMI && EFI
|
||||
select EFI_VARS
|
||||
depends on X86 && ACPI && DMI
|
||||
help
|
||||
Say Y here if you want to enable SMI callbacks for Google
|
||||
platforms. This provides an interface for writing to and
|
||||
clearing the EFI event log and reading and writing NVRAM
|
||||
clearing the event log. If EFI_VARS is also enabled this
|
||||
driver provides an interface for reading and writing NVRAM
|
||||
variables.
|
||||
|
||||
config GOOGLE_COREBOOT_TABLE
|
||||
tristate
|
||||
depends on GOOGLE_COREBOOT_TABLE_ACPI || GOOGLE_COREBOOT_TABLE_OF
|
||||
|
||||
config GOOGLE_COREBOOT_TABLE_ACPI
|
||||
tristate "Coreboot Table Access - ACPI"
|
||||
depends on ACPI
|
||||
select GOOGLE_COREBOOT_TABLE
|
||||
tristate "Coreboot Table Access"
|
||||
depends on ACPI || OF
|
||||
help
|
||||
This option enables the coreboot_table module, which provides other
|
||||
firmware modules to access to the coreboot table. The coreboot table
|
||||
pointer is accessed through the ACPI "GOOGCB00" object.
|
||||
firmware modules access to the coreboot table. The coreboot table
|
||||
pointer is accessed through the ACPI "GOOGCB00" object or the
|
||||
device tree node /firmware/coreboot.
|
||||
If unsure say N.
|
||||
|
||||
config GOOGLE_COREBOOT_TABLE_OF
|
||||
tristate "Coreboot Table Access - Device Tree"
|
||||
depends on OF
|
||||
config GOOGLE_COREBOOT_TABLE_ACPI
|
||||
tristate
|
||||
select GOOGLE_COREBOOT_TABLE
|
||||
|
||||
config GOOGLE_COREBOOT_TABLE_OF
|
||||
tristate
|
||||
select GOOGLE_COREBOOT_TABLE
|
||||
help
|
||||
This option enable the coreboot_table module, which provide other
|
||||
firmware modules to access coreboot table. The coreboot table pointer
|
||||
is accessed through the device tree node /firmware/coreboot.
|
||||
If unsure say N.
|
||||
|
||||
config GOOGLE_MEMCONSOLE
|
||||
tristate
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
obj-$(CONFIG_GOOGLE_SMI) += gsmi.o
|
||||
obj-$(CONFIG_GOOGLE_COREBOOT_TABLE) += coreboot_table.o
|
||||
obj-$(CONFIG_GOOGLE_COREBOOT_TABLE_ACPI) += coreboot_table-acpi.o
|
||||
obj-$(CONFIG_GOOGLE_COREBOOT_TABLE_OF) += coreboot_table-of.o
|
||||
obj-$(CONFIG_GOOGLE_FRAMEBUFFER_COREBOOT) += framebuffer-coreboot.o
|
||||
obj-$(CONFIG_GOOGLE_MEMCONSOLE) += memconsole.o
|
||||
obj-$(CONFIG_GOOGLE_MEMCONSOLE_COREBOOT) += memconsole-coreboot.o
|
||||
|
|
|
|||
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
* coreboot_table-acpi.c
|
||||
*
|
||||
* Using ACPI to locate Coreboot table and provide coreboot table access.
|
||||
*
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License v2.0 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "coreboot_table.h"
|
||||
|
||||
static int coreboot_table_acpi_probe(struct platform_device *pdev)
|
||||
{
|
||||
phys_addr_t phyaddr;
|
||||
resource_size_t len;
|
||||
struct coreboot_table_header __iomem *header = NULL;
|
||||
struct resource *res;
|
||||
void __iomem *ptr = NULL;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
|
||||
len = resource_size(res);
|
||||
if (!res->start || !len)
|
||||
return -EINVAL;
|
||||
|
||||
phyaddr = res->start;
|
||||
header = ioremap_cache(phyaddr, sizeof(*header));
|
||||
if (header == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
ptr = ioremap_cache(phyaddr,
|
||||
header->header_bytes + header->table_bytes);
|
||||
iounmap(header);
|
||||
if (!ptr)
|
||||
return -ENOMEM;
|
||||
|
||||
return coreboot_table_init(&pdev->dev, ptr);
|
||||
}
|
||||
|
||||
static int coreboot_table_acpi_remove(struct platform_device *pdev)
|
||||
{
|
||||
return coreboot_table_exit();
|
||||
}
|
||||
|
||||
static const struct acpi_device_id cros_coreboot_acpi_match[] = {
|
||||
{ "GOOGCB00", 0 },
|
||||
{ "BOOT0000", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, cros_coreboot_acpi_match);
|
||||
|
||||
static struct platform_driver coreboot_table_acpi_driver = {
|
||||
.probe = coreboot_table_acpi_probe,
|
||||
.remove = coreboot_table_acpi_remove,
|
||||
.driver = {
|
||||
.name = "coreboot_table_acpi",
|
||||
.acpi_match_table = ACPI_PTR(cros_coreboot_acpi_match),
|
||||
},
|
||||
};
|
||||
|
||||
static int __init coreboot_table_acpi_init(void)
|
||||
{
|
||||
return platform_driver_register(&coreboot_table_acpi_driver);
|
||||
}
|
||||
|
||||
module_init(coreboot_table_acpi_init);
|
||||
|
||||
MODULE_AUTHOR("Google, Inc.");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* coreboot_table-of.c
|
||||
*
|
||||
* Coreboot table access through open firmware.
|
||||
*
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License v2.0 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "coreboot_table.h"
|
||||
|
||||
static int coreboot_table_of_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *fw_dn = pdev->dev.of_node;
|
||||
void __iomem *ptr;
|
||||
|
||||
ptr = of_iomap(fw_dn, 0);
|
||||
of_node_put(fw_dn);
|
||||
if (!ptr)
|
||||
return -ENOMEM;
|
||||
|
||||
return coreboot_table_init(&pdev->dev, ptr);
|
||||
}
|
||||
|
||||
static int coreboot_table_of_remove(struct platform_device *pdev)
|
||||
{
|
||||
return coreboot_table_exit();
|
||||
}
|
||||
|
||||
static const struct of_device_id coreboot_of_match[] = {
|
||||
{ .compatible = "coreboot" },
|
||||
{},
|
||||
};
|
||||
|
||||
static struct platform_driver coreboot_table_of_driver = {
|
||||
.probe = coreboot_table_of_probe,
|
||||
.remove = coreboot_table_of_remove,
|
||||
.driver = {
|
||||
.name = "coreboot_table_of",
|
||||
.of_match_table = coreboot_of_match,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init platform_coreboot_table_of_init(void)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct device_node *of_node;
|
||||
|
||||
/* Limit device creation to the presence of /firmware/coreboot node */
|
||||
of_node = of_find_node_by_path("/firmware/coreboot");
|
||||
if (!of_node)
|
||||
return -ENODEV;
|
||||
|
||||
if (!of_match_node(coreboot_of_match, of_node))
|
||||
return -ENODEV;
|
||||
|
||||
pdev = of_platform_device_create(of_node, "coreboot_table_of", NULL);
|
||||
if (!pdev)
|
||||
return -ENODEV;
|
||||
|
||||
return platform_driver_register(&coreboot_table_of_driver);
|
||||
}
|
||||
|
||||
module_init(platform_coreboot_table_of_init);
|
||||
|
||||
MODULE_AUTHOR("Google, Inc.");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -16,12 +16,15 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "coreboot_table.h"
|
||||
|
|
@ -29,8 +32,6 @@
|
|||
#define CB_DEV(d) container_of(d, struct coreboot_device, dev)
|
||||
#define CB_DRV(d) container_of(d, struct coreboot_driver, drv)
|
||||
|
||||
static struct coreboot_table_header __iomem *ptr_header;
|
||||
|
||||
static int coreboot_bus_match(struct device *dev, struct device_driver *drv)
|
||||
{
|
||||
struct coreboot_device *device = CB_DEV(dev);
|
||||
|
|
@ -70,12 +71,6 @@ static struct bus_type coreboot_bus_type = {
|
|||
.remove = coreboot_bus_remove,
|
||||
};
|
||||
|
||||
static int __init coreboot_bus_init(void)
|
||||
{
|
||||
return bus_register(&coreboot_bus_type);
|
||||
}
|
||||
module_init(coreboot_bus_init);
|
||||
|
||||
static void coreboot_device_release(struct device *dev)
|
||||
{
|
||||
struct coreboot_device *device = CB_DEV(dev);
|
||||
|
|
@ -97,62 +92,117 @@ void coreboot_driver_unregister(struct coreboot_driver *driver)
|
|||
}
|
||||
EXPORT_SYMBOL(coreboot_driver_unregister);
|
||||
|
||||
int coreboot_table_init(struct device *dev, void __iomem *ptr)
|
||||
static int coreboot_table_populate(struct device *dev, void *ptr)
|
||||
{
|
||||
int i, ret;
|
||||
void *ptr_entry;
|
||||
struct coreboot_device *device;
|
||||
struct coreboot_table_entry entry;
|
||||
struct coreboot_table_header header;
|
||||
struct coreboot_table_entry *entry;
|
||||
struct coreboot_table_header *header = ptr;
|
||||
|
||||
ptr_header = ptr;
|
||||
memcpy_fromio(&header, ptr_header, sizeof(header));
|
||||
ptr_entry = ptr + header->header_bytes;
|
||||
for (i = 0; i < header->table_entries; i++) {
|
||||
entry = ptr_entry;
|
||||
|
||||
if (strncmp(header.signature, "LBIO", sizeof(header.signature))) {
|
||||
pr_warn("coreboot_table: coreboot table missing or corrupt!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ptr_entry = (void *)ptr_header + header.header_bytes;
|
||||
for (i = 0; i < header.table_entries; i++) {
|
||||
memcpy_fromio(&entry, ptr_entry, sizeof(entry));
|
||||
|
||||
device = kzalloc(sizeof(struct device) + entry.size, GFP_KERNEL);
|
||||
if (!device) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
device = kzalloc(sizeof(struct device) + entry->size, GFP_KERNEL);
|
||||
if (!device)
|
||||
return -ENOMEM;
|
||||
|
||||
dev_set_name(&device->dev, "coreboot%d", i);
|
||||
device->dev.parent = dev;
|
||||
device->dev.bus = &coreboot_bus_type;
|
||||
device->dev.release = coreboot_device_release;
|
||||
memcpy_fromio(&device->entry, ptr_entry, entry.size);
|
||||
memcpy(&device->entry, ptr_entry, entry->size);
|
||||
|
||||
ret = device_register(&device->dev);
|
||||
if (ret) {
|
||||
put_device(&device->dev);
|
||||
break;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ptr_entry += entry.size;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(coreboot_table_init);
|
||||
|
||||
int coreboot_table_exit(void)
|
||||
{
|
||||
if (ptr_header) {
|
||||
bus_unregister(&coreboot_bus_type);
|
||||
iounmap(ptr_header);
|
||||
ptr_header = NULL;
|
||||
ptr_entry += entry->size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(coreboot_table_exit);
|
||||
|
||||
static int coreboot_table_probe(struct platform_device *pdev)
|
||||
{
|
||||
resource_size_t len;
|
||||
struct coreboot_table_header *header;
|
||||
struct resource *res;
|
||||
struct device *dev = &pdev->dev;
|
||||
void *ptr;
|
||||
int ret;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
|
||||
len = resource_size(res);
|
||||
if (!res->start || !len)
|
||||
return -EINVAL;
|
||||
|
||||
/* Check just the header first to make sure things are sane */
|
||||
header = memremap(res->start, sizeof(*header), MEMREMAP_WB);
|
||||
if (!header)
|
||||
return -ENOMEM;
|
||||
|
||||
len = header->header_bytes + header->table_bytes;
|
||||
ret = strncmp(header->signature, "LBIO", sizeof(header->signature));
|
||||
memunmap(header);
|
||||
if (ret) {
|
||||
dev_warn(dev, "coreboot table missing or corrupt!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ptr = memremap(res->start, len, MEMREMAP_WB);
|
||||
if (!ptr)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = bus_register(&coreboot_bus_type);
|
||||
if (!ret) {
|
||||
ret = coreboot_table_populate(dev, ptr);
|
||||
if (ret)
|
||||
bus_unregister(&coreboot_bus_type);
|
||||
}
|
||||
memunmap(ptr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int coreboot_table_remove(struct platform_device *pdev)
|
||||
{
|
||||
bus_unregister(&coreboot_bus_type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static const struct acpi_device_id cros_coreboot_acpi_match[] = {
|
||||
{ "GOOGCB00", 0 },
|
||||
{ "BOOT0000", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, cros_coreboot_acpi_match);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id coreboot_of_match[] = {
|
||||
{ .compatible = "coreboot" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, coreboot_of_match);
|
||||
#endif
|
||||
|
||||
static struct platform_driver coreboot_table_driver = {
|
||||
.probe = coreboot_table_probe,
|
||||
.remove = coreboot_table_remove,
|
||||
.driver = {
|
||||
.name = "coreboot_table",
|
||||
.acpi_match_table = ACPI_PTR(cros_coreboot_acpi_match),
|
||||
.of_match_table = of_match_ptr(coreboot_of_match),
|
||||
},
|
||||
};
|
||||
module_platform_driver(coreboot_table_driver);
|
||||
MODULE_AUTHOR("Google, Inc.");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -91,10 +91,4 @@ int coreboot_driver_register(struct coreboot_driver *driver);
|
|||
/* Unregister a driver that uses the data from a coreboot table. */
|
||||
void coreboot_driver_unregister(struct coreboot_driver *driver);
|
||||
|
||||
/* Initialize coreboot table module given a pointer to iomem */
|
||||
int coreboot_table_init(struct device *dev, void __iomem *ptr);
|
||||
|
||||
/* Cleanup coreboot table module */
|
||||
int coreboot_table_exit(void);
|
||||
|
||||
#endif /* __COREBOOT_TABLE_H */
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <linux/efi.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ucs2_string.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#define GSMI_SHUTDOWN_CLEAN 0 /* Clean Shutdown */
|
||||
/* TODO([email protected]): Tie in HARDLOCKUP_DETECTOR with NMIWDT */
|
||||
|
|
@ -70,6 +71,8 @@
|
|||
#define GSMI_CMD_SET_NVRAM_VAR 0x03
|
||||
#define GSMI_CMD_SET_EVENT_LOG 0x08
|
||||
#define GSMI_CMD_CLEAR_EVENT_LOG 0x09
|
||||
#define GSMI_CMD_LOG_S0IX_SUSPEND 0x0a
|
||||
#define GSMI_CMD_LOG_S0IX_RESUME 0x0b
|
||||
#define GSMI_CMD_CLEAR_CONFIG 0x20
|
||||
#define GSMI_CMD_HANDSHAKE_TYPE 0xC1
|
||||
|
||||
|
|
@ -84,7 +87,7 @@ struct gsmi_buf {
|
|||
u32 address; /* physical address of buffer */
|
||||
};
|
||||
|
||||
struct gsmi_device {
|
||||
static struct gsmi_device {
|
||||
struct platform_device *pdev; /* platform device */
|
||||
struct gsmi_buf *name_buf; /* variable name buffer */
|
||||
struct gsmi_buf *data_buf; /* generic data buffer */
|
||||
|
|
@ -122,7 +125,6 @@ struct gsmi_log_entry_type_1 {
|
|||
u32 instance;
|
||||
} __packed;
|
||||
|
||||
|
||||
/*
|
||||
* Some platforms don't have explicit SMI handshake
|
||||
* and need to wait for SMI to complete.
|
||||
|
|
@ -133,6 +135,15 @@ module_param(spincount, uint, 0600);
|
|||
MODULE_PARM_DESC(spincount,
|
||||
"The number of loop iterations to use when using the spin handshake.");
|
||||
|
||||
/*
|
||||
* Platforms might not support S0ix logging in their GSMI handlers. In order to
|
||||
* avoid any side-effects of generating an SMI for S0ix logging, use the S0ix
|
||||
* related GSMI commands only for those platforms that explicitly enable this
|
||||
* option.
|
||||
*/
|
||||
static bool s0ix_logging_enable;
|
||||
module_param(s0ix_logging_enable, bool, 0600);
|
||||
|
||||
static struct gsmi_buf *gsmi_buf_alloc(void)
|
||||
{
|
||||
struct gsmi_buf *smibuf;
|
||||
|
|
@ -289,6 +300,10 @@ static int gsmi_exec(u8 func, u8 sub)
|
|||
return rc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EFI_VARS
|
||||
|
||||
static struct efivars efivars;
|
||||
|
||||
static efi_status_t gsmi_get_variable(efi_char16_t *name,
|
||||
efi_guid_t *vendor, u32 *attr,
|
||||
unsigned long *data_size,
|
||||
|
|
@ -466,6 +481,8 @@ static const struct efivar_operations efivar_ops = {
|
|||
.get_next_variable = gsmi_get_next_variable,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_EFI_VARS */
|
||||
|
||||
static ssize_t eventlog_write(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr,
|
||||
char *buf, loff_t pos, size_t count)
|
||||
|
|
@ -480,11 +497,10 @@ static ssize_t eventlog_write(struct file *filp, struct kobject *kobj,
|
|||
if (count < sizeof(u32))
|
||||
return -EINVAL;
|
||||
param.type = *(u32 *)buf;
|
||||
count -= sizeof(u32);
|
||||
buf += sizeof(u32);
|
||||
|
||||
/* The remaining buffer is the data payload */
|
||||
if (count > gsmi_dev.data_buf->length)
|
||||
if ((count - sizeof(u32)) > gsmi_dev.data_buf->length)
|
||||
return -EINVAL;
|
||||
param.data_len = count - sizeof(u32);
|
||||
|
||||
|
|
@ -504,7 +520,7 @@ static ssize_t eventlog_write(struct file *filp, struct kobject *kobj,
|
|||
|
||||
spin_unlock_irqrestore(&gsmi_dev.lock, flags);
|
||||
|
||||
return rc;
|
||||
return (rc == 0) ? count : rc;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -716,6 +732,12 @@ static const struct dmi_system_id gsmi_dmi_table[] __initconst = {
|
|||
DMI_MATCH(DMI_BOARD_VENDOR, "Google, Inc."),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Coreboot Firmware",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(dmi, gsmi_dmi_table);
|
||||
|
|
@ -762,7 +784,6 @@ static __init int gsmi_system_valid(void)
|
|||
}
|
||||
|
||||
static struct kobject *gsmi_kobj;
|
||||
static struct efivars efivars;
|
||||
|
||||
static const struct platform_device_info gsmi_dev_info = {
|
||||
.name = "gsmi",
|
||||
|
|
@ -771,6 +792,78 @@ static const struct platform_device_info gsmi_dev_info = {
|
|||
.dma_mask = DMA_BIT_MASK(32),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static void gsmi_log_s0ix_info(u8 cmd)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* If platform has not enabled S0ix logging, then no action is
|
||||
* necessary.
|
||||
*/
|
||||
if (!s0ix_logging_enable)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&gsmi_dev.lock, flags);
|
||||
|
||||
memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
|
||||
|
||||
gsmi_exec(GSMI_CALLBACK, cmd);
|
||||
|
||||
spin_unlock_irqrestore(&gsmi_dev.lock, flags);
|
||||
}
|
||||
|
||||
static int gsmi_log_s0ix_suspend(struct device *dev)
|
||||
{
|
||||
/*
|
||||
* If system is not suspending via firmware using the standard ACPI Sx
|
||||
* types, then make a GSMI call to log the suspend info.
|
||||
*/
|
||||
if (!pm_suspend_via_firmware())
|
||||
gsmi_log_s0ix_info(GSMI_CMD_LOG_S0IX_SUSPEND);
|
||||
|
||||
/*
|
||||
* Always return success, since we do not want suspend
|
||||
* to fail just because of logging failure.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gsmi_log_s0ix_resume(struct device *dev)
|
||||
{
|
||||
/*
|
||||
* If system did not resume via firmware, then make a GSMI call to log
|
||||
* the resume info and wake source.
|
||||
*/
|
||||
if (!pm_resume_via_firmware())
|
||||
gsmi_log_s0ix_info(GSMI_CMD_LOG_S0IX_RESUME);
|
||||
|
||||
/*
|
||||
* Always return success, since we do not want resume
|
||||
* to fail just because of logging failure.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops gsmi_pm_ops = {
|
||||
.suspend_noirq = gsmi_log_s0ix_suspend,
|
||||
.resume_noirq = gsmi_log_s0ix_resume,
|
||||
};
|
||||
|
||||
static int gsmi_platform_driver_probe(struct platform_device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver gsmi_driver_info = {
|
||||
.driver = {
|
||||
.name = "gsmi",
|
||||
.pm = &gsmi_pm_ops,
|
||||
},
|
||||
.probe = gsmi_platform_driver_probe,
|
||||
};
|
||||
#endif
|
||||
|
||||
static __init int gsmi_init(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
|
@ -782,6 +875,14 @@ static __init int gsmi_init(void)
|
|||
|
||||
gsmi_dev.smi_cmd = acpi_gbl_FADT.smi_command;
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
ret = platform_driver_register(&gsmi_driver_info);
|
||||
if (unlikely(ret)) {
|
||||
printk(KERN_ERR "gsmi: unable to register platform driver\n");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* register device */
|
||||
gsmi_dev.pdev = platform_device_register_full(&gsmi_dev_info);
|
||||
if (IS_ERR(gsmi_dev.pdev)) {
|
||||
|
|
@ -886,11 +987,14 @@ static __init int gsmi_init(void)
|
|||
goto out_remove_bin_file;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EFI_VARS
|
||||
ret = efivars_register(&efivars, &efivar_ops, gsmi_kobj);
|
||||
if (ret) {
|
||||
printk(KERN_INFO "gsmi: Failed to register efivars\n");
|
||||
goto out_remove_sysfs_files;
|
||||
sysfs_remove_files(gsmi_kobj, gsmi_attrs);
|
||||
goto out_remove_bin_file;
|
||||
}
|
||||
#endif
|
||||
|
||||
register_reboot_notifier(&gsmi_reboot_notifier);
|
||||
register_die_notifier(&gsmi_die_notifier);
|
||||
|
|
@ -901,8 +1005,6 @@ static __init int gsmi_init(void)
|
|||
|
||||
return 0;
|
||||
|
||||
out_remove_sysfs_files:
|
||||
sysfs_remove_files(gsmi_kobj, gsmi_attrs);
|
||||
out_remove_bin_file:
|
||||
sysfs_remove_bin_file(gsmi_kobj, &eventlog_bin_attr);
|
||||
out_err:
|
||||
|
|
@ -922,7 +1024,9 @@ static void __exit gsmi_exit(void)
|
|||
unregister_die_notifier(&gsmi_die_notifier);
|
||||
atomic_notifier_chain_unregister(&panic_notifier_list,
|
||||
&gsmi_panic_notifier);
|
||||
#ifdef CONFIG_EFI_VARS
|
||||
efivars_unregister(&efivars);
|
||||
#endif
|
||||
|
||||
sysfs_remove_files(gsmi_kobj, gsmi_attrs);
|
||||
sysfs_remove_bin_file(gsmi_kobj, &eventlog_bin_attr);
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ static int vpd_section_init(const char *name, struct vpd_section *sec,
|
|||
|
||||
sec->name = name;
|
||||
|
||||
/* We want to export the raw partion with name ${name}_raw */
|
||||
/* We want to export the raw partition with name ${name}_raw */
|
||||
sec->raw_name = kasprintf(GFP_KERNEL, "%s_raw", name);
|
||||
if (!sec->raw_name) {
|
||||
err = -ENOMEM;
|
||||
|
|
|
|||
Loading…
Reference in a new issue