From de3bd7e6de25141c466773c2e0fa319b2fa93655 Mon Sep 17 00:00:00 2001 From: Danny Kukawka Date: Tue, 14 Feb 2012 15:35:03 +0100 Subject: spi-topcliff-pch: fix -Wuninitialized warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix for: drivers/spi/spi-topcliff-pch.c: In function ‘pch_spi_handler_sub’: drivers/spi/spi-topcliff-pch.c:325:17: warning: ‘bpw_len’ may be used uninitialized in this function [-Wuninitialized] drivers/spi/spi-topcliff-pch.c:325:42: warning: ‘rx_index’ may be used uninitialized in this function [-Wuninitialized] drivers/spi/spi-topcliff-pch.c:325:42: warning: ‘tx_index’ may be used uninitialized in this function [-Wuninitialized] Move usage of tx_index, rx_index and bpw_len into the same block as where they are set to prevent uninitialized usage. v2: instead of init variables with 0 move the whole block Signed-off-by: Danny Kukawka Signed-off-by: Grant Likely --- drivers/spi/spi-topcliff-pch.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'drivers/spi/spi-topcliff-pch.c') diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 2a6429d8c36..88e6b3fd1f1 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -318,22 +318,23 @@ static void pch_spi_handler_sub(struct pch_spi_data *data, u32 reg_spsr_val, data->tx_index = tx_index; data->rx_index = rx_index; - } - - /* if transfer complete interrupt */ - if (reg_spsr_val & SPSR_FI_BIT) { - if ((tx_index == bpw_len) && (rx_index == tx_index)) { - /* disable interrupts */ - pch_spi_setclr_reg(data->master, PCH_SPCR, 0, PCH_ALL); - - /* transfer is completed; - inform pch_spi_process_messages */ - data->transfer_complete = true; - data->transfer_active = false; - wake_up(&data->wait); - } else { - dev_err(&data->master->dev, - "%s : Transfer is not completed", __func__); + /* if transfer complete interrupt */ + if (reg_spsr_val & SPSR_FI_BIT) { + if ((tx_index == bpw_len) && (rx_index == tx_index)) { + /* disable interrupts */ + pch_spi_setclr_reg(data->master, PCH_SPCR, 0, + PCH_ALL); + + /* transfer is completed; + inform pch_spi_process_messages */ + data->transfer_complete = true; + data->transfer_active = false; + wake_up(&data->wait); + } else { + dev_err(&data->master->dev, + "%s : Transfer is not completed", + __func__); + } } } } -- cgit v1.2.3 From e290cf276bc2a6cdcb360fd72b7a6a24539505fc Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 15 Dec 2011 08:11:25 +0800 Subject: spi: Convert to DEFINE_PCI_DEVICE_TABLE Convert static struct pci_device_id *[] to static DEFINE_PCI_DEVICE_TABLE tables. Signed-off-by: Axel Lin Signed-off-by: Grant Likely --- drivers/spi/spi-topcliff-pch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/spi/spi-topcliff-pch.c') diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 88e6b3fd1f1..4a5fafb8d57 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -216,7 +216,7 @@ struct pch_pd_dev_save { struct pch_spi_board_data *board_dat; }; -static struct pci_device_id pch_spi_pcidev_id[] = { +static DEFINE_PCI_DEVICE_TABLE(pch_spi_pcidev_id) = { { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_GE_SPI), 1, }, { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_SPI), 2, }, { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_SPI), 1, }, -- cgit v1.2.3 From ee2ece5261a639b89f194d141444b03b4c923179 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Fri, 9 Dec 2011 13:11:42 +0900 Subject: spi-topcliff-pch: Modify pci-bus number dynamically to get DMA device info Signed-off-by: Tomoya MORINAGA Signed-off-by: Grant Likely --- drivers/spi/spi-topcliff-pch.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/spi/spi-topcliff-pch.c') diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 4a5fafb8d57..4b32fd7d057 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -924,7 +924,8 @@ static void pch_spi_request_dma(struct pch_spi_data *data, int bpw) dma_cap_set(DMA_SLAVE, mask); /* Get DMA's dev information */ - dma_dev = pci_get_bus_and_slot(2, PCI_DEVFN(12, 0)); + dma_dev = pci_get_bus_and_slot(data->board_dat->pdev->bus->number, + PCI_DEVFN(12, 0)); /* Set Tx DMA */ param = &dma->param_tx; -- cgit v1.2.3 From 7d05b3e868ee0f9231baf40cb77be3df5dd1f18c Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Fri, 9 Dec 2011 13:13:27 +0900 Subject: spi-topcliff-pch: Fix issue for transmitting over 4KByte Currently, when spi-topcliff-pch receives transmit request over 4KByte, this driver can't process correctly. This driver needs to divide the data into 4Kbyte unit. This patch fixes the issue. Signed-off-by: Tomoya MORINAGA Signed-off-by: Grant Likely --- drivers/spi/spi-topcliff-pch.c | 66 +++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 11 deletions(-) (limited to 'drivers/spi/spi-topcliff-pch.c') diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 4b32fd7d057..4fdb83a765d 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -196,6 +196,7 @@ struct pch_spi_data { struct pch_spi_dma_ctrl dma; int use_dma; u8 irq_reg_sts; + int save_total_len; }; /** @@ -823,11 +824,13 @@ static void pch_spi_copy_rx_data_for_dma(struct pch_spi_data *data, int bpw) rx_dma_buf = data->dma.rx_buf_virt; for (j = 0; j < data->bpw_len; j++) *rx_buf++ = *rx_dma_buf++ & 0xFF; + data->cur_trans->rx_buf = rx_buf; } else { rx_sbuf = data->cur_trans->rx_buf; rx_dma_sbuf = data->dma.rx_buf_virt; for (j = 0; j < data->bpw_len; j++) *rx_sbuf++ = *rx_dma_sbuf++; + data->cur_trans->rx_buf = rx_sbuf; } } @@ -853,6 +856,9 @@ static int pch_spi_start_transfer(struct pch_spi_data *data) rtn = wait_event_interruptible_timeout(data->wait, data->transfer_complete, msecs_to_jiffies(2 * HZ)); + if (!rtn) + dev_err(&data->master->dev, + "%s wait-event timeout\n", __func__); dma_sync_sg_for_cpu(&data->master->dev, dma->sg_rx_p, dma->nent, DMA_FROM_DEVICE); @@ -989,6 +995,7 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw) int i; int size; int rem; + int head; unsigned long flags; struct pch_spi_dma_ctrl *dma; @@ -1017,6 +1024,11 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw) } data->bpw_len = data->cur_trans->len / (*bpw / 8); + if (data->bpw_len > PCH_BUF_SIZE) { + data->bpw_len = PCH_BUF_SIZE; + data->cur_trans->len -= PCH_BUF_SIZE; + } + /* copy Tx Data */ if (data->cur_trans->tx_buf != NULL) { if (*bpw == 8) { @@ -1031,10 +1043,17 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw) *tx_dma_sbuf++ = *tx_sbuf++; } } + + /* Calculate Rx parameter for DMA transmitting */ if (data->bpw_len > PCH_DMA_TRANS_SIZE) { - num = data->bpw_len / PCH_DMA_TRANS_SIZE + 1; + if (data->bpw_len % PCH_DMA_TRANS_SIZE) { + num = data->bpw_len / PCH_DMA_TRANS_SIZE + 1; + rem = data->bpw_len % PCH_DMA_TRANS_SIZE; + } else { + num = data->bpw_len / PCH_DMA_TRANS_SIZE; + rem = PCH_DMA_TRANS_SIZE; + } size = PCH_DMA_TRANS_SIZE; - rem = data->bpw_len % PCH_DMA_TRANS_SIZE; } else { num = 1; size = data->bpw_len; @@ -1094,15 +1113,23 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw) dma->nent = num; dma->desc_rx = desc_rx; - /* TX */ - if (data->bpw_len > PCH_DMA_TRANS_SIZE) { - num = data->bpw_len / PCH_DMA_TRANS_SIZE; + /* Calculate Tx parameter for DMA transmitting */ + if (data->bpw_len > PCH_MAX_FIFO_DEPTH) { + head = PCH_MAX_FIFO_DEPTH - PCH_DMA_TRANS_SIZE; + if (data->bpw_len % PCH_DMA_TRANS_SIZE > 4) { + num = data->bpw_len / PCH_DMA_TRANS_SIZE + 1; + rem = data->bpw_len % PCH_DMA_TRANS_SIZE - head; + } else { + num = data->bpw_len / PCH_DMA_TRANS_SIZE; + rem = data->bpw_len % PCH_DMA_TRANS_SIZE + + PCH_DMA_TRANS_SIZE - head; + } size = PCH_DMA_TRANS_SIZE; - rem = 16; } else { num = 1; size = data->bpw_len; rem = data->bpw_len; + head = 0; } dma->sg_tx_p = kzalloc(sizeof(struct scatterlist)*num, GFP_ATOMIC); @@ -1112,11 +1139,17 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw) for (i = 0; i < num; i++, sg++) { if (i == 0) { sg->offset = 0; + sg_set_page(sg, virt_to_page(dma->tx_buf_virt), size + head, + sg->offset); + sg_dma_len(sg) = size + head; + } else if (i == (num - 1)) { + sg->offset = head + size * i; + sg->offset = sg->offset * (*bpw / 8); sg_set_page(sg, virt_to_page(dma->tx_buf_virt), rem, sg->offset); sg_dma_len(sg) = rem; } else { - sg->offset = rem + size * (i - 1); + sg->offset = head + size * i; sg->offset = sg->offset * (*bpw / 8); sg_set_page(sg, virt_to_page(dma->tx_buf_virt), size, sg->offset); @@ -1204,6 +1237,7 @@ static void pch_spi_process_messages(struct work_struct *pwork) data->current_msg->spi->bits_per_word); pch_spi_writereg(data->master, PCH_SSNXCR, SSN_NO_CONTROL); do { + int cnt; /* If we are already processing a message get the next transfer structure from the message otherwise retrieve the 1st transfer request from the message. */ @@ -1223,11 +1257,20 @@ static void pch_spi_process_messages(struct work_struct *pwork) } spin_unlock(&data->lock); + if (!data->cur_trans->len) + goto out; + cnt = (data->cur_trans->len - 1) / PCH_BUF_SIZE + 1; + data->save_total_len = data->cur_trans->len; if (data->use_dma) { - pch_spi_handle_dma(data, &bpw); - if (!pch_spi_start_transfer(data)) - goto out; - pch_spi_copy_rx_data_for_dma(data, bpw); + int i; + char *save_rx_buf = data->cur_trans->rx_buf; + for (i = 0; i < cnt; i ++) { + pch_spi_handle_dma(data, &bpw); + if (!pch_spi_start_transfer(data)) + goto out; + pch_spi_copy_rx_data_for_dma(data, bpw); + } + data->cur_trans->rx_buf = save_rx_buf; } else { pch_spi_set_tx(data, &bpw); pch_spi_set_ir(data); @@ -1238,6 +1281,7 @@ static void pch_spi_process_messages(struct work_struct *pwork) data->pkt_tx_buff = NULL; } /* increment message count */ + data->cur_trans->len = data->save_total_len; data->current_msg->actual_length += data->cur_trans->len; dev_dbg(&data->master->dev, -- cgit v1.2.3 From f258b44e22e07f5e98ac2260c70acff5784791b6 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Fri, 9 Dec 2011 13:13:28 +0900 Subject: spi-topcliff-pch: supports a spi mode setup and bit order setup by IO control This patch supports a spi mode setup and bit order setup by IO control. spi mode: mode 0 to mode 3 bit order: LSB first, MSB first Signed-off-by: Tomoya MORINAGA Signed-off-by: Grant Likely --- drivers/spi/spi-topcliff-pch.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/spi/spi-topcliff-pch.c') diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 4fdb83a765d..5a477e91426 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -1434,6 +1434,7 @@ static int __devinit pch_spi_pd_probe(struct platform_device *plat_dev) master->num_chipselect = PCH_MAX_CS; master->setup = pch_spi_setup; master->transfer = pch_spi_transfer; + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; data->board_dat = board_dat; data->plat_dev = plat_dev; -- cgit v1.2.3 From 0f57e168aa109775430c76cc663fb64909813d84 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Fri, 9 Dec 2011 13:13:29 +0900 Subject: spi-topcliff-pch: add recovery processing in case wait-event timeout Currently, pch_spi_start_transfer failure is not anticipated. This patch adds the processing. Signed-off-by: Tomoya MORINAGA Signed-off-by: Grant Likely --- drivers/spi/spi-topcliff-pch.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/spi/spi-topcliff-pch.c') diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 5a477e91426..c9e1fcc923b 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -1266,8 +1266,16 @@ static void pch_spi_process_messages(struct work_struct *pwork) char *save_rx_buf = data->cur_trans->rx_buf; for (i = 0; i < cnt; i ++) { pch_spi_handle_dma(data, &bpw); - if (!pch_spi_start_transfer(data)) + if (!pch_spi_start_transfer(data)) { + data->transfer_complete = true; + data->current_msg->status = -EIO; + data->current_msg->complete + (data->current_msg->context); + data->bcurrent_msg_processing = false; + data->current_msg = NULL; + data->cur_trans = NULL; goto out; + } pch_spi_copy_rx_data_for_dma(data, bpw); } data->cur_trans->rx_buf = save_rx_buf; -- cgit v1.2.3