aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/musbhsdma.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2010-11-16 10:44:50 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2010-11-16 10:44:50 -0800
commit491acf0032c08a74a4c88032ca1c03b498bfec37 (patch)
treeb7194d3afb144fa007d0ca6a11c96297f36d42f8 /drivers/usb/musb/musbhsdma.c
parent06fc8846a2c0ddcc51e6666a78fc29a8e749ca3b (diff)
parente53beacd23d9cb47590da6a7a7f6d417b941a994 (diff)
downloadkernel_samsung_smdk4412-491acf0032c08a74a4c88032ca1c03b498bfec37.zip
kernel_samsung_smdk4412-491acf0032c08a74a4c88032ca1c03b498bfec37.tar.gz
kernel_samsung_smdk4412-491acf0032c08a74a4c88032ca1c03b498bfec37.tar.bz2
Staging: Merge 2.6.37-rc2 into staging-next
This was necessary in order to resolve some conflicts that happened between -rc1 and -rc2 with the following files: drivers/staging/bcm/Bcmchar.c drivers/staging/intel_sst/intel_sst_app_interface.c All should be resolved now. Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/musb/musbhsdma.c')
-rw-r--r--drivers/usb/musb/musbhsdma.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
index 6f771af..563114d 100644
--- a/drivers/usb/musb/musbhsdma.c
+++ b/drivers/usb/musb/musbhsdma.c
@@ -158,6 +158,8 @@ static int dma_channel_program(struct dma_channel *channel,
dma_addr_t dma_addr, u32 len)
{
struct musb_dma_channel *musb_channel = channel->private_data;
+ struct musb_dma_controller *controller = musb_channel->controller;
+ struct musb *musb = controller->private_data;
DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n",
musb_channel->epnum,
@@ -167,6 +169,18 @@ static int dma_channel_program(struct dma_channel *channel,
BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN ||
channel->status == MUSB_DMA_STATUS_BUSY);
+ /*
+ * The DMA engine in RTL1.8 and above cannot handle
+ * DMA addresses that are not aligned to a 4 byte boundary.
+ * It ends up masking the last two bits of the address
+ * programmed in DMA_ADDR.
+ *
+ * Fail such DMA transfers, so that the backup PIO mode
+ * can carry out the transfer
+ */
+ if ((musb->hwvers >= MUSB_HWVERS_1800) && (dma_addr % 4))
+ return false;
+
channel->actual_len = 0;
musb_channel->start_addr = dma_addr;
musb_channel->len = len;