diff options
| -rw-r--r-- | drivers/extcon/extcon-class.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon-class.c index 39d3e4d48472..d398821097f3 100644 --- a/drivers/extcon/extcon-class.c +++ b/drivers/extcon/extcon-class.c | |||
| @@ -441,6 +441,8 @@ static int _call_per_cable(struct notifier_block *nb, unsigned long val, | |||
| 441 | * extcon device. | 441 | * extcon device. |
| 442 | * @obj: an empty extcon_specific_cable_nb object to be returned. | 442 | * @obj: an empty extcon_specific_cable_nb object to be returned. |
| 443 | * @extcon_name: the name of extcon device. | 443 | * @extcon_name: the name of extcon device. |
| 444 | * if NULL, extcon_register_interest will register | ||
| 445 | * every cable with the target cable_name given. | ||
| 444 | * @cable_name: the target cable name. | 446 | * @cable_name: the target cable name. |
| 445 | * @nb: the notifier block to get notified. | 447 | * @nb: the notifier block to get notified. |
| 446 | * | 448 | * |
| @@ -460,22 +462,44 @@ int extcon_register_interest(struct extcon_specific_cable_nb *obj, | |||
| 460 | const char *extcon_name, const char *cable_name, | 462 | const char *extcon_name, const char *cable_name, |
| 461 | struct notifier_block *nb) | 463 | struct notifier_block *nb) |
| 462 | { | 464 | { |
| 463 | if (!obj || !extcon_name || !cable_name || !nb) | 465 | if (!obj || !cable_name || !nb) |
| 464 | return -EINVAL; | 466 | return -EINVAL; |
| 465 | 467 | ||
| 466 | obj->edev = extcon_get_extcon_dev(extcon_name); | 468 | if (extcon_name) { |
| 467 | if (!obj->edev) | 469 | obj->edev = extcon_get_extcon_dev(extcon_name); |
| 468 | return -ENODEV; | 470 | if (!obj->edev) |
| 471 | return -ENODEV; | ||
| 469 | 472 | ||
| 470 | obj->cable_index = extcon_find_cable_index(obj->edev, cable_name); | 473 | obj->cable_index = extcon_find_cable_index(obj->edev, cable_name); |
| 471 | if (obj->cable_index < 0) | 474 | if (obj->cable_index < 0) |
| 472 | return -EINVAL; | 475 | return -ENODEV; |
| 473 | 476 | ||
| 474 | obj->user_nb = nb; | 477 | obj->user_nb = nb; |
| 475 | 478 | ||
| 476 | obj->internal_nb.notifier_call = _call_per_cable; | 479 | obj->internal_nb.notifier_call = _call_per_cable; |
| 477 | 480 | ||
| 478 | return raw_notifier_chain_register(&obj->edev->nh, &obj->internal_nb); | 481 | return raw_notifier_chain_register(&obj->edev->nh, &obj->internal_nb); |
| 482 | } else { | ||
| 483 | struct class_dev_iter iter; | ||
| 484 | struct extcon_dev *extd; | ||
| 485 | struct device *dev; | ||
| 486 | |||
| 487 | if (!extcon_class) | ||
| 488 | return -ENODEV; | ||
| 489 | class_dev_iter_init(&iter, extcon_class, NULL, NULL); | ||
| 490 | while ((dev = class_dev_iter_next(&iter))) { | ||
| 491 | extd = (struct extcon_dev *)dev_get_drvdata(dev); | ||
| 492 | |||
| 493 | if (extcon_find_cable_index(extd, cable_name) < 0) | ||
| 494 | continue; | ||
| 495 | |||
| 496 | class_dev_iter_exit(&iter); | ||
| 497 | return extcon_register_interest(obj, extd->name, | ||
| 498 | cable_name, nb); | ||
| 499 | } | ||
| 500 | |||
| 501 | return -ENODEV; | ||
| 502 | } | ||
| 479 | } | 503 | } |
| 480 | 504 | ||
| 481 | /** | 505 | /** |
