aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/musbhsdma.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/usb/musb/musbhsdma.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/usb/musb/musbhsdma.c')
-rw-r--r--drivers/usb/musb/musbhsdma.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
index 6dc107f25245..f70c5a577736 100644
--- a/drivers/usb/musb/musbhsdma.c
+++ b/drivers/usb/musb/musbhsdma.c
@@ -91,7 +91,7 @@ static struct dma_channel *dma_channel_allocate(struct dma_controller *c,
91 channel = &(musb_channel->channel); 91 channel = &(musb_channel->channel);
92 channel->private_data = musb_channel; 92 channel->private_data = musb_channel;
93 channel->status = MUSB_DMA_STATUS_FREE; 93 channel->status = MUSB_DMA_STATUS_FREE;
94 channel->max_len = 0x10000; 94 channel->max_len = 0x100000;
95 /* Tx => mode 1; Rx => mode 0 */ 95 /* Tx => mode 1; Rx => mode 0 */
96 channel->desired_mode = transmit; 96 channel->desired_mode = transmit;
97 channel->actual_len = 0; 97 channel->actual_len = 0;
@@ -122,11 +122,12 @@ static void configure_channel(struct dma_channel *channel,
122{ 122{
123 struct musb_dma_channel *musb_channel = channel->private_data; 123 struct musb_dma_channel *musb_channel = channel->private_data;
124 struct musb_dma_controller *controller = musb_channel->controller; 124 struct musb_dma_controller *controller = musb_channel->controller;
125 struct musb *musb = controller->private_data;
125 void __iomem *mbase = controller->base; 126 void __iomem *mbase = controller->base;
126 u8 bchannel = musb_channel->idx; 127 u8 bchannel = musb_channel->idx;
127 u16 csr = 0; 128 u16 csr = 0;
128 129
129 DBG(4, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n", 130 dev_dbg(musb->controller, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
130 channel, packet_sz, dma_addr, len, mode); 131 channel, packet_sz, dma_addr, len, mode);
131 132
132 if (mode) { 133 if (mode) {
@@ -158,8 +159,10 @@ static int dma_channel_program(struct dma_channel *channel,
158 dma_addr_t dma_addr, u32 len) 159 dma_addr_t dma_addr, u32 len)
159{ 160{
160 struct musb_dma_channel *musb_channel = channel->private_data; 161 struct musb_dma_channel *musb_channel = channel->private_data;
162 struct musb_dma_controller *controller = musb_channel->controller;
163 struct musb *musb = controller->private_data;
161 164
162 DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n", 165 dev_dbg(musb->controller, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n",
163 musb_channel->epnum, 166 musb_channel->epnum,
164 musb_channel->transmit ? "Tx" : "Rx", 167 musb_channel->transmit ? "Tx" : "Rx",
165 packet_sz, dma_addr, len, mode); 168 packet_sz, dma_addr, len, mode);
@@ -167,6 +170,26 @@ static int dma_channel_program(struct dma_channel *channel,
167 BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN || 170 BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN ||
168 channel->status == MUSB_DMA_STATUS_BUSY); 171 channel->status == MUSB_DMA_STATUS_BUSY);
169 172
173 /* Let targets check/tweak the arguments */
174 if (musb->ops->adjust_channel_params) {
175 int ret = musb->ops->adjust_channel_params(channel,
176 packet_sz, &mode, &dma_addr, &len);
177 if (ret)
178 return ret;
179 }
180
181 /*
182 * The DMA engine in RTL1.8 and above cannot handle
183 * DMA addresses that are not aligned to a 4 byte boundary.
184 * It ends up masking the last two bits of the address
185 * programmed in DMA_ADDR.
186 *
187 * Fail such DMA transfers, so that the backup PIO mode
188 * can carry out the transfer
189 */
190 if ((musb->hwvers >= MUSB_HWVERS_1800) && (dma_addr % 4))
191 return false;
192
170 channel->actual_len = 0; 193 channel->actual_len = 0;
171 musb_channel->start_addr = dma_addr; 194 musb_channel->start_addr = dma_addr;
172 musb_channel->len = len; 195 musb_channel->len = len;
@@ -252,7 +275,7 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data)
252#endif 275#endif
253 276
254 if (!int_hsdma) { 277 if (!int_hsdma) {
255 DBG(2, "spurious DMA irq\n"); 278 dev_dbg(musb->controller, "spurious DMA irq\n");
256 279
257 for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) { 280 for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) {
258 musb_channel = (struct musb_dma_channel *) 281 musb_channel = (struct musb_dma_channel *)
@@ -266,7 +289,7 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data)
266 } 289 }
267 } 290 }
268 291
269 DBG(2, "int_hsdma = 0x%x\n", int_hsdma); 292 dev_dbg(musb->controller, "int_hsdma = 0x%x\n", int_hsdma);
270 293
271 if (!int_hsdma) 294 if (!int_hsdma)
272 goto done; 295 goto done;
@@ -293,7 +316,7 @@ static irqreturn_t dma_controller_irq(int irq, void *private_data)
293 channel->actual_len = addr 316 channel->actual_len = addr
294 - musb_channel->start_addr; 317 - musb_channel->start_addr;
295 318
296 DBG(2, "ch %p, 0x%x -> 0x%x (%zu / %d) %s\n", 319 dev_dbg(musb->controller, "ch %p, 0x%x -> 0x%x (%zu / %d) %s\n",
297 channel, musb_channel->start_addr, 320 channel, musb_channel->start_addr,
298 addr, channel->actual_len, 321 addr, channel->actual_len,
299 musb_channel->len, 322 musb_channel->len,
@@ -363,7 +386,7 @@ dma_controller_create(struct musb *musb, void __iomem *base)
363 struct musb_dma_controller *controller; 386 struct musb_dma_controller *controller;
364 struct device *dev = musb->controller; 387 struct device *dev = musb->controller;
365 struct platform_device *pdev = to_platform_device(dev); 388 struct platform_device *pdev = to_platform_device(dev);
366 int irq = platform_get_irq(pdev, 1); 389 int irq = platform_get_irq_byname(pdev, "dma");
367 390
368 if (irq == 0) { 391 if (irq == 0) {
369 dev_err(dev, "No DMA interrupt line!\n"); 392 dev_err(dev, "No DMA interrupt line!\n");