diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-01-17 20:13:31 +0300 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-02-17 19:48:25 +0300 |
commit | f971dbd5da4e2fbf756d07b938a9c65a9c75178b (patch) | |
tree | d21b138ac2ea3ada0e27910425cfd988f72dbede /drivers/pcmcia/socket_sysfs.c | |
parent | cfe5d809518eda3d5e2da87c5ccbe8647143573a (diff) | |
download | linux-f971dbd5da4e2fbf756d07b938a9c65a9c75178b.tar.xz |
pcmcia: use pccardd to handle eject, insert, suspend and resume requests
This avoids any sysfs-related deadlock (or lockdep warning), such
as reported at http://lkml.org/lkml/2010/1/17/88 .
Reported-by: Ming Lei <tom.leiming@gmail.com>
Tested-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/pcmcia/socket_sysfs.c')
-rw-r--r-- | drivers/pcmcia/socket_sysfs.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index e8826df00a36..fba0e30183f4 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c @@ -88,15 +88,14 @@ static DEVICE_ATTR(card_vcc, 0444, pccard_show_vcc, NULL); static ssize_t pccard_store_insert(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - ssize_t ret; struct pcmcia_socket *s = to_socket(dev); if (!count) return -EINVAL; - ret = pcmcia_insert_card(s); + pcmcia_parse_uevents(s, PCMCIA_UEVENT_INSERT); - return ret ? ret : count; + return count; } static DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert); @@ -113,18 +112,22 @@ static ssize_t pccard_store_card_pm_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - ssize_t ret = -EINVAL; struct pcmcia_socket *s = to_socket(dev); + ssize_t ret = count; if (!count) return -EINVAL; - if (!(s->state & SOCKET_SUSPEND) && !strncmp(buf, "off", 3)) - ret = pcmcia_suspend_card(s); - else if ((s->state & SOCKET_SUSPEND) && !strncmp(buf, "on", 2)) - ret = pcmcia_resume_card(s); + if (!strncmp(buf, "off", 3)) + pcmcia_parse_uevents(s, PCMCIA_UEVENT_SUSPEND); + else { + if (!strncmp(buf, "on", 2)) + pcmcia_parse_uevents(s, PCMCIA_UEVENT_RESUME); + else + ret = -EINVAL; + } - return ret ? -ENODEV : count; + return ret; } static DEVICE_ATTR(card_pm_state, 0644, pccard_show_card_pm_state, pccard_store_card_pm_state); @@ -132,15 +135,14 @@ static ssize_t pccard_store_eject(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - ssize_t ret; struct pcmcia_socket *s = to_socket(dev); if (!count) return -EINVAL; - ret = pcmcia_eject_card(s); + pcmcia_parse_uevents(s, PCMCIA_UEVENT_EJECT); - return ret ? ret : count; + return count; } static DEVICE_ATTR(card_eject, 0200, NULL, pccard_store_eject); |