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