dev_dbg(&s->dev, "shutdown\n");
send_event(s, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
+
+ mutex_lock(&s->ops_mutex);
s->state &= SOCKET_INUSE | SOCKET_PRESENT;
msleep(shutdown_delay * 10);
s->state &= SOCKET_INUSE;
}
s->state &= ~SOCKET_INUSE;
+ mutex_unlock(&s->ops_mutex);
}
static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
dev_dbg(&skt->dev, "insert\n");
+ mutex_lock(&skt->ops_mutex);
WARN_ON(skt->state & SOCKET_INUSE);
skt->state |= SOCKET_INUSE;
}
#endif
dev_dbg(&skt->dev, "insert done\n");
+ mutex_unlock(&skt->ops_mutex);
send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
} else {
+ mutex_unlock(&skt->ops_mutex);
socket_shutdown(skt);
}
if (skt->state & SOCKET_SUSPEND)
return -EBUSY;
+ mutex_lock(&skt->ops_mutex);
skt->suspended_state = skt->state;
send_event(skt, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
if (skt->ops->suspend)
skt->ops->suspend(skt);
skt->state |= SOCKET_SUSPEND;
-
+ mutex_unlock(&skt->ops_mutex);
return 0;
}
static int socket_early_resume(struct pcmcia_socket *skt)
{
+ mutex_lock(&skt->ops_mutex);
skt->socket = dead_socket;
skt->ops->init(skt);
skt->ops->set_socket(skt, &skt->socket);
if (skt->state & SOCKET_PRESENT)
skt->resume_status = socket_setup(skt, resume_delay);
+ mutex_unlock(&skt->ops_mutex);
return 0;
}
static int socket_late_resume(struct pcmcia_socket *skt)
{
+ mutex_lock(&skt->ops_mutex);
skt->state &= ~SOCKET_SUSPEND;
+ mutex_unlock(&skt->ops_mutex);
if (!(skt->state & SOCKET_PRESENT))
return socket_insert(skt);
send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);
if (skt->callback)
skt->callback->suspend(skt);
- if (socket_reset(skt) == 0) {
+ mutex_lock(&skt->ops_mutex);
+ ret = socket_reset(skt);
+ mutex_unlock(&skt->ops_mutex);
+ if (ret == 0) {
send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
if (skt->callback)
skt->callback->resume(skt);
}
if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
+ mutex_lock(&s->ops_mutex);
if (mod->Attributes & CONF_ENABLE_IRQ) {
c->Attributes |= CONF_ENABLE_IRQ;
s->socket.io_irq = s->irq.AssignedIRQ;
s->socket.io_irq = 0;
}
s->ops->set_socket(s, &s->socket);
+ mutex_unlock(&s->ops_mutex);
}
if (mod->Attributes & CONF_VCC_CHANGE_VALID) {
dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n");
return -EINVAL;
}
+ mutex_lock(&s->ops_mutex);
s->socket.Vpp = mod->Vpp1;
if (s->ops->set_socket(s, &s->socket)) {
+ mutex_unlock(&s->ops_mutex);
dev_printk(KERN_WARNING, &s->dev,
"Unable to set VPP\n");
return -EIO;
}
+ mutex_unlock(&s->ops_mutex);
} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
config_t *c = p_dev->function_config;
int i;
+ mutex_lock(&s->ops_mutex);
if (p_dev->_locked) {
p_dev->_locked = 0;
if (--(s->lock_count) == 0) {
}
if (c->state & CONFIG_LOCKED) {
c->state &= ~CONFIG_LOCKED;
- mutex_lock(&s->ops_mutex);
if (c->state & CONFIG_IO_REQ)
for (i = 0; i < MAX_IO_WIN; i++) {
if (!s->io[i].res)
io.map = i;
s->ops->set_io_map(s, &io);
}
- mutex_unlock(&s->ops_mutex);
}
+ mutex_unlock(&s->ops_mutex);
return 0;
} /* pcmcia_release_configuration */
return -EACCES;
}
+ mutex_lock(&s->ops_mutex);
/* Do power control. We don't allow changes in Vcc. */
s->socket.Vpp = req->Vpp;
if (s->ops->set_socket(s, &s->socket)) {
+ mutex_unlock(&s->ops_mutex);
dev_printk(KERN_WARNING, &s->dev,
"Unable to set socket state\n");
return -EINVAL;
s->socket.io_irq = 0;
s->ops->set_socket(s, &s->socket);
s->lock_count++;
+ mutex_unlock(&s->ops_mutex);
/* Set up CIS configuration registers */
base = c->ConfigBase = req->ConfigBase;
return -EBUSY;
}
+ mutex_lock(&s->ops_mutex);
/* Decide what type of interrupt we are registering */
type = 0;
if (s->functions > 1) /* All of this ought to be handled higher up */
pcmcia_used_irq[irq]++;
#endif
+ mutex_unlock(&s->ops_mutex);
+
return 0;
} /* pcmcia_request_irq */
EXPORT_SYMBOL(pcmcia_request_irq);