aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-topcliff-pch.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-21 13:32:00 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-21 13:32:00 -0400
commit5f0e685f316a1de6d3af8b23eaf46651faca32ab (patch)
treeaf1ed231b7fcfc65b146be59a0aee699aa9f6353 /drivers/spi/spi-topcliff-pch.c
parentf8974cb71310a05632aada76be6a27576d61e609 (diff)
parent87bf5ab82884c829366914aaa813cc8b07b9fe58 (diff)
Merge tag 'spi-for-linus' of git://git.secretlab.ca/git/linux-2.6
Pull SPI changes for v3.4 from Grant Likely: "Mostly a bunch of new drivers and driver bug fixes; but this also includes a few patches that create a core message queue infrastructure for the spi subsystem instead of making each driver open code it." * tag 'spi-for-linus' of git://git.secretlab.ca/git/linux-2.6: (34 commits) spi/fsl-espi: Make sure pm is within 2..32 spi/fsl-espi: make the clock computation easier to read spi: sh-hspi: modify write/read method spi: sh-hspi: control spi clock more correctly spi: sh-hspi: convert to using core message queue spi: s3c64xx: Fix build spi: s3c64xx: remove unnecessary callback msg->complete spi: remove redundant variable assignment spi: release lock on error path in spi_pump_messages() spi: Compatibility with direction which is used in samsung DMA operation spi-topcliff-pch: add recovery processing in case wait-event timeout spi-topcliff-pch: supports a spi mode setup and bit order setup by IO control spi-topcliff-pch: Fix issue for transmitting over 4KByte spi-topcliff-pch: Modify pci-bus number dynamically to get DMA device info spi/imx: simplify error handling to free gpios spi: Convert to DEFINE_PCI_DEVICE_TABLE spi: add Broadcom BCM63xx SPI controller driver SPI: add CSR SiRFprimaII SPI controller driver spi-topcliff-pch: fix -Wuninitialized warning spi: Mark spi_register_board_info() __devinit ...
Diffstat (limited to 'drivers/spi/spi-topcliff-pch.c')
-rw-r--r--drivers/spi/spi-topcliff-pch.c113
1 files changed, 84 insertions, 29 deletions
diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c
index 10182eb50068..5c6fa5ed3366 100644
--- a/drivers/spi/spi-topcliff-pch.c
+++ b/drivers/spi/spi-topcliff-pch.c
@@ -196,6 +196,7 @@ struct pch_spi_data {
196 struct pch_spi_dma_ctrl dma; 196 struct pch_spi_dma_ctrl dma;
197 int use_dma; 197 int use_dma;
198 u8 irq_reg_sts; 198 u8 irq_reg_sts;
199 int save_total_len;
199}; 200};
200 201
201/** 202/**
@@ -216,7 +217,7 @@ struct pch_pd_dev_save {
216 struct pch_spi_board_data *board_dat; 217 struct pch_spi_board_data *board_dat;
217}; 218};
218 219
219static struct pci_device_id pch_spi_pcidev_id[] = { 220static DEFINE_PCI_DEVICE_TABLE(pch_spi_pcidev_id) = {
220 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_GE_SPI), 1, }, 221 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_GE_SPI), 1, },
221 { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_SPI), 2, }, 222 { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_SPI), 2, },
222 { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_SPI), 1, }, 223 { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_SPI), 1, },
@@ -318,22 +319,23 @@ static void pch_spi_handler_sub(struct pch_spi_data *data, u32 reg_spsr_val,
318 data->tx_index = tx_index; 319 data->tx_index = tx_index;
319 data->rx_index = rx_index; 320 data->rx_index = rx_index;
320 321
321 } 322 /* if transfer complete interrupt */
322 323 if (reg_spsr_val & SPSR_FI_BIT) {
323 /* if transfer complete interrupt */ 324 if ((tx_index == bpw_len) && (rx_index == tx_index)) {
324 if (reg_spsr_val & SPSR_FI_BIT) { 325 /* disable interrupts */
325 if ((tx_index == bpw_len) && (rx_index == tx_index)) { 326 pch_spi_setclr_reg(data->master, PCH_SPCR, 0,
326 /* disable interrupts */ 327 PCH_ALL);
327 pch_spi_setclr_reg(data->master, PCH_SPCR, 0, PCH_ALL); 328
328 329 /* transfer is completed;
329 /* transfer is completed; 330 inform pch_spi_process_messages */
330 inform pch_spi_process_messages */ 331 data->transfer_complete = true;
331 data->transfer_complete = true; 332 data->transfer_active = false;
332 data->transfer_active = false; 333 wake_up(&data->wait);
333 wake_up(&data->wait); 334 } else {
334 } else { 335 dev_err(&data->master->dev,
335 dev_err(&data->master->dev, 336 "%s : Transfer is not completed",
336 "%s : Transfer is not completed", __func__); 337 __func__);
338 }
337 } 339 }
338 } 340 }
339} 341}
@@ -822,11 +824,13 @@ static void pch_spi_copy_rx_data_for_dma(struct pch_spi_data *data, int bpw)
822 rx_dma_buf = data->dma.rx_buf_virt; 824 rx_dma_buf = data->dma.rx_buf_virt;
823 for (j = 0; j < data->bpw_len; j++) 825 for (j = 0; j < data->bpw_len; j++)
824 *rx_buf++ = *rx_dma_buf++ & 0xFF; 826 *rx_buf++ = *rx_dma_buf++ & 0xFF;
827 data->cur_trans->rx_buf = rx_buf;
825 } else { 828 } else {
826 rx_sbuf = data->cur_trans->rx_buf; 829 rx_sbuf = data->cur_trans->rx_buf;
827 rx_dma_sbuf = data->dma.rx_buf_virt; 830 rx_dma_sbuf = data->dma.rx_buf_virt;
828 for (j = 0; j < data->bpw_len; j++) 831 for (j = 0; j < data->bpw_len; j++)
829 *rx_sbuf++ = *rx_dma_sbuf++; 832 *rx_sbuf++ = *rx_dma_sbuf++;
833 data->cur_trans->rx_buf = rx_sbuf;
830 } 834 }
831} 835}
832 836
@@ -852,6 +856,9 @@ static int pch_spi_start_transfer(struct pch_spi_data *data)
852 rtn = wait_event_interruptible_timeout(data->wait, 856 rtn = wait_event_interruptible_timeout(data->wait,
853 data->transfer_complete, 857 data->transfer_complete,
854 msecs_to_jiffies(2 * HZ)); 858 msecs_to_jiffies(2 * HZ));
859 if (!rtn)
860 dev_err(&data->master->dev,
861 "%s wait-event timeout\n", __func__);
855 862
856 dma_sync_sg_for_cpu(&data->master->dev, dma->sg_rx_p, dma->nent, 863 dma_sync_sg_for_cpu(&data->master->dev, dma->sg_rx_p, dma->nent,
857 DMA_FROM_DEVICE); 864 DMA_FROM_DEVICE);
@@ -923,7 +930,8 @@ static void pch_spi_request_dma(struct pch_spi_data *data, int bpw)
923 dma_cap_set(DMA_SLAVE, mask); 930 dma_cap_set(DMA_SLAVE, mask);
924 931
925 /* Get DMA's dev information */ 932 /* Get DMA's dev information */
926 dma_dev = pci_get_bus_and_slot(2, PCI_DEVFN(12, 0)); 933 dma_dev = pci_get_bus_and_slot(data->board_dat->pdev->bus->number,
934 PCI_DEVFN(12, 0));
927 935
928 /* Set Tx DMA */ 936 /* Set Tx DMA */
929 param = &dma->param_tx; 937 param = &dma->param_tx;
@@ -987,6 +995,7 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw)
987 int i; 995 int i;
988 int size; 996 int size;
989 int rem; 997 int rem;
998 int head;
990 unsigned long flags; 999 unsigned long flags;
991 struct pch_spi_dma_ctrl *dma; 1000 struct pch_spi_dma_ctrl *dma;
992 1001
@@ -1015,6 +1024,11 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw)
1015 } 1024 }
1016 data->bpw_len = data->cur_trans->len / (*bpw / 8); 1025 data->bpw_len = data->cur_trans->len / (*bpw / 8);
1017 1026
1027 if (data->bpw_len > PCH_BUF_SIZE) {
1028 data->bpw_len = PCH_BUF_SIZE;
1029 data->cur_trans->len -= PCH_BUF_SIZE;
1030 }
1031
1018 /* copy Tx Data */ 1032 /* copy Tx Data */
1019 if (data->cur_trans->tx_buf != NULL) { 1033 if (data->cur_trans->tx_buf != NULL) {
1020 if (*bpw == 8) { 1034 if (*bpw == 8) {
@@ -1029,10 +1043,17 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw)
1029 *tx_dma_sbuf++ = *tx_sbuf++; 1043 *tx_dma_sbuf++ = *tx_sbuf++;
1030 } 1044 }
1031 } 1045 }
1046
1047 /* Calculate Rx parameter for DMA transmitting */
1032 if (data->bpw_len > PCH_DMA_TRANS_SIZE) { 1048 if (data->bpw_len > PCH_DMA_TRANS_SIZE) {
1033 num = data->bpw_len / PCH_DMA_TRANS_SIZE + 1; 1049 if (data->bpw_len % PCH_DMA_TRANS_SIZE) {
1050 num = data->bpw_len / PCH_DMA_TRANS_SIZE + 1;
1051 rem = data->bpw_len % PCH_DMA_TRANS_SIZE;
1052 } else {
1053 num = data->bpw_len / PCH_DMA_TRANS_SIZE;
1054 rem = PCH_DMA_TRANS_SIZE;
1055 }
1034 size = PCH_DMA_TRANS_SIZE; 1056 size = PCH_DMA_TRANS_SIZE;
1035 rem = data->bpw_len % PCH_DMA_TRANS_SIZE;
1036 } else { 1057 } else {
1037 num = 1; 1058 num = 1;
1038 size = data->bpw_len; 1059 size = data->bpw_len;
@@ -1092,15 +1113,23 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw)
1092 dma->nent = num; 1113 dma->nent = num;
1093 dma->desc_rx = desc_rx; 1114 dma->desc_rx = desc_rx;
1094 1115
1095 /* TX */ 1116 /* Calculate Tx parameter for DMA transmitting */
1096 if (data->bpw_len > PCH_DMA_TRANS_SIZE) { 1117 if (data->bpw_len > PCH_MAX_FIFO_DEPTH) {
1097 num = data->bpw_len / PCH_DMA_TRANS_SIZE; 1118 head = PCH_MAX_FIFO_DEPTH - PCH_DMA_TRANS_SIZE;
1119 if (data->bpw_len % PCH_DMA_TRANS_SIZE > 4) {
1120 num = data->bpw_len / PCH_DMA_TRANS_SIZE + 1;
1121 rem = data->bpw_len % PCH_DMA_TRANS_SIZE - head;
1122 } else {
1123 num = data->bpw_len / PCH_DMA_TRANS_SIZE;
1124 rem = data->bpw_len % PCH_DMA_TRANS_SIZE +
1125 PCH_DMA_TRANS_SIZE - head;
1126 }
1098 size = PCH_DMA_TRANS_SIZE; 1127 size = PCH_DMA_TRANS_SIZE;
1099 rem = 16;
1100 } else { 1128 } else {
1101 num = 1; 1129 num = 1;
1102 size = data->bpw_len; 1130 size = data->bpw_len;
1103 rem = data->bpw_len; 1131 rem = data->bpw_len;
1132 head = 0;
1104 } 1133 }
1105 1134
1106 dma->sg_tx_p = kzalloc(sizeof(struct scatterlist)*num, GFP_ATOMIC); 1135 dma->sg_tx_p = kzalloc(sizeof(struct scatterlist)*num, GFP_ATOMIC);
@@ -1110,11 +1139,17 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw)
1110 for (i = 0; i < num; i++, sg++) { 1139 for (i = 0; i < num; i++, sg++) {
1111 if (i == 0) { 1140 if (i == 0) {
1112 sg->offset = 0; 1141 sg->offset = 0;
1142 sg_set_page(sg, virt_to_page(dma->tx_buf_virt), size + head,
1143 sg->offset);
1144 sg_dma_len(sg) = size + head;
1145 } else if (i == (num - 1)) {
1146 sg->offset = head + size * i;
1147 sg->offset = sg->offset * (*bpw / 8);
1113 sg_set_page(sg, virt_to_page(dma->tx_buf_virt), rem, 1148 sg_set_page(sg, virt_to_page(dma->tx_buf_virt), rem,
1114 sg->offset); 1149 sg->offset);
1115 sg_dma_len(sg) = rem; 1150 sg_dma_len(sg) = rem;
1116 } else { 1151 } else {
1117 sg->offset = rem + size * (i - 1); 1152 sg->offset = head + size * i;
1118 sg->offset = sg->offset * (*bpw / 8); 1153 sg->offset = sg->offset * (*bpw / 8);
1119 sg_set_page(sg, virt_to_page(dma->tx_buf_virt), size, 1154 sg_set_page(sg, virt_to_page(dma->tx_buf_virt), size,
1120 sg->offset); 1155 sg->offset);
@@ -1202,6 +1237,7 @@ static void pch_spi_process_messages(struct work_struct *pwork)
1202 data->current_msg->spi->bits_per_word); 1237 data->current_msg->spi->bits_per_word);
1203 pch_spi_writereg(data->master, PCH_SSNXCR, SSN_NO_CONTROL); 1238 pch_spi_writereg(data->master, PCH_SSNXCR, SSN_NO_CONTROL);
1204 do { 1239 do {
1240 int cnt;
1205 /* If we are already processing a message get the next 1241 /* If we are already processing a message get the next
1206 transfer structure from the message otherwise retrieve 1242 transfer structure from the message otherwise retrieve
1207 the 1st transfer request from the message. */ 1243 the 1st transfer request from the message. */
@@ -1221,11 +1257,28 @@ static void pch_spi_process_messages(struct work_struct *pwork)
1221 } 1257 }
1222 spin_unlock(&data->lock); 1258 spin_unlock(&data->lock);
1223 1259
1260 if (!data->cur_trans->len)
1261 goto out;
1262 cnt = (data->cur_trans->len - 1) / PCH_BUF_SIZE + 1;
1263 data->save_total_len = data->cur_trans->len;
1224 if (data->use_dma) { 1264 if (data->use_dma) {
1225 pch_spi_handle_dma(data, &bpw); 1265 int i;
1226 if (!pch_spi_start_transfer(data)) 1266 char *save_rx_buf = data->cur_trans->rx_buf;
1227 goto out; 1267 for (i = 0; i < cnt; i ++) {
1228 pch_spi_copy_rx_data_for_dma(data, bpw); 1268 pch_spi_handle_dma(data, &bpw);
1269 if (!pch_spi_start_transfer(data)) {
1270 data->transfer_complete = true;
1271 data->current_msg->status = -EIO;
1272 data->current_msg->complete
1273 (data->current_msg->context);
1274 data->bcurrent_msg_processing = false;
1275 data->current_msg = NULL;
1276 data->cur_trans = NULL;
1277 goto out;
1278 }
1279 pch_spi_copy_rx_data_for_dma(data, bpw);
1280 }
1281 data->cur_trans->rx_buf = save_rx_buf;
1229 } else { 1282 } else {
1230 pch_spi_set_tx(data, &bpw); 1283 pch_spi_set_tx(data, &bpw);
1231 pch_spi_set_ir(data); 1284 pch_spi_set_ir(data);
@@ -1236,6 +1289,7 @@ static void pch_spi_process_messages(struct work_struct *pwork)
1236 data->pkt_tx_buff = NULL; 1289 data->pkt_tx_buff = NULL;
1237 } 1290 }
1238 /* increment message count */ 1291 /* increment message count */
1292 data->cur_trans->len = data->save_total_len;
1239 data->current_msg->actual_length += data->cur_trans->len; 1293 data->current_msg->actual_length += data->cur_trans->len;
1240 1294
1241 dev_dbg(&data->master->dev, 1295 dev_dbg(&data->master->dev,
@@ -1388,6 +1442,7 @@ static int __devinit pch_spi_pd_probe(struct platform_device *plat_dev)
1388 master->num_chipselect = PCH_MAX_CS; 1442 master->num_chipselect = PCH_MAX_CS;
1389 master->setup = pch_spi_setup; 1443 master->setup = pch_spi_setup;
1390 master->transfer = pch_spi_transfer; 1444 master->transfer = pch_spi_transfer;
1445 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
1391 1446
1392 data->board_dat = board_dat; 1447 data->board_dat = board_dat;
1393 data->plat_dev = plat_dev; 1448 data->plat_dev = plat_dev;