1d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */ 27b96953bSKirti Wankhede /* 37b96953bSKirti Wankhede * Mediated device definition 47b96953bSKirti Wankhede * 57b96953bSKirti Wankhede * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 67b96953bSKirti Wankhede * Author: Neo Jia <cjia@nvidia.com> 77b96953bSKirti Wankhede * Kirti Wankhede <kwankhede@nvidia.com> 87b96953bSKirti Wankhede */ 97b96953bSKirti Wankhede 107b96953bSKirti Wankhede #ifndef MDEV_H 117b96953bSKirti Wankhede #define MDEV_H 127b96953bSKirti Wankhede 13bdef2b78SChristoph Hellwig #include <linux/device.h> 14bdef2b78SChristoph Hellwig #include <linux/uuid.h> 15bdef2b78SChristoph Hellwig 16417fd5bfSJason Gunthorpe struct mdev_type; 17417fd5bfSJason Gunthorpe 182a3d15f2SJason Gunthorpe struct mdev_device { 192a3d15f2SJason Gunthorpe struct device dev; 202a3d15f2SJason Gunthorpe guid_t uuid; 212a3d15f2SJason Gunthorpe struct list_head next; 22417fd5bfSJason Gunthorpe struct mdev_type *type; 232a3d15f2SJason Gunthorpe bool active; 242a3d15f2SJason Gunthorpe }; 252a3d15f2SJason Gunthorpe 26*da44c340SChristoph Hellwig struct mdev_type { 27*da44c340SChristoph Hellwig /* set by the driver before calling mdev_register parent: */ 28*da44c340SChristoph Hellwig const char *sysfs_name; 29*da44c340SChristoph Hellwig 30*da44c340SChristoph Hellwig /* set by the core, can be used drivers */ 31*da44c340SChristoph Hellwig struct mdev_parent *parent; 32*da44c340SChristoph Hellwig 33*da44c340SChristoph Hellwig /* internal only */ 34*da44c340SChristoph Hellwig struct kobject kobj; 35*da44c340SChristoph Hellwig struct kobject *devices_kobj; 36*da44c340SChristoph Hellwig }; 37*da44c340SChristoph Hellwig 3889345d51SChristoph Hellwig /* embedded into the struct device that the mdev devices hang off */ 3989345d51SChristoph Hellwig struct mdev_parent { 4089345d51SChristoph Hellwig struct device *dev; 4189345d51SChristoph Hellwig struct mdev_driver *mdev_driver; 4289345d51SChristoph Hellwig struct kset *mdev_types_kset; 4389345d51SChristoph Hellwig /* Synchronize device creation/removal with parent unregistration */ 4489345d51SChristoph Hellwig struct rw_semaphore unreg_sem; 45*da44c340SChristoph Hellwig struct mdev_type **types; 46*da44c340SChristoph Hellwig unsigned int nr_types; 4789345d51SChristoph Hellwig }; 4889345d51SChristoph Hellwig 492a3d15f2SJason Gunthorpe static inline struct mdev_device *to_mdev_device(struct device *dev) 502a3d15f2SJason Gunthorpe { 512a3d15f2SJason Gunthorpe return container_of(dev, struct mdev_device, dev); 522a3d15f2SJason Gunthorpe } 537b96953bSKirti Wankhede 549169cff1SJason Gunthorpe struct device *mtype_get_parent_dev(struct mdev_type *mtype); 5515fcc44bSJason Gunthorpe 567b96953bSKirti Wankhede /* interface for exporting mdev supported type attributes */ 577b96953bSKirti Wankhede struct mdev_type_attribute { 587b96953bSKirti Wankhede struct attribute attr; 599169cff1SJason Gunthorpe ssize_t (*show)(struct mdev_type *mtype, 609169cff1SJason Gunthorpe struct mdev_type_attribute *attr, char *buf); 619169cff1SJason Gunthorpe ssize_t (*store)(struct mdev_type *mtype, 629169cff1SJason Gunthorpe struct mdev_type_attribute *attr, const char *buf, 639169cff1SJason Gunthorpe size_t count); 647b96953bSKirti Wankhede }; 657b96953bSKirti Wankhede 667b96953bSKirti Wankhede #define MDEV_TYPE_ATTR(_name, _mode, _show, _store) \ 677b96953bSKirti Wankhede struct mdev_type_attribute mdev_type_attr_##_name = \ 687b96953bSKirti Wankhede __ATTR(_name, _mode, _show, _store) 697b96953bSKirti Wankhede #define MDEV_TYPE_ATTR_RW(_name) \ 707b96953bSKirti Wankhede struct mdev_type_attribute mdev_type_attr_##_name = __ATTR_RW(_name) 717b96953bSKirti Wankhede #define MDEV_TYPE_ATTR_RO(_name) \ 727b96953bSKirti Wankhede struct mdev_type_attribute mdev_type_attr_##_name = __ATTR_RO(_name) 737b96953bSKirti Wankhede #define MDEV_TYPE_ATTR_WO(_name) \ 747b96953bSKirti Wankhede struct mdev_type_attribute mdev_type_attr_##_name = __ATTR_WO(_name) 757b96953bSKirti Wankhede 767b96953bSKirti Wankhede /** 777b96953bSKirti Wankhede * struct mdev_driver - Mediated device driver 787b96953bSKirti Wankhede * @probe: called when new device created 797b96953bSKirti Wankhede * @remove: called when device removed 80*da44c340SChristoph Hellwig * @types_attrs: attributes to the type kobjects. 817b96953bSKirti Wankhede * @driver: device driver structure 827b96953bSKirti Wankhede **/ 837b96953bSKirti Wankhede struct mdev_driver { 842a3d15f2SJason Gunthorpe int (*probe)(struct mdev_device *dev); 852a3d15f2SJason Gunthorpe void (*remove)(struct mdev_device *dev); 86*da44c340SChristoph Hellwig const struct attribute * const *types_attrs; 877b96953bSKirti Wankhede struct device_driver driver; 887b96953bSKirti Wankhede }; 897b96953bSKirti Wankhede 907b96953bSKirti Wankhede extern struct bus_type mdev_bus_type; 917b96953bSKirti Wankhede 9289345d51SChristoph Hellwig int mdev_register_parent(struct mdev_parent *parent, struct device *dev, 93*da44c340SChristoph Hellwig struct mdev_driver *mdev_driver, struct mdev_type **types, 94*da44c340SChristoph Hellwig unsigned int nr_types); 9589345d51SChristoph Hellwig void mdev_unregister_parent(struct mdev_parent *parent); 967b96953bSKirti Wankhede 9791b9969dSJason Gunthorpe int mdev_register_driver(struct mdev_driver *drv); 9850732af3SParav Pandit void mdev_unregister_driver(struct mdev_driver *drv); 997b96953bSKirti Wankhede 10050732af3SParav Pandit struct device *mdev_parent_dev(struct mdev_device *mdev); 1012a3d15f2SJason Gunthorpe static inline struct device *mdev_dev(struct mdev_device *mdev) 1022a3d15f2SJason Gunthorpe { 1032a3d15f2SJason Gunthorpe return &mdev->dev; 1042a3d15f2SJason Gunthorpe } 1052a3d15f2SJason Gunthorpe static inline struct mdev_device *mdev_from_dev(struct device *dev) 1062a3d15f2SJason Gunthorpe { 1072a3d15f2SJason Gunthorpe return dev->bus == &mdev_bus_type ? to_mdev_device(dev) : NULL; 1082a3d15f2SJason Gunthorpe } 1099372e6feSAlex Williamson 1107b96953bSKirti Wankhede #endif /* MDEV_H */ 111