aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenny TC <jenny.tc@intel.com>2012-10-18 08:00:32 -0400
committerMyungJoo Ham <myungjoo.ham@samsung.com>2012-10-23 03:32:18 -0400
commit4f2de3bf177e57417963eec6a131a7bb2d2b660d (patch)
treeaf4c10d1848ea4e075b16b8b578ed493fe4c4d61
parent44b7bccf7c5372eab3408593ab2142a5dcde03f6 (diff)
extcon : register for cable interest by cable name
There are some scnearios where a driver/framework needs to register interest for a particular cable without specifying the extcon device name. One such scenario is charger notifications. The platform will have charger cabel which will be bound to any extcon device. It's not mandatory for the charger driver to know which extcon device it should use. This patch enables the support for registering interest for a cable just by cable name wihtout specifying the extcon device name Signed-off-by: Jenny TC <jenny.tc@intel.com> Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com> Tested-by: Chanwoo Choi <cw00.choi@samsung.com> -- Kernel-doc comment added by MyungJoo Ham
-rw-r--r--drivers/extcon/extcon-class.c44
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/**