aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/extcon
diff options
context:
space:
mode:
authorSangjung Woo <sangjung.woo@samsung.com>2014-04-21 06:10:08 -0400
committerChanwoo Choi <cw00.choi@samsung.com>2014-04-24 06:36:55 -0400
commit1111244ff4493448c0ee66e814e20c6e81d3b93d (patch)
tree67e3d29dc335fcd67f85d4a4683c271d3749829a /drivers/extcon
parent369afd4ba22f5b8de0c9229b6e62b3f9e2207034 (diff)
extcon: Add resource-managed extcon register function
Add resource-managed extcon device register function for convenience. For example, if a extcon device is attached with new devm_extcon_dev_register(), that extcon device is automatically unregistered on driver detach. Signed-off-by: Sangjung Woo <sangjung.woo@samsung.com> [Fix bug about devm_extcon_dev_match/release() and code clean by Chanwoo Choi] Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Diffstat (limited to 'drivers/extcon')
-rw-r--r--drivers/extcon/extcon-class.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon-class.c
index 7ab21aa6eaa1..f6df68989651 100644
--- a/drivers/extcon/extcon-class.c
+++ b/drivers/extcon/extcon-class.c
@@ -819,6 +819,75 @@ void extcon_dev_unregister(struct extcon_dev *edev)
819} 819}
820EXPORT_SYMBOL_GPL(extcon_dev_unregister); 820EXPORT_SYMBOL_GPL(extcon_dev_unregister);
821 821
822static void devm_extcon_dev_unreg(struct device *dev, void *res)
823{
824 extcon_dev_unregister(*(struct extcon_dev **)res);
825}
826
827static int devm_extcon_dev_match(struct device *dev, void *res, void *data)
828{
829 struct extcon_dev **r = res;
830
831 if (!r || !*r) {
832 WARN_ON(!r || !*r);
833 return 0;
834 }
835
836 return *r == data;
837}
838
839/**
840 * devm_extcon_dev_register() - Resource-managed extcon_dev_register()
841 * @dev: device to allocate extcon device
842 * @edev: the new extcon device to register
843 *
844 * Managed extcon_dev_register() function. If extcon device is attached with
845 * this function, that extcon device is automatically unregistered on driver
846 * detach. Internally this function calls extcon_dev_register() function.
847 * To get more information, refer that function.
848 *
849 * If extcon device is registered with this function and the device needs to be
850 * unregistered separately, devm_extcon_dev_unregister() should be used.
851 *
852 * Returns 0 if success or negaive error number if failure.
853 */
854int devm_extcon_dev_register(struct device *dev, struct extcon_dev *edev)
855{
856 struct extcon_dev **ptr;
857 int ret;
858
859 ptr = devres_alloc(devm_extcon_dev_unreg, sizeof(*ptr), GFP_KERNEL);
860 if (!ptr)
861 return -ENOMEM;
862
863 ret = extcon_dev_register(edev);
864 if (ret) {
865 devres_free(ptr);
866 return ret;
867 }
868
869 *ptr = edev;
870 devres_add(dev, ptr);
871
872 return 0;
873}
874EXPORT_SYMBOL_GPL(devm_extcon_dev_register);
875
876/**
877 * devm_extcon_dev_unregister() - Resource-managed extcon_dev_unregister()
878 * @dev: device the extcon belongs to
879 * @edev: the extcon device to unregister
880 *
881 * Unregister extcon device that is registered with devm_extcon_dev_register()
882 * function.
883 */
884void devm_extcon_dev_unregister(struct device *dev, struct extcon_dev *edev)
885{
886 WARN_ON(devres_release(dev, devm_extcon_dev_unreg,
887 devm_extcon_dev_match, edev));
888}
889EXPORT_SYMBOL_GPL(devm_extcon_dev_unregister);
890
822#ifdef CONFIG_OF 891#ifdef CONFIG_OF
823/* 892/*
824 * extcon_get_edev_by_phandle - Get the extcon device from devicetree 893 * extcon_get_edev_by_phandle - Get the extcon device from devicetree