From 25f1ca31e230598eaf3c38d387a355a64bd772a7 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 16 Apr 2020 11:15:51 +0300 Subject: platform/x86: intel_pmc_ipc: Convert to MFD This driver only creates a bunch of platform devices sharing resources belonging to the PMC device. This is pretty much what MFD subsystem is for so move the driver there, renaming it to intel_pmc_bxt.c which should be more clear what it is. MFD subsystem provides nice helper APIs for subdevice creation so convert the driver to use those. Unfortunately the ACPI device includes separate resources for most of the subdevices so we cannot simply call mfd_add_devices() to create all of them but instead we need to call it separately for each device. The new MFD driver continues to expose two sysfs attributes that allow userspace to send IPC commands to the PMC/SCU to avoid breaking any existing applications that may use these. Generally this is bad idea so document this in the ABI documentation. Signed-off-by: Mika Westerberg Reviewed-by: Andy Shevchenko Signed-off-by: Lee Jones --- .../ABI/obsolete/sysfs-driver-intel_pmc_bxt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/ABI/obsolete/sysfs-driver-intel_pmc_bxt (limited to 'Documentation') diff --git a/Documentation/ABI/obsolete/sysfs-driver-intel_pmc_bxt b/Documentation/ABI/obsolete/sysfs-driver-intel_pmc_bxt new file mode 100644 index 000000000000..39d5659f388b --- /dev/null +++ b/Documentation/ABI/obsolete/sysfs-driver-intel_pmc_bxt @@ -0,0 +1,22 @@ +These files allow sending arbitrary IPC commands to the PMC/SCU which +may be dangerous. These will be removed eventually and should not be +used in any new applications. + +What: /sys/bus/platform/devices/INT34D2:00/simplecmd +Date: Jun 2015 +KernelVersion: 4.1 +Contact: Mika Westerberg +Description: This interface allows userspace to send an arbitrary + IPC command to the PMC/SCU. + + Format: %d %d where first number is command and + second number is subcommand. + +What: /sys/bus/platform/devices/INT34D2:00/northpeak +Date: Jun 2015 +KernelVersion: 4.1 +Contact: Mika Westerberg +Description: This interface allows userspace to enable and disable + Northpeak through the PMC/SCU. + + Format: %u. -- cgit v1.2.3 From 2d30fcdd439f766fa984df3854fd57c3c5daba7e Mon Sep 17 00:00:00 2001 From: Jithu Joseph Date: Mon, 27 Apr 2020 16:15:14 -0700 Subject: platform/x86: Add Slim Bootloader firmware update signaling driver Slim Bootloader(SBL) is a small open-source boot firmware, designed for running on certain Intel platforms. SBL can be thought-of as fulfilling the role of a minimal BIOS implementation, i.e initializing the hardware and booting Operating System. Since SBL is not UEFI compliant, firmware update cannot be triggered using standard UEFI runtime services. Further considering performance impact, SBL doesn't look for a firmware update image on every reset and does so only when firmware update signal is asserted. SBL exposes an ACPI-WMI device which comes up in sysfs as /sys/bus/wmi/44FADEB1xxx and this driver adds a "firmware_update_request" device attribute. This attribute normally has a value of 0 and userspace can signal SBL to update firmware, on next reboot, by writing a value of 1 like: echo 1 > /sys/bus/wmi/devices/44FADEB1xxx/firmware_update_request This driver only implements a signaling mechanism, the actual firmware update process and various details like firmware update image format, firmware image location etc are defined by SBL and are not in the scope of this driver. DocLink: https://slimbootloader.github.io/security/firmware-update.html Signed-off-by: Jithu Joseph Signed-off-by: Andy Shevchenko --- .../testing/sysfs-platform-intel-wmi-sbl-fw-update | 12 ++ MAINTAINERS | 7 + drivers/platform/x86/Kconfig | 10 ++ drivers/platform/x86/Makefile | 1 + drivers/platform/x86/intel-wmi-sbl-fw-update.c | 145 +++++++++++++++++++++ 5 files changed, 175 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-platform-intel-wmi-sbl-fw-update create mode 100644 drivers/platform/x86/intel-wmi-sbl-fw-update.c (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-platform-intel-wmi-sbl-fw-update b/Documentation/ABI/testing/sysfs-platform-intel-wmi-sbl-fw-update new file mode 100644 index 000000000000..5aa618987cad --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-intel-wmi-sbl-fw-update @@ -0,0 +1,12 @@ +What: /sys/bus/wmi/devices/44FADEB1-B204-40F2-8581-394BBDC1B651/firmware_update_request +Date: April 2020 +KernelVersion: 5.7 +Contact: "Jithu Joseph" +Description: + Allow user space entities to trigger update of Slim + Bootloader (SBL). This attribute normally has a value + of 0 and userspace can signal SBL to update firmware, + on next reboot, by writing a value of 1. + There are two available states: + * 0 -> Skip firmware update while rebooting + * 1 -> Attempt firmware update on next reboot diff --git a/MAINTAINERS b/MAINTAINERS index 4dd1b940c728..3759c99d41a3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8837,6 +8837,13 @@ F: Documentation/admin-guide/wimax/i2400m.rst F: drivers/net/wimax/i2400m/ F: include/uapi/linux/wimax/i2400m.h +INTEL WMI SLIM BOOTLOADER (SBL) FIRMWARE UPDATE DRIVER +M: Jithu Joseph +R: Maurice Ma +S: Maintained +W: https://slimbootloader.github.io/security/firmware-update.html +F: drivers/platform/x86/intel-wmi-sbl-fw-update.c + INTEL WMI THUNDERBOLT FORCE POWER DRIVER M: Mario Limonciello S: Maintained diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 4a888b5270e3..fb739b242796 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -78,6 +78,16 @@ config HUAWEI_WMI To compile this driver as a module, choose M here: the module will be called huawei-wmi. +config INTEL_WMI_SBL_FW_UPDATE + tristate "Intel WMI Slim Bootloader firmware update signaling driver" + depends on ACPI_WMI + help + Say Y here if you want to be able to use the WMI interface to signal + Slim Bootloader to trigger update on next reboot. + + To compile this driver as a module, choose M here: the module will + be called intel-wmi-sbl-fw-update. + config INTEL_WMI_THUNDERBOLT tristate "Intel WMI thunderbolt force power driver" depends on ACPI_WMI diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 70284a52f24f..2b85852a1a87 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_WMI_BMOF) += wmi-bmof.o # WMI drivers obj-$(CONFIG_ALIENWARE_WMI) += alienware-wmi.o obj-$(CONFIG_HUAWEI_WMI) += huawei-wmi.o +obj-$(CONFIG_INTEL_WMI_SBL_FW_UPDATE) += intel-wmi-sbl-fw-update.o obj-$(CONFIG_INTEL_WMI_THUNDERBOLT) += intel-wmi-thunderbolt.o obj-$(CONFIG_MXM_WMI) += mxm-wmi.o obj-$(CONFIG_PEAQ_WMI) += peaq-wmi.o diff --git a/drivers/platform/x86/intel-wmi-sbl-fw-update.c b/drivers/platform/x86/intel-wmi-sbl-fw-update.c new file mode 100644 index 000000000000..ea87fa0786e8 --- /dev/null +++ b/drivers/platform/x86/intel-wmi-sbl-fw-update.c @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Slim Bootloader(SBL) firmware update signaling driver + * + * Slim Bootloader is a small, open-source, non UEFI compliant, boot firmware + * optimized for running on certain Intel platforms. + * + * SBL exposes an ACPI-WMI device via /sys/bus/wmi/devices/. + * This driver further adds "firmware_update_request" device attribute. + * This attribute normally has a value of 0 and userspace can signal SBL + * to update firmware, on next reboot, by writing a value of 1. + * + * More details of SBL firmware update process is available at: + * https://slimbootloader.github.io/security/firmware-update.html + */ + +#include +#include +#include +#include +#include +#include + +#define INTEL_WMI_SBL_GUID "44FADEB1-B204-40F2-8581-394BBDC1B651" + +static int get_fwu_request(struct device *dev, u32 *out) +{ + struct acpi_buffer result = {ACPI_ALLOCATE_BUFFER, NULL}; + union acpi_object *obj; + acpi_status status; + + status = wmi_query_block(INTEL_WMI_SBL_GUID, 0, &result); + if (ACPI_FAILURE(status)) { + dev_err(dev, "wmi_query_block failed\n"); + return -ENODEV; + } + + obj = (union acpi_object *)result.pointer; + if (!obj || obj->type != ACPI_TYPE_INTEGER) { + dev_warn(dev, "wmi_query_block returned invalid value\n"); + kfree(obj); + return -EINVAL; + } + + *out = obj->integer.value; + kfree(obj); + + return 0; +} + +static int set_fwu_request(struct device *dev, u32 in) +{ + struct acpi_buffer input; + acpi_status status; + u32 value; + + value = in; + input.length = sizeof(u32); + input.pointer = &value; + + status = wmi_set_block(INTEL_WMI_SBL_GUID, 0, &input); + if (ACPI_FAILURE(status)) { + dev_err(dev, "wmi_set_block failed\n"); + return -ENODEV; + } + + return 0; +} + +static ssize_t firmware_update_request_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + u32 val; + int ret; + + ret = get_fwu_request(dev, &val); + if (ret) + return ret; + + return sprintf(buf, "%d\n", val); +} + +static ssize_t firmware_update_request_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned int val; + int ret; + + ret = kstrtouint(buf, 0, &val); + if (ret) + return ret; + + /* May later be extended to support values other than 0 and 1 */ + if (val > 1) + return -ERANGE; + + ret = set_fwu_request(dev, val); + if (ret) + return ret; + + return count; +} +static DEVICE_ATTR_RW(firmware_update_request); + +static struct attribute *firmware_update_attrs[] = { + &dev_attr_firmware_update_request.attr, + NULL +}; +ATTRIBUTE_GROUPS(firmware_update); + +static int intel_wmi_sbl_fw_update_probe(struct wmi_device *wdev, + const void *context) +{ + dev_info(&wdev->dev, "Slim Bootloader signaling driver attached\n"); + return 0; +} + +static int intel_wmi_sbl_fw_update_remove(struct wmi_device *wdev) +{ + dev_info(&wdev->dev, "Slim Bootloader signaling driver removed\n"); + return 0; +} + +static const struct wmi_device_id intel_wmi_sbl_id_table[] = { + { .guid_string = INTEL_WMI_SBL_GUID }, + {} +}; +MODULE_DEVICE_TABLE(wmi, intel_wmi_sbl_id_table); + +static struct wmi_driver intel_wmi_sbl_fw_update_driver = { + .driver = { + .name = "intel-wmi-sbl-fw-update", + .dev_groups = firmware_update_groups, + }, + .probe = intel_wmi_sbl_fw_update_probe, + .remove = intel_wmi_sbl_fw_update_remove, + .id_table = intel_wmi_sbl_id_table, +}; +module_wmi_driver(intel_wmi_sbl_fw_update_driver); + +MODULE_AUTHOR("Jithu Joseph "); +MODULE_DESCRIPTION("Slim Bootloader firmware update signaling driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3