Commit 66787112 authored by Russell King's avatar Russell King

[PCMCIA] Socket quiescing changes

This patch changes the way in which we turn off power to PCMCIA sockets.
We have traditionally relied on the socket drivers "init" method to
shut down the power to the socket by calling its own "set_socket" function.

Rather than relying on all socket drivers replicating this behaviour, we
move this into the core by calling the "set_socket" method explicitly
after we clear out the socket state structure.
parent 4d705dab
......@@ -449,6 +449,7 @@ static void shutdown_socket(struct pcmcia_socket *s)
s->state &= SOCKET_PRESENT|SOCKET_INUSE;
s->socket = dead_socket;
s->ops->init(s);
s->ops->set_socket(s, &s->socket);
s->irq.AssignedIRQ = s->irq.Config = 0;
s->lock_count = 0;
destroy_cis_cache(s);
......@@ -456,15 +457,6 @@ static void shutdown_socket(struct pcmcia_socket *s)
kfree(s->fake_cis);
s->fake_cis = NULL;
}
/* Should not the socket be forced quiet as well? e.g. turn off Vcc */
/* Without these changes, the socket is left hot, even though card-services */
/* realizes that no card is in place. */
s->socket.flags &= ~SS_OUTPUT_ENA;
s->socket.Vpp = 0;
s->socket.Vcc = 0;
s->socket.io_irq = 0;
s->ops->set_socket(s, &s->socket);
/* */
#ifdef CONFIG_CARDBUS
cb_free(s);
#endif
......@@ -484,6 +476,14 @@ static void shutdown_socket(struct pcmcia_socket *s)
}
free_regions(&s->a_region);
free_regions(&s->c_region);
{
int status;
skt->ops->get_status(skt, &status);
if (status & SS_POWERON) {
printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", skt);
}
}
} /* shutdown_socket */
/*======================================================================
......@@ -638,6 +638,12 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(cs_to_timeout(vcc_settle));
skt->ops->get_status(skt, &status);
if (!(status & SS_POWERON)) {
pcmcia_error(skt, "unable to apply power.\n");
return CS_BAD_TYPE;
}
return socket_reset(skt);
}
......@@ -697,6 +703,7 @@ static int socket_resume(struct pcmcia_socket *skt)
skt->socket = dead_socket;
skt->ops->init(skt);
skt->ops->set_socket(skt, &skt->socket);
ret = socket_setup(skt, resume_delay);
if (ret == CS_SUCCESS) {
......@@ -769,6 +776,7 @@ static int pccardd(void *__skt)
skt->socket = dead_socket;
skt->ops->init(skt);
skt->ops->set_socket(skt, &skt->socket);
/* register with the device core */
ret = class_device_register(&skt->dev);
......
......@@ -347,11 +347,7 @@ static int hs_init(struct pcmcia_socket *s)
hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
DPRINTK("hs_init(%d)\n", sp->number);
sp->state.Vcc = 0;
sp->state.Vpp = 0;
hs_set_voltages(sp, 0, 0);
return 0;
}
......
......@@ -426,7 +426,6 @@ static int i82092aa_init(struct pcmcia_socket *sock)
enter("i82092aa_init");
mem.sys_stop = 0x0fff;
i82092aa_set_socket(sock, &dead_socket);
for (i = 0; i < 2; i++) {
io.map = i;
i82092aa_set_io_map(sock, &io);
......
......@@ -1322,7 +1322,6 @@ static int pcic_init(struct pcmcia_socket *s)
pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
mem.sys_stop = 0x1000;
pcic_set_socket(s, &dead_socket);
for (i = 0; i < 2; i++) {
io.map = i;
pcic_set_io_map(s, &io);
......
......@@ -232,8 +232,6 @@ static int sa1100_pcmcia_sock_init(struct pcmcia_socket *sock)
DEBUG(2, "%s(): initializing socket %u\n", __FUNCTION__, skt->nr);
skt->ops->socket_init(skt);
sa1100_pcmcia_config_skt(skt, &dead_socket);
return 0;
}
......
......@@ -865,7 +865,6 @@ static int tcic_init(struct pcmcia_socket *s)
pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
mem.sys_stop = 0x1000;
tcic_set_socket(s, &dead_socket);
for (i = 0; i < 2; i++) {
io.map = i;
tcic_set_io_map(s, &io);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment