summaryrefslogtreecommitdiffstats
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 {
struct tifm_dev *dev;
struct timer_list timer;
struct memstick_request *req;
+ struct tasklet_struct notify;
unsigned int mode_mask;
unsigned int block_pos;
unsigned long timeout_jiffies;
@@ -455,49 +456,51 @@ static void tifm_ms_card_event(struct tifm_dev *sock)
return;
}
-static void tifm_ms_request(struct memstick_host *msh)
+static void tifm_ms_req_tasklet(unsigned long data)
{
+ struct memstick_host *msh = (struct memstick_host *)data;
struct tifm_ms *host = memstick_priv(msh);
struct tifm_dev *sock = host->dev;
unsigned long flags;
int rc;
spin_lock_irqsave(&sock->lock, flags);
- if (host->req) {
- printk(KERN_ERR "%s : unfinished request detected\n",
- sock->dev.bus_id);
- spin_unlock_irqrestore(&sock->lock, flags);
- tifm_eject(host->dev);
- return;
- }
+ if (!host->req) {
+ if (host->eject) {
+ do {
+ rc = memstick_next_req(msh, &host->req);
+ if (!rc)
+ host->req->error = -ETIME;
+ } while (!rc);
+ spin_unlock_irqrestore(&sock->lock, flags);
+ return;
+ }
- if (host->eject) {
do {
rc = memstick_next_req(msh, &host->req);
- if (!rc)
- host->req->error = -ETIME;
- } while (!rc);
- spin_unlock_irqrestore(&sock->lock, flags);
- return;
+ } while (!rc && tifm_ms_issue_cmd(host));
}
-
- do {
- rc = memstick_next_req(msh, &host->req);
- } while (!rc && tifm_ms_issue_cmd(host));
-
spin_unlock_irqrestore(&sock->lock, flags);
+}
+
+static void tifm_ms_dummy_submit(struct memstick_host *msh)
+{
return;
}
-static void tifm_ms_set_param(struct memstick_host *msh,
- enum memstick_param param,
- int value)
+static void tifm_ms_submit_req(struct memstick_host *msh)
{
struct tifm_ms *host = memstick_priv(msh);
- struct tifm_dev *sock = host->dev;
- unsigned long flags;
- spin_lock_irqsave(&sock->lock, flags);
+ tasklet_schedule(&host->notify);
+}
+
+static int tifm_ms_set_param(struct memstick_host *msh,
+ enum memstick_param param,
+ int value)
+{
+ struct tifm_ms *host = memstick_priv(msh);
+ struct tifm_dev *sock = host->dev;
switch (param) {
case MEMSTICK_POWER:
@@ -512,7 +515,8 @@ static void tifm_ms_set_param(struct memstick_host *msh,
writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR,
sock->addr + SOCK_MS_SYSTEM);
writel(0xffffffff, sock->addr + SOCK_MS_STATUS);
- }
+ } else
+ return -EINVAL;
break;
case MEMSTICK_INTERFACE:
if (value == MEMSTICK_SERIAL) {
@@ -525,11 +529,12 @@ static void tifm_ms_set_param(struct memstick_host *msh,
writel(TIFM_CTRL_FAST_CLK
| readl(sock->addr + SOCK_CONTROL),
sock->addr + SOCK_CONTROL);
- }
+ } else
+ return -EINVAL;
break;
};
- spin_unlock_irqrestore(&sock->lock, flags);
+ return 0;
}
static void tifm_ms_abort(unsigned long data)
@@ -570,8 +575,9 @@ static int tifm_ms_probe(struct tifm_dev *sock)
host->timeout_jiffies = msecs_to_jiffies(1000);
setup_timer(&host->timer, tifm_ms_abort, (unsigned long)host);
+ tasklet_init(&host->notify, tifm_ms_req_tasklet, (unsigned long)msh);
- msh->request = tifm_ms_request;
+ msh->request = tifm_ms_submit_req;
msh->set_param = tifm_ms_set_param;
sock->card_event = tifm_ms_card_event;
sock->data_event = tifm_ms_data_event;
@@ -593,6 +599,8 @@ static void tifm_ms_remove(struct tifm_dev *sock)
int rc = 0;
unsigned long flags;
+ msh->request = tifm_ms_dummy_submit;
+ tasklet_kill(&host->notify);
spin_lock_irqsave(&sock->lock, flags);
host->eject = 1;
if (host->req) {
OpenPOWER on IntegriCloud