mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Ben Hutchings <ben@decadent.org.uk>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: torvalds@linux-foundation.org, akpm@linux-foundation.org,
	alan@lxorguk.ukuu.org.uk, Tomoya MORINAGA <tomoya.rohm@gmail.com>,
	Grant Likely <grant.likely@secretlab.ca>
Subject: [ 33/53] spi-topcliff-pch: Fix issue for transmitting over 4KByte
Date: Fri, 18 May 2012 03:33:27 +0100	[thread overview]
Message-ID: <20120518023258.848665132@decadent.org.uk> (raw)
In-Reply-To: <20120518023254.339945758@decadent.org.uk>

3.2.18-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Tomoya MORINAGA <tomoya.rohm@gmail.com>

commit 7d05b3e868ee0f9231baf40cb77be3df5dd1f18c upstream.

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 <tomoya.rohm@gmail.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
 drivers/spi/spi-topcliff-pch.c |   66 +++++++++++++++++++++++++++++++++-------
 1 file changed, 55 insertions(+), 11 deletions(-)

diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c
index 4b32fd7..4fdb83a 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,
-- 
1.7.10




  parent reply	other threads:[~2012-05-18  2:55 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-05-18  2:32 [ 00/53] 3.2.18-stable review Ben Hutchings
2012-05-18  2:32 ` [ 01/53] regulator: Fix the logic to ensure new voltage setting in valid range Ben Hutchings
2012-05-18  2:32 ` [ 02/53] ARM: OMAP: Revert "ARM: OMAP: ctrl: Fix CONTROL_DSIPHY register fields" Ben Hutchings
2012-05-18  2:32 ` [ 03/53] ALSA: echoaudio: Remove incorrect part of assertion Ben Hutchings
2012-05-18  2:32 ` [ 04/53] ARM: orion5x: Fix GPIO enable bits for MPP9 Ben Hutchings
2012-05-18  2:32 ` [ 05/53] ALSA: HDA: Lessen CPU usage when waiting for chip to respond Ben Hutchings
2012-05-18  2:33 ` [ 06/53] percpu: pcpu_embed_first_chunk() should free unused parts after all allocs are complete Ben Hutchings
2012-05-18  2:33 ` [ 07/53] hugetlb: prevent BUG_ON in hugetlb_fault() -> hugetlb_cow() Ben Hutchings
2012-05-18  2:33 ` [ 08/53] namespaces, pid_ns: fix leakage on fork() failure Ben Hutchings
2012-05-18  2:33 ` [ 09/53] mm: nobootmem: fix sign extend problem in __free_pages_memory() Ben Hutchings
2012-05-18  2:33 ` [ 10/53] asix: Fix tx transfer padding for full-speed USB Ben Hutchings
2012-05-18  2:33 ` [ 11/53] netem: fix possible skb leak Ben Hutchings
2012-05-18  2:33 ` [ 12/53] net: In unregister_netdevice_notifier unregister the netdevices Ben Hutchings
2012-05-18  5:09   ` Herton Ronaldo Krzesinski
2012-05-18  5:41     ` David Miller
2012-05-19  0:31       ` Ben Hutchings
2012-05-19  3:43         ` David Miller
2012-05-18  2:33 ` [ 13/53] net: l2tp: unlock socket lock before returning from l2tp_ip_sendmsg Ben Hutchings
2012-05-18  2:33 ` [ 14/53] sky2: propogate rx hash when packet is copied Ben Hutchings
2012-05-18  2:33 ` [ 15/53] sky2: fix receive length error in mixed non-VLAN/VLAN traffic Ben Hutchings
2012-05-18  2:33 ` [ 16/53] sungem: Fix WakeOnLan Ben Hutchings
2012-05-18  2:33 ` [ 17/53] tg3: Avoid panic from reserved statblk field access Ben Hutchings
2012-05-18  2:33 ` [ 18/53] tcp: fix infinite cwnd in tcp_complete_cwr() Ben Hutchings
2012-05-18  2:33 ` [ 19/53] tcp: change tcp_adv_win_scale and tcp_rmem[2] Ben Hutchings
2012-05-18  2:33 ` [ 20/53] brcm80211: smac: pass missing argument to brcms_b_mute Ben Hutchings
2012-05-18  2:33 ` [ 21/53] phy:icplus:fix Auto Power Saving in ip101a_config_init Ben Hutchings
2012-05-18  2:33 ` [ 22/53] NFSv4: Revalidate uid/gid after open Ben Hutchings
2012-05-18  2:33 ` [ 23/53] target: Drop incorrect se_lun_acl release for dynamic -> explict ACL conversion Ben Hutchings
2012-05-18  2:33 ` [ 24/53] [media] marvell-cam: fix an ARM build error Ben Hutchings
2012-05-18  2:33 ` [ 25/53] [media] rc: Postpone ISR registration Ben Hutchings
2012-05-18  2:33 ` [ 26/53] cdc_ether: Ignore bogus union descriptor for RNDIS devices Ben Hutchings
2012-05-18  2:33 ` [ 27/53] jffs2: Fix lock acquisition order bug in gc path Ben Hutchings
2012-05-18  2:33 ` [ 28/53] [media] s5p-fimc: Fix locking in subdev set_crop op Ben Hutchings
2012-05-18  2:33 ` [ 29/53] dm mpath: check if scsi_dh module already loaded before trying to load Ben Hutchings
2012-05-18  2:33 ` [ 30/53] sparc64: Do not clobber %g2 in xcall_fetch_glob_regs() Ben Hutchings
2012-05-18  2:33 ` [ 31/53] gpio: Add missing spin_lock_init in gpio-ml-ioh driver Ben Hutchings
2012-05-18  2:33 ` [ 32/53] spi-topcliff-pch: Modify pci-bus number dynamically to get DMA device info Ben Hutchings
2012-05-18  2:33 ` Ben Hutchings [this message]
2012-05-18  2:33 ` [ 34/53] spi-topcliff-pch: supports a spi mode setup and bit order setup by IO control Ben Hutchings
2012-05-18  2:33 ` [ 35/53] spi-topcliff-pch: add recovery processing in case wait-event timeout Ben Hutchings
2012-05-18  2:33 ` [ 36/53] ext4: avoid deadlock on sync-mounted FS w/o journal Ben Hutchings
2012-05-18  2:33 ` [ 37/53] ia64: Add accept4() syscall Ben Hutchings
2012-05-18  2:33 ` [ 38/53] brcm80211: smac: fix endless retry of A-MPDU transmissions Ben Hutchings
2012-05-18  2:33 ` [ 39/53] ARM: 7417/1: vfp: ensure preemption is disabled when enabling VFP access Ben Hutchings
2012-05-18  2:33 ` [ 40/53] target: Fix SPC-2 RELEASE bug for multi-session iSCSI client setups Ben Hutchings
2012-05-18  2:33 ` [ 41/53] crypto: mv_cesa requires on CRYPTO_HASH to build Ben Hutchings
2012-05-18  2:33 ` [ 42/53] ALSA: hda/idt - Fix power-map for speaker-pins with some HP laptops Ben Hutchings
2012-05-18  2:33 ` [ 43/53] ASoC: wm8994: Fix AIF2ADC power down Ben Hutchings
2012-05-18  2:33 ` [ 44/53] usbnet: fix skb traversing races during unlink(v2) Ben Hutchings
2012-05-18  2:33 ` [ 45/53] cdc_ether: add Novatel USB551L device IDs for FLAG_WWAN Ben Hutchings
2012-05-18  2:33 ` [ 46/53] ARM: prevent VM_GROWSDOWN mmaps extending below FIRST_USER_ADDRESS Ben Hutchings
2012-05-18  2:33 ` [ 47/53] arch/tile: apply commit 74fca9da0 to the compat signal handling as well Ben Hutchings
2012-05-18  2:33 ` [ 48/53] MD: Add del_timer_sync to mddev_suspend (fix nasty panic) Ben Hutchings
2012-05-18  2:33 ` [ 49/53] target: Fix bug in handling of FILEIO + block_device resize ops Ben Hutchings
2012-05-18  2:33 ` [ 50/53] tcp: do_tcp_sendpages() must try to push data out on oom conditions Ben Hutchings
2012-05-18  2:33 ` [ 51/53] e1000: Prevent reset task killing itself Ben Hutchings
2012-05-18  2:33 ` [ 52/53] mtd: map.h: fix arm cross-build failure Ben Hutchings
2012-05-18  2:33 ` [ 53/53] stmmac: Fix compilation error in mmc_core.c Ben Hutchings
2012-05-18 14:46 ` [ 00/53] 3.2.18-stable review Steven Rostedt
2012-05-18 18:22   ` Greg KH
2012-05-18 22:00     ` Ben Hutchings
2012-05-18 22:04       ` Willy Tarreau
2012-05-19  0:48       ` Steven Rostedt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120518023258.848665132@decadent.org.uk \
    --to=ben@decadent.org.uk \
    --cc=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=grant.likely@secretlab.ca \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tomoya.rohm@gmail.com \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome