mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 00:22:00 +02:00
Arm SCMI updates/fixes for v6.18
These SCMI changes bring a mix of improvements, fixes, and cleanups:
1. Device Tree bindings - allow multiple SCMI instances by suffixing
node names (Nikunj Kela).
2. Code hardening - constify both scmi_{transport,voltage_proto}_ops
so they reside in read-only memory (Christophe JAILLET).
3. VirtIO transport initialization - set DRIVER_OK before SCMI probing
to prevent potential stalls; while recent rework removes the practical
risk, this ensures correctness (Junnan Wu).
4. Quirk handling - fix a critical bug by preventing writes to string
constants, avoiding faults in read-only memory (Johan Hovold).
5. i.MX SCMI MISC protocol - extend support to discover board info,
retrieve configuration and build data, and document the new
MISC_BOARD_INFO command; all handled gracefully if unsupported (Peng Fan).
6. Logging cleanup - simplify device tree node name logging by using
the %pOF format to print full paths (Krzysztof Kozlowski).
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEEunHlEgbzHrJD3ZPhAEG6vDF+4pgFAmjEAPYACgkQAEG6vDF+
4pjb9hAA0jwFS90rfpe1B7YlrRkRluzZXherIaR3ePQMxJ0ohaTGXd77BD+Ce2Cs
HYYuJGvlaQ91Kdy0NsvrmEoAwq5m8Xl5MDPCXCOxJ0xtr1VWQiaRlBUJ3ZLia5cf
JjME2e+xHtd6AtZLRL98yUbM7PM3CLYc+o3beQskEqcAmPYkT4v2qU9MBAo99JQ9
29GcH3ZcChXCA7gJtHbVMbfbeQhkc1b+sBTqerh3Qn43iMNEX7cJfIa2KitaQMtC
5//XznXib05+s2Cs1iI/X7k2bWq2CKSaM/uLK/A22uGWFsyGw5Fppdup28RvLlxZ
i1bobgNInM98jFaoOcz49QX4MaVaEHwsouuPcGMd82HW2UVmvK/gyOJdXMY1qyAT
cy71jHeysXifGqwhqlMIdKikcyp/MsylZvIDkX5D17aNbdqnUpU+DS5wSJ/yraEp
N9pah2DvXRTLLu9FWORDgT0Oa/izXTdarNWJTdWiWDfN8+r+/GXjMZ+qRWnNE2bb
ZeK2ddMev6INpMThhOOnbBsgj01CH/djaS5q+y+MHK+fiipaHK5giu8JWESTWXDe
dgiCdmg+QQUigTKInEUphfwFc6EGtJhh/gMGVEtH9YtsbcgTICVq2+mj6W1W6lvx
nm326GgCGUS4joJlIaiQdIOnPOc0ei6uWG7sKVTbz1xrZM48dLQ=
=Pkr7
-----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmjIIQoACgkQmmx57+YA
GNnfUhAAnXkihxT0jMSSO6LnvG+OymCFmqF9722foBzZFv2eyFjXfV9gmAth7jyD
lLZfQ/0VdUnEQjfV26RECii7CHCW9BtVQ4/kcPO6ZNtThq/1emaEhtntVOWovUej
Yq5ofnXYVCPpXy6KoNUuMDMpKUDc+zMgACPVFqHOVv2D03FvOQ+zaqkJAiQmg91l
I7s4WJ4kUTRM+xVtGG71oTlTK3+tZJyrZgNPNrtiCESWD+r6D21jKd/xrJUS8gWS
BvWPq16Rtqc9NeOmqmic7xg8tO2YXM3VXE61+N2AY4B0KHLPa3TucSL8wqST9Fkr
hPUVMGzS6WmmA96AM50bMc6FS8F5H61Cnxn3tMtzWSxtTKCxQXYhXUElndOp8j8T
/pxqjpjsYjKcHt0hVRENJMjVjzuesFwkKOX7Zt0ShVatA4YJw+TMxXlsMPxT/1Lb
UZhoNM81VcUWnbE9lHsX6e+P8Umk3/r2hECnJgCEuJOFugZFpR9/xJCQjY6RfFBC
Dexldw2VSZIOufxotPwh7f7DpePlgN6880dwScMNPCXjdfhZFwZmyOH8qWVOsLRc
Hw2I8hjAM+G+g7s8fz8UxeFSIdx/T6XuIYGSiQ0Z65BeiTUGyN8/2zsWmmEJumhE
jzLpav7UMGLNMU92nbHJxiil9+uxVZillMkAubuJU06rCtxorpg=
=PkTj
-----END PGP SIGNATURE-----
Merge tag 'scmi-updates-6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into soc/drivers
Arm SCMI updates/fixes for v6.18
These SCMI changes bring a mix of improvements, fixes, and cleanups:
1. Device Tree bindings - allow multiple SCMI instances by suffixing
node names (Nikunj Kela).
2. Code hardening - constify both scmi_{transport,voltage_proto}_ops
so they reside in read-only memory (Christophe JAILLET).
3. VirtIO transport initialization - set DRIVER_OK before SCMI probing
to prevent potential stalls; while recent rework removes the practical
risk, this ensures correctness (Junnan Wu).
4. Quirk handling - fix a critical bug by preventing writes to string
constants, avoiding faults in read-only memory (Johan Hovold).
5. i.MX SCMI MISC protocol - extend support to discover board info,
retrieve configuration and build data, and document the new
MISC_BOARD_INFO command; all handled gracefully if unsupported (Peng Fan).
6. Logging cleanup - simplify device tree node name logging by using
the %pOF format to print full paths (Krzysztof Kozlowski).
* tag 'scmi-updates-6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux:
firmware: arm_scmi: Simplify printks with pOF format
firmware: arm_scmi: imx: Discover MISC board info from the system manager
firmware: arm_scmi: imx: Support retrieving MISC protocol configuration info
firmware: arm_scmi: imx: Discover MISC build info from the system manager
firmware: arm_scmi: imx: Add documentation for MISC_BOARD_INFO
firmware: arm_scmi: quirk: Prevent writes to string constants
firmware: arm_scmi: Fix function name typo in scmi_perf_proto_ops struct
firmware: arm_scmi: Mark VirtIO ready before registering scmi_virtio_driver
firmware: arm_scmi: Constify struct scmi_transport_ops
firmware: arm_scmi: Constify struct scmi_voltage_proto_ops
dt-bindings: firmware: arm,scmi: Allow multiple instances
Link: https://lore.kernel.org/r/20250915101341.2987516-1-sudeep.holla@arm.com
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
bc43efa137
|
|
@ -27,7 +27,7 @@ anyOf:
|
|||
|
||||
properties:
|
||||
$nodename:
|
||||
const: scmi
|
||||
pattern: '^scmi(-[0-9]+)?$'
|
||||
|
||||
compatible:
|
||||
oneOf:
|
||||
|
|
|
|||
|
|
@ -401,8 +401,8 @@ static void scmi_device_release(struct device *dev)
|
|||
|
||||
static void __scmi_device_destroy(struct scmi_device *scmi_dev)
|
||||
{
|
||||
pr_debug("(%s) Destroying SCMI device '%s' for protocol 0x%x (%s)\n",
|
||||
of_node_full_name(scmi_dev->dev.parent->of_node),
|
||||
pr_debug("(%pOF) Destroying SCMI device '%s' for protocol 0x%x (%s)\n",
|
||||
scmi_dev->dev.parent->of_node,
|
||||
dev_name(&scmi_dev->dev), scmi_dev->protocol_id,
|
||||
scmi_dev->name);
|
||||
|
||||
|
|
@ -474,9 +474,8 @@ __scmi_device_create(struct device_node *np, struct device *parent,
|
|||
if (retval)
|
||||
goto put_dev;
|
||||
|
||||
pr_debug("(%s) Created SCMI device '%s' for protocol 0x%x (%s)\n",
|
||||
of_node_full_name(parent->of_node),
|
||||
dev_name(&scmi_dev->dev), protocol, name);
|
||||
pr_debug("(%pOF) Created SCMI device '%s' for protocol 0x%x (%s)\n",
|
||||
parent->of_node, dev_name(&scmi_dev->dev), protocol, name);
|
||||
|
||||
return scmi_dev;
|
||||
put_dev:
|
||||
|
|
@ -493,8 +492,8 @@ _scmi_device_create(struct device_node *np, struct device *parent,
|
|||
|
||||
sdev = __scmi_device_create(np, parent, protocol, name);
|
||||
if (!sdev)
|
||||
pr_err("(%s) Failed to create device for protocol 0x%x (%s)\n",
|
||||
of_node_full_name(parent->of_node), protocol, name);
|
||||
pr_err("(%pOF) Failed to create device for protocol 0x%x (%s)\n",
|
||||
parent->of_node, protocol, name);
|
||||
|
||||
return sdev;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/hashtable.h>
|
||||
|
|
@ -89,9 +90,9 @@
|
|||
struct scmi_quirk {
|
||||
bool enabled;
|
||||
const char *name;
|
||||
char *vendor;
|
||||
char *sub_vendor_id;
|
||||
char *impl_ver_range;
|
||||
const char *vendor;
|
||||
const char *sub_vendor_id;
|
||||
const char *impl_ver_range;
|
||||
u32 start_range;
|
||||
u32 end_range;
|
||||
struct static_key_false *key;
|
||||
|
|
@ -217,7 +218,7 @@ static unsigned int scmi_quirk_signature(const char *vend, const char *sub_vend)
|
|||
|
||||
static int scmi_quirk_range_parse(struct scmi_quirk *quirk)
|
||||
{
|
||||
const char *last, *first = quirk->impl_ver_range;
|
||||
const char *last, *first __free(kfree) = NULL;
|
||||
size_t len;
|
||||
char *sep;
|
||||
int ret;
|
||||
|
|
@ -228,8 +229,12 @@ static int scmi_quirk_range_parse(struct scmi_quirk *quirk)
|
|||
if (!len)
|
||||
return 0;
|
||||
|
||||
first = kmemdup(quirk->impl_ver_range, len + 1, GFP_KERNEL);
|
||||
if (!first)
|
||||
return -ENOMEM;
|
||||
|
||||
last = first + len - 1;
|
||||
sep = strchr(quirk->impl_ver_range, '-');
|
||||
sep = strchr(first, '-');
|
||||
if (sep)
|
||||
*sep = '\0';
|
||||
|
||||
|
|
|
|||
|
|
@ -127,8 +127,8 @@ static int mailbox_chan_validate(struct device *cdev, int *a2p_rx_chan,
|
|||
(num_mb == 1 && num_sh != 1) || (num_mb == 3 && num_sh != 2) ||
|
||||
(num_mb == 4 && num_sh != 2)) {
|
||||
dev_warn(cdev,
|
||||
"Invalid channel descriptor for '%s' - mbs:%d shm:%d\n",
|
||||
of_node_full_name(np), num_mb, num_sh);
|
||||
"Invalid channel descriptor for '%pOF' - mbs:%d shm:%d\n",
|
||||
np, num_mb, num_sh);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -140,8 +140,7 @@ static int mailbox_chan_validate(struct device *cdev, int *a2p_rx_chan,
|
|||
of_parse_phandle(np, "shmem", 1);
|
||||
|
||||
if (!np_tx || !np_rx || np_tx == np_rx) {
|
||||
dev_warn(cdev, "Invalid shmem descriptor for '%s'\n",
|
||||
of_node_full_name(np));
|
||||
dev_warn(cdev, "Invalid shmem descriptor for '%pOF'\n", np);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -498,7 +498,7 @@ static void scmi_optee_mark_txdone(struct scmi_chan_info *cinfo, int ret,
|
|||
mutex_unlock(&channel->mu);
|
||||
}
|
||||
|
||||
static struct scmi_transport_ops scmi_optee_ops = {
|
||||
static const struct scmi_transport_ops scmi_optee_ops = {
|
||||
.chan_available = scmi_optee_chan_available,
|
||||
.chan_setup = scmi_optee_chan_setup,
|
||||
.chan_free = scmi_optee_chan_free,
|
||||
|
|
|
|||
|
|
@ -871,6 +871,9 @@ static int scmi_vio_probe(struct virtio_device *vdev)
|
|||
/* Ensure initialized scmi_vdev is visible */
|
||||
smp_store_mb(scmi_vdev, vdev);
|
||||
|
||||
/* Set device ready */
|
||||
virtio_device_ready(vdev);
|
||||
|
||||
ret = platform_driver_register(&scmi_virtio_driver);
|
||||
if (ret) {
|
||||
vdev->priv = NULL;
|
||||
|
|
|
|||
111
drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c
vendored
111
drivers/firmware/arm_scmi/vendors/imx/imx-sm-misc.c
vendored
|
|
@ -25,7 +25,10 @@
|
|||
enum scmi_imx_misc_protocol_cmd {
|
||||
SCMI_IMX_MISC_CTRL_SET = 0x3,
|
||||
SCMI_IMX_MISC_CTRL_GET = 0x4,
|
||||
SCMI_IMX_MISC_DISCOVER_BUILD_INFO = 0x6,
|
||||
SCMI_IMX_MISC_CTRL_NOTIFY = 0x8,
|
||||
SCMI_IMX_MISC_CFG_INFO_GET = 0xC,
|
||||
SCMI_IMX_MISC_BOARD_INFO = 0xE,
|
||||
};
|
||||
|
||||
struct scmi_imx_misc_info {
|
||||
|
|
@ -65,6 +68,27 @@ struct scmi_imx_misc_ctrl_get_out {
|
|||
__le32 val[];
|
||||
};
|
||||
|
||||
struct scmi_imx_misc_buildinfo_out {
|
||||
__le32 buildnum;
|
||||
__le32 buildcommit;
|
||||
#define MISC_MAX_BUILDDATE 16
|
||||
u8 builddate[MISC_MAX_BUILDDATE];
|
||||
#define MISC_MAX_BUILDTIME 16
|
||||
u8 buildtime[MISC_MAX_BUILDTIME];
|
||||
};
|
||||
|
||||
struct scmi_imx_misc_board_info_out {
|
||||
__le32 attributes;
|
||||
#define MISC_MAX_BRDNAME 16
|
||||
u8 brdname[MISC_MAX_BRDNAME];
|
||||
};
|
||||
|
||||
struct scmi_imx_misc_cfg_info_out {
|
||||
__le32 msel;
|
||||
#define MISC_MAX_CFGNAME 16
|
||||
u8 cfgname[MISC_MAX_CFGNAME];
|
||||
};
|
||||
|
||||
static int scmi_imx_misc_attributes_get(const struct scmi_protocol_handle *ph,
|
||||
struct scmi_imx_misc_info *mi)
|
||||
{
|
||||
|
|
@ -272,6 +296,81 @@ static int scmi_imx_misc_ctrl_set(const struct scmi_protocol_handle *ph,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int scmi_imx_misc_build_info_discover(const struct scmi_protocol_handle *ph)
|
||||
{
|
||||
char date[MISC_MAX_BUILDDATE], time[MISC_MAX_BUILDTIME];
|
||||
struct scmi_imx_misc_buildinfo_out *out;
|
||||
struct scmi_xfer *t;
|
||||
int ret;
|
||||
|
||||
ret = ph->xops->xfer_get_init(ph, SCMI_IMX_MISC_DISCOVER_BUILD_INFO, 0,
|
||||
sizeof(*out), &t);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ph->xops->do_xfer(ph, t);
|
||||
if (!ret) {
|
||||
out = t->rx.buf;
|
||||
strscpy(date, out->builddate, MISC_MAX_BUILDDATE);
|
||||
strscpy(time, out->buildtime, MISC_MAX_BUILDTIME);
|
||||
dev_info(ph->dev, "SM Version\t= Build %u, Commit %08x %s %s\n",
|
||||
le32_to_cpu(out->buildnum), le32_to_cpu(out->buildcommit),
|
||||
date, time);
|
||||
}
|
||||
|
||||
ph->xops->xfer_put(ph, t);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int scmi_imx_misc_board_info(const struct scmi_protocol_handle *ph)
|
||||
{
|
||||
struct scmi_imx_misc_board_info_out *out;
|
||||
char name[MISC_MAX_BRDNAME];
|
||||
struct scmi_xfer *t;
|
||||
int ret;
|
||||
|
||||
ret = ph->xops->xfer_get_init(ph, SCMI_IMX_MISC_BOARD_INFO, 0, sizeof(*out), &t);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ph->xops->do_xfer(ph, t);
|
||||
if (!ret) {
|
||||
out = t->rx.buf;
|
||||
strscpy(name, out->brdname, MISC_MAX_BRDNAME);
|
||||
dev_info(ph->dev, "Board\t\t= %s, attr=0x%08x\n",
|
||||
name, le32_to_cpu(out->attributes));
|
||||
}
|
||||
|
||||
ph->xops->xfer_put(ph, t);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int scmi_imx_misc_cfg_info_get(const struct scmi_protocol_handle *ph)
|
||||
{
|
||||
struct scmi_imx_misc_cfg_info_out *out;
|
||||
char name[MISC_MAX_CFGNAME];
|
||||
struct scmi_xfer *t;
|
||||
int ret;
|
||||
|
||||
ret = ph->xops->xfer_get_init(ph, SCMI_IMX_MISC_CFG_INFO_GET, 0, sizeof(*out), &t);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ph->xops->do_xfer(ph, t);
|
||||
if (!ret) {
|
||||
out = t->rx.buf;
|
||||
strscpy(name, out->cfgname, MISC_MAX_CFGNAME);
|
||||
dev_info(ph->dev, "SM Config\t= %s, mSel = %u\n",
|
||||
name, le32_to_cpu(out->msel));
|
||||
}
|
||||
|
||||
ph->xops->xfer_put(ph, t);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct scmi_imx_misc_proto_ops scmi_imx_misc_proto_ops = {
|
||||
.misc_ctrl_set = scmi_imx_misc_ctrl_set,
|
||||
.misc_ctrl_get = scmi_imx_misc_ctrl_get,
|
||||
|
|
@ -299,6 +398,18 @@ static int scmi_imx_misc_protocol_init(const struct scmi_protocol_handle *ph)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = scmi_imx_misc_build_info_discover(ph);
|
||||
if (ret && ret != -EOPNOTSUPP)
|
||||
return ret;
|
||||
|
||||
ret = scmi_imx_misc_board_info(ph);
|
||||
if (ret && ret != -EOPNOTSUPP)
|
||||
return ret;
|
||||
|
||||
ret = scmi_imx_misc_cfg_info_get(ph);
|
||||
if (ret && ret != -EOPNOTSUPP)
|
||||
return ret;
|
||||
|
||||
return ph->set_priv(ph, minfo, version);
|
||||
}
|
||||
|
||||
|
|
|
|||
25
drivers/firmware/arm_scmi/vendors/imx/imx95.rst
vendored
25
drivers/firmware/arm_scmi/vendors/imx/imx95.rst
vendored
|
|
@ -1660,6 +1660,7 @@ protocol_id: 0x84
|
|||
|Name |Description |
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|int32 status |SUCCESS: system log return |
|
||||
| |NOT_SUPPORTED: system log not available |
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|uint32 numLogflags |Descriptor for the log data returned by this call. |
|
||||
| |Bits[31:20] Number of remaining log words. |
|
||||
|
|
@ -1670,6 +1671,30 @@ protocol_id: 0x84
|
|||
|uint32 syslog[N] |Log data array, N is defined in bits[11:0] of numLogflags|
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|
||||
MISC_BOARD_INFO
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
message_id: 0xE
|
||||
protocol_id: 0x84
|
||||
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|Return values |
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|Name |Description |
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|int32 status |SUCCESS: config name return |
|
||||
| |NOT_SUPPORTED: name not available |
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|uint32 attributes |Board-specific attributes reserved for future expansion |
|
||||
| |without breaking backwards compatibility. The firmware |
|
||||
| |sets the value to 0 |
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|uint8 boardname[16] |Board name. NULL terminated ASCII string, up to 16 bytes |
|
||||
| |in length. This is System Manager(SM) firmware-exported |
|
||||
| |board-name and may not align with the board name in the |
|
||||
| |device tree. |
|
||||
+--------------------+---------------------------------------------------------+
|
||||
|
||||
NEGOTIATE_PROTOCOL_VERSION
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ static int scmi_voltage_domains_num_get(const struct scmi_protocol_handle *ph)
|
|||
return vinfo->num_domains;
|
||||
}
|
||||
|
||||
static struct scmi_voltage_proto_ops voltage_proto_ops = {
|
||||
static const struct scmi_voltage_proto_ops voltage_proto_ops = {
|
||||
.num_domains_get = scmi_voltage_domains_num_get,
|
||||
.info_get = scmi_voltage_info_get,
|
||||
.config_set = scmi_voltage_config_set,
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ struct scmi_perf_domain_info {
|
|||
* for a given device
|
||||
* @fast_switch_rate_limit: gets the minimum time (us) required between
|
||||
* successive fast_switching requests
|
||||
* @power_scale_mw_get: indicates if the power values provided are in milliWatts
|
||||
* @power_scale_get: indicates if the power values provided are in milliWatts
|
||||
* or in some other (abstract) scale
|
||||
*/
|
||||
struct scmi_perf_proto_ops {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user