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 354616 2019-11-11 15:28:27Z 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/kdev_t.h> 44219820Sjeff#include <asm/atomic.h> 45219820Sjeff 46219820Sjeff#include <sys/bus.h> 47219820Sjeff 48328653Shselaskystruct device; 49328653Shselaskystruct fwnode_handle; 50328653Shselasky 51219820Sjeffstruct class { 52219820Sjeff const char *name; 53219820Sjeff struct module *owner; 54219820Sjeff struct kobject kobj; 55219820Sjeff devclass_t bsdclass; 56328653Shselasky const struct dev_pm_ops *pm; 57354616Shselasky const struct attribute_group **dev_groups; 58219820Sjeff void (*class_release)(struct class *class); 59219820Sjeff void (*dev_release)(struct device *dev); 60270710Shselasky char * (*devnode)(struct device *dev, umode_t *mode); 61219820Sjeff}; 62219820Sjeff 63328653Shselaskystruct dev_pm_ops { 64328653Shselasky int (*suspend)(struct device *dev); 65328653Shselasky int (*suspend_late)(struct device *dev); 66328653Shselasky int (*resume)(struct device *dev); 67328653Shselasky int (*resume_early)(struct device *dev); 68328653Shselasky int (*freeze)(struct device *dev); 69328653Shselasky int (*freeze_late)(struct device *dev); 70328653Shselasky int (*thaw)(struct device *dev); 71328653Shselasky int (*thaw_early)(struct device *dev); 72328653Shselasky int (*poweroff)(struct device *dev); 73328653Shselasky int (*poweroff_late)(struct device *dev); 74328653Shselasky int (*restore)(struct device *dev); 75328653Shselasky int (*restore_early)(struct device *dev); 76328653Shselasky int (*runtime_suspend)(struct device *dev); 77328653Shselasky int (*runtime_resume)(struct device *dev); 78328653Shselasky int (*runtime_idle)(struct device *dev); 79328653Shselasky}; 80328653Shselasky 81328653Shselaskystruct device_driver { 82328653Shselasky const char *name; 83328653Shselasky const struct dev_pm_ops *pm; 84328653Shselasky}; 85328653Shselasky 86328653Shselaskystruct device_type { 87328653Shselasky const char *name; 88328653Shselasky}; 89328653Shselasky 90219820Sjeffstruct device { 91219820Sjeff struct device *parent; 92219820Sjeff struct list_head irqents; 93219820Sjeff device_t bsddev; 94311801Shselasky /* 95311801Shselasky * The following flag is used to determine if the LinuxKPI is 96311801Shselasky * responsible for detaching the BSD device or not. If the 97311801Shselasky * LinuxKPI got the BSD device using devclass_get_device(), it 98311801Shselasky * must not try to detach or delete it, because it's already 99311801Shselasky * done somewhere else. 100311801Shselasky */ 101311801Shselasky bool bsddev_attached_here; 102328653Shselasky struct device_driver *driver; 103328653Shselasky struct device_type *type; 104219820Sjeff dev_t devt; 105219820Sjeff struct class *class; 106219820Sjeff void (*release)(struct device *dev); 107219820Sjeff struct kobject kobj; 108219820Sjeff uint64_t *dma_mask; 109219820Sjeff void *driver_data; 110219820Sjeff unsigned int irq; 111310246Shselasky#define LINUX_IRQ_INVALID 65535 112351841Shselasky unsigned int irq_start; 113351841Shselasky unsigned int irq_end; 114299933Shselasky const struct attribute_group **groups; 115328653Shselasky struct fwnode_handle *fwnode; 116328653Shselasky 117328653Shselasky spinlock_t devres_lock; 118328653Shselasky struct list_head devres_head; 119219820Sjeff}; 120219820Sjeff 121292987Shselaskyextern struct device linux_root_device; 122292987Shselaskyextern struct kobject linux_class_root; 123292987Shselaskyextern const struct kobj_type linux_dev_ktype; 124292987Shselaskyextern const struct kobj_type linux_class_ktype; 125219820Sjeff 126219820Sjeffstruct class_attribute { 127331756Semaste struct attribute attr; 128331756Semaste ssize_t (*show)(struct class *, struct class_attribute *, char *); 129331756Semaste ssize_t (*store)(struct class *, struct class_attribute *, const char *, size_t); 130331756Semaste const void *(*namespace)(struct class *, const struct class_attribute *); 131219820Sjeff}; 132270710Shselasky 133219820Sjeff#define CLASS_ATTR(_name, _mode, _show, _store) \ 134219820Sjeff struct class_attribute class_attr_##_name = \ 135219820Sjeff { { #_name, NULL, _mode }, _show, _store } 136219820Sjeff 137219820Sjeffstruct device_attribute { 138219820Sjeff struct attribute attr; 139219820Sjeff ssize_t (*show)(struct device *, 140270710Shselasky struct device_attribute *, char *); 141219820Sjeff ssize_t (*store)(struct device *, 142270710Shselasky struct device_attribute *, const char *, 143270710Shselasky size_t); 144219820Sjeff}; 145219820Sjeff 146219820Sjeff#define DEVICE_ATTR(_name, _mode, _show, _store) \ 147219820Sjeff struct device_attribute dev_attr_##_name = \ 148328653Shselasky __ATTR(_name, _mode, _show, _store) 149328653Shselasky#define DEVICE_ATTR_RO(_name) \ 150328653Shselasky struct device_attribute dev_attr_##_name = __ATTR_RO(_name) 151328653Shselasky#define DEVICE_ATTR_WO(_name) \ 152328653Shselasky struct device_attribute dev_attr_##_name = __ATTR_WO(_name) 153328653Shselasky#define DEVICE_ATTR_RW(_name) \ 154328653Shselasky struct device_attribute dev_attr_##_name = __ATTR_RW(_name) 155219820Sjeff 156270710Shselasky/* Simple class attribute that is just a static string */ 157270710Shselaskystruct class_attribute_string { 158270710Shselasky struct class_attribute attr; 159270710Shselasky char *str; 160270710Shselasky}; 161270710Shselasky 162270710Shselaskystatic inline ssize_t 163270710Shselaskyshow_class_attr_string(struct class *class, 164270710Shselasky struct class_attribute *attr, char *buf) 165270710Shselasky{ 166270710Shselasky struct class_attribute_string *cs; 167270710Shselasky cs = container_of(attr, struct class_attribute_string, attr); 168270710Shselasky return snprintf(buf, PAGE_SIZE, "%s\n", cs->str); 169270710Shselasky} 170270710Shselasky 171270710Shselasky/* Currently read-only only */ 172270710Shselasky#define _CLASS_ATTR_STRING(_name, _mode, _str) \ 173270710Shselasky { __ATTR(_name, _mode, show_class_attr_string, NULL), _str } 174270710Shselasky#define CLASS_ATTR_STRING(_name, _mode, _str) \ 175270710Shselasky struct class_attribute_string class_attr_##_name = \ 176270710Shselasky _CLASS_ATTR_STRING(_name, _mode, _str) 177270710Shselasky 178219820Sjeff#define dev_err(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 179219820Sjeff#define dev_warn(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 180219820Sjeff#define dev_info(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 181299933Shselasky#define dev_notice(dev, fmt, ...) device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 182328653Shselasky#define dev_dbg(dev, fmt, ...) do { } while (0) 183219820Sjeff#define dev_printk(lvl, dev, fmt, ...) \ 184219820Sjeff device_printf((dev)->bsddev, fmt, ##__VA_ARGS__) 185219820Sjeff 186345910Shselasky#define dev_err_once(dev, ...) do { \ 187345910Shselasky static bool __dev_err_once; \ 188345910Shselasky if (!__dev_err_once) { \ 189345910Shselasky __dev_err_once = 1; \ 190345910Shselasky dev_err(dev, __VA_ARGS__); \ 191345910Shselasky } \ 192345910Shselasky} while (0) 193345910Shselasky 194328653Shselasky#define dev_err_ratelimited(dev, ...) do { \ 195328653Shselasky static linux_ratelimit_t __ratelimited; \ 196328653Shselasky if (linux_ratelimited(&__ratelimited)) \ 197328653Shselasky dev_err(dev, __VA_ARGS__); \ 198328653Shselasky} while (0) 199328653Shselasky 200328653Shselasky#define dev_warn_ratelimited(dev, ...) do { \ 201328653Shselasky static linux_ratelimit_t __ratelimited; \ 202328653Shselasky if (linux_ratelimited(&__ratelimited)) \ 203328653Shselasky dev_warn(dev, __VA_ARGS__); \ 204328653Shselasky} while (0) 205328653Shselasky 206219820Sjeffstatic inline void * 207299933Shselaskydev_get_drvdata(const struct device *dev) 208219820Sjeff{ 209219820Sjeff 210219820Sjeff return dev->driver_data; 211219820Sjeff} 212219820Sjeff 213219820Sjeffstatic inline void 214219820Sjeffdev_set_drvdata(struct device *dev, void *data) 215219820Sjeff{ 216219820Sjeff 217219820Sjeff dev->driver_data = data; 218219820Sjeff} 219219820Sjeff 220219820Sjeffstatic inline struct device * 221219820Sjeffget_device(struct device *dev) 222219820Sjeff{ 223219820Sjeff 224219820Sjeff if (dev) 225219820Sjeff kobject_get(&dev->kobj); 226219820Sjeff 227219820Sjeff return (dev); 228219820Sjeff} 229219820Sjeff 230219820Sjeffstatic inline char * 231219820Sjeffdev_name(const struct device *dev) 232219820Sjeff{ 233219820Sjeff 234331756Semaste return kobject_name(&dev->kobj); 235219820Sjeff} 236219820Sjeff 237219820Sjeff#define dev_set_name(_dev, _fmt, ...) \ 238219820Sjeff kobject_set_name(&(_dev)->kobj, (_fmt), ##__VA_ARGS__) 239219820Sjeff 240219820Sjeffstatic inline void 241219820Sjeffput_device(struct device *dev) 242219820Sjeff{ 243219820Sjeff 244219820Sjeff if (dev) 245219820Sjeff kobject_put(&dev->kobj); 246219820Sjeff} 247219820Sjeff 248219820Sjeffstatic inline int 249219820Sjeffclass_register(struct class *class) 250219820Sjeff{ 251219820Sjeff 252219820Sjeff class->bsdclass = devclass_create(class->name); 253292987Shselasky kobject_init(&class->kobj, &linux_class_ktype); 254219820Sjeff kobject_set_name(&class->kobj, class->name); 255292987Shselasky kobject_add(&class->kobj, &linux_class_root, class->name); 256219820Sjeff 257219820Sjeff return (0); 258219820Sjeff} 259219820Sjeff 260219820Sjeffstatic inline void 261219820Sjeffclass_unregister(struct class *class) 262219820Sjeff{ 263219820Sjeff 264219820Sjeff kobject_put(&class->kobj); 265219820Sjeff} 266219820Sjeff 267299933Shselaskystatic inline struct device *kobj_to_dev(struct kobject *kobj) 268299933Shselasky{ 269299933Shselasky return container_of(kobj, struct device, kobj); 270299933Shselasky} 271299933Shselasky 272219820Sjeff/* 273299933Shselasky * Devices are registered and created for exporting to sysfs. Create 274219820Sjeff * implies register and register assumes the device fields have been 275219820Sjeff * setup appropriately before being called. 276219820Sjeff */ 277299933Shselaskystatic inline void 278299933Shselaskydevice_initialize(struct device *dev) 279299933Shselasky{ 280311801Shselasky device_t bsddev = NULL; 281311801Shselasky int unit = -1; 282299933Shselasky 283299933Shselasky if (dev->devt) { 284311801Shselasky unit = MINOR(dev->devt); 285299933Shselasky bsddev = devclass_get_device(dev->class->bsdclass, unit); 286311801Shselasky dev->bsddev_attached_here = false; 287311801Shselasky } else if (dev->parent == NULL) { 288311801Shselasky bsddev = devclass_get_device(dev->class->bsdclass, 0); 289311801Shselasky dev->bsddev_attached_here = false; 290311801Shselasky } else { 291311801Shselasky dev->bsddev_attached_here = true; 292299933Shselasky } 293311801Shselasky 294311801Shselasky if (bsddev == NULL && dev->parent != NULL) { 295311801Shselasky bsddev = device_add_child(dev->parent->bsddev, 296311801Shselasky dev->class->kobj.name, unit); 297311801Shselasky } 298311801Shselasky 299299933Shselasky if (bsddev != NULL) 300299933Shselasky device_set_softc(bsddev, dev); 301299933Shselasky 302299933Shselasky dev->bsddev = bsddev; 303311801Shselasky MPASS(dev->bsddev != NULL); 304299933Shselasky kobject_init(&dev->kobj, &linux_dev_ktype); 305328653Shselasky 306328653Shselasky spin_lock_init(&dev->devres_lock); 307328653Shselasky INIT_LIST_HEAD(&dev->devres_head); 308299933Shselasky} 309299933Shselasky 310219820Sjeffstatic inline int 311299933Shselaskydevice_add(struct device *dev) 312311801Shselasky{ 313299933Shselasky if (dev->bsddev != NULL) { 314299933Shselasky if (dev->devt == 0) 315299933Shselasky dev->devt = makedev(0, device_get_unit(dev->bsddev)); 316299933Shselasky } 317299933Shselasky kobject_add(&dev->kobj, &dev->class->kobj, dev_name(dev)); 318354615Shselasky 319354615Shselasky if (dev->groups) 320354615Shselasky return (sysfs_create_groups(&dev->kobj, dev->groups)); 321354615Shselasky 322299933Shselasky return (0); 323299933Shselasky} 324299933Shselasky 325299933Shselaskystatic inline void 326299933Shselaskydevice_create_release(struct device *dev) 327299933Shselasky{ 328299933Shselasky kfree(dev); 329299933Shselasky} 330299933Shselasky 331299933Shselaskystatic inline struct device * 332299933Shselaskydevice_create_groups_vargs(struct class *class, struct device *parent, 333299933Shselasky dev_t devt, void *drvdata, const struct attribute_group **groups, 334299933Shselasky const char *fmt, va_list args) 335299933Shselasky{ 336299933Shselasky struct device *dev = NULL; 337299933Shselasky int retval = -ENODEV; 338299933Shselasky 339299933Shselasky if (class == NULL || IS_ERR(class)) 340299933Shselasky goto error; 341299933Shselasky 342299933Shselasky dev = kzalloc(sizeof(*dev), GFP_KERNEL); 343299933Shselasky if (!dev) { 344299933Shselasky retval = -ENOMEM; 345299933Shselasky goto error; 346299933Shselasky } 347299933Shselasky 348299933Shselasky dev->devt = devt; 349299933Shselasky dev->class = class; 350299933Shselasky dev->parent = parent; 351299933Shselasky dev->groups = groups; 352299933Shselasky dev->release = device_create_release; 353311801Shselasky /* device_initialize() needs the class and parent to be set */ 354311801Shselasky device_initialize(dev); 355299933Shselasky dev_set_drvdata(dev, drvdata); 356299933Shselasky 357299933Shselasky retval = kobject_set_name_vargs(&dev->kobj, fmt, args); 358299933Shselasky if (retval) 359299933Shselasky goto error; 360299933Shselasky 361299933Shselasky retval = device_add(dev); 362299933Shselasky if (retval) 363299933Shselasky goto error; 364299933Shselasky 365299933Shselasky return dev; 366299933Shselasky 367299933Shselaskyerror: 368299933Shselasky put_device(dev); 369299933Shselasky return ERR_PTR(retval); 370299933Shselasky} 371299933Shselasky 372299933Shselaskystatic inline struct device * 373299933Shselaskydevice_create_with_groups(struct class *class, 374299933Shselasky struct device *parent, dev_t devt, void *drvdata, 375299933Shselasky const struct attribute_group **groups, const char *fmt, ...) 376299933Shselasky{ 377299933Shselasky va_list vargs; 378299933Shselasky struct device *dev; 379299933Shselasky 380299933Shselasky va_start(vargs, fmt); 381299933Shselasky dev = device_create_groups_vargs(class, parent, devt, drvdata, 382299933Shselasky groups, fmt, vargs); 383299933Shselasky va_end(vargs); 384299933Shselasky return dev; 385299933Shselasky} 386299933Shselasky 387328653Shselaskystatic inline bool 388328653Shselaskydevice_is_registered(struct device *dev) 389328653Shselasky{ 390328653Shselasky 391328653Shselasky return (dev->bsddev != NULL); 392328653Shselasky} 393328653Shselasky 394299933Shselaskystatic inline int 395219820Sjeffdevice_register(struct device *dev) 396219820Sjeff{ 397311801Shselasky device_t bsddev = NULL; 398311801Shselasky int unit = -1; 399219820Sjeff 400328653Shselasky if (device_is_registered(dev)) 401311801Shselasky goto done; 402299674Shselasky 403219820Sjeff if (dev->devt) { 404219820Sjeff unit = MINOR(dev->devt); 405219820Sjeff bsddev = devclass_get_device(dev->class->bsdclass, unit); 406311801Shselasky dev->bsddev_attached_here = false; 407299674Shselasky } else if (dev->parent == NULL) { 408299674Shselasky bsddev = devclass_get_device(dev->class->bsdclass, 0); 409311801Shselasky dev->bsddev_attached_here = false; 410311801Shselasky } else { 411311801Shselasky dev->bsddev_attached_here = true; 412299674Shselasky } 413299931Shselasky if (bsddev == NULL && dev->parent != NULL) { 414219820Sjeff bsddev = device_add_child(dev->parent->bsddev, 415219820Sjeff dev->class->kobj.name, unit); 416299931Shselasky } 417299931Shselasky if (bsddev != NULL) { 418219820Sjeff if (dev->devt == 0) 419219820Sjeff dev->devt = makedev(0, device_get_unit(bsddev)); 420219820Sjeff device_set_softc(bsddev, dev); 421219820Sjeff } 422219820Sjeff dev->bsddev = bsddev; 423311801Shselaskydone: 424292987Shselasky kobject_init(&dev->kobj, &linux_dev_ktype); 425219820Sjeff kobject_add(&dev->kobj, &dev->class->kobj, dev_name(dev)); 426219820Sjeff 427354616Shselasky sysfs_create_groups(&dev->kobj, dev->class->dev_groups); 428354616Shselasky 429219820Sjeff return (0); 430219820Sjeff} 431219820Sjeff 432219820Sjeffstatic inline void 433219820Sjeffdevice_unregister(struct device *dev) 434219820Sjeff{ 435219820Sjeff device_t bsddev; 436219820Sjeff 437354616Shselasky sysfs_remove_groups(&dev->kobj, dev->class->dev_groups); 438354616Shselasky 439219820Sjeff bsddev = dev->bsddev; 440299933Shselasky dev->bsddev = NULL; 441299933Shselasky 442311801Shselasky if (bsddev != NULL && dev->bsddev_attached_here) { 443299960Shselasky mtx_lock(&Giant); 444219820Sjeff device_delete_child(device_get_parent(bsddev), bsddev); 445299960Shselasky mtx_unlock(&Giant); 446299960Shselasky } 447219820Sjeff put_device(dev); 448219820Sjeff} 449219820Sjeff 450299933Shselaskystatic inline void 451299933Shselaskydevice_del(struct device *dev) 452299933Shselasky{ 453299933Shselasky device_t bsddev; 454299933Shselasky 455299933Shselasky bsddev = dev->bsddev; 456299933Shselasky dev->bsddev = NULL; 457299933Shselasky 458311801Shselasky if (bsddev != NULL && dev->bsddev_attached_here) { 459299960Shselasky mtx_lock(&Giant); 460299933Shselasky device_delete_child(device_get_parent(bsddev), bsddev); 461299960Shselasky mtx_unlock(&Giant); 462299960Shselasky } 463299933Shselasky} 464299933Shselasky 465219820Sjeffstruct device *device_create(struct class *class, struct device *parent, 466219820Sjeff dev_t devt, void *drvdata, const char *fmt, ...); 467219820Sjeff 468219820Sjeffstatic inline void 469219820Sjeffdevice_destroy(struct class *class, dev_t devt) 470219820Sjeff{ 471219820Sjeff device_t bsddev; 472219820Sjeff int unit; 473219820Sjeff 474219820Sjeff unit = MINOR(devt); 475219820Sjeff bsddev = devclass_get_device(class->bsdclass, unit); 476299933Shselasky if (bsddev != NULL) 477219820Sjeff device_unregister(device_get_softc(bsddev)); 478219820Sjeff} 479219820Sjeff 480335428Shselasky#define dev_pm_set_driver_flags(dev, flags) do { \ 481335428Shselasky} while (0) 482335428Shselasky 483219820Sjeffstatic inline void 484292987Shselaskylinux_class_kfree(struct class *class) 485219820Sjeff{ 486219820Sjeff 487219820Sjeff kfree(class); 488219820Sjeff} 489219820Sjeff 490219820Sjeffstatic inline struct class * 491219820Sjeffclass_create(struct module *owner, const char *name) 492219820Sjeff{ 493219820Sjeff struct class *class; 494219820Sjeff int error; 495219820Sjeff 496219820Sjeff class = kzalloc(sizeof(*class), M_WAITOK); 497219820Sjeff class->owner = owner; 498328653Shselasky class->name = name; 499292987Shselasky class->class_release = linux_class_kfree; 500219820Sjeff error = class_register(class); 501219820Sjeff if (error) { 502219820Sjeff kfree(class); 503219820Sjeff return (NULL); 504219820Sjeff } 505219820Sjeff 506219820Sjeff return (class); 507219820Sjeff} 508219820Sjeff 509219820Sjeffstatic inline void 510219820Sjeffclass_destroy(struct class *class) 511219820Sjeff{ 512219820Sjeff 513219820Sjeff if (class == NULL) 514219820Sjeff return; 515219820Sjeff class_unregister(class); 516219820Sjeff} 517219820Sjeff 518219820Sjeffstatic inline int 519219820Sjeffdevice_create_file(struct device *dev, const struct device_attribute *attr) 520219820Sjeff{ 521219820Sjeff 522219820Sjeff if (dev) 523219820Sjeff return sysfs_create_file(&dev->kobj, &attr->attr); 524219820Sjeff return -EINVAL; 525219820Sjeff} 526219820Sjeff 527219820Sjeffstatic inline void 528219820Sjeffdevice_remove_file(struct device *dev, const struct device_attribute *attr) 529219820Sjeff{ 530219820Sjeff 531219820Sjeff if (dev) 532219820Sjeff sysfs_remove_file(&dev->kobj, &attr->attr); 533219820Sjeff} 534219820Sjeff 535219820Sjeffstatic inline int 536219820Sjeffclass_create_file(struct class *class, const struct class_attribute *attr) 537219820Sjeff{ 538219820Sjeff 539219820Sjeff if (class) 540219820Sjeff return sysfs_create_file(&class->kobj, &attr->attr); 541219820Sjeff return -EINVAL; 542219820Sjeff} 543219820Sjeff 544219820Sjeffstatic inline void 545219820Sjeffclass_remove_file(struct class *class, const struct class_attribute *attr) 546219820Sjeff{ 547219820Sjeff 548219820Sjeff if (class) 549219820Sjeff sysfs_remove_file(&class->kobj, &attr->attr); 550219820Sjeff} 551219820Sjeff 552292987Shselaskystatic inline int 553292987Shselaskydev_to_node(struct device *dev) 554255932Salfred{ 555331756Semaste return -1; 556255932Salfred} 557255932Salfred 558285088Shselaskychar *kvasprintf(gfp_t, const char *, va_list); 559278865Shselaskychar *kasprintf(gfp_t, const char *, ...); 560270710Shselasky 561219820Sjeff#endif /* _LINUX_DEVICE_H_ */ 562