aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi-rspi.c320
-rw-r--r--include/linux/spi/rspi.h31
2 files changed, 345 insertions, 6 deletions
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 354f170eab95..4894bde4bbff 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -31,7 +31,11 @@
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/clk.h> 33#include <linux/clk.h>
34#include <linux/dmaengine.h>
35#include <linux/dma-mapping.h>
36#include <linux/sh_dma.h>
34#include <linux/spi/spi.h> 37#include <linux/spi/spi.h>
38#include <linux/spi/rspi.h>
35 39
36#define RSPI_SPCR 0x00 40#define RSPI_SPCR 0x00
37#define RSPI_SSLP 0x01 41#define RSPI_SSLP 0x01
@@ -141,6 +145,16 @@ struct rspi_data {
141 spinlock_t lock; 145 spinlock_t lock;
142 struct clk *clk; 146 struct clk *clk;
143 unsigned char spsr; 147 unsigned char spsr;
148
149 /* for dmaengine */
150 struct sh_dmae_slave dma_tx;
151 struct sh_dmae_slave dma_rx;
152 struct dma_chan *chan_tx;
153 struct dma_chan *chan_rx;
154 int irq;
155
156 unsigned dma_width_16bit:1;
157 unsigned dma_callbacked:1;
144}; 158};
145 159
146static void rspi_write8(struct rspi_data *rspi, u8 data, u16 offset) 160static void rspi_write8(struct rspi_data *rspi, u8 data, u16 offset)
@@ -265,11 +279,125 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg,
265 return 0; 279 return 0;
266} 280}
267 281
268static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, 282static void rspi_dma_complete(void *arg)
269 struct spi_transfer *t) 283{
284 struct rspi_data *rspi = arg;
285
286 rspi->dma_callbacked = 1;
287 wake_up_interruptible(&rspi->wait);
288}
289
290static int rspi_dma_map_sg(struct scatterlist *sg, void *buf, unsigned len,
291 struct dma_chan *chan,
292 enum dma_transfer_direction dir)
293{
294 sg_init_table(sg, 1);
295 sg_set_buf(sg, buf, len);
296 sg_dma_len(sg) = len;
297 return dma_map_sg(chan->device->dev, sg, 1, dir);
298}
299
300static void rspi_dma_unmap_sg(struct scatterlist *sg, struct dma_chan *chan,
301 enum dma_transfer_direction dir)
302{
303 dma_unmap_sg(chan->device->dev, sg, 1, dir);
304}
305
306static void rspi_memory_to_8bit(void *buf, const void *data, unsigned len)
307{
308 u16 *dst = buf;
309 const u8 *src = data;
310
311 while (len) {
312 *dst++ = (u16)(*src++);
313 len--;
314 }
315}
316
317static void rspi_memory_from_8bit(void *buf, const void *data, unsigned len)
318{
319 u8 *dst = buf;
320 const u16 *src = data;
321
322 while (len) {
323 *dst++ = (u8)*src++;
324 len--;
325 }
326}
327
328static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
329{
330 struct scatterlist sg;
331 void *buf = NULL;
332 struct dma_async_tx_descriptor *desc;
333 unsigned len;
334 int ret = 0;
335
336 if (rspi->dma_width_16bit) {
337 /*
338 * If DMAC bus width is 16-bit, the driver allocates a dummy
339 * buffer. And, the driver converts original data into the
340 * DMAC data as the following format:
341 * original data: 1st byte, 2nd byte ...
342 * DMAC data: 1st byte, dummy, 2nd byte, dummy ...
343 */
344 len = t->len * 2;
345 buf = kmalloc(len, GFP_KERNEL);
346 if (!buf)
347 return -ENOMEM;
348 rspi_memory_to_8bit(buf, t->tx_buf, t->len);
349 } else {
350 len = t->len;
351 buf = (void *)t->tx_buf;
352 }
353
354 if (!rspi_dma_map_sg(&sg, buf, len, rspi->chan_tx, DMA_TO_DEVICE)) {
355 ret = -EFAULT;
356 goto end_nomap;
357 }
358 desc = dmaengine_prep_slave_sg(rspi->chan_tx, &sg, 1, DMA_TO_DEVICE,
359 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
360 if (!desc) {
361 ret = -EIO;
362 goto end;
363 }
364
365 /*
366 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be
367 * called. So, this driver disables the IRQ while DMA transfer.
368 */
369 disable_irq(rspi->irq);
370
371 rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR);
372 rspi_enable_irq(rspi, SPCR_SPTIE);
373 rspi->dma_callbacked = 0;
374
375 desc->callback = rspi_dma_complete;
376 desc->callback_param = rspi;
377 dmaengine_submit(desc);
378 dma_async_issue_pending(rspi->chan_tx);
379
380 ret = wait_event_interruptible_timeout(rspi->wait,
381 rspi->dma_callbacked, HZ);
382 if (ret > 0 && rspi->dma_callbacked)
383 ret = 0;
384 else if (!ret)
385 ret = -ETIMEDOUT;
386 rspi_disable_irq(rspi, SPCR_SPTIE);
387
388 enable_irq(rspi->irq);
389
390end:
391 rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE);
392end_nomap:
393 if (rspi->dma_width_16bit)
394 kfree(buf);
395
396 return ret;
397}
398
399static void rspi_receive_init(struct rspi_data *rspi)
270{ 400{
271 int remain = t->len;
272 u8 *data;
273 unsigned char spsr; 401 unsigned char spsr;
274 402
275 spsr = rspi_read8(rspi, RSPI_SPSR); 403 spsr = rspi_read8(rspi, RSPI_SPSR);
@@ -278,6 +406,15 @@ static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
278 if (spsr & SPSR_OVRF) 406 if (spsr & SPSR_OVRF)
279 rspi_write8(rspi, rspi_read8(rspi, RSPI_SPSR) & ~SPSR_OVRF, 407 rspi_write8(rspi, rspi_read8(rspi, RSPI_SPSR) & ~SPSR_OVRF,
280 RSPI_SPCR); 408 RSPI_SPCR);
409}
410
411static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
412 struct spi_transfer *t)
413{
414 int remain = t->len;
415 u8 *data;
416
417 rspi_receive_init(rspi);
281 418
282 data = (u8 *)t->rx_buf; 419 data = (u8 *)t->rx_buf;
283 while (remain > 0) { 420 while (remain > 0) {
@@ -307,6 +444,120 @@ static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg,
307 return 0; 444 return 0;
308} 445}
309 446
447static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
448{
449 struct scatterlist sg, sg_dummy;
450 void *dummy = NULL, *rx_buf = NULL;
451 struct dma_async_tx_descriptor *desc, *desc_dummy;
452 unsigned len;
453 int ret = 0;
454
455 if (rspi->dma_width_16bit) {
456 /*
457 * If DMAC bus width is 16-bit, the driver allocates a dummy
458 * buffer. And, finally the driver converts the DMAC data into
459 * actual data as the following