device.h revision 328653
1219820Sjeff/*-
2219820Sjeff * Copyright (c) 2010 Isilon Systems, Inc.
3219820Sjeff * Copyright (c) 2010 iX Systems, Inc.
4219820Sjeff * Copyright (c) 2010 Panasas, Inc.
5299674Shselasky * Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
6219820Sjeff * All rights reserved.
7219820Sjeff *
8219820Sjeff * Redistribution and use in source and binary forms, with or without
9219820Sjeff * modification, are permitted provided that the following conditions
10219820Sjeff * are met:
11219820Sjeff * 1. Redistributions of source code must retain the above copyright
12219820Sjeff *    notice unmodified, this list of conditions, and the following
13219820Sjeff *    disclaimer.
14219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright
15219820Sjeff *    notice, this list of conditions and the following disclaimer in the
16219820Sjeff *    documentation and/or other materials provided with the distribution.
17219820Sjeff *
18219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19219820Sjeff * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20219820Sjeff * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21219820Sjeff * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22219820Sjeff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23219820Sjeff * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24219820Sjeff * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25219820Sjeff * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26219820Sjeff * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27219820Sjeff * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28289644Shselasky *
29289644Shselasky * $FreeBSD: stable/11/sys/compat/linuxkpi/common/include/linux/device.h 328653 2018-02-01 13:01:44Z hselasky $
30219820Sjeff */
31219820Sjeff#ifndef	_LINUX_DEVICE_H_
32219820Sjeff#define	_LINUX_DEVICE_H_
33219820Sjeff
34299933Shselasky#include <linux/err.h>
35219820Sjeff#include <linux/types.h>
36219820Sjeff#include <linux/kobject.h>
37290335Shselasky#include <linux/sysfs.h>
38219820Sjeff#include <linux/list.h>
39219820Sjeff#include <linux/compiler.h>
40219820Sjeff#include <linux/types.h>
41219820Sjeff#include <linux/module.h>
42219820Sjeff#include <linux/workqueue.h>
43219820Sjeff#include <linux/sysfs.h>
44219820Sjeff#include <linux/kdev_t.h>
45219820Sjeff#include <asm/atomic.h>
46219820Sjeff
47219820Sjeff#include <sys/bus.h>
48219820Sjeff
49219820Sjeffenum irqreturn	{ IRQ_NONE = 0, IRQ_HANDLED, IRQ_WAKE_THREAD, };
50219820Sjefftypedef enum irqreturn	irqreturn_t;
51219820Sjeff
52328653Shselaskystruct device;
53328653Shselaskystruct fwnode_handle;
54328653Shselasky
55219820Sjeffstruct class {
56219820Sjeff	const char	*name;
57219820Sjeff	struct module	*owner;
58219820Sjeff	struct kobject	kobj;
59219820Sjeff	devclass_t	bsdclass;
60328653Shselasky	const struct dev_pm_ops *pm;
61219820Sjeff	void		(*class_release)(struct class *class);
62219820Sjeff	void		(*dev_release)(struct device *dev);
63270710Shselasky	char *		(*devnode)(struct device *dev, umode_t *mode);
64219820Sjeff};
65219820Sjeff
66328653Shselaskystruct dev_pm_ops {
67328653Shselasky	int (*suspend)(struct device *dev);
68328653Shselasky	int (*suspend_late)(struct device *dev);
69328653Shselasky	int (*resume)(struct device *dev);
70328653Shselasky	int (*resume_early)(struct device *dev);
71328653Shselasky	int (*freeze)(struct device *dev);
72328653Shselasky	int (*freeze_late)(struct device *dev);
73328653Shselasky	int (*thaw)(struct device *dev);
74328653Shselasky	int (*thaw_early)(struct device *dev);
75328653Shselasky	int (*poweroff)(struct device *dev);
76328653Shselasky	int (*poweroff_late)(struct device *dev);
77328653Shselasky	int (*restore)(struct device *dev);
78328653Shselasky	int (*restore_early)(struct device *dev);
79328653Shselasky	int (*runtime_suspend)(struct device *dev);
80328653Shselasky	int (*runtime_resume)(struct device *dev);
81328653Shselasky	int (*runtime_idle)(struct device *dev);
82328653Shselasky};
83328653Shselasky
84328653Shselaskystruct device_driver {
85328653Shselasky	const char	*name;
86328653Shselasky	const struct dev_pm_ops *pm;
87328653Shselasky};
88328653Shselasky
89328653Shselaskystruct device_type {
90328653Shselasky	const char	*name;
91328653Shselasky};
92328653Shselasky
93219820Sjeffstruct device {
94219820Sjeff	struct device	*parent;
95219820Sjeff	struct list_head irqents;
96219820Sjeff	device_t	bsddev;
97311801Shselasky	/*
98311801Shselasky	 * The following flag is used to determine if the LinuxKPI is
99311801Shselasky	 * responsible for detaching the BSD device or not. If the
100311801Shselasky	 * LinuxKPI got the BSD device using devclass_get_device(), it
101311801Shselasky	 * must not try to detach or delete it, because it's already
102311801Shselasky	 * done somewhere else.
103311801Shselasky	 */
104311801Shselasky	bool		bsddev_attached_here;
105328653Shselasky	struct device_driver *driver;
106328653Shselasky	struct device_type *type;
107219820Sjeff	dev_t		devt;
108219820Sjeff	struct class	*class;
109219820Sjeff	void		(*release)(struct device *dev);
110219820Sjeff	struct kobject	kobj;
111219820Sjeff	uint64_t	*dma_mask;
112219820Sjeff	void		*driver_data;
113219820Sjeff	unsigned int	irq;
114310246Shselasky#define	LINUX_IRQ_INVALID	65535
115219820Sjeff	unsigned int	msix;
116219820Sjeff	unsigned int	msix_max;
117299933Shselasky	const struct attribute_group **groups;
118328653Shselasky	struct fwnode_handle *fwnode;
119328653Shselasky
120328653Shselasky	spinlock_t	devres_lock;
121328653Shselasky	struct list_head devres_head;
122219820Sjeff};
123219820Sjeff
124292987Shselaskyextern struct device linux_root_device;
125292987Shselaskyextern struct kobject linux_class_root;
126292987Shselaskyextern const struct kobj_type linux_dev_ktype;
127292987Shselaskyextern const struct kobj_type linux_class_ktype;
128219820Sjeff
129219820Sjeffstruct class_attribute {
130270710Shselasky        struct attribute attr;
131270710Shselasky        ssize_t (*show)(struct class *, struct class_attribute *, char *);
132270710Shselasky        ssize_t (*store)(struct class *, struct class_attribute *, const char *, size_t);
133270710Shselasky        const void *(*namespace)(struct class *, const struct class_attribute *);
134219820Sjeff};
135270710Shselasky
136219820Sjeff#define	CLASS_ATTR(_name, _mode, _show, _store)				\
137219820Sjeff	struct class_attribute class_attr_##_name =			\
138219820Sjeff	    { { #_name, NULL, _mode }, _show, _store }
139219820Sjeff
140219820Sjeffstruct device_attribute {
141219820Sjeff	struct attribute	attr;
142219820Sjeff	ssize_t			(*show)(struct device *,
143270710Shselasky					struct device_attribute *, char *);
144219820Sjeff	ssize_t			(*store)(struct device *,
145270710Shselasky					struct device_attribute *, const char *,
146270710Shselasky					size_t);
147219820Sjeff};
148219820Sjeff
149219820Sjeff#define	DEVICE_ATTR(_name, _mode, _show, _store)			\
150219820Sjeff	struct device_attribute dev_attr_##_name =			\
151328653Shselasky	    __ATTR(_name, _mode, _show, _store)
152328653Shselasky#define	DEVICE_ATTR_RO(_name)						\
153328653Shselasky	struct device_attribute dev_attr_##_name = __ATTR_RO(_name)
154328653Shselasky#define	DEVICE_ATTR_WO(_name)						\
155328653Shselasky	struct device_attribute dev_attr_##_name = __ATTR_WO(_name)
156328653Shselasky#define	DEVICE_ATTR_RW(_name)						\
157328653Shselasky	struct device_attribute dev_attr_##_name = __ATTR_RW(_name)
158219820Sjeff
159270710Shselasky/* Simple class attribute that is just a static string */
160270710Shselaskystruct class_attribute_string {
161270710Shselasky	struct class_attribute attr;
162270710Shselasky	char *str;
163270710Shselasky};
164270710Shselasky
165270710Shselaskystatic inline ssize_t
166270710Shselaskyshow_class_attr_string(struct class *class,
167270710Shselasky				struct class_attribute *attr, char *buf)
168270710Shselasky{
169270710Shselasky	struct class_attribute_string *cs;
170270710Shselasky	cs = container_of(attr, struct class_attribute_string, attr);
171270710Shselasky	return snprintf(buf, PAGE_SIZE, "%s\n", cs->str);
172270710Shselasky}
173270710Shselasky
174270710Shselasky/* Currently read-only only */
175270710Shselasky#define _CLASS_ATTR_STRING(_name, _mode, _str) \
176270710Shselasky	{ __ATTR(_name, _mode, show_class_attr_string, NULL), _str }
177270710Shselasky#define CLASS_ATTR_STRING(_name, _mode, _str) \
178270710Shselasky	struct class_attribute_string class_attr_##_name = \
179270710Shselasky		_CLASS_ATTR_STRING(_name, _mode, _str)
180270710Shselasky
181219820Sjeff#define	dev_err(dev, fmt, ...)	device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
182219820Sjeff#define	dev_warn(dev, fmt, ...)	device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
183219820Sjeff#define	dev_info(dev, fmt, ...)	device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
184299933Shselasky#define	dev_notice(dev, fmt, ...)	device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
185328653Shselasky#define	dev_dbg(dev, fmt, ...)	do { } while (0)
186219820Sjeff#define	dev_printk(lvl, dev, fmt, ...)					\
187219820Sjeff	    device_printf((dev)->bsddev, fmt, ##__VA_ARGS__)
188219820Sjeff
189328653Shselasky#define	dev_err_ratelimited(dev, ...) do {	\
190328653Shselasky	static linux_ratelimit_t __ratelimited;	\
191328653Shselasky	if (linux_ratelimited(&__ratelimited))	\
192328653Shselasky		dev_err(dev, __VA_ARGS__);	\
193328653Shselasky} while (0)
194328653Shselasky
195328653Shselasky#define	dev_warn_ratelimited(dev, ...) do {	\
196328653Shselasky	static linux_ratelimit_t __ratelimited;	\
197328653Shselasky	if (linux_ratelimited(&__ratelimited))	\
198328653Shselasky		dev_warn(dev, __VA_ARGS__);	\
199328653Shselasky} while (0)
200328653Shselasky
201219820Sjeffstatic inline void *
202299933Shselaskydev_get_drvdata(const struct device *dev)
203219820Sjeff{
204219820Sjeff
205219820Sjeff	return dev->driver_data;
206219820Sjeff}
207219820Sjeff
208219820Sjeffstatic inline void
209219820Sjeffdev_set_drvdata(struct device *dev, void *data)
210219820Sjeff{
211219820Sjeff
212219820Sjeff	dev->driver_data = data;
213219820Sjeff}
214219820Sjeff
215219820Sjeffstatic inline struct device *
216219820Sjeffget_device(struct device *dev)
217219820Sjeff{
218219820Sjeff
219219820Sjeff	if (dev)
220219820Sjeff		kobject_get(&dev->kobj);
221219820Sjeff
222219820Sjeff	return (dev);
223219820Sjeff}
224219820Sjeff
225219820Sjeffstatic inline char *
226219820Sjeffdev_name(const struct device *dev)
227219820Sjeff{
228219820Sjeff
229219820Sjeff 	return kobject_name(&dev->kobj);
230219820Sjeff}
231219820Sjeff
232219820Sjeff#define	dev_set_name(_dev, _fmt, ...)					\
233219820Sjeff	kobject_set_name(&(_dev)->kobj, (_fmt), ##__VA_ARGS__)
234219820Sjeff
235219820Sjeffstatic inline void
236219820Sjeffput_device(struct device *dev)
237219820Sjeff{
238219820Sjeff
239219820Sjeff	if (dev)
240219820Sjeff		kobject_put(&dev->kobj);
241219820Sjeff}
242219820Sjeff
243219820Sjeffstatic inline int
244219820Sjeffclass_register(struct class *class)
245219820Sjeff{
246219820Sjeff
247219820Sjeff	class->bsdclass = devclass_create(class->name);
248292987Shselasky	kobject_init(&class->kobj, &linux_class_ktype);
249219820Sjeff	kobject_set_name(&class->kobj, class->name);
250292987Shselasky	kobject_add(&class->kobj, &linux_class_root, class->name);
251219820Sjeff
252219820Sjeff	return (0);
253219820Sjeff}
254219820Sjeff
255219820Sjeffstatic inline void
256219820Sjeffclass_unregister(struct class *class)
257219820Sjeff{
258219820Sjeff
259219820Sjeff	kobject_put(&class->kobj);
260219820Sjeff}
261219820Sjeff
262299933Shselaskystatic inline struct device *kobj_to_dev(struct kobject *kobj)
263299933Shselasky{
264299933Shselasky	return container_of(kobj, struct device, kobj);
265299933Shselasky}
266299933Shselasky
267219820Sjeff/*
268299933Shselasky * Devices are registered and created for exporting to sysfs. Create
269219820Sjeff * implies register and register assumes the device fields have been
270219820Sjeff * setup appropriately before being called.
271219820Sjeff */
272299933Shselaskystatic inline void
273299933Shselaskydevice_initialize(struct device *dev)
274299933Shselasky{
275311801Shselasky	device_t bsddev = NULL;
276311801Shselasky	int unit = -1;
277299933Shselasky
278299933Shselasky	if (dev->devt) {
279311801Shselasky		unit = MINOR(dev->devt);
280299933Shselasky		bsddev = devclass_get_device(dev->class->bsdclass, unit);
281311801Shselasky		dev->bsddev_attached_here = false;
282311801Shselasky	} else if (dev->parent == NULL) {
283311801Shselasky		bsddev = devclass_get_device(dev->class->bsdclass, 0);
284311801Shselasky		dev->bsddev_attached_here = false;
285311801Shselasky	} else {
286311801Shselasky		dev->bsddev_attached_here = true;
287299933Shselasky	}
288311801Shselasky
289311801Shselasky	if (bsddev == NULL && dev->parent != NULL) {
290311801Shselasky		bsddev = device_add_child(dev->parent->bsddev,
291311801Shselasky		    dev->class->kobj.name, unit);
292311801Shselasky	}
293311801Shselasky
294299933Shselasky	if (bsddev != NULL)
295299933Shselasky		device_set_softc(bsddev, dev);
296299933Shselasky
297299933Shselasky	dev->bsddev = bsddev;
298311801Shselasky	MPASS(dev->bsddev != NULL);
299299933Shselasky	kobject_init(&dev->kobj, &linux_dev_ktype);
300328653Shselasky
301328653Shselasky	spin_lock_init(&dev->devres_lock);
302328653Shselasky	INIT_LIST_HEAD(&dev->devres_head);
303299933Shselasky}
304299933Shselasky
305219820Sjeffstatic inline int
306299933Shselaskydevice_add(struct device *dev)
307311801Shselasky{
308299933Shselasky	if (dev->bsddev != NULL) {
309299933Shselasky		if (dev->devt == 0)
310299933Shselasky			dev->devt = makedev(0, device_get_unit(dev->bsddev));
311299933Shselasky	}
312299933Shselasky	kobject_add(&dev->kobj, &dev->class->kobj, dev_name(dev));
313299933Shselasky	return (0);
314299933Shselasky}
315299933Shselasky
316299933Shselaskystatic inline void
317299933Shselaskydevice_create_release(struct device *dev)
318299933Shselasky{
319299933Shselasky	kfree(dev);
320299933Shselasky}
321299933Shselasky
322299933Shselaskystatic inline struct device *
323299933Shselaskydevice_create_groups_vargs(struct class *class, struct device *parent,
324299933Shselasky    dev_t devt, void *drvdata, const struct attribute_group **groups,
325299933Shselasky    const char *fmt, va_list args)
326299933Shselasky{
327299933Shselasky	struct device *dev = NULL;
328299933Shselasky	int retval = -ENODEV;
329299933Shselasky
330299933Shselasky	if (class == NULL || IS_ERR(class))
331299933Shselasky		goto error;
332299933Shselasky
333299933Shselasky	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
334299933Shselasky	if (!dev) {
335299933Shselasky		retval = -ENOMEM;
336299933Shselasky		goto error;
337299933Shselasky	}
338299933Shselasky
339299933Shselasky	dev->devt = devt;
340299933Shselasky	dev->class = class;
341299933Shselasky	dev->parent = parent;
342299933Shselasky	dev->groups = groups;
343299933Shselasky	dev->release = device_create_release;
344311801Shselasky	/* device_initialize() needs the class and parent to be set */
345311801Shselasky	device_initialize(dev);
346299933Shselasky	dev_set_drvdata(dev, drvdata);
347299933Shselasky
348299933Shselasky	retval = kobject_set_name_vargs(&dev->kobj, fmt, args);
349299933Shselasky	if (retval)
350299933Shselasky		goto error;
351299933Shselasky
352299933Shselasky	retval = device_add(dev);
353299933Shselasky	if (retval)
354299933Shselasky		goto error;
355299933Shselasky
356299933Shselasky	return dev;
357299933Shselasky
358299933Shselaskyerror:
359299933Shselasky	put_device(dev);
360299933Shselasky	return ERR_PTR(retval);
361299933Shselasky}
362299933Shselasky
363299933Shselaskystatic inline struct device *
364299933Shselaskydevice_create_with_groups(struct class *class,
365299933Shselasky    struct device *parent, dev_t devt, void *drvdata,
366299933Shselasky    const struct attribute_group **groups, const char *fmt, ...)
367299933Shselasky{
368299933Shselasky	va_list vargs;
369299933Shselasky	struct device *dev;
370299933Shselasky
371299933Shselasky	va_start(vargs, fmt);
372299933Shselasky	dev = device_create_groups_vargs(class, parent, devt, drvdata,
373299933Shselasky	    groups, fmt, vargs);
374299933Shselasky	va_end(vargs);
375299933Shselasky	return dev;
376299933Shselasky}
377299933Shselasky
378328653Shselaskystatic inline bool
379328653Shselaskydevice_is_registered(struct device *dev)
380328653Shselasky{
381328653Shselasky
382328653Shselasky	return (dev->bsddev != NULL);
383328653Shselasky}
384328653Shselasky
385299933Shselaskystatic inline int
386219820Sjeffdevice_register(struct device *dev)
387219820Sjeff{
388311801Shselasky	device_t bsddev = NULL;
389311801Shselasky	int unit = -1;
390219820Sjeff
391328653Shselasky	if (device_is_registered(dev))
392311801Shselasky		goto done;
393299674Shselasky
394219820Sjeff	if (dev->devt) {
395219820Sjeff		unit = MINOR(dev->devt);
396219820Sjeff		bsddev = devclass_get_device(dev->class->bsdclass, unit);
397311801Shselasky		dev->bsddev_attached_here = false;
398299674Shselasky	} else if (dev->parent == NULL) {
399299674Shselasky		bsddev = devclass_get_device(dev->class->bsdclass, 0);
400311801Shselasky		dev->bsddev_attached_here = false;
401311801Shselasky	} else {
402311801Shselasky		dev->bsddev_attached_here = true;
403299674Shselasky	}
404299931Shselasky	if (bsddev == NULL && dev->parent != NULL) {
405219820Sjeff		bsddev = device_add_child(dev->parent->bsddev,
406219820Sjeff		    dev->class->kobj.name, unit);
407299931Shselasky	}
408299931Shselasky	if (bsddev != NULL) {
409219820Sjeff		if (dev->devt == 0)
410219820Sjeff			dev->devt = makedev(0, device_get_unit(bsddev));
411219820Sjeff		device_set_softc(bsddev, dev);
412219820Sjeff	}
413219820Sjeff	dev->bsddev = bsddev;
414311801Shselaskydone:
415292987Shselasky	kobject_init(&dev->kobj, &linux_dev_ktype);
416219820Sjeff	kobject_add(&dev->kobj, &dev->class->kobj, dev_name(dev));
417219820Sjeff
418219820Sjeff	return (0);
419219820Sjeff}
420219820Sjeff
421219820Sjeffstatic inline void
422219820Sjeffdevice_unregister(struct device *dev)
423219820Sjeff{
424219820Sjeff	device_t bsddev;
425219820Sjeff
426219820Sjeff	bsddev = dev->bsddev;
427299933Shselasky	dev->bsddev = NULL;
428299933Shselasky
429311801Shselasky	if (bsddev != NULL && dev->bsddev_attached_here) {
430299960Shselasky		mtx_lock(&Giant);
431219820Sjeff		device_delete_child(device_get_parent(bsddev), bsddev);
432299960Shselasky		mtx_unlock(&Giant);
433299960Shselasky	}
434219820Sjeff	put_device(dev);
435219820Sjeff}
436219820Sjeff
437299933Shselaskystatic inline void
438299933Shselaskydevice_del(struct device *dev)
439299933Shselasky{
440299933Shselasky	device_t bsddev;
441299933Shselasky
442299933Shselasky	bsddev = dev->bsddev;
443299933Shselasky	dev->bsddev = NULL;
444299933Shselasky
445311801Shselasky	if (bsddev != NULL && dev->bsddev_attached_here) {
446299960Shselasky		mtx_lock(&Giant);
447299933Shselasky		device_delete_child(device_get_parent(bsddev), bsddev);
448299960Shselasky		mtx_unlock(&Giant);
449299960Shselasky	}
450299933Shselasky}
451299933Shselasky
452219820Sjeffstruct device *device_create(struct class *class, struct device *parent,
453219820Sjeff	    dev_t devt, void *drvdata, const char *fmt, ...);
454219820Sjeff
455219820Sjeffstatic inline void
456219820Sjeffdevice_destroy(struct class *class, dev_t devt)
457219820Sjeff{
458219820Sjeff	device_t bsddev;
459219820Sjeff	int unit;
460219820Sjeff
461219820Sjeff	unit = MINOR(devt);
462219820Sjeff	bsddev = devclass_get_device(class->bsdclass, unit);
463299933Shselasky	if (bsddev != NULL)
464219820Sjeff		device_unregister(device_get_softc(bsddev));
465219820Sjeff}
466219820Sjeff
467219820Sjeffstatic inline void
468292987Shselaskylinux_class_kfree(struct class *class)
469219820Sjeff{
470219820Sjeff
471219820Sjeff	kfree(class);
472219820Sjeff}
473219820Sjeff
474219820Sjeffstatic inline struct class *
475219820Sjeffclass_create(struct module *owner, const char *name)
476219820Sjeff{
477219820Sjeff	struct class *class;
478219820Sjeff	int error;
479219820Sjeff
480219820Sjeff	class = kzalloc(sizeof(*class), M_WAITOK);
481219820Sjeff	class->owner = owner;
482328653Shselasky	class->name = name;
483292987Shselasky	class->class_release = linux_class_kfree;
484219820Sjeff	error = class_register(class);
485219820Sjeff	if (error) {
486219820Sjeff		kfree(class);
487219820Sjeff		return (NULL);
488219820Sjeff	}
489219820Sjeff
490219820Sjeff	return (class);
491219820Sjeff}
492219820Sjeff
493219820Sjeffstatic inline void
494219820Sjeffclass_destroy(struct class *class)
495219820Sjeff{
496219820Sjeff
497219820Sjeff	if (class == NULL)
498219820Sjeff		return;
499219820Sjeff	class_unregister(class);
500219820Sjeff}
501219820Sjeff
502219820Sjeffstatic inline int
503219820Sjeffdevice_create_file(struct device *dev, const struct device_attribute *attr)
504219820Sjeff{
505219820Sjeff
506219820Sjeff	if (dev)
507219820Sjeff		return sysfs_create_file(&dev->kobj, &attr->attr);
508219820Sjeff	return -EINVAL;
509219820Sjeff}
510219820Sjeff
511219820Sjeffstatic inline void
512219820Sjeffdevice_remove_file(struct device *dev, const struct device_attribute *attr)
513219820Sjeff{
514219820Sjeff
515219820Sjeff	if (dev)
516219820Sjeff		sysfs_remove_file(&dev->kobj, &attr->attr);
517219820Sjeff}
518219820Sjeff
519219820Sjeffstatic inline int
520219820Sjeffclass_create_file(struct class *class, const struct class_attribute *attr)
521219820Sjeff{
522219820Sjeff
523219820Sjeff	if (class)
524219820Sjeff		return sysfs_create_file(&class->kobj, &attr->attr);
525219820Sjeff	return -EINVAL;
526219820Sjeff}
527219820Sjeff
528219820Sjeffstatic inline void
529219820Sjeffclass_remove_file(struct class *class, const struct class_attribute *attr)
530219820Sjeff{
531219820Sjeff
532219820Sjeff	if (class)
533219820Sjeff		sysfs_remove_file(&class->kobj, &attr->attr);
534219820Sjeff}
535219820Sjeff
536292987Shselaskystatic inline int
537292987Shselaskydev_to_node(struct device *dev)
538255932Salfred{
539255932Salfred                return -1;
540255932Salfred}
541255932Salfred
542285088Shselaskychar *kvasprintf(gfp_t, const char *, va_list);
543278865Shselaskychar *kasprintf(gfp_t, const char *, ...);
544270710Shselasky
545219820Sjeff#endif	/* _LINUX_DEVICE_H_ */
546