Skip to content

Commit cf9e478

Browse files
Hisashi Nakamurabroonie
authored andcommitted
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 <[email protected]> Signed-off-by: Hiromitsu Yamasaki <[email protected]> [geert: Timeout handling cleanup, spi core integration, cancellation, rewording] Signed-off-by: Geert Uytterhoeven <[email protected]> Acked-by: Rob Herring <[email protected]> Signed-off-by: Mark Brown <[email protected]>
1 parent aa2ea91 commit cf9e478

File tree

3 files changed

+86
-33
lines changed

3 files changed

+86
-33
lines changed

Documentation/devicetree/bindings/spi/sh-msiof.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ Optional properties:
3838
specifiers, one for transmission, and one for
3939
reception.
4040
- 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.
4143
- renesas,dtdl : delay sync signal (setup) in transmit mode.
4244
Must contain one of the following values:
4345
0 (no bit delay)

drivers/spi/spi-sh-msiof.c

Lines changed: 78 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
* SuperH MSIOF SPI Master Interface
33
*
44
* 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
67
*
78
* This program is free software; you can redistribute it and/or modify
89
* it under the terms of the GNU General Public License version 2 as
@@ -33,7 +34,6 @@
3334

3435
#include <asm/unaligned.h>
3536

36-
3737
struct sh_msiof_chipdata {
3838
u16 tx_fifo_size;
3939
u16 rx_fifo_size;
@@ -53,6 +53,7 @@ struct sh_msiof_spi_priv {
5353
void *rx_dma_page;
5454
dma_addr_t tx_dma_addr;
5555
dma_addr_t rx_dma_addr;
56+
bool slave_aborted;
5657
};
5758

5859
#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,
337338
tmp |= !cs_high << MDR1_SYNCAC_SHIFT;
338339
tmp |= lsb_first << MDR1_BITLSB_SHIFT;
339340
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);
341345
if (p->master->flags & SPI_MASTER_MUST_TX) {
342346
/* These bits are reserved if RX needs TX */
343347
tmp &= ~0x0000ffff;
@@ -564,38 +568,69 @@ static int sh_msiof_prepare_message(struct spi_master *master,
564568

565569
static int sh_msiof_spi_start(struct sh_msiof_spi_priv *p, void *rx_buf)
566570
{
567-
int ret;
571+
bool slave = spi_controller_is_slave(p->master);
572+
int ret = 0;
568573

569574
/* 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);
571577
if (rx_buf && !ret)
572578
ret = sh_msiof_modify_ctr_wait(p, 0, CTR_RXE);
573579
if (!ret)
574580
ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TXE);
575581

576582
/* start by setting frame bit */
577-
if (!ret)
583+
if (!ret && !slave)
578584
ret = sh_msiof_modify_ctr_wait(p, 0, CTR_TFSE);
579585

580586
return ret;
581587
}
582588

583589
static int sh_msiof_spi_stop(struct sh_msiof_spi_priv *p, void *rx_buf)
584590
{
585-
int ret;
591+
bool slave = spi_controller_is_slave(p->master);
592+
int ret = 0;
586593

587594
/* 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);
589597
if (!ret)
590598
ret = sh_msiof_modify_ctr_wait(p, CTR_TXE, 0);
591599
if (rx_buf && !ret)
592600
ret = sh_msiof_modify_ctr_wait(p, CTR_RXE, 0);
593-
if (!ret)
601+
if (!ret && !slave)
594602
ret = sh_msiof_modify_ctr_wait(p, CTR_TSCKE, 0);
595603

596604
return ret;
597605
}
598606

607+
static 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+
616+
static 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+
599634
static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
600635
void (*tx_fifo)(struct sh_msiof_spi_priv *,
601636
const void *, int, int),
@@ -628,6 +663,7 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
628663
tx_fifo(p, tx_buf, words, fifo_shift);
629664

630665
reinit_completion(&p->done);
666+
p->slave_aborted = false;
631667

632668
ret = sh_msiof_spi_start(p, rx_buf);
633669
if (ret) {
@@ -636,11 +672,9 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p,
636672
}
637673

638674
/* wait for tx fifo to be emptied / rx fifo to be filled */
639-
if (!wait_for_completion_timeout(&p->done, HZ)) {
640-
dev_err(&p->pdev->dev, "PIO timeout\n");
641-
ret = -ETIMEDOUT;
675+
ret = sh_msiof_wait_for_completion(p);
676+
if (ret)
642677
goto stop_reset;
643-
}
644678

645679
/* read rx fifo */
646680
if (rx_buf)
@@ -732,6 +766,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
732766
sh_msiof_write(p, IER, ier_bits);
733767

734768
reinit_completion(&p->done);
769+
p->slave_aborted = false;
735770

736771
/* Now start DMA */
737772
if (rx)
@@ -746,11 +781,9 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx,
746781
}
747782

748783
/* wait for tx fifo to be emptied / rx fifo to be filled */
749-
if (!wait_for_completion_timeout(&p->done, HZ)) {
750-
dev_err(&p->pdev->dev, "DMA timeout\n");
751-
ret = -ETIMEDOUT;
784+
ret = sh_msiof_wait_for_completion(p);
785+
if (ret)
752786
goto stop_reset;
753-
}
754787

755788
/* clear status bits */
756789
sh_msiof_reset_str(p);
@@ -843,7 +876,8 @@ static int sh_msiof_transfer_one(struct spi_master *master,
843876
int ret;
844877

845878
/* 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);
847881

848882
while (master->dma_tx && len > 15) {
849883
/*
@@ -998,8 +1032,12 @@ static struct sh_msiof_spi_info *sh_msiof_spi_parse_dt(struct device *dev)
9981032
if (!info)
9991033
return NULL;
10001034

1035+
info->mode = of_property_read_bool(np, "spi-slave") ? MSIOF_SPI_SLAVE
1036+
: MSIOF_SPI_MASTER;
1037+
10011038
/* 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);
10031041
of_property_read_u32(np, "renesas,tx-fifo-size",
10041042
&info->tx_fifo_override);
10051043
of_property_read_u32(np, "renesas,rx-fifo-size",
@@ -1159,34 +1197,40 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
11591197
struct spi_master *master;
11601198
const struct sh_msiof_chipdata *chipdata;
11611199
const struct of_device_id *of_id;
1200+
struct sh_msiof_spi_info *info;
11621201
struct sh_msiof_spi_priv *p;
11631202
int i;
11641203
int ret;
11651204

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-
11751205
of_id = of_match_device(sh_msiof_match, &pdev->dev);
11761206
if (of_id) {
11771207
chipdata = of_id->data;
1178-
p->info = sh_msiof_spi_parse_dt(&pdev->dev);
1208+
info = sh_msiof_spi_parse_dt(&pdev->dev);
11791209
} else {
11801210
chipdata = (const void *)pdev->id_entry->driver_data;
1181-
p->info = dev_get_platdata(&pdev->dev);
1211+
info = dev_get_platdata(&pdev->dev);
11821212
}
11831213

1184-
if (!p->info) {
1214+
if (!info) {
11851215
dev_err(&pdev->dev, "failed to obtain device info\n");
1186-
ret = -ENXIO;
1187-
goto err1;
1216+
return -ENXIO;
11881217
}
11891218

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+
11901234
init_completion(&p->done);
11911235

11921236
p->clk = devm_clk_get(&pdev->dev, NULL);
@@ -1237,6 +1281,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
12371281
master->num_chipselect = p->info->num_chipselect;
12381282
master->setup = sh_msiof_spi_setup;
12391283
master->prepare_message = sh_msiof_prepare_message;
1284+
master->slave_abort = sh_msiof_slave_abort;
12401285
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32);
12411286
master->auto_runtime_pm = true;
12421287
master->transfer_one = sh_msiof_transfer_one;

include/linux/spi/sh_msiof.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
#ifndef __SPI_SH_MSIOF_H__
22
#define __SPI_SH_MSIOF_H__
33

4+
enum {
5+
MSIOF_SPI_MASTER,
6+
MSIOF_SPI_SLAVE,
7+
};
8+
49
struct sh_msiof_spi_info {
510
int tx_fifo_override;
611
int rx_fifo_override;
712
u16 num_chipselect;
13+
int mode;
814
unsigned int dma_tx_id;
915
unsigned int dma_rx_id;
1016
u32 dtdl;

0 commit comments

Comments
 (0)