diff options
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/arm_scmi/driver.c | 2 | ||||
-rw-r--r-- | drivers/firmware/arm_scmi/scmi_pm_domain.c | 4 | ||||
-rw-r--r-- | drivers/firmware/efi/apple-properties.c | 2 | ||||
-rw-r--r-- | drivers/firmware/efi/efi.c | 2 | ||||
-rw-r--r-- | drivers/firmware/efi/vars.c | 5 | ||||
-rw-r--r-- | drivers/firmware/google/Kconfig | 8 | ||||
-rw-r--r-- | drivers/firmware/imx/imx-scu-irq.c | 60 | ||||
-rw-r--r-- | drivers/firmware/imx/seco_mu.c | 6 | ||||
-rw-r--r-- | drivers/firmware/psci/psci.c | 15 | ||||
-rw-r--r-- | drivers/firmware/qemu_fw_cfg.c | 20 | ||||
-rw-r--r-- | drivers/firmware/scpi_pm_domain.c | 10 |
11 files changed, 102 insertions, 32 deletions
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 4e43bdfa041f..f0b055bc027c 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -983,7 +983,7 @@ static struct platform_driver scmi_driver = { module_platform_driver(scmi_driver); -MODULE_ALIAS("platform: arm-scmi"); +MODULE_ALIAS("platform:arm-scmi"); MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>"); MODULE_DESCRIPTION("ARM SCMI protocol driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/firmware/arm_scmi/scmi_pm_domain.c b/drivers/firmware/arm_scmi/scmi_pm_domain.c index 041f8152272b..177874adccf0 100644 --- a/drivers/firmware/arm_scmi/scmi_pm_domain.c +++ b/drivers/firmware/arm_scmi/scmi_pm_domain.c @@ -106,9 +106,7 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev) scmi_pd_data->domains = domains; scmi_pd_data->num_domains = num_domains; - of_genpd_add_provider_onecell(np, scmi_pd_data); - - return 0; + return of_genpd_add_provider_onecell(np, scmi_pd_data); } static const struct scmi_device_id scmi_id_table[] = { diff --git a/drivers/firmware/efi/apple-properties.c b/drivers/firmware/efi/apple-properties.c index 0e206c9e0d7a..7ad2d85d7270 100644 --- a/drivers/firmware/efi/apple-properties.c +++ b/drivers/firmware/efi/apple-properties.c @@ -23,7 +23,7 @@ static bool dump_properties __initdata; static int __init dump_properties_enable(char *arg) { dump_properties = true; - return 0; + return 1; } __setup("dump_apple_properties", dump_properties_enable); diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 415d7b3a59f8..8fd74a7501d4 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -231,7 +231,7 @@ static int __init efivar_ssdt_setup(char *str) memcpy(efivar_ssdt, str, strlen(str)); else pr_warn("efivar_ssdt: name too long: %s\n", str); - return 0; + return 1; } __setup("efivar_ssdt=", efivar_ssdt_setup); diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c index 436d1776bc7b..a32d15b2928f 100644 --- a/drivers/firmware/efi/vars.c +++ b/drivers/firmware/efi/vars.c @@ -750,6 +750,7 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes, { const struct efivar_operations *ops; efi_status_t status; + unsigned long varsize; if (!__efivars) return -EINVAL; @@ -772,15 +773,17 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes, return efivar_entry_set_nonblocking(name, vendor, attributes, size, data); + varsize = size + ucs2_strsize(name, 1024); if (!block) { if (down_trylock(&efivars_lock)) return -EBUSY; + status = check_var_size_nonblocking(attributes, varsize); } else { if (down_interruptible(&efivars_lock)) return -EINTR; + status = check_var_size(attributes, varsize); } - status = check_var_size(attributes, size + ucs2_strsize(name, 1024)); if (status != EFI_SUCCESS) { up(&efivars_lock); return -ENOSPC; diff --git a/drivers/firmware/google/Kconfig b/drivers/firmware/google/Kconfig index a3a6ca659ffa..20dfe39a0537 100644 --- a/drivers/firmware/google/Kconfig +++ b/drivers/firmware/google/Kconfig @@ -3,9 +3,9 @@ menuconfig GOOGLE_FIRMWARE bool "Google Firmware Drivers" default n help - These firmware drivers are used by Google's servers. They are - only useful if you are working directly on one of their - proprietary servers. If in doubt, say "N". + These firmware drivers are used by Google servers, + Chromebooks and other devices using coreboot firmware. + If in doubt, say "N". if GOOGLE_FIRMWARE @@ -21,7 +21,7 @@ config GOOGLE_SMI config GOOGLE_COREBOOT_TABLE tristate "Coreboot Table Access" - depends on ACPI || OF + depends on HAS_IOMEM && (ACPI || OF) help This option enables the coreboot_table module, which provides other firmware modules access to the coreboot table. The coreboot table diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c index 369621c14105..b4272a75a315 100644 --- a/drivers/firmware/imx/imx-scu-irq.c +++ b/drivers/firmware/imx/imx-scu-irq.c @@ -10,10 +10,11 @@ #include <linux/firmware/imx/sci.h> #include <linux/mailbox_client.h> #include <linux/suspend.h> +#include <linux/sysfs.h> +#include <linux/kobject.h> #define IMX_SC_IRQ_FUNC_ENABLE 1 #define IMX_SC_IRQ_FUNC_STATUS 2 -#define IMX_SC_IRQ_NUM_GROUP 7 static u32 mu_resource_id; @@ -39,6 +40,20 @@ struct imx_sc_msg_irq_enable { u8 enable; } __packed; +struct scu_wakeup { + u32 mask; + u32 wakeup_src; + bool valid; +}; + +/* Sysfs functions */ +struct kobject *wakeup_obj; +static ssize_t wakeup_source_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +static struct kobj_attribute wakeup_source_attr = __ATTR(wakeup_src, 0660, wakeup_source_show, NULL); + +static struct scu_wakeup scu_irq_wakeup[IMX_SC_IRQ_NUM_GROUP]; + + static struct imx_sc_ipc *imx_sc_irq_ipc_handle; static struct work_struct imx_sc_irq_work; static BLOCKING_NOTIFIER_HEAD(imx_scu_irq_notifier_chain); @@ -70,6 +85,10 @@ static void imx_scu_irq_work_handler(struct work_struct *work) u8 i; for (i = 0; i < IMX_SC_IRQ_NUM_GROUP; i++) { + if (scu_irq_wakeup[i].mask) { + scu_irq_wakeup[i].valid = false; + scu_irq_wakeup[i].wakeup_src = 0; + } ret = imx_scu_irq_get_status(i, &irq_status); if (ret) { pr_err("get irq group %d status failed, ret %d\n", @@ -79,7 +98,12 @@ static void imx_scu_irq_work_handler(struct work_struct *work) if (!irq_status) continue; - + if (scu_irq_wakeup[i].mask & irq_status) { + scu_irq_wakeup[i].valid = true; + scu_irq_wakeup[i].wakeup_src = irq_status & scu_irq_wakeup[i].mask; + } else { + scu_irq_wakeup[i].wakeup_src = irq_status; + } pm_system_wakeup(); imx_scu_irq_notifier_call_chain(irq_status, &i); } @@ -134,6 +158,11 @@ int imx_scu_irq_group_enable(u8 group, u32 mask, u8 enable) pr_err("enable irq failed, group %d, mask %d, ret %d\n", group, mask, ret); + if (enable) + scu_irq_wakeup[group].mask |= mask; + else + scu_irq_wakeup[group].mask &= ~mask; + return ret; } EXPORT_SYMBOL(imx_scu_irq_group_enable); @@ -143,6 +172,24 @@ static void imx_scu_irq_callback(struct mbox_client *c, void *msg) schedule_work(&imx_sc_irq_work); } +static ssize_t wakeup_source_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + u8 i = 0, size = 0; + + for (i = 0; i < IMX_SC_IRQ_NUM_GROUP; i++) { + if (scu_irq_wakeup[i].wakeup_src != 0) { + if (scu_irq_wakeup[i].valid) + size += sprintf(buf + size, "Wakeup source group = %d, irq = 0x%x\n", + i, scu_irq_wakeup[i].wakeup_src); + else + size += sprintf(buf + size, "Spurious SCU wakeup, group = %d, irq = 0x%x\n", + i, scu_irq_wakeup[i].wakeup_src); + } + } + return strlen(buf); +} + int imx_scu_enable_general_irq_channel(struct device *dev) { struct of_phandle_args spec; @@ -182,6 +229,15 @@ int imx_scu_enable_general_irq_channel(struct device *dev) mu_resource_id = IMX_SC_R_MU_0A + i; + /* Create directory under /sysfs/firmware */ + wakeup_obj = kobject_create_and_add("scu_wakeup_source", firmware_kobj); + + if (sysfs_create_file(wakeup_obj, &wakeup_source_attr.attr)) { + pr_err("Cannot create sysfs file......\n"); + kobject_put(wakeup_obj); + sysfs_remove_file(firmware_kobj, &wakeup_source_attr.attr); + } + return ret; } EXPORT_SYMBOL(imx_scu_enable_general_irq_channel); diff --git a/drivers/firmware/imx/seco_mu.c b/drivers/firmware/imx/seco_mu.c index d3633d0f286a..75744e4197f9 100644 --- a/drivers/firmware/imx/seco_mu.c +++ b/drivers/firmware/imx/seco_mu.c @@ -91,8 +91,6 @@ #define MAX_DATA_SIZE_PER_USER (65 * 1024) -#define SC_IRQ_V2X_RESET (1<<7) - /* Header of the messages exchange with the SECO */ struct she_mu_hdr { u8 ver; @@ -1017,7 +1015,7 @@ static int imx_sc_v2x_reset_notify(struct notifier_block *nb, struct seco_mu_device_ctx *dev_ctx = container_of(nb, struct seco_mu_device_ctx, scu_notify); - if (!(event & SC_IRQ_V2X_RESET)) + if (!(event & IMX_SC_IRQ_V2X_RESET)) return 0; dev_ctx->v2x_reset = true; @@ -1179,7 +1177,7 @@ static int seco_mu_probe(struct platform_device *pdev) } ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_WAKE, - SC_IRQ_V2X_RESET, true); + IMX_SC_IRQ_V2X_RESET, true); if (ret) { dev_warn(&pdev->dev, "v2x Enable irq failed.\n"); return ret; diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c index 84f4ff351c62..eb797081d159 100644 --- a/drivers/firmware/psci/psci.c +++ b/drivers/firmware/psci/psci.c @@ -57,6 +57,21 @@ struct psci_operations psci_ops = { .smccc_version = SMCCC_VERSION_1_0, }; +enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void) +{ + if (psci_ops.smccc_version < SMCCC_VERSION_1_1) + return SMCCC_CONDUIT_NONE; + + switch (psci_ops.conduit) { + case PSCI_CONDUIT_SMC: + return SMCCC_CONDUIT_SMC; + case PSCI_CONDUIT_HVC: + return SMCCC_CONDUIT_HVC; + default: + return SMCCC_CONDUIT_NONE; + } +} + typedef unsigned long (psci_fn)(unsigned long, unsigned long, unsigned long, unsigned long); static psci_fn *invoke_psci_fn; diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index 59db70fb4561..314b9bb78e43 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -385,9 +385,7 @@ static void fw_cfg_sysfs_cache_cleanup(void) struct fw_cfg_sysfs_entry *entry, *next; list_for_each_entry_safe(entry, next, &fw_cfg_entry_cache, list) { - /* will end up invoking fw_cfg_sysfs_cache_delist() - * via each object's release() method (i.e. destructor) - */ + fw_cfg_sysfs_cache_delist(entry); kobject_put(&entry->kobj); } } @@ -445,7 +443,6 @@ static void fw_cfg_sysfs_release_entry(struct kobject *kobj) { struct fw_cfg_sysfs_entry *entry = to_entry(kobj); - fw_cfg_sysfs_cache_delist(entry); kfree(entry); } @@ -598,20 +595,18 @@ static int fw_cfg_register_file(const struct fw_cfg_file *f) /* set file entry information */ entry->size = be32_to_cpu(f->size); entry->select = be16_to_cpu(f->select); - memcpy(entry->name, f->name, FW_CFG_MAX_FILE_PATH); + strscpy(entry->name, f->name, FW_CFG_MAX_FILE_PATH); /* register entry under "/sys/firmware/qemu_fw_cfg/by_key/" */ err = kobject_init_and_add(&entry->kobj, &fw_cfg_sysfs_entry_ktype, fw_cfg_sel_ko, "%d", entry->select); - if (err) { - kobject_put(&entry->kobj); - return err; - } + if (err) + goto err_put_entry; /* add raw binary content access */ err = sysfs_create_bin_file(&entry->kobj, &fw_cfg_sysfs_attr_raw); if (err) - goto err_add_raw; + goto err_del_entry; /* try adding "/sys/firmware/qemu_fw_cfg/by_name/" symlink */ fw_cfg_build_symlink(fw_cfg_fname_kset, &entry->kobj, entry->name); @@ -620,9 +615,10 @@ static int fw_cfg_register_file(const struct fw_cfg_file *f) fw_cfg_sysfs_cache_enlist(entry); return 0; -err_add_raw: +err_del_entry: kobject_del(&entry->kobj); - kfree(entry); +err_put_entry: + kobject_put(&entry->kobj); return err; } diff --git a/drivers/firmware/scpi_pm_domain.c b/drivers/firmware/scpi_pm_domain.c index 51201600d789..800673910b51 100644 --- a/drivers/firmware/scpi_pm_domain.c +++ b/drivers/firmware/scpi_pm_domain.c @@ -16,7 +16,6 @@ struct scpi_pm_domain { struct generic_pm_domain genpd; struct scpi_ops *ops; u32 domain; - char name[30]; }; /* @@ -110,8 +109,13 @@ static int scpi_pm_domain_probe(struct platform_device *pdev) scpi_pd->domain = i; scpi_pd->ops = scpi_ops; - sprintf(scpi_pd->name, "%pOFn.%d", np, i); - scpi_pd->genpd.name = scpi_pd->name; + scpi_pd->genpd.name = devm_kasprintf(dev, GFP_KERNEL, + "%pOFn.%d", np, i); + if (!scpi_pd->genpd.name) { + dev_err(dev, "Failed to allocate genpd name:%pOFn.%d\n", + np, i); + continue; + } scpi_pd->genpd.power_off = scpi_pd_power_off; scpi_pd->genpd.power_on = scpi_pd_power_on; |