Thread (34 messages) 34 messages, 4 authors, 2018-03-20

Re: [PATCH v6 03/20] firmware: arm_scmi: add basic driver infrastructure for SCMI

From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Date: 2018-03-05 14:47:42
Also in: linux-arm-kernel, lkml

quoted
quoted
+/**
+ * scmi_one_xfer_get() - Allocate one message
+ *
+ * @handle: SCMI entity handle
+ *
+ * Helper function which is used by various command functions that are
+ * exposed to clients of this driver for allocating a message traffic event.
+ *
+ * This function can sleep depending on pending requests already in the system
+ * for the SCMI entity. Further, this also holds a spinlock to maintain
+ * integrity of internal data structures.
+ *
+ * Return: 0 if all went fine, else corresponding error.
+ */
+static struct scmi_xfer *scmi_one_xfer_get(const struct scmi_handle *handle)  
Maybe it's just me, but I think this would be more clearly named as
scmi_xfer_alloc.
  
Agreed to some extent. The reason I didn't have it as alloc as they are
preallocated and this just returns a reference to free slot in that
preallocated array.
quoted
I'd assume we were dealing with one anyway as it's not called scmi_xfers_get
and the get to my mind implies a reference counter rather than allocating
an xfer for use...
  
Ah OK, I get your concerne with _get/_put but _alloc/_free is equally
bad then in the contect of preallocated buffers.
Sure, this is always a fun question.  Lots of other options
_assign _deassign works but never feels nice.
...
quoted
quoted
+	.max_msg = 20,		/* Limited by MBOX_TX_QUEUE_LEN */
+	.max_msg_size = 128,
+};
+
+/* Each compatible listed below must have descriptor associated with it */
+static const struct of_device_id scmi_of_match[] = {
+	{ .compatible = "arm,scmi", .data = &scmi_generic_desc },
+	{ /* Sentinel */ },
+};
+
+MODULE_DEVICE_TABLE(of, scmi_of_match);
+
+static int scmi_xfer_info_init(struct scmi_info *sinfo)
+{
+	int i;
+	struct scmi_xfer *xfer;
+	struct device *dev = sinfo->dev;
+	const struct scmi_desc *desc = sinfo->desc;
+	struct scmi_xfers_info *info = &sinfo->minfo;
+
+	/* Pre-allocated messages, no more than what hdr.seq can support */
+	if (WARN_ON(desc->max_msg >= (MSG_TOKEN_ID_MASK + 1))) {
+		dev_err(dev, "Maximum message of %d exceeds supported %d\n",
+			desc->max_msg, MSG_TOKEN_ID_MASK + 1);
+		return -EINVAL;
+	}
+
+	info->xfer_block = devm_kcalloc(dev, desc->max_msg,
+					sizeof(*info->xfer_block), GFP_KERNEL);
+	if (!info->xfer_block)
+		return -ENOMEM;
+
+	info->xfer_alloc_table = devm_kcalloc(dev, BITS_TO_LONGS(desc->max_msg),
+					      sizeof(long), GFP_KERNEL);
+	if (!info->xfer_alloc_table)
+		return -ENOMEM;  
Hmm. I wonder if it is worth adding a devm_bitmap_alloc?
  
OK
quoted
quoted
+
+	bitmap_zero(info->xfer_alloc_table, desc->max_msg);  
kcalloc zeros the memory.
  
quoted
+
+	/* Pre-initialize the buffer pointer to pre-allocated buffers */
+	for (i = 0, xfer = info->xfer_block; i < desc->max_msg; i++, xfer++) {
+		xfer->rx.buf = devm_kcalloc(dev, sizeof(u8), desc->max_msg_size,
+					    GFP_KERNEL);
+		if (!xfer->rx.buf)
+			return -ENOMEM;
+
+		xfer->tx.buf = xfer->rx.buf;
+		init_completion(&xfer->done);
+	}
+
+	spin_lock_init(&info->xfer_lock);
+
+	return 0;
+}
+
+static int scmi_mailbox_check(struct device_node *np)
+{
+	struct of_phandle_args arg;
+
+	return of_parse_phandle_with_args(np, "mboxes", "#mbox-cells", 0, &arg);
+}
+
+static int scmi_mbox_free_channel(struct scmi_info *info)  
Some of the naming in here could do with being adjusted to be obviously
'balanced'.  The moment I see a free I expect a matched alloc but in this
case the alloc is done in scmi_mbox_chan_setup which at very least
should be scmi_mbox_setup_channel and should really imply that it is
doing allocation as well.
  
That's inline with mailbox APIs.
oh goody.  Fair enough if ugly
...
OK
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help