diff options
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/arm_scmi/perf.c | 5 | ||||
-rw-r--r-- | drivers/firmware/dmi-id.c | 2 | ||||
-rw-r--r-- | drivers/firmware/dmi_scan.c | 1 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/tpm.c | 2 | ||||
-rw-r--r-- | drivers/firmware/psci_checker.c | 83 | ||||
-rw-r--r-- | drivers/firmware/raspberrypi.c | 29 |
6 files changed, 80 insertions, 42 deletions
diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c index 2a219b1261b1..721e6c57beae 100644 --- a/drivers/firmware/arm_scmi/perf.c +++ b/drivers/firmware/arm_scmi/perf.c @@ -363,8 +363,6 @@ static int scmi_dvfs_device_opps_add(const struct scmi_handle *handle, return domain; dom = pi->dom_info + domain; - if (!dom) - return -EIO; for (opp = dom->opp, idx = 0; idx < dom->opp_count; idx++, opp++) { freq = opp->perf * dom->mult_factor; @@ -394,9 +392,6 @@ static int scmi_dvfs_transition_latency_get(const struct scmi_handle *handle, return domain; dom = pi->dom_info + domain; - if (!dom) - return -EIO; - /* uS to nS */ return dom->opp[dom->opp_count - 1].trans_latency_us * 1000; } diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c index 951b6c79f166..624a11cb07e2 100644 --- a/drivers/firmware/dmi-id.c +++ b/drivers/firmware/dmi-id.c @@ -47,6 +47,7 @@ DEFINE_DMI_ATTR_WITH_SHOW(product_name, 0444, DMI_PRODUCT_NAME); DEFINE_DMI_ATTR_WITH_SHOW(product_version, 0444, DMI_PRODUCT_VERSION); DEFINE_DMI_ATTR_WITH_SHOW(product_serial, 0400, DMI_PRODUCT_SERIAL); DEFINE_DMI_ATTR_WITH_SHOW(product_uuid, 0400, DMI_PRODUCT_UUID); +DEFINE_DMI_ATTR_WITH_SHOW(product_sku, 0444, DMI_PRODUCT_SKU); DEFINE_DMI_ATTR_WITH_SHOW(product_family, 0444, DMI_PRODUCT_FAMILY); DEFINE_DMI_ATTR_WITH_SHOW(board_vendor, 0444, DMI_BOARD_VENDOR); DEFINE_DMI_ATTR_WITH_SHOW(board_name, 0444, DMI_BOARD_NAME); @@ -193,6 +194,7 @@ static void __init dmi_id_init_attr_table(void) ADD_DMI_ATTR(product_serial, DMI_PRODUCT_SERIAL); ADD_DMI_ATTR(product_uuid, DMI_PRODUCT_UUID); ADD_DMI_ATTR(product_family, DMI_PRODUCT_FAMILY); + ADD_DMI_ATTR(product_sku, DMI_PRODUCT_SKU); ADD_DMI_ATTR(board_vendor, DMI_BOARD_VENDOR); ADD_DMI_ATTR(board_name, DMI_BOARD_NAME); ADD_DMI_ATTR(board_version, DMI_BOARD_VERSION); diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 54e66adef252..f2483548cde9 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -447,6 +447,7 @@ static void __init dmi_decode(const struct dmi_header *dm, void *dummy) dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6); dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7); dmi_save_uuid(dm, DMI_PRODUCT_UUID, 8); + dmi_save_ident(dm, DMI_PRODUCT_SKU, 25); dmi_save_ident(dm, DMI_PRODUCT_FAMILY, 26); break; case 2: /* Base Board Information */ diff --git a/drivers/firmware/efi/libstub/tpm.c b/drivers/firmware/efi/libstub/tpm.c index caa37a6dd9d4..a90b0b8fc69a 100644 --- a/drivers/firmware/efi/libstub/tpm.c +++ b/drivers/firmware/efi/libstub/tpm.c @@ -64,7 +64,7 @@ static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg) efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID; efi_guid_t linux_eventlog_guid = LINUX_EFI_TPM_EVENT_LOG_GUID; efi_status_t status; - efi_physical_addr_t log_location, log_last_entry; + efi_physical_addr_t log_location = 0, log_last_entry = 0; struct linux_efi_tpm_eventlog *log_tbl = NULL; unsigned long first_entry_addr, last_entry_addr; size_t log_size, last_entry_size; diff --git a/drivers/firmware/psci_checker.c b/drivers/firmware/psci_checker.c index bb1c068bff19..346943657962 100644 --- a/drivers/firmware/psci_checker.c +++ b/drivers/firmware/psci_checker.c @@ -77,28 +77,6 @@ static int psci_ops_check(void) return 0; } -static int find_cpu_groups(const struct cpumask *cpus, - const struct cpumask **cpu_groups) -{ - unsigned int nb = 0; - cpumask_var_t tmp; - - if (!alloc_cpumask_var(&tmp, GFP_KERNEL)) - return -ENOMEM; - cpumask_copy(tmp, cpus); - - while (!cpumask_empty(tmp)) { - const struct cpumask *cpu_group = - topology_core_cpumask(cpumask_any(tmp)); - - cpu_groups[nb++] = cpu_group; - cpumask_andnot(tmp, tmp, cpu_group); - } - - free_cpumask_var(tmp); - return nb; -} - /* * offlined_cpus is a temporary array but passing it as an argument avoids * multiple allocations. @@ -166,29 +144,66 @@ static unsigned int down_and_up_cpus(const struct cpumask *cpus, return err; } +static void free_cpu_groups(int num, cpumask_var_t **pcpu_groups) +{ + int i; + cpumask_var_t *cpu_groups = *pcpu_groups; + + for (i = 0; i < num; ++i) + free_cpumask_var(cpu_groups[i]); + kfree(cpu_groups); +} + +static int alloc_init_cpu_groups(cpumask_var_t **pcpu_groups) +{ + int num_groups = 0; + cpumask_var_t tmp, *cpu_groups; + + if (!alloc_cpumask_var(&tmp, GFP_KERNEL)) + return -ENOMEM; + + cpu_groups = kcalloc(nb_available_cpus, sizeof(cpu_groups), + GFP_KERNEL); + if (!cpu_groups) + return -ENOMEM; + + cpumask_copy(tmp, cpu_online_mask); + + while (!cpumask_empty(tmp)) { + const struct cpumask *cpu_group = + topology_core_cpumask(cpumask_any(tmp)); + + if (!alloc_cpumask_var(&cpu_groups[num_groups], GFP_KERNEL)) { + free_cpu_groups(num_groups, &cpu_groups); + return -ENOMEM; + } + cpumask_copy(cpu_groups[num_groups++], cpu_group); + cpumask_andnot(tmp, tmp, cpu_group); + } + + free_cpumask_var(tmp); + *pcpu_groups = cpu_groups; + + return num_groups; +} + static int hotplug_tests(void) { - int err; - cpumask_var_t offlined_cpus; - int i, nb_cpu_group; - const struct cpumask **cpu_groups; + int i, nb_cpu_group, err = -ENOMEM; + cpumask_var_t offlined_cpus, *cpu_groups; char *page_buf; - err = -ENOMEM; if (!alloc_cpumask_var(&offlined_cpus, GFP_KERNEL)) return err; - /* We may have up to nb_available_cpus cpu_groups. */ - cpu_groups = kmalloc_array(nb_available_cpus, sizeof(*cpu_groups), - GFP_KERNEL); - if (!cpu_groups) + + nb_cpu_group = alloc_init_cpu_groups(&cpu_groups); + if (nb_cpu_group < 0) goto out_free_cpus; page_buf = (char *)__get_free_page(GFP_KERNEL); if (!page_buf) goto out_free_cpu_groups; err = 0; - nb_cpu_group = find_cpu_groups(cpu_online_mask, cpu_groups); - /* * Of course the last CPU cannot be powered down and cpu_down() should * refuse doing that. @@ -212,7 +227,7 @@ static int hotplug_tests(void) free_page((unsigned long)page_buf); out_free_cpu_groups: - kfree(cpu_groups); + free_cpu_groups(nb_cpu_group, &cpu_groups); out_free_cpus: free_cpumask_var(offlined_cpus); return err; diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c index 6692888f04cf..a200a2174611 100644 --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c @@ -21,6 +21,10 @@ #define MBOX_DATA28(msg) ((msg) & ~0xf) #define MBOX_CHAN_PROPERTY 8 +#define MAX_RPI_FW_PROP_BUF_SIZE 32 + +static struct platform_device *rpi_hwmon; + struct rpi_firmware { struct mbox_client cl; struct mbox_chan *chan; /* The property channel. */ @@ -143,18 +147,22 @@ int rpi_firmware_property(struct rpi_firmware *fw, /* Single tags are very small (generally 8 bytes), so the * stack should be safe. */ - u8 data[buf_size + sizeof(struct rpi_firmware_property_tag_header)]; + u8 data[sizeof(struct rpi_firmware_property_tag_header) + + MAX_RPI_FW_PROP_BUF_SIZE]; struct rpi_firmware_property_tag_header *header = (struct rpi_firmware_property_tag_header *)data; int ret; + if (WARN_ON(buf_size > sizeof(data) - sizeof(*header))) + return -EINVAL; + header->tag = tag; header->buf_size = buf_size; header->req_resp_size = 0; memcpy(data + sizeof(struct rpi_firmware_property_tag_header), tag_data, buf_size); - ret = rpi_firmware_property_list(fw, &data, sizeof(data)); + ret = rpi_firmware_property_list(fw, &data, buf_size + sizeof(*header)); memcpy(tag_data, data + sizeof(struct rpi_firmware_property_tag_header), buf_size); @@ -183,6 +191,20 @@ rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) } } +static void +rpi_register_hwmon_driver(struct device *dev, struct rpi_firmware *fw) +{ + u32 packet; + int ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_THROTTLED, + &packet, sizeof(packet)); + + if (ret) + return; + + rpi_hwmon = platform_device_register_data(dev, "raspberrypi-hwmon", + -1, NULL, 0); +} + static int rpi_firmware_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -209,6 +231,7 @@ static int rpi_firmware_probe(struct platform_device *pdev) platform_set_drvdata(pdev, fw); rpi_firmware_print_firmware_revision(fw); + rpi_register_hwmon_driver(dev, fw); return 0; } @@ -217,6 +240,8 @@ static int rpi_firmware_remove(struct platform_device *pdev) { struct rpi_firmware *fw = platform_get_drvdata(pdev); + platform_device_unregister(rpi_hwmon); + rpi_hwmon = NULL; mbox_free_channel(fw->chan); return 0; |