// SPDX-License-Identifier: GPL-2.0-only
/*
* drivers / extcon / devres . c - EXTCON device ' s resource management
*
* Copyright ( C ) 2016 Samsung Electronics
* Author : Chanwoo Choi < cw00 . choi @ samsung . com >
*/
#include "extcon.h"
static int devm_extcon_dev_match(struct device *dev, void *res, void *data)
{
struct extcon_dev **r = res;
if (WARN_ON(!r || !*r))
return 0 ;
return *r == data;
}
static void devm_extcon_dev_release(struct device *dev, void *res)
{
extcon_dev_free(*(struct extcon_dev **)res);
}
static void devm_extcon_dev_unreg(struct device *dev, void *res)
{
extcon_dev_unregister(*(struct extcon_dev **)res);
}
struct extcon_dev_notifier_devres {
struct extcon_dev *edev;
unsigned int id;
struct notifier_block *nb;
};
static void devm_extcon_dev_notifier_unreg(struct device *dev, void *res)
{
struct extcon_dev_notifier_devres *this = res;
extcon_unregister_notifier(this ->edev, this ->id, this ->nb);
}
static void devm_extcon_dev_notifier_all_unreg(struct device *dev, void *res)
{
struct extcon_dev_notifier_devres *this = res;
extcon_unregister_notifier_all(this ->edev, this ->nb);
}
/**
* devm_extcon_dev_allocate - Allocate managed extcon device
* @ dev : the device owning the extcon device being created
* @ supported_cable : the array of the supported external connectors
* ending with EXTCON_NONE .
*
* This function manages automatically the memory of extcon device using device
* resource management and simplify the control of freeing the memory of extcon
* device .
*
* Returns the pointer memory of allocated extcon_dev if success
* or ERR_PTR ( err ) if fail
*/
struct extcon_dev *devm_extcon_dev_allocate(struct device *dev,
const unsigned int *supported_cable)
{
struct extcon_dev **ptr, *edev;
ptr = devres_alloc(devm_extcon_dev_release, sizeof (*ptr), GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);
edev = extcon_dev_allocate(supported_cable);
if (IS_ERR(edev)) {
devres_free(ptr);
return edev;
}
edev->dev.parent = dev;
*ptr = edev;
devres_add(dev, ptr);
return edev;
}
EXPORT_SYMBOL_GPL(devm_extcon_dev_allocate);
/**
* devm_extcon_dev_free ( ) - Resource - managed extcon_dev_unregister ( )
* @ dev : the device owning the extcon device being created
* @ edev : the extcon device to be freed
*
* Free the memory that is allocated with devm_extcon_dev_allocate ( )
* function .
*/
void devm_extcon_dev_free(struct device *dev, struct extcon_dev *edev)
{
WARN_ON(devres_release(dev, devm_extcon_dev_release,
devm_extcon_dev_match, edev));
}
EXPORT_SYMBOL_GPL(devm_extcon_dev_free);
/**
* devm_extcon_dev_register ( ) - Resource - managed extcon_dev_register ( )
* @ dev : the device owning the extcon device being created
* @ edev : the extcon device to be registered
*
* this function , that extcon device is automatically unregistered on driver
* detach . Internally this function calls extcon_dev_register ( ) function .
* To get more information , refer that function .
*
* If extcon device is registered with this function and the device needs to be
* unregistered separately , devm_extcon_dev_unregister ( ) should be used .
*
* Returns 0 if success or negaive error number if failure .
*/
int devm_extcon_dev_register(struct device *dev, struct extcon_dev *edev)
{
struct extcon_dev **ptr;
int ret;
ptr = devres_alloc(devm_extcon_dev_unreg, sizeof (*ptr), GFP_KERNEL);
if (!ptr)
return -ENOMEM;
ret = extcon_dev_register(edev);
if (ret) {
devres_free(ptr);
return ret;
}
*ptr = edev;
devres_add(dev, ptr);
return 0 ;
}
EXPORT_SYMBOL_GPL(devm_extcon_dev_register);
/**
* devm_extcon_dev_unregister ( ) - Resource - managed extcon_dev_unregister ( )
* @ dev : the device owning the extcon device being created
* @ edev : the extcon device to unregistered
*
* Unregister extcon device that is registered with devm_extcon_dev_register ( )
* function .
*/
void devm_extcon_dev_unregister(struct device *dev, struct extcon_dev *edev)
{
WARN_ON(devres_release(dev, devm_extcon_dev_unreg,
devm_extcon_dev_match, edev));
}
EXPORT_SYMBOL_GPL(devm_extcon_dev_unregister);
/**
* devm_extcon_register_notifier ( ) - Resource - managed extcon_register_notifier ( )
* @ dev : the device owning the extcon device being created
* @ edev : the extcon device
* @ id : the unique id among the extcon enumeration
* @ nb : a notifier block to be registered
*
* This function manages automatically the notifier of extcon device using
* device resource management and simplify the control of unregistering
* the notifier of extcon device .
*
* Note that the second parameter given to the callback of nb ( val ) is
* " old_state " , not the current state . The current state can be retrieved
* by looking at the third pameter ( edev pointer ) ' s state value .
*
* Returns 0 if success or negaive error number if failure .
*/
int devm_extcon_register_notifier(struct device *dev, struct extcon_dev *edev,
unsigned int id, struct notifier_block *nb)
{
struct extcon_dev_notifier_devres *ptr;
int ret;
ptr = devres_alloc(devm_extcon_dev_notifier_unreg, sizeof (*ptr),
GFP_KERNEL);
if (!ptr)
return -ENOMEM;
ret = extcon_register_notifier(edev, id, nb);
if (ret) {
devres_free(ptr);
return ret;
}
ptr->edev = edev;
ptr->id = id;
ptr->nb = nb;
devres_add(dev, ptr);
return 0 ;
}
EXPORT_SYMBOL(devm_extcon_register_notifier);
/**
* devm_extcon_unregister_notifier ( )
* - Resource - managed extcon_unregister_notifier ( )
* @ dev : the device owning the extcon device being created
* @ edev : the extcon device
* @ id : the unique id among the extcon enumeration
* @ nb : a notifier block to be registered
*/
void devm_extcon_unregister_notifier(struct device *dev,
struct extcon_dev *edev, unsigned int id,
struct notifier_block *nb)
{
WARN_ON(devres_release(dev, devm_extcon_dev_notifier_unreg,
devm_extcon_dev_match, edev));
}
EXPORT_SYMBOL(devm_extcon_unregister_notifier);
/**
* devm_extcon_register_notifier_all ( )
* - Resource - managed extcon_register_notifier_all ( )
* @ dev : the device owning the extcon device being created
* @ edev : the extcon device
* @ nb : a notifier block to be registered
*
* This function manages automatically the notifier of extcon device using
* device resource management and simplify the control of unregistering
* the notifier of extcon device . To get more information , refer that function .
*
* Returns 0 if success or negaive error number if failure .
*/
int devm_extcon_register_notifier_all(struct device *dev, struct extcon_dev *edev,
struct notifier_block *nb)
{
struct extcon_dev_notifier_devres *ptr;
int ret;
ptr = devres_alloc(devm_extcon_dev_notifier_all_unreg, sizeof (*ptr),
GFP_KERNEL);
if (!ptr)
return -ENOMEM;
ret = extcon_register_notifier_all(edev, nb);
if (ret) {
devres_free(ptr);
return ret;
}
ptr->edev = edev;
ptr->nb = nb;
devres_add(dev, ptr);
return 0 ;
}
EXPORT_SYMBOL(devm_extcon_register_notifier_all);
/**
* devm_extcon_unregister_notifier_all ( )
* - Resource - managed extcon_unregister_notifier_all ( )
* @ dev : the device owning the extcon device being created
* @ edev : the extcon device
* @ nb : a notifier block to be registered
*/
void devm_extcon_unregister_notifier_all(struct device *dev,
struct extcon_dev *edev,
struct notifier_block *nb)
{
WARN_ON(devres_release(dev, devm_extcon_dev_notifier_all_unreg,
devm_extcon_dev_match, edev));
}
EXPORT_SYMBOL(devm_extcon_unregister_notifier_all);
Messung V0.5 in Prozent C=97 H=100 G=98
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland