From: Eddie James <eajames@linux.ibm.com>
To: openbmc@lists.ozlabs.org
Cc: joel@jms.id.au, Brad Bishop <bradleyb@fuzziesquirrel.com>,
Eddie James <eajames@linux.ibm.com>
Subject: [PATCH linux dev-5.7 6/6] eeprom: at25: Split reads into chunks and cap write size
Date: Wed, 29 Jul 2020 15:45:28 -0500 [thread overview]
Message-ID: <20200729204528.15157-7-eajames@linux.ibm.com> (raw)
In-Reply-To: <20200729204528.15157-1-eajames@linux.ibm.com>
From: Brad Bishop <bradleyb@fuzziesquirrel.com>
Make use of spi_max_transfer_size to avoid requesting transfers that are
too large for some spi controllers.
Signed-off-by: Eddie James <eajames@linux.ibm.com>
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
---
drivers/misc/eeprom/at25.c | 94 ++++++++++++++++++++++----------------
1 file changed, 54 insertions(+), 40 deletions(-)
diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
index cde9a2fc1325..3ed041cb3083 100644
--- a/drivers/misc/eeprom/at25.c
+++ b/drivers/misc/eeprom/at25.c
@@ -64,12 +64,17 @@ static int at25_ee_read(void *priv, unsigned int offset,
{
struct at25_data *at25 = priv;
char *buf = val;
+ size_t max_chunk = spi_max_transfer_size(at25->spi);
+ size_t num_msgs = count / max_chunk + (bool)(count % max_chunk);
+ size_t nr_bytes = 0;
u8 command[EE_MAXADDRLEN + 1];
u8 *cp;
ssize_t status;
struct spi_transfer t[2];
struct spi_message m;
u8 instr;
+ unsigned msg_offset;
+ size_t msg_count;
if (unlikely(offset >= at25->chip.byte_len))
return -EINVAL;
@@ -78,57 +83,64 @@ static int at25_ee_read(void *priv, unsigned int offset,
if (unlikely(!count))
return -EINVAL;
- cp = command;
-
- instr = AT25_READ;
- if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR)
- if (offset >= (1U << (at25->addrlen * 8)))
- instr |= AT25_INSTR_BIT3;
- *cp++ = instr;
-
- /* 8/16/24-bit address is written MSB first */
- switch (at25->addrlen) {
- default: /* case 3 */
- *cp++ = offset >> 16;
- /* fall through */
- case 2:
- *cp++ = offset >> 8;
- /* fall through */
- case 1:
- case 0: /* can't happen: for better codegen */
- *cp++ = offset >> 0;
- }
+ msg_offset = (unsigned) offset;
+ msg_count = min(count, max_chunk);
+ while (num_msgs) {
+ cp = command;
- spi_message_init(&m);
- memset(t, 0, sizeof(t));
+ instr = AT25_READ;
+ if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR)
+ if (msg_offset >= (1U << (at25->addrlen * 8)))
+ instr |= AT25_INSTR_BIT3;
+ *cp++ = instr;
- t[0].tx_buf = command;
- t[0].len = at25->addrlen + 1;
- spi_message_add_tail(&t[0], &m);
+ /* 8/16/24-bit address is written MSB first */
+ switch (at25->addrlen) {
+ default: /* case 3 */
+ *cp++ = msg_offset >> 16;
+ /* fall through */
+ case 2:
+ *cp++ = msg_offset >> 8;
+ /* fall through */
+ case 1:
+ case 0: /* can't happen: for better codegen */
+ *cp++ = msg_offset >> 0;
+ }
- t[1].rx_buf = buf;
- t[1].len = count;
- spi_message_add_tail(&t[1], &m);
+ spi_message_init(&m);
+ memset(t, 0, sizeof(t));
- mutex_lock(&at25->lock);
+ t[0].tx_buf = command;
+ t[0].len = at25->addrlen + 1;
+ spi_message_add_tail(&t[0], &m);
- /* Read it all at once.
- *
- * REVISIT that's potentially a problem with large chips, if
- * other devices on the bus need to be accessed regularly or
- * this chip is clocked very slowly
- */
- status = spi_sync(at25->spi, &m);
- dev_dbg(&at25->spi->dev, "read %zu bytes at %d --> %zd\n",
- count, offset, status);
+ t[1].rx_buf = buf + nr_bytes;
+ t[1].len = msg_count;
+ spi_message_add_tail(&t[1], &m);
- mutex_unlock(&at25->lock);
- return status;
+ mutex_lock(&at25->lock);
+
+ status = spi_sync(at25->spi, &m);
+
+ mutex_unlock(&at25->lock);
+
+ if (status)
+ return status;
+
+ --num_msgs;
+ msg_offset += msg_count;
+ nr_bytes += msg_count;
+ }
+
+ dev_dbg(&at25->spi->dev, "read %zu bytes at %d\n",
+ count, offset);
+ return 0;
}
static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count)
{
struct at25_data *at25 = priv;
+ size_t maxsz = spi_max_transfer_size(at25->spi);
const char *buf = val;
int status = 0;
unsigned buf_size;
@@ -191,6 +203,8 @@ static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count)
segment = buf_size - (offset % buf_size);
if (segment > count)
segment = count;
+ if (segment > maxsz)
+ segment = maxsz;
memcpy(cp, buf, segment);
status = spi_write(at25->spi, bounce,
segment + at25->addrlen + 1);
--
2.24.0
next prev parent reply other threads:[~2020-07-29 20:45 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-29 20:45 [PATCH linux dev-5.7 0/6] spi: Fix FSI-attached controller and AT25 drivers Eddie James
2020-07-29 20:45 ` [PATCH linux dev-5.7 1/6] spi: fsi: Handle 9 to 15 byte transfers lengths Eddie James
2020-07-29 23:41 ` Joel Stanley
2020-07-29 20:45 ` [PATCH linux dev-5.7 2/6] spi: fsi: Fix clock running too fast Eddie James
2020-07-29 23:25 ` Joel Stanley
2020-07-30 21:31 ` Eddie James
2020-07-29 20:45 ` [PATCH linux dev-5.7 3/6] spi: fsi: Fix use of the bneq+ sequencer instruction Eddie James
2020-07-29 23:27 ` Joel Stanley
2020-07-29 20:45 ` [PATCH linux dev-5.7 4/6] dt-bindings: fsi: fsi2spi: Document new restricted property Eddie James
2020-07-29 23:27 ` Joel Stanley
2020-07-29 20:45 ` [PATCH linux dev-5.7 5/6] spi: fsi: Implement restricted size for certain controllers Eddie James
2020-07-29 23:33 ` Joel Stanley
2020-07-29 20:45 ` Eddie James [this message]
2020-07-29 23:28 ` [PATCH linux dev-5.7 6/6] eeprom: at25: Split reads into chunks and cap write size Milton Miller II
2020-07-29 23:35 ` [PATCH linux dev-5.7 0/6] spi: Fix FSI-attached controller and AT25 drivers Joel Stanley
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=20200729204528.15157-7-eajames@linux.ibm.com \
--to=eajames@linux.ibm.com \
--cc=bradleyb@fuzziesquirrel.com \
--cc=joel@jms.id.au \
--cc=openbmc@lists.ozlabs.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.