diff options
Diffstat (limited to 'drivers/spi/dw_spi.c')
-rw-r--r-- | drivers/spi/dw_spi.c | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c index b50bf5ba873f..497ecb3ab83f 100644 --- a/drivers/spi/dw_spi.c +++ b/drivers/spi/dw_spi.c | |||
@@ -288,8 +288,10 @@ static void *next_transfer(struct dw_spi *dws) | |||
288 | */ | 288 | */ |
289 | static int map_dma_buffers(struct dw_spi *dws) | 289 | static int map_dma_buffers(struct dw_spi *dws) |
290 | { | 290 | { |
291 | if (!dws->cur_msg->is_dma_mapped || !dws->dma_inited | 291 | if (!dws->cur_msg->is_dma_mapped |
292 | || !dws->cur_chip->enable_dma) | 292 | || !dws->dma_inited |
293 | || !dws->cur_chip->enable_dma | ||
294 | || !dws->dma_ops) | ||
293 | return 0; | 295 | return 0; |
294 | 296 | ||
295 | if (dws->cur_transfer->tx_dma) | 297 | if (dws->cur_transfer->tx_dma) |
@@ -341,7 +343,7 @@ static void int_error_stop(struct dw_spi *dws, const char *msg) | |||
341 | tasklet_schedule(&dws->pump_transfers); | 343 | tasklet_schedule(&dws->pump_transfers); |
342 | } | 344 | } |
343 | 345 | ||
344 | static void transfer_complete(struct dw_spi *dws) | 346 | void dw_spi_xfer_done(struct dw_spi *dws) |
345 | { | 347 | { |
346 | /* Update total byte transfered return count actual bytes read */ | 348 | /* Update total byte transfered return count actual bytes read */ |
347 | dws->cur_msg->actual_length += dws->len; | 349 | dws->cur_msg->actual_length += dws->len; |
@@ -356,6 +358,7 @@ static void transfer_complete(struct dw_spi *dws) | |||
356 | } else | 358 | } else |
357 | tasklet_schedule(&dws->pump_transfers); | 359 | tasklet_schedule(&dws->pump_transfers); |
358 | } | 360 | } |
361 | EXPORT_SYMBOL_GPL(dw_spi_xfer_done); | ||
359 | 362 | ||
360 | static irqreturn_t interrupt_transfer(struct dw_spi *dws) | 363 | static irqreturn_t interrupt_transfer(struct dw_spi *dws) |
361 | { | 364 | { |
@@ -387,7 +390,7 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws) | |||
387 | if (dws->tx_end > dws->tx) | 390 | if (dws->tx_end > dws->tx) |
388 | spi_umask_intr(dws, SPI_INT_TXEI); | 391 | spi_umask_intr(dws, SPI_INT_TXEI); |
389 | else | 392 | else |
390 | transfer_complete(dws); | 393 | dw_spi_xfer_done(dws); |
391 | } | 394 | } |
392 | 395 | ||
393 | return IRQ_HANDLED; | 396 | return IRQ_HANDLED; |
@@ -422,11 +425,7 @@ static void poll_transfer(struct dw_spi *dws) | |||
422 | */ | 425 | */ |
423 | dws->read(dws); | 426 | dws->read(dws); |
424 | 427 | ||
425 | transfer_complete(dws); | 428 | dw_spi_xfer_done(dws); |
426 | } | ||
427 | |||
428 | static void dma_transfer(struct dw_spi *dws, int cs_change) | ||
429 | { | ||
430 | } | 429 | } |
431 | 430 | ||
432 | static void pump_transfers(unsigned long data) | 431 | static void pump_transfers(unsigned long data) |
@@ -608,7 +607,7 @@ static void pump_transfers(unsigned long data) | |||
608 | } | 607 | } |
609 | 608 | ||
610 | if (dws->dma_mapped) | 609 | if (dws->dma_mapped) |
611 | dma_transfer(dws, cs_change); | 610 | dws->dma_ops->dma_transfer(dws, cs_change); |
612 | 611 | ||
613 | if (chip->poll_mode) | 612 | if (chip->poll_mode) |
614 | poll_transfer(dws); | 613 | poll_transfer(dws); |
@@ -904,11 +903,17 @@ int __devinit dw_spi_add_host(struct dw_spi *dws) | |||
904 | master->setup = dw_spi_setup; | 903 | master->setup = dw_spi_setup; |
905 | master->transfer = dw_spi_transfer; | 904 | master->transfer = dw_spi_transfer; |
906 | 905 | ||
907 | dws->dma_inited = 0; | ||
908 | |||
909 | /* Basic HW init */ | 906 | /* Basic HW init */ |
910 | spi_hw_init(dws); | 907 | spi_hw_init(dws); |
911 | 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 | |||
912 | /* Initial and start queue */ | 917 | /* Initial and start queue */ |
913 | ret = init_queue(dws); | 918 | ret = init_queue(dws); |
914 | if (ret) { | 919 | if (ret) { |
@@ -933,6 +938,8 @@ int __devinit dw_spi_add_host(struct dw_spi *dws) | |||
933 | 938 | ||
934 | err_queue_alloc: | 939 | err_queue_alloc: |
935 | destroy_queue(dws); | 940 | destroy_queue(dws); |
941 | if (dws->dma_ops && dws->dma_ops->dma_exit) | ||
942 | dws->dma_ops->dma_exit(dws); | ||
936 | err_diable_hw: | 943 | err_diable_hw: |
937 | spi_enable_chip(dws, 0); | 944 | spi_enable_chip(dws, 0); |
938 | free_irq(dws->irq, dws); | 945 | free_irq(dws->irq, dws); |
@@ -957,6 +964,8 @@ void __devexit dw_spi_remove_host(struct dw_spi *dws) | |||
957 | dev_err(&dws->master->dev, "dw_spi_remove: workqueue will not " | 964 | dev_err(&dws->master->dev, "dw_spi_remove: workqueue will not " |
958 | "complete, message memory not freed\n"); | 965 | "complete, message memory not freed\n"); |
959 | 966 | ||
967 | if (dws->dma_ops && dws->dma_ops->dma_exit) | ||
968 | dws->dma_ops->dma_exit(dws); | ||
960 | spi_enable_chip(dws, 0); | 969 | spi_enable_chip(dws, 0); |
961 | /* Disable clk */ | 970 | /* Disable clk */ |
962 | spi_set_clk(dws, 0); | 971 | spi_set_clk(dws, 0); |