diff options
Diffstat (limited to 'drivers/spi/spi-sirf.c')
-rw-r--r-- | drivers/spi/spi-sirf.c | 61 |
1 files changed, 17 insertions, 44 deletions
diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c index 0808cd56bf8d..fc20bcfd90c3 100644 --- a/drivers/spi/spi-sirf.c +++ b/drivers/spi/spi-sirf.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/of_gpio.h> | 19 | #include <linux/of_gpio.h> |
20 | #include <linux/spi/spi.h> | 20 | #include <linux/spi/spi.h> |
21 | #include <linux/spi/spi_bitbang.h> | 21 | #include <linux/spi/spi_bitbang.h> |
22 | #include <linux/pinctrl/consumer.h> | ||
23 | 22 | ||
24 | #define DRIVER_NAME "sirfsoc_spi" | 23 | #define DRIVER_NAME "sirfsoc_spi" |
25 | 24 | ||
@@ -127,7 +126,6 @@ struct sirfsoc_spi { | |||
127 | void __iomem *base; | 126 | void __iomem *base; |
128 | u32 ctrl_freq; /* SPI controller clock speed */ | 127 | u32 ctrl_freq; /* SPI controller clock speed */ |
129 | struct clk *clk; | 128 | struct clk *clk; |
130 | struct pinctrl *p; | ||
131 | 129 | ||
132 | /* rx & tx bufs from the spi_transfer */ | 130 | /* rx & tx bufs from the spi_transfer */ |
133 | const void *tx; | 131 | const void *tx; |
@@ -142,9 +140,6 @@ struct sirfsoc_spi { | |||
142 | unsigned int left_tx_cnt; | 140 | unsigned int left_tx_cnt; |
143 | unsigned int left_rx_cnt; | 141 | unsigned int left_rx_cnt; |
144 | 142 | ||
145 | /* tasklet to push tx msg into FIFO */ | ||
146 | struct tasklet_struct tasklet_tx; | ||
147 | |||
148 | int chipselect[0]; | 143 | int chipselect[0]; |
149 | }; | 144 | }; |
150 | 145 | ||
@@ -236,17 +231,6 @@ static void spi_sirfsoc_tx_word_u32(struct sirfsoc_spi *sspi) | |||
236 | sspi->left_tx_cnt--; | 231 | sspi->left_tx_cnt--; |
237 | } | 232 | } |
238 | 233 | ||
239 | static void spi_sirfsoc_tasklet_tx(unsigned long arg) | ||
240 | { | ||
241 | struct sirfsoc_spi *sspi = (struct sirfsoc_spi *)arg; | ||
242 | |||
243 | /* Fill Tx FIFO while there are left words to be transmitted */ | ||
244 | while (!((readl(sspi->base + SIRFSOC_SPI_TXFIFO_STATUS) & | ||
245 | SIRFSOC_SPI_FIFO_FULL)) && | ||
246 | sspi->left_tx_cnt) | ||
247 | sspi->tx_word(sspi); | ||
248 | } | ||
249 | |||
250 | static irqreturn_t spi_sirfsoc_irq(int irq, void *dev_id) | 234 | static irqreturn_t spi_sirfsoc_irq(int irq, void *dev_id) |
251 | { | 235 | { |
252 | struct sirfsoc_spi *sspi = dev_id; | 236 | struct sirfsoc_spi *sspi = dev_id; |
@@ -261,25 +245,25 @@ static irqreturn_t spi_sirfsoc_irq(int irq, void *dev_id) | |||
261 | writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN); | 245 | writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN); |
262 | } | 246 | } |
263 | 247 | ||
264 | if (spi_stat & SIRFSOC_SPI_FRM_END) { | 248 | if (spi_stat & (SIRFSOC_SPI_FRM_END |
249 | | SIRFSOC_SPI_RXFIFO_THD_REACH)) | ||
265 | while (!((readl(sspi->base + SIRFSOC_SPI_RXFIFO_STATUS) | 250 | while (!((readl(sspi->base + SIRFSOC_SPI_RXFIFO_STATUS) |
266 | & SIRFSOC_SPI_FIFO_EMPTY)) && | 251 | & SIRFSOC_SPI_FIFO_EMPTY)) && |
267 | sspi->left_rx_cnt) | 252 | sspi->left_rx_cnt) |
268 | sspi->rx_word(sspi); | 253 | sspi->rx_word(sspi); |
269 | 254 | ||
270 | /* Received all words */ | 255 | if (spi_stat & (SIRFSOC_SPI_FIFO_EMPTY |
271 | if ((sspi->left_rx_cnt == 0) && (sspi->left_tx_cnt == 0)) { | 256 | | SIRFSOC_SPI_TXFIFO_THD_REACH)) |
272 | complete(&sspi->done); | 257 | while (!((readl(sspi->base + SIRFSOC_SPI_TXFIFO_STATUS) |
273 | writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN); | 258 | & SIRFSOC_SPI_FIFO_FULL)) && |
274 | } | 259 | sspi->left_tx_cnt) |
275 | } | 260 | sspi->tx_word(sspi); |
276 | |||
277 | if (spi_stat & SIRFSOC_SPI_RXFIFO_THD_REACH || | ||
278 | spi_stat & SIRFSOC_SPI_TXFIFO_THD_REACH || | ||
279 | spi_stat & SIRFSOC_SPI_RX_FIFO_FULL || | ||
280 | spi_stat & SIRFSOC_SPI_TXFIFO_EMPTY) | ||
281 | tasklet_schedule(&sspi->tasklet_tx); | ||
282 | 261 | ||
262 | /* Received all words */ | ||
263 | if ((sspi->left_rx_cnt == 0) && (sspi->left_tx_cnt == 0)) { | ||
264 | complete(&sspi->done); | ||
265 | writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN); | ||
266 | } | ||
283 | return IRQ_HANDLED; | 267 | return IRQ_HANDLED; |
284 | } | 268 | } |
285 | 269 | ||
@@ -426,9 +410,7 @@ spi_sirfsoc_setup_transfer(struct spi_device *spi, struct spi_transfer *t) | |||
426 | SIRFSOC_SPI_FIFO_WIDTH_DWORD; | 410 | SIRFSOC_SPI_FIFO_WIDTH_DWORD; |
427 | break; | 411 | break; |
428 | default: | 412 | default: |
429 | dev_err(&spi->dev, "Bits per word %d not supported\n", | 413 | BUG(); |
430 | bits_per_word); | ||
431 | return -EINVAL; | ||
432 | } | 414 | } |
433 | 415 | ||
434 | if (!(spi->mode & SPI_CS_HIGH)) | 416 | if (!(spi->mode & SPI_CS_HIGH)) |
@@ -556,26 +538,20 @@ static int spi_sirfsoc_probe(struct platform_device *pdev) | |||
556 | sspi->bitbang.txrx_bufs = spi_sirfsoc_transfer; | 538 | sspi->bitbang.txrx_bufs = spi_sirfsoc_transfer; |
557 | sspi->bitbang.master->setup = spi_sirfsoc_setup; | 539 | sspi->bitbang.master->setup = spi_sirfsoc_setup; |
558 | master->bus_num = pdev->id; | 540 | master->bus_num = pdev->id; |
541 | master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(12) | | ||
542 | SPI_BPW_MASK(16) | SPI_BPW_MASK(32); | ||
559 | sspi->bitbang.master->dev.of_node = pdev->dev.of_node; | 543 | sspi->bitbang.master->dev.of_node = pdev->dev.of_node; |
560 | 544 | ||
561 | sspi->p = pinctrl_get_select_default(&pdev->dev); | ||
562 | ret = IS_ERR(sspi->p); | ||
563 | if (ret) | ||
564 | goto free_master; | ||
565 | |||
566 | sspi->clk = clk_get(&pdev->dev, NULL); | 545 | sspi->clk = clk_get(&pdev->dev, NULL); |
567 | if (IS_ERR(sspi->clk)) { | 546 | if (IS_ERR(sspi->clk)) { |
568 | ret = -EINVAL; | 547 | ret = -EINVAL; |
569 | goto free_pin; | 548 | goto free_master; |
570 | } | 549 | } |
571 | clk_prepare_enable(sspi->clk); | 550 | clk_prepare_enable(sspi->clk); |
572 | sspi->ctrl_freq = clk_get_rate(sspi->clk); | 551 | sspi->ctrl_freq = clk_get_rate(sspi->clk); |
573 | 552 | ||
574 | init_completion(&sspi->done); | 553 | init_completion(&sspi->done); |
575 | 554 | ||
576 | tasklet_init(&sspi->tasklet_tx, spi_sirfsoc_tasklet_tx, | ||
577 | (unsigned long)sspi); | ||
578 | |||
579 | writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_RXFIFO_OP); | 555 | writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_RXFIFO_OP); |
580 | writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_TXFIFO_OP); | 556 | writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_TXFIFO_OP); |
581 | writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_RXFIFO_OP); | 557 | writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_RXFIFO_OP); |
@@ -594,8 +570,6 @@ static int spi_sirfsoc_probe(struct platform_device *pdev) | |||
594 | free_clk: | 570 | free_clk: |
595 | clk_disable_unprepare(sspi->clk); | 571 | clk_disable_unprepare(sspi->clk); |
596 | clk_put(sspi->clk); | 572 | clk_put(sspi->clk); |
597 | free_pin: | ||
598 | pinctrl_put(sspi->p); | ||
599 | free_master: | 573 | free_master: |
600 | spi_master_put(master); | 574 | spi_master_put(master); |
601 | err_cs: | 575 | err_cs: |
@@ -618,7 +592,6 @@ static int spi_sirfsoc_remove(struct platform_device *pdev) | |||
618 | } | 592 | } |
619 | clk_disable_unprepare(sspi->clk); | 593 | clk_disable_unprepare(sspi->clk); |
620 | clk_put(sspi->clk); | 594 | clk_put(sspi->clk); |
621 | pinctrl_put(sspi->p); | ||
622 | spi_master_put(master); | 595 | spi_master_put(master); |
623 | return 0; | 596 | return 0; |
624 | } | 597 | } |