Introduce devres-based helper for of_reserved_mem_device_init() to help fight dangling references and ever so slightly reduce the number of boilerplate deinitialization calls.
Unified · Split
| @@ -788,6 +788,50 @@ void of_reserved_mem_device_release(struct device *dev) · 787 unmodified lines | ||
| 788 | 788 | } |
| 789 | 789 | EXPORT_SYMBOL_GPL(of_reserved_mem_device_release); |
| 790 | 790 | |
| 791 | +static void devm_of_reserved_mem_device_release(struct device *dev, void *res) | |
| 792 | +{ | |
| 793 | + of_reserved_mem_device_release(*(struct device **)res); | |
| 794 | +} | |
| 795 | + | |
| 796 | +static int devm_of_reserved_mem_device_init_by_idx(struct device *dev, | |
| 797 | + struct device_node *np, int idx) | |
| 798 | +{ | |
| 799 | + struct device **ptr; | |
| 800 | + int ret; | |
| 801 | + | |
| 802 | + ptr = devres_alloc(devm_of_reserved_mem_device_release, sizeof(*ptr), | |
| 803 | + GFP_KERNEL); | |
| 804 | + if (!ptr) | |
| 805 | + return -ENOMEM; | |
| 806 | + | |
| 807 | + ret = of_reserved_mem_device_init_by_idx(dev, np, idx); | |
| 808 | + if (ret) { | |
| 809 | + devres_free(ptr); | |
| 810 | + return ret; | |
| 811 | + } | |
| 812 | + | |
| 813 | + *ptr = dev; | |
| 814 | + devres_add(dev, ptr); | |
| 815 | + | |
| 816 | + return 0; | |
| 817 | +} | |
| 818 | + | |
| 819 | +/** | |
| 820 | + * devm_of_reserved_mem_device_init() - Resource managed of_reserved_mem_device_init() | |
| 821 | + * @dev: Pointer to the device to configure | |
| 822 | + * | |
| 823 | + * This is a resource managed version of of_reserved_mem_device_init(). | |
| 824 | + * The reserved memory region will be released automatically when the device | |
| 825 | + * is unbound. | |
| 826 | + * | |
| 827 | + * Returns: Negative errno on failure or zero on success. | |
| 828 | + */ | |
| 829 | +int devm_of_reserved_mem_device_init(struct device *dev) | |
| 830 | +{ | |
| 831 | + return devm_of_reserved_mem_device_init_by_idx(dev, dev->of_node, 0); | |
| 832 | +} | |
| 833 | +EXPORT_SYMBOL_GPL(devm_of_reserved_mem_device_init); | |
| 834 | + | |
| 791 | 835 | /** |
| 792 | 836 | * of_reserved_mem_lookup() - acquire reserved_mem from a device node |
| 793 | 837 | * @np: node pointer of the desired reserved-memory region |
| @@ -40,6 +40,8 @@ int of_reserved_mem_device_init_by_name(struct device *dev, · 39 unmodified lines | ||
| 40 | 40 | const char *name); |
| 41 | 41 | void of_reserved_mem_device_release(struct device *dev); |
| 42 | 42 | |
| 43 | +int devm_of_reserved_mem_device_init(struct device *dev); | |
| 44 | + | |
| 43 | 45 | struct reserved_mem *of_reserved_mem_lookup(struct device_node *np); |
| 44 | 46 | int of_reserved_mem_region_to_resource(const struct device_node *np, |
| 45 | 47 | unsigned int idx, struct resource *res); |
| @@ -68,6 +70,11 @@ static inline int of_reserved_mem_device_init_by_name(struct device *dev, · 22 unmodified lines | ||
| 68 | 70 | |
| 69 | 71 | static inline void of_reserved_mem_device_release(struct device *pdev) { } |
| 70 | 72 | |
| 73 | +static inline int devm_of_reserved_mem_device_init(struct device *dev) | |
| 74 | +{ | |
| 75 | + return -EOPNOTSUPP; | |
| 76 | +} | |
| 77 | + | |
| 71 | 78 | static inline struct reserved_mem *of_reserved_mem_lookup(struct device_node *np) |
| 72 | 79 | { |
| 73 | 80 | return NULL; |