From: Greg KH <gregkh@linuxfoundation.org>
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: [ 43/47] spi-topcliff-pch: Fix issue for transmitting over 4KByte
Date: Fri, 18 May 2012 14:27:32 -0700 [thread overview]
Message-ID: <20120518212653.093913025@linuxfoundation.org> (raw)
In-Reply-To: <20120518212701.GA5023@kroah.com>
3.3-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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/spi/spi-topcliff-pch.c | 66 ++++++++++++++++++++++++++++++++++-------
1 file changed, 55 insertions(+), 11 deletions(-)
--- 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
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
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 pc
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 pc
}
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 pc
*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 pc
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 pc
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(str
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(str
}
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(str
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,
next prev parent reply other threads:[~2012-05-18 23:09 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-18 21:27 [ 00/47] 3.3.7-stable review Greg KH
2012-05-18 21:26 ` [ 01/47] ALSA: echoaudio: Remove incorrect part of assertion Greg KH
2012-05-18 21:26 ` [ 02/47] ALSA: HDA: Lessen CPU usage when waiting for chip to respond Greg KH
2012-05-18 21:26 ` [ 03/47] ALSA: hda/realtek - Add missing CD-input pin for MSI-7350 mobo Greg KH
2012-05-18 21:26 ` [ 04/47] ALSA: hda/idt - Fix power-map for speaker-pins with some HP laptops Greg KH
2012-05-18 21:26 ` [ 05/47] usbnet: fix skb traversing races during unlink(v2) Greg KH
2012-05-18 21:26 ` [ 06/47] namespaces, pid_ns: fix leakage on fork() failure Greg KH
2012-05-18 21:26 ` [ 07/47] sparc64: Do not clobber %g2 in xcall_fetch_glob_regs() Greg KH
2012-05-18 21:26 ` [ 08/47] media: marvell-cam: fix an ARM build error Greg KH
2012-05-18 21:26 ` [ 09/47] ARM: 7417/1: vfp: ensure preemption is disabled when enabling VFP access Greg KH
2012-05-18 21:26 ` [ 10/47] ARM: prevent VM_GROWSDOWN mmaps extending below FIRST_USER_ADDRESS Greg KH
2012-05-18 21:27 ` [ 11/47] media: s5p-fimc: Fix locking in subdev set_crop op Greg KH
2012-05-18 21:27 ` [ 12/47] media: rc: Postpone ISR registration Greg KH
2012-05-18 21:27 ` [ 13/47] media: dvb_frontend: fix a regression with DVB-S zig-zag Greg KH
2012-05-18 21:27 ` [ 14/47] ASoC: cs42l73: Sync digital mixer kcontrols to allow for 0dB Greg KH
2012-05-18 21:27 ` [ 15/47] ASoC: wm8994: Fix AIF2ADC power down Greg KH
2012-05-18 21:27 ` [ 16/47] cdc_ether: Ignore bogus union descriptor for RNDIS devices Greg KH
2012-05-18 21:27 ` [ 17/47] cdc_ether: add Novatel USB551L device IDs for FLAG_WWAN Greg KH
2012-05-18 21:27 ` [ 18/47] percpu: pcpu_embed_first_chunk() should free unused parts after all allocs are complete Greg KH
2012-05-18 21:27 ` [ 19/47] kmemleak: Fix the kmemleak tracking of the percpu areas with !SMP Greg KH
2012-05-18 21:27 ` [ 20/47] mtd: fix oops in dataflash driver Greg KH
2012-05-18 21:27 ` [ 21/47] hugetlb: prevent BUG_ON in hugetlb_fault() -> hugetlb_cow() Greg KH
2012-05-18 21:27 ` [ 22/47] mm: nobootmem: fix sign extend problem in __free_pages_memory() Greg KH
2012-05-18 21:27 ` [ 23/47] jffs2: Fix lock acquisition order bug in gc path Greg KH
2012-05-18 21:27 ` [ 24/47] arch/tile: apply commit 74fca9da0 to the compat signal handling as well Greg KH
2012-05-18 21:27 ` [ 25/47] crypto: mv_cesa requires on CRYPTO_HASH to build Greg KH
2012-05-18 21:27 ` [ 26/47] target: Drop incorrect se_lun_acl release for dynamic -> explict ACL conversion Greg KH
2012-05-18 21:27 ` [ 27/47] target: Fix SPC-2 RELEASE bug for multi-session iSCSI client setups Greg KH
2012-05-18 21:27 ` [ 28/47] target: Fix bug in handling of FILEIO + block_device resize ops Greg KH
2012-05-18 21:27 ` [ 29/47] virtio: console: tell host of open ports after resume from s3/s4 Greg KH
2012-05-18 21:27 ` [ 30/47] dm mpath: check if scsi_dh module already loaded before trying to load Greg KH
2012-05-18 21:27 ` [ 31/47] e1000: Prevent reset task killing itself Greg KH
2012-05-18 21:27 ` [ 32/47] MD: Add del_timer_sync to mddev_suspend (fix nasty panic) Greg KH
2012-05-18 21:27 ` [ 33/47] tcp: do_tcp_sendpages() must try to push data out on oom conditions Greg KH
2012-05-18 21:27 ` [ 34/47] init: dont try mounting device as nfs root unless type fully matches Greg KH
2012-05-18 21:27 ` [ 35/47] ext4: avoid deadlock on sync-mounted FS w/o journal Greg KH
2012-05-18 21:27 ` [ 36/47] memcg: free spare array to avoid memory leak Greg KH
2012-05-18 21:27 ` [ 37/47] cifs: fix revalidation test in cifs_llseek() Greg KH
2012-05-18 21:27 ` [ 38/47] compat: Fix RT signal mask corruption via sigprocmask Greg KH
2012-05-18 21:27 ` [ 39/47] dl2k: Clean up rio_ioctl Greg KH
2012-05-18 21:27 ` [ 40/47] OMAPDSS: VENC: fix NULL pointer dereference in DSS2 VENC sysfs debug attr on OMAP4 Greg KH
2012-05-18 21:27 ` [ 41/47] i2c-eg20t: change timeout value 50msec to 1000msec Greg KH
2012-05-18 21:27 ` [ 42/47] spi-topcliff-pch: Modify pci-bus number dynamically to get DMA device info Greg KH
2012-05-18 21:27 ` Greg KH [this message]
2012-05-18 21:27 ` [ 44/47] spi-topcliff-pch: supports a spi mode setup and bit order setup by IO control Greg KH
2012-05-18 21:27 ` [ 45/47] spi-topcliff-pch: add recovery processing in case wait-event timeout Greg KH
2012-05-18 21:27 ` [ 46/47] Avoid beyond bounds copy while caching ACL Greg KH
2012-05-18 21:27 ` [ 47/47] Avoid reading past buffer when calling GETACL Greg KH
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=20120518212653.093913025@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.