aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/extcon/extcon-class.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/extcon/extcon-class.c')
-rw-r--r--drivers/extcon/extcon-class.c70
1 files changed, 58 insertions, 12 deletions
diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon-class.c
index 654ed52e17c2..18d42c0e4581 100644
--- a/drivers/extcon/extcon-class.c
+++ b/drivers/extcon/extcon-class.c
@@ -601,6 +601,64 @@ void extcon_dev_free(struct extcon_dev *edev)
601} 601}
602EXPORT_SYMBOL_GPL(extcon_dev_free); 602EXPORT_SYMBOL_GPL(extcon_dev_free);
603 603
604static int devm_extcon_dev_match(struct device *dev, void *res, void *data)
605{
606 struct extcon_dev **r = res;
607
608 if (WARN_ON(!r || !*r))
609 return 0;
610
611 return *r == data;
612}
613
614static void devm_extcon_dev_release(struct device *dev, void *res)
615{
616 extcon_dev_free(*(struct extcon_dev **)res);
617}
618
619/**
620 * devm_extcon_dev_allocate - Allocate managed extcon device
621 * @dev: device owning the extcon device being created
622 * @supported_cable: Array of supported cable names ending with NULL.
623 * If supported_cable is NULL, cable name related APIs
624 * are disabled.
625 *
626 * This function manages automatically the memory of extcon device using device
627 * resource management and simplify the control of freeing the memory of extcon
628 * device.
629 *
630 * Returns the pointer memory of allocated extcon_dev if success
631 * or ERR_PTR(err) if fail
632 */
633struct extcon_dev *devm_extcon_dev_allocate(struct device *dev,
634 const char **supported_cable)
635{
636 struct extcon_dev **ptr, *edev;
637
638 ptr = devres_alloc(devm_extcon_dev_release, sizeof(*ptr), GFP_KERNEL);
639 if (!ptr)
640 return ERR_PTR(-ENOMEM);
641
642 edev = extcon_dev_allocate(supported_cable);
643 if (IS_ERR(edev)) {
644 devres_free(ptr);
645 return edev;
646 }
647
648 *ptr = edev;
649 devres_add(dev, ptr);
650
651 return edev;
652}
653EXPORT_SYMBOL_GPL(devm_extcon_dev_allocate);
654
655void devm_extcon_dev_free(struct device *dev, struct extcon_dev *edev)
656{
657 WARN_ON(devres_release(dev, devm_extcon_dev_release,
658 devm_extcon_dev_match, edev));
659}
660EXPORT_SYMBOL_GPL(devm_extcon_dev_free);
661
604/** 662/**
605 * extcon_dev_register() - Register a new extcon device 663 * extcon_dev_register() - Register a new extcon device
606 * @edev : the new extcon device (should be allocated before calling) 664 * @edev : the new extcon device (should be allocated before calling)
@@ -860,18 +918,6 @@ static void devm_extcon_dev_unreg(struct device *dev, void *res)
860 extcon_dev_unregister(*(struct extcon_dev **)res); 918 extcon_dev_unregister(*(struct extcon_dev **)res);
861} 919}
862 920
863static int devm_extcon_dev_match(struct device *dev, void *res, void *data)
864{
865 struct extcon_dev **r = res;
866
867 if (!r || !*r) {
868 WARN_ON(!r || !*r);
869 return 0;
870 }
871
872 return *r == data;
873}
874
875/** 921/**
876 * devm_extcon_dev_register() - Resource-managed extcon_dev_register() 922 * devm_extcon_dev_register() - Resource-managed extcon_dev_register()
877 * @dev: device to allocate extcon device 923 * @dev: device to allocate extcon device