aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjoern A. Zeeb <bz@FreeBSD.org>2021-05-28 11:04:34 +0000
committerBjoern A. Zeeb <bz@FreeBSD.org>2021-07-18 00:35:03 +0000
commit05cb0d21ed4bf7ac5a78a62a10b33b222f3762cc (patch)
tree939e891675a9deef3a2cf422a37352b38f3e08ea
parentb9e51ecb5a477ed5b0c3e9c67f09472ed6d0a46a (diff)
downloadsrc-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.h67
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)
{