diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2011-06-06 01:18:44 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-06-07 12:10:09 -0400 |
commit | d3af90a5e4e8fb7a93d408799682e566c9270808 (patch) | |
tree | 9eb60a7464d0f1eb380d65ff89239b0a5a044f77 /drivers/usb | |
parent | 97664a207bc2601a03a300f00e6922038cd5b99c (diff) |
usb: renesas_usbhs: add usbhsf_fifo
renesas_usbhs has CFIFO/D0FIFO/D1FIFO.
But current renesas_usbhs is using CFIFO (for PIO) only for now.
The fifo selection method is needed for DMAEngine support.
This is a 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/usb')
-rw-r--r-- | drivers/usb/renesas_usbhs/common.c | 9 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/common.h | 5 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/fifo.c | 75 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/fifo.h | 12 |
4 files changed, 77 insertions, 24 deletions
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index f3664d6af661..e510b29216b3 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c | |||
@@ -323,10 +323,14 @@ static int __devinit usbhs_probe(struct platform_device *pdev) | |||
323 | if (ret < 0) | 323 | if (ret < 0) |
324 | goto probe_end_iounmap; | 324 | goto probe_end_iounmap; |
325 | 325 | ||
326 | ret = usbhs_mod_probe(priv); | 326 | ret = usbhs_fifo_probe(priv); |
327 | if (ret < 0) | 327 | if (ret < 0) |
328 | goto probe_end_pipe_exit; | 328 | goto probe_end_pipe_exit; |
329 | 329 | ||
330 | ret = usbhs_mod_probe(priv); | ||
331 | if (ret < 0) | ||
332 | goto probe_end_fifo_exit; | ||
333 | |||
330 | /* dev_set_drvdata should be called after usbhs_mod_init */ | 334 | /* dev_set_drvdata should be called after usbhs_mod_init */ |
331 | dev_set_drvdata(&pdev->dev, priv); | 335 | dev_set_drvdata(&pdev->dev, priv); |
332 | 336 | ||
@@ -374,6 +378,8 @@ probe_end_call_remove: | |||
374 | usbhs_platform_call(priv, hardware_exit, pdev); | 378 | usbhs_platform_call(priv, hardware_exit, pdev); |
375 | probe_end_mod_exit: | 379 | probe_end_mod_exit: |
376 | usbhs_mod_remove(priv); | 380 | usbhs_mod_remove(priv); |
381 | probe_end_fifo_exit: | ||
382 | usbhs_fifo_remove(priv); | ||
377 | probe_end_pipe_exit: | 383 | probe_end_pipe_exit: |
378 | usbhs_pipe_remove(priv); | 384 | usbhs_pipe_remove(priv); |
379 | probe_end_iounmap: | 385 | probe_end_iounmap: |
@@ -404,6 +410,7 @@ static int __devexit usbhs_remove(struct platform_device *pdev) | |||
404 | 410 | ||
405 | usbhs_platform_call(priv, hardware_exit, pdev); | 411 | usbhs_platform_call(priv, hardware_exit, pdev); |
406 | usbhs_mod_remove(priv); | 412 | usbhs_mod_remove(priv); |
413 | usbhs_fifo_remove(priv); | ||
407 | usbhs_pipe_remove(priv); | 414 | usbhs_pipe_remove(priv); |
408 | iounmap(priv->base); | 415 | iounmap(priv->base); |
409 | kfree(priv); | 416 | kfree(priv); |
diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index 7bf675c23a5e..06d7239a044d 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h | |||
@@ -194,6 +194,11 @@ struct usbhs_priv { | |||
194 | * pipe control | 194 | * pipe control |
195 | */ | 195 | */ |
196 | struct usbhs_pipe_info pipe_info; | 196 | struct usbhs_pipe_info pipe_info; |
197 | |||
198 | /* | ||
199 | * fifo control | ||
200 | */ | ||
201 | struct usbhs_fifo_info fifo_info; | ||
197 | }; | 202 | }; |
198 | 203 | ||
199 | /* | 204 | /* |
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 3cda71e5a35a..53e2b35dd325 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c | |||
@@ -19,6 +19,8 @@ | |||
19 | #include "./common.h" | 19 | #include "./common.h" |
20 | #include "./pipe.h" | 20 | #include "./pipe.h" |
21 | 21 | ||
22 | #define usbhsf_get_cfifo(p) (&((p)->fifo_info.cfifo)) | ||
23 | |||
22 | /* | 24 | /* |
23 | * packet info function | 25 | * packet info function |
24 | */ | 26 | */ |
@@ -194,20 +196,22 @@ static void usbhsf_rx_irq_ctrl(struct usbhs_pipe *pipe, int enable) | |||
194 | /* | 196 | /* |
195 | * FIFO ctrl | 197 | * FIFO ctrl |
196 | */ | 198 | */ |
197 | static void usbhsf_send_terminator(struct usbhs_pipe *pipe) | 199 | static void usbhsf_send_terminator(struct usbhs_pipe *pipe, |
200 | struct usbhs_fifo *fifo) | ||
198 | { | 201 | { |
199 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | 202 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); |
200 | 203 | ||
201 | usbhs_bset(priv, CFIFOCTR, BVAL, BVAL); | 204 | usbhs_bset(priv, fifo->ctr, BVAL, BVAL); |
202 | } | 205 | } |
203 | 206 | ||
204 | static int usbhsf_fifo_barrier(struct usbhs_priv *priv) | 207 | static int usbhsf_fifo_barrier(struct usbhs_priv *priv, |
208 | struct usbhs_fifo *fifo) | ||
205 | { | 209 | { |
206 | int timeout = 1024; | 210 | int timeout = 1024; |
207 | 211 | ||
208 | do { | 212 | do { |
209 | /* The FIFO port is accessible */ | 213 | /* The FIFO port is accessible */ |
210 | if (usbhs_read(priv, CFIFOCTR) & FRDY) | 214 | if (usbhs_read(priv, fifo->ctr) & FRDY) |
211 | return 0; | 215 | return 0; |
212 | 216 | ||
213 | udelay(10); | 217 | udelay(10); |
@@ -216,22 +220,26 @@ static int usbhsf_fifo_barrier(struct usbhs_priv *priv) | |||
216 | return -EBUSY; | 220 | return -EBUSY; |
217 | } | 221 | } |
218 | 222 | ||
219 | static void usbhsf_fifo_clear(struct usbhs_pipe *pipe) | 223 | static void usbhsf_fifo_clear(struct usbhs_pipe *pipe, |
224 | struct usbhs_fifo *fifo) | ||
220 | { | 225 | { |
221 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | 226 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); |
222 | 227 | ||
223 | if (!usbhs_pipe_is_dcp(pipe)) | 228 | if (!usbhs_pipe_is_dcp(pipe)) |
224 | usbhsf_fifo_barrier(priv); | 229 | usbhsf_fifo_barrier(priv, fifo); |
225 | 230 | ||
226 | usbhs_write(priv, CFIFOCTR, BCLR); | 231 | usbhs_write(priv, fifo->ctr, BCLR); |
227 | } | 232 | } |
228 | 233 | ||
229 | static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv) | 234 | static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv, |
235 | struct usbhs_fifo *fifo) | ||
230 | { | 236 | { |
231 | return usbhs_read(priv, CFIFOCTR) & DTLN_MASK; | 237 | return usbhs_read(priv, fifo->ctr) & DTLN_MASK; |
232 | } | 238 | } |
233 | 239 | ||
234 | static int usbhsf_fifo_select(struct usbhs_pipe *pipe, int write) | 240 | static int usbhsf_fifo_select(struct usbhs_pipe *pipe, |
241 | struct usbhs_fifo *fifo, | ||
242 | int write) | ||
235 | { | 243 | { |
236 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | 244 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); |
237 | struct device *dev = usbhs_priv_to_dev(priv); | 245 | struct device *dev = usbhs_priv_to_dev(priv); |
@@ -243,11 +251,11 @@ static int usbhsf_fifo_select(struct usbhs_pipe *pipe, int write) | |||
243 | base |= (1 == write) << 5; /* ISEL */ | 251 | base |= (1 == write) << 5; /* ISEL */ |
244 | 252 | ||
245 | /* "base" will be used below */ | 253 | /* "base" will be used below */ |
246 | usbhs_write(priv, CFIFOSEL, base | MBW_32); | 254 | usbhs_write(priv, fifo->sel, base | MBW_32); |
247 | 255 | ||
248 | /* check ISEL and CURPIPE value */ | 256 | /* check ISEL and CURPIPE value */ |
249 | while (timeout--) { | 257 | while (timeout--) { |
250 | if (base == (mask & usbhs_read(priv, CFIFOSEL))) | 258 | if (base == (mask & usbhs_read(priv, fifo->sel))) |
251 | return 0; | 259 | return 0; |
252 | udelay(10); | 260 | udelay(10); |
253 | } | 261 | } |
@@ -265,14 +273,15 @@ static int usbhsf_try_push(struct usbhs_pkt *pkt, int *is_done) | |||
265 | struct usbhs_pipe *pipe = pkt->pipe; | 273 | struct usbhs_pipe *pipe = pkt->pipe; |
266 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | 274 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); |
267 | struct device *dev = usbhs_priv_to_dev(priv); | 275 | struct device *dev = usbhs_priv_to_dev(priv); |
268 | void __iomem *addr = priv->base + CFIFO; | 276 | struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); /* CFIFO */ |
277 | void __iomem *addr = priv->base + fifo->port; | ||
269 | u8 *buf; | 278 | u8 *buf; |
270 | int maxp = usbhs_pipe_get_maxpacket(pipe); | 279 | int maxp = usbhs_pipe_get_maxpacket(pipe); |
271 | int total_len; | 280 | int total_len; |
272 | int i, ret, len; | 281 | int i, ret, len; |
273 | int is_short; | 282 | int is_short; |
274 | 283 | ||
275 | ret = usbhsf_fifo_select(pipe, 1); | 284 | ret = usbhsf_fifo_select(pipe, fifo, 1); |
276 | if (ret < 0) | 285 | if (ret < 0) |
277 | goto usbhs_fifo_write_busy; | 286 | goto usbhs_fifo_write_busy; |
278 | 287 | ||
@@ -280,7 +289,7 @@ static int usbhsf_try_push(struct usbhs_pkt *pkt, int *is_done) | |||
280 | if (ret < 0) | 289 | if (ret < 0) |
281 | goto usbhs_fifo_write_busy; | 290 | goto usbhs_fifo_write_busy; |
282 | 291 | ||
283 | ret = usbhsf_fifo_barrier(priv); | 292 | ret = usbhsf_fifo_barrier(priv, fifo); |
284 | if (ret < 0) | 293 | if (ret < 0) |
285 | goto usbhs_fifo_write_busy; | 294 | goto usbhs_fifo_write_busy; |
286 | 295 | ||
@@ -321,7 +330,7 @@ static int usbhsf_try_push(struct usbhs_pkt *pkt, int *is_done) | |||
321 | * pipe/irq handling | 330 | * pipe/irq handling |
322 | */ | 331 | */ |
323 | if (is_short) | 332 | if (is_short) |
324 | usbhsf_send_terminator(pipe); | 333 | usbhsf_send_terminator(pipe, fifo); |
325 | 334 | ||
326 | usbhsf_tx_irq_ctrl(pipe, !*is_done); | 335 | usbhsf_tx_irq_ctrl(pipe, !*is_done); |
327 | usbhs_pipe_enable(pipe); | 336 | usbhs_pipe_enable(pipe); |
@@ -358,19 +367,21 @@ struct usbhs_pkt_handle usbhs_fifo_push_handler = { | |||
358 | static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) | 367 | static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) |
359 | { | 368 | { |
360 | struct usbhs_pipe *pipe = pkt->pipe; | 369 | struct usbhs_pipe *pipe = pkt->pipe; |
370 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | ||
371 | struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); /* CFIFO */ | ||
361 | int ret; | 372 | int ret; |
362 | 373 | ||
363 | /* | 374 | /* |
364 | * select pipe and enable it to prepare packet receive | 375 | * select pipe and enable it to prepare packet receive |
365 | */ | 376 | */ |
366 | ret = usbhsf_fifo_select(pipe, 0); | 377 | ret = usbhsf_fifo_select(pipe, fifo, 0); |
367 | if (ret < 0) | 378 | if (ret < 0) |
368 | return ret; | 379 | return ret; |
369 | 380 | ||
370 | usbhs_pipe_enable(pipe); | 381 | usbhs_pipe_enable(pipe); |
371 | usbhsf_rx_irq_ctrl(pipe, 1); | 382 | usbhsf_rx_irq_ctrl(pipe, 1); |
372 | 383 | ||
373 | return ret; | 384 | return 0; |
374 | } | 385 | } |
375 | 386 | ||
376 | static int usbhsf_try_pop(struct usbhs_pkt *pkt, int *is_done) | 387 | static int usbhsf_try_pop(struct usbhs_pkt *pkt, int *is_done) |
@@ -378,7 +389,8 @@ static int usbhsf_try_pop(struct usbhs_pkt *pkt, int *is_done) | |||
378 | struct usbhs_pipe *pipe = pkt->pipe; | 389 | struct usbhs_pipe *pipe = pkt->pipe; |
379 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | 390 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); |
380 | struct device *dev = usbhs_priv_to_dev(priv); | 391 | struct device *dev = usbhs_priv_to_dev(priv); |
381 | void __iomem *addr = priv->base + CFIFO; | 392 | struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); /* CFIFO */ |
393 | void __iomem *addr = priv->base + fifo->port; | ||
382 | u8 *buf; | 394 | u8 *buf; |
383 | u32 data = 0; | 395 | u32 data = 0; |
384 | int maxp = usbhs_pipe_get_maxpacket(pipe); | 396 | int maxp = usbhs_pipe_get_maxpacket(pipe); |
@@ -386,15 +398,15 @@ static int usbhsf_try_pop(struct usbhs_pkt *pkt, int *is_done) | |||
386 | int i, ret; | 398 | int i, ret; |
387 | int total_len = 0; | 399 | int total_len = 0; |
388 | 400 | ||
389 | ret = usbhsf_fifo_select(pipe, 0); | 401 | ret = usbhsf_fifo_select(pipe, fifo, 0); |
390 | if (ret < 0) | 402 | if (ret < 0) |
391 | return ret; | 403 | return ret; |
392 | 404 | ||
393 | ret = usbhsf_fifo_barrier(priv); | 405 | ret = usbhsf_fifo_barrier(priv, fifo); |
394 | if (ret < 0) | 406 | if (ret < 0) |
395 | return ret; | 407 | return ret; |
396 | 408 | ||
397 | rcv_len = usbhsf_fifo_rcv_len(priv); | 409 | rcv_len = usbhsf_fifo_rcv_len(priv, fifo); |
398 | 410 | ||
399 | buf = pkt->buf + pkt->actual; | 411 | buf = pkt->buf + pkt->actual; |
400 | len = pkt->length - pkt->actual; | 412 | len = pkt->length - pkt->actual; |
@@ -408,7 +420,7 @@ static int usbhsf_try_pop(struct usbhs_pkt *pkt, int *is_done) | |||
408 | * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function" | 420 | * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function" |
409 | */ | 421 | */ |
410 | if (0 == rcv_len) { | 422 | if (0 == rcv_len) { |
411 | usbhsf_fifo_clear(pipe); | 423 | usbhsf_fifo_clear(pipe, fifo); |
412 | goto usbhs_fifo_read_end; | 424 | goto usbhs_fifo_read_end; |
413 | } | 425 | } |
414 | 426 | ||
@@ -555,3 +567,20 @@ void usbhs_fifo_quit(struct usbhs_priv *priv) | |||
555 | mod->irq_bempsts = 0; | 567 | mod->irq_bempsts = 0; |
556 | mod->irq_brdysts = 0; | 568 | mod->irq_brdysts = 0; |
557 | } | 569 | } |
570 | |||
571 | int usbhs_fifo_probe(struct usbhs_priv *priv) | ||
572 | { | ||
573 | struct usbhs_fifo *fifo; | ||
574 | |||
575 | /* CFIFO */ | ||
576 | fifo = usbhsf_get_cfifo(priv); | ||
577 | fifo->port = CFIFO; | ||
578 | fifo->sel = CFIFOSEL; | ||
579 | fifo->ctr = CFIFOCTR; | ||
580 | |||
581 | return 0; | ||
582 | } | ||
583 | |||
584 | void usbhs_fifo_remove(struct usbhs_priv *priv) | ||
585 | { | ||
586 | } | ||
diff --git a/drivers/usb/renesas_usbhs/fifo.h b/drivers/usb/renesas_usbhs/fifo.h index fcb1ecef57da..04d000ae7bdc 100644 --- a/drivers/usb/renesas_usbhs/fifo.h +++ b/drivers/usb/renesas_usbhs/fifo.h | |||
@@ -19,6 +19,16 @@ | |||
19 | 19 | ||
20 | #include "pipe.h" | 20 | #include "pipe.h" |
21 | 21 | ||
22 | struct usbhs_fifo { | ||
23 | u32 port; /* xFIFO */ | ||
24 | u32 sel; /* xFIFOSEL */ | ||
25 | u32 ctr; /* xFIFOCTR */ | ||
26 | }; | ||
27 | |||
28 | struct usbhs_fifo_info { | ||
29 | struct usbhs_fifo cfifo; | ||
30 | }; | ||
31 | |||
22 | struct usbhs_pkt_handle; | 32 | struct usbhs_pkt_handle; |
23 | struct usbhs_pkt { | 33 | struct usbhs_pkt { |
24 | struct list_head node; | 34 | struct list_head node; |
@@ -38,6 +48,8 @@ struct usbhs_pkt_handle { | |||
38 | /* | 48 | /* |
39 | * fifo | 49 | * fifo |
40 | */ | 50 | */ |
51 | int usbhs_fifo_probe(struct usbhs_priv *priv); | ||
52 | void usbhs_fifo_remove(struct usbhs_priv *priv); | ||
41 | void usbhs_fifo_init(struct usbhs_priv *priv); | 53 | void usbhs_fifo_init(struct usbhs_priv *priv); |
42 | void usbhs_fifo_quit(struct usbhs_priv *priv); | 54 | void usbhs_fifo_quit(struct usbhs_priv *priv); |
43 | 55 | ||