aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2009-11-26 06:10:05 -0500
committerGrant Likely <grant.likely@secretlab.ca>2009-12-13 02:48:27 -0500
commit8051effcbced8478119167b93b0e9554cb82d28e (patch)
tree03ce88851ca697c8ed5f1d8eadcb32972342dbac
parent41df70d9ac2d0d36b23a0ec4866f67e540f366ff (diff)
spi: SuperH MSIOF SPI Master driver V2
This patch is V2 of SPI Master support for the SuperH MSIOF. Full duplex, spi mode 0-3, active high cs, 3-wire and lsb first should all be supported, but the driver has so far only been tested with "mmc_spi". The MSIOF hardware comes with 32-bit FIFOs for receive and transmit, and this driver simply breaks the SPI messages into FIFO-sized chunks. The MSIOF hardware manages the pins for clock, receive and transmit (sck/miso/mosi), but the chip select pin is managed by software and must be configured as a regular GPIO pin by the board code. Performance wise there is still room for improvement, but on a Ecovec board with the built-in sh7724 MSIOF0 this driver gets Mini-sd read speeds of about half a megabyte per second. Future work include better clock setup and merging of 8-bit transfers into 32-bit words to reduce interrupt load and improve throughput. Signed-off-by: Magnus Damm <damm@opensource.se> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
-rw-r--r--drivers/spi/Kconfig7
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/spi_sh_msiof.c691
-rw-r--r--include/linux/spi/sh_msiof.h10
4 files changed, 709 insertions, 0 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index c00f9e5b9df8..06e1c0c9d35e 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -223,6 +223,13 @@ config SPI_S3C24XX_GPIO
223 the inbuilt hardware cannot provide the transfer mode, or 223 the inbuilt hardware cannot provide the transfer mode, or
224 where the board is using non hardware connected pins. 224 where the board is using non hardware connected pins.
225 225
226config SPI_SH_MSIOF
227 tristate "SuperH MSIOF SPI controller"
228 depends on SUPERH && HAVE_CLK
229 select SPI_BITBANG
230 help
231 SPI driver for SuperH MSIOF blocks.
232
226config SPI_SH_SCI 233config SPI_SH_SCI
227 tristate "SuperH SCI SPI controller" 234 tristate "SuperH SCI SPI controller"
228 depends on SUPERH 235 depends on SUPERH
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 2f2bebc63b64..9c51e2526892 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o
35obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o 35obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o
36obj-$(CONFIG_SPI_XILINX_PLTFM) += xilinx_spi_pltfm.o 36obj-$(CONFIG_SPI_XILINX_PLTFM) += xilinx_spi_pltfm.o
37obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o 37obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o
38obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o
38obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o 39obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o
39# ... add above this line ... 40# ... add above this line ...
40 41
diff --git a/drivers/spi/spi_sh_msiof.c b/drivers/spi/spi_sh_msiof.c
new file mode 100644
index 000000000000..51e5e1dfa6e5
--- /dev/null
+++ b/drivers/spi/spi_sh_msiof.c
@@ -0,0 +1,691 @@
1/*
2 * SuperH MSIOF SPI Master Interface
3 *
4 * Copyright (c) 2009 Magnus Damm
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/interrupt.h>
16#include <linux/platform_device.h>
17#include <linux/completion.h>
18#include <linux/pm_runtime.h>
19#include <linux/gpio.h>
20#include <linux/bitmap.h>
21#include <linux/clk.h>
22#include <linux/io.h>
23
24#include <linux/spi/spi.h>
25#include <linux/spi/spi_bitbang.h>
26#include <linux/spi/sh_msiof.h>
27
28#include <asm/spi.h>
29#include <asm/unaligned.h>
30
31struct sh_msiof_spi_priv {
32 struct spi_bitbang bitbang; /* must be first for spi_bitbang.c */
33 void __iomem *mapbase;
34 struct clk *clk;
35 struct platform_device *pdev;
36 struct sh_msiof_spi_info *info;
37 struct completion done;
38 unsigned long flags;
39 int tx_fifo_size;
40 int rx_fifo_size;
41};
42
43#define TMDR1 0x00
44#define TMDR2 0x04
45#define TMDR3 0x08
46#define RMDR1 0x10
47#define RMDR2 0x14
48#define RMDR3 0x18
49#define TSCR 0x20
50#define RSCR 0x22
51#define CTR 0x28
52#define FCTR 0x30
53#define STR 0x40
54#define IER 0x44
55#define TDR1 0x48
56#define TDR2 0x4c
57#define TFDR 0x50
58#define RDR1 0x58
59#define RDR2 0x5c
60#define RFDR 0x60
61
62#define CTR_TSCKE (1 << 15)
63#define CTR_TFSE (1 << 14)
64#define CTR_TXE (1 << 9)
65#define CTR_RXE (1 << 8)
66
67#define STR_TEOF (1 << 23)
68#define STR_REOF (1 << 7)
69
70static unsigned long sh_msiof_read(struct sh_msiof_spi_priv *p, int reg_offs)
71{
72 switch (reg_offs) {
73 case TSCR:
74 case RSCR:
75 return ioread16(p->mapbase + reg_offs);
76 default:
77 return ioread32(p->mapbase + reg_offs);
78 }
79}
80
81static void sh_msiof_write(struct sh_msiof_spi_priv *p, int reg_offs,
82 unsigned long value)
83{
84 switch (reg_offs) {
85 case TSCR:
86 case RSCR:
87 iowrite16(value, p->mapbase + reg_offs);
88 break;
89 default:
90 iowrite32(value, p->mapbase + reg_offs);
91 break;
92 }
93}
94
95static int sh_msiof_modify_ctr_wait(struct sh_msiof_spi_priv *p,
96 unsigned long clr, unsigned long set)
97{
98 unsigned long mask = clr | set;
99 unsigned long data;
100 int k;
101
102 data = sh_msiof_read(p, CTR);
103 data &= ~clr;
104 data |= set;
105 sh_msiof_write(p, CTR, data);
106
107 for (k = 100; k > 0; k--) {
108 if ((sh_msiof_read(p, CTR) & mask) == set)
109 break;
110
111 udelay(10);
112 }
113
114 return k > 0 ? 0 : -ETIMEDOUT;
115}
116
117static irqreturn_t sh_msiof_spi_irq(int irq, void *data)
118{
119 struct sh_msiof_spi_priv *p = data;
120
121 /* just disable the interrupt and wake up */
122 sh_msiof_write(p, IER, 0);
123 complete(&p->done);
124
125 return IRQ_HANDLED;
126}
127
128static struct {
129 unsigned short div;
130 unsigned short scr;
131} const sh_msiof_spi_clk_table[] = {
132 { 1, 0x0007 },
133 { 2, 0x0000 },
134 { 4, 0x0001 },
135 { 8, 0x0002 },
136 { 16, 0x0003 },
137 { 32, 0x0004 },
138 { 64, 0x1f00 },
139 { 128, 0x1f01 },
140 { 256, 0x1f02 },
141 { 512, 0x1f03 },
142 { 1024, 0x1f04 },
143};
144
145static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p,
146 unsigned long parent_rate,
147 unsigned long spi_hz)
148{
149 unsigned long div = 1024;
150 size_t k;
151
152 if (!WARN_ON(!spi_hz || !parent_rate))
153 div = parent_rate / spi_hz;
154
155 /* TODO: make more fine grained */
156
157 for (k = 0; k < ARRAY_SIZE(sh_msiof_spi_clk_table); k++) {
158 if (sh_msiof_spi_clk_table[k].div >= div)
159 break;
160 }
161
162 k = min_t(int, k, ARRAY_SIZE(sh_msiof_spi_clk_table) - 1);
163
164 sh_msiof_write(p, TSCR, sh_msiof_spi_clk_table[k].scr);
165 sh_msiof_write(p, RSCR, sh_msiof_spi_clk_table[k].scr);
166}
167
168static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p,
169 int cpol, int cpha,
170 int tx_hi_z, int lsb_first)
171{
172 unsigned long tmp;
173 int edge;
174
175 /*
176 * CPOL CPHA TSCKIZ RSCKIZ TEDG REDG(!)
177 * 0 0 10 10 1 0
178 * 0 1 10 10 0 1
179 * 1 0 11 11 0 1
180 * 1 1 11 11 1 0
181 *
182 * (!) Note: REDG is inverted recommended data sheet setting
183 */
184
185 sh_msiof_write(p, FCTR, 0);
186 sh_msiof_write(p, TMDR1, 0xe2000005 | (lsb_first << 24));
187 sh_msiof_write(p, RMDR1, 0x22000005 | (lsb_first << 24));
188
189 tmp = 0xa0000000;
190 tmp |= cpol << 30; /* TSCKIZ */
191 tmp |= cpol << 28; /* RSCKIZ */
192
193 edge = cpol ? cpha : !cpha;
194
195 tmp |= edge << 27; /* TEDG */
196 tmp |= !edge << 26; /* REDG */
197 tmp |= (tx_hi_z ? 2 : 0) << 22; /* TXDIZ */
198 sh_msiof_write(p, CTR, tmp);
199}
200
201static void sh_msiof_spi_set_mode_regs(struct sh_msiof_spi_priv *p,
202 const void *tx_buf, void *rx_buf,
203 int bits, int words)
204{
205 unsigned long dr2;
206
207 dr2 = ((bits - 1) << 24) | ((words - 1) << 16);
208
209 if (tx_buf)
210 sh_msiof_write(p, TMDR2, dr2);
211 else
212 sh_msiof_write(p, TMDR2, dr2 | 1);
213
214 if (rx_buf)
215 sh_msiof_write(p, RMDR2, dr2);
216
217 sh_msiof_write(p, IER, STR_TEOF | STR_REOF);
218}
219
220static void sh_msiof_reset_str(struct sh_msiof_spi_priv *p)
221{
222 sh_msiof_write(p, STR, sh_msiof_read(p, STR));
223}
224
225static void sh_msiof_spi_write_fifo_8(struct sh_msiof_spi_priv *p,
226 const void *tx_buf, int words, int fs)
227{
228 const unsigned char *buf_8 = tx_buf;
229 int k;
230
231 for (k = 0; k < words; k++)
232 sh_msiof_write(p, TFDR, buf_8[k] << fs);
233}
234
235static void sh_msiof_spi_write_fifo_16(struct sh_msiof_spi_priv *p,
236 const void *tx_buf, int words, int fs)
237{
238 const unsigned short *buf_16 = tx_buf;
239 int k;
240
241 for (k = 0; k < words; k++)
242 sh_msiof_write(p, TFDR, buf_16[k] << fs);
243}
244
245static void sh_msiof_spi_write_fifo_16u(struct sh_msiof_spi_priv *p,
246 const void *tx_buf, int words, int fs)
247{
248 const unsigned short *buf_16 = tx_buf;
249 int k;
250
251 for (k = 0; k < words; k++)
252 sh_msiof_write(p, TFDR, get_unaligned(&buf_16[k]) << fs);
253}
254
255static void sh_msiof_spi_write_fifo_32(struct sh_msiof_spi_priv *p,
256 const void *tx_buf, int words, int fs)
257{
258 const unsigned int *buf_32 = tx_buf;
259 int k;
260
261 for (k = 0; k < words; k++)
262 sh_msiof_write(p, TFDR, buf_32[k] << fs);
263}
264
265static void sh_msiof_spi_write_fifo_32u(struct sh_msiof_spi_priv *p,
266 const void *tx_buf, int words, int fs)
267{
268 const unsigned int *buf_32 = tx_buf;
269 int k;
270
271 for (k = 0; k < words; k++)
272 sh_msiof_write(p, TFDR, get_unaligned(&buf_32[k]) << fs);
273}
274
275static void sh_msiof_spi_read_fifo_8(struct sh_msiof_spi_priv *p,
276 void *rx_buf, int words, int fs)
277{
278 unsigned char *buf_8 = rx_buf;
279 int k;
280
281 for (k = 0; k < words; k++)
282 buf_8[k] = sh_msiof_read(p, RFDR) >> fs;
283}
284
285static void sh_msiof_spi_read_fifo_16(struct sh_msiof_spi_priv *p,
286 void *rx_buf, int words, int fs)
287{
288 unsigned short *buf_16 = rx_buf;
289 int k;
290
291 for (k = 0; k < words; k++)
292 buf_16[k] = sh_msiof_read(p, RFDR) >> fs;
293}
294
295static void sh_msiof_spi_read_fifo_16u(struct sh_msiof_spi_priv *p,
296 void *rx_buf, int words, int fs)
297{
298 unsigned short *buf_16 = rx_buf;
299 int k;
300
301 for (k = 0; k < words; k++)
302 put_unaligned(sh_msiof_read(p, RFDR) >> fs, &buf_16[k]);
303}
304
305static void sh_msiof_spi_read_fifo_32(struct sh_msiof_spi_priv *p,
306 void *rx_buf, int words, int fs)
307{
308 unsigned int *buf_32 = rx_buf;
309 int k;
310
311 for (k = 0; k < words; k++)
312 buf_32[k] = sh_msiof_read(p, RFDR) >> fs;
313}
314
315static void sh_msiof_spi_read_fifo_32u(struct sh_msiof_spi_priv *p,
316 void *rx_buf, int words, int fs)
317{
318 unsigned int *buf_32 = rx_buf;
319 int k;
320
321 for (k = 0; k < words; k++)
322 put_unaligned(sh_msiof_read(p, RFDR) >> fs, &buf_32[k]);
323}
324
325static int sh_msiof_spi_bits(struct spi_device *spi, struct spi_transfer *t)
326{
327 int bits;
328
329 bits = t ? t->bits_per_word : 0;
330 bits = bits ? bits : spi->bits_per_word;
331 return bits;
332}
333
334static unsigned long sh_msiof_spi_hz(struct spi_device *spi,
335 struct spi_transfer *t)
336{
337 unsigned long hz;
338
339 hz = t ? t->speed_hz : 0;
340 hz = hz ? hz : spi->max_speed_hz;
341 return hz;
342}
343
344static int sh_msiof_spi_setup_transfer(struct spi_device *spi,
345 struct spi_transfer *t)
346{
347 int bits;
348
349 /* noting to check hz values against since parent clock is disabled */
350
351 bits = sh_msiof_spi_bits(spi, t);
352 if (bits < 8)
353 return -EINVAL;
354 if (bits > 32)
355 return -EINVAL;
356
357 return spi_bitbang_setup_transfer(spi, t);
358}
359
360static void sh_msiof_spi_chipselect(struct spi_device *spi, int is_on)
361{
362 struct sh_msiof_spi_priv *p = spi_master_get_devdata(spi->master);
363 int value;
364
365 /* chip select is active low unless SPI_CS_HIGH is set */
366 if (spi->mode & SPI_CS_HIGH)
367 value = (is_on == BITBANG_CS_ACTIVE) ? 1 : 0;
368 else
369 value = (is_on == BITBANG_CS_ACTIVE) ? 0 : 1;
370
371 if (is_on == BITBANG_CS_ACTIVE) {
372 if (!test_and_set_bit(0, &p->flags)) {
373 pm_runtime_get_sync(&p->pdev->dev);
374 clk_enable(p->clk);
375 }
376
377 /* Configure pins before asserting CS */
378 sh_msiof_spi_set_pin_regs(p, !!(spi->mode & SPI_CPOL),
379 !!(spi->mode & SPI_CPHA),
380 !!(spi->mode & SPI_3WIRE),
381 !!(spi->mode & SPI_LSB_FIRST));
382 }
383
384 /* use spi->controller data for CS (same strategy as spi_gpio) */
385 gpio_set_value((unsigned)spi->controller_data, value);
386
387 if (is_on == BITBANG_CS_INACTIVE) {
388 if (test_and_clear_bit(0, &p->flags)) {
389 clk_disable(p->clk);
390 pm_runtime_put(&p->pdev->dev);
391 }
392 }
393}
394
395static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
396 void (*tx_fifo)(struct sh_msiof_spi_priv *,
397 const void *, int, int),
398 void (*rx_fifo)(struct sh_msiof_spi_priv *,
399 void *, int, int),
400 const void *tx_buf, void *rx_buf,
401 int words, int bits)
402{
403 int fifo_shift;
404 int ret;
405
406 /* limit maximum word transfer to rx/tx fifo size */
407 if (tx_buf)
408 words = min_t(int, words, p->tx_fifo_size);
409 if (rx_buf)
410 words = min_t(int, words, p->rx_fifo_size);
411
412 /* the fifo contents need shifting */
413 fifo_shift = 32 - bits;
414
415 /* setup msiof transfer mode registers */
416 sh_msiof_spi_set_mode_regs(p, tx_buf, rx_buf, bits, words);
417
418 /* write tx fifo */
419 if (tx_buf)
420 tx_fifo(p, tx_buf, words, fifo_shift);
421
422 /* setup clock and rx/tx signals */
423 ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TSCKE);
424 if (rx_buf)
425 ret = ret ? ret : sh_msiof_modify_ctr_wait(p, 0, CTR_RXE);
426 ret = ret ? ret : sh_msiof_modify_ctr_wait(p, 0, CTR_TXE);
427
428 /* start by setting frame bit */
429 INIT_COMPLETION(p->done);
430 ret = ret ? ret : sh_msiof_modify_ctr_wait(p, 0, CTR_TFSE);
431 if (ret) {
432 dev_err(&p->pdev->dev, "failed to start hardware\n");
433 goto err;
434 }
435
436 /* wait for tx fifo to be emptied / rx fifo to be filled */
437 wait_for_completion(&p->done);
438
439 /* read rx fifo */
440 if (rx_buf)
441 rx_fifo(p, rx_buf, words, fifo_shift);
442
443 /* clear status bits */
444 sh_msiof_reset_str(p);
445
446 /* shut down frame, tx/tx and clock signals */
447 ret = sh_msiof_modify_ctr_wait(p, CTR_TFSE, 0);
448 ret = ret ? ret : sh_msiof_modify_ctr_wait(p, CTR_TXE, 0);
449 if (rx_buf)
450 ret = ret ? ret : sh_msiof_modify_ctr_wait(p, CTR_RXE, 0);
451 ret = ret ? ret : sh_msiof_modify_ctr_wait(p, CTR_TSCKE, 0);
452 if (ret) {
453 dev_err(&p->pdev->dev, "failed to shut down hardware\n");
454 goto err;
455 }
456
457 return words;
458
459 err:
460 sh_msiof_write(p, IER, 0);
461 return ret;
462}
463
464static int sh_msiof_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
465{
466 struct sh_msiof_spi_priv *p = spi_master_get_devdata(spi->master);
467 void (*tx_fifo)(struct sh_msiof_spi_priv *, const void *, int, int);
468 void (*rx_fifo)(struct sh_msiof_spi_priv *, void *, int, int);
469 int bits;
470 int bytes_per_word;
471 int bytes_done;
472 int words;
473 int n;
474
475 bits = sh_msiof_spi_bits(spi, t);
476
477 /* setup bytes per word and fifo read/write functions */
478 if (bits <= 8) {
479 bytes_per_word = 1;
480 tx_fifo = sh_msiof_spi_write_fifo_8;
481 rx_fifo = sh_msiof_spi_read_fifo_8;
482 } else if (bits <= 16) {
483 bytes_per_word = 2;
484 if ((unsigned long)t->tx_buf & 0x01)
485 tx_fifo = sh_msiof_spi_write_fifo_16u;
486 else
487 tx_fifo = sh_msiof_spi_write_fifo_16;
488
489 if ((unsigned long)t->rx_buf & 0x01)
490 rx_fifo = sh_msiof_spi_read_fifo_16u;
491 else
492 rx_fifo = sh_msiof_spi_read_fifo_16;
493 } else {
494 bytes_per_word = 4;
495 if ((unsigned long)t->tx_buf & 0x03)
496 tx_fifo = sh_msiof_spi_write_fifo_32u;
497 else
498 tx_fifo = sh_msiof_spi_write_fifo_32;
499
500 if ((unsigned long)t->rx_buf & 0x03)
501 rx_fifo = sh_msiof_spi_read_fifo_32u;
502 else
503 rx_fifo = sh_msiof_spi_read_fifo_32;
504 }
505
506 /* setup clocks (clock already enabled in chipselect()) */
507 sh_msiof_spi_set_clk_regs(p, clk_get_rate(p->clk),
508 sh_msiof_spi_hz(spi, t));
509
510 /* transfer in fifo sized chunks */
511 words = t->len / bytes_per_word;
512 bytes_done = 0;
513
514 while (bytes_done < t->len) {
515 n = sh_msiof_spi_txrx_once(p, tx_fifo, rx_fifo,
516 t->tx_buf + bytes_done,
517 t->rx_buf + bytes_done,
518 words, bits);
519 if (n < 0)
520 break;
521
522 bytes_done += n * bytes_per_word;
523 words -= n;
524 }
525
526 return bytes_done;
527}
528
529static u32 sh_msiof_spi_txrx_word(struct spi_device *spi, unsigned nsecs,
530 u32 word, u8 bits)
531{
532 BUG(); /* unused but needed by bitbang code */
533 return 0;
534}
535
536static int sh_msiof_spi_probe(struct platform_device *pdev)
537{
538 struct resource *r;
539 struct spi_master *master;
540 struct sh_msiof_spi_priv *p;
541 char clk_name[16];
542 int i;
543 int ret;
544
545 master = spi_alloc_master(&pdev->dev, sizeof(struct sh_msiof_spi_priv));
546 if (master == NULL) {
547 dev_err(&pdev->dev, "failed to allocate spi master\n");
548 ret = -ENOMEM;
549 goto err0;
550 }
551
552 p = spi_master_get_devdata(master);
553
554 platform_set_drvdata(pdev, p);
555 p->info = pdev->dev.platform_data;
556 init_completion(&p->done);
557
558 snprintf(clk_name, sizeof(clk_name), "msiof%d", pdev->id);
559 p->clk = clk_get(&pdev->dev, clk_name);
560 if (IS_ERR(p->clk)) {
561 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
562 ret = PTR_ERR(p->clk);
563 goto err1;
564 }
565
566 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
567 i = platform_get_irq(pdev, 0);
568 if (!r || i < 0) {
569 dev_err(&pdev->dev, "cannot get platform resources\n");
570 ret = -ENOENT;
571 goto err2;
572 }
573 p->mapbase = ioremap_nocache(r->start, resource_size(r));
574 if (!p->mapbase) {
575 dev_err(&pdev->dev, "unable to ioremap\n");
576 ret = -ENXIO;
577 goto err2;
578 }
579
580 ret = request_irq(i, sh_msiof_spi_irq, IRQF_DISABLED,
581 dev_name(&pdev->dev), p);
582 if (ret) {
583 dev_err(&pdev->dev, "unable to request irq\n");
584 goto err3;
585 }
586
587 p->pdev = pdev;
588 pm_runtime_enable(&pdev->dev);
589
590 /* The standard version of MSIOF use 64 word FIFOs */
591 p->tx_fifo_size = 64;
592 p->rx_fifo_size = 64;
593
594 /* Platform data may override FIFO sizes */
595 if (p->info->tx_fifo_override)
596 p->tx_fifo_size = p->info->tx_fifo_override;
597 if (p->info->rx_fifo_override)
598 p->rx_fifo_size = p->info->rx_fifo_override;
599
600 /* init master and bitbang code */
601 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
602 master->mode_bits |= SPI_LSB_FIRST | SPI_3WIRE;
603 master->flags = 0;
604 master->bus_num = pdev->id;
605 master->num_chipselect = p->info->num_chipselect;
606 master->setup = spi_bitbang_setup;
607 master->cleanup = spi_bitbang_cleanup;
608
609 p->bitbang.master = master;
610 p->bitbang.chipselect = sh_msiof_spi_chipselect;
611 p->bitbang.setup_transfer = sh_msiof_spi_setup_transfer;
612 p->bitbang.txrx_bufs = sh_msiof_spi_txrx;
613 p->bitbang.txrx_word[SPI_MODE_0] = sh_msiof_spi_txrx_word;
614 p->bitbang.txrx_word[SPI_MODE_1] = sh_msiof_spi_txrx_word;
615 p->bitbang.txrx_word[SPI_MODE_2] = sh_msiof_spi_txrx_word;
616 p->bitbang.txrx_word[SPI_MODE_3] = sh_msiof_spi_txrx_word;
617
618 ret = spi_bitbang_start(&p->bitbang);
619 if (ret == 0)
620 return 0;
621
622 pm_runtime_disable(&pdev->dev);
623 err3:
624 iounmap(p->mapbase);
625 err2:
626 clk_put(p->clk);
627 err1:
628 spi_master_put(master);
629 err0:
630 return ret;
631}
632
633static int sh_msiof_spi_remove(struct platform_device *pdev)
634{
635 struct sh_msiof_spi_priv *p = platform_get_drvdata(pdev);
636 int ret;
637
638 ret = spi_bitbang_stop(&p->bitbang);
639 if (!ret) {
640 pm_runtime_disable(&pdev->dev);
641 free_irq(platform_get_irq(pdev, 0), sh_msiof_spi_irq);
642 iounmap(p->mapbase);
643 clk_put(p->clk);
644 spi_master_put(p->bitbang.master);
645 }
646 return ret;
647}
648
649static int sh_msiof_spi_runtime_nop(struct device *dev)
650{
651 /* Runtime PM callback shared between ->runtime_suspend()
652 * and ->runtime_resume(). Simply returns success.
653 *
654 * This driver re-initializes all registers after
655 * pm_runtime_get_sync() anyway so there is no need
656 * to save and restore registers here.
657 */
658 return 0;
659}
660
661static struct dev_pm_ops sh_msiof_spi_dev_pm_ops = {
662 .runtime_suspend = sh_msiof_spi_runtime_nop,
663 .runtime_resume = sh_msiof_spi_runtime_nop,
664};
665
666static struct platform_driver sh_msiof_spi_drv = {
667 .probe = sh_msiof_spi_probe,
668 .remove = sh_msiof_spi_remove,
669 .driver = {
670 .name = "spi_sh_msiof",
671 .owner = THIS_MODULE,
672 .pm = &sh_msiof_spi_dev_pm_ops,
673 },
674};
675
676static int __init sh_msiof_spi_init(void)
677{
678 return platform_driver_register(&sh_msiof_spi_drv);
679}
680module_init(sh_msiof_spi_init);
681
682static void __exit sh_msiof_spi_exit(void)
683{
684 platform_driver_unregister(&sh_msiof_spi_drv);
685}
686module_exit(sh_msiof_spi_exit);
687
688MODULE_DESCRIPTION("SuperH MSIOF SPI Master Interface Driver");
689MODULE_AUTHOR("Magnus Damm");
690MODULE_LICENSE("GPL v2");
691MODULE_ALIAS("platform:spi_sh_msiof");
diff --git a/include/linux/spi/sh_msiof.h b/include/linux/spi/sh_msiof.h
new file mode 100644
index 000000000000..2e8db3d2d2e5
--- /dev/null
+++ b/include/linux/spi/sh_msiof.h
@@ -0,0 +1,10 @@
1#ifndef __SPI_SH_MSIOF_H__
2#define __SPI_SH_MSIOF_H__
3
4struct sh_msiof_spi_info {
5 int tx_fifo_override;
6 int rx_fifo_override;
7 u16 num_chipselect;
8};
9
10#endif /* __SPI_SH_MSIOF_H__ */