diff options
Diffstat (limited to 'drivers/mmc/host/omap.c')
-rw-r--r-- | drivers/mmc/host/omap.c | 382 |
1 files changed, 173 insertions, 209 deletions
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 3e8dcf8d2e05..a5999a74496a 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -17,10 +17,12 @@ | |||
17 | #include <linux/ioport.h> | 17 | #include <linux/ioport.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/dmaengine.h> | ||
20 | #include <linux/dma-mapping.h> | 21 | #include <linux/dma-mapping.h> |
21 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
22 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
23 | #include <linux/timer.h> | 24 | #include <linux/timer.h> |
25 | #include <linux/omap-dma.h> | ||
24 | #include <linux/mmc/host.h> | 26 | #include <linux/mmc/host.h> |
25 | #include <linux/mmc/card.h> | 27 | #include <linux/mmc/card.h> |
26 | #include <linux/clk.h> | 28 | #include <linux/clk.h> |
@@ -128,6 +130,10 @@ struct mmc_omap_host { | |||
128 | unsigned char id; /* 16xx chips have 2 MMC blocks */ | 130 | unsigned char id; /* 16xx chips have 2 MMC blocks */ |
129 | struct clk * iclk; | 131 | struct clk * iclk; |
130 | struct clk * fclk; | 132 | struct clk * fclk; |
133 | struct dma_chan *dma_rx; | ||
134 | u32 dma_rx_burst; | ||
135 | struct dma_chan *dma_tx; | ||
136 | u32 dma_tx_burst; | ||
131 | struct resource *mem_res; | 137 | struct resource *mem_res; |
132 | void __iomem *virt_base; | 138 | void __iomem *virt_base; |
133 | unsigned int phys_base; | 139 | unsigned int phys_base; |
@@ -153,12 +159,8 @@ struct mmc_omap_host { | |||
153 | 159 | ||
154 | unsigned use_dma:1; | 160 | unsigned use_dma:1; |
155 | unsigned brs_received:1, dma_done:1; | 161 | unsigned brs_received:1, dma_done:1; |
156 | unsigned dma_is_read:1; | ||
157 | unsigned dma_in_use:1; | 162 | unsigned dma_in_use:1; |
158 | int dma_ch; | ||
159 | spinlock_t dma_lock; | 163 | spinlock_t dma_lock; |
160 | struct timer_list dma_timer; | ||
161 | unsigned dma_len; | ||
162 | 164 | ||
163 | struct mmc_omap_slot *slots[OMAP_MMC_MAX_SLOTS]; | 165 | struct mmc_omap_slot *slots[OMAP_MMC_MAX_SLOTS]; |
164 | struct mmc_omap_slot *current_slot; | 166 | struct mmc_omap_slot *current_slot; |
@@ -406,18 +408,25 @@ mmc_omap_release_dma(struct mmc_omap_host *host, struct mmc_data *data, | |||
406 | int abort) | 408 | int abort) |
407 | { | 409 | { |
408 | enum dma_data_direction dma_data_dir; | 410 | enum dma_data_direction dma_data_dir; |
411 | struct device *dev = mmc_dev(host->mmc); | ||
412 | struct dma_chan *c; | ||
409 | 413 | ||
410 | BUG_ON(host->dma_ch < 0); | 414 | if (data->flags & MMC_DATA_WRITE) { |
411 | if (data->error) | ||
412 | omap_stop_dma(host->dma_ch); | ||
413 | /* Release DMA channel lazily */ | ||
414 | mod_timer(&host->dma_timer, jiffies + HZ); | ||
415 | if (data->flags & MMC_DATA_WRITE) | ||
416 | dma_data_dir = DMA_TO_DEVICE; | 415 | dma_data_dir = DMA_TO_DEVICE; |
417 | else | 416 | c = host->dma_tx; |
417 | } else { | ||
418 | dma_data_dir = DMA_FROM_DEVICE; | 418 | dma_data_dir = DMA_FROM_DEVICE; |
419 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len, | 419 | c = host->dma_rx; |
420 | dma_data_dir); | 420 | } |
421 | if (c) { | ||
422 | if (data->error) { | ||
423 | dmaengine_terminate_all(c); | ||
424 | /* Claim nothing transferred on error... */ | ||
425 | data->bytes_xfered = 0; | ||
426 | } | ||
427 | dev = c->device->dev; | ||
428 | } | ||
429 | dma_unmap_sg(dev, data->sg, host->sg_len, dma_data_dir); | ||
421 | } | 430 | } |
422 | 431 | ||
423 | static void mmc_omap_send_stop_work(struct work_struct *work) | 432 | static void mmc_omap_send_stop_work(struct work_struct *work) |
@@ -525,16 +534,6 @@ mmc_omap_end_of_data(struct mmc_omap_host *host, struct mmc_data *data) | |||
525 | } | 534 | } |
526 | 535 | ||
527 | static void | 536 | static void |
528 | mmc_omap_dma_timer(unsigned long data) | ||
529 | { | ||
530 | struct mmc_omap_host *host = (struct mmc_omap_host *) data; | ||
531 | |||
532 | BUG_ON(host->dma_ch < 0); | ||
533 | omap_free_dma(host->dma_ch); | ||
534 | host->dma_ch = -1; | ||
535 | } | ||
536 | |||
537 | static void | ||
538 | mmc_omap_dma_done(struct mmc_omap_host *host, struct mmc_data *data) | 537 | mmc_omap_dma_done(struct mmc_omap_host *host, struct mmc_data *data) |
539 | { | 538 | { |
540 | unsigned long flags; | 539 | unsigned long flags; |
@@ -669,7 +668,7 @@ mmc_omap_clk_timer(unsigned long data) | |||
669 | static void | 668 | static void |
670 | mmc_omap_xfer_data(struct mmc_omap_host *host, int write) | 669 | mmc_omap_xfer_data(struct mmc_omap_host *host, int write) |
671 | { | 670 | { |
672 | int n; | 671 | int n, nwords; |
673 | 672 | ||
674 | if (host->buffer_bytes_left == 0) { | 673 | if (host->buffer_bytes_left == 0) { |
675 | host->sg_idx++; | 674 | host->sg_idx++; |
@@ -679,15 +678,23 @@ mmc_omap_xfer_data(struct mmc_omap_host *host, int write) | |||
679 | n = 64; | 678 | n = 64; |
680 | if (n > host->buffer_bytes_left) | 679 | if (n > host->buffer_bytes_left) |
681 | n = host->buffer_bytes_left; | 680 | n = host->buffer_bytes_left; |
681 | |||
682 | nwords = n / 2; | ||
683 | nwords += n & 1; /* handle odd number of bytes to transfer */ | ||
684 | |||
682 | host->buffer_bytes_left -= n; | 685 | host->buffer_bytes_left -= n; |
683 | host->total_bytes_left -= n; | 686 | host->total_bytes_left -= n; |
684 | host->data->bytes_xfered += n; | 687 | host->data->bytes_xfered += n; |
685 | 688 | ||
686 | if (write) { | 689 | if (write) { |
687 | __raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n); | 690 | __raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA), |
691 | host->buffer, nwords); | ||
688 | } else { | 692 | } else { |
689 | __raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n); | 693 | __raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA), |
694 | host->buffer, nwords); | ||
690 | } | 695 | } |
696 | |||
697 | host->buffer += nwords; | ||
691 | } | 698 | } |
692 | 699 | ||
693 | static inline void mmc_omap_report_irq(u16 status) | 700 | static inline void mmc_omap_report_irq(u16 status) |
@@ -891,159 +898,15 @@ static void mmc_omap_cover_handler(unsigned long param) | |||
891 | jiffies + msecs_to_jiffies(OMAP_MMC_COVER_POLL_DELAY)); | 898 | jiffies + msecs_to_jiffies(OMAP_MMC_COVER_POLL_DELAY)); |
892 | } | 899 | } |
893 | 900 | ||
894 | /* Prepare to transfer the next segment of a scatterlist */ | 901 | static void mmc_omap_dma_callback(void *priv) |
895 | static void | ||
896 | mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data) | ||
897 | { | ||
898 | int dma_ch = host->dma_ch; | ||
899 | unsigned long data_addr; | ||
900 | u16 buf, frame; | ||
901 | u32 count; | ||
902 | struct scatterlist *sg = &data->sg[host->sg_idx]; | ||
903 | int src_port = 0; | ||
904 | int dst_port = 0; | ||
905 | int sync_dev = 0; | ||
906 | |||
907 | data_addr = host->phys_base + OMAP_MMC_REG(host, DATA); | ||
908 | frame = data->blksz; | ||
909 | count = sg_dma_len(sg); | ||
910 | |||
911 | if ((data->blocks == 1) && (count > data->blksz)) | ||
912 | count = frame; | ||
913 | |||
914 | host->dma_len = count; | ||
915 | |||
916 | /* FIFO is 16x2 bytes on 15xx, and 32x2 bytes on 16xx and 24xx. | ||
917 | * Use 16 or 32 word frames when the blocksize is at least that large. | ||
918 | * Blocksize is usually 512 bytes; but not for some SD reads. | ||
919 | */ | ||
920 | if (cpu_is_omap15xx() && frame > 32) | ||
921 | frame = 32; | ||
922 | else if (frame > 64) | ||
923 | frame = 64; | ||
924 | count /= frame; | ||
925 | frame >>= 1; | ||
926 | |||
927 | if (!(data->flags & MMC_DATA_WRITE)) { | ||
928 | buf = 0x800f | ((frame - 1) << 8); | ||
929 | |||
930 | if (cpu_class_is_omap1()) { | ||
931 | src_port = OMAP_DMA_PORT_TIPB; | ||
932 | dst_port = OMAP_DMA_PORT_EMIFF; | ||
933 | } | ||
934 | if (cpu_is_omap24xx()) | ||
935 | sync_dev = OMAP24XX_DMA_MMC1_RX; | ||
936 | |||
937 | omap_set_dma_src_params(dma_ch, src_port, | ||
938 | OMAP_DMA_AMODE_CONSTANT, | ||
939 | data_addr, 0, 0); | ||
940 | omap_set_dma_dest_params(dma_ch, dst_port, | ||
941 | OMAP_DMA_AMODE_POST_INC, | ||
942 | sg_dma_address(sg), 0, 0); | ||
943 | omap_set_dma_dest_data_pack(dma_ch, 1); | ||
944 | omap_set_dma_dest_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4); | ||
945 | } else { | ||
946 | buf = 0x0f80 | ((frame - 1) << 0); | ||
947 | |||
948 | if (cpu_class_is_omap1()) { | ||
949 | src_port = OMAP_DMA_PORT_EMIFF; | ||
950 | dst_port = OMAP_DMA_PORT_TIPB; | ||
951 | } | ||
952 | if (cpu_is_omap24xx()) | ||
953 | sync_dev = OMAP24XX_DMA_MMC1_TX; | ||
954 | |||
955 | omap_set_dma_dest_params(dma_ch, dst_port, | ||
956 | OMAP_DMA_AMODE_CONSTANT, | ||
957 | data_addr, 0, 0); | ||
958 | omap_set_dma_src_params(dma_ch, src_port, | ||
959 | OMAP_DMA_AMODE_POST_INC, | ||
960 | sg_dma_address(sg), 0, 0); | ||
961 | omap_set_dma_src_data_pack(dma_ch, 1); | ||
962 | omap_set_dma_src_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4); | ||
963 | } | ||
964 | |||
965 | /* Max limit for DMA frame count is 0xffff */ | ||
966 | BUG_ON(count > 0xffff); | ||
967 | |||
968 | OMAP_MMC_WRITE(host, BUF, buf); | ||
969 | omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S16, | ||
970 | frame, count, OMAP_DMA_SYNC_FRAME, | ||
971 | sync_dev, 0); | ||
972 | } | ||
973 | |||
974 | /* A scatterlist segment completed */ | ||
975 | static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data) | ||
976 | { | 902 | { |
977 | struct mmc_omap_host *host = (struct mmc_omap_host *) data; | 903 | struct mmc_omap_host *host = priv; |
978 | struct mmc_data *mmcdat = host->data; | 904 | struct mmc_data *data = host->data; |
979 | 905 | ||
980 | if (unlikely(host->dma_ch < 0)) { | 906 | /* If we got to the end of DMA, assume everything went well */ |
981 | dev_err(mmc_dev(host->mmc), | 907 | data->bytes_xfered += data->blocks * data->blksz; |
982 | "DMA callback while DMA not enabled\n"); | ||
983 | return; | ||
984 | } | ||
985 | /* FIXME: We really should do something to _handle_ the errors */ | ||
986 | if (ch_status & OMAP1_DMA_TOUT_IRQ) { | ||
987 | dev_err(mmc_dev(host->mmc),"DMA timeout\n"); | ||
988 | return; | ||
989 | } | ||
990 | if (ch_status & OMAP_DMA_DROP_IRQ) { | ||
991 | dev_err(mmc_dev(host->mmc), "DMA sync error\n"); | ||
992 | return; | ||
993 | } | ||
994 | if (!(ch_status & OMAP_DMA_BLOCK_IRQ)) { | ||
995 | return; | ||
996 | } | ||
997 | mmcdat->bytes_xfered += host->dma_len; | ||
998 | host->sg_idx++; | ||
999 | if (host->sg_idx < host->sg_len) { | ||
1000 | mmc_omap_prepare_dma(host, host->data); | ||
1001 | omap_start_dma(host->dma_ch); | ||
1002 | } else | ||
1003 | mmc_omap_dma_done(host, host->data); | ||
1004 | } | ||
1005 | |||
1006 | static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data *data) | ||
1007 | { | ||
1008 | const char *dma_dev_name; | ||
1009 | int sync_dev, dma_ch, is_read, r; | ||
1010 | |||
1011 | is_read = !(data->flags & MMC_DATA_WRITE); | ||
1012 | del_timer_sync(&host->dma_timer); | ||
1013 | if (host->dma_ch >= 0) { | ||
1014 | if (is_read == host->dma_is_read) | ||
1015 | return 0; | ||
1016 | omap_free_dma(host->dma_ch); | ||
1017 | host->dma_ch = -1; | ||
1018 | } | ||
1019 | |||
1020 | if (is_read) { | ||
1021 | if (host->id == 0) { | ||
1022 | sync_dev = OMAP_DMA_MMC_RX; | ||
1023 | dma_dev_name = "MMC1 read"; | ||
1024 | } else { | ||
1025 | sync_dev = OMAP_DMA_MMC2_RX; | ||
1026 | dma_dev_name = "MMC2 read"; | ||
1027 | } | ||
1028 | } else { | ||
1029 | if (host->id == 0) { | ||
1030 | sync_dev = OMAP_DMA_MMC_TX; | ||
1031 | dma_dev_name = "MMC1 write"; | ||
1032 | } else { | ||
1033 | sync_dev = OMAP_DMA_MMC2_TX; | ||
1034 | dma_dev_name = "MMC2 write"; | ||
1035 | } | ||
1036 | } | ||
1037 | r = omap_request_dma(sync_dev, dma_dev_name, mmc_omap_dma_cb, | ||
1038 | host, &dma_ch); | ||
1039 | if (r != 0) { | ||
1040 | dev_dbg(mmc_dev(host->mmc), "omap_request_dma() failed with %d\n", r); | ||
1041 | return r; | ||
1042 | } | ||
1043 | host->dma_ch = dma_ch; | ||
1044 | host->dma_is_read = is_read; | ||
1045 | 908 | ||
1046 | return 0; | 909 | mmc_omap_dma_done(host, data); |
1047 | } | 910 | } |
1048 | 911 | ||
1049 | static inline void set_cmd_timeout(struct mmc_omap_host *host, struct mmc_request *req) | 912 | static inline void set_cmd_timeout(struct mmc_omap_host *host, struct mmc_request *req) |
@@ -1118,33 +981,85 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req) | |||
1118 | 981 | ||
1119 | host->sg_idx = 0; | 982 | host->sg_idx = 0; |
1120 | if (use_dma) { | 983 | if (use_dma) { |
1121 | if (mmc_omap_get_dma_channel(host, data) == 0) { | 984 | enum dma_data_direction dma_data_dir; |
1122 | enum dma_data_direction dma_data_dir; | 985 | struct dma_async_tx_descriptor *tx; |
1123 | 986 | struct dma_chan *c; | |
1124 | if (data->flags & MMC_DATA_WRITE) | 987 | u32 burst, *bp; |
1125 | dma_data_dir = DMA_TO_DEVICE; | 988 | u16 buf; |
1126 | else | 989 | |
1127 | dma_data_dir = DMA_FROM_DEVICE; | 990 | /* |
1128 | 991 | * FIFO is 16x2 bytes on 15xx, and 32x2 bytes on 16xx | |
1129 | host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg, | 992 | * and 24xx. Use 16 or 32 word frames when the |
1130 | sg_len, dma_data_dir); | 993 | * blocksize is at least that large. Blocksize is |
1131 | host->total_bytes_left = 0; | 994 | * usually 512 bytes; but not for some SD reads. |
1132 | mmc_omap_prepare_dma(host, req->data); | 995 | */ |
1133 | host->brs_received = 0; | 996 | burst = cpu_is_omap15xx() ? 32 : 64; |
1134 | host->dma_done = 0; | 997 | if (burst > data->blksz) |
1135 | host->dma_in_use = 1; | 998 | burst = data->blksz; |
1136 | } else | 999 | |
1137 | use_dma = 0; | 1000 | burst >>= 1; |
1001 | |||
1002 | if (data->flags & MMC_DATA_WRITE) { | ||
1003 | c = host->dma_tx; | ||
1004 | bp = &host->dma_tx_burst; | ||
1005 | buf = 0x0f80 | (burst - 1) << 0; | ||
1006 | dma_data_dir = DMA_TO_DEVICE; | ||
1007 | } else { | ||
1008 | c = host->dma_rx; | ||
1009 | bp = &host->dma_rx_burst; | ||
1010 | buf = 0x800f | (burst - 1) << 8; | ||
1011 | dma_data_dir = DMA_FROM_DEVICE; | ||
1012 | } | ||
1013 | |||
1014 | if (!c) | ||
1015 | goto use_pio; | ||
1016 | |||
1017 | /* Only reconfigure if we have a different burst size */ | ||
1018 | if (*bp != burst) { | ||
1019 | struct dma_slave_config cfg; | ||
1020 | |||
1021 | cfg.src_addr = host->phys_base + OMAP_MMC_REG(host, DATA); | ||
1022 | cfg.dst_addr = host->phys_base + OMAP_MMC_REG(host, DATA); | ||
1023 | cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
1024 | cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
1025 | cfg.src_maxburst = burst; | ||
1026 | cfg.dst_maxburst = burst; | ||
1027 | |||
1028 | if (dmaengine_slave_config(c, &cfg)) | ||
1029 | goto use_pio; | ||
1030 | |||
1031 | *bp = burst; | ||
1032 | } | ||
1033 | |||
1034 | host->sg_len = dma_map_sg(c->device->dev, data->sg, sg_len, | ||
1035 | dma_data_dir); | ||
1036 | if (host->sg_len == 0) | ||
1037 | goto use_pio; | ||
1038 | |||
1039 | tx = dmaengine_prep_slave_sg(c, data->sg, host->sg_len, | ||
1040 | data->flags & MMC_DATA_WRITE ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, | ||
1041 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
1042 | if (!tx) | ||
1043 | goto use_pio; | ||
1044 | |||
1045 | OMAP_MMC_WRITE(host, BUF, buf); | ||
1046 | |||
1047 | tx->callback = mmc_omap_dma_callback; | ||
1048 | tx->callback_param = host; | ||
1049 | dmaengine_submit(tx); | ||
1050 | host->brs_received = 0; | ||
1051 | host->dma_done = 0; | ||
1052 | host->dma_in_use = 1; | ||
1053 | return; | ||
1138 | } | 1054 | } |
1055 | use_pio: | ||
1139 | 1056 | ||
1140 | /* Revert to PIO? */ | 1057 | /* Revert to PIO? */ |
1141 | if (!use_dma) { | 1058 | OMAP_MMC_WRITE(host, BUF, 0x1f1f); |
1142 | OMAP_MMC_WRITE(host, BUF, 0x1f1f); | 1059 | host->total_bytes_left = data->blocks * block_size; |
1143 | host->total_bytes_left = data->blocks * block_size; | 1060 | host->sg_len = sg_len; |
1144 | host->sg_len = sg_len; | 1061 | mmc_omap_sg_to_buf(host); |
1145 | mmc_omap_sg_to_buf(host); | 1062 | host->dma_in_use = 0; |
1146 | host->dma_in_use = 0; | ||
1147 | } | ||
1148 | } | 1063 | } |
1149 | 1064 | ||
1150 | static void mmc_omap_start_request(struct mmc_omap_host *host, | 1065 | static void mmc_omap_start_request(struct mmc_omap_host *host, |
@@ -1157,8 +1072,12 @@ static void mmc_omap_start_request(struct mmc_omap_host *host, | |||
1157 | /* only touch fifo AFTER the controller readies it */ | 1072 | /* only touch fifo AFTER the controller readies it */ |
1158 | mmc_omap_prepare_data(host, req); | 1073 | mmc_omap_prepare_data(host, req); |
1159 | mmc_omap_start_command(host, req->cmd); | 1074 | mmc_omap_start_command(host, req->cmd); |
1160 | if (host->dma_in_use) | 1075 | if (host->dma_in_use) { |
1161 | omap_start_dma(host->dma_ch); | 1076 | struct dma_chan *c = host->data->flags & MMC_DATA_WRITE ? |
1077 | host->dma_tx : host->dma_rx; | ||
1078 | |||
1079 | dma_async_issue_pending(c); | ||
1080 | } | ||
1162 | } | 1081 | } |
1163 | 1082 | ||
1164 | static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req) | 1083 | static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req) |
@@ -1400,6 +1319,8 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev) | |||
1400 | struct omap_mmc_platform_data *pdata = pdev->dev.platform_data; | 1319 | struct omap_mmc_platform_data *pdata = pdev->dev.platform_data; |
1401 | struct mmc_omap_host *host = NULL; | 1320 | struct mmc_omap_host *host = NULL; |
1402 | struct resource *res; | 1321 | struct resource *res; |
1322 | dma_cap_mask_t mask; | ||
1323 | unsigned sig; | ||
1403 | int i, ret = 0; | 1324 | int i, ret = 0; |
1404 | int irq; | 1325 | int irq; |
1405 | 1326 | ||
@@ -1439,7 +1360,6 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev) | |||
1439 | setup_timer(&host->clk_timer, mmc_omap_clk_timer, (unsigned long) host); | 1360 | setup_timer(&host->clk_timer, mmc_omap_clk_timer, (unsigned long) host); |
1440 | 1361 | ||
1441 | spin_lock_init(&host->dma_lock); | 1362 | spin_lock_init(&host->dma_lock); |
1442 | setup_timer(&host->dma_timer, mmc_omap_dma_timer, (unsigned long) host); | ||
1443 | spin_lock_init(&host->slot_lock); | 1363 | spin_lock_init(&host->slot_lock); |
1444 | init_waitqueue_head(&host->slot_wq); | 1364 | init_waitqueue_head(&host->slot_wq); |
1445 | 1365 | ||
@@ -1450,11 +1370,7 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev) | |||
1450 | host->id = pdev->id; | 1370 | host->id = pdev->id; |
1451 | host->mem_res = res; | 1371 | host->mem_res = res; |
1452 | host->irq = irq; | 1372 | host->irq = irq; |
1453 | |||
1454 | host->use_dma = 1; | 1373 | host->use_dma = 1; |
1455 | host->dev->dma_mask = &pdata->dma_mask; | ||
1456 | host->dma_ch = -1; | ||
1457 | |||
1458 | host->irq = irq; | 1374 | host->irq = irq; |
1459 | host->phys_base = host->mem_res->start; | 1375 | host->phys_base = host->mem_res->start; |
1460 | host->virt_base = ioremap(res->start, resource_size(res)); | 1376 | host->virt_base = ioremap(res->start, resource_size(res)); |
@@ -1474,9 +1390,48 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev) | |||
1474 | goto err_free_iclk; | 1390 | goto err_free_iclk; |
1475 | } | 1391 | } |
1476 | 1392 | ||
1393 | dma_cap_zero(mask); | ||
1394 | dma_cap_set(DMA_SLAVE, mask); | ||
1395 | |||
1396 | host->dma_tx_burst = -1; | ||
1397 | host->dma_rx_burst = -1; | ||
1398 | |||
1399 | if (cpu_is_omap24xx()) | ||
1400 | sig = host->id == 0 ? OMAP24XX_DMA_MMC1_TX : OMAP24XX_DMA_MMC2_TX; | ||
1401 | else | ||
1402 | sig = host->id == 0 ? OMAP_DMA_MMC_TX : OMAP_DMA_MMC2_TX; | ||
1403 | host->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig); | ||
1404 | #if 0 | ||
1405 | if (!host->dma_tx) { | ||
1406 | dev_err(host->dev, "unable to obtain TX DMA engine channel %u\n", | ||
1407 | sig); | ||
1408 | goto err_dma; | ||
1409 | } | ||
1410 | #else | ||
1411 | if (!host->dma_tx) | ||
1412 | dev_warn(host->dev, "unable to obtain TX DMA engine channel %u\n", | ||
1413 | sig); | ||
1414 | #endif | ||
1415 | if (cpu_is_omap24xx()) | ||
1416 | sig = host->id == 0 ? OMAP24XX_DMA_MMC1_RX : OMAP24XX_DMA_MMC2_RX; | ||
1417 | else | ||
1418 | sig = host->id == 0 ? OMAP_DMA_MMC_RX : OMAP_DMA_MMC2_RX; | ||
1419 | host->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig); | ||
1420 | #if 0 | ||
1421 | if (!host->dma_rx) { | ||
1422 | dev_err(host->dev, "unable to obtain RX DMA engine channel %u\n", | ||
1423 | sig); | ||
1424 | goto err_dma; | ||
1425 | } | ||
1426 | #else | ||
1427 | if (!host->dma_rx) | ||
1428 | dev_warn(host->dev, "unable to obtain RX DMA engine channel %u\n", | ||
1429 | sig); | ||
1430 | #endif | ||
1431 | |||
1477 | ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host); | 1432 | ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host); |
1478 | if (ret) | 1433 | if (ret) |
1479 | goto err_free_fclk; | 1434 | goto err_free_dma; |
1480 | 1435 | ||
1481 | if (pdata->init != NULL) { | 1436 | if (pdata->init != NULL) { |
1482 | ret = pdata->init(&pdev->dev); | 1437 | ret = pdata->init(&pdev->dev); |
@@ -1510,7 +1465,11 @@ err_plat_cleanup: | |||
1510 | pdata->cleanup(&pdev->dev); | 1465 | pdata->cleanup(&pdev->dev); |
1511 | err_free_irq: | 1466 | err_free_irq: |
1512 | free_irq(host->irq, host); | 1467 | free_irq(host->irq, host); |
1513 | err_free_fclk: | 1468 | err_free_dma: |
1469 | if (host->dma_tx) | ||
1470 | dma_release_channel(host->dma_tx); | ||
1471 | if (host->dma_rx) | ||
1472 | dma_release_channel(host->dma_rx); | ||
1514 | clk_put(host->fclk); | 1473 | clk_put(host->fclk); |
1515 | err_free_iclk: | 1474 | err_free_iclk: |
1516 | clk_disable(host->iclk); | 1475 | clk_disable(host->iclk); |
@@ -1545,6 +1504,11 @@ static int __devexit mmc_omap_remove(struct platform_device *pdev) | |||
1545 | clk_disable(host->iclk); | 1504 | clk_disable(host->iclk); |
1546 | clk_put(host->iclk); | 1505 | clk_put(host->iclk); |
1547 | 1506 | ||
1507 | if (host->dma_tx) | ||
1508 | dma_release_channel(host->dma_tx); | ||
1509 | if (host->dma_rx) | ||
1510 | dma_release_channel(host->dma_rx); | ||
1511 | |||
1548 | iounmap(host->virt_base); | 1512 | iounmap(host->virt_base); |
1549 | release_mem_region(pdev->resource[0].start, | 1513 | release_mem_region(pdev->resource[0].start, |
1550 | pdev->resource[0].end - pdev->resource[0].start + 1); | 1514 | pdev->resource[0].end - pdev->resource[0].start + 1); |