aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/renesas_usbhs/fifo.c
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-06-06 01:18:28 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-06-07 12:10:08 -0400
commitdad67397f2090b29cd1f169e6a4ac6f3532c6858 (patch)
tree02f3fe42ef7307b5c70a901b59598478897baa1b /drivers/usb/renesas_usbhs/fifo.c
parent659d495404d20ff8f96644fca82c772455f1226c (diff)
usb: renesas_usbhs: modify data transfer interrupt
On current driver, overall data transfer method was implemented in fifo.c, but its interrupt which is member of packet queue control was still in mod_gadget.c. This patch move it into fifo.c. By this patch, the packet/fifo control is independent from mod_gadget. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/renesas_usbhs/fifo.c')
-rw-r--r--drivers/usb/renesas_usbhs/fifo.c168
1 files changed, 154 insertions, 14 deletions
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index b5031e3a1569..e9c4d3d8ef6e 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -22,19 +22,44 @@
22/* 22/*
23 * packet info function 23 * packet info function
24 */ 24 */
25static 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
35static struct usbhs_pkt_handle usbhsf_null_handler = {
36 .prepare = usbhsf_null_handle,
37 .try_run = usbhsf_null_handle,
38};
39
25void usbhs_pkt_init(struct usbhs_pkt *pkt) 40void usbhs_pkt_init(struct usbhs_pkt *pkt)
26{ 41{
27 INIT_LIST_HEAD(&pkt->node); 42 INIT_LIST_HEAD(&pkt->node);
28} 43}
29 44
30void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, 45void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt,
46 struct usbhs_pkt_handle *handler,
31 void *buf, int len, int zero) 47 void *buf, int len, int zero)
32{ 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
33 list_del_init(&pkt->node); 57 list_del_init(&pkt->node);
34 list_add_tail(&pkt->node, &pipe->list); 58 list_add_tail(&pkt->node, &pipe->list);
35 59
36 pkt->pipe = pipe; 60 pkt->pipe = pipe;
37 pkt->buf = buf; 61 pkt->buf = buf;
62 pkt->handler = handler;
38 pkt->length = len; 63 pkt->length = len;
39 pkt->zero = zero; 64 pkt->zero = zero;
40 pkt->actual = 0; 65 pkt->actual = 0;
@@ -163,12 +188,7 @@ static int usbhsf_fifo_select(struct usbhs_pipe *pipe, int write)
163/* 188/*
164 * PIO fifo functions 189 * PIO fifo functions
165 */ 190 */
166int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe) 191static int usbhsf_try_push(struct usbhs_pkt *pkt)
167{
168 return usbhsf_fifo_select(pipe, 1);
169}
170
171int usbhs_fifo_write(struct usbhs_pkt *pkt)
172{ 192{
173 struct usbhs_pipe *pipe = pkt->pipe; 193 struct usbhs_pipe *pipe = pkt->pipe;
174 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 194 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
@@ -181,11 +201,11 @@ int usbhs_fifo_write(struct usbhs_pkt *pkt)
181 int i, ret, len; 201 int i, ret, len;
182 int is_short, is_done; 202 int is_short, is_done;
183 203
184 ret = usbhs_pipe_is_accessible(pipe); 204 ret = usbhsf_fifo_select(pipe, 1);
185 if (ret < 0) 205 if (ret < 0)
186 goto usbhs_fifo_write_busy; 206 goto usbhs_fifo_write_busy;
187 207
188 ret = usbhsf_fifo_select(pipe, 1); 208 ret = usbhs_pipe_is_accessible(pipe);
189 if (ret < 0) 209 if (ret < 0)
190 goto usbhs_fifo_write_busy; 210 goto usbhs_fifo_write_busy;
191 211
@@ -246,8 +266,7 @@ int usbhs_fifo_write(struct usbhs_pkt *pkt)
246 if (usbhs_pipe_is_dcp(pipe)) 266 if (usbhs_pipe_is_dcp(pipe))
247 usbhs_dcp_control_transfer_done(pipe); 267 usbhs_dcp_control_transfer_done(pipe);
248 268
249 if (info->tx_done) 269 info->done(pkt);
250 info->tx_done(pkt);
251 } 270 }
252 271
253 return 0; 272 return 0;
@@ -262,8 +281,14 @@ usbhs_fifo_write_busy:
262 return ret; 281 return ret;
263} 282}
264 283
265int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe) 284struct usbhs_pkt_handle usbhs_fifo_push_handler = {
285 .prepare = usbhsf_try_push,
286 .try_run = usbhsf_try_push,
287};
288
289static int usbhsf_prepare_pop(struct usbhs_pkt *pkt)
266{ 290{
291 struct usbhs_pipe *pipe = pkt->pipe;
267 int ret; 292 int ret;
268 293
269 /* 294 /*
@@ -279,7 +304,7 @@ int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe)
279 return ret; 304 return ret;
280} 305}
281 306
282int usbhs_fifo_read(struct usbhs_pkt *pkt) 307static int usbhsf_try_pop(struct usbhs_pkt *pkt)
283{ 308{
284 struct usbhs_pipe *pipe = pkt->pipe; 309 struct usbhs_pipe *pipe = pkt->pipe;
285 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 310 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
@@ -355,9 +380,124 @@ usbhs_fifo_read_end:
355 usbhsf_rx_irq_ctrl(pipe, 0); 380 usbhsf_rx_irq_ctrl(pipe, 0);
356 usbhs_pipe_disable(pipe); 381 usbhs_pipe_disable(pipe);
357 382
358 if (info->rx_done) 383 info->done(pkt);
359 info->rx_done(pkt);
360 } 384 }
361 385
362 return 0; 386 return 0;
363} 387}
388
389struct 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 */
397static 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
410struct 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 */
418static 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
450static 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 */
485void 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
495void 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}