diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2013-11-12 10:37:46 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2013-11-25 11:54:06 -0500 |
commit | d373a8534d5e1e7a350e40d3c11961a7cd8d530b (patch) | |
tree | bcfb4d9f9c9e5a228216a3bb1f5ec0525eecab81 /drivers/usb/musb | |
parent | 37cfbc42887fbd4ff0f4c520c9f3fdea9e6f2a82 (diff) |
usb: musb: musb_cppi41: factor most of cppi41_dma_callback() into cppi41_trans_done()
This patch moves most of the logic in cppi41_dma_callback() into
cppi41_trans_done() where it can be called from another function.
Instead of computing "transferred" (the number of bytes transferred in
the last transaction) in cppi41_trans_done() the member
"cppi41_channel->prog_len" is now set to 0 if the transfer as a whole
can be considered as done. If it is != 0 then the next iteration is
assumed.
This is a preparation for a workaround.
Cc: stable@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r-- | drivers/usb/musb/musb_cppi41.c | 59 |
1 files changed, 36 insertions, 23 deletions
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index ff9d6de2b746..83a8a1d125ac 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c | |||
@@ -96,31 +96,15 @@ static void update_rx_toggle(struct cppi41_dma_channel *cppi41_channel) | |||
96 | cppi41_channel->usb_toggle = toggle; | 96 | cppi41_channel->usb_toggle = toggle; |
97 | } | 97 | } |
98 | 98 | ||
99 | static void cppi41_dma_callback(void *private_data) | 99 | static void cppi41_dma_callback(void *private_data); |
100 | |||
101 | static void cppi41_trans_done(struct dma_channel *channel) | ||
100 | { | 102 | { |
101 | struct dma_channel *channel = private_data; | ||
102 | struct cppi41_dma_channel *cppi41_channel = channel->private_data; | 103 | struct cppi41_dma_channel *cppi41_channel = channel->private_data; |
103 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; | 104 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; |
104 | struct musb *musb = hw_ep->musb; | 105 | struct musb *musb = hw_ep->musb; |
105 | unsigned long flags; | ||
106 | struct dma_tx_state txstate; | ||
107 | u32 transferred; | ||
108 | 106 | ||
109 | spin_lock_irqsave(&musb->lock, flags); | 107 | if (!cppi41_channel->prog_len) { |
110 | |||
111 | dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie, | ||
112 | &txstate); | ||
113 | transferred = cppi41_channel->prog_len - txstate.residue; | ||
114 | cppi41_channel->transferred += transferred; | ||
115 | |||
116 | dev_dbg(musb->controller, "DMA transfer done on hw_ep=%d bytes=%d/%d\n", | ||
117 | hw_ep->epnum, cppi41_channel->transferred, | ||
118 | cppi41_channel->total_len); | ||
119 | |||
120 | update_rx_toggle(cppi41_channel); | ||
121 | |||
122 | if (cppi41_channel->transferred == cppi41_channel->total_len || | ||
123 | transferred < cppi41_channel->packet_sz) { | ||
124 | 108 | ||
125 | /* done, complete */ | 109 | /* done, complete */ |
126 | cppi41_channel->channel.actual_len = | 110 | cppi41_channel->channel.actual_len = |
@@ -150,10 +134,8 @@ static void cppi41_dma_callback(void *private_data) | |||
150 | remain_bytes, | 134 | remain_bytes, |
151 | direction, | 135 | direction, |
152 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 136 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
153 | if (WARN_ON(!dma_desc)) { | 137 | if (WARN_ON(!dma_desc)) |
154 | spin_unlock_irqrestore(&musb->lock, flags); | ||
155 | return; | 138 | return; |
156 | } | ||
157 | 139 | ||
158 | dma_desc->callback = cppi41_dma_callback; | 140 | dma_desc->callback = cppi41_dma_callback; |
159 | dma_desc->callback_param = channel; | 141 | dma_desc->callback_param = channel; |
@@ -166,6 +148,37 @@ static void cppi41_dma_callback(void *private_data) | |||
166 | musb_writew(epio, MUSB_RXCSR, csr); | 148 | musb_writew(epio, MUSB_RXCSR, csr); |
167 | } | 149 | } |
168 | } | 150 | } |
151 | } | ||
152 | |||
153 | static void cppi41_dma_callback(void *private_data) | ||
154 | { | ||
155 | struct dma_channel *channel = private_data; | ||
156 | struct cppi41_dma_channel *cppi41_channel = channel->private_data; | ||
157 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; | ||
158 | struct musb *musb = hw_ep->musb; | ||
159 | unsigned long flags; | ||
160 | struct dma_tx_state txstate; | ||
161 | u32 transferred; | ||
162 | |||
163 | spin_lock_irqsave(&musb->lock, flags); | ||
164 | |||
165 | dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie, | ||
166 | &txstate); | ||
167 | transferred = cppi41_channel->prog_len - txstate.residue; | ||
168 | cppi41_channel->transferred += transferred; | ||
169 | |||
170 | dev_dbg(musb->controller, "DMA transfer done on hw_ep=%d bytes=%d/%d\n", | ||
171 | hw_ep->epnum, cppi41_channel->transferred, | ||
172 | cppi41_channel->total_len); | ||
173 | |||
174 | update_rx_toggle(cppi41_channel); | ||
175 | |||
176 | if (cppi41_channel->transferred == cppi41_channel->total_len || | ||
177 | transferred < cppi41_channel->packet_sz) | ||
178 | cppi41_channel->prog_len = 0; | ||
179 | |||
180 | cppi41_trans_done(channel); | ||
181 | |||
169 | spin_unlock_irqrestore(&musb->lock, flags); | 182 | spin_unlock_irqrestore(&musb->lock, flags); |
170 | } | 183 | } |
171 | 184 | ||