musbhsdma.c revision 6e16edfe62eb49274c8a74dc04d1c6f315f8f82b
1550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi/*
2550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * MUSB OTG driver - support for Mentor's DMA controller
3550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi *
4550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Copyright 2005 Mentor Graphics Corporation
5550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Copyright (C) 2005-2007 by Texas Instruments
6550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi *
7550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * This program is free software; you can redistribute it and/or
8550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * modify it under the terms of the GNU General Public License
9550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * version 2 as published by the Free Software Foundation.
10550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi *
11550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * This program is distributed in the hope that it will be useful, but
12550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * WITHOUT ANY WARRANTY; without even the implied warranty of
13550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * General Public License for more details.
15550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi *
16550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * You should have received a copy of the GNU General Public License
17550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * along with this program; if not, write to the Free Software
18550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * 02110-1301 USA
20550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi *
21550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
22550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
24550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi *
32550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi */
33550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#include <linux/device.h>
34550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#include <linux/interrupt.h>
35550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#include <linux/platform_device.h>
365a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
37550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#include "musb_core.h"
386995eb68aab70e79eedb710d7d6d1f22d8aea4a7Bryan Wu#include "musbhsdma.h"
39550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
40550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic int dma_controller_start(struct dma_controller *c)
41550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
42550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	/* nothing to do */
43550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	return 0;
44550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
45550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
46458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbistatic void dma_channel_release(struct dma_channel *channel);
47550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
48550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic int dma_controller_stop(struct dma_controller *c)
49550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
50458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_controller *controller = container_of(c,
51458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			struct musb_dma_controller, controller);
52458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb *musb = controller->private_data;
53458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct dma_channel *channel;
54458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 bit;
55550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
56458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	if (controller->used_channels != 0) {
57550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		dev_err(musb->controller,
58550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			"Stopping DMA controller while channel active\n");
59550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
60458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		for (bit = 0; bit < MUSB_HSDMA_CHANNELS; bit++) {
61458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			if (controller->used_channels & (1 << bit)) {
62458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				channel = &controller->channel[bit].channel;
63458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				dma_channel_release(channel);
64550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
65458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				if (!controller->used_channels)
66550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					break;
67550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			}
68550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		}
69550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
70458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
71550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	return 0;
72550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
73550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
74550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic struct dma_channel *dma_channel_allocate(struct dma_controller *c,
75550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				struct musb_hw_ep *hw_ep, u8 transmit)
76550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
77458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_controller *controller = container_of(c,
78458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			struct musb_dma_controller, controller);
79458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel = NULL;
80458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct dma_channel *channel = NULL;
81458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 bit;
82458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
83458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	for (bit = 0; bit < MUSB_HSDMA_CHANNELS; bit++) {
84458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		if (!(controller->used_channels & (1 << bit))) {
85458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			controller->used_channels |= (1 << bit);
86458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel = &(controller->channel[bit]);
87458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel->controller = controller;
88458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel->idx = bit;
89458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel->epnum = hw_ep->epnum;
90458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel->transmit = transmit;
91458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel = &(musb_channel->channel);
92458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel->private_data = musb_channel;
93458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel->status = MUSB_DMA_STATUS_FREE;
946587cc0f30cd2f27cf0677e470f18792925a23a4Anil Shetty			channel->max_len = 0x100000;
95550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			/* Tx => mode 1; Rx => mode 0 */
96458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel->desired_mode = transmit;
97458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel->actual_len = 0;
98550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			break;
99550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		}
100550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
101458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
102458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	return channel;
103550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
104550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
105458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbistatic void dma_channel_release(struct dma_channel *channel)
106550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
107458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel = channel->private_data;
108550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
109458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	channel->actual_len = 0;
110458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->start_addr = 0;
111458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->len = 0;
112550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
113458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->controller->used_channels &=
114458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		~(1 << musb_channel->idx);
115550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
116458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	channel->status = MUSB_DMA_STATUS_UNKNOWN;
117550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
118550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
119458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbistatic void configure_channel(struct dma_channel *channel,
120550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				u16 packet_sz, u8 mode,
121550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				dma_addr_t dma_addr, u32 len)
122550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
123458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel = channel->private_data;
124458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_controller *controller = musb_channel->controller;
125458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	void __iomem *mbase = controller->base;
126458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 bchannel = musb_channel->idx;
127550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	u16 csr = 0;
128550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
129550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	DBG(4, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
130458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel, packet_sz, dma_addr, len, mode);
131550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
132550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (mode) {
133550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		csr |= 1 << MUSB_HSDMA_MODE1_SHIFT;
134550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		BUG_ON(len < packet_sz);
135550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
136c0f1f8e38fda8e345cad9269c559b4f036378120Hema HK	csr |= MUSB_HSDMA_BURSTMODE_INCR16
137c0f1f8e38fda8e345cad9269c559b4f036378120Hema HK				<< MUSB_HSDMA_BURSTMODE_SHIFT;
138550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
139458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	csr |= (musb_channel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT)
140550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		| (1 << MUSB_HSDMA_ENABLE_SHIFT)
141550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		| (1 << MUSB_HSDMA_IRQENABLE_SHIFT)
142458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		| (musb_channel->transmit
143550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				? (1 << MUSB_HSDMA_TRANSMIT_SHIFT)
144550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				: 0);
145550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
146550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	/* address/count */
1476995eb68aab70e79eedb710d7d6d1f22d8aea4a7Bryan Wu	musb_write_hsdma_addr(mbase, bchannel, dma_addr);
1486995eb68aab70e79eedb710d7d6d1f22d8aea4a7Bryan Wu	musb_write_hsdma_count(mbase, bchannel, len);
149550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
150550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	/* control (this should start things) */
151550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	musb_writew(mbase,
152458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL),
153550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		csr);
154550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
155550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
156458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbistatic int dma_channel_program(struct dma_channel *channel,
157550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				u16 packet_sz, u8 mode,
158550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				dma_addr_t dma_addr, u32 len)
159550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
160458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel = channel->private_data;
1616e16edfe62eb49274c8a74dc04d1c6f315f8f82bAnand Gadiyar	struct musb_dma_controller *controller = musb_channel->controller;
1626e16edfe62eb49274c8a74dc04d1c6f315f8f82bAnand Gadiyar	struct musb *musb = controller->private_data;
163550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
164550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n",
165458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		musb_channel->epnum,
166458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		musb_channel->transmit ? "Tx" : "Rx",
167550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		packet_sz, dma_addr, len, mode);
168550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
169458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN ||
170458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		channel->status == MUSB_DMA_STATUS_BUSY);
171550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
1726e16edfe62eb49274c8a74dc04d1c6f315f8f82bAnand Gadiyar	/*
1736e16edfe62eb49274c8a74dc04d1c6f315f8f82bAnand Gadiyar	 * The DMA engine in RTL1.8 and above cannot handle
1746e16edfe62eb49274c8a74dc04d1c6f315f8f82bAnand Gadiyar	 * DMA addresses that are not aligned to a 4 byte boundary.
1756e16edfe62eb49274c8a74dc04d1c6f315f8f82bAnand Gadiyar	 * It ends up masking the last two bits of the address
1766e16edfe62eb49274c8a74dc04d1c6f315f8f82bAnand Gadiyar	 * programmed in DMA_ADDR.
1776e16edfe62eb49274c8a74dc04d1c6f315f8f82bAnand Gadiyar	 *
1786e16edfe62eb49274c8a74dc04d1c6f315f8f82bAnand Gadiyar	 * Fail such DMA transfers, so that the backup PIO mode
1796e16edfe62eb49274c8a74dc04d1c6f315f8f82bAnand Gadiyar	 * can carry out the transfer
1806e16edfe62eb49274c8a74dc04d1c6f315f8f82bAnand Gadiyar	 */
1816e16edfe62eb49274c8a74dc04d1c6f315f8f82bAnand Gadiyar	if ((musb->hwvers >= MUSB_HWVERS_1800) && (dma_addr % 4))
1826e16edfe62eb49274c8a74dc04d1c6f315f8f82bAnand Gadiyar		return false;
1836e16edfe62eb49274c8a74dc04d1c6f315f8f82bAnand Gadiyar
184458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	channel->actual_len = 0;
185458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->start_addr = dma_addr;
186458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->len = len;
187458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->max_packet_sz = packet_sz;
188458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	channel->status = MUSB_DMA_STATUS_BUSY;
189550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
1908ca47c8a7621835914c053caaec74e66147dd7dcAnand Gadiyar	configure_channel(channel, packet_sz, mode, dma_addr, len);
191550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
192550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	return true;
193550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
194550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
195458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbistatic int dma_channel_abort(struct dma_channel *channel)
196550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
197458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel = channel->private_data;
198458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	void __iomem *mbase = musb_channel->controller->base;
199458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
200458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 bchannel = musb_channel->idx;
201b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov	int offset;
202550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	u16 csr;
203550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
204458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	if (channel->status == MUSB_DMA_STATUS_BUSY) {
205458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		if (musb_channel->transmit) {
206b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			offset = MUSB_EP_OFFSET(musb_channel->epnum,
207b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov						MUSB_TXCSR);
208b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov
209b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			/*
210b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			 * The programming guide says that we must clear
211b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			 * the DMAENAB bit before the DMAMODE bit...
212b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			 */
213b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			csr = musb_readw(mbase, offset);
214b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB);
215b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			musb_writew(mbase, offset, csr);
216b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			csr &= ~MUSB_TXCSR_DMAMODE;
217b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			musb_writew(mbase, offset, csr);
218550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		} else {
219b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			offset = MUSB_EP_OFFSET(musb_channel->epnum,
220b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov						MUSB_RXCSR);
221b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov
222b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			csr = musb_readw(mbase, offset);
223550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			csr &= ~(MUSB_RXCSR_AUTOCLEAR |
224550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				 MUSB_RXCSR_DMAENAB |
225550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				 MUSB_RXCSR_DMAMODE);
226b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			musb_writew(mbase, offset, csr);
227550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		}
228550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
229550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		musb_writew(mbase,
230458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL),
231550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			0);
2326995eb68aab70e79eedb710d7d6d1f22d8aea4a7Bryan Wu		musb_write_hsdma_addr(mbase, bchannel, 0);
2336995eb68aab70e79eedb710d7d6d1f22d8aea4a7Bryan Wu		musb_write_hsdma_count(mbase, bchannel, 0);
234458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		channel->status = MUSB_DMA_STATUS_FREE;
235550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
236458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
237550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	return 0;
238550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
239550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
240550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic irqreturn_t dma_controller_irq(int irq, void *private_data)
241550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
242458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_controller *controller = private_data;
243458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb *musb = controller->private_data;
244458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel;
245458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct dma_channel *channel;
246458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
247458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	void __iomem *mbase = controller->base;
248458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
249550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	irqreturn_t retval = IRQ_NONE;
250458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
251550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	unsigned long flags;
252550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
253458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 bchannel;
254458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 int_hsdma;
255458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
256f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar	u32 addr, count;
257458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u16 csr;
258458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
259550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	spin_lock_irqsave(&musb->lock, flags);
260550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
261550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	int_hsdma = musb_readb(mbase, MUSB_HSDMA_INTR);
262550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
2636bd03e7b9d0f70928f9cd793326c28e4e08ffc96Cliff Cai#ifdef CONFIG_BLACKFIN
2646bd03e7b9d0f70928f9cd793326c28e4e08ffc96Cliff Cai	/* Clear DMA interrupt flags */
2656bd03e7b9d0f70928f9cd793326c28e4e08ffc96Cliff Cai	musb_writeb(mbase, MUSB_HSDMA_INTR, int_hsdma);
2666bd03e7b9d0f70928f9cd793326c28e4e08ffc96Cliff Cai#endif
2676bd03e7b9d0f70928f9cd793326c28e4e08ffc96Cliff Cai
268f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar	if (!int_hsdma) {
269f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar		DBG(2, "spurious DMA irq\n");
270f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar
271f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar		for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) {
272f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar			musb_channel = (struct musb_dma_channel *)
273f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar					&(controller->channel[bchannel]);
274f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar			channel = &musb_channel->channel;
275f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar			if (channel->status == MUSB_DMA_STATUS_BUSY) {
276f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar				count = musb_read_hsdma_count(mbase, bchannel);
277f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar
278f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar				if (count == 0)
279f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar					int_hsdma |= (1 << bchannel);
280f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar			}
281f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar		}
282f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar
283f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar		DBG(2, "int_hsdma = 0x%x\n", int_hsdma);
284f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar
285f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar		if (!int_hsdma)
286f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar			goto done;
287f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar	}
288f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar
289458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) {
290458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		if (int_hsdma & (1 << bchannel)) {
291458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel = (struct musb_dma_channel *)
292458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					&(controller->channel[bchannel]);
293458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel = &musb_channel->channel;
294550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
295550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			csr = musb_readw(mbase,
296458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					MUSB_HSDMA_CHANNEL_OFFSET(bchannel,
297550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi							MUSB_HSDMA_CONTROL));
298550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
299458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			if (csr & (1 << MUSB_HSDMA_BUSERROR_SHIFT)) {
300458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				musb_channel->channel.status =
301550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					MUSB_DMA_STATUS_BUS_ABORT;
302458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			} else {
303550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				u8 devctl;
304550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
3056995eb68aab70e79eedb710d7d6d1f22d8aea4a7Bryan Wu				addr = musb_read_hsdma_addr(mbase,
3066995eb68aab70e79eedb710d7d6d1f22d8aea4a7Bryan Wu						bchannel);
307458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				channel->actual_len = addr
308458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					- musb_channel->start_addr;
309550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
31032340d3f75dba732a0545173ac65aab6fc3d4952Mike Frysinger				DBG(2, "ch %p, 0x%x -> 0x%x (%zu / %d) %s\n",
311458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					channel, musb_channel->start_addr,
312458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					addr, channel->actual_len,
313458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					musb_channel->len,
314458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					(channel->actual_len
315458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi						< musb_channel->len) ?
316550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					"=> reconfig 0" : "=> complete");
317550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
318550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				devctl = musb_readb(mbase, MUSB_DEVCTL);
319550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
320458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				channel->status = MUSB_DMA_STATUS_FREE;
321550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
322550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				/* completed */
323550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				if ((devctl & MUSB_DEVCTL_HM)
324458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					&& (musb_channel->transmit)
325458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					&& ((channel->desired_mode == 0)
326458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					    || (channel->actual_len &
327458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					    (musb_channel->max_packet_sz - 1)))
328b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov				    ) {
329b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					u8  epnum  = musb_channel->epnum;
330b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					int offset = MUSB_EP_OFFSET(epnum,
331b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov								    MUSB_TXCSR);
332b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					u16 txcsr;
333b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov
334b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					/*
335b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					 * The programming guide says that we
336b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					 * must clear DMAENAB before DMAMODE.
337b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					 */
338b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					musb_ep_select(mbase, epnum);
339b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					txcsr = musb_readw(mbase, offset);
340b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					txcsr &= ~(MUSB_TXCSR_DMAENAB
341b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov							| MUSB_TXCSR_AUTOSET);
342b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					musb_writew(mbase, offset, txcsr);
343550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					/* Send out the packet */
344b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					txcsr &= ~MUSB_TXCSR_DMAMODE;
345b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					txcsr |=  MUSB_TXCSR_TXPKTRDY;
346b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					musb_writew(mbase, offset, txcsr);
347458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				}
348c7bbc056a92476b3b3d70a8df7cc746ac5d56de7Sergei Shtylyov				musb_dma_completion(musb, musb_channel->epnum,
349c7bbc056a92476b3b3d70a8df7cc746ac5d56de7Sergei Shtylyov						    musb_channel->transmit);
350550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			}
351550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		}
352550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
3536995eb68aab70e79eedb710d7d6d1f22d8aea4a7Bryan Wu
354550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	retval = IRQ_HANDLED;
355550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbidone:
356550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	spin_unlock_irqrestore(&musb->lock, flags);
357550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	return retval;
358550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
359550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
360550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbivoid dma_controller_destroy(struct dma_controller *c)
361550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
362458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_controller *controller = container_of(c,
363458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			struct musb_dma_controller, controller);
364550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
365550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (!controller)
366550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		return;
367550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
368550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (controller->irq)
369550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		free_irq(controller->irq, c);
370550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
371550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	kfree(controller);
372550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
373550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
374550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistruct dma_controller *__init
375458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbidma_controller_create(struct musb *musb, void __iomem *base)
376550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
377550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	struct musb_dma_controller *controller;
378550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	struct device *dev = musb->controller;
379550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	struct platform_device *pdev = to_platform_device(dev);
380550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	int irq = platform_get_irq(pdev, 1);
381550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
382550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (irq == 0) {
383550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		dev_err(dev, "No DMA interrupt line!\n");
384550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		return NULL;
385550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
386550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
387458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller = kzalloc(sizeof(*controller), GFP_KERNEL);
388550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (!controller)
389550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		return NULL;
390550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
391458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->channel_count = MUSB_HSDMA_CHANNELS;
392458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->private_data = musb;
393458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->base = base;
394550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
395458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.start = dma_controller_start;
396458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.stop = dma_controller_stop;
397458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.channel_alloc = dma_channel_allocate;
398458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.channel_release = dma_channel_release;
399458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.channel_program = dma_channel_program;
400458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.channel_abort = dma_channel_abort;
401550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
402550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (request_irq(irq, dma_controller_irq, IRQF_DISABLED,
403427c4f333474f5447f62387c1fb060e586c1a781Kay Sievers			dev_name(musb->controller), &controller->controller)) {
404550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		dev_err(dev, "request_irq %d failed!\n", irq);
405458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		dma_controller_destroy(&controller->controller);
406458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
407550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		return NULL;
408550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
409550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
410550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	controller->irq = irq;
411550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
412458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	return &controller->controller;
413550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
414