From: Bjorn Andersson <bjorn.andersson@linaro.org>
To: srinivas.kandagatla@linaro.org
Cc: gregkh@linuxfoundation.org, broonie@kernel.org,
alsa-devel@alsa-project.org, sdharia@codeaurora.org, bp@suse.de,
poeschel@lemonage.de, treding@nvidia.com,
gong.chen@linux.intel.com, andreas.noever@gmail.com,
alan@linux.intel.com, mathieu.poirier@linaro.org,
daniel@ffwll.ch, jkosina@suse.cz, sharon.dvir1@mail.huji.ac.il,
joe@perches.com, davem@davemloft.net, james.hogan@imgtec.com,
michael.opdenacker@free-electrons.com, robh+dt@kernel.org,
pawel.moll@arm.com, mark.rutland@arm.com,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
kheitke@audience.com, linux-arm-msm@vger.kernel.org,
arnd@arndb.de
Subject: Re: [Patch v6 2/7] slimbus: Add messaging APIs to slimbus framework
Date: Tue, 17 Oct 2017 23:15:00 -0700 [thread overview]
Message-ID: <20171018061500.GE1575@tuxbook> (raw)
In-Reply-To: <20171006155136.4682-3-srinivas.kandagatla@linaro.org>
On Fri 06 Oct 08:51 PDT 2017, srinivas.kandagatla@linaro.org wrote:
> From: Sagar Dharia <sdharia@codeaurora.org>
>
> Slimbus devices use value-element, and information elements to
> control device parameters (e.g. value element is used to represent
> gain for codec, information element is used to represent interrupt
> status for codec when codec interrupt fires).
> Messaging APIs are used to set/get these value and information
> elements. Slimbus specification uses 8-bit "transaction IDs" for
> messages where a read-value is anticipated. Framework uses a table
> of pointers to store those TIDs and responds back to the caller in
> O(1).
I think we can implement this "optimization" with less complex code,
regardless I don't think we need to mention this in the commit
message...
[..]
> diff --git a/drivers/slimbus/slim-messaging.c b/drivers/slimbus/slim-messaging.c
[..]
> +/**
> + * slim_msg_response: Deliver Message response received from a device to the
> + * framework.
> + * @ctrl: Controller handle
> + * @reply: Reply received from the device
> + * @len: Length of the reply
> + * @tid: Transaction ID received with which framework can associate reply.
> + * Called by controller to inform framework about the response received.
> + * This helps in making the API asynchronous, and controller-driver doesn't need
> + * to manage 1 more table other than the one managed by framework mapping TID
> + * with buffers
> + */
> +void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 len)
Even if tid and len comes from the spec I recommend you making them int
and size_t.
> +{
> + struct slim_val_inf *msg;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&ctrl->txn_lock, flags);
> + msg = ctrl->tid_tbl[tid];
> + if (msg == NULL || msg->rbuf == NULL) {
if (!msg || !msg->rbuf)
When is it valid to add a transaction to tid_tbl with msg->rbuf = NULL?
Should we reject it earlier?
> + spin_unlock_irqrestore(&ctrl->txn_lock, flags);
> + dev_err(&ctrl->dev, "Got response to invalid TID:%d, len:%d\n",
> + tid, len);
> + return;
> + }
> + ctrl->tid_tbl[tid] = NULL;
> + spin_unlock_irqrestore(&ctrl->txn_lock, flags);
> +
> + memcpy(msg->rbuf, reply, len);
> + if (msg->comp_cb)
> + msg->comp_cb(msg->ctx, 0);
> +}
> +EXPORT_SYMBOL_GPL(slim_msg_response);
[..]
> +int slim_processtxn(struct slim_controller *ctrl,
> + struct slim_msg_txn *txn)
> +{
> + int ret, i = 0;
> + unsigned long flags;
> + u8 *buf;
> + bool async = false;
> + struct slim_cb_data cbd;
> + DECLARE_COMPLETION_ONSTACK(done);
> + bool need_tid = slim_tid_txn(txn->mt, txn->mc);
> +
> + if (!txn->msg->comp_cb) {
> + txn->msg->comp_cb = slim_sync_default_cb;
> + cbd.comp = &done;
> + txn->msg->ctx = &cbd;
> + } else {
> + async = true;
> + }
> +
> + buf = slim_get_tx(ctrl, txn, need_tid);
> + if (!buf)
> + return -ENOMEM;
> +
> + if (need_tid) {
> + spin_lock_irqsave(&ctrl->txn_lock, flags);
> + for (i = 0; i < ctrl->last_tid; i++) {
> + if (ctrl->tid_tbl[i] == NULL)
> + break;
> + }
> + if (i >= ctrl->last_tid) {
> + if (ctrl->last_tid == (SLIM_MAX_TIDS - 1)) {
> + spin_unlock_irqrestore(&ctrl->txn_lock, flags);
> + slim_return_tx(ctrl, -ENOMEM);
> + return -ENOMEM;
> + }
> + ctrl->last_tid++;
> + }
> + ctrl->tid_tbl[i] = txn->msg;
> + txn->tid = i;
> + spin_unlock_irqrestore(&ctrl->txn_lock, flags);
> + }
> +
> + ret = ctrl->xfer_msg(ctrl, txn, buf);
> +
> + if (!ret && !async) { /* sync transaction */
> + /* Fine-tune calculation after bandwidth management */
> + unsigned long ms = txn->rl + 100;
> +
> + ret = wait_for_completion_timeout(&done,
> + msecs_to_jiffies(ms));
> + if (!ret)
> + slim_return_tx(ctrl, -ETIMEDOUT);
> +
> + ret = cbd.ret;
> + }
> +
> + if (ret && need_tid) {
> + spin_lock_irqsave(&ctrl->txn_lock, flags);
> + /* Invalidate the transaction */
> + ctrl->tid_tbl[txn->tid] = NULL;
> + spin_unlock_irqrestore(&ctrl->txn_lock, flags);
> + }
> + if (ret)
> + dev_err(&ctrl->dev, "Tx:MT:0x%x, MC:0x%x, LA:0x%x failed:%d\n",
> + txn->mt, txn->mc, txn->la, ret);
if (ret) {
if (need_tid)
drop();
dev_err();
}
Would probably make this a little bit cleaner...
> + if (!async) {
> + txn->msg->comp_cb = NULL;
> + txn->msg->ctx = NULL;
I believe txn->msg is always required, so you don't need to do this
contidionally.
> + }
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(slim_processtxn);
[..]
> +int slim_request_val_element(struct slim_device *sb,
> + struct slim_val_inf *msg)
> +{
> + struct slim_controller *ctrl = sb->ctrl;
> +
> + if (!ctrl)
> + return -EINVAL;
>From patch 1 I believe it's invalid for sb->ctrl to be NULL, so there
shouldn't be a need to check this.
> +
> + return slim_xfer_msg(ctrl, sb, msg, SLIM_MSG_MC_REQUEST_VALUE);
> +}
> +EXPORT_SYMBOL_GPL(slim_request_val_element);
[..]
> +int slim_return_rx(struct slim_controller *ctrl, void *buf)
> +{
> + unsigned long flags;
> +
> + spin_lock_irqsave(&ctrl->rx.lock, flags);
> + if (ctrl->rx.tail == ctrl->rx.head) {
> + spin_unlock_irqrestore(&ctrl->rx.lock, flags);
> + return -ENODATA;
> + }
> + memcpy(buf, ctrl->rx.base + (ctrl->rx.head * ctrl->rx.sl_sz),
> + ctrl->rx.sl_sz);
> + ctrl->rx.head = (ctrl->rx.head + 1) % ctrl->rx.n;
> + spin_unlock_irqrestore(&ctrl->rx.lock, flags);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(slim_return_rx);
> +
Please provide kerneldoc for exported symbols.
> +void slim_return_tx(struct slim_controller *ctrl, int err)
> +{
> + unsigned long flags;
> + int idx;
> + struct slim_pending cur;
> +
> + spin_lock_irqsave(&ctrl->tx.lock, flags);
> + idx = ctrl->tx.head;
> + ctrl->tx.head = (ctrl->tx.head + 1) % ctrl->tx.n;
> + cur = ctrl->pending_wr[idx];
Why is this doing struct copy?
> + spin_unlock_irqrestore(&ctrl->tx.lock, flags);
> +
> + if (!cur.cb)
> + dev_err(&ctrl->dev, "NULL Transaction or completion");
> + else
> + cur.cb(cur.ctx, err);
> +
> + up(&ctrl->tx_sem);
> +}
> +EXPORT_SYMBOL_GPL(slim_return_tx);
[..]
> /**
> + * struct slim_val_inf: Slimbus value or information element
> + * @start_offset: Specifies starting offset in information/value element map
> + * @num_bytes: upto 16. This ensures that the message will fit the slicesize
> + * per slimbus spec
> + * @comp_cb: Callback if this read/write is asynchronous
> + * @ctx: Argument for comp_cb
> + */
> +struct slim_val_inf {
> + u16 start_offset;
> + u8 num_bytes;
> + u8 *rbuf;
This is not mentioned in the kerneldoc. Use void * for data buffers.
> + const u8 *wbuf;
Can a message ever be read and write? Otherwise it should be sufficient
to only have one data pointer.
> + void (*comp_cb)(void *ctx, int err);
> + void *ctx;
> +};
> +
[..]
> +/**
> + * struct slim_ctrl_buf: circular buffer used by contoller for TX, RX
> + * @base: virtual base address for this buffer
> + * @phy: physical address for this buffer (this is useful if controller can
> + * DMA the buffers for TX and RX to/from controller hardware
> + * @lock: lock protecting head and tail
> + * @head: index where buffer is returned back
> + * @tail: index from where buffer is consumed
> + * @sl_sz: byte-size of each slot in this buffer
> + * @n: number of elements in this circular ring, note that this needs to be
> + * 1 more than actual buffers to allow for one open slot
> + */
Is this ringbuffer mechanism defined in the slimbus specification? Looks
like something specific to the Qualcomm controller, rather than
something that should be enforced in the framework.
> +struct slim_ctrl_buf {
> + void *base;
> + phys_addr_t phy;
> + spinlock_t lock;
> + int head;
> + int tail;
> + int sl_sz;
> + int n;
> +};
[..]
> +/**
> * struct slim_controller: Controls every instance of SLIMbus
> * (similar to 'master' on SPI)
> * 'Manager device' is responsible for device management, bandwidth
> @@ -139,6 +246,16 @@ struct slim_addrt {
> * @addrt: Logical address table
> * @num_dev: Number of active slimbus slaves on this bus
> * @wq: Workqueue per controller used to notify devices when they report present
> + * @tid_tbl: Table of transactions having transaction ID
> + * @txn_lock: Lock to protect table of transactions
> + * @rx: RX buffers used by controller to receive messages. Ctrl may receive more
> + * than 1 message (e.g. multiple report-present messages or messages from
> + * multiple slaves).
> + * @tx: TX buffers used by controller to transmit messages. Ctrl may have
> + * ability to send/queue multiple messages to HW at once.
> + * @pending_wr: Pending write transactions to be acknowledged by controller
This is out list of pending write requests, yet it's implemented as an
array used in a complex ring buffer fashion. Wouldn't it be easier to
just have this as a linked list of slim_pending struct?
> + * @tx_sem: Semaphore for available TX buffers for this controller
> + * @last_tid: Last used entry for TID transactions
> * @xfer_msg: Transfer a message on this controller (this can be a broadcast
> * control/status message like data channel setup, or a unicast message
> * like value element read/write.
> @@ -161,6 +278,15 @@ struct slim_controller {
> struct slim_addrt *addrt;
> u8 num_dev;
> struct workqueue_struct *wq;
> + struct slim_val_inf *tid_tbl[SLIM_MAX_TIDS];
> + u8 last_tid;
I suggest that you replace these two with an idr, rather than having a
fixed size array and then last_tid as an optimization to limit how far
you linear search for an empty space.
> + spinlock_t txn_lock;
> + struct slim_ctrl_buf tx;
> + struct slim_ctrl_buf rx;
> + struct slim_pending *pending_wr;
> + struct semaphore tx_sem;
Please don't use semaphores. If you keep pending_wr as a list you can
use list_empty() instead...
> + int (*xfer_msg)(struct slim_controller *ctrl,
> + struct slim_msg_txn *tx, void *buf);
I believe buf has fixed size, so please document this.
> int (*set_laddr)(struct slim_controller *ctrl,
> struct slim_eaddr *ea, u8 laddr);
> int (*get_laddr)(struct slim_controller *ctrl,
> @@ -295,5 +421,40 @@ static inline void slim_set_devicedata(struct slim_device *dev, void *data)
> {
> dev_set_drvdata(&dev->dev, data);
> }
Regards,
Bjorn
next prev parent reply other threads:[~2017-10-18 6:15 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-06 15:51 [Patch v6 0/7] Introduce framework for SLIMbus device drivers srinivas.kandagatla
2017-10-06 15:51 ` [Patch v6 1/7] slimbus: Device management on SLIMbus srinivas.kandagatla
2017-10-10 10:05 ` Charles Keepax
2017-10-10 12:34 ` Srinivas Kandagatla
2017-10-10 12:56 ` Charles Keepax
2017-10-11 10:23 ` Mark Brown
2017-10-12 11:01 ` [alsa-devel] " Sanyog Kale
2017-10-12 13:26 ` Srinivas Kandagatla
2017-10-23 9:06 ` Mark Brown
[not found] ` <20171006155136.4682-2-srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2017-10-07 4:14 ` Jonathan Neuschäfer
2017-10-07 10:24 ` Srinivas Kandagatla
2017-10-10 10:45 ` [alsa-devel] " Vinod Koul
2017-10-10 12:34 ` Srinivas Kandagatla
2017-10-10 16:49 ` Vinod Koul
2017-10-10 17:21 ` [alsa-devel] " Srinivas Kandagatla
2017-10-11 4:07 ` Vinod Koul
2017-10-11 9:42 ` Srinivas Kandagatla
2017-10-11 10:21 ` Vinod Koul
2017-10-11 11:23 ` Srinivas Kandagatla
2017-10-13 19:26 ` Rob Herring
2017-10-16 9:28 ` Srinivas Kandagatla
2017-10-17 6:23 ` Bjorn Andersson
2017-10-18 16:38 ` Srinivas Kandagatla
[not found] ` <1a1d2777-be69-98ca-afba-0ffd0e3dd80f-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2017-11-01 23:08 ` Bjorn Andersson
2017-10-25 0:16 ` Stephen Boyd
2017-10-06 15:51 ` [Patch v6 3/7] slimbus: qcom: Add Qualcomm Slimbus controller driver srinivas.kandagatla
2017-10-07 7:45 ` Jonathan Neuschäfer
2017-10-07 10:24 ` Srinivas Kandagatla
2017-10-13 19:17 ` Rob Herring
2017-10-16 9:28 ` Srinivas Kandagatla
2017-10-18 7:27 ` Bjorn Andersson
2017-10-18 16:39 ` Srinivas Kandagatla
2017-10-06 15:51 ` [Patch v6 4/7] slimbus: Add support for 'clock-pause' feature srinivas.kandagatla
2017-10-07 8:06 ` Jonathan Neuschäfer
2017-10-07 10:24 ` Srinivas Kandagatla
2017-10-06 15:51 ` [Patch v6 6/7] regmap: add SLIMBUS support srinivas.kandagatla
2017-10-07 5:02 ` Jonathan Neuschäfer
2017-10-07 10:25 ` Srinivas Kandagatla
2017-10-20 5:00 ` Bjorn Andersson
[not found] ` <20171006155136.4682-1-srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2017-10-06 15:51 ` [Patch v6 2/7] slimbus: Add messaging APIs to slimbus framework srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A
2017-10-07 6:42 ` Jonathan Neuschäfer
2017-10-07 10:24 ` Srinivas Kandagatla
2017-10-07 12:29 ` Jonathan Neuschäfer
2017-10-10 12:19 ` Charles Keepax
2017-10-10 13:01 ` Srinivas Kandagatla
2017-10-11 4:38 ` [alsa-devel] " Vinod Koul
2017-10-11 7:53 ` Arnd Bergmann
2017-10-11 9:42 ` Srinivas Kandagatla
[not found] ` <aa117cb8-ba59-894c-5a82-1b38facfa841-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2017-10-11 10:24 ` [alsa-devel] " Vinod Koul
2017-10-11 11:12 ` Srinivas Kandagatla
2017-10-18 6:15 ` Bjorn Andersson [this message]
2017-10-18 16:39 ` Srinivas Kandagatla
2017-10-20 5:00 ` Bjorn Andersson
2017-10-06 15:51 ` [Patch v6 5/7] slimbus: qcom: Add runtime-pm support using clock-pause feature srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A
2017-10-07 8:22 ` Jonathan Neuschäfer
2017-10-07 10:25 ` Srinivas Kandagatla
2017-10-06 15:51 ` [Patch v6 7/7] MAINTAINERS: Add SLIMbus maintainer srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A
2017-10-20 5:00 ` Bjorn Andersson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171018061500.GE1575@tuxbook \
--to=bjorn.andersson@linaro.org \
--cc=alan@linux.intel.com \
--cc=alsa-devel@alsa-project.org \
--cc=andreas.noever@gmail.com \
--cc=arnd@arndb.de \
--cc=bp@suse.de \
--cc=broonie@kernel.org \
--cc=daniel@ffwll.ch \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=gong.chen@linux.intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=james.hogan@imgtec.com \
--cc=jkosina@suse.cz \
--cc=joe@perches.com \
--cc=kheitke@audience.com \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mathieu.poirier@linaro.org \
--cc=michael.opdenacker@free-electrons.com \
--cc=pawel.moll@arm.com \
--cc=poeschel@lemonage.de \
--cc=robh+dt@kernel.org \
--cc=sdharia@codeaurora.org \
--cc=sharon.dvir1@mail.huji.ac.il \
--cc=srinivas.kandagatla@linaro.org \
--cc=treding@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).