1a8ae6085SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2a8ae6085SGreg Kroah-Hartman /*
3a8ae6085SGreg Kroah-Hartman * The class-specific portions of the driver model
4a8ae6085SGreg Kroah-Hartman *
5a8ae6085SGreg Kroah-Hartman * Copyright (c) 2001-2003 Patrick Mochel <[email protected]>
6a8ae6085SGreg Kroah-Hartman * Copyright (c) 2004-2009 Greg Kroah-Hartman <[email protected]>
7a8ae6085SGreg Kroah-Hartman * Copyright (c) 2008-2009 Novell Inc.
8a8ae6085SGreg Kroah-Hartman * Copyright (c) 2012-2019 Greg Kroah-Hartman <[email protected]>
9a8ae6085SGreg Kroah-Hartman * Copyright (c) 2012-2019 Linux Foundation
10a8ae6085SGreg Kroah-Hartman *
11a8ae6085SGreg Kroah-Hartman * See Documentation/driver-api/driver-model/ for more information.
12a8ae6085SGreg Kroah-Hartman */
13a8ae6085SGreg Kroah-Hartman
14a8ae6085SGreg Kroah-Hartman #ifndef _DEVICE_CLASS_H_
15a8ae6085SGreg Kroah-Hartman #define _DEVICE_CLASS_H_
16a8ae6085SGreg Kroah-Hartman
17a8ae6085SGreg Kroah-Hartman #include <linux/kobject.h>
18a8ae6085SGreg Kroah-Hartman #include <linux/klist.h>
19a8ae6085SGreg Kroah-Hartman #include <linux/pm.h>
20a8ae6085SGreg Kroah-Hartman #include <linux/device/bus.h>
21a8ae6085SGreg Kroah-Hartman
22a8ae6085SGreg Kroah-Hartman struct device;
23a8ae6085SGreg Kroah-Hartman struct fwnode_handle;
24a8ae6085SGreg Kroah-Hartman
25a8ae6085SGreg Kroah-Hartman /**
26a8ae6085SGreg Kroah-Hartman * struct class - device classes
27a8ae6085SGreg Kroah-Hartman * @name: Name of the class.
28a8ae6085SGreg Kroah-Hartman * @class_groups: Default attributes of this class.
29a8ae6085SGreg Kroah-Hartman * @dev_groups: Default attributes of the devices that belong to the class.
30a8ae6085SGreg Kroah-Hartman * @dev_uevent: Called when a device is added, removed from this class, or a
31a8ae6085SGreg Kroah-Hartman * few other things that generate uevents to add the environment
32a8ae6085SGreg Kroah-Hartman * variables.
33a8ae6085SGreg Kroah-Hartman * @devnode: Callback to provide the devtmpfs.
34a8ae6085SGreg Kroah-Hartman * @class_release: Called to release this class.
35a8ae6085SGreg Kroah-Hartman * @dev_release: Called to release the device.
36a8ae6085SGreg Kroah-Hartman * @shutdown_pre: Called at shut-down time before driver shutdown.
37a8ae6085SGreg Kroah-Hartman * @ns_type: Callbacks so sysfs can detemine namespaces.
38a8ae6085SGreg Kroah-Hartman * @namespace: Namespace of the device belongs to this class.
39a8ae6085SGreg Kroah-Hartman * @get_ownership: Allows class to specify uid/gid of the sysfs directories
40a8ae6085SGreg Kroah-Hartman * for the devices belonging to the class. Usually tied to
41a8ae6085SGreg Kroah-Hartman * device's namespace.
42a8ae6085SGreg Kroah-Hartman * @pm: The default device power management operations of this class.
43a8ae6085SGreg Kroah-Hartman *
44a8ae6085SGreg Kroah-Hartman * A class is a higher-level view of a device that abstracts out low-level
45a8ae6085SGreg Kroah-Hartman * implementation details. Drivers may see a SCSI disk or an ATA disk, but,
46a8ae6085SGreg Kroah-Hartman * at the class level, they are all simply disks. Classes allow user space
47a8ae6085SGreg Kroah-Hartman * to work with devices based on what they do, rather than how they are
48a8ae6085SGreg Kroah-Hartman * connected or how they work.
49a8ae6085SGreg Kroah-Hartman */
50a8ae6085SGreg Kroah-Hartman struct class {
51a8ae6085SGreg Kroah-Hartman const char *name;
52a8ae6085SGreg Kroah-Hartman
53a8ae6085SGreg Kroah-Hartman const struct attribute_group **class_groups;
54a8ae6085SGreg Kroah-Hartman const struct attribute_group **dev_groups;
55a8ae6085SGreg Kroah-Hartman
5623680f0bSGreg Kroah-Hartman int (*dev_uevent)(const struct device *dev, struct kobj_uevent_env *env);
57ff62b8e6SGreg Kroah-Hartman char *(*devnode)(const struct device *dev, umode_t *mode);
58a8ae6085SGreg Kroah-Hartman
59979207caSGreg Kroah-Hartman void (*class_release)(const struct class *class);
60a8ae6085SGreg Kroah-Hartman void (*dev_release)(struct device *dev);
61a8ae6085SGreg Kroah-Hartman
62a8ae6085SGreg Kroah-Hartman int (*shutdown_pre)(struct device *dev);
63a8ae6085SGreg Kroah-Hartman
64a8ae6085SGreg Kroah-Hartman const struct kobj_ns_type_operations *ns_type;
65fa627348SGreg Kroah-Hartman const void *(*namespace)(const struct device *dev);
66a8ae6085SGreg Kroah-Hartman
67fa627348SGreg Kroah-Hartman void (*get_ownership)(const struct device *dev, kuid_t *uid, kgid_t *gid);
68a8ae6085SGreg Kroah-Hartman
69a8ae6085SGreg Kroah-Hartman const struct dev_pm_ops *pm;
70a8ae6085SGreg Kroah-Hartman };
71a8ae6085SGreg Kroah-Hartman
72a8ae6085SGreg Kroah-Hartman struct class_dev_iter {
73a8ae6085SGreg Kroah-Hartman struct klist_iter ki;
74a8ae6085SGreg Kroah-Hartman const struct device_type *type;
75ddaf098eSGreg Kroah-Hartman struct subsys_private *sp;
76a8ae6085SGreg Kroah-Hartman };
77a8ae6085SGreg Kroah-Hartman
7843a7206bSGreg Kroah-Hartman int __must_check class_register(const struct class *class);
79517d4927SGreg Kroah-Hartman void class_unregister(const struct class *class);
806f14c022SGreg Kroah-Hartman bool class_is_registered(const struct class *class);
81a8ae6085SGreg Kroah-Hartman
82a8ae6085SGreg Kroah-Hartman struct class_compat;
83a8ae6085SGreg Kroah-Hartman struct class_compat *class_compat_register(const char *name);
84a8ae6085SGreg Kroah-Hartman void class_compat_unregister(struct class_compat *cls);
85827ed8b1SHeiner Kallweit int class_compat_create_link(struct class_compat *cls, struct device *dev);
86827ed8b1SHeiner Kallweit void class_compat_remove_link(struct class_compat *cls, struct device *dev);
87a8ae6085SGreg Kroah-Hartman
8843718dcaSGreg Kroah-Hartman void class_dev_iter_init(struct class_dev_iter *iter, const struct class *class,
8943718dcaSGreg Kroah-Hartman const struct device *start, const struct device_type *type);
9043718dcaSGreg Kroah-Hartman struct device *class_dev_iter_next(struct class_dev_iter *iter);
9143718dcaSGreg Kroah-Hartman void class_dev_iter_exit(struct class_dev_iter *iter);
92a8ae6085SGreg Kroah-Hartman
93767b74e0SZijun Hu int class_for_each_device(const struct class *class, const struct device *start,
94767b74e0SZijun Hu void *data, device_iter_t fn);
9543718dcaSGreg Kroah-Hartman struct device *class_find_device(const struct class *class, const struct device *start,
96b45ed06fSZijun Hu const void *data, device_match_t match);
97a8ae6085SGreg Kroah-Hartman
98a8ae6085SGreg Kroah-Hartman /**
99a8ae6085SGreg Kroah-Hartman * class_find_device_by_name - device iterator for locating a particular device
100a8ae6085SGreg Kroah-Hartman * of a specific name.
101a8ae6085SGreg Kroah-Hartman * @class: class type
102a8ae6085SGreg Kroah-Hartman * @name: name of the device to match
103a8ae6085SGreg Kroah-Hartman */
class_find_device_by_name(const struct class * class,const char * name)104cf41015eSGreg Kroah-Hartman static inline struct device *class_find_device_by_name(const struct class *class,
105a8ae6085SGreg Kroah-Hartman const char *name)
106a8ae6085SGreg Kroah-Hartman {
107a8ae6085SGreg Kroah-Hartman return class_find_device(class, NULL, name, device_match_name);
108a8ae6085SGreg Kroah-Hartman }
109a8ae6085SGreg Kroah-Hartman
110a8ae6085SGreg Kroah-Hartman /**
111a8ae6085SGreg Kroah-Hartman * class_find_device_by_of_node : device iterator for locating a particular device
112a8ae6085SGreg Kroah-Hartman * matching the of_node.
113a8ae6085SGreg Kroah-Hartman * @class: class type
114a8ae6085SGreg Kroah-Hartman * @np: of_node of the device to match.
115a8ae6085SGreg Kroah-Hartman */
class_find_device_by_of_node(const struct class * class,const struct device_node * np)116cf41015eSGreg Kroah-Hartman static inline struct device *class_find_device_by_of_node(const struct class *class,
117cf41015eSGreg Kroah-Hartman const struct device_node *np)
118a8ae6085SGreg Kroah-Hartman {
119a8ae6085SGreg Kroah-Hartman return class_find_device(class, NULL, np, device_match_of_node);
120a8ae6085SGreg Kroah-Hartman }
121a8ae6085SGreg Kroah-Hartman
122a8ae6085SGreg Kroah-Hartman /**
123a8ae6085SGreg Kroah-Hartman * class_find_device_by_fwnode : device iterator for locating a particular device
124a8ae6085SGreg Kroah-Hartman * matching the fwnode.
125a8ae6085SGreg Kroah-Hartman * @class: class type
126a8ae6085SGreg Kroah-Hartman * @fwnode: fwnode of the device to match.
127a8ae6085SGreg Kroah-Hartman */
class_find_device_by_fwnode(const struct class * class,const struct fwnode_handle * fwnode)128cf41015eSGreg Kroah-Hartman static inline struct device *class_find_device_by_fwnode(const struct class *class,
129a8ae6085SGreg Kroah-Hartman const struct fwnode_handle *fwnode)
130a8ae6085SGreg Kroah-Hartman {
131a8ae6085SGreg Kroah-Hartman return class_find_device(class, NULL, fwnode, device_match_fwnode);
132a8ae6085SGreg Kroah-Hartman }
133a8ae6085SGreg Kroah-Hartman
134a8ae6085SGreg Kroah-Hartman /**
135a8ae6085SGreg Kroah-Hartman * class_find_device_by_devt : device iterator for locating a particular device
136a8ae6085SGreg Kroah-Hartman * matching the device type.
137a8ae6085SGreg Kroah-Hartman * @class: class type
138a8ae6085SGreg Kroah-Hartman * @devt: device type of the device to match.
139a8ae6085SGreg Kroah-Hartman */
class_find_device_by_devt(const struct class * class,dev_t devt)140cf41015eSGreg Kroah-Hartman static inline struct device *class_find_device_by_devt(const struct class *class,
141a8ae6085SGreg Kroah-Hartman dev_t devt)
142a8ae6085SGreg Kroah-Hartman {
143a8ae6085SGreg Kroah-Hartman return class_find_device(class, NULL, &devt, device_match_devt);
144a8ae6085SGreg Kroah-Hartman }
145a8ae6085SGreg Kroah-Hartman
146a8ae6085SGreg Kroah-Hartman #ifdef CONFIG_ACPI
147a8ae6085SGreg Kroah-Hartman struct acpi_device;
148a8ae6085SGreg Kroah-Hartman /**
149a8ae6085SGreg Kroah-Hartman * class_find_device_by_acpi_dev : device iterator for locating a particular
150a8ae6085SGreg Kroah-Hartman * device matching the ACPI_COMPANION device.
151a8ae6085SGreg Kroah-Hartman * @class: class type
152a8ae6085SGreg Kroah-Hartman * @adev: ACPI_COMPANION device to match.
153a8ae6085SGreg Kroah-Hartman */
class_find_device_by_acpi_dev(const struct class * class,const struct acpi_device * adev)154cf41015eSGreg Kroah-Hartman static inline struct device *class_find_device_by_acpi_dev(const struct class *class,
155cf41015eSGreg Kroah-Hartman const struct acpi_device *adev)
156a8ae6085SGreg Kroah-Hartman {
157a8ae6085SGreg Kroah-Hartman return class_find_device(class, NULL, adev, device_match_acpi_dev);
158a8ae6085SGreg Kroah-Hartman }
159a8ae6085SGreg Kroah-Hartman #else
class_find_device_by_acpi_dev(const struct class * class,const void * adev)160cf41015eSGreg Kroah-Hartman static inline struct device *class_find_device_by_acpi_dev(const struct class *class,
161cf41015eSGreg Kroah-Hartman const void *adev)
162a8ae6085SGreg Kroah-Hartman {
163a8ae6085SGreg Kroah-Hartman return NULL;
164a8ae6085SGreg Kroah-Hartman }
165a8ae6085SGreg Kroah-Hartman #endif
166a8ae6085SGreg Kroah-Hartman
167a8ae6085SGreg Kroah-Hartman struct class_attribute {
168a8ae6085SGreg Kroah-Hartman struct attribute attr;
16975a2d422SGreg Kroah-Hartman ssize_t (*show)(const struct class *class, const struct class_attribute *attr,
170a8ae6085SGreg Kroah-Hartman char *buf);
17175a2d422SGreg Kroah-Hartman ssize_t (*store)(const struct class *class, const struct class_attribute *attr,
172a8ae6085SGreg Kroah-Hartman const char *buf, size_t count);
173a8ae6085SGreg Kroah-Hartman };
174a8ae6085SGreg Kroah-Hartman
175a8ae6085SGreg Kroah-Hartman #define CLASS_ATTR_RW(_name) \
176a8ae6085SGreg Kroah-Hartman struct class_attribute class_attr_##_name = __ATTR_RW(_name)
177a8ae6085SGreg Kroah-Hartman #define CLASS_ATTR_RO(_name) \
178a8ae6085SGreg Kroah-Hartman struct class_attribute class_attr_##_name = __ATTR_RO(_name)
179a8ae6085SGreg Kroah-Hartman #define CLASS_ATTR_WO(_name) \
180a8ae6085SGreg Kroah-Hartman struct class_attribute class_attr_##_name = __ATTR_WO(_name)
181a8ae6085SGreg Kroah-Hartman
18243718dcaSGreg Kroah-Hartman int __must_check class_create_file_ns(const struct class *class, const struct class_attribute *attr,
183a8ae6085SGreg Kroah-Hartman const void *ns);
18443718dcaSGreg Kroah-Hartman void class_remove_file_ns(const struct class *class, const struct class_attribute *attr,
185a8ae6085SGreg Kroah-Hartman const void *ns);
186a8ae6085SGreg Kroah-Hartman
class_create_file(const struct class * class,const struct class_attribute * attr)18780842a92SGreg Kroah-Hartman static inline int __must_check class_create_file(const struct class *class,
188a8ae6085SGreg Kroah-Hartman const struct class_attribute *attr)
189a8ae6085SGreg Kroah-Hartman {
190a8ae6085SGreg Kroah-Hartman return class_create_file_ns(class, attr, NULL);
191a8ae6085SGreg Kroah-Hartman }
192a8ae6085SGreg Kroah-Hartman
class_remove_file(const struct class * class,const struct class_attribute * attr)19380842a92SGreg Kroah-Hartman static inline void class_remove_file(const struct class *class,
194a8ae6085SGreg Kroah-Hartman const struct class_attribute *attr)
195a8ae6085SGreg Kroah-Hartman {
196*8fd74a31SZijun Hu class_remove_file_ns(class, attr, NULL);
197a8ae6085SGreg Kroah-Hartman }
198a8ae6085SGreg Kroah-Hartman
199a8ae6085SGreg Kroah-Hartman /* Simple class attribute that is just a static string */
200a8ae6085SGreg Kroah-Hartman struct class_attribute_string {
201a8ae6085SGreg Kroah-Hartman struct class_attribute attr;
202a8ae6085SGreg Kroah-Hartman char *str;
203a8ae6085SGreg Kroah-Hartman };
204a8ae6085SGreg Kroah-Hartman
205a8ae6085SGreg Kroah-Hartman /* Currently read-only only */
206a8ae6085SGreg Kroah-Hartman #define _CLASS_ATTR_STRING(_name, _mode, _str) \
207a8ae6085SGreg Kroah-Hartman { __ATTR(_name, _mode, show_class_attr_string, NULL), _str }
208a8ae6085SGreg Kroah-Hartman #define CLASS_ATTR_STRING(_name, _mode, _str) \
209a8ae6085SGreg Kroah-Hartman struct class_attribute_string class_attr_##_name = \
210a8ae6085SGreg Kroah-Hartman _CLASS_ATTR_STRING(_name, _mode, _str)
211a8ae6085SGreg Kroah-Hartman
21275a2d422SGreg Kroah-Hartman ssize_t show_class_attr_string(const struct class *class, const struct class_attribute *attr,
21375a2d422SGreg Kroah-Hartman char *buf);
214a8ae6085SGreg Kroah-Hartman
215a8ae6085SGreg Kroah-Hartman struct class_interface {
216a8ae6085SGreg Kroah-Hartman struct list_head node;
2176b0d49beSGreg Kroah-Hartman const struct class *class;
218a8ae6085SGreg Kroah-Hartman
2192243acd5SGreg Kroah-Hartman int (*add_dev) (struct device *dev);
2202243acd5SGreg Kroah-Hartman void (*remove_dev) (struct device *dev);
221a8ae6085SGreg Kroah-Hartman };
222a8ae6085SGreg Kroah-Hartman
22343718dcaSGreg Kroah-Hartman int __must_check class_interface_register(struct class_interface *);
22443718dcaSGreg Kroah-Hartman void class_interface_unregister(struct class_interface *);
225a8ae6085SGreg Kroah-Hartman
22643718dcaSGreg Kroah-Hartman struct class * __must_check class_create(const char *name);
227517d4927SGreg Kroah-Hartman void class_destroy(const struct class *cls);
228a8ae6085SGreg Kroah-Hartman
229a8ae6085SGreg Kroah-Hartman #endif /* _DEVICE_CLASS_H_ */
230