mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-13 23:34:05 +08:00
Merge branch 'ib-extcon-4.12' into HEAD
This commit is contained in:
commit
bc9a5c37a5
@ -50,6 +50,13 @@ static void devm_extcon_dev_notifier_unreg(struct device *dev, void *res)
|
|||||||
extcon_unregister_notifier(this->edev, this->id, this->nb);
|
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
|
* devm_extcon_dev_allocate - Allocate managed extcon device
|
||||||
* @dev: device owning the extcon device being created
|
* @dev: device owning the extcon device being created
|
||||||
@ -214,3 +221,57 @@ void devm_extcon_unregister_notifier(struct device *dev,
|
|||||||
devm_extcon_dev_match, edev));
|
devm_extcon_dev_match, edev));
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(devm_extcon_unregister_notifier);
|
EXPORT_SYMBOL(devm_extcon_unregister_notifier);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* devm_extcon_register_notifier_all()
|
||||||
|
* - Resource-managed extcon_register_notifier_all()
|
||||||
|
* @dev: device to allocate extcon device
|
||||||
|
* @edev: the extcon device that has the external connecotr.
|
||||||
|
* @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: device to allocate extcon device
|
||||||
|
* @edev: the extcon device that has the external connecotr.
|
||||||
|
* @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);
|
||||||
|
@ -448,8 +448,19 @@ int extcon_sync(struct extcon_dev *edev, unsigned int id)
|
|||||||
spin_lock_irqsave(&edev->lock, flags);
|
spin_lock_irqsave(&edev->lock, flags);
|
||||||
|
|
||||||
state = !!(edev->state & BIT(index));
|
state = !!(edev->state & BIT(index));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call functions in a raw notifier chain for the specific one
|
||||||
|
* external connector.
|
||||||
|
*/
|
||||||
raw_notifier_call_chain(&edev->nh[index], state, edev);
|
raw_notifier_call_chain(&edev->nh[index], state, edev);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call functions in a raw notifier chain for the all supported
|
||||||
|
* external connectors.
|
||||||
|
*/
|
||||||
|
raw_notifier_call_chain(&edev->nh_all, state, edev);
|
||||||
|
|
||||||
/* This could be in interrupt handler */
|
/* This could be in interrupt handler */
|
||||||
prop_buf = (char *)get_zeroed_page(GFP_ATOMIC);
|
prop_buf = (char *)get_zeroed_page(GFP_ATOMIC);
|
||||||
if (!prop_buf) {
|
if (!prop_buf) {
|
||||||
@ -954,6 +965,59 @@ int extcon_unregister_notifier(struct extcon_dev *edev, unsigned int id,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(extcon_unregister_notifier);
|
EXPORT_SYMBOL_GPL(extcon_unregister_notifier);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* extcon_register_notifier_all() - Register a notifier block for all connectors
|
||||||
|
* @edev: the extcon device that has the external connecotr.
|
||||||
|
* @nb: a notifier block to be registered.
|
||||||
|
*
|
||||||
|
* This fucntion registers a notifier block in order to receive the state
|
||||||
|
* change of all supported external connectors from extcon device.
|
||||||
|
* And The second parameter given to the callback of nb (val) is
|
||||||
|
* the current state and third parameter is the edev pointer.
|
||||||
|
*
|
||||||
|
* Returns 0 if success or error number if fail
|
||||||
|
*/
|
||||||
|
int extcon_register_notifier_all(struct extcon_dev *edev,
|
||||||
|
struct notifier_block *nb)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!edev || !nb)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&edev->lock, flags);
|
||||||
|
ret = raw_notifier_chain_register(&edev->nh_all, nb);
|
||||||
|
spin_unlock_irqrestore(&edev->lock, flags);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(extcon_register_notifier_all);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* extcon_unregister_notifier_all() - Unregister a notifier block from extcon.
|
||||||
|
* @edev: the extcon device that has the external connecotr.
|
||||||
|
* @nb: a notifier block to be registered.
|
||||||
|
*
|
||||||
|
* Returns 0 if success or error number if fail
|
||||||
|
*/
|
||||||
|
int extcon_unregister_notifier_all(struct extcon_dev *edev,
|
||||||
|
struct notifier_block *nb)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!edev || !nb)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&edev->lock, flags);
|
||||||
|
ret = raw_notifier_chain_unregister(&edev->nh_all, nb);
|
||||||
|
spin_unlock_irqrestore(&edev->lock, flags);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(extcon_unregister_notifier_all);
|
||||||
|
|
||||||
static struct attribute *extcon_attrs[] = {
|
static struct attribute *extcon_attrs[] = {
|
||||||
&dev_attr_state.attr,
|
&dev_attr_state.attr,
|
||||||
&dev_attr_name.attr,
|
&dev_attr_name.attr,
|
||||||
@ -1212,6 +1276,8 @@ int extcon_dev_register(struct extcon_dev *edev)
|
|||||||
for (index = 0; index < edev->max_supported; index++)
|
for (index = 0; index < edev->max_supported; index++)
|
||||||
RAW_INIT_NOTIFIER_HEAD(&edev->nh[index]);
|
RAW_INIT_NOTIFIER_HEAD(&edev->nh[index]);
|
||||||
|
|
||||||
|
RAW_INIT_NOTIFIER_HEAD(&edev->nh_all);
|
||||||
|
|
||||||
dev_set_drvdata(&edev->dev, edev);
|
dev_set_drvdata(&edev->dev, edev);
|
||||||
edev->state = 0;
|
edev->state = 0;
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
* @dev: Device of this extcon.
|
* @dev: Device of this extcon.
|
||||||
* @state: Attach/detach state of this extcon. Do not provide at
|
* @state: Attach/detach state of this extcon. Do not provide at
|
||||||
* register-time.
|
* register-time.
|
||||||
|
* @nh_all: Notifier for the state change events for all supported
|
||||||
|
* external connectors from this extcon.
|
||||||
* @nh: Notifier for the state change events from this extcon
|
* @nh: Notifier for the state change events from this extcon
|
||||||
* @entry: To support list of extcon devices so that users can
|
* @entry: To support list of extcon devices so that users can
|
||||||
* search for extcon devices based on the extcon name.
|
* search for extcon devices based on the extcon name.
|
||||||
@ -43,6 +45,7 @@ struct extcon_dev {
|
|||||||
|
|
||||||
/* Internal data. Please do not set. */
|
/* Internal data. Please do not set. */
|
||||||
struct device dev;
|
struct device dev;
|
||||||
|
struct raw_notifier_head nh_all;
|
||||||
struct raw_notifier_head *nh;
|
struct raw_notifier_head *nh;
|
||||||
struct list_head entry;
|
struct list_head entry;
|
||||||
int max_supported;
|
int max_supported;
|
||||||
|
@ -236,11 +236,11 @@ extern int extcon_set_property_capability(struct extcon_dev *edev,
|
|||||||
unsigned int id, unsigned int prop);
|
unsigned int id, unsigned int prop);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Following APIs are to monitor every action of a notifier.
|
* Following APIs are to monitor the status change of the external connectors.
|
||||||
* Registrar gets notified for every external port of a connection device.
|
* extcon_register_notifier(*edev, id, *nb) : Register a notifier block
|
||||||
* Probably this could be used to debug an action of notifier; however,
|
* for specific external connector of the extcon.
|
||||||
* we do not recommend to use this for normal 'notifiee' device drivers who
|
* extcon_register_notifier_all(*edev, *nb) : Register a notifier block
|
||||||
* want to be notified by a specific external port of the notifier.
|
* for all supported external connectors of the extcon.
|
||||||
*/
|
*/
|
||||||
extern int extcon_register_notifier(struct extcon_dev *edev, unsigned int id,
|
extern int extcon_register_notifier(struct extcon_dev *edev, unsigned int id,
|
||||||
struct notifier_block *nb);
|
struct notifier_block *nb);
|
||||||
@ -253,6 +253,17 @@ extern void devm_extcon_unregister_notifier(struct device *dev,
|
|||||||
struct extcon_dev *edev, unsigned int id,
|
struct extcon_dev *edev, unsigned int id,
|
||||||
struct notifier_block *nb);
|
struct notifier_block *nb);
|
||||||
|
|
||||||
|
extern int extcon_register_notifier_all(struct extcon_dev *edev,
|
||||||
|
struct notifier_block *nb);
|
||||||
|
extern int extcon_unregister_notifier_all(struct extcon_dev *edev,
|
||||||
|
struct notifier_block *nb);
|
||||||
|
extern int devm_extcon_register_notifier_all(struct device *dev,
|
||||||
|
struct extcon_dev *edev,
|
||||||
|
struct notifier_block *nb);
|
||||||
|
extern void devm_extcon_unregister_notifier_all(struct device *dev,
|
||||||
|
struct extcon_dev *edev,
|
||||||
|
struct notifier_block *nb);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Following API get the extcon device from devicetree.
|
* Following API get the extcon device from devicetree.
|
||||||
* This function use phandle of devicetree to get extcon device directly.
|
* This function use phandle of devicetree to get extcon device directly.
|
||||||
|
Loading…
Reference in New Issue
Block a user