diff options
author | Chanwoo Choi <cw00.choi@samsung.com> | 2016-06-27 07:03:39 -0400 |
---|---|---|
committer | Chanwoo Choi <cw00.choi@samsung.com> | 2016-06-27 08:03:23 -0400 |
commit | 58f386560a68dd98bd6744a28fc853eef11faebe (patch) | |
tree | 79265ea59e032c3bd44523374e3a59c263d5fce1 | |
parent | b225d00f3ad2d996f914790a0f6324a4efd18768 (diff) |
extcon: Add resource-managed functions to register extcon notifier
This patch adds the resource-managed functions for register/unregister
the extcon notifier with the id of each external connector. This function
will make it easy to handle the extcon notifier.
- int devm_extcon_register_notifier(struct device *dev,
struct extcon_dev *edev, unsigned int id,
struct notifier_block *nb);
- void devm_extcon_unregister_notifier(struct device *dev,
struct extcon_dev *edev, unsigned int id,
struct notifier_block *nb);
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
-rw-r--r-- | drivers/extcon/devres.c | 73 | ||||
-rw-r--r-- | include/linux/extcon.h | 17 |
2 files changed, 90 insertions, 0 deletions
diff --git a/drivers/extcon/devres.c b/drivers/extcon/devres.c index 694ca85d5a70..e686acd1c459 100644 --- a/drivers/extcon/devres.c +++ b/drivers/extcon/devres.c | |||
@@ -37,6 +37,19 @@ static void devm_extcon_dev_unreg(struct device *dev, void *res) | |||
37 | extcon_dev_unregister(*(struct extcon_dev **)res); | 37 | extcon_dev_unregister(*(struct extcon_dev **)res); |
38 | } | 38 | } |
39 | 39 | ||
40 | struct extcon_dev_notifier_devres { | ||
41 | struct extcon_dev *edev; | ||
42 | unsigned int id; | ||
43 | struct notifier_block *nb; | ||
44 | }; | ||
45 | |||
46 | static void devm_extcon_dev_notifier_unreg(struct device *dev, void *res) | ||
47 | { | ||
48 | struct extcon_dev_notifier_devres *this = res; | ||
49 | |||
50 | extcon_unregister_notifier(this->edev, this->id, this->nb); | ||
51 | } | ||
52 | |||
40 | /** | 53 | /** |
41 | * devm_extcon_dev_allocate - Allocate managed extcon device | 54 | * devm_extcon_dev_allocate - Allocate managed extcon device |
42 | * @dev: device owning the extcon device being created | 55 | * @dev: device owning the extcon device being created |
@@ -141,3 +154,63 @@ void devm_extcon_dev_unregister(struct device *dev, struct extcon_dev *edev) | |||
141 | devm_extcon_dev_match, edev)); | 154 | devm_extcon_dev_match, edev)); |
142 | } | 155 | } |
143 | EXPORT_SYMBOL_GPL(devm_extcon_dev_unregister); | 156 | EXPORT_SYMBOL_GPL(devm_extcon_dev_unregister); |
157 | |||
158 | /** | ||
159 | * devm_extcon_register_notifier() - Resource-managed extcon_register_notifier() | ||
160 | * @dev: device to allocate extcon device | ||
161 | * @edev: the extcon device that has the external connecotr. | ||
162 | * @id: the unique id of each external connector in extcon enumeration. | ||
163 | * @nb: a notifier block to be registered. | ||
164 | * | ||
165 | * This function manages automatically the notifier of extcon device using | ||
166 | * device resource management and simplify the control of unregistering | ||
167 | * the notifier of extcon device. | ||
168 | * | ||
169 | * Note that the second parameter given to the callback of nb (val) is | ||
170 | * "old_state", not the current state. The current state can be retrieved | ||
171 | * by looking at the third pameter (edev pointer)'s state value. | ||
172 | * | ||
173 | * Returns 0 if success or negaive error number if failure. | ||
174 | */ | ||
175 | int devm_extcon_register_notifier(struct device *dev, struct extcon_dev *edev, | ||
176 | unsigned int id, struct notifier_block *nb) | ||
177 | { | ||
178 | struct extcon_dev_notifier_devres *ptr; | ||
179 | int ret; | ||
180 | |||
181 | ptr = devres_alloc(devm_extcon_dev_notifier_unreg, sizeof(*ptr), | ||
182 | GFP_KERNEL); | ||
183 | if (!ptr) | ||
184 | return -ENOMEM; | ||
185 | |||
186 | ret = extcon_register_notifier(edev, id, nb); | ||
187 | if (ret) { | ||
188 | devres_free(ptr); | ||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | ptr->edev = edev; | ||
193 | ptr->id = id; | ||
194 | ptr->nb = nb; | ||
195 | devres_add(dev, ptr); | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | EXPORT_SYMBOL(devm_extcon_register_notifier); | ||
200 | |||
201 | /** | ||
202 | * devm_extcon_unregister_notifier() | ||
203 | - Resource-managed extcon_unregister_notifier() | ||
204 | * @dev: device to allocate extcon device | ||
205 | * @edev: the extcon device that has the external connecotr. | ||
206 | * @id: the unique id of each external connector in extcon enumeration. | ||
207 | * @nb: a notifier block to be registered. | ||
208 | */ | ||
209 | void devm_extcon_unregister_notifier(struct device *dev, | ||
210 | struct extcon_dev *edev, unsigned int id, | ||
211 | struct notifier_block *nb) | ||
212 | { | ||
213 | WARN_ON(devres_release(dev, devm_extcon_dev_notifier_unreg, | ||
214 | devm_extcon_dev_match, edev)); | ||
215 | } | ||
216 | EXPORT_SYMBOL(devm_extcon_unregister_notifier); | ||
diff --git a/include/linux/extcon.h b/include/linux/extcon.h index 1b2c8b6809cc..7bf530f3f4f5 100644 --- a/include/linux/extcon.h +++ b/include/linux/extcon.h | |||
@@ -182,6 +182,12 @@ extern int extcon_register_notifier(struct extcon_dev *edev, unsigned int id, | |||
182 | struct notifier_block *nb); | 182 | struct notifier_block *nb); |
183 | extern int extcon_unregister_notifier(struct extcon_dev *edev, unsigned int id, | 183 | extern int extcon_unregister_notifier(struct extcon_dev *edev, unsigned int id, |
184 | struct notifier_block *nb); | 184 | struct notifier_block *nb); |
185 | extern int devm_extcon_register_notifier(struct device *dev, | ||
186 | struct extcon_dev *edev, unsigned int id, | ||
187 | struct notifier_block *nb); | ||
188 | extern void devm_extcon_unregister_notifier(struct device *dev, | ||
189 | struct extcon_dev *edev, unsigned int id, | ||
190 | struct notifier_block *nb); | ||
185 | 191 | ||
186 | /* | 192 | /* |
187 | * Following API get the extcon device from devicetree. | 193 | * Following API get the extcon device from devicetree. |
@@ -273,6 +279,17 @@ static inline int extcon_unregister_notifier(struct extcon_dev *edev, | |||
273 | return 0; | 279 | return 0; |
274 | } | 280 | } |
275 | 281 | ||
282 | static inline int devm_extcon_register_notifier(struct device *dev, | ||
283 | struct extcon_dev *edev, unsigned int id, | ||
284 | struct notifier_block *nb) | ||
285 | { | ||
286 | return -ENOSYS; | ||
287 | } | ||
288 | |||
289 | static inline void devm_extcon_unregister_notifier(struct device *dev, | ||
290 | struct extcon_dev *edev, unsigned int id, | ||
291 | struct notifier_block *nb) { } | ||
292 | |||
276 | static inline struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, | 293 | static inline struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, |
277 | int index) | 294 | int index) |
278 | { | 295 | { |