diff options
Diffstat (limited to 'drivers/spi/spi-omap2-mcspi.c')
-rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 246 |
1 files changed, 136 insertions, 110 deletions
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 46ef5fe51db5..b2fb141da375 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/device.h> | 28 | #include <linux/device.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/dma-mapping.h> | 30 | #include <linux/dma-mapping.h> |
31 | #include <linux/dmaengine.h> | ||
32 | #include <linux/omap-dma.h> | ||
31 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
32 | #include <linux/err.h> | 34 | #include <linux/err.h> |
33 | #include <linux/clk.h> | 35 | #include <linux/clk.h> |
@@ -39,7 +41,6 @@ | |||
39 | 41 | ||
40 | #include <linux/spi/spi.h> | 42 | #include <linux/spi/spi.h> |
41 | 43 | ||
42 | #include <plat/dma.h> | ||
43 | #include <plat/clock.h> | 44 | #include <plat/clock.h> |
44 | #include <plat/mcspi.h> | 45 | #include <plat/mcspi.h> |
45 | 46 | ||
@@ -93,8 +94,8 @@ | |||
93 | 94 | ||
94 | /* We have 2 DMA channels per CS, one for RX and one for TX */ | 95 | /* We have 2 DMA channels per CS, one for RX and one for TX */ |
95 | struct omap2_mcspi_dma { | 96 | struct omap2_mcspi_dma { |
96 | int dma_tx_channel; | 97 | struct dma_chan *dma_tx; |
97 | int dma_rx_channel; | 98 | struct dma_chan *dma_rx; |
98 | 99 | ||
99 | int dma_tx_sync_dev; | 100 | int dma_tx_sync_dev; |
100 | int dma_rx_sync_dev; | 101 | int dma_rx_sync_dev; |
@@ -300,20 +301,46 @@ static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit) | |||
300 | return 0; | 301 | return 0; |
301 | } | 302 | } |
302 | 303 | ||
304 | static void omap2_mcspi_rx_callback(void *data) | ||
305 | { | ||
306 | struct spi_device *spi = data; | ||
307 | struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master); | ||
308 | struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | ||
309 | |||
310 | complete(&mcspi_dma->dma_rx_completion); | ||
311 | |||
312 | /* We must disable the DMA RX request */ | ||
313 | omap2_mcspi_set_dma_req(spi, 1, 0); | ||
314 | } | ||
315 | |||
316 | static void omap2_mcspi_tx_callback(void *data) | ||
317 | { | ||
318 | struct spi_device *spi = data; | ||
319 | struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master); | ||
320 | struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | ||
321 | |||
322 | complete(&mcspi_dma->dma_tx_completion); | ||
323 | |||
324 | /* We must disable the DMA TX request */ | ||
325 | omap2_mcspi_set_dma_req(spi, 0, 0); | ||
326 | } | ||
327 | |||
303 | static unsigned | 328 | static unsigned |
304 | omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | 329 | omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) |
305 | { | 330 | { |
306 | struct omap2_mcspi *mcspi; | 331 | struct omap2_mcspi *mcspi; |
307 | struct omap2_mcspi_cs *cs = spi->controller_state; | 332 | struct omap2_mcspi_cs *cs = spi->controller_state; |
308 | struct omap2_mcspi_dma *mcspi_dma; | 333 | struct omap2_mcspi_dma *mcspi_dma; |
309 | unsigned int count, c; | 334 | unsigned int count; |
310 | unsigned long base, tx_reg, rx_reg; | 335 | int word_len, element_count; |
311 | int word_len, data_type, element_count; | ||
312 | int elements = 0; | 336 | int elements = 0; |
313 | u32 l; | 337 | u32 l; |
314 | u8 * rx; | 338 | u8 * rx; |
315 | const u8 * tx; | 339 | const u8 * tx; |
316 | void __iomem *chstat_reg; | 340 | void __iomem *chstat_reg; |
341 | struct dma_slave_config cfg; | ||
342 | enum dma_slave_buswidth width; | ||
343 | unsigned es; | ||
317 | 344 | ||
318 | mcspi = spi_master_get_devdata(spi->master); | 345 | mcspi = spi_master_get_devdata(spi->master); |
319 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | 346 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; |
@@ -321,74 +348,99 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
321 | 348 | ||
322 | chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0; | 349 | chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0; |
323 | 350 | ||
351 | if (cs->word_len <= 8) { | ||
352 | width = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
353 | es = 1; | ||
354 | } else if (cs->word_len <= 16) { | ||
355 | width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
356 | es = 2; | ||
357 | } else { | ||
358 | width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
359 | es = 4; | ||
360 | } | ||
361 | |||
362 | memset(&cfg, 0, sizeof(cfg)); | ||
363 | cfg.src_addr = cs->phys + OMAP2_MCSPI_RX0; | ||
364 | cfg.dst_addr = cs->phys + OMAP2_MCSPI_TX0; | ||
365 | cfg.src_addr_width = width; | ||
366 | cfg.dst_addr_width = width; | ||
367 | cfg.src_maxburst = 1; | ||
368 | cfg.dst_maxburst = 1; | ||
369 | |||
370 | if (xfer->tx_buf && mcspi_dma->dma_tx) { | ||
371 | struct dma_async_tx_descriptor *tx; | ||
372 | struct scatterlist sg; | ||
373 | |||
374 | dmaengine_slave_config(mcspi_dma->dma_tx, &cfg); | ||
375 | |||
376 | sg_init_table(&sg, 1); | ||
377 | sg_dma_address(&sg) = xfer->tx_dma; | ||
378 | sg_dma_len(&sg) = xfer->len; | ||
379 | |||
380 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, &sg, 1, | ||
381 | DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
382 | if (tx) { | ||
383 | tx->callback = omap2_mcspi_tx_callback; | ||
384 | tx->callback_param = spi; | ||
385 | dmaengine_submit(tx); | ||
386 | } else { | ||
387 | /* FIXME: fall back to PIO? */ | ||
388 | } | ||
389 | } | ||
390 | |||
391 | if (xfer->rx_buf && mcspi_dma->dma_rx) { | ||
392 | struct dma_async_tx_descriptor *tx; | ||
393 | struct scatterlist sg; | ||
394 | size_t len = xfer->len - es; | ||
395 | |||
396 | dmaengine_slave_config(mcspi_dma->dma_rx, &cfg); | ||
397 | |||
398 | if (l & OMAP2_MCSPI_CHCONF_TURBO) | ||
399 | len -= es; | ||
400 | |||
401 | sg_init_table(&sg, 1); | ||
402 | sg_dma_address(&sg) = xfer->rx_dma; | ||
403 | sg_dma_len(&sg) = len; | ||
404 | |||
405 | tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, &sg, 1, | ||
406 | DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
407 | if (tx) { | ||
408 | tx->callback = omap2_mcspi_rx_callback; | ||
409 | tx->callback_param = spi; | ||
410 | dmaengine_submit(tx); | ||
411 | } else { | ||
412 | /* FIXME: fall back to PIO? */ | ||
413 | } | ||
414 | } | ||
415 | |||
324 | count = xfer->len; | 416 | count = xfer->len; |
325 | c = count; | ||
326 | word_len = cs->word_len; | 417 | word_len = cs->word_len; |
327 | 418 | ||
328 | base = cs->phys; | ||
329 | tx_reg = base + OMAP2_MCSPI_TX0; | ||
330 | rx_reg = base + OMAP2_MCSPI_RX0; | ||
331 | rx = xfer->rx_buf; | 419 | rx = xfer->rx_buf; |
332 | tx = xfer->tx_buf; | 420 | tx = xfer->tx_buf; |
333 | 421 | ||
334 | if (word_len <= 8) { | 422 | if (word_len <= 8) { |
335 | data_type = OMAP_DMA_DATA_TYPE_S8; | ||
336 | element_count = count; | 423 | element_count = count; |
337 | } else if (word_len <= 16) { | 424 | } else if (word_len <= 16) { |
338 | data_type = OMAP_DMA_DATA_TYPE_S16; | ||
339 | element_count = count >> 1; | 425 | element_count = count >> 1; |
340 | } else /* word_len <= 32 */ { | 426 | } else /* word_len <= 32 */ { |
341 | data_type = OMAP_DMA_DATA_TYPE_S32; | ||
342 | element_count = count >> 2; | 427 | element_count = count >> 2; |
343 | } | 428 | } |
344 | 429 | ||
345 | if (tx != NULL) { | 430 | if (tx != NULL) { |
346 | omap_set_dma_transfer_params(mcspi_dma->dma_tx_channel, | 431 | dma_async_issue_pending(mcspi_dma->dma_tx); |
347 | data_type, element_count, 1, | ||
348 | OMAP_DMA_SYNC_ELEMENT, | ||
349 | mcspi_dma->dma_tx_sync_dev, 0); | ||
350 | |||
351 | omap_set_dma_dest_params(mcspi_dma->dma_tx_channel, 0, | ||
352 | OMAP_DMA_AMODE_CONSTANT, | ||
353 | tx_reg, 0, 0); | ||
354 | |||
355 | omap_set_dma_src_params(mcspi_dma->dma_tx_channel, 0, | ||
356 | OMAP_DMA_AMODE_POST_INC, | ||
357 | xfer->tx_dma, 0, 0); | ||
358 | } | ||
359 | |||
360 | if (rx != NULL) { | ||
361 | elements = element_count - 1; | ||
362 | if (l & OMAP2_MCSPI_CHCONF_TURBO) | ||
363 | elements--; | ||
364 | |||
365 | omap_set_dma_transfer_params(mcspi_dma->dma_rx_channel, | ||
366 | data_type, elements, 1, | ||
367 | OMAP_DMA_SYNC_ELEMENT, | ||
368 | mcspi_dma->dma_rx_sync_dev, 1); | ||
369 | |||
370 | omap_set_dma_src_params(mcspi_dma->dma_rx_channel, 0, | ||
371 | OMAP_DMA_AMODE_CONSTANT, | ||
372 | rx_reg, 0, 0); | ||
373 | |||
374 | omap_set_dma_dest_params(mcspi_dma->dma_rx_channel, 0, | ||
375 | OMAP_DMA_AMODE_POST_INC, | ||
376 | xfer->rx_dma, 0, 0); | ||
377 | } | ||
378 | |||
379 | if (tx != NULL) { | ||
380 | omap_start_dma(mcspi_dma->dma_tx_channel); | ||
381 | omap2_mcspi_set_dma_req(spi, 0, 1); | 432 | omap2_mcspi_set_dma_req(spi, 0, 1); |
382 | } | 433 | } |
383 | 434 | ||
384 | if (rx != NULL) { | 435 | if (rx != NULL) { |
385 | omap_start_dma(mcspi_dma->dma_rx_channel); | 436 | dma_async_issue_pending(mcspi_dma->dma_rx); |
386 | omap2_mcspi_set_dma_req(spi, 1, 1); | 437 | omap2_mcspi_set_dma_req(spi, 1, 1); |
387 | } | 438 | } |
388 | 439 | ||
389 | if (tx != NULL) { | 440 | if (tx != NULL) { |
390 | wait_for_completion(&mcspi_dma->dma_tx_completion); | 441 | wait_for_completion(&mcspi_dma->dma_tx_completion); |
391 | dma_unmap_single(&spi->dev, xfer->tx_dma, count, DMA_TO_DEVICE); | 442 | dma_unmap_single(mcspi->dev, xfer->tx_dma, count, |
443 | DMA_TO_DEVICE); | ||
392 | 444 | ||
393 | /* for TX_ONLY mode, be sure all words have shifted out */ | 445 | /* for TX_ONLY mode, be sure all words have shifted out */ |
394 | if (rx == NULL) { | 446 | if (rx == NULL) { |
@@ -403,10 +455,14 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
403 | 455 | ||
404 | if (rx != NULL) { | 456 | if (rx != NULL) { |
405 | wait_for_completion(&mcspi_dma->dma_rx_completion); | 457 | wait_for_completion(&mcspi_dma->dma_rx_completion); |
406 | dma_unmap_single(&spi->dev, xfer->rx_dma, count, DMA_FROM_DEVICE); | 458 | dma_unmap_single(mcspi->dev, xfer->rx_dma, count, |
459 | DMA_FROM_DEVICE); | ||
407 | omap2_mcspi_set_enable(spi, 0); | 460 | omap2_mcspi_set_enable(spi, 0); |
408 | 461 | ||
462 | elements = element_count - 1; | ||
463 | |||
409 | if (l & OMAP2_MCSPI_CHCONF_TURBO) { | 464 | if (l & OMAP2_MCSPI_CHCONF_TURBO) { |
465 | elements--; | ||
410 | 466 | ||
411 | if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0) | 467 | if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0) |
412 | & OMAP2_MCSPI_CHSTAT_RXS)) { | 468 | & OMAP2_MCSPI_CHSTAT_RXS)) { |
@@ -723,64 +779,38 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, | |||
723 | return 0; | 779 | return 0; |
724 | } | 780 | } |
725 | 781 | ||
726 | static void omap2_mcspi_dma_rx_callback(int lch, u16 ch_status, void *data) | ||
727 | { | ||
728 | struct spi_device *spi = data; | ||
729 | struct omap2_mcspi *mcspi; | ||
730 | struct omap2_mcspi_dma *mcspi_dma; | ||
731 | |||
732 | mcspi = spi_master_get_devdata(spi->master); | ||
733 | mcspi_dma = &(mcspi->dma_channels[spi->chip_select]); | ||
734 | |||
735 | complete(&mcspi_dma->dma_rx_completion); | ||
736 | |||
737 | /* We must disable the DMA RX request */ | ||
738 | omap2_mcspi_set_dma_req(spi, 1, 0); | ||
739 | } | ||
740 | |||
741 | static void omap2_mcspi_dma_tx_callback(int lch, u16 ch_status, void *data) | ||
742 | { | ||
743 | struct spi_device *spi = data; | ||
744 | struct omap2_mcspi *mcspi; | ||
745 | struct omap2_mcspi_dma *mcspi_dma; | ||
746 | |||
747 | mcspi = spi_master_get_devdata(spi->master); | ||
748 | mcspi_dma = &(mcspi->dma_channels[spi->chip_select]); | ||
749 | |||
750 | complete(&mcspi_dma->dma_tx_completion); | ||
751 | |||
752 | /* We must disable the DMA TX request */ | ||
753 | omap2_mcspi_set_dma_req(spi, 0, 0); | ||
754 | } | ||
755 | |||
756 | static int omap2_mcspi_request_dma(struct spi_device *spi) | 782 | static int omap2_mcspi_request_dma(struct spi_device *spi) |
757 | { | 783 | { |
758 | struct spi_master *master = spi->master; | 784 | struct spi_master *master = spi->master; |
759 | struct omap2_mcspi *mcspi; | 785 | struct omap2_mcspi *mcspi; |
760 | struct omap2_mcspi_dma *mcspi_dma; | 786 | struct omap2_mcspi_dma *mcspi_dma; |
787 | dma_cap_mask_t mask; | ||
788 | unsigned sig; | ||
761 | 789 | ||
762 | mcspi = spi_master_get_devdata(master); | 790 | mcspi = spi_master_get_devdata(master); |
763 | mcspi_dma = mcspi->dma_channels + spi->chip_select; | 791 | mcspi_dma = mcspi->dma_channels + spi->chip_select; |
764 | 792 | ||
765 | if (omap_request_dma(mcspi_dma->dma_rx_sync_dev, "McSPI RX", | 793 | init_completion(&mcspi_dma->dma_rx_completion); |
766 | omap2_mcspi_dma_rx_callback, spi, | 794 | init_completion(&mcspi_dma->dma_tx_completion); |
767 | &mcspi_dma->dma_rx_channel)) { | 795 | |
768 | dev_err(&spi->dev, "no RX DMA channel for McSPI\n"); | 796 | dma_cap_zero(mask); |
797 | dma_cap_set(DMA_SLAVE, mask); | ||
798 | sig = mcspi_dma->dma_rx_sync_dev; | ||
799 | mcspi_dma->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig); | ||
800 | if (!mcspi_dma->dma_rx) { | ||
801 | dev_err(&spi->dev, "no RX DMA engine channel for McSPI\n"); | ||
769 | return -EAGAIN; | 802 | return -EAGAIN; |
770 | } | 803 | } |
771 | 804 | ||
772 | if (omap_request_dma(mcspi_dma->dma_tx_sync_dev, "McSPI TX", | 805 | sig = mcspi_dma->dma_tx_sync_dev; |
773 | omap2_mcspi_dma_tx_callback, spi, | 806 | mcspi_dma->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig); |
774 | &mcspi_dma->dma_tx_channel)) { | 807 | if (!mcspi_dma->dma_tx) { |
775 | omap_free_dma(mcspi_dma->dma_rx_channel); | 808 | dev_err(&spi->dev, "no TX DMA engine channel for McSPI\n"); |
776 | mcspi_dma->dma_rx_channel = -1; | 809 | dma_release_channel(mcspi_dma->dma_rx); |
777 | dev_err(&spi->dev, "no TX DMA channel for McSPI\n"); | 810 | mcspi_dma->dma_rx = NULL; |
778 | return -EAGAIN; | 811 | return -EAGAIN; |
779 | } | 812 | } |
780 | 813 | ||
781 | init_completion(&mcspi_dma->dma_rx_completion); | ||
782 | init_completion(&mcspi_dma->dma_tx_completion); | ||
783 | |||
784 | return 0; | 814 | return 0; |
785 | } | 815 | } |
786 | 816 | ||
@@ -801,7 +831,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) | |||
801 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | 831 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; |
802 | 832 | ||
803 | if (!cs) { | 833 | if (!cs) { |
804 | cs = devm_kzalloc(&spi->dev , sizeof *cs, GFP_KERNEL); | 834 | cs = kzalloc(sizeof *cs, GFP_KERNEL); |
805 | if (!cs) | 835 | if (!cs) |
806 | return -ENOMEM; | 836 | return -ENOMEM; |
807 | cs->base = mcspi->base + spi->chip_select * 0x14; | 837 | cs->base = mcspi->base + spi->chip_select * 0x14; |
@@ -812,8 +842,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) | |||
812 | list_add_tail(&cs->node, &ctx->cs); | 842 | list_add_tail(&cs->node, &ctx->cs); |
813 | } | 843 | } |
814 | 844 | ||
815 | if (mcspi_dma->dma_rx_channel == -1 | 845 | if (!mcspi_dma->dma_rx || !mcspi_dma->dma_tx) { |
816 | || mcspi_dma->dma_tx_channel == -1) { | ||
817 | ret = omap2_mcspi_request_dma(spi); | 846 | ret = omap2_mcspi_request_dma(spi); |
818 | if (ret < 0) | 847 | if (ret < 0) |
819 | return ret; | 848 | return ret; |
@@ -842,18 +871,19 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) | |||
842 | cs = spi->controller_state; | 871 | cs = spi->controller_state; |
843 | list_del(&cs->node); | 872 | list_del(&cs->node); |
844 | 873 | ||
874 | kfree(cs); | ||
845 | } | 875 | } |
846 | 876 | ||
847 | if (spi->chip_select < spi->master->num_chipselect) { | 877 | if (spi->chip_select < spi->master->num_chipselect) { |
848 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | 878 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; |
849 | 879 | ||
850 | if (mcspi_dma->dma_rx_channel != -1) { | 880 | if (mcspi_dma->dma_rx) { |
851 | omap_free_dma(mcspi_dma->dma_rx_channel); | 881 | dma_release_channel(mcspi_dma->dma_rx); |
852 | mcspi_dma->dma_rx_channel = -1; | 882 | mcspi_dma->dma_rx = NULL; |
853 | } | 883 | } |
854 | if (mcspi_dma->dma_tx_channel != -1) { | 884 | if (mcspi_dma->dma_tx) { |
855 | omap_free_dma(mcspi_dma->dma_tx_channel); | 885 | dma_release_channel(mcspi_dma->dma_tx); |
856 | mcspi_dma->dma_tx_channel = -1; | 886 | mcspi_dma->dma_tx = NULL; |
857 | } | 887 | } |
858 | } | 888 | } |
859 | } | 889 | } |
@@ -1031,7 +1061,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, | |||
1031 | return 0; | 1061 | return 0; |
1032 | } | 1062 | } |
1033 | 1063 | ||
1034 | static int __init omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) | 1064 | static int __devinit omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) |
1035 | { | 1065 | { |
1036 | struct spi_master *master = mcspi->master; | 1066 | struct spi_master *master = mcspi->master; |
1037 | struct omap2_mcspi_regs *ctx = &mcspi->ctx; | 1067 | struct omap2_mcspi_regs *ctx = &mcspi->ctx; |
@@ -1173,7 +1203,6 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev) | |||
1173 | break; | 1203 | break; |
1174 | } | 1204 | } |
1175 | 1205 | ||
1176 | mcspi->dma_channels[i].dma_rx_channel = -1; | ||
1177 | mcspi->dma_channels[i].dma_rx_sync_dev = dma_res->start; | 1206 | mcspi->dma_channels[i].dma_rx_sync_dev = dma_res->start; |
1178 | sprintf(dma_ch_name, "tx%d", i); | 1207 | sprintf(dma_ch_name, "tx%d", i); |
1179 | dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, | 1208 | dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, |
@@ -1184,7 +1213,6 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev) | |||
1184 | break; | 1213 | break; |
1185 | } | 1214 | } |
1186 | 1215 | ||
1187 | mcspi->dma_channels[i].dma_tx_channel = -1; | ||
1188 | mcspi->dma_channels[i].dma_tx_sync_dev = dma_res->start; | 1216 | mcspi->dma_channels[i].dma_tx_sync_dev = dma_res->start; |
1189 | } | 1217 | } |
1190 | 1218 | ||
@@ -1200,18 +1228,16 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev) | |||
1200 | 1228 | ||
1201 | status = spi_register_master(master); | 1229 | status = spi_register_master(master); |
1202 | if (status < 0) | 1230 | if (status < 0) |
1203 | goto err_spi_register; | 1231 | goto disable_pm; |
1204 | 1232 | ||
1205 | return status; | 1233 | return status; |
1206 | 1234 | ||
1207 | err_spi_register: | ||
1208 | spi_master_put(master); | ||
1209 | disable_pm: | 1235 | disable_pm: |
1210 | pm_runtime_disable(&pdev->dev); | 1236 | pm_runtime_disable(&pdev->dev); |
1211 | dma_chnl_free: | 1237 | dma_chnl_free: |
1212 | kfree(mcspi->dma_channels); | 1238 | kfree(mcspi->dma_channels); |
1213 | free_master: | 1239 | free_master: |
1214 | kfree(master); | 1240 | spi_master_put(master); |
1215 | platform_set_drvdata(pdev, NULL); | 1241 | platform_set_drvdata(pdev, NULL); |
1216 | return status; | 1242 | return status; |
1217 | } | 1243 | } |