aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-01-18 02:43:39 -0500
committerDominik Brodowski <linux@dominikbrodowski.net>2010-02-17 11:48:28 -0500
commitc3bfc96ef7366aa996fb8286a36f3333a3b4ff25 (patch)
tree6f1430068891518bfe8c72b835783bb8302429cc /drivers/pcmcia
parentaa584ca4cdd8db370a524c61fd3ca408303281e9 (diff)
pcmcia: avoid sysfs-related lockup for cardbus
In cb_free(), we remove some sysfs files -- other sysfs files might grab ops_mutex, so we cannot hold it while removing sysfs files. This fixes http://lkml.org/lkml/2010/1/17/88 . Tested-by: Wolfram Sang <w.sang@pengutronix.de> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/cs.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index d529e02c2d54..9a49c394f04f 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -400,10 +400,19 @@ static void socket_shutdown(struct pcmcia_socket *s)
400 s->lock_count = 0; 400 s->lock_count = 0;
401 kfree(s->fake_cis); 401 kfree(s->fake_cis);
402 s->fake_cis = NULL; 402 s->fake_cis = NULL;
403 s->functions = 0;
404
405 /* From here on we can be sure that only we (that is, the
406 * pccardd thread) accesses this socket, and all (16-bit)
407 * PCMCIA interactions are gone. Therefore, release
408 * ops_mutex so that we don't get a sysfs-related lockdep
409 * warning.
410 */
411 mutex_unlock(&s->ops_mutex);
412
403#ifdef CONFIG_CARDBUS 413#ifdef CONFIG_CARDBUS
404 cb_free(s); 414 cb_free(s);
405#endif 415#endif
406 s->functions = 0;
407 416
408 /* give socket some time to power down */ 417 /* give socket some time to power down */
409 msleep(100); 418 msleep(100);
@@ -415,7 +424,6 @@ static void socket_shutdown(struct pcmcia_socket *s)
415 } 424 }
416 425
417 s->state &= ~SOCKET_INUSE; 426 s->state &= ~SOCKET_INUSE;
418 mutex_unlock(&s->ops_mutex);
419} 427}
420 428
421static int socket_setup(struct pcmcia_socket *skt, int initial_delay) 429static int socket_setup(struct pcmcia_socket *skt, int initial_delay)