aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHisashi Nakamura <hisashi.nakamura.ak@renesas.com>2017-05-22 09:11:43 -0400
committerMark Brown <broonie@kernel.org>2017-05-26 08:11:54 -0400
commitcf9e4784f3bde3e4749163384f27450ddffe746c (patch)
treea4047eb127979d77db50eea2930faf6cff4f78e0
parentaa2ea9115bc3f0735aa65b833076cc5fe3da1489 (diff)
spi: sh-msiof: Add slave mode support
Add slave mode support to the MSIOF driver, in both PIO and DMA mode. For now this only supports the transmission of messages with a size that is known in advance. Signed-off-by: Hisashi Nakamura <hisashi.nakamura.ak@renesas.com> Signed-off-by: Hiromitsu Yamasaki <hiromitsu.yamasaki.ym@renesas.com> [geert: Timeout handling cleanup, spi core integration, cancellation, rewording] Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Acked-by: Rob Herring <robh@kernel.org> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--Documentation/devicetree/bindings/spi/sh-msiof.txt2
-rw-r--r--drivers/spi/spi-sh-msiof.c111
-rw-r--r--include/linux/spi/sh_msiof.h6
3 files changed, 86 insertions, 33 deletions
diff --git a/Documentation/devicetree/bindings/spi/sh-msiof.txt b/Documentation/devicetree/bindings/spi/sh-msiof.txt
index dc975064fa27..64ee489571c4 100644
--- a/Documentation/devicetree/bindings/spi/sh-msiof.txt
+++ b/Documentation/devicetree/bindings/spi/sh-msiof.txt
@@ -38,6 +38,8 @@ Optional properties:
38 specifiers, one for transmission, and one for 38 specifiers, one for transmission, and one for
39 reception. 39 reception.
40- dma-names : Must contain a list of two DMA names, "tx" and "rx". 40- dma-names : Must contain a list of two DMA names, "tx" and "rx".
41- spi-slave : Empty property indicating the SPI controller is used
42 in slave mode.
41- renesas,dtdl : delay sync signal (setup) in transmit mode. 43- renesas,dtdl : delay sync signal (setup) in transmit mode.
42 Must contain one of the following values: 44 Must contain one of the following values:
43 0 (no bit delay) 45 0 (no bit delay)
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
index 2ce15ca97782..c304c7167866 100644
--- a/drivers/spi/spi-sh-msiof.c
+++ b/drivers/spi/spi-sh-msiof.c
@@ -2,7 +2,8 @@
2 * SuperH MSIOF SPI Master Interface 2 * SuperH MSIOF SPI Master Interface
3 * 3 *
4 * Copyright (c) 2009 Magnus Damm 4 * Copyright (c) 2009 Magnus Damm
5 * Copyright (C) 2014 Glider bvba 5 * Copyright (C) 2014 Renesas Electronics Corporation
6 * Copyright (C) 2014-2017 Glider bvba
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -33,7 +34,6 @@
33 34
34#include <asm/unaligned.h> 35#include <asm/unaligned.h>
35 36
36
37struct sh_msiof_chipdata { 37struct sh_msiof_chipdata {
38 u16 tx_fifo_size; 38 u16 tx_fifo_size;
39 u16 rx_fifo_size; 39 u16 rx_fifo_size;
@@ -53,6 +53,7 @@ struct sh_msiof_spi_priv {
53 void *rx_dma_page; 53 void *rx_dma_page;
54 dma_addr_t tx_dma_addr; 54 dma_addr_t tx_dma_addr;
55 dma_addr_t rx_dma_addr; 55 dma_addr_t rx_dma_addr;
56 bool slave_aborted;
56}; 57};
57 58
58#define TMDR1 0x00 /* Transmit Mode Register 1 */ 59#define TMDR1 0x00 /* Transmit Mode Register 1 */
@@ -337,7 +338,10 @@ static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p,
337 tmp |= !cs_high << MDR1_SYNCAC_SHIFT; 338 tmp |= !cs_high << MDR1_SYNCAC_SHIFT;
338 tmp |= lsb_first << MDR1_BITLSB_SHIFT; 339 tmp |= lsb_first << MDR1_BITLSB_SHIFT;
339 tmp |= sh_msiof_spi_get_dtdl_and_syncdl(p); 340 tmp |= sh_msiof_spi_get_dtdl_and_syncdl(p);
340 sh_msiof_write(p, TMDR1, tmp | MDR1_TRMD | TMDR1_PCON); 341 if (spi_controller_is_slave(p->master))
342 sh_msiof_write(p, TMDR1, tmp | TMDR1_PCON);
343 else
344 sh_msiof_write(p, TMDR1, tmp | MDR1_TRMD | TMDR1_PCON);
341 if (p->master->flags & SPI_MASTER_MUST_TX) { 345 if (p->master->flags & SPI_MASTER_MUST_TX) {
342 /* These bits are reserved if RX needs TX */ 346 /* These bits are reserved if RX needs TX */
343 tmp &= ~0x0000ffff; 347 tmp &= ~0x0000ffff;
@@ -564,17 +568,19 @@ static int sh_msiof_prepare_message(struct spi_master *master,
564 568
565static int sh_msiof_spi_start(struct sh_msiof_spi_priv *p, void *rx_buf) 569static int sh_msiof_spi_start(struct sh_msiof_spi_priv *p, void *rx_buf)
566{ 570{
567 int ret; 571 bool slave = spi_controller_is_slave(p->master);
572 int ret = 0;
568 573
569 /* setup clock and rx/tx signals */ 574 /* setup clock and rx/tx signals */
570 ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TSCKE); 575 if (!slave)
576 ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TSCKE);
571 if (rx_buf && !ret) 577 if (rx_buf && !ret)
572 ret = sh_msiof_modify_ctr_wait(p, 0, CTR_RXE); 578 ret = sh_msiof_modify_ctr_wait(p, 0, CTR_RXE);
573 if (!ret) 579 if (!ret)
574 ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TXE); 580 ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TXE);
575 581
576 /* start by setting frame bit */ 582 /* start by setting frame bit */
577 if (!ret) 583 if (!ret && !slave)
578 ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TFSE); 584 ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TFSE);
579 585
580 return ret; 586 return ret;
@@ -582,20 +588,49 @@ static int sh_msiof_spi_start(struct sh_msiof_spi_priv *p, void *rx_buf)
582 588
583static int sh_msiof_spi_stop(struct sh_msiof_spi_priv *p, void *rx_buf) 589static int sh_msiof_spi_stop(struct sh_msiof_spi_priv *p, void *rx_buf)
584{ 590{
585 int ret; 591 bool slave = spi_controller_is_slave(p->master);
592 int ret = 0;
586 593
587 /* shut down frame, rx/tx and clock signals */ 594 /* shut down frame, rx/tx and clock signals */
588 ret = sh_msiof_modify_ctr_wait(p, CTR_TFSE, 0); 595 if (!slave)
596 ret = sh_msiof_modify_ctr_wait(p, CTR_TFSE, 0);
589 if (!ret) 597 if (!ret)
590 ret = sh_msiof_modify_ctr_wait(p, CTR_TXE, 0); 598 ret = sh_msiof_modify_ctr_wait(p, CTR_TXE, 0);
591 if (rx_buf && !ret) 599 if (rx_buf && !ret)
592 ret = sh_msiof_modify_ctr_wait(p, CTR_RXE, 0); 600 ret = sh_msiof_modify_ctr_wait(p, CTR_RXE, 0);
593 if (!ret) 601 if (!ret && !slave)
594 ret = sh_msiof_modify_ctr_wait(p, CTR_TSCKE, 0); 602 ret = sh_msiof_modify_ctr_wait(p, CTR_TSCKE, 0);
595 603
596 return ret; 604 return ret;
597} 605}
598 606
607static int sh_msiof_slave_abort(struct spi_master *master)
608{
609 struct sh_msiof_spi_priv *p = spi_master_get_devdata(master);
610
611 p->slave_aborted = true;
612 complete(&p->done);
613 return 0;
614}
615
616static int sh_msiof_wait_for_completion(struct sh_msiof_spi_priv *p)
617{
618 if (spi_controller_is_slave(p->master)) {
619 if (wait_for_completion_interruptible(&p->done) ||
620 p->slave_aborted) {
621 dev_dbg(&p->pdev->dev, "interrupted\n");
622 return -EINTR;
623 }
624 } else {
625 if (!wait_for_completion_timeout(&p->done, HZ)) {
626 dev_err(&p->pdev->dev, "timeout\n");
627 return -ETIMEDOUT;
628 }
629 }
630
631 return 0;
632}
633
599static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p, 634static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
600 void (*tx_fifo)(struct sh_msiof_spi_priv *, 635 void (*tx_fifo)(struct sh_msiof_spi_priv *,
601 const void *, int, int), 636 const void *, int, int),
@@ -628,6 +663,7 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
628 tx_fifo(p, tx_buf, words, fifo_shift); 663 tx_fifo(p, tx_buf, words, fifo_shift);
629 664
630 reinit_completion(&p->done); 665 reinit_completion(&p->done);
666 p->slave_aborted = false;
631 667
632 ret = sh_msiof_spi_start(p, rx_buf); 668 ret = sh_msiof_spi_start(p, rx_buf);
633 if (ret) { 669 if (ret) {
@@ -636,11 +672,9 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
636 } 672 }
637 673
638 /* wait for tx fifo to be emptied / rx fifo to be filled */ 674 /* wait for tx fifo to be emptied / rx fifo to be filled */
639 if (!wait_for_completion_timeout(&p->done, HZ)) { 675 ret = sh_msiof_wait_for_completion(p);
640 dev_err(&p->pdev->dev, "PIO timeout\n"); 676 if (ret)
641 ret = -ETIMEDOUT;
642 goto stop_reset; 677 goto stop_reset;
643 }
644 678
645 /* read rx fifo */ 679 /* read rx fifo */
646 if (rx_buf) 680 if (rx_buf)
@@ -732,6 +766,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
732 sh_msiof_write(p, IER, ier_bits); 766 sh_msiof_write(p, IER, ier_bits);
733 767
734 reinit_completion(&p->done); 768 reinit_completion(&p->done);
769 p->slave_aborted = false;
735 770
736 /* Now start DMA */ 771 /* Now start DMA */
737 if (rx) 772 if (rx)
@@ -746,11 +781,9 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
746 } 781 }
747 782
748 /* wait for tx fifo to be emptied / rx fifo to be filled */ 783 /* wait for tx fifo to be emptied / rx fifo to be filled */
749 if (!wait_for_completion_timeout(&p->done, HZ)) { 784 ret = sh_msiof_wait_for_completion(p);
750 dev_err(&p->pdev->dev, "DMA timeout\n"); 785 if (ret)
751 ret = -ETIMEDOUT;
752 goto stop_reset; 786 goto stop_reset;
753 }
754 787
755 /* clear status bits */ 788 /* clear status bits */
756 sh_msiof_reset_str(p); 789 sh_msiof_reset_str(p);
@@ -843,7 +876,8 @@ static int sh_msiof_transfer_one(struct spi_master *master,
843 int ret; 876 int ret;
844 877
845 /* setup clocks (clock already enabled in chipselect()) */ 878 /* setup clocks (clock already enabled in chipselect()) */
846 sh_msiof_spi_set_clk_regs(p, clk_get_rate(p->clk), t->speed_hz); 879 if (!spi_controller_is_slave(p->master))
880 sh_msiof_spi_set_clk_regs(p, clk_get_rate(p->clk), t->speed_hz);
847 881
848 while (master->dma_tx && len > 15) { 882 while (master->dma_tx && len > 15) {
849 /* 883 /*
@@ -998,8 +1032,12 @@ static struct sh_msiof_spi_info *sh_msiof_spi_parse_dt(struct device *dev)
998 if (!info) 1032 if (!info)
999 return NULL; 1033 return NULL;
1000 1034
1035 info->mode = of_property_read_bool(np, "spi-slave") ? MSIOF_SPI_SLAVE
1036 : MSIOF_SPI_MASTER;
1037
1001 /* Parse the MSIOF properties */ 1038 /* Parse the MSIOF properties */
1002 of_property_read_u32(np, "num-cs", &num_cs); 1039 if (info->mode == MSIOF_SPI_MASTER)
1040 of_property_read_u32(np, "num-cs", &num_cs);
1003 of_property_read_u32(np, "renesas,tx-fifo-size", 1041 of_property_read_u32(np, "renesas,tx-fifo-size",
1004 &info->tx_fifo_override); 1042 &info->tx_fifo_override);
1005 of_property_read_u32(np, "renesas,rx-fifo-size", 1043 of_property_read_u32(np, "renesas,rx-fifo-size",
@@ -1159,34 +1197,40 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
1159 struct spi_master *master; 1197 struct spi_master *master;
1160 const struct sh_msiof_chipdata *chipdata; 1198 const struct sh_msiof_chipdata *chipdata;
1161 const struct of_device_id *of_id; 1199 const struct of_device_id *of_id;
1200 struct sh_msiof_spi_info *info;
1162 struct sh_msiof_spi_priv *p; 1201 struct sh_msiof_spi_priv *p;
1163 int i; 1202 int i;
1164 int ret; 1203 int ret;
1165 1204
1166 master = spi_alloc_master(&pdev->dev, sizeof(struct sh_msiof_spi_priv));
1167 if (master == NULL)
1168 return -ENOMEM;
1169
1170 p = spi_master_get_devdata(master);
1171
1172 platform_set_drvdata(pdev, p);
1173 p->master = master;
1174
1175 of_id = of_match_device(sh_msiof_match, &pdev->dev); 1205 of_id = of_match_device(sh_msiof_match, &pdev->dev);
1176 if (of_id) { 1206 if (of_id) {
1177 chipdata = of_id->data; 1207 chipdata = of_id->data;
1178 p->info = sh_msiof_spi_parse_dt(&pdev->dev); 1208 info = sh_msiof_spi_parse_dt(&pdev->dev);
1179 } else { 1209 } else {
1180 chipdata = (const void *)pdev->id_entry->driver_data; 1210 chipdata = (const void *)pdev->id_entry->driver_data;
1181 p->info = dev_get_platdata(&pdev->dev); 1211 info = dev_get_platdata(&pdev->dev);
1182 } 1212 }
1183 1213
1184 if (!p->info) { 1214 if (!info) {
1185 dev_err(&pdev->dev, "failed to obtain device info\n"); 1215 dev_err(&pdev->dev, "failed to obtain device info\n");
1186 ret = -ENXIO; 1216 return -ENXIO;
1187 goto err1;
1188 } 1217 }
1189 1218
1219 if (info->mode == MSIOF_SPI_SLAVE)
1220 master = spi_alloc_slave(&pdev->dev,
1221 sizeof(struct sh_msiof_spi_priv));
1222 else
1223 master = spi_alloc_master(&pdev->dev,
1224 sizeof(struct sh_msiof_spi_priv));
1225 if (master == NULL)
1226 return -ENOMEM;
1227
1228 p = spi_master_get_devdata(master);
1229
1230 platform_set_drvdata(pdev, p);
1231 p->master = master;
1232 p->info = info;
1233
1190 init_completion(&p->done); 1234 init_completion(&p->done);
1191 1235
1192 p->clk = devm_clk_get(&pdev->dev, NULL); 1236 p->clk = devm_clk_get(&pdev->dev, NULL);
@@ -1237,6 +1281,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
1237 master->num_chipselect = p->info->num_chipselect; 1281 master->num_chipselect = p->info->num_chipselect;
1238 master->setup = sh_msiof_spi_setup; 1282 master->setup = sh_msiof_spi_setup;
1239 master->prepare_message = sh_msiof_prepare_message; 1283 master->prepare_message = sh_msiof_prepare_message;
1284 master->slave_abort = sh_msiof_slave_abort;
1240 master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32); 1285 master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32);
1241 master->auto_runtime_pm = true; 1286 master->auto_runtime_pm = true;
1242 master->transfer_one = sh_msiof_transfer_one; 1287 master->transfer_one = sh_msiof_transfer_one;
diff --git a/include/linux/spi/sh_msiof.h b/include/linux/spi/sh_msiof.h
index b087a85f5f72..f74b581f242f 100644
--- a/include/linux/spi/sh_msiof.h
+++ b/include/linux/spi/sh_msiof.h
@@ -1,10 +1,16 @@
1#ifndef __SPI_SH_MSIOF_H__ 1#ifndef __SPI_SH_MSIOF_H__
2#define __SPI_SH_MSIOF_H__ 2#define __SPI_SH_MSIOF_H__
3 3
4enum {
5 MSIOF_SPI_MASTER,
6 MSIOF_SPI_SLAVE,
7};
8
4struct sh_msiof_spi_info { 9struct sh_msiof_spi_info {
5 int tx_fifo_override; 10 int tx_fifo_override;
6 int rx_fifo_override; 11 int rx_fifo_override;
7 u16 num_chipselect; 12 u16 num_chipselect;
13 int mode;
8 unsigned int dma_tx_id; 14 unsigned int dma_tx_id;
9 unsigned int dma_rx_id; 15 unsigned int dma_rx_id;
10 u32 dtdl; 16 u32 dtdl;