diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2011-06-06 01:18:28 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-06-07 12:10:08 -0400 |
commit | dad67397f2090b29cd1f169e6a4ac6f3532c6858 (patch) | |
tree | 02f3fe42ef7307b5c70a901b59598478897baa1b /drivers | |
parent | 659d495404d20ff8f96644fca82c772455f1226c (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')
-rw-r--r-- | drivers/usb/renesas_usbhs/fifo.c | 168 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/fifo.h | 21 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_gadget.c | 291 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/pipe.c | 12 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/pipe.h | 6 |
5 files changed, 204 insertions, 294 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 | */ |
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 | |||
25 | void usbhs_pkt_init(struct usbhs_pkt *pkt) | 40 | void 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 | ||
30 | void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, | 45 | void 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 | */ |
166 | int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe) | 191 | static int usbhsf_try_push(struct usbhs_pkt *pkt) |
167 | { | ||
168 | return usbhsf_fifo_select(pipe, 1); | ||
169 | } | ||
170 | |||
171 | int 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 | ||
265 | int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe) | 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) | ||
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 | ||
282 | int usbhs_fifo_read(struct usbhs_pkt *pkt) | 307 | static 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 | |||
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 | } | ||
diff --git a/drivers/usb/renesas_usbhs/fifo.h b/drivers/usb/renesas_usbhs/fifo.h index 04d8cddaf812..eab3258e9834 100644 --- a/drivers/usb/renesas_usbhs/fifo.h +++ b/drivers/usb/renesas_usbhs/fifo.h | |||
@@ -19,30 +19,43 @@ | |||
19 | 19 | ||
20 | #include "pipe.h" | 20 | #include "pipe.h" |
21 | 21 | ||
22 | struct usbhs_pkt_handle; | ||
22 | struct usbhs_pkt { | 23 | struct usbhs_pkt { |
23 | struct list_head node; | 24 | struct list_head node; |
24 | struct usbhs_pipe *pipe; | 25 | struct usbhs_pipe *pipe; |
26 | struct usbhs_pkt_handle *handler; | ||
25 | void *buf; | 27 | void *buf; |
26 | int length; | 28 | int length; |
27 | int actual; | 29 | int actual; |
28 | int zero; | 30 | int zero; |
29 | }; | 31 | }; |
30 | 32 | ||
33 | struct usbhs_pkt_handle { | ||
34 | int (*prepare)(struct usbhs_pkt *pkt); | ||
35 | int (*try_run)(struct usbhs_pkt *pkt); | ||
36 | }; | ||
37 | |||
31 | /* | 38 | /* |
32 | * fifo | 39 | * fifo |
33 | */ | 40 | */ |
34 | int usbhs_fifo_write(struct usbhs_pkt *pkt); | 41 | void usbhs_fifo_init(struct usbhs_priv *priv); |
35 | int usbhs_fifo_read(struct usbhs_pkt *pkt); | 42 | void usbhs_fifo_quit(struct usbhs_priv *priv); |
36 | int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe); | ||
37 | int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe); | ||
38 | 43 | ||
39 | /* | 44 | /* |
40 | * packet info | 45 | * packet info |
41 | */ | 46 | */ |
47 | extern struct usbhs_pkt_handle usbhs_fifo_push_handler; | ||
48 | extern struct usbhs_pkt_handle usbhs_fifo_pop_handler; | ||
49 | extern struct usbhs_pkt_handle usbhs_ctrl_stage_end_handler; | ||
50 | |||
42 | void usbhs_pkt_init(struct usbhs_pkt *pkt); | 51 | void usbhs_pkt_init(struct usbhs_pkt *pkt); |
43 | void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, | 52 | void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, |
53 | struct usbhs_pkt_handle *handler, | ||
44 | void *buf, int len, int zero); | 54 | void *buf, int len, int zero); |
45 | void usbhs_pkt_pop(struct usbhs_pkt *pkt); | 55 | void usbhs_pkt_pop(struct usbhs_pkt *pkt); |
46 | struct usbhs_pkt *usbhs_pkt_get(struct usbhs_pipe *pipe); | 56 | struct usbhs_pkt *usbhs_pkt_get(struct usbhs_pipe *pipe); |
47 | 57 | ||
58 | #define usbhs_pkt_start(p) ((p)->handler->prepare(p)) | ||
59 | #define usbhs_pkt_run(p) ((p)->handler->try_run(p)) | ||
60 | |||
48 | #endif /* RENESAS_USB_FIFO_H */ | 61 | #endif /* RENESAS_USB_FIFO_H */ |
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 298984f533dd..50c7566369eb 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c | |||
@@ -31,7 +31,6 @@ struct usbhsg_request { | |||
31 | 31 | ||
32 | #define EP_NAME_SIZE 8 | 32 | #define EP_NAME_SIZE 8 |
33 | struct usbhsg_gpriv; | 33 | struct usbhsg_gpriv; |
34 | struct usbhsg_pipe_handle; | ||
35 | struct usbhsg_uep { | 34 | struct usbhsg_uep { |
36 | struct usb_ep ep; | 35 | struct usb_ep ep; |
37 | struct usbhs_pipe *pipe; | 36 | struct usbhs_pipe *pipe; |
@@ -39,7 +38,7 @@ struct usbhsg_uep { | |||
39 | char ep_name[EP_NAME_SIZE]; | 38 | char ep_name[EP_NAME_SIZE]; |
40 | 39 | ||
41 | struct usbhsg_gpriv *gpriv; | 40 | struct usbhsg_gpriv *gpriv; |
42 | struct usbhsg_pipe_handle *handler; | 41 | struct usbhs_pkt_handle *handler; |
43 | }; | 42 | }; |
44 | 43 | ||
45 | struct usbhsg_gpriv { | 44 | struct usbhsg_gpriv { |
@@ -57,11 +56,6 @@ struct usbhsg_gpriv { | |||
57 | #define USBHSG_STATUS_WEDGE (1 << 2) | 56 | #define USBHSG_STATUS_WEDGE (1 << 2) |
58 | }; | 57 | }; |
59 | 58 | ||
60 | struct usbhsg_pipe_handle { | ||
61 | int (*prepare)(struct usbhsg_uep *uep, struct usbhsg_request *ureq); | ||
62 | int (*try_run)(struct usbhsg_uep *uep, struct usbhsg_request *ureq); | ||
63 | }; | ||
64 | |||
65 | struct usbhsg_recip_handle { | 59 | struct usbhsg_recip_handle { |
66 | char *name; | 60 | char *name; |
67 | int (*device)(struct usbhs_priv *priv, struct usbhsg_uep *uep, | 61 | int (*device)(struct usbhs_priv *priv, struct usbhsg_uep *uep, |
@@ -164,7 +158,8 @@ static void usbhsg_queue_push(struct usbhsg_uep *uep, | |||
164 | /* | 158 | /* |
165 | ********* assume under spin lock ********* | 159 | ********* assume under spin lock ********* |
166 | */ | 160 | */ |
167 | usbhs_pkt_push(pipe, pkt, req->buf, req->length, req->zero); | 161 | usbhs_pkt_push(pipe, pkt, uep->handler, |
162 | req->buf, req->length, req->zero); | ||
168 | req->actual = 0; | 163 | req->actual = 0; |
169 | req->status = -EINPROGRESS; | 164 | req->status = -EINPROGRESS; |
170 | 165 | ||
@@ -187,22 +182,15 @@ static struct usbhsg_request *usbhsg_queue_get(struct usbhsg_uep *uep) | |||
187 | return usbhsg_pkt_to_ureq(pkt); | 182 | return usbhsg_pkt_to_ureq(pkt); |
188 | } | 183 | } |
189 | 184 | ||
190 | #define usbhsg_queue_prepare(uep) __usbhsg_queue_handler(uep, 1); | 185 | static int usbhsg_queue_start(struct usbhsg_uep *uep) |
191 | #define usbhsg_queue_handle(uep) __usbhsg_queue_handler(uep, 0); | ||
192 | static int __usbhsg_queue_handler(struct usbhsg_uep *uep, int prepare) | ||
193 | { | 186 | { |
194 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | 187 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); |
195 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | 188 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); |
196 | struct usbhsg_request *ureq; | 189 | struct usbhs_pkt *pkt; |
197 | spinlock_t *lock; | 190 | spinlock_t *lock; |
198 | unsigned long flags; | 191 | unsigned long flags; |
199 | int ret = 0; | 192 | int ret = 0; |
200 | 193 | ||
201 | if (!uep->handler) { | ||
202 | dev_err(dev, "no handler function\n"); | ||
203 | return -EIO; | ||
204 | } | ||
205 | |||
206 | /* | 194 | /* |
207 | * CAUTION [*queue handler*] | 195 | * CAUTION [*queue handler*] |
208 | * | 196 | * |
@@ -224,13 +212,10 @@ static int __usbhsg_queue_handler(struct usbhsg_uep *uep, int prepare) | |||
224 | /****************** spin try lock *******************/ | 212 | /****************** spin try lock *******************/ |
225 | lock = usbhsg_trylock(gpriv, &flags); | 213 | lock = usbhsg_trylock(gpriv, &flags); |
226 | 214 | ||
227 | ureq = usbhsg_queue_get(uep); | 215 | pkt = usbhs_pkt_get(pipe); |
228 | if (ureq) { | 216 | if (pkt) |
229 | if (prepare) | 217 | ret = usbhs_pkt_start(pkt); |
230 | ret = uep->handler->prepare(uep, ureq); | 218 | |
231 | else | ||
232 | ret = uep->handler->try_run(uep, ureq); | ||
233 | } | ||
234 | usbhsg_unlock(lock, &flags); | 219 | usbhsg_unlock(lock, &flags); |
235 | /******************** spin unlock ******************/ | 220 | /******************** spin unlock ******************/ |
236 | 221 | ||
@@ -277,59 +262,10 @@ static void usbhsg_queue_pop(struct usbhsg_uep *uep, | |||
277 | 262 | ||
278 | /* more request ? */ | 263 | /* more request ? */ |
279 | if (0 == status) | 264 | if (0 == status) |
280 | usbhsg_queue_prepare(uep); | 265 | usbhsg_queue_start(uep); |
281 | } | 266 | } |
282 | 267 | ||
283 | /* | 268 | static void usbhsg_queue_done(struct usbhs_pkt *pkt) |
284 | * irq enable/disable function | ||
285 | */ | ||
286 | #define usbhsg_irq_callback_ctrl(uep, status, enable) \ | ||
287 | ({ \ | ||
288 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); \ | ||
289 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); \ | ||
290 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); \ | ||
291 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); \ | ||
292 | if (!mod) \ | ||
293 | return; \ | ||
294 | if (enable) \ | ||
295 | mod->irq_##status |= (1 << usbhs_pipe_number(pipe)); \ | ||
296 | else \ | ||
297 | mod->irq_##status &= ~(1 << usbhs_pipe_number(pipe)); \ | ||
298 | usbhs_irq_callback_update(priv, mod); \ | ||
299 | }) | ||
300 | |||
301 | static void usbhsg_irq_empty_ctrl(struct usbhsg_uep *uep, int enable) | ||
302 | { | ||
303 | usbhsg_irq_callback_ctrl(uep, bempsts, enable); | ||
304 | } | ||
305 | |||
306 | static void usbhsg_irq_ready_ctrl(struct usbhsg_uep *uep, int enable) | ||
307 | { | ||
308 | usbhsg_irq_callback_ctrl(uep, brdysts, enable); | ||
309 | } | ||
310 | |||
311 | /* | ||
312 | * handler function | ||
313 | */ | ||
314 | static int usbhsg_try_run_ctrl_stage_end(struct usbhsg_uep *uep, | ||
315 | struct usbhsg_request *ureq) | ||
316 | { | ||
317 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
318 | |||
319 | /* | ||
320 | ********* assume under spin lock ********* | ||
321 | */ | ||
322 | |||
323 | usbhs_dcp_control_transfer_done(pipe); | ||
324 | usbhsg_queue_pop(uep, ureq, 0); | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | /* | ||
330 | * packet send hander | ||
331 | */ | ||
332 | static void usbhsg_send_packet_done(struct usbhs_pkt *pkt) | ||
333 | { | 269 | { |
334 | struct usbhs_pipe *pipe = pkt->pipe; | 270 | struct usbhs_pipe *pipe = pkt->pipe; |
335 | struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); | 271 | struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); |
@@ -340,108 +276,6 @@ static void usbhsg_send_packet_done(struct usbhs_pkt *pkt) | |||
340 | usbhsg_queue_pop(uep, ureq, 0); | 276 | usbhsg_queue_pop(uep, ureq, 0); |
341 | } | 277 | } |
342 | 278 | ||
343 | static int usbhsg_try_run_send_packet(struct usbhsg_uep *uep, | ||
344 | struct usbhsg_request *ureq) | ||
345 | { | ||
346 | struct usbhs_pkt *pkt = usbhsg_ureq_to_pkt(ureq); | ||
347 | |||
348 | /* | ||
349 | ********* assume under spin lock ********* | ||
350 | */ | ||
351 | |||
352 | usbhs_fifo_write(pkt); | ||
353 | |||
354 | return 0; | ||
355 | } | ||
356 | |||
357 | static int usbhsg_prepare_send_packet(struct usbhsg_uep *uep, | ||
358 | struct usbhsg_request *ureq) | ||
359 | { | ||
360 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
361 | |||
362 | /* | ||
363 | ********* assume under spin lock ********* | ||
364 | */ | ||
365 | |||
366 | usbhs_fifo_prepare_write(pipe); | ||
367 | usbhsg_try_run_send_packet(uep, ureq); | ||
368 | |||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | /* | ||
373 | * packet recv hander | ||
374 | */ | ||
375 | static void usbhsg_receive_packet_done(struct usbhs_pkt *pkt) | ||
376 | { | ||
377 | struct usbhs_pipe *pipe = pkt->pipe; | ||
378 | struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); | ||
379 | struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); | ||
380 | |||
381 | ureq->req.actual = pkt->actual; | ||
382 | |||
383 | usbhsg_queue_pop(uep, ureq, 0); | ||
384 | } | ||
385 | |||
386 | static int usbhsg_try_run_receive_packet(struct usbhsg_uep *uep, | ||
387 | struct usbhsg_request *ureq) | ||
388 | { | ||
389 | struct usbhs_pkt *pkt = usbhsg_ureq_to_pkt(ureq); | ||
390 | |||
391 | /* | ||
392 | ********* assume under spin lock ********* | ||
393 | */ | ||
394 | |||
395 | return usbhs_fifo_read(pkt); | ||
396 | } | ||
397 | |||
398 | static int usbhsg_prepare_receive_packet(struct usbhsg_uep *uep, | ||
399 | struct usbhsg_request *ureq) | ||
400 | { | ||
401 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
402 | |||
403 | /* | ||
404 | ********* assume under spin lock ********* | ||
405 | */ | ||
406 | |||
407 | return usbhs_fifo_prepare_read(pipe); | ||
408 | } | ||
409 | |||
410 | static struct usbhsg_pipe_handle usbhsg_handler_send_by_empty = { | ||
411 | .prepare = usbhsg_prepare_send_packet, | ||
412 | .try_run = usbhsg_try_run_send_packet, | ||
413 | }; | ||
414 | |||
415 | static struct usbhsg_pipe_handle usbhsg_handler_send_by_ready = { | ||
416 | .prepare = usbhsg_prepare_send_packet, | ||
417 | .try_run = usbhsg_try_run_send_packet, | ||
418 | }; | ||
419 | |||
420 | static struct usbhsg_pipe_handle usbhsg_handler_recv_by_ready = { | ||
421 | .prepare = usbhsg_prepare_receive_packet, | ||
422 | .try_run = usbhsg_try_run_receive_packet, | ||
423 | }; | ||
424 | |||
425 | static struct usbhsg_pipe_handle usbhsg_handler_ctrl_stage_end = { | ||
426 | .prepare = usbhsg_try_run_ctrl_stage_end, | ||
427 | .try_run = usbhsg_try_run_ctrl_stage_end, | ||
428 | }; | ||
429 | |||
430 | /* | ||
431 | * DCP pipe can NOT use "ready interrupt" for "send" | ||
432 | * it should use "empty" interrupt. | ||
433 | * see | ||
434 | * "Operation" - "Interrupt Function" - "BRDY Interrupt" | ||
435 | * | ||
436 | * on the other hand, normal pipe can use "ready interrupt" for "send" | ||
437 | * even though it is single/double buffer | ||
438 | */ | ||
439 | #define usbhsg_handler_send_ctrl usbhsg_handler_send_by_empty | ||
440 | #define usbhsg_handler_recv_ctrl usbhsg_handler_recv_by_ready | ||
441 | |||
442 | #define usbhsg_handler_send_packet usbhsg_handler_send_by_ready | ||
443 | #define usbhsg_handler_recv_packet usbhsg_handler_recv_by_ready | ||
444 | |||
445 | /* | 279 | /* |
446 | * USB_TYPE_STANDARD / clear feature functions | 280 | * USB_TYPE_STANDARD / clear feature functions |
447 | */ | 281 | */ |
@@ -473,7 +307,7 @@ static int usbhsg_recip_handler_std_clear_endpoint(struct usbhs_priv *priv, | |||
473 | 307 | ||
474 | usbhsg_recip_handler_std_control_done(priv, uep, ctrl); | 308 | usbhsg_recip_handler_std_control_done(priv, uep, ctrl); |
475 | 309 | ||
476 | usbhsg_queue_prepare(uep); | 310 | usbhsg_queue_start(uep); |
477 | 311 | ||
478 | return 0; | 312 | return 0; |
479 | } | 313 | } |
@@ -580,13 +414,13 @@ static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv, | |||
580 | 414 | ||
581 | switch (stage) { | 415 | switch (stage) { |
582 | case READ_DATA_STAGE: | 416 | case READ_DATA_STAGE: |
583 | dcp->handler = &usbhsg_handler_send_ctrl; | 417 | dcp->handler = &usbhs_fifo_push_handler; |
584 | break; | 418 | break; |
585 | case WRITE_DATA_STAGE: | 419 | case WRITE_DATA_STAGE: |
586 | dcp->handler = &usbhsg_handler_recv_ctrl; | 420 | dcp->handler = &usbhs_fifo_pop_handler; |
587 | break; | 421 | break; |
588 | case NODATA_STATUS_STAGE: | 422 | case NODATA_STATUS_STAGE: |
589 | dcp->handler = &usbhsg_handler_ctrl_stage_end; | 423 | dcp->handler = &usbhs_ctrl_stage_end_handler; |
590 | break; | 424 | break; |
591 | default: | 425 | default: |
592 | return ret; | 426 | return ret; |
@@ -620,72 +454,6 @@ static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv, | |||
620 | return ret; | 454 | return ret; |
621 | } | 455 | } |
622 | 456 | ||
623 | static int usbhsg_irq_empty(struct usbhs_priv *priv, | ||
624 | struct usbhs_irq_state *irq_state) | ||
625 | { | ||
626 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); | ||
627 | struct usbhsg_uep *uep; | ||
628 | struct usbhs_pipe *pipe; | ||
629 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
630 | int i, ret; | ||
631 | |||
632 | if (!irq_state->bempsts) { | ||
633 | dev_err(dev, "debug %s !!\n", __func__); | ||
634 | return -EIO; | ||
635 | } | ||
636 | |||
637 | dev_dbg(dev, "irq empty [0x%04x]\n", irq_state->bempsts); | ||
638 | |||
639 | /* | ||
640 | * search interrupted "pipe" | ||
641 | * not "uep". | ||
642 | */ | ||
643 | usbhs_for_each_pipe_with_dcp(pipe, priv, i) { | ||
644 | if (!(irq_state->bempsts & (1 << i))) | ||
645 | continue; | ||
646 | |||
647 | uep = usbhsg_pipe_to_uep(pipe); | ||
648 | ret = usbhsg_queue_handle(uep); | ||
649 | if (ret < 0) | ||
650 | dev_err(dev, "send error %d : %d\n", i, ret); | ||
651 | } | ||
652 | |||
653 | return 0; | ||
654 | } | ||
655 | |||
656 | static int usbhsg_irq_ready(struct usbhs_priv *priv, | ||
657 | struct usbhs_irq_state *irq_state) | ||
658 | { | ||
659 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); | ||
660 | struct usbhsg_uep *uep; | ||
661 | struct usbhs_pipe *pipe; | ||
662 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
663 | int i, ret; | ||
664 | |||
665 | if (!irq_state->brdysts) { | ||
666 | dev_err(dev, "debug %s !!\n", __func__); | ||
667 | return -EIO; | ||
668 | } | ||
669 | |||
670 | dev_dbg(dev, "irq ready [0x%04x]\n", irq_state->brdysts); | ||
671 | |||
672 | /* | ||
673 | * search interrupted "pipe" | ||
674 | * not "uep". | ||
675 | */ | ||
676 | usbhs_for_each_pipe_with_dcp(pipe, priv, i) { | ||
677 | if (!(irq_state->brdysts & (1 << i))) | ||
678 | continue; | ||
679 | |||
680 | uep = usbhsg_pipe_to_uep(pipe); | ||
681 | ret = usbhsg_queue_handle(uep); | ||
682 | if (ret < 0) | ||
683 | dev_err(dev, "receive error %d : %d\n", i, ret); | ||
684 | } | ||
685 | |||
686 | return 0; | ||
687 | } | ||
688 | |||
689 | /* | 457 | /* |
690 | * | 458 | * |
691 | * usb_dcp_ops | 459 | * usb_dcp_ops |
@@ -716,7 +484,6 @@ static int usbhsg_pipe_disable(struct usbhsg_uep *uep) | |||
716 | { | 484 | { |
717 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | 485 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); |
718 | struct usbhsg_request *ureq; | 486 | struct usbhsg_request *ureq; |
719 | int disable = 0; | ||
720 | 487 | ||
721 | /* | 488 | /* |
722 | ********* assume under spin lock ********* | 489 | ********* assume under spin lock ********* |
@@ -724,12 +491,6 @@ static int usbhsg_pipe_disable(struct usbhsg_uep *uep) | |||
724 | 491 | ||
725 | usbhs_pipe_disable(pipe); | 492 | usbhs_pipe_disable(pipe); |
726 | 493 | ||
727 | /* | ||
728 | * disable pipe irq | ||
729 | */ | ||
730 | usbhsg_irq_empty_ctrl(uep, disable); | ||
731 | usbhsg_irq_ready_ctrl(uep, disable); | ||
732 | |||
733 | while (1) { | 494 | while (1) { |
734 | ureq = usbhsg_queue_get(uep); | 495 | ureq = usbhsg_queue_get(uep); |
735 | if (!ureq) | 496 | if (!ureq) |
@@ -782,9 +543,9 @@ static int usbhsg_ep_enable(struct usb_ep *ep, | |||
782 | pipe->mod_private = uep; | 543 | pipe->mod_private = uep; |
783 | 544 | ||
784 | if (usb_endpoint_dir_in(desc)) | 545 | if (usb_endpoint_dir_in(desc)) |
785 | uep->handler = &usbhsg_handler_send_packet; | 546 | uep->handler = &usbhs_fifo_push_handler; |
786 | else | 547 | else |
787 | uep->handler = &usbhsg_handler_recv_packet; | 548 | uep->handler = &usbhs_fifo_pop_handler; |
788 | 549 | ||
789 | ret = 0; | 550 | ret = 0; |
790 | } | 551 | } |
@@ -879,7 +640,7 @@ static int usbhsg_ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
879 | usbhsg_unlock(lock, &flags); | 640 | usbhsg_unlock(lock, &flags); |
880 | /******************** spin unlock ******************/ | 641 | /******************** spin unlock ******************/ |
881 | 642 | ||
882 | usbhsg_queue_prepare(uep); | 643 | usbhsg_queue_start(uep); |
883 | 644 | ||
884 | return ret; | 645 | return ret; |
885 | } | 646 | } |
@@ -1006,8 +767,8 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) | |||
1006 | * pipe initialize and enable DCP | 767 | * pipe initialize and enable DCP |
1007 | */ | 768 | */ |
1008 | usbhs_pipe_init(priv, | 769 | usbhs_pipe_init(priv, |
1009 | usbhsg_send_packet_done, | 770 | usbhsg_queue_done); |
1010 | usbhsg_receive_packet_done); | 771 | usbhs_fifo_init(priv); |
1011 | usbhsg_uep_init(gpriv); | 772 | usbhsg_uep_init(gpriv); |
1012 | usbhsg_dcp_enable(dcp); | 773 | usbhsg_dcp_enable(dcp); |
1013 | 774 | ||
@@ -1026,10 +787,6 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) | |||
1026 | */ | 787 | */ |
1027 | mod->irq_dev_state = usbhsg_irq_dev_state; | 788 | mod->irq_dev_state = usbhsg_irq_dev_state; |
1028 | mod->irq_ctrl_stage = usbhsg_irq_ctrl_stage; | 789 | mod->irq_ctrl_stage = usbhsg_irq_ctrl_stage; |
1029 | mod->irq_empty = usbhsg_irq_empty; | ||
1030 | mod->irq_ready = usbhsg_irq_ready; | ||
1031 | mod->irq_bempsts = 0; | ||
1032 | mod->irq_brdysts = 0; | ||
1033 | usbhs_irq_callback_update(priv, mod); | 790 | usbhs_irq_callback_update(priv, mod); |
1034 | 791 | ||
1035 | usbhsg_try_start_unlock: | 792 | usbhsg_try_start_unlock: |
@@ -1059,13 +816,11 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status) | |||
1059 | !usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD)) | 816 | !usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD)) |
1060 | goto usbhsg_try_stop_unlock; | 817 | goto usbhsg_try_stop_unlock; |
1061 | 818 | ||
819 | usbhs_fifo_quit(priv); | ||
820 | |||
1062 | /* disable all irq */ | 821 | /* disable all irq */ |
1063 | mod->irq_dev_state = NULL; | 822 | mod->irq_dev_state = NULL; |
1064 | mod->irq_ctrl_stage = NULL; | 823 | mod->irq_ctrl_stage = NULL; |
1065 | mod->irq_empty = NULL; | ||
1066 | mod->irq_ready = NULL; | ||
1067 | mod->irq_bempsts = 0; | ||
1068 | mod->irq_brdysts = 0; | ||
1069 | usbhs_irq_callback_update(priv, mod); | 824 | usbhs_irq_callback_update(priv, mod); |
1070 | 825 | ||
1071 | usbhsg_dcp_disable(dcp); | 826 | usbhsg_dcp_disable(dcp); |
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c index 6e77791f07c8..56137d59e3b2 100644 --- a/drivers/usb/renesas_usbhs/pipe.c +++ b/drivers/usb/renesas_usbhs/pipe.c | |||
@@ -532,13 +532,18 @@ static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type) | |||
532 | } | 532 | } |
533 | 533 | ||
534 | void usbhs_pipe_init(struct usbhs_priv *priv, | 534 | void usbhs_pipe_init(struct usbhs_priv *priv, |
535 | void (*tx_done)(struct usbhs_pkt *pkt), | 535 | void (*done)(struct usbhs_pkt *pkt)) |
536 | void (*rx_done)(struct usbhs_pkt *pkt)) | ||
537 | { | 536 | { |
538 | struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv); | 537 | struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv); |
538 | struct device *dev = usbhs_priv_to_dev(priv); | ||
539 | struct usbhs_pipe *pipe; | 539 | struct usbhs_pipe *pipe; |
540 | int i; | 540 | int i; |
541 | 541 | ||
542 | if (!done) { | ||
543 | dev_err(dev, "no done function\n"); | ||
544 | return; | ||
545 | } | ||
546 | |||
542 | /* | 547 | /* |
543 | * FIXME | 548 | * FIXME |
544 | * | 549 | * |
@@ -565,8 +570,7 @@ void usbhs_pipe_init(struct usbhs_priv *priv, | |||
565 | usbhsp_pipectrl_set(pipe, ACLRM, 0); | 570 | usbhsp_pipectrl_set(pipe, ACLRM, 0); |
566 | } | 571 | } |
567 | 572 | ||
568 | info->tx_done = tx_done; | 573 | info->done = done; |
569 | info->rx_done = rx_done; | ||
570 | } | 574 | } |
571 | 575 | ||
572 | struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv, | 576 | struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv, |
diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h index 535e6aa434c7..20e3cf46f70c 100644 --- a/drivers/usb/renesas_usbhs/pipe.h +++ b/drivers/usb/renesas_usbhs/pipe.h | |||
@@ -42,8 +42,7 @@ struct usbhs_pipe_info { | |||
42 | int size; /* array size of "pipe" */ | 42 | int size; /* array size of "pipe" */ |
43 | int bufnmb_last; /* FIXME : driver needs good allocator */ | 43 | int bufnmb_last; /* FIXME : driver needs good allocator */ |
44 | 44 | ||
45 | void (*tx_done)(struct usbhs_pkt *pkt); | 45 | void (*done)(struct usbhs_pkt *pkt); |
46 | void (*rx_done)(struct usbhs_pkt *pkt); | ||
47 | }; | 46 | }; |
48 | 47 | ||
49 | /* | 48 | /* |
@@ -82,8 +81,7 @@ void usbhs_pipe_remove(struct usbhs_priv *priv); | |||
82 | int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe); | 81 | int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe); |
83 | int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe); | 82 | int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe); |
84 | void usbhs_pipe_init(struct usbhs_priv *priv, | 83 | void usbhs_pipe_init(struct usbhs_priv *priv, |
85 | void (*tx_done)(struct usbhs_pkt *pkt), | 84 | void (*done)(struct usbhs_pkt *pkt)); |
86 | void (*rx_done)(struct usbhs_pkt *pkt)); | ||
87 | int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe); | 85 | int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe); |
88 | void usbhs_pipe_clear_sequence(struct usbhs_pipe *pipe); | 86 | void usbhs_pipe_clear_sequence(struct usbhs_pipe *pipe); |
89 | int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe); | 87 | int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe); |