/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES */ #ifndef __LINUX_FWCTL_H #define __LINUX_FWCTL_H #include #include #include struct fwctl_device; struct fwctl_uctx; struct fwctl_ops { }; /** * struct fwctl_device - Per-driver registration struct * @dev: The sysfs (class/fwctl/fwctlXX) device * * Each driver instance will have one of these structs with the driver private * data following immediately after. This struct is refcounted, it is freed by * calling fwctl_put(). */ struct fwctl_device { struct device dev; /* private: */ struct cdev cdev; const struct fwctl_ops *ops; }; struct fwctl_device *_fwctl_alloc_device(struct device *parent, const struct fwctl_ops *ops, size_t size); /** * fwctl_alloc_device - Allocate a fwctl * @parent: Physical device that provides the FW interface * @ops: Driver ops to register * @drv_struct: 'struct driver_fwctl' that holds the struct fwctl_device * @member: Name of the struct fwctl_device in @drv_struct * * This allocates and initializes the fwctl_device embedded in the drv_struct. * Upon success the pointer must be freed via fwctl_put(). Returns a 'drv_struct * \*' on success, NULL on error. */ #define fwctl_alloc_device(parent, ops, drv_struct, member) \ ({ \ static_assert(__same_type(struct fwctl_device, \ ((drv_struct *)NULL)->member)); \ static_assert(offsetof(drv_struct, member) == 0); \ (drv_struct *)_fwctl_alloc_device(parent, ops, \ sizeof(drv_struct)); \ }) static inline struct fwctl_device *fwctl_get(struct fwctl_device *fwctl) { get_device(&fwctl->dev); return fwctl; } static inline void fwctl_put(struct fwctl_device *fwctl) { put_device(&fwctl->dev); } DEFINE_FREE(fwctl, struct fwctl_device *, if (_T) fwctl_put(_T)); int fwctl_register(struct fwctl_device *fwctl); void fwctl_unregister(struct fwctl_device *fwctl); #endif