musbhsdma.c revision f933a0c0fe0ea5f49a35bcd45e3e4850e0606cba
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>
36550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#include "musb_core.h"
376995eb68aab70e79eedb710d7d6d1f22d8aea4a7Bryan Wu#include "musbhsdma.h"
38550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
39550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic int dma_controller_start(struct dma_controller *c)
40550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
41550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	/* nothing to do */
42550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	return 0;
43550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
44550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
45458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbistatic void dma_channel_release(struct dma_channel *channel);
46550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
47550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic int dma_controller_stop(struct dma_controller *c)
48550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
49458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_controller *controller = container_of(c,
50458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			struct musb_dma_controller, controller);
51458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb *musb = controller->private_data;
52458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct dma_channel *channel;
53458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 bit;
54550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
55458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	if (controller->used_channels != 0) {
56550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		dev_err(musb->controller,
57550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			"Stopping DMA controller while channel active\n");
58550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
59458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		for (bit = 0; bit < MUSB_HSDMA_CHANNELS; bit++) {
60458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			if (controller->used_channels & (1 << bit)) {
61458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				channel = &controller->channel[bit].channel;
62458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				dma_channel_release(channel);
63550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
64458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				if (!controller->used_channels)
65550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					break;
66550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			}
67550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		}
68550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
69458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
70550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	return 0;
71550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
72550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
73550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic struct dma_channel *dma_channel_allocate(struct dma_controller *c,
74550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				struct musb_hw_ep *hw_ep, u8 transmit)
75550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
76458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_controller *controller = container_of(c,
77458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			struct musb_dma_controller, controller);
78458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel = NULL;
79458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct dma_channel *channel = NULL;
80458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 bit;
81458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
82458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	for (bit = 0; bit < MUSB_HSDMA_CHANNELS; bit++) {
83458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		if (!(controller->used_channels & (1 << bit))) {
84458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			controller->used_channels |= (1 << bit);
85458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel = &(controller->channel[bit]);
86458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel->controller = controller;
87458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel->idx = bit;
88458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel->epnum = hw_ep->epnum;
89458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel->transmit = transmit;
90458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel = &(musb_channel->channel);
91458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel->private_data = musb_channel;
92458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel->status = MUSB_DMA_STATUS_FREE;
93458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel->max_len = 0x10000;
94550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			/* Tx => mode 1; Rx => mode 0 */
95458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel->desired_mode = transmit;
96458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel->actual_len = 0;
97550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			break;
98550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		}
99550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
100458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
101458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	return channel;
102550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
103550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
104458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbistatic void dma_channel_release(struct dma_channel *channel)
105550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
106458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel = channel->private_data;
107550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
108458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	channel->actual_len = 0;
109458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->start_addr = 0;
110458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->len = 0;
111550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
112458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->controller->used_channels &=
113458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		~(1 << musb_channel->idx);
114550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
115458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	channel->status = MUSB_DMA_STATUS_UNKNOWN;
116550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
117550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
118458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbistatic void configure_channel(struct dma_channel *channel,
119550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				u16 packet_sz, u8 mode,
120550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				dma_addr_t dma_addr, u32 len)
121550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
122458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel = channel->private_data;
123458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_controller *controller = musb_channel->controller;
124458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	void __iomem *mbase = controller->base;
125458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 bchannel = musb_channel->idx;
126550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	u16 csr = 0;
127550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
128550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	DBG(4, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
129458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel, packet_sz, dma_addr, len, mode);
130550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
131550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (mode) {
132550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		csr |= 1 << MUSB_HSDMA_MODE1_SHIFT;
133550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		BUG_ON(len < packet_sz);
134550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
135550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		if (packet_sz >= 64) {
136550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			csr |= MUSB_HSDMA_BURSTMODE_INCR16
137550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					<< MUSB_HSDMA_BURSTMODE_SHIFT;
138550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		} else if (packet_sz >= 32) {
139550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			csr |= MUSB_HSDMA_BURSTMODE_INCR8
140550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					<< MUSB_HSDMA_BURSTMODE_SHIFT;
141550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		} else if (packet_sz >= 16) {
142550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			csr |= MUSB_HSDMA_BURSTMODE_INCR4
143550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					<< MUSB_HSDMA_BURSTMODE_SHIFT;
144550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		}
145550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
146550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
147458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	csr |= (musb_channel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT)
148550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		| (1 << MUSB_HSDMA_ENABLE_SHIFT)
149550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		| (1 << MUSB_HSDMA_IRQENABLE_SHIFT)
150458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		| (musb_channel->transmit
151550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				? (1 << MUSB_HSDMA_TRANSMIT_SHIFT)
152550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				: 0);
153550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
154550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	/* address/count */
1556995eb68aab70e79eedb710d7d6d1f22d8aea4a7Bryan Wu	musb_write_hsdma_addr(mbase, bchannel, dma_addr);
1566995eb68aab70e79eedb710d7d6d1f22d8aea4a7Bryan Wu	musb_write_hsdma_count(mbase, bchannel, len);
157550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
158550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	/* control (this should start things) */
159550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	musb_writew(mbase,
160458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL),
161550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		csr);
162550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
163550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
164458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbistatic int dma_channel_program(struct dma_channel *channel,
165550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				u16 packet_sz, u8 mode,
166550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				dma_addr_t dma_addr, u32 len)
167550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
168458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel = channel->private_data;
169550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
170550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n",
171458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		musb_channel->epnum,
172458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		musb_channel->transmit ? "Tx" : "Rx",
173550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		packet_sz, dma_addr, len, mode);
174550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
175458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN ||
176458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		channel->status == MUSB_DMA_STATUS_BUSY);
177550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
178458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	channel->actual_len = 0;
179458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->start_addr = dma_addr;
180458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->len = len;
181458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->max_packet_sz = packet_sz;
182458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	channel->status = MUSB_DMA_STATUS_BUSY;
183550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
184550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if ((mode == 1) && (len >= packet_sz))
185458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		configure_channel(channel, packet_sz, 1, dma_addr, len);
186550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	else
187458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		configure_channel(channel, packet_sz, 0, dma_addr, len);
188550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
189550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	return true;
190550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
191550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
192458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbistatic int dma_channel_abort(struct dma_channel *channel)
193550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
194458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel = channel->private_data;
195458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	void __iomem *mbase = musb_channel->controller->base;
196458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
197458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 bchannel = musb_channel->idx;
198b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov	int offset;
199550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	u16 csr;
200550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
201458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	if (channel->status == MUSB_DMA_STATUS_BUSY) {
202458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		if (musb_channel->transmit) {
203b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			offset = MUSB_EP_OFFSET(musb_channel->epnum,
204b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov						MUSB_TXCSR);
205b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov
206b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			/*
207b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			 * The programming guide says that we must clear
208b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			 * the DMAENAB bit before the DMAMODE bit...
209b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			 */
210b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			csr = musb_readw(mbase, offset);
211b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB);
212b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			musb_writew(mbase, offset, csr);
213b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			csr &= ~MUSB_TXCSR_DMAMODE;
214b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			musb_writew(mbase, offset, csr);
215550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		} else {
216b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			offset = MUSB_EP_OFFSET(musb_channel->epnum,
217b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov						MUSB_RXCSR);
218b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov
219b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			csr = musb_readw(mbase, offset);
220550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			csr &= ~(MUSB_RXCSR_AUTOCLEAR |
221550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				 MUSB_RXCSR_DMAENAB |
222550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				 MUSB_RXCSR_DMAMODE);
223b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov			musb_writew(mbase, offset, csr);
224550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		}
225550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
226550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		musb_writew(mbase,
227458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL),
228550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			0);
2296995eb68aab70e79eedb710d7d6d1f22d8aea4a7Bryan Wu		musb_write_hsdma_addr(mbase, bchannel, 0);
2306995eb68aab70e79eedb710d7d6d1f22d8aea4a7Bryan Wu		musb_write_hsdma_count(mbase, bchannel, 0);
231458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		channel->status = MUSB_DMA_STATUS_FREE;
232550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
233458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
234550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	return 0;
235550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
236550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
237550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic irqreturn_t dma_controller_irq(int irq, void *private_data)
238550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
239458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_controller *controller = private_data;
240458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb *musb = controller->private_data;
241458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel;
242458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct dma_channel *channel;
243458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
244458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	void __iomem *mbase = controller->base;
245458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
246550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	irqreturn_t retval = IRQ_NONE;
247458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
248550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	unsigned long flags;
249550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
250458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 bchannel;
251458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 int_hsdma;
252458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
253f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar	u32 addr, count;
254458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u16 csr;
255458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
256550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	spin_lock_irqsave(&musb->lock, flags);
257550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
258550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	int_hsdma = musb_readb(mbase, MUSB_HSDMA_INTR);
259550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
2606bd03e7b9d0f70928f9cd793326c28e4e08ffc96Cliff Cai#ifdef CONFIG_BLACKFIN
2616bd03e7b9d0f70928f9cd793326c28e4e08ffc96Cliff Cai	/* Clear DMA interrupt flags */
2626bd03e7b9d0f70928f9cd793326c28e4e08ffc96Cliff Cai	musb_writeb(mbase, MUSB_HSDMA_INTR, int_hsdma);
2636bd03e7b9d0f70928f9cd793326c28e4e08ffc96Cliff Cai#endif
2646bd03e7b9d0f70928f9cd793326c28e4e08ffc96Cliff Cai
265f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar	if (!int_hsdma) {
266f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar		DBG(2, "spurious DMA irq\n");
267f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar
268f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar		for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) {
269f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar			musb_channel = (struct musb_dma_channel *)
270f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar					&(controller->channel[bchannel]);
271f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar			channel = &musb_channel->channel;
272f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar			if (channel->status == MUSB_DMA_STATUS_BUSY) {
273f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar				count = musb_read_hsdma_count(mbase, bchannel);
274f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar
275f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar				if (count == 0)
276f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar					int_hsdma |= (1 << bchannel);
277f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar			}
278f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar		}
279f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar
280f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar		DBG(2, "int_hsdma = 0x%x\n", int_hsdma);
281f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar
282f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar		if (!int_hsdma)
283f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar			goto done;
284f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar	}
285f933a0c0fe0ea5f49a35bcd45e3e4850e0606cbaAnand Gadiyar
286458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) {
287458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		if (int_hsdma & (1 << bchannel)) {
288458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel = (struct musb_dma_channel *)
289458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					&(controller->channel[bchannel]);
290458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel = &musb_channel->channel;
291550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
292550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			csr = musb_readw(mbase,
293458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					MUSB_HSDMA_CHANNEL_OFFSET(bchannel,
294550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi							MUSB_HSDMA_CONTROL));
295550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
296458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			if (csr & (1 << MUSB_HSDMA_BUSERROR_SHIFT)) {
297458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				musb_channel->channel.status =
298550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					MUSB_DMA_STATUS_BUS_ABORT;
299458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			} else {
300550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				u8 devctl;
301550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
3026995eb68aab70e79eedb710d7d6d1f22d8aea4a7Bryan Wu				addr = musb_read_hsdma_addr(mbase,
3036995eb68aab70e79eedb710d7d6d1f22d8aea4a7Bryan Wu						bchannel);
304458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				channel->actual_len = addr
305458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					- musb_channel->start_addr;
306550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
30732340d3f75dba732a0545173ac65aab6fc3d4952Mike Frysinger				DBG(2, "ch %p, 0x%x -> 0x%x (%zu / %d) %s\n",
308458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					channel, musb_channel->start_addr,
309458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					addr, channel->actual_len,
310458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					musb_channel->len,
311458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					(channel->actual_len
312458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi						< musb_channel->len) ?
313550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					"=> reconfig 0" : "=> complete");
314550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
315550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				devctl = musb_readb(mbase, MUSB_DEVCTL);
316550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
317458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				channel->status = MUSB_DMA_STATUS_FREE;
318550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
319550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				/* completed */
320550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				if ((devctl & MUSB_DEVCTL_HM)
321458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					&& (musb_channel->transmit)
322458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					&& ((channel->desired_mode == 0)
323458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					    || (channel->actual_len &
324458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					    (musb_channel->max_packet_sz - 1)))
325b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov				    ) {
326b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					u8  epnum  = musb_channel->epnum;
327b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					int offset = MUSB_EP_OFFSET(epnum,
328b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov								    MUSB_TXCSR);
329b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					u16 txcsr;
330b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov
331b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					/*
332b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					 * The programming guide says that we
333b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					 * must clear DMAENAB before DMAMODE.
334b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					 */
335b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					musb_ep_select(mbase, epnum);
336b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					txcsr = musb_readw(mbase, offset);
337b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					txcsr &= ~(MUSB_TXCSR_DMAENAB
338b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov							| MUSB_TXCSR_AUTOSET);
339b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					musb_writew(mbase, offset, txcsr);
340550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					/* Send out the packet */
341b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					txcsr &= ~MUSB_TXCSR_DMAMODE;
342b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					txcsr |=  MUSB_TXCSR_TXPKTRDY;
343b6e434a5404b9ce8c285ea081b6ea5c523b29db4Sergei Shtylyov					musb_writew(mbase, offset, txcsr);
344458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				}
345c7bbc056a92476b3b3d70a8df7cc746ac5d56de7Sergei Shtylyov				musb_dma_completion(musb, musb_channel->epnum,
346c7bbc056a92476b3b3d70a8df7cc746ac5d56de7Sergei Shtylyov						    musb_channel->transmit);
347550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			}
348550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		}
349550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
3506995eb68aab70e79eedb710d7d6d1f22d8aea4a7Bryan Wu
351550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	retval = IRQ_HANDLED;
352550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbidone:
353550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	spin_unlock_irqrestore(&musb->lock, flags);
354550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	return retval;
355550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
356550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
357550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbivoid dma_controller_destroy(struct dma_controller *c)
358550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
359458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_controller *controller = container_of(c,
360458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			struct musb_dma_controller, controller);
361550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
362550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (!controller)
363550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		return;
364550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
365550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (controller->irq)
366550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		free_irq(controller->irq, c);
367550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
368550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	kfree(controller);
369550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
370550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
371550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistruct dma_controller *__init
372458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbidma_controller_create(struct musb *musb, void __iomem *base)
373550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
374550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	struct musb_dma_controller *controller;
375550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	struct device *dev = musb->controller;
376550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	struct platform_device *pdev = to_platform_device(dev);
377550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	int irq = platform_get_irq(pdev, 1);
378550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
379550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (irq == 0) {
380550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		dev_err(dev, "No DMA interrupt line!\n");
381550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		return NULL;
382550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
383550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
384458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller = kzalloc(sizeof(*controller), GFP_KERNEL);
385550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (!controller)
386550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		return NULL;
387550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
388458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->channel_count = MUSB_HSDMA_CHANNELS;
389458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->private_data = musb;
390458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->base = base;
391550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
392458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.start = dma_controller_start;
393458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.stop = dma_controller_stop;
394458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.channel_alloc = dma_channel_allocate;
395458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.channel_release = dma_channel_release;
396458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.channel_program = dma_channel_program;
397458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.channel_abort = dma_channel_abort;
398550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
399550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (request_irq(irq, dma_controller_irq, IRQF_DISABLED,
400427c4f333474f5447f62387c1fb060e586c1a781Kay Sievers			dev_name(musb->controller), &controller->controller)) {
401550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		dev_err(dev, "request_irq %d failed!\n", irq);
402458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		dma_controller_destroy(&controller->controller);
403458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
404550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		return NULL;
405550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
406550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
407550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	controller->irq = irq;
408550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
409458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	return &controller->controller;
410550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
411