aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-rspi.c
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert+renesas@linux-m68k.org>2014-01-24 03:43:58 -0500
committerMark Brown <broonie@linaro.org>2014-01-27 15:05:34 -0500
commit9372220678cd4c62992f7637b2ee36b47fa58d37 (patch)
tree92b77a96b9c1ea9e23c33a2baefc1cbadb18bfe1 /drivers/spi/spi-rspi.c
parent340a15e6f0d6cd436c55693f7328a1de02fcdb96 (diff)
spi: rspi: Add support for more than one interrupt
Add support for multiple interrupts, based on the SDK reference code. This is needed for RZ/A1H, which supports 3 interrupts. When using multiple interrupts, they must be called "rx" (SPRI) and "tx" (SPTI). The error interrupt (SPEI) is not used, as it matters for slave mode only. When using a single interrupt, it may be called "mux". If it cannot be found, the first interrupt in the device's resources will be used. Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-rspi.c')
-rw-r--r--drivers/spi/spi-rspi.c106
1 files changed, 87 insertions, 19 deletions
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index 5d39cd3eba62..d2ade5e09f58 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * SH RSPI driver 2 * SH RSPI driver
3 * 3 *
4 * Copyright (C) 2012 Renesas Solutions Corp. 4 * Copyright (C) 2012, 2013 Renesas Solutions Corp.
5 * 5 *
6 * Based on spi-sh.c: 6 * Based on spi-sh.c:
7 * Copyright (C) 2011 Renesas Solutions Corp. 7 * Copyright (C) 2011 Renesas Solutions Corp.
@@ -183,12 +183,12 @@ struct rspi_data {
183 struct clk *clk; 183 struct clk *clk;
184 u8 spsr; 184 u8 spsr;
185 u16 spcmd; 185 u16 spcmd;
186 int rx_irq, tx_irq;
186 const struct spi_ops *ops; 187 const struct spi_ops *ops;
187 188
188 /* for dmaengine */ 189 /* for dmaengine */
189 struct dma_chan *chan_tx; 190 struct dma_chan *chan_tx;
190 struct dma_chan *chan_rx; 191 struct dma_chan *chan_rx;
191 int irq;
192 192
193 unsigned dma_width_16bit:1; 193 unsigned dma_width_16bit:1;
194 unsigned dma_callbacked:1; 194 unsigned dma_callbacked:1;
@@ -440,7 +440,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
440 struct scatterlist sg; 440 struct scatterlist sg;
441 const void *buf = NULL; 441 const void *buf = NULL;
442 struct dma_async_tx_descriptor *desc; 442 struct dma_async_tx_descriptor *desc;
443 unsigned len; 443 unsigned int len;
444 int ret = 0; 444 int ret = 0;
445 445
446 if (rspi->dma_width_16bit) { 446 if (rspi->dma_width_16bit) {
@@ -478,7 +478,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
478 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be 478 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be
479 * called. So, this driver disables the IRQ while DMA transfer. 479 * called. So, this driver disables the IRQ while DMA transfer.
480 */ 480 */
481 disable_irq(rspi->irq); 481 disable_irq(rspi->tx_irq);
482 482
483 rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR); 483 rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, RSPI_SPCR);
484 rspi_enable_irq(rspi, SPCR_SPTIE); 484 rspi_enable_irq(rspi, SPCR_SPTIE);
@@ -497,7 +497,7 @@ static int rspi_send_dma(struct rspi_data *rspi, struct spi_transfer *t)
497 ret = -ETIMEDOUT; 497 ret = -ETIMEDOUT;
498 rspi_disable_irq(rspi, SPCR_SPTIE); 498 rspi_disable_irq(rspi, SPCR_SPTIE);
499 499
500 enable_irq(rspi->irq); 500 enable_irq(rspi->tx_irq);
501 501
502end: 502end:
503 rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE); 503 rspi_dma_unmap_sg(&sg, rspi->chan_tx, DMA_TO_DEVICE);
@@ -536,7 +536,7 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
536 struct scatterlist sg, sg_dummy; 536 struct scatterlist sg, sg_dummy;
537 void *dummy = NULL, *rx_buf = NULL; 537 void *dummy = NULL, *rx_buf = NULL;
538 struct dma_async_tx_descriptor *desc, *desc_dummy; 538 struct dma_async_tx_descriptor *desc, *desc_dummy;
539 unsigned len; 539 unsigned int len;
540 int ret = 0; 540 int ret = 0;
541 541
542 if (rspi->dma_width_16bit) { 542 if (rspi->dma_width_16bit) {
@@ -594,7 +594,9 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
594 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be 594 * DMAC needs SPTIE, but if SPTIE is set, this IRQ routine will be
595 * called. So, this driver disables the IRQ while DMA transfer. 595 * called. So, this driver disables the IRQ while DMA transfer.
596 */ 596 */
597 disable_irq(rspi->irq); 597 disable_irq(rspi->tx_irq);
598 if (rspi->rx_irq != rspi->tx_irq)
599 disable_irq(rspi->rx_irq);
598 600
599 rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR); 601 rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, RSPI_SPCR);
600 rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE); 602 rspi_enable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
@@ -617,7 +619,9 @@ static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t)
617 ret = -ETIMEDOUT; 619 ret = -ETIMEDOUT;
618 rspi_disable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE); 620 rspi_disable_irq(rspi, SPCR_SPTIE | SPCR_SPRIE);
619 621
620 enable_irq(rspi->irq); 622 enable_irq(rspi->tx_irq);
623 if (rspi->rx_irq != rspi->tx_irq)
624 enable_irq(rspi->rx_irq);
621 625
622end: 626end:
623 rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE); 627 rspi_dma_unmap_sg(&sg, rspi->chan_rx, DMA_FROM_DEVICE);
@@ -775,7 +779,7 @@ static int rspi_unprepare_message(struct spi_master *master,
775 return 0; 779 return 0;
776} 780}
777 781
778static irqreturn_t rspi_irq(int irq, void *_sr) 782static irqreturn_t rspi_irq_mux(int irq, void *_sr)
779{ 783{
780 struct rspi_data *rspi = _sr; 784 struct rspi_data *rspi = _sr;
781 u8 spsr; 785 u8 spsr;
@@ -797,6 +801,36 @@ static irqreturn_t rspi_irq(int irq, void *_sr)
797 return ret; 801 return ret;
798} 802}
799 803
804static irqreturn_t rspi_irq_rx(int irq, void *_sr)
805{
806 struct rspi_data *rspi = _sr;
807 u8 spsr;
808
809 rspi->spsr = spsr = rspi_read8(rspi, RSPI_SPSR);
810 if (spsr & SPSR_SPRF) {
811 rspi_disable_irq(rspi, SPCR_SPRIE);
812 wake_up(&rspi->wait);
813 return IRQ_HANDLED;
814 }
815
816 return 0;
817}
818
819static irqreturn_t rspi_irq_tx(int irq, void *_sr)
820{
821 struct rspi_data *rspi = _sr;
822 u8 spsr;
823
824 rspi->spsr = spsr = rspi_read8(rspi, RSPI_SPSR);
825 if (spsr & SPSR_SPTEF) {
826 rspi_disable_irq(rspi, SPCR_SPTIE);
827 wake_up(&rspi->wait);
828 return IRQ_HANDLED;
829 }
830
831 return 0;
832}
833
800static int rspi_request_dma(struct rspi_data *rspi, 834static int rspi_request_dma(struct rspi_data *rspi,
801 struct platform_device *pdev) 835 struct platform_device *pdev)
802{ 836{
@@ -868,12 +902,25 @@ static int rspi_remove(struct platform_device *pdev)
868 return 0; 902 return 0;
869} 903}
870 904
905static int rspi_request_irq(struct device *dev, unsigned int irq,
906 irq_handler_t handler, const char *suffix,
907 void *dev_id)
908{
909 const char *base = dev_name(dev);
910 size_t len = strlen(base) + strlen(suffix) + 2;
911 char *name = devm_kzalloc(dev, len, GFP_KERNEL);
912 if (!name)
913 return -ENOMEM;
914 snprintf(name, len, "%s:%s", base, suffix);
915 return devm_request_irq(dev, irq, handler, 0, name, dev_id);
916}
917
871static int rspi_probe(struct platform_device *pdev) 918static int rspi_probe(struct platform_device *pdev)
872{ 919{
873 struct resource *res; 920 struct resource *res;
874 struct spi_master *master; 921 struct spi_master *master;
875 struct rspi_data *rspi; 922 struct rspi_data *rspi;
876 int ret, irq; 923 int ret;
877 char clk_name[16]; 924 char clk_name[16];
878 const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev); 925 const struct rspi_plat_data *rspi_pd = dev_get_platdata(&pdev->dev);
879 const struct spi_ops *ops; 926 const struct spi_ops *ops;
@@ -886,12 +933,6 @@ static int rspi_probe(struct platform_device *pdev)
886 return -ENODEV; 933 return -ENODEV;
887 } 934 }
888 935
889 irq = platform_get_irq(pdev, 0);
890 if (irq < 0) {
891 dev_err(&pdev->dev, "platform_get_irq error\n");
892 return -ENODEV;
893 }
894
895 master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data)); 936 master = spi_alloc_master(&pdev->dev, sizeof(struct rspi_data));
896 if (master == NULL) { 937 if (master == NULL) {
897 dev_err(&pdev->dev, "spi_alloc_master error.\n"); 938 dev_err(&pdev->dev, "spi_alloc_master error.\n");
@@ -934,14 +975,41 @@ static int rspi_probe(struct platform_device *pdev)
934 master->unprepare_message = rspi_unprepare_message; 975 master->unprepare_message = rspi_unprepare_message;
935 master->mode_bits = SPI_CPHA | SPI_CPOL; 976 master->mode_bits = SPI_CPHA | SPI_CPOL;
936 977
937 ret = devm_request_irq(&pdev->dev, irq, rspi_irq, 0, 978 ret = platform_get_irq_byname(pdev, "rx");
938 dev_name(&pdev->dev), rspi); 979 if (ret < 0) {
980 ret = platform_get_irq_byname(pdev, "mux");
981 if (ret < 0)
982 ret = platform_get_irq(pdev, 0);
983 if (ret >= 0)
984 rspi->rx_irq = rspi->tx_irq = ret;
985 } else {
986 rspi->rx_irq = ret;
987 ret = platform_get_irq_byname(pdev, "tx");
988 if (ret >= 0)
989 rspi->tx_irq = ret;
990 }
991 if (ret < 0) {
992 dev_err(&pdev->dev, "platform_get_irq error\n");
993 goto error2;
994 }
995
996 if (rspi->rx_irq == rspi->tx_irq) {
997 /* Single multiplexed interrupt */
998 ret = rspi_request_irq(&pdev->dev, rspi->rx_irq, rspi_irq_mux,
999 "mux", rspi);
1000 } else {
1001 /* Multi-interrupt mode, only SPRI and SPTI are used */
1002 ret = rspi_request_irq(&pdev->dev, rspi->rx_irq, rspi_irq_rx,
1003 "rx", rspi);
1004 if (!ret)
1005 ret = rspi_request_irq(&pdev->dev, rspi->tx_irq,
1006 rspi_irq_tx, "tx", rspi);
1007 }
939 if (ret < 0) { 1008 if (ret < 0) {
940 dev_err(&pdev->dev, "request_irq error\n"); 1009 dev_err(&pdev->dev, "request_irq error\n");
941 goto error2; 1010 goto error2;
942 } 1011 }
943 1012
944 rspi->irq = irq;
945 ret = rspi_request_dma(rspi, pdev); 1013 ret = rspi_request_dma(rspi, pdev);
946 if (ret < 0) { 1014 if (ret < 0) {
947 dev_err(&pdev->dev, "rspi_request_dma failed.\n"); 1015 dev_err(&pdev->dev, "rspi_request_dma failed.\n");