From: Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
To: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
Cc: Julia Lawall <Julia.Lawall-L2FTfq7BK8M@public.gmane.org>,
spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Jonathan Cameron <jic23-KWPb1pKIrIJaa/9Udqfwiw@public.gmane.org>,
linux-iio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
Subject: [PATCH 1/3] spi: Add helper functions for setting up transfers
Date: Wed, 9 Jan 2013 18:31:09 +0100 [thread overview]
Message-ID: <1357752671-30222-1-git-send-email-lars@metafoo.de> (raw)
Quite often the pattern used for setting up and transferring a synchronous SPI
transaction looks very much like the following:
struct spi_message msg;
struct spi_transfer xfers[] = {
...
};
spi_message_init(&msg);
spi_message_add_tail(&xfers[0], &msg);
...
spi_message_add_tail(&xfers[ARRAY_SIZE(xfers) - 1], &msg);
ret = spi_sync(&msg);
This patch adds two new helper functions for handling this case. The first
helper function spi_message_init_with_transfers() takes a spi_message and an
array of spi_transfers. It will initialize the message and then call
spi_message_add_tail() for each transfer in the array. E.g. the following
spi_message_init(&msg);
spi_message_add_tail(&xfers[0], &msg);
...
spi_message_add_tail(&xfers[ARRAY_SIZE(xfers) - 1], &msg);
can be rewritten as
spi_message_init_with_transfers(&msg, xfers, ARRAY_SIZE(xfers));
The second function spi_sync_transfer() takes a SPI device and an array of
spi_transfers. It will allocate a new spi_message (on the stack) and add all
transfers in the array to the message. Finally it will call spi_sync() on the
message.
E.g. the follwing
struct spi_message msg;
struct spi_transfer xfers[] = {
...
};
spi_message_init(&msg);
spi_message_add_tail(&xfers[0], &msg);
...
spi_message_add_tail(&xfers[ARRAY_SIZE(xfers) - 1], &msg);
ret = spi_sync(spi, &msg);
can be rewritten as
struct spi_transfer xfers[] = {
...
};
ret = spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers));
The patch also adds a new cocci script which can detect such sequences as
described above and transform them automatically to use the new helper
functions.
Signed-off-by: Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
---
I'm not entirely happy with names of the two new functions and I'm open for
better suggestions.
---
include/linux/spi/spi.h | 44 ++++++++
scripts/coccinelle/api/spi_sync_transfer.cocci | 141 +++++++++++++++++++++++++
2 files changed, 185 insertions(+)
create mode 100644 scripts/coccinelle/api/spi_sync_transfer.cocci
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index f629189..7dbe586 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -591,6 +591,26 @@ spi_transfer_del(struct spi_transfer *t)
list_del(&t->transfer_list);
}
+/**
+ * spi_message_init_with_transfers - Initialize spi_message and append transfers
+ * @m: spi_message to be initialized
+ * @xfers: An array of spi transfers
+ * @num_xfers: Number of items in the xfer array
+ *
+ * This function initializes the given spi_message and adds each spi_transfer in
+ * the given array to the message.
+ */
+static inline void
+spi_message_init_with_transfers(struct spi_message *m,
+struct spi_transfer *xfers, unsigned int num_xfers)
+{
+ unsigned int i;
+
+ spi_message_init(m);
+ for (i = 0; i < num_xfers; ++i)
+ spi_message_add_tail(&xfers[i], m);
+}
+
/* It's fine to embed message and transaction structures in other data
* structures so long as you don't free them while they're in use.
*/
@@ -683,6 +703,30 @@ spi_read(struct spi_device *spi, void *buf, size_t len)
return spi_sync(spi, &m);
}
+/**
+ * spi_sync_transfer - synchronous SPI data transfer
+ * @spi: device with which data will be exchanged
+ * @xfers: An array of spi_transfers
+ * @num_xfers: Number of items in the xfer array
+ * Context: can sleep
+ *
+ * Does a synchronous SPI data transfer of the given spi_transfer array.
+ *
+ * For more specific semantics see spi_sync().
+ *
+ * It returns zero on success, else a negative error code.
+ */
+static inline int
+spi_sync_transfer(struct spi_device *spi, struct spi_transfer *xfers,
+ unsigned int num_xfers)
+{
+ struct spi_message msg;
+
+ spi_message_init_with_transfers(&msg, xfers, num_xfers);
+
+ return spi_sync(spi, &msg);
+}
+
/* this copies txbuf and rxbuf data; for small transfers only! */
extern int spi_write_then_read(struct spi_device *spi,
const void *txbuf, unsigned n_tx,
diff --git a/scripts/coccinelle/api/spi_sync_transfer.cocci b/scripts/coccinelle/api/spi_sync_transfer.cocci
new file mode 100644
index 0000000..1e2efe3
--- /dev/null
+++ b/scripts/coccinelle/api/spi_sync_transfer.cocci
@@ -0,0 +1,141 @@
+///
+/// Use spi_sync_transfer instead of open-coding it
+///
+// Confidence: High
+// Options: --no-includes
+//
+// Keywords: spi_sync, spi_sync_transfer
+// Version min: 3.9
+//
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+@r1@
+identifier fn;
+identifier xfers;
+@@
+fn(...)
+{
+ ...
+(
+ struct spi_transfer xfers[...];
+|
+ struct spi_transfer xfers[];
+)
+ ...
+}
+
+@depends on patch@
+identifier msg;
+expression spi;
+identifier r1.fn;
+identifier r1.xfers;
+@@
+fn(...)
+{
+...
+-struct spi_message msg;
+...
+-spi_message_init(&msg);
+<...
+-spi_message_add_tail(&xfers[...], &msg);
+...>
+
+-spi_sync(spi, &msg)
++spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers))
+...
+}
+
+@r3 depends on context || org || report@
+identifier msg;
+expression spi;
+identifier r1.xfers;
+identifier r1.fn;
+position p;
+@@
+fn(...)
+{
+...
+*struct spi_message msg;
+...
+*spi_message_init(&msg);
+<...
+*spi_message_add_tail(&xfers[...], &msg);
+...>
+*spi_sync@p(spi, &msg)
+...
+}
+
+@r2@
+identifier fn;
+identifier xfer;
+@@
+fn(...)
+{
+ ...
+ struct spi_transfer xfer;
+ ...
+}
+
+@depends on patch@
+identifier msg;
+expression spi;
+identifier r2.xfer;
+identifier r2.fn;
+@@
+fn(...)
+{
+...
+-struct spi_message msg;
+...
+-spi_message_init(&msg);
+...
+-spi_message_add_tail(&xfer, &msg);
+...
+-spi_sync(spi, &msg)
++spi_sync_transfer(spi, &xfer, 1)
+...
+}
+
+@r4 depends on context || org || report@
+identifier msg;
+expression spi;
+identifier r2.xfer;
+identifier r2.fn;
+position p;
+@@
+fn(...)
+{
+...
+*struct spi_message msg;
+...
+*spi_message_init(&msg);
+...
+*spi_message_add_tail(&xfer, &msg);
+...
+*spi_sync@p(spi, &msg)
+...
+}
+
+@script:python depends on report@
+p << r3.p;
+@@
+coccilib.report.print_report(p[0], "Consider using spi_sync_transfer instead of open-conding it.")
+
+@script:python depends on report@
+p << r4.p;
+@@
+coccilib.report.print_report(p[0], "Consider using spi_sync_transfer instead of open-conding it.")
+
+@script:python depends on org@
+p << r3.p;
+@@
+coccilib.org.print_todo(p[0], "Consider using spi_sync_transfer instead of open-conding it.")
+
+@script:python depends on org@
+p << r4.p;
+@@
+coccilib.org.print_todo(p[0], "Consider using spi_sync_transfer instead of open-conding it.")
--
1.8.0
next reply other threads:[~2013-01-09 17:31 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-09 17:31 Lars-Peter Clausen [this message]
[not found] ` <1357752671-30222-1-git-send-email-lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
2013-01-09 17:31 ` [PATCH 2/3] iio: Use spi_sync_transfer() Lars-Peter Clausen
2013-01-09 17:31 ` [PATCH 3/3] staging:iio: " Lars-Peter Clausen
2013-01-09 19:20 ` [PATCH 1/3] spi: Add helper functions for setting up transfers Jonathan Cameron
2013-01-09 20:56 ` Lars-Peter Clausen
[not found] ` <50EDD96A.5080900-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
2013-01-09 21:36 ` Jonathan Cameron
2013-01-10 8:53 ` Julia Lawall
[not found] ` <alpine.DEB.2.02.1301100951060.2063-bi+AKbBUZKagILUCTcTcHdKyNwTtLsGr@public.gmane.org>
2013-01-10 9:55 ` Lars-Peter Clausen
[not found] ` <50EE8FFD.2000000-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
2013-01-10 10:28 ` Julia Lawall
2013-01-27 3:33 ` Mark Brown
[not found] ` <20130127033358.GA20672-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2013-02-05 14:07 ` Grant Likely
2013-02-06 19:20 ` Jonathan Cameron
[not found] ` <5112ACF5.3020906-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2013-02-09 11:14 ` Jonathan Cameron
2013-02-09 10:59 ` Jonathan Cameron
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=1357752671-30222-1-git-send-email-lars@metafoo.de \
--to=lars-qo5elluwu/uelga04laivw@public.gmane.org \
--cc=Julia.Lawall-L2FTfq7BK8M@public.gmane.org \
--cc=grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org \
--cc=jic23-KWPb1pKIrIJaa/9Udqfwiw@public.gmane.org \
--cc=linux-iio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
/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).