diff options
| author | Mark Brown <broonie@kernel.org> | 2026-10-30 11:30:28 +0000 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-10-30 11:30:28 +0000 |
| commit | 506ca150016d59cd308d0ec622760958df57e205 (patch) | |
| tree | e0d4d520d882d48773fac2be37c777c86e1ac41b | |
| parent | 7c58608f4a4b62134f725aa0f0bc51c8158b24f3 (diff) | |
| parent | c64a20a250d5eb8bb43ceffadb24aa852a7158b5 (diff) | |
| download | linux-next-506ca150016d59cd308d0ec622760958df57e205.tar.gz linux-next-506ca150016d59cd308d0ec622760958df57e205.zip | |
Merge branch 'for-linux-next' of https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git
| -rw-r--r-- | arch/arm64/boot/dts/arm/corstone1000-a320.dtsi | 2 | ||||
| -rw-r--r-- | drivers/firmware/arm_ffa/driver.c | 11 | ||||
| -rw-r--r-- | drivers/firmware/arm_scmi/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/firmware/arm_scmi/bus.c | 110 | ||||
| -rw-r--r-- | drivers/firmware/arm_scmi/driver.c | 4 | ||||
| -rw-r--r-- | drivers/firmware/arm_scmi/notify.c | 4 | ||||
| -rw-r--r-- | drivers/firmware/arm_scmi/transports/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/firmware/arm_scmi/transports/mailbox.c | 7 | ||||
| -rw-r--r-- | drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c | 18 | ||||
| -rw-r--r-- | drivers/irqchip/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/pinctrl/freescale/pinctrl-imx-scmi.c | 2 | ||||
| -rw-r--r-- | include/linux/arm-smccc.h | 7 | ||||
| -rw-r--r-- | include/linux/firmware/imx/sm.h | 6 |
13 files changed, 113 insertions, 64 deletions
diff --git a/arch/arm64/boot/dts/arm/corstone1000-a320.dtsi b/arch/arm64/boot/dts/arm/corstone1000-a320.dtsi index f0937914350c..f895a024fc92 100644 --- a/arch/arm64/boot/dts/arm/corstone1000-a320.dtsi +++ b/arch/arm64/boot/dts/arm/corstone1000-a320.dtsi @@ -73,7 +73,7 @@ #size-cells = <1>; interrupt-controller; reg = <0x1c000000 0x10000>, - <0x1c040000 0x80000>; + <0x1c040000 0x100000>; interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>; }; diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c index 28abc808fd32..ae8cc3a2ba2e 100644 --- a/drivers/firmware/arm_ffa/driver.c +++ b/drivers/firmware/arm_ffa/driver.c @@ -1223,6 +1223,7 @@ struct notifier_cb_info { ffa_fwk_notifier_cb fwk_cb; ffa_notifier_cb cb; void *cb_data; + u16 notify_id; }; static int @@ -1302,7 +1303,8 @@ notifier_hnode_get_by_vmid(u16 notify_id, int vmid) struct notifier_cb_info *node; hash_for_each_possible(drv_info->notifier_hash, node, hnode, notify_id) - if (node->fwk_cb && vmid == node->dev->vm_id) + if (node->notify_id == notify_id && node->fwk_cb && + vmid == node->dev->vm_id) return node; return NULL; @@ -1317,7 +1319,8 @@ notifier_hnode_get_by_vmid_uuid(u16 notify_id, int vmid, const uuid_t *uuid) return notifier_hnode_get_by_vmid(notify_id, vmid); hash_for_each_possible(drv_info->notifier_hash, node, hnode, notify_id) - if (node->fwk_cb && vmid == node->dev->vm_id && + if (node->notify_id == notify_id && node->fwk_cb && + vmid == node->dev->vm_id && uuid_equal(&node->dev->uuid, uuid)) return node; @@ -1330,7 +1333,8 @@ notifier_hnode_get_by_type(u16 notify_id, enum notify_type type) struct notifier_cb_info *node; hash_for_each_possible(drv_info->notifier_hash, node, hnode, notify_id) - if (node->cb && type == ffa_notify_type_get(node->dev->vm_id)) + if (node->notify_id == notify_id && node->cb && + type == ffa_notify_type_get(node->dev->vm_id)) return node; return NULL; @@ -1422,6 +1426,7 @@ static int __ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu, cb_info->dev = dev; cb_info->cb_data = cb_data; + cb_info->notify_id = notify_id; if (is_framework) cb_info->fwk_cb = cb; else diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig index 783c24a20e29..9f6241efd592 100644 --- a/drivers/firmware/arm_scmi/Kconfig +++ b/drivers/firmware/arm_scmi/Kconfig @@ -52,7 +52,7 @@ config ARM_SCMI_RAW_MODE_SUPPORT_COEX Allow SCMI Raw transmission mode to coexist with normal SCMI stack. This will allow regular SCMI drivers to register with the core and - operate normally, thing which could make an SCMI test suite using the + operate normally, things which could make an SCMI test suite using the SCMI Raw mode support unreliable. If unsure, say N. config ARM_SCMI_DEBUG_COUNTERS diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index 25197197db8e..7613ea2893ef 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c @@ -36,6 +36,12 @@ struct scmi_requested_dev { /* Track globally the SCMI SystemPower protocol device. */ static struct scmi_device *scmi_syspower_registered; +static bool scmi_raw_mode_only(void) +{ + return IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT) && + !IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX); +} + /** * scmi_protocol_device_request - Helper to request a device * @@ -60,8 +66,7 @@ static int scmi_protocol_device_request(const struct scmi_device_id *id_table) pr_debug("Requesting SCMI device (%s) for protocol %x\n", id_table->name, id_table->protocol_id); - if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT) && - !IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX)) { + if (scmi_raw_mode_only()) { pr_warn("SCMI Raw mode active. Rejecting '%s'/0x%02X\n", id_table->name, id_table->protocol_id); return -EINVAL; @@ -181,12 +186,43 @@ static void scmi_protocol_device_unrequest(const struct scmi_device_id *id_table } } +/* Standard protocols table */ +static const struct scmi_device_id scmi_std_id_table[] = { + { SCMI_PROTOCOL_POWER, "genpd" }, + { SCMI_PROTOCOL_SYSTEM, "syspower" }, + { SCMI_PROTOCOL_PERF, "perf" }, + { SCMI_PROTOCOL_PERF, "cpufreq" }, + { SCMI_PROTOCOL_CLOCK, "clocks" }, + { SCMI_PROTOCOL_SENSOR, "hwmon" }, + { SCMI_PROTOCOL_SENSOR, "iiodev" }, + { SCMI_PROTOCOL_RESET, "reset" }, + { SCMI_PROTOCOL_VOLTAGE, "regulator" }, + { SCMI_PROTOCOL_POWERCAP, "powercap" }, + { SCMI_PROTOCOL_PINCTRL, "pinctrl" }, + { }, +}; + +static bool scmi_device_id_in_std_id_table(const struct scmi_device_id *id) +{ + for (int i = 0; scmi_std_id_table[i].name[0]; i++) { + if (scmi_std_id_table[i].protocol_id == id->protocol_id && + !strcmp(scmi_std_id_table[i].name, id->name)) + return true; + } + + return false; +} + static int scmi_protocol_table_register(const struct scmi_device_id *id_table) { const struct scmi_device_id *entry; int ret; for (entry = id_table; entry->name[0]; entry++) { + /* Skip standard devices as they are created unconditionally */ + if (scmi_device_id_in_std_id_table(entry)) + continue; + ret = scmi_protocol_device_request(entry); if (ret) goto err_unrequest; @@ -195,8 +231,11 @@ static int scmi_protocol_table_register(const struct scmi_device_id *id_table) return 0; err_unrequest: - while (entry != id_table) - scmi_protocol_device_unrequest(--entry); + while (entry != id_table) { + --entry; + if (!scmi_device_id_in_std_id_table(entry)) + scmi_protocol_device_unrequest(entry); + } return ret; } @@ -206,16 +245,23 @@ scmi_protocol_table_unregister(const struct scmi_device_id *id_table) { const struct scmi_device_id *entry; - for (entry = id_table; entry->name[0]; entry++) - scmi_protocol_device_unrequest(entry); + for (entry = id_table; entry->name[0]; entry++) { + if (!scmi_device_id_in_std_id_table(entry)) + scmi_protocol_device_unrequest(entry); + } } -static bool scmi_device_is_transport(const struct scmi_device *scmi_dev) +static bool scmi_device_name_is_transport(const char *name) { - return !strncmp(scmi_dev->name, SCMI_TRANSPORT_DEVNAME_PREFIX, + return !strncmp(name, SCMI_TRANSPORT_DEVNAME_PREFIX, strlen(SCMI_TRANSPORT_DEVNAME_PREFIX)); } +static bool scmi_device_is_transport(const struct scmi_device *scmi_dev) +{ + return scmi_device_name_is_transport(scmi_dev->name); +} + static int __scmi_dev_match_by_id_table(struct scmi_device *scmi_dev, const struct scmi_device_id *id_table, bool skip_transport) @@ -524,6 +570,11 @@ _scmi_device_create(struct fwnode_handle *fwnode, struct device *parent, { struct scmi_device *sdev; + /* The perf device is only needed when it provides power domains. */ + if (protocol == SCMI_PROTOCOL_PERF && !strcmp(name, "perf") && + !fwnode_property_present(fwnode, "#power-domain-cells")) + return NULL; + sdev = __scmi_device_create(fwnode, parent, protocol, name); if (!sdev) pr_err("(%pfwf) Failed to create device - protocol 0x%x (%s)\n", @@ -532,34 +583,6 @@ _scmi_device_create(struct fwnode_handle *fwnode, struct device *parent, return sdev; } -/* Standard protocols table */ -static const struct scmi_device_id scmi_std_id_table[] = { - { SCMI_PROTOCOL_POWER, "genpd" }, - { SCMI_PROTOCOL_SYSTEM, "syspower" }, - { SCMI_PROTOCOL_PERF, "perf" }, - { SCMI_PROTOCOL_PERF, "cpufreq" }, - { SCMI_PROTOCOL_CLOCK, "clocks" }, - { SCMI_PROTOCOL_SENSOR, "hwmon" }, - { SCMI_PROTOCOL_SENSOR, "iiodev" }, - { SCMI_PROTOCOL_RESET, "reset" }, - { SCMI_PROTOCOL_VOLTAGE, "regulator" }, - { SCMI_PROTOCOL_POWERCAP, "powercap" }, - { SCMI_PROTOCOL_PINCTRL, "pinctrl" }, - { SCMI_PROTOCOL_PINCTRL, "pinctrl-imx" }, - { }, -}; - -static bool scmi_device_id_in_std_id_table(const struct scmi_device_id *id) -{ - for (int i = 0; scmi_std_id_table[i].name[0]; i++) { - if (scmi_std_id_table[i].protocol_id == id->protocol_id && - !strcmp(scmi_std_id_table[i].name, id->name)) - return true; - } - - return false; -} - /** * scmi_device_create - A method to create one or more SCMI devices * @@ -578,10 +601,8 @@ static bool scmi_device_id_in_std_id_table(const struct scmi_device_id *id) * * Return: The created device (or one of them if @name was NOT provided and * multiple devices were created) or NULL if no device was created; - * note that NULL indicates an error ONLY in case a specific @name - * was provided: when @name param was not provided, a number of devices - * could have been potentially created for a whole protocol, unless no - * device was found to have been requested for that specific protocol. + * note that NULL can also indicate that a named device is not needed + * for this fwnode, or that no device was requested when @name is NULL. */ struct scmi_device *scmi_device_create(struct fwnode_handle *fwnode, struct device *parent, int protocol, @@ -591,6 +612,11 @@ struct scmi_device *scmi_device_create(struct fwnode_handle *fwnode, struct scmi_requested_dev *rdev; struct scmi_device *sdev, *scmi_dev = NULL; + /* Exclusive raw mode still needs transport devices for its channels. */ + if (scmi_raw_mode_only() && + (!name || !scmi_device_name_is_transport(name))) + return NULL; + if (name) return _scmi_device_create(fwnode, parent, protocol, name); @@ -619,10 +645,6 @@ struct scmi_device *scmi_device_create(struct fwnode_handle *fwnode, /* Walk the list of requested devices for protocol and create them */ list_for_each_entry(rdev, phead, node) { - /* Standard proto matches already have their dev created above */ - if (scmi_device_id_in_std_id_table(rdev->id_table)) - continue; - sdev = _scmi_device_create(fwnode, parent, rdev->id_table->protocol_id, rdev->id_table->name); diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 1e6f69b14321..6c6cb7209b13 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -3107,11 +3107,7 @@ static void scmi_debugfs_common_cleanup(void *d) static const char *scmi_acpi_device_hid(struct acpi_device *adev) { -#ifdef CONFIG_ACPI return adev ? acpi_device_hid(adev) : "unknown"; -#else - return "unknown"; -#endif } static struct scmi_debug_info *scmi_debugfs_common_setup(struct scmi_info *info) diff --git a/drivers/firmware/arm_scmi/notify.c b/drivers/firmware/arm_scmi/notify.c index fb60fb07c0ed..e5de0d29c346 100644 --- a/drivers/firmware/arm_scmi/notify.c +++ b/drivers/firmware/arm_scmi/notify.c @@ -1395,8 +1395,10 @@ static int scmi_notifier_register(const struct scmi_handle *handle, /* Enable events for not pending handlers */ if (!IS_HNDL_PENDING(hndl)) { ret = scmi_event_handler_enable_events(hndl); - if (ret) + if (ret) { + blocking_notifier_chain_unregister(&hndl->chain, nb); scmi_put_handler(ni, hndl); + } } return ret; diff --git a/drivers/firmware/arm_scmi/transports/Kconfig b/drivers/firmware/arm_scmi/transports/Kconfig index 0e34fbf25053..6ba0dcb86204 100644 --- a/drivers/firmware/arm_scmi/transports/Kconfig +++ b/drivers/firmware/arm_scmi/transports/Kconfig @@ -5,7 +5,7 @@ config ARM_SCMI_HAVE_TRANSPORT bool help This declares whether at least one SCMI transport has been configured. - Used to trigger a build bug when trying to build SCMI without any + Used to trigger a runtime warning when enabling SCMI without any configured transport. config ARM_SCMI_HAVE_SHMEM diff --git a/drivers/firmware/arm_scmi/transports/mailbox.c b/drivers/firmware/arm_scmi/transports/mailbox.c index 56af2cb0f424..49c472e2ba27 100644 --- a/drivers/firmware/arm_scmi/transports/mailbox.c +++ b/drivers/firmware/arm_scmi/transports/mailbox.c @@ -206,8 +206,11 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, smbox->shmem = core->shmem->setup_iomap(cinfo, dev, tx, NULL, &smbox->io_ops); - if (IS_ERR(smbox->shmem)) - return PTR_ERR(smbox->shmem); + if (IS_ERR(smbox->shmem)) { + ret = PTR_ERR(smbox->shmem); + devm_kfree(dev, smbox); + return ret; + } cl = &smbox->cl; cl->dev = cdev; diff --git a/drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c b/drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c index 637973fb45e6..f00f7acba845 100644 --- a/drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c +++ b/drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c @@ -273,10 +273,16 @@ static int scmi_imx_misc_ctrl_get(const struct scmi_protocol_handle *ph, { struct scmi_imx_misc_ctrl_get_out *out; struct scmi_xfer *t; + u32 num_values, max_values; int ret, i; int max_msg_size = ph->hops->get_max_msg_size(ph); int max_num = (max_msg_size - sizeof(*out)) / sizeof(__le32); + if (!num || !val || !*num) + return -EINVAL; + + max_values = *num; + ret = scmi_imx_misc_ctrl_validate_id(ph, ctrl_id); if (ret) return ret; @@ -290,16 +296,18 @@ static int scmi_imx_misc_ctrl_get(const struct scmi_protocol_handle *ph, ret = ph->xops->do_xfer(ph, t); if (!ret) { out = t->rx.buf; - *num = le32_to_cpu(out->num); + num_values = le32_to_cpu(out->num); - if (*num >= max_num || - *num * sizeof(__le32) > t->rx.len - sizeof(__le32)) { + if (num_values > max_values || num_values >= max_num || + num_values * sizeof(__le32) > t->rx.len - sizeof(__le32)) { ph->xops->xfer_put(ph, t); return -EINVAL; } - for (i = 0; i < *num; i++) + for (i = 0; i < num_values; i++) val[i] = le32_to_cpu(out->val[i]); + + *num = num_values; } ph->xops->xfer_put(ph, t); @@ -438,7 +446,7 @@ static int iter_misc_syslog_update_state(struct scmi_iterator_state *st, st->num_returned = RETURNED(r->numlogflags); st->num_remaining = REMAINING(r->numlogflags); - *p->size = st->num_returned + st->num_remaining; + *p->size = st->desc_index + st->num_returned; return 0; } diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 136bab41f801..ca915fca0ef5 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -37,7 +37,7 @@ config ARM_GIC_V3 bool select IRQ_DOMAIN_HIERARCHY select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP - select HAVE_ARM_SMCCC_DISCOVERY + select HAVE_ARM_SMCCC_DISCOVERY if ARM64 select IRQ_MSI_IOMMU config ARM_GIC_ITS_PARENT diff --git a/drivers/pinctrl/freescale/pinctrl-imx-scmi.c b/drivers/pinctrl/freescale/pinctrl-imx-scmi.c index 613552e35070..b259a526ccc1 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx-scmi.c +++ b/drivers/pinctrl/freescale/pinctrl-imx-scmi.c @@ -354,7 +354,7 @@ static int scmi_pinctrl_imx_probe(struct scmi_device *sdev) } static const struct scmi_device_id scmi_id_table[] = { - { SCMI_PROTOCOL_PINCTRL, "pinctrl-imx" }, + { SCMI_PROTOCOL_PINCTRL, "pinctrl" }, { } }; MODULE_DEVICE_TABLE(scmi, scmi_id_table); diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h index 4de81848fe2e..75f9d3f1723b 100644 --- a/include/linux/arm-smccc.h +++ b/include/linux/arm-smccc.h @@ -324,6 +324,7 @@ enum arm_smccc_conduit { SMCCC_CONDUIT_HVC, }; +#ifdef CONFIG_HAVE_ARM_SMCCC_DISCOVERY /** * arm_smccc_1_1_get_conduit() * @@ -363,6 +364,12 @@ s32 arm_smccc_get_soc_id_version(void); * When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED. */ s32 arm_smccc_get_soc_id_revision(void); +#else /* CONFIG_HAVE_ARM_SMCCC_DISCOVERY */ +#define arm_smccc_1_1_get_conduit() SMCCC_CONDUIT_NONE +#define arm_smccc_get_version() 0 +#define arm_smccc_get_soc_id_version() SMCCC_RET_NOT_SUPPORTED +#define arm_smccc_get_soc_id_revision() SMCCC_RET_NOT_SUPPORTED +#endif /* CONFIG_HAVE_ARM_SMCCC_DISCOVERY */ #ifndef __ASSEMBLY__ diff --git a/include/linux/firmware/imx/sm.h b/include/linux/firmware/imx/sm.h index ba5d93bd6158..0aec7da0ae78 100644 --- a/include/linux/firmware/imx/sm.h +++ b/include/linux/firmware/imx/sm.h @@ -29,6 +29,12 @@ #define SCMI_IMX952_CTRL_BYPASS_AUDMIX 8U /* WAKE AUDMIX */ #if IS_ENABLED(CONFIG_IMX_SCMI_MISC_DRV) +/** + * scmi_imx_misc_ctrl_get() - Read an i.MX MISC control + * @id: Control identifier + * @num: On entry, capacity of @val in words; on return, words read + * @val: Buffer for the control value + */ int scmi_imx_misc_ctrl_get(u32 id, u32 *num, u32 *val); int scmi_imx_misc_ctrl_set(u32 id, u32 val); #else |
