aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-06-06 01:18:07 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-06-07 12:10:07 -0400
commit4bd0481152d0d5e8326d7e24329b0069713ed718 (patch)
treeeee0db4a089f8a853305293a72bc10b3d8b8177c /drivers
parente8d548d549688d335236f7f6f8bcee141a207ff8 (diff)
usb: renesas_usbhs: divide data transfer functions
DMAEngine will be supported to this driver in the future. Then, both PIO and DMA data transfer method should be supported. But, the transfer function can returns the result immediately in PIO version, but it can't in DMA version. This patch divides data transfer functions into top/bottom half in preparation for DMAEngine support. 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/common.h1
-rw-r--r--drivers/usb/renesas_usbhs/fifo.c57
-rw-r--r--drivers/usb/renesas_usbhs/fifo.h21
-rw-r--r--drivers/usb/renesas_usbhs/mod_gadget.c115
-rw-r--r--drivers/usb/renesas_usbhs/pipe.c8
-rw-r--r--drivers/usb/renesas_usbhs/pipe.h8
6 files changed, 150 insertions, 60 deletions
diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h
index 24f756024bed..0aadcb402764 100644
--- a/drivers/usb/renesas_usbhs/common.h
+++ b/drivers/usb/renesas_usbhs/common.h
@@ -24,7 +24,6 @@ struct usbhs_priv;
24 24
25#include "./mod.h" 25#include "./mod.h"
26#include "./pipe.h" 26#include "./pipe.h"
27#include "./fifo.h"
28 27
29/* 28/*
30 * 29 *
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index 3fd3adf90541..098388489813 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -20,6 +20,20 @@
20#include "./pipe.h" 20#include "./pipe.h"
21 21
22/* 22/*
23 * packet info function
24 */
25void usbhs_pkt_update(struct usbhs_pkt *pkt,
26 struct usbhs_pipe *pipe,
27 void *buf, int len)
28{
29 pkt->pipe = pipe;
30 pkt->buf = buf;
31 pkt->length = len;
32 pkt->actual = 0;
33 pkt->maxp = 0;
34}
35
36/*
23 * FIFO ctrl 37 * FIFO ctrl
24 */ 38 */
25static void usbhsf_send_terminator(struct usbhs_pipe *pipe) 39static void usbhsf_send_terminator(struct usbhs_pipe *pipe)
@@ -93,13 +107,16 @@ int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe)
93 return usbhsf_fifo_select(pipe, 1); 107 return usbhsf_fifo_select(pipe, 1);
94} 108}
95 109
96int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len) 110int usbhs_fifo_write(struct usbhs_pkt *pkt)
97{ 111{
112 struct usbhs_pipe *pipe = pkt->pipe;
98 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 113 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
114 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
99 void __iomem *addr = priv->base + CFIFO; 115 void __iomem *addr = priv->base + CFIFO;
100 int maxp = usbhs_pipe_get_maxpacket(pipe); 116 int maxp = usbhs_pipe_get_maxpacket(pipe);
101 int total_len; 117 int total_len;
102 int i, ret; 118 u8 *buf = pkt->buf;
119 int i, ret, len;
103 120
104 ret = usbhs_pipe_is_accessible(pipe); 121 ret = usbhs_pipe_is_accessible(pipe);
105 if (ret < 0) 122 if (ret < 0)
@@ -113,7 +130,7 @@ int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len)
113 if (ret < 0) 130 if (ret < 0)
114 return ret; 131 return ret;
115 132
116 len = min(len, maxp); 133 len = min(pkt->length, maxp);
117 total_len = len; 134 total_len = len;
118 135
119 /* 136 /*
@@ -135,7 +152,16 @@ int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len)
135 if (total_len < maxp) 152 if (total_len < maxp)
136 usbhsf_send_terminator(pipe); 153 usbhsf_send_terminator(pipe);
137 154
138 return total_len; 155 usbhs_pipe_enable(pipe);
156
157 /* update pkt */
158 if (info->tx_done) {
159 pkt->actual = total_len;
160 pkt->maxp = maxp;
161 info->tx_done(pkt);
162 }
163
164 return 0;
139} 165}
140 166
141int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe) 167int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe)
@@ -154,13 +180,16 @@ int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe)
154 return ret; 180 return ret;
155} 181}
156 182
157int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len) 183int usbhs_fifo_read(struct usbhs_pkt *pkt)
158{ 184{
185 struct usbhs_pipe *pipe = pkt->pipe;
159 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 186 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
187 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
160 void __iomem *addr = priv->base + CFIFO; 188 void __iomem *addr = priv->base + CFIFO;
161 int rcv_len; 189 u8 *buf = pkt->buf;
190 int rcv_len, len;
162 int i, ret; 191 int i, ret;
163 int total_len; 192 int total_len = 0;
164 u32 data = 0; 193 u32 data = 0;
165 194
166 ret = usbhsf_fifo_select(pipe, 0); 195 ret = usbhsf_fifo_select(pipe, 0);
@@ -181,10 +210,10 @@ int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len)
181 */ 210 */
182 if (0 == rcv_len) { 211 if (0 == rcv_len) {
183 usbhsf_fifo_clear(pipe); 212 usbhsf_fifo_clear(pipe);
184 return 0; 213 goto usbhs_fifo_read_end;
185 } 214 }
186 215
187 len = min(rcv_len, len); 216 len = min(rcv_len, pkt->length);
188 total_len = len; 217 total_len = len;
189 218
190 /* 219 /*
@@ -207,5 +236,13 @@ int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len)
207 buf[i] = (data >> ((i & 0x03) * 8)) & 0xff; 236 buf[i] = (data >> ((i & 0x03) * 8)) & 0xff;
208 } 237 }
209 238
210 return total_len; 239usbhs_fifo_read_end:
240 if (info->rx_done) {
241 /* update pkt */
242 pkt->actual = total_len;
243 pkt->maxp = usbhs_pipe_get_maxpacket(pipe);
244 info->rx_done(pkt);
245 }
246
247 return 0;
211} 248}
diff --git a/drivers/usb/renesas_usbhs/fifo.h b/drivers/usb/renesas_usbhs/fifo.h
index 75a7c1577ad3..758d85dd31dd 100644
--- a/drivers/usb/renesas_usbhs/fifo.h
+++ b/drivers/usb/renesas_usbhs/fifo.h
@@ -17,14 +17,29 @@
17#ifndef RENESAS_USB_FIFO_H 17#ifndef RENESAS_USB_FIFO_H
18#define RENESAS_USB_FIFO_H 18#define RENESAS_USB_FIFO_H
19 19
20#include "common.h" 20#include "pipe.h"
21
22struct usbhs_pkt {
23 struct usbhs_pipe *pipe;
24 int maxp;
25 void *buf;
26 int length;
27 int actual;
28};
21 29
22/* 30/*
23 * fifo 31 * fifo
24 */ 32 */
25int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len); 33int usbhs_fifo_write(struct usbhs_pkt *pkt);
26int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len); 34int usbhs_fifo_read(struct usbhs_pkt *pkt);
27int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe); 35int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe);
28int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe); 36int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe);
29 37
38/*
39 * packet info
40 */
41void usbhs_pkt_update(struct usbhs_pkt *pkt,
42 struct usbhs_pipe *pipe,
43 void *buf, int len);
44
30#endif /* RENESAS_USB_FIFO_H */ 45#endif /* RENESAS_USB_FIFO_H */
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index 128c8da8db85..4a1d1fcc90fd 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -27,6 +27,7 @@
27struct usbhsg_request { 27struct usbhsg_request {
28 struct usb_request req; 28 struct usb_request req;
29 struct list_head node; 29 struct list_head node;
30 struct usbhs_pkt pkt;
30}; 31};
31 32
32#define EP_NAME_SIZE 8 33#define EP_NAME_SIZE 8
@@ -110,6 +111,10 @@ struct usbhsg_recip_handle {
110#define usbhsg_pipe_to_uep(p) ((p)->mod_private) 111#define usbhsg_pipe_to_uep(p) ((p)->mod_private)
111#define usbhsg_is_dcp(u) ((u) == usbhsg_gpriv_to_dcp((u)->gpriv)) 112#define usbhsg_is_dcp(u) ((u) == usbhsg_gpriv_to_dcp((u)->gpriv))
112 113
114#define usbhsg_ureq_to_pkt(u) (&(u)->pkt)
115#define usbhsg_pkt_to_ureq(i) \
116 container_of(i, struct usbhsg_request, pkt)
117
113#define usbhsg_is_not_connected(gp) ((gp)->gadget.speed == USB_SPEED_UNKNOWN) 118#define usbhsg_is_not_connected(gp) ((gp)->gadget.speed == USB_SPEED_UNKNOWN)
114 119
115/* status */ 120/* status */
@@ -319,38 +324,32 @@ static int usbhsg_try_run_ctrl_stage_end(struct usbhsg_uep *uep,
319 return 0; 324 return 0;
320} 325}
321 326
322static int usbhsg_try_run_send_packet(struct usbhsg_uep *uep, 327/*
323 struct usbhsg_request *ureq) 328 * packet send hander
329 */
330static void usbhsg_try_run_send_packet_bh(struct usbhs_pkt *pkt)
324{ 331{
325 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 332 struct usbhs_pipe *pipe = pkt->pipe;
333 struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe);
334 struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt);
326 struct usb_request *req = &ureq->req; 335 struct usb_request *req = &ureq->req;
327 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 336 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
328 struct device *dev = usbhsg_gpriv_to_dev(gpriv); 337 struct device *dev = usbhsg_gpriv_to_dev(gpriv);
329 void *buf; 338 int remainder, send, maxp;
330 int remainder, send;
331 int is_done = 0; 339 int is_done = 0;
332 int enable; 340 int enable;
333 int maxp;
334 341
335 /* 342 maxp = pkt->maxp;
336 ********* assume under spin lock ********* 343 send = pkt->actual;
337 */ 344 remainder = pkt->length;
338
339 maxp = usbhs_pipe_get_maxpacket(pipe);
340 buf = req->buf + req->actual;
341 remainder = req->length - req->actual;
342
343 send = usbhs_fifo_write(pipe, buf, remainder);
344 345
345 /* 346 /*
346 * send < 0 : pipe busy
347 * send = 0 : send zero packet 347 * send = 0 : send zero packet
348 * send > 0 : send data 348 * send > 0 : send data
349 * 349 *
350 * send <= max_packet 350 * send <= max_packet
351 */ 351 */
352 if (send > 0) 352 req->actual += send;
353 req->actual += send;
354 353
355 /* send all packet ? */ 354 /* send all packet ? */
356 if (send < remainder) 355 if (send < remainder)
@@ -372,13 +371,6 @@ static int usbhsg_try_run_send_packet(struct usbhsg_uep *uep,
372 uep->handler->irq_mask(uep, enable); 371 uep->handler->irq_mask(uep, enable);
373 372
374 /* 373 /*
375 * usbhs_fifo_enable execute
376 * - after callback_update,
377 * - before queue_pop / stage_end
378 */
379 usbhs_pipe_enable(pipe);
380
381 /*
382 * all data were sent ? 374 * all data were sent ?
383 */ 375 */
384 if (is_done) { 376 if (is_done) {
@@ -389,6 +381,30 @@ static int usbhsg_try_run_send_packet(struct usbhsg_uep *uep,
389 381
390 usbhsg_queue_pop(uep, ureq, 0); 382 usbhsg_queue_pop(uep, ureq, 0);
391 } 383 }
384}
385
386static int usbhsg_try_run_send_packet(struct usbhsg_uep *uep,
387 struct usbhsg_request *ureq)
388{
389 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
390 struct usb_request *req = &ureq->req;
391 struct usbhs_pkt *pkt = usbhsg_ureq_to_pkt(ureq);
392 int ret;
393
394 /*
395 ********* assume under spin lock *********
396 */
397
398 usbhs_pkt_update(pkt, pipe,
399 req->buf + req->actual,
400 req->length - req->actual);
401
402 ret = usbhs_fifo_write(pkt);
403 if (ret < 0) {
404 /* pipe is busy.
405 * retry in interrupt */
406 uep->handler->irq_mask(uep, 1);
407 }
392 408
393 return 0; 409 return 0;
394} 410}
@@ -408,35 +424,30 @@ static int usbhsg_prepare_send_packet(struct usbhsg_uep *uep,
408 return 0; 424 return 0;
409} 425}
410 426
411static int usbhsg_try_run_receive_packet(struct usbhsg_uep *uep, 427/*
412 struct usbhsg_request *ureq) 428 * packet recv hander
429 */
430static void usbhsg_try_run_receive_packet_bh(struct usbhs_pkt *pkt)
413{ 431{
414 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 432 struct usbhs_pipe *pipe = pkt->pipe;
433 struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe);
434 struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt);
415 struct usb_request *req = &ureq->req; 435 struct usb_request *req = &ureq->req;
416 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 436 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
417 struct device *dev = usbhsg_gpriv_to_dev(gpriv); 437 struct device *dev = usbhsg_gpriv_to_dev(gpriv);
418 void *buf; 438 int remainder, recv, maxp;
419 int maxp;
420 int remainder, recv;
421 int is_done = 0; 439 int is_done = 0;
422 440
423 /* 441 maxp = pkt->maxp;
424 ********* assume under spin lock ********* 442 remainder = pkt->length;
425 */ 443 recv = pkt->actual;
426
427 maxp = usbhs_pipe_get_maxpacket(pipe);
428 buf = req->buf + req->actual;
429 remainder = req->length - req->actual;
430 444
431 recv = usbhs_fifo_read(pipe, buf, remainder);
432 /* 445 /*
433 * recv < 0 : pipe busy 446 * recv < 0 : pipe busy
434 * recv >= 0 : receive data 447 * recv >= 0 : receive data
435 * 448 *
436 * recv <= max_packet 449 * recv <= max_packet
437 */ 450 */
438 if (recv < 0)
439 return -EBUSY;
440 451
441 /* update parameters */ 452 /* update parameters */
442 req->actual += recv; 453 req->actual += recv;
@@ -457,8 +468,24 @@ static int usbhsg_try_run_receive_packet(struct usbhsg_uep *uep,
457 usbhs_pipe_disable(pipe); 468 usbhs_pipe_disable(pipe);
458 usbhsg_queue_pop(uep, ureq, 0); 469 usbhsg_queue_pop(uep, ureq, 0);
459 } 470 }
471}
460 472
461 return 0; 473static int usbhsg_try_run_receive_packet(struct usbhsg_uep *uep,
474 struct usbhsg_request *ureq)
475{
476 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
477 struct usb_request *req = &ureq->req;
478 struct usbhs_pkt *pkt = usbhsg_ureq_to_pkt(ureq);
479
480 /*
481 ********* assume under spin lock *********
482 */
483
484 usbhs_pkt_update(pkt, pipe,
485 req->buf + req->actual,
486 req->length - req->actual);
487
488 return usbhs_fifo_read(pkt);
462} 489}
463 490
464static int usbhsg_prepare_receive_packet(struct usbhsg_uep *uep, 491static int usbhsg_prepare_receive_packet(struct usbhsg_uep *uep,
@@ -1086,7 +1113,9 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status)
1086 /* 1113 /*
1087 * pipe initialize and enable DCP 1114 * pipe initialize and enable DCP
1088 */ 1115 */
1089 usbhs_pipe_init(priv); 1116 usbhs_pipe_init(priv,
1117 usbhsg_try_run_send_packet_bh,
1118 usbhsg_try_run_receive_packet_bh);
1090 usbhsg_uep_init(gpriv); 1119 usbhsg_uep_init(gpriv);
1091 usbhsg_dcp_enable(dcp); 1120 usbhsg_dcp_enable(dcp);
1092 1121
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c
index 75e9e3cbc0e5..7a11616d6e28 100644
--- a/drivers/usb/renesas_usbhs/pipe.c
+++ b/drivers/usb/renesas_usbhs/pipe.c
@@ -531,7 +531,9 @@ static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type)
531 return pipe; 531 return pipe;
532} 532}
533 533
534void usbhs_pipe_init(struct usbhs_priv *priv) 534void usbhs_pipe_init(struct usbhs_priv *priv,
535 void (*tx_done)(struct usbhs_pkt *pkt),
536 void (*rx_done)(struct usbhs_pkt *pkt))
535{ 537{
536 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv); 538 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
537 struct usbhs_pipe *pipe; 539 struct usbhs_pipe *pipe;
@@ -561,6 +563,9 @@ void usbhs_pipe_init(struct usbhs_priv *priv)
561 usbhsp_pipectrl_set(pipe, ACLRM, ACLRM); 563 usbhsp_pipectrl_set(pipe, ACLRM, ACLRM);
562 usbhsp_pipectrl_set(pipe, ACLRM, 0); 564 usbhsp_pipectrl_set(pipe, ACLRM, 0);
563 } 565 }
566
567 info->tx_done = tx_done;
568 info->rx_done = rx_done;
564} 569}
565 570
566struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv, 571struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
@@ -639,7 +644,6 @@ void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe)
639 usbhsp_pipectrl_set(pipe, CCPL, CCPL); 644 usbhsp_pipectrl_set(pipe, CCPL, CCPL);
640} 645}
641 646
642
643/* 647/*
644 * pipe module function 648 * pipe module function
645 */ 649 */
diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h
index 2fb69df932ed..1f871b0c4971 100644
--- a/drivers/usb/renesas_usbhs/pipe.h
+++ b/drivers/usb/renesas_usbhs/pipe.h
@@ -18,6 +18,7 @@
18#define RENESAS_USB_PIPE_H 18#define RENESAS_USB_PIPE_H
19 19
20#include "./common.h" 20#include "./common.h"
21#include "./fifo.h"
21 22
22/* 23/*
23 * struct 24 * struct
@@ -39,6 +40,9 @@ struct usbhs_pipe_info {
39 struct usbhs_pipe *pipe; 40 struct usbhs_pipe *pipe;
40 int size; /* array size of "pipe" */ 41 int size; /* array size of "pipe" */
41 int bufnmb_last; /* FIXME : driver needs good allocator */ 42 int bufnmb_last; /* FIXME : driver needs good allocator */
43
44 void (*tx_done)(struct usbhs_pkt *pkt);
45 void (*rx_done)(struct usbhs_pkt *pkt);
42}; 46};
43 47
44/* 48/*
@@ -76,7 +80,9 @@ int usbhs_pipe_probe(struct usbhs_priv *priv);
76void usbhs_pipe_remove(struct usbhs_priv *priv); 80void usbhs_pipe_remove(struct usbhs_priv *priv);
77int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe); 81int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe);
78int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe); 82int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe);
79void usbhs_pipe_init(struct usbhs_priv *priv); 83void usbhs_pipe_init(struct usbhs_priv *priv,
84 void (*tx_done)(struct usbhs_pkt *pkt),
85 void (*rx_done)(struct usbhs_pkt *pkt));
80int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe); 86int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe);
81void usbhs_pipe_clear_sequence(struct usbhs_pipe *pipe); 87void usbhs_pipe_clear_sequence(struct usbhs_pipe *pipe);
82int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe); 88int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe);