summaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/socket_sysfs.c
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-01-17 18:13:31 +0100
committerDominik Brodowski <linux@dominikbrodowski.net>2010-02-17 17:48:25 +0100
commitf971dbd5da4e2fbf756d07b938a9c65a9c75178b (patch)
treed21b138ac2ea3ada0e27910425cfd988f72dbede /drivers/pcmcia/socket_sysfs.c
parentpcmcia: use ops_mutex for rsrc_{mgr,nonstatic} locking (diff)
downloadlinux-f971dbd5da4e2fbf756d07b938a9c65a9c75178b.tar.xz
linux-f971dbd5da4e2fbf756d07b938a9c65a9c75178b.zip
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.c26
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);