diff options
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/edd.c | 8 | ||||
-rw-r--r-- | drivers/firmware/iscsi_ibft.c | 5 | ||||
-rw-r--r-- | drivers/firmware/psci.c | 55 | ||||
-rw-r--r-- | drivers/firmware/qemu_fw_cfg.c | 4 |
4 files changed, 58 insertions, 14 deletions
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c index e22957665808..60a8f1363a10 100644 --- a/drivers/firmware/edd.c +++ b/drivers/firmware/edd.c @@ -669,10 +669,10 @@ edd_get_pci_dev(struct edd_device *edev) struct edd_info *info = edd_dev_get_info(edev); if (edd_dev_is_type(edev, "PCI") || edd_dev_is_type(edev, "XPRS")) { - return pci_get_bus_and_slot(info->params.interface_path.pci.bus, - PCI_DEVFN(info->params.interface_path.pci.slot, - info->params.interface_path.pci. - function)); + return pci_get_domain_bus_and_slot(0, + info->params.interface_path.pci.bus, + PCI_DEVFN(info->params.interface_path.pci.slot, + info->params.interface_path.pci.function)); } return NULL; } diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c index 14042a64bdd5..6bc8e6640d71 100644 --- a/drivers/firmware/iscsi_ibft.c +++ b/drivers/firmware/iscsi_ibft.c @@ -719,8 +719,9 @@ static int __init ibft_create_kobject(struct acpi_table_ibft *header, * executes only devices which are in domain 0. Furthermore, the * iBFT spec doesn't have a domain id field :-( */ - pci_dev = pci_get_bus_and_slot((nic->pci_bdf & 0xff00) >> 8, - (nic->pci_bdf & 0xff)); + pci_dev = pci_get_domain_bus_and_slot(0, + (nic->pci_bdf & 0xff00) >> 8, + (nic->pci_bdf & 0xff)); if (pci_dev) { rc = sysfs_create_link(&boot_kobj->kobj, &pci_dev->dev.kobj, "device"); diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c index 8b25d31e8401..c80ec1d03274 100644 --- a/drivers/firmware/psci.c +++ b/drivers/firmware/psci.c @@ -59,7 +59,10 @@ bool psci_tos_resident_on(int cpu) return cpu == resident_cpu; } -struct psci_operations psci_ops; +struct psci_operations psci_ops = { + .conduit = PSCI_CONDUIT_NONE, + .smccc_version = SMCCC_VERSION_1_0, +}; typedef unsigned long (psci_fn)(unsigned long, unsigned long, unsigned long, unsigned long); @@ -210,6 +213,22 @@ static unsigned long psci_migrate_info_up_cpu(void) 0, 0, 0); } +static void set_conduit(enum psci_conduit conduit) +{ + switch (conduit) { + case PSCI_CONDUIT_HVC: + invoke_psci_fn = __invoke_psci_fn_hvc; + break; + case PSCI_CONDUIT_SMC: + invoke_psci_fn = __invoke_psci_fn_smc; + break; + default: + WARN(1, "Unexpected PSCI conduit %d\n", conduit); + } + + psci_ops.conduit = conduit; +} + static int get_set_conduit_method(struct device_node *np) { const char *method; @@ -222,9 +241,9 @@ static int get_set_conduit_method(struct device_node *np) } if (!strcmp("hvc", method)) { - invoke_psci_fn = __invoke_psci_fn_hvc; + set_conduit(PSCI_CONDUIT_HVC); } else if (!strcmp("smc", method)) { - invoke_psci_fn = __invoke_psci_fn_smc; + set_conduit(PSCI_CONDUIT_SMC); } else { pr_warn("invalid \"method\" property: %s\n", method); return -EINVAL; @@ -493,6 +512,31 @@ static void __init psci_init_migrate(void) pr_info("Trusted OS resident on physical CPU 0x%lx\n", cpuid); } +static void __init psci_init_smccc(void) +{ + u32 ver = ARM_SMCCC_VERSION_1_0; + int feature; + + feature = psci_features(ARM_SMCCC_VERSION_FUNC_ID); + + if (feature != PSCI_RET_NOT_SUPPORTED) { + u32 ret; + ret = invoke_psci_fn(ARM_SMCCC_VERSION_FUNC_ID, 0, 0, 0); + if (ret == ARM_SMCCC_VERSION_1_1) { + psci_ops.smccc_version = SMCCC_VERSION_1_1; + ver = ret; + } + } + + /* + * Conveniently, the SMCCC and PSCI versions are encoded the + * same way. No, this isn't accidental. + */ + pr_info("SMC Calling Convention v%d.%d\n", + PSCI_VERSION_MAJOR(ver), PSCI_VERSION_MINOR(ver)); + +} + static void __init psci_0_2_set_functions(void) { pr_info("Using standard PSCI v0.2 function IDs\n"); @@ -541,6 +585,7 @@ static int __init psci_probe(void) psci_init_migrate(); if (PSCI_VERSION_MAJOR(ver) >= 1) { + psci_init_smccc(); psci_init_cpu_suspend(); psci_init_system_suspend(); } @@ -654,9 +699,9 @@ int __init psci_acpi_init(void) pr_info("probing for conduit method from ACPI.\n"); if (acpi_psci_use_hvc()) - invoke_psci_fn = __invoke_psci_fn_hvc; + set_conduit(PSCI_CONDUIT_HVC); else - invoke_psci_fn = __invoke_psci_fn_smc; + set_conduit(PSCI_CONDUIT_SMC); return psci_probe(); } diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index deb483064f53..a41b572eeeb1 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -694,10 +694,8 @@ static int fw_cfg_cmdline_set(const char *arg, const struct kernel_param *kp) */ fw_cfg_cmdline_dev = platform_device_register_simple("fw_cfg", PLATFORM_DEVID_NONE, res, processed); - if (IS_ERR(fw_cfg_cmdline_dev)) - return PTR_ERR(fw_cfg_cmdline_dev); - return 0; + return PTR_ERR_OR_ZERO(fw_cfg_cmdline_dev); } static int fw_cfg_cmdline_get(char *buf, const struct kernel_param *kp) |