[RFC 03/11] platform/chrome: ChromeOS firmware interface driver
Ulrich Hecht
ulrich.hecht+renesas at gmail.com
Fri Sep 29 06:09:05 PDT 2017
Ported from chromeos-3.18 kernel.
Signed-off-by: Ulrich Hecht <ulrich.hecht+renesas at gmail.com>
---
drivers/platform/chrome/Kconfig | 18 +++
drivers/platform/chrome/Makefile | 2 +
drivers/platform/chrome/chromeos.c | 120 +++++++++++++++
drivers/platform/chrome/chromeos.h | 61 ++++++++
drivers/platform/chrome/chromeos_arm.c | 264 +++++++++++++++++++++++++++++++++
drivers/platform/chrome/elog.h | 186 +++++++++++++++++++++++
include/linux/chromeos_platform.h | 27 ++++
7 files changed, 678 insertions(+)
create mode 100644 drivers/platform/chrome/chromeos.c
create mode 100644 drivers/platform/chrome/chromeos.h
create mode 100644 drivers/platform/chrome/chromeos_arm.c
create mode 100644 drivers/platform/chrome/elog.h
create mode 100644 include/linux/chromeos_platform.h
diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
index 0ad6e29..f8b1876 100644
--- a/drivers/platform/chrome/Kconfig
+++ b/drivers/platform/chrome/Kconfig
@@ -14,6 +14,24 @@ menuconfig CHROME_PLATFORMS
if CHROME_PLATFORMS
+config CHROMEOS
+ bool
+ depends on CHROMEOS_OF_FIRMWARE || (NVRAM && ACPI_CHROMEOS)
+
+ ---help---
+ Provides abstracted interfaces to the firmware features provided on
+ ChromeOS devices. It depends on a lowlevel driver to implement the
+ firmware interface on the platform.
+
+config CHROMEOS_OF_FIRMWARE
+ bool "ChromeOS firmware interface driver"
+ depends on OF
+ select CHROMEOS
+ ---help---
+ This driver provides an interface to ChromeOS firmware.
+
+ Say Y here if you are building for a ChromeOS device.
+
config CHROMEOS_LAPTOP
tristate "Chrome OS Laptop"
depends on I2C && DMI && X86
diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile
index 66c345c..f10a7b6 100644
--- a/drivers/platform/chrome/Makefile
+++ b/drivers/platform/chrome/Makefile
@@ -1,4 +1,6 @@
+obj-$(CONFIG_CHROMEOS) += chromeos.o
+obj-$(CONFIG_CHROMEOS_OF_FIRMWARE) += chromeos_arm.o
obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o
obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o
cros_ec_devs-objs := cros_ec_dev.o cros_ec_sysfs.o \
diff --git a/drivers/platform/chrome/chromeos.c b/drivers/platform/chrome/chromeos.c
new file mode 100644
index 0000000..8b01630
--- /dev/null
+++ b/drivers/platform/chrome/chromeos.c
@@ -0,0 +1,120 @@
+/*
+ * ChromeOS platform support code. Glue layer between higher level functions
+ * and per-platform firmware interfaces.
+ *
+ * Copyright (C) 2010 The Chromium OS Authors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/chromeos_platform.h>
+#include <linux/module.h>
+#include "chromeos.h"
+
+static struct chromeos_vbc *chromeos_vbc_ptr;
+
+static int vbc_read(u8 *buf, int buf_size);
+static int vbc_write_byte(unsigned offset, u8 value);
+
+/* the following defines are copied from
+ * vboot_reference:firmware/lib/vboot_nvstorage.c.
+ */
+#define RECOVERY_OFFSET 2
+#define VBNV_RECOVERY_RW_INVALID_OS 0x43
+
+int chromeos_set_need_recovery(void)
+{
+ if (!chromeos_legacy_set_need_recovery())
+ return 0;
+
+ return vbc_write_byte(RECOVERY_OFFSET, VBNV_RECOVERY_RW_INVALID_OS);
+}
+EXPORT_SYMBOL(chromeos_set_need_recovery);
+
+/*
+ * Lifted from vboot_reference:firmware/lib/vboot_nvstorage.c and formatted.
+ *
+ * Return CRC-8 of the data, using x^8 + x^2 + x + 1 polynomial. A table-based
+ * algorithm would be faster, but for only 15 bytes isn't worth the code size.
+ */
+static u8 crc8(const u8 *data, int len)
+{
+ unsigned crc = 0;
+ int i, j;
+
+ for (j = len; j; j--, data++) {
+ crc ^= (*data << 8);
+ for (i = 8; i; i--) {
+ if (crc & 0x8000)
+ crc ^= (0x1070 << 3);
+ crc <<= 1;
+ }
+ }
+ return (u8)(crc >> 8);
+}
+
+static int vbc_write_byte(unsigned offset, u8 value)
+{
+ u8 buf[MAX_VBOOT_CONTEXT_BUFFER_SIZE];
+ ssize_t size;
+
+ if (!chromeos_vbc_ptr)
+ return -ENOSYS;
+
+ size = vbc_read(buf, sizeof(buf));
+ if (size <= 0)
+ return -EINVAL;
+
+ if (offset >= (size - 1))
+ return -EINVAL;
+
+ if (buf[offset] == value)
+ return 0;
+
+ buf[offset] = value;
+ buf[size - 1] = crc8(buf, size - 1);
+
+ return chromeos_vbc_ptr->write(buf, size);
+}
+
+/*
+ * Read vboot context and verify it. If everything checks out, return number
+ * of bytes in the vboot context buffer, -1 on any error (uninitialized
+ * subsystem, corrupted crc8 value, not enough room in the buffer, etc.).
+ */
+static int vbc_read(u8 *buf, int buf_size)
+{
+ ssize_t size;
+
+ if (!chromeos_vbc_ptr)
+ return -ENOSYS;
+
+ size = chromeos_vbc_ptr->read(buf, buf_size);
+ if (size <= 0)
+ return -1;
+
+ if (buf[size - 1] != crc8(buf, size - 1)) {
+ pr_err("%s: vboot context contents corrupted\n", __func__);
+ return -1;
+ }
+ return size;
+}
+
+int chromeos_vbc_register(struct chromeos_vbc *chromeos_vbc)
+{
+ chromeos_vbc_ptr = chromeos_vbc;
+ return 0;
+}
diff --git a/drivers/platform/chrome/chromeos.h b/drivers/platform/chrome/chromeos.h
new file mode 100644
index 0000000..8f4384a
--- /dev/null
+++ b/drivers/platform/chrome/chromeos.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 The Chromium OS Authors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef _DRIVERS_PLATFORM_CHROMEOS_H
+#define _DRIVERS_PLATFORM_CHROMEOS_H
+
+#define MAX_VBOOT_CONTEXT_BUFFER_SIZE 64 /* Should be enough for anything. */
+
+#ifdef CONFIG_ACPI_CHROMEOS
+extern int chromeos_legacy_set_need_recovery(void);
+#else
+static inline int chromeos_legacy_set_need_recovery(void) { return -ENODEV; }
+#endif
+
+struct chromeos_vbc {
+ /**
+ * Read vboot context to buffer
+ *
+ * @param buf Pointer to buffer for storing vboot context
+ * @param count Size of buffer
+ * @return on success, the number of bytes read is returned and
+ * on error, -err is returned.
+ */
+ ssize_t (*read)(void *buf, size_t count);
+
+ /**
+ * Write vboot context from buffer
+ *
+ * @param buf Pointer to buffer of new vboot context content
+ * @param count Size of buffer
+ * @return on success, the number of bytes written is returned and
+ * on error, -err is returned.
+ */
+ ssize_t (*write)(const void *buf, size_t count);
+
+ const char *name;
+};
+
+/**
+ * Register chromeos_vbc callbacks.
+ *
+ * @param chromeos_vbc Pointer to struct holding callbacks
+ * @return on success, return 0, on error, -err is returned.
+ */
+int chromeos_vbc_register(struct chromeos_vbc *chromeos_vbc);
+
+#endif /* _DRIVERS_PLATFORM_CHROMEOS_H */
diff --git a/drivers/platform/chrome/chromeos_arm.c b/drivers/platform/chrome/chromeos_arm.c
new file mode 100644
index 0000000..337e24d
--- /dev/null
+++ b/drivers/platform/chrome/chromeos_arm.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2011 The Chromium OS Authors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define pr_fmt(fmt) "chromeos_arm: " fmt
+
+#include <linux/bcd.h>
+#include <linux/gpio.h>
+#include <linux/notifier.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "chromeos.h"
+#include "elog.h"
+
+struct chromeos_arm_elog_panic_buffer {
+ uint32_t start;
+ uint32_t size;
+ void __iomem *virt_addr;
+ struct notifier_block nb;
+};
+
+/*
+ * Update the checksum at the last byte
+ */
+static void elog_update_checksum(struct event_header *event, u8 checksum)
+{
+ u8 *event_data = (u8 *)event;
+ event_data[event->length - 1] = checksum;
+}
+
+/*
+ * Simple byte checksum for events
+ */
+static u8 elog_checksum_event(struct event_header *event)
+{
+ u8 index, checksum = 0;
+ u8 *data = (u8 *)event;
+
+ for (index = 0; index < event->length; index++)
+ checksum += data[index];
+ return checksum;
+}
+
+/*
+ * Populate timestamp in event header with current time
+ */
+static void elog_fill_timestamp(struct event_header *event)
+{
+ struct timeval timeval;
+ struct tm time;
+
+ do_gettimeofday(&timeval);
+ time_to_tm(timeval.tv_sec, 0, &time);
+
+ event->second = bin2bcd(time.tm_sec);
+ event->minute = bin2bcd(time.tm_min);
+ event->hour = bin2bcd(time.tm_hour);
+ event->day = bin2bcd(time.tm_mday);
+ event->month = bin2bcd(time.tm_mon + 1);
+ event->year = bin2bcd(time.tm_year % 100);
+}
+
+/*
+ * Fill out an event structure with space for the data and checksum.
+ */
+void elog_prepare_event(struct event_header *event, u8 event_type, void *data,
+ u8 data_size)
+{
+ event->type = event_type;
+ event->length = sizeof(*event) + data_size + 1;
+ elog_fill_timestamp(event);
+
+ if (data_size)
+ memcpy(&event[1], data, data_size);
+
+ /* Zero the checksum byte and then compute checksum */
+ elog_update_checksum(event, 0);
+ elog_update_checksum(event, -(elog_checksum_event(event)));
+}
+
+static int chromeos_arm_elog_panic(struct notifier_block *this,
+ unsigned long p_event, void *ptr)
+{
+ struct chromeos_arm_elog_panic_buffer *buf;
+ uint32_t reason = ELOG_SHUTDOWN_PANIC;
+ const u8 data_size = sizeof(reason);
+ union {
+ struct event_header hdr;
+ u8 bytes[sizeof(struct event_header) + data_size + 1];
+ } event;
+
+ buf = container_of(this, struct chromeos_arm_elog_panic_buffer, nb);
+ elog_prepare_event(&event.hdr, ELOG_TYPE_OS_EVENT, &reason, data_size);
+ memcpy_toio(buf->virt_addr, event.bytes, sizeof(event.bytes));
+
+ return NOTIFY_DONE;
+}
+
+static int chromeos_arm_panic_init(struct platform_device *pdev, u32 start,
+ u32 size)
+{
+ int ret = -EINVAL;
+ struct chromeos_arm_elog_panic_buffer *buf;
+
+ buf = kmalloc(sizeof(*buf), GFP_KERNEL);
+ if (!buf) {
+ dev_err(&pdev->dev, "failed to allocate panic notifier.\n");
+ ret = -ENOMEM;
+ goto fail1;
+ }
+
+ buf->start = start;
+ buf->size = size;
+ buf->nb.notifier_call = chromeos_arm_elog_panic;
+
+ if (!request_mem_region(start, size, "elog panic event")) {
+ dev_err(&pdev->dev, "failed to request panic event buffer.\n");
+ goto fail2;
+ }
+
+ buf->virt_addr = ioremap(start, size);
+ if (!buf->virt_addr) {
+ dev_err(&pdev->dev, "failed to map panic event buffer.\n");
+ goto fail3;
+ }
+
+ atomic_notifier_chain_register(&panic_notifier_list, &buf->nb);
+
+ platform_set_drvdata(pdev, buf);
+
+ return 0;
+
+fail3:
+ release_mem_region(start, size);
+fail2:
+ kfree(buf);
+fail1:
+ return ret;
+}
+
+static int dt_gpio_init(struct platform_device *pdev, const char *of_list_name,
+ const char *gpio_desc_name, const char *sysfs_name)
+{
+ int gpio, err, active_low;
+ enum of_gpio_flags flags;
+ struct device_node *np = pdev->dev.of_node;
+
+ gpio = of_get_named_gpio_flags(np, of_list_name, 0, &flags);
+ if (!gpio_is_valid(gpio)) {
+ dev_err(&pdev->dev, "invalid %s descriptor\n", of_list_name);
+ return -EINVAL;
+ }
+
+ err = gpio_request_one(gpio, GPIOF_DIR_IN, gpio_desc_name);
+ if (err)
+ return err;
+
+ active_low = !!(flags & OF_GPIO_ACTIVE_LOW);
+// err = gpio_sysfs_set_active_low(gpio, active_low);
+// if (err)
+// return err;
+
+ gpio_export(gpio, 0);
+ gpio_export_link(&pdev->dev, sysfs_name, gpio);
+ return 0;
+}
+
+static int chromeos_arm_probe(struct platform_device *pdev)
+{
+ int err;
+ u32 elog_panic_event[2];
+ struct device_node *np = pdev->dev.of_node;
+
+ if (!np) {
+ err = -ENODEV;
+ goto err;
+ }
+
+ err = dt_gpio_init(pdev, "write-protect-gpio",
+ "firmware-write-protect", "write-protect");
+ if (err)
+ goto err;
+ err = dt_gpio_init(pdev, "recovery-switch",
+ "firmware-recovery-switch", "recovery-switch");
+ err = dt_gpio_init(pdev, "developer-switch",
+ "firmware-developer-switch", "developer-switch");
+
+ if (!of_property_read_u32_array(np, "elog-panic-event",
+ elog_panic_event,
+ ARRAY_SIZE(elog_panic_event))) {
+ err = chromeos_arm_panic_init(pdev, elog_panic_event[0],
+ elog_panic_event[1]);
+ if (err)
+ goto err;
+ }
+
+ dev_info(&pdev->dev, "chromeos system detected\n");
+
+ err = 0;
+err:
+ of_node_put(np);
+
+ return err;
+}
+
+static int chromeos_arm_remove(struct platform_device *pdev)
+{
+ struct chromeos_arm_elog_panic_buffer *buf;
+
+ buf = platform_get_drvdata(pdev);
+ platform_set_drvdata(pdev, NULL);
+ if (buf) {
+ atomic_notifier_chain_unregister(&panic_notifier_list,
+ &buf->nb);
+ release_mem_region(buf->start, buf->size);
+ iounmap(buf->virt_addr);
+ kfree(buf);
+ }
+ return 0;
+}
+
+static struct platform_driver chromeos_arm_driver = {
+ .probe = chromeos_arm_probe,
+ .remove = chromeos_arm_remove,
+ .driver = {
+ .name = "chromeos_arm",
+ },
+};
+
+static int __init chromeos_arm_init(void)
+{
+ struct device_node *fw_dn;
+ struct platform_device *pdev;
+
+ fw_dn = of_find_compatible_node(NULL, NULL, "chromeos-firmware");
+ if (!fw_dn)
+ return -ENODEV;
+
+ pdev = platform_device_register_simple("chromeos_arm", -1, NULL, 0);
+ pdev->dev.of_node = fw_dn;
+
+ platform_driver_register(&chromeos_arm_driver);
+
+ return 0;
+}
+subsys_initcall(chromeos_arm_init);
diff --git a/drivers/platform/chrome/elog.h b/drivers/platform/chrome/elog.h
new file mode 100644
index 0000000..84b005f
--- /dev/null
+++ b/drivers/platform/chrome/elog.h
@@ -0,0 +1,186 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#ifndef ELOG_H_
+#define ELOG_H_
+
+/* SMI command code for GSMI event logging */
+#define ELOG_GSMI_APM_CNT 0xEF
+
+#define MAX_EVENT_SIZE 0x7F
+
+/* End of log */
+#define ELOG_TYPE_EOL 0xFF
+
+/*
+ * Standard SMBIOS event log types below 0x80
+ */
+#define ELOG_TYPE_UNDEFINED_EVENT 0x00
+#define ELOG_TYPE_SINGLE_BIT_ECC_MEM_ERR 0x01
+#define ELOG_TYPE_MULTI_BIT_ECC_MEM_ERR 0x02
+#define ELOG_TYPE_MEM_PARITY_ERR 0x03
+#define ELOG_TYPE_BUS_TIMEOUT 0x04
+#define ELOG_TYPE_IO_CHECK 0x05
+#define ELOG_TYPE_SW_NMI 0x06
+#define ELOG_TYPE_POST_MEM_RESIZE 0x07
+#define ELOG_TYPE_POST_ERR 0x08
+#define ELOG_TYPE_PCI_PERR 0x09
+#define ELOG_TYPE_PCI_SERR 0x0A
+#define ELOG_TYPE_CPU_FAIL 0x0B
+#define ELOG_TYPE_EISA_TIMEOUT 0x0C
+#define ELOG_TYPE_CORRECTABLE_MEMLOG_DIS 0x0D
+#define ELOG_TYPE_LOG_DISABLED 0x0E
+#define ELOG_TYPE_UNDEFINED_EVENT2 0x0F
+#define ELOG_TYPE_SYS_LIMIT_EXCEED 0x10
+#define ELOG_TYPE_ASYNC_HW_TIMER_EXPIRED 0x11
+#define ELOG_TYPE_SYS_CONFIG_INFO 0x12
+#define ELOG_TYPE_HDD_INFO 0x13
+#define ELOG_TYPE_SYS_RECONFIG 0x14
+#define ELOG_TYPE_CPU_ERROR 0x15
+#define ELOG_TYPE_LOG_CLEAR 0x16
+#define ELOG_TYPE_BOOT 0x17
+
+/*
+ * Extended defined OEM event types start at 0x80
+ */
+
+/* OS/kernel events */
+#define ELOG_TYPE_OS_EVENT 0x81
+#define ELOG_SHUTDOWN_CLEAN 0 /* Clean Shutdown */
+#define ELOG_SHUTDOWN_NMIWDT 1 /* NMI Watchdog */
+#define ELOG_SHUTDOWN_PANIC 2 /* Panic */
+#define ELOG_SHUTDOWN_OOPS 3 /* Oops */
+#define ELOG_SHUTDOWN_DIE 4 /* Die - No longer meaningful */
+#define ELOG_SHUTDOWN_MCE 5 /* Machine Check */
+#define ELOG_SHUTDOWN_SOFTWDT 6 /* Software Watchdog */
+#define ELOG_SHUTDOWN_MBE 7 /* Uncorrected ECC */
+#define ELOG_SHUTDOWN_TRIPLE 8 /* Triple Fault */
+#define ELOG_SHUTDOWN_THERMAL 9 /* Critical Thermal Threshold */
+
+/* Last event from coreboot */
+#define ELOG_TYPE_OS_BOOT 0x90
+
+/* Embedded controller event */
+#define ELOG_TYPE_EC_EVENT 0x91
+#define EC_EVENT_LID_CLOSED 0x01
+#define EC_EVENT_LID_OPEN 0x02
+#define EC_EVENT_POWER_BUTTON 0x03
+#define EC_EVENT_AC_CONNECTED 0x04
+#define EC_EVENT_AC_DISCONNECTED 0x05
+#define EC_EVENT_BATTERY_LOW 0x06
+#define EC_EVENT_BATTERY_CRITICAL 0x07
+#define EC_EVENT_BATTERY 0x08
+#define EC_EVENT_THERMAL_THRESHOLD 0x09
+#define EC_EVENT_THERMAL_OVERLOAD 0x0a
+#define EC_EVENT_THERMAL 0x0b
+#define EC_EVENT_USB_CHARGER 0x0c
+#define EC_EVENT_KEY_PRESSED 0x0d
+#define EC_EVENT_INTERFACE_READY 0x0e
+#define EC_EVENT_KEYBOARD_RECOVERY 0x0f
+#define EC_EVENT_THERMAL_SHUTDOWN 0x10
+#define EC_EVENT_BATTERY_SHUTDOWN 0x11
+#define EC_EVENT_FAN_ERROR 0x12
+
+/* Power */
+#define ELOG_TYPE_POWER_FAIL 0x92
+#define ELOG_TYPE_SUS_POWER_FAIL 0x93
+#define ELOG_TYPE_PWROK_FAIL 0x94
+#define ELOG_TYPE_SYS_PWROK_FAIL 0x95
+#define ELOG_TYPE_POWER_ON 0x96
+#define ELOG_TYPE_POWER_BUTTON 0x97
+#define ELOG_TYPE_POWER_BUTTON_OVERRIDE 0x98
+
+/* Reset */
+#define ELOG_TYPE_RESET_BUTTON 0x99
+#define ELOG_TYPE_SYSTEM_RESET 0x9a
+#define ELOG_TYPE_RTC_RESET 0x9b
+#define ELOG_TYPE_TCO_RESET 0x9c
+
+/* Sleep/Wake */
+#define ELOG_TYPE_ACPI_ENTER 0x9d
+#define ELOG_TYPE_ACPI_WAKE 0x9e
+#define ELOG_TYPE_WAKE_SOURCE 0x9f
+#define ELOG_WAKE_SOURCE_PCIE 0x00
+#define ELOG_WAKE_SOURCE_PME 0x01
+#define ELOG_WAKE_SOURCE_PME_INTERNAL 0x02
+#define ELOG_WAKE_SOURCE_RTC 0x03
+#define ELOG_WAKE_SOURCE_GPIO 0x04
+#define ELOG_WAKE_SOURCE_SMBUS 0x05
+#define ELOG_WAKE_SOURCE_PWRBTN 0x06
+struct elog_event_data_wake {
+ u8 source;
+ u32 instance;
+} __packed;
+
+/* Chrome OS related events */
+#define ELOG_TYPE_CROS_DEVELOPER_MODE 0xa0
+#define ELOG_TYPE_CROS_RECOVERY_MODE 0xa1
+#define ELOG_CROS_RECOVERY_MODE_BUTTON 0x02
+
+/* Management Engine Events */
+#define ELOG_TYPE_MANAGEMENT_ENGINE 0xa2
+#define ELOG_TYPE_MANAGEMENT_ENGINE_EXT 0xa4
+struct elog_event_data_me_extended {
+ u8 current_working_state;
+ u8 operation_state;
+ u8 operation_mode;
+ u8 error_code;
+ u8 progress_code;
+ u8 current_pmevent;
+ u8 current_state;
+} __packed;
+
+/* Last post code from previous boot */
+#define ELOG_TYPE_LAST_POST_CODE 0xa3
+
+/* EC Shutdown Reason */
+#define ELOG_TYPE_EC_SHUTDOWN 0xa5
+
+/* ARM/generic versions of sleep/wake */
+#define ELOG_TYPE_SLEEP 0xa7
+#define ELOG_TYPE_WAKE 0xa8
+
+/* ELOG header */
+struct elog_header {
+ u32 magic;
+ u8 version;
+ u8 header_size;
+ u8 reserved[2];
+} __packed;
+
+/* ELOG related constants */
+#define ELOG_SIGNATURE 0x474f4c45 /* 'ELOG' */
+#define ELOG_VERSION 1
+
+/* SMBIOS event log header */
+struct event_header {
+ u8 type;
+ u8 length;
+ u8 year;
+ u8 month;
+ u8 day;
+ u8 hour;
+ u8 minute;
+ u8 second;
+} __packed;
+
+extern void elog_prepare_event(struct event_header *event, u8 event_type,
+ void *data, u8 data_size);
+
+#endif /* ELOG_H_ */
diff --git a/include/linux/chromeos_platform.h b/include/linux/chromeos_platform.h
new file mode 100644
index 0000000..32c4510
--- /dev/null
+++ b/include/linux/chromeos_platform.h
@@ -0,0 +1,27 @@
+#ifndef _LINUX_CHROMEOS_PLATFORM_H
+#define _LINUX_CHROMEOS_PLATFORM_H
+
+#include <linux/errno.h>
+#include <linux/types.h>
+
+#ifdef CONFIG_CHROMEOS
+/*
+ * ChromeOS platform support code. Glue layer between higher level functions
+ * and per-platform firmware interfaces.
+ */
+
+/*
+ * Set the taint bit telling firmware that the currently running side needs
+ * recovery (or reinstall).
+ */
+extern int chromeos_set_need_recovery(void);
+
+#else
+
+static inline int chromeos_set_need_recovery(void)
+{
+ return -ENODEV;
+}
+#endif /* CONFIG_CHROMEOS */
+
+#endif /* _LINUX_CHROMEOS_PLATFORM_H */
--
2.7.4
More information about the linux-arm-kernel
mailing list