device.h revision 351841
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 351841 2019-09-05 09:30:55Z 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 49328653Shselaskystruct device; 50328653Shselaskystruct fwnode_handle; 51328653Shselasky 52219820Sjeffstruct class { 53219820Sjeff const char *name; 54219820Sjeff struct module *owner; 55219820Sjeff struct kobject kobj; 56219820Sjeff devclass_t bsdclass; 57328653Shselasky const struct dev_pm_ops *pm; 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)); 318299933Shselasky return (0); 319299933Shselasky} 320299933Shselasky 321299933Shselaskystatic inline void 322299933Shselaskydevice_create_release(struct device *dev) 323299933Shselasky{ 324299933Shselasky kfree(dev); 325299933Shselasky} 326299933Shselasky 327299933Shselaskystatic inline struct device * 328299933Shselaskydevice_create_groups_vargs(struct class *class, struct device *parent, 329299933Shselasky dev_t devt, void *drvdata, const struct attribute_group **groups, 330299933Shselasky const char *fmt, va_list args) 331299933Shselasky{ 332299933Shselasky struct device *dev = NULL; 333299933Shselasky int retval = -ENODEV; 334299933Shselasky 335299933Shselasky if (class == NULL || IS_ERR(class)) 336299933Shselasky goto error; 337299933Shselasky 338299933Shselasky dev = kzalloc(sizeof(*dev), GFP_KERNEL); 339299933Shselasky if (!dev) { 340299933Shselasky retval = -ENOMEM; 341299933Shselasky goto error; 342299933Shselasky } 343299933Shselasky 344299933Shselasky dev->devt = devt; 345299933Shselasky dev->class = class; 346299933Shselasky dev->parent = parent; 347299933Shselasky dev->groups = groups; 348299933Shselasky dev->release = device_create_release; 349311801Shselasky /* device_initialize() needs the class and parent to be set */ 350311801Shselasky device_initialize(dev); 351299933Shselasky dev_set_drvdata(dev, drvdata); 352299933Shselasky 353299933Shselasky retval = kobject_set_name_vargs(&dev->kobj, fmt, args); 354299933Shselasky if (retval) 355299933Shselasky goto error; 356299933Shselasky 357299933Shselasky retval = device_add(dev); 358299933Shselasky if (retval) 359299933Shselasky goto error; 360299933Shselasky 361299933Shselasky return dev; 362299933Shselasky 363299933Shselaskyerror: 364299933Shselasky put_device(dev); 365299933Shselasky return ERR_PTR(retval); 366299933Shselasky} 367299933Shselasky 368299933Shselaskystatic inline struct device * 369299933Shselaskydevice_create_with_groups(struct class *class, 370299933Shselasky struct device *parent, dev_t devt, void *drvdata, 371299933Shselasky const struct attribute_group **groups, const char *fmt, ...) 372299933Shselasky{ 373299933Shselasky va_list vargs; 374299933Shselasky struct device *dev; 375299933Shselasky 376299933Shselasky va_start(vargs, fmt); 377299933Shselasky dev = device_create_groups_vargs(class, parent, devt, drvdata, 378299933Shselasky groups, fmt, vargs); 379299933Shselasky va_end(vargs); 380299933Shselasky return dev; 381299933Shselasky} 382299933Shselasky 383328653Shselaskystatic inline bool 384328653Shselaskydevice_is_registered(struct device *dev) 385328653Shselasky{ 386328653Shselasky 387328653Shselasky return (dev->bsddev != NULL); 388328653Shselasky} 389328653Shselasky 390299933Shselaskystatic inline int 391219820Sjeffdevice_register(struct device *dev) 392219820Sjeff{ 393311801Shselasky device_t bsddev = NULL; 394311801Shselasky int unit = -1; 395219820Sjeff 396328653Shselasky if (device_is_registered(dev)) 397311801Shselasky goto done; 398299674Shselasky 399219820Sjeff if (dev->devt) { 400219820Sjeff unit = MINOR(dev->devt); 401219820Sjeff bsddev = devclass_get_device(dev->class->bsdclass, unit); 402311801Shselasky dev->bsddev_attached_here = false; 403299674Shselasky } else if (dev->parent == NULL) { 404299674Shselasky bsddev = devclass_get_device(dev->class->bsdclass, 0); 405311801Shselasky dev->bsddev_attached_here = false; 406311801Shselasky } else { 407311801Shselasky dev->bsddev_attached_here = true; 408299674Shselasky } 409299931Shselasky if (bsddev == NULL && dev->parent != NULL) { 410219820Sjeff bsddev = device_add_child(dev->parent->bsddev, 411219820Sjeff dev->class->kobj.name, unit); 412299931Shselasky } 413299931Shselasky if (bsddev != NULL) { 414219820Sjeff if (dev->devt == 0) 415219820Sjeff dev->devt = makedev(0, device_get_unit(bsddev)); 416219820Sjeff device_set_softc(bsddev, dev); 417219820Sjeff } 418219820Sjeff dev->bsddev = bsddev; 419311801Shselaskydone: 420292987Shselasky kobject_init(&dev->kobj, &linux_dev_ktype); 421219820Sjeff kobject_add(&dev->kobj, &dev->class->kobj, dev_name(dev)); 422219820Sjeff 423219820Sjeff return (0); 424219820Sjeff} 425219820Sjeff 426219820Sjeffstatic inline void 427219820Sjeffdevice_unregister(struct device *dev) 428219820Sjeff{ 429219820Sjeff device_t bsddev; 430219820Sjeff 431219820Sjeff bsddev = dev->bsddev; 432299933Shselasky dev->bsddev = NULL; 433299933Shselasky 434311801Shselasky if (bsddev != NULL && dev->bsddev_attached_here) { 435299960Shselasky mtx_lock(&Giant); 436219820Sjeff device_delete_child(device_get_parent(bsddev), bsddev); 437299960Shselasky mtx_unlock(&Giant); 438299960Shselasky } 439219820Sjeff put_device(dev); 440219820Sjeff} 441219820Sjeff 442299933Shselaskystatic inline void 443299933Shselaskydevice_del(struct device *dev) 444299933Shselasky{ 445299933Shselasky device_t bsddev; 446299933Shselasky 447299933Shselasky bsddev = dev->bsddev; 448299933Shselasky dev->bsddev = NULL; 449299933Shselasky 450311801Shselasky if (bsddev != NULL && dev->bsddev_attached_here) { 451299960Shselasky mtx_lock(&Giant); 452299933Shselasky device_delete_child(device_get_parent(bsddev), bsddev); 453299960Shselasky mtx_unlock(&Giant); 454299960Shselasky } 455299933Shselasky} 456299933Shselasky 457219820Sjeffstruct device *device_create(struct class *class, struct device *parent, 458219820Sjeff dev_t devt, void *drvdata, const char *fmt, ...); 459219820Sjeff 460219820Sjeffstatic inline void 461219820Sjeffdevice_destroy(struct class *class, dev_t devt) 462219820Sjeff{ 463219820Sjeff device_t bsddev; 464219820Sjeff int unit; 465219820Sjeff 466219820Sjeff unit = MINOR(devt); 467219820Sjeff bsddev = devclass_get_device(class->bsdclass, unit); 468299933Shselasky if (bsddev != NULL) 469219820Sjeff device_unregister(device_get_softc(bsddev)); 470219820Sjeff} 471219820Sjeff 472335428Shselasky#define dev_pm_set_driver_flags(dev, flags) do { \ 473335428Shselasky} while (0) 474335428Shselasky 475219820Sjeffstatic inline void 476292987Shselaskylinux_class_kfree(struct class *class) 477219820Sjeff{ 478219820Sjeff 479219820Sjeff kfree(class); 480219820Sjeff} 481219820Sjeff 482219820Sjeffstatic inline struct class * 483219820Sjeffclass_create(struct module *owner, const char *name) 484219820Sjeff{ 485219820Sjeff struct class *class; 486219820Sjeff int error; 487219820Sjeff 488219820Sjeff class = kzalloc(sizeof(*class), M_WAITOK); 489219820Sjeff class->owner = owner; 490328653Shselasky class->name = name; 491292987Shselasky class->class_release = linux_class_kfree; 492219820Sjeff error = class_register(class); 493219820Sjeff if (error) { 494219820Sjeff kfree(class); 495219820Sjeff return (NULL); 496219820Sjeff } 497219820Sjeff 498219820Sjeff return (class); 499219820Sjeff} 500219820Sjeff 501219820Sjeffstatic inline void 502219820Sjeffclass_destroy(struct class *class) 503219820Sjeff{ 504219820Sjeff 505219820Sjeff if (class == NULL) 506219820Sjeff return; 507219820Sjeff class_unregister(class); 508219820Sjeff} 509219820Sjeff 510219820Sjeffstatic inline int 511219820Sjeffdevice_create_file(struct device *dev, const struct device_attribute *attr) 512219820Sjeff{ 513219820Sjeff 514219820Sjeff if (dev) 515219820Sjeff return sysfs_create_file(&dev->kobj, &attr->attr); 516219820Sjeff return -EINVAL; 517219820Sjeff} 518219820Sjeff 519219820Sjeffstatic inline void 520219820Sjeffdevice_remove_file(struct device *dev, const struct device_attribute *attr) 521219820Sjeff{ 522219820Sjeff 523219820Sjeff if (dev) 524219820Sjeff sysfs_remove_file(&dev->kobj, &attr->attr); 525219820Sjeff} 526219820Sjeff 527219820Sjeffstatic inline int 528219820Sjeffclass_create_file(struct class *class, const struct class_attribute *attr) 529219820Sjeff{ 530219820Sjeff 531219820Sjeff if (class) 532219820Sjeff return sysfs_create_file(&class->kobj, &attr->attr); 533219820Sjeff return -EINVAL; 534219820Sjeff} 535219820Sjeff 536219820Sjeffstatic inline void 537219820Sjeffclass_remove_file(struct class *class, const struct class_attribute *attr) 538219820Sjeff{ 539219820Sjeff 540219820Sjeff if (class) 541219820Sjeff sysfs_remove_file(&class->kobj, &attr->attr); 542219820Sjeff} 543219820Sjeff 544292987Shselaskystatic inline int 545292987Shselaskydev_to_node(struct device *dev) 546255932Salfred{ 547331756Semaste return -1; 548255932Salfred} 549255932Salfred 550285088Shselaskychar *kvasprintf(gfp_t, const char *, va_list); 551278865Shselaskychar *kasprintf(gfp_t, const char *, ...); 552270710Shselasky 553219820Sjeff#endif /* _LINUX_DEVICE_H_ */ 554