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/renesas_usbhs/fifo.c | |
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/renesas_usbhs/fifo.c')
-rw-r--r-- | drivers/usb/renesas_usbhs/fifo.c | 75 |
1 files changed, 52 insertions, 23 deletions
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 | } | ||