aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/memstick/host/tifm_ms.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/memstick/host/tifm_ms.c')
-rw-r--r--drivers/memstick/host/tifm_ms.c66
1 files changed, 37 insertions, 29 deletions
diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c
index 8577de4ebb0e..d32d6ad8f3fc 100644
--- a/drivers/memstick/host/tifm_ms.c
+++ b/drivers/memstick/host/tifm_ms.c
@@ -71,6 +71,7 @@ struct tifm_ms {
71 struct tifm_dev *dev; 71 struct tifm_dev *dev;
72 struct timer_list timer; 72 struct timer_list timer;
73 struct memstick_request *req; 73 struct memstick_request *req;
74 struct tasklet_struct notify;
74 unsigned int mode_mask; 75 unsigned int mode_mask;
75 unsigned int block_pos; 76 unsigned int block_pos;
76 unsigned long timeout_jiffies; 77 unsigned long timeout_jiffies;
@@ -455,49 +456,51 @@ static void tifm_ms_card_event(struct tifm_dev *sock)
455 return; 456 return;
456} 457}
457 458
458static void tifm_ms_request(struct memstick_host *msh) 459static void tifm_ms_req_tasklet(unsigned long data)
459{ 460{
461 struct memstick_host *msh = (struct memstick_host *)data;
460 struct tifm_ms *host = memstick_priv(msh); 462 struct tifm_ms *host = memstick_priv(msh);
461 struct tifm_dev *sock = host->dev; 463 struct tifm_dev *sock = host->dev;
462 unsigned long flags; 464 unsigned long flags;
463 int rc; 465 int rc;
464 466
465 spin_lock_irqsave(&sock->lock, flags); 467 spin_lock_irqsave(&sock->lock, flags);
466 if (host->req) { 468 if (!host->req) {
467 printk(KERN_ERR "%s : unfinished request detected\n", 469 if (host->eject) {
468 sock->dev.bus_id); 470 do {
469 spin_unlock_irqrestore(&sock->lock, flags); 471 rc = memstick_next_req(msh, &host->req);
470 tifm_eject(host->dev); 472 if (!rc)
471 return; 473 host->req->error = -ETIME;
472 } 474 } while (!rc);
475 spin_unlock_irqrestore(&sock->lock, flags);
476 return;
477 }
473 478
474 if (host->eject) {
475 do { 479 do {
476 rc = memstick_next_req(msh, &host->req); 480 rc = memstick_next_req(msh, &host->req);
477 if (!rc) 481 } while (!rc && tifm_ms_issue_cmd(host));
478 host->req->error = -ETIME;
479 } while (!rc);
480 spin_unlock_irqrestore(&sock->lock, flags);
481 return;
482 } 482 }
483
484 do {
485 rc = memstick_next_req(msh, &host->req);
486 } while (!rc && tifm_ms_issue_cmd(host));
487
488 spin_unlock_irqrestore(&sock->lock, flags); 483 spin_unlock_irqrestore(&sock->lock, flags);
484}
485
486static void tifm_ms_dummy_submit(struct memstick_host *msh)
487{
489 return; 488 return;
490} 489}
491 490
492static void tifm_ms_set_param(struct memstick_host *msh, 491static void tifm_ms_submit_req(struct memstick_host *msh)
493 enum memstick_param param,
494 int value)
495{ 492{
496 struct tifm_ms *host = memstick_priv(msh); 493 struct tifm_ms *host = memstick_priv(msh);
497 struct tifm_dev *sock = host->dev;
498 unsigned long flags;
499 494
500 spin_lock_irqsave(&sock->lock, flags); 495 tasklet_schedule(&host->notify);
496}
497
498static int tifm_ms_set_param(struct memstick_host *msh,
499 enum memstick_param param,
500 int value)
501{
502 struct tifm_ms *host = memstick_priv(msh);
503 struct tifm_dev *sock = host->dev;
501 504
502 switch (param) { 505 switch (param) {
503 case MEMSTICK_POWER: 506 case MEMSTICK_POWER:
@@ -512,7 +515,8 @@ static void tifm_ms_set_param(struct memstick_host *msh,
512 writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR, 515 writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR,
513 sock->addr + SOCK_MS_SYSTEM); 516 sock->addr + SOCK_MS_SYSTEM);
514 writel(0xffffffff, sock->addr + SOCK_MS_STATUS); 517 writel(0xffffffff, sock->addr + SOCK_MS_STATUS);
515 } 518 } else
519 return -EINVAL;
516 break; 520 break;
517 case MEMSTICK_INTERFACE: 521 case MEMSTICK_INTERFACE:
518 if (value == MEMSTICK_SERIAL) { 522 if (value == MEMSTICK_SERIAL) {
@@ -525,11 +529,12 @@ static void tifm_ms_set_param(struct memstick_host *msh,
525 writel(TIFM_CTRL_FAST_CLK 529 writel(TIFM_CTRL_FAST_CLK
526 | readl(sock->addr + SOCK_CONTROL), 530 | readl(sock->addr + SOCK_CONTROL),
527 sock->addr + SOCK_CONTROL); 531 sock->addr + SOCK_CONTROL);
528 } 532 } else
533 return -EINVAL;
529 break; 534 break;
530 }; 535 };
531 536
532 spin_unlock_irqrestore(&sock->lock, flags); 537 return 0;
533} 538}
534 539
535static void tifm_ms_abort(unsigned long data) 540static void tifm_ms_abort(unsigned long data)
@@ -570,8 +575,9 @@ static int tifm_ms_probe(struct tifm_dev *sock)
570 host->timeout_jiffies = msecs_to_jiffies(1000); 575 host->timeout_jiffies = msecs_to_jiffies(1000);
571 576
572 setup_timer(&host->timer, tifm_ms_abort, (unsigned long)host); 577 setup_timer(&host->timer, tifm_ms_abort, (unsigned long)host);
578 tasklet_init(&host->notify, tifm_ms_req_tasklet, (unsigned long)msh);
573 579
574 msh->request = tifm_ms_request; 580 msh->request = tifm_ms_submit_req;
575 msh->set_param = tifm_ms_set_param; 581 msh->set_param = tifm_ms_set_param;
576 sock->card_event = tifm_ms_card_event; 582 sock->card_event = tifm_ms_card_event;
577 sock->data_event = tifm_ms_data_event; 583 sock->data_event = tifm_ms_data_event;
@@ -593,6 +599,8 @@ static void tifm_ms_remove(struct tifm_dev *sock)
593 int rc = 0; 599 int rc = 0;
594 unsigned long flags; 600 unsigned long flags;
595 601
602 msh->request = tifm_ms_dummy_submit;
603 tasklet_kill(&host->notify);
596 spin_lock_irqsave(&sock->lock, flags); 604 spin_lock_irqsave(&sock->lock, flags);
597 host->eject = 1; 605 host->eject = 1;
598 if (host->req) { 606 if (host->req) {