musbhsdma.c revision 427c4f333474f5447f62387c1fb060e586c1a781
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"
37550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
38550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
39550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#include "omap2430.h"
40550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#endif
41550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
42550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_BASE		0x200
43550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_INTR		(MUSB_HSDMA_BASE + 0)
44550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_CONTROL		0x4
45550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_ADDRESS		0x8
46550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_COUNT		0xc
47550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
48458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi#define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset)		\
49458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		(MUSB_HSDMA_BASE + (_bchannel << 4) + _offset)
50550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
51550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi/* control register (16-bit): */
52550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_ENABLE_SHIFT		0
53550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_TRANSMIT_SHIFT		1
54550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_MODE1_SHIFT		2
55550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_IRQENABLE_SHIFT		3
56550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_ENDPOINT_SHIFT		4
57550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_BUSERROR_SHIFT		8
58550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_BURSTMODE_SHIFT		9
59550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_BURSTMODE		(3 << MUSB_HSDMA_BURSTMODE_SHIFT)
60550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_BURSTMODE_UNSPEC	0
61550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_BURSTMODE_INCR4	1
62550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_BURSTMODE_INCR8	2
63550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_BURSTMODE_INCR16	3
64550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
65550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi#define MUSB_HSDMA_CHANNELS		8
66550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
67550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistruct musb_dma_controller;
68550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
69550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistruct musb_dma_channel {
70458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct dma_channel		channel;
71550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	struct musb_dma_controller	*controller;
72458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u32				start_addr;
73550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	u32				len;
74458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u16				max_packet_sz;
75458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8				idx;
76550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	u8				epnum;
77550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	u8				transmit;
78550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi};
79550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
80550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistruct musb_dma_controller {
81458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct dma_controller		controller;
82458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel		channel[MUSB_HSDMA_CHANNELS];
83458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	void				*private_data;
84458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	void __iomem			*base;
85458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8				channel_count;
86458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8				used_channels;
87550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	u8				irq;
88550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi};
89550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
90550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic int dma_controller_start(struct dma_controller *c)
91550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
92550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	/* nothing to do */
93550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	return 0;
94550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
95550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
96458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbistatic void dma_channel_release(struct dma_channel *channel);
97550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
98550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic int dma_controller_stop(struct dma_controller *c)
99550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
100458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_controller *controller = container_of(c,
101458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			struct musb_dma_controller, controller);
102458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb *musb = controller->private_data;
103458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct dma_channel *channel;
104458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 bit;
105550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
106458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	if (controller->used_channels != 0) {
107550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		dev_err(musb->controller,
108550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			"Stopping DMA controller while channel active\n");
109550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
110458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		for (bit = 0; bit < MUSB_HSDMA_CHANNELS; bit++) {
111458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			if (controller->used_channels & (1 << bit)) {
112458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				channel = &controller->channel[bit].channel;
113458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				dma_channel_release(channel);
114550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
115458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				if (!controller->used_channels)
116550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					break;
117550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			}
118550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		}
119550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
120458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
121550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	return 0;
122550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
123550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
124550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic struct dma_channel *dma_channel_allocate(struct dma_controller *c,
125550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				struct musb_hw_ep *hw_ep, u8 transmit)
126550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
127458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_controller *controller = container_of(c,
128458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			struct musb_dma_controller, controller);
129458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel = NULL;
130458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct dma_channel *channel = NULL;
131458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 bit;
132458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
133458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	for (bit = 0; bit < MUSB_HSDMA_CHANNELS; bit++) {
134458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		if (!(controller->used_channels & (1 << bit))) {
135458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			controller->used_channels |= (1 << bit);
136458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel = &(controller->channel[bit]);
137458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel->controller = controller;
138458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel->idx = bit;
139458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel->epnum = hw_ep->epnum;
140458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel->transmit = transmit;
141458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel = &(musb_channel->channel);
142458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel->private_data = musb_channel;
143458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel->status = MUSB_DMA_STATUS_FREE;
144458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel->max_len = 0x10000;
145550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			/* Tx => mode 1; Rx => mode 0 */
146458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel->desired_mode = transmit;
147458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel->actual_len = 0;
148550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			break;
149550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		}
150550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
151458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
152458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	return channel;
153550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
154550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
155458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbistatic void dma_channel_release(struct dma_channel *channel)
156550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
157458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel = channel->private_data;
158550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
159458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	channel->actual_len = 0;
160458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->start_addr = 0;
161458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->len = 0;
162550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
163458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->controller->used_channels &=
164458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		~(1 << musb_channel->idx);
165550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
166458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	channel->status = MUSB_DMA_STATUS_UNKNOWN;
167550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
168550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
169458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbistatic void configure_channel(struct dma_channel *channel,
170550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				u16 packet_sz, u8 mode,
171550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				dma_addr_t dma_addr, u32 len)
172550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
173458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel = channel->private_data;
174458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_controller *controller = musb_channel->controller;
175458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	void __iomem *mbase = controller->base;
176458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 bchannel = musb_channel->idx;
177550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	u16 csr = 0;
178550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
179550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	DBG(4, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
180458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel, packet_sz, dma_addr, len, mode);
181550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
182550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (mode) {
183550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		csr |= 1 << MUSB_HSDMA_MODE1_SHIFT;
184550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		BUG_ON(len < packet_sz);
185550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
186550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		if (packet_sz >= 64) {
187550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			csr |= MUSB_HSDMA_BURSTMODE_INCR16
188550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					<< MUSB_HSDMA_BURSTMODE_SHIFT;
189550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		} else if (packet_sz >= 32) {
190550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			csr |= MUSB_HSDMA_BURSTMODE_INCR8
191550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					<< MUSB_HSDMA_BURSTMODE_SHIFT;
192550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		} else if (packet_sz >= 16) {
193550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			csr |= MUSB_HSDMA_BURSTMODE_INCR4
194550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					<< MUSB_HSDMA_BURSTMODE_SHIFT;
195550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		}
196550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
197550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
198458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	csr |= (musb_channel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT)
199550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		| (1 << MUSB_HSDMA_ENABLE_SHIFT)
200550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		| (1 << MUSB_HSDMA_IRQENABLE_SHIFT)
201458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		| (musb_channel->transmit
202550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				? (1 << MUSB_HSDMA_TRANSMIT_SHIFT)
203550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				: 0);
204550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
205550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	/* address/count */
206550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	musb_writel(mbase,
207458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS),
208550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		dma_addr);
209550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	musb_writel(mbase,
210458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT),
211550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		len);
212550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
213550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	/* control (this should start things) */
214550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	musb_writew(mbase,
215458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL),
216550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		csr);
217550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
218550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
219458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbistatic int dma_channel_program(struct dma_channel *channel,
220550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				u16 packet_sz, u8 mode,
221550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				dma_addr_t dma_addr, u32 len)
222550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
223458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel = channel->private_data;
224550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
225550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n",
226458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		musb_channel->epnum,
227458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		musb_channel->transmit ? "Tx" : "Rx",
228550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		packet_sz, dma_addr, len, mode);
229550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
230458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN ||
231458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		channel->status == MUSB_DMA_STATUS_BUSY);
232550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
233458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	channel->actual_len = 0;
234458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->start_addr = dma_addr;
235458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->len = len;
236458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	musb_channel->max_packet_sz = packet_sz;
237458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	channel->status = MUSB_DMA_STATUS_BUSY;
238550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
239550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if ((mode == 1) && (len >= packet_sz))
240458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		configure_channel(channel, packet_sz, 1, dma_addr, len);
241550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	else
242458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		configure_channel(channel, packet_sz, 0, dma_addr, len);
243550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
244550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	return true;
245550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
246550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
247458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbistatic int dma_channel_abort(struct dma_channel *channel)
248550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
249458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel = channel->private_data;
250458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	void __iomem *mbase = musb_channel->controller->base;
251458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
252458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 bchannel = musb_channel->idx;
253550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	u16 csr;
254550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
255458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	if (channel->status == MUSB_DMA_STATUS_BUSY) {
256458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		if (musb_channel->transmit) {
257550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
258550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			csr = musb_readw(mbase,
259458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				MUSB_EP_OFFSET(musb_channel->epnum,
260550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi						MUSB_TXCSR));
261550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			csr &= ~(MUSB_TXCSR_AUTOSET |
262550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				 MUSB_TXCSR_DMAENAB |
263550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				 MUSB_TXCSR_DMAMODE);
264550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			musb_writew(mbase,
265458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				MUSB_EP_OFFSET(musb_channel->epnum, MUSB_TXCSR),
266550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				csr);
267550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		} else {
268550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			csr = musb_readw(mbase,
269458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				MUSB_EP_OFFSET(musb_channel->epnum,
270550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi						MUSB_RXCSR));
271550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			csr &= ~(MUSB_RXCSR_AUTOCLEAR |
272550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				 MUSB_RXCSR_DMAENAB |
273550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				 MUSB_RXCSR_DMAMODE);
274550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			musb_writew(mbase,
275458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				MUSB_EP_OFFSET(musb_channel->epnum, MUSB_RXCSR),
276550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				csr);
277550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		}
278550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
279550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		musb_writew(mbase,
280458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL),
281550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			0);
282550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		musb_writel(mbase,
283458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS),
284550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			0);
285550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		musb_writel(mbase,
286458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT),
287550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			0);
288550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
289458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		channel->status = MUSB_DMA_STATUS_FREE;
290550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
291458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
292550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	return 0;
293550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
294550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
295550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistatic irqreturn_t dma_controller_irq(int irq, void *private_data)
296550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
297458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_controller *controller = private_data;
298458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb *musb = controller->private_data;
299458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_channel *musb_channel;
300458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct dma_channel *channel;
301458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
302458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	void __iomem *mbase = controller->base;
303458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
304550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	irqreturn_t retval = IRQ_NONE;
305458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
306550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	unsigned long flags;
307550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
308458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 bchannel;
309458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u8 int_hsdma;
310458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
311458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u32 addr;
312458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	u16 csr;
313458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
314550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	spin_lock_irqsave(&musb->lock, flags);
315550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
316550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	int_hsdma = musb_readb(mbase, MUSB_HSDMA_INTR);
317550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (!int_hsdma)
318550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		goto done;
319550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
320458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) {
321458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		if (int_hsdma & (1 << bchannel)) {
322458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			musb_channel = (struct musb_dma_channel *)
323458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					&(controller->channel[bchannel]);
324458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			channel = &musb_channel->channel;
325550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
326550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			csr = musb_readw(mbase,
327458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					MUSB_HSDMA_CHANNEL_OFFSET(bchannel,
328550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi							MUSB_HSDMA_CONTROL));
329550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
330458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			if (csr & (1 << MUSB_HSDMA_BUSERROR_SHIFT)) {
331458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				musb_channel->channel.status =
332550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					MUSB_DMA_STATUS_BUS_ABORT;
333458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			} else {
334550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				u8 devctl;
335550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
336458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				addr = musb_readl(mbase,
337550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi						MUSB_HSDMA_CHANNEL_OFFSET(
338458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi							bchannel,
339550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi							MUSB_HSDMA_ADDRESS));
340458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				channel->actual_len = addr
341458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					- musb_channel->start_addr;
342550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
343550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				DBG(2, "ch %p, 0x%x -> 0x%x (%d / %d) %s\n",
344458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					channel, musb_channel->start_addr,
345458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					addr, channel->actual_len,
346458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					musb_channel->len,
347458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					(channel->actual_len
348458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi						< musb_channel->len) ?
349550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					"=> reconfig 0" : "=> complete");
350550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
351550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				devctl = musb_readb(mbase, MUSB_DEVCTL);
352550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
353458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				channel->status = MUSB_DMA_STATUS_FREE;
354550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
355550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				/* completed */
356550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi				if ((devctl & MUSB_DEVCTL_HM)
357458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					&& (musb_channel->transmit)
358458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					&& ((channel->desired_mode == 0)
359458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					    || (channel->actual_len &
360458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi					    (musb_channel->max_packet_sz - 1)))
361550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					 ) {
362550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					/* Send out the packet */
363550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					musb_ep_select(mbase,
364458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi						musb_channel->epnum);
365550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					musb_writew(mbase, MUSB_EP_OFFSET(
366458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi							musb_channel->epnum,
367550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi							MUSB_TXCSR),
368550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi						MUSB_TXCSR_TXPKTRDY);
369458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				} else {
370550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi					musb_dma_completion(
371550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi						musb,
372458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi						musb_channel->epnum,
373458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi						musb_channel->transmit);
374458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi				}
375550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi			}
376550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		}
377550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
378550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	retval = IRQ_HANDLED;
379550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbidone:
380550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	spin_unlock_irqrestore(&musb->lock, flags);
381550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	return retval;
382550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
383550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
384550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbivoid dma_controller_destroy(struct dma_controller *c)
385550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
386458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	struct musb_dma_controller *controller = container_of(c,
387458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi			struct musb_dma_controller, controller);
388550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
389550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (!controller)
390550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		return;
391550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
392550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (controller->irq)
393550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		free_irq(controller->irq, c);
394550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
395550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	kfree(controller);
396550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
397550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
398550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbistruct dma_controller *__init
399458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbidma_controller_create(struct musb *musb, void __iomem *base)
400550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi{
401550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	struct musb_dma_controller *controller;
402550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	struct device *dev = musb->controller;
403550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	struct platform_device *pdev = to_platform_device(dev);
404550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	int irq = platform_get_irq(pdev, 1);
405550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
406550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (irq == 0) {
407550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		dev_err(dev, "No DMA interrupt line!\n");
408550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		return NULL;
409550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
410550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
411458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller = kzalloc(sizeof(*controller), GFP_KERNEL);
412550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (!controller)
413550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		return NULL;
414550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
415458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->channel_count = MUSB_HSDMA_CHANNELS;
416458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->private_data = musb;
417458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->base = base;
418550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
419458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.start = dma_controller_start;
420458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.stop = dma_controller_stop;
421458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.channel_alloc = dma_channel_allocate;
422458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.channel_release = dma_channel_release;
423458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.channel_program = dma_channel_program;
424458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	controller->controller.channel_abort = dma_channel_abort;
425550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
426550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	if (request_irq(irq, dma_controller_irq, IRQF_DISABLED,
427427c4f333474f5447f62387c1fb060e586c1a781Kay Sievers			dev_name(musb->controller), &controller->controller)) {
428550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		dev_err(dev, "request_irq %d failed!\n", irq);
429458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi		dma_controller_destroy(&controller->controller);
430458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi
431550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi		return NULL;
432550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	}
433550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
434550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi	controller->irq = irq;
435550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi
436458e6a511f9dc91e5af5e64740b0a5c9650a25fbFelipe Balbi	return &controller->controller;
437550a7375fe720924241f0eb76e4a5c1a3eb8c32fFelipe Balbi}
438