aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/dw_spi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/dw_spi.c')
-rw-r--r--drivers/spi/dw_spi.c52
1 files changed, 32 insertions, 20 deletions
diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c
index 0838c79861e4..22af77f98816 100644
--- a/drivers/spi/dw_spi.c
+++ b/drivers/spi/dw_spi.c
@@ -164,20 +164,23 @@ static inline void mrst_spi_debugfs_remove(struct dw_spi *dws)
164 164
165static void wait_till_not_busy(struct dw_spi *dws) 165static void wait_till_not_busy(struct dw_spi *dws)
166{ 166{
167 unsigned long end = jiffies + 1 + usecs_to_jiffies(1000); 167 unsigned long end = jiffies + 1 + usecs_to_jiffies(5000);
168 168
169 while (time_before(jiffies, end)) { 169 while (time_before(jiffies, end)) {
170 if (!(dw_readw(dws, sr) & SR_BUSY)) 170 if (!(dw_readw(dws, sr) & SR_BUSY))
171 return; 171 return;
172 cpu_relax();
172 } 173 }
173 dev_err(&dws->master->dev, 174 dev_err(&dws->master->dev,
174 "DW SPI: Status keeps busy for 1000us after a read/write!\n"); 175 "DW SPI: Status keeps busy for 5000us after a read/write!\n");
175} 176}
176 177
177static void flush(struct dw_spi *dws) 178static void flush(struct dw_spi *dws)
178{ 179{
179 while (dw_readw(dws, sr) & SR_RF_NOT_EMPT) 180 while (dw_readw(dws, sr) & SR_RF_NOT_EMPT) {
180 dw_readw(dws, dr); 181 dw_readw(dws, dr);
182 cpu_relax();
183 }
181 184
182 wait_till_not_busy(dws); 185 wait_till_not_busy(dws);
183} 186}
@@ -285,8 +288,10 @@ static void *next_transfer(struct dw_spi *dws)
285 */ 288 */
286static int map_dma_buffers(struct dw_spi *dws) 289static int map_dma_buffers(struct dw_spi *dws)
287{ 290{
288 if (!dws->cur_msg->is_dma_mapped || !dws->dma_inited 291 if (!dws->cur_msg->is_dma_mapped
289 || !dws->cur_chip->enable_dma) 292 || !dws->dma_inited
293 || !dws->cur_chip->enable_dma
294 || !dws->dma_ops)
290 return 0; 295 return 0;
291 296
292 if (dws->cur_transfer->tx_dma) 297 if (dws->cur_transfer->tx_dma)
@@ -338,7 +343,7 @@ static void int_error_stop(struct dw_spi *dws, const char *msg)
338 tasklet_schedule(&dws->pump_transfers); 343 tasklet_schedule(&dws->pump_transfers);
339} 344}
340 345
341static void transfer_complete(struct dw_spi *dws) 346void dw_spi_xfer_done(struct dw_spi *dws)
342{ 347{
343 /* Update total byte transfered return count actual bytes read */ 348 /* Update total byte transfered return count actual bytes read */
344 dws->cur_msg->actual_length += dws->len; 349 dws->cur_msg->actual_length += dws->len;
@@ -353,6 +358,7 @@ static void transfer_complete(struct dw_spi *dws)
353 } else 358 } else
354 tasklet_schedule(&dws->pump_transfers); 359 tasklet_schedule(&dws->pump_transfers);
355} 360}
361EXPORT_SYMBOL_GPL(dw_spi_xfer_done);
356 362
357static irqreturn_t interrupt_transfer(struct dw_spi *dws) 363static irqreturn_t interrupt_transfer(struct dw_spi *dws)
358{ 364{
@@ -384,7 +390,7 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws)
384 if (dws->tx_end > dws->tx) 390 if (dws->tx_end > dws->tx)
385 spi_umask_intr(dws, SPI_INT_TXEI); 391 spi_umask_intr(dws, SPI_INT_TXEI);
386 else 392 else
387 transfer_complete(dws); 393 dw_spi_xfer_done(dws);
388 } 394 }
389 395
390 return IRQ_HANDLED; 396 return IRQ_HANDLED;
@@ -419,11 +425,7 @@ static void poll_transfer(struct dw_spi *dws)
419 */ 425 */
420 dws->read(dws); 426 dws->read(dws);
421 427
422 transfer_complete(dws); 428 dw_spi_xfer_done(dws);
423}
424
425static void dma_transfer(struct dw_spi *dws, int cs_change)
426{
427} 429}
428 430
429static void pump_transfers(unsigned long data) 431static void pump_transfers(unsigned long data)
@@ -592,7 +594,7 @@ static void pump_transfers(unsigned long data)
592 spi_set_clk(dws, clk_div ? clk_div : chip->clk_div); 594 spi_set_clk(dws, clk_div ? clk_div : chip->clk_div);
593 spi_chip_sel(dws, spi->chip_select); 595 spi_chip_sel(dws, spi->chip_select);
594 596
595 /* Set the interrupt mask, for poll mode just diable all int */ 597 /* Set the interrupt mask, for poll mode just disable all int */
596 spi_mask_intr(dws, 0xff); 598 spi_mask_intr(dws, 0xff);
597 if (imask) 599 if (imask)
598 spi_umask_intr(dws, imask); 600 spi_umask_intr(dws, imask);
@@ -605,7 +607,7 @@ static void pump_transfers(unsigned long data)
605 } 607 }
606 608
607 if (dws->dma_mapped) 609 if (dws->dma_mapped)
608 dma_transfer(dws, cs_change); 610 dws->dma_ops->dma_transfer(dws, cs_change);
609 611
610 if (chip->poll_mode) 612 if (chip->poll_mode)
611 poll_transfer(dws); 613 poll_transfer(dws);
@@ -901,11 +903,17 @@ int __devinit dw_spi_add_host(struct dw_spi *dws)
901 master->setup = dw_spi_setup; 903 master->setup = dw_spi_setup;
902 master->transfer = dw_spi_transfer; 904 master->transfer = dw_spi_transfer;
903 905
904 dws->dma_inited = 0;
905
906 /* Basic HW init */ 906 /* Basic HW init */
907 spi_hw_init(dws); 907 spi_hw_init(dws);
908 908
909 if (dws->dma_ops && dws->dma_ops->dma_init) {
910 ret = dws->dma_ops->dma_init(dws);
911 if (ret) {
912 dev_warn(&master->dev, "DMA init failed\n");
913 dws->dma_inited = 0;
914 }
915 }
916
909 /* Initial and start queue */ 917 /* Initial and start queue */
910 ret = init_queue(dws); 918 ret = init_queue(dws);
911 if (ret) { 919 if (ret) {
@@ -930,6 +938,8 @@ int __devinit dw_spi_add_host(struct dw_spi *dws)
930 938
931err_queue_alloc: 939err_queue_alloc:
932 destroy_queue(dws); 940 destroy_queue(dws);
941 if (dws->dma_ops && dws->dma_ops->dma_exit)
942 dws->dma_ops->dma_exit(dws);
933err_diable_hw: 943err_diable_hw:
934 spi_enable_chip(dws, 0); 944 spi_enable_chip(dws, 0);
935 free_irq(dws->irq, dws); 945 free_irq(dws->irq, dws);
@@ -938,7 +948,7 @@ err_free_master:
938exit: 948exit:
939 return ret; 949 return ret;
940} 950}
941EXPORT_SYMBOL(dw_spi_add_host); 951EXPORT_SYMBOL_GPL(dw_spi_add_host);
942 952
943void __devexit dw_spi_remove_host(struct dw_spi *dws) 953void __devexit dw_spi_remove_host(struct dw_spi *dws)
944{ 954{
@@ -954,6 +964,8 @@ void __devexit dw_spi_remove_host(struct dw_spi *dws)
954 dev_err(&dws->master->dev, "dw_spi_remove: workqueue will not " 964 dev_err(&dws->master->dev, "dw_spi_remove: workqueue will not "
955 "complete, message memory not freed\n"); 965 "complete, message memory not freed\n");
956 966
967 if (dws->dma_ops && dws->dma_ops->dma_exit)
968 dws->dma_ops->dma_exit(dws);
957 spi_enable_chip(dws, 0); 969 spi_enable_chip(dws, 0);
958 /* Disable clk */ 970 /* Disable clk */
959 spi_set_clk(dws, 0); 971 spi_set_clk(dws, 0);
@@ -962,7 +974,7 @@ void __devexit dw_spi_remove_host(struct dw_spi *dws)
962 /* Disconnect from the SPI framework */ 974 /* Disconnect from the SPI framework */
963 spi_unregister_master(dws->master); 975 spi_unregister_master(dws->master);
964} 976}
965EXPORT_SYMBOL(dw_spi_remove_host); 977EXPORT_SYMBOL_GPL(dw_spi_remove_host);
966 978
967int dw_spi_suspend_host(struct dw_spi *dws) 979int dw_spi_suspend_host(struct dw_spi *dws)
968{ 980{
@@ -975,7 +987,7 @@ int dw_spi_suspend_host(struct dw_spi *dws)
975 spi_set_clk(dws, 0); 987 spi_set_clk(dws, 0);
976 return ret; 988 return ret;
977} 989}
978EXPORT_SYMBOL(dw_spi_suspend_host); 990EXPORT_SYMBOL_GPL(dw_spi_suspend_host);
979 991
980int dw_spi_resume_host(struct dw_spi *dws) 992int dw_spi_resume_host(struct dw_spi *dws)
981{ 993{
@@ -987,7 +999,7 @@ int dw_spi_resume_host(struct dw_spi *dws)
987 dev_err(&dws->master->dev, "fail to start queue (%d)\n", ret); 999 dev_err(&dws->master->dev, "fail to start queue (%d)\n", ret);
988 return ret; 1000 return ret;
989} 1001}
990EXPORT_SYMBOL(dw_spi_resume_host); 1002EXPORT_SYMBOL_GPL(dw_spi_resume_host);
991 1003
992MODULE_AUTHOR("Feng Tang <feng.tang@intel.com>"); 1004MODULE_AUTHOR("Feng Tang <feng.tang@intel.com>");
993MODULE_DESCRIPTION("Driver for DesignWare SPI controller core"); 1005MODULE_DESCRIPTION("Driver for DesignWare SPI controller core");