diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-01-17 12:13:31 -0500 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-02-17 11:48:25 -0500 |
commit | f971dbd5da4e2fbf756d07b938a9c65a9c75178b (patch) | |
tree | d21b138ac2ea3ada0e27910425cfd988f72dbede /drivers/pcmcia/socket_sysfs.c | |
parent | cfe5d809518eda3d5e2da87c5ccbe8647143573a (diff) |
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); | |||
88 | static ssize_t pccard_store_insert(struct device *dev, struct device_attribute *attr, | 88 | static ssize_t pccard_store_insert(struct device *dev, struct device_attribute *attr, |
89 | const char *buf, size_t count) | 89 | const char *buf, size_t count) |
90 | { | 90 | { |
91 | ssize_t ret; | ||
92 | struct pcmcia_socket *s = to_socket(dev); | 91 | struct pcmcia_socket *s = to_socket(dev); |
93 | 92 | ||
94 | if (!count) | 93 | if (!count) |
95 | return -EINVAL; | 94 | return -EINVAL; |
96 | 95 | ||
97 | ret = pcmcia_insert_card(s); | 96 | pcmcia_parse_uevents(s, PCMCIA_UEVENT_INSERT); |
98 | 97 | ||
99 | return ret ? ret : count; | 98 | return count; |
100 | } | 99 | } |
101 | static DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert); | 100 | static DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert); |
102 | 101 | ||
@@ -113,18 +112,22 @@ static ssize_t pccard_store_card_pm_state(struct device *dev, | |||
113 | struct device_attribute *attr, | 112 | struct device_attribute *attr, |
114 | const char *buf, size_t count) | 113 | const char *buf, size_t count) |
115 | { | 114 | { |
116 | ssize_t ret = -EINVAL; | ||
117 | struct pcmcia_socket *s = to_socket(dev); | 115 | struct pcmcia_socket *s = to_socket(dev); |
116 | ssize_t ret = count; | ||
118 | 117 | ||
119 | if (!count) | 118 | if (!count) |
120 | return -EINVAL; | 119 | return -EINVAL; |
121 | 120 | ||
122 | if (!(s->state & SOCKET_SUSPEND) && !strncmp(buf, "off", 3)) | 121 | if (!strncmp(buf, "off", 3)) |
123 | ret = pcmcia_suspend_card(s); | 122 | pcmcia_parse_uevents(s, PCMCIA_UEVENT_SUSPEND); |
124 | else if ((s->state & SOCKET_SUSPEND) && !strncmp(buf, "on", 2)) | 123 | else { |
125 | ret = pcmcia_resume_card(s); | 124 | if (!strncmp(buf, "on", 2)) |
125 | pcmcia_parse_uevents(s, PCMCIA_UEVENT_RESUME); | ||
126 | else | ||
127 | ret = -EINVAL; | ||
128 | } | ||
126 | 129 | ||
127 | return ret ? -ENODEV : count; | 130 | return ret; |
128 | } | 131 | } |
129 | static DEVICE_ATTR(card_pm_state, 0644, pccard_show_card_pm_state, pccard_store_card_pm_state); | 132 | static DEVICE_ATTR(card_pm_state, 0644, pccard_show_card_pm_state, pccard_store_card_pm_state); |
130 | 133 | ||
@@ -132,15 +135,14 @@ static ssize_t pccard_store_eject(struct device *dev, | |||
132 | struct device_attribute *attr, | 135 | struct device_attribute *attr, |
133 | const char *buf, size_t count) | 136 | const char *buf, size_t count) |
134 | { | 137 | { |
135 | ssize_t ret; | ||
136 | struct pcmcia_socket *s = to_socket(dev); | 138 | struct pcmcia_socket *s = to_socket(dev); |
137 | 139 | ||
138 | if (!count) | 140 | if (!count) |
139 | return -EINVAL; | 141 | return -EINVAL; |
140 | 142 | ||
141 | ret = pcmcia_eject_card(s); | 143 | pcmcia_parse_uevents(s, PCMCIA_UEVENT_EJECT); |
142 | 144 | ||
143 | return ret ? ret : count; | 145 | return count; |
144 | } | 146 | } |
145 | static DEVICE_ATTR(card_eject, 0200, NULL, pccard_store_eject); | 147 | static DEVICE_ATTR(card_eject, 0200, NULL, pccard_store_eject); |
146 | 148 | ||