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