Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1615660
| Path | csiph.com!news.mixmin.net!news.unit0.net!news.panservice.it!bofh.it!news.nic.it!robomod |
|---|---|
| From | Chanwoo Choi <cw00.choi@samsung.com> |
| Newsgroups | linux.kernel |
| Subject | [PATCH v2 2/2] extcon: Add new extcon_register_notifier_all() to monitor all external connectors |
| Date | Tue, 04 Apr 2017 04:30:01 +0200 |
| Message-ID | <tsmoh-71b-1@gated-at.bofh.it> (permalink) |
| References | <tsmoh-71b-3@gated-at.bofh.it> <tsmoh-71b-5@gated-at.bofh.it> <tsmoh-71b-3@gated-at.bofh.it> |
| X-Auditid | b6c32a35-f79806d000002bf4-94-58e3031c26f3 |
| X-Mailer | git-send-email 1.8.0 |
| X-Brightmail-Tracker | H4sIAAAAAAAAA+NgFtrDKsWRmVeSWpSXmKPExsWy7bCmvq4M8+MIgxd/TCxeTjjMaDHxxhUW i+tfnrNavDk+ncni8q45bBa3G1ewObB57Jx1l91j06pONo/3+66yefRtWcXo8XmTXABrVKpN RmpiSmqRQmpecn5KZl66rZJ3cLxzvKmZgaGuoaWFuZJCXmJuqq2Si0+ArltmDtAFSgpliTml QKGAxOJiJX07m6L80pJUhYz84hJbpWhDQyM9QwNzPSMjIz0T41grI1OgkoTUjC9n37IXTPSr 2Pn4BnMD4xmHLkZODgkBE4mLL+YxQdhiEhfurWfrYuTiEBLYwSjRM2EtC4TTziRxesU1FpiO vSt2skIkljNK3HzZwwTh/GCUeLX/A1gVm4CWxP4XN9hAbBEBBYnNvc9YQWxmgUqJ2YvngO0T FsiWuPl3ClicRUBVomfFcnYQm1fARaL54DuobXISH/Y8AotzCrhKnDr+DOwkCYHnbBJbD88E auYAcmQlNh1ghjBdJNas8IJoFZZ4dXwLO4QtLbHq3y0miNZ2RonNc+5BzelglLi/spEVospY 4v6De8wQh/JJvPvaAzWfV6KjTQiixEOibep1qHJHifYV1xghnp/BKDHpxVuWCYwyCxgZVjGK pRYU56anFhsWGOoVJ+YWl+al6yXn525iBKccLdMdjFPO+RxiFOBgVOLhXeD0KEKINbGsuDL3 EKMEB7OSCO+ViUAh3pTEyqrUovz4otKc1OJDjKbAcJrILCWanA9Mh3kl8YYmlgYmZkbARGJp aKgkziu6/lqEkEB6YklqdmpqQWoRTB8TB6dUA2PfRsbV1izvlBbdM6i4XzOvMj7ylHZpVELQ FParjgscI+YxbNwakfRAROJjw6U8tR051bbWe4L3f51st3nyUdFQp13bD0xa3M/T95mLf2el kzJr0P2utYfc/aMPZkcJc/LfkN6pV5viqGMj9Xvih5/LPgl90rknOUvGw/zKcYb4LSbrLlh/ qVdiKc5INNRiLipOBADLmmhwTwMAAA== |
| X-Brightmail-Tracker | H4sIAAAAAAAAA+NgFnrBLMWRmVeSWpSXmKPExsVy+t9jAV0Z5scRBpcXaVi8nHCY0WLijSss Fte/PGe1eHN8OpPF5V1z2CxuN65gc2Dz2DnrLrvHplWdbB7v911l8+jbsorR4/MmuQDWKDeb jNTElNQihdS85PyUzLx0W6XQEDddCyWFvMTcVFulCF3fkCAlhbLEnFIgz8gADTg4B7gHK+nb JbhlfDn7lr1gol/Fzsc3mBsYzzh0MXJySAiYSOxdsZMVwhaTuHBvPVsXIxeHkMBSRokZnQsY IZwfjBJXfx5jA6liE9CS2P/iBpgtIqAgsbn3GVg3s0ClxI5dZ8FsYYFsiZt/p4DZLAKqEj0r lrOD2LwCLhLNB9+xQGyTk/iw5xFYnFPAVeLU8WdgcSGgmq8nlrFNYORdwMiwilEitSC5oDgp PdcwL7Vcrzgxt7g0L10vOT93EyM4lJ9J7WA8uMv9EKMAB6MSD+8Cp0cRQqyJZcWVuYcYJTiY lUR4r0wECvGmJFZWpRblxxeV5qQWH2I0BTpsIrOUaHI+MM7ySuINTcxNzI0NLMwtLU2MlMR5 G2c/CxcSSE8sSc1OTS1ILYLpY+LglGpgtBRadXkvH8dt06tH/t+4YKlRJGKzLyfuiebjP288 sjgCfA57LbVPaXbelfpALuR7SUT1d/uMw3HrHM7oTA3M/qGvUZLKXyCkpPhW/3OPy7t+1omd IR1bt7H5WhbOm3u6XSXmpPrH3uPtt751HTX3yrp/ZO/GvX7rLz74uu7MifhD7gcuxO+vVGIp zkg01GIuKk4EANzu2qR7AgAA |
| X-Mtr | 20000000000000000@CPGS |
| X-Cms-Mailid | 20170404022116epcas1p14a3ffd2df99d13cbef7e361bee8a9621 |
| X-Msg-Generator | CA |
| X-Sender-IP | 203.254.230.26 |
| X-Local-Sender | 최찬우Tizen Platform Lab(S/W센터)삼성전자Senior Engineer |
| X-Global-Sender | Chanwoo ChoiTizen Platform Lab.Samsung ElectronicsSenior Engineer |
| X-Sender-Code | C10STAFC10V8111 |
| Cms-Type | 101P |
| Dlp-Filter | Pass |
| X-Cfilter-Loop | Reflected |
| X-Cms-Rootmailid | 20170404022116epcas1p14a3ffd2df99d13cbef7e361bee8a9621 |
| X-Rootmtr | 20170404022116epcas1p14a3ffd2df99d13cbef7e361bee8a9621 |
| Sender | robomod@news.nic.it |
| List-ID | <linux-kernel.vger.kernel.org> |
| X-Mailing-List | linux-kernel@vger.kernel.org |
| Approved | robomod@news.nic.it |
| Lines | 269 |
| Organization | linux.* mail to news gateway |
| X-Original-Cc | cw00.choi@samsung.com, hdegoede@redhat.com, andy.shevchenko@gmail.com, chanwoo@kernel.org, myungjoo.ham@samsung.com |
| X-Original-Date | Tue, 04 Apr 2017 11:21:14 +0900 |
| X-Original-Message-ID | <1491272474-3422-2-git-send-email-cw00.choi@samsung.com> |
| X-Original-References | <1491272474-3422-1-git-send-email-cw00.choi@samsung.com> <CGME20170404022116epcas1p14a3ffd2df99d13cbef7e361bee8a9621@epcas1p1.samsung.com> <1491272474-3422-1-git-send-email-cw00.choi@samsung.com> |
| X-Original-Sender | linux-kernel-owner@vger.kernel.org |
| Xref | csiph.com linux.kernel:1615660 |
Show key headers only | View raw
The extcon core already provides the extcon_register_notifier() function
in order to register the notifier block which is used to monitor
the state change for the specific external connector such as EXTCON_USB,
EXTCON_USB_HOST and so on. The extcon consumer uses the this function.
The extcon consumer might need to monitor the all supported external
connectors from the extcon device. In this case, The extcon consumer
should have each notifier_block structure for each external connector.
This patch adds the new extcon_register_notifier_all() function
that extcon consumer is able to monitor the state change of all
supported external connectors by using only one notifier_block structure.
- List of new added functions:
int extcon_register_notifier_all(struct extcon_dev *edev,
struct notifier_block *nb);
int extcon_unregister_notifier_all(struct extcon_dev *edev,
struct notifier_block *nb);
int devm_extcon_register_notifier_all(struct device *dev,
struct extcon_dev *edev, struct notifier_block *nb);
void devm_extcon_unregister_notifier_all(struct device *dev,
struct extcon_dev *edev, struct notifier_block *nb);
Suggested-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Tested-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Hans de Goede <hdegoede@redhat.com>
---
Changes from v1:
- Modify the function description
- Add tested/acked-by tag of Hans de Goede <hdegoede@redhat.com>
drivers/extcon/devres.c | 61 +++++++++++++++++++++++++++++++++++++++++++++
drivers/extcon/extcon.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++
drivers/extcon/extcon.h | 3 +++
include/linux/extcon.h | 21 ++++++++++++----
4 files changed, 146 insertions(+), 5 deletions(-)
diff --git a/drivers/extcon/devres.c b/drivers/extcon/devres.c
index b40eb1805927..186fd735eb28 100644
--- a/drivers/extcon/devres.c
+++ b/drivers/extcon/devres.c
@@ -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);
}
+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: device owning the extcon device being created
@@ -214,3 +221,57 @@ void devm_extcon_unregister_notifier(struct device *dev,
devm_extcon_dev_match, edev));
}
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);
diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c
index 193a3a673d10..f422a78ba342 100644
--- a/drivers/extcon/extcon.c
+++ b/drivers/extcon/extcon.c
@@ -445,8 +445,19 @@ int extcon_sync(struct extcon_dev *edev, unsigned int id)
spin_lock_irqsave(&edev->lock, flags);
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);
+ /*
+ * 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 */
prop_buf = (char *)get_zeroed_page(GFP_ATOMIC);
if (!prop_buf) {
@@ -951,6 +962,59 @@ int extcon_unregister_notifier(struct extcon_dev *edev, unsigned int id,
}
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[] = {
&dev_attr_state.attr,
&dev_attr_name.attr,
@@ -1199,6 +1263,8 @@ int extcon_dev_register(struct extcon_dev *edev)
for (index = 0; index < edev->max_supported; index++)
RAW_INIT_NOTIFIER_HEAD(&edev->nh[index]);
+ RAW_INIT_NOTIFIER_HEAD(&edev->nh_all);
+
dev_set_drvdata(&edev->dev, edev);
edev->state = 0;
diff --git a/drivers/extcon/extcon.h b/drivers/extcon/extcon.h
index 993ddccafe11..dddddcfa0587 100644
--- a/drivers/extcon/extcon.h
+++ b/drivers/extcon/extcon.h
@@ -21,6 +21,8 @@
* @dev: Device of this extcon.
* @state: Attach/detach state of this extcon. Do not provide at
* 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
* @entry: To support list of extcon devices so that users can
* search for extcon devices based on the extcon name.
@@ -43,6 +45,7 @@ struct extcon_dev {
/* Internal data. Please do not set. */
struct device dev;
+ struct raw_notifier_head nh_all;
struct raw_notifier_head *nh;
struct list_head entry;
int max_supported;
diff --git a/include/linux/extcon.h b/include/linux/extcon.h
index 3929d2e8a3c7..e20f318c0c6d 100644
--- a/include/linux/extcon.h
+++ b/include/linux/extcon.h
@@ -270,11 +270,11 @@ extern int extcon_set_property_capability(struct extcon_dev *edev,
unsigned int id, unsigned int prop);
/*
- * Following APIs are to monitor every action of a notifier.
- * Registrar gets notified for every external port of a connection device.
- * Probably this could be used to debug an action of notifier; however,
- * we do not recommend to use this for normal 'notifiee' device drivers who
- * want to be notified by a specific external port of the notifier.
+ * Following APIs are to monitor the status change of the external connectors.
+ * extcon_register_notifier(*edev, id, *nb) : Register a notifier block
+ * for specific external connector of the extcon.
+ * extcon_register_notifier_all(*edev, *nb) : Register a notifier block
+ * for all supported external connectors of the extcon.
*/
extern int extcon_register_notifier(struct extcon_dev *edev, unsigned int id,
struct notifier_block *nb);
@@ -287,6 +287,17 @@ extern void devm_extcon_unregister_notifier(struct device *dev,
struct extcon_dev *edev, unsigned int id,
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.
* This function use phandle of devicetree to get extcon device directly.
--
1.9.1
Back to linux.kernel | Previous | Next | Find similar | Unroll thread
[PATCH v2 2/2] extcon: Add new extcon_register_notifier_all() to monitor all external connectors Chanwoo Choi <cw00.choi@samsung.com> - 2017-04-04 04:30 +0200
csiph-web