Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'spi/merge' of git://git.secretlab.ca/git/linux-2.6

* 'spi/merge' of git://git.secretlab.ca/git/linux-2.6:
spi-topcliff-pch: Fix overrun issue
spi-topcliff-pch: Add recovery processing in case FIFO overrun error occurs
spi-topcliff-pch: Fix CPU read complete condition issue
spi-topcliff-pch: Fix SSN Control issue
spi-topcliff-pch: add tx-memory clear after complete transmitting

+66 -27
+66 -27
drivers/spi/spi-topcliff-pch.c
··· 50 50 #define PCH_RX_THOLD 7 51 51 #define PCH_RX_THOLD_MAX 15 52 52 53 + #define PCH_TX_THOLD 2 54 + 53 55 #define PCH_MAX_BAUDRATE 5000000 54 56 #define PCH_MAX_FIFO_DEPTH 16 55 57 ··· 60 58 #define PCH_SLEEP_TIME 10 61 59 62 60 #define SSN_LOW 0x02U 61 + #define SSN_HIGH 0x03U 63 62 #define SSN_NO_CONTROL 0x00U 64 63 #define PCH_MAX_CS 0xFF 65 64 #define PCI_DEVICE_ID_GE_SPI 0x8816 ··· 319 316 320 317 /* if transfer complete interrupt */ 321 318 if (reg_spsr_val & SPSR_FI_BIT) { 322 - if (tx_index < bpw_len) 319 + if ((tx_index == bpw_len) && (rx_index == tx_index)) { 320 + /* disable interrupts */ 321 + pch_spi_setclr_reg(data->master, PCH_SPCR, 0, PCH_ALL); 322 + 323 + /* transfer is completed; 324 + inform pch_spi_process_messages */ 325 + data->transfer_complete = true; 326 + data->transfer_active = false; 327 + wake_up(&data->wait); 328 + } else { 323 329 dev_err(&data->master->dev, 324 330 "%s : Transfer is not completed", __func__); 325 - /* disable interrupts */ 326 - pch_spi_setclr_reg(data->master, PCH_SPCR, 0, PCH_ALL); 327 - 328 - /* transfer is completed;inform pch_spi_process_messages */ 329 - data->transfer_complete = true; 330 - data->transfer_active = false; 331 - wake_up(&data->wait); 331 + } 332 332 } 333 333 } 334 334 ··· 354 348 "%s returning due to suspend\n", __func__); 355 349 return IRQ_NONE; 356 350 } 357 - if (data->use_dma) 358 - return IRQ_NONE; 359 351 360 352 io_remap_addr = data->io_remap_addr; 361 353 spsr = io_remap_addr + PCH_SPSR; 362 354 363 355 reg_spsr_val = ioread32(spsr); 364 356 365 - if (reg_spsr_val & SPSR_ORF_BIT) 366 - dev_err(&board_dat->pdev->dev, "%s Over run error", __func__); 357 + if (reg_spsr_val & SPSR_ORF_BIT) { 358 + dev_err(&board_dat->pdev->dev, "%s Over run error\n", __func__); 359 + if (data->current_msg->complete != 0) { 360 + data->transfer_complete = true; 361 + data->current_msg->status = -EIO; 362 + data->current_msg->complete(data->current_msg->context); 363 + data->bcurrent_msg_processing = false; 364 + data->current_msg = NULL; 365 + data->cur_trans = NULL; 366 + } 367 + } 368 + 369 + if (data->use_dma) 370 + return IRQ_NONE; 367 371 368 372 /* Check if the interrupt is for SPI device */ 369 373 if (reg_spsr_val & (SPSR_FI_BIT | SPSR_RFI_BIT)) { ··· 772 756 773 757 wait_event_interruptible(data->wait, data->transfer_complete); 774 758 775 - pch_spi_writereg(data->master, PCH_SSNXCR, SSN_NO_CONTROL); 776 - dev_dbg(&data->master->dev, 777 - "%s:no more control over SSN-writing 0 to SSNXCR.", __func__); 778 - 779 759 /* clear all interrupts */ 780 760 pch_spi_writereg(data->master, PCH_SPSR, 781 761 pch_spi_readreg(data->master, PCH_SPSR)); ··· 827 815 } 828 816 } 829 817 830 - static void pch_spi_start_transfer(struct pch_spi_data *data) 818 + static int pch_spi_start_transfer(struct pch_spi_data *data) 831 819 { 832 820 struct pch_spi_dma_ctrl *dma; 833 821 unsigned long flags; 822 + int rtn; 834 823 835 824 dma = &data->dma; 836 825 ··· 846 833 initiating the transfer. */ 847 834 dev_dbg(&data->master->dev, 848 835 "%s:waiting for transfer to get over\n", __func__); 849 - wait_event_interruptible(data->wait, data->transfer_complete); 836 + rtn = wait_event_interruptible_timeout(data->wait, 837 + data->transfer_complete, 838 + msecs_to_jiffies(2 * HZ)); 850 839 851 840 dma_sync_sg_for_cpu(&data->master->dev, dma->sg_rx_p, dma->nent, 852 841 DMA_FROM_DEVICE); 842 + 843 + dma_sync_sg_for_cpu(&data->master->dev, dma->sg_tx_p, dma->nent, 844 + DMA_FROM_DEVICE); 845 + memset(data->dma.tx_buf_virt, 0, PAGE_SIZE); 846 + 853 847 async_tx_ack(dma->desc_rx); 854 848 async_tx_ack(dma->desc_tx); 855 849 kfree(dma->sg_tx_p); 856 850 kfree(dma->sg_rx_p); 857 851 858 852 spin_lock_irqsave(&data->lock, flags); 859 - pch_spi_writereg(data->master, PCH_SSNXCR, SSN_NO_CONTROL); 860 - dev_dbg(&data->master->dev, 861 - "%s:no more control over SSN-writing 0 to SSNXCR.", __func__); 862 853 863 854 /* clear fifo threshold, disable interrupts, disable SPI transfer */ 864 855 pch_spi_setclr_reg(data->master, PCH_SPCR, 0, ··· 875 858 pch_spi_clear_fifo(data->master); 876 859 877 860 spin_unlock_irqrestore(&data->lock, flags); 861 + 862 + return rtn; 878 863 } 879 864 880 865 static void pch_dma_rx_complete(void *arg) ··· 1042 1023 /* set receive fifo threshold and transmit fifo threshold */ 1043 1024 pch_spi_setclr_reg(data->master, PCH_SPCR, 1044 1025 ((size - 1) << SPCR_RFIC_FIELD) | 1045 - ((PCH_MAX_FIFO_DEPTH - PCH_DMA_TRANS_SIZE) << 1046 - SPCR_TFIC_FIELD), 1026 + (PCH_TX_THOLD << SPCR_TFIC_FIELD), 1047 1027 MASK_RFIC_SPCR_BITS | MASK_TFIC_SPCR_BITS); 1048 1028 1049 1029 spin_unlock_irqrestore(&data->lock, flags); ··· 1053 1035 /* offset, length setting */ 1054 1036 sg = dma->sg_rx_p; 1055 1037 for (i = 0; i < num; i++, sg++) { 1056 - if (i == 0) { 1057 - sg->offset = 0; 1038 + if (i == (num - 2)) { 1039 + sg->offset = size * i; 1040 + sg->offset = sg->offset * (*bpw / 8); 1058 1041 sg_set_page(sg, virt_to_page(dma->rx_buf_virt), rem, 1059 1042 sg->offset); 1060 1043 sg_dma_len(sg) = rem; 1044 + } else if (i == (num - 1)) { 1045 + sg->offset = size * (i - 1) + rem; 1046 + sg->offset = sg->offset * (*bpw / 8); 1047 + sg_set_page(sg, virt_to_page(dma->rx_buf_virt), size, 1048 + sg->offset); 1049 + sg_dma_len(sg) = size; 1061 1050 } else { 1062 - sg->offset = rem + size * (i - 1); 1051 + sg->offset = size * i; 1063 1052 sg->offset = sg->offset * (*bpw / 8); 1064 1053 sg_set_page(sg, virt_to_page(dma->rx_buf_virt), size, 1065 1054 sg->offset); ··· 1090 1065 dma->desc_rx = desc_rx; 1091 1066 1092 1067 /* TX */ 1068 + if (data->bpw_len > PCH_DMA_TRANS_SIZE) { 1069 + num = data->bpw_len / PCH_DMA_TRANS_SIZE; 1070 + size = PCH_DMA_TRANS_SIZE; 1071 + rem = 16; 1072 + } else { 1073 + num = 1; 1074 + size = data->bpw_len; 1075 + rem = data->bpw_len; 1076 + } 1077 + 1093 1078 dma->sg_tx_p = kzalloc(sizeof(struct scatterlist)*num, GFP_ATOMIC); 1094 1079 sg_init_table(dma->sg_tx_p, num); /* Initialize SG table */ 1095 1080 /* offset, length setting */ ··· 1197 1162 if (data->use_dma) 1198 1163 pch_spi_request_dma(data, 1199 1164 data->current_msg->spi->bits_per_word); 1165 + pch_spi_writereg(data->master, PCH_SSNXCR, SSN_NO_CONTROL); 1200 1166 do { 1201 1167 /* If we are already processing a message get the next 1202 1168 transfer structure from the message otherwise retrieve ··· 1220 1184 1221 1185 if (data->use_dma) { 1222 1186 pch_spi_handle_dma(data, &bpw); 1223 - pch_spi_start_transfer(data); 1187 + if (!pch_spi_start_transfer(data)) 1188 + goto out; 1224 1189 pch_spi_copy_rx_data_for_dma(data, bpw); 1225 1190 } else { 1226 1191 pch_spi_set_tx(data, &bpw); ··· 1259 1222 1260 1223 } while (data->cur_trans != NULL); 1261 1224 1225 + out: 1226 + pch_spi_writereg(data->master, PCH_SSNXCR, SSN_HIGH); 1262 1227 if (data->use_dma) 1263 1228 pch_spi_release_dma(data); 1264 1229 }