diff options
author | Bjoern A. Zeeb <bz@FreeBSD.org> | 2021-05-28 11:04:34 +0000 |
---|---|---|
committer | Bjoern A. Zeeb <bz@FreeBSD.org> | 2021-07-18 00:35:03 +0000 |
commit | 05cb0d21ed4bf7ac5a78a62a10b33b222f3762cc (patch) | |
tree | 939e891675a9deef3a2cf422a37352b38f3e08ea | |
parent | b9e51ecb5a477ed5b0c3e9c67f09472ed6d0a46a (diff) | |
download | src-05cb0d21ed4bf7ac5a78a62a10b33b222f3762cc.tar.gz src-05cb0d21ed4bf7ac5a78a62a10b33b222f3762cc.zip |
LinuxKPI: add device_reprobe() and device_release_driver()
Add two new (though untested) functions to linux/device.h which are
dealing with manually managing the device/driver and are used by
at least one wireless driver. We may have to re-fine them in the
future.
Move the devres declarations further up so they can be used earlier
in the file.
Sponsored by: The FreeBSD Foundation
Reviewed by: imp
Differential Revision: https://reviews.freebsd.org/D30519
(cherry picked from commit 644b4f117634e3b571031026be87429bea0c30dd)
-rw-r--r-- | sys/compat/linuxkpi/common/include/linux/device.h | 67 |
1 files changed, 47 insertions, 20 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/device.h b/sys/compat/linuxkpi/common/include/linux/device.h index 4ef35e6abcd3..4bdc3b831e58 100644 --- a/sys/compat/linuxkpi/common/include/linux/device.h +++ b/sys/compat/linuxkpi/common/include/linux/device.h @@ -209,6 +209,25 @@ show_class_attr_string(struct class *class, dev_warn(dev, __VA_ARGS__); \ } while (0) +/* Public and LinuxKPI internal devres functions. */ +void *lkpi_devres_alloc(void(*release)(struct device *, void *), size_t, gfp_t); +void lkpi_devres_add(struct device *, void *); +void lkpi_devres_free(void *); +void *lkpi_devres_find(struct device *, void(*release)(struct device *, void *), + int (*match)(struct device *, void *, void *), void *); +int lkpi_devres_destroy(struct device *, void(*release)(struct device *, void *), + int (*match)(struct device *, void *, void *), void *); +#define devres_alloc(_r, _s, _g) lkpi_devres_alloc(_r, _s, _g) +#define devres_add(_d, _p) lkpi_devres_add(_d, _p) +#define devres_free(_p) lkpi_devres_free(_p) +#define devres_find(_d, _rfn, _mfn, _mp) \ + lkpi_devres_find(_d, _rfn, _mfn, _mp) +#define devres_destroy(_d, _rfn, _mfn, _mp) \ + lkpi_devres_destroy(_d, _rfn, _mfn, _mp) +void lkpi_devres_release_free_list(struct device *); +void lkpi_devres_unlink(struct device *, void *); +void lkpi_devm_kmalloc_release(struct device *, void *); + static inline void * dev_get_drvdata(const struct device *dev) { @@ -483,6 +502,34 @@ device_destroy(struct class *class, dev_t devt) device_unregister(device_get_softc(bsddev)); } +static inline void +device_release_driver(struct device *dev) +{ + + /* We also need to cleanup LinuxKPI bits. What else? */ + lkpi_devres_release_free_list(dev); + dev_set_drvdata(dev, NULL); + /* Do not call dev->release! */ + + mtx_lock(&Giant); + if (device_is_attached(dev->bsddev)) + device_detach(dev->bsddev); + mtx_unlock(&Giant); +} + +static inline int +device_reprobe(struct device *dev) +{ + int error; + + device_release_driver(dev); + mtx_lock(&Giant); + error = device_probe_and_attach(dev->bsddev); + mtx_unlock(&Giant); + + return (-error); +} + #define dev_pm_set_driver_flags(dev, flags) do { \ } while (0) @@ -566,26 +613,6 @@ char *lkpi_devm_kasprintf(struct device *, gfp_t, const char *, ...); #define devm_kasprintf(_dev, _gfp, _fmt, ...) \ lkpi_devm_kasprintf(_dev, _gfp, _fmt, ##__VA_ARGS__) -void *lkpi_devres_alloc(void(*release)(struct device *, void *), size_t, gfp_t); -void lkpi_devres_add(struct device *, void *); -void lkpi_devres_free(void *); -void *lkpi_devres_find(struct device *, void(*release)(struct device *, void *), - int (*match)(struct device *, void *, void *), void *); -int lkpi_devres_destroy(struct device *, void(*release)(struct device *, void *), - int (*match)(struct device *, void *, void *), void *); -#define devres_alloc(_r, _s, _g) lkpi_devres_alloc(_r, _s, _g) -#define devres_add(_d, _p) lkpi_devres_add(_d, _p) -#define devres_free(_p) lkpi_devres_free(_p) -#define devres_find(_d, _rfn, _mfn, _mp) \ - lkpi_devres_find(_d, _rfn, _mfn, _mp) -#define devres_destroy(_d, _rfn, _mfn, _mp) \ - lkpi_devres_destroy(_d, _rfn, _mfn, _mp) - -/* LinuxKPI internal functions. */ -void lkpi_devres_release_free_list(struct device *); -void lkpi_devres_unlink(struct device *, void *); -void lkpi_devm_kmalloc_release(struct device *, void *); - static __inline void * devm_kmalloc(struct device *dev, size_t size, gfp_t gfp) { |