usb: renesas_usbhs: modify data transfer interrupt
[pandora-kernel.git] / drivers / usb / renesas_usbhs / fifo.c
1 /*
2  * Renesas USB driver
3  *
4  * Copyright (C) 2011 Renesas Solutions Corp.
5  * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
15  *
16  */
17 #include <linux/delay.h>
18 #include <linux/io.h>
19 #include "./common.h"
20 #include "./pipe.h"
21
22 /*
23  *              packet info function
24  */
25 static int usbhsf_null_handle(struct usbhs_pkt *pkt)
26 {
27         struct usbhs_priv *priv = usbhs_pipe_to_priv(pkt->pipe);
28         struct device *dev = usbhs_priv_to_dev(priv);
29
30         dev_err(dev, "null handler\n");
31
32         return -EINVAL;
33 }
34
35 static struct usbhs_pkt_handle usbhsf_null_handler = {
36         .prepare = usbhsf_null_handle,
37         .try_run = usbhsf_null_handle,
38 };
39
40 void usbhs_pkt_init(struct usbhs_pkt *pkt)
41 {
42         INIT_LIST_HEAD(&pkt->node);
43 }
44
45 void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt,
46                     struct usbhs_pkt_handle *handler,
47                     void *buf, int len, int zero)
48 {
49         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
50         struct device *dev = usbhs_priv_to_dev(priv);
51
52         if (!handler) {
53                 dev_err(dev, "no handler function\n");
54                 handler = &usbhsf_null_handler;
55         }
56
57         list_del_init(&pkt->node);
58         list_add_tail(&pkt->node, &pipe->list);
59
60         pkt->pipe       = pipe;
61         pkt->buf        = buf;
62         pkt->handler    = handler;
63         pkt->length     = len;
64         pkt->zero       = zero;
65         pkt->actual     = 0;
66 }
67
68 void usbhs_pkt_pop(struct usbhs_pkt *pkt)
69 {
70         list_del_init(&pkt->node);
71 }
72
73 struct usbhs_pkt *usbhs_pkt_get(struct usbhs_pipe *pipe)
74 {
75         if (list_empty(&pipe->list))
76                 return NULL;
77
78         return list_entry(pipe->list.next, struct usbhs_pkt, node);
79 }
80
81 /*
82  *              irq enable/disable function
83  */
84 #define usbhsf_irq_empty_ctrl(p, e) usbhsf_irq_callback_ctrl(p, bempsts, e)
85 #define usbhsf_irq_ready_ctrl(p, e) usbhsf_irq_callback_ctrl(p, brdysts, e)
86 #define usbhsf_irq_callback_ctrl(pipe, status, enable)                  \
87         ({                                                              \
88                 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);     \
89                 struct usbhs_mod *mod = usbhs_mod_get_current(priv);    \
90                 u16 status = (1 << usbhs_pipe_number(pipe));            \
91                 if (!mod)                                               \
92                         return;                                         \
93                 if (enable)                                             \
94                         mod->irq_##status |= status;                    \
95                 else                                                    \
96                         mod->irq_##status &= ~status;                   \
97                 usbhs_irq_callback_update(priv, mod);                   \
98         })
99
100 static void usbhsf_tx_irq_ctrl(struct usbhs_pipe *pipe, int enable)
101 {
102         /*
103          * And DCP pipe can NOT use "ready interrupt" for "send"
104          * it should use "empty" interrupt.
105          * see
106          *   "Operation" - "Interrupt Function" - "BRDY Interrupt"
107          *
108          * on the other hand, normal pipe can use "ready interrupt" for "send"
109          * even though it is single/double buffer
110          */
111         if (usbhs_pipe_is_dcp(pipe))
112                 usbhsf_irq_empty_ctrl(pipe, enable);
113         else
114                 usbhsf_irq_ready_ctrl(pipe, enable);
115 }
116
117 static void usbhsf_rx_irq_ctrl(struct usbhs_pipe *pipe, int enable)
118 {
119         usbhsf_irq_ready_ctrl(pipe, enable);
120 }
121
122 /*
123  *              FIFO ctrl
124  */
125 static void usbhsf_send_terminator(struct usbhs_pipe *pipe)
126 {
127         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
128
129         usbhs_bset(priv, CFIFOCTR, BVAL, BVAL);
130 }
131
132 static int usbhsf_fifo_barrier(struct usbhs_priv *priv)
133 {
134         int timeout = 1024;
135
136         do {
137                 /* The FIFO port is accessible */
138                 if (usbhs_read(priv, CFIFOCTR) & FRDY)
139                         return 0;
140
141                 udelay(10);
142         } while (timeout--);
143
144         return -EBUSY;
145 }
146
147 static void usbhsf_fifo_clear(struct usbhs_pipe *pipe)
148 {
149         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
150
151         if (!usbhs_pipe_is_dcp(pipe))
152                 usbhsf_fifo_barrier(priv);
153
154         usbhs_write(priv, CFIFOCTR, BCLR);
155 }
156
157 static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv)
158 {
159         return usbhs_read(priv, CFIFOCTR) & DTLN_MASK;
160 }
161
162 static int usbhsf_fifo_select(struct usbhs_pipe *pipe, int write)
163 {
164         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
165         struct device *dev = usbhs_priv_to_dev(priv);
166         int timeout = 1024;
167         u16 mask = ((1 << 5) | 0xF);            /* mask of ISEL | CURPIPE */
168         u16 base = usbhs_pipe_number(pipe);     /* CURPIPE */
169
170         if (usbhs_pipe_is_dcp(pipe))
171                 base |= (1 == write) << 5;      /* ISEL */
172
173         /* "base" will be used below  */
174         usbhs_write(priv, CFIFOSEL, base | MBW_32);
175
176         /* check ISEL and CURPIPE value */
177         while (timeout--) {
178                 if (base == (mask & usbhs_read(priv, CFIFOSEL)))
179                         return 0;
180                 udelay(10);
181         }
182
183         dev_err(dev, "fifo select error\n");
184
185         return -EIO;
186 }
187
188 /*
189  *              PIO fifo functions
190  */
191 static int usbhsf_try_push(struct usbhs_pkt *pkt)
192 {
193         struct usbhs_pipe *pipe = pkt->pipe;
194         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
195         struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
196         struct device *dev = usbhs_priv_to_dev(priv);
197         void __iomem *addr = priv->base + CFIFO;
198         u8 *buf;
199         int maxp = usbhs_pipe_get_maxpacket(pipe);
200         int total_len;
201         int i, ret, len;
202         int is_short, is_done;
203
204         ret = usbhsf_fifo_select(pipe, 1);
205         if (ret < 0)
206                 goto usbhs_fifo_write_busy;
207
208         ret = usbhs_pipe_is_accessible(pipe);
209         if (ret < 0)
210                 goto usbhs_fifo_write_busy;
211
212         ret = usbhsf_fifo_barrier(priv);
213         if (ret < 0)
214                 goto usbhs_fifo_write_busy;
215
216         buf             = pkt->buf    + pkt->actual;
217         len             = pkt->length - pkt->actual;
218         len             = min(len, maxp);
219         total_len       = len;
220         is_short        = total_len < maxp;
221
222         /*
223          * FIXME
224          *
225          * 32-bit access only
226          */
227         if (len >= 4 && !((unsigned long)buf & 0x03)) {
228                 iowrite32_rep(addr, buf, len / 4);
229                 len %= 4;
230                 buf += total_len - len;
231         }
232
233         /* the rest operation */
234         for (i = 0; i < len; i++)
235                 iowrite8(buf[i], addr + (0x03 - (i & 0x03)));
236
237         /*
238          * variable update
239          */
240         pkt->actual += total_len;
241
242         if (pkt->actual < pkt->length)
243                 is_done = 0;            /* there are remainder data */
244         else if (is_short)
245                 is_done = 1;            /* short packet */
246         else
247                 is_done = !pkt->zero;   /* send zero packet ? */
248
249         /*
250          * pipe/irq handling
251          */
252         if (is_short)
253                 usbhsf_send_terminator(pipe);
254
255         usbhsf_tx_irq_ctrl(pipe, !is_done);
256         usbhs_pipe_enable(pipe);
257
258         dev_dbg(dev, "  send %d (%d/ %d/ %d/ %d)\n",
259                 usbhs_pipe_number(pipe),
260                 pkt->length, pkt->actual, is_done, pkt->zero);
261
262         /*
263          * Transmission end
264          */
265         if (is_done) {
266                 if (usbhs_pipe_is_dcp(pipe))
267                         usbhs_dcp_control_transfer_done(pipe);
268
269                 info->done(pkt);
270         }
271
272         return 0;
273
274 usbhs_fifo_write_busy:
275         /*
276          * pipe is busy.
277          * retry in interrupt
278          */
279         usbhsf_tx_irq_ctrl(pipe, 1);
280
281         return ret;
282 }
283
284 struct usbhs_pkt_handle usbhs_fifo_push_handler = {
285         .prepare = usbhsf_try_push,
286         .try_run = usbhsf_try_push,
287 };
288
289 static int usbhsf_prepare_pop(struct usbhs_pkt *pkt)
290 {
291         struct usbhs_pipe *pipe = pkt->pipe;
292         int ret;
293
294         /*
295          * select pipe and enable it to prepare packet receive
296          */
297         ret = usbhsf_fifo_select(pipe, 0);
298         if (ret < 0)
299                 return ret;
300
301         usbhs_pipe_enable(pipe);
302         usbhsf_rx_irq_ctrl(pipe, 1);
303
304         return ret;
305 }
306
307 static int usbhsf_try_pop(struct usbhs_pkt *pkt)
308 {
309         struct usbhs_pipe *pipe = pkt->pipe;
310         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
311         struct device *dev = usbhs_priv_to_dev(priv);
312         void __iomem *addr = priv->base + CFIFO;
313         u8 *buf;
314         u32 data = 0;
315         int maxp = usbhs_pipe_get_maxpacket(pipe);
316         int rcv_len, len;
317         int i, ret;
318         int total_len = 0;
319         int is_done = 0;
320
321         ret = usbhsf_fifo_select(pipe, 0);
322         if (ret < 0)
323                 return ret;
324
325         ret = usbhsf_fifo_barrier(priv);
326         if (ret < 0)
327                 return ret;
328
329         rcv_len = usbhsf_fifo_rcv_len(priv);
330
331         buf             = pkt->buf    + pkt->actual;
332         len             = pkt->length - pkt->actual;
333         len             = min(len, rcv_len);
334         total_len       = len;
335
336         /*
337          * Buffer clear if Zero-Length packet
338          *
339          * see
340          * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function"
341          */
342         if (0 == rcv_len) {
343                 usbhsf_fifo_clear(pipe);
344                 goto usbhs_fifo_read_end;
345         }
346
347         /*
348          * FIXME
349          *
350          * 32-bit access only
351          */
352         if (len >= 4 && !((unsigned long)buf & 0x03)) {
353                 ioread32_rep(addr, buf, len / 4);
354                 len %= 4;
355                 buf += total_len - len;
356         }
357
358         /* the rest operation */
359         for (i = 0; i < len; i++) {
360                 if (!(i & 0x03))
361                         data = ioread32(addr);
362
363                 buf[i] = (data >> ((i & 0x03) * 8)) & 0xff;
364         }
365
366         pkt->actual += total_len;
367
368 usbhs_fifo_read_end:
369         if ((pkt->actual == pkt->length) ||     /* receive all data */
370             (total_len < maxp))                 /* short packet */
371                 is_done = 1;
372
373         dev_dbg(dev, "  recv %d (%d/ %d/ %d/ %d)\n",
374                 usbhs_pipe_number(pipe),
375                 pkt->length, pkt->actual, is_done, pkt->zero);
376
377         if (is_done) {
378                 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
379
380                 usbhsf_rx_irq_ctrl(pipe, 0);
381                 usbhs_pipe_disable(pipe);
382
383                 info->done(pkt);
384         }
385
386         return 0;
387 }
388
389 struct usbhs_pkt_handle usbhs_fifo_pop_handler = {
390         .prepare = usbhsf_prepare_pop,
391         .try_run = usbhsf_try_pop,
392 };
393
394 /*
395  *              handler function
396  */
397 static int usbhsf_ctrl_stage_end(struct usbhs_pkt *pkt)
398 {
399         struct usbhs_pipe *pipe = pkt->pipe;
400         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
401         struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
402
403         usbhs_dcp_control_transfer_done(pipe);
404
405         info->done(pkt);
406
407         return 0;
408 }
409
410 struct usbhs_pkt_handle usbhs_ctrl_stage_end_handler = {
411         .prepare = usbhsf_ctrl_stage_end,
412         .try_run = usbhsf_ctrl_stage_end,
413 };
414
415 /*
416  *              irq functions
417  */
418 static int usbhsf_irq_empty(struct usbhs_priv *priv,
419                             struct usbhs_irq_state *irq_state)
420 {
421         struct usbhs_pipe *pipe;
422         struct usbhs_pkt *pkt;
423         struct device *dev = usbhs_priv_to_dev(priv);
424         int i, ret;
425
426         if (!irq_state->bempsts) {
427                 dev_err(dev, "debug %s !!\n", __func__);
428                 return -EIO;
429         }
430
431         dev_dbg(dev, "irq empty [0x%04x]\n", irq_state->bempsts);
432
433         /*
434          * search interrupted "pipe"
435          * not "uep".
436          */
437         usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
438                 if (!(irq_state->bempsts & (1 << i)))
439                         continue;
440
441                 pkt = usbhs_pkt_get(pipe);
442                 ret = usbhs_pkt_run(pkt);
443                 if (ret < 0)
444                         dev_err(dev, "irq_empty run_error %d : %d\n", i, ret);
445         }
446
447         return 0;
448 }
449
450 static int usbhsf_irq_ready(struct usbhs_priv *priv,
451                             struct usbhs_irq_state *irq_state)
452 {
453         struct usbhs_pipe *pipe;
454         struct usbhs_pkt *pkt;
455         struct device *dev = usbhs_priv_to_dev(priv);
456         int i, ret;
457
458         if (!irq_state->brdysts) {
459                 dev_err(dev, "debug %s !!\n", __func__);
460                 return -EIO;
461         }
462
463         dev_dbg(dev, "irq ready [0x%04x]\n", irq_state->brdysts);
464
465         /*
466          * search interrupted "pipe"
467          * not "uep".
468          */
469         usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
470                 if (!(irq_state->brdysts & (1 << i)))
471                         continue;
472
473                 pkt = usbhs_pkt_get(pipe);
474                 ret = usbhs_pkt_run(pkt);
475                 if (ret < 0)
476                         dev_err(dev, "irq_ready run_error %d : %d\n", i, ret);
477         }
478
479         return 0;
480 }
481
482 /*
483  *              fifo init
484  */
485 void usbhs_fifo_init(struct usbhs_priv *priv)
486 {
487         struct usbhs_mod *mod = usbhs_mod_get_current(priv);
488
489         mod->irq_empty          = usbhsf_irq_empty;
490         mod->irq_ready          = usbhsf_irq_ready;
491         mod->irq_bempsts        = 0;
492         mod->irq_brdysts        = 0;
493 }
494
495 void usbhs_fifo_quit(struct usbhs_priv *priv)
496 {
497         struct usbhs_mod *mod = usbhs_mod_get_current(priv);
498
499         mod->irq_empty          = NULL;
500         mod->irq_ready          = NULL;
501         mod->irq_bempsts        = 0;
502         mod->irq_brdysts        = 0;
503 }