Skip to content

Commit e19b63c

Browse files
larsclausenbroonie
authored andcommitted
spi: altera: Switch to SPI core transfer queue management
The Altera SPI driver currently uses the spi-bitbang infrastructure for transfer queue management, but non of the bitbang functionality itself. This is because when the driver was written this was the only way to not have to do queue management in the driver itself. Nowadays transfer queue management is available from the SPI driver core itself and using the bitbang infrastructure just adds an additional level of indirection. Switch the driver over to using the core queue management directly. Signed-off-by: Lars-Peter Clausen <[email protected]> Signed-off-by: Mark Brown <[email protected]>
1 parent 5771a8c commit e19b63c

File tree

2 files changed

+27
-68
lines changed

2 files changed

+27
-68
lines changed

drivers/spi/Kconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ comment "SPI Master Controller Drivers"
5555

5656
config SPI_ALTERA
5757
tristate "Altera SPI Controller"
58-
select SPI_BITBANG
5958
help
6059
This is the driver for the Altera SPI Controller.
6160

drivers/spi/spi-altera.c

Lines changed: 27 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include <linux/module.h>
1919
#include <linux/platform_device.h>
2020
#include <linux/spi/spi.h>
21-
#include <linux/spi/spi_bitbang.h>
2221
#include <linux/io.h>
2322
#include <linux/of.h>
2423

@@ -45,10 +44,6 @@
4544
#define ALTERA_SPI_CONTROL_SSO_MSK 0x400
4645

4746
struct altera_spi {
48-
/* bitbang has to be first */
49-
struct spi_bitbang bitbang;
50-
struct completion done;
51-
5247
void __iomem *base;
5348
int irq;
5449
int len;
@@ -66,39 +61,18 @@ static inline struct altera_spi *altera_spi_to_hw(struct spi_device *sdev)
6661
return spi_master_get_devdata(sdev->master);
6762
}
6863

69-
static void altera_spi_chipsel(struct spi_device *spi, int value)
64+
static void altera_spi_set_cs(struct spi_device *spi, bool is_high)
7065
{
7166
struct altera_spi *hw = altera_spi_to_hw(spi);
7267

73-
if (spi->mode & SPI_CS_HIGH) {
74-
switch (value) {
75-
case BITBANG_CS_INACTIVE:
76-
writel(1 << spi->chip_select,
77-
hw->base + ALTERA_SPI_SLAVE_SEL);
78-
hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK;
79-
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
80-
break;
81-
82-
case BITBANG_CS_ACTIVE:
83-
hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK;
84-
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
85-
writel(0, hw->base + ALTERA_SPI_SLAVE_SEL);
86-
break;
87-
}
68+
if (is_high) {
69+
hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK;
70+
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
71+
writel(0, hw->base + ALTERA_SPI_SLAVE_SEL);
8872
} else {
89-
switch (value) {
90-
case BITBANG_CS_INACTIVE:
91-
hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK;
92-
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
93-
break;
94-
95-
case BITBANG_CS_ACTIVE:
96-
writel(1 << spi->chip_select,
97-
hw->base + ALTERA_SPI_SLAVE_SEL);
98-
hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK;
99-
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
100-
break;
101-
}
73+
writel(BIT(spi->chip_select), hw->base + ALTERA_SPI_SLAVE_SEL);
74+
hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK;
75+
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
10276
}
10377
}
10478

@@ -116,9 +90,10 @@ static inline unsigned int hw_txbyte(struct altera_spi *hw, int count)
11690
return 0;
11791
}
11892

119-
static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
93+
static int altera_spi_txrx(struct spi_master *master,
94+
struct spi_device *spi, struct spi_transfer *t)
12095
{
121-
struct altera_spi *hw = altera_spi_to_hw(spi);
96+
struct altera_spi *hw = spi_master_get_devdata(master);
12297

12398
hw->tx = t->tx_buf;
12499
hw->rx = t->rx_buf;
@@ -133,11 +108,6 @@ static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
133108

134109
/* send the first byte */
135110
writel(hw_txbyte(hw, 0), hw->base + ALTERA_SPI_TXDATA);
136-
137-
wait_for_completion(&hw->done);
138-
/* disable receive interrupt */
139-
hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK;
140-
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
141111
} else {
142112
while (hw->count < hw->len) {
143113
unsigned int rxd;
@@ -164,14 +134,16 @@ static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
164134

165135
hw->count++;
166136
}
137+
spi_finalize_current_transfer(master);
167138
}
168139

169-
return hw->count * hw->bytes_per_word;
140+
return t->len;
170141
}
171142

172143
static irqreturn_t altera_spi_irq(int irq, void *dev)
173144
{
174-
struct altera_spi *hw = dev;
145+
struct spi_master *master = dev;
146+
struct altera_spi *hw = spi_master_get_devdata(master);
175147
unsigned int rxd;
176148

177149
rxd = readl(hw->base + ALTERA_SPI_RXDATA);
@@ -189,10 +161,15 @@ static irqreturn_t altera_spi_irq(int irq, void *dev)
189161

190162
hw->count++;
191163

192-
if (hw->count < hw->len)
164+
if (hw->count < hw->len) {
193165
writel(hw_txbyte(hw, hw->count), hw->base + ALTERA_SPI_TXDATA);
194-
else
195-
complete(&hw->done);
166+
} else {
167+
/* disable receive interrupt */
168+
hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK;
169+
writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
170+
171+
spi_finalize_current_transfer(master);
172+
}
196173

197174
return IRQ_HANDLED;
198175
}
@@ -214,14 +191,10 @@ static int altera_spi_probe(struct platform_device *pdev)
214191
master->mode_bits = SPI_CS_HIGH;
215192
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 16);
216193
master->dev.of_node = pdev->dev.of_node;
194+
master->transfer_one = altera_spi_txrx;
195+
master->set_cs = altera_spi_set_cs;
217196

218197
hw = spi_master_get_devdata(master);
219-
platform_set_drvdata(pdev, hw);
220-
221-
/* setup the state for the bitbang driver */
222-
hw->bitbang.master = master;
223-
hw->bitbang.chipselect = altera_spi_chipsel;
224-
hw->bitbang.txrx_bufs = altera_spi_txrx;
225198

226199
/* find and map our resources */
227200
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -239,15 +212,13 @@ static int altera_spi_probe(struct platform_device *pdev)
239212
/* irq is optional */
240213
hw->irq = platform_get_irq(pdev, 0);
241214
if (hw->irq >= 0) {
242-
init_completion(&hw->done);
243215
err = devm_request_irq(&pdev->dev, hw->irq, altera_spi_irq, 0,
244-
pdev->name, hw);
216+
pdev->name, master);
245217
if (err)
246218
goto exit;
247219
}
248220

249-
/* register our spi controller */
250-
err = spi_bitbang_start(&hw->bitbang);
221+
err = devm_spi_register_master(&pdev->dev, master);
251222
if (err)
252223
goto exit;
253224
dev_info(&pdev->dev, "base %p, irq %d\n", hw->base, hw->irq);
@@ -258,16 +229,6 @@ static int altera_spi_probe(struct platform_device *pdev)
258229
return err;
259230
}
260231

261-
static int altera_spi_remove(struct platform_device *dev)
262-
{
263-
struct altera_spi *hw = platform_get_drvdata(dev);
264-
struct spi_master *master = hw->bitbang.master;
265-
266-
spi_bitbang_stop(&hw->bitbang);
267-
spi_master_put(master);
268-
return 0;
269-
}
270-
271232
#ifdef CONFIG_OF
272233
static const struct of_device_id altera_spi_match[] = {
273234
{ .compatible = "ALTR,spi-1.0", },
@@ -279,7 +240,6 @@ MODULE_DEVICE_TABLE(of, altera_spi_match);
279240

280241
static struct platform_driver altera_spi_driver = {
281242
.probe = altera_spi_probe,
282-
.remove = altera_spi_remove,
283243
.driver = {
284244
.name = DRV_NAME,
285245
.pm = NULL,

0 commit comments

Comments
 (0)