aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-06-06 01:18:44 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-06-07 12:10:09 -0400
commitd3af90a5e4e8fb7a93d408799682e566c9270808 (patch)
tree9eb60a7464d0f1eb380d65ff89239b0a5a044f77
parent97664a207bc2601a03a300f00e6922038cd5b99c (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>
-rw-r--r--drivers/usb/renesas_usbhs/common.c9
-rw-r--r--drivers/usb/renesas_usbhs/common.h5
-rw-r--r--drivers/usb/renesas_usbhs/fifo.c75
-rw-r--r--drivers/usb/renesas_usbhs/fifo.h12
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);
375probe_end_mod_exit: 379probe_end_mod_exit:
376 usbhs_mod_remove(priv); 380 usbhs_mod_remove(priv);
381probe_end_fifo_exit:
382 usbhs_fifo_remove(priv);
377probe_end_pipe_exit: 383probe_end_pipe_exit:
378 usbhs_pipe_remove(priv); 384 usbhs_pipe_remove(priv);
379probe_end_iounmap: 385probe_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 */
197static void usbhsf_send_terminator(struct usbhs_pipe *pipe) 199static 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
204static int usbhsf_fifo_barrier(struct usbhs_priv *priv) 207static 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
219static void usbhsf_fifo_clear(struct usbhs_pipe *pipe) 223static 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
229static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv) 234static 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
234static int usbhsf_fifo_select(struct usbhs_pipe *pipe, int write) 240static 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 = {
358static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) 367static 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
376static int usbhsf_try_pop(struct usbhs_pkt *pkt, int *is_done) 387static 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
571int 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
584void 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
22struct usbhs_fifo {
23 u32 port; /* xFIFO */
24 u32 sel; /* xFIFOSEL */
25 u32 ctr; /* xFIFOCTR */
26};
27
28struct usbhs_fifo_info {
29 struct usbhs_fifo cfifo;
30};
31
22struct usbhs_pkt_handle; 32struct usbhs_pkt_handle;
23struct usbhs_pkt { 33struct 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 */
51int usbhs_fifo_probe(struct usbhs_priv *priv);
52void usbhs_fifo_remove(struct usbhs_priv *priv);
41void usbhs_fifo_init(struct usbhs_priv *priv); 53void usbhs_fifo_init(struct usbhs_priv *priv);
42void usbhs_fifo_quit(struct usbhs_priv *priv); 54void usbhs_fifo_quit(struct usbhs_priv *priv);
43 55