diff options
Diffstat (limited to 'drivers/firmware/arm_scmi')
-rw-r--r-- | drivers/firmware/arm_scmi/bus.c | 3 | ||||
-rw-r--r-- | drivers/firmware/arm_scmi/driver.c | 14 | ||||
-rw-r--r-- | drivers/firmware/arm_scmi/mailbox.c | 37 |
3 files changed, 45 insertions, 9 deletions
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index 73140b854b31..c15928b8c5cc 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c @@ -14,7 +14,6 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/device.h> -#include <linux/of.h> #include "common.h" @@ -436,7 +435,7 @@ struct scmi_device *scmi_device_create(struct device_node *np, /* Nothing to do. */ if (!phead) { mutex_unlock(&scmi_requested_devices_mtx); - return scmi_dev; + return NULL; } /* Walk the list of requested devices for protocol and create them */ diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index d21c7eafd641..dbc474ff62b7 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -2221,8 +2221,8 @@ static int __scmi_xfer_info_init(struct scmi_info *sinfo, hash_init(info->pending_xfers); /* Allocate a bitmask sized to hold MSG_TOKEN_MAX tokens */ - info->xfer_alloc_table = devm_kcalloc(dev, BITS_TO_LONGS(MSG_TOKEN_MAX), - sizeof(long), GFP_KERNEL); + info->xfer_alloc_table = devm_bitmap_zalloc(dev, MSG_TOKEN_MAX, + GFP_KERNEL); if (!info->xfer_alloc_table) return -ENOMEM; @@ -2657,6 +2657,7 @@ static int scmi_probe(struct platform_device *pdev) struct scmi_handle *handle; const struct scmi_desc *desc; struct scmi_info *info; + bool coex = IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX); struct device *dev = &pdev->dev; struct device_node *child, *np = dev->of_node; @@ -2731,16 +2732,13 @@ static int scmi_probe(struct platform_device *pdev) dev_warn(dev, "Failed to setup SCMI debugfs.\n"); if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { - bool coex = - IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX); - ret = scmi_debugfs_raw_mode_setup(info); if (!coex) { if (ret) goto clear_dev_req_notifier; - /* Bail out anyway when coex enabled */ - return ret; + /* Bail out anyway when coex disabled. */ + return 0; } /* Coex enabled, carry on in any case. */ @@ -2764,6 +2762,8 @@ static int scmi_probe(struct platform_device *pdev) ret = scmi_protocol_acquire(handle, SCMI_PROTOCOL_BASE); if (ret) { dev_err(dev, "unable to communicate with SCMI\n"); + if (coex) + return 0; goto notification_exit; } diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scmi/mailbox.c index 0d9c9538b7f4..112c285deb97 100644 --- a/drivers/firmware/arm_scmi/mailbox.c +++ b/drivers/firmware/arm_scmi/mailbox.c @@ -52,6 +52,39 @@ static bool mailbox_chan_available(struct device_node *of_node, int idx) "#mbox-cells", idx, NULL); } +static int mailbox_chan_validate(struct device *cdev) +{ + int num_mb, num_sh, ret = 0; + struct device_node *np = cdev->of_node; + + num_mb = of_count_phandle_with_args(np, "mboxes", "#mbox-cells"); + num_sh = of_count_phandle_with_args(np, "shmem", NULL); + /* Bail out if mboxes and shmem descriptors are inconsistent */ + if (num_mb <= 0 || num_sh > 2 || num_mb != num_sh) { + dev_warn(cdev, "Invalid channel descriptor for '%s'\n", + of_node_full_name(np)); + return -EINVAL; + } + + if (num_sh > 1) { + struct device_node *np_tx, *np_rx; + + np_tx = of_parse_phandle(np, "shmem", 0); + np_rx = of_parse_phandle(np, "shmem", 1); + /* SCMI Tx and Rx shared mem areas have to be distinct */ + if (!np_tx || !np_rx || np_tx == np_rx) { + dev_warn(cdev, "Invalid shmem descriptor for '%s'\n", + of_node_full_name(np)); + ret = -EINVAL; + } + + of_node_put(np_tx); + of_node_put(np_rx); + } + + return ret; +} + static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, bool tx) { @@ -64,6 +97,10 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, resource_size_t size; struct resource res; + ret = mailbox_chan_validate(cdev); + if (ret) + return ret; + smbox = devm_kzalloc(dev, sizeof(*smbox), GFP_KERNEL); if (!smbox) return -ENOMEM; |