usb: renesas_usbhs: shrink spin lock area
[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, int *is_done)
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         unsigned long flags;
52
53         /********************  spin lock ********************/
54         usbhs_lock(priv, flags);
55
56         if (!handler) {
57                 dev_err(dev, "no handler function\n");
58                 handler = &usbhsf_null_handler;
59         }
60
61         list_del_init(&pkt->node);
62         list_add_tail(&pkt->node, &pipe->list);
63
64         pkt->pipe       = pipe;
65         pkt->buf        = buf;
66         pkt->handler    = handler;
67         pkt->length     = len;
68         pkt->zero       = zero;
69         pkt->actual     = 0;
70
71         usbhs_unlock(priv, flags);
72         /********************  spin unlock ******************/
73 }
74
75 static void __usbhsf_pkt_del(struct usbhs_pkt *pkt)
76 {
77         list_del_init(&pkt->node);
78 }
79
80 static struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe)
81 {
82         if (list_empty(&pipe->list))
83                 return NULL;
84
85         return list_entry(pipe->list.next, struct usbhs_pkt, node);
86 }
87
88 struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt)
89 {
90         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
91         unsigned long flags;
92
93         /********************  spin lock ********************/
94         usbhs_lock(priv, flags);
95
96         if (!pkt)
97                 pkt = __usbhsf_pkt_get(pipe);
98
99         if (pkt)
100                 __usbhsf_pkt_del(pkt);
101
102         usbhs_unlock(priv, flags);
103         /********************  spin unlock ******************/
104
105         return pkt;
106 }
107
108 int __usbhs_pkt_handler(struct usbhs_pipe *pipe, int type)
109 {
110         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
111         struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
112         struct usbhs_pkt *pkt;
113         struct device *dev = usbhs_priv_to_dev(priv);
114         int (*func)(struct usbhs_pkt *pkt, int *is_done);
115         unsigned long flags;
116         int ret = 0;
117         int is_done = 0;
118
119         /********************  spin lock ********************/
120         usbhs_lock(priv, flags);
121
122         pkt = __usbhsf_pkt_get(pipe);
123         if (!pkt)
124                 goto __usbhs_pkt_handler_end;
125
126         switch (type) {
127         case USBHSF_PKT_PREPARE:
128                 func = pkt->handler->prepare;
129                 break;
130         case USBHSF_PKT_TRY_RUN:
131                 func = pkt->handler->try_run;
132                 break;
133         default:
134                 dev_err(dev, "unknown pkt hander\n");
135                 goto __usbhs_pkt_handler_end;
136         }
137
138         ret = func(pkt, &is_done);
139
140         if (is_done)
141                 __usbhsf_pkt_del(pkt);
142
143 __usbhs_pkt_handler_end:
144         usbhs_unlock(priv, flags);
145         /********************  spin unlock ******************/
146
147         if (is_done)
148                 info->done(pkt);
149
150         return ret;
151 }
152
153 /*
154  *              irq enable/disable function
155  */
156 #define usbhsf_irq_empty_ctrl(p, e) usbhsf_irq_callback_ctrl(p, bempsts, e)
157 #define usbhsf_irq_ready_ctrl(p, e) usbhsf_irq_callback_ctrl(p, brdysts, e)
158 #define usbhsf_irq_callback_ctrl(pipe, status, enable)                  \
159         ({                                                              \
160                 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);     \
161                 struct usbhs_mod *mod = usbhs_mod_get_current(priv);    \
162                 u16 status = (1 << usbhs_pipe_number(pipe));            \
163                 if (!mod)                                               \
164                         return;                                         \
165                 if (enable)                                             \
166                         mod->irq_##status |= status;                    \
167                 else                                                    \
168                         mod->irq_##status &= ~status;                   \
169                 usbhs_irq_callback_update(priv, mod);                   \
170         })
171
172 static void usbhsf_tx_irq_ctrl(struct usbhs_pipe *pipe, int enable)
173 {
174         /*
175          * And DCP pipe can NOT use "ready interrupt" for "send"
176          * it should use "empty" interrupt.
177          * see
178          *   "Operation" - "Interrupt Function" - "BRDY Interrupt"
179          *
180          * on the other hand, normal pipe can use "ready interrupt" for "send"
181          * even though it is single/double buffer
182          */
183         if (usbhs_pipe_is_dcp(pipe))
184                 usbhsf_irq_empty_ctrl(pipe, enable);
185         else
186                 usbhsf_irq_ready_ctrl(pipe, enable);
187 }
188
189 static void usbhsf_rx_irq_ctrl(struct usbhs_pipe *pipe, int enable)
190 {
191         usbhsf_irq_ready_ctrl(pipe, enable);
192 }
193
194 /*
195  *              FIFO ctrl
196  */
197 static void usbhsf_send_terminator(struct usbhs_pipe *pipe)
198 {
199         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
200
201         usbhs_bset(priv, CFIFOCTR, BVAL, BVAL);
202 }
203
204 static int usbhsf_fifo_barrier(struct usbhs_priv *priv)
205 {
206         int timeout = 1024;
207
208         do {
209                 /* The FIFO port is accessible */
210                 if (usbhs_read(priv, CFIFOCTR) & FRDY)
211                         return 0;
212
213                 udelay(10);
214         } while (timeout--);
215
216         return -EBUSY;
217 }
218
219 static void usbhsf_fifo_clear(struct usbhs_pipe *pipe)
220 {
221         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
222
223         if (!usbhs_pipe_is_dcp(pipe))
224                 usbhsf_fifo_barrier(priv);
225
226         usbhs_write(priv, CFIFOCTR, BCLR);
227 }
228
229 static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv)
230 {
231         return usbhs_read(priv, CFIFOCTR) & DTLN_MASK;
232 }
233
234 static int usbhsf_fifo_select(struct usbhs_pipe *pipe, int write)
235 {
236         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
237         struct device *dev = usbhs_priv_to_dev(priv);
238         int timeout = 1024;
239         u16 mask = ((1 << 5) | 0xF);            /* mask of ISEL | CURPIPE */
240         u16 base = usbhs_pipe_number(pipe);     /* CURPIPE */
241
242         if (usbhs_pipe_is_dcp(pipe))
243                 base |= (1 == write) << 5;      /* ISEL */
244
245         /* "base" will be used below  */
246         usbhs_write(priv, CFIFOSEL, base | MBW_32);
247
248         /* check ISEL and CURPIPE value */
249         while (timeout--) {
250                 if (base == (mask & usbhs_read(priv, CFIFOSEL)))
251                         return 0;
252                 udelay(10);
253         }
254
255         dev_err(dev, "fifo select error\n");
256
257         return -EIO;
258 }
259
260 /*
261  *              PIO fifo functions
262  */
263 static int usbhsf_try_push(struct usbhs_pkt *pkt, int *is_done)
264 {
265         struct usbhs_pipe *pipe = pkt->pipe;
266         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
267         struct device *dev = usbhs_priv_to_dev(priv);
268         void __iomem *addr = priv->base + CFIFO;
269         u8 *buf;
270         int maxp = usbhs_pipe_get_maxpacket(pipe);
271         int total_len;
272         int i, ret, len;
273         int is_short;
274
275         ret = usbhsf_fifo_select(pipe, 1);
276         if (ret < 0)
277                 goto usbhs_fifo_write_busy;
278
279         ret = usbhs_pipe_is_accessible(pipe);
280         if (ret < 0)
281                 goto usbhs_fifo_write_busy;
282
283         ret = usbhsf_fifo_barrier(priv);
284         if (ret < 0)
285                 goto usbhs_fifo_write_busy;
286
287         buf             = pkt->buf    + pkt->actual;
288         len             = pkt->length - pkt->actual;
289         len             = min(len, maxp);
290         total_len       = len;
291         is_short        = total_len < maxp;
292
293         /*
294          * FIXME
295          *
296          * 32-bit access only
297          */
298         if (len >= 4 && !((unsigned long)buf & 0x03)) {
299                 iowrite32_rep(addr, buf, len / 4);
300                 len %= 4;
301                 buf += total_len - len;
302         }
303
304         /* the rest operation */
305         for (i = 0; i < len; i++)
306                 iowrite8(buf[i], addr + (0x03 - (i & 0x03)));
307
308         /*
309          * variable update
310          */
311         pkt->actual += total_len;
312
313         if (pkt->actual < pkt->length)
314                 *is_done = 0;           /* there are remainder data */
315         else if (is_short)
316                 *is_done = 1;           /* short packet */
317         else
318                 *is_done = !pkt->zero;  /* send zero packet ? */
319
320         /*
321          * pipe/irq handling
322          */
323         if (is_short)
324                 usbhsf_send_terminator(pipe);
325
326         usbhsf_tx_irq_ctrl(pipe, !*is_done);
327         usbhs_pipe_enable(pipe);
328
329         dev_dbg(dev, "  send %d (%d/ %d/ %d/ %d)\n",
330                 usbhs_pipe_number(pipe),
331                 pkt->length, pkt->actual, *is_done, pkt->zero);
332
333         /*
334          * Transmission end
335          */
336         if (*is_done) {
337                 if (usbhs_pipe_is_dcp(pipe))
338                         usbhs_dcp_control_transfer_done(pipe);
339         }
340
341         return 0;
342
343 usbhs_fifo_write_busy:
344         /*
345          * pipe is busy.
346          * retry in interrupt
347          */
348         usbhsf_tx_irq_ctrl(pipe, 1);
349
350         return ret;
351 }
352
353 struct usbhs_pkt_handle usbhs_fifo_push_handler = {
354         .prepare = usbhsf_try_push,
355         .try_run = usbhsf_try_push,
356 };
357
358 static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done)
359 {
360         struct usbhs_pipe *pipe = pkt->pipe;
361         int ret;
362
363         /*
364          * select pipe and enable it to prepare packet receive
365          */
366         ret = usbhsf_fifo_select(pipe, 0);
367         if (ret < 0)
368                 return ret;
369
370         usbhs_pipe_enable(pipe);
371         usbhsf_rx_irq_ctrl(pipe, 1);
372
373         return ret;
374 }
375
376 static int usbhsf_try_pop(struct usbhs_pkt *pkt, int *is_done)
377 {
378         struct usbhs_pipe *pipe = pkt->pipe;
379         struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
380         struct device *dev = usbhs_priv_to_dev(priv);
381         void __iomem *addr = priv->base + CFIFO;
382         u8 *buf;
383         u32 data = 0;
384         int maxp = usbhs_pipe_get_maxpacket(pipe);
385         int rcv_len, len;
386         int i, ret;
387         int total_len = 0;
388
389         ret = usbhsf_fifo_select(pipe, 0);
390         if (ret < 0)
391                 return ret;
392
393         ret = usbhsf_fifo_barrier(priv);
394         if (ret < 0)
395                 return ret;
396
397         rcv_len = usbhsf_fifo_rcv_len(priv);
398
399         buf             = pkt->buf    + pkt->actual;
400         len             = pkt->length - pkt->actual;
401         len             = min(len, rcv_len);
402         total_len       = len;
403
404         /*
405          * Buffer clear if Zero-Length packet
406          *
407          * see
408          * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function"
409          */
410         if (0 == rcv_len) {
411                 usbhsf_fifo_clear(pipe);
412                 goto usbhs_fifo_read_end;
413         }
414
415         /*
416          * FIXME
417          *
418          * 32-bit access only
419          */
420         if (len >= 4 && !((unsigned long)buf & 0x03)) {
421                 ioread32_rep(addr, buf, len / 4);
422                 len %= 4;
423                 buf += total_len - len;
424         }
425
426         /* the rest operation */
427         for (i = 0; i < len; i++) {
428                 if (!(i & 0x03))
429                         data = ioread32(addr);
430
431                 buf[i] = (data >> ((i & 0x03) * 8)) & 0xff;
432         }
433
434         pkt->actual += total_len;
435
436 usbhs_fifo_read_end:
437         if ((pkt->actual == pkt->length) ||     /* receive all data */
438             (total_len < maxp)) {               /* short packet */
439                 *is_done = 1;
440                 usbhsf_rx_irq_ctrl(pipe, 0);
441                 usbhs_pipe_disable(pipe);
442         }
443
444         dev_dbg(dev, "  recv %d (%d/ %d/ %d/ %d)\n",
445                 usbhs_pipe_number(pipe),
446                 pkt->length, pkt->actual, *is_done, pkt->zero);
447
448         return 0;
449 }
450
451 struct usbhs_pkt_handle usbhs_fifo_pop_handler = {
452         .prepare = usbhsf_prepare_pop,
453         .try_run = usbhsf_try_pop,
454 };
455
456 /*
457  *              handler function
458  */
459 static int usbhsf_ctrl_stage_end(struct usbhs_pkt *pkt, int *is_done)
460 {
461         usbhs_dcp_control_transfer_done(pkt->pipe);
462
463         *is_done = 1;
464
465         return 0;
466 }
467
468 struct usbhs_pkt_handle usbhs_ctrl_stage_end_handler = {
469         .prepare = usbhsf_ctrl_stage_end,
470         .try_run = usbhsf_ctrl_stage_end,
471 };
472
473 /*
474  *              irq functions
475  */
476 static int usbhsf_irq_empty(struct usbhs_priv *priv,
477                             struct usbhs_irq_state *irq_state)
478 {
479         struct usbhs_pipe *pipe;
480         struct device *dev = usbhs_priv_to_dev(priv);
481         int i, ret;
482
483         if (!irq_state->bempsts) {
484                 dev_err(dev, "debug %s !!\n", __func__);
485                 return -EIO;
486         }
487
488         dev_dbg(dev, "irq empty [0x%04x]\n", irq_state->bempsts);
489
490         /*
491          * search interrupted "pipe"
492          * not "uep".
493          */
494         usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
495                 if (!(irq_state->bempsts & (1 << i)))
496                         continue;
497
498                 ret = usbhs_pkt_run(pipe);
499                 if (ret < 0)
500                         dev_err(dev, "irq_empty run_error %d : %d\n", i, ret);
501         }
502
503         return 0;
504 }
505
506 static int usbhsf_irq_ready(struct usbhs_priv *priv,
507                             struct usbhs_irq_state *irq_state)
508 {
509         struct usbhs_pipe *pipe;
510         struct device *dev = usbhs_priv_to_dev(priv);
511         int i, ret;
512
513         if (!irq_state->brdysts) {
514                 dev_err(dev, "debug %s !!\n", __func__);
515                 return -EIO;
516         }
517
518         dev_dbg(dev, "irq ready [0x%04x]\n", irq_state->brdysts);
519
520         /*
521          * search interrupted "pipe"
522          * not "uep".
523          */
524         usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
525                 if (!(irq_state->brdysts & (1 << i)))
526                         continue;
527
528                 ret = usbhs_pkt_run(pipe);
529                 if (ret < 0)
530                         dev_err(dev, "irq_ready run_error %d : %d\n", i, ret);
531         }
532
533         return 0;
534 }
535
536 /*
537  *              fifo init
538  */
539 void usbhs_fifo_init(struct usbhs_priv *priv)
540 {
541         struct usbhs_mod *mod = usbhs_mod_get_current(priv);
542
543         mod->irq_empty          = usbhsf_irq_empty;
544         mod->irq_ready          = usbhsf_irq_ready;
545         mod->irq_bempsts        = 0;
546         mod->irq_brdysts        = 0;
547 }
548
549 void usbhs_fifo_quit(struct usbhs_priv *priv)
550 {
551         struct usbhs_mod *mod = usbhs_mod_get_current(priv);
552
553         mod->irq_empty          = NULL;
554         mod->irq_ready          = NULL;
555         mod->irq_bempsts        = 0;
556         mod->irq_brdysts        = 0;
557 }