aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/efi/Kconfig2
-rw-r--r--drivers/firmware/efi/cper-x86.c11
-rw-r--r--drivers/firmware/efi/efi.c2
-rw-r--r--drivers/firmware/efi/embedded-firmware.c2
-rw-r--r--drivers/firmware/xilinx/zynqmp.c64
5 files changed, 62 insertions, 19 deletions
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 36ec1f718893..d9895491ff34 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -270,7 +270,7 @@ config EFI_DEV_PATH_PARSER
config EFI_EARLYCON
def_bool y
- depends on SERIAL_EARLYCON && !ARM && !IA64
+ depends on EFI && SERIAL_EARLYCON && !ARM && !IA64
select FONT_SUPPORT
select ARCH_USE_MEMREMAP_PROT
diff --git a/drivers/firmware/efi/cper-x86.c b/drivers/firmware/efi/cper-x86.c
index 2531de49f56c..438ed9eff6d0 100644
--- a/drivers/firmware/efi/cper-x86.c
+++ b/drivers/firmware/efi/cper-x86.c
@@ -2,6 +2,7 @@
// Copyright (C) 2018, Advanced Micro Devices, Inc.
#include <linux/cper.h>
+#include <linux/acpi.h>
/*
* We don't need a "CPER_IA" prefix since these are all locally defined.
@@ -347,9 +348,13 @@ void cper_print_proc_ia(const char *pfx, const struct cper_sec_proc_ia *proc)
ctx_info->mm_reg_addr);
}
- printk("%sRegister Array:\n", newpfx);
- print_hex_dump(newpfx, "", DUMP_PREFIX_OFFSET, 16, groupsize,
- (ctx_info + 1), ctx_info->reg_arr_size, 0);
+ if (ctx_info->reg_ctx_type != CTX_TYPE_MSR ||
+ arch_apei_report_x86_error(ctx_info, proc->lapic_id)) {
+ printk("%sRegister Array:\n", newpfx);
+ print_hex_dump(newpfx, "", DUMP_PREFIX_OFFSET, 16,
+ groupsize, (ctx_info + 1),
+ ctx_info->reg_arr_size, 0);
+ }
ctx_info = (struct cper_ia_proc_ctx *)((long)ctx_info + size);
}
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 5e5480a0a32d..6c6eec044a97 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -390,10 +390,10 @@ static int __init efisubsys_init(void)
if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE |
EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME)) {
- efivar_ssdt_load();
error = generic_ops_register();
if (error)
goto err_put;
+ efivar_ssdt_load();
platform_device_register_simple("efivars", 0, NULL, 0);
}
diff --git a/drivers/firmware/efi/embedded-firmware.c b/drivers/firmware/efi/embedded-firmware.c
index 21ae0c48232a..f5be8e22305b 100644
--- a/drivers/firmware/efi/embedded-firmware.c
+++ b/drivers/firmware/efi/embedded-firmware.c
@@ -12,7 +12,7 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
-#include <crypto/sha.h>
+#include <crypto/sha2.h>
/* Exported for use by lib/test_firmware.c only */
LIST_HEAD(efi_embedded_fw_list);
diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index 8d1ff2454e2e..fd95edeb702b 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -20,12 +20,28 @@
#include <linux/of_platform.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
+#include <linux/hashtable.h>
#include <linux/firmware/xlnx-zynqmp.h>
#include "zynqmp-debug.h"
+/* Max HashMap Order for PM API feature check (1<<7 = 128) */
+#define PM_API_FEATURE_CHECK_MAX_ORDER 7
+
static bool feature_check_enabled;
-static u32 zynqmp_pm_features[PM_API_MAX];
+static DEFINE_HASHTABLE(pm_api_features_map, PM_API_FEATURE_CHECK_MAX_ORDER);
+
+/**
+ * struct pm_api_feature_data - PM API Feature data
+ * @pm_api_id: PM API Id, used as key to index into hashmap
+ * @feature_status: status of PM API feature: valid, invalid
+ * @hentry: hlist_node that hooks this entry into hashtable
+ */
+struct pm_api_feature_data {
+ u32 pm_api_id;
+ int feature_status;
+ struct hlist_node hentry;
+};
static const struct mfd_cell firmware_devs[] = {
{
@@ -142,26 +158,37 @@ static int zynqmp_pm_feature(u32 api_id)
int ret;
u32 ret_payload[PAYLOAD_ARG_CNT];
u64 smc_arg[2];
+ struct pm_api_feature_data *feature_data;
if (!feature_check_enabled)
return 0;
- /* Return value if feature is already checked */
- if (zynqmp_pm_features[api_id] != PM_FEATURE_UNCHECKED)
- return zynqmp_pm_features[api_id];
+ /* Check for existing entry in hash table for given api */
+ hash_for_each_possible(pm_api_features_map, feature_data, hentry,
+ api_id) {
+ if (feature_data->pm_api_id == api_id)
+ return feature_data->feature_status;
+ }
+
+ /* Add new entry if not present */
+ feature_data = kmalloc(sizeof(*feature_data), GFP_KERNEL);
+ if (!feature_data)
+ return -ENOMEM;
+ feature_data->pm_api_id = api_id;
smc_arg[0] = PM_SIP_SVC | PM_FEATURE_CHECK;
smc_arg[1] = api_id;
ret = do_fw_call(smc_arg[0], smc_arg[1], 0, ret_payload);
- if (ret) {
- zynqmp_pm_features[api_id] = PM_FEATURE_INVALID;
- return PM_FEATURE_INVALID;
- }
+ if (ret)
+ ret = -EOPNOTSUPP;
+ else
+ ret = ret_payload[1];
- zynqmp_pm_features[api_id] = ret_payload[1];
+ feature_data->feature_status = ret;
+ hash_add(pm_api_features_map, &feature_data->hentry, api_id);
- return zynqmp_pm_features[api_id];
+ return ret;
}
/**
@@ -197,9 +224,12 @@ int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 arg0, u32 arg1,
* Make sure to stay in x0 register
*/
u64 smc_arg[4];
+ int ret;
- if (zynqmp_pm_feature(pm_api_id) == PM_FEATURE_INVALID)
- return -ENOTSUPP;
+ /* Check if feature is supported or not */
+ ret = zynqmp_pm_feature(pm_api_id);
+ if (ret < 0)
+ return ret;
smc_arg[0] = PM_SIP_SVC | pm_api_id;
smc_arg[1] = ((u64)arg1 << 32) | arg0;
@@ -612,7 +642,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_set_sd_tapdelay);
*/
int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type)
{
- return zynqmp_pm_invoke_fn(PM_IOCTL, node_id, IOCTL_SET_SD_TAPDELAY,
+ return zynqmp_pm_invoke_fn(PM_IOCTL, node_id, IOCTL_SD_DLL_RESET,
type, 0, NULL);
}
EXPORT_SYMBOL_GPL(zynqmp_pm_sd_dll_reset);
@@ -1249,9 +1279,17 @@ static int zynqmp_firmware_probe(struct platform_device *pdev)
static int zynqmp_firmware_remove(struct platform_device *pdev)
{
+ struct pm_api_feature_data *feature_data;
+ int i;
+
mfd_remove_devices(&pdev->dev);
zynqmp_pm_api_debugfs_exit();
+ hash_for_each(pm_api_features_map, i, feature_data, hentry) {
+ hash_del(&feature_data->hentry);
+ kfree(feature_data);
+ }
+
return 0;
}