1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2021 Intel Corporation. All rights rsvd. */
3 #include <linux/init.h>
4 #include <linux/kernel.h>
5 #include <linux/module.h>
6 #include <linux/device.h>
7 #include <linux/device/bus.h>
10 extern void device_driver_detach(struct device
*dev
);
12 #define DRIVER_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \
13 struct driver_attribute driver_attr_##_name = \
14 __ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store)
16 static ssize_t
unbind_store(struct device_driver
*drv
, const char *buf
, size_t count
)
18 const struct bus_type
*bus
= drv
->bus
;
22 dev
= bus_find_device_by_name(bus
, NULL
, buf
);
23 if (dev
&& dev
->driver
) {
24 device_driver_detach(dev
);
30 static DRIVER_ATTR_IGNORE_LOCKDEP(unbind
, 0200, NULL
, unbind_store
);
32 static ssize_t
bind_store(struct device_driver
*drv
, const char *buf
, size_t count
)
34 const struct bus_type
*bus
= drv
->bus
;
36 struct device_driver
*alt_drv
= NULL
;
38 struct idxd_dev
*idxd_dev
;
40 dev
= bus_find_device_by_name(bus
, NULL
, buf
);
41 if (!dev
|| dev
->driver
|| drv
!= &dsa_drv
.drv
)
44 idxd_dev
= confdev_to_idxd_dev(dev
);
45 if (is_idxd_dev(idxd_dev
)) {
46 alt_drv
= driver_find("idxd", bus
);
47 } else if (is_idxd_wq_dev(idxd_dev
)) {
48 struct idxd_wq
*wq
= confdev_to_wq(dev
);
50 if (is_idxd_wq_kernel(wq
))
51 alt_drv
= driver_find("dmaengine", bus
);
52 else if (is_idxd_wq_user(wq
))
53 alt_drv
= driver_find("user", bus
);
58 rc
= device_driver_attach(alt_drv
, dev
);
64 static DRIVER_ATTR_IGNORE_LOCKDEP(bind
, 0200, NULL
, bind_store
);
66 static struct attribute
*dsa_drv_compat_attrs
[] = {
67 &driver_attr_bind
.attr
,
68 &driver_attr_unbind
.attr
,
72 static const struct attribute_group dsa_drv_compat_attr_group
= {
73 .attrs
= dsa_drv_compat_attrs
,
76 static const struct attribute_group
*dsa_drv_compat_groups
[] = {
77 &dsa_drv_compat_attr_group
,
81 static int idxd_dsa_drv_probe(struct idxd_dev
*idxd_dev
)
86 static void idxd_dsa_drv_remove(struct idxd_dev
*idxd_dev
)
90 static enum idxd_dev_type dev_types
[] = {
94 struct idxd_device_driver dsa_drv
= {
96 .probe
= idxd_dsa_drv_probe
,
97 .remove
= idxd_dsa_drv_remove
,
100 .suppress_bind_attrs
= true,
101 .groups
= dsa_drv_compat_groups
,
105 module_idxd_driver(dsa_drv
);
106 MODULE_IMPORT_NS(IDXD
);