Index: sys/compat/linuxkpi/common/include/linux/device.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/device.h +++ sys/compat/linuxkpi/common/include/linux/device.h @@ -209,6 +209,25 @@ 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_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 @@ #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) {