Skip to content

Commit 25e803f

Browse files
Tomoya MORINAGAglikely
authored andcommitted
spi-topcliff-pch: Add recovery processing in case FIFO overrun error occurs
Add recovery processing in case FIFO overrun error occurs with DMA transfer mode. Signed-off-by: Tomoya MORINAGA <[email protected]> Signed-off-by: Grant Likely <[email protected]>
1 parent 373b0eb commit 25e803f

File tree

1 file changed

+24
-7
lines changed

1 file changed

+24
-7
lines changed

drivers/spi/spi-topcliff-pch.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -352,16 +352,26 @@ static irqreturn_t pch_spi_handler(int irq, void *dev_id)
352352
"%s returning due to suspend\n", __func__);
353353
return IRQ_NONE;
354354
}
355-
if (data->use_dma)
356-
return IRQ_NONE;
357355

358356
io_remap_addr = data->io_remap_addr;
359357
spsr = io_remap_addr + PCH_SPSR;
360358

361359
reg_spsr_val = ioread32(spsr);
362360

363-
if (reg_spsr_val & SPSR_ORF_BIT)
364-
dev_err(&board_dat->pdev->dev, "%s Over run error", __func__);
361+
if (reg_spsr_val & SPSR_ORF_BIT) {
362+
dev_err(&board_dat->pdev->dev, "%s Over run error\n", __func__);
363+
if (data->current_msg->complete != 0) {
364+
data->transfer_complete = true;
365+
data->current_msg->status = -EIO;
366+
data->current_msg->complete(data->current_msg->context);
367+
data->bcurrent_msg_processing = false;
368+
data->current_msg = NULL;
369+
data->cur_trans = NULL;
370+
}
371+
}
372+
373+
if (data->use_dma)
374+
return IRQ_NONE;
365375

366376
/* Check if the interrupt is for SPI device */
367377
if (reg_spsr_val & (SPSR_FI_BIT | SPSR_RFI_BIT)) {
@@ -815,10 +825,11 @@ static void pch_spi_copy_rx_data_for_dma(struct pch_spi_data *data, int bpw)
815825
}
816826
}
817827

818-
static void pch_spi_start_transfer(struct pch_spi_data *data)
828+
static int pch_spi_start_transfer(struct pch_spi_data *data)
819829
{
820830
struct pch_spi_dma_ctrl *dma;
821831
unsigned long flags;
832+
int rtn;
822833

823834
dma = &data->dma;
824835

@@ -833,7 +844,9 @@ static void pch_spi_start_transfer(struct pch_spi_data *data)
833844
initiating the transfer. */
834845
dev_dbg(&data->master->dev,
835846
"%s:waiting for transfer to get over\n", __func__);
836-
wait_event_interruptible(data->wait, data->transfer_complete);
847+
rtn = wait_event_interruptible_timeout(data->wait,
848+
data->transfer_complete,
849+
msecs_to_jiffies(2 * HZ));
837850

838851
dma_sync_sg_for_cpu(&data->master->dev, dma->sg_rx_p, dma->nent,
839852
DMA_FROM_DEVICE);
@@ -860,6 +873,8 @@ static void pch_spi_start_transfer(struct pch_spi_data *data)
860873
pch_spi_clear_fifo(data->master);
861874

862875
spin_unlock_irqrestore(&data->lock, flags);
876+
877+
return rtn;
863878
}
864879

865880
static void pch_dma_rx_complete(void *arg)
@@ -1187,7 +1202,8 @@ static void pch_spi_process_messages(struct work_struct *pwork)
11871202

11881203
if (data->use_dma) {
11891204
pch_spi_handle_dma(data, &bpw);
1190-
pch_spi_start_transfer(data);
1205+
if (!pch_spi_start_transfer(data))
1206+
goto out;
11911207
pch_spi_copy_rx_data_for_dma(data, bpw);
11921208
} else {
11931209
pch_spi_set_tx(data, &bpw);
@@ -1225,6 +1241,7 @@ static void pch_spi_process_messages(struct work_struct *pwork)
12251241

12261242
} while (data->cur_trans != NULL);
12271243

1244+
out:
12281245
pch_spi_writereg(data->master, PCH_SSNXCR, SSN_HIGH);
12291246
if (data->use_dma)
12301247
pch_spi_release_dma(data);

0 commit comments

Comments
 (0)