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
MFC after:	10 days
Reviewed by:	imp
Differential Revision: https://reviews.freebsd.org/D30519
This commit is contained in:
Bjoern A. Zeeb 2021-05-28 11:04:34 +00:00
parent 1411f52fac
commit 644b4f1176

View File

@ -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)
{