xref: /linux-6.15/include/linux/fwctl.h (revision 2e4986cf)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES
4  */
5 #ifndef __LINUX_FWCTL_H
6 #define __LINUX_FWCTL_H
7 #include <linux/device.h>
8 #include <linux/cdev.h>
9 #include <linux/cleanup.h>
10 
11 struct fwctl_device;
12 struct fwctl_uctx;
13 
14 struct fwctl_ops {
15 };
16 
17 /**
18  * struct fwctl_device - Per-driver registration struct
19  * @dev: The sysfs (class/fwctl/fwctlXX) device
20  *
21  * Each driver instance will have one of these structs with the driver private
22  * data following immediately after. This struct is refcounted, it is freed by
23  * calling fwctl_put().
24  */
25 struct fwctl_device {
26 	struct device dev;
27 	/* private: */
28 	struct cdev cdev;
29 	const struct fwctl_ops *ops;
30 };
31 
32 struct fwctl_device *_fwctl_alloc_device(struct device *parent,
33 					 const struct fwctl_ops *ops,
34 					 size_t size);
35 /**
36  * fwctl_alloc_device - Allocate a fwctl
37  * @parent: Physical device that provides the FW interface
38  * @ops: Driver ops to register
39  * @drv_struct: 'struct driver_fwctl' that holds the struct fwctl_device
40  * @member: Name of the struct fwctl_device in @drv_struct
41  *
42  * This allocates and initializes the fwctl_device embedded in the drv_struct.
43  * Upon success the pointer must be freed via fwctl_put(). Returns a 'drv_struct
44  * \*' on success, NULL on error.
45  */
46 #define fwctl_alloc_device(parent, ops, drv_struct, member)               \
47 	({                                                                \
48 		static_assert(__same_type(struct fwctl_device,            \
49 					  ((drv_struct *)NULL)->member)); \
50 		static_assert(offsetof(drv_struct, member) == 0);         \
51 		(drv_struct *)_fwctl_alloc_device(parent, ops,            \
52 						  sizeof(drv_struct));    \
53 	})
54 
55 static inline struct fwctl_device *fwctl_get(struct fwctl_device *fwctl)
56 {
57 	get_device(&fwctl->dev);
58 	return fwctl;
59 }
60 static inline void fwctl_put(struct fwctl_device *fwctl)
61 {
62 	put_device(&fwctl->dev);
63 }
64 DEFINE_FREE(fwctl, struct fwctl_device *, if (_T) fwctl_put(_T));
65 
66 int fwctl_register(struct fwctl_device *fwctl);
67 void fwctl_unregister(struct fwctl_device *fwctl);
68 
69 #endif
70