![]() |
|
|||
0001 /* SPDX-License-Identifier: GPL-2.0-only */ 0002 #ifndef __LINUX_DEVM_HELPERS_H 0003 #define __LINUX_DEVM_HELPERS_H 0004 0005 /* 0006 * Functions which do automatically cancel operations or release resources upon 0007 * driver detach. 0008 * 0009 * These should be helpful to avoid mixing the manual and devm-based resource 0010 * management which can be source of annoying, rarely occurring, 0011 * hard-to-reproduce bugs. 0012 * 0013 * Please take into account that devm based cancellation may be performed some 0014 * time after the remove() is ran. 0015 * 0016 * Thus mixing devm and manual resource management can easily cause problems 0017 * when unwinding operations with dependencies. IRQ scheduling a work in a queue 0018 * is typical example where IRQs are often devm-managed and WQs are manually 0019 * cleaned at remove(). If IRQs are not manually freed at remove() (and this is 0020 * often the case when we use devm for IRQs) we have a period of time after 0021 * remove() - and before devm managed IRQs are freed - where new IRQ may fire 0022 * and schedule a work item which won't be cancelled because remove() was 0023 * already ran. 0024 */ 0025 0026 #include <linux/device.h> 0027 #include <linux/workqueue.h> 0028 0029 static inline void devm_delayed_work_drop(void *res) 0030 { 0031 cancel_delayed_work_sync(res); 0032 } 0033 0034 /** 0035 * devm_delayed_work_autocancel - Resource-managed delayed work allocation 0036 * @dev: Device which lifetime work is bound to 0037 * @w: Work item to be queued 0038 * @worker: Worker function 0039 * 0040 * Initialize delayed work which is automatically cancelled when driver is 0041 * detached. A few drivers need delayed work which must be cancelled before 0042 * driver is detached to avoid accessing removed resources. 0043 * devm_delayed_work_autocancel() can be used to omit the explicit 0044 * cancelleation when driver is detached. 0045 */ 0046 static inline int devm_delayed_work_autocancel(struct device *dev, 0047 struct delayed_work *w, 0048 work_func_t worker) 0049 { 0050 INIT_DELAYED_WORK(w, worker); 0051 return devm_add_action(dev, devm_delayed_work_drop, w); 0052 } 0053 0054 static inline void devm_work_drop(void *res) 0055 { 0056 cancel_work_sync(res); 0057 } 0058 0059 /** 0060 * devm_work_autocancel - Resource-managed work allocation 0061 * @dev: Device which lifetime work is bound to 0062 * @w: Work to be added (and automatically cancelled) 0063 * @worker: Worker function 0064 * 0065 * Initialize work which is automatically cancelled when driver is detached. 0066 * A few drivers need to queue work which must be cancelled before driver 0067 * is detached to avoid accessing removed resources. 0068 * devm_work_autocancel() can be used to omit the explicit 0069 * cancelleation when driver is detached. 0070 */ 0071 static inline int devm_work_autocancel(struct device *dev, 0072 struct work_struct *w, 0073 work_func_t worker) 0074 { 0075 INIT_WORK(w, worker); 0076 return devm_add_action(dev, devm_work_drop, w); 0077 } 0078 0079 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |