1 From 243970ea035623f70431a80ece802f572cd446be Mon Sep 17 00:00:00 2001
2 From: Jonas Gorski <jogo@openwrt.org>
3 Date: Sun, 9 Dec 2012 00:10:00 +0100
4 Subject: [PATCH V2 1/2] spi/bcm63xx: reject transfers unable to transfer
6 The hardware does not support keeping CS asserted after sending one
7 FIFO buffer worth of data, so reject transfers requiring CS being kept
8 asserted, either between transers or for a certain time after it,
9 or exceeding the FIFO size.
11 Signed-off-by: Jonas Gorski <jogo@openwrt.org>
13 drivers/spi/spi-bcm63xx.c | 91 +++++++++++++++++++++------------------------
14 1 file changed, 42 insertions(+), 49 deletions(-)
16 --- a/drivers/spi/spi-bcm63xx.c
17 +++ b/drivers/spi/spi-bcm63xx.c
18 @@ -49,16 +49,10 @@ struct bcm63xx_spi {
19 unsigned int msg_type_shift;
20 unsigned int msg_ctl_width;
23 - const unsigned char *tx_ptr;
24 - unsigned char *rx_ptr;
28 const u8 __iomem *rx_io;
30 - int remaining_bytes;
33 struct platform_device *pdev;
35 @@ -175,24 +169,13 @@ static int bcm63xx_spi_setup(struct spi_
39 -/* Fill the TX FIFO with as many bytes as possible */
40 -static void bcm63xx_spi_fill_tx_fifo(struct bcm63xx_spi *bs)
44 - /* Fill the Tx FIFO with as many bytes as possible */
45 - size = bs->remaining_bytes < bs->fifo_size ? bs->remaining_bytes :
47 - memcpy_toio(bs->tx_io, bs->tx_ptr, size);
48 - bs->remaining_bytes -= size;
51 -static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi,
52 - struct spi_transfer *t)
53 +static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
55 struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
59 + unsigned int timeout = 0;
61 /* Disable the CMD_DONE interrupt */
62 bcm_spi_writeb(bs, 0, SPI_INT_MASK);
63 @@ -200,14 +183,8 @@ static unsigned int bcm63xx_txrx_bufs(st
64 dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
65 t->tx_buf, t->rx_buf, t->len);
67 - /* Transmitter is inhibited */
68 - bs->tx_ptr = t->tx_buf;
69 - bs->rx_ptr = t->rx_buf;
72 - bs->remaining_bytes = t->len;
73 - bcm63xx_spi_fill_tx_fifo(bs);
76 + memcpy_toio(bs->tx_io, t->tx_buf, t->len);
78 init_completion(&bs->done);
80 @@ -239,7 +216,18 @@ static unsigned int bcm63xx_txrx_bufs(st
81 /* Enable the CMD_DONE interrupt */
82 bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
84 - return t->len - bs->remaining_bytes;
85 + timeout = wait_for_completion_timeout(&bs->done, HZ);
89 + /* read out all data */
90 + rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
92 + /* Read out all the data */
94 + memcpy_fromio(t->rx_ptr, bs->rx_io, rx_tail);
99 static int bcm63xx_spi_prepare_transfer(struct spi_master *master)
100 @@ -267,36 +255,41 @@ static int bcm63xx_spi_transfer_one(stru
101 struct spi_transfer *t;
102 struct spi_device *spi = m->spi;
104 - unsigned int timeout = 0;
106 list_for_each_entry(t, &m->transfers, transfer_list) {
107 - unsigned int len = t->len;
110 status = bcm63xx_spi_check_transfer(spi, t);
114 + /* we can only transfer one fifo worth of data */
115 + if (t->len > bs->fifo_size) {
116 + dev_err(&spi->dev, "unable to do transfers larger than FIFO size (%i > %i)\n",
117 + t->len, bs->fifo_size);
122 + /* CS will be deasserted directly after transfer */
123 + if (t->delay_usecs) {
124 + dev_err(&spi->dev, "unable to keep CS asserted after transfer\n");
129 + if (!t->cs_change &&
130 + !list_is_last(&t->transfer_list, &m->transfers)) {
131 + dev_err(&spi->dev, "unable to keep CS asserted between transfers\n");
136 /* configure adapter for a new transfer */
137 bcm63xx_spi_setup_transfer(spi, t);
140 - /* send the data */
141 - len -= bcm63xx_txrx_bufs(spi, t);
143 - timeout = wait_for_completion_timeout(&bs->done, HZ);
145 - status = -ETIMEDOUT;
149 - /* read out all data */
150 - rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
152 - /* Read out all the data */
154 - memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail);
156 + /* send the data */
157 + status = bcm63xx_txrx_bufs(spi, t);
161 m->actual_length += t->len;