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

Merge remote-tracking branches 'spi/topic/spidev', 'spi/topic/sunxi', 'spi/topic/ti-qspi', 'spi/topic/topcliff-pch' and 'spi/topic/xlp' into spi-next

+107 -27
+23 -2
Documentation/devicetree/bindings/spi/spi-sun6i.txt
··· 1 - Allwinner A31 SPI controller 1 + Allwinner A31/H3 SPI controller 2 2 3 3 Required properties: 4 - - compatible: Should be "allwinner,sun6i-a31-spi". 4 + - compatible: Should be "allwinner,sun6i-a31-spi" or "allwinner,sun8i-h3-spi". 5 5 - reg: Should contain register location and length. 6 6 - interrupts: Should contain interrupt. 7 7 - clocks: phandle to the clocks feeding the SPI controller. Two are ··· 12 12 - resets: phandle to the reset controller asserting this device in 13 13 reset 14 14 15 + Optional properties: 16 + - dmas: DMA specifiers for rx and tx dma. See the DMA client binding, 17 + Documentation/devicetree/bindings/dma/dma.txt 18 + - dma-names: DMA request names should include "rx" and "tx" if present. 19 + 15 20 Example: 16 21 17 22 spi1: spi@01c69000 { ··· 26 21 clocks = <&ahb1_gates 21>, <&spi1_clk>; 27 22 clock-names = "ahb", "mod"; 28 23 resets = <&ahb1_rst 21>; 24 + }; 25 + 26 + spi0: spi@01c68000 { 27 + compatible = "allwinner,sun8i-h3-spi"; 28 + reg = <0x01c68000 0x1000>; 29 + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; 30 + clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>; 31 + clock-names = "ahb", "mod"; 32 + dmas = <&dma 23>, <&dma 23>; 33 + dma-names = "rx", "tx"; 34 + pinctrl-names = "default"; 35 + pinctrl-0 = <&spi0_pins>; 36 + resets = <&ccu RST_BUS_SPI0>; 37 + status = "disabled"; 38 + #address-cells = <1>; 39 + #size-cells = <0>; 29 40 };
+67 -8
drivers/spi/spi-sun4i.c
··· 46 46 #define SUN4I_CTL_TP BIT(18) 47 47 48 48 #define SUN4I_INT_CTL_REG 0x0c 49 + #define SUN4I_INT_CTL_RF_F34 BIT(4) 50 + #define SUN4I_INT_CTL_TF_E34 BIT(12) 49 51 #define SUN4I_INT_CTL_TC BIT(16) 50 52 51 53 #define SUN4I_INT_STA_REG 0x10 ··· 63 61 #define SUN4I_CLK_CTL_CDR1(div) (((div) & SUN4I_CLK_CTL_CDR1_MASK) << 8) 64 62 #define SUN4I_CLK_CTL_DRS BIT(12) 65 63 64 + #define SUN4I_MAX_XFER_SIZE 0xffffff 65 + 66 66 #define SUN4I_BURST_CNT_REG 0x20 67 - #define SUN4I_BURST_CNT(cnt) ((cnt) & 0xffffff) 67 + #define SUN4I_BURST_CNT(cnt) ((cnt) & SUN4I_MAX_XFER_SIZE) 68 68 69 69 #define SUN4I_XMIT_CNT_REG 0x24 70 - #define SUN4I_XMIT_CNT(cnt) ((cnt) & 0xffffff) 70 + #define SUN4I_XMIT_CNT(cnt) ((cnt) & SUN4I_MAX_XFER_SIZE) 71 + 71 72 72 73 #define SUN4I_FIFO_STA_REG 0x28 73 74 #define SUN4I_FIFO_STA_RF_CNT_MASK 0x7f ··· 101 96 writel(value, sspi->base_addr + reg); 102 97 } 103 98 99 + static inline u32 sun4i_spi_get_tx_fifo_count(struct sun4i_spi *sspi) 100 + { 101 + u32 reg = sun4i_spi_read(sspi, SUN4I_FIFO_STA_REG); 102 + 103 + reg >>= SUN4I_FIFO_STA_TF_CNT_BITS; 104 + 105 + return reg & SUN4I_FIFO_STA_TF_CNT_MASK; 106 + } 107 + 108 + static inline void sun4i_spi_enable_interrupt(struct sun4i_spi *sspi, u32 mask) 109 + { 110 + u32 reg = sun4i_spi_read(sspi, SUN4I_INT_CTL_REG); 111 + 112 + reg |= mask; 113 + sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, reg); 114 + } 115 + 116 + static inline void sun4i_spi_disable_interrupt(struct sun4i_spi *sspi, u32 mask) 117 + { 118 + u32 reg = sun4i_spi_read(sspi, SUN4I_INT_CTL_REG); 119 + 120 + reg &= ~mask; 121 + sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, reg); 122 + } 123 + 104 124 static inline void sun4i_spi_drain_fifo(struct sun4i_spi *sspi, int len) 105 125 { 106 126 u32 reg, cnt; ··· 148 118 149 119 static inline void sun4i_spi_fill_fifo(struct sun4i_spi *sspi, int len) 150 120 { 121 + u32 cnt; 151 122 u8 byte; 152 123 153 - if (len > sspi->len) 154 - len = sspi->len; 124 + /* See how much data we can fit */ 125 + cnt = SUN4I_FIFO_DEPTH - sun4i_spi_get_tx_fifo_count(sspi); 126 + 127 + len = min3(len, (int)cnt, sspi->len); 155 128 156 129 while (len--) { 157 130 byte = sspi->tx_buf ? *sspi->tx_buf++ : 0; ··· 217 184 u32 reg; 218 185 219 186 /* We don't support transfer larger than the FIFO */ 220 - if (tfr->len > SUN4I_FIFO_DEPTH) 187 + if (tfr->len > SUN4I_MAX_XFER_SIZE) 221 188 return -EMSGSIZE; 222 189 223 - if (tfr->tx_buf && tfr->len >= SUN4I_FIFO_DEPTH) 190 + if (tfr->tx_buf && tfr->len >= SUN4I_MAX_XFER_SIZE) 224 191 return -EMSGSIZE; 225 192 226 193 reinit_completion(&sspi->done); ··· 319 286 sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH - 1); 320 287 321 288 /* Enable the interrupts */ 322 - sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC); 289 + sun4i_spi_enable_interrupt(sspi, SUN4I_INT_CTL_TC | 290 + SUN4I_INT_CTL_RF_F34); 291 + /* Only enable Tx FIFO interrupt if we really need it */ 292 + if (tx_len > SUN4I_FIFO_DEPTH) 293 + sun4i_spi_enable_interrupt(sspi, SUN4I_INT_CTL_TF_E34); 323 294 324 295 /* Start the transfer */ 325 296 reg = sun4i_spi_read(sspi, SUN4I_CTL_REG); ··· 343 306 goto out; 344 307 } 345 308 346 - sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH); 347 309 348 310 out: 349 311 sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0); ··· 358 322 /* Transfer complete */ 359 323 if (status & SUN4I_INT_CTL_TC) { 360 324 sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_TC); 325 + sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH); 361 326 complete(&sspi->done); 327 + return IRQ_HANDLED; 328 + } 329 + 330 + /* Receive FIFO 3/4 full */ 331 + if (status & SUN4I_INT_CTL_RF_F34) { 332 + sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH); 333 + /* Only clear the interrupt _after_ draining the FIFO */ 334 + sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_RF_F34); 335 + return IRQ_HANDLED; 336 + } 337 + 338 + /* Transmit FIFO 3/4 empty */ 339 + if (status & SUN4I_INT_CTL_TF_E34) { 340 + sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH); 341 + 342 + if (!sspi->len) 343 + /* nothing left to transmit */ 344 + sun4i_spi_disable_interrupt(sspi, SUN4I_INT_CTL_TF_E34); 345 + 346 + /* Only clear the interrupt _after_ re-seeding the FIFO */ 347 + sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_TF_E34); 348 + 362 349 return IRQ_HANDLED; 363 350 } 364 351
+13 -5
drivers/spi/spi-sun6i.c
··· 17 17 #include <linux/interrupt.h> 18 18 #include <linux/io.h> 19 19 #include <linux/module.h> 20 + #include <linux/of_device.h> 20 21 #include <linux/platform_device.h> 21 22 #include <linux/pm_runtime.h> 22 23 #include <linux/reset.h> ··· 25 24 #include <linux/spi/spi.h> 26 25 27 26 #define SUN6I_FIFO_DEPTH 128 27 + #define SUN8I_FIFO_DEPTH 64 28 28 29 29 #define SUN6I_GBL_CTL_REG 0x04 30 30 #define SUN6I_GBL_CTL_BUS_ENABLE BIT(0) ··· 92 90 const u8 *tx_buf; 93 91 u8 *rx_buf; 94 92 int len; 93 + unsigned long fifo_depth; 95 94 }; 96 95 97 96 static inline u32 sun6i_spi_read(struct sun6i_spi *sspi, u32 reg) ··· 158 155 159 156 static size_t sun6i_spi_max_transfer_size(struct spi_device *spi) 160 157 { 161 - return SUN6I_FIFO_DEPTH - 1; 158 + struct sun6i_spi *sspi = spi_master_get_devdata(spi->master); 159 + 160 + return sspi->fifo_depth - 1; 162 161 } 163 162 164 163 static int sun6i_spi_transfer_one(struct spi_master *master, ··· 175 170 u32 reg; 176 171 177 172 /* We don't support transfer larger than the FIFO */ 178 - if (tfr->len > SUN6I_FIFO_DEPTH) 173 + if (tfr->len > sspi->fifo_depth) 179 174 return -EINVAL; 180 175 181 176 reinit_completion(&sspi->done); ··· 270 265 SUN6I_BURST_CTL_CNT_STC(tx_len)); 271 266 272 267 /* Fill the TX FIFO */ 273 - sun6i_spi_fill_fifo(sspi, SUN6I_FIFO_DEPTH); 268 + sun6i_spi_fill_fifo(sspi, sspi->fifo_depth); 274 269 275 270 /* Enable the interrupts */ 276 271 sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, SUN6I_INT_CTL_TC); ··· 293 288 goto out; 294 289 } 295 290 296 - sun6i_spi_drain_fifo(sspi, SUN6I_FIFO_DEPTH); 291 + sun6i_spi_drain_fifo(sspi, sspi->fifo_depth); 297 292 298 293 out: 299 294 sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0); ··· 403 398 } 404 399 405 400 sspi->master = master; 401 + sspi->fifo_depth = (unsigned long)of_device_get_match_data(&pdev->dev); 402 + 406 403 master->max_speed_hz = 100 * 1000 * 1000; 407 404 master->min_speed_hz = 3 * 1000; 408 405 master->set_cs = sun6i_spi_set_cs; ··· 477 470 } 478 471 479 472 static const struct of_device_id sun6i_spi_match[] = { 480 - { .compatible = "allwinner,sun6i-a31-spi", }, 473 + { .compatible = "allwinner,sun6i-a31-spi", .data = (void *)SUN6I_FIFO_DEPTH }, 474 + { .compatible = "allwinner,sun8i-h3-spi", .data = (void *)SUN8I_FIFO_DEPTH }, 481 475 {} 482 476 }; 483 477 MODULE_DEVICE_TABLE(of, sun6i_spi_match);
+1
drivers/spi/spi-ti-qspi.c
··· 411 411 tx->callback = ti_qspi_dma_callback; 412 412 tx->callback_param = qspi; 413 413 cookie = tx->tx_submit(tx); 414 + reinit_completion(&qspi->transfer_complete); 414 415 415 416 ret = dma_submit_error(cookie); 416 417 if (ret) {
+1 -12
drivers/spi/spi-topcliff-pch.c
··· 1268 1268 static int pch_spi_get_resources(struct pch_spi_board_data *board_dat, 1269 1269 struct pch_spi_data *data) 1270 1270 { 1271 - int retval = 0; 1272 - 1273 1271 dev_dbg(&board_dat->pdev->dev, "%s ENTRY\n", __func__); 1274 - 1275 1272 1276 1273 /* reset PCH SPI h/w */ 1277 1274 pch_spi_reset(data->master); ··· 1277 1280 1278 1281 dev_dbg(&board_dat->pdev->dev, "%s data->irq_reg_sts=true\n", __func__); 1279 1282 1280 - if (retval != 0) { 1281 - dev_err(&board_dat->pdev->dev, 1282 - "%s FAIL:invoking pch_spi_free_resources\n", __func__); 1283 - pch_spi_free_resources(board_dat, data); 1284 - } 1285 - 1286 - dev_dbg(&board_dat->pdev->dev, "%s Return=%d\n", __func__, retval); 1287 - 1288 - return retval; 1283 + return 0; 1289 1284 } 1290 1285 1291 1286 static void pch_free_dma_buf(struct pch_spi_board_data *board_dat,
+1
drivers/spi/spi-xlp.c
··· 451 451 { .compatible = "netlogic,xlp832-spi" }, 452 452 { }, 453 453 }; 454 + MODULE_DEVICE_TABLE(of, xlp_spi_dt_id); 454 455 455 456 static struct platform_driver xlp_spi_driver = { 456 457 .probe = xlp_spi_probe,
+1
drivers/spi/spidev.c
··· 696 696 static const struct of_device_id spidev_dt_ids[] = { 697 697 { .compatible = "rohm,dh2228fv" }, 698 698 { .compatible = "lineartechnology,ltc2488" }, 699 + { .compatible = "ge,achc" }, 699 700 {}, 700 701 }; 701 702 MODULE_DEVICE_TABLE(of, spidev_dt_ids);