mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-23 07:23:12 +02:00

Create the class, character device and functions for a fwctl driver to un/register to the subsystem. A typical fwctl driver has a sysfs presence like: $ ls -l /dev/fwctl/fwctl0 crw------- 1 root root 250, 0 Apr 25 19:16 /dev/fwctl/fwctl0 $ ls /sys/class/fwctl/fwctl0 dev device power subsystem uevent $ ls /sys/class/fwctl/fwctl0/device/infiniband/ ibp0s10f0 $ ls /sys/class/infiniband/ibp0s10f0/device/fwctl/ fwctl0/ $ ls /sys/devices/pci0000:00/0000:00:0a.0/fwctl/fwctl0 dev device power subsystem uevent Which allows userspace to link all the multi-subsystem driver components together and learn the subsystem specific names for the device's components. Link: https://patch.msgid.link/r/1-v5-642aa0c94070+4447f-fwctl_jgg@nvidia.com Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Dan Williams <dan.j.williams@intel.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Shannon Nelson <shannon.nelson@amd.com> Tested-by: Dave Jiang <dave.jiang@intel.com> Tested-by: Shannon Nelson <shannon.nelson@amd.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
70 lines
2.0 KiB
C
70 lines
2.0 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES
|
|
*/
|
|
#ifndef __LINUX_FWCTL_H
|
|
#define __LINUX_FWCTL_H
|
|
#include <linux/device.h>
|
|
#include <linux/cdev.h>
|
|
#include <linux/cleanup.h>
|
|
|
|
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
|