diff options
Diffstat (limited to 'drivers/extcon/extcon.c')
-rw-r--r-- | drivers/extcon/extcon.c | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index 76157ab9faf3..43b57b02d050 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c | |||
@@ -124,25 +124,35 @@ static int find_cable_index_by_id(struct extcon_dev *edev, const unsigned int id | |||
124 | return -EINVAL; | 124 | return -EINVAL; |
125 | } | 125 | } |
126 | 126 | ||
127 | static int find_cable_index_by_name(struct extcon_dev *edev, const char *name) | 127 | static int find_cable_id_by_name(struct extcon_dev *edev, const char *name) |
128 | { | 128 | { |
129 | unsigned int id = EXTCON_NONE; | 129 | unsigned int id = -EINVAL; |
130 | int i = 0; | 130 | int i = 0; |
131 | 131 | ||
132 | if (edev->max_supported == 0) | 132 | /* Find the id of extcon cable */ |
133 | return -EINVAL; | ||
134 | |||
135 | /* Find the the number of extcon cable */ | ||
136 | while (extcon_name[i]) { | 133 | while (extcon_name[i]) { |
137 | if (!strncmp(extcon_name[i], name, CABLE_NAME_MAX)) { | 134 | if (!strncmp(extcon_name[i], name, CABLE_NAME_MAX)) { |
138 | id = i; | 135 | id = i; |
139 | break; | 136 | break; |
140 | } | 137 | } |
138 | i++; | ||
141 | } | 139 | } |
142 | 140 | ||
143 | if (id == EXTCON_NONE) | 141 | return id; |
142 | } | ||
143 | |||
144 | static int find_cable_index_by_name(struct extcon_dev *edev, const char *name) | ||
145 | { | ||
146 | unsigned int id; | ||
147 | |||
148 | if (edev->max_supported == 0) | ||
144 | return -EINVAL; | 149 | return -EINVAL; |
145 | 150 | ||
151 | /* Find the the number of extcon cable */ | ||
152 | id = find_cable_id_by_name(edev, name); | ||
153 | if (id < 0) | ||
154 | return id; | ||
155 | |||
146 | return find_cable_index_by_id(edev, id); | 156 | return find_cable_index_by_id(edev, id); |
147 | } | 157 | } |
148 | 158 | ||
@@ -228,9 +238,11 @@ static ssize_t cable_state_show(struct device *dev, | |||
228 | struct extcon_cable *cable = container_of(attr, struct extcon_cable, | 238 | struct extcon_cable *cable = container_of(attr, struct extcon_cable, |
229 | attr_state); | 239 | attr_state); |
230 | 240 | ||
241 | int i = cable->cable_index; | ||
242 | |||
231 | return sprintf(buf, "%d\n", | 243 | return sprintf(buf, "%d\n", |
232 | extcon_get_cable_state_(cable->edev, | 244 | extcon_get_cable_state_(cable->edev, |
233 | cable->cable_index)); | 245 | cable->edev->supported_cable[i])); |
234 | } | 246 | } |
235 | 247 | ||
236 | /** | 248 | /** |
@@ -263,20 +275,25 @@ int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state) | |||
263 | spin_lock_irqsave(&edev->lock, flags); | 275 | spin_lock_irqsave(&edev->lock, flags); |
264 | 276 | ||
265 | if (edev->state != ((edev->state & ~mask) | (state & mask))) { | 277 | if (edev->state != ((edev->state & ~mask) | (state & mask))) { |
278 | u32 old_state; | ||
279 | |||
266 | if (check_mutually_exclusive(edev, (edev->state & ~mask) | | 280 | if (check_mutually_exclusive(edev, (edev->state & ~mask) | |
267 | (state & mask))) { | 281 | (state & mask))) { |
268 | spin_unlock_irqrestore(&edev->lock, flags); | 282 | spin_unlock_irqrestore(&edev->lock, flags); |
269 | return -EPERM; | 283 | return -EPERM; |
270 | } | 284 | } |
271 | 285 | ||
272 | for (index = 0; index < edev->max_supported; index++) { | 286 | old_state = edev->state; |
273 | if (is_extcon_changed(edev->state, state, index, &attached)) | ||
274 | raw_notifier_call_chain(&edev->nh[index], attached, edev); | ||
275 | } | ||
276 | |||
277 | edev->state &= ~mask; | 287 | edev->state &= ~mask; |
278 | edev->state |= state & mask; | 288 | edev->state |= state & mask; |
279 | 289 | ||
290 | for (index = 0; index < edev->max_supported; index++) { | ||
291 | if (is_extcon_changed(old_state, edev->state, index, | ||
292 | &attached)) | ||
293 | raw_notifier_call_chain(&edev->nh[index], | ||
294 | attached, edev); | ||
295 | } | ||
296 | |||
280 | /* This could be in interrupt handler */ | 297 | /* This could be in interrupt handler */ |
281 | prop_buf = (char *)get_zeroed_page(GFP_ATOMIC); | 298 | prop_buf = (char *)get_zeroed_page(GFP_ATOMIC); |
282 | if (prop_buf) { | 299 | if (prop_buf) { |
@@ -361,8 +378,13 @@ EXPORT_SYMBOL_GPL(extcon_get_cable_state_); | |||
361 | */ | 378 | */ |
362 | int extcon_get_cable_state(struct extcon_dev *edev, const char *cable_name) | 379 | int extcon_get_cable_state(struct extcon_dev *edev, const char *cable_name) |
363 | { | 380 | { |
364 | return extcon_get_cable_state_(edev, find_cable_index_by_name | 381 | unsigned int id; |
365 | (edev, cable_name)); | 382 | |
383 | id = find_cable_id_by_name(edev, cable_name); | ||
384 | if (id < 0) | ||
385 | return id; | ||
386 | |||
387 | return extcon_get_cable_state_(edev, id); | ||
366 | } | 388 | } |
367 | EXPORT_SYMBOL_GPL(extcon_get_cable_state); | 389 | EXPORT_SYMBOL_GPL(extcon_get_cable_state); |
368 | 390 | ||
@@ -404,8 +426,13 @@ EXPORT_SYMBOL_GPL(extcon_set_cable_state_); | |||
404 | int extcon_set_cable_state(struct extcon_dev *edev, | 426 | int extcon_set_cable_state(struct extcon_dev *edev, |
405 | const char *cable_name, bool cable_state) | 427 | const char *cable_name, bool cable_state) |
406 | { | 428 | { |
407 | return extcon_set_cable_state_(edev, find_cable_index_by_name | 429 | unsigned int id; |
408 | (edev, cable_name), cable_state); | 430 | |
431 | id = find_cable_id_by_name(edev, cable_name); | ||
432 | if (id < 0) | ||
433 | return id; | ||
434 | |||
435 | return extcon_set_cable_state_(edev, id, cable_state); | ||
409 | } | 436 | } |
410 | EXPORT_SYMBOL_GPL(extcon_set_cable_state); | 437 | EXPORT_SYMBOL_GPL(extcon_set_cable_state); |
411 | 438 | ||