Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Lars-Peter Clausen and committed by
Mark Brown
e19b63cd 5771a8c0

+27 -68
-1
drivers/spi/Kconfig
··· 55 55 56 56 config SPI_ALTERA 57 57 tristate "Altera SPI Controller" 58 - select SPI_BITBANG 59 58 help 60 59 This is the driver for the Altera SPI Controller. 61 60
+27 -67
drivers/spi/spi-altera.c
··· 18 18 #include <linux/module.h> 19 19 #include <linux/platform_device.h> 20 20 #include <linux/spi/spi.h> 21 - #include <linux/spi/spi_bitbang.h> 22 21 #include <linux/io.h> 23 22 #include <linux/of.h> 24 23 ··· 44 45 #define ALTERA_SPI_CONTROL_SSO_MSK 0x400 45 46 46 47 struct altera_spi { 47 - /* bitbang has to be first */ 48 - struct spi_bitbang bitbang; 49 - struct completion done; 50 - 51 48 void __iomem *base; 52 49 int irq; 53 50 int len; ··· 61 66 return spi_master_get_devdata(sdev->master); 62 67 } 63 68 64 - static void altera_spi_chipsel(struct spi_device *spi, int value) 69 + static void altera_spi_set_cs(struct spi_device *spi, bool is_high) 65 70 { 66 71 struct altera_spi *hw = altera_spi_to_hw(spi); 67 72 68 - if (spi->mode & SPI_CS_HIGH) { 69 - switch (value) { 70 - case BITBANG_CS_INACTIVE: 71 - writel(1 << spi->chip_select, 72 - hw->base + ALTERA_SPI_SLAVE_SEL); 73 - hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK; 74 - writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); 75 - break; 76 - 77 - case BITBANG_CS_ACTIVE: 78 - hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK; 79 - writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); 80 - writel(0, hw->base + ALTERA_SPI_SLAVE_SEL); 81 - break; 82 - } 73 + if (is_high) { 74 + hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK; 75 + writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); 76 + writel(0, hw->base + ALTERA_SPI_SLAVE_SEL); 83 77 } else { 84 - switch (value) { 85 - case BITBANG_CS_INACTIVE: 86 - hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK; 87 - writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); 88 - break; 89 - 90 - case BITBANG_CS_ACTIVE: 91 - writel(1 << spi->chip_select, 92 - hw->base + ALTERA_SPI_SLAVE_SEL); 93 - hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK; 94 - writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); 95 - break; 96 - } 78 + writel(BIT(spi->chip_select), hw->base + ALTERA_SPI_SLAVE_SEL); 79 + hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK; 80 + writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); 97 81 } 98 82 } 99 83 ··· 90 116 return 0; 91 117 } 92 118 93 - static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t) 119 + static int altera_spi_txrx(struct spi_master *master, 120 + struct spi_device *spi, struct spi_transfer *t) 94 121 { 95 - struct altera_spi *hw = altera_spi_to_hw(spi); 122 + struct altera_spi *hw = spi_master_get_devdata(master); 96 123 97 124 hw->tx = t->tx_buf; 98 125 hw->rx = t->rx_buf; ··· 108 133 109 134 /* send the first byte */ 110 135 writel(hw_txbyte(hw, 0), hw->base + ALTERA_SPI_TXDATA); 111 - 112 - wait_for_completion(&hw->done); 113 - /* disable receive interrupt */ 114 - hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK; 115 - writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); 116 136 } else { 117 137 while (hw->count < hw->len) { 118 138 unsigned int rxd; ··· 134 164 135 165 hw->count++; 136 166 } 167 + spi_finalize_current_transfer(master); 137 168 } 138 169 139 - return hw->count * hw->bytes_per_word; 170 + return t->len; 140 171 } 141 172 142 173 static irqreturn_t altera_spi_irq(int irq, void *dev) 143 174 { 144 - struct altera_spi *hw = dev; 175 + struct spi_master *master = dev; 176 + struct altera_spi *hw = spi_master_get_devdata(master); 145 177 unsigned int rxd; 146 178 147 179 rxd = readl(hw->base + ALTERA_SPI_RXDATA); ··· 161 189 162 190 hw->count++; 163 191 164 - if (hw->count < hw->len) 192 + if (hw->count < hw->len) { 165 193 writel(hw_txbyte(hw, hw->count), hw->base + ALTERA_SPI_TXDATA); 166 - else 167 - complete(&hw->done); 194 + } else { 195 + /* disable receive interrupt */ 196 + hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK; 197 + writel(hw->imr, hw->base + ALTERA_SPI_CONTROL); 198 + 199 + spi_finalize_current_transfer(master); 200 + } 168 201 169 202 return IRQ_HANDLED; 170 203 } ··· 191 214 master->mode_bits = SPI_CS_HIGH; 192 215 master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 16); 193 216 master->dev.of_node = pdev->dev.of_node; 217 + master->transfer_one = altera_spi_txrx; 218 + master->set_cs = altera_spi_set_cs; 194 219 195 220 hw = spi_master_get_devdata(master); 196 - platform_set_drvdata(pdev, hw); 197 - 198 - /* setup the state for the bitbang driver */ 199 - hw->bitbang.master = master; 200 - hw->bitbang.chipselect = altera_spi_chipsel; 201 - hw->bitbang.txrx_bufs = altera_spi_txrx; 202 221 203 222 /* find and map our resources */ 204 223 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ··· 212 239 /* irq is optional */ 213 240 hw->irq = platform_get_irq(pdev, 0); 214 241 if (hw->irq >= 0) { 215 - init_completion(&hw->done); 216 242 err = devm_request_irq(&pdev->dev, hw->irq, altera_spi_irq, 0, 217 - pdev->name, hw); 243 + pdev->name, master); 218 244 if (err) 219 245 goto exit; 220 246 } 221 247 222 - /* register our spi controller */ 223 - err = spi_bitbang_start(&hw->bitbang); 248 + err = devm_spi_register_master(&pdev->dev, master); 224 249 if (err) 225 250 goto exit; 226 251 dev_info(&pdev->dev, "base %p, irq %d\n", hw->base, hw->irq); ··· 227 256 exit: 228 257 spi_master_put(master); 229 258 return err; 230 - } 231 - 232 - static int altera_spi_remove(struct platform_device *dev) 233 - { 234 - struct altera_spi *hw = platform_get_drvdata(dev); 235 - struct spi_master *master = hw->bitbang.master; 236 - 237 - spi_bitbang_stop(&hw->bitbang); 238 - spi_master_put(master); 239 - return 0; 240 259 } 241 260 242 261 #ifdef CONFIG_OF ··· 240 279 241 280 static struct platform_driver altera_spi_driver = { 242 281 .probe = altera_spi_probe, 243 - .remove = altera_spi_remove, 244 282 .driver = { 245 283 .name = DRV_NAME, 246 284 .pm = NULL,